4. Kubernetes 进阶之节点(node)

节点

在这里插入图片描述

节点介绍

Kubernetes 通过将容器放入在节点(Node)上运行的 Pod 中来执行你的工作负载。 节点可以是一个虚拟机或者物理机器,取决于所在的集群配置。 每个节点包含运行 Pod 所需的服务; 这些节点由 master 组件负责管理。

节点上的组件包括 :

  • kubelet
  • 容器运行时 CRI
  • kube-proxy

节点状态

节点的状态包含如下信息:

  • Addresses
  • Conditions
    Conditions 描述了节点的状态。Condition的例子有:
Node Condition描述
OutOfDisk如果节点上的空白磁盘空间不够,不能够再添加新的节点时,该字段为 True,其他情况为 False
Ready如果节点是健康的且已经就绪可以接受新的 Pod。则节点Ready字段为 TrueFalse表明了该节点不健康,不能够接受新的 Pod。
MemoryPressure如果节点内存紧张,则该字段为 True,否则为False
PIDPressure如果节点上进程过多,则该字段为 True,否则为 False
DiskPressure如果节点磁盘空间紧张,则该字段为 True,否则为 False
NetworkUnvailable如果节点的网络配置有问题,则该字段为 True,否则为 False
  • Capacity and Allocatable
  • System Info

执行以下命令可查看所有节点的列表:

root@master:/# kubectl get nodes -o wide
NAME     STATUS   ROLES           AGE   VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
master   Ready    control-plane   35d   v1.25.0   192.168.3.153   <none>        Ubuntu 18.04.5 LTS   5.4.0-126-generic   docker://20.10.8
node1    Ready    <none>          35d   v1.25.0   192.168.3.190   <none>        Ubuntu 16.04.6 LTS   4.4.0-142-generic   docker://20.10.7

执行以下命令可查看节点状态以及节点的其他详细信息:

root@master:/# kubectl describe node node1
Name:               node1
Roles:              <none>
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=node1
                    kubernetes.io/os=linux
Annotations:        flannel.alpha.coreos.com/backend-data: {"VNI":1,"VtepMAC":"46:05:07:4c:77:02"}
                    flannel.alpha.coreos.com/backend-type: vxlan
                    flannel.alpha.coreos.com/kube-subnet-manager: true
                    flannel.alpha.coreos.com/public-ip: 192.168.3.190
                    kubeadm.alpha.kubernetes.io/cri-socket: /var/run/cri-dockerd.sock
                    node.alpha.kubernetes.io/ttl: 0
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Mon, 05 Sep 2022 18:39:04 +0800
Taints:             <none>
Unschedulable:      false
Lease:
  HolderIdentity:  node1
  AcquireTime:     <unset>
  RenewTime:       Tue, 11 Oct 2022 17:10:52 +0800
Conditions:
  Type                 Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----                 ------  -----------------                 ------------------                ------                       -------
  NetworkUnavailable   False   Sun, 09 Oct 2022 10:18:19 +0800   Sun, 09 Oct 2022 10:18:19 +0800   FlannelIsUp                  Flannel is running on this node
  MemoryPressure       False   Tue, 11 Oct 2022 17:09:38 +0800   Mon, 05 Sep 2022 18:39:04 +0800   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure         False   Tue, 11 Oct 2022 17:09:38 +0800   Mon, 05 Sep 2022 18:39:04 +0800   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure          False   Tue, 11 Oct 2022 17:09:38 +0800   Mon, 05 Sep 2022 18:39:04 +0800   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready                True    Tue, 11 Oct 2022 17:09:38 +0800   Mon, 05 Sep 2022 19:23:33 +0800   KubeletReady                 kubelet is posting ready status. AppArmor enabled
Addresses:
  InternalIP:  192.168.3.190 #通常是从节点内部可以访问的 IP 地址
  Hostname:    node1 #在节点命令行界面上执行 hostname 命令所获得的值
Capacity:	# 容量:节点上的资源总数
  cpu:                4
  ephemeral-storage:  959061464Ki
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             49299724Ki
  pods:               110 # 该节点可调度的最大 pod 数量
Allocatable: # 可分配量:该节点上可分配给普通 Pod 的资源总数
  cpu:                4
  ephemeral-storage:  883871043759
  hugepages-1Gi:      0
  hugepages-2Mi:      0
  memory:             49197324Ki
  pods:               110 # 该节点可调度的最大 pod 数量
