前言KubeSphere 集群默認(rèn)安裝的證書是自簽發(fā)證書,瀏覽器訪問訪問會(huì)發(fā)出安全提醒。本文記" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

18143453325 在線咨詢 在線咨詢
18143453325 在線咨詢
所在位置: 首頁(yè) > 營(yíng)銷資訊 > 建站知識(shí) > 為 KubeSphere 集群?jiǎn)⒂妹赓M(fèi)的泛域名 SSL 證書并實(shí)現(xiàn)證書自動(dòng)更新和分發(fā)

為 KubeSphere 集群?jiǎn)⒂妹赓M(fèi)的泛域名 SSL 證書并實(shí)現(xiàn)證書自動(dòng)更新和分發(fā)

時(shí)間:2023-02-19 22:24:01 | 來源:建站知識(shí)

時(shí)間:2023-02-19 22:24:01 來源:建站知識(shí)

為 KubeSphere 集群?jiǎn)⒂妹赓M(fèi)的泛域名 SSL 證書并實(shí)現(xiàn)證書自動(dòng)更新和分發(fā):
作者:scwang18,主要負(fù)責(zé)技術(shù)架構(gòu),在容器云方向頗有研究。

前言

KubeSphere 集群默認(rèn)安裝的證書是自簽發(fā)證書,瀏覽器訪問訪問會(huì)發(fā)出安全提醒。本文記錄了利用 let's encrytp 泛域名證書實(shí)現(xiàn) Kubernetes 集群外部服務(wù)自動(dòng)證書配置和證書到期自動(dòng)更新,支持 HTTPS 訪問。我們還部署了證書自動(dòng)分發(fā)組件,實(shí)現(xiàn)證書文件自動(dòng)分發(fā)到其他 namespace 。

架構(gòu)

在 KubeSphere 集群中使用 HTTPS 協(xié)議,需要一個(gè)證書管理器、一個(gè)證書自動(dòng)簽發(fā)服務(wù)

cert-manager 是一個(gè)云原生證書管理開源項(xiàng)目,用于在 KubeSphere 集群中提供 HTTPS 證書并自動(dòng)續(xù)期,支持 Let’s Encrypt, HashiCorp Vault 這些免費(fèi)證書的簽發(fā)。在 KubeSphere 集群中,我們可以通過 Kubernetes Ingress 和 Let’s Encrypt 實(shí)現(xiàn)外部服務(wù)的自動(dòng)化 HTTPS。



Issuers/ClusterIssuers:定義使用什么證書頒發(fā)機(jī)構(gòu) (CA) 來去頒發(fā)證書,Issuers 和 ClusterIssuers 區(qū)別是: issuers 是一個(gè)名稱空間級(jí)別的資源,只能用來簽發(fā)自己所在 namespace 下的證書,ClusterIssuer 是個(gè)集群級(jí)別的資源 可以簽發(fā)任意 namespace 下的證書

Certificate:定義所需的 X.509 證書,該證書將更新并保持最新。Certificate 是一個(gè)命名空間資源,當(dāng) Certificate 被創(chuàng)建時(shí),它會(huì)去創(chuàng)建相應(yīng)的 CertificateRequest 資源來去申請(qǐng)證書。

安裝證書管理器

安裝證書管理器比較簡(jiǎn)單,直接執(zhí)行以下腳本就可以了。

$ kubectl create ns cert-manager$ helm uninstall cert-manager -n cert-manager$ helm install cert-manager jetstack/cert-manager / -n cert-manager / --version v1.8.0 / --set installCRDs=true / --set prometheus.enabled=false / --set 'extraArgs={--dns01-recursive-nameservers-only,--dns01-recursive-nameservers=119.29.29.29:53/,8.8.8.8:53}'

選擇證書頒發(fā)者

cert-manager 支持以下幾種證書頒發(fā)者:

我們選擇使用 ACME 來頒發(fā)證書。

選擇證書校驗(yàn)方式

