如何使用 NetworkPolicy 阻止所有流量 pods 匹配标签
How to block all traffic to pods matching a label using a NetworkPolicy
Afaik,K8s NetworkPolicy
只能允许 pods 匹配标签来做某事。我不想:
- 拒绝所有流量
- 允许除匹配我的标签
之外的所有pods流量
而是:
- 允许所有流量
- 拒绝 pods 匹配我的标签
的流量
我该怎么做?
来自kubectl explain NetworkPolicy.spec.ingress.from
:
DESCRIPTION:
List of sources which should be able to access the pods selected for this
rule. Items in this list are combined using a logical OR operation. If this
field is empty or missing, this rule matches all sources (traffic not
restricted by source). If this field is present and contains at least one
item, this rule allows traffic only if the traffic matches at least one
item in the from list.
据我了解,我们只能允许,不能拒绝。
正如您在评论中提到的,您正在使用 运行 Kubernetes 的 Kind 工具。而不是 kindnet CNI plugin (default CNI plugin for Kind) which does not support Kubernetes network policies, you can use Calico CNI plugin which support Kubernetes network policies + it has its own, similar solution called Calico network policies.
示例 - 我将使用禁用的默认类型 CNI 插件 + 创建集群以进行测试(假设您已经安装了 kind
+ kubectl
工具):
kind-cluster-config.yaml 文件:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
disableDefaultCNI: true # disable kindnet
podSubnet: 192.168.0.0/16 # set to Calico's default subnet
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30000
hostPort: 30000
listenAddress: "0.0.0.0" # Optional, defaults to "0.0.0.0"
protocol: tcp # Optional, defaults to tcp
使用以上配置创建集群的时间:
kind create cluster --config kind-cluster-config.yaml
集群准备就绪后,我将安装 Calico CNI 插件:
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
我会等到所有 calico pods 都准备好(kubectl get pods -n kube-system
命令检查)。然后,我将创建示例 nginx deployment + 用于访问的服务类型 NodePort:
nginx-deploy-service.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30000
让我们应用它:kubectl apply -f nginx-deploy-service.yaml
到目前为止一切顺利。现在我将尝试使用节点 IP 访问 nginx-service
(kubectl get nodes -o wide
命令检查节点 IP 地址):
curl 172.18.0.2:30000
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
好的,它正在运行。
现在 install calicoctl
and apply some example policy - based on this tutorial - 仅阻止 pods 的入口流量,标签为 app
,值为 nginx
:
印花布-rule.yaml:
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: default-deny
spec:
selector: app == "nginx"
types:
- Ingress
应用它:
calicoctl apply -f calico-rule.yaml
Successfully applied 1 'GlobalNetworkPolicy' resource(s)
现在我无法访问之前有效的地址 172.18.0.2:30000
。该政策运作良好!
阅读有关 calico 政策的更多信息:
另请查看 this GitHub topic 了解有关 Kind 中 NetworkPolicy 支持的更多信息。
编辑:
似乎是 Calico 插件 supports as well Kubernetes NetworkPolicy,因此您可以只安装 Calico CNI 插件并应用以下策略:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: default-deny
spec:
podSelector:
matchLabels:
app: nginx
policyTypes:
- Ingress
我测试了它,似乎它也工作正常。
Afaik,K8s NetworkPolicy
只能允许 pods 匹配标签来做某事。我不想:
- 拒绝所有流量
- 允许除匹配我的标签 之外的所有pods流量
而是:
- 允许所有流量
- 拒绝 pods 匹配我的标签 的流量
我该怎么做?
来自kubectl explain NetworkPolicy.spec.ingress.from
:
DESCRIPTION:
List of sources which should be able to access the pods selected for this
rule. Items in this list are combined using a logical OR operation. If this
field is empty or missing, this rule matches all sources (traffic not
restricted by source). If this field is present and contains at least one
item, this rule allows traffic only if the traffic matches at least one
item in the from list.
据我了解,我们只能允许,不能拒绝。
正如您在评论中提到的,您正在使用 运行 Kubernetes 的 Kind 工具。而不是 kindnet CNI plugin (default CNI plugin for Kind) which does not support Kubernetes network policies, you can use Calico CNI plugin which support Kubernetes network policies + it has its own, similar solution called Calico network policies.
示例 - 我将使用禁用的默认类型 CNI 插件 + kind
+ kubectl
工具):
kind-cluster-config.yaml 文件:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
disableDefaultCNI: true # disable kindnet
podSubnet: 192.168.0.0/16 # set to Calico's default subnet
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30000
hostPort: 30000
listenAddress: "0.0.0.0" # Optional, defaults to "0.0.0.0"
protocol: tcp # Optional, defaults to tcp
使用以上配置创建集群的时间:
kind create cluster --config kind-cluster-config.yaml
集群准备就绪后,我将安装 Calico CNI 插件:
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
我会等到所有 calico pods 都准备好(kubectl get pods -n kube-system
命令检查)。然后,我将创建示例 nginx deployment + 用于访问的服务类型 NodePort:
nginx-deploy-service.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30000
让我们应用它:kubectl apply -f nginx-deploy-service.yaml
到目前为止一切顺利。现在我将尝试使用节点 IP 访问 nginx-service
(kubectl get nodes -o wide
命令检查节点 IP 地址):
curl 172.18.0.2:30000
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...
好的,它正在运行。
现在 install calicoctl
and apply some example policy - based on this tutorial - 仅阻止 pods 的入口流量,标签为 app
,值为 nginx
:
印花布-rule.yaml:
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
name: default-deny
spec:
selector: app == "nginx"
types:
- Ingress
应用它:
calicoctl apply -f calico-rule.yaml
Successfully applied 1 'GlobalNetworkPolicy' resource(s)
现在我无法访问之前有效的地址 172.18.0.2:30000
。该政策运作良好!
阅读有关 calico 政策的更多信息:
另请查看 this GitHub topic 了解有关 Kind 中 NetworkPolicy 支持的更多信息。
编辑:
似乎是 Calico 插件 supports as well Kubernetes NetworkPolicy,因此您可以只安装 Calico CNI 插件并应用以下策略:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: default-deny
spec:
podSelector:
matchLabels:
app: nginx
policyTypes:
- Ingress
我测试了它,似乎它也工作正常。