k8s中网络策略(networkpolicy)的工作原理


1、工作原理说明

 

1.1、什么是k8s的网络策略?

 

在k8s中,如何要实现容器访问的安全策略,可以通过网络策略,在pod上增加网络的访问限制,控制哪些客户端可以访问这个pod,也可以控制pod可以访问哪些其他的网络。

 

k8s的网络策略想要工作,也就是说,真正的实现pod间的访问流量的控制,需要部署k8s的网络插件。

 

1.2、k8s网络策略的基本实现原理

 

用下面的公式可以表示:

 

k8s容器网络流量控制 = 网络策略配置 + 网络控制器插件

 

1.3、k8s的默认的网络策略

 

默认情况,在k8s的集群中,允许所有的pod之间的网络访问。

 

也就是,没有任何的限制。

 

同时,设置的网络策略,都是允许访问的设置。

 

1.4、k8s的网络策略的配置模板说明

 

下面,我们看一个k8s网络策略配置的模板文件:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - ipBlock:
            cidr: 172.17.0.0/16
            except:
              - 172.17.1.0/24
        - namespaceSelector:
            matchLabels:
              project: myproject
        - podSelector:
            matchLabels:
              role: frontend
      ports:
        - protocol: TCP
          port: 6379
  egress:
    - to:
        - ipBlock:
            cidr: 10.0.0.0/24
      ports:
        - protocol: TCP
          port: 5978

 

 

各个参数解释如下:


下面的部分,设置的是,将网络策略设置在哪些pod上

在网络策略的设置中,通过标签匹配的方式,设置作用的pod范围。

spec:
  podSelector:
    matchLabels:
      role: db

 

 

 

策略类型的设置部分,设置允许的规则类型,ingress是入站规则,egress是出站规则。

 

入站规则:就是哪些条件可以访问目标pod

出站规则:就是目标pod可以访问哪些地址

  policyTypes:
    - Ingress
    - Egress

 

 

是入站规则的设置部分

from中的条件,表示条件可以访问目标pod,在这个例子里面就是哪些条件可以访问,有标签role: db 的pod

  ingress:
    - from:
        - ipBlock:
            cidr: 172.17.0.0/16
            except:
              - 172.17.1.0/24
        - namespaceSelector:
            matchLabels:
              project: myproject
        - podSelector:
            matchLabels:
              role: frontend
      ports:
        - protocol: TCP
          port: 6379

 

 

设置ip的范围,这些范围内的IP地址可以访问目标pod

        - ipBlock:
            cidr: 172.17.0.0/16
            except:
              - 172.17.1.0/24

 

 

命名空间的匹配,在这个命名空间中的pod可以访问目标pod

        - namespaceSelector:
            matchLabels:
              project: myproject

 

 

客户端的pod,如果有role: frontend这样的标签,就可以访问目标的pod

        - podSelector:
            matchLabels:
              role: frontend

 

 

被访问的目标pod的端口的设置,目标pod的6379允许被访问到

      ports:
        - protocol: TCP
          port: 6379

 


出站规则设置,允许目标pod访问某个IP范围的5978端口

  egress:
    - to:
        - ipBlock:
            cidr: 10.0.0.0/24
      ports:
        - protocol: TCP
          port: 5978

 

 

OK,k8s的网络策略简单的工作原理说明之后,下面通过一些实验,让你直观的感受一下,在k8s的集群中,设置了这些的网络策略之后,对网络的访问,到底有什么影响

 

2、网络策略实验

 

如前面所说的,默认的k8s集群中,所有的pod间的访问都是允许的,都是放开的,并且,网络策略的设置,也是允许的访问设置。

 

这样,就看不出来有哪些的影响了,所以,我们现在做两件事情:

 

  • 部署网络插件(本示例使用calico的网路插件)
  • 修改默认的网络策略,禁止所有的pod间的访问。

 

2.1、网络插件部署

 

如果使用的是calico的网络插件,需要确保在k8s的集群中,有calico-kube-controllers的pod在运行

[root@nccztsjb-node-23 yamls]# kubectl get pod -n kube-system | grep calico-kube
calico-kube-controllers-7cf968cdfd-gghj7   1/1     Running   2 (110d ago)   168d
[root@nccztsjb-node-23 yamls]# 

 

 

在calico-kube-controllers中,包含了policy controller,可以用来同步和管理k8s 网络策略。

 

2.2、禁止所有的入站访问流量设置

 

设置如下的网络策略,默认禁止所有的pod的入站访问

kubectl apply -f - <<EOF
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: default-deny-ingress
  namespace: default
spec:
  podSelector:
    matchLabels: {}
  policyTypes:
  - Ingress
EOF  
[root@nccztsjb-node-23 yamls]# kubectl get networkpolicy
NAME                   POD-SELECTOR   AGE
default-deny-ingress   <none>         11s

 

这样,在default命名空间中的pod,就禁止任何其他的pod访问了。

 

nginx-deployment 这个pod就不允许外部的访问了

 

