文章目录

  • 1. 网络策略
  • 2. 环境的配置
  • 2.1 拉取镜像
  • 2.2清理实验环境
  • 3. 配置Calico网络插件
  • 3.1 配置calico
  • 3.2 测试
  • 4. 网络策略示例
  • 4.1 限制访问指定服务
  • 4.2 允许指定pod访问服务
  • 4.3 禁止 namespace 中所有 Pod 之间的相互访问
  • 4.4 禁止其他 namespace 访问服务
  • 4.5 只允许指定namespace访问服务
  • 4.6 允许外网访问服务


1. 网络策略

官网

  • 前置条件
    网络策略通过网络插件 来实现。要使用网络策略,你必须使用支持 NetworkPolicy 的网络解决方案。 创建一个 NetworkPolicy 资源对象而没有控制器来使它生效的话,是没有任何作用的。(Flannel不支持 NetworkPolicy,所以使用Flannei网络插件是不会隔离pod的)
  • 隔离和非隔离的 Pod
    默认情况下,Pod 是非隔离的,它们接受任何来源的流量。
    Pod 在被某 NetworkPolicy 选中时进入被隔离状态。 一旦名字空间中有 NetworkPolicy 选择了特定的 Pod,该 Pod 会拒绝该 NetworkPolicy 所不允许的连接。 (名字空间下其他未被 NetworkPolicy 所选择的 Pod 会继续接受所有的流量)
    网络策略不会冲突,它们是累积的。 如果任何一个或多个策略选择了一个 Pod, 则该 Pod 受限于这些策略的 入站(Ingress)/出站(Egress)规则的并集。因此评估的顺序并不会影响策略的结果。
    为了允许两个 Pods 之间的网络数据流,源端 Pod 上的出站(Egress)规则和 目标端 Pod 上的入站(Ingress)规则都需要允许该流量。 如果源端的出站(Egress)规则或目标端的入站(Ingress)规则拒绝该流量, 则流量将被拒绝。

2. 环境的配置

2.1 拉取镜像

##1. 拉取
[root@server1 harbor]# docker pull calico/kube-controllers:v3.16.1   ##拉取的镜像可以通过官网下载的calico.yaml文件来查看
[root@server1 harbor]# docker pull calico/cni:v3.16.1
[root@server1 harbor]# docker pull calico/pod2daemon-flexvol:v3.16.1
[root@server1 harbor]# docker pull calico/node:v3.16.1

## 2. 上传
[root@server1 harbor]# docker tag calico/node:v3.16.1 reg.westos.org/calico/node:v3.16.1
[root@server1 harbor]# docker push reg.westos.org/calico/node:v3.16.1 
[root@server1 harbor]# docker tag calico/pod2daemon-flexvol:v3.16.1 reg.westos.org/calico/pod2daemon-flexvol:v3.16.1
[root@server1 harbor]# docker push  reg.westos.org/calico/pod2daemon-flexvol:v3.16.1
[root@server1 harbor]# docker tag calico/cni:v3.16.1 reg.westos.org/calico/cni:v3.16.1
[root@server1 harbor]# docker push reg.westos.org/calico/cni:v3.16.1
[root@server1 harbor]# docker tag calico/kube-controllers:v3.16.1 reg.westos.org/calico/kube-controllers:v3.16.1
[root@server1 harbor]# docker push  reg.westos.org/calico/kube-controllers:v3.16.1

docker 本地网络 docker 本地网络插件_docker 本地网络

2.2清理实验环境

[root@server2 ~]# kubectl delete -f kube-flannel.yml    ##删除fannel网络插件配置
[root@server2 ~]# kubectl -n kube-system get pod    ##查看是否删除
[root@server2 ~]# kubectl get pod
NAME                          READY   STATUS    RESTARTS   AGE
deployment-6456d7c676-crj5z   1/1     Running   3          7d3h
deployment-6456d7c676-k8z6h   1/1     Running   1          7d3h
[root@server2 ~]# kubectl delete deployments.apps deployment 
deployment.apps "deployment" deleted
[root@server2 ~]# kubectl  get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   36d
nginx-svc    ClusterIP   10.102.145.154   <none>        80/TCP    7d3h
[root@server2 ~]# kubectl  delete svc nginx-svc
service "nginx-svc" deleted
[root@server2 ~]# kubectl get all
NAME                              READY   STATUS        RESTARTS   AGE
pod/deployment-6456d7c676-k8z6h   0/1     Terminating   1          7d3h

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   36d

