标签 (Label)

Label 是 Kubernetes 系统中的一个核心概念。Label 以 key/value 键值对的形式附加到任何对象上,如 Pod,Service,Node,RC(ReplicationController)/RS(ReplicaSet)等。Label 可以在创建对象时就附加到对象上,也可以在对象创建后通过 API 进行额外添加或修改。

在为对象定义好 Label 后,其他对象就可以通过 Label 来对对象进行引用。Label 的最常见的用法便是通过spec.selector来引用对象。下面是文章:Kubernetes 对象之 ReplicaSet 中新建一个 RC 的例子:

apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80

关于 Label 的用法重点在于这两步:

  • 通过template.metadata.labels字段为即将新建的 Pod 附加 Label。在上面的例子中,新建了一个名称为 nginx 的 Pod,它拥有一个键值对为app:nginx的 Label。
  • 通过spec.selector字段来指定这个 RC 管理哪些 Pod。在上面的例子中,新建的 RC 会管理所有拥有app:nginxLabel 的 Pod。这样的spec.selector在 Kubernetes 中被称作Label Selector

Label 的定义

我们通常使用metadata.labels字段,来为对象添加 Label。Label 可以为多个。一个简单的例子如下:

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
    release: stable
spec:
  containers:
    - name: nginx
      image: nginx
      ports:
        - containerPort: 80

上面的描述文件为名为 nginx 的 Pod 添加了两个 Label,分别为app: nginxrelease: stable

常见的 Label

一般来说,我们会给一个 Pod(或其他对象)定义多个 Label,以便于配置,部署等管理工作。例如:部署不同版本的应用到不同的环境中;或者监控和分析应用(日志记录,监控,报警等)。通过多个 Label 的设置,我们就可以多维度的 Pod 或其他对象进行精细化管理。一些常用的 Label 示例如下:

relase: stable
release: canary
environment: dev
environemnt: qa
environment: production
tier: frontend
tier: backend
tier: middleware
......

Label 是自定义的一些 key/value 对,你可以随心所欲的设置。

Label Selector

带有 Label 的对象创建好之后,我们就可以通过 Label Selector 来引用这些对象。

通常我们通过描述文件中的spec.selector字段来指定 Label,从而 Kubernetes 寻找到所有包含你指定 Label 的对象,进行管理。

Kubernetes 目前支持两种类型的 Label Selector:

  • 基于等式的 Selector(Equality-based)
  • 基于集合的 Selector(Set-based)

RC 只支持基于等式的 Selector,而 RS 两种 Selector 都支持。

基于等式的 Selector

上文中创建 RC 的例子中的使用的就是基于等式的 Selector。基于等式的 Selector 通过等式类的表达式来进行筛选。例如:

  • app=nginx 选择所有 Label 中 key 为 app,value 为 nginx 的对象。
  • env!=dev 选择所有 Label 中 key 为 env,value 不等于 dev 的对象。

基于集合的 Selector

基于集合的 Selector 通过集合操作的表达式来进行筛选。例如:

  • name in (redis-master, redis-slave) 选择所有 Label 中 key 为 name,并且 value 为 redis-master 或 redis-slave 的对象。
  • env not in (dev) 选择所有 Label 中 key 为 env,并且 value 不为 dev 的对象。

使用 Label 可以给对象创建一组或多组标签,Service,RC/RS 等组件则通过 Label Selector 来定位需要管理的对象,Label 和 Label Selector 共同构成了 Kubernetes 系统中最核心的应用模型,使得对象能够精细分组,同时实现了集群的高可用性。

对 node 添加标签

kubectl label nodes <node-name> <label-key>=<label-value>

eg:

$ kubectl get nodes
NAME         STATUS   ROLES    AGE    VERSION
k8s-master   Ready    master   171m   v1.14.0
k8s-node1    Ready    <none>   169m   v1.14.0
k8s-node2    Ready    <none>   169m   v1.14.0
$ kubectl label nodes k8s-master traefik=proxy
node/k8s-master labeled
$ kubectl get nodes --show-labels
NAME         STATUS   ROLES    AGE    VERSION   LABELS
k8s-master   Ready    master   172m   v1.14.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,traefik=proxy,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master,kubernetes.io/os=linux,node-role.kubernetes.io/master=
k8s-node1    Ready    <none>   171m   v1.14.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node1,kubernetes.io/os=linux
k8s-node2    Ready    <none>   171m   v1.14.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node2,kubernetes.io/os=linux

label 的其他操作

删除 label, 使用 key 与减号相连, 如:

kubectl label nodes k8s-master traefik-

为各种资源添加标签:

kubectl label svc test1 test=test1 -n test
kubectl label rc test-controller test=test1 -n test
kubectl label rs test-set test=test1 -n test

污点标记

使用 Taint 规则,将拒绝 Pod 在 Node 上运行。

Taint 需要和 Tolerations 配合使用,让 Pod 避开那些不合适的 Node。在 Node 上设置一个或多个 Taint 之后,除非 Pod 明确声明能够容忍这些“污点”,否则无法在这些 Node 上运行。Toleration 是 Pod 的属性,让 Pod 能够运行在标注了 Taint 的 Node 节点上。

  1. 使用 kubectl taint 命令为 Node 设置 Taint 信息:
kubectl taint nodes nodeName key=value:NoSchedule
# 比如: 禁止 k8s-master1 部署 pod
kubectl taint nodes k8s-master1 node-role.kubernetes.io/master=true:NoSchedule

为 node 节点的 k8s-master 加上一个 Taint, Taint 的键为 Key,值为 value, Taint 的效果是 NoSchedule。这里表示的含义是任何 Pod 都不能调度到这个节点,除非设置了 toleration.

  1. 删除节点上的 taint
kubectl taint nodes --all key:NoSchedule-

默认的 master 节点是不能调度应用 pod 的,需要给 master 节点消除污点标记

kubectl taint nodes --all node-role.kubernetes.io/master-

容忍标记

在 Pod 中定义容忍(Tolerate)具有该 Taint 的 Node,使得 Pod 可以被调度到这个节点:

tolerations:
  - key: "key"
    operator: "Equal"
    value: "value"
    effect: "NoSchedule"

或者

tolerations:
  - key: "key"
    operator: "Exists"
    effect: "NoSchedule"
    tolerationSeconds: 6000
  • value 的值可以为 NoSchedule、PreferNoSchedule 或 NoExecute。
  • tolerationSeconds 是当 pod 需要被驱逐时,可以继续在 node 上运行的时间。

node(s) didn't match node selector

报错如:

0/3 nodes are available: 3 node(s) didn't match node selector.

如果指定的 label 在所有 node 上都无法匹配,则创建 Pod 失败,会提示无法调度

对应 yaml 的 nodeSelector 字段, 如:

---
spec:
  nodeSelector:
    traefik: proxy

需要为 node 指定标签

kubectl label nodes <node-name> <label-key>=<label-value>

比如:

kubectl label nodes k8s-node1 traefik=proxy

如果要删除标签:

kubectl label nodes --all traefik-

MIT Licensed | Copyright © 2018-present 滇ICP备16006294号

Design by Quanzaiyu | Power by VuePress