騰訊云手把手教你使用cert-manager簽發(fā)免費(fèi)證書(shū)

來(lái)源: 騰訊云原生
作者:roc 陳鵬
時(shí)間:2020-10-27
17304
隨著HTTPS不斷普及,越來(lái)越多的網(wǎng)站都在從HTTP升級(jí)到HTTPS,使用HTTPS就需要向權(quán)威機(jī)構(gòu)申請(qǐng)證書(shū),需要付出一定的成本,如果需求數(shù)量多,也是一筆不小的開(kāi)支。

概述

隨著HTTPS不斷普及,越來(lái)越多的網(wǎng)站都在從HTTP升級(jí)到HTTPS,使用HTTPS就需要向權(quán)威機(jī)構(gòu)申請(qǐng)證書(shū),需要付出一定的成本,如果需求數(shù)量多,也是一筆不小的開(kāi)支。cert-manager是Kubernetes上的全能證書(shū)管理工具,如果對(duì)安全級(jí)別和證書(shū)功能要求不高,可以利用cert-manager[1]基于ACME[2]協(xié)議與Let's Encrypt[3]來(lái)簽發(fā)免費(fèi)證書(shū)并自動(dòng)續(xù)期,實(shí)現(xiàn)永久免費(fèi)使用證書(shū)。

cert-manager工作原理

cert-manager部署到Kubernetes集群后,它會(huì)watch它所支持的CRD資源,我們通過(guò)創(chuàng)建CRD資源來(lái)指示cert-manager為我們簽發(fā)證書(shū)并自動(dòng)續(xù)期:

640.png

解釋下幾個(gè)關(guān)鍵的資源:

·Issuer/ClusterIssuer:用于指示cert-manager用什么方式簽發(fā)證書(shū),本文主要講解簽發(fā)免費(fèi)證書(shū)的ACME方式。ClusterIssuer與Issuer的唯一區(qū)別就是Issuer只能用來(lái)簽發(fā)自己所在namespace下的證書(shū),ClusterIssuer可以簽發(fā)任意namespace下的證書(shū)。

·Certificate:用于告訴cert-manager我們想要什么域名的證書(shū)以及簽發(fā)證書(shū)所需要的一些配置,包括對(duì)Issuer/ClusterIssuer的引用。

免費(fèi)證書(shū)簽發(fā)原理

Let’s Encrypt利用ACME協(xié)議來(lái)校驗(yàn)域名是否真的屬于你,校驗(yàn)成功后就可以自動(dòng)頒發(fā)免費(fèi)證書(shū),證書(shū)有效期只有90天,在到期前需要再校驗(yàn)一次來(lái)實(shí)現(xiàn)續(xù)期,幸運(yùn)的是cert-manager可以自動(dòng)續(xù)期,這樣就可以使用永久免費(fèi)的證書(shū)了。如何校驗(yàn)這個(gè)域名是否屬于你呢?主流的兩種校驗(yàn)方式是HTTP-01和DNS-01,詳細(xì)校驗(yàn)原理可參考Let's Encrypt的運(yùn)作方式[4],下面將簡(jiǎn)單描述下。

HTTP-01校驗(yàn)原理

HTTP-01的校驗(yàn)原理是給你域名指向的HTTP服務(wù)增加一個(gè)臨時(shí)location,Let’s Encrypt會(huì)發(fā)送http請(qǐng)求到http:///.well-known/acme-challenge/,YOUR_DOMAIN就是被校驗(yàn)的域名,TOKEN是ACME協(xié)議的客戶端負(fù)責(zé)放置的文件,在這里ACME客戶端就是cert-manager,它通過(guò)修改或創(chuàng)建Ingress規(guī)則來(lái)增加這個(gè)臨時(shí)校驗(yàn)路徑并指向提供TOKEN的服務(wù)。Let’s Encrypt會(huì)對(duì)比TOKEN是否符合預(yù)期,校驗(yàn)成功后就會(huì)頒發(fā)證書(shū)。此方法僅適用于給使用Ingress暴露流量的服務(wù)頒發(fā)證書(shū),并且不支持泛域名證書(shū)。

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.。然后Let’s Encrypt將向DNS系統(tǒng)查詢?cè)撚涗?,如果找到匹配?xiàng),就可以頒發(fā)證書(shū)。此方法不需要你的服務(wù)使用Ingress,并且支持泛域名證書(shū)。