常用的校驗(yàn)方式有 HTTP-01 、DNS-01 。

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ā)證書。此方法支持泛域名證書。

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/,參數(shù)中 YOUR_DOMAIN 就是被校驗(yàn)的域名,TOKEN 是 ACME 協(xié)議的客戶端負(fù)責(zé)放置的文件,ACME 客戶端就是 cert-manager,它通過修改或創(chuàng)建 Ingress 規(guī)則來增加這個(gè)臨時(shí)校驗(yàn)路徑并指向提供 TOKEN 的服務(wù)。Let’s Encrypt 會(huì)對(duì)比 TOKEN 是否符合預(yù)期,校驗(yàn)成功后就會(huì)頒發(fā)證書。此方法僅適用于給使用 Ingress 暴露流量的服務(wù)頒發(fā)證書,不支持泛域名證書。

優(yōu)劣對(duì)比

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

DNS-01 的校驗(yàn)方式的優(yōu)點(diǎn)是沒有 HTTP-01 校驗(yàn)方式缺點(diǎn),不依賴 Ingress,也支持泛域名;缺點(diǎn)就是不同 DNS 提供商的配置方式不一樣,而且只有 cert-manager 支持的 DNS 提供商才可以選擇這種方式。

Cert-manager 支持使用外部 webhook 的接入 DNS 提供商,正好公司使用騰訊云的 DNSPOD 屬于支持的行列。我們可以選擇 DNS-01 。

HTTP-01 配置示例

這個(gè)配置示例僅供參考,使用這種方式,有多少的 Ingress 服務(wù),就需要申請(qǐng)多少?gòu)堊C書,比較麻煩,但是配置較為簡(jiǎn)單,不依賴 DNS 服務(wù)商。

1. 創(chuàng)建 CA 群集證書頒發(fā)者

證書管理器需要 Issuer 或 ClusterIssuer 資源,才能頒發(fā)證書。 這兩種 Kubernetes 資源的功能完全相同,區(qū)別在于 Issuer 適用于單一命名空間,而 ClusterIssuer 適用于所有命名空間。

# ClusterIssuer.yamlapiVersion: cert-manager.io/v1kind: ClusterIssuermetadata: name: letsencryptspec: acme: email: scwang18@xxx.xxx server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: issuer-account-key solvers: - http01: ingress: class: nginx說明:

$ kubectl apply -f ClusterIssuer.yaml -n cert-manager執(zhí)行成功后,會(huì)將申請(qǐng)的證書文件放置在 issuer-account-key 這個(gè) Secret 中。

查看證書是否自動(dòng)創(chuàng)建成功:

$ kubectl -n infra get certificate

2. 在 Ingress 中使用上步申請(qǐng)到的 SSL 證書

# ingreess-wikijs.yamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata: annotations: cert-manager.io/cluster-issuer: letsencrypt nginx.ingress.kubernetes.io/proxy-body-size: "0" name: ingress-wikijsspec: ingressClassName: nginx rules: - host: wiki.xxx.xxx http: paths: - backend: service: name: wikijs port: number: 3000 path: / pathType: Prefix tls: - hosts: - wikijs.xxx.xxx secretName: ingress-wikijs-tls
注意:在 annotations 里 設(shè)置 cert-manager.io/cluster-issuer 為簽名創(chuàng)建的集群證書頒發(fā)者 letsencrypt

使用 yaml 文件創(chuàng)建 ingress 后,就可以使用該 Ingress 對(duì)外提供 HTTPS 服務(wù)了。

# 執(zhí)行創(chuàng)建 ingresskubectl apply -f ingress-wikijs.yaml -n infra

DNS01 配置示例

使用這種方式需要 DNS 服務(wù)商支持通過 API 創(chuàng)建 DNS 記錄,正好我的 DNS 服務(wù)商是騰訊云 dnspod 支持,因此在我們的及群里,最終采用了這種方式。

