Calico

Calico是一个开源虚拟化网络方案,用于为云原生应用实现互联及策略控制.与 Flannel 相比,Calico 的一个显著优势是对网络策略(network policy)的支持,它允许用户动态定义 ACL 规则控制进出容器的数据报文,实现为 Pod 间的通信按需施加安全策略.事实上,Calico 可以整合进大多数主流的编排系统,如 Kubernetes、Apache Mesos、Docker和 OpenStack
Calico 本身是一个三层的虚拟网络方案,它将每个节点都当作路由器,将每个节点的容器都当作是节点路由器的一个终端并为其分配一个 IP 地址,各节点路由器通过 BGP(Border Gateway Protocol)学习生成路由规则,从而将不同节点上的容器连接起来.因此,Calico 方案其实是一个纯三层的解决方案,通过每个节点协议栈的三层(网络层)确保容器之间的连通性,这摆脱了 flannel host-gw 类型的所有节点必须位于同一二层网络的限制,从而极大地扩展了网络规模和网络边界

BGP

BGP 是互联网上一个核心的去中心化自治路由协议,它通过维护IP路由表或前缀表来实现自治系统(AS)之间的可达性,属于矢量路由协议.不过,考虑到并非所有的网络都能支持 BGP,以及 Calico 控制平面的设计要求物理网络必须是二层网络,以确保 vRouter间 均直接可达,路由不能够将物理设备当作下一跳等原因,为了支持三层网络,Calico 还推出了 IP-in-IP 叠加的模型,它也使用 Overlay 的方式来传输数据.IPIP 的包头非常小,而且也是内置在内核中,因此理论上它的速度要比VxLAN快一点,但安全性更差.Calico 3.x的默认配置使用的是 IPIP 类型的传输方案而非 BGP

Calico 部署

Calico 作为网络插件使用时,工作与 192.168.0.0/16 网段,并会为每一个节点被分配一个子网

需要满足几种条件:

  1. 部署 kubelet 时必须设置定义 --network-plugin=cni
  2. kube-proxy 必须使用 iptables 模式
  3. kube-proxy 必须不能使用 --masquerade--all calico 并不支持 lvs

Calico 部署方式有很多,这里使用作为 pod 资源并通过 k8s 的 apiserver 调用 Etcd 的部署方式

