问题描述
我一直在尝试使用 calico 网络规则,但我发现在拒绝所有入口和出口规则后,很难让入口和出口规则与 calico 中的 order
一起使用。
kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
hello-web3 1/1 Running 0 45m app=foo
hello-web4 1/1 Running 0 45m app=bar
hello-web5 1/1 Running 0 15s app=foobar
hello-web6 1/1 Running 0 4s app=barbar
我的网络政策如下
---
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
Metadata:
name: ppdp-default
spec:
selector: all()
order: 2000
types:
- Ingress
- Egress
---
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
Metadata:
name: ppdp-egress-trusted
spec:
selector: app == 'foo'
order: 1000
types:
- Egress
egress:
- action: Allow
destination:
selector: app == 'bar'
---
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
Metadata:
name: ppdp-ingress-trusted
spec:
selector: app == 'foobar'
order: 100
types:
- Ingress
ingress:
- action: Allow
source:
selector: app == 'barbar'
入口输出:
(base) ➜ ✗ kubectl exec --stdin --tty hello-web5 -- sh
/ # ^C
/ # wget -qO- --timeout=2 http://hello-web6:8080
^C
/ # wget -qO- --timeout=2 http://hello-web6:8080
wget: bad address 'hello-web6:8080'
/ # command terminated with exit code 1
---
(base) ➜ ✗ kubectl exec --stdin --tty hello-web6 -- sh
/ # wget -qO- --timeout=2 http://hello-web5:8080
wget: bad address 'hello-web5:8080'
/ # command terminated with exit code 1
出口输出
(base) ➜ ✗ kubectl exec --stdin --tty hello-web3 -- sh
/ # wget -qO- --timeout=2 http://hello-web4:8080
^C
/ # command terminated with exit code 130
我错过了什么吗?任何帮助都会很有用。
提前致谢
解决方法
在命名空间中,我想首先拒绝所有 Pod 之间的流量,然后允许特定 Pod 之间的出口或入口流量 (匹配标签)
虽然我不知道你为什么要使用 order 或 calico 网络策略,但评论中描述的目标可以通过 Calico CNI 支持的 Kubernetes 网络策略来实现。我准备了一个简单的示例,说明网络策略如何与这些策略配合使用。因此,让我们从我在 dev
命名空间中创建的 pod 列表开始:
➜ ~ kgp -n dev --show-labels -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
centos 1/1 Running 0 30m 10.244.120.68 minikube <none> <none> host=centos
echo-server 1/1 Running 0 30m 10.244.120.69 minikube <none> <none> host=echo-server
注意标签。在我的示例中,我们将允许从名为 echo-server
的主机到 centos
的入口流量。让我们首先测试它们之间的连接是否有效:
[root@centos /]# curl 10.244.120.69:80 -v
* About to connect() to 10.244.120.69 port 80 (#0)
* Trying 10.244.120.69...
* Connected to 10.244.120.69 (10.244.120.69) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 10.244.120.69
> Accept: */*
"path": "/","headers": {
"user-agent": "curl/7.29.0","host": "10.244.120.69","accept": "*/*"
"os": {
"hostname": "echo-server"
},"connection": {}
* Connection #0 to host 10.244.120.69 left intact
现在让我们拒绝该命名空间中的所有流量:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: dev
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
一旦此策略到位,之前的测试就会失败:
➜ ~ keti -n dev centos bash
[root@centos /]# curl 10.244.120.69:80 -v
* About to connect() to 10.244.120.69 port 80 (#0)
* Trying 10.244.120.69...
* Connection timed out
* Failed connect to 10.244.120.69:80; Connection timed out
* Closing connection 0
curl: (7) Failed connect to 10.244.120.69:80; Connection timed out
现在让我们应用允许我们到达 echo-server
的入口策略。所以基本上我们选择我们希望策略应用到的 pod 标签,并选择允许来自哪个 pod 入口流量:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-echo
namespace: dev
spec:
podSelector:
matchLabels:
host: echo-server
ingress:
- from:
- podSelector:
matchLabels:
host: centos
现在,由于我们允许流量流向我们的 echo-server
,我们可能会想立即对此进行测试,但这仍然无法正常工作。虽然我们允许流向 echo-server
的入口流量,但我们必须记住,我们在 ingress
策略中拒绝了 egress
和 deny-all
。这意味着我们必须允许来自 egress
pod 的 centos
流量:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: egress-centos
namespace: dev
spec:
podSelector:
matchLabels:
host: centos
egress:
- to:
- podSelector:
matchLabels:
host: echo-server
之后,我们成功地允许同一命名空间中某些特定 Pod 的流量,同时拒绝每个与标签不匹配的 Pod。