Openstack 인프라에 VM으로 K8s를 1.23버전으로 새로 배포하는 도중, Cinder와 연결되는 CSI plugin과 openstack-cloud-contoller-manager가 아래와 같은 이유로 Error가 발생하였습니다.
# kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
….
kube-system openstack-cloud-controller-manager-8zd7x 0/1 Error 1 (11s ago) 14s
kube-system openstack-cloud-controller-manager-hg28f 0/1 Error 1 (11s ago) 14s
kube-system openstack-cloud-controller-manager-p7c5d 0/1 Error 1 (11s ago) 15s
x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0
Go의 1.15 이후 버전부터 위해 K8s API와 관련된 TLS 인증서에서 Subject Alternative Name(SAN)이 없을 때 Common Name(CN)을 참조하도록 하는 기존의 방식이 disable 되었습니다. 문제를 해결하기 위해서는 특정 Pod에 환경 변수를 적용하거나, SAN에 적절한 Domain Name이 포함된 Cert를 발급하는 방법이 있습니다.
1. 환경 변수 설정으로 Go의 변경 사항 무시
외부에서 K8s Cluster로 유입되는 HTTPS 요청의 TLS Cert를 재발급하기 힘든 상황에서 일시적으로 사용할 수 있는 방법입니다. 하지만, Go 1.18 이후 버전에서 부터는 사용할 수 없다고 하네요.
kube-apiserver, csi-plugin, ingress-nginx, registry 등 SAN이 없는 인증서를 가진 Client와의 통신이 필요한 Pod들에 아래 처럼 환경 변수를 추가해 줍니다.
# kubectl edit ds -n kube-system openstack-cloud-controller-manager
spec:
containers:
- args:
...
env: <<<
- name: GODEBUG
value: x509ignoreCN=0
2. subjectAltName가 있는 인증서 생성
위의 환경 변수를 적용하였으나, 여전히 서비스가 불가능한 몇 Pod가 있었습니다. Worker Node에서 K8s에 띄워져 있는 registry로 docker push를 시도하였으나, registry가 사용하는 ingress의 domain name과 ingress-nginx cert의 SAN이 일치하지 않아서 실패하였습니다.
# kubectl get secrets -o json -n ingress-nginx ingress-controller-default-tls | jq '.data."tls.crt"' -r | base64 -d | openssl x509 -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
...
X509v3 extensions:
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Subject Alternative Name:
DNS:ingress.local <<<
X509v3 Extended Key Usage:
TLS Web Server Authentication
ingress-nginx에 설정할 모든 domain name을 포함한 cert를 새로 발급해서 Mount하니 잘 동작하였습니다.
1. RSA key 생성
# openssl genrsa -out server.key 2048
2. cert의 conf 파일 생성
# vim csr.conf
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn
[ dn ]
C = KR
L = Seoul
CN = Kubernetes-ca
[ req_ext ]
subjectAltName = @alt_names
[ alt_names ]
DNS.1 = nginx.local
DNS.2 = k8s-registry.local
DNS.3 = k8s-prometheus.local
...
[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=@alt_names
3. RSA key와 conf 파일로 cert 생성
# openssl req -new -key server.key -out server.csr -config csr.conf
4. Root CA에 수동 CSR approve (Master의 '/etc/kubernetes/pki' 경로에 필요한 파일을 옮긴 후 명령어 실행)
# openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt -days 10000 \
-extensions v3_ext -extfile csr.conf -sha256
5. Cert로 Secret 생성
# kubectl create secret --namespace ingress-nginx tls ingress-controller-default-tls \
--key server.key \
--cert server.crt \
--dry-run=client -o yaml > ingress-controller-default-tls.yaml
Reference
https://golang.google.cn/doc/go1.15#commonname
Go 1.15 Release Notes - The Go Programming Language
Go 1.15 Release Notes <!-- NOTE: In this document and others in this directory, the convention is to set fixed-width phrases with non-fixed-width spaces, as in hello world . Do not send CLs removing the interior tags from such phrases. --> Introduction to
golang.google.cn
GENERAL: What should I do if I get an "x509: certificate relies on legacy Common Name field" error?
Elina Floim 2022-03-31 05:40 Description: x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0 This error indicates that the SSL certificate does not comply with the changes i
jfrog.com
'System Engineering > Kubernetes' 카테고리의 다른 글
Kubelet MCE Memory Error - EDAC (0) | 2024.09.25 |
---|---|
Node Problem Detector and Draino (0) | 2022.09.27 |
Kubernetes Authentication (0) | 2022.09.11 |
Kubernetes Lease (Node Heartbeat) (0) | 2022.01.10 |
8. K8s AutoScaling (0) | 2021.04.11 |