如何使用出口网络策略允许访问 kubernetes api?

How to allow access to kubernetes api using egress network policy?

使用kubectl get pod命令初始化容器用于获取其他pod的就绪状态。

开启 Egress NetworkPolicy 后,init 容器无法访问 Kubernetes API:Unable to connect to the server: dial tcp 10.96.0.1:443: i/o timeout。 CNI 是 Calico。

尝试了几条规则,但其中 none 行得通(服务和主控主机 IP,不同的 CIDR 掩码):

...
  egress:
  - to:
    - ipBlock:
        cidr: 10.96.0.1/32
    ports:
    - protocol: TCP
      port: 443
...

或使用命名空间(默认和 kube-system 命名空间):

...
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: default
    ports:
    - protocol: TCP
      port: 443
...

看起来 ipBlock 规则不起作用,命名空间规则也不起作用,因为 kubernetes api 是非标准 pod。

可以配置吗? Kubernetes 是 1.9.5,Calico 是 3.1.1。

GKE 1.13.7-gke.8 和 calico 3.2.7 问题仍然存在

更新:先尝试

如果它对您不起作用(它对我有用!),以下可能是一种解决方法:

  podSelector:
    matchLabels:
      white: listed
  egress:
    - to:
        - ipBlock:
            cidr: 0.0.0.0/0

这将允许访问 API 服务器 - 以及互联网上的所有其他 IP 地址 :-/

您可以将此与 DENY all non-whitelisted traffic from a namespace 规则结合使用以拒绝所有其他 pods 的出口。

您需要使用 kubectl get endpoints --namespace default kubernetes 获取 master 的真实 ip,并制定出口政策以允许这样做。

---
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1 
metadata:
  name: allow-apiserver
  namespace: test
spec:
  policyTypes:
  - Egress
  podSelector: {}
  egress:
  - ports:
    - port: 443
      protocol: TCP
    to:
    - ipBlock:
        cidr: x.x.x.x/32

我们不在 GCP 上,但同样适用。

我们向 AWS 查询主节点的 CIDR,并将此数据用作 helm 图表的值,为 k8s API 访问创建 NetworkPolicy。

在我们的例子中,master 是自动缩放组的一部分,所以我们需要 CIDR。在您的情况下,IP 可能就足够了。