金山云KCE集群对接KCI

最近更新时间:2023-09-12 17:04:26

查看PDF

如果您已经通过金山云容器服务(Kingsoft Container Engine,简称KCE)创建Kubernetes集群,可以通过集群中部署虚拟节点的方式来接入KCI,使用KCI来承载弹性业务。下面将介绍如何在KCE集群中创建虚拟节点。

前提

  • 您已经开通容器实例服务。
  • 您已经在金山云容器服务提前创建好一个Kubernetes集群,操作步骤详见创建集群

注意:当前版本KCI中虚拟节点仅支持适配kubenetes v1.23以下的版本,请确保您创建的容器服务集群对应的kubenetes版本小于v1.23

步骤1:配置Kubeconfig

登录容器服务控制台,获取集群kubeconfig文件,导入集群node节点。以导入路径为“/root/.kube/config”为例,创建secret保存到集群里,供后续virtual-kubelet挂载使用。

kubectl create secret generic --from-file=config=/root/.kube/config rbkci-kubeconfig-secret -n kube-system   # /root/.kube/config 可替换为实际保存路径

步骤2:创建KCI相关的RBAC资源

登录KCE中的目标集群,验证集群中有无system:kubelet-api-admin这个clusterrole,若没有需通过下述配置创建,若已有则跳过此步:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: system:kubelet-api-admin
rules:
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - proxy
- apiGroups:
  - ""
  resources:
  - nodes/log
  - nodes/metrics
  - nodes/proxy
  - nodes/spec
  - nodes/stats
  verbs:
  - '*'

创建KCI相关的RBAC资源:

# kubectl apply -f rbkci-rbac.yaml
serviceaccount/kcilet-client created
clusterrolebinding.rbac.authorization.k8s.io/kcilet-rb created
serviceaccount/rbkci-virtual-kubelet-sa created
clusterrolebinding.rbac.authorization.k8s.io/rbkci-virtual-kubelet-rb created

rbkci-rbac.yaml详情如下:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: kcilet-client
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kcilet-rb
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: system:kubelet-api-admin
subjects:
  - apiGroup: ""
    kind: ServiceAccount
    name: kcilet-client
    namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: virtual-kubelet-sa
  namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: virtual-kubelet-rb
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
  - apiGroup: ""
    kind: ServiceAccount
    name: virtual-kubelet-sa
    namespace: kube-system

步骤3:基于virtual-kubelet组件创建虚拟节点

您需要通过部署virtual-kubelet组件来创建虚拟节点,部署前需准备如下信息:

