K8S 运维管理

Node 管理

Node是K8S中负责运行业务的计算节点,常见的操作有:1)将一个新的Node加入到集群,2)对某个存在的Node进行升级维护(扩大内存,增加磁盘,升级OS,重启等),3)将一个不再使用的Node从集群中删除。

  • join

在新的Node上安装完kubeadm,kubelet,containerd等以后,可以在新Node上执行 kubeadm join将该Node加入到集群。执行以下命令,可以打印出加入集群的命令,kubeadm token create --print-join-command

  • taint

对某个Node打上taint标记,K8S不会将新的Pod调度到有taint的Node上,除非这个Pod标记了可以容忍这个taint,taint是Key-Value的定义形式。

  • cordon

将某个Node标记为不可调度(SchedulingDisable),这样任何Pod都不会被调度到此Node上。

  • uncordon

恢复对某个Node的调度。

  • drain

将某个Node标记为不可调度,同驱逐其上面的Pod到其它Node。一般在需要对该Node进行维护时使用。

  • delete

删除某个Node,将其从K8S集群中移除。

cordon、drain和delete三个命令都会使node停止被调度,后期创建的pod不会继续被调度到该节点上,但操作的暴力程度却不一样。

cordon停止调度(不可调度,临时从K8S集群隔离)。影响最小,只会将node标识为SchedulingDisabled不可调度状态。之后K8S再创建的pod资源,不会被调度到该节点,但旧有的pod不会受到影响,仍正常对外提供服务。

drain驱逐节点(先不可调度,然后排干)。首先,驱逐Node上的pod资源到其他节点重新创建。接着,将节点调为SchedulingDisabled不可调度状态。drain方式是安全驱逐pod,会等到pod容器应用程序优雅停止后再删除该pod。drain驱逐流程:先在Node节点删除pod,然后再在其他Node节点创建该pod。

delete删除节点。delete是一种暴力删除node的方式。在驱逐pod时是强制干掉容器进程,做不到优雅终止Pod。相比较而言,显然drain更安全。

集群环境共享与隔离

K8S集群可以被多个租户使用,不同的租户具备相应的权限,同时,不同租户在K8S中创建的资源是被隔离的,胡不影响。

K8S中通过Namespace和Context能够实现多租户管理以及资源的隔离,不同的租户操作的都是自己Namespace中的资源。通过可以对ServiceAccount进行RBAC授权管理,使用某个租户只具备某些权限,例如只能查看Pod,Service而不能创建Pod或Service。

容器资源限制

在创建Pod时,可以通过指定requests和limits来限定Pod中容器对CPU和内存的申请数量以及上限数量。K8S只会将Pod调度到满足此要求的Node上,如果没有任何Node满足此要求,则Pod会调度失败。

如果每个Pod都手动增加requests和limits限制,操作比较繁琐,可以在Namespace上创建LimitRange来设定默认的requests和默认的limits。

服务质量管理(QoS)

服务质量包含三个层级,BestEffort,Burstable和Guaranteed,服务等级依次增高。如果Node资源不足,K8S会优先kill掉低服务等级的Pod,从而为高等级的Pod腾出资源。

Guaranteed:1)Pod中的每个容器都定义了requests和limits,且对应的值一样(需要同时定义CPU和内存限制)。2)Pod中每个容器都定义了limits。默认requests和limits的值一样,所以可以只定义limits。是最高级别的 QoS 级别,它可以保证在任何情况下资源需求得到满足。当一个 Pod 被划分到这种 QoS 级别时,它会在可用资源范围内得到最大比例的资源分配。这种 QoS 级别通常用于需要高可靠性和高可用性的任务,比如数据库、关键业务等。

Burstable:1)虽然Pod中的每个容器都定义了requests和limits,但其值不一样。2)一个容器定义了资源配置,而另一个没有定义。3)一个容器没定义CPU限制,另一个容器没定义内存限制。是中级 QoS 级别,它可以保证在特定情况下资源需求得到满足。当一个 Pod 被划分到这种 QoS 级别时,它会在可用资源范围内得到一定比例的资源分配。Kubernetes 调度器会为这类 Pod 分配足够的资源,以满足它们的需求。这种 QoS 级别通常用于一些非关键任务,比如网页浏览、电子邮件发送等。

BestEffort:Pod中的每个容器都没有定义requests和limits,就是BestEffort。是一种最低优先级,主要用于无法保证服务的资源请求,比如不消耗任何资源,没有任何网络延迟,它适用于一切不可用的情况。Pod 被划分为这种 QoS 级别,通常是由于它的服务类型,比如备份任务、流量转向等。这类 Pod 不受 Kubernetes 调度器约束,可能会在资源空闲时被调度到节点上。

下面示例三种不同QoS的Pod,

apiVersion: v1
kind: Pod
metadata:
  name: qos-demo
  namespace: qos-example
spec:
  containers:
  - name: guaranteed
    image: nginx
    resources:
      requests:
        memory: "100Mi"
        cpu: "200m"
      limits:
        memory: "100Mi"
        cpu: "200m"
---
apiVersion: v1
kind: Pod
metadata:
  name: qos-demo
  namespace: qos-example
