k8s的进阶-01

Posted 王佐的运维笔记

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了k8s的进阶-01相关的知识,希望对你有一定的参考价值。

至此,k8s的基础已经结束了,下边开始新的里程碑,k8s进阶。

首先从架构上来说,什么是节点,怎么查看节点,节点的状态呢?


Kubernetes中节点(node)指的是一个工作机器,曾经叫做 minion。不同的集群中,节点可能是虚拟机也可能是物理机。每个节点都由 master 组件管理,并包含了运行 Pod(容器组)所需的服务。这些服务包括:

  • 容器引擎(上一篇提到的)

  • kubelet

  • kube-proxy

那如何查看节点的状态,节点的状态信息又包括哪些?

  • Addresses

  • Conditions

  • Capacity and Allocatable

  • Info


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

kubectl get nodes -o wide

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

kubectl describe node <your-node-name>
例如:kubectl describe node node1

输出结果如下所示:

Name: node1Roles: <none>Labels: beta.kubernetes.io/arch=amd64 beta.kubernetes.io/os=linux kubernetes.io/arch=amd64 kubernetes.io/hostname=node1 kubernetes.io/os=linux node02=node02Annotations: node.alpha.kubernetes.io/ttl: 0 projectcalico.org/IPv4Address: 10.244.1.1/24 projectcalico.org/IPv4IPIPTunnelAddr: 10.100.166.128 volumes.kubernetes.io/controller-managed-attach-detach: trueCreationTimestamp: Thu, 18 Mar 2021 14:08:24 +0800Taints: <none>Unschedulable: falseLease: HolderIdentity: node1 AcquireTime: <unset> RenewTime: Thu, 18 Mar 2021 17:10:29 +0800Conditions: Type Status LastHeartbeatTime LastTransitionTime Reason Message ---- ------ ----------------- ------------------ ------ ------- NetworkUnavailable False Thu, 18 Mar 2021 15:02:07 +0800 Thu, 18 Mar 2021 15:02:07 +0800 CalicoIsUp Calico is running on this node MemoryPressure False Thu, 18 Mar 2021 17:06:35 +0800 Thu, 18 Mar 2021 14:08:24 +0800 KubeletHasSufficientMemory kubelet has sufficient memory available DiskPressure False Thu, 18 Mar 2021 17:06:35 +0800 Thu, 18 Mar 2021 14:08:24 +0800 KubeletHasNoDiskPressure kubelet has no disk pressure PIDPressure False Thu, 18 Mar 2021 17:06:35 +0800 Thu, 18 Mar 2021 14:08:24 +0800 KubeletHasSufficientPID kubelet has sufficient PID available Ready True Thu, 18 Mar 2021 17:06:35 +0800 Thu, 18 Mar 2021 14:08:34 +0800 KubeletReady kubelet is posting ready statusAddresses: InternalIP: 192.168.0.131 Hostname: node1Capacity: cpu: 4 ephemeral-storage: 49250820Ki hugepages-1Gi: 0 hugepages-2Mi: 0 memory: 4045080Ki pods: 110Allocatable: cpu: 4 ephemeral-storage: 45389555637 hugepages-1Gi: 0 hugepages-2Mi: 0 memory: 3942680Ki pods: 110System Info: Machine ID: 41381d3178bd478ab9e52d1743c438f8 System UUID: C6081F42-8094-35D2-BB92-45202EBA7170 Boot ID: 190a64d4-7bf5-4cfc-b606-32e94c076629 Kernel Version: 3.10.0-1127.13.1.el7.x86_64 OS Image: CentOS Linux 7 (Core) Operating System: linux Architecture: amd64 Container Runtime Version: docker://19.3.11 Kubelet Version: v1.20.2 Kube-Proxy Version: v1.20.2PodCIDR: 10.100.2.0/24PodCIDRs: 10.100.2.0/24Non-terminated Pods: (3 in total) Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits AGE --------- ---- ------------ ---------- --------------- ------------- --- kube-system calico-node-m58ts 250m (6%) 0 (0%) 0 (0%) 0 (0%) 3h2m kube-system kube-proxy-qrphw 0 (0%) 0 (0%) 0 (0%) 0 (0%) 3h2m nginx-ingress nginx-ingress-hvjn7 0 (0%) 0 (0%) 0 (0%) 0 (0%) 3h2mAllocated resources: (Total limits may be over 100 percent, i.e., overcommitted.) Resource Requests Limits -------- -------- ------ cpu 250m (6%) 0 (0%) memory 0 (0%) 0 (0%) ephemeral-storage 0 (0%) 0 (0%) hugepages-1Gi 0 (0%) 0 (0%) hugepages-2Mi 0 (0%) 0 (0%)Events: <none>

下边就详细说下节点状态的主要内容:

Addresses

依据你集群部署的方式(在哪个云供应商部署,或是在物理机上部署),Addesses 字段可能有所不同。

  • HostName:在节点命令行界面上执行 hostname 命令所获得的值。启动 kubelet 时,可以通过参数 --hostname-override 覆盖


Conditions

Conditions 描述了节点的状态。Condition的例子有:


Node Condition 描述
OutOfDisk 如果节点上的空白磁盘空间不够,不能够再添加新的节点时,该字段为 True,其他情况为 False
Ready 如果节点是健康的且已经就绪可以接受新的 Pod。则节点Ready字段为 True。False表明了该节点不健康,不能够接受新的 Pod
MemoryPressure

