因為工作上的需求,需要在 k8s 環境上設定一個進階功能:使用者可以透過 CNAME 指定自己的 domain 到服務上,例如使用者擁有 example.cc 可以透過 CNAME 指向到 hosting.example.com,之後在服務上的 web service 可以透過 virtual host 的方式使用自定義網域。
其中透過 CNAME 本身連到外部 web service 可以透過 virtual host 的方式完成,然而憑證就相對麻煩: 對於憑證本身會驗證 DNS 等相關欄位,這導致需要 1) 使用者自己匯入憑證 或者 2) 服務方替申請憑證。
就結論來說:
- 自身服務的 sub-domain 使用 DNS-01
- 使用者自行設定的網域則使用 HTTP-01
Cert Manager
cert-manager
是一個用 Go 寫的 k8s addon,可以用來偵測、申請、更新 letsencrypt 的憑證。
可以直接透過官方提供的釋出版本直接安裝 (目前最新版本為
v1.0.2
),之後可以透過 kubectl apply -f
安裝。之後可以使用 kubectl -n cert-manager get pod
判斷是否已經安裝完成三個主要 POD 服務跟兩個
service。
之後撰寫自己需要的 Issuer 的設定檔,按照官方的 範例 來產生一個 selfsign 的憑證:
apiVersion: v1
kind: Namespace
metadata:
name: cert-manager-test
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: test-selfsigned
namespace: cert-manager-test
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: selfsigned-cert
namespace: cert-manager-test
spec:
dnsNames:
- example.com
secretName: selfsigned-cert-tls
issuerRef:
name: test-selfsigned
之後就可以用 kubectl -n cert-manager-test describe certificate
檢查憑證的狀況
kubtctl plugin
針對 cert-manager 有推出自己的 k8s plugin (Linux-based),或者使用 kubectl-krew 安裝。
Web Hook
如果要使用 Godaddy 來使用 DNS-01 驗證方式,就需要安裝額外的 web-hook 套件。 找了一下之後使用 snowdrop 所提供的 webhook 套件
權限
如果需要全自動化設定域名、可以透過程式化的方式設定整個 k8s 環境:用 Python 當做例子就可以使用 kubernetes-client 所提供的套件。使用上可以設定 service account 管理相關權限: 需要注意的是 service account、issuer、certificate 跟 deployment 需要在同一個 namespace。下面是一個範例的設定檔:
apiVersion: v1
kind: ServiceAccount
metadata:
name: issuer
namespace: cert-issuer
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: hostname-issuer
rules:
# create new certificate by issuer
- apiGroups:
- cert-manager.io
resources:
- issuers
- certificates
verbs:
- get
- list
- create
- patch
- delete
# create related ingress
- apiGroups:
- networking.k8s.io
resources:
- ingresses
verbs:
- get
- list
- create
- delete
- patch
- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: issuer
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: hostname-issuer
subjects:
- kind: ServiceAccount
name: issuer
namespace: cert-issuer
透過安裝上面的設定檔之後,只要透過程式化的方式新增一個 Certificate 並指定 issuerRef 到上面的 Issuer, cert-manager 就看處裡後續憑證相關的部分。
權限檢查
K8S 是透過 RESTFul API 來控制資源,可以透過 kubectl auth can-i
來檢查是否有足夠權限控制資源。
如果是針對 service account,就需要使用 --as system:serviceaccount:<NAMESPACE>:<NAME>