跳到主要内容

网络策略

网络策略

目录

[toc]

介绍

默认情况下,Kubernetes 集群网络没任何网络限制,Pod 可以与任何其他Pod通信,在某些场景下就需要进行网络控制,减少网络攻击面,提高安全性,这就会用到网络策略。

网络策略(Network Policy):是一个K8s资源,用于限制Pod出入流量,提供Pod级别和Namespace级别网络访问控制。

默认情况,k8集群里,Pod和Pod,Node和Pod之间都是可以随意通信的。

网络策略的应用场景:

  • 应用程序间的访问控制,例如项目A不能访问项目B的Pod
  • 开发环境命名空间不能访问测试环境命名空间Pod
  • 当Pod暴露到外部时,需要做Pod白名单
  • 多租户网络环境隔离

网络策略:yaml文件示例

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: db
policyTypes:
- Ingress
- Egress
ingress:
- from:
- ipBlock:
cidr: 172.17.0.0/16
except:
- 172.17.1.0/24
- namespaceSelector:
matchLabels:
project: myproject
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 6379
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/24
ports:
- protocol: TCP
port: 5978

image-20230519080001099

podSelector:目标Pod,根据标签选择。

policyTypes:策略类型,指定策略用于入站、出站流量。

Ingress:from是可以访问的白名单,可以来自于IP段、命名空间、Pod标签等,ports是可以访问的端口。

Egress:这个Pod组可以访问外部的IP段和端口。

注意:

{} 代表包括所有
不写ingress或者egress代表默认行为,拒绝所有。

案例1:拒绝命名空间下所有Pod出入站流量

==💘 案例:拒绝命名空间下所有Pod出入站流量-2023.1.6(测试成功)==

次策略实际过程中不会用到。

image-20230521155150999

  • 实验环境
实验环境:
1、win10,vmwrokstation虚机;
2、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
k8s version:v1.22.2
containerd://1.5.5
  • 实验软件

无。

1、创建测试命名空间和相应pod

(1)创建测试命名空间test
[root@k8s-master1 ~]#kubectl create ns test
namespace/test created

(2)创建相应pod
#在test命名空间下创建2个pod
[root@k8s-master1 ~]#kubectl run busybox-test --image=busybox -n test -- sleep 12h
pod/busybox-test created
[root@k8s-master1 ~]#kubectl run web-test --image=nginx -n test
pod/web-test created
[root@k8s-master1 ~]#kubectl get po -owide -ntest
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
busybox-test 1/1 Running 0 13s 10.244.36.74 k8s-node1 <none> <none>
web-test 1/1 Running 0 8s 10.244.169.138 k8s-node2 <none> <none>

#在default命名空间下创建1个pod
[root@k8s-master1 ~]#kubectl run busybox-default --image=busybox -- sleep 12h
pod/busybox-default created
[root@k8s-master1 ~]#kubectl get po -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
busybox-default 1/1 Running 0 5s 10.244.169.140 k8s-node2 <none> <none>

2、测试k8s默认网络策略

(1)同命名空间下pod是可以互相访问的
[root@k8s-master1 ~]#kubectl exec -it busybox-test -ntest -- sh
/ #
/ # ping 10.244.169.138
PING 10.244.169.138 (10.244.169.138): 56 data bytes
64 bytes from 10.244.169.138: seq=0 ttl=62 time=0.601 ms
64 bytes from 10.244.169.138: seq=1 ttl=62 time=0.393 ms
^C
--- 10.244.169.138 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.393/0.497/0.601 ms

(2)不同命名空间下pod是可以互相访问的
[root@k8s-master1 ~]#kubectl exec -it busybox-test -ntest -- sh
/ #
/ # ping 10.244.169.140
PING 10.244.169.140 (10.244.169.140): 56 data bytes
64 bytes from 10.244.169.140: seq=0 ttl=62 time=0.657 ms
^C
--- 10.244.169.140 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.657/0.657/0.657 ms

(3)node是可以访问pod地址的
[root@k8s-master1 ~]#ping 10.244.36.74
PING 10.244.36.74 (10.244.36.74) 56(84) bytes of data.
64 bytes from 10.244.36.74: icmp_seq=1 ttl=63 time=0.485 ms
64 bytes from 10.244.36.74: icmp_seq=2 ttl=63 time=0.440 ms
^C
--- 10.244.36.74 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.440/0.462/0.485/0.031 ms

