1

我有两个 pod,即 payroll 和 mysql,分别标记为name=payrollname=mysql。还有另一个名为 internal 的 pod 带有 label name=internal。我试图允许从内部到其他两个 pod 的出口流量,同时允许所有入口流量。我的NetworkPoliy样子是这样的:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: internal-policy
spec:
  podSelector:
    matchLabels:
      name: internal
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - {}       
  egress:
  - to:
    - podSelector:
        matchExpressions:
          - {key: name, operator: In, values: [payroll, mysql]}
    ports:
    - protocol: TCP
      port: 8080
    - protocol: TCP
      port: 3306

这与两个 pod payroll 和 mysql 不匹配。我究竟做错了什么?

以下作品:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: internal-policy
spec:
  podSelector:
    matchLabels:
      name: internal
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - {}       
  egress:
  - to:
    - podSelector:
        matchLabels:
          name: payroll
    - podSelector:
        matchLabels:
          name: mysql
    ports:
    - protocol: TCP
      port: 8080
    - protocol: TCP
      port: 3306

写 a 的最佳方法是什么NetWorkPolicy,为什么第一个不正确?

我也想知道为什么该to字段是一个数组,而podSelector它也是一个数组?我的意思是他们是一样的吗?多个podSelector或多个to字段。使用其中之一有效。

4

1 回答 1

3

这与两个 pod payroll 和 mysql 不匹配。我究竟做错了什么?

  • 我已经使用 pod-to-service 和 pod-to-pod 环境重现了您的场景,在这两种情况下,两种 yaml 都运行良好。这就是说在第 19 行修复缩进后两者podSelector应该处于同一级别,如下所示:
  - to:
    - podSelector:
        matchLabels:
          name: payroll
    - podSelector:
        matchLabels:
          name: mysql

最好的写法是NetWorkPolicy什么?

  • 最好的方法取决于每种情况,为每个规则创建一个网络策略是一种很好的做法。如果您打算在两个 pod 上公开端口8080,我会说第一个 yaml 是最好的3306,否则最好创建两个规则,以避免留下不必要的开放端口。

我也想知道为什么该to字段是一个数组,而podSelector它也是一个数组?我的意思是他们是一样的吗?多个podSelector或多个to字段。使用其中之一有效。


为什么第一个不正确?

  • 两条规则基本相同,只是格式不同。我会说你应该检查是否有任何其他规则对相同的标签有效。
  • 我建议您创建一个测试集群并尝试应用我将在下面留下的分步示例。

再生产:

  • 此示例与您的情况非常相似。我使用nginx图像是为了方便测试并将端口更改为80on NetworkPolicy。我打电话给你的第一个 yamlinternal-original.yaml和你发布的第二个second-internal.yaml
$ cat internal-original.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: internal-original
spec:
  podSelector:
    matchLabels:
      name: internal
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - {}
  egress:
  - to:
    - podSelector:
        matchExpressions:
          - {key: name, operator: In, values: [payroll, mysql]}
    ports:
    - protocol: TCP
      port: 80

$ cat second-internal.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: internal-policy
spec:
  podSelector:
    matchLabels:
      name: internal
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - {}       
  egress:
  - to:
    - podSelector:
        matchLabels:
          name: payroll
    - podSelector:
        matchLabels:
          name: mysql
    ports:
    - protocol: TCP
      port: 80
  • 现在我们使用标签创建 pod 并公开服务:
$ kubectl run mysql --generator=run-pod/v1 --labels="name=mysql" --image=nginx 
pod/mysql created
$ kubectl run internal --generator=run-pod/v1 --labels="name=internal" --image=nginx
pod/internal created
$ kubectl run payroll --generator=run-pod/v1 --labels="name=payroll" --image=nginx
pod/payroll created
$ kubectl run other --generator=run-pod/v1 --labels="name=other" --image=nginx
pod/other created

$ kubectl expose pod mysql --port=80
service/mysql exposed
$ kubectl expose pod payroll --port=80
service/payroll exposed
$ kubectl expose pod other --port=80
service/other exposed
  • 现在,在应用之前networkpolicy,我将登录到internalpod 进行下载wget,因为之后外部访问将被阻止:
$ kubectl exec internal -it -- /bin/bash
root@internal:/# apt update
root@internal:/# apt install wget -y
root@internal:/# exit
  • 由于您的规则阻止访问 DNS,我将列出 IP 并对其进行测试:
$ kubectl get pods -o wide
NAME       READY   STATUS    RESTARTS   AGE   IP
internal   1/1     Running   0          62s   10.244.0.192
mysql      1/1     Running   0          74s   10.244.0.141
other      1/1     Running   0          36s   10.244.0.216
payroll    1/1     Running   0          48s   10.244.0.17 

$ kubectl get services
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
mysql        ClusterIP   10.101.209.87   <none>        80/TCP    23s
other        ClusterIP   10.103.39.7     <none>        80/TCP    9s
payroll      ClusterIP   10.109.102.5    <none>        80/TCP    14s
  • 现在让我们用第一个 yaml 测试访问:
$ kubectl get networkpolicy
No resources found in default namespace.

$ kubectl apply -f internal-original.yaml 
networkpolicy.networking.k8s.io/internal-original created

$ kubectl exec internal -it -- /bin/bash
root@internal:/# wget --spider --timeout=1 http://10.101.209.87
Spider mode enabled. Check if remote file exists.
--2020-06-08 18:17:55--  http://10.101.209.87/
Connecting to 10.101.209.87:80... connected.
HTTP request sent, awaiting response... 200 OK

root@internal:/# wget --spider --timeout=1 http://10.109.102.5
Spider mode enabled. Check if remote file exists.
--2020-06-08 18:18:04--  http://10.109.102.5/
Connecting to 10.109.102.5:80... connected.
HTTP request sent, awaiting response... 200 OK

root@internal:/# wget --spider --timeout=1 http://10.103.39.7
Spider mode enabled. Check if remote file exists.
--2020-06-08 18:18:08--  http://10.103.39.7/
Connecting to 10.103.39.7:80... failed: Connection timed out.
  • 现在让我们使用第二个 yaml 测试访问:
$ kubectl get networkpolicy
NAME                POD-SELECTOR    AGE
internal-original   name=internal   96s

$ kubectl delete networkpolicy internal-original
networkpolicy.networking.k8s.io "internal-original" deleted

$ kubectl apply -f second-internal.yaml 
networkpolicy.networking.k8s.io/internal-policy created

$ kubectl exec internal -it -- /bin/bash
root@internal:/# wget --spider --timeout=1 http://10.101.209.87
Spider mode enabled. Check if remote file exists.
--2020-06-08 17:18:24--  http://10.101.209.87/
Connecting to 10.101.209.87:80... connected.
HTTP request sent, awaiting response... 200 OK

root@internal:/# wget --spider --timeout=1 http://10.109.102.5
Spider mode enabled. Check if remote file exists.
--2020-06-08 17:18:30--  http://10.109.102.5/
Connecting to 10.109.102.5:80... connected.
HTTP request sent, awaiting response... 200 OK

root@internal:/# wget --spider --timeout=1 http://10.103.39.7
Spider mode enabled. Check if remote file exists.
--2020-06-08 17:18:35--  http://10.103.39.7/
Connecting to 10.103.39.7:80... failed: Connection timed out.
  • 如您所见,与带有标签的服务的连接正常,而与具有其他标签的 pod 的连接失败。

注意:如果您希望允许 pod 解析 DNS,可以按照本指南:允许 DNS 出口流量

如果您有任何问题,请在评论中告诉我。

于 2020-06-08T18:23:16.430 回答