Kubernetes控制节点的部署

标签和nodeSelector

标签(Label)是附加到 Kubernetes 对象上的键值对,如果用 json 表示附加到 metadata 的 label:

"metadata": {
  "labels": {
    "key1" : "value1",
    "key2" : "value2"
  }
}

yaml:

metadata:
  labels:
    key1: "value1"
    key2: "value2"

标签主要是用于表示对用户有意义的对象的属性标识。

可以给节点设定一些 Label,例如在 kube-system 命名空间中,运行着 Kubernetes 的核心组件,我们可以查看此命名空间中所有组件的 Label。

kubectl get nodes --namespace=kube-system --show-labels
beta.kubernetes.io/arch=amd64,
beta.kubernetes.io/os=linux,
kubernetes.io/arch=amd64,
... ...

我们也可以手动给一个 Node 添加标签。

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

例如我们给节点设置一个 disksize,表示节点的硬盘是否够大。

kubectl label nginx disksize=big

然后我们在编写 yaml 文件时,希望这个 pod 在容量大的 Node 上运行,可以这样写:

  nodeSelector:
    disksize=big

顺便聊一下官方的一个例子,设置 Node 的 Label,表示硬盘是 ssd。

kubectl label nodes kubernetes-foo-node-1.c.a-robinson.internal disktype=ssd

在 yaml 文件的节点选择器中,添加选择。

spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    disktype: ssd

Label 可以在多个地方使用,例如在 Node 上添加 Label,标识此 Node;而在 NodeSelector 里使用,可以选择合适的 Node 运行 Pod;在 metadata 中使用,可以对元数据加以描述。

在 metadata 中添加的 Label,可以在命令查询时做筛选。

查询 pod 的 Label:

kubectl get pods --show-labels

查找符合条件的 pod(参考 LABELS 字段,可以根据里面的标签选择):

kubectl get pods -l app=nginx

标签选择

在前面,我们学习了 nodeSelector ,可以帮助我们选择合适的 Node 运行 Pod,实际上 Kubernets 的标签选择是丰富多样的,例如:

  nodeSelector:
    disktype: ssd
    disksize: big

则表示节点选择器是等值选择,表达式是 disktype=ssd && disksize=big

标签选择有等值和集合两种,其中等值选择有 ===!= 三种,= 和 == 无区别。在多个需求(多个label)的情况下,相对于使用 && 运算符,但是选择器不存在 ||这种逻辑或运算符。

yaml 只支持 {key}:{value} 这种形式,而我们使用命令形式时,则可使用以上三种运算符。

kubectl get nodes -l disktype=ssd,disksize!=big
# 多个条件使用 逗号","" 隔开,而不是 "&&"。

对于集合选择方式,支持三种操作符:innotin 和 exists。不过别理解成是从集合中选择,下面举个例子。

假如有三个 Node,其 disksize 有 big、medium、small,我们要部署一个 pod,在 big、medium 中都可以运行,则:

... -l disksize in (big,medium)
... -l disksize notin (small)
# 不在 small 中运行

而 exists 则跟 != 类似,但是 exists 表示只要存在这个 label 即可,而不论其设置了是什么值。

-l disksize
# 等同 -l disksize in (big,medium,small)

我们也可以使用 '' 把选择表达式包起来。

kubectl get pods -l 'app=nginx'

前面已经提到了 yaml 的 nodeSelector 和 命令式的选择,这里我们介绍 yaml 的 selector。

前面我们提到在 Deployment 的 metadata 中加上 Label,即 pod 加上 Label,我们也在 kubectl get pods 中使用 Label 选择过滤 pod。同样,当我们创建 Service 或者使用 ReplicationController 时,也可以使用标签选择合适的 pod。

假如我们已经部署了 nginx,那么查询 kubectl get pods --show-labels 时,其 pod 的 LABELS 会有 app=nginx,那么我们可以这样选择:

  selector:
    app: nginx

完整版本:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 6666
status:
  loadBalancer:
    ingress:
      - ip: 192.0.2.127

selector 还支持以下选择方式 matchLabelsmatchExpressions

matchLabels 是由 {key,value} 对组成的映射。 matchLabels 映射中的单个 {key,value } 等同于 matchExpressions 的元素, 其 key 字段为 "key",operator 为 "In",而 values 数组仅包含 "value"。

