自建Kubernetes集群对接VNode
更新时间:2025-06-05
如果您在线下IDC或者百度云BCC上自建了Kubernetes集群,您需要在集群中部署虚拟节点(VNode)来使用BCI。本文为您介绍自建的Kubernetes集群如何对接VNode。
前提条件
- 已部署好Kubernetes集群,且集群的版本属于1.18~1.22版本。
 - Vnode需要占用您集群资源,预计是1 vCPU、2 GiB内存,请提前在集群中准备好资源。
 - 如果您的Kubernetes集群部署在线下IDC或者其他云厂商,请确保已通过专线或者VPN网关等方式打通IDC和云上网络。
 
准备工作
操作前,请准备创建虚拟节点所需的参数信息,并了解虚拟节点所需的权限信息。需要准备的参数如下表所示。
| 参数 | 描述 | 操作 | 
|---|---|---|
| 地域(region) | 地域指的是物理的数据中心。请根据您以及您目标用户所在的地理位置,资源价格等因素选择合适的地域。 不同地域云产品之间内网不互通;建议选择最靠近您目标用户的地域,以降低访问延时,创建成功后 不支持 更换地域  | 
您可以通过容器实例BCI控制台获取所支持的地域信息。 | 
| 私有网络(VPC) | 私有网络(Virtual private Cloud,VPC) 是用户自定义的虚拟网络,,不同的专有网络之间逻辑上彻底隔离。 更多信息,请参考 私有网络 VPC。  | 
您可以在私有网络控制台的创建并查看专有网络。 | 
| 子网(subnet) | 子网是 VPC 内的用户可定义的IP地址范围,在私有网络VPC中创建BCI及其相关资源时,需要指定子网(subnet)。 更多信息,请参考 私有网络 VPC - 子网。  | 
您可以在私有网络子网控制台的创建并查看子网,根据已选的VPC来选择对应的子网。 | 
| 安全组(securityGroup) | 安全组是一种虚拟防火墙,可以控制组内资源的进出流量,从而提高网络安全性。 更多信息,请参考 私有网络 VPC - 安全组。  | 
您可以在私有网络安全组控制台的创建并查看安全组,根据已选的VPC来选择对应的安全组。 | 
| AK/SK | AK(Access Key ID)/SK(Secret Access Key)用于对用户的调用行为进行鉴权和认证,相当于百度智能云API专用的用户名及密码。 更多信息,请参考 AK/SK简介。  | 
您可以在管理控制台获取AK/SK。 | 
| BCI API 服务域名 | BCI对外暴露的正式OpenAPI的Endpoint | 您可以在 BCI线上文档,根据不同的地域获取不同OpenAPI地址。 | 
步骤一:签发证书
需要签发virtual-kubelet(VK)使用的双向客户端证书用于API端点认证,以及kube-proxy sidecar使用的证书(可选)。
签发证书依赖cfssl工具,集群CA证书和CA Key,集群以及CA Config。
- 准备访问集群的 hosts 列表:
 
- 集群的公网访问地址(如有):可以直接从 kubeconfig 文件中,server 字段获取
 - apiserver 的集群内访问地址:
 
                Plain Text
                
            
            1kubectl get svc kubernetes
            
完整的 Hosts 列表:
                Plain Text
                
            
            1"hosts": [
2    "${公网访问地址}"(如有),
3    "${集群内访问地址}",
4    "*.cluster.local", 
5    "127.0.0.1"
6]
            - 签发VK客户端证书:
 
                Plain Text
                
            
            1# 准备自建集群的CA证书及配置文件,一般在k8s master节点的 /etc/kubernetes/pki 目录下,获取的相关文件如下:
2$ ls 
3ca-config.json  ca-key.pem  ca.pem
4
5# 设置 CA_PATH 环境变量,将存放CA证书的目录设置为环境变量 ${CA_PATH}
6$ export CA_PATH=`pwd`
7
8# 设置 CA_PROFILE 环境变量,将CA配置文件中定义的证书签发策略名保存到环境变量中
9$ export CA_PROFILE=$(jq -r '.signing.profiles | to_entries[0].key' ca.config)
10
11# 创建vk证书签发的csr文件
12$ cat >vk-csr.json <<EOF
13{
14  "CN": "system:node",
15  "hosts": [
16   "xx.xx.xx.xx", #用户集群的公网访问 IP,如192.168.0.17
17   "yy.yy.yy.yy", #用户集群的集群内访问 IP,如192.168.18.4。可通过kubectl cluster-info获取
18   "*.cluster.local", 
19   "127.0.0.1"
20  ],
21  "key": {
22    "algo": "rsa",
23    "size": 2048
24  },
25  "names": [
26    {
27      "C": "CN",
28      "ST": "BeiJing",
29      "L": "BeiJing",
30      "O": "system:node",
31      "OU": "cloudnative"
32    }
33  ]
34}
35EOF
36
37# 使用cfssl生成证书
38$ cfssl gencert -ca=${CA_PATH}/ca.pem -ca-key=${CA_PATH}/ca-key.pem -config=${CA_PATH}/ca-config.json -profile=${CA_PROFILE} vk-csr.json | cfssljson -bare vk
39
40# 证书文件
41$ ls
42vk.csr  vk-csr.json  vk-key.pem  vk.pem
            签发kube-proxy sidecar证书(可选):
                Plain Text
                
            
            1# 设置 CA_PATH 以及 CA_PROFILE 变量,方法同上