就是说,如果在ns1这个命名空间中,有一个pod,这个pod还是允许被访问的。

 

ns1命名空间中的pod是允许被其他命名空间中的pod访问的。

[root@nccztsjb-node-23 yamls]# kubectl get pod -n ns1 -o wide
NAME                        READY   STATUS    RESTARTS   AGE     IP             NODE               NOMINATED NODE   READINESS GATES
nginx-ns1-fb8566f97-n4wfn   1/1     Running   0          5m35s   172.39.21.68   nccztsjb-node-25   <none>           <none>
[root@nccztsjb-node-23 yamls]# 
[root@nccztsjb-node-23 yamls]# 
[root@nccztsjb-node-23 yamls]# kubectl exec -it testpod3 -- sh
/ # 
/ # wget 172.39.21.68
Connecting to 172.39.21.68 (172.39.21.68:80)
saving to 'index.html'
index.html           100% |****************************************************************************************************************************************************************************************************************************|   615  0:00:00 ETA
'index.html' saved
/ # 

 

 

这里有个结论,网络策略的作用范围是在命名空间级别的。

2.3、设置网络策略

 

这里,通过以下的配置,设置网络策略:

 

这个网络策略,设置要访问有app=nginx标签的pod,在default命名空间中

并且只允许,有run=testpod3标签的pod进行访问

并且只可以访问80端口

kubectl apply -f - <<EOF
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default  # 命名空间名称
spec:
  podSelector:
    matchLabels:
      app: nginx  # 标签选择要受影响的 Pod
  policyTypes:
    - Ingress  # 定义入站规则
  ingress:
    - from:      
      - podSelector:
          matchLabels:
            run: testpod3 # 允许来自 app: frontend 标签的 Pod
      ports:
      - protocol: TCP
        port: 80
EOF

 

 

 

在环境里面,就有2个网络策略了

[root@nccztsjb-node-23 yamls]# kubectl get networkpolicy
NAME                   POD-SELECTOR   AGE
default-deny-ingress   <none>         6m3s
test-network-policy    app=nginx      5s
[root@nccztsjb-node-23 yamls]# 

 

 

 

这个时候,做下面的访问测试

 

下面的pod有app=nginx标签

[root@nccztsjb-node-23 yamls]# kubectl get pod -o wide -l app=nginx
NAME                                READY   STATUS             RESTARTS           AGE   IP               NODE               NOMINATED NODE   READINESS GATES
nginx-deployment-6bfdb59f47-4qgr4   1/1     Running            0                  55d   172.39.157.240   nccztsjb-node-24   <none>           <none>
nginx-deployment-6bfdb59f47-6kjn5   1/1     Running            0                  55d   172.39.21.114    nccztsjb-node-25   <none>           <none>
nginx-deployment-6bfdb59f47-dlr47   1/1     Running            0                  55d   172.39.21.115    nccztsjb-node-25   <none>           <none>
nginx-deployment-7fbdb85b5b-8vxhp   0/1     CrashLoopBackOff   3947 (3m53s ago)   14d   172.39.21.74     nccztsjb-node-25   <none>           <none>
[root@nccztsjb-node-23 yamls]# 

 

 

通过其他的pod进行访问

 

选择一个标签是run=testpod4的pod进行访问,发现无法访问

