这里探讨使用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 这样的专家来促进安全的网络机制,使你们可以更容易地实施。同时,云原生的技术帮助咱们自动这些事情。