校驗(yàn)方式對(duì)比

HTTP-01的校驗(yàn)方式的優(yōu)點(diǎn)是:配置簡(jiǎn)單通用,不管使用哪個(gè)DNS提供商都可以使用相同的配置方法;缺點(diǎn)是:需要依賴Ingress,如果你的服務(wù)不是用Ingress暴露流量的就不適用,而且不支持泛域名證書(shū)。

DNS-01的校驗(yàn)方式的優(yōu)點(diǎn)是沒(méi)有HTTP-01校驗(yàn)方式缺點(diǎn),不依賴Ingress,也支持泛域名;缺點(diǎn)就是不同DNS提供商的配置方式不一樣,而且DNS提供商有很多,cert-manager的Issuer不可能每個(gè)都去支持,不過(guò)有一些可以通過(guò)部署實(shí)現(xiàn)了cert-manager的Webhook[5]的服務(wù)來(lái)擴(kuò)展Issuer進(jìn)行支持,比如DNSPod和阿里DNS,詳細(xì)Webhook列表請(qǐng)參考:https://cert-manager.io/docs/configuration/acme/dns01/#webhook

選擇哪種方式呢?條件允許的話,建議是盡量用DNS-01的方式,限制更少,功能更全。

操作步驟

安裝cert-manager

通常直接使用yaml方式一鍵安裝cert-manager到集群,參考官網(wǎng)文檔Installing with regular manifests[6]。

cert-manager官方使用的鏡像在quay.io,國(guó)內(nèi)拉取可能比較慢,也可以使用下面命令一鍵安裝(使用同步到國(guó)內(nèi)CCR的鏡像):

kubectl apply--validate=false-f https://raw.githubusercontent.com/TencentCloudContainerTeam/manifest/master/cert-manager/cert-manager.yaml

以上命令安裝方式要求集群版本不低于1.16。

配置DNS

登錄你的DNS提供商后臺(tái),配置域名的DNS A記錄,指向你需要證書(shū)的后端服務(wù)對(duì)外暴露的IP地址,以cloudflare為例:

640 (1).png

HTTP-01校驗(yàn)方式簽發(fā)證書(shū)

如果使用HTTP-01的校驗(yàn)方式,需要用到Ingress來(lái)配合校驗(yàn)。cert-manager會(huì)通過(guò)自動(dòng)修改Ingress規(guī)則或自動(dòng)新增Ingress來(lái)實(shí)現(xiàn)對(duì)外暴露校驗(yàn)所需的臨時(shí)HTTP路徑,這個(gè)就是在給Issuer配置http01校驗(yàn),指定Ingress的name或class的區(qū)別(見(jiàn)下面的示例)。

TKE自帶的Ingress是每個(gè)Ingress資源都會(huì)對(duì)應(yīng)一個(gè)CLB,如果你使用TKE自帶的Ingress暴露服務(wù),并且使用HTTP-01方式校驗(yàn),那么只能使用自動(dòng)修改Ingress的方式,不能自動(dòng)新增Ingress,因?yàn)樽詣?dòng)新增出來(lái)的Ingress會(huì)自動(dòng)創(chuàng)建其它CLB,對(duì)外的IP地址就與我們后端服務(wù)的Ingress不一致,Let's Encrypt校驗(yàn)時(shí)就無(wú)法從我們服務(wù)的Ingress找到校驗(yàn)所需的臨時(shí)路徑,從而導(dǎo)致校驗(yàn)失敗,無(wú)法簽發(fā)證書(shū)。如果使用自建Ingress,比如在TKE上部署Nginx Ingress,同一個(gè)Ingress class的Ingress共享同一個(gè)CLB,這樣就可以使用自動(dòng)新增Ingress的方式。

