Kubernetes部署与运维08 Label与Annotation

308 阅读9分钟

Kubernetes目前大约每年发布三次,由于迭代速度快,目前市场上绝大部分的教程相对陈旧。更重要的是,从Kubernetes 1.20开始,Kubernetes官方宣布逐步弃用Docker作为容器运行时,并计划在Kubernetes 1.24版本中完全移除对Docker作为容器运行时的支持。这意味着,从Kubernetes 1.24版本开始,将不能使用Docker作为容器运行时来运行Kubernetes节点上的Pods。因此,市场上关于直接使用containerd容器运行时的新版Kubernetes教程几乎没有,更重要的是因为的Kubernetes涉及到镜像需要单独配置才能获取,这无疑拉高了初学者门槛。本教程采用互联网的形式进行发布,便于保持与Kubernetes最新版的同步,尽量自包含,便于读者学习、实践。

关键字Kubernetes 1.32; containerd; nerdctl; debain 12

整体规划

为方便后续内容学习,本部分将基于【Kubernetes部署与运维07 Helm部署】中的环境开展KubernetesLabelAnnotation部署与学习。整体规划如下:

虚拟机名称IP地址主机名域名CPU核心内存角色
k8s_Master1_2G192.168.152.200master1master.rz22GBmaster
K8s_Worker1_2G192.168.152.201worker1worker1.rz12GBworker
K8s_Worker2_2G192.168.152.202worker2worker2.rz12GBworker

参见【Kubernetes部署与运维02 Nerdctl Rootful部署】,Kubernetes基础环境各组件与版本信息如下:

- nerdctl: v1.7.7
- containerd: v1.7.22
- runc: v1.1.14
- CNI plugins: v1.5.1
- BuildKit: v0.15.2
- Stargz Snapshotter: v0.15.1
- imgcrypt: v1.1.11
- RootlessKit: v2.3.1
- slirp4netns: v1.3.1
- bypass4netns: v0.4.1
- fuse-overlayfs: v1.13
- containerd-fuse-overlayfs: v1.0.8
- Kubo (IPFS): v0.29.0
- Tini: v0.19.0
- buildg: v0.4.1

Kubernetes版本号为1.32

理论知识

标签Label

【官方参考文档】

  • https://kubernetes.io/zh/docs/concepts/overview/working-with-objects/labels/

标签(Labels)是附加到Kubernetes对象(比如Pod)上的键值对。标签旨在用于指定对用户有意义且相关的对象的标识属性,但不直接对核心系统有语义含义。标签使用户能够以松散耦合的方式将他们自己的组织结构映射到系统对象,而无需客户端存储这些映射。标签可以在创建时附加到对象,随后可以随时添加和修改。每个对象都可以定义一组键/值标签。每个键对于给定对象必须是唯一的。具体说来,Label的作用如下:

  • 控制器Controller通过标签Label与选择器Selector来控制Pod生命周期及副本数;
  • 服务Service通过选择器Selector与标签LabelPod进行分组;
  • 影响调度;
  • 影响网络策略。

注解Annotation

【官方参考文档】

  • https://kubernetes.io/zh/docs/concepts/overview/working-with-objects/annotations/

可以使用Kubernetes注解为对象附加任意的非标识的元数据。客户端程序(例如工具和库)能够获取这些元数据信息。

可用标签或注解将元数据附加到Kubernetes对象。标签可以用来选择对象和查找满足某些条件的对象集合。相反,注解不用于标识和选择对象。注解中的元数据,可以很小,也可以很大,可以是结构化的,也可以是非结构化的,能够包含标签不允许的字符。

以下例子可用于说明哪些信息可使用注解进行记录:

  • 由声明性配置所管理的字段。将这些字段附加为注解,能够将它们与客户端或服务端设置的默认值、自动生成的字段以及通过自动调整大小或自动伸缩系统设置的字段区分开来;
  • 构建、发布或镜像信息(如时间戳、发布IDGit分支、镜像哈希、仓库地址);
  • 指向日志记录、监控、分析或审计仓库的指针;
  • 可用于调试目的的客户端库或工具信息:例如,名称、版本和构建信息;
  • 用户或者工具/系统的来源信息,例如来自其他生态系统组件的相关对象的URL;
  • 轻量级上线工具的元数据信息:例如,配置或检查点;
  • 负责人员的电话或呼机号码,或指定在何处可以找到该信息的目录条目,如团队网站;
  • 从用户到最终运行的指令,以修改行为或使用非标准功能。