這個(gè)方式的配置會(huì)比較麻煩,踩了很久的坑,主要是因?yàn)槲业募簡(jiǎn)⒂昧吮镜?DNS 服務(wù)器,默認(rèn) cert-manager 會(huì)通過本地 DNS 服務(wù)器去驗(yàn)證通過 API 創(chuàng)建的 DNS txt 記錄,會(huì)一直檢查不到新增的 txt 記錄,造成在 challenge 階段就一直 pendding。解決方案附后。

1. 在 dnspod 創(chuàng)建 API ID 和 API Token

參考騰訊云官方文檔(https://support.dnspod.cn/Kb/showarticle/tsid/227/)記錄下創(chuàng)建的 API ID 和 API Token (加碼處理,需要自行獲取自己的 API ID 和 API Token)。

AKIDVt3z4uVss11xjIdmddgMmHXXssssHp9D2buxrWR8SekbG2gqdflQs5xxxviGagX8TYO

2. 安裝 cert-manager-webhook-dnspod

使用 helm 安裝 roc/cert-manager-webhook-dnspod。

$ helm repo add roc https://charts.imroc.cc$ helm uninstall cert-manager-webhook-dnspod -n cert-manager$ helm install cert-manager-webhook-dnspod roc/cert-manager-webhook-dnspod / -n cert-manager / --set clusterIssuer.secretId=AKIDVt3z4uVss11xjIdmddgMmHXXssssHp9D2buxrWR8 / --set clusterIssuer.secretKey=SekbG2gqdflQs5xxxviGagX8TYO / --set clusterIssuer.email=xxx@xxx.xxx

3. 創(chuàng)建泛域名證書

# ipincloud-crt.yamlapiVersion: cert-manager.io/v1kind: Certificatemetadata: name: ipincloud-crtspec: secretName: ipincloud-crt issuerRef: name: dnspod kind: ClusterIssuer group: cert-manager.io dnsNames: - "*.xxx.xxx"創(chuàng)建集群證書頒發(fā)者:

$ kubectl apply -f ipincloud-crt.yaml -n infra

4. 驗(yàn)證證書

查看證書是否創(chuàng)建成功:

$ kubectl get Certificate -n cert-managerNAME READY SECRET AGEcert-manager-webhook-dnspod-ca True cert-manager-webhook-dnspod-ca 18mcert-manager-webhook-dnspod-webhook-tls True cert-manager-webhook-dnspod-webhook-tls 18mipincloud-crt True ipincloud-crt 3m12s以上可以看出 ipincloud-crt 已經(jīng)創(chuàng)建成功, READY 狀態(tài)也是 True。

查看證書對(duì)應(yīng)的域名:

$ kubectl describe Certificate ipincloud-crt -n cert-managerName: ipincloud-crtNamespace: cert-managerLabels: <none>Annotations: <none>API Version: cert-manager.io/v1Kind: CertificateMetadata: Creation Timestamp: 2022-05-07T14:19:07Z ...Spec: Dns Names: *.xxx.xxx Issuer Ref: Group: cert-manager.io Kind: ClusterIssuer Name: dnspod Secret Name: ipincloud-crtStatus: Conditions: Last Transition Time: 2022-05-07T14:19:14Z Message: Certificate is up to date and has not expired Observed Generation: 1 Reason: Ready Status: True Type: Ready Not After: 2022-08-05T13:19:11Z Not Before: 2022-05-07T13:19:12Z Renewal Time: 2022-07-06T13:19:11Z Revision: 1Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Issuing 4m35s cert-manager-certificates-trigger Issuing certificate as Secret does not exist Normal Generated 4m35s cert-manager-certificates-key-manager Stored new private key in temporary Secret resource "ipincloud-crt-4ml59" Normal Requested 4m35s cert-manager-certificates-request-manager Created new CertificateRequest resource "ipincloud-crt-r76wp" Normal Issuing 4m28s cert-manager-certificates-issuing The certificate has been successfully issued 從 Certificate 的描述信息可以看到,這個(gè)證書是對(duì)應(yīng)所有 *.xxx.xxx 的泛域名。

查看證書內(nèi)容:

$ kubectl describe secret ipincloud-crt -n cert-managerName: ipincloud-crtNamespace: cert-managerLabels: <none>Annotations: cert-manager.io/alt-names: *.xxx.xxx cert-manager.io/certificate-name: ipincloud-crt cert-manager.io/common-name: *.xxx.xxx cert-manager.io/ip-sans: cert-manager.io/issuer-group: cert-manager.io cert-manager.io/issuer-kind: ClusterIssuer cert-manager.io/issuer-name: dnspod cert-manager.io/uri-sans: Type: kubernetes.io/tlsData====tls.crt: 5587 bytestls.key: 1675 bytesTLS 證書保存在 cert-manager 命名空間里的 ipincloud-crt secret??梢怨┧?``*.http://xxx.xxx` 的服務(wù)使用。

其他

這個(gè)過程中,遇到最大的坑是:我的集群使用了自建的 DNS 服務(wù)器,默認(rèn) cert-manager 會(huì)使用這個(gè)集群的自建 DNS SERVER 進(jìn)行證書發(fā)行的驗(yàn)證,雖然通過調(diào)用 dnspod 的 webook 在 騰訊云 DNS 服務(wù)器上創(chuàng)建的 _acme-challenge 握手?jǐn)?shù)據(jù),但是在我的自建 DNS 里是查不到的,所以會(huì)一直卡 pending 狀態(tài)。

