【kubernetes/k8s概念】kube-ovn-controller 源码分析之二

    kube-ovn-controller 逻辑职责是翻译 kubernetes 网络概念到 OVN,可以理解为 kube-ovn 的控制面功能,通过 kube-apiserver watch 所有网络相关事件,包括 Pod creation/deletion, Service/Endpoint modification, Networkpolicy changes 等等。然后翻译转为 OVN 逻辑网络的修改。也 watch kube-ovn 添加的 CRD,比如 VPC Subnet Vlan IP 等

    本文分析 network 策略,service,endpoint 三个控制器的源码实现

 1. network pllicy 网络策略处理

    包括 runUpdateNpWorker 和 runDeleteNpWorker 两种处理

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.1 handleUpdateNp

    ovnClient.DeletePortGroup 调用命令 ovn-nbctl get port_group node.node1 _uuid 查询是否存在,存在则调用 ovn-nbctl pg-del ${name},删除存在的 port group 来更新 acl 规则,acl 用来设置访问控制列表,并且只能应用在逻辑交换机或者port group上,不能应用在逻辑路由器上。 参数包括优先级,方向,匹配域和动作。注意: 只在 acl table 添加规则是没用的,还需要将其应用到逻辑交换机或者 port group。

    ovnClient.CreatePortGroup 调用命令 ovn-nbctl --data=bare --no-heading --columns=_uuid find port_group name=allow.all.ingress.default 查询,调用命令 ovn-nbctl pg-add ${name} -- set port_group ${name} external_ids:np=${namespace}/${networkpolicy_name} 创建 port_group

    fetchSelectedPorts 根据设置的 podSelector 选择器选择所有标签匹配的 pod 列表

    SetPortsToPortGroup 调用命令 ovn-nbctl clear port_group ${name} ports pg-set-ports ${name} ${port列表}

_uuid               : dca911e3-23bd-4d18-93b2-38f3be02beab
acls                : [2ef5eeb0-0298-4d73-9ec5-89f53fed3019, 45af5469-7e51-4163-8c5a-120f5b9c21f3, 784e4419-a112-4fa9-96bd-4f2ffc8a7655, 83cc0b42-27a5-4274-959d-452757c6869a, 88a129e6-8a45-4577-a394-3b1c6bc1a9e8, 8bee9705-304b-4b4b-aec8-022cb99456be]
external_ids        : {np="default/test-network-policy"}
name                : test.network.policy.default
ports               : []

    1.1.1 如果存在 ingress 规则

    a. 先处理 ipBlock 这模块,如果 ingress 的 from 未设置则允许设置 0.0.0.0/0,包含 from 则取出允许和拒绝的网段

    ovnClient.CreateAddressSet 调用命令 ovn-nbctl --data=bare --no-heading --columns=_uuid find address_set name=allow.all.ingress.default.ingress.allow.IPv4.0 查询。调用命令创建 ovn-nbctl create address_set name=${name} external_ids:np=${namespace}/${networkpolicy名字}/方向

_uuid               : d32700a9-49c8-43e2-819f-fde4f13ad632
addresses           : ["172.17.0.0/16"]
external_ids        : {np="default/test-network-policy/ingress"}
name                : test.network.policy.default.ingress.allow.IPv4.0

   同样,设置拒绝的的 address_set

   b. 如果设置了 from 中的允许和拒绝的内容,则调用 ovnClient.CreateIngressACL 使用命令 acl-add 添加 acl 规则

_uuid               : 88a129e6-8a45-4577-a394-3b1c6bc1a9e8
action              : drop
direction           : from-lport
external_ids        : {}
log                 : true
match               : "ip4.src == $test.network.policy.default_ip4"
meter               : []
name                : "default/test-network-policy"
priority            : 2000
severity            : warning

    c. 如果未设置 ingress,创建 address_set 和 ingress acl 规则

_uuid               : 12a2caa5-00f0-447f-87af-690f845e6d77
addresses           : []
external_ids        : {np="default/allow-all-ingress/ingress"}
name                : allow.all.ingress.default.ingress.allow.IPv4.all

_uuid               : d853e287-dd01-4fc2-b4dd-edc6fb0a58bf
action              : drop
direction           : to-lport
external_ids        : {}
log                 : true
match               : "ip4.dst == $allow.all.ingress.default_ip4"
meter               : []
name                : "default/allow-all-ingress"
priority            : 2000
severity            : warning

    d. 如果未设置 ingress 内容,则删除所有相关的 acl 方向出口,以及所有其相关的 address_set

    1.1.2 如果存在 egress 规则

    这里就不详解了,跟 ingress 处理类似

    1.1.3 创建网关 ACL 规则

    创建 subnet 网关的 ACL 规则,包括 ingress 和 egress 两个方向

