NetworkPolicy

Network Policies

一、相同namespace的隔离性

1、在同一个namespace下创建应用测试互访

# 创建一个namespace
kubectl create namespace policy-demo

# 创建pod
kubectl run --namespace=policy-demo nginx --image=nginx --labels=app=nginx
kubectl run nginx --image=nginx --labels=app=nginx

# 创建service
kubectl expose --namespace=policy-demo pod nginx --port=80
kubectl expose pod nginx --port=80

# 测试访问正常
kubectl -n policy-demo run test --image=busybox:1.28 --labels=app=busybox --command -- sleep 3600000
kubectl run test --image=busybox:1.28 --labels=app=busybox --command -- sleep 3600000
kubectl -n policy-demo exec -it test -- wget -q nginx -O -
kubectl exec -it test -- wget -q nginx -O -

# 结果:访问正常

2、创建默认拒绝策略

cat <> YAML/default-deny.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: default-deny
  namespace: policy-demo
spec:
  podSelector:
    matchLabels: {}
EOF
# 此规则表示ns:policy-demo下的所有pod拒绝所有的入口流量,包括本ns和其他ns的入口流量。但是ns:policy-demo下的所有pod可以访问其他ns的pod。
# 其实等同于ns:policy-demo拒绝所有的入口流量,允许出口流量。

kubectl apply -f YAML/default-deny.yaml

# 访问测试
#1、同ns和不同ns的入口流量被拒绝。
kubectl -n policy-demo exec -ti test -- wget -q nginx -O -
kubectl exec -ti test -- wget -q nginx -O -
wget: Download time out
# 可以看见被拒绝访问了

#2、ns:policy-demo中的pod可以访问其他ns的服务,即允许出口流量。
kubectl -n policy-demo exec -ti test -- wget -q nginx.default -O -
# 可以访问

3、添加允许策略

cat <> YAML/access-nginx.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: access-nginx
  namespace: policy-demo
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: busybox
EOF
# 这条规则意思,允许policy-demo namespace下label为 app:busyboxy 的pod访问 policy-demo namespace 下label为 app:nginx 的pod

kubectl create -f  YAML/access-nginx.yaml

# 访问测试
# 1、policy-demo namespace下label为 app:busyboxy 的pod访问 policy-demo namespace 下label为 app:nginx 的pod
kubectl -n policy-demo exec -ti test -- wget -q nginx -O -
# 结果:访问成功

#2、default namespace下label为 app:busyboxy 的pod访问 policy-demo namespace 下label为 app:nginx 的pod
kubectl exec -ti test -- wget -q nginx -O -
# 结果:访问失败

#3、创建一个不是 app:busybox 的pod去测试访问
kubectl -n policy-demo run demo --image=busybox:1.28 --labels=app=test --command -- sleep 3600000
kubectl -n policy-demo exec -it demo -- wget -q nginx -O -
# 结果:wget:Download time out

# 结论:同namespace下可以使用Policy在限制pod与pod之间的访问
# 清空环境
kubectl delete namespace policy-demo

二、 不同namespace的隔离性

1、跨namespaces访问测试

# 创建两个namespace policy-demo、policy-demo2
# 在policy-demo里面创建nginx-pod和对应的service,再创建一个busybox,
# 在policy-demo2里面创建busybox,
# 分别用两个namespace里的busybox去访问policy-demo里面的nginx
kubectl create namespace policy-demo
kubectl create namespace policy-demo2
kubectl run --namespace=policy-demo nginx --image=nginx --labels=app=nginx
kubectl run --namespace=policy-demo2 nginx --image=nginx --labels=app=nginx
kubectl expose --namespace=policy-demo pod nginx --port=80
kubectl expose --namespace=policy-demo2 pod nginx --port=80

kubectl -n policy-demo run test --image=busybox:1.28 --labels=app=busybox --command -- sleep 3600000
kubectl -n policy-demo2 run test --image=busybox:1.28 --labels=app=busybox --command -- sleep 3600000