docker 本地网络 docker 本地网络插件_ico_02


docker 本地网络 docker 本地网络插件_docker 本地网络_03

##移除fannel生成的配置文件 [root@server2 ~]# cd /etc/cni/ 
[root@server2 cni]# cd net.d/ [root@server2 net.d]# ls 10-flannel.conflist [
root@server2 net.d]# mv 10-flannel.conflist /mnt/   ##每一个节点都需要移除 
[root@server3 net.d]# mv 10-flannel.conflist /mnt/ 
[root@server4 net.d]# mv 10-flannel.conflist /mnt/ 
[root@server2 net.d]# ps ax | grep flannel 
 3962 ?        Ssl    0:01 /opt/bin/flanneld --ip-masq --kube-subnet-mgr
24219 pts/0    S+     0:00 grep --color=auto flannel

docker 本地网络 docker 本地网络插件_ico_04

3. 配置Calico网络插件

3.1 配置calico

官网

- calico简介:
	flannel实现的是网络通信,calico的特性是在pod之间的隔离(网络策略)。
	通过BGP路由,但大规模端点的拓扑计算和收敛往往需要一定的时间和计算资源。
	纯三层的转发,中间没有任何的NAT和overlay,转发效率最好。
	
	Calico 仅依赖三层路由可达。Calico 较少的依赖性使它能适配所有 VM、Container、白盒或者混合环境场景。

- 安装calico:
	# wget https://docs.projectcalico.org/manifests/calico.yaml    ##通过官网可以查看(最新版本下载比较慢,所以我使用的是)
	# vim calico.yml
	            - name: CALICO_IPV4POOL_IPIP        ##IPIP表示隧道
	              value: "off"
	# kubectl apply -f calico.yaml     ##创建
[root@server2 ~]# mkdir calico   
[root@server2 ~]# cd calico/
[root@server2 calico]# ls
calico.yaml  deny-nginx.yaml
[root@server2 calico]# kubectl apply -f calico.yaml   ##应用calico网络插件
[root@server2 calico]# kubectl -n kube-system get pod    ##查看calico节点是否运行
[root@server2 calico]# cd /etc/cni/net.d/   ##查看calico插件配置,每个结点都有
[root@server2 net.d]# ls 
10-calico.conflist  calico-kubeconfig

docker 本地网络 docker 本地网络插件_Pod_05


docker 本地网络 docker 本地网络插件_ico_06

3.2 测试

## 1.先生成两个标签为nginx的pod
[root@server2 ~]# cd ingress/
[root@server2 ingress]# ls
auth  demo.yml  deploy.yaml  nginx-svc.yml  nginx.yml  tls.crt  tls.key
[root@server2 ingress]# vim nginx-svc.yml 
[root@server2 ingress]# kubectl get ingress
NAME           CLASS    HOSTS             ADDRESS       PORTS     AGE
ingress-demo   <none>   www1.westos.org   192.168.0.3   80, 443   7d2h
[root@server2 ingress]# kubectl describe ingress ingress-demo ^C
[root@server2 ingress]# kubectl apply -f nginx-svc.yml 
service/nginx-svc created
deployment.apps/deployment created
[root@server2 ingress]# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   36d
nginx-svc    ClusterIP   10.97.34.4   <none>        80/TCP    10s
[root@server2 ingress]# kubectl get pod -L app
[root@server2 ingress]# kubectl get pod -o wide
[root@server2 ingress]# curl 10.97.34.4
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@server2 ingress]# curl 10.97.34.4/hostname.html
deployment-6456d7c676-4fkn5

docker 本地网络 docker 本地网络插件_ico_07

## 2. 运行测试文件,查看是否隔离标签为nginx的pod(网络策略,隔离所有ngix标签的pod)
[root@server2 calico]# cat deny-nginx.yaml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy      
metadata:
  name: deny-nginx
spec:
  podSelector:
    matchLabels:
      app: nginx
[root@server2 calico]# kubectl apply -f deny-nginx.yaml 
networkpolicy.networking.k8s.io/deny-nginx created
[root@server2 calico]# kubectl get networkpolicies.networking.k8s.io 
NAME         POD-SELECTOR   AGE
deny-nginx   app=nginx      34s
[root@server2 calico]# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   36d
nginx-svc    ClusterIP   10.97.34.4   <none>        80/TCP    7m30s
[root@server2 calico]# curl 10.97.34.4
^C
[root@server2 calico]# kubectl get pod -L app