2$ ls ${CA_PATH}
3ca-config.json  ca-key.pem  ca.pem
4
5# 创建kube-proxy证书签发的csr文件
6$ cat >kube-proxy-csr.json <<EOF
7{
8  "CN": "system:kube-proxy",
9  "hosts": [
10   "xx.xx.xx.xx", #用户集群的公网访问 IP,如192.168.0.17   
11   "yy.yy.yy.yy", #用户集群的集群内访问 IP,如192.168.18.4。可通过kubectl cluster-info获取   
12   "*.cluster.local",
13   "127.0.0.1"
14   ],
15  "key": {
16    "algo": "rsa",
17    "size": 2048
18  },
19  "names": [
20    {
21      "C": "CN",
22      "ST": "BeiJing",
23      "L": "BeiJing",
24      "O": "system:kube-proxy",
25      "OU": "cloudnative"
26    }
27  ]
28}
29EOF
30
31# 使用cfssl生成证书
32$ cfssl gencert -ca=${CA_PATH}/ca.pem -ca-key=${CA_PATH}/ca-key.pem -config=${CA_PATH}/ca-config.json -profile=${CA_PROFILE} kube-proxy-csr.json | cfssljson -bare kube-proxy
33
34# 证书文件
35$ ls
36kube-proxy.csr  kube-proxy-csr.json  kube-proxy-key.pem  kube-proxy.pem
            将生成的vk.pem, vk-key.pem, kube-proxy.pem, kube-proxy-key.pem置于同一目录下,生成证书secret:
                Plain Text
                
            
            1$ ls
2kube-proxy.csr  kube-proxy-csr.json  kube-proxy-key.pem  kube-proxy.pem  vk.csr  vk-csr.json  vk-key.pem  vk.pem
3
4# 需指定namespace为kube-system
5$ kubectl -n kube-system create secret generic vk-certs --from-file ./ 
            步骤二:创建AK/SK secret
您可以在管理控制台获取AK/SK,然后将AK/SK保存到用户自建集群的secret中。
                Plain Text
                
            
            1# 需指定namespace为kube-system
2$ kubectl -n kube-system create secret generic vk-aksk \
3  --from-literal=ak=<Your AK> \
4  --from-literal=sk=<Your SK>
            步骤三:部署virtual-kubelet
                Plain Text
                
            
            1$ helm repo add bce-public https://kubernetes-charts.baidubce.com/public 
2# 需指定namespace为kube-system
3$ helm -n kube-system install vk -f values.yaml bce-public/cce-virtual-kubelet
            参考values.yaml如下
                Plain Text
                
            
            1# Default values for bci-virtual-kubelet.
2# This is a YAML-formatted file.
3# Declare variables to be passed into your templates.
4
5# Virtual kubelet image. Keep the tag empty to use the default tag.
6images:
7  virtualKubelet: # Virtual kubelet image. Keep the tag empty to use the default tag.
8    repository: "registry.baidubce.com/cce-plugin-pro/bci-virtual-kubelet"
9    tag: "bciv2"
10  kubectl: # Kubectl image. Keep the tag empty to use the default tag.
11    repository: "registry.baidubce.com/cce-plugin-pro/kubectl"
12    tag: ""
13
14# Maximum log backups for virtual kubelet. Each log file will consume 256MiB disk space.
15maximumLogBackups: "4"
16# 必填项,地域简称. 取值项: bj,su,gz,bd,hkg,fwh
17region: ""
18
19# 必填项,用户自建集群的cluster id. 需要保证唯一性。
20clusterID: ""
21
22# Attributes of BCI pods running on the virtual node.
23bci:
24  # Subnet list, specify one subnet at least.
25  # If multiple subnets are specified, one subnet will be randomly chosen for each pod creation attempt.
26  # 必填项,subnets
27  subnets:
28  - zone: ""
29    subnetID: ""
30  - zone: ""
31    subnetID: ""
32  # 必填项,securityGroupID,Security group applied on pod.
33  securityGroupID: ""
34
35# Attributes of virtual node.
36virtualNode:
37  # Virtual node count to create, default 1.
38  nodeCount: 1
39  # The virtual nodes will be named as ${nodeNamePrefix}-0, ${nodeNamePrefix}-1, ...
40  nodeNamePrefix: "bci-virtual-kubelet"
41  # CPU capacity.
42  cpuCapacity: "1000"
43  # Memory capacity.
44  memoryCapacity: "4Ti"
45  # Pods capacity.
46  podsCapacity: "1000"
47  # IPs capacity.
48  ipsCapacity: "1000"
49  # ENIs capacity.
50  enisCapacity: "1000"
51  # Ephemeral-storage capacity.
52  ephemeralStorageCapacity: "40Ti"
53  # Enable NodeLease or not. NodeLease is only available for k8s version > 1.14
54  enableNodeLease: true
55  # Enable pod cache or not.
56  enablePodCache: true
57
58# Keep the endpoints empty to use the default values. Override them if needed.
59endpoints:
60  # 必填项,BCI 在目标地域 OpenAPI Endpoint
61  bci: ""
            安装参数说明(带有*号的参数为用户必填项):
