- 什么是cert-manager茶行?
- cert-manager的工作原理
- 安裝和部署cert-manager
- 具體的使用
- 需要注意的事項(xiàng)
什么是cert-manager?
cert-manager 是一個(gè)云原生證書管理開源項(xiàng)目气堕,用于在 Kubernetes 集群中提供 HTTPS 證書并自動(dòng)續(xù)期纺腊,支持 Let’s Encrypt, HashiCorp Vault 這些免費(fèi)證書的簽發(fā)。在Kubernetes集群中茎芭,我們可以通過 Kubernetes Ingress 和 Let’sEncrypt實(shí)現(xiàn)外部服務(wù)的自動(dòng)化HTTPS揖膜。
在Kubernetes集群中使用 HTTPS 協(xié)議,需要一個(gè)證書管理器梅桩、一個(gè)證書自動(dòng)簽發(fā)服務(wù)壹粟,主要通過 Ingress 來發(fā)布 HTTPS 服務(wù),因此需要Ingress Controller并進(jìn)行配置宿百,啟用 HTTPS 及其路由趁仙。
letsencrypt:基于ACME協(xié)議, 生成免費(fèi)的證書工具。</br>
ACME: 自動(dòng)證書管理環(huán)境 Automated Certificate Management Environment垦页。
cert-manager的工作原理
這里有2個(gè)概念就是issuer雀费、certificate:
issuer:證書頒發(fā)者,它是k8s的資源痊焊,接受執(zhí)行證書簽名請(qǐng)求生成簽名證書盏袄。有issuer和clusterIssuer兩個(gè)類別忿峻,區(qū)別就在與issuer要指定namespace,只能在指定的namespace下工作辕羽,而clusterIssuer是不指定namespace逛尚,可以在整個(gè)集群下工作。
certificate:可以把這個(gè)資源理解為執(zhí)行證書刁愿,通過執(zhí)行證書的配置绰寞,會(huì)向cert-manager對(duì)應(yīng)的issuer發(fā)送一個(gè)certificateRequest,如果成功酌毡,就會(huì)將生成的密鑰tls.key和證書tls.crt存到secret里面克握。
證書頒布原理
Let’s Encrypt 利用 ACME 協(xié)議來校驗(yàn)域名是否真的屬于你,校驗(yàn)成功后就可以自動(dòng)頒發(fā)免費(fèi)證書枷踏,證書有效期只有 90 天,在到期前需要再校驗(yàn)一次來實(shí)現(xiàn)續(xù)期掰曾,幸運(yùn)的是 cert-manager 可以自動(dòng)續(xù)期旭蠕,這樣就可以使用永久免費(fèi)的證書了。如何校驗(yàn)?zāi)銓?duì)這個(gè)域名屬于你呢旷坦?主流的兩種校驗(yàn)方式是 HTTP-01 和 DNS-01掏熬。
HTTP-01 校驗(yàn)原理
HTTP-01 的校驗(yàn)原理是給你域名指向的 HTTP 服務(wù)增加一個(gè)臨時(shí) location ,Let’s Encrypt 會(huì)發(fā)送 http 請(qǐng)求到 http://<YOUR_DOMAIN>/.well-known/acme-challenge/<TOKEN>秒梅,YOUR_DOMAIN 就是被校驗(yàn)的域名旗芬,TOKEN 是 ACME 協(xié)議的客戶端負(fù)責(zé)放置的文件,在這里 ACME 客戶端就是 cert-manager捆蜀,它通過修改 Ingress 規(guī)則來增加這個(gè)臨時(shí)校驗(yàn)路徑并指向提供 TOKEN 的服務(wù)疮丛。Let’s Encrypt 會(huì)對(duì)比 TOKEN 是否符合預(yù)期,校驗(yàn)成功后就會(huì)頒發(fā)證書辆它。此方法僅適用于給使用 Ingress 暴露流量的服務(wù)頒發(fā)證書誊薄,并且不支持泛域名證書。
DNS-01 校驗(yàn)原理
DNS-01 的校驗(yàn)原理是利用 DNS 提供商的 API Key 拿到你的 DNS 控制權(quán)限锰茉, 在 Let’s Encrypt 為 ACME 客戶端提供令牌后呢蔫,ACME 客戶端 (cert-manager) 將創(chuàng)建從該令牌和您的帳戶密鑰派生的 TXT 記錄,并將該記錄放在 _acme-challenge.<YOUR_DOMAIN>飒筑。 然后 Let’s Encrypt 將向 DNS 系統(tǒng)查詢?cè)撚涗浧酰绻业狡ヅ漤?xiàng),就可以頒發(fā)證書协屡。此方法不需要你的服務(wù)使用 Ingress俏脊,并且支持泛域名證書。
安裝和部署cert-manager
安裝
安裝方式有兩種
- 使用helm安裝:
echo $(helm version) //我這里使用的helm 是v2.14.3
// 安裝Tiller
helm init --upgrade --wait
echo "Install the CustomResourceDefinition resources separately"
kubectl apply --validate=false -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.13/deploy/manifests/00-crds.yaml
echo "Add the Jetstack Helm repository"
helm repo add jetstack https://charts.jetstack.io
helm repo update
echo "Install the cert-manager helm chart"
helm upgrade --install cert-manager --namespace cert-manager --version v0.13.1 jetstack/cert-manager
安裝cert-manager chart著瓶,如果helm版本不一樣联予,命令也不一樣
# Helm v3+
$ helm install \
cert-manager jetstack/cert-manager \
--namespace cert-manager \
--version v0.14.0
# Helm v2
$ helm install \
--name cert-manager \
--namespace cert-manager \
--version v0.14.0 \
jetstack/cert-manager
安裝成功可以后啼县,kubectl get pods -n cert-manager
cert-manager-webhook的啟動(dòng)時(shí)間會(huì)稍微長一點(diǎn),大約也是在1min之內(nèi)沸久,到這里季眷,cert-manager也就安裝好了。
- 也可以使用regular manifests 進(jìn)行安裝卷胯,具體的可以參考 https://cert-manager.io/docs/installation/kubernetes/#installing-with-regular-manifests
具體的使用
這里是使用http01校驗(yàn)子刮,給使用ingress暴露流量的服務(wù)頒發(fā)證書。
接下來需要?jiǎng)?chuàng)建一個(gè)證書頒布者Issuer:kubectl apply -f ./kubernetes/issuer.yml
issuer-stg.yml
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: evalizhangli@gmail.com
privateKeySecretRef:
name: letsencrypt-staging
solvers:
- http01:
ingress:
class: nginx
需要注意的地方就是窑睁,如果還在開發(fā)測(cè)試階段挺峡,盡可能的不要使用letsencrypt-prod,因?yàn)閟taging的證書頒布server對(duì)于創(chuàng)建證書沒有限制担钮,但是prod的證書頒布server有很嚴(yán)格的次數(shù)限制橱赠。
issuer.yml
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: evalizhangli@gmail.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
創(chuàng)建成功以后可以kubectl get clusterIssuer
看到這個(gè)issuer的狀態(tài)為ready,就代表已經(jīng)創(chuàng)建好了箫津。
接下來狭姨,我們只需要在你需要使用到cert-manager管理證書的ingress的configfile里面改動(dòng),然后將你的服務(wù)重新部署
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example
namespace: ${NAMESPACE}
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- my.example.net
secretName: tls-secret-my
rules:
- host: my.example.net
http:
paths:
- path: /
backend:
serviceName: my-service
servicePort: http
使用起來非常的方便以及簡單苏遥,kubectl get certificate -n ${NAMESPACE}
就能看到 tls-secret-my
的certificate饼拍,等到狀態(tài)ready為true, kubectl get secret -n ${NAMESPACE}
也能看到tls-secret-my
的secret田炭。
如果certificate的ready為false师抄,可以kubectl describe certificate tls-secret-my -n ${NAMESPACE}
查看一下envents,或者查看一下cert-manager pod 的log教硫。
需要注意的事項(xiàng)
- 在開發(fā)和測(cè)試階段叨吮,盡可能的使用letsencrypt-staging
- letsencrypt-prod有rate limit,如果查看cert-manager的log一直顯示waiting CertificateRequest status is not complete栋豫,有可能就是申請(qǐng)創(chuàng)建證書達(dá)到了次數(shù)限制
- 同一個(gè)主域下一周只能申請(qǐng) 50 張證書 (例如 http://www.example.com 的主域是 http://example.com)
- 每個(gè)賬戶每個(gè)域名每小時(shí)申請(qǐng)驗(yàn)證失敗的次數(shù)為 5 次
- 每周只能創(chuàng)建 5 個(gè)重復(fù)的證書挤安,即使是通過不同賬戶創(chuàng)建
- 每個(gè)賬戶同一個(gè) IPv4 地址每 3 小時(shí)最多可創(chuàng)建 10 張證書
- 每個(gè)多域名(SAN)證書最多包含 100 個(gè)子域
- 更新證書沒有次數(shù)的限制,但是更新證書會(huì)受到上述重復(fù)證書的限制
- 如果要重新install cert-manger丧鸯,可以使用
helm delete --purge cert-manager
章節(jié)外:使用DNS01校驗(yàn)蛤铜,頒發(fā)泛域名證書
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: example-issuer
spec:
acme:
email: evalizhangli@gmail.com
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: example-issuer-account-key
solvers:
- dns01:
clouddns:
project: my-project
serviceAccountSecretRef:
name: prod-clouddns-svc-acct-secret
key: dns01-solver-credential.json
selector:
dnsNames:
- 'my.example.net'
- '*.example.net'
dnsZones:
- '*.example.net'
這里我是google cloud的dns服務(wù),對(duì)應(yīng)的config可以參考https://cert-manager.io/docs/configuration/acme/dns01/