kubernetes权威指南阅读笔记——第五章运维指南
目录:
5 kubernetes运维指南
5.1 kubernetes管理指南
5.1.1 Node管理
Node的隔离与恢复
在硬件升级维护时,需要对Node进行隔离,脱离kubernetes集群的调度范围。
apiVersion: v1
kind: Node
metadata:
name: k8s-node-1
labals:
kubernetes.io/hostname: k8s-node-1
spec:
unschedulable: ture
然后通过
kubectl replace -f unscedule_node.yaml
可以在获取Node状态的时候看到Node状态中新增了SchedulingDisabled:?待测试上图
kubectl get nodes
也可以直接通过kubectl命令
kubectl patch node k8s-node-1 -p '{ "spec" : { "unschedulable" : true}}''
隔离只是新的Pod不会落到上边,但是以前已经运行的Pod不会停止,需要手动停止该Pod。
而将Node重新纳入集群调度范围只需要通过以上两种方式将unschedulable设置为false。
对于1.2版本以后支持
kubectl cordon k8s-node-1
kubectl uncordon k8s-node-1
Node的扩容
kubernetes的Node扩容非常容易,直接在新的Node启动Docker,kubelet和kube-proxy服务,通过kubelet的自动注册机制,新的Node就可以加入集群。
5.1.2 更新资源对象Label
Label附属在资源对象上,可以进行增改查删
增
kubectl label pod redis-master-bobr0 role=backend
改
kubectl label pod redis-master-bobr0 role=master --overwrite
查
kubectl pod redis-master-bobr0 -Lrole
删
kubectl label pod redis-master-bobr0 role-
5.1.3 NameSpace:集群环境共享与隔离
创建namespace
apiVersion: v1
kind: Namespace
metadata:
name: development
书中示例定义了development和production两个namespace
定义Context(运行环境)
定义Context
kubectl config set-cluster kubernetes-cluster --server=https://192.168.1.128:8080
将Context置于之前创建的命名空间
kubectl config set-context ctx-dev --namespace=development -cluster=kubernetes-cluster --user=dev
kubectl config set-context ctx-pro --namespace=production -cluster=kubernetes-cluster --user=pro
查看定义的Context
kubectl config view
kubectl config的本质是在${HOME}/.kube目录创建一个config的文件,kubectl config view本质就是查看这个文件,所以可以通过手工编辑的方式设置Context。?手工编辑实时生效吗,定时读取吗。
设置工作组在特定的Context环境工作
将当前运行环境设置为‘ctx-dev’
kubectl config use-context ctx-dev
通过这个命令可以将当前环境设置为开发组所需环境,之后所有操作都是在名为development的命名空间中完成。
5.1.4 Kubernetes资源管理
计算资源
计算济源分两个种,一个是请求资源(Request),容器会分配到满足请求资源的Node上;另一个是资源限制(limit),这个上限影响着节点发生资源竞争的时候的解决策略。
Request和Limit都是可选的,
- 如果没有设置,那么会使用系统的默认值,这默认值取决于集群配置,那么集群配置是什么?
- 如果Request没有设置则和Limit相同
- 并且任何情况下Limit都应该设置大于Request
Pod级别的Request和Limit是对Pod中所有容器
- CPU配置,0.5为半个CPU,1为一个CPU,0.1代表100millicpu,在kubernetes的API中自动转化0.1为100m,所以CPU最多支持三位小数,并且CPU严格遵循着绝对值,不论在单核还是多核,1都代表一个CPU
- 内存配置,计量单位为bytes,使用整数或者定点证书加上国际单位制表示。
国际单位制
- 十进制E,P,T,G,M,K,m
- 二进制Ei,Pi,Ti,Gi,Mi,Ki,mi
例如:
- KiB和MiB是二进制表示字节单位,1KiB=2^10bytes = 1024bytes = 8192bits
- KB和MB是十进制表示字节单位,1KB=1000bytes = 8000bits
基于Requests和Limits的Pod调度机制
kubernetes在调度Pod的之后只考虑满足requests的值,而计算Node剩余资源的时候,也是参考Node原本可用内存直接减去requests。
这个原本内存和CPU获取
kubectl describe node k8s-node-1
- Capacity可用资源容量上限
- Allocated已分配资源容量
Requests和Limits资源配置机制
kubelet启动一个Pod的一个容器时,会将Request和Limits的值转化成对应的容器启动参数传递给容器执行器。
spec.container[].resources.requests.cpu
这个值会转化成核数,作为--cpu-shares
参数传递给docker run
,当然也是转化成一个权重值;spec.container[].resources.limits.cpu
这个值也会转化成核数,作为--cpu-quota
参数传递给docker run
,--cpu-period
为默认参数100000,两个参数共同限制cpu的使用时间;spec.container[].resources.requests.memory
这个值只作为kubernetes调度器作为调度的依据;spec.container[].resources.limits.memory
这个值会转化为单位为bytes的整数,作为--memory
参数传递给docker run
。
计算资源使用情况监控
Pod资源使用情况会作为Pod状态上报给Master,如果集群中配置了Heapster,可以从Heapster获取。能不能从api server获取呢?
计算资源相关常见问题分析
- Pod状态为pending,错误信息为FailedScheduling,由于资源不足导致调度失败
- 容器被强行终止(Terminated),通过
kuectl describe pod <pod-name>
来查看原因,如果Restart Count数量很多次,可以通过以下命令
kubectl get pod -o go-template='{{range.status.containerStatuses}}{{"Container Name:"}}{{.name}}{{"\r\nLastState"}}{{.lastState}}{{end}}'
计算资源管理的演进
未来可以支持磁盘空间甚至自定义的限制。
资源的配置范围管理(LimitRange)
防止Pod内存配置超过Node内存上限,不同命名空间可以使用不同的限制
创建namespace
为namespace设置LimitRange
创建Pod时触发LimitRange
资源的服务质量管理(Resource Qos)
资源的配额管理(Resource Quotas)
Resource Quotas和LimitRange实践指南
资源管理总结
5.1.5 kubernetes集群高可用部署方案
etcd高可用部署
Master高可用部署
5.1.6 Kubernetes集群监控
通过cAdvisor页面查看容器的运行状态
Heapster+Influxdb+Grafana集群性能监控平台搭建
5.1.7 kubelet的垃圾回收机制
Kubernetes的GC机制由kubelet完成,定期清理不再使用的镜像和容器,每分钟进行一次容器GC,每5分钟进行一次镜像的GC。
容器GC设置
暂无测试,测试集群被删掉了。未完待续?
镜像GC设置
暂无测试,测试集群被删掉了。未完待续?
5.2 Kubernetes 高级案例
高级案例略过,如果日后有部署测试,会贴过来链接
5.2.1 Elastic日志搜索集群查询和展现案例
高级案例略过,如果日后有部署测试,会贴过来链接
5.2.2 Cassandra集群部署案例
高级案例略过,如果日后有部署测试,会贴过来链接
5.3 Trouble Shooting指导
常见问题排查
- 查看对象运行信息,对象相关的Event事件
- 对于容器,服务的问题,需要进入容器进行诊断
- 对于复杂的问题,例如Pod调度这种全局性问题需要结合Kubernetes服务日志排查
5.3.1 查看系统的Event事件
直接通过kubectl describe pod <pod-name>
进行查看即可,对于不是default的namespace需要加上--namespace=<namespace>
。
包括了Pod创建时定义的信息与该Pod相关的Event,一般Pod创建失败的原因不外乎没有可用Pod调度,正在下载镜像,或者Node的资源不满足资源配额
5.3.2 查看问题日志
查看容器内部应用程序生成的日志
kubectl logs <pod-name>
如果Pod包含多个容器,查看指定容器日志
kubectl logs <pod-name> -c <container_name>
容器应用程序生成的日志和容器的生命周期是一致的,容器被销毁后,容器内部的文件也会销毁,如果想要保留需要通过挂载Valume实现,也可以进行日志采集。
5.3.3 查看Kubernetes服务日志
在Linux系统安装,可通过systemd管理Kubernetes服务管理输出日志
5.3.4 常见问题
无法下载pause镜像导致Pod一直处于Pending状态
通过pod的describe日志可以看到pause的镜像无法下载,可以通过kubelet启动的时候指定为内网镜像仓库下载镜像,我这边的处理方式是直接在每个Node上直接Load了pause镜像,之后通过云服务的auto scaling服务扩容主机的镜像直接就Load了pause镜像,这个问题就可以避免了。
Pod创建成功,但状态始终不是Ready,并且RESTARTS的数量在增加
造成这种问题的原因是镜像没有在前台保持运行,Pod启动的时候,容器启动的命令执行完成,认为容器运行完成并结束(ExitCode=0),Pod根据默认的重启策略,RC重启了该容器。
5.4 kubernetes v1.3 开发的新功能
5.4.1 Pet Set
Pet Set是有状态的,每个实例有唯一标识,并且各个实例可能还有启动顺序的要求。
- 唯一不变的hostname,并保存在DNS中
- 唯一的顺序编号,用于确保各个实例的启动顺序
- 为每个容器提供永久的存储,与其hostname的启动顺序绑定 为什么是与hostname绑定?
适用场景
- 数据库应用,实例需要挂载一个外部的永久存储
- 集群化应用软件,etcd,zookeeper和Elasticsearch
创建PetSet
未完待续?
5.4.2 Init Container(初始化容器)
在应用的场景就会有很多初始化操作
- 等待其他关联组件正常运行(例如数据库或某个后台服务)
- 基于环境变量或配置模板生成配置文件
- 从远程数据库获取本地所需配置,或者将自身注册到某个中央数据库
- 下载相关依赖包,对系统进行一些预配置
未完待续?
5.4.3 Cluster Federation(集群联邦)
管理多个kubernetes集群,用于多个集群中的服务统一管理,以及当一个集群发生故障,业务能够第一时间将业务恢复到其他集群,目前只能在谷歌云或者亚马逊云上使用。
这就尴尬了