kubernetes权威指南阅读笔记——第五章运维指南

时间:Nov. 28, 2017 分类:

目录:

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中所有容器

  1. CPU配置,0.5为半个CPU,1为一个CPU,0.1代表100millicpu,在kubernetes的API中自动转化0.1为100m,所以CPU最多支持三位小数,并且CPU严格遵循着绝对值,不论在单核还是多核,1都代表一个CPU
  2. 内存配置,计量单位为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指导

常见问题排查

  1. 查看对象运行信息,对象相关的Event事件
  2. 对于容器,服务的问题,需要进入容器进行诊断
  3. 对于复杂的问题,例如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集群,用于多个集群中的服务统一管理,以及当一个集群发生故障,业务能够第一时间将业务恢复到其他集群,目前只能在谷歌云或者亚马逊云上使用。

这就尴尬了