【Linux39-6】k8s部署网络插件Calico、选择器to from、创建网络策略(入站与出站策略)

1. Calico


1.1 简介


Calico 是一个安全的 L3 网络和网络策略驱动。

部署calico官方详解

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

在这里插入图片描述

1.2 网络架构


Felix:监听ECTD中心的存储获取事件,用户创建pod后, Felix负责将其网卡、IP、 MAC都设置好,然后在内核的路由表里面写一条,注明这个IP应该到这张网卡。同样如果用户制定了隔离策略,Felix同样 会将该策略创建到ACL中,以实现隔离。

BIRD:一个标准的路由程序,它会从内核里面获取哪-些IP的路由发生了 变化,然后通过标准BGP的路由协议扩散到整个其他的宿主机上,让外界都知道这个IP在这里,路由的时候到这里来。

在这里插入图片描述

2. 部署网络插件Calico


2.1 准备


之前安装过Flannel插件,需要清理相关信息:

master端:

kubectl delete -f kube-flannel.yml

所有节点执行:

mv /etc/cni/net.d/10-flannel.conflist /mnt/

2.2 安装


1.建立目录

mkdir calico
cd calico/

2.下载yaml文件:

官网:wget https://docs.projectcalico.org/manifests/calico.yaml

这里使用自己定义的部署文件,还是在官网基础上修改的
#v3.16.1版本
需要修改一下内容及镜像版本
            - name: CALICO_IPV4POOL_IPIP
              value: "off"

3.部署

kubectl apply -f calico.yaml 

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

3. 网络策略 NetworkPolicy


如果你希望在 IP 地址或端口层面(OSI 第 3 层或第 4 层)控制网络流量, 则你可以考虑为集群中特定应用使用 Kubernetes 网络策略(NetworkPolicy)。NetworkPolicy 是一种以应用为中心的结构,允许你设置如何允许 Pod 与网络上的各类网络“实体” (我们这里使用实体以避免过度使用诸如“端点”和“服务”这类常用术语, 这些术语在 Kubernetes 中有特定含义)通信。

Pod 可以通信的 Pod 是通过如下三个标识符的组合来辩识的:

  • 其他被允许的 Pods(例外:Pod 无法阻塞对自身的访问)
  • 被允许的命名空间
  • IP 组块

3.1 隔离和非隔离的 Pod


默认情况下,Pod 是非隔离的,它们接受任何来源的流量。

Pod 在被某 NetworkPolicy 选中时进入被隔离状态。 一旦名字空间中有 NetworkPolicy 选择了特定的 Pod,该 Pod 会拒绝该 NetworkPolicy 所不允许的连接。 (名字空间下其他未被 NetworkPolicy 所选择的 Pod 会继续接受所有的流量)

网络策略不会冲突,它们是累积的。 如果任何一个或多个策略选择了一个 Pod, 则该 Pod 受限于这些策略的 入站(Ingress)/出站(Egress)规则的并集。因此评估的顺序并不会影响策略的结果。

为了允许两个 Pods 之间的网络数据流,源端 Pod 上的出站(Egress)规则和 目标端 Pod 上的入站(Ingress)规则都需要允许该流量。 如果源端的出站(Egress)规则或目标端的入站(Ingress)规则拒绝该流量, 则流量将被拒绝

3.2 选择器 to 和 from

可以在 ingress 的 from 部分或 egress 的 to 部分中指定四种选择器:

podSelector: 此选择器将在与 NetworkPolicy 相同的名字空间中选择特定的 Pod,应将其允许作为入站流量来源或出站流量目的地。

namespaceSelector:此选择器将选择特定的名字空间,应将所有 Pod 用作其 入站流量来源或出站流量目的地。

namespaceSelector 和 podSelector: 一个指定 namespaceSelector 和 podSelector 的 to/from 条目选择特定名字空间中的特定 Pod。

3.3 字段详解


必需字段:与所有其他的 Kubernetes 配置一样,NetworkPolicy 需要 apiVersionkindmetadata 字段

spec:NetworkPolicy 规约 中包含了在一个名字空间中定义特定网络策略所需的所有信息。

podSelector:每个 NetworkPolicy 都包括一个 podSelector,它对该策略所 适用的一组 Pod 进行选择。示例中的策略选择带有 “role=db” 标签的 Pod。 空的 podSelector 选择名字空间下的所有 Pod。

