【问题标题】:How to secure the read-only port 10255 in Google Kubernetes Engine (GKE)?如何保护 Google Kubernetes Engine (GKE) 中的只读端口 10255?
【发布时间】:2019-11-15 05:19:47
【问题描述】:

我使用以下命令创建了一个 GKE 私有集群(版本:1.13.6-gke.13):

gcloud container clusters create a-cluster-with-user-pass \
 --network vpc-name \
 --subnetwork subnet-name    \
 --enable-master-authorized-networks \
 --username random \
 --password averylongpassword \
 --enable-ip-alias \
 --enable-private-nodes \
 --enable-private-endpoint \
 --master-ipv4-cidr xxx.xx.xx.xx/28 \
 --cluster-version 1.13.6-gke.13 \
 --num-nodes 2 \
 --zone asia-south1-a

我可以看到端口 (10255) 在上述集群中创建的两个节点(或者我们可以说是 GCP 计算实例)中都是打开的。

如果我创建一个简单的 GCP 计算实例(因此我总共有 3 个 VM 实例)并尝试从该 VM 访问 10255 端口上的 GKE 节点的内部 IP,我无需任何身份验证或授权即可访问它。 以下是用于创建 GCP 计算实例的命令:

gcloud compute instances create vm-name \
 --network vpc-name \
 --subnetwork subnet-name    \
 --zone asia-south1-a

如果我向 (xxx.xx.xx.xx:10255/pods) 发送一个简单的 CURL GET 请求,我会得到大量关于 pod 和应用程序的信息。 正如我在 Kubernetes here 的文档中看到的,提到:

--read-only-port int32
     The read-only port for the Kubelet to serve on with no authentication/authorization (set to 0 to disable) (default 10255)

我尝试通过编辑节点中的kube-config.yaml 文件来禁用端口,方法是执行ssh 并重新启动kubelet,我成功了。但这是一个好方法吗?我相信当 xxx.xx.xx.xx:10255/metrics 被禁用时可能会出现多个问题。有没有办法保护港口?而不是禁用它?

我看到了这个github issue,我确信有办法保护这个端口。我不知道该怎么做。

我看到 Kubernetes 文档通常为我们提供了多种保护端口的方法。如何在 Google Kubernetes Engine 中做到这一点?

【问题讨论】:

    标签: kubernetes google-cloud-platform google-kubernetes-engine kubelet


    【解决方案1】:

    Kubelet 正在使用此端口公开收集的节点指标。未能在此处公开这些指标可能会导致意外行为,因为系统基本上会失明。

    由于 GKE 是一个托管系统,因此您实际上不应该调整 kubelet 标志,因为重新创建节点时设置将被重置(节点基于 GCE 模板,不包含您自己的配置)。

    至于安全性,我认为保留该端口是安全的,因为您使用的是私有集群,这意味着仅允许同一 VPC 中的资源到达节点。

    【讨论】:

    • 但是有没有办法至少向端点添加身份验证或授权,以便不是所有的虚拟机而是只有允许的虚拟机访问端点?
    • 正如其他回复中所建议的,您可以添加 VPC 级别的防火墙规则来禁用访问。请记住,GKE 集群中的所有节点都有network tags,这可能会让您更轻松地操作防火墙。
    【解决方案2】:

    正如 Yahir Hernández 在他的回答中所建议的那样,此端口用于公开与确保平稳运行的系统相关的指标。禁用此端口可能不是一个好主意。

    我们需要做的是防止从VPC外部访问该端口。

    由于您在 GCP 上使用 GKE。如果您使用 VPC,您可以将防火墙规则添加到端口 (10255),以仅允许来自 VPC 资源的传入流量。禁止从 Internet 访问此端口。

    【讨论】:

    • 如果仔细观察,我创建的集群只有内部 IP 地址,默认情况下无法从 VPC 外部访问。事实上,同一 VPC 中另一个子网中的虚拟机甚至无法访问私有集群。所以我不关心来自 VPC 或子网外部的流量。我担心来自同一子网中虚拟机的流量。这些没有任何作用域或身份验证的 VM 只需发送 GET 请求即可访问此端口。我想在其中添加身份验证。
    • 好的。您要解决的问题是什么?鉴于只有您的 pod 会在其中运行,为什么您会有来自 VM 内部的流量?
    • 我要解决的问题与安全性有关。假设在同一子网中有一个虚拟机是为了其他目的而不是访问集群而创建的。即使没有任何授权和身份验证,GKE 也允许虚拟机访问此端口并获取大量信息。
    • 那么它不应该在不同的子网中吗?如果不尝试阻止从 VM 到端口 10255 的传出流量。
    • 我想到了那个解决方案,但只为集群创建一个子网对我来说似乎有点矫枉过正。而blocking outgoing traffic to port 10255 from the VM 看起来并不是一个好的解决方案。如果重新创建集群并且 IP 更改了怎么办?如果同一子网中有另一个集群访问其他集群 IP:10255 怎么办?因此,与其限制调用者,我更愿意保护目标。
    【解决方案3】:

    根据CIS Google Kubernetes Engine (GKE) Benchmark v1.0.0第196和197页,“建议”>“Kubelet”:

    • 建议(广泛适用,应该适用于几乎所有环境)禁用只读端口10255
    • 您可以通过编辑 kubelet 配置文件将 readOnlyPort 设置为 0 然后重新启动 kubelet 服务来做到这一点

    同时Google mentions(第4.2.4点)表示默认不禁用端口,因为:

    部分 GKE 监控组件使用 kubelet 只读端口获取指标。


    ?

    来自 CIS 基准的建议是聋哑人,几乎一文不值。

    • GKE 的重点是不必自己管理 kubelet。
    • 目前尚不清楚该建议会对 GKE 对您的集群的监控产生什么影响。
    • 如何将设置永久保存在自动缩放集群中并不明显。 (以privileged 运行的守护程序集,其唯一目的是覆盖 GKE 的 kubelet 配置?)

    在我看来,您能做的最好的缓解措施是:

    1. 确保端口只能从 VPC 内部访问。
    2. 为您的 pod 设置良好的出口网络策略。 (或者在其他一些 管理出口流量的方式。)避免让 pod 允许所有端口上的所有出口。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-16
      • 2018-09-07
      • 2014-04-16
      • 1970-01-01
      • 1970-01-01
      • 2018-12-25
      • 2020-11-21
      • 1970-01-01
      相关资源
      最近更新 更多