這裏探討使用Let's Encrypt實現Kubernetes Ingress中自動建立、管理和部署證書,實現HTTPS支持。html
在Kubernetes集羣中使用HTTPS協議發佈服務,須要一個證書管理器、一個證書自動簽發服務,主要經過Ingress來發布https服務,所以須要Ingress Controller並進行配置,啓用https及其路由。nginx
在Kubernetes中使用HTTPS的支持軟件架構組成以下:git
幾天之前,讀到 Troy Hunt寫的關於HTTPS的文章,標題是 "HTTPS is easy"(http://www.javashuo.com/article/p-kfaortfm-bw.html)。 HTTPS 並不難,尤爲是在 Kubernetes這樣的平臺上。不幸的是,不是全部的人都贊成這一觀點。我理解對於大型機構來講,把全部的流量都轉化到HTTPS上是很是困難的事情。但你能夠將HTTPS用於全部的外部流量,經過 Kubernetes ingress 和 Let's Encrypt 實現外部服務端點的自動化。意味着,只要你願意,能夠直接 "切換到 HTTPS"。所提供的插件能夠處理須要作的一切。github
爲了在Kubernetes中自動化HTTPS,須要先部署 ingress controller。 什麼是 ingress呢? 經過ingress(中文譯:入口)在 Kubernetes中的使用, 能夠控制外部流量的路由。Ingress controller 與 Kubernetes API 實現了集成,但其服務須要安裝相應的引擎(目前有Nginx和Traefic兩種)。api
要求的軟件:瀏覽器
我寫過一些關於ingress controller的文章。如何知足這些需求,能夠參考:AWS Cost Savings by Utilizing Kubernetes Ingress with Classic ELB。安全
管理 SSL/TLS 證書的組件是Cert manager。它對於每個ingress endpoint將會自動建立一個新的證書。當 certificates 過時時還能自動更新。Cert manager 也能夠和其它的providers一塊兒工做,例如HashiCorp Vault。在個人與Kubernetes相關的文章中,我使用 Helm來部署,主要是爲了方便,但在生產環境下,我並不建議如此。參見 read my blog post about Helm。服務器
你須要配置一個缺缺省的 cluster issuer,當部署Cert manager的時候,用於支持 kubernetes.io/tls-acme: "true"
annotation來自動化TLS:網絡
ingressShim.defaultIssuerName=letsencrypt-prod ingressShim.defaultIssuerKind=ClusterIssuer
你將在後面定義 letsencrypt-prod
cluster issuer。先來部署 Cert manager:架構
⚡ helm install --name cert-manager \ --namespace ingress \ --set ingressShim.defaultIssuerName=letsencrypt-prod \ --set ingressShim.defaultIssuerKind=ClusterIssuer \ stable/cert-manager ⚡ kubectl get pod -n ingress --selector=app=cert-manager NAME READY STATUS RESTARTS AGE cert-manager-cert-manager-7797579f9-m4dbc 1/1 Running 0 1m
當安裝 Cert manager 提供的 Kubernetes custom resources:
⚡ kubectl get crd NAME AGE certificates.certmanager.k8s.io 1m clusterissuers.certmanager.k8s.io 1m issuers.certmanager.k8s.io 1m
最後一步,定義集羣範圍內的 issuer letsencrypt-prod
,在上面的步驟中咱們已經設置了。使用自定義資源來定義cluster issuer clusterissuers.certmanager.k8s.io
:
⚡ cat << EOF| kubectl create -n ingress -f - apiVersion: certmanager.k8s.io/v1alpha1 kind: ClusterIssuer metadata: name: letsencrypt-prod spec: acme: server: https://acme-v02.api.letsencrypt.org/directory email: me@example.com privateKeySecretRef: name: letsencrypt-prod http01: {} EOF
注意: 使用有效的 email 地址!
如今測試一下。部署一個新的Ghost blog 到集羣上,將經過ghost.test.akomljen.com
域名訪問,缺省使用了 HTTPS 。使用Helm來安裝:
⚡ cat > values.yaml <<EOF serviceType: ClusterIP ghostHost: ghost.test.akomljen.com ingress: enabled: true annotations: kubernetes.io/ingress.class: nginx kubernetes.io/tls-acme: "true" hosts: - ghost.test.akomljen.com tls: - secretName: test-app-tls hosts: - ghost.test.akomljen.com mariadb: replication: enabled: true EOF ⚡ helm install --name test-app \ -f values.yaml \ stable/ghost
注意: 這裏有一個 a Helm issue, boolean 值沒法做爲 string 被正確滴解析。這就是爲何我要使用文件而不是 --set
和 --set-string
參數來更新缺省值的緣由。
幾分鐘後,你可使用定義的endpoint打開網頁,HTTPS缺省支持!
很容易,對吧?咱們很幸運有像 Troy Hunt 這樣的專家來促進安全的網絡機制,使你們可以更容易地實施。同時,雲原生的技術幫助咱們自動這些事情。