docker 本地网络 docker 本地网络插件_ico_08

4. 网络策略示例

4.1 限制访问指定服务

### 3.2详细测试结果
[root@server2 calico]# kubectl run demo --image=busyboxplus -it
[root@server2 calico]# kubectl run nginx --image=myapp:v2 
pod/nginx created
[root@server2 calico]# kubectl get pod -L app
NAME                          READY   STATUS    RESTARTS   AGE     APP
demo                          1/1     Running   0          8m18s   
deployment-6456d7c676-4fkn5   1/1     Running   1          62m     nginx
deployment-6456d7c676-rbfdf   1/1     Running   1          62m     nginx
nginx                         1/1     Running   0          16s     
[root@server2 calico]# kubectl get pod -o wide
NAME                          READY   STATUS    RESTARTS   AGE     IP               NODE      NOMINATED NODE   READINESS GATES
demo                          1/1     Running   0          8m29s   10.244.22.3      server4   <none>           <none>
deployment-6456d7c676-4fkn5   1/1     Running   1          62m     10.244.22.2      server4   <none>           <none>
deployment-6456d7c676-rbfdf   1/1     Running   1          62m     10.244.141.194   server3   <none>           <none>
nginx                         1/1     Running   0          27s     10.244.141.196   server3   <none>           <none>
[root@server2 calico]# kubectl attach demo -it
[root@server2 calico]# kubectl get networkpolicies.
NAME         POD-SELECTOR   AGE
deny-nginx   app=nginx      12h
[root@server2 calico]# kubectl get networkpolicies. deny-nginx -o yaml

docker 本地网络 docker 本地网络插件_Pod_09

docker 本地网络 docker 本地网络插件_ico_10

4.2 允许指定pod访问服务

[root@server2 calico]# vim access-demo.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: access-nginx
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - from:
      - podSelector:
          matchLabels:
            app: demo
[root@server2 calico]# kubectl apply -f access-demo.yaml
networkpolicy.networking.k8s.io/access-nginx created
[root@server2 calico]# kubectl get networkpolicies.
NAME           POD-SELECTOR   AGE
access-nginx   app=nginx      8s
deny-nginx     app=nginx      12h
[root@server2 calico]# kubectl label pod demo app=demo  ##设置标签
pod/demo labeled
[root@server2 calico]# kubectl get pod -L app
NAME                          READY   STATUS    RESTARTS   AGE   APP
demo                          1/1     Running   0          11h   demo
deployment-6456d7c676-4fkn5   1/1     Running   1          12h   nginx
deployment-6456d7c676-rbfdf   1/1     Running   1          12h   nginx
nginx                         1/1     Running   0          11h   
[root@server2 calico]# kubectl attach demo -it
[root@server2 calico]# kubectl get pod -o wide
NAME                          READY   STATUS    RESTARTS   AGE   IP               NODE      NOMINATED NODE   READINESS GATES
demo                          1/1     Running   0          11h   10.244.22.3      server4   <none>           <none>
deployment-6456d7c676-4fkn5   1/1     Running   1          12h   10.244.22.2      server4   <none>           <none>
deployment-6456d7c676-rbfdf   1/1     Running   1          12h   10.244.141.194   server3   <none>           <none>
nginx                         1/1     Running   0          11h   10.244.141.196   server3   <none>           <none>

docker 本地网络 docker 本地网络插件_Pod_11


docker 本地网络 docker 本地网络插件_docker 本地网络_12

4.3 禁止 namespace 中所有 Pod 之间的相互访问

[root@server2 calico]# kubectl create namespace demo ##创建新的namespace实验
namespace/demo created
[root@server2 calico]# kubectl get ns
[root@server2 calico]# kubectl run  demo1 --image=busyboxplus -it -n demo ##创建demo1
[root@server2 calico]# kubectl run  demo2 --image=busyboxplus -it -n demo
[root@server2 calico]# kubectl -n demo get pod
[root@server2 calico]# kubectl -n demo  get pod --show-labels 
NAME    READY   STATUS    RESTARTS   AGE   LABELS
demo1   1/1     Running   0          55s   run=demo1
demo2   1/1     Running   0          29s   run=demo2
[root@server2 calico]# kubectl -n demo  get pod -L run
[root@server2 calico]# kubectl get pod 

