环境说明
操作系统版本 | 内核版本 | Docker版本 | Kubernetes版本 |
---|---|---|---|
7.6.1810 | 4.19.12 | 19.03.13 | v1.18.18 |
操作系统版本
$ cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
内核版本
$ uname -r
4.19.12-1.el7.elrepo.x86_64
Docker版本
$ docker --version
Docker version 19.03.13, build 4484c46
Kubernetes版本
$ kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master Ready <none> 7d22h v1.18.18
k8s-node01 Ready <none> 7d22h v1.18.18
k8s-node02 Ready <none> 7d22h v1.18.18
k8s-node03 Ready <none> 7d22h v1.18.18
此实验参考 kubernetes官网 和 calico官网
web命名空间跑业务容器,client命名空间跑测试业务容器,以下是容器的运行情况
$ kubectl get pod -n web -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
http-647dffb4db-vwxmf 1/1 Running 0 17s 20.0.58.213 k8s-node02 <none> <none>
nginx-5cd55947c-jfgpd 1/1 Running 1 6h8m 20.0.235.233 k8s-master <none> <none>
$ kubectl get pod -n client -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
busybox-5778d9f5ff-dsfxd 1/1 Running 1 5h50m 20.0.135.156 k8s-node03 <none> <none>
centos-6774cc9984-84wlh 1/1 Running 0 6m45s 20.0.85.222 k8s-node01 <none> <none>
限制任何pod进入web命名空间的任何pod,下面的实验都基于这个限制。
$ cat > web-np-deny.yaml <<-EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-deny
namespace: web
spec:
podSelector:
matchLabels: {}
policyTypes:
- Ingress
EOF
$ kubectl apply -f web-np-deny.yaml
networkpolicy.networking.k8s.io/web-deny created
网络策略分类
ipBlock
# 不同IP段,设置前验证
$ kubectl exec -it busybox-5778d9f5ff-dsfxd -n client -- wget -q --timeout=3 http.web.svc.cluster.local -O -
wget: download timed out
command terminated with exit code 1
$ kubectl exec -it centos-6774cc9984-84wlh -n client -- wget -q --timeout=3 http.web.svc.cluster.local -O -
wget: download timed out
command terminated with exit code 1
$ cat > web-np-ipblock.yaml<<-EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-ipblock
namespace: web
spec:
podSelector:
matchLabels:
app: httpd
policyTypes:
- Ingress
ingress:
- from:
- ipBlock:
cidr: 20.0.0.0/16
except:
- 20.0.135.0/24
ports:
- port: 80
protocol: TCP
EOF
$ kubectl apply -f web-np-ipblock.yaml
networkpolicy.networking.k8s.io/web-ipblock created
# 设置后验证
$ kubectl exec -it centos-6774cc9984-84wlh -n client -- wget -q --timeout=3 http.web.svc.cluster.local -O -
<html><body><h1>It works!</h1></body></html>
$ kubectl exec -it busybox-5778d9f5ff-dsfxd -n client -- wget -q --timeout=3 http.web.svc.cluster.local -O -
wget: download timed out
command terminated with exit code 1
注意: ingress下的字段。如果是 与 的关系,那么不需要用
-
。如果是 或 的关系,请使用-
。
上面的示例是20.0.0.0/16
网段,除了20.0.135.0/24
之外,在这个范围的所有IP地址都可以访问 web 命名空间下带有app=httpd
标签pod的80
端口。
namespaceSelector
# 不同命名空间,设置前测试
$ kubectl -n web exec -it busybox-5778d9f5ff-dsfxd -- curl --connect-time 3 http.web.svc.cluster.local
curl: (28) Connection timed out after 3001 milliseconds
command terminated with exit code 28
$ cat > web-np-web-allow.yaml << EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-allow
namespace: web
spec:
podSelector:
matchLabels: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
role: client
EOF
$ kubectl apply -f web-np-web-allow.yaml
networkpolicy.networking.k8s.io/web-allow created
# 设置后测试
$ kubectl -n web exec -it busybox-5778d9f5ff-dsfxd -- curl --connect-time 3 http.web.svc.cluster.local
<html><body><h1>It works!</h1></body></html>
上面的示例是允许命名空间
client
下的所有pod可以访问命名空间web
下的所有pod。
podSelector
# 相同命名空间不同pod,设置前验证
$ kubectl -n web exec -it nginx-5cd55947c-jfgpd -- curl --connect-timeout 3 http.web.svc.cluster.local
curl: (28) Connection timed out after 3000 milliseconds
command terminated with exit code 28
$ cat > web-np-web-allow.yaml<<-EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: web-allow
namespace: web
spec:
podSelector:
matchLabels:
app: httpd
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: nginx
EOF
$ kubectl apply -f web-np-web-allow.yaml
networkpolicy.networking.k8s.io/web-allow created
# 设置后验证
$ kubectl -n web exec -it nginx-5cd55947c-jfgpd -- curl --connect-timeout 3 http.web.svc.cluster.local
<html><body><h1>It works!</h1></body></html>
允许命名空间 web 下,带有
app=nginx
的pod,允许访问 web 命名空间下,带有app=httpd
的pod。
namespaceSelector 和 podSelector
# 不同命名空间下特定pod访问,设置前访问
$ kubectl -n client exec -it busybox-5778d9f5ff-dsfxd -- wget -q --timeout=3 http.web.svc.cluster.local -O -
wget: download timed out
command terminated with exit code 1
$ kubectl -n client exec -it centos-6774cc9984-84wlh -- wget -q --timeout=3 nginx.web.svc.cluster.local -O -
wget: download timed out
command terminated with exit code 1
$ cat > web-np-clientPod-allow.yaml <<-EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: clientpod-allow
namespace: web
spec:
podSelector:
matchLabels:
app: httpd
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: client
namespaceSelector:
matchLabels:
role: client
ports:
- port: 80
protocol: TCP
EOF
$ kubectl apply -f web-np-clientPod-allow.yaml
networkpolicy.networking.k8s.io/clientpod-allow created
# 设置后访问
$ kubectl -n client exec -it busybox-5778d9f5ff-dsfxd -- wget -q --timeout=3 http.web.svc.cluster.local -O -
<html><body><h1>It works!</h1></body></html>
$ kubectl -n client exec -it centos-6774cc9984-84wlh -- wget -q --timeout=3 nginx.web.svc.cluster.local -O -
wget: download timed out
command terminated with exit code 1
上面的示例是允许命名空间带有
role=client
的标签 且 pod带有app=client
的标签去访问httpd
的80
端口的服务。
扩展知识
其实上面的网络策略是由 calico 网络插件来实现的,如果上面的网络策略限制的不精准的话,可以直接查看calico生成的网络策略。
$ calicoctl get networkpolicy -n web
NAMESPACE NAME
web knp.default.clientpod-allow
web knp.default.web-deny
$ calicoctl get networkpolicy -n web knp.default.clientpod-allow -oyaml
apiVersion: projectcalico.org/v3
kind: NetworkPolicy
metadata:
creationTimestamp: "2021-08-23T01:54:45Z"
name: knp.default.clientpod-allow
namespace: web
resourceVersion: "1743939"
uid: 989ac5e1-239b-4428-a3d7-82612e642ad9
spec:
ingress:
- action: Allow
destination:
ports:
- 80
protocol: TCP
source:
namespaceSelector: role == 'client'
selector: projectcalico.org/orchestrator == 'k8s' && app == 'client'
order: 1000
selector: projectcalico.org/orchestrator == 'k8s' && app == 'httpd'
types:
- Ingress
当
calico
网络策略出现两个action
参数。那说明有两个规则生效,导致权限控制不精准。