K8S学习笔记04

4.3 常用运维技巧集锦

4.3.1 Node的隔离和恢复

有些情况下我们需要将某些Node进行隔离,脱离K8S的调度范围,在spec中可以指定参数unschedulable: true来实现。

apiVersion: v1
kind: Node
metadata:
  name: kubernetes-minion1
  lables:
  	kubernetes.io/hostname: kubernetes-minion1
  spec:
    unschedulable

使用kubectl replace命令完成对Node状态的修改:

kubectl replace -f unschedule_node.yaml

需要注意的是,将某个Node脱离调度范围时,在该节点运行的Pod不会自动停止。

4.3.2 Node的扩容

在K8S集群中,在需要新加入的节点上安装Docker、Kubelet和kube-proxy服务,然后将Kubelet和kube-proxy的启动参数中的Master URL指定为当前K8S集群Master的地址,最后启动这些服务。基于Kubelet的自动注册机制,新的Node将会自动加入现有的K8S集群中。K8S Master在接受了新的Node的注册后,会自动将其纳入当前集群的调度范围内。

4.3.3 Pod动态扩容和缩放

通过kubectl scale rc <name> --replicas=<number>来实现。如果运行的Pod小于number,则会增加Pod,如果运行的Pod大于number,则会终止一些运行中的Pod。

[root@hdss7-21 redis]# kubectl get po
NAME                 READY   STATUS              RESTARTS   AGE
redis-slave-qfrk5    1/1     Running             0          97s
redis-slave-vbft8    1/1     Running             0          97s

Pod扩容

[root@hdss7-21 redis]# kubectl scale rc redis-slave --replicas=3
replicationcontroller/redis-slave scaled

[root@hdss7-21 redis]# kubectl get po
NAME                 READY   STATUS              RESTARTS   AGE
redis-slave-lpsgm    0/1     ContainerCreating   0          3s
redis-slave-qfrk5    1/1     Running             0          2m49s
redis-slave-vbft8    1/1     Running             0          2m49s

pod缩容

[root@hdss7-21 redis]# kubectl scale rc redis-slave --replicas=1
replicationcontroller/redis-slave scaled

[root@hdss7-21 redis]# kubectl get po
NAME                 READY   STATUS        RESTARTS   AGE
redis-slave-lpsgm    1/1     Terminating   0          78s
redis-slave-qfrk5    1/1     Terminating   0          4m4s
redis-slave-vbft8    1/1     Running       0          4m4s

[root@hdss7-21 redis]# kubectl get po
NAME                 READY   STATUS    RESTARTS   AGE
redis-slave-vbft8    1/1     Running   0          4m55s

4.3.4 更新资源对象的Lable

Lable作为用户可灵活定义的对象属性,在对已创建的对象上,仍然可以随时通过kubectl label命令对其进行增删改查等操作。

[root@hdss7-21 redis]# kubectl label pod redis-slave-vbft8 role=backend
pod/redis-slave-vbft8 labeled

查看pod标签

[root@hdss7-21 redis]# kubectl get po -Lrole
NAME                 READY   STATUS    RESTARTS   AGE     ROLE
redis-slave-vbft8    1/1     Running   0          16m     backend

删除pod标签

[root@hdss7-21 redis]# kubectl label pod redis-slave-vbft8 role-
pod/redis-slave-vbft8 labeled

[root@hdss7-21 redis]# kubectl get po -Lrole
NAME                 READY   STATUS    RESTARTS   AGE     ROLE
redis-slave-vbft8    1/1     Running   0          18m

4.3.5 将Pod调度到指定的Node

首先,我们可以kubectl给node打上一个特定的标签:

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

kubectl label nodes kubernetes-minimon1 zone=north

然后以redis-master-controller.yaml为例,在配置文件中加入nodeSelector定义

apiVersion: v1
kind: ReplicationController
metadata:
  name: redis-master
  labels:
    name: redis-master