_uuid               : 3808acb1-b9b1-43f6-ac1a-4f4240879e82
action              : allow-related
direction           : from-lport
external_ids        : {}
log                 : false
match               : "ip4.dst == 10.16.0.1"
meter               : []
name                : []
priority            : 2001
severity            : []

_uuid               : d48d27e3-fdb8-439c-99d9-e29c75fae8f0
action              : allow-related
direction           : to-lport
external_ids        : {}
log                 : false
match               : "ip4.src == 10.16.0.1"
meter               : []
name                : []
priority            : 2001
severity            : []

2. Service 处理

   包括 runUpdateServiceWorker 和 runDeleteServiceWorker

   2.1 runUpdateServiceWorker 

    这边不处理 Spec.ClusterIP 为空或者 service 类型为 None 的,service 的注解如果未设置 ovn.kubernetes.io/vpc 则使用默认 vpc,如果 SessionAffinity 设置未 ClientIP,会话保持,则使用会话的负载均衡

tcpLb, udpLb := vpc.Status.TcpLoadBalancer, vpc.Status.UdpLoadBalancer
oTcpLb, oUdpLb := vpc.Status.TcpSessionLoadBalancer, vpc.Status.UdpSessionLoadBalancer
if svc.Spec.SessionAffinity == v1.ServiceAffinityClientIP {
	tcpLb, udpLb = vpc.Status.TcpSessionLoadBalancer, vpc.Status.UdpSessionLoadBalancer
	oTcpLb, oUdpLb = vpc.Status.TcpLoadBalancer, vpc.Status.UdpLoadBalancer
}

status:
  default: false
  defaultLogicalSwitch: net1
  router: test-vpc-1
  standby: true
  subnets:
  - net1
  tcpLoadBalancer: vpc-test-vpc-1-tcp-load
  tcpSessionLoadBalancer: vpc-test-vpc-1-tcp-sess-load
  udpLoadBalancer: vpc-test-vpc-1-udp-load
  udpSessionLoadBalancer: vpc-test-vpc-1-udp-sess-load

    ovnClient.FindLoadbalancer 调用命令 ovn-nbctl --data=bare --no-heading --columns=_uuid find load_balancer name=vpc-test-vpc-1-tcp-load 查出该 vpc 的 tcp 负载均衡的 uuid,ovnClient.GetLoadBalancerVips 调用命令 ovn-nbctl --data=bare --no-heading get load_balancer vpc-test-vpc-1-tcp-load vips 获得该下的 vip

_uuid               : 18fb75e2-d609-402c-8966-e0b9b7035ba5
external_ids        : {}
health_check        : []
ip_port_mappings    : {}
name                : vpc-test-vpc-1-tcp-load
options             : {}
protocol            : tcp
selection_fields    : []
vips                : {"10.233.14.99:80"="10.0.1.2:80,10.0.1.3:80"} 

     新添加的 vip 不再已存在中,则 updateEndpointQueue.Add,向 Endpoint 队列添加,根据 service 标签选择器过滤出所有 pod,

3. Endpoint 处理

    这里也是不处理,clusterIP 未空或者 service 类型为 none, 遍历所有 pod,如果 pod 注解为空也不处理,根据 endpoint 中的 subnet 结合 pod 的注解 找出 vpc

subsets:
- addresses:
  - ip: 10.0.1.2
    nodeName: node1
    targetRef:
      kind: Pod
      name: nginx-57dd86f5cc-mgwj5
      namespace: ns1
      resourceVersion: "368323"
      uid: 2283bc51-667b-4f0d-bedf-aa458c5e8245
  - ip: 10.0.1.3
    nodeName: node1
    targetRef:
      kind: Pod
      name: nginx-57dd86f5cc-s7tk9
      namespace: ns1
      resourceVersion: "368317"
      uid: 6cfc9daf-4637-40a9-85f7-3abdb836169a
  ports:
  - port: 80
    protocol: TCP

    则根据 service 的注解 ovn.kubernetes.io/vpc: test-vpc-1,否则设置默认 vpc,ovn-cluster

    根据 service 的 ports 字段内容进行处理,遍历所有 service 的 ports,getServicePortBackends 获取后端,调用 ovnClient.CreateLoadBalancerRule 调用命令 ovn-nbctl lb-add ${lb} ${vip} ${ips} ${protocol}

总结:

  service 中 clientIP 对应北向数据库中的表 load_balancer

  endpoint 对应北向数据库中的表 load_balancer 的 vip

  networkpolicy 对应北向数据库中的表 ACL,涉及 port_group

  

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值