下面給出一些示例。

如果你的服務(wù)使用TKE自帶的Ingress暴露服務(wù),不太適合用cert-manager簽發(fā)管理免費(fèi)證書(shū),因?yàn)樽C書(shū)是要上傳到證書(shū)管理[7]來(lái)引用的,不在K8S中管理。

假設(shè)是在TKE上部署Nginx Ingress,且后端服務(wù)的Ingress是prod/web,創(chuàng)建Issuer示例:

apiVersion: cert-manager.io/v1

kind: Issuer

metadata:

  name: letsencrypt-http01

  namespace: prod

spec:

  acme:

    server: https://acme-v02.api.letsencrypt.org/directory

    privateKeySecretRef:

      name: letsencrypt-http01-account-key

    solvers:

    - http01:

       ingress:

         name: web # 指定被自動(dòng)修改的 Ingress 名稱

使用上面的Issuer簽發(fā)證書(shū),cert-manager會(huì)自動(dòng)修改prod/web這個(gè)Ingress資源,以暴露校驗(yàn)所需的臨時(shí)路徑,這是自動(dòng)修改Ingress的方式,你可以使用自動(dòng)新增Ingress的方式,示例:

apiVersion: cert-manager.io/v1

kind: Issuer

metadata:

  name: letsencrypt-http01

  namespace: prod

spec:

  acme:

    server: https://acme-v02.api.letsencrypt.org/directory

    privateKeySecretRef:

      name: letsencrypt-http01-account-key

    solvers:

    - http01:

       ingress:

         class: nginx # 指定自動(dòng)創(chuàng)建的 Ingress 的 ingress class

使用上面的Issuer簽發(fā)證書(shū),cert-manager會(huì)自動(dòng)創(chuàng)建Ingress資源,以暴露校驗(yàn)所需的臨時(shí)路徑。

有了Issuer,接下來(lái)就可以創(chuàng)建Certificate并引用Issuer進(jìn)行簽發(fā)了,示例:

apiVersion: cert-manager.io/v1

kind: Certificate

metadata:

  name: test-mydomain-com

  namespace: prod

spec:

  dnsNames:

  - test.mydomain.com # 要簽發(fā)證書(shū)的域名

  issuerRef:

    kind: Issuer

    name: letsencrypt-http01 # 引用 Issuer,指示采用 http01 方式進(jìn)行校驗(yàn)

  secretName: test-mydomain-com-tls # 最終簽發(fā)出來(lái)的證書(shū)會(huì)保存在這個(gè) Secret 里面

DNS-01校驗(yàn)方式簽發(fā)證書(shū)

如果使用DNS-01的校驗(yàn)方式,就需要看你使用的哪個(gè)DNS提供商了,cert-manager內(nèi)置了一些DNS提供商的支持,詳細(xì)列表和用法請(qǐng)參考Supported DNS01 providers[8],不過(guò)cert-manager不可能去支持所有的DNS提供商,如果沒(méi)有你所使用的DNS提供商怎么辦呢?有兩種方案:

·方案一:設(shè)置Custom Nameserver。在你的DNS提供商后臺(tái)設(shè)置custom nameserver,指向像cloudflare這種可以管理其它DNS提供商域名的nameserver地址,具體地址可登錄cloudflare后臺(tái)查看:

640 (2).png

下面是namecheap設(shè)置custom nameserver的示例:

640 (3).png

最后配置Issuer指定DNS-01驗(yàn)證時(shí),加上cloudflare的一些信息即可(見(jiàn)下文示例)。

·方案二:使用Webhook。使用cert-manager的Webhook來(lái)擴(kuò)展cert-manager的DNS-01驗(yàn)證所支持的DNS提供商,已經(jīng)有許多第三方實(shí)現(xiàn),包括國(guó)內(nèi)常用的DNSPod與阿里DNS,詳細(xì)列表參考:Webhook[9]。

下面以cloudflare為例來(lái)簽發(fā)證書(shū):

