cert-manager-with-kubernetes-ingress
說起免費的HTTPS cert 很多人都會用let’s encrypt的服務 原因是簡單,易用 在VM上裝一個script然後簡單配置一下nginx就可以生成一張數個月的ssl certificate
但當來到kubernetes就有點麻煩 原因是你配置的服務很多可能都不在同一部機上 當你生成了一張ssl cert之後可能要手動去更新相應的配置 而且要建立自動更新難度更大
所以這時侯就可以用到cert-manager了 https://github.com/jetstack/cert-manager 他是一個k8s的addon 可以生成一系列的resources去幫以上的配置自動化 而且除了let’s encrypt之外也支持其他的ssl cert發行者
如果是用let’s encrypt的話 原理大致如下
首先你會生成一個ingress 並加一些特殊的annotation去表明你想cert-manager去幫你配置ssl cert 在這邊你需要先指定一個secret,讓cert-manager把配置好的ssl存放在裡面
之後cert-manager接收到相應的事件觸發後就會開始工作流程 他會先建立一張self-signed的ssl cert並放在該secret裡面 這個時侯你去訪問ingress就會發現https已經能夠使用 但ssl cert是不被瀏覽器信任的
然後cert-manager會建立一個暫時的ingress 去接收來自let’s encrypt的acme challenge 去證明你擁有該域名 如果驗證成功的話就會生成一張正確的ssl cert並更新secret 之後你再訪問https就會看到鎖頭了
實際操作這邊就懶得說了 直接看這裡 https://docs.cert-manager.io/en/latest/tutorials/acme/quick-start/index.html
有一點範例沒有說清楚 但卻至關重要,因為你如你是用nginx-ingress的話好有可能會出現這個問題
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example
annotations:
certmanager.k8s.io/cluster-issuer: "letsencrypt-prod"
certmanager.k8s.io/acme-challenge-type: http01
certmanager.k8s.io/acme-http01-edit-in-place: "true"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- hosts:
- a1.example.com
secretName: al-example-com-tls
rules:
- host: a1.example.com
http:
paths:
- path: /api
backend:
serviceName: backend
servicePort: 80
當中certmanager.k8s.io/acme-http01-edit-in-place: "true"
這句是很重要的
因為nginx-ingress是不能如時接受兩個ingress resources
就是如果你有兩個ingress,而兩個都有同一個host的話
只有其中一個能運行,另一個則無效
大概猜到原因是nginx的配置有關
因為nginx-ingress-controller會接收ingress的配置並且在/etc/nginx/conf.d中生成配置文件
而cert-manager預設是acme-challenger會生成另一個ingress資源出來 所以你要把這個配置設定成true,目的就是希望cert-manager去更改原本的ingress 且不是新開另一個出來