3、为test命名空间配置网络策略

#deny-all.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: test
spec:
podSelector: {} # 匹配本命名空间所有pod
policyTypes:
- Ingress
- Egress
# ingress和egress没有指定规则,则不允许任何流量进出pod

部署:

[root@k8s-master1 ~]#kubectl apply -f deny-all.yaml
networkpolicy.networking.k8s.io/deny-all created
[root@k8s-master1 ~]#kubectl get networkpolicy -ntest
NAME POD-SELECTOR AGE
deny-all <none> 21s

4、测试

(1)测试访问外部(拒绝访问):
[root@k8s-master1 ~]#kubectl exec -it busybox-test -n test -- sh
/ #
/ # ping 10.244.169.140
PING 10.244.169.140 (10.244.169.140): 56 data bytes
^C
--- 10.244.169.140 ping statistics ---
4 packets transmitted, 0 packets received, 100% packet loss


(2)测试外部pod访问(拒绝访问):
[root@k8s-master1 ~]#kubectl exec -it busybox-default -- sh
/ #
/ # ping 10.244.36.74
PING 10.244.36.74 (10.244.36.74): 56 data bytes
^C
--- 10.244.36.74 ping statistics ---
4 packets transmitted, 0 packets received, 100% packet loss
/ #


(3)测试内部pod之间访问(拒绝访问):
[root@k8s-master1 ~]#kubectl exec -it busybox-test -n test -- sh
/ #
/ # ping 10.244.169.138
PING 10.244.169.138 (10.244.169.138): 56 data bytes
^C
--- 10.244.169.138 ping statistics ---
4 packets transmitted, 0 packets received, 100% packet loss
/ #

测试结束。😘

案例2:拒绝其他命名空间Pod访问

==💘 案例2:拒绝其他命名空间Pod访问-2023.1.6(测试成功)==

image-20230521155210673

案例2:拒绝其他命名空间Pod访问
需求:test命名空间下所有pod可以互相访问,也可以访问其他命
名空间Pod,但其他命名空间不能访问test命名空间Pod。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-namespaces
namespace: test
spec:
podSelector: {} # 未配置,匹配本命名空间所有pod
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {} # 未配置,匹配本命名空间所有pod

#说明
一般情况,我们配置的ingress规则会多些,而出规则egress很少去配置的;
  • 实验环境
实验环境:
1、win10,vmwrokstation虚机;
2、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
k8s version:v1.20.0
docker://20.10.7
  • 实验软件

无。

准备测试环境:

  • 先创建下test命名空间:
[root@k8s-master ~]#kubectl create ns test
namespace/test created
  • 再创建2个pod:
[root@k8s-master np]#kubectl run web --image=nginx -n test
pod/web created
[root@k8s-master ~]#kubectl run busybox --image=busybox -n test -- sleep 24h
pod/busybox created

#查看
[root@k8s-master ~]#kubectl get pod -n test
NAME READY STATUS RESTARTS AGE
busybox 1/1 Running 0 9s
web-96d5df5c8-7r6w6 1/1 Running 0 3m11s
[root@k8s-master ~]#kubectl get pod -n test -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
busybox 1/1 Running 0 21h 10.244.169.148 k8s-node2 <none> <none>
web 1/1 Running 0 7h26m 10.244.169.151 k8s-node2 <none> <none>

#默认情况下,`Kubernetes 集群网络没任何网络限制,Pod 可以与任何其他 Pod 通信`
[root@k8s-master ~]#kubectl exec busybox -n test -- ping 10.244.169.151
PING 10.244.169.151 (10.244.169.151): 56 data bytes
64 bytes from 10.244.169.151: seq=0 ttl=63 time=0.283 ms
64 bytes from 10.244.169.151: seq=1 ttl=63 time=0.126 ms
^C
[root@k8s-master ~]#
  • 我们再次在默认命名空间下创建一个pod,并测试不同命名空间下的pod是否可以进行通信:=>是可以通信的
[root@k8s-master ~]#kubectl run busybox --image=busybox -- sleep 24h

[root@k8s-master ~]#kubectl get pod -o wide
[root@k8s-master ~]#kubectl get pod -o wide -n test
[root@k8s-master ~]#kubectl exec busybox -- ping 10.244.169.157

现在进行按题目需求进行限制:

拒绝其他命名空间Pod访问 需求:test命名空间下所有pod可以互相访问,也可以访问其他命名空间Pod,但其他命名空间不能访问test命名空间Pod。

  • 创建np目录:
