全部产品
Search
文档中心

容器服务 Kubernetes 版 ACK:自动初始化本地存储资源

更新时间:Sep 06, 2023

Kubernetes集群中的本地存储资源一般通过手动或者使用Ansible进行批量初始化,但是这两种方式操作复杂且不适用于大规模集群,而Node Resource Manager组件根据ConfigMap的定义可自动初始化并更新当前节点上的本地存储资源。本文介绍如何通过Node Resource Manager组件实现本地存储资源的自动初始化。

背景信息

Kubernetes集群中的本地存储资源初始化一直是个令人困扰的问题,迄今为止一般手动或者使用Ansible进行批量初始化,但是这两种方式存在以下问题:

  • Ansible无法便捷的使用Kubernetes特有的节点信息进行定制化部署,需要提前安装Kubelet,执行shell command命令以及需要自助解析返回结果。

  • 在大规模集群中,手动登录节点部署本地存储资源是很难实现的。

  • 无法持续维护初始化的资源,若某个节点需要更新资源,则需要手动登录节点更新资源,且相关存储资源的使用信息无法上报,在Kubernetes调度Pod时无法被利用起来。

基于以上问题可通过Node Resource Manager组件实现本地存储资源的自动初始化。Node Resource Manager组件是一个简单易用的Kubernetes本地存储管理组件,可上报本地存储资源的使用信息,配合Scheduler自动化调度使用本地存储资源的Pod。关于Node Resource Manager组件的更多信息,请参见node-resource-manager

步骤一:通过ConfigMap定义资源所在节点

通过以下三个参数共同定义资源所在的节点。

key: kubernetes.io/hostname
operator: In
value: xxxxx

参数

说明

key

匹配Kubernetes Node Labels中的key值。

operator

Kubernetes定义的Labels selector operator,主要包含如下四种操作符:

  • In:只有value值与节点上Labels Key对应的value值相同时匹配。

  • NotIn:只有value值与节点上Labels Key对应的value值不相同时匹配。

  • Exists:只要节点的Labels上存在Key就会匹配。

  • DoesNotExist:只要节点的Labels上不存在Key就会匹配。

value

匹配Kubernetes Node Labels Key对应的value值。

根据需要选择定义资源拓扑的方式,即LVM或Quotapath,进而初始化定义节点上的本地存储资源。

使用LVM定义资源拓扑

通过LVM定义资源拓扑,支持以下三种方式:

  • type: device:通过Node Resource Manager组件所在宿主机上的块设备devices进行LVM的声明,声明的块设备会组成一个volumegroupvolumegroup的名称由name指定,供后续应用启动时分配Logical Volume。

  • type: alibabacloud-local-disk:通过Node Resource Manager组件所在宿主机上所有的本地盘(选择带有本地盘的ECS类型)共同创建一个名称为name值的volumegroup

    重要

    在使用本地SSD型 (i2)实例创建的ECS实例中,手动挂载的块设备为云盘,非本地盘。

  • type: pmem:通过Node Resource Manager组件所在宿主机上的PMEM资源创建一个名称为name值的volumegroup,其中regions可以指定当前机器上多个PMEM的region资源。

根据以下YAML示例,使用LVM定义资源拓扑:

apiVersion: v1
kind: ConfigMap
metadata:
  name: unified-resource-topo
  namespace: kube-system
data:
  volumegroup: |-
    volumegroup:
    - name: volumegroup1
      key: kubernetes.io/hostname
      operator: In
      value: cn-zhangjiakou.192.168.XX.XX
      topology:
        type: device
        devices:
        - /dev/vdb
        - /dev/vdc
    - name: volumegroup2
      key: kubernetes.io/nodetype
      operator: NotIn
      value: localdisk
      topology:
        type: alibabacloud-local-disk
    - name: volumegroup1
      key: kubernetes.io/hostname
      operator: Exists
      value: cn-beijing.192.168.XX.XX
      topology:
        type: pmem
        regions:
        - region0

使用Quotapath定义资源拓扑

通过Quotapath定义资源拓扑,支持以下两种方式:

  • type: device:通过Node Resource Manager组件所在宿主机的块设备初始化Quotapath,初始化路径是name字段定义的值。

  • type: pmem:通过Node Resource Manager组件所在宿主机的PMEM设备初始化Quotapath,初始化路径是name字段定义的值。

根据以下YAML示例,使用Quotapath定义资源拓扑:

apiVersion: v1
kind: ConfigMap
metadata:
  name: unified-resource-topo
  namespace: kube-system
data:
  quotapath: |-
    quotapath:
    - name: /mnt/path1
      key: kubernetes.io/hostname
      operator: In
      value: cn-beijing.192.168.XX.XX
      topology:
        type: device
        options: prjquota
        fstype: ext4
        devices:
        - /dev/vdb
    - name: /mnt/path2
      key: kubernetes.io/hostname
      operator: In
      value: cn-beijing.192.168.XX.XX
      topology:
        type: pmem
        options: prjquota,shared
        fstype: ext4
        regions:
        - region0

相关参数说明如下表所示:

参数

说明

options

在挂载块设备时使用的参数。

fstype

格式化块设备使用的文件系统,默认使用ext4

devices

挂载使用的块设备,可声明多个块设备。在多个块设备的情况下,将依次尝试挂载,直到挂载成功。

步骤二:部署Node Resource Manager组件

通过在集群中创建DaemonSet工作负载部署Node Resource Manager组件,YAML示例如下所示:

cat <<EOF | kubectl apply -f -
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: node-resource-manager
  namespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: node-resource-manager
rules:
  - apiGroups: [""]
    resources: ["configmaps"]
    verbs: ["get", "watch", "list", "delete", "update", "create"]
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["get", "list", "watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: node-resource-manager-binding
subjects:
  - kind: ServiceAccount
    name: node-resource-manager
    namespace: kube-system
roleRef:
  kind: ClusterRole
  name: node-resource-manager
  apiGroup: rbac.authorization.k8s.io
---
kind: DaemonSet
apiVersion: apps/v1
metadata:
  name: node-resource-manager
  namespace: kube-system
spec:
  selector:
    matchLabels:
      app: node-resource-manager
  template:
    metadata:
      labels:
        app: node-resource-manager
    spec:
      tolerations:
        - operator: "Exists"
      priorityClassName: system-node-critical
      serviceAccountName: node-resource-manager
      hostNetwork: true
      hostPID: true
      containers:
        - name: node-resource-manager
          securityContext:
            privileged: true
            capabilities:
              add: ["SYS_ADMIN"]
            allowPrivilegeEscalation: true
          image: registry.cn-hangzhou.aliyuncs.com/acs/node-resource-manager:v1.18.8.0-983ce56-aliyun
          imagePullPolicy: "Always"
          args:
            - "--nodeid=$(KUBE_NODE_NAME)"
          env:
            - name: KUBE_NODE_NAME
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: spec.nodeName
          volumeMounts:
            - mountPath: /dev
              mountPropagation: "HostToContainer"
              name: host-dev
            - mountPath: /var/log/
              name: host-log
            - name: etc
              mountPath: /host/etc
            - name: config
              mountPath: /etc/unified-config
      volumes:
        - name: host-dev
          hostPath:
            path: /dev
        - name: host-log
          hostPath:
            path: /var/log/
        - name: etc
          hostPath:
            path: /etc
        - name: config
          configMap:
            name: node-resource-topo
EOF

部署完成之后,组件会自动将ConfigMap中的配置应用到节点上。如果更新ConfigMap,组件会在一分钟内对资源更新。

重要

为了保障数据安全,Node Resource Manager组件不会删除任何资源。