kubectl -n policy-demo exec -it test -- wget -q nginx.policy-demo -O -
kubectl -n policy-demo exec -it test -- wget -q nginx.policy-demo2 -O -
kubectl -n policy-demo2 exec -it test -- wget -q nginx.policy-demo -O -
kubectl -n policy-demo2 exec -it test -- wget -q nginx.policy-demo2 -O -
# 测试访问正常,还没设置NetworkPolicy时分别从policy-demo和policy-demo2两个namespace去busybox去访问nginx,访问成功。即,默认是没有策略的。
# 需要注意的是跨namespaces访问时service名后要加上namespace名

2、创建默认拒绝策略

cat <> YAML/default-deny.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: default-deny
  namespace: policy-demo
spec:
  podSelector:
    matchLabels: {}
EOF

kubectl create -f YAML/default-deny.yaml

# 默认拒绝所有入口流量,此时两个namespace下的的busybox都不能访问nginx
kubectl -n policy-demo exec -it test -- wget -q nginx.policy-demo -O -
kubectl -n policy-demo2 exec -it test -- wget -q nginx.policy-demo -O -

# 默认不拒绝出口流量,即policy-demo下的pod可以访问其他ns的service
kubectl -n policy-demo exec -it test -- wget -q nginx.policy-demo2 -O -

3、添加允许策略

# 配置允许所有 namespace Label 为 run:access 下的容器,访问policy-demo namespaces下Label 为 app:nginx 的 Pod。
cat <> YAML/namespace-access.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: namespace-access
  namespace: policy-demo
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
    - from:
      - namespaceSelector:
          matchLabels:
            run: access
EOF

kubectl create -f YAML/namespace-access.yaml

# 给namespace添加标签
kubectl label namespaces policy-demo2 run=access

# 访问测试
#1、拥有run=access标签的policy-demo2 ns可以访问policy-demo ns下app=nginx的pod
kubectl -n policy-demo2 exec -it test -- wget -q nginx.policy-demo -O -

#2、未拥有run=access标签的policy-demo ns不可以访问policy-demo ns下app=nginx的pod
kubectl -n policy-demo exec -it test -- wget -q nginx.policy-demo -O -

4、扩展练习

# 两个namespaces分别为policy-test1、policy-test2
# policy-test1中分别部署mysql、nginx、busybox
# Policy-test2中部署busybox
# 策略要求:
# 1、只允policy-test1 中 nginx 访问 mysql 3306 端口
# 2、只允许policy-test2 中 busybox 访问 nginx 80 端口

# 创建所需要应用
kubectl create namespace policy-test1
kubectl create namespace policy-test2
kubectl run -n policy-test1 mysql --image=mysql --env MYSQL_ROOT_PASSWORD=password
kubectl run -n policy-test1 nginx --image=nginx
kubectl expose pod -n policy-test1 mysql --port=3306
kubectl expose pod -n policy-test1 nginx --port=80
kubectl run -n policy-test1 busybox --image=busybox:1.28.3 sleep 3600000
kubectl run -n policy-test2 busybox --image=busybox:1.28.3 sleep 3600000

# 查看部署状态
kubectl get pod  -n policy-test1 
NAME      READY   STATUS    RESTARTS   AGE
busybox   1/1     Running   0          111s
mysql     1/1     Running   0          4m5s
nginx     1/1     Running   0          7m56s

kubectl get service -n policy-test1 
NAME    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
mysql   ClusterIP   10.108.14.117    <none>        3306/TCP   2m2s
nginx   ClusterIP   10.104.167.116   <none>        80/TCP     107s

kubectl get pod -n policy-test2
NAME      READY   STATUS    RESTARTS   AGE
busybox   1/1     Running   0          9s

