使用Let's Encrypt實現Kubernetes Ingress自動化HTTPS

這裏探討使用Let's Encrypt實現Kubernetes Ingress中自動建立、管理和部署證書,實現HTTPS支持。html

HTTPS是什麼?

  • HTTPS是加密的http協議,提供數據通道加密和服務器驗證功能。
    • 使用支持https的瀏覽器上網,數據傳輸是加密的、並且能夠防止中間被篡改;
    • 對服務器須要進行驗證,若是是假冒服務器瀏覽器會告警並拒絕與之鏈接,從而保護用戶免於上當受騙。
  • 不過,僅僅一個協議,也不是萬能的。
    • 好比瀏覽器若是就是被篡改的版本,徹底可能將網站資源指向錯誤的路標;
    • 證書依賴第三方機構認證,已經出現過假冒證書的狀況,自簽名證書也難以提供真正的安全;
    • 部分瀏覽器或定製程序能夠越過證書驗證直接訪問資源(不建議使用)。
  • 須要指出的是,在隱私保護方面,https不支持IP地址隱藏、也不支持域名加密。

在Kubernetes中使用HTTPS

在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 ingressLet's Encrypt 實現外部服務端點的自動化。意味着,只要你願意,能夠直接 "切換到 HTTPS"。所提供的插件能夠處理須要作的一切。github

預先要求

爲了在Kubernetes中自動化HTTPS,須要先部署 ingress controller。 什麼是 ingress呢? 經過ingress(中文譯:入口)在 Kubernetes中的使用, 能夠控制外部流量的路由。Ingress controller 與 Kubernetes API 實現了集成,但其服務須要安裝相應的引擎(目前有Nginx和Traefic兩種)。api

要求的軟件:瀏覽器

  • Ingress controller,在 Kubernetes上部署。
  • 自動化的 DNS(域名服務)。

我寫過一些關於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 這樣的專家來促進安全的網絡機制,使你們可以更容易地實施。同時,雲原生的技術幫助咱們自動這些事情。

相關文章
相關標籤/搜索