| 参数 | 描述 | 获取方式 | 示例 | 
|---|---|---|---|
| region* | 地域 | 填写所在地域的英文缩写,仅支持开放BCI产品的地域 | bj | 
| clusterID* | 集群id,用于区分不同k8s集群的标识,会在BCI页面显示 | 保证对于不同集群不重复即可,长度不可超过20个字符 | k8s-xxxxxxxx | 
| bci.subnets* | 创建BCI的子网信息,需要填写子网id和子网所属可用区。至少填写一个子网;指定多个子网时,每次创建会从子网列表中随机选择一个。 | 从私有网络VPC-子网页面获取 | - subnetID: sbn-4syxw5hsuc7e zone: zoneC  | 
| bci.securityGroupID* | 安全组ID | 从私有网络VPC-安全组页面获取 | g-f90242zt83dd | 
| images.virtualKubelet.repository | virtual-kubelet镜像repository,需要覆盖默认值时填写 | - | registry.baidubce.com/cce-plugin-pro/bci-virtual-kubelet | 
| images.virtualKubelet.tag* | virtual-kubelet镜像tag | - | bciv2 | 
| images.kubectl.repository | kubectl镜像repository,需要覆盖默认值时填写 | - | registry.baidubce.com/cce-plugin-pro/kubectl | 
| maximumLogBackups | virtual-kubelet组件日志文件保留,每份日志文件将占用所在节点/var/log下256Mi空间 | - | "4" | 
| virtualNode.nodeCount | 需要创建的虚拟节点数量,默认为1 | - | 1 | 
| virtualNode.nodeNamePrefix | 虚拟节点名称前缀,虚拟节点将按照 <前缀>-0 , <前缀>-1 , ... 依次命名  | 
- | bci-virtual-kubelet | 
| virtualNode.cpuCapacity | 虚拟节点CPU Capacity | - | "1000" | 
| virtualNode.memoryCapacity | 虚拟节点Memory Capacity | - | "4Ti" | 
| virtualNode.podsCapacity | 虚拟节点Pods Capacity | - | "1000" | 
| virtualNode.ephemeralStorageCapacity | 虚拟节点Ephemeral Storage Capacity | - | "40Ti" | 
| virtualNode.enableNodeLease | 是否开启Node Lease,K8S 1.14版本以上建议开启 | - | true | 
| virtualNode.enablePodCache | 是否开启Pod Cache,可以提升Pod并发创建性能,无特殊需求建议开启 | - | true | 
| endpoints.apiserver | BCI中kube-proxy sidecar访问K8S APIServer的端点,不用可以留空 | - | "https://192.168.0.1:6443" | 
| endpoints.bci | BCI服务Endpoint,默认为空则使用默认值,需要覆盖时填写 | - | "bci.bj.baidubce.com" | 
安装成功后,在集群中执行kubectl get node,看到对应的虚拟节点创建即可。
步骤四:配置反亲和性策略
由于VNode不是真实节点,因此无法运行DaemonSet。创建VNode后,您需要修改kube-proxy的DaemonSet,配置nodeAffinity来禁止DaemonSet调度到VNode。相关配置如下:
- 执行以下命令修改DaemonSet配置。
 - 配置nodeAffinity。在spec>template>spec下添加以下YAML:
 
                Plain Text
                
            
            1affinity:
2  nodeAffinity:
3    requiredDuringSchedulingIgnoredDuringExecution:
4      nodeSelectorTerms:
5      - matchExpressions:
6        - key: type
7          operator: NotInvalues:
8          - virtual-kubelet
            