• 【CKA考试笔记】十三、k8s中的网络


    实验环境

    完成初始化集群的环境:
    (vms21)192.168.26.21——master1
    (vms22)192.168.26.22——worker1
    (vms23)192.168.26.23——worker2

    两台非k8s集群环境的虚拟机:
    (vms31)192.168.26.31
    (vms32)192.168.26.32

    一、calico通信的过程

    calico有两种通信模式:ipip、bgp

    ipip模式:

    1.如下图有两个节点,当我们装好calico之后,会在各节点里建立一个接口、隧道(各节点中都有一个calico-node容器,它负责来创建tunl0这个接口、隧道),如下图节点A里的tunl0和节点B里的tunl0,这两个tunl0即隧道的两端,它们之间可以看成一个直接相通的隧道(一个虚拟的线路,不是真实的物理线路),多个节点之间就会建立起多个隧道
    2.这个隧道能连通的前提是这个两个节点之间物理上能通信,因此,各节点中的tunl0必须在节点中选择一张物理网卡来连接,如下图的ens32
    3.每当在节点中创建一个pod或容器时,就会动态地新建一张虚拟网卡来将pod或容器与tunl0接口连接起来,pod或容器里会有一张网卡与这张虚拟网卡连接,他们之间是vethpair的关系(即直接相连),这张虚拟网卡是动态创建的,一旦pod或容器被删除,这张虚拟网卡也会被删除
    4.pod或容器向外发送数据包时,就直接发给这张虚拟网卡,虚拟网卡又将数据包发送给tunl0,然后通过隧道将数据发送给接收方
    在这里插入图片描述

    bgp模式

    bgp模式与ipip不同的地方在于,ipip模式是通过隧道来传输数据,bgp则是通过bgp协议、以路由的方式传输数据

    实验:在非k8s环境里,准备两台机器,通过calico实现容器跨主机通信

    calico的信息,是存储在etcd数据库里面的,假设两个使用calico通信节点不是在k8s集群环境里,则需要对每个节点都对应建立一个etcd来保存calico信息
    在这里插入图片描述
    搭建etcd集群
    这里我们使用docker来管理镜像
    一、两台机器上都安装docker和etcd

    yum install docker-ce etcd -y
    
    • 1

    二、配置etcd

    vim /etc/etcd/etcd.conf
    
    • 1

    修改vms31、vms32上etcd.conf配置文件中以下内容:

    ETCD_DATA_DIR="/var/lib/etcd/cluster.etcd"
    ETCD_LISTEN_PEER_URLS="http://192.168.26.31:2380,http://localhost:2380"
    ETCD_LISTEN_CLIENT_URLS="http://192.168.26.31:2379,http://localhost:2379"
    ETCD_NAME="etcd-31"
    ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.26.31:2380"
    ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379,http://192.168.26.31:2379"
    ETCD_INITIAL_CLUSTER="etcd-31=http://192.168.26.31:2380,etcd-32=http://192.168.26.32:2380"
    ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
    ETCD_INITIAL_CLUSTER_STATE="new"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    将配置文件拷贝到vms32上

    scp /etc/etcd/etcd.conf 192.168.26.32:/etc/etcd/
    
    • 1

    并作相应修改,将前6行中的31改为32

    ETCD_DATA_DIR="/var/lib/etcd/cluster.etcd"
    ETCD_LISTEN_PEER_URLS="http://192.168.26.32:2380,http://localhost:2380"
    ETCD_LISTEN_CLIENT_URLS="http://192.168.26.32:2379,http://localhost:2379"
    ETCD_NAME="etcd-32"
    ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.26.32:2380"
    ETCD_ADVERTISE_CLIENT_URLS="http://localhost:2379,http://192.168.26.32:2379"
    ETCD_INITIAL_CLUSTER="etcd-31=http://192.168.26.31:2380,etcd-32=http://192.168.26.32:2380"
    ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
    ETCD_INITIAL_CLUSTER_STATE="new"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    三、开启并设置开机自启etcd(两台机器上)

    systemctl enable etcd --now
    
    • 1

    四、查看docker的启动脚本

    systemctl status docker
    #输出:
    ● docker.service - Docker Application Container Engine
       Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
       Active: inactive (dead)
         Docs: https://docs.docker.com
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    得知docker的启动脚本为:/usr/lib/systemd/system/docker.service

    五、编辑docker的启动脚本,使docker能够去读取etcd里的数据

    vim /usr/lib/systemd/system/docker.service
    
    • 1

    编辑ExecStart后的值,增加访问etcd的地址
    修改后为:

    #vms31中的修改为:
    ExecStart=/usr/bin/dockerd --cluster-store=etcd://192.168.26.31:2379 -H fd:// --containerd=/run/containerd/containerd.sock
    
    #vms32中的修改为:
    ExecStart=/usr/bin/dockerd --cluster-store=etcd://192.168.26.32:2379 -H fd:// --containerd=/run/containerd/containerd.sock
    
    • 1
    • 2
    • 3
    • 4
    • 5

    六、重启etcd、启动docker

    systemctl daemon-reload ; systemctl start etcd
    systemctl daemon-reload ; systemctl start docker
    
    • 1
    • 2

    七、在两台机器上准备calico所需的配置文件
    使用calico网络时,在每个节点都会有一个calico-node容器,它会去创建tunl0隧道接口
    因此需要在两台机器上都创建一个calico配置文件

    #1.两个节点上创建文件夹
    mkdir /etc/calico
    
    #2.vms31上创建配置文件
    cat > /etc/calico/calicoctl.cfg <<EOF
    apiVersion: v1
    kind: calicoApiConfig
    metadata:
    spec:
      datastoreType: "etcdv2"
      etcdEndpoints: "http://192.168.26.31:2379"
    EOF
    
    #3.vms32上创建配置文件
    cat > /etc/calico/calicoctl.cfg <<EOF
    apiVersion: v1
    kind: calicoApiConfig
    metadata:
    spec:
      datastoreType: "etcdv2"
      etcdEndpoints: "http://192.168.26.32:2379"
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    八、两个节点上都准备好了calico配置文件,若欲让两个节点通信,建立隧道,则各个节点上都需要建立并运行一个calico-node(calico-node会帮我们建立隧道接口,不需要我们手动建立)
    两个节点上安装calico客户端工具calicoctl及拉取calico-node镜像
    二进制形式安装calicoctl

    wget https://github.com/projectcalico/calicoctl/releases/download/v1.5.0/calicoctl -O calicoctl
    
    • 1

    授予可执行权限,并将文件移动到/bin目录下

    chmod +x calicoctl ; mv calicoctl /bin/
    
    • 1

    拉取calico-node镜像

    docker pull docker.io/calico/node:v2.6.12
    
    • 1

    九、在每个节点上都建立calico-node的pod

    #建立calico-node的pod,并加载calicoctl.cfg配置文件
    calicoctl node run --node-image=docker.io/calico/node:v2.6.12 -c /etc/calico/calicoctl.cfg
    
    • 1
    • 2

    建立成功
    在这里插入图片描述
    十、测试,可以查看对方节点的信息

    calicoctl node status
    
    • 1

    在这里插入图片描述
    十一、建立两个节点之间的隧道
    在任意节点上创建网络,会同步给远端

    #--driver calico:指定使用calico的libnetwork CNM driver
    #--ipam-driver calico-ipam:指定使用calico的IPAM driver管理IP
    docker network create --driver calico --ipam-driver calico-ipam calnet1
    
    • 1
    • 2
    • 3

    (calico为global网络,etcd会将calnet1同步到所有主机,只要使用calico网络创建出来的,都可以识别出来
    创建好后,在另一个节点上可以查看到网络

    docker network list
    
    • 1

    在这里插入图片描述
    十二、各节点上拉取busybox镜像

    docker pull busybox
    
    • 1

    十三、另打开一个vms31的控制台,创建一个名为c31,使用calnet1网络的busybox容器,创建后即进入容器

    docker run -it --name=c31 --network=calnet1 busybox
    
    • 1

    此时在vms32上就无法创建name为c31的容器了(冲突了),因为已经存在这个通道了
    在vms32上创建名为c32,使用calnet1网络的busybox容器

    docker run -it --name=c32 --network=calnet1 busybox
    
    • 1

    回到vms31的busybox容器中,通过ip address查看网络信息

    ip a
    
    • 1

    可以看到cali0@if9这张网卡,即容器里的网卡
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/7927c37eba114e3aadfcf3a628f6ccc3.png
    回到vms原先的控制台,通过ip address查看该节点(宿主机)的网络信息

    ip a
    
    • 1

    可以看到cali9d25e873a83@if8这张网卡,即对应c31容器的虚拟网卡
    在这里插入图片描述
    “8: cali0@if9” 中的 “if9” 即对应虚拟网卡 “9: cali9d25e873a83@if8” 中的 “9”
    虚拟网卡 “cali9d25e873a83@if8” 中的 “if8” 即对应 “8: cali0@if9” 中的 “8”
    这就是它们之间形成的vethpair关系

    同理,vms32中的c32容器中的网卡与vms32中虚拟网卡也是这样的vethpair关系
    查看c32的网络信息
    在这里插入图片描述
    另打开一个vms32的控制台,查看网络信息
    在这里插入图片描述
    即如下图所示:
    在这里插入图片描述
    十四、测试跨主机通信
    c31容器中的网卡cali0@if9的IP地址为:192.168.18.2/32
    c32容器中的网卡cali0@if5的IP地址为:192.168.3.64/32
    测试在c31容器中ping c32的IP

    ping 192.168.3.64
    
    • 1

    在这里插入图片描述
    可以ping通,验证了可以跨主机通信
    回到vms31宿主机上, 查看路由信息,可以看到数据的转发过程

    route -n
    ip route
    
    • 1
    • 2

    在这里插入图片描述
    在这里插入图片描述

    二、网络策略

    使用calico的一个优点即它支持网络策略(两个pod跨主机通信时,可以实现类似防火墙的策略)

    网络策略本质上就是一个防火墙,在没有网络策略的情况下,所有数据包都是能通信的,但是,一旦配置了网络策略,则除了允许的那部分之外,其他都是被拒绝的

    创建网络策略时有几个要考虑的地方:
    1.策略应用到谁?——保护哪个pod
    2.是针对流量入(限制流量流入pod)、还是流量出(限制pod往外连接)
    3.网络策略具体的规则

    创建网络策略

    1.在k8s文档中搜索networkpolicy
    (截图)
    在这里插入图片描述
    2.找到yaml文件模板,如下:
    在这里插入图片描述

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    spec.podSelector——配置该网络策略应用到谁(保护哪些pod),通过pod的标签来匹配,配置多个pod的共同标签即保护多个pod
    若想应用到当前命名空间下的所有pod,保护所有pod,则直接写为:

    podSelector:{}
    #或
    podSelector:
      matchLabels:
    
    • 1
    • 2
    • 3
    • 4

    spec.policyTypes——配置是入策略还是出策略,Ingress为入策略,Egress为出策略,两个都写则为都启用

    spec.ingress.from——配置哪些允许哪些客户端可以访问进来(流量入)
    ipBlock:通过ip限制,cidr下配置允许访问的ip,except表示除了xx之外,如cidr:192.168.26.0 except:192.168.26.31,表示只允许192.168.26.0网段下的网络,除了192.168.26.31之外,都可以访问进来
    namespaceSelector:通过命名空间限制,只有在指定命名空间下的pod可以访问进来,若想所有命名空间下的pod都可以访问进来,则将matchLabels下清空matchLabels:,例:只允许default命名空间下的pod可以访问进来,则先获取default命名空间的标签kubectl get ns --show-labels default,查得为“kubernetes.io/metadata.name=default”,然后将matchLabels下写为“kubernetes.io/metadata.name: default”
    podSelector:通过标签限制,注意,前提是在当前命名空间下,即和这个网络策略是同一个命名空间下的pod,并且只有匹配matchLabels下配置的标签的pod才可以访问进来(只有在k8s集群中,才有标签的概念),若想在当前命名空间下所有pod都可以访问,则直接将matchLabels下清空matchLabels:
    spec.ports——配置允许哪些端口可以访问进来,若没指定则表示允许所有端口访问

    spec.egress.to——配置允许pod访问哪些地址(流量出),选择器的配置同ingress

    查看网络策略

    kubectl get networkpolicy
    
    • 1

    实验:流量入的策略

    创建命名空间net,在命名空间net下,创建两个pod:pod1、pod2,针对这两个pod分别创建两个LoadBalancer类型的svc:svc1关联pod1、svc2关联pod2
    在net命名空间下再创建一个pod,名为testpod
    在default命名空间下创建一个pod,名为default-testpod
    在这里插入图片描述
    (1)创建命名空间net,并使用kubens工具切换net为当前命名空间

    kubectl create ns net
    kubens net
    
    • 1
    • 2

    (2)创建pod1,yaml文件pod11.yaml内容如下:

    apiVersion: v1
    kind: Pod
    metadata:
      creationTimestamp: null
      labels:
        run: pod1
      name: pod1
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - image: nginx
        imagePullPolicy: IfNotPresent
        name: pod1
        resources: {}
      dnsPolicy: ClusterFirst
      restartPolicy: Always
    status: {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    (3)创建pod2,除名字改为pod2外,其他都与pod1相同
    用sed替换关键字"pod1"为"pod2",然后创建

    sed 's/pod1/pod2/' pod11.yaml | kubectl apply -f -
    
    • 1

    (4)修改pod1、pod2的nginx容器内主页内容

    kubectl exec -it pod1 -- sh -c "echo 111 > /usr/share/nginx/html/index.html"
    kubectl exec -it pod2 -- sh -c "echo 222 > /usr/share/nginx/html/index.html"
    
    • 1
    • 2

    (5)针对pod1、pod2创建LoadBalancer类型的svc

    kubectl expose --name=svc1 pod pod1 --port 80 --type LoadBalancer
    kubectl expose --name=svc2 pod pod2 --port 80 --type LoadBalancer
    
    • 1
    • 2

    (6)另打开两个控制台,创建两个测试用的pod

    #net命名空间下的testpod
    kubectl run testpod -it --rm --image nginx --image-pull-policy IfNotPresent -- bash
    #default命名空间下default-testpod
    kubectl run default-testpod -it --image nginx --image-pull-policy IfNotPresent -n default -- bash
    
    • 1
    • 2
    • 3
    • 4

    (7)此时没有网络策略时,任何数据包都是能通信的
    创建完testpod后,进入了testpod内,测试访问svc1、svc2,都是可以访问通的

    curl svc1
    #输出:
    111
    
    curl svc2
    #输出:
    222
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    相同的,default命名空间下的default-testpod也可以访问pod1、pod2

    curl svc1.net
    #输出:
    111
    
    curl svc2.net
    #输出:
    222
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    (8)创建一个限制流量入的网络策略
    先查看pod1、pod2的标签

    kubectl get pods --show-labels
    #输出:
    NAME      READY   STATUS    RESTARTS   AGE    LABELS
    pod1      1/1     Running   0          146m   run=pod1
    pod2      1/1     Running   0          146m   run=pod2
    testpod   1/1     Running   0          142m   run=testpod
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在master上创建针对pod1的流量入的策略,根据k8s文档中的yaml模板,编辑mypolicy1.yaml,如下:
    a.配置网络策略应用为pod1,标签选择器podSelector.matchLabels配置为run=pod1
    b.配置policyTypes为Ingress
    c.删除metadata下namespace的配置,表示默认在当前命名空间下
    d.spec下使用ingress及ingress下的from来配置网络策略
    e.配置只允许192.168.26.0/24网段下的网络可以访问进来
    f.配置只允许端口80的可以访问进来

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: mypolicy1
    spec:
      podSelector:
        matchLabels:
          run: pod1
      policyTypes:
        - Ingress
      ingress:
        - from:
            - ipBlock:
                cidr: 192.168.26.0/24
          #      except:
          #        - 172.17.1.0/24
          #  - namespaceSelector:
          #      matchLabels:
          #        project: myproject
          #  - podSelector:
          #      matchLabels:
          #        role: frontend
          ports:
            - protocol: TCP
              port: 80
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    创建该网络策略

    kubectl apply -f mypolicy1.yaml
    
    • 1

    (9)测试,因所有pod的网段都是10.244.x.x,我们通过pod测试访问svc1
    testpod测试访问svc1curl svc1——无法访问
    default-testpod测试访问svc1curl svc1.net——无法访问
    而访问svc2可以正常访问(因为我们只对pod1应用了网络策略),并且在master及worker节点上可以正常访问svc1
    (10)现在我们改变网络策略规则,要求在default命名空间下,且含有标签xx=xx的pod才可以访问进来,yaml中设置如下:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: mypolicy1
    spec:
      podSelector:
        matchLabels:
          run: pod1
      policyTypes:
        - Ingress
      ingress:
        - from:
          #  - ipBlock:
          #      cidr: 192.168.26.0/24
          #      except:
          #        - 172.17.1.0/24
            - namespaceSelector:
                matchLabels:
                  kubernetes.io/metadata.name: default
            - podSelector:
                matchLabels:
                  xx: xx
          ports:
            - protocol: TCP
              port: 80
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    (11)刚才两个条件是并且的关系,因为前面带“-”,表示为同级别并列的两个对象,若我们想让条件变为:在default命名空间下的pod,或含有标签xx=xx的pod可以访问进来,则将两个条件都在一个“-”下即可,yaml如下:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: mypolicy1
    spec:
      podSelector:
        matchLabels:
          run: pod1
      policyTypes:
        - Ingress
      ingress:
        - from:
          #  - ipBlock:
          #      cidr: 192.168.26.0/24
          #      except:
          #        - 172.17.1.0/24
            - namespaceSelector:
                matchLabels:
                  kubernetes.io/metadata.name: default
              podSelector:
                matchLabels:
                  xx: xx
          ports:
            - protocol: TCP
              port: 80
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    (12)现在改变需求,如下:
    假设服务有多个端口
    a.允许192.168.26.0/24网段下的主机可以访问80,但不能访问808
    b.允许所有含有xx=xx标签的pod能访问808,但不能访问80
    这种情况下,只需配置多个ingress下的from即可,yaml如下:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: mypolicy1
    spec:
      podSelector:
        matchLabels:
          run: pod1
      policyTypes:
        - Ingress
      ingress:
        - from:
            - ipBlock:
                cidr: 192.168.26.0/24
          ports:
            - protocol: TCP
              port: 80
        - from:
            - podSelector:
                matchLabels:
                  xx: xx
          ports:
            - protocol: TCP
              port: 808
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    实验:流量出的策略

    沿用上一个实验中的环境
    (1)创建一个针对pod1的限制流量出的网络策略,pod1对外访问时,只允许它访问svc2
    yaml文件为mypolicy2.yaml,yaml文件内容如下:
    a.配置网络策略应用为pod1,标签选择器podSelector.matchLabels配置为run=pod1
    b.配置policyTypes为Egress
    c.删除metadata下namespace的配置,表示默认在当前命名空间下
    d.spec下使用egress及egress下的to来配置网络策略
    e.配置只允许对外访问pod2,pod2的标签为run=pod2,配置egress.to.podSelector.matchLabels为:run=pod2
    f.配置只允许对外访问端口为80的服务进程

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: mypolicy2
    spec:
      podSelector:
        matchLabels:
          run: pod1
      policyTypes:
        - Egress
      egress:
        - to:
            - podSelector:
                matchLabels:
                  run: pod2
          ports:
            - protocol: TCP
              port: 80
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    (2)创建这个网络策略

    kubectl apply -f mypolicy2.yaml
    
    • 1

    (3)查看pod2的ip、svc2的ip

    kubectl get pods -o wide
    #输出:
    NAME      READY   STATUS    RESTARTS        AGE     IP             NODE            NOMINATED NODE   READINESS GATES
    pod1      1/1     Running   1 (2m48s ago)   5h58m   10.244.7.40    vms22.rhce.cc   <none>           <none>
    pod2      1/1     Running   1 (2m46s ago)   5h58m   10.244.70.84   vms23.rhce.cc   <none>           <none>
    testpod   1/1     Running   1 (2m48s ago)   5h54m   10.244.7.37    vms22.rhce.cc   <none>           <none>
    
    kubectl get svc
    #输出:
    NAME   TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
    svc1   LoadBalancer   10.108.53.108   192.168.26.240   80:31078/TCP   5h55m
    svc2   LoadBalancer   10.96.105.161   192.168.26.241   80:30594/TCP   5h55m
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    (4)进入pod1,测试直接访问pod2、访问svc2,都能访问成功

    kubectl exec -it pod1 -- bash
    
    curl 10.244.70.84
    #输出:
    222
    
    curl 10.96.105.161
    #输出:
    222
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    但是若通过svc2的名字访问,则会失败,这是因为没有通过coredns解析(现在只允许访问svc2,不允许去访问kube-system命名空间下的coredns做解析)
    (5)现在我们希望可以去解析
    获取kube-system命名空间的标签信息

    kubectl get ns kube-system --show-labels
    #输出:
    NAME          STATUS   AGE   LABELS
    kube-system   Active   26d   kubernetes.io/metadata.name=kube-system
    
    • 1
    • 2
    • 3
    • 4

    查看kube-system下的coredns的pod及标签信息

    kubectl get pods -n kube-system --show-labels | grep core
    #输出:
    coredns-74586cf9b6-rlkhp                   1/1     Running   15 (58m ago)   26d   k8s-app=kube-dns,pod-template-hash=74586cf9b6
    coredns-74586cf9b6-x5vld                   1/1     Running   15 (58m ago)   26d   k8s-app=kube-dns,pod-template-hash=74586cf9b6
    
    • 1
    • 2
    • 3
    • 4

    yaml文件中修改:
    增加一个to配置项,使用namespaceSelector配置允许访问kube-system命名空间下的pod,并且通过podSelector配置含有标签k8s-app=kube-dns的pod
    即允许访问kube-system命名空间下的含有标签k8s-app=kube-dns的pod

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: mypolicy2
    spec:
      podSelector:
        matchLabels:
          run: pod1
      policyTypes:
        - Egress
      egress:
        - to:
            - namespaceSelector:
                matchLabels:
                  kubernetes.io/metadata.name: kube-system
              podSelector:
                matchLabels:
                  k8s-app: kube-dns
          ports:
            - protocol: UDP
              port: 53
        - to:
            - podSelector:
                matchLabels:
                  run: pod2
          ports:
            - protocol: TCP
              port: 80
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    默认策略

    前面说过,若是没有配置网络策略的情况下,所有数据包都是能通信的,这是因为默认允许所有入站流量,相反,也可以设置默认拒绝所有入站流量,yaml如下:

    默认拒绝所有入站流量:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: default-deny-ingress
    spec:
      podSelector: {}
      policyTypes:
      - Ingress
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    默认允许所有入站流量:

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-all-ingress
    spec:
      podSelector: {}
      policyTypes:
      - Ingress
      ingress:
      - {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 相关阅读:
    关于离子色谱仪的结构和应用原理分析
    SuperMap iClient3D for WebGL教程(S3MTilesLayer)- 显示优化设置
    【提问募集】向世界级软件开发大师“Bob 大叔”Robert C. Martin 提出你的疑虑!
    Java代码审计15之Apache log4j2漏洞
    Java回顾-面向对象(抽象类与抽象方法/接口/内部类)
    Mysql高级
    JavaScript中常用数据类型,你知道几个?
    【计算机网络】数据链路层-MAC和ARP协议
    【vue项目适配可借助于插件lib-flexible 和postcss-px2rem】
    Kotlin快速运用第二阶段(匿名函数&Lambda)
  • 原文地址:https://blog.csdn.net/weixin_41755556/article/details/125969948