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
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
# 测试完成