[root@k8s-master ~]#mkdir np
[root@k8s-master ~]#cd np/
[root@k8s-master np]#vim deny-all-namespaces.yaml #配置yaml,这就是所谓的白名单
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-namespaces
namespace: test
spec:
podSelector: {} # 未配置,匹配本命名空间所有pod
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {} # 未配置,匹配本命名空间所有pod
  • apply并测试效果:=>完全符合预期效果。
 #apply下
[root@k8s-master np]#kubectl apply -f deny-all-namespaces.yaml
networkpolicy.networking.k8s.io/deny-all-namespaces created

#验证效果
[root@k8s-master np]#kubectl exec busybox -- ping 10.244.169.157 #做了网络策略限制后,从默认命名空间下不能ping通test命名空间下的web pod了。
^C

#但在test下ping不同命名空间下的pod是依然可以访问的
[root@k8s-master np]#kubectl exec busybox -n test -- ping 10.244.169.157
PING 10.244.169.157 (10.244.169.157): 56 data bytes
64 bytes from 10.244.169.157: seq=0 ttl=63 time=0.245 ms
64 bytes from 10.244.169.157: seq=1 ttl=63 time=0.307 ms
^C

#test命名空间下也是可以直接访问外网的;
[root@k8s-master np]#kubectl exec busybox -n test -- ping www.baidu.com
PING www.baidu.com (180.101.49.11): 56 data bytes
64 bytes from 180.101.49.11: seq=0 ttl=127 time=12.591 ms
64 bytes from 180.101.49.11: seq=1 ttl=127 time=9.736 ms
^C
[root@k8s-master np]#

#至此,案例2测试成功!

测试结束。😘

案例3:允许其他命名空间Pod访问指定应用

==💘 案例3:允许其他命名空间Pod访问指定应用-2023.5.21(测试成功)==

image-20230521163949187

  • 实验环境
实验环境:
1、win10,vmwrokstation虚机;
2、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
k8s version:v1.20.0
docker://20.10.7
  • 实验软件

无。

  • 先创建下test命名空间:
[root@k8s-master ~]#kubectl create ns test
namespace/test created
  • 创建网络策略
[root@k8s-master1 ~]#mkdir np
[root@k8s-master1 ~]#cd np
[root@k8s-master1 np]#vim allow-all-namespace.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-all-namespaces
namespace: test
spec:
podSelector:
matchLabels:
run: web
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector: {} # 匹配所有命名空间的pod
  • 部署
[root@k8s-master1 np]#kubectl  apply -f allow-all-namespace.yaml 
networkpolicy.networking.k8s.io/allow-all-namespaces created
[root@k8s-master1 np]#kubectl get networkpolicy -ntest
NAME POD-SELECTOR AGE
allow-all-namespaces app=web 32s
  • 创建测试pod
kubectl run busybox --image=busybox -n test -- sleep 12h
kubectl run web --image=nginx -n test

kubectl run busybox --image=busybox - sleep 12h
kubectl run web --image=nginx

[root@k8s-master1 ~]#kubectl get po -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
busybox 1/1 Running 0 84s 10.244.169.155 k8s-node2 <none> <none>
web 1/1 Running 0 2m50s 10.244.36.90 k8s-node1 <none> <none>
[root@k8s-master1 np]#kubectl get po -owide -ntest --show-labels
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
busybox 1/1 Running 0 6m23s 10.244.169.153 k8s-node2 <none> <none> run=busybox
web 1/1 Running 0 6m23s 10.244.36.89 k8s-node1 <none> <none> run=web
  • 在default命名空间下ping测test命名空间下的2个pod,观察效果
[root@k8s-master1 np]#kubectl  exec -it busybox -- sh
/ # ping 10.244.169.153 #ping测buxybox
PING 10.244.169.153 (10.244.169.153): 56 data bytes
64 bytes from 10.244.169.153: seq=0 ttl=63 time=0.168 ms
^C
--- 10.244.169.153 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.168/0.168/0.168 ms
/ # ping 10.244.36.89 #ping测web
PING 10.244.36.89 (10.244.36.89): 56 data bytes
64 bytes from 10.244.36.89: seq=0 ttl=62 time=0.504 ms
64 bytes from 10.244.36.89: seq=1 ttl=62 time=0.448 ms
^C
--- 10.244.36.89 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.448/0.476/0.504 ms
/ #
  • 问题来了:不是已经配置了策略了吗?怎么还能ping通test命名空间下的buxybox pod呢?

