• Tungsten Fabric SDN — 与 Kubernetes 的资源映射


    目录

    Kubernetes to Contrail Object Mapping

    contrail-kube-manager 会 Watch 这些 K8s resource 的变更,并转发到 TF API 请求。

    在这里插入图片描述

    K8s Namespace mapping to TF Shared or single project(multi-tenancy,多租户增强)

    K8s Namespace 可以映射到 TF Shared Project 或 TF Single Project。

    1. K8s Namespace mapping to TF Shared Project(TF Single Tenant,单租户集成模式):TF 对应 K8s Cluster 只有一个 Tenant。K8s Namespace 映射为 TF VN。

    2. K8s Namespace mapping to TF Single Project(TF Multi Tenant,多租户集成模式):TF 对应 K8s Cluster 有多个 Tenants。K8s Namespace 映射为 TF Project。

    K8s Namespace mapping to TF Shared Project

    可以通过修改 kube-manager 的配置文件 /etc/contrail/contrail-kubernetes.conf 中的配置项 [KUBERNETES].cluster_project 来指定实施 “单租户集成模式”。例如:

    [KUBERNETES]
    cluster_project = {'domain': 'default-domain', 'project': 'kubernetes'}
    ...
    
    • 1
    • 2
    • 3

    单租户集成模式中,所有的 non-Isolated network 都会共享默认的 cluster-network VN VRF;所有的 Isolated network 都具有独立的 VN VRF。

    K8s Namespace mapping to TF Single Project

    默认的,contrail-ansible-deployer 会实施 “多租户集成模式”。初始状态下,存在 5 个 TF Projects 对应 5 个 K8s Namespaces。之后再新建一个 K8s Namespace 就会同时创建一个 TF Project。

    每个对应 K8s Namespace 的 TF Project 下都包含了 2 个 VNs:k8s-{vn_name}-service-network 和 k8s-{vn_name}-pod-network,并且绑定了相应的 IPAM 和 Network Policies。分别用于 Pod 和 Service 资源。

    默认情况下,除了 k8s-{vn_name}-pod-network 之外,其他的 VN 是无法连接到 k8s-{vn_name}-service-network 的,这由 TF Network Policy 来进行控制。

    k8s-default Project 存放了大量可以被 Shared 的资源,例如:IPAM、Network Policy、Security group 等等。

    • 3 个 TF IPAM:k8s-pod-ipam、k8s-service-ipam 和 k8s-ip-fabric-ipam,分别作为 K8s Pods、Services、Underlay(IP Fabric)的 Subnet IP Pool。
    • 3 条 Network Policies:k8s-default-service-np、k8s-default-ip-fabric-np 和 k8s-default-pod-service-np。
      • k8s-default-service-np 允许指定的 VN 可以访问 K8s service VN。
      • k8s-default-pod-service-np 允许指定的 Pod VN 可以访问 K8s service VN。
      • k8s-default-ip-fabric-np 允许指定的 VN 可以访问 K8s underlay(IP Fabric)VN。
    • 1 条 Security Group:允许 Pod VIF 的所有 Ingress/Egress 流量。

    K8s Pod mapping to TF VRF Virtual Interface IP(network isolation,网络隔离增强)

    创建一个 K8s Pod 就会在相应的 TF VN 中创建一个 VIF,并挂载到 Pod 所处的 Linux Network Namespace。

    Kubernetes 的基本网络模型是一个扁平的网络(Flat networking),通过 K8s Network policy 来提供 Pod-to-Pod 的安全访问控制。但 K8s Flat networking 并没有实现真正的多租户隔离,这意味着任何 Namespace 中的 Pod 都可以与任何 Other Namespace 中的 Pods 进行通信。换句话说,如果 Target Pod 的 Domain Name 或 IP address 已知,则无法阻止从一个 Namespace 中的 Pod 到 Other Namespace 中的 Pods 的通信。

    可见,Kubernetes 的基本网络模型并不适用于对安全隔离性要求高的场景。针对这一需求,TF 除了为 K8s 提供 CNI 标准强制要求的 Flat Networking(Non-Isolated 网络模型)之外,还为 K8s 提供了 Network isolation 网络增强功能。

    Default Mode(Non-Isolated Namespaces)

    为了保持 K8s 基本的 Flat Networking(扁平网络)模型,TF 默认提供了 Non-Isolated Namespaces(非隔离命名空间)模式。

    TF 为 K8s Cluster 预配置了 2 个 Default VN(虚拟网络):k8s-default-pod-network 和 k8s-default-service-network。它们分别为所有 Non-Isolated Namespaces 中的 Pods 或 Services 提供网络。使得所有的 Non-Isolated Namespaces 中的 Pods 或 Services 处于一个扁平的网络中的(包括 Default Namespace),可以跨越不同的 Namespace 互联互通。

    从 TF 的角度看,这些 Non-Isolated Namespaces 对应的 Projects 共享了 2 个 Public VRF:

    • k8s-default-pod-network: the pod virtual network/VRF table, with the default subnet 10.32.0.0/12
    • k8s-default-service-network: the service virtual network /VRF table, with a default subnet 10.96.0.0/12

    也就是说,当你新建一个(默认)Non-Isolated Namespace 时,TF 会自动为该 Project 授权这 2 个 Default VN/VRF。

    NOTE:无论是 Non-Isolated Namespace 还是 Isolated Namespace 中,每个 TF virtual network 都具有独立的 VRF,所以两个不同的 virtual network 需要互通时,依旧需要配置相应的 Network Policy。例如:k8s-default-pod-network 和 k8s-default-service-network 之间就是通过 Network Policy 来实现互通的。

    NOTE:kube-system namespace 是一个特殊的 underlay 网络,不在 K8s Cluster 范围内,也就是说不属于 TF 管理。

    Isolation Mode(Isolated Namespaces)

    Isolated Namespace 拥有独立隔离的 Pod 和 Service VN/VRF。也就是说:

    1. Isolated Namespace 中的 Pod 只能与同一个 Namespace 中的其他 Pods 互通,无法访问 other Namespaces 中的 Pods,但可以访问 non-Isolated Namespaces 中的 Services。创建一个 Isolated Namespace 如下。
    apiVersion: v1
    kind: Namespace 
    metadata:
      annotations: 
        "opencontrail.org/isolation" : "true"  # The value of true indicates this is an isolated namespace.
      name: ns-isolated
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. Isolated Namespace 中的 Service(k8s service-ip)只能与同一个 Namespace 中的其他 Pods 互通,other Namespace 中的 Pods 无法访问 Isolated Namespace 中的 Service。根据需求,如果 Isolated Namespace 中的 Service 需要被 other Namespace 中的 Pods 访问到,则可以配置 disabling service isolation。此时 other Namespace 的 Pods 可以范围该 Service,同时 Isolated Namespace 中的 Pods 依旧是隔离的。
    apiVersion: v1
    kind: Namespace 
    metadata:
      annotations: 
        "opencontrail.org/isolation" : "true"  # The value of true indicates this is an isolated namespace.
        "opencontrail.org/isolation.service": "false"
      name: ns-isolated
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    从 YAML 可以看出,contrail-kube-manager 对 K8s resources 进行了扩展。新建一个 Namespace 时,contrail-kube-manager 会 Watch K8s API Server 并读取到 opencontrail.org/isolation 注释,然后根据 Namespace 的隔离类型来进行相应的处理。当 isolation 为 true,TF 就会使用相应的 VRF 来创建该 Namespace 映射的 Project。

    举例说明:假设现在具有 3 个 Namespace: default、ns-non-isolated、ns-isolated,并在每个 Namespace 中创建了 VN vn-left-1。那么你将会看见以下 VNs/VRFs,它们的隔离关系如图所示。

    • default-domain:k8s-default:k8s-default-pod-network

    • default-domain:k8s-default:k8s-default-service-network

    • default-domain:k8s-default:k8s-vn-left-1-pod-network

    • default-domain:k8s-ns-non-isolated:k8s-vn-left-1-pod-network

    • default-domain:k8s-ns-isolated:k8s-ns-isolated-pod-network

    • default-domain:k8s-ns-isolated:k8s-ns-isolated-service-network

    • default-domain:k8s-ns-isolated:k8s-vn-left-1-pod-network

    NOTE:Isolated Namespaces Mode 下,如果两个 Namespaces 需要互通时,则可以对 Namespace 下属的 VN 配置相应的 Network Policy。

    在这里插入图片描述

    Custom Isolation Mode

    该模式中,用户可以通过修改 Application YAML annotations 来自定义自己的 Namespace 中所使用的 Virtual Network。例如:

    annotations: {
        "opencontrail.org/network" : '{"domain":"default-domain", "project": "k8s-default", "name":"k8s-blue-net-pod-network"}'
    }
    
    • 1
    • 2
    • 3
    1. 如果该 annotations 配置 Pod YAML 上,则指定 Pod 启动在指定 Namespace 的 Virtual network 上。
    2. 如果该 annotations 配置 Namespace YAML 上,则该 Namespace 中的所有 Pods 都启动在 Virtual network 上。

    操作示例:验证路由隔离是否有效

    1. 新建 non-Isolated Namespace
    $ cat ns-non-isolated.yaml
    
    apiVersion: v1
    kind: Namespace
    metadata:
      name: ns-non-isolated
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    1. 新建 Isolated Namespace
    $ cat ns-isolated.yaml
    
    apiVersion: v1
    kind: Namespace
    metadata:
      annotations:
        "opencontrail.org/isolation": "true"
      name: ns-isolated
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 创建 Pods
    $ kubectl apply -f pod-busybox.yaml -n default
    $ kubectl apply -f pod-busybox.yaml -n ns-non-isolated
    $ kubectl apply -f pod-busybox.yaml -n ns-isolated
    
    $ kubectl get pods -A -o wide | grep busybox
    default           busybox                                 1/1     Running   0          39s     10.47.255.248   worker02
    ns-isolated       busybox                                 1/1     Running   0          3m38s   10.47.255.250   worker02
    ns-non-isolated   busybox                                 1/1     Running   0          2m5s    10.47.255.249   worker01
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    1. 对比验证 Pods 之间的网络隔离性
    # 验证 Isolated 和 non-Isolated 之间的隔离性
    kubectl exec -it -n ns-isolated busybox -- ping 10.47.255.249
    
    # 验证 Default 和 Isolated 之间的隔离性
    kubectl exec -it -n default busybox -- ping 10.47.255.250
    
    # 验证 Default 和 non-Isolated 之间的隔离性
    kubectl exec -it -n default busybox -- ping 10.47.255.249
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    K8s Service mapping to TF ECMP-based native LoadBalancer(load-balancing,负载均衡增强)

    K8s Service 支持以下 4 种模式,还支持使用 ExternalIP。

    1. ClusterIP
    2. NodePort
    3. LoadBalancer
    4. ExternalName

    而 TF 则主要支持了其中必要的 2 种模式,以及 ExternalIP。

    1. TF ClusterIP
    2. TF LoadBalancer

    TF ClusterIP Service

    TF ClusterIP Service 通过 ECMP 和 NAT 技术,实现了在 Service 和 Pods 之间进行 L4 负载均衡转发。

    TF Native Load Balancer

    新建一个 K8s ClusterIP Service 时,TF 会从同步新建一个 TF Load Balancer,LB Provider Type 为 Native,底层实现为 vRouter ECMP。所以也称为 TF Native Load Balancer。

    并且 TF 还会从相应的 Service VN 的 Subnet Pool 分配一个 IP 作为 LB VIP,也就是 ClusterIP。

    在这里插入图片描述

    TF Floating IP NAT

    在有了 TF Native LB VIP 作为 Front-end IP 之后,还需要将流量转发到 Backend IPs(Pods),TF 使用 NAT 技术来实现这一功能,而不是引入一个重型的 HAProxy-like 负载均衡器。

    同时,由于 TF Floating IP 本身就具有 NAT 的功能特性,所以就可以直接使用 TF Floating IP 来完成这项工作。

    另外,由于 ClusterIP Service 只能在 K8s Cluster Internal 被访问,所以针对 ClusterIP Service 的 FIP 实际上是一个 Inter-FIP。直接从相应的 Service VN 中的 FIP Pool 分配的,而不需要从 Public VN 中分配。

    在这里插入图片描述

    使用示例

    1. 创建 ClusterIP Service。
    $ cat nginx-deployment-clusterip-service.yaml
    
    ---
    apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
    kind: Deployment
    metadata:
      name: nginx-deployment-clusterip-service
    spec:
      strategy:
        type: Recreate
      selector:
        matchLabels:
          app: nginx
      replicas: 2 # tells deployment to run 1 pods matching the template
      template: # create pods using pod definition in this template
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx
            ports:
            - containerPort: 80
    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-deployment-clusterip-service
      namespace: default
      labels:
        app: nginx
    spec:
      ports:
      - name: http
        port: 80
        protocol: TCP
        targetPort: 80
      selector:
        app: nginx
        
    
    $ kubectl get pods -A -o wide | grep nginx
    default           nginx-56db997f77-9qxwd                  1/1     Running   0          15m    10.47.255.246   worker01 
    default           nginx-56db997f77-thpxd                  1/1     Running   0          15m    10.47.255.247   worker02 
    
    
    $ kubectl describe service -n default nginx
    Name:              nginx
    Namespace:         default
    Labels:            app=nginx
    Annotations:       kubectl.kubernetes.io/last-applied-configuration:
                         {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"nginx"},"name":"nginx","namespace":"default"},"spec":{"p...
    Selector:          app=nginx
    Type:              ClusterIP
    IP:                10.97.137.130
    Port:              http  80/TCP
    TargetPort:        80/TCP
    Endpoints:         10.47.255.246:80,10.47.255.247:80
    Session Affinity:  None
    Events:            >
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    1. 查看 ClusterIP Service 对应的 TF LB。
      在这里插入图片描述

    2. 查看 TF LB 在 vRouter 上的 ECMP Routes。
      请添加图片描述

    3. 查看 ClusterIP 的 FIP。
      在这里插入图片描述

    TF Loadbalancer Service

    TF Loadbalancer Service 的实现方式是在 TF ClusterIP Service(Native LB + Inter-FIP NAT)的基础之上,再叠加了一个 External FIP NAT。因为 Loadbalancer Service 相对于 ClusterIP Sercice 而言,是提供给 External Network 访问的。

    • ClusterIP Service as a Cluster Internal LB VIP
    • Loadbalancer Service as a Cluster External Floating VIP

    在这里插入图片描述

    可见,对于 Loadbalancer Service 而言拥有 3 个关键 IP:

    1. TF Native LB IP:从 Service VN Subnet Pool 分配,作为内部 L3-4 负载均衡 VIP。
    2. Inter-FIP:从 Service VN FIP Pool 分配,作为内部 L3-4 NAT Front-end IP。
    3. Ext-FIP:从 Public VN FIP Pool(Namespace FIP Pool 或 Global FIP Pool)分配,作为外部 L3-4 NAT Front-end IP。

    在这里插入图片描述

    相对的,Loadbalancer Service 中也存在着 2 种类型的 ECMP:

    1. Internal ECMP:Cluster IP 和 Pod IPs 之间的 ECMP
    2. External ECMP:External VIP 和 Cluster IPs(跨节点)之间的 ECMP。

    在这里插入图片描述

    使用示例

    • 新建 Loadbalancer Service
    $ vi service-web-lb.yaml
    
    apiVersion: v1
    kind: Service
    metadata:
      name: service-web-lb
      spec:
        ports:
        - port: 8888
        targetPort: 80 selector:
      app: webserver
      type: LoadBalancer
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    NodePort Service(kube-proxy iptables NAT)

    NodePort Service 依赖原生的 kube-proxy iptables NAT 技术来实现,在 TF 的场景中,通常没必要使用到。

    使用示例

    • 创建 Nginx Deployment NodePort Service。
    $ cat nginx-deployment-nodeport-service.yaml
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment-nodeport-service
      labels:
        name: nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          name: nginx
      template:
        metadata:
          labels:
            name: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.7.9
            ports:
            - containerPort: 80
    
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-deployment-nodeport-service
      labels:
        name: nginx
    spec:
      type: NodePort
      ports:
        - port: 80
          nodePort: 30080
          name: http
      selector:
        name: nginx
        
    
    $ kubectl get pods -A -o wide | grep nodeport
    default           nginx-deployment-nodeport-service-69f7cb4f44-pjm9r   1/1     Running   0          30s     10.47.255.247   worker02
    
    
    $ kubectl describe service -n default nginx-deployment-nodeport-service
    Name:                     nginx-deployment-nodeport-service
    Namespace:                default
    Labels:                   name=nginx
    Annotations:              kubectl.kubernetes.io/last-applied-configuration:
                                {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"name":"nginx"},"name":"nginx-deployment-nodeport-service","nam...
    Selector:                 name=nginx
    Type:                     NodePort
    IP:                       10.98.140.244
    Port:                     http  80/TCP
    TargetPort:               80/TCP
    NodePort:                 http  30080/TCP
    Endpoints:                10.47.255.247:80
    Session Affinity:         None
    External Traffic Policy:  Cluster
    Events:                   >
    
    
    # worker02
    $ curl http://172.27.10.75:30080
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 查看 Service 对应的 LB。
      在这里插入图片描述
    • 查看 ClusterIP 的 FIP。
      在这里插入图片描述

    K8s Ingress mapping to TF HAProxy L7 LoadBalancer(外部网络接入增强)

    TF 提供了基于 HAProxy 的 Ingress 实现,创建 K8s Ingress 就会创建一个 TF HAProxy LoadBalancer。

    其中,由 contrail-svc-monitor 执行具体的 LBaaS 任务。contrail-svc-monitor 作为 TF 内部组件(e.g. Config Node)与外部组件(e.g. Loadbalancer Provider、OpenStack API)之间进行交互的桥梁。

    K8s Network Policy mapping to TF Security group(micro-segmentation)

    TF Security Group 可以通过限制 Protocol、Ports 等参数来管理任意 Pods 之间、以及 Pod 与 Service 之间的访问控制,当新建一个 K8s Network Policy 就会创建一个 TF Security Group。

    TF Security Group 会被转化为具体的 TF Firewall Rules。

  • 相关阅读:
    【宜居星球改造计划】Python 实现
    群狼调研(长沙消费者满意度调查) | 参展观众满意度调查流程
    极值存在区间搜索(c#实现)
    算法leetcode|15. 三数之和(rust重拳出击)
    关于支持向量机,他的重难点是什么?
    疫情期间忙于视频会议的你,工作效率真的提高了吗?
    Docker部署前后端服务示例
    NFTScan | 09.04~09.10 NFT 市场热点汇总
    Python入门之函数调用
    简述二进制码、十进制码、BCD码、十六进制码转换的算法
  • 原文地址:https://blog.csdn.net/Jmilk/article/details/126308847