matchExpressions 是 Pod 选择算符需求的列表。 有效的运算符包括 InNotInExists 和 DoesNotExist。 在 In 和 NotIn 的情况下,设置的值必须是非空的。 来自 matchLabels 和 matchExpressions 的所有要求都按逻辑与的关系组合到一起 -- 它们必须都满足才能匹配。

示例如下:

selector:
  matchLabels:
    component: redis
  matchExpressions:
    - {key: tier, operator: In, values: [cache]}
    - {key: environment, operator: NotIn, values: [dev]}

这里就不在详细说这些选择规则了,前面提到的已经够用了,读者可以查阅官方文档学习更多复杂的操作:https://kubernetes.io/zh/docs/concepts/overview/working-with-objects/labels/

亲和性和反亲和性

前面我们学习了 nodeSelector ,使用 nodeSelector 选择合适的 Label,可以表达我们约束的类型。

亲和性则类似于 nodeSelector,可以根据节点上的标签约束 pod 可以调度到哪些节点。

pod 亲和性有两种别为:

  • requiredDuringSchedulingIgnoredDuringExecution

    硬需求,将 pod 调度到一个节点必须满足的规则。

  • preferredDuringSchedulingIgnoredDuringExecution

    尝试执行但是不能保证偏好。

这是官方的一个例子:

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/e2e-az-name
            operator: In
            values:
            - e2e-az1
            - e2e-az2
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value
  containers:
  - name: with-node-affinity
    image: k8s.gcr.io/pause:2.0

亲和性的约束相对于:

... ... -l kubernetes.io/e2e-az-name in (e2e-az1,e2e-az2)

affinity 设置亲密关系,nodeAffinity 设置节点亲密关系,最后才到 亲和性,它们表示必须满足和尽量满足。

如果我们设置了多个 nodeSelectorTerms :

requiredDuringSchedulingIgnoredDuringExecution:
  nodeSelectorTerms:
  ...
  nodeSelectorTerms:

则只需要满足其中一种即可调度 pod 到 node 上。

如果你同时指定了 nodeSelector 和 nodeAffinity,两者必须都要满足, 才能将 Pod 调度到候选节点上。

节点亲和性语法支持下面的操作符: InNotInExistsDoesNotExistGtLt

Pod 亲和性与反亲和性的合法操作符有 InNotInExistsDoesNotExist

通过 -Affinity 可以设置亲和性,例如节点亲和性 nodeAffinity,而且设置反亲和性使用 -AntiAffinity,例如 nodeAntiAffinity

反亲和性跟亲和性一样,都有 requiredDuringSchedulingIgnoredDuringExecution 硬限制和 preferredDuringSchedulingIgnoredDuringExecution 软限制,只是反亲和性是相反的表示,如果符合条件则不能调度。

关于亲和性和反亲和性的说明就到这里,着两者的配置比较多和复杂,读者可以参考官方文档,这里不在赘述。

污点和容忍度

前面提到亲和性和反亲和性,我们加以通过 pod 选择合适的 node,或者 service 选择合适的 pod,这些拥有 Label 的对象都是被选择的。

这里,我们介绍污点和容忍度,它们可以排斥 “被选择” 的命运。

节点污点(taint) 可以排斥一类特定的 pod,而 容忍度(Tolerations)则表示能够容忍这个对象的污点。

当节点添加一个污点后,除非 pod 声明能够容忍这个污点,否则 pod 不会被调度到这个 节点上。

系统会 尽量 避免将 Pod 调度到存在其不能容忍污点的节点上, 但这不是强制的。Kubernetes 处理多个污点和容忍度的过程就像一个过滤器:从一个节点的所有污点开始遍历, 过滤掉那些 Pod 中存在与之相匹配的容忍度的污点。

但是如果你只有一个 worker,那么设置了污点,那 pod 也只能选择在这个节点上运行。

添加污点格式:

kubectl taint node [node] key=value:[effect]

更新污点或覆盖:

kubectl taint node [node] key=value:[effect] --overwrite=true

使用 kubectl taint 给节点增加一个污点。

kubectl taint nodes node1 key1=value1:NoSchedule

移除污点:

kubectl taint nodes node1 key1=value1:NoSchedule-

其中,污点需要设置 label ,并设置这个 label 的效果为 NoSchedule。

污点的效果称为 effect ,节点的污点可以设置为以下三种效果:

  • NoSchedule:不能容忍此污点的 Pod 不会被调度到节点上;不会影响已存在的 pod。
  • PreferNoSchedule:Kubernetes 会避免将不能容忍此污点的 Pod 安排到节点上。
  • NoExecute:如果 Pod 已在节点上运行,则会将该 Pod 从节点中逐出;如果尚未在节点上运行,则不会将其安排到节点上。