这是因为这个策略实际上是没有意义的,因为k8s默认的策略就是各个命名空间下的pod是可以互访的。

网路策略是由网络组件控制的,网络组件是由iptable完成的,iptables是从上到下匹配的。

因此,可以看到,在default命名空间下都是可以ping通test命名空间下2个pod的。

image-20230521165353497

但是,该如何解决呢?

此时就需要配合案例1的网络策略进行使用。

把案例1的网络策略当做一个安全基础,然后在此基础上做白名单限制。

[root@k8s-master1 np]#vim deny-all.yaml
#deny-all.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: test
spec:
podSelector: {} # 匹配本命名空间所有pod
policyTypes:
- Ingress
- Egress
# ingress和egress没有指定规则,则不允许任何流量进出pod


#部署
#注意:此时需要先删除刚才创建的那条策略,然后先部署deny-all.yaml,再部署allow-all-namespace.yaml
kubectl delete -f allow-all-namespace.yaml
[root@k8s-master1 np]#kubectl apply -f deny-all.yaml
networkpolicy.networking.k8s.io/deny-all created
[root@k8s-master1 np]#kubectl apply -f allow-all-namespace.yaml
networkpolicy.networking.k8s.io/allow-all-namespaces created
  • 再次测试
[root@k8s-master1 np]#kubectl  exec -it busybox -- sh
/ # ping 10.244.36.89 #ping测web
PING 10.244.36.89 (10.244.36.89): 56 data bytes
64 bytes from 10.244.36.89: seq=0 ttl=62 time=0.470 ms
^C
--- 10.244.36.89 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.470/0.470/0.470 ms
/ # ping 10.244.169.153 #ping测buxybox
PING 10.244.169.153 (10.244.169.153): 56 data bytes
^C
--- 10.244.169.153 ping statistics ---
3 packets transmitted, 0 packets received, 100% packet loss
/ #

测试结束。😘

案例4:同一个命名空间下应用之间限制访

==💘 案例4:同一个命名空间下应用之间限制访-2023.5.21(测试成功)==

image-20230521175402961

案例4:同一个命名空间下应用之间限制访问

需求:将test命名空间携带run=web标签的Pod隔离,只允许test
命名空间携带run=client1标签的Pod访问80端口。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: app-to-app
namespace: test
spec:
podSelector:
matchLabels:
run: web
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
run: client1
ports:
- protocol: TCP
port: 80
  • 实验环境
实验环境:
1、win10,vmwrokstation虚机;
2、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
k8s version:v1.20.0
docker://20.10.7
  • 实验软件

无。

  • 我们这边做测试时,先把上面的网络策略规则给删除掉:
[root@k8s-master1 np]#kubectl delete -f .
networkpolicy.networking.k8s.io "allow-all-namespaces" deleted
networkpolicy.networking.k8s.io "deny-all" deleted
  • 创建2个test命名空间下的不同label的测试pod:
[root@k8s-master np]#kubectl get pod -n test --show-labels
NAME READY STATUS RESTARTS AGE LABELS
busybox 1/1 Running 1 22h run=busybox
web 1/1 Running 1 8h run=web

[root@k8s-master np]#kubectl run client1 -l run=client1 --image=busybox -n test -- sleep 12h
pod/client1 created
[root@k8s-master np]#kubectl run client2 -l run=client2 --image=busybox -n test -- sleep 12h
pod/client2 created

[root@k8s-master np]#kubectl get pod -n test --show-labels
NAME READY STATUS RESTARTS AGE LABELS
busybox 1/1 Running 1 22h run=busybox
client1 1/1 Running 0 33s run=client1
client2 1/1 Running 0 20s run=client2
web 1/1 Running 1 8h run=web
[root@k8s-master np]#
  • 配置前测试:默认同一个命名空间下的pod都是可以直接访问的:

  • 现在开始配置网络策略:
[root@k8s-master np]#vim app-to-app.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: app-to-app
namespace: test
spec:
podSelector:
matchLabels:
run: web
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
run: client1
ports:
- protocol: TCP
port: 80

[root@k8s-master np]#kubectl apply -f app-to-app.yaml
networkpolicy.networking.k8s.io/app-to-app created

  • 测试失效效果:=>符合预期。

至此,案例4实验完成。😘

