# 使用NCP Operator集成K8s ###### tags: `NCP` &emsp;&emsp;本文介绍一下使用NCP Operator集成K8s与NSX-T的方法和注意事项. 除Operator方法外原集成方式依然可用, 原方法文档可以参考张敏(Matt)制作的手册. 张敏的文档中阐述了集成的准备事项, 部分原理, 和详细步骤以及问题排查问题方法. 我无法写得比他更好了, 所以本文只做少许补充材料, 主要说明如果使用NCP Operator集成K8s的方法和优点. &emsp;&emsp;Matt文档链接: [NSX-T-NCP-k8s-部署手册-v3.1.0](https://onevmw-my.sharepoint.com/:w:/g/personal/taoh_vmware_com/EfdanmNpuLdPqqj9Ai1LThsBZJjpLGhjXF0LaLWTWTNA4A?e=28bRx4) ## NCP集成结构 图一, 说明了NCP可以理解为一个NSX-T的K8s Operator, 并不负责具体的转发层面执行工作, 只是作为指令的转发和API的翻译工作. ![](https://i.imgur.com/5Hx8pMl.png) <br> 图二, 步骤7, NSX CNI为容器提供端口配置, 因为NSX CNI是用Python2写的(在/opt/cni/bin下), 所以每个VM Node必须安装Python2, 否则启动Pod时会报错无法启动网络沙箱容器. ![](https://i.imgur.com/ubPzUws.png) <br> 图三阐述了OVS, NSX Kube Proxy,的工作职责 ![](https://i.imgur.com/DU62czA.png) <br> NSX CNI控制OVS为每个容器仓(Pod)打上本地VLAN标签, 到达NSX-T的Segment时, NSX-T通过Hyperbus上的节点标签知道的Pod网络的归属. 从而才能将Pod分配到正确的Segment, 和执行对Pod的分布式防火墙. ![](https://i.imgur.com/YbIkzNU.png) ## NCP Operator Operator是NCP的Oprator,并没有实现NCP+NCP Operator一体化. 简而言之NCP Operator目的是为了简化安装和集成NSX-T与K8s. 提炼几点要点NCP Operator要点: 1. NCP Operator简化集成参数, 集中在一个Configmap中完成 2. 简化TLS Ingress和OVS Kernel module的安装 3. 批量为VM Node打上Hyperbus所需要的标签 4. 简化与Openshift的集成 个人觉得生产部署中第三点很重要, VM Node节点多的话, 能够批量自动打标签不但快, 最终要的是减少了犯错的概率. 如果使用原安装方式集成的话, 可以用我个人写的批量为VM Node打标签的脚本[Rock写的批量为VIF打标签的脚本](https://github.com/Rock981119/tagnsxnode_vifs) ![](https://i.imgur.com/5i4w2Tg.png) ## 配置 ### 准备事项 1. 每个VM Node最少两张VIF, VIF1作为Kubelet和管理网卡, VIF2作为数据通讯网卡托管给OVS 2. VM Node的两张网卡最好在相同T1 Router下, 否则需要手工做No SNAT. 3. 解压NCP安装包, 上传NCP Operator镜像, 推荐使用私有镜像仓库. 4. 规划好你想要的拓扑, 可以参考张敏的文档 其余地址池如,Pod Subnet, LB VIP Pool, Egress NAT Pool等可以参考官方文档或张敏的文档. ### 演示环境 | Product | Version | | ------- | ------------------ | | NCP | 3.1.2 | | NSX-T | 3.1.0 | | K8s | v1.18.9 | | OS | Ubuntu 18.04.5 LTS | | Kernel | 4.15.0-112-generic | | Runtime | docker://19.3.13 | NCP压缩包解压后, 在operator文件夹下kubernetes内有安装所需的所有YAML ``` /operator/kubernetes kubernetes ls configmap.yaml operator.nsx.vmware.com_ncpinstalls_crd.yaml role_binding.yaml lb-secret.yaml operator.nsx.vmware.com_v1_ncpinstall_cr.yaml service_account.yaml namespace.yaml operator.yaml nsx-secret.yaml role.yaml ``` ### 准备YAML * 先编辑operator.yaml Operator的自己的镜像在压缩包内, 上传至私有镜像库或直接上传到节点上. 该环境变量指定了待会部署NCP时从何处拉取镜像, 我填的是私有镜像库 - name: NCP_IMAGE value: "192.168.31.250:5000/nsx-ncp:3.1.2" ``` apiVersion: apps/v1 kind: Deployment metadata: name: nsx-ncp-operator namespace: nsx-system-operator spec: replicas: 1 selector: matchLabels: name: nsx-ncp-operator template: metadata: labels: name: nsx-ncp-operator spec: hostNetwork: true serviceAccountName: nsx-ncp-operator tolerations: - effect: NoSchedule key: node-role.kubernetes.io/master - effect: NoSchedule key: node.kubernetes.io/not-ready - effect: NoSchedule key: node.kubernetes.io/network-unavailable volumes: - hostPath: {path: /etc/os-release} name: host-os-release containers: - name: nsx-ncp-operator image: vmware/nsx-container-plugin-operator command: ["/bin/bash", "-c", "nsx-ncp-operator --zap-time-encoding=iso8601"] volumeMounts: - {mountPath: /host/etc/os-release, name: host-os-release} imagePullPolicy: IfNotPresent env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: OPERATOR_NAME value: "nsx-ncp-operator" - name: NCP_IMAGE value: "192.168.31.250:5000/nsx-ncp:3.1.2" - name: WATCH_NAMESPACE value: "nsx-system-operator" ``` 编辑configmap.yaml, 篇幅问题, 至粘贴跟测试环境相关的选项 ``` [coe] adaptor = kubernetes cluster = k8s-03-cluster node_type = HOSTVM [nsx_v3] policy_nsxapi = True nsx_api_managers = 192.168.31.245 nsx_api_user = admin nsx_api_password = VMware1!VMware1! insecure = True use_native_loadbalancer = True default_ingress_class_nsx = True client_ssl_profile = k8s-lb-profile ## 可选项, 如果要开始NSX-T LB对TLS Ingress的支持. k8s-lb-profile是我自定义的, 系统内有内置的Profile可以选择 lb_default_cert_path = /etc/nsx-ujo/lb-cert/tls.crt ## 可选项, 如果要开始NSX-T LB对TLS Ingress的支持. LB默认证书的挂载位置 lb_priv_key_path = /etc/nsx-ujo/lb-cert/tls.key ## LB默认私钥的挂载位置 service_size = SMALL no_snat_ip_blocks = K8SC3_Pod_NoNAT_IPB external_ip_pools = K8SC3_Egress_IPP container_ip_blocks = K8SC3_Pod_IPB top_tier_router = K8C3-T1 ## 选择了T1作为SNAT执行点 single_tier_topology = True ## 拓扑模型选择Per T1 Per Cluster single_tier_sr_topology = False external_ip_pools_lb = K8SC3_Ingress_IPP overlay_tz = c86d3989-ae46-461d-a0f9-caa63c195515 edge_cluster = ff8ba3ff-e48d-49b6-b8ff-d498149290ad ## TZ & edge_cluster必须填写UUID, 不能写名字 x_forwarded_for = INSERT [k8s] apiserver_host_ip = 172.16.0.200 apiserver_host_port = 6443 enable_multus = True [nsx_node_agent] ovs_bridge = br-int ovs_uplink_port = ens192 ``` 由于我需要开启NSX-T LB 对TLS Ingress的支持, 需要上传一张默认LB证书, 官方文档有提供自签名证书的脚本如下: ``` #!/bin/bash host="www.example.com" filename=server openssl genrsa -out ca.key 4096 openssl req -key ca.key -new -x509 -days 365 -sha256 -extensions v3_ca -out ca.crt -subj "/C=US/ST=CA/L=Palo Alto/O=OS3/OU=Eng/CN=${host}" openssl req -out ${filename}.csr -new -newkey rsa:2048 -nodes -keyout ${filename}.key -subj "/C=US/ST=CA/L=Palo Alto/O=OS3/OU=Eng/CN=${host}" openssl x509 -req -days 360 -in ${filename}.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out ${filename}.crt -sha256 ``` **Tips**: NSX-T不可以使用根证书与私钥作为LB证书, 手工上传时就会报错. 必须采用跟为证书为CSR签发的证书, 如官方脚本的例子. 如果你使用自己制作的证书, 最后手工上传测试, 无报错再使用. 将证书文档输出为Base64格式后, 填入lb-secret.yaml ``` cat tls.crt |base64 -w0 cat tls.key |base64 -w0 ``` lb-secret.yaml ``` apiVersion: v1 data: {tls.crt: "<cat tls.crt |base64 -w0>", tls.key: "<cat tls.key |base64 -w0>"} kind: Secret metadata: {name: lb-secret, namespace: nsx-system-operator} type: kubernetes.io/tls ``` 最后编辑operator.nsx.vmware.com_v1_ncpinstall_cr.yaml, 我将addNodeTag设为True, Oper将自动为每个VM Node的VIF打标签. ``` apiVersion: operator.nsx.vmware.com/v1 kind: NcpInstall metadata: name: ncp-install namespace: nsx-system-operator spec: ncpReplicas: 1 addNodeTag: True ``` 建议按顺序Apply YAMLs, 当然你整个文件夹一次性Apply也行. namespace.yaml role.yaml role_binding.yaml service_account.yaml lb-secret.yaml nsx-secret.yaml configmap.yaml operator.nsx.vmware.com_ncpinstalls_crd.yaml operator.nsx.vmware.com_v1_ncpinstall_cr.yaml operator.yaml ## 校验 正常部署后大概会是这样一番景象, NCP Pod与Node Agent正常工作, CoreDNS正常工作. ![](https://i.imgur.com/F75QgeS.png) NSX-T的界面中出现了跟namespace相关的segment ![](https://i.imgur.com/wewoUr6.png) 在Transmit Segment上检查每个Node VIF是否已经打上了正确的标签. 如果没有, 确保operator.nsx.vmware.com_v1_ncpinstall_cr.yaml里的addNodeTag设为True, 重启Operator, 再回来检查. ![](https://i.imgur.com/JVicSHN.png) 最后检查默认LB证书是否上传成功 ![](https://i.imgur.com/dT2xnfE.png) ![](https://i.imgur.com/LDoE9Tu.png) 如果都校验功过说明你已经集成成功了, 部署几个Pod, 尝试发布Tls Ingress试试吧.