但是某些系统创建的 Pod 可以容忍所有 NoExecute 和 NoSchedule 污点,因此不会被逐出,例如 master 节点是不能被部署 pod 的,但是 kube-system 命名空间却有很多系统 pod。当然通过修改污点,可以让 户 pod 部署到 master 节点中。

查询节点的污点:

kubectl describe nodes | grep Taints
Taints:             node-role.kubernetes.io/master:NoSchedule
Taints:             key1=value1:NoSchedule

系统默认污点

我们去除 master 的污点:

kubectl taint node instance-1 node-role.kubernetes.io/master:NoSchedule-

然后部署 nginx pod。

kubectl create deployment nginxtaint --image=nginx:latest --replicas=3

查看 pod:

kubectl get pods -o wide

结果笔者查到三个副本都在 master 节点上。

为了保证集群安全,我们需要恢复 master 的污点。

kubectl taint node instance-1 node-role.kubernetes.io/master:NoSchedule

当某种条件为真时,节点控制器会自动给节点添加一个污点。当前内置的污点包括:

  • node.kubernetes.io/not-ready:节点未准备好。这相当于节点状态 Ready 的值为 "False"。
  • node.kubernetes.io/unreachable:节点控制器访问不到节点. 这相当于节点状态 Ready 的值为 "Unknown"。
  • node.kubernetes.io/out-of-disk:节点磁盘耗尽。
  • node.kubernetes.io/memory-pressure:节点存在内存压力。
  • node.kubernetes.io/disk-pressure:节点存在磁盘压力。
  • node.kubernetes.io/network-unavailable:节点网络不可用。
  • node.kubernetes.io/unschedulable: 节点不可调度。
  • node.cloudprovider.kubernetes.io/uninitialized:如果 kubelet 启动时指定了一个 "外部" 云平台驱动, 它将给当前节点添加一个污点将其标志为不可用。在 cloud-controller-manager 的一个控制器初始化这个节点后,kubelet 将删除这个污点。

容忍度

一个 node 可以设置污点,排斥 pod,但是 pod 也可以设置 容忍度,容忍 node 的污点。

tolerations:
- key: "key1"
  operator: "Exists"
  effect: "NoSchedule"

也可以设置 value。

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

operator 的默认值是 Equal

一个容忍度和一个污点相“匹配”是指它们有一样的键名和效果,并且:

  • 如果 operator 是 Exists

    此时容忍度不能指定 value,如果存在 key 为 key1 的 label,且污点效果为 NoSchedule,则容忍。

  • 如果 operator 是 Equal ,则它们的 value 应该相等

如果 effect 留空,则表示只要是 label 为 key1 的节点,都可以容忍。

如果:

tolerations:
  operator: "Exists"

则表示此 pod 能够容忍任意的污点,无论 node 怎么设置 keyvalue 、effect ,此 pod 都不会介意。

如果要在 master 上也能部署 pod,则可以修改 pod 的容忍度:

    spec:
      tolerations:
      # this toleration is to have the daemonset runnable on master nodes
      # remove it if your masters can't run pods
      - key: node-role.kubernetes.io/master
        effect: NoSchedule

DaemonSet

在 Kubernetes 中,有三个 -Set ,分别是 ReplicaSet、DaemonSet、StatefulSets。而 负载类型有 Deployments、ReplicaSet、DaemonSet、StatefulSets等(或者说有这几个控制器)。

前面已经介绍过 Deployments ,而 kind: ReplicaSet 一般是没必要的,可以在 kind: Deployment 加上 replicas: 

而 kind: DaemonSet 需要使用一个 yaml 来描述,但是整体跟 Deployment 一样。

DaemonSet 可以确保一个节点只运行一个 Pod 副本,假如有个 nginx 的 pod,当新的 Node 加入集群时,会自动在这个 Node 上部署一个 pod;当节点从集群中移开时,这个 Node 上的 Pod 会被回收;如果 DaemontSet 配置被删除,则也会删除所有由它创建的 Pod。

DaemonSet 的一些典型用法:

  • 在每个节点上运行集群守护进程
  • 在每个节点上运行日志收集守护进程
  • 在每个节点上运行监控守护进程

在 yaml 中,要配置 Daemont,可以使用 tolerations,配置示例:

kind: DaemontSet
... ...

