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
参数 | 说明 |
| 匹配Kubernetes Node Labels中的 |
| Kubernetes定义的Labels selector operator,主要包含如下四种操作符:
|
| 匹配Kubernetes Node Labels Key对应的 |
根据需要选择定义资源拓扑的方式,即LVM或Quotapath,进而初始化定义节点上的本地存储资源。
使用LVM定义资源拓扑
通过LVM定义资源拓扑,支持以下三种方式:
type: device
:通过Node Resource Manager组件所在宿主机上的块设备devices
进行LVM的声明,声明的块设备会组成一个volumegroup
,volumegroup
的名称由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
相关参数说明如下表所示:
参数 | 说明 |
| 在挂载块设备时使用的参数。 |
| 格式化块设备使用的文件系统,默认使用 |
| 挂载使用的块设备,可声明多个块设备。在多个块设备的情况下,将依次尝试挂载,直到挂载成功。 |
步骤二:部署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组件不会删除任何资源。