Skip to main content

Using Kubernetes cert-manager

under construction

The English version of this document is under construction and will be available soon.


本文將介紹如何在 Kubernetes 中透過 cert-manager 和 Issuer,使用您自己的私有憑證來簽發與管理 TLS 憑證,實現自動化、不中斷的安全管理流程。


開始之前

  • 請先參考此文件建立並存取 K8s 叢集。

Step 1. 部署 echo-server

vim ingress-echo-server-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: echo-server
namespace: default
labels:
app: echo-server
spec:
containers:
- name: echo-server
image: gcr.io/google-containers/echoserver:1.10
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: echo-server-service
namespace: default
spec:
selector:
app: echo-server
ports:
- protocol: TCP
port: 2145
targetPort: 8080
kubectl apply -f ingress-echo-server-pod.yaml

Step 2. 建立自簽根 CA 的 Issuer (selfsigned-issuer)

vim selfsigned-issuer.yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-issuer
namespace: default
spec:
selfSigned: {}
kubectl apply -f selfsigned-issuer.yaml
tip
  • selfsigned-issuer 是用來生成自簽根 CA 的起點。它的 selfSigned: {} 配置表示它會生成一個沒有上層簽發者的證書。
  • 我們需要一個根 CA 作為證書鏈的頂端,後續的證書(如 test.local)將由這個根 CA 簽發。
kubectl get issuer selfsigned-issuer -n default -o yaml

確定 status.conditions 的 type 為 Ready


Step 3. 生成自簽根 CA 證書 (selfsigned-ca)

vim selfsigned-ca.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: selfsigned-ca
namespace: default
spec:
isCA: true
commonName: "Self-Signed CA"
secretName: selfsigned-ca-secret
privateKey:
algorithm: RSA
size: 2048
issuerRef:
name: selfsigned-issuer
kind: Issuer
group: cert-manager.io
kubectl apply -f selfsigned-ca.yaml
tip
  • 此 Certificate 資源使用 selfsigned-issuer 生成一個自簽根 CA。
  • isCA: true 表示這是一個 CA 證書,可以用來簽發其他證書。
  • 生成的證書和私鑰會存儲在 selfsigned-ca-secret 中,作為後續簽發證書的基礎。

Step 4. 創建基於根 CA 的 Issuer (ca-issuer)

vim ca-issuer.yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: ca-issuer
namespace: default
spec:
ca:
secretName: selfsigned-ca-secret
kubectl apply -f ca-issuer.yaml

Step 5. 建立對外 IP

vim ingress-lb-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
name: loadbalancer-ingress-nginx
namespace: ingress-nginx
spec:
type: LoadBalancer
externalTrafficPolicy: Cluster
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
kubectl apply -f ingress-lb-service.yaml
caution

請確保您的安全性群組有設定 ingress 80 與 443 port 的規則。


Step 6. 配置 Ingress 並啟用 TLS

vim ingress-rule.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: echo-ingress
namespace: default
annotations:
cert-manager.io/issuer: "ca-issuer"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- test.local # 虛擬域名,稍後用本地 hosts 文件解析
secretName: my-cert-secret
rules:
- host: test.local
http:
paths:
- path: /vkstestpath
pathType: Prefix
backend:
service:
name: echo-server-service
port:
number: 2145
kubectl apply -f ingress-rule.yaml

Step 7. 設定 /etc/hosts 來解析域名

kubectl get services -n ingress-nginx
sudo vim /etc/hosts

## 加入
EXTERNAL-IP test.local


Step 8. 匯入根 CA

kubectl get secret selfsigned-ca-secret -n default -o jsonpath="{.data.tls\.crt}" | base64 -d > selfsigned-ca.pem
sudo cp ~/selfsigned-ca.pem /usr/local/share/ca-certificates
sudo cp /usr/local/share/ca-certificates/selfsigned-ca.pem /usr/local/share/ca-certificates/selfsigned-ca.crt
sudo update-ca-certificates

Step 9. 確認憑證是否已匯入

curl -v --resolve test.local:443:<external-ip> https://test.local/vkstestpath