spec:
  replicas: 2
  selector:
    name: redis-master
  template:
    metadata:
      labels:
        name: redis-master
    spec:
      containers:
      - name: master
        image: redis
        ports:
        - containerPort: 6379
      # 看这里
			nodeSelector:
				zone: north

通过这样,可以将不同的node贴上不同的标签,比如开发环境、测试环境和生产环境等。

注意:如果在pod中设置了nodeSelector,但是所有node中都不存在有这个标签的节点,即使有其他可用的node,也会调度失败。

4.3.6 应用滚动升级

K8S提供了rolling-update来实现滚动升级。

使用配置文件

使用命令:

kubectl rolling-update

该命令创建了一个新的RC,然后自动将旧的RC中的Pod副本数减少到0,同时新的RC中的Pod副本数从0逐步增加到目标值。

在这个过程中需要注意的是:

  • 新的RC需要与旧的RC在相同Namespace中。
  • RC的名字不能与旧的RC名字相同。
  • 在selector中应至少有一个Label与旧的Label不同,以标识其为新的RC。

直接使用命令

使用kubectl rolling-update再加上--image参数指定新版镜像名称来完成Pod的滚动升级。

4.3.7 K8S集群高可用方案

主要包括两方面的高可用:

  • etcd
  • K8S Master组件

1、etcd高可用性方案

etcd在整个集群中处于中心数据库的地位,为保证K8S集群的高可用性,首先需要保证数据库不是单点,另一方面,etcd存储的数据本身也应该考虑使用可靠的存储设备

2、K8S Master组件高可用性方案

在K8S集群中,Master服务扮演着总控中心的角色,主要的三个服务kube-apiserver、kube-controller-manager和kube-scheduler通过不断与工作节点上的Kubelet和kube-proxy进行通信,来维护整个集群的健康工作状态。如果Master的服务无法访问到某个Node,则会将该Node标记为不可用,不再向其调度新建的Pod。但对Master自身则需要进行额外的监控,使Master不成为集群的单故障点,所以对Master服务也需要进行高可用方式的部署。

4.4 资源配额管理

目前容器支持CPU和内存两类资源的配额限制。

4.4.1 指定容器配额

apiVersion: v1
kind: ReplicationController
metadata:
	name: redis-master
	labels:
		name: redis-master
spec:
	replicas: 1
	selector:
		name: redis-master
	template:
		metadata:
			labels:
				name: redis-master
		spec:
			containers:
			- name: master
				image: kubeguide/redis-master
				ports:
				- containerPort: 6379
				# 资源配额限制
				resources:
					limits:
						cpu: 0.5
						memory: 128Mi

CPU限制计算方法可参考官网解释,不是通过单纯的字面意思来计算。

如果一个容器在运行过程中超出了内存配额,那么容器可能会被“杀掉”然后重新启动,因此,需要准确评估容器所需内存大小。而超出CPU限制而不会被强行“杀掉”。

更多底层知识请查看Linux cgroup方面的内容。

4.2.2 全局默认配额

除了通过RC文件中给指定的容器增加配额参数,还可以通过创建LimitRange对象来定义一个全局默认的配额模板。这个默认配额模板回加载到集群中的每个Pod及容器上。

LimitRange对象可以同时在Pod和Container两个级别上对资源配额进行管理。

apiVersion: v1
kind: LimitRange
metadata:
	name: limit-range-1
spec:
	limits:
    - type: "Pod"
      max:
        cpu: "2"
        memory: 1Gi
      min:
        cpu: 250m
        memory: 32Mi
    - type: "Container"
      max:
        cpu: "2"
        memory: 1Gi
      min:
        cpu: 250m
        memory: 32Mi
      default:
        cpu: 250m
        memory: 64Mi

LimitRange是与Namespace捆绑的,每个Namespace都可以关联一个不同的LimitRange作为其全局默认配额配置。在创建LimitRange时可以在命令行以指定--namespace=命名空间的方式关联到指定的Namespace上,也可以在定义文件中直接指定namespace:

apiVersion: v1
kind: LimitRange
metadata:
	name: limit-range-1
	# 指定名称空间
	namespace: development