Calico 策略管理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DFUd57sH-1624628065853)(https://raw.githubusercontent.com/ma823956028/image/master/picgo/20200924200040.png)]

规则分为入站和出站规则,通过 pod 选择器来让策略生效于那些 pod,还可以设置名称空间的规则

[root@master-0 ~]# kubectl explain networkPolicy.spec
KIND:     NetworkPolicy
VERSION:  networking.k8s.io/v1

RESOURCE: spec <Object>

DESCRIPTION:
     Specification of the desired behavior for this NetworkPolicy.

     NetworkPolicySpec provides the specification of a NetworkPolicy

FIELDS:
   egress <[]Object>                    # 出站规则,默认策略拒绝
     List of egress rules to be applied to the selected pods. Outgoing traffic
     is allowed if there are no NetworkPolicies selecting the pod (and cluster
     policy otherwise allows the traffic), OR if the traffic matches at least
     one egress rule across all of the NetworkPolicy objects whose podSelector
     matches the pod. If this field is empty then this NetworkPolicy limits all
     outgoing traffic (and serves solely to ensure that the pods it selects are
     isolated by default). This field is beta-level in 1.8

   ingress <[]Object>                   # 入站规则,默认策略拒绝
     List of ingress rules to be applied to the selected pods. Traffic is
     allowed to a pod if there are no NetworkPolicies selecting the pod (and
     cluster policy otherwise allows the traffic), OR if the traffic source is
     the pod's local node, OR if the traffic matches at least one ingress rule
     across all of the NetworkPolicy objects whose podSelector matches the pod.
     If this field is empty then this NetworkPolicy does not allow any traffic
     (and serves solely to ensure that the pods it selects are isolated by
     default)

   podSelector <Object> -required-      # 标签选择器
     Selects the pods to which this NetworkPolicy object applies. The array of
     ingress rules is applied to any pods selected by this field. Multiple
     network policies can select the same set of pods. In this case, the ingress
     rules for each are combined additively. This field is NOT optional and
     follows standard label selector semantics. An empty podSelector matches all
     pods in this namespace.

   policyTypes <[]string>               # 选择生效的策略或两者都生效,没有定义的策略则生效其默认策略
     List of rule types that the NetworkPolicy relates to. Valid options are
     "Ingress", "Egress", or "Ingress,Egress". If this field is not specified,
     it will default based on the existence of Ingress or Egress rules; policies
     that contain an Egress section are assumed to affect Egress, and all
     policies (whether or not they contain an Ingress section) are assumed to
     affect Ingress. If you want to write an egress-only policy, you must
     explicitly specify policyTypes [ "Egress" ]. Likewise, if you want to write
     a policy that specifies that no egress is allowed, you must specify a
     policyTypes value that include "Egress" (since such a policy would not
     include an Egress section and would otherwise default to just [ "Ingress"
     ]). This field is beta-level in 1.8

Ingress

  1. 在 ns dev 中 Ingress 拒绝所有请求

    [root@master-0 ~]# cat ingress-def.yaml
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: deny-all-ingress
    spec:
      podSelector: {}               # 选择 ns 中所有 pod
      policyTypes:
      - Ingress                     # 没有定义 Ingress 则生效默认策略
    networkpolicy.networking.k8s.io/deny-all-ingress created
    [root@master-0 ~]# kubectl get netpol -ndev
    NAME               POD-SELECTOR   AGE
    deny-all-ingress   <none>         8m41s
    [root@master-0 ~]# cat pod-A.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: pod1
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
    [root@master-0 ~]# kubectl apply -f pod-A.yaml -ndev
    pod/pod1 created
    [root@master-0 ~]# kubectl get po -ndev -owide
    NAME   READY   STATUS    RESTARTS   AGE   IP           NODE             NOMINATED NODE   READINESS GATES
    pod1   1/1     Running   0          92s   10.244.2.4   slave-0.shared   <none>           <none>
    [root@master-0 ~]# curl 10.244.2.4
    ^C
    [root@master-0 ~]# kubectl apply -f pod-A.yaml -n prod
    pod/pod1 unchanged
    [root@master-0 ~]# kubectl get po -n prod -owide
    NAME   READY   STATUS    RESTARTS   AGE   IP           NODE             NOMINATED NODE   READINESS GATES
    pod1   1/1     Running   0          70s   10.244.1.3   slave-1.shared   <none>           <none>
    [root@master-0 ~]# curl 10.244.1.3
    Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
    
  2. 在 ns dev 中 Ingress 允许所有请求

    [root@master-0 ~]# cat ingress-def.yaml
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: deny-all-ingress
    spec:
      podSelector: {}
      ingress:
      - {}                      # 允许所有 Pod 之间 Ingress 通信
      policyTypes:
      - Ingress
    [root@master-0 ~]# kubectl apply -f ingress-def.yaml -n dev
    networkpolicy.networking.k8s.io/deny-all-ingress configured
    [root@master-0 ~]# kubectl get pods -n dev -owide
    NAME   READY   STATUS    RESTARTS   AGE   IP           NODE             NOMINATED NODE   READINESS GATES
    pod1   1/1     Running   0          11m   10.244.2.4   slave-0.shared   <none>           <none>
    [root@master-0 ~]# curl 10.244.2.4
    Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
    
  3. 设置 10.211.55.0 网段中除了 10.211.55.1/32 以外所有的 ip 均能访问拥有标签为 myapp 的 pod 的 TCP 协议 80 端口

    [root@master-0 ~]# cat allow-netpol.yaml
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-myapp-ingress
    spec:
      podSelector:
        matchLabels:
          app: myapp
      ingress:
      - from:                     # ingress 的白名单,可以更为细节的区分哪些 Pod 之间可以 Ingress 通信
        - ipBlock:
            cidr: 10.211.55.0/16
            except:
            - 10.211.55.1/32
        ports:
        - protocol: TCP           # 与 port 为一组
          port: 80
    

Engress

其写法与 Ingress 一致

  1. 在 ns dev 中 Egress 拒绝所有请求

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: deny-all-egress
    spec:
      podSelector: {}
      policyTypes:
      - Egress
    
  2. 在 ns dev 中 Egress 允许所有请求

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: deny-all-egress
    spec:
      podSelector: {}
      egress:
      - {}
      policyTypes:
      - Egress
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值