四种模式、七大元素:玩转TF+K8s CNI集成部署



  • Tungsten Fabric从4.0版本起,就开始支持用于将Kubernetes自动化平台与TF的集成的容器网络接口(CNI)。本文就来介绍基于CNI的TF+K8s集成部署。

    什么是Kubernetes

    Kubernetes也称为K8s,是一个开放源代码平台,用于跨主机集群自动执行应用程序容器的部署、扩展和运行,从而提供以容器为中心的基础架构。它提供了跨公共云和私有云的可移植平台。Kubernetes支持应用程序的部署、扩展和自动修复。

    Kubernetes支持可用于大多数基本网络连接的容器网络接口(CNI)的可插入框架,包括容器Pod寻址、网络隔离、基于策略的安全性、网关、SNAT、负载均衡器,以及Kubernetes编排的服务链功能。Tungsten Fabric自4.0版本起即可支持Kubernetes的CNI功能。

    Kubernetes提供了一个扁平的网络模型,其中所有容器Pod都可以彼此通信。添加了网络策略功能,以提供Pod之间的安全性。与Kubernetes集成的Tungsten Fabric则添加了其它网络功能,包括多租户、网络隔离、具有网络策略的微分段和负载均衡等。

    表1列出了Kubernetes概念与Tungsten Fabric资源之间的映射。

    表1:Kubernetes到Tungsten Fabric的映射
    b4449080-97eb-4ab3-a6c4-732513e08bb6-image.png

    什么是Kubernetes Pod?

    Kubernetes pod是一组单个或多个容器(例如Docker容器),这些容器共享的存储和如何运行容器的配置选项。Pod始终位于同一位置,在同一时间编排,并在共享的上下文中运行。Pod的共享上下文是一组Linux命名空间、cgroup和其它隔离方面。在Pod的相关环境中,每个应用程序可能会有进一步的子隔离。

    你可以在以下位置找到有关Kubernetes的更多信息:
    http://kubernetes.io/docs/whatisk8s/

    TF+K8s的四种配置模式

    可以在Kubernetes中以几种不同的模式配置Tungsten Fabric,本节介绍的几种配置模式包括:

    • 默认模式
    • 命名空间隔离模式
    • 自定义隔离模式
    • 嵌套模式

    默认模式

    在Kubernetes中,所有Pod可以与所有其它Pod通信,而无需使用网络地址转换(NAT)。这也是TF Kubernetes集群的默认模式。在默认模式下,Tungsten Fabric创建一个由所有命名空间共享的虚拟网络,从该命名空间分配服务和Pod IP地址。

    Kubernetes集群中产生的所有命名空间中的所有Pod都可以相互通信。所有Pod的IP地址都是从TF Kubernetes管理器中配置的Pod子网分配的。

    注意:
    在kube-system命名空间中生成的系统Pod不在Kubernetes集群中运行;它们以underlay的方式运行,并且这些pod的网络也不是由TF处理的。

    命名空间隔离模式

    除了Kubernetes授权使用的默认网络模型外,Tungsten Fabric还支持其他自定义网络模型,这些模型为Kubernetes集群的用户提供了许多丰富的Tungsten Fabric功能。其中一种这样的功能,就是Kubernetes命名空间的网络隔离。

    对于命名空间隔离模式,集群管理员可以配置命名空间注释以打开隔离。在该模式下,除非明确定义了安全组或网络策略以允许访问,否则无法从其它命名空间访问该命名空间中的服务。

    可以通过注释Kubernetes命名空间元数据,来将Kubernetes命名空间配置为隔离的:

    opencontrail.org/isolation : true

    命名空间隔离为Pod提供了网络隔离,因为隔离的命名空间中的Pod无法访问集群中其它命名空间中的Pod。

    命名空间隔离还为Pod提供服务的隔离。如果任何Kubernetes服务是由隔离命名空间中的Pod实现的,则这些Pod仅可通过Kubernetes service-ip到达同一命名空间中的Pod。

    为了使服务仍然可以访问其它命名空间,可以通过在命名空间上标记以下注释来禁用服务隔离:

    opencontrail.org/isolation.service : false

    禁用服务隔离,可以使服务访问其它命名空间中的Pod,但是隔离的命名空间中的Pod仍然无法访问其它命名空间中的Pod。

    对于Pod和服务隔离都被标记为“已隔离”的命名空间,具有以下网络行为:

    • 在隔离的命名空间中创建的所有Pod彼此之间都具有网络可达性。
    • Kubernetes集群中其它命名空间中的pod无法到达隔离命名空间中的pod。
    • 在隔离命名空间中创建的pod可以到达非隔离命名空间中的pod。
    • 隔离命名空间中的Pod可以访问Kubernetes集群中任何命名空间中的非隔离服务。
    • 来自其它命名空间的Pod无法到达隔离命名空间中的服务。

    被标记为“已隔离”,且服务隔离被禁用、pod隔离被启用的命名空间,具有以下网络行为:

    • 在隔离的命名空间中创建的所有Pod彼此之间都具有网络可达性。
    • Kubernetes集群中其它命名空间中的pod无法到达隔离命名空间中的pod。
    • 在隔离命名空间中创建的pod可以到达其它命名空间中的pod。
    • 隔离命名空间中的Pod可以访问Kubernetes集群中任何命名空间中的非隔离服务。
    • 来自其它命名空间的Pod可以到达隔离命名空间中的服务。

    自定义隔离模式

    管理员和应用程序开发人员可以添加注释,以指定要在其中配置一个或多个Pod的虚拟网络。用于指定此自定义虚拟网络的注释为:

    "opencontrail.org/network: "

    如果在Pod规范上配置了此注释,则会在该网络中启动Pod。如果在命名空间规范中配置了注释,则将在提供的网络中启动命名空间中的所有Pod。

    注意:
    在Pod或命名空间规范中配置虚拟网络之前,必须使用Tungsten Fabric VNC API或Tungsten Fabric-UI创建虚拟网络。

    嵌套模式

    Tungsten Fabric支持在OpenStack集群内部配置Kubernetes集群。虽然这种集群的嵌套本身并不是独一无二的,但Tungsten Fabric提供了一个折叠式的控制和数据平面,在这个平面中,一个TF控制平面和一个网络栈同时管理和服务OpenStack和Kubernetes集群。通过统一的控制和数据平面,这些集群的互通和配置是无缝的,并且没有复制和重叠的现象,使其成为非常有效的选项。

    在嵌套模式下,一个OpenStack集群的虚拟机中预配置了一个Kubernetes集群。Kubernetes集群的CNI插件和TF-kubernetes管理器,直接与管理OpenStack集群的Tungsten Fabric组件交互。

    在嵌套模式部署中,所有Kubernetes特性、功能和规格都可以被支持。嵌套部署允许其与底层的OpenStack集群在同一平面上运行,从而扩展了Kubernetes的边界和局限性。

    想要了解更多的信息,请查看以下链接:
    https://www.juniper.net/documentation/en_US/contrail20/topics/task/installation/provisioning-k8s-cluster.html

    Kubernetes服务

    Kubernetes服务是一种抽象概念,它定义了逻辑上的Pod集以及用于访问Pod的策略。根据服务定义中的LabelSelector字段选择实现服务的Pod集。在Tungsten Fabric中,Kubernetes服务被实现为原生于ECMP的负载均衡器。

    TF Kubernetes集成支持以下ServiceType:

    • “clusterIP”:这是默认模式。选择此ServiceType可使服务通过集群网络访问。
    • “LoadBalancer”:将ServiceType指定为“LoadBalancer”可以从外部访问该服务。为“LoadBalancer”_Service_分配了CluserIP和ExternalIP地址。此ServiceType假定用户已使用浮动IP池配置了公共网络。

    TF Kubernetes服务集成支持TCP和UDP协议。另外,服务可以暴露多个端口,而这些端口都与targetPort不同。例如:

    kind: Service
    apiVersion: v1
    metadata:
      name: my-service
    spec:
        selector:
          app: MyApp
        ports:
          - name: http
            protocol: TCP
            port: 80
            targetPort: 9376
          - name: https
            protocol: TCP
            port: 443
            targetPort: 9377
    

    Kubernetes用户可以为LoadBalancer和clusterIP ServiceTypes指定spec.clusterIP和spec.externalIPs。

    如果ServiceType为LoadBalancer,并且用户未指定spec.externalIP,那么conutil-kube-manager将从公共池中分配一个浮动IP,并将其关联到ExternalIP地址。

    Ingress

    Kubernetes服务可以通过多种方式在外部公开或在集群外部暴露。

    有关从外部公开Kubernetes服务的所有方法的列表,请参见链接:
    https://kubernetes.io/docs/concepts/services-networking/ingress/#alternatives

    Ingress就是这样一种方法。Ingress提供7层负载均衡,而其它方法提供4层负载均衡。Tungsten Fabric支持基于http的单一服务入口、简单扇出入口,和基于命名的虚拟主机入口。

    TF K8s解决方案的七大元素

    Tungsten Fabric Kubernetes解决方案包括以下元素:

    • TF Kubernetes Manager
    • Kubernetes服务的ECMP负载均衡器
    • 用于Kubernetes Ingress的HAProxy 负载均衡器
    • Kubernetes网络策略的安全组
    • Kubernetes对安全策略的支持
    • 域名服务器(DNS)
    • 支持的Kubernetes注释

    接下来请它们一一登场。

    TF Kubernetes Manager

    TF Kubernetes的实施需要侦听Kubernetes API消息,并在Tungsten Fabric API数据库中创建相应的资源。

    在Docker容器中运行一个新的模块——conilil-kube-manager,以侦听来自Kubernetes API服务器的消息。

    Kubernetes服务的ECMP负载均衡器

    Kubernetes中的每个服务都由一个负载均衡器对象表示。Kubernetes分配的服务IP用作负载均衡器的VIP。正在侦听的服务端口上会创建侦听器。每个Pod都被添加为侦听器池的成员。Consilute-kube-manager会侦听基于服务标签或Pod标签的任何更改,并使用添加、更新或删除的Pod更新成员池列表。

    服务的负载均衡是基于ECMP的4层原生、非代理的负载均衡。instance-ip(service-ip)链接到服务中每个Pod的端口。这将在Tungsten Fabric中创建一个ECMP下一跳,并且流量直接从源pod进行负载均衡。

    用于Kubernetes Ingress的HAProxy 负载均衡器

    Kubernetes Ingress是通过Tungsten Fabric中的HAProxy负载均衡器功能实现的。只要在Kubernetes中配置了入口,contrail-kube-manager就会在contrail-controller中创建负载均衡器对象。TF服务监视器将侦听负载均衡器对象,并根据主备模式下的入口规范规则以适当的配置启动HAProxy。

    有关负载均衡器的更多信息,请参见:
    https://www.juniper.net/documentation/en_US/contrail20/topics/task/configuration/lbaas-contrail3-F5.html

    Kubernetes网络策略的安全组

    Kubernetes网络策略是有关如何允许Pod组彼此通信,以及与其它网络端点进行通信的规范。NetworkPolicy资源使用标签来选择Pod,并定义允许列表规则,该规则除了对给定命名空间的隔离策略所允许的内容外,还允许对选定Pod的访问。

    有关Kubernetes网络策略的更多信息,请参阅:
    https://kubernetes.io/docs/concepts/services-networking/networkpolicies/

    Contil-kube-manager侦听Kubernetes网络策略事件以创建、更新和删除,并将Kubernetes网络策略转换为应用于虚拟机接口(VMI)的Tungsten Fabric安全组对象。当添加和删除pod和标签时,VMI会动态更新。

    Kubernetes对安全策略的支持

    在Kubernetes环境中创建的网络策略,是通过使用Tungsten Fabric安全策略框架来实现的。Kubernetes环境中的标签(labels)在Tungsten Fabric中作为标签(tags)公开。从Tungsten Fabric 5.0版开始,你可以为Kubernetes环境定义标签。Tungsten Fabric安全策略使用这些标签来实现指定的Kubernetes策略。你可以在UI中定义标签或以JSON格式上传配置。新定义的标签可用于在TF Security中创建和实施策略。

    域名服务器(DNS)

    Kubernetes使用SkyDNS实施DNS,SkyDNS是一个小型DNS应用程序,可响应来自Pod的DNS请求以解析服务名称。SkyDNS在Kubernetes中作为pod运行。

    支持的Kubernetes注释

    当前,Tungsten Fabric支持以下Kubernetes注释:

    'opencontrail.org/network': '{"domain":"default-domain", "project": "k8s-contrail", "name":"deu"}'
    'opencontrail.org/isolation': 'true'
    'opencontrail.org/fip-pool': '{"domain": "default-domain", "project": "k8s-default", "network": "k8s-default-svc-public", "name": "default"}'
    

    有关更多详细信息,请参阅:
    https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/.

    验证Kubernetes的CNI配置

    你可以使用下面的验证步骤,来查看和验证针对Kubernetes的Tungsten Fabric容器网络接口(CNI)的配置。

    查看Pod名称和IP地址

    使用以下命令查看分配给Pod的IP地址。

    [root@device ~]# kubectl get pods --all-namespaces -o wide 
    NAMESPACE         NAME               READY     STATUS    RESTARTS   AGE       IP                         NODE
    default               client-1            1/1         Running     0               19d       10.47.25.247   k8s-minion-1-3
    default               client-2            1/1         Running     0               19d       10.47.25.246   k8s-minion-1-1
    default               client-x             1/1        Running     0               19d       10.84.21.272   k8s-minion-1-1
    

    验证Pod的可达性

    执行以下步骤,以验证各个pod是否可以相互到达。

    1.确定pod的IP地址和名称。

    [root@device ~]# kubectl get pods --all-namespaces -o wide
    NAME                        READY     STATUS    RESTARTS   AGE       IP              NODE
    example1-36xpr   1/1       Running   0          43s       10.47.25.251   b3s37
    example2-pldp1   1/1       Running   0          39s       10.47.25.250   b3s37
    

    2.从源Pod去ping目标Pod,以验证Pod是否可达。

    root@device ~]# kubectl exec -it example1-36xpr  ping 10.47.25.250
    PING 10.47.25.250 (10.47.25.250): 56 data bytes
    64 bytes from 10.47.25.250: icmp_seq=0 ttl=63 time=1.510 ms
    64 bytes from 10.47.25.250: icmp_seq=1 ttl=63 time=0.094 ms
    

    验证隔离命名空间的Pod是否为不可访问

    执行以下步骤,以验证非隔离命名空间中的pod是否无法访问隔离命名空间中的pod。

    1.确定隔离命名空间中Pod的IP地址和名称。

    [root@device ~]# kubectl get pod -n test-isolated-ns -o wide
    NAME                        READY     STATUS    RESTARTS   AGE       IP              NODE
    example3-bvqx5   1/1       Running   0          1h        10.47.25.249   b3s37
    

    2.确定非隔离命名空间中的Pod的IP地址。

    [root@device ~]# kubectl get pods
    NAME                        READY     STATUS    RESTARTS   AGE
    example1-36xpr   1/1       Running   0          15h
    example2-pldp1   1/1       Running   0          15h
    

    3.从非隔离命名空间中的Pod去ping隔离命名空间中的Pod的IP地址。

    [root@device ~]# kubectl exec -it example1-36xpr ping 10.47.25.249
            --- 10.47.255.249 ping statistics ---
     2 packets transmitted, 0 packets received, 100% packet loss
    

    验证非隔离命名空间的Pod是否为可以访问

    执行以下步骤,以验证非隔离命名空间中的Pod是否可以访问非隔离命名空间中的Pod。

    1.确定非隔离命名空间中Pod的IP地址。

    [root@device ~]# kubectl get pods -o wide
    NAME                        READY     STATUS    RESTARTS   AGE       IP              NODE
    example1-36xpr   1/1       Running   0          15h       10.47.25.251   b3s37
    example2-pldp1   1/1       Running   0          15h       10.47.25.250   b3s37
    

    2.确定隔离命名空间中的Pod的IP地址和名称。

    [root@device ~]# kubectl get pod -n test-isolated-ns -o wide
    NAME                        READY     STATUS    RESTARTS   AGE       IP              NODE
    example3-bvqx5   1/1       Running   0          1h        10.47.25.249   b3s37
    

    3.从隔离命名空间中的pod去ping非隔离命名空间中pod的IP地址。

    [root@device ~]# kubectl exec -it example3-bvqx5 -n test-isolated-ns ping 10.47.25.251
    PING 10.47.25.251 (10.47.25.251): 56 data bytes
    64 bytes from 10.47.25.251: icmp_seq=0 ttl=63 time=1.467 ms
    64 bytes from 10.47.25.251: icmp_seq=1 ttl=63 time=0.137 ms
    ^C--- 10.47.25.251 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max/stddev = 0.137/0.802/1.467/0.665 ms
    

    验证命名空间是否隔离

    命名空间注释用于打开Kubernetes命名空间中的隔离。在隔离的Kubernetes命名空间中,命名空间元数据使用opencontrail.org/isolation : true标注进行注释。

    使用以下命令查看命名空间上的注释。

    [root@a7s16 ~]#
    kubectl describe namespace test-isolated-ns   
    Name:       test-isolated-ns
    Labels:     
    Annotations:    opencontrail.org/isolation : true     Namespace is isolated
    Status:     Active
    

    原文链接:
    https://www.juniper.net/documentation/en_US/contrail20/topics/concept/kubernetes-cni-contrail.html
    https://www.juniper.net/documentation/en_US/contrail20/topics/task/verification/verifying-cni-k8s.html



Log in to reply