其它地方跟 Deployment 一致。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Kubernetes关键组件与结构组成介绍

    架构组成 我们可以看一下这两张图,所表示的都是关于 Kubernetes 集群的架构. 一个 kubernetes 集群是由一组被称为节点(Node)的机器或虚拟机组成,集群由 master.worker 节点组成,每个机器至少具有一个 worker 节点. Master 在前面两个图中,可以看到 Master 是由一组称为控制平面组件组成的,我们可以打开 /etc/kubernetes/manifests/ 目录,里面是 k8s 默认的控制平面组件. . ├── etcd.yaml ├── k

  • kubernetes中的namespace、node、pod介绍

    namepace.node.pod? 当我们讨论 k8s 时总是会讨论集群,k8s 中的每个集群由多个机器/虚拟机组成,集群也被称为 命名空间(namespace),命名空间是虚拟的,因此也叫虚拟集群. Namespace 是对一组资源和对象的抽象集合. node 是集群中的单个机器/虚拟机,node 有两种,一种是 master ,一种是 worker.master 用来运行 kubernetes 服务,例如 API Server:worker 是真正工作的节点,用来运行你的容器. maste

  • Minikube搭建Kubernetes集群

    Minikube 打开 https://github.com/kubernetes/minikube/releases/tag/v1.19.0 下载最新版本的二进制软件包(deb.rpm包),再使用 apt 或 yum 安装. 或者直接下载 minikube 最新版本二进制文件(推荐). curl -Lo minikube https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v1.19.0/minikube-linu

  • 配置Kubernetes外网访问集群

    查询 Service 关于 Service,读者可以查看官方文档的资料:https://kubernetes.io/zh/docs/concepts/services-networking/service/ Service 是 k8s 中为多个 pod 公开网络服务的抽象方法.在 k8s 中,每个 pod 都有自己的 ip 地址,而且 Service 可以为一组 pod 提供相同的 DNS ,使得多个 pod 之间可以相互通讯,k8s 可以在这些 pod 之间进行负载均衡. 查询 pod: ku

  • Kubernetes部署实例并配置Deployment、网络映射、副本集

    Deployment Deployment 是 Kubernetes 提供的一种自我修复机制来解决机器故障维护的问题. 当我们单独使用 docker 部署应用时,为了应用挂了后能够重启,我们可以使用 --restart=always 参数,例如: docker run -itd --restart=always -p 666:80 nginx:latest 但是这种方式只能单纯重启容器,并不具备从机器故障中恢复的能力. Kubernetes Deployment 是一个配置,它可以指挥 Kube

  • 使用kubeadm命令行工具创建kubernetes集群

    目录 命令行工具 通过软件仓库安装 二进制文件下载安装 ubutu & centos 快速安装 创建 kubernetes 集群 1,创建 Master 2,然后初始化集群网络. 3,加入集群 清除环境 命令行工具 主要有三个工具,命令行工具使用 kube 前缀命名. kubeadm:用来初始化集群的指令. kubelet:在集群中的每个节点上用来启动 Pod 和容器等. kubectl:用来与集群通信的命令行工具. 通过软件仓库安装 方法 ① 此方法是通过 Google 的源下载安装工具包.

  • Kubernetes集群的组成介绍

    Kubernetes集群的组成 我们谈起 Kubernetes 和应用部署时,往往会涉及到容器.节点.Pods 等概念,还有各种术语,令人眼花缭乱.为了更好地摸清 Kubernetes,下面我们将介绍 Kubernetes 中与应用程序部署(deployment)和执行(execution)相关的知识. Kubernetes 集群由多个组件(components).硬件(hardware).软件(software)组成,它们共同工作来管理容器化(containerized)应用的部署和执行,这些

  • Kubernetes控制节点的部署

    标签和nodeSelector 标签(Label)是附加到 Kubernetes 对象上的键值对,如果用 json 表示附加到 metadata 的 label: "metadata": { "labels": { "key1" : "value1", "key2" : "value2" } } yaml: metadata: labels: key1: "value1&quo

  • jQuery通过控制节点实现仅在前台通过get方法完成参数传递

    本文实例讲述了jQuery通过控制节点实现仅在前台通过get方法完成参数传递.分享给大家供大家参考.具体分析如下: 这样也是HTML DOM那部分的内容,javascript与jquery等前端脚本语言的核心就是要控制每一个节点,对每一个节点进行增删改查,这样才能够真正地活用javascript与jquery等前端脚本写出一个又一个华丽丽的东西. javascript控制节点,笔者已经在之前的[JavaScript针对网页节点的增删改查用法实例]有过相关介绍,现在是通过jquery这一javas

  • Unity3D使用陀螺仪控制节点旋转

    本文实例为大家分享了Unity3D陀螺仪控制节点旋转的具体代码,供大家参考,具体内容如下 /******************************************************************** Desc: 陀螺仪对相机的逻辑类. *********************************************************************/ using System; using System.Collections; using

  • Docker安装node-red、导入节点、部署查看的步骤详解

    一.node-red官网: https://nodered.org/ 二.node-red官网上docker安装node-red的教程: https://nodered.org/docs/getting-started/docker 三.安装步骤: 1.前提是本地或服务器已经安装好docker和配置好阿里云镜像加速. 2.执行命令: # 拉取node-red的镜像 docker pull nodered/node-red # 运行node-red的镜像成为容器 docker run -it -p

  • 使用Kubernetes集群环境部署MySQL数据库的实战记录

    目录 1 编写 mysql.yaml文件 2 执行如下命令创建 3 通过如下命令查看创建结果 4 命令行进入Pod并登录mysql 5 至此,数据库已经安装完成,然后即可通过ip+端口,这里是30001,进行数据库链接了 1 编写 mysql.yaml文件 编写yaml如下 apiVersion: v1 kind: Namespace metadata: name: devops # Namespace 的名称 --- apiVersion: apps/v1 kind: Deployment m

  • OpenStack安装部署Liberty Neutron

    最近在两台物理机环境中部署了OpenStack的Liberty版本,各个模块都遇到或多或少的问题,但尤以Neutron的问题最让人头疼.尽管OpenStack一直致力于简化Neutron的部署,但对于非网络技术人员来说依然存在着很大的挑战,根本原因还是由于网络自身的复杂性所导致的,因此想要成功部署Neutron还是需要网络基础的,但这并不意味着没有网络基础就不能成功部署Neutron并使其工作.本文将总结Neutron的安装部署步骤,并对遇到的问题进行详细的描述,旨在提供解决问题的思路或者给与一

  • kubernetes环境部署单节点redis数据库的方法

    kubernetes部署redis数据库(单节点) redis简介 Redis 是我们常用的非关系型数据库,在项目开发.测试.部署到生成环境时,经常需要部署一套 Redis 来对数据进行缓存.这里介绍下如何在 Kubernetes 环境中部署用于开发.测试的环境的 Redis 数据库,当然,部署的是单节点模式,并非用于生产环境的主从.哨兵或集群模式.单节点的 Redis 部署简单,且配置存活探针,能保证快速检测 Redis 是否可用,当不可用时快速进行重启. redis 参数配置 在使用 Kub

  • 使用Kubeadm在CentOS7.2上部署Kubernetes集群的方法

    本文参考kubernetes官网文章Installing Kubernetes on Linux with kubeadm在CentOS7.2使用Kubeadm部署Kuebernetes集群,解决了一些在按照该文档部署时遇到的问题. 操作系统版本 # cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) 内核版本 # uname -r 3.10.0-327.el7.x86_64 集群节点 192.168.120.122 kube

  • Kubernetes(K8S)容器集群管理环境完整部署详细教程-上篇

    Kubernetes(通常称为"K8S")是Google开源的容器集群管理系统.其设计目标是在主机集群之间提供一个能够自动化部署.可拓展.应用容器可运营的平台.Kubernetes通常结合docker容器工具工作,并且整合多个运行着docker容器的主机集群,Kubernetes不仅仅支持Docker,还支持Rocket,这是另一种容器技术.Kubernetes是一个用于容器集群的自动化部署.扩容以及运维的开源平台. 本文系列: Kubernetes(K8S)容器集群管理环境完整部署详

  • Centos7 安装部署Kubernetes(k8s)集群实现过程

    目录 一.系统环境 二.前言 三.Kubernetes 3.1 概述 3.2 Kubernetes 组件 3.2.1 控制平面组件 3.2.2 Node组件 四.安装部署Kubernetes集群 4.1 环境介绍 4.2 配置节点的基本环境 4.3 节点安装docker,并进行相关配置 4.4 安装kubelet,kubeadm,kubectl 4.5 kubeadm初始化 4.6 添加worker节点到k8s集群 4.7 部署CNI网络插件calico 4.8 配置kubectl命令tab键自

随机推荐