Viya 4 는 sas-pyconfig CronJob 으로 Python 런타임을 내려받아 공유 볼륨에 설치한다. 이 Job 은 내려받은 소스 압축본의 PGP 서명을 검증하는 단계를 거치는데, Python 버전을 바꾸면 이 단계에서 막히는 경우가 있다. 릴리스마다 서명한 사람이 다르기 때문이다.
Job 파드가 초기화 단계에서 죽고 로그에 다음이 남는다.
{"level":"fatal","source":"pyconfig.app",
"message":"Unable to check signature. Path: /tmp/pyconfig-build-... unknown entity"}
서명 검증을 끄려고 값을 비우거나 none 을 넣으면 다른 오류로 바뀔 뿐 통과하지 않는다.
{"level":"fatal","source":"pyconfig.app",
"message":"The Python source signer file location is not reachable or is invalid.
Key/Value: default_py.python_signer=none"}
python_signer 는 도달 가능한 URL 또는 파일 경로여야 하며, 검증 단계에서 바로 확인한다. 끄는 옵션이 아니다.
Python 릴리스 tarball 의 .asc 서명은 그 시리즈의 릴리스 매니저 개인 키로 만들어진다. 3.9 와 3.10 은 릴리스 매니저가 다르므로 공개키도 다르다. default_py.python_version 만 바꾸고 default_py.python_signer 를 그대로 두면, 바뀐 버전의 서명자 키가 signer 파일에 없어 unknown entity 가 된다.
먼저 실제로 누가 서명했는지 본다. 대상 버전의 .asc 파일만 있으면 된다.
curl -fLO https://www.python.org/ftp/python/3.9.12/Python-3.9.12.tgz.asc
gpg --list-packets Python-3.9.12.tgz.asc | egrep -i 'keyid|issuer'
:signature packet: algo 1, keyid B26995E310250568
hashed subpkt 33 len 21 (issuer fpr v4 E3FF2839C048B25C084DEBE9B26995E310250568)
이 키 ID 의 공개키를 받아 ASCII armor 로 내보낸다.
gpg --keyserver hkps://keys.openpgp.org --recv-keys B26995E310250568 \
|| gpg --keyserver keyserver.ubuntu.com --recv-keys B26995E310250568
gpg --armor --export B26995E310250568 > python-3.9.12-signer.asc
gpg --show-keys python-3.9.12-signer.asc | head
URL 로 지정하면 파드가 그 주소에 닿아야 하므로 프록시나 폐쇄망에서 다시 막힌다. ConfigMap 으로 넣고 파일 경로로 지정하는 편이 안정적이다.
kubectl create cm -n <VIYA_NS> python-signer \
--from-file=python-signer.asc=./python-3.9.12-signer.asc \
--dry-run=client -o yaml | kubectl apply -f -
CronJob 에 볼륨과 마운트를 추가한다. 컨테이너 배열의 순서를 먼저 확인한다 — initContainer 가 있으면 인덱스가 달라진다.
kubectl get cronjob -n <VIYA_NS> sas-pyconfig \
-o jsonpath='{range .spec.jobTemplate.spec.template.spec.containers[*]}{.name}{"\n"}{end}'
kubectl patch cronjob -n <VIYA_NS> sas-pyconfig --type=json -p='[
{"op":"add","path":"/spec/jobTemplate/spec/template/spec/volumes/-",
"value":{"name":"python-signer","configMap":{"name":"python-signer"}}},
{"op":"add","path":"/spec/jobTemplate/spec/template/spec/containers/0/volumeMounts/-",
"value":{"name":"python-signer","mountPath":"/opt/sas/viya/config/pykeys","readOnly":true}}
]'
파라미터 ConfigMap 에서 경로를 가리킨다. 이름 끝에 해시가 붙어 있으므로 실제 이름을 찾아 쓴다.
kubectl get cm -n <VIYA_NS> | grep sas-pyconfig-parameters
kubectl patch cm -n <VIYA_NS> <PARAM_CM> --type=merge -p \
'{"data":{"default_py.python_signer":"/opt/sas/viya/config/pykeys/python-signer.asc"}}'
이 변경은 배포 산출물 밖의 임시 조치다. 다음 배포에서 되돌아가므로, 확인이 끝나면 kustomize 오버레이에 같은 내용을 넣어 영구화한다.
CronJob 에서 Job 을 직접 만들어 돌린다.
kubectl delete job -n <VIYA_NS> sas-pyconfig-job --ignore-not-found
kubectl create job -n <VIYA_NS> --from=cronjob/sas-pyconfig pyconfig-manual-$(date +%H%M%S)
kubectl logs -n <VIYA_NS> -l job-name=pyconfig-manual --tail=200 -f
설치 대상 PVC 에 이전 시도의 산출물이 남아 다음 실행이 엉키는 경우가 있다. 파라미터를 바꿔도 md5sum 기록이 비어 있거나 갱신되지 않는다면 이쪽을 의심한다.
NFS 로 제공되는 PVC 라면 NFS 서버에서 직접 확인할 수 있다.
kubectl get pv | grep <VIYA_NS>
BASE=/<NFS_EXPORT>/pvc-<UID>
ls -al "$BASE"
지우기 전에 어느 파드가 그 PVC 를 쓰는지 확인하고, 해당 워크로드를 내린 뒤에 정리한다. 돌고 있는 파드 밑에서 파일을 지우면 알 수 없는 상태가 된다.
테스트 목적이라면 원래 통과하던 버전으로 되돌리는 것이 가장 빠르다. default_py.python_version 과 함께 python_signer 도 그 버전에 맞는 값으로 같이 되돌려야 한다. 두 값은 짝이다.