$ kubectl get challenge -ANAMESPACE NAME STATE DOMAIN AGEcert-manager ipincloud-crt-f9kp6-381578565-136350475 pending xxx.xxx 24s查看原因是:

Waiting for DNS-01 challenge propagation: DNS record for "xxx.xxx" not yet

$ kubectl -n cert-manager describe challenge ipincloud-crt-f9kp6-381578565-136350475Name: ipincloud-crt-f9kp6-381578565-136350475Namespace: cert-managerLabels: <none>Annotations: <none>API Version: acme.cert-manager.io/v1Kind: Challenge---中間略---Status: Presented: true Processing: true Reason: Waiting for DNS-01 challenge propagation: DNS record for "xxx.xxx" not yet propagated State: pendingEvents: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Started 41s cert-manager-challenges Challenge scheduled for processing Normal Presented 39s cert-manager-challenges Presented challenge using DNS-01 challenge mechanism查了很多資料,在官網(wǎng)上找到解決方案。辦法是讓 cert-manager 強(qiáng)制使用指定的 DNS 服務(wù)器進(jìn)行握手驗(yàn)證。

我是用的是 helm 安裝 cert-manager,所以添加一下 set 參數(shù)。

--set 'extraArgs={--dns01-recursive-nameservers-only,--dns01-recursive-nameservers=119.29.29.29:53/,8.8.8.8:53}' 參考文檔:https://cert-manager.io/docs/configuration/acme/dns01/#setting-nameservers-for-dns01-self-check

配置證書復(fù)制到其他 namespace

安裝 kubed

$ helm repo add appscode https://charts.appscode.com/stable/$ helm repo update$ helm install kubed appscode/kubed / --version v0.13.2 / --namespace cert-manager

修改 Certificated 文件

為 certificated 對(duì)象設(shè)置 secretTemplate, 設(shè)置需要同步到哪些 namespace。

# ipincloud-crt.yamlapiVersion: cert-manager.io/v1kind: Certificatemetadata: name: ipincloud-crtspec: secretName: ipincloud-crt issuerRef: name: dnspod kind: ClusterIssuer group: cert-manager.io dnsNames: - "*.xxx.xxx" secretTemplate: annotations: kubed.appscode.com/sync: "cert-manager-tls=ipincloud-crt"

給需要同步的目標(biāo) namespace 打 label

