k8s-基于Canal来定义网络策略

安装要求:

  • https://docs.projectcalico.org/getting-started/kubernetes/flannel/flannel
    

1、 使用Kubernetes API数据存储进行安装(推荐)

2、CNI插件需要启用,Calico安装为CNI插件。必须通过传递--network-plugin=cni参数将kubelet配置为使用CNI网络。(在kubeadm上,这是默认设置。)

3、支持kube-proxy的模式

  • - iptables
    - ipvs需要1.9以上的
    

4 如果您使用的是pod CIDR 10.244.0.0/16 可以直接apply 如果您使用其他Pod CIDR,请确保在清单中取消对CALICO_IPV4POOL_CIDR变量的注释,并将其设置为与所选Pod CIDR相同的值。

安装Clico用于策略和Flannel用于网络

我们这里使用Kubernetes的etcd进行安装,首先确保Kubernetes设置--cluster-cidr=10.244.0.0/16--allocate-node-cidrs=true。(kubeadm是默认安装的)

安装Calico

kubectl apply -f https://docs.projectcalico.org/manifests/canal.yaml

kubernetes中的网络控制策略

NetworkPolicy是kubernetes对pod的隔离手段,可以看到,NetworkPolicy实际上只是宿主机上的一系列iptables规则。

img

  • Egress 表示出站流量,就是pod作为客户端访问外部服务,pod地址作为源地址。策略可以定义目标地址或者目的端口
  • Ingress 表示入站流量,pod地址和服务作为服务端,提供外部访问。pod地址作为目标地址。策略可以定义源地址和自己端口
  • podSelector 规则生效在那个pod上,可以配置单个pod或者一组pod。可以定义单方向。空 podSelector选择命名空间中的Pod。

kubectl explain networkpolicy.spec讲解:

  • egress 出站流量规则 可以根据ports和to去定义规则。ports下可以指定目标端口和协议。to(目标地址):目标地址分为ip地址段、pod、namespace
  • ingress 入站流量规则 可以根据ports和from。ports下可以指定目标端口和协议。from(来自那个地址可以进来):地址分为ip地址段、pod、namespace
  • podSelector 定义NetworkPolicy的限制范围。直白的说就是规则应用到那个pod上。podSelector: {},留空就是定义对当前namespace下的所有pod生效。没有定义白名单的话 默认就是Deny ALL (拒绝所有)
  • policyTypes 指定那个规则 那个规则生效,不指定就是默认规则。

在dev的namespace下定义一个入站流量拒绝的规则:

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

$ kubectl apply -f network-policy.yaml  -n dev

在dev和prod的namespace下个各自创建一个pod

apiVersion: v1
kind: Pod
metadata:
  name: pod-1
  labels:
    name: myapp
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
$  kubectl apply -f policy-pod.yaml  -n dev

$  kubectl apply -f policy-pod.yaml  -n prod# 测试一下

$ kubectl get pod -o wide   -n prod NAME      READY     STATUS    RESTARTS   AGE       IP           NODEpod-1     1/1       Running   0          3h        10.244.2.7   k8s-node02$

kubectl get pod -owide   -n dev NAME      READY     STATUS    RESTARTS   AGE       IP           NODEpod-1     1/1       Running   0          3h        10.244.2.8   k8s-node02$ curl 10.244.2.8
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>$ 10.244.2.8 不通

放行dev名称空间所有入站流量

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

$ kubectl apply -f  network-policy.yaml  -n dev 

测试
$ curl 10.244.2.2                              
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

放行特定的入站访问流量

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-myapp-policy
spec:
  podSelector: 
    matchLabels:
      app: myapp   #选择app=myapp 的标签放行
  ingress:
  - from:
    - ipBlock:   #地址段
        cidr: 10.244.0.0/16  允许这个地址段访问
        except:    排除一下地址不可以访问
        - 10.244.1.2/32
    ports:
    - port: 80   只运行访问80端口
      protocol: TCP
$ kubectl apply -f alloy-pod.yaml -n dev 

测试一下

$ curl 10.244.2.8
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>

下面写一个完整的NetworkPolicy对象:

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

大概意思:

  • 该规则只在default 的namespace下,携带role:db标签的pod生效。限制请求的类型包括Ingress和Egress。
  • Kubernetes会拒绝任何访问被隔离pod的请求,除非这个请求来自以下“白名单”里的对象。并且访问的是被隔离pod的6379端口。
  • default Namespace里的,携带了role=fronted标签的pod可以访问
  • 任何Namespace里的,携带了project=myproject标签的pod可以访问
  • 任何源地址数据172.17.0.0/16网段,且不属于172.17.1.0/24网段的请求
  • Kubernetes会拒绝被隔离pod对外发起任何请求,除非请求的目的地址属于10.0.0.0/24网段,并且访问的是该网段地址的5978端口。
posted @ 2021-01-19 19:12  爱可耐  阅读(485)  评论(0编辑  收藏  举报