环境变量 含义 是否必填
KCI_ACCESS_KEY 用户AccessKey,如何获取AccessKey,请参考为IAM子用户创建访问密钥 否,若未提供TEMP_AKSK_CM则必填
KCI_SECRET_KEY 用户SecretKey,如何获取SecretKey,请参考为IAM子用户创建访问密钥 否,若未提供TEMP_AKSK_CM则必填
TEMP_AKSK_CM KCE集群中临时AK/SK configmap name,见kube-system命名空间下,原始名称为user-temp-aksk 否,若未提供KCI_ACCESS_KEY和KCI_SECRET_KEY则必填
KCI_CLUSTER_ID 集群ID,若该集群是金山云容器服务的集群,则为ClusterId; 若集群是自建集群,则用户自定义一个唯一标识作为集群ID,建议使用uuid格式
KCI_REGION 地域名称,查询容器实例支持的地域,请参考支持地域 否,使用TEMP_AKSK_CM时可不填,使用KCI_ACCESS_KEY和KCI_SECRET_KEY时必填
KCI_SUBNET_ID 容器实例部署的子网
KCI_SECURITY_GROUP_IDS 容器实例所属的安全组,支持设置多个,请以","分割,最多允许设置3个
KCI_HOST_ALIASES 若需使用自建镜像仓库,在vk级别配置实例hostAliases,生效于该vk所管理的实例底层系统内,用于解析镜像仓库地址,必须为json字符串格式(参考Adding additional entries with hostAliases
KCI_DNS_CONFIG 若需使用自建镜像仓库,在vk级别配置实例dnsconfig,生效于该vk所管理的实例底层系统内,用于解析镜像仓库地址,必须为json字符串格式(参考Pod’s DNS Config
VKUBELET_POD_IP virtual-kubelet的pod的InternalIP,固定值,引入virtual-kubelet的pod.status.podIP
KCI_BASE_IMAGE vk全局指定所管理的所有实例使用的基础镜像(对配置该值后创建的实例生效)
KCI_INSTANCE_FAMILY vk全局指定自动匹配机型,如用户创建Pod时未通过Annotation指定机型套餐,则会根据Pod的规格从自动匹配机型中按顺序依次自动匹配套餐
KCI_PROJECT_ID vk全局指定所管理的所有实例使用的项目ID(对配置该值后创建的实例生效)

按照如下示例部署virtual-kubelet组件,替换示例中的对应参数值。rbkci-vk.yaml示例如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: rbkci-virtual-kubelet
  namespace: kube-system
  labels:
    k8s-app: rbkci-virtual-kubelet
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: rbkci-virtual-kubelet
  template:
    metadata:
      name: rbkci-virtual-kubelet
      labels:
        k8s-app: rbkci-virtual-kubelet
    spec:
      serviceAccountName: virtual-kubelet-sa
      containers:
        - name: virtual-kubelet
          image: hub.kce.ksyun.com/ksyun/rbkci-virtual-kubelet:v1.5.0
          args:
            # 自定义虚拟节点名称,默认值为rbkci-virtual-kubelet
            - --nodename=rbkci-virtual-kubelet
            # 指定虚拟节点的DNS配置,KCE集群为集群内coredns服务的IP地址
            - --cluster-dns=10.254.0.10
            # 指定集群域名,KCE集群默认为‘cluster.local’
            - --cluster-domain=cluster.local
            # 指定集群kubeconfig文件路径,值为kubeconfig volume对应的mountPath
            - --kcilet-kubeconfig-path=/root/.kube/config
            # kubernetes版本大于等于1.13建议启用lease资源用于节点心跳
            - --enable-node-lease
            # 虚拟节点管理的所有实例使能kube-proxy
            - --kube-proxy-enable
            # 节点管理的所有实例基础系统盘大小,单位GB,范围20-500GB,Local_SSD最大100GB,其他类型最大500GB。该值为空时CPU机型默认为20GB,GPU机型默认为50GB
            - --base-system-disk-size=50
          imagePullPolicy: Always
          env:
            - name: VKUBELET_POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: TEMP_AKSK_CM
              value: user-temp-aksk 
            - name: KCI_CLUSTER_ID
              value: ${cluster_id} 
            - name: KCI_SUBNET_ID
              value: ${subnet_id}
            - name: KCI_SECURITY_GROUP_IDS
              value: ${security_group_ids} 
          volumeMounts:
            - mountPath: /root/.kube
              name: kubeconfig
            - mountPath: /var/log/kci-virtual-kubelet
              name: kci-provider-log
      volumes:
        - name: kubeconfig
          secret:
            secretName: rbkci-kubeconfig-secret
        - name: kci-provider-log
          hostPath:
            path: /var/log/kci-virtual-kubelet

部署并验证:

# kubectl apply -f rbkci-vk.yaml

# kubectl get deployment -n kube-system | grep rbkci
rbkci-virtual-kubelet                 1/1     1            1           35s

# kubectl get node 
NAME                    STATUS   ROLES    AGE    VERSION
192.168.1.106           Ready    master   127d   v1.21.3
192.168.1.141           Ready    master   127d   v1.21.3
192.168.1.149           Ready    master   127d   v1.21.3
192.168.3.212           Ready    node     51d    v1.21.3
192.168.3.73            Ready    node     51d    v1.21.3
rbkci-virtual-kubelet   Ready    agent    40s    v1.19.3-vk-v1.5.0

步骤4:调度KCI容器实例到虚拟节点

通过YAML创建

Kubernetes集群通过虚拟节点创建Pod到KCI时,可以通过在 yaml 中定义 annotation 的方式,实现为 Pod 绑定安全组、分配资源等能力。 KCI目前支持的Annotation列表如下:

Annotation Key Annotation Value示例 是否必填 描述
k8s.ksyun.com/kci-instance-cpu 4 指定容器实例CPU核数,单位:核
k8s.ksyun.com/kci-instance-memory 8 指定容器实例内存,单位:GiB
k8s.ksyun.com/kci-instance-type 如’S3.2A’, ‘S6.4B’ 指定云服务器资源套餐类型,支持选择多个,以逗号分隔
k8s.ksyun.com/kci-security-group-id xxxxxxxx,xxxxxxxxx 支持填写多个,virtual-kubelet启动时,通过配置参数设置默认安全组,所有创建在虚拟节点上的Pod默认使用virtual-kubelet配置的安全组创建KCI实例,如果用户希望使用同VPC下其他安全组创建KCI实例,需要通过注解方式显示指定安全组
k8s.ksyun.com/kci-subnet-id xxxxxxx virtual-kubelet启动时,通过配置参数设置默认的子网,所有创建在虚拟节点上的Pod默认在virtual-kubelet配置的子网下创建KCI实例,如果用户希望在同VPC下其他子网创建KCI实例,需要通过注解方式显示指定子网
k8s.ksyun.com/kci-kube-proxy-enabled ‘true’/ ‘false’ 默认值:‘false’。当为true时,为该pod开启kube-proxy,使该pod具备访问集群内ClusterIP类型服务的能力;否则不开启。
k8s.ksyun.com/kci-dns-config '{"nameservers":["1.1.1.1"],"options":[{"name":"ndots","value":"2"},{"name":"timeout","value":"3"}],"searches":["test1.com"]}' 使用自建镜像仓库时,若未在vk维度配置,可在实例维度配置dnsconfig,生效于实例底层系统内,用于解析镜像仓库地址,必须为json字符串格式(参考Pod’s DNS Config
k8s.ksyun.com/kci-host-aliases '[{"ip":"1.2.3.4","hostnames":["www.privaterepo1.com"]},{"ip":"2.3.4.5","hostnames":["www.privaterepo2.com"]}]' 使用自建镜像仓库时,若未在vk维度配置,可在实例维度配置hostAliases,生效于实例底层系统内,用于解析镜像仓库地址,必须为json字符串格式(参考Adding additional entries with hostAliases
k8s.ksyun.com/kci-base-system-disk-size “50” 设置实例基础系统盘大小,单位GB,默认20GB,范围20-500GB,Local_SSD最⼤100GB,其他类型最⼤500GB
k8s.ksyun.com/kci-base-system-disk-type Local_SSD/SSD3.0/EHDD 设置实例基础系统盘类型,⽀持三种类型:Local_SSD/SSD3.0/EHDD,该值为空时系统会⾃动适配
k8s.ksyun.com/kci-base-image xxxxxxx 指定容器实例的基础镜像ID
k8s.ksyun.com/kci-charge-type HourlyInstantSettlement/Spot 容器实例的计费方式,支持按小时实时结算和竞价型实例。不指定计费方式时,默认为按小时实时结算
k8s.ksyun.com/kci-spot-strategy SpotAsPriceGo 否,若k8s.ksyun.com/kci-charge-type设置为Spot则必填 竞价实例的抢占策略。
SpotAsPriceGo:系统自动出价,出价为固定折扣乘以列表价
k8s.ksyun.com/kci-retain-ip ‘true’/ ‘false’ 默认值:‘false’。当为true时,为该Pod开启固定IP功能。开启此功能的Pod,当Pod被销毁后默认会保留这个Pod的IP 24小时。24小时内重建同名的Pod,还能使用该IP。24小时以后,该IP有可能被其他Pod抢占。仅对statefulset、rawpod生效
k8s.ksyun.com/kci-retain-ip-hours “48” 修改Pod固定IP的保留时长,单位是小时。如Pod 销毁之后超过这个时长没有创建回来,IP将被释放。默认是24小时,最大可支持保留一年。仅对statefulset、rawpod生效
k8s.ksyun.com/kci-eip-allocation-id xxxxxxx 指定容器实例绑定的EIP实例ID
k8s.ksyun.com/kci-core-pattern “/tmp/cores/core.%h.%e.%p.%t” 设置容器实例的Core dump文件保存目录
k8s.ksyun.com/kci-http-registry 192.168.xx.xx:5000 使用HTTP协议的自建镜像仓库中的镜像创建容器实例时,需配置该Annotation使得容器实例使用HTTP协议拉取镜像,避免因协议不同而导致镜像拉取失败。支持配置多个仓库域名或IP,以逗号隔开
k8s.ksyun.com/kci-insecure-registry harbor.example.com 使用自签发证书的自建镜像仓库中的镜像创建容器实例时,需配置该Annotation来跳过证书认证,避免因证书认证失败而导致镜像拉取失败。支持配置多个仓库域名或IP,以逗号隔开
k8s.ksyun.com/kci-project-id “1700” 指定容器实例的项目ID
k8s.ksyun.com/kci-image-cache-id xxxxxxx 指定镜像缓存ID。
如果指定了镜像缓存id同时开启了自动匹配镜像缓存,则仍以指定的镜像缓存id为准,自动匹配镜像缓存的功能不会生效
k8s.ksyun.com/kci-auto-image-cache ‘true’/ ‘false’ 默认值:‘false’,当为true时,为该Pod开启自动匹配镜像缓存的功能

注:

  1. 若指定KCI Pod的规格,需要同时设置k8s.ksyun.com/kci-instance-cpuk8s.ksyun.com/kci-instance-memory参数。
  2. 除了通过指定CPU和内存的方式创建KCI实例,在对实例规格有特殊需求的场景(如:网络吞吐量、网卡队列数等),您也可以指定KCI实例底层所使用的云服务器套餐规格来创建实例,套餐规格可参考支持的云服务器类型
  3. 在不指定KCI规格或套餐时,金山云容器服务会自动规整KCI Pod的规格,详细计算方法请参考指定KCI Pod规格
  4. 虚拟节点创建时默认存在污点rbkci-virtual-kubelet.io/provider:kingsoftcloud,若要将容器实例调度到虚拟节点,可通过为pod配置容忍度或指定节点调度实现。
  5. 如您从私有镜像仓库拉取镜像,需配置镜像访问凭证,详细配置方法请参考此文档的镜像访问凭证章节。

您可以通过指定nodeName等方式将pod调度到KCI上运行,yaml示例如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-rbkci
  namespace: default
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
        annotations:
            k8s.ksyun.com/kci-instance-type: N3.2B  #指定N3机型,2核4G的云服务器为容器实例底层资源
        labels:
            app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
      nodeName: rbkci-virtual-kubelet  #指定nodeName将pod调度到虚拟节点上

验证

登录容器服务控制台,点击工作负载>Deployment>Pod列表,查询资源的创建状态。

image20211223145330660.png

登录容器实例控制台,查看KCI的创建情况。

image20211223145418021.png

后续操作

升级Virtual Kubelet

随容器实例功能迭代,Virtual Kubelet版本会相应进行更新,目前您可通过手动修改VK镜像版本的方式进行升级。具体操作步骤如下:

步骤1:将对应虚拟节点置为不可调度
# kubectl cordon rbkci-virtual-kubelet
node/rbkci-virtual-kubelet cordoned
步骤2:更新虚拟节点对应的Deployment镜像版本
# kubectl edit deployments.apps -n kube-system rbkci-virtual-kubelet

示例如下:

...
    spec:
      containers:
      - args:
        - --nodename=rbkci-virtual-kubelet
        - --cluster-dns=10.254.0.10
        - --cluster-domain=cluster.local
        - --kcilet-kubeconfig-path=/root/.kube/config
        env:
        - name: VKUBELET_POD_IP
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: status.podIP
        - name: TEMP_AKSK_CM
          value: user-temp-aksk
        - name: KCI_CLUSTER_ID
          value: b4327dda-bfeb-43b4-b424-d6dbcb1a388f
        - name: KCI_SUBNET_ID
          value: 588e25a2-e052-4620-913a-38519f59563c
        - name: KCI_SECURITY_GROUP_IDS
          value: 379103c8-2439-44ac-95e7-82e77e6fdf75
        image: hub.kce.ksyun.com/ksyun/rbkci-virtual-kubelet:v1.5.0    #将镜像tag改为最新版本
        imagePullPolicy: Always
        name: virtual-kubelet
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /root/.kube/config
          name: kubeconfig
        - mountPath: /var/log/kci-virtual-kubelet
          name: kci-provider-log
 ...  
步骤3:将对应节点恢复为可调度状态

在rbkci-virtual-kubelet Deployment滚动更新完成后,将对应节点恢复为可调度状态。

# kubectl uncordon rbkci-virtual-kubelet
node/rbkci-virtual-kubelet uncordoned

文档内容是否对您有帮助?

根本没帮助
文档较差
文档一般
文档不错
文档很好

在文档使用中是否遇到以下问题

内容不全,不深入
内容更新不及时
描述不清晰,比较混乱
系统或功能太复杂,缺乏足够的引导
内容冗长

更多建议

0/200

评价建议不能为空

提交成功!

非常感谢您的反馈,我们会继续努力做到更好!

问题反馈