在數據中心里,同時擁有OpenStack和Kubernetes集群的情況正變得越來越普遍。
一邊是由OpenStack管理的虛擬機,另一邊是由K8s控制的容器化工作負載。現實情況下,可能會發生虛擬機和容器需要相互“交談”的情況。如果是這樣,我們需要以某種方式實現兩個獨立集群之間的通信。作為兩個不同的集群,每個集群都有自己的網絡平面。OpenStack可能會依賴OVS,而Kubernetes則會部署某個可用的CNI。由于每個集群都是獨立于其它集群的,因此必須在第三個“元素”上啟用通信。這第三個元素可以是IP Fabric。虛擬機將通過提供商網絡退出計算,并在VLAN內的IP Fabric上現身。容器也會做類似的事情。因此,我們可能最終會有兩個VLAN,通過配置IP Fabric葉子節點(或spine節點)作為L2/L3 gw來允許它們相互對話。另外,L3 gw的角色可能會被委托給上層設備,比如SDN gw(在這種情況下,IP Fabric葉子節點/spine節點只會是L2 gw)。這里的一個關鍵要點是,虛擬/容器化的工作負載成為underlay的一部分,使得服務平面(工作負載)和網絡平面(IP Fabric)相互交錯。提供服務也需要在IP Fabric underlay進行配置。我們在探索數據中心使用Tungsten Fabric的優勢時,談到過這個概念,請見下面鏈接:https://iosonounrouter.wordpress.com/2020/04/28/which-sdn-solution-is-better-what-i-learned/同樣的考慮在這里也適用,另外我們不僅需要連接虛擬機,還需要連接容器。我們假設需要部署一個應用程序,其構件既有虛擬機又有容器。這意味著我們需要在OpenStack里部署一些對象,在Kubernetes里部署另外一些對象。從網絡的角度來看,我們需要對OpenStack、K8s和IP Fabric進行操作。如果能簡化這一點就好了。Tungsten Fabric來了!TF可以與OpenStack和K8s一起工作(作為CNI)。當然,代碼的某些部分是“編排器專用”的。我的意思是,TF一方面需要與Neutron/Nova進行交互,另一方面需要與K8s API和其它K8s組件進行交互。總之,除了這些,解決方案的核心還是一樣的!虛擬網絡也還是VRF。工作負載也還是接口!不管我們的接口后面是虛擬機還是容器,對于Tungsten Fabric來說,它只是放到VRF中的一個接口。對于計算節點之間和通向SDN網關的overlay(MPLSoUDP、MPLSoGRE、VXLAN)也是一樣的。因此,讓虛擬機與容器進行通信,只是在同一個VRF(虛擬網絡)中放置接口的問題。這可以通過讓一個實體來“控制”OpenStack和Kubernetes集群的虛擬網絡來實現。這個實體就是我們最愛的TF Controller。我們的數據中心將會是這樣的:如你所見,從配置的角度來看,集群還是有區別的。Kubernetes master控制容器,而OpenStack controller負責Nova虛擬機。這里的關鍵變化在于Tungsten Fabric控制器(controller)的存在,它將與OpenStack計算節點和Kubernetes worker節點進行交互(仍然使用XMPP)。這樣我們就為集群提供了一個單一的網絡平面。由于TF在overlay層工作,我們不再需要IP Fabric來“看到”虛擬機和容器。工作負載的流量被隱藏在overlay隧道中(無論是在計算節點之間,還是通向SDN網關……就像任何一個TF集群一樣)。擁有一個單一的網絡平面還會帶來其它優勢。例如,TF將負責IP地址分配。假設我們有一個地址為192.168.1.0/24的虛擬網絡。如果我們在該VN上創建一個虛擬機,TF將分配地址192.168.1.3。之后,如果我們在Kubernetes中創建一個容器,并將其連接到同一個VN,TF將分配地址192.168.1.4,因為它知道.3已經在使用。如果有兩個不同的集群,實現這個功能需要額外的“工具”(例如配置靜態分配池或讓更高級別的編排器充當IPAM管理器角色)。Tungsten Fabric則簡化了這種網絡操作。現在,理論已經說得夠多了。讓我們來看一個實際的例子!我在一個虛擬實驗室中構建了上述拓撲。為了部署Tungsten Fabric,我使用了Ansible部署器,它允許我們同時配置OpenStack和Kubernetes集群。我不會去詳細介紹如何使用Ansible部署器安裝TF(這里是一個部署K8s集群的例子);我假設對這個工具有預先的了解。大家知道,Ansible部署器的核心是instances.yaml文件。下面是我使用的一個文件:###FILE USED TO DESCRIBE THE CONTRAIL CLOUD THAT ANSIBLE DEPLOYER HAS TO BUILDglobal_configuration:CONTAINER_REGISTRY: hub.juniper.net/contrailCONTAINER_REGISTRY_USERNAME: xxxCONTAINER_REGISTRY_PASSWORD: yyyprovider_config:bms:ssh_user: rootssh_pwd: Embe1mplsntpserver: 10.102.255.254domainsuffix: multiorch.contrailinstances:cnt-control:provider: bmsip: 10.102.240.183roles:config:config_database:control:webui:analytics:analytics_database:analytics_alarm:os-control:provider: bmsip: 10.102.240.178roles:openstack:os-compute:provider: bmsip: 10.102.240.171roles:vrouter:VROUTER_GATEWAY: 192.168.200.1openstack_compute:k8s-master:provider: bmsroles:k8s_master:kubemanager:ip: 10.102.240.174k8s-worker:provider: bmsroles:vrouter:VROUTER_GATEWAY: 192.168.200.1k8s_node:ip: 10.102.240.172contrail_configuration:CLOUD_ORCHESTRATOR: openstackCONTRAIL_CONTAINER_TAG: 2008.121CONTRAIL_VERSION: 2008.121OPENSTACK_VERSION: queensENCAP_PRIORITY: "VXLAN,MPLSoUDP,MPLSoGRE"BGP_ASN: 65100CONFIG_NODEMGR__DEFAULTS__minimum_diskGB: 2DATABASE_NODEMGR__DEFAULTS__minimum_diskGB: 2CONFIG_DATABASE_NODEMGR__DEFAULTS__minimum_diskGB: 2KUBERNETES_CLUSTER_PROJECT: {}KUBERNETES_API_NODES: 192.168.200.12KUBERNETES_API_SERVER: 192.168.200.12KUBEMANAGER_NODES: 192.168.200.12RABBITMQ_NODE_PORT: 5673KEYSTONE_AUTH_URL_VERSION: /v3VROUTER_GATEWAY: 192.168.200.1CONTROLLER_NODES: 10.102.240.183CONTROL_NODES: 192.168.200.10JVM_EXTRA_OPTS: "-Xms1g -Xmx2g"PHYSICAL_INTERFACE: "ens3f1"kolla_config:kolla_globals:enable_haproxy: noenable_ironic: noenable_swift: noenable_barbican: nokolla_passwords:keystone_admin_password: contrail123metadata_secret: meta123實例部分包括5臺服務器:
openstack controller
kubernetes master
contrail controller
openstack compute
kubernetes worker
如果你去看“contrail_configuration”部分,就會注意到我們配置TF是為了與openstack controller(KEYSTONE_AUTH_URL_VERSION)和kubernetes master(KUBERNETES_API_NODES)交互。一旦所有節點都做好安裝準備,從“deployer”節點(可以是contrail controller本身)運行以下命令:ansible-playbook -e orchestrator=openstack -i inventory/ playbooks/configure_instances.ymlansible-playbook -e orchestrator=openstack -i inventory/ playbooks/install_openstack.ymlansible-playbook -e orchestrator=openstack -i inventory/ playbooks/install_k8s.ymlansible-playbook -e orchestrator=openstack -i inventory/ playbooks/install_contrail.yml如果一切順利的話,我們的集群應該可以運行了。讓我們連接到Tungsten Fabric GUI:我們看到兩個虛擬路由器:os-compute和k8s-worker!我們看一下控制節點:只有一個控制器!我們“單一網絡平面”的關鍵概念變成了現實。接下來,我創建了一個虛擬網絡:
啟動一個連接到該VN的虛擬機:nova boot --image cirros2 --flavor cirros --nic net-id= vm(kolla-toolbox)[ansible@os-control /]$ nova list+--------------------------------------+------+--------+------------+-------------+------------------------+| ID ??????????????????????????????????| Name | Status | Task State | Power State | Networks ??????????????|+--------------------------------------+------+--------+------------+-------------+------------------------+| 3cf82185-5261-4b35-87bf-4eaa9de3caaf | vm ??| ACTIVE | - ?????????| Running ????| seamless=192.168.100.3 |+--------------------------------------+------+--------+------------+-------------+------------------------+接下來,創建一個連接到該VN的容器:[root@k8s-master ~]# cat cn.yaml---kind: NamespaceapiVersion: v1metadata:name: seamlessannotations:'opencontrail.org/network' : '{"domain":"default-domain", "project": "k8s-contrail", "name":"seamless"}'labels:name: seamless---apiVersion: v1kind: Podmetadata:name: contnamespace: seamlessspec:containers:- name: contimage: alpinecommand: ["tail"]args: ["-f", "/dev/null"]kubectl apply -f vn.yaml[root@k8s-master ~]# kubectl get pod -n seamless -o wideNAME ??READY ??STATUS ???RESTARTS ??AGE ??IP ?????????????NODE ????????NOMINATED NODE ??READINESS GATEScont ??1/1 ????Running ??0 ?????????74s ??192.168.100.4 ??k8s-worker ?? ??????????[root@k8s-master ~]# kubectl get -f cn.yaml -o wideNAME ????????????????STATUS ??AGEnamespace/seamless ??Active ??31mNAME ??????READY ??STATUS ???RESTARTS ??AGE ??IP ?????????????NODE ????????NOMINATED NODE ??READINESS GATESpod/cont ??1/1 ????Running ??0 ?????????31m ??192.168.100.4 ??k8s-worker ?? ??????????如你所見,由于192.168.100.3已經被VM占用了,pod被分配了192.168.100.4的IP地址。這也是多個集群使用單一網絡平面的優勢之一。讓我們從GUI中查看一下路由表:兩個IP都有!我們剛剛把一個虛擬機連接到一個工作負載上……而這對underlay是完全透明的!讓我們再到worker節點,查看一下vRouter代理:(vrouter-agent)[root@k8s-worker /]$ vif --get 3Vrouter Interface Tablevif0/3 ?????OS: tapeth0-11ccbe NH: 51Type:Virtual HWaddr:00:00:5e:00:01:00 IPaddr:192.168.100.4Vrf:4 Mcast Vrf:4 Flags:PL3L2DEr QOS:-1 Ref:6RX packets:67 ?bytes:2814 errors:0TX packets:87 ?bytes:3654 errors:0Drops:67(vrouter-agent)[root@k8s-worker /]$ rt --get 192.168.100.3/32 --vrf 4Match 192.168.100.3/32 in vRouter inet4 table 0/4/unicastFlags: L=Label Valid, P=Proxy ARP, T=Trap ARP, F=Flood ARPvRouter inet4 routing table 0/4/unicastDestination ??????????PPL ???????Flags ???????Label ????????Nexthop ???Stitched MAC(Index)192.168.100.3/32 ???????0 ??????????LP ????????25 ????????????39 ???????2:85:bf:53:6b:67(96024)(vrouter-agent)[root@k8s-worker /]$ nh --get 39Id:39 ????????Type:Tunnel ????????Fmly: AF_INET ?Rid:0 ?Ref_cnt:8 ?????????Vrf:0Flags:Valid, MPLSoUDP, Etree Root,Oif:0 Len:14 Data:56 68 a6 6f 05 ff 56 68 a6 6f 06 f7 08 00Sip:192.168.200.14 Dip:192.168.200.13所有的路由信息都在那里!容器可以通過連接Kubernetes worker節點和OpenStack計算節點的MPLSoUPD隧道到達虛擬機。這樣就可以進行通信了嗎?還不行!別忘了安全組還在那里!虛擬機屬于一個OpenStack項目(這里是管理項目),而容器屬于另一個項目(映射到Kubernetes命名空間)。每個項目都有自己的安全組。默認情況下,安全組只允許來自屬于同一安全組的入口流量。由于兩個工作負載的接口被分配到不同的安全組,因此它們之間不允許對話!為了解決這個問題,我們需要對安全組采取行動。簡單的方法是在兩個安全組上都允許來自0.0.0.0/0的入口流量(這是容器安全組,但同樣也可以在虛擬機安全組上進行):另外,我們也可以在入口方向允許特定的安全組。例如,在k8s-seamless-default-sg(容器所屬命名空間/項目的安全組)上,我們允許默認安全組(虛擬機所屬OpenStack項目的安全組)。同樣地,也可以在分配給虛擬機接口的安全組上進行:現在,讓我們訪問容器,并且ping一下虛擬機:[root@k8s-worker ~]# docker ps | grep seaml18c3898a09ac ???????alpine ????????????????????????????????????????????????????????"tail -f /dev/null" ?????9 seconds ago ??????Up 8 seconds ???????????????????????????k8s_cont_cont_seamless_e4a7ed6d-38e9-11eb-b8fe-5668a66f06f8_06bb1c3b40300 ???????k8s.gcr.io/pause:3.1 ??????????????????????????????????????????"/pause" ????????????????17 seconds ago ?????Up 15 seconds ??????????????????????????k8s_POD_cont_seamless_e4a7ed6d-38e9-11eb-b8fe-5668a66f06f8_0[root@k8s-worker ~]# docker exec -it 18c38 sh/ # ip add1: lo: mtu 65536 qdisc noqueue state UNKNOWN qlen 1000link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever24: eth0@if25: mtu 1500 qdisc noqueue state UPlink/ether 02:e4:e5:52:ce:38 brd ff:ff:ff:ff:ff:ffinet 192.168.100.4/24 scope global eth0valid_lft forever preferred_lft forever/ # ping 192.168.100.3PING 192.168.100.3 (192.168.100.3): 56 data bytes64 bytes from 192.168.100.3: seq=0 ttl=64 time=3.813 ms64 bytes from 192.168.100.3: seq=1 ttl=64 time=1.802 ms64 bytes from 192.168.100.3: seq=2 ttl=64 time=2.260 ms64 bytes from 192.168.100.3: seq=3 ttl=64 time=1.945 ms^C--- 192.168.100.3 ping statistics ---4 packets transmitted, 4 packets received, 0% packet lossround-trip min/avg/max = 1.802/2.455/3.813 ms/ #就是這樣!虛擬機和容器可以互相對話了!無論你的工作負載是虛擬機還是容器……至少從網絡的角度來看,一切都是在Tungsten Fabric的機制下進行的。
作者:Umberto Manferdini ?譯者:TF編譯組原文鏈接:https://iosonounrouter.wordpress.com/2020/12/14/contrail-providing-seamless-virtual-networking-to-openstack-and-kubernetes-clusters/
猜你喜歡
Tungsten Fabric解決方案指南-Gateway MX
Tungsten Fabric解決方案指南-Kubernetes集成
Tungsten Fabric:為云網絡而生的SDN控制器
如何在Tungsten Fabric上整合裸金屬服務器(附配置驗證過程)
如何在OpenStack-Ansible上集成Tungsten Fabric
如何搞定Netronome Agilio vRouter智能網卡(安裝和設置指南)
如何在OpenStack Kolla上部署Tungsten Fabric(附14個常見的配置問題)
如何實現oVirt與Tungsten?Fabric的集成
TF中文社區多云互聯 · 開源開放
總結
以上是生活随笔為你收集整理的openstack vlan配置_为OpenStack和K8s集群提供无缝虚拟网络的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。