5.1 k8s集群管理指南
主要包括:node管理 label管理 namespace资源共享 资源配额管理 集群master高可用 集群监控等
5.1.1 node的隔离与恢复
如果某些node需要进行硬件升级、维护等,需要将某些node进行隔离与恢复,有如下三种方法:
方式一: 通过node的yaml文件修改node的状态
1)定义配置文件如下:
unsechedule_node.yaml
apiVersion: v1
kind: Node
metadata:
name: k8s-node-1
labels:
kubenetes.io/hostname: k8s-node-1
spec:
unschedulable: true
2)kubectl replace 命令执行
kubectl replace -f unschedule_node.yaml
此时获取node的状态:
kubectl get nodes
说明:此时node的status增加了SchedulingDisabled
方式二: 直接使用命令,如:
kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}'
方式三:使用命令:如
kubectl cordon k8s-node-1 #node隔离
kubectl uncordon k8s-node-1 #node解除隔离整理说明:node被隔离后,对于后续创建的Pod,系统讲不会再向该Node调度;
对于node被隔离前在node上创建的pod会一直存在,Pod不会自动停止,需要管理员手动停止在该Node上运行的Pod2 node的扩容
新的Node节点,安装docker、kubelet和kube-proxy服务并启动,将master url指定为当前k8s集群的地址则可以实现自动注册。5.1.2 更新资源对象的label
kubectl label pod redis-pod role=backend #对名称为redis-pod的pod增加label: role=backend
kubectl get pods -Lrole # 查看该pod的label
kubectl label pod redis-pod role- #对pod删除key为role的label
kubectl label pod redis-pod role=master --overwrite5.1.3 namespace 集群环境共享与隔离
同一个k8s集群可能用于多条业务线或者多环境来,所以需要引入命名空间的概念,防止不同业务线或环境相互影响。
假设需要开发和生产两个命名空间,流程主要如下:
1 创建namespace
namespace-development.yaml
apiVersion: v1
kind: Namespace
metadata:
name: developmentnamespace-production.yaml
apiVersion: v1
kind: Namespace
metadata:
name: production
执行指令:
kubectl create -f namespace-development.yaml
kubectl create -f namespace-production.yaml2 定义context
需要为两个工作组分别定义一个context,即运行环境。具体指令如下:
kuctl config set-cluster kubernetes-cluster --server=https://192.168.1.128:8080
kubtctl config set-context ctx-dev --namespace=development --cluster=kubernetes-cluster --user=dev
kubtctl config set-context ctx-prod --namespace=production --cluster=kubernetes-cluster --user=prodkubectl config view 查看已经定义的context
注意:通过kubectl config命令在${HOME}/.kube目录下生成了一个名为config的文件,具体内容即使上面指令查看到的内容3 设置工作组则特定context中工作
kubectl config use-context ctx-dev #将当前运行环境设置为“ctx-dev”
然后通过kubectl create -f即可创建pod等资源 5.1.4 k8s资源管理
计算资源:cpu和内存
资源的两种配置:requests 和 limits
pod和容器的requests和limits,有如下四个参数:
spec.container[].resources.requests.cpu #cpu的请求
spec.container[].resources.limits.cpu #cpu的限制
spec.container[].resources.requests.memeory #内存的请求
spec.container[].resources.limits.memory #内存的限制
说明:两者都是可选的,request没有配置会默认等于limits,limits应该大于requestsspec.container[].resources.requests.cpu如果被设置为0.5,含义如下:
该容器会获得半个cpu,该值是绝对值,即无论几核cpu的资源都是0.5cpuspec.container[].resources.requests.memeory 可以被设置为64M,即需要的内存是64M
基于资源进行的Pod调度
如果某个node的内存只有4G,其中3G用来运行Pod,pod内存的Request为1G,Limits为2G;那么节点最多可以运行3个这种Pod。
后期再有Pod需要创建,则不会分配到该节点。参数生效:
对容器设置的cpu资源限制会作为参数传给docker
内存的request不传给docker,limits会传给docker。
如果容器原型超过了其内存limits的限制,则该容器可能会被杀掉,如果这个容器是一个可重启的容器,那么之后他会被kubelet重启
cpu因为在容器技术中属于可压缩资源,因此对于CPU的limits配置一般不会因超标导致容器被kill资源的配置范围管理:
具体可能存在如下场景:
1)node一共2G内存,管理员不希望任何Pod申请超过2G的的内存
2)集群分为不同namespace,希望为不同的namespace设置最大的可使用空间
3)避免资源浪费,如每个Pod使用node的40%资源,2个使用80%,那么剩下20%会非常尴尬k8s提供了LimitRange机制限制Pod和容器的Reques和Limits配置。下面是个实例:
1)创建namespace,如:
kubectl create namespace limit-example
2) 为namespace设置LimitRange
3)创建Pod时触发LimitRange限制 5.1.5 资源紧缺时的Pod驱逐机制
目的:对于内存、磁盘等不可压缩的资源在进去的情况下继续保证node的稳定性驱逐策略:
资源过于紧张时,kubelet会主动停止一个或多个Pod,回收紧缺的资源;
Pod被终止是,哦容器会全部停止,pod的状态会被设置为Failed驱逐信号:
驱逐策略基于驱逐信号来执行,驱逐信号包括:memory.avaliable nodefs.avaliable imagefs.avaliable 驱逐阈值
驱逐信号获取当前系统资源状态,驱逐阈值则定义资源状态在什么情况下要触发驱逐动作。
阈值的定义方式:
<eviction-signal><operator><quantity>,即驱逐信号 运算符 数量表达式,如:
memory.avaliable<10%
memory.avaliable<1Gi
驱逐软阈值:资源消耗达到软阈值时,持续时间达到宽限期之前kubelet不会触发驱动动作
驱逐硬阈值:达到驱逐阈值,kubelet立即杀掉Pod并进行资源的回收,如:--eviction-hard=memory.avaliable<100Mi驱逐监控频率
定义驱逐阈值评估的时间间隔,参数 --housekeeping-interval节点的状况
kubelet会持续向master报告节点的状态回收node界别的资源
如果节点达到了驱逐阈值,并且也过了宽限期,kubelet并不会立刻回收超出限量的资源,而是先尝试回收资源,包括删除无用镜像、删除死掉的Pod、容器等手段,如果依旧达到驱逐阈值,则会驱逐用户的Pod驱逐用户的Pod:
bestEffort:对紧缺资源消耗最多的Pod最先被驱逐
burstable:先清除资源消耗超出requests的的Pod,没有则按照bestEffort
Guaranteed资源最少回收量
为了避免驱逐Pod仅回收了很少的资源,导致kubelet反复触发驱逐阈值。可以设置一次驱逐回收的最少资源数量。
通过配置--eviction-minimum-reclaim 5.1.7 k8s集群高可用部署方案
k8s集群通过对Pod运行状况的监控和调控,实现了应用层的高可用性。所以保证k8s的高可用性十分重要。
包括两个方面:etcd的高可用 master节点的高可用etcd的高可用:
etcd在k8s集群中处于中心数据库的地位,用于存储各种资源的具体信息,所以需要保证etcd的高可用,所以需要部署一个至少由三台服务器组成的etcd集群。master的高可用:
master上的进程不断与工作节点上的kubelet和kube-proxy进行通信,来维护整个集群的健康工作状态。为了保证master的高可用,也需要部署一个至少由三台服务器组成的emaster集群k8s典型的部署方式:如图
通过kubelet服务以容器和的形式启动和运行kube-ap[iserver\ kube-controller-master\kube-scheduler.
1)kube-apiserver的高可用部署
预先为kube-apiserver创建所有需要的CA证书和基本鉴权文件等,并子啊每台服务器上创建日志文件:
touch /var/log/kube-apiserver.log
2) 为kube-apiserver配置负载均衡器
3)kube-controller-manager和kube-scheduler的高可用配置,通过租赁锁来实现5.1.8 k8s集群监控
开源软件cAdvisor
页面查看某个node的容器的运行状态:cpu、内存、网络吞吐量、文件系统使用情况等
问题:仅能对一台Node进行监控,大规模容器集群中则不易使用。Heapster + Influxdb + Grafana集群性能监控平台
heapster:汇聚集群各Node上cAdvisor的数据采集系统
InfluxDB:分布式时序数据库,用于实施数据采集、事件跟踪记录、存储时间图表等
Grafana:通过dashboard将Influxdb中的时序数据展现成图表或曲线等5.1.9 集群统一日志管理
k8s推荐采用Fluentd + ES + kibana完成对系统和容器日志的采集5.1.10 k8s审计日志
记录谁在什么时候对什么做了什么操作,该日志记录与kube -apiserver中。5.1.11 使用web UI管理集群
要求部署Heapster,可提供部署应用、资源对象管理、日志查询、系统监控查询等集群管理功能。5.1.12 Helm,k8s应用包管理工具
5.2 Trouble shooting指导
5.2.1 查看系统event事件
kubectl describe pod podName
5.2.2 查看容器日志
kubectl logs podName
5.2.3 查看k8s服务日志
如果在linux系统上安装,且systemd系统来管理k8s服务,那么systemd的journal系统会接管服务程序的食醋胡日志。此时可使用systemd status 或 journactl工具来查看系统服务的日志。