# 同namespaces访问测试
kubectl exec -ti -n policy-test1 busybox -- sh
/ # wget --spider --timeout=1 nginx:80
Connecting to nginx:80 (10.104.167.116:80)		# 成功
/ # wget --spider --timeout=1 mysql:3306
Connecting to mysql:3306 (10.108.14.117:3306)	
wget: bad header line: 8.0.21					# 成功,
/ # wget --spider --timeout=1 mysql:3307		
Connecting to mysql:3307 (10.108.14.117:3307)
wget: download timed out						# 失败会显示 time out

# 跨namespaces访问测试
kubectl exec -ti -n policy-test2 busybox -- sh
/ # wget --spider --timeout=1 nginx.policy-test1:80
Connecting to nginx.policy-test1:80 (10.104.167.116:80)
/ # wget --spider --timeout=1 mysql.policy-test1:3306
Connecting to mysql.policy-test1:3306 (10.108.14.117:3306)
wget: bad header line: 8.0.21

#从以上测试中可以看出,不管是同namespaces还是跨namespaces应用都是可以互访,不受任何限制。

# 在namespace没有配置任何策略前,默认允许所有进、出流量
# 常用的方法一般是:
#	入口方向使用拒绝所有,允许个别的方式配置网络策略
#	出口方向允许所有(默认就是,不用配置)

# 创建策略文件
vim YAML/networkpolicy.yaml

# deny-all
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all			
spec:
  podSelector: {}
  policyTypes:
  - Ingress
# allow-nginx-to-mysql
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-nginx-to-mysql
  namespace: policy-test1
spec:
  podSelector:
    matchLabels:
      run: mysql
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          run: nginx
    ports:
    - protocol: TCP
      port: 3306
# allow-test2_busybox-to-nginx
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-test2-busybox-to-nginx
  namespace: policy-test1
spec:
  podSelector:
    matchLabels:
      run: nginx
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          project: test2
    - podSelector:
        matchLabels:
          run: busybox
    ports:
    - protocol: TCP
      port: 80

# 测试连接,同namespaces
# nginx 访问 mysql
kubectl exec -ti -n policy-test1 nginx -- bash
root@nginx:/# curl mysql:3306
Warning: Binary output can mess up your terminal. Use "--output -" to tell 		# 连接成功
Warning: curl to output it to your terminal anyway, or consider "--output 
Warning: " to save to a file.

# busybox访问nginx和mysql
kubectl exec -ti -n policy-test1 busybox -- sh
/ #  wget --spider --timeout=1 nginx:80	
Connecting to nginx:80 (10.104.167.116:80)										# 连接成功
/ #  wget --spider --timeout=1 mysql:3306
Connecting to mysql:3306 (10.108.14.117:3306)
wget: download timed out														# 连接失败

# 测试连接,跨namespaces
# test2中的busybox访问test1中的nginx和mysql,两个都不通,不符我们的实验要求
kubectl exec -ti -n policy-test2 busybox -- sh
/ # wget --spider --timeout=1 nginx.policy-test1:80
Connecting to nginx.policy-test1:80 (10.104.167.116:80)
wget: download timed out														# 连接失败,不符合实验要求
/ # wget --spider --timeout=1 mysql.policy-test1:3306
Connecting to mysql.policy-test1:3306 (10.108.14.117:3306)
wget: download timed out														# 连接失败

kubectl label namespaces policy-test2 project=test2	# 给namespaces打个标签再测试

kubectl exec -ti -n policy-test2 busybox -- sh
/ # wget --spider --timeout=1 nginx.policy-test1:80	
Connecting to nginx.policy-test1:80 (10.104.167.116:80)							# 连接成功
/ # wget --spider --timeout=1 mysql.policy-test1:3306
Connecting to mysql.policy-test1:3306 (10.108.14.117:3306)						# 连接失败
wget: download timed out
      
# 测试完成

只要满足三个其中一个条件,就会允许访问。
NetworkPolicy_第1张图片

你可能感兴趣的:(kubernetes)