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

2020-12-02 10:10:45 浏览数 (1)

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的映射

Kubernetes

Tungsten Fabric资源

Namespace命名空间

共享或单个项目

Pod

虚拟机,接口,实例IP

Service

基于ECMP的原生负载均衡器

Ingress

基于HAProxy的用于URL路由的L7负载均衡器,

Network policy网络策略

基于命名空间和Pod选择器的安全组

什么是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: <fq_network_name>"

如果在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不同。例如:

代码语言:javascript复制
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注释:

代码语言:javascript复制
'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地址。

代码语言:javascript复制
[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地址和名称。

代码语言:javascript复制
[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是否可达。

代码语言:javascript复制
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地址和名称。

代码语言:javascript复制
[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地址。

代码语言:javascript复制
[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地址。

代码语言:javascript复制
[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地址。

代码语言:javascript复制
[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地址和名称。

代码语言:javascript复制
[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地址。

代码语言:javascript复制
[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标注进行注释。

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

代码语言:javascript复制
[root@a7s16 ~]#
kubectl describe namespace test-isolated-ns   
Name:       test-isolated-ns
Labels:     <none>
Annotations:    opencontrail.org/isolation : true     Namespace is isolated
Status:     Active

0 人点赞