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

相关文章
相关标签/搜索