spec:
  containers:
  - name: burstable
    image: nginx
    resources:
      requests:
        memory: "50Mi"
        cpu: "100m"
---
apiVersion: v1
kind: Pod
metadata:
  name: qos-demo
  namespace: qos-example
spec:
  containers:
  - name: best-effort
    image: nginx

资源配额管理 (Quotas)

虽然通过limits和requests可以限制每个Pod的资源使用情况,但是其无法限制某个Namespace中所有Pod的资源使用总和,资源配额管理(Quotas)可以满足此需求。其对某个Namespace中的CPU request,CPU limit,Memory request,Memory limit,Pod,Storage等总的数量进行限制,以免该Namespace中的这些配额超标。

同时,可以通过scopes来指定Quotas限定的QoS的作用域,例如,只针对BestEffort或者Burstable的Pod进行限制。

以下是Quotas示例,

1)限制CPU和内存总量

bash 复制代码
apiVersion: v1
kind: ResourceQuota
metadata:
  name: object-quota-demo
spec:
  hard:
    limits.cpu: '6'        #所有非终止状态的 Pod,其 CPU 限额总量不能超过该值。
    limits.memory: '20Gi'  #所有非终止状态的 Pod,其内存限额总量不能超过该值。
    requests.cpu: '4'        #所有非终止状态的 Pod,其 CPU 需求总量不能超过该值。
    requests.memory: '15Gi'  #所有非终止状态的 Pod,其内存需求总量不能超过该值。

2)限制存储使用总量

bash 复制代码
apiVersion: v1
kind: ResourceQuota
metadata:
  name: object-quota-sc-demo
spec:
  hard:
    requests.storage: "20Gi"     #所有 PVC,存储资源的需求总量不能超过该值。
    persistentvolumeclaims: "50Gi"  #在该命名空间中所允许的 PVC 总量。
    local-path.storageclass.storage.k8s.io/requests.storage: "10Gi"  #在所有与 <storage-class-name> 相关的持久卷申领中,存储请求的总和不能超过该值 。
    local-path.storageclass.storage.k8s.io/persistentvolumeclaims: 3  #在与 storage-class-name 相关的所有持久卷申领中,命名空间中可以存在的持久卷申领总数

3)限制对象数量

bash 复制代码
apiVersion: v1
kind: ResourceQuota
metadata:
  name: object-quota-count-demo
spec:
  hard:
    configmaps: 10  #在该命名空间中允许存在的 ConfigMap 总数上限。
    persistentvolumeclaims: 5  #在该命名空间中允许存在的 PVC 的总数上限。
    pods: 15    #在该命名空间中允许存在的非终止状态的 Pod 总数上限。Pod 终止状态等价于 Pod 的 .status.phase in (Failed, Succeeded) 为真。
    replicationcontrollers: 10  #在该命名空间中允许存在的 ReplicationController 总数上限。
    resourcequotas: 5  #在该命名空间中允许存在的 ResourceQuota 总数上限。
    services: 5        #在该命名空间中允许存在的 Service 总数上限。
    services.loadbalancers: 5  #在该命名空间中允许存在的 LoadBalancer 类型的 Service 总数上限。
    services.nodeports: 5      #在该命名空间中允许存在的 NodePort 类型的 Service 总数上限。
    secrets: 7  #在该命名空间中允许存在的 Secret 总数上限。

更多详细信息参考官方文档:限制范围 | Kubernetes

资源紧缺时Pod的驱逐机制

Kubelet在驱逐用户Pod之前,会先尝试回收Node级别的资源。例如先删除已经停掉的Pod来清除nodefs上的存储资源,如果是imagesfs达到了驱逐阈值,会删除掉无用的image。

如果kubelet无法在Node上回收足够的资源,则其会尝试驱逐用户的Pod,按照QoS等级进行先后 驱逐,即先驱逐BestEffort,然后Burstable,最后Guaranteed。

相关推荐
dessler25 分钟前
Docker-如何启动docker
运维·docker·云原生·容器·eureka
zhy2956325 分钟前
【DOCKER】基于DOCKER的服务之DUFS
运维·docker·容器·dufs
蜜獾云2 小时前
docker 安装雷池WAF防火墙 守护Web服务器
linux·运维·服务器·网络·网络安全·docker·容器
年薪丰厚3 小时前
如何在K8S集群中查看和操作Pod内的文件?
docker·云原生·容器·kubernetes·k8s·container
zhangj11253 小时前
K8S Ingress 服务配置步骤说明
云原生·容器·kubernetes
岁月变迁呀3 小时前
kubeadm搭建k8s集群
云原生·容器·kubernetes
墨水\\3 小时前
二进制部署k8s
云原生·容器·kubernetes
Source、3 小时前
k8s-metrics-server
云原生·容器·kubernetes
上海运维Q先生3 小时前
面试题整理15----K8s常见的网络插件有哪些
运维·网络·kubernetes
颜淡慕潇3 小时前
【K8S问题系列 |19 】如何解决 Pod 无法挂载 PVC问题
后端·云原生·容器·kubernetes