既上次 Day 16 使用自簽憑證的過程,其實原本是打算使用cert-manager來簽署憑證的,但因為http01 solver發生一些問題,無法正確create出.well-known
path在ingress上,那這次就改用dns01來挑戰去簽出一個可信賴於internet的網站憑證,透過Let's encrypt。
首先為這次的實驗,我先從godaddy租了一個(首年)99元的憑證,因為預計是要透過cloudflare託管的,需要去注意一下domain的level是要能夠被cloudflare支援的。而domain託管的意思就是修改原domain供應商的dns server,將其修改設定為透過cloudflare的dns。
如果明年沒打算要續用,記得都要去取消自動續約喔。
接著我們透過helm安裝 Cert-Manager
helm repo add jetstack https://charts.jetstack.io
helm repo update
kubectl create ns cert-manager
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--version v1.5.3 \
--set prometheus.enabled=false \
--set webhook.timeoutSeconds=4 \
--set installCRDs=true
接著我們要去cloudflare上設定使用的api token,需要開啟的範圍為:
會產出一組token,我們需要將它設定在kubernetes secret中。
kubectl apply -f cloudflare-secret.yml
apiVersion: v1
kind: Secret
metadata:
name: cloudflare-api-token-secret
namespace: cert-manager
type: Opaque
stringData:
api-token: xxxxx-token
接著我們這次是直接使用cluster-issuer(與issuer不同,能跨越namespace),先創建測試用的kubectl apply -f cluster-issuer-stage.yml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
namespace: cert-manager
spec:
acme:
email: xxxxx@gmail.com
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-stage
solvers:
- dns01:
cloudflare:
email: xxxxxx@gmail.com
apiTokenSecretRef:
name: cloudflare-api-token-secret
key: api-token
接著調整ingress,將host置換為homelab.gurubear.info、放入cluster-issuer的annotation
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-staging"
name: ithomelab-ing
namespace: ithomelab
spec:
rules:
- host: homelab.gurubear.info
http:
paths:
- backend:
service:
name: ithomelab-react-deployment
port:
number: 80
path: /
pathType: Prefix
- backend:
service:
name: ithomelab-api-deployment
port:
number: 80
path: /API
pathType: Prefix
tls:
- hosts:
- homelab.gurubear.info
secretName: gurubear-new-tls
檢查event,觀察到tls rotate 成功
打開瀏覽器,檢視憑證確實是let'encrypt的憑證(不安全是正常現象)
這樣子的流程沒問題後,我們再去新增cluster-issuer-prod,最主要就是將acme server調整為正式的server。
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
namespace: cert-manager
spec:
acme:
email: xxxxx@gmail.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- dns01:
cloudflare:
email: xxxxxx@gmail.com
apiTokenSecretRef:
name: cloudflare-api-token-secret
key: api-token
調整ingress annotation的cluster-issuer
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
name: ithomelab-ing
namespace: ithomelab
.
.
.
一樣檢查event,觀察到tls rotate 成功
打開瀏覽器檢查憑證,可以看到被識別為安全的憑證了
因為正式的憑證簽署是有限制的,所以我們確立流程前會先使用測試的server進行驗證,沒問題就轉為正式。透過這樣子方式就可以免費簽署到有效的憑證啦,而後續也能夠透過自動更新來當個實實在在的免費仔。
檢查custom resources內容可以看到
kubectl get certificates.cert-manager.io gurubear-new-tls -n ithomelab -o yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
.......
.......
status:
conditions:
- lastTransitionTime: "2021-09-18T08:03:07Z"
message: Certificate is up to date and has not expired
observedGeneration: 2
reason: Ready
status: "True"
type: Ready
notAfter: "2021-12-17T07:03:04Z"
notBefore: "2021-09-18T07:03:05Z"
renewalTime: "2021-11-17T07:03:04Z"
revision: 2
憑證的有效期限為90天,更新時間為到期前30天,而這些設定也能夠在annotation上去調整,有需要可以自己去官網認真看看囉~
到今天為止,我的鐵人賽第二階段算是告一段落啦。從開發點小程式到建置環境、佈署、發行、domain&憑證、log&monitoring相信都是一般公司不可少的,當然可能還有不足的地方就多多包容了~接下的部分就會是比較亂的內容了,我想到什麼做什麼XD