Google Kubernetes Engine:为服务类型启用 HTTPS
Posted
技术标签:
【中文标题】Google Kubernetes Engine:为服务类型启用 HTTPS【英文标题】:Google Kubernetes Engine: Enable HTTPS for Service type 【发布时间】:2018-07-06 04:13:07 【问题描述】:我在 GKE 上有一个应用程序,我希望只能通过 HTTPS 访问,因此我获得了一个签名证书来使用 TLS 保护应用程序。
我查看了很多关于如何做到这一点的教程,但它们都提到了使用 Ingress 并使用 LetsEncrypt 和 KubeLego 自动请求证书。但我希望继续使用外部负载均衡器(谷歌为我提供的计算引擎实例),但我只想通过 https 访问我的应用程序。
如何应用我的 server.crt 和 server.key 文件来启用 https.Do I apply it to the Load balancers 或 kubernetes 集群。
【问题讨论】:
可能你想看看这个开源项目。 github.com/appscode/voyager 【参考方案1】:解决办法:
在运行时获取您的证书,很多人使用 LetsEncrypt,因为它非常简单,但您可以将证书存储在真正安全的存储中,例如您的云平台的密钥管理存储,或者运行您自己的 Hashicorp Vault(我推荐 Hashicorp Vault,它非常好!)然后在运行时安全地检索您的秘密。
您注意到每个教程或指南都建议动态获取它们。
但它们都指使用 Ingress 并使用 LetsEncrypt 和 KubeLego 自动请求证书。
原因如下:
https://kubernetes.io/docs/concepts/configuration/secret/#risks
风险
在 API 服务器中,秘密数据以明文形式存储在 etcd 中;所以: 管理员应将 etcd 的访问权限限制为管理员用户 API server 中的秘密数据保存在 etcd 使用的磁盘上;管理员可能希望在不再使用时擦除/粉碎 etcd 使用的磁盘
可以创建使用密钥的 pod 的用户也可以看到该密钥的值。即使 apiserver 策略不允许该用户读取机密对象,用户也可以运行一个暴露机密的 pod。
如果运行了多个 etcd 副本,那么秘密将在它们之间共享。默认情况下,etcd 不使用 SSL/TLS 保护对等通信,尽管可以配置。
目前,在任何节点上拥有 root 权限的任何人都可以通过模拟 kubelet 从 apiserver 读取任何秘密。这是一个计划中的功能,只向实际需要它们的节点发送秘密,以限制根漏洞对单个节点的影响。
因此,每个人都正确地建议您不要使用 K8s SECRETS 来存储您的宝贵证书,因为它不适合这项工作。
【讨论】:
这确实是另一种方式。但需要明确的是,从 Kubernetes 1.7 开始,可以启用静态加密来加密机密:kubernetes.io/docs/tasks/administer-cluster/encrypt-data【参考方案2】:在通过 HTTPS 公开您的应用程序时,Ingress 可能是您的最佳选择。 Ingress 资源指定了一个后端服务,因此您将继续将您的应用程序公开为 Kubernetes 服务,只需将类型设置为 ClusterIP
。这将为您的集群生成一个“内部”服务,并且一旦您设置它就可以通过 Ingress 进行外部访问。
现在,特别是在 Google Kubernetes Engine (GKE) 中,您集群中定义的任何入口资源都将由 Google Cloud Load Balancer 提供服务,因此我认为您不必担心部署自己的入口控制器(例如 nginx入口控制器)。
就 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
以下是一个很好的教程,可引导您了解 GKE 上的 Ingress: https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer
【讨论】:
非常感谢,我已经这样做了,并使用了默认的 nginx 服务进行测试,但我希望它在地址栏中表明该站点是安全的,但事实并非如此。此过程是否表明该站点是安全的? @Ogbe 通过这种沟通方式很难弄清楚。你是如何获得证书的?您的浏览器是否信任它?是否正在送达证书? DNS 名称是否与证书中的名称(或 SAN 中的名称)匹配? 注意:Kubernetes 机密存储在 etcd 上的 PLAINTEXT 中,任何有权访问 APIserver 的节点都可以访问任何机密,即使未分配。适当照顾! kubernetes.io/docs/concepts/configuration/secret/#risks 从 Kubernetes 1.7 开始,可以启用静态加密来加密机密:kubernetes.io/docs/tasks/administer-cluster/encrypt-data 我向这个答案授予了赏金,我已经能够安装 ssl 证书,但我需要将所有 http 请求路由到 https,将 ssl_redirect 注释设置为 true 并允许 https 注释为 false 没有帮助实现这一目标【参考方案3】:Ingress 是最简单的方法。您不需要使用 LetsEncrypt,您可以指定自己的证书。
入口控制器只是一个 NGINX 代理。如果您不想使用入口(为什么?),您必须自己创建此代理服务。这基本上是这项服务的入口。
【讨论】:
使用入口是否意味着我必须创建一个新的负载均衡器? 为每个 LoadBalancer 类型的服务(每个外部暴露的服务)创建一个负载均衡器。这个想法是只有一个入口,所有其他服务都应该是内部的。以上是关于Google Kubernetes Engine:为服务类型启用 HTTPS的主要内容,如果未能解决你的问题,请参考以下文章
Google Kubernetes Engine(GKE)使用初探 | Linux 中国
Google Kubernetes Engine:为服务类型启用 HTTPS
使用 Config Connector 对 Google Kubernetes Engine 集群进行地形改造
如何使用工作负载身份通过 Google Cloud .NET SDK 访问 Google Kubernetes Engine 中的 ESP?
Vertex AI 自定义预测与 Google Kubernetes Engine
Google Cloud、Kubernetes 和 Cloud SQL 代理:默认 Compute Engine 服务帐户问题