案例5:只允许指定命名空间中的应用访问

==💘 案例5:只允许指定命名空间中的应用访问-2023.5.21(测试成功)==

image-20230521201826470

  • 实验环境
实验环境:
1、win10,vmwrokstation虚机;
2、k8s集群:3台centos7.6 1810虚机,1个master节点,2个node节点
k8s version:v1.20.0
docker://20.10.7
  • 实验软件

无。

根据题目需求进行测试

  • 创建ns dev与标签为env=dev的pod
[root@k8s-master1 np]#kubectl create ns dev
namespace/dev created

[root@k8s-master1 np]#kubectl run web --image=nginx -l env=dev -n dev
pod/web created
[root@k8s-master1 np]#kubectl get po -ndev --show-labels -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES LABELS
web 1/1 Running 0 30s 10.244.169.156 k8s-node2 <none> <none> env=dev
  • 创建ns prod及网络策略.yaml
#创建ns prod并打上标签
[root@k8s-master1 np]#kubectl create ns prod
namespace/prod created
[root@k8s-master1 np]#kubectl label ns prod env=prod
namespace/prod labeled
[root@k8s-master1 np]#kubectl get ns prod --show-labels
NAME STATUS AGE LABELS
prod Active 30s env=prod

#创建网络策略.yaml
[root@k8s-master1 np]#vim test.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: dev-web
namespace: dev
spec:
podSelector:
matchLabels:
env: dev
policyTypes:
- Ingress
ingress:
# 满足允许prod命名空间中的pod访问
- from:
- namespaceSelector:
matchLabels:
env: prod
# 允许pod标签为app=client1的pod访问,所有命名空间
- from:
- namespaceSelector: {}
podSelector:
matchLabels:
app: client1

#部署
[root@k8s-master1 np]#kubectl apply -f test.yaml
networkpolicy.networking.k8s.io/dev-web created
  • 测试
#创建测试pod
kubectl run busybox --image=busybox -n prod -- sleep 12h #预期:会访问成功
kubectl run busybox --image=busybox -- sleep 12h #预期:会访问失败
kubectl run busybox2 --image=busybox -l app=client1 -- sleep 12h #预期:会访问成功

#ping测试
kubectl run busybox --image=busybox -n prod-- sleep 12h #预期:会访问成功
kubectl run busybox --image=busybox -- sleep 12h #预期:会访问失败
kubectl run busybox2 --image=busybox -l app=client1 -- sleep 12h #预期:会访问成功

#测试效果(以下均符合预期效果)
[root@k8s-master1 np]#kubectl exec busybox -nprod -- ping 10.244.169.156
PING 10.244.169.156 (10.244.169.156): 56 data bytes
64 bytes from 10.244.169.156: seq=0 ttl=63 time=0.161 ms
^C
[root@k8s-master1 np]#kubectl exec -it busybox -- ping 10.244.169.156
PING 10.244.169.156 (10.244.169.156): 56 data bytes
^C
--- 10.244.169.156 ping statistics ---
2 packets transmitted, 0 packets received, 100% packet loss
command terminated with exit code 1
[root@k8s-master1 np]#kubectl exec -it busybox2 -- ping 10.244.169.156
PING 10.244.169.156 (10.244.169.156): 56 data bytes
64 bytes from 10.244.169.156: seq=0 ttl=62 time=0.951 ms
64 bytes from 10.244.169.156: seq=1 ttl=62 time=0.600 ms
^C
--- 10.244.169.156 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.600/0.775/0.951 ms

测试结束。😘

关于我

我的博客主旨:

  • 排版美观,语言精炼;
  • 文档即手册,步骤明细,拒绝埋坑,提供源码;
  • 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!

🍀 微信二维码 x2675263825 (舍得), qq:2675263825。

image-20230107215114763

🍀 微信公众号 《云原生架构师实战》

image-20230107215126971

🍀 个人博客站点

http://47.97.48.237/ (即将上线域名:onedayxyy.cn)

image-20230917111843405

🍀 语雀

https://www.yuque.com/xyy-onlyone

image-20230912072007284

🍀 csdn https://blog.csdn.net/weixin_39246554?spm=1010.2135.3001.5421

image-20230107215149885

🍀 知乎 https://www.zhihu.com/people/foryouone

image-20230107215203185

最后

好了,关于本次就到这里了,感谢大家阅读,最后祝大家生活快乐,每天都过的有意义哦,我们下期见!