policyTypes: 每个 NetworkPolicy 都包含一个 policyTypes 列表,其中包含 IngressEgress 或两者兼具。policyTypes 字段表示给定的策略是应用于 进入所选 Pod 的入站流量还是来自所选 Pod 的出站流量,或两者兼有。 如果 NetworkPolicy 未指定 policyTypes 则默认情况下始终设置 Ingress; 如果 NetworkPolicy 有任何出口规则的话则设置 Egress

ingress: 每个 NetworkPolicy 可包含一个 ingress 规则的白名单列表。 每个规则都允许同时匹配 fromports 部分的流量。示例策略中包含一条 简单的规则: 它匹配某个特定端口,来自三个来源中的一个,第一个通过 ipBlock 指定,第二个通过 namespaceSelector 指定,第三个通过 podSelector 指定。

egress: 每个 NetworkPolicy 可包含一个 egress 规则的白名单列表。 每个规则都允许匹配 toport 部分的流量。该示例策略包含一条规则, 该规则将指定端口上的流量匹配到 10.0.0.0/24 中的任何目的地。

4. 创建网络策略


准备svc

创建带有标签:app=nginx 的服务nginx-svc

kubectl apply -f /root/ingress/nginx-svc.yml

# /root/ingress/nginx-svc.yml
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: myapp
        image: myapp:v2

测试可以访问:

在这里插入图片描述

4.1 拒绝访问指定服务


设置带app=nginx标签的不能访问:

# deny-nginx.yml 
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-nginx
spec:
  podSelector:
    matchLabels:
      app: nginx

创建:kubectl apply -f deny-nginx.yml

在这里插入图片描述

测试:curl访问失败

在这里插入图片描述

4.2 允许指定pod访问服务


允许标签 app: demo 访问带标签 app:nginx的服务:

# acces-demo.yml 
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: access-nginx
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - from:
      - podSelector:
          matchLabels:
            app: demo

未创建策略前pod访问app:nginx的服务被拒绝:
在这里插入图片描述

创建策略:kubectl apply -f acces-demo.yml

在这里插入图片描述

添加标签 app:demo

在这里插入图片描述

测试:成功访问

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

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


1.创建命名空间demo:
kubectl create namespace demo
2.创建两个pod并交互式(命名空间为demo)
kubectl run demo1 --image=radial/busyboxplus -it -n demo 
kubectl run demo2 --image=radial/busyboxplus -it -n demo

在这里插入图片描述

命名空间demo中的pod可以相互访问:

在这里插入图片描述

创建策略:kubectl apply -f deny-pod.yml

# deny-pod.yml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: demo
spec:
  podSelector: {
    
    }

在这里插入图片描述

创建策略成功后:命名空间demo中的pod不能相互访问

在这里插入图片描述

4.4 禁止其他 namespace 访问服务


创建pod:可以访问

kubectl run nginx --image=myapp:v2
在这里插入图片描述
在这里插入图片描述

创建策略:kubectl apply -f deny-ns.yml

# deny-ns.yml 
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: deny-namespace
spec:
  podSelector:
    matchLabels:
  ingress:
  - from:
    - podSelector: {
    
    }

测试:访问失败

在这里插入图片描述

4.5 允许指定namespace访问服务


  • 允许 role=prod并且ns 为 test的 pod 可以访问 run=nginx

1.创建namespace为test
kubectl create namespace test
2.为test添加标签role:prod
kubectl label ns test role=prod
3.创建test下的pod并交互式
kubectl run test1 --image=radial/busyboxplus -it -n test 
4.测试发现不能访问(在4.1中设置带app=nginx标签的不能访问)
curl 10.244.22.3

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

创建策略:kubectl apply -f acces-ns.yml

# acces-ns.yml 
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: access-namespace
spec:
  podSelector:
    matchLabels:
      run: nginx
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          role: prod

测试:成功访问
在这里插入图片描述

4.6 允许外网访问服务


  • 带标签 app=nginx 的pod可以从外网访问到

创建ingress:

kubectl apply -f /root/ingress/nginx.yml

# /root/ingress/nginx.yml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-demo
spec:
  rules:
  - host: www1.westos.org
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx-svc
          servicePort: 80

外网测试访问失败(提前解析www1.westos.org)

curl www1.westos.org

创建策略:

kubectl apply -f acces-ex.yml

# acces-ex.yml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
  name: web-allow-external
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - ports:
    - port: 80
    from: []

外网可以成功访问:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_46069582/article/details/114040660
今日推荐