System Info: # 描述了节点的基本信息
  Machine ID:                 959acb4bc3df3086d845d40960702460
  System UUID:                4C4C4544-0044-3510-805A-C8C04F384233
  Boot ID:                    35d07f76-4238-4db8-a0cb-2d96d61e52b2
  Kernel Version:             4.4.0-142-generic # Linux 内核版本
  OS Image:                   Ubuntu 16.04.6 LTS # 系统镜像
  Operating System:           linux # 操作系统名称
  Architecture:               amd64
  Container Runtime Version:  docker://20.10.7  # Docker 版本
  Kubelet Version:            v1.25.0 # Kubernetes 版本
  Kube-Proxy Version:         v1.25.0
PodCIDR:                      10.244.1.0/24
PodCIDRs:                     10.244.1.0/24
Non-terminated Pods:          (26 in total)
  Namespace                   Name                                          CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
  ---------                   ----                                          ------------  ----------  ---------------  -------------  ---
  default                     sc-deployment-78f5b66dd6-sqxkg                0 (0%)        0 (0%)      0 (0%)           0 (0%)         34d
  ingress-nginx               ingress-nginx-controller-54f8f88b77-hscfl     100m (2%)     0 (0%)      90Mi (0%)        0 (0%)         35d
  kube-flannel                kube-flannel-ds-qzd7k                         100m (2%)     100m (2%)   50Mi (0%)        50Mi (0%)      35d
  kube-system                 coredns-658fdc5f4b-t6s6w                      100m (2%)     0 (0%)      70Mi (0%)        170Mi (0%)     35d
  kube-system                 coredns-658fdc5f4b-tbpb2                      100m (2%)     0 (0%)      70Mi (0%)        170Mi (0%)     35d
  kube-system                 kube-proxy-t6nbm                              0 (0%)        0 (0%)      0 (0%)           0 (0%)         35d
  kube-system                 metrics-server-6c4b958989-hwmd4               100m (2%)     0 (0%)      200Mi (0%)       0 (0%)         35d
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests    Limits
  --------           --------    ------
  cpu                500m (12%)  100m (2%)
  memory             680Mi (1%)  2438Mi (5%)
  ephemeral-storage  0 (0%)      0 (0%)
  hugepages-1Gi      0 (0%)      0 (0%)
  hugepages-2Mi      0 (0%)      0 (0%)
Events:              <none>

节点管理

与 Pod 和 Service 不一样,节点并不是由 Kubernetes 创建的,节点由云供应商(例如,Google Compute Engine、阿里云等)创建,或者节点已经存在于您的物理机/虚拟机的资源池。向 Kubernetes 中创建节点时,仅仅是创建了一个描述该节点的 API 对象。节点 API 对象创建成功后,Kubernetes将检查该节点是否有效。例如,假设您创建如下节点信息:

kind: Node
apiVersion: v1
metadata:
  name: "10.240.79.157"
  labels:
    name: "my-first-k8s-node"

Kubernetes 在 APIServer 上创建一个节点 API 对象(节点的描述),并且基于 metadata.name 字段对节点进行健康检查。如果节点有效(节点组件正在运行),则可以向该节点调度 Pod;否则,该节点 API 对象将被忽略,直到节点变为有效状态。

Kubernetes 将保留无效的节点 API 对象,并不断地检查该节点是否有效。除非您使用 kubectl delete node my-first-k8s-node 命令删除该节点。

有三个组件与Kubernetes节点接口进行交互:节点控制器(node controller)、kubelet和kubectl。

节点名称唯一性

节点的名称用来标识 Node 对象。 没有两个 Node 可以同时使用相同的名称。 Kubernetes 还假定名字相同的资源是同一个对象。 就 Node 而言,隐式假定使用相同名称的实例会具有相同的状态(例如网络配置、根磁盘内容) 和类似节点标签这类属性。这可能在节点被更改但其名称未变时导致系统状态不一致。 如果某个 Node 需要被替换或者大量变更,需要从 API 服务器移除现有的 Node 对象, 之后再在更新之后重新将其加入

节点控制器(Node Controller)

节点控制器是一个负责管理节点的 Kubernetes master 组件。在节点的生命周期中,节点控制器起到了许多作用。

  1. 在注册时将CIDR块分配给节点。

  2. 使节点控制器的内部列表与云提供商的可用机器列表保持最新。当在云环境中运行时,每当节点不健康时,节点控制器将询问云提供程序是否该节点的VM仍然可用,如果不可用,节点控制器会从其节点列表中删除该节点。

  3. 监测节点的健康状况。当节点变为不可访问时,节点控制器负责将NodeStatus的NodeReady条件更新为ConditionUnknown,随后从节点中卸载所有pod ,如果节点继续无法访问,(默认超时时间为40 --node-monitor-period秒,开始报告ConditionUnknown,之后为5m开始卸载)。节点控制器按每秒来检查每个节点的状态。