1.登錄cloudflare,點(diǎn)到My Profile>API Tokens>Create Token來(lái)創(chuàng)建Token:

640 (4).png

復(fù)制Token并妥善保管:

640 (5).png

將Token保存到Secret中:

apiVersion: v1

kind: Secret

metadata:

  name: cloudflare-api-token-secret

  namespace: cert-manager

type: Opaque

stringData:

  api-token: <API Token> # 粘貼 Token 到這里,不需要 base64 加密。

如果是要?jiǎng)?chuàng)建ClusterIssuer,Secret需要?jiǎng)?chuàng)建在cert-manager所在命名空間中,如果是Issuer,那就創(chuàng)建在Issuer所在命名空間中。

創(chuàng)建ClusterIssuer:

apiVersion: cert-manager.io/v1

kind: ClusterIssuer

metadata:

  name: letsencrypt-dns01

spec:

  acme:

    privateKeySecretRef:

      name: letsencrypt-dns01

    server: https://acme-v02.api.letsencrypt.org/directory

    solvers:

    - dns01:

        cloudflare:

          email: my-cloudflare-acc@example.com # 替換成你的 cloudflare 郵箱賬號(hào),API Token 方式認(rèn)證非必需,API Keys 認(rèn)證是必需

          apiTokenSecretRef:

            key: api-token

            name: cloudflare-api-token-secret # 引用保存 cloudflare 認(rèn)證信息的 Secret

創(chuàng)建Certificate:

apiVersion: cert-manager.io/v1

kind: Certificate

metadata:

  name: test-mydomain-com

  namespace: default

spec:

  dnsNames:

  - test.mydomain.com # 要簽發(fā)證書(shū)的域名

  issuerRef:

    kind: ClusterIssuer

    name: letsencrypt-dns01 # 引用 ClusterIssuer,指示采用 dns01 方式進(jìn)行校驗(yàn)

  secretName: test-mydomain-com-tls # 最終簽發(fā)出來(lái)的證書(shū)會(huì)保存在這個(gè) Secret 里面

獲取和使用證書(shū)

創(chuàng)建好Certificate后,等一小會(huì)兒,我們可以kubectl查看是否簽發(fā)成功:

$ kubectl get certificate -n prod

NAME                          READY           SECRET                             AGE

test-mydomain-com   True               test-mydomain-com-tls   1m

如果READY為False表示失敗,可以通過(guò)describe查看event來(lái)排查失敗原因:

$kubectl describe certificate test-mydomain-com-n prod

如果為T(mén)rue表示簽發(fā)成功,證書(shū)就保存在我們所指定的Secret中(上面的例子是default/test-mydomain-com-tls),可以通過(guò)kubectl查看:

$ kubectl get secret test-mydomain-com-tls -n default

...

data:

  tls.crt: <cert>

  tls.key: <private key>

其中tls.crt就是證書(shū),tls.key是密鑰。

你可以將它們掛載到你需要證書(shū)的應(yīng)用中,或者使用自建的Ingress,可以直接在Ingress中引用secret,示例:

apiVersion: networking.k8s.io/v1beta1

kind: Ingress

metadata:

  name: test-ingress

  annotations:

    kubernetes.io/Ingress.class: nginx

spec:

  rules:

  - host: test.mydomain.com

    http:

      paths:

      - path: /web

        backend:

          serviceName: web

          servicePort: 80

  tls:

    hosts:

    - test.mydomain.com

    secretName: test-mydomain-com-tls

小結(jié)

本文介紹了cert-manager的工作原理,安裝方法以及簽發(fā)免費(fèi)證書(shū)的兩種校驗(yàn)方式(HTTP-01與DNS-01)的原理、對(duì)比以及操作方法。

參考資料

[1]cert-manager:https://cert-manager.io/

[2]ACME:https://tools.ietf.org/html/rfc8555X

[3]Let's Encrypt:https://letsencrypt.org/

[4]Let's Encrypt的運(yùn)作方式:https://letsencrypt.org/zh-cn/how-it-works/

