antony@notes:~/networking$ cat "Cert-manager-with-SelfSigned-Issuers.md"
Cert-manager with SelfSigned Issuers
Cert-manager with SelfSigned Issuers
實作目標
透過 Cert-manager 產生自簽 CA 憑證,再透過這個自簽的 CA 憑證簽發給 Ingress 用的 TLS 憑證,最後建一個 Nginx 來測試 TLS Ingress 是否符合預期,且憑證到期時間會自動更新。
先備知識
Issuer
Issuers 和 ClusterIssuers 是 Kubernetes 中的資源,代表著憑證授權機構(certificate authorities [CAs]),它們可以通過證書簽名請求 ( certificate signing requests )來生成簽名的證書 ( signed certificates )。
# 建立工作目錄
$ mkdir -p ~/wulin/cert-manager && cd ~/wulin/cert-manager
# 建立 selfsigned Issuer
$ cat <<EOF > default-selfsigned-issuer
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-issuer
namespace: default
spec:
selfSigned: {}
EOF
$ kubectl apply -f default-selfsigned-issuer
# 檢查 Issuer 的狀態
$ kubectl get issuers selfsigned-issuer -o wide
NAME READY STATUS AGE
selfsigned-issuer True 15d
# Bootstrapping CA Issuers
$ cat <<EOF > default-ca.certificate.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: my-selfsigned-ca
namespace: default
spec:
isCA: true
commonName: my-selfsigned-ca
secretName: root-secret
subject:
organizations:
- Lab
organizationalUnits:
- Test
duration: 2h
renewBefore: 1h
privateKey:
algorithm: ECDSA
size: 256
issuerRef:
name: selfsigned-issuer
kind: Issuer
group: cert-manager.io
EOF
$ kubectl apply -f default-ca.certificate.yaml
# 可以看到 root-secret ( CA 憑證 ) 已經被自動生成,並存在 Secret 中
$ kubectl get certificate my-selfsigned-ca -o wide
NAME READY SECRET ISSUER STATUS AGE
my-selfsigned-ca True root-secret selfsigned-issuer Certificate is up to date and has not expired 22s
# 檢視 root-secret
$ kubectl get secret root-secret -o yaml
apiVersion: v1
data:
ca.crt:
...
tls.crt:
...
tls.key:
...
#
$ cat <<EOF > default-my-ca-issuer.yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: my-ca-issuer
namespace: default
spec:
ca:
secretName: root-secret
EOF
$ kubectl apply -f default-my-ca-issuer.yaml
$ kubectl get issuers my-ca-issuer -o wide
NAME READY STATUS AGE
my-ca-issuer True Signing CA verified 8m12sRun Nginx with TLS Ingress
$ kubectl run nginx --image=harbor.example.com/rancher/library-nginx:1.19.2-alpine -l run=nginx
$ kubectl get pods -l run=nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 18s 10.42.44.57 k2w1 <none> <none>
$ NGINX_PodIP=$(kubectl get pods -l run=nginx -o custom-columns=POD_IP:.status.podIP --no-headers)
$ curl http://$NGINX_PodIP
...
<title>Welcome to nginx!</title>
...
# Create TLS Ingress
$ cat <<EOF > default-tls-nginx-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-nginx-ingress
namespace: default
annotations:
# add an annotation indicating the issuer to use.
cert-manager.io/issuer: my-ca-issuer
spec:
ingressClassName: nginx
tls:
- hosts:
- 192.168.11.174.nip.io
secretName: tls-nginx-ingress
rules:
- host: 192.168.11.174.nip.io
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx
port:
number: 80
EOF
# 檢視 Ingress 部屬狀態
$ kubectl get ing
NAME CLASS HOSTS ADDRESS PORTS AGE
tls-nginx-ingress nginx 192.168.11.174.nip.io 192.168.11.173,192.168.11.174 80, 443 45s
# 測試透過 Ingress 連接網站
$ curl -k https://192.168.11.174.nip.io
...
<title>Welcome to nginx!</title>
...
# 匯出 CA 憑證
$ kubectl get secret root-secret -o jsonpath='{.data.ca\.crt}' | base64 -d >
ing-ca.crt
$ sudo cp ing-ca.crt /etc/pki/ca-trust/source/anchors/ && sudo sudo update-ca-trust
# 這次 curl 就不用加 -k 跳過憑證確認了
$ curl https://192.168.11.174.nip.io
...
<title>Welcome to nginx!</title>
...
# 檢視憑證過期日期
$ echo | openssl s_client -connect 192.168.11.174.nip.io:443 2>/dev/null | openssl x509 -noout -dates
notBefore=Apr 15 03:08:33 2024 GMT
notAfter=Jul 14 03:08:33 2024 GMT
# 下載 Cert-manager 管理工具
$ curl -fsSL -o cmctl.tar.gz https://github.com/cert-manager/cert-manager/releases/latest/download/cmctl-linux-amd64.tar.gz && tar xzf cmctl.tar.gz && sudo mv cmctl /usr/local/bin
# 手動 renew 憑證到期日期
$ cmctl renew tls-nginx-ingress
Manually triggered issuance of Certificate default/tls-nginx-ingress
$ echo | openssl s_client -connect 192.168.11.174.nip.io:443 2>/dev/null | openssl x509 -noout -dates
notBefore=Apr 15 03:32:44 2024 GMT
notAfter=Jul 14 03:32:44 2024 GMT
# 清除環境
$ kubectl delete -f ./ && kubectl delete pod nginx
certificate.cert-manager.io "my-selfsigned-ca" deleted
issuer.cert-manager.io "my-ca-issuer" deleted
issuer.cert-manager.io "selfsigned-issuer" deleted
ingress.networking.k8s.io "tls-nginx-ingress" deleted
pod "nginx" deleted流程圖解
https://cert-manager.io/docs/usage/ingress/#inner-workings-diagram-for-developers