spec:
	limits:
    - type: "Container"
      default:
        cpu: 250m
        memory: 64Mi

4.4.3 多租户配额管理

多租户在K8S中以Namespace来体现,这里的多租户可以是多个用户、多个业务系统或者相互隔离的多种作业环境。一个集群中的资源总是有限的,当这个集群被多个租户的应用同时使用时,就需要将资源配额的管理单元提升到租户级别,只需要在不同租户对应的Namespace上加载对应的ResourceQuota配置即可达到目的。

以开发组和测试组为例,首先创建开发组对应的namespace:

apiVersion: v1
kind: Namespace
metadata:
	name: devlopment

然后创建ResourceQuota对象,并指定Namespace:

apiVersion: v1
kind: ResourceQuota
metadata:
	name: quota-development
	namespace: devlopment
spec:
	hard:
		cpu: "32"
		memory: 256Gi
		persistentvolumeclaims: "10"
		pods: "100"
		replicationcontrollers: "50"
		resourcequotas: "1"
		secrets: "20"
		services: "50"

测试组操作同上,只是namespace需要设置为test

在创建完ResourceQuota之后,对于所有需要创建的Pod都必须指定具体的资源配额设置,否则,创建Pod回失败。

然后可以使用命令来查看某个租户的配额使用情况:

# kubectl describe resourcequota <quota name> --namespace=<namespace>

kubectl describe resourcequota quota-development --namespace=development

4.5 K8S网络配置方案详解

  • 4.5.1 直接路由
  • 4.5.2 使用flannel
  • 4.5.3 使用Open vSwitch

4.6 K8S集群监控

  • kube-ui
  • cAdvisor

4.7 Trouble Shooting指导

  1. 查看K8S对象的当前运行时信息,特别是与对象关联的Event事件。
  2. 查看对象运行时的数据,排查是否有参数错误、关联错误、状态异常等问题。可能会涉及到多个相关对象的排查。
  3. 服务/容器的问题,则需要先查看容器和服务的日志,然后再深入容器内部进行排查。
  4. 对于某些复杂的问题,可能需要结合集群中每个节点上的K8S服务日志来排查。比如Master上的组件日志、节点上的Kubelet、kube-proxy服务日志。

常见问题汇总

Pod Pending状态

  • 没有可用的Node以供调度
  • 开启了资源配额管理并且当前Pod的目标节点上刚好没有可用资源

Pod状态不是Ready,且重启次数持续增加

  • 通常是因为容器的启动命令不能保持在前台运行

4.7.1 对象的Event事件

# kubectl describe po <pod name>

[root@hdss7-21 redis]# kubectl describe po redis-master-qtczc
Name:         redis-master-qtczc
Namespace:    default
Priority:     0
Node:         hdss7-21.host.com/192.168.50.21
Start Time:   Wed, 29 Dec 2021 10:13:44 +0800
Labels:       name=redis-master
Annotations:  <none>
Status:       Running
IP:           172.7.21.7
IPs:
  IP:           172.7.21.7
Controlled By:  ReplicationController/redis-master
# 省略.................
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:          <none>

可以看到有Event相关事件,可以从Event相关事件中查看到某些异常是因何导致的。

4.7.2 容器日志

如果一个Pod中包含多个容器,则需要通过-c参数指定容器名称进行查看:

kubectl logs <pod name> -c <container name>

4.7.3 K8S系统日志

如果在Linux系统上进行安装,并使用systemd来管理K8S服务,那么systemd的journal就会接管服务程序的输出日志,那么就可以通过使用systemd status或journalctl工具来查看系统服务的日志。

如果不使用systemd系统接管K8S的标准输出,则可以通过其他一些服务的启动参数来指定日志存放目录:

--logtostderr=false # 不输出到stderr
--log-dir=/var/log/kubernetes # 日志存放目录
--v=0 # glog日志级别
原文地址:https://www.cnblogs.com/liuhuan086/p/15747787.html