[5]Webhook:https://cert-manager.io/docs/concepts/webhook/

[6]Installing with regular manifests:https://cert-manager.io/docs/installation/kubernetes/#installing-with-regular-manifests

[7]證書(shū)管理:https://console.cloud.tencent.com/ssl

[8]Supported DNS01 providers:https://cert-manager.io/docs/configuration/acme/dns01/#supported-dns01-providers

[9]Webhook:https://cert-manager.io/docs/configuration/acme/dns01/#webhook

[10]Issuer API文檔:https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.Issuer

[11]Certificate API文檔:https://cert-manager.io/docs/reference/api-docs/#cert-manager.io/v1.Certificate

立即登錄,閱讀全文
版權(quán)說(shuō)明:
本文內(nèi)容來(lái)自于騰訊云原生,本站不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。文章內(nèi)容系作者個(gè)人觀點(diǎn),不代表快出海對(duì)觀點(diǎn)贊同或支持。如有侵權(quán),請(qǐng)聯(lián)系管理員(zzx@kchuhai.com)刪除!
相關(guān)文章
騰訊云數(shù)據(jù)庫(kù)PostgreSQL全面支持PG 17
騰訊云數(shù)據(jù)庫(kù)PostgreSQL全面支持PG 17
即日起,騰訊云PostgreSQL全面支持PostgreSQL 17.0。所有用戶可使用大版本升級(jí)能力升級(jí)至最新的PostgreSQL 17.0進(jìn)行體驗(yàn),也可以在產(chǎn)品購(gòu)買(mǎi)頁(yè)直接購(gòu)買(mǎi)。
騰訊云
云服務(wù)
2024-12-152024-12-15
高可用這個(gè)問(wèn)題,加機(jī)器就能解決?
高可用這個(gè)問(wèn)題,加機(jī)器就能解決?
互聯(lián)網(wǎng)服務(wù)的可用性問(wèn)題是困擾企業(yè)IT人員的達(dá)摩克利斯之劍:防于未然,體現(xiàn)不出價(jià)值。已然發(fā)生,又面臨P0危機(jī)。就更別提穩(wěn)定性建設(shè)背后顯性的IT預(yù)算問(wèn)題與隱性的人員成本問(wèn)題。
騰訊云
云服務(wù)
2024-11-252024-11-25
TDSQL TDStore引擎版替換HBase:在歷史庫(kù)場(chǎng)景中的成本與性能優(yōu)勢(shì)
TDSQL TDStore引擎版替換HBase:在歷史庫(kù)場(chǎng)景中的成本與性能優(yōu)勢(shì)
HBase憑借其高可用性、高擴(kuò)展性和強(qiáng)一致性,以及在廉價(jià)PC服務(wù)器上的低部署成本,廣泛應(yīng)用于大規(guī)模數(shù)據(jù)分析。
騰訊云
云服務(wù)
2024-11-042024-11-04
復(fù)雜查詢性能弱,只讀分析引擎來(lái)幫忙
復(fù)雜查詢性能弱,只讀分析引擎來(lái)幫忙
隨著當(dāng)今業(yè)務(wù)的高速發(fā)展,復(fù)雜多表關(guān)聯(lián)的場(chǎng)景越來(lái)越普遍。但基于行式存儲(chǔ)的數(shù)據(jù)庫(kù)在進(jìn)行復(fù)雜查詢時(shí)性能相對(duì)較弱。
騰訊云
云服務(wù)
2024-11-022024-11-02
優(yōu)質(zhì)服務(wù)商推薦
更多
掃碼登錄
打開(kāi)掃一掃, 關(guān)注公眾號(hào)后即可登錄/注冊(cè)
加載中
二維碼已失效 請(qǐng)重試
刷新
賬號(hào)登錄/注冊(cè)
個(gè)人VIP
小程序
快出海小程序
公眾號(hào)
快出海公眾號(hào)
商務(wù)合作
商務(wù)合作
投稿采訪
投稿采訪
出海管家
出海管家