一、安装
因为Kubernetes官方用的flannel无法实现多租户环境下的网络隔离,建立起来的pod之间实际可以相互访问,而Calico可以实现。所以我们安装的是使用flannel作为通信网络,calico作为网络策略。
官网安装地址:https://docs.projectcalico.org/getting-started/kubernetes/flannel/flannel#installing-with-the-kubernetes-api-datastore-recommended
k8s访问策略官网地址:https://kubernetes.io/zh/docs/concepts/services-networking/network-policies/
1.1 下载文件:
curl https://docs.projectcalico.org/manifests/canal.yaml -O
1.2 部署:
kubectl apply -f canal.yaml
1.3查看pod是否都起来。
查看使用方法:
kubectl explain networkpolicy.spec
二、部署简单的网络策略
编写了一个控制Pod所有入网都不能访问的策略:
[root@master calico]# cat deny-all-ingress.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
spec:
podSelector: {} # 选择所有Pod
policyTypes:
- Ingress # 控制入网策略
部署到dev环境:
kubectl create ns dev
kubectl apply -f deny-all-ingress.yml -n dev
三、测试
2.1 创建两个namespace:dev、prod
kubectl create ns dev # 上一步已经创建
kubectl create ns prod
2.2 生成简单的deployment资源清单
kubectl create deployment nginx --image=nginx --dry-run -o yaml >nginxtt.yml
去除无用配置:
[root@master calico]# cat nginxtt.yml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-tt
name: nginx-tt
spec:
replicas: 2
selector:
matchLabels:
app: nginx-tt
template:
metadata:
labels:
app: nginx-tt
spec:
containers:
- image: nginx
name: nginx
2.3 部署测试拒绝所有入网访问
kubectl apply -f nginxtt.yml -n dev
kubectl apply -f nginxtt.yml -n prod
查看Pod的IP
[root@master calico]# kubectl get pod -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-tt-7c54bb59d5-4rs8v 1/1 Running 0 6s 10.244.1.16 node1 <none> <none>
nginx-tt-7c54bb59d5-dpr8l 1/1 Running 0 6s 10.244.2.16 node2 <none> <none>
访问,由于我们设置了dev命名空间所有的入网访问,所以是访问不到Pod的内容的。
[root@master calico]# curl 10.244.1.16
^C
测试访问prod的Pod
[root@master calico]# kubectl get pod -n prod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-tt-7c54bb59d5-86nqg 1/1 Running 0 9s 10.244.2.14 node2 <none> <none>
nginx-tt-7c54bb59d5-dfmcx 1/1 Running 0 9s 10.244.1.15 node1 <none> <none>
prod环境没有设置访问策略,所以我们是能够访问的。
[root@master calico]# curl 10.244.2.14
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
2.4 测试允许所有入网访问
修改访问策略:
[root@master calico]# cat deny-all-ingress.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
spec:
podSelector: {}
ingress: # 配置ingress(入网)策略
- {} # {} 允许所有
policyTypes:
- Ingress
重新在dev部署策略
kubectl apply -f deny-all-ingress.yml -n dev
再次访问dev中的Pod,发现可以访问了:
[root@master calico]# curl 10.244.1.16
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
2.5 测试允许某些Pod入网访问
首先设置dev pod 拒绝所有入网访问
deny-all-ingress.yml 去掉以下配置,重新部署到dev
ingress: # 配置ingress(入网)策略
- {} # {} 允许所有
kubectl apply -f deny-all-ingress.yml -n dev
为pod 添加标签apps=myapp:
[root@master calico]# kubectl label -n dev pod nginx-tt-7c54bb59d5-4rs8v apps=myapp
pod/nginx-tt-7c54bb59d5-4rs8v labeled
书写资源清单:
[root@master calico]# cat allow-myapp-ingress.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-myapp-ingess
spec:
podSelector:
matchLabels:
apps: myapp # 匹配带有apps: myapp标签的Pod
ingress:
- from:
- ipBlock:
cidr: 10.244.0.0/16 # 允许的IP段
except:
- 10.244.1.2/32 # 拒绝的IP段
ports:
- protocol: TCP
port: 80 # 允许访问tcp80端口
ipBlock
: 此选择器将选择特定的 IP CIDR 范围以用作入站流量来源或出站流量目的地。 这些应该是集群外部 IP,因为 Pod IP 存在时间短暂的且随机产生。
cidr
: 无类别域间路由(Classless Inter-Domain Routing、CIDR)是一个用于给用户分配IP地址以及在互联网上有效地路由IP数据包的对IP地址进行归类的方法。
部署新的网络策略:
kubectl apply -f allow-myapp-ingress.yml -n dev
此时访问nginx-tt-7c54bb59d5-4rs8v Pod 的IP就可以访问了,但是没添加apps: myapp的就不能访问:
[root@master calico]# curl 10.244.1.16
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@master calico]# kubectl get pod -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-tt-7c54bb59d5-4rs8v 1/1 Running 0 81m 10.244.1.16 node1 <none> <none>
nginx-tt-7c54bb59d5-ldjxw 1/1 Running 0 81m 10.244.2.17 node2 <none> <none>
[root@master calico]# curl 10.244.2.17
^C
2.6 测试拒绝所有出网访问
编写资源清单:
[root@master calico]# cat deny-all-egress.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
spec:
podSelector: {}
policyTypes:
- Egress
prod环境部署
[root@master calico]# kubectl apply -f deny-all-egress.yml -n prod
networkpolicy.networking.k8s.io/deny-all-egress created
[root@master calico]# kubectl get networkpolicies. -n prod
NAME POD-SELECTOR AGE
deny-all-egress <none> 17s
prod环境创建Pod(自己构建了一个镜像xqkang/nginx:1.18.0 带有ping功能):
[root@master calico]# cat nginxtt.yml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-tt
name: nginx-tt
spec:
replicas: 4
selector:
matchLabels:
app: nginx-tt
template:
metadata:
labels:
app: nginx-tt
spec:
containers:
- image: xqkang/nginx:1.18.0
name: nginx
kubectl apply -f nginxtt.yml
[root@master calico]# kubectl get pod -n prod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-tt-6f7db67468-8tjq8 1/1 Running 0 84s 10.244.1.18 node1 <none> <none>
nginx-tt-6f7db67468-9glpj 1/1 Running 0 84s 10.244.1.19 node1 <none> <none>
nginx-tt-6f7db67468-gppg2 1/1 Running 0 84s 10.244.2.19 node2 <none> <none>
nginx-tt-6f7db67468-xcckl 1/1 Running 0 84s 10.244.2.18 node2 <none> <none>
容器内部是访问不了其他IP的:
[root@master calico]# kubectl exec -it nginx-tt-6f7db67468-44hz5 -- bash -n prod
root@nginx-tt-6f7db67468-44hz5:/usr/share/nginx/html# curl 10.244.2.45
^C
设置允许所有出网,再次进入容器是可以访问的:
[root@master calico]# cat deny-all-egress.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
spec:
podSelector: {}
egress:
- {}
policyTypes:
- Egress
kubectl apply -f deny-all-egress.yml -n prod
[root@master calico]# kubectl exec -it nginx-tt-6f7db67468-44hz5 -- bash-n prod
root@nginx-tt-6f7db67468-44hz5:/usr/share/nginx/html# curl 10.244.2.45
<h1>既然选择了远方,便只顾风雨兼程</h1>