上一步的 secretTemplate 里指定了同步的目標(biāo) namespace 的 label 過濾條件 cert-manager-tls=ipincloud-crt , 因此,我們需要對(duì)接收同步 secret 的 namespace 打上相應(yīng)的 label。

$ kubectl label ns default cert-manager-tls=ipincloud-crt$ kubectl label ns app cert-manager-tls=ipincloud-crt$ kubectl label ns dev-app cert-manager-tls=ipincloud-crt$ kubectl label ns dev-infra cert-manager-tls=ipincloud-crt$ kubectl label ns dev-wly cert-manager-tls=ipincloud-crt$ kubectl label ns infra cert-manager-tls=ipincloud-crt$ kubectl label ns istio-system cert-manager-tls=ipincloud-crt$ kubectl label ns uat-app cert-manager-tls=ipincloud-crt$ kubectl label ns uat-wly cert-manager-tls=ipincloud-crt$ kubectl label ns wly cert-manager-tls=ipincloud-crt$ kubectl label ns kubesphere-controls-system cert-manager-tls=ipincloud-crt

查看是否復(fù)制成功

查看目標(biāo) namespace 是否復(fù)制 secret 成功。

$ kubectl get secret ipincloud-crtNAME TYPE DATA AGEipincloud-crt kubernetes.io/tls 2 18m查看復(fù)制的 secret ,可以看到 label 信息中記錄了證書來源信息。

$ kubectl describe secret ipincloud-crtName: ipincloud-crtNamespace: defaultLabels: kubed.appscode.com/origin.cluster=unicorn kubed.appscode.com/origin.name=ipincloud-crt kubed.appscode.com/origin.namespace=cert-managerAnnotations: cert-manager.io/alt-names: *.xxx.xxx cert-manager.io/certificate-name: ipincloud-crt cert-manager.io/common-name: *.xxx.xxx cert-manager.io/ip-sans: cert-manager.io/issuer-group: cert-manager.io cert-manager.io/issuer-kind: ClusterIssuer cert-manager.io/issuer-name: dnspod cert-manager.io/uri-sans: kubed.appscode.com/origin: {"namespace":"cert-manager","name":"ipincloud-crt","uid":"b4713633-731e-4151-844f-0f6d9cf6352c","resourceVersion":"12531075"}Type: kubernetes.io/tlsData====tls.crt: 5587 bytestls.key: 1675 bytes

使用 TLS 證書配置 Ingress

設(shè)置 Ingress

kind: IngressapiVersion: networking.k8s.io/v1metadata: name: wikijs namespace: infra annotations: nginx.ingress.kubernetes.io/proxy-body-size: '0'spec: ingressClassName: nginx tls: - hosts: - wiki.xxx.xxx secretName: ipincloud-crt rules: - host: wiki.xxx.xxx http: paths: - path: / pathType: ImplementationSpecific backend: service: name: wikijs port: number: 3000

測(cè)試

以上配置完成后,就可以使用 HTTPS 來訪問新的 wiki.js 服務(wù)了。

$ curl -I https://wiki.xxx.xxxHTTP/1.1 302 FoundDate: Sat, 07 May 2022 14:52:39 GMTContent-Type: text/plain; charset=utf-8Content-Length: 28Connection: keep-aliveX-Frame-Options: denyX-XSS-Protection: 1; mode=blockX-Content-Type-Options: nosniffX-UA-Compatible: IE=edgeReferrer-Policy: same-originContent-Language: zhSet-Cookie: loginRedirect=%2F; Max-Age=900; Path=/; Expires=Sat, 07 May 2022 15:07:39 GMTLocation: /loginVary: Accept, Accept-EncodingStrict-Transport-Security: max-age=15724800; includeSubDomains如上所示,就是成功啟動(dòng)了 HTTPS 。

參考

關(guān)鍵詞:證書,實(shí)現(xiàn),分發(fā),更新,啟用,免費(fèi)

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