使用cert-manager实现Ingress https
什么是https
超文本傳輸協議HTTP協議被用于在Web瀏覽器和網站服務器之間傳遞信息,HTTP協議以明文方式發送內容,不提供任何方式的數據加密,如果攻擊者截取了Web瀏覽器和網站服務器之間的傳輸報文,就可以直接讀懂其中的信息,因此,HTTP協議不適合傳輸一些敏感信息,比如:信用卡號、密碼等支付信息。
為了解決HTTP協議的這一缺陷,需要使用另一種協議:安全套接字層超文本傳輸協議HTTPS,為了數據傳輸的安全,HTTPS在HTTP的基礎上加入了SSL協議,SSL依靠證書來驗證服務器的身份,并為瀏覽器和服務器之間的通信加密。http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。
什么是cert-manager
cert-manager 是一個云原生證書管理開源項目,用于在 Kubernetes 集群中提供 HTTPS 證書并自動續期,支持 Let’s Encrypt, HashiCorp Vault 這些免費證書的簽發。在Kubernetes集群中,我們可以通過 Kubernetes Ingress 和 Let’s Encrypt 實現外部服務的自動化 HTTPS。
在Kubernetes集群中使用 HTTPS 協議,需要一個證書管理器、一個證書自動簽發服務,主要通過 Ingress 來發布 HTTPS 服務,因此需要Ingress Controller并進行配置,啟用 HTTPS 及其路由。
環境依賴
- 本文使用 Helm 安裝,所以請確保 Helm 已安裝,且版本最好>2.10
- 集群必須已經裝有 Ingress Controller
- 外部客戶端配置hosts,IP 指向 Ingress Controller 對外暴露的地址(如果IP是公網地址并做了域名解析,則無需配置)
部署cert-manager
使用helm安裝cert-manager
安裝 CustomResourceDefinition資源
| 1 | kubectl apply -f https://raw.githubusercontent.com/jetstack/cert-manager/release-0.7/deploy/manifests/00-crds.yaml |
?
創建cert-manager namespace
| 1 | kubectl create namespace cert-manager |
?
標記cert-Manager命名空間以禁用資源驗證
| 1 | kubectl label namespace cert-manager certmanager.k8s.io/disable-validation=true |
?
添加 Jetstack Helm repository
| 1 | helm repo add jetstack https://charts.jetstack.io |
?
更新本地Helm chart repository
| 1 | helm repo update |
?
使用Helm chart安裝cert-manager
| 1 2 3 4 5 | helm install \ --name cert-manager \ --namespace cert-manager \ --version v0.7.0 \ jetstack/cert-manager |
?
查看cert-manager部署結果
| 1 2 3 4 5 | # kubectl get pods --namespace cert-manager NAME READY STATUS RESTARTS AGE cert-manager-5658b7db79-824lt 1/1 Running 0 11h cert-manager-cainjector-768fd47f68-ls6zh 1/1 Running 0 11h cert-manager-webhook-5b4bc6b547-8qk2v 1/1 Running 0 11h |
?
創建ClusterIssuer
我們需要先創建一個簽發機構,cert-manager 給我們提供了 Issuer 和 ClusterIssuer 這兩種用于創建簽發機構的自定義資源對象,Issuer 只能用來簽發自己所在 namespace 下的證書,ClusterIssuer 可以簽發任意 namespace 下的證書,這里以 ClusterIssuer 為例創建一個簽發機構:
| 1 2 3 4 5 6 7 8 9 10 11 12 |
?
說明:
- metadata.name 是我們創建的簽發機構的名稱,后面我們創建證書的時候會引用它
- spec.acme.email 是你自己的郵箱,證書快過期的時候會有郵件提醒,不過 cert-manager 會利用 acme 協議自動給我們重新頒發證書來續期
- spec.acme.server 是 acme 協議的服務端,我們這里用 Let’s Encrypt,這個地址就寫死成這樣就行
- spec.acme.privateKeySecretRef 指示此簽發機構的私鑰將要存儲到哪個 Secret 對象中,名稱不重要
- spec.acme.http01 這里指示簽發機構使用 HTTP-01 的方式進行 acme 協議 (還可以用 DNS 方式,acme 協議的目的是證明這臺機器和域名都是屬于你的,然后才準許給你頒發證書)
部署
| 1 |
?
查看clusterissuer創建結果
| 1 2 3 | # kubectl get clusterissuer NAME AGE letsencrypt-prod 11m |
?
創建Certificate
有了簽發機構,接下來我們就可以生成免費證書了,cert-manager 給我們提供了 Certificate 這個用于生成證書的自定義資源對象,它必須局限在某一個 namespace 下,證書最終會在這個 namespace 下以 Secret 的資源對象存儲,創建一個 Certificate 對象:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # cat cert.yaml apiVersion: certmanager.k8s.io/v1alpha1 kind: Certificate metadata: name: dashboard-imroc-io namespace: istio-system spec: secretName: dashboard-imroc-io issuerRef: name: letsencrypt-prod kind: ClusterIssuer dnsNames: - istio.kiali.com acme: config: - http01: ingressClass: traefik domains: - istio.kiali.com |
?
說明:
- spec.secretName 指示證書最終存到哪個 Secret 中
- spec.issuerRef.kind 值為 ClusterIssuer 說明簽發機構不在本 namespace 下,而是在全局
- spec.issuerRef.name 我們創建的簽發機構的名稱 (ClusterIssuer.metadata.name)
- spec.dnsNames 指示該證書的可以用于哪些域名
- spec.acme.config.http01.ingressClass 使用 HTTP-01 方式校驗該域名和機器時,cert-manager 會嘗試創建Ingress 對象來實現該校驗,如果指定該值,會給創建的 Ingress 加上 kubernetes.io/ingress.class 這個 annotation,如果我們的 Ingress Controller 是 traefik Ingress Controller,指定這個字段可以讓創建的 Ingress 被 traefik Ingress Controller 處理。
- spec.acme.config.http01.domains 指示該證書的可以用于哪些域名
執行部署命令
| 1 |
?
查看certificate創建結果
| 1 2 3 | # kubectl get certificate -n istio-system NAME AGE dashboard-imroc-io 54s |
?
執行上述步驟,如有問題,可使用如下命令排查原因
| 1 2 |
?
查看生成的secret 結果
| 1 2 | # kubectl get secret -n istio-system | grep dashboard-imroc-io dashboard-imroc-io kubernetes.io/tls 3 2m32s |
?
測試Ingress使用https
創建一個nginx
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | # cat test-nginx.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: my-nginx spec: replicas: 1 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 443 |
?
需要注意的是上面我們添加的兩個annotations非常重要,這個將告訴 Cert Manager 去生成證書,然后由于我們這里要使用 HTTPS,所以我們需要添加一個 tls 證書,而證書就是通過k8sui-tls這個 Secret 對象來提供的,要注意的是這個 Secret 對象并不是我們手動創建的,而是 Cert Manager 自動創建的證書對應的對應。然后直接創建這個資源對象即可:
| 1 |
?
創建完成后隔一會兒我們可以看到會多出現一個隨機名稱的 Ingress 對象,這個 Ingress 對象就是用來專門驗證證書的:
| 1 2 3 | # kubectl get ingress -n istio-system NAME HOSTS ADDRESS PORTS AGE cm-acme-http-solver-z562f test.nginx.com 80 62s |
?
我們可以通過 Traefik 的 Dashboard 可以觀察到這一變化,驗證成功后,這個 Ingress 對象也自動刪除了:
這個時候我們可以去describe下我們的 Ingress 對象,查看有無報錯
| 1 |
?
同樣我們可以去查看 Cert manager 的 Pod 日志信息:
| 1 | # kubectl logs -f cert-manager-5658b7db79-824lt --namespace cert-manager |
?
最后,我們來打開瀏覽器使用https訪問服務
到這里我們就完成了使用Let’s Encrypt實現Kubernetes Ingress自動化 HTTPS。
參考資料
項目地址:https://github.com/jetstack/cert-manager
文檔地址:https://cert-manager.readthedocs.io
轉載于:https://www.cnblogs.com/cheyunhua/p/10768067.html
總結
以上是生活随笔為你收集整理的使用cert-manager实现Ingress https的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux安装/升级pip
- 下一篇: python 字符编码判断 charde