[root@server2 calico]# vim deny-pod.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: demo
spec:
  podSelector: {}
[root@server2 calico]# kubectl apply -f deny-pod.yaml 
[root@server2 calico]# kubectl get networkpolicies. -n demo

##测试
[root@server2 calico]# kubectl attach demo1 -it -n demo  ##测试demo1和demo2之间是否可以相互访问
[root@server2 calico]# kubectl  get pod -o wide -n demo 
NAME    READY   STATUS    RESTARTS   AGE   IP            NODE      NOMINATED NODE   READINESS GATES
demo1   1/1     Running   0          23m   10.244.22.4   server4   <none>           <none>
demo2   1/1     Running   0          23m   10.244.22.5   server4   <none>           <none>
[root@server2 calico]# kubectl attach demo1 -it -n demo

docker 本地网络 docker 本地网络插件_docker 本地网络_13


docker 本地网络 docker 本地网络插件_docker 本地网络_14

docker 本地网络 docker 本地网络插件_docker 本地网络_15

4.4 禁止其他 namespace 访问服务

[root@server2 calico]# kubectl  get pod --show-labels 
[root@server2 calico]# kubectl  get pod -o wide
[root@server2 calico]# vim deny-ns.yaml
[root@server2 calico]# kubectl apply -f deny-ns.yaml 
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: deny-namespace
spec:
  podSelector:
    matchLabels:
  ingress:
  - from:
    - podSelector: {}

[root@server2 calico]# kubectl attach demo1 -it -n demo 
Defaulting container name to demo2.
Use 'kubectl describe pod/demo2 -n demo' to see all of the containers in this pod.
If you don't see a command prompt, try pressing enter.
/ # curl 10.244.141.196

docker 本地网络 docker 本地网络插件_Pod_16

4.5 只允许指定namespace访问服务

[root@server2 calico]# kubectl create namespace test   #创建新的ns
[root@server2 calico]# kubectl run demo3 --image=busyboxplus -it -n test   ##创建测试pod
[root@server2 calico]# vim access-ns.yaml
[root@server2 calico]# cat access-ns.yaml 
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: access-namespace
spec:
  podSelector:
    matchLabels:
      run: nginx         ##指定标签
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          role: prod    ##指定ns的角色名字

[root@server2 calico]# kubectl label ns test role=prod  ##设置namespace标签
[root@server2 calico]# kubectl get ns --show-labels 


[root@server2 calico]# kubectl apply -f access-ns.yaml   ##访问指定标签的pod
[root@server2 calico]# kubectl attach demo3 -it -n test
[ root@demo3:/ ]$ curl 10.244.141.196
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a> ##标签为run=nginx的pod节点,且访问成功
[root@server2 calico]# kubectl attach demo2 -it -n demo
[ root@demo2:/ ]$ curl 10.244.141.196   ##标签不为run=nginx的pod节点,访问不成功
^C

docker 本地网络 docker 本地网络插件_docker 本地网络_17


docker 本地网络 docker 本地网络插件_Pod_18

4.6 允许外网访问服务

[root@server2 ~]# cd ingress/
[root@server2 ingress]# vim demo.yml 
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-demo
spec:
#  tls:
#    - hosts:
#      - www1.westos.org
#      secretName: tls-secret           
  rules:
  - host: www1.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-svc
          servicePort: 80

[root@server2 ingress]# kubectl apply -f demo.yml 
[root@server2 ingress]# kubectl get ingress
[root@server2 ingress]# kubectl -n ingress-nginx get svc

docker 本地网络 docker 本地网络插件_Pod_19


docker 本地网络 docker 本地网络插件_ico_20

[root@server2 ~]# cd calico/
[root@server2 calico]# vim access-ex.yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: web-allow-external
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - ports:
    - port: 80
    from: []
[root@server2 calico]# kubectl apply -f access-ex.yaml 
networkpolicy.networking.k8s.io/web-allow-external created
[root@foundation50 Desktop]# curl www1.westos.org
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@foundation50 Desktop]# curl www1.westos.org/hostname.html
deployment-6456d7c676-4fkn5
[root@foundation50 Desktop]# curl www1.westos.org/hostname.html
deployment-6456d7c676-rbfdf

docker 本地网络 docker 本地网络插件_Pod_21