虽然可将这类信息存储在外部数据库或目录中而不使用注解,但这样做就使得开发人员很难生成用于部署、管理、自检的客户端共享库和工具。

Kubernetes提供了注解相关的命令,其语法与标签完全一致,只是命令中使用的是kubectl annotate,而不是kubectl label。此外,也没有对应的--show-annotation参数。

案例实践

前期准备

同时开启K8s_Master1_2GK8s_Worker1_2GK8s_Worker2_2G三台虚拟机。

标签Label查看、添加与删除

【实践01-标签的查看、添加与删除】

使用Kubernetes 命令查看、添加与删除标签。

1)可使用kubectl get <type> <name> --show-labels命令查看标签。例如,查看当前所有节点的标签:

root@master1:~# kubectl get nodes --show-labels
NAME      STATUS   ROLES           LABELS
master1   Ready    control-plane   ...node-role.kubernetes.io/control-plane=,...
worker1   Ready    <none>          ...,kubernetes.io/os=linux
worker2   Ready    <none>          ...,kubernetes.io/os=linux

由于排版限制,略去部分列内容。

也可单独查看某一节点的标签:

root@master1:~# kubectl get nodes worker1 --show-labels
NAME      STATUS   ROLES    AGE   VERSION   LABELS
worker1   Ready    <none>   8h    v1.32.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=worker1,kubernetes.io/os=linux

2)可使用kubectl describe <type> <name>命令查看对象详细信息,其Labels部分包含有标签信息。例如,查看工作节点worker1的详细信息:

root@master1:~# kubectl describe nodes worker1
Name:               worker1
Roles:              <none>
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=worker1
                    kubernetes.io/os=linux

3)可使用kubectl label <type> <name> key=value命令为对象添加标签Label。例如,向工作节点worker1添加标签app(值为空):

root@master1:~# kubectl get nodes worker1 --show-labels
NAME      STATUS   ROLES    AGE   VERSION   LABELS
worker1   Ready    <none>   8h    v1.32.1   app=,...,kubernetes.io/os=linux

由于排版限制,略去部分列内容。添加标签app之后,查看工作节点worker1标签,app已经添加成功。对于同一个资源,其标签Labelkey是唯一的。因此,如果同一个资源对象上再次添加key相同的标签Lable,则必须使用--overwrite参数,进行覆盖。例如,将工作节点worker1的标签app更新为app=test

root@master1:~# kubectl label nodes worker1 app=test
error: 'app' already has a value (), and --overwrite is false

root@master1:~# kubectl label nodes worker1 app=test --overwrite
node/worker1 labeled

root@master1:~# kubectl get nodes worker1 --show-labels
NAME      STATUS   ROLES    AGE   VERSION   LABELS
worker1   Ready    <none>   8h    v1.32.1   app=test,...,kubernetes.io/os=linux

4)可使用kubectl label <type> <name> key-命令,直接删除之前添加的标签Label。也即,将之前添加标签Label的命令中key之后所有信息替换为减号-即可。例如,删除工作节点worker1之上的标签app=test

root@master1:~# kubectl label nodes worker1 app-
node/worker1 unlabeled

root@master1:~# kubectl get nodes worker1 --show-labels
NAME      STATUS   ROLES    AGE   VERSION   LABELS
worker1   Ready    <none>   8h    v1.32.1   ...,kubernetes.io/os=linux

删除标签app之后,工作节点worker1标签信息恢复至初始状态。

节点分配角色

【实践02- 为工作节点分配角色】

使用Kubernetes 命令为两个工作节点分配角色worker

1)在使用kubectl get nodes查看节点简略信息时,有一列为ROLES角色列:

root@master1:~# kubectl get nodes
NAME      STATUS   ROLES           AGE     VERSION
master1   Ready    control-plane   24h     v1.32.1
worker1   Ready    <none>          8h      v1.32.1
worker2   Ready    <none>          6h44m   v1.32.1

2)主节点master1ROLEScontrol-plane角色是该节点在初始化控制平面集群时,自动分配好的。而手动添加的计算节点是没有任何角色的,因此上面的输出中除了主节点master1之外,其他工作节点的ROLES列均为<none>(无)。角色其实就是通过Label实现的。使用kubectl get nodes --show-lables查看节点标签:

root@master1:~# kubectl get nodes --show-labels
NAME      LABELS
master1   ...kubernetes.io/hostname=master1,...,node-role.kubernetes.io/control-plane=,...
worker1   ...kubernetes.io/hostname=worker1,kubernetes.io/os=linux
worker2   ...kubernetes.io/hostname=worker2,kubernetes.io/os=linux