在Kubernetes 1.4中,我们更新了节点控制器的逻辑,以更好地处理大量节点到达主节点的一些问题(例如,主节某些网络问题)。从1.4开始,节点控制器将在决定关于pod卸载的过程中会查看集群中所有节点的状态。

在大多数情况下,节点控制器将逐出速率限制为 --node-eviction-rate(默认为0.1)/秒,这意味着它不会每10秒从多于1个节点驱逐Pod。

当给定可用性的区域中的节点变得不健康时,节点逐出行为发生变化,节点控制器同时检查区域中节点的不健康百分比(NodeReady条件为ConditionUnknown或ConditionFalse)。如果不健康节点的比例为 --unhealthy-zone-threshold(默认为0.55),那么驱逐速度就会降低:如果集群很小(即小于或等于–large-cluster-size-threshold节点 - 默认值为50),则停止驱逐,否则, --secondary-node-eviction-rate(默认为0.01)每秒。这些策略在可用性区域内实现的原因是,一个可用性区域可能会从主分区中被分区,而其他可用区域则保持连接。如果集群没有跨多个云提供商可用性区域,那么只有一个可用区域(整个集群)。

在可用区域之间传播节点的一个主要原因是,当整个区域停止时,工作负载可以转移到健康区域。因此,如果区域中的所有节点都不健康,则节点控制器以正常速率逐出–node-eviction-rate。如所有的区域都是完全不健康的(即群集中没有健康的节点),在这种情况下,节点控制器会假设主连接有一些问题,并停止所有驱逐,直到某些连接恢复。

自 Kubernetes v1.6 开始,节点控制器同时也负责为带有 NoExecute 污点的节点驱逐其上的 Pod。此外,节点控制器还负责根据节点的状态(例如,节点不可用,节点未就绪等)为节点添加污点。参考 NoExecute) 获取更多信息。

自 Kubernetes v1.8 开始,节点控制器可以根据节点的 Condition 为节点添加污点,此特性处于 alpha 阶段

节点自注册(Self-Registration)

当kubelet flag --register-node为true(默认值)时,kubelet将向API服务器注册自身。这是大多数发行版使用的首选模式。

对于self-registration,kubelet从以下选项开始:

  • --kubeconfig:向 apiserver 进行认证时所用身份信息的路径
  • --cloud-provider:向云供应商读取节点自身元数据
  • --register-node:自动向 API Server 注册节点
  • --register-with-taints:注册节点时,为节点添加污点(逗号分隔,格式为 =:
  • --node-ip:节点的 IP 地址
  • --node-labels:注册节点时,为节点添加标签
  • --node-status-update-frequency:向 master 节点发送心跳信息的时间间隔

手动管理节点

集群管理员可以创建和修改节点API对象。

如果管理员想要手工创建节点API对象,可以将 kubelet 的启动参数 --register-node 设置为 false。

管理员可以修改节点API对象(不管是否设置了 --register-node 参数)。可以修改的内容有:

  • 增加/减少标签
  • 标记节点为不可调度(unschedulable)

节点的标签与 Pod 上的节点选择器(node selector)配合,可以控制调度方式,例如,限定 Pod 只能在某一组节点上运行。

执行如下命令可将节点标记为不可调度(unschedulable),此时将阻止新的 Pod 被调度到该节点上,但是不影响任何已经在该节点上运行的 Pod。这在准备重启节点之前非常有用。

kubectl cordon $NODENAME

DaemonSet Controller 创建的 Pod 将绕过 Kubernetes 调度器,并且忽略节点的 unschedulable 属性。因为我们假设 Daemons 守护进程属于节点,尽管该节点在准备重启前,已经排空了上面所有的应用程序。

节点容量(Node Capacity)

节点API对象中描述了节点的容量(Capacity),例如,CPU数量、内存大小等信息。通常,节点在向 APIServer 注册的同时,在节点API对象里汇报了其容量(Capacity)。

Kubernetes 调度器在调度 Pod 到节点上时,将确保节点上有足够的资源。具体来说,调度器检查节点上所有容器的资源请求之和不大于节点的容量。此时,只能检查由 kubelet 启动的容器,不包括直接由容器引擎启动的容器,更不包括不在容器里运行的进程。

如果要明确保留非pod过程的资源,可以创建一个占位符pod。使用以下模板:

apiVersion: v1
kind: Pod
metadata:
  name: resource-reserver
spec:
  containers:
  - name: sleep-forever
    image: gcr.io/google_containers/pause:0.8.0
    resources:
      requests:
        cpu: 100m
        memory: 100Mi

将cpu和内存值设置为你想要保留的资源量,将文件放置在manifest目录中(--config=DIR flag of kubelet)。在要预留资源的每个kubelet上执行此操作。

参考:
Kubernetes 架构 节点
节点控制器-node-controller

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值