如果节点内存紧张,则该字段为 True,否则为False

PIDPressure

如果节点上进程过多,则该字段为 True,否则为 False

DiskPressure 如果节点磁盘空间紧张,则该字段为 True,否则为 False
NetworkUnvailable 如果节点的网络配置有问题,则该字段为 True,否则为 False

Node Condition 以一个 JSON 对象的形式存在。例如,下面的yaml 描述了一个健康状态下节点的 Condition,如下所示:

"conditions": [ { "type": "Ready", "status": "True", "reason": "KubeletReady", "message": "kubelet is posting ready status",    "lastHeartbeatTime": "2021-03-17T22:38:35Z",    "lastTransitionTime": "2021-03-17T21:24:27Z" }]

如果 Ready 类型Condition 的 status 持续为 Unkown 或者 False 超过 pod-eviction-timeoutkube-controller-manage (opens new window)的参数)所指定的时间,节点控制器(node controller)将对该节点上的所有 Pod 执行删除的调度动作。默认的 pod-eviction-timeout 时间是 5 分钟。某些情况下(例如,节点网络故障),apiserver 不能够与节点上的 kubelet 通信,删除 Pod 的指令不能下达到该节点的 kubelet 上,直到 apiserver 与节点的通信重新建立,指令才下达到节点。这意味着,虽然对 Pod 执行了删除的调度指令,但是这些 Pod 可能仍然在失联的节点上运行。


在 kubernetes v1.5 以前,节点控制器将从 apiserver 强制删除这些失联节点上的 Pod。在 v1.5 及以后的版本中,节点控制器将不会强制删除这些 Pod,直到已经确认他们已经停止运行为止。您可能会发现失联节点上的 Pod 仍然在运行(在该节点上执行 docker ps 命令可查看容器的运行状态),然而 apiserver 中,他们的状态已经变为 Terminating 或者 Unknown。如果 Kubernetes 不能通过 cloud-controller-manager 判断失联节点是否已经永久从集群中移除(例如,在虚拟机或物理机上自己部署 Kubernetes 的情况),集群管理员需要手工(通过 kubectl delete node your-node-name 命令)删除 apiserver 中的节点对象。此时,Kubernetes 将删除该节点上的所有 Pod。


在 Kubernetes v1.12 中,TaintNodesByCondition 特性进入 beta 阶段,此时 node lifecycle controller 将自动创建该 Condition 对应的 污点。相应地,调度器在选择合适的节点时,不再关注节点的 Condition,而是检查节点的污点和 Pod 的容忍。


Capacity and Allocatable(容量和可分配量)

容量和可分配量(Capacity and Allocatable)描述了节点上的可用资源的情况:

  • cpu

  • 内存

  • 该节点可调度的最大 pod 数量


  Capacity 中的字段表示节点上的资源总数,Allocatable 中的字段表示该节点上可分配给普通 Pod 的资源总数。


Info

描述了节点的基本信息,例如:

  • Linux 内核版本

  • Kubernetes 版本(kubelet 和 kube-proxy 的版本)

  • Docker 版本

  • 操作系统名称


这些信息是由节点(node)上的kubelet收集。


节点管理:

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

kind: NodeapiVersion: v1metadata: name: "10.240.79.157" labels: name: "node01"

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

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


节点控制器(Node Controller)

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

  • 第二,节点控制器通过云供应商(cloud-controller-manager)接口检查节点列表中每一个节点对象对应的虚拟机是否可用。在云环境中,只要节点状态异常,节点控制器检查其虚拟机在云供应商的状态,如果虚拟机不可用,自动将节点对象从 APIServer 中删除。

  • 节点控制器监控节点的健康状况。当节点变得不可触达时(例如,由于节点已停机,节点控制器不再收到来自节点的心跳信号),节点控制器将节点API对象的 NodeStatus Condition 取值从 NodeReady 更新为 Unknown;然后在等待 pod-eviction-timeout 时间后,将节点上的所有 Pod 从节点驱逐。


    tips:

    默认40秒未收到心跳,修改 NodeStatus Condition 为 Unknown;默认 pod-eviction-timeout 为 5分钟节点控制器每隔 --node-monitor-period 秒检查一次节点的状态

节点自注册(Self-Registration)


如果 kubelet 的启动参数 --register-node为 true(默认为 true),kubelet 会尝试将自己注册到 API Server。kubelet自行注册时,将使用如下选项:

  • --kubeconfig:向 apiserver 进行认证时所用身份信息的路径

  • --cloud-provider:向云供应商读取节点自身元数据

  • --register-node:自动向 API Server 注册节点

  • --register-with-taints:注册节点时,为节点添加污点(逗号分隔,格式为 <key>=<value>:<effect>

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

节点容量(Node Capacity)

节点API对象中描述了节点的容量(Capacity),例如,CPU数量、内存大小等信息。通常,节点在向 APIServer 注册的同时,在节点API对象里汇报了其容量(Capacity)。如果您 手动管理节点,您需要在添加节点时自己设置节点的容量。

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




以上是关于k8s的进阶-01的主要内容,如果未能解决你的问题,请参考以下文章

Atom编辑器入门到精通 Atom使用进阶

Atom编辑器入门到精通 Atom使用进阶

我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情

Atom编辑器入门到精通 Atom使用进阶

第二篇:二进制部署K8s集群进阶使用

K8s进阶