使用helm管理Ingress的TLS Secret證書
為什麼要管理TLS Secret證書
使用ingress將服務以https暴露到叢集外邊時,需要ssl證書。在https://github.com/kubernetes/contrib/tree/master/ingress/controllers/nginx/examples/tls
這個例子中, ingress的定義如下:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: foo namespace: default spec: tls: - hosts: - foo.bar.com secretName: foo-secret rules: - host: foo.bar.com http: paths: - backend: serviceName: echoheaders-x servicePort: 80 path: /
對於域名foo.bar.com
的證書引用的是相同namespace下的secretfoo-secret
。 這說明在Kubernetes中管理站點的TLS證書,使用的是Secret。
假設在已經取得foo.bar.com
的證書和私鑰分別為foo.bar.com.crt
和foo.bar.com.key
,使用下面的命令就可以在default名稱空間中建立TLS型別的Secret:
kubectl create secret tls foo-secret --cert=foo.bar.com.crt --key=foo.bar.com.key -n default
實際情況中,我們的證書往往都是泛域名的證書,例如對於frognew.com
,是支援*.frognew.com
所有的二級域名的。 不同的服務的Ingress被建立在不同的namespace中,每個namespace中都需要建立TLS Secret。 因此需要一種更加整合和高效的方式管理TLS Secret。
先來看一下微服務在開發和部署上要考慮的兩個問題:
- 微服務在開發上需要考慮如何“拆”的問題(拆分的時機、拆分的粒度、拆分的方式)
- 微服務在部署時需要考慮整合與整合的問題,即如何“合”
使用helm管理Ingress的TLS Secret證書
一個產品由多個微服務組成,這個產品部署到Kubernetes上,每個服務都可能需要在Kubernetes上建立下面幾種資源:Ingress, Service, Deployment, ConfigMap, Secret,Job,CronJob等等。我們已經使用Helm,將產品的各個微服務在部署上當成一個邏輯整體,即為每個產品建立一個helm chart,這個helmchart包含了產品所有微服務的部署,將前面每個服務所需要的資源模板化。本篇要解決的是如何整合和高效的管理Ingress的TLS Secret,即將TLS Secret的建立也整合到產品的這個helm chart中。
helm的模板功能十分強大,這裡演示一下如何使用heml chart在Kubernetes管理TLS證書,先簡單實現一下:
chart的模板檔案tls-secrets.yaml:
{{- range $tlsSecretName, $tlsSecret := .Values.tlsSecrets }} apiVersion: v1 kind: Secret type: kubernetes.io/tls metadata: name: {{ $tlsSecretName }} labels: chart: {{ $.Chart.Name }}-{{ $.Chart.Version | replace "+" "_" }} release: {{ $.Release.Name }} heritage: {{ $.Release.Service }} data: tls.crt: {{ $tlsSecret.certificate | b64enc }} tls.key: {{ $tlsSecret.key | b64enc }} {{- end }}
values.yaml:
tlsSecrets: foo-secret: certificate: |- -----BEGIN CERTIFICATE----- ..... -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- ..... -----END CERTIFICATE----- key: |- -----BEGIN PRIVATE KEY----- ...... -----END PRIVATE KEY-----
values.yaml中提供每個TLS Secret的證書和私鑰的文字內容,在tls-secrets.yaml中使用模板的b64enc函式,將證書內容編碼成Secret所需的Base64。 這樣TLS Secret也使用helm管理起來了。
我們的實踐
我們實際實踐中使用的是另一種方式,利用了helm的檔案訪問功能Accessing Files Inside Templates 。
將證書檔案直接放到Chart目錄的files子目錄下:
. ├── charts ├── Chart.yaml ├── files │└── frognew.com │├── cert.pem │├── chain.pem │├── fullchain.pem │├── privkey.pem │└── README ├── templates ├── ...... │└── tls-secrets.yaml ├── values.yaml
chart的模板檔案tls-secrets.yaml:
{{- range $tlsSecretName, $tlsSecret := .Values.tlsSecrets }} apiVersion: v1 kind: Secret type: kubernetes.io/tls metadata: name: {{ $tlsSecretName }} labels: chart: {{ $.Chart.Name }}-{{ $.Chart.Version | replace "+" "_" }} release: {{ $.Release.Name }} heritage: {{ $.Release.Service }} data: tls.crt: {{ $.Files.Get $tlsSecret.certificate | b64enc }} tls.key: {{ $.Files.Get $tlsSecret.key | b64enc }} {{- end }}
values.yaml:
tlsSecrets: frognew-tls-secret: certificate: "files/frognew.com/fullchain.pem" key: "files/frognew.com/privkey.pem"
使用Files.Get去讀取證書檔案內容,通過b64enc編碼為Base64。
-
這種將證書檔案放到Chart中的使用方式需要注意受限於Kubernetes限制,Chart的大小不能超過1MB。
- 關於在Helm模板中訪問檔案的能力還有很多高階用法,具體可以檢視Accessing Files Inside Templates
總結
本文介紹瞭如何使用Helm在Kubernetes中整合管理Ingress的TLS Secret證書,其實對於其它型別的Secret也是通用的。例如對於Opaque Secret
、kubernetes.io/dockercfg Secret
都可以納入到helm chart管理中。這樣部署一個應用所需要的所有資源就全部納入Helm Chart管理了。