前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kubernetes中网络控制器之NetworkPolicy

Kubernetes中网络控制器之NetworkPolicy

作者头像
极客运维圈
发布2020-03-22 09:25:15
7340
发布2020-03-22 09:25:15
举报
文章被收录于专栏:乔边故事

在Kubernetes中,网络隔离功能是通过叫NetworkPolicy的API对象来描述的。 如下一个完整的NetworkPolicy定义:

代码语言:javascript
复制
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:  name: test-network-policy  namespace: defaultspec:  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

解释:

  • podSelector:定义这个NetworkPolicy的限制范围,上面就是定义namespace中标签为role: db的Pod,如果没空,则标识这个namespace下的所有Pod,如果一旦被podSelector选中,则这个Pod就会进入拒绝所有的状态,即这个Pod既不允许被外界访问,也不能对外界发起访问。
  • policyTypes:定义NetworkPolicy的类型,ingress表示流入请求,egress表示流出请求。
  • ingress:定义流入的规则
  • egress:定义流出的规则

其中ingress字段中的from和ports,定义允许流入的白名单和端口,这里面的白名单有三种限制方式:

  • ipBlock:限制IP,上面定义的即为允许172.17.0.0/16但不是172.17.1.0/24的网段请求;
  • namespaceSelector:限制namespace,上面定义即为允许default namespace下标签为project: myproject的的Pod请求;
  • podSelector:限制Pod,上面定义即为允许标签为role: frontend的Pod请求;

而egress字段中的to和ports,则指定允许流出的白名单和端口,这里的限制方式和ingress类似。

注意:下面这两种白名单的定义方式是不一样的。 (1)、第一种

代码语言:javascript
复制
  ...  ingress:  - from:    - namespaceSelector:        matchLabels:          user: alice    - podSelector:        matchLabels:          role: client  ...

(2)、第二种

代码语言:javascript
复制
...  ingress:  - from:    - namespaceSelector:        matchLabels:          user: alice      podSelector:        matchLabels:          role: client  ...

这两种看起来类似,但是其表示的意义是不一样的,对于第一种表示的是一种OR(或)的关系,对于这种情况只要其中一种规则满足要求都可以通过,而对于第二种则表示AND(与)的关系,必须两种同时满足才会通过。 ** Kubernetes对Pod的网络隔离其实是靠宿主机上生成NetworkPolicy对应的iptables规则来实现的。 比如定义好了上面的NetworkPolicy,那么就会生成类似下面的iptables规则:

代码语言:javascript
复制
iptables -A KUBE-NWPLCY-CHAIN -s $srcIP -d $dstIP -p $protocol -m $protocol --dport $port -j ACCEPT

其中:

  • srcIP:原IP
  • dstIP:目的IP
  • protocol:协议
  • port:端口

这些参数都是从我们定义的NetworkPolicy中取出来,然后还将对所有对被隔离Pod的访问请求都转发到KUBE-NWPLCY-CHAIN上去匹配,如果匹配不通过则拒绝。 第一组KUBE-NWPLCY-CHAIN规则如下:

代码语言:javascript
复制
iptables -A FORWARD -d $podIP -m physdev --physdev-is-bridged -j KUBE-POD-SPECIFIC-FW-CHAINiptables -A FORWARD -d $podIP -j KUBE-POD-SPECIFIC-FW-CHAIN

其中:

  • 第一条FORWARD链的作用是通过本机网桥设备发往podIP的IP包;
  • 第二条就是拦截跨主机通信,定义规则都到KUBE-POD-SPECIFIC-FW-CHAIN规则上

第二组KUBE-POD-SPECIFIC-FW-CHAIN规则如下:

代码语言:javascript
复制
iptables -A KUBE-POD-SPECIFIC-FW-CHAIN -j KUBE-NWPLCY-CHAINiptables -A KUBE-POD-SPECIFIC-FW-CHAIN -j REJECT --reject-with icmp-port-unreachable

其中:

  • 第一条是把数据包发到KUBE-NWPLCY-CHAIN去匹配;
  • 第二条就是把不满足NetworkPolicy中定义的请求都拒绝掉,从而实现对容器的隔离;

默认的Policies: (1)、默认拒绝所有Ingress:

代码语言:javascript
复制
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:  name: default-denyspec:  podSelector: {}  policyTypes:  - Ingress

(2)、默认允许所有ingress:

代码语言:javascript
复制
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:  name: allow-allspec:  podSelector: {}  ingress:  - {}  policyTypes:  - Ingress

(3)、默认拒绝所有Egress:

代码语言:javascript
复制
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:  name: default-denyspec:  podSelector: {}  policyTypes:  - Egress

(4)、默认允许所有Egress:

代码语言:javascript
复制
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:  name: allow-allspec:  podSelector: {}  egress:  - {}  policyTypes:  - Egress

(5)、拒绝所有Ingress和Egress:

代码语言:javascript
复制
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:  name: default-denyspec:  podSelector: {}  policyTypes:  - Ingress  - Egress

例子: 1、创建两个namespace

代码语言:javascript
复制
# kubectl create ns dev# kubectl create ns sit

2、给dev下的所有pod配置Ingress权限,不允许所有人访问

代码语言:javascript
复制
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata:  name: networkpolicy-ingress-demospec:  podSelector: {}  policyTypes:  - Ingress

然后使其作用于dev

代码语言:javascript
复制
# kubectl apply -f ingress-demo.yaml -n dev

我们在dev里创建一个Pod,在外部访问查看情况

代码语言:javascript
复制
apiVersion: v1kind: Podmetadata:  name: myappspec:  containers:  - name: myapp    image: nginx:1.7.9    imagePullPolicy: IfNotPresent    command:    - "/bin/sh"    - "-c"    args:    - "nginx && sleep 3600"

启动Pod

代码语言:javascript
复制
# kubectl apply -f pod-demo.yaml -n dev

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-02-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 乔边故事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档