使用helm管理Ingress的TLS Secret证书

2018-09-12 阅读: Helm Kubernetes

为什么要管理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下的secret foo-secret。 这说明在Kubernetes中管理站点的TLS证书,使用的是Secret。

假设在已经取得foo.bar.com的证书和私钥分别为foo.bar.com.crtfoo.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在Kubernetes中整合管理Ingress的TLS Secret证书,其实对于其它类型的Secret也是通用的。例如对于Opaque Secretkubernetes.io/dockercfg Secret都可以纳入到helm chart管理中。这样部署一个应用所需要的所有资源就全部纳入Helm Chart管理了。

参考

标题:使用helm管理Ingress的TLS Secret证书
本文链接:https://blog.frognew.com/2018/09/using-helm-manage-tls-secret.html
转载请注明出处。

目录