由于排版限制,略去部分列内容。对比三个节点标签,可以发现主节点master1相较于工作节点worker1worker2多出一个标签:node-role.kubernetes.io/control-plane=。而control-plane恰恰是主节点master1的角色。

3)可以采用手动为主节点master1、工作节点worker1worker2添加标签的方式,给它们分配角色:

root@master1:~# kubectl label nodes master1 node-role.kubernetes.io/master=
node/master1 labeled

root@master1:~# kubectl label nodes worker1 node-role.kubernetes.io/worker=
node/worker1 labeled

root@master1:~# kubectl label nodes worker2 node-role.kubernetes.io/worker=
node/worker2 labeled

root@master1:~# kubectl get nodes
NAME      STATUS   ROLES                  AGE     VERSION
master1   Ready    control-plane,master   24h     v1.32.1
worker1   Ready    worker                 9h      v1.32.1
worker2   Ready    worker                 6h52m   v1.32.1

注意,角色相应对的标签的key格式是固定的,以node-role.kubernetes.io/开头,后续跟的即为与角色相应的字符串。这里ROLES(角色)仅能起到供运维人员查看的作用。但是可以通过一些产品对角色起调用的作用,比如在公有云平台,可以根据不同的角色,生成指定的命令,向对应的节点安装对应的核心组件。

4)使用kubectl describe nodes worker1命令查看修改之后工作节点worker1的标签:

root@master1:~# kubectl describe nodes worker1
Name:               worker1
Roles:              worker
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=worker1
                    kubernetes.io/os=linux
                    node-role.kubernetes.io/worker=
...

注解Annotation查看、添加与删除

【实践03- 注解Annotation查看、添加与删除】

使用Kubernetes 命令查看工作节点worker1 注解并添加、删除app=test注解。

1)查看工作节点worker1的注解:

root@master1:~# kubectl describe nodes worker1
Name:               worker1
Roles:              worker
Labels:             beta.kubernetes.io/arch=amd64
...
Annotations:        kubeadm.alpha.kubernetes.io/cri-socket: unix:///var/run/containerd/containerd.sock
                    node.alpha.kubernetes.io/ttl: 0
                    projectcalico.org/IPv4Address: 192.168.152.201/24
                    projectcalico.org/IPv4IPIPTunnelAddr: 10.244.235.128
                    volumes.kubernetes.io/controller-managed-attach-detach: true

工作节点worker1的注解中含有【Kubernetes部署与运维04 Kubernetes集群创建-Calico网络插件部署】部分安装的Calico网络信息projectcalico.org/IPv4Addressprojectcalico.org/IPv4IPIPTunnelAddr

2)为工作节点worker1添加注解app=test

root@master1:~# kubectl annotate nodes worker1 app=test
node/worker1 annotated
root@master1:~# kubectl describe nodes worker1
Name:               worker1
Roles:              worker
Labels:             beta.kubernetes.io/arch=amd64
...
Annotations:        app: test
                    kubeadm.alpha.kubernetes.io/cri-socket: unix:///var/run/containerd/containerd.sock
                    node.alpha.kubernetes.io/ttl: 0
                    projectcalico.org/IPv4Address: 192.168.152.201/24
                    projectcalico.org/IPv4IPIPTunnelAddr: 10.244.235.128
                    volumes.kubernetes.io/controller-managed-attach-detach: true
...

3)删除之前添加的注解app

root@master1:~# kubectl annotate nodes worker1 app-
node/worker1 annotated
root@master1:~# kubectl describe nodes worker1
Name:               worker1
Roles:              worker
Labels:             beta.kubernetes.io/arch=amd64
...
Annotations:        kubeadm.alpha.kubernetes.io/cri-socket: unix:///var/run/containerd/containerd.sock
                    node.alpha.kubernetes.io/ttl: 0
                    projectcalico.org/IPv4Address: 192.168.152.201/24
                    projectcalico.org/IPv4IPIPTunnelAddr: 10.244.235.128
                    volumes.kubernetes.io/controller-managed-attach-detach: true
...

收尾工作

1)使用poweroff命令,关闭三台虚拟机。

2)AI时代背景之下,运维将从传统CPU服务器切入到GPU服务器与端边设备,对于运维开发人员,技术玩家而言,也同步需要跟上新的技术栈。本学习内容涉及到的软件包、配置文件等资源,可以直接从百度网盘下载获取:

  • 百度网盘分享文件:Kubernetes1.32
  • 链接:https://pan.baidu.com/s/18XeGQ28BDPjHh8JKj0uZFQ?pwd=6x17 提取码:6x17