问题 Google Kubernetes Engine:为服务类型启用HTTPS


我在GKE上有一个应用程序,我希望仅通过HTTPS提供,因此我获得了一个签名证书,以使用TLS保护应用程序。

我已经查看了很多有关如何执行此操作的教程,但它们都是指使用Ingress并使用LetsEncrypt和KubeLego自动请求证书。但我希望继续使用外部负载平衡器(谷歌提供给我的计算引擎实例),但我只想通过https访问我的应用程序。

如何应用我的server.crt和server.key文件来启用https.Do I  将其应用于负载平衡器 或者到kubernetes集群。


2526
2018-01-26 18:57


起源

可能你想看看这个开源项目。 github.com/appscode/voyager - aerokite


答案:


在通过HTTPS公开您的应用程序时,Ingress可能是您最好的选择。 Ingress资源指定后端服务,因此您将继续将您的应用程序公开为Kubernetes服务,只需将类型设置为 ClusterIP。这将生成一个对您的群集“内部”的服务,并且一旦您进行设置,就可以通过Ingress从外部访问。

现在,特别是在Google Kubernetes Engine(GKE)中,群集中定义的任何入口资源都将由Google Cloud Load Balancer提供,因此我认为您不必担心部署自己的Ingress Controller(例如Nginx Ingress Controller) 。

就TLS而言,如果您有证书,可以使用自己的证书。必须通过Kubernetes Secret将证书上载到群集。一旦定义了该秘密,您就可以在Ingress定义中引用该秘密。 (https://kubernetes.io/docs/concepts/services-networking/ingress/#tls

您可以使用以下命令创建密钥:

kubectl create secret tls my-app-certs --key /tmp/tls.key --cert /tmp/tls.crt

一旦掌握了秘密,就可以在入口资源中引用它:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: my-app-ingress
spec:
  tls:
  - secretName: my-app-certs
  backend:
    serviceName: s1
    servicePort: 80

创建入口资源后,GKE将配置负载均衡器并为您提供可以使用的可公开访问的IP:

kubectl get ingress my-app-ingress

以下是一个很好的教程,带您了解Ingress on GKE: https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer


6
2018-01-30 23:51



非常感谢,我已经完成了这个,并使用默认的nginx服务进行测试,但我希望它表明该网站在地址栏中是安全的,但它没有。此过程是否表明该网站是安全的? - Ogbe
@Ogbe通过这种沟通方法很难弄明白。你是如何获得证书的?它是否受到您的浏览器的信任?是否提供证书? DNS名称是否与证书中的名称(或SAN中的名称)相匹配? - AlexBrand
注意:Kubernetes秘密存储在etcd上的PLAINTEXT中,任何有权访问API服务器的节点都可以访问任何秘密,即使没有分配。小心谨慎! kubernetes.io/docs/concepts/configuration/secret/#risks - BookOfGreg
从Kubernetes 1.7开始,可以启用静态加密来加密秘密: kubernetes.io/docs/tasks/administer-cluster/encrypt-data - AlexBrand
我给这个答案奖励,我已经能够安装ssl证书,但是我需要将所有http请求路由到https,将ssl_redirect注释设置为true并允许https注释为false并没有帮助实现这一点 - Ogbe


Ingress是最简单的方法。您不需要使用LetsEncrypt,您可以指定自己的证书。

Ingress控制器只是一个NGINX代理。如果你不想使用入口(为什么?),你必须自己创建这个代理服务。这基本上是这项服务的入口。


3
2018-01-27 01:57



使用入口意味着我必须创建一个新的负载均衡器? - Ogbe
为LoadBalancer类型的每个服务(每个外部公开的服务)创建一个负载均衡器。这个想法是拥有一个入口,所有其他服务应该是内部的。 - Lev Kuznetsov


解决方案:

在运行时获取证书,很多人使用LetsEncrypt因为它有多简单,但您可以将证书存储在实际安全的存储中,例如您的云平台的密钥管理存储,或运行您自己的Hashicorp Vault(我推荐Hashicorp Vault,它是 非常 好!)然后在运行时安全地检索你的秘密。


您注意到每个教程或指南都建议动态获取它们。

但他们都提到使用Ingress并使用LetsEncrypt和KubeLego自动请求证书。

其原因如下:

https://kubernetes.io/docs/concepts/configuration/secret/#risks

风险

在API服务器中,秘密数据以明文形式存储在etcd中;因此:   管理员应限制对管理员用户的etcd访问权限   API服务器中的秘密数据在etcd使用的磁盘上处于静止状态;管理员可能想要在不再使用时擦除/粉碎etcd使用的磁盘

可以创建使用秘密的窗格的用户也可以看到该秘密的值。即使apiserver策略不允许该用户读取秘密对象,用户也可以运行暴露秘密的pod。

如果运行了etcd的多个副本,则它们之间将共享秘密。默认情况下,etcd不保护与SSL / TLS的对等通信,但可以配置。

目前,任何在任何节点上具有root权限的人都可以通过模拟kubelet从apiserver中读取任何秘密。计划的功能是仅向实际需要它们的节点发送秘密,以限制根漏洞对单个节点的影响。

因此,每个人都正确地推荐你 不要使用K8s秘密 用于存储贵重证书,因为它不适合工作。


2
2018-02-04 13:54



这确实是另一种做法。但要明确的是,从Kubernetes 1.7开始,可以启用静态加密来加密秘密: kubernetes.io/docs/tasks/administer-cluster/encrypt-data - AlexBrand