[root@nccztsjb-node-23 yamls]# kubectl get pod -o wide --show-labels
NAME                                   READY   STATUS             RESTARTS           AGE    IP               NODE               NOMINATED NODE   READINESS GATES   LABELS
bash                                   0/1     ImagePullBackOff   0                  56d    172.39.21.110    nccztsjb-node-25   <none>           <none>            run=bash
deployment-nodename-598765fbc9-g9xdj   1/1     Running            0                  46d    172.39.157.210   nccztsjb-node-24   <none>           <none>            app=example-app,pod-template-hash=598765fbc9
deployment-nodename-598765fbc9-rfzkz   1/1     Running            0                  46d    172.39.157.199   nccztsjb-node-24   <none>           <none>            app=example-app,pod-template-hash=598765fbc9
deployment-nodename-598765fbc9-z8qvt   1/1     Running            0                  46d    172.39.157.238   nccztsjb-node-24   <none>           <none>            app=example-app,pod-template-hash=598765fbc9
load-generator                         1/1     Running            0                  151d   172.39.21.81     nccztsjb-node-25   <none>           <none>            run=load-generator
nginx-deployment-6bfdb59f47-4qgr4      1/1     Running            0                  55d    172.39.157.240   nccztsjb-node-24   <none>           <none>            app=nginx,pod-template-hash=6bfdb59f47
nginx-deployment-6bfdb59f47-6kjn5      1/1     Running            0                  55d    172.39.21.114    nccztsjb-node-25   <none>           <none>            app=nginx,pod-template-hash=6bfdb59f47
nginx-deployment-6bfdb59f47-dlr47      1/1     Running            0                  55d    172.39.21.115    nccztsjb-node-25   <none>           <none>            app=nginx,pod-template-hash=6bfdb59f47
nginx-deployment-7fbdb85b5b-8vxhp      0/1     Error              3948 (5m22s ago)   14d    172.39.21.74     nccztsjb-node-25   <none>           <none>            app=nginx,pod-template-hash=7fbdb85b5b
nginx-network-75c8777ddf-r7glj         1/1     Running            0                  50d    172.39.157.202   nccztsjb-node-24   <none>           <none>            app=nginx2,pod-template-hash=75c8777ddf
nginxhostport                          1/1     Running            1 (80d ago)        90d    172.39.157.198   nccztsjb-node-24   <none>           <none>            app=nginxhostport
nginxhostport2                         1/1     Running            0                  90d    172.39.21.98     nccztsjb-node-25   <none>           <none>            app=nginxhostport2
nginxhostport3                         0/1     Pending            0                  90d    <none>           <none>             <none>           <none>            app=nginxhostport3
php-apache-6cb76cff7b-n5lpt            1/1     Running            0                  75d    172.39.157.228   nccztsjb-node-24   <none>           <none>            pod-template-hash=6cb76cff7b,run=php-apache
pod-nodename                           1/1     Running            0                  46d    172.39.157.204   nccztsjb-node-24   <none>           <none>            <none>
testpod                                0/1     ErrImagePull       0                  56d    172.39.21.106    nccztsjb-node-25   <none>           <none>            run=testpod
testpod2                               0/1     CrashLoopBackOff   15772 (45s ago)    56d    172.39.157.249   nccztsjb-node-24   <none>           <none>            run=testpod2
testpod3                               1/1     Running            1 (55d ago)        56d    172.39.21.113    nccztsjb-node-25   <none>           <none>            run=testpod3
testpod4                               1/1     Running            1 (55d ago)        55d    172.39.157.195   nccztsjb-node-24   <none>           <none>            run=testpod4
[root@nccztsjb-node-23 yamls]# 
[root@nccztsjb-node-23 yamls]# 
[root@nccztsjb-node-23 yamls]# kubectl exec -it testpod4 -- sh
/ # 
/ # wget 172.39.157.240 
Connecting to 172.39.157.240 (172.39.157.240:80)

 

 

选择run=testpod3的pod进行访问,发现在testpo3 pod里面,是可以访问任何的app=nginx的pod的

 

满足预期的目标。

 

 

3、附录

 

前面对禁止所有的入站规则,并且开放某些pod的入站规则,其他的测试也是类似的,可以自行设置。

 

3.1、禁止所有的出站流量规则设置

 

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-egress
spec:
  podSelector: {}
  policyTypes:
  - Egress

 

 

3.2、同时禁止入站、出站的流量规则设置

 

通过下面的设置,可以同时禁止掉,出站和入站的规则设置。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress

 

 

3.3、允许所有的入站流量规则设置

 

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-ingress
spec:
  podSelector: {}
  ingress:
  - {}
  policyTypes:
  - Ingress

 

 

3.4、允许所有的出站流量规则的设置

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-egress
spec:
  podSelector: {}
  egress:
  - {}
  policyTypes:
  - Egress

 

你好,

如果你读完了整个技术文章,说明你是个技术爱好者,钻研者。

在4年多的k8s体系运维时间里,我整理了230个,k8s最常见(最关键)的问题。

这些问题,让我轻松地应对几乎所有的k8s问题,并且,都是基于项目及大量的实验的总结。

如果你能够彻底掌握这些问题,你的知识体系,k8s基本功,就可以轻松超过80%的k8s运维人员。

更重要的是,掌握这些知识非常简单,每天5个问题,2个月后,你就可以打下k8s的见识基础,让你在云原生领域游刃有余。

每个问题,都有对应的答案,以及相关的示例演示(有些还有项目背景说明)

只要,一步一步,跟着做,就可以了。

当然,如果你想要在更短的时间内,成为k8s高手,你只需要多练习几次就可以了。

不过,和你自己从头摸索相比较,大大减少了你的学习时间,同时,大大提升了你的学习效力。

更加重要的是,如果你知道20/80原理,你就会明白,这些都是工作中最常用,最有效的20%的问题。

这个资料是第一次公开,为了了解市场上,有多少人在关注k8s的技术,我决定免费赠送这个问题指南,只当交个朋友。

添加微信:13240133388,备注:k8s

我将送你一份免费的PDF报告。

你应该知道,一本k8s权威指南(800页,没几个人看得完),要179.90元,这些问题,是在反复阅读和实践了这本书之后,结合项目实践,得出来的精华。

想想看,这将节省你多少时间?而你得到是最精华的部分?

相信你,掌握之后,立马让你的工作的效率大增,你的领导会对你的进步刮目相看。

PS. 行动是一切的开始,现在立马订阅吧。期待你的蜕变。

 

posted @ 2023-08-15 11:39  Zhai_David  阅读(551)  评论(0编辑  收藏  举报