文章目录
- 2.1 Pod的生命周期Lifecycle
- 2.2 Pod的重启策略RestartPolicy
- 2.3 静态Pod
- 2.4 Pod的健康检查
- 2.5 ConfigMap
- 2.6.4 第二种Secret类型:kubernetes.io/dockerconfigjson(了解即可)
- 2.6.5 第三种Secret类型:kubernetes.io/service-account-token(了解即可)
- 五、尾声
一、前言
本文介绍了Kubernetes中Pod进阶、Controller进阶、Resource和Dashboard等知识。
二、Pod进阶学习之路
2.1 Pod的生命周期Lifecycle
官网
:https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/
- 挂起(Pending):Pod 已被 Kubernetes 系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度 Pod 的时间和通过网络下载镜像的时间,这可能需要花点时间。
- 运行中(Running):该 Pod 已经绑定到了一个节点上,Pod 中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。
- 成功(Succeeded):Pod 中的所有容器都被成功终止,并且不会再重启。
- 失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
- 未知(Unknown):因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败。
注意:对于最小逻辑单元pod来说( kubectl get pod) 正常状态是 running;
对于最小物理单元node来说( kubectl get node),正常状态是 ready 。
2.2 Pod的重启策略RestartPolicy
官网
:https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policyA PodSpec has a restartPolicy field with possible values Always, OnFailure, and Never. The default value is Always. (默认是always) restartPolicy applies to all Containers in the Pod. restartPolicy only refers to restarts of the Containers by the kubelet on the same node. Exited Containers that are restarted by the kubelet are restarted with an exponential back-off delay (10s, 20s, 40s …) capped at five minutes, and is reset after ten minutes of successful execution. As discussed in the Pods document, once bound to a node, a Pod will never be rebound to another node.
小结:Pod中重启策略包括三种,如下:
- Always:容器失效时重启(默认方式)
- OnFailure:容器终止运行且退出码不为0时重启,即失败重启
- Never:永远不重启
2.3 静态Pod
Pod分为两类,一类是普通Pod,通过yaml创建,一类是静态Pod(Static Pod)。
静态Pod
(1) 静态Pod是由kubelet进行管理的;
(2) 存在于特定的Node上,比如master节点Node;
(3) 无法与ReplicationController,Ddeployment或者DaemonSet进行关联,也无法进行健康检查。
普通Pod
(1) 通过API Server进行管理;
(2) 随机分配到某个node执行,除非使用 selectNode 属性指定运行在哪个node上;
(3) 可以与ReplicationController,Ddeployment或者DaemonSet进行关联,也无法进行健康检查。
静态Pod可以通过 kubectl get pods -o wide -n kube-system
来查看,这些都是 kubeadm-init 初始化安装的, 在 /etc/kubernetes/manifests 目录下, 里面有很多 yaml ,如下:
问题:开发中,程序员如何一眼判断哪些是静态Pod,哪些是普通Pod?
回答:静态Pod存在于特定的Node上,比如master节点Node。使用 kubectl get pod -o wide ,查看 IP 这一列,这一列都是内网ip,但是有不同,静态Pod都是使用的是具体的node的内网ip,普通Pod使用的都是 calico 生成的虚拟IP。
2.4 Pod的健康检查
pod的健康检查:deployment里面的一个可选属性,即是否开启健康检查。
官网
:https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes
Pod的健康检查是通过探针来完成的,针对运行中的容器,kubelet 可以选择是否执行以下三种探针(存活态探针、就绪态探针、启动探针 ),以及如何针对探测结果作出反应:
livenessProbe
指示容器是否正在运行。如果存活态探测失败,则 kubelet 会杀死容器, 并且容器将根据其重启策略(三种:Always、OnFailure、Never)决定未来。如果容器不提供存活探针, 则默认状态为 Success。
readinessProbe
指示容器是否准备好为请求提供服务。如果就绪态探测失败, 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。 初始延迟之前的就绪态的状态值默认为 Failure。 如果容器不提供就绪态探针,则默认状态为 Success。
startupProbe
指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被 禁用,直到此探针成功为止。如果启动探测失败,kubelet 将杀死容器,而容器依其 重启策略进行重启。 如果容器没有提供启动探测,则默认状态为 Success。
2.5 ConfigMap
官网
:https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/
ConfigMaps allow you to decouple configuration artifacts from image content to keep containerized applications portable.
说白了就是用来保存配置数据的键值对,也可以保存单个属性,也可以保存配置文件。
所有的配置内容都存储在etcd中,创建的数据可以供Pod使用。
2.5.1 ConfigMap的创建
创建方式1:命令行创建configmap
创建方式2:根据配置文件中创建configmap
创建一个文件,名称为app.properties
演示如下:
创建方式3:通过yaml文件创建configmap
configmaps.yaml
演示如下:
2.5.2 ConfigMap的使用
- 使用方式
- 注意
使用方式1:环境变量env使用configmap
需要使用valueFrom、configMapKeyRef、name:
(1) valueFrom在最外层,表示是env某个key对应的value值
(2) configMapKeyRef 在 valueFrom 下面一层,表示这个 valueFrom 的值来自某个结构
(3) name 又在 configMapKeyRef 下面一层,
使用方式2:命令行command使用configmap
key的话指定要用到的key
使用方式3:volume挂载使用configmap
2.6 Secret
2.6.1 Secret类型
- Opaque:使用base64编码存储信息,可以通过
base64 --decode
解码获得原始数据,因此安全性弱。 - kubernetes.io/dockerconfigjson:用于存储docker registry的认证信息。
- kubernetes.io/service-account-token:用于被 serviceaccount 引用。serviceaccout 创建时 Kubernetes 会默认创建对应的 secret。Pod 如果使用了 serviceaccount,对应的 secret 会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中。
2.6.2 第一种Secret类型:Opaque Secret
Opaque类型的Secret的value为base64位编码后的值
创建方式1:从文件中创建Secret
演示如下:
创建方式2:使用yaml文件创建Secret
(1)对数据进行64位编码
(2)定义mysecret.yaml文件
(3)根据yaml文件创建资源并查看
演示如下:
2.6.3 Secret使用的两种方式
- 以Volume方式
- 以环境变量方式
使用方式1:以Volume方式使用Secret
kubectl apply -f mypod.yaml
以Volume方式使用Secret,演示如下:
使用方式2:将Secret设置为环境变量
演示如下:
小结:无论configmap还是secret,都可以多种方式被创建,创建完之后都可以被pod里面的container去使用
使用的方式:环境变量(container下面的env)、参数(container下面的args)、volume目录挂载(container下面的volume)
2.6.4 第二种Secret类型:kubernetes.io/dockerconfigjson(了解即可)
kubernetes.io/dockerconfigjson用于存储docker registry的认证信息,可以直接使用
kubectl create secret
命令创建
2.6.5 第三种Secret类型:kubernetes.io/service-account-token(了解即可)
用于被 serviceaccount 引用。
serviceaccout 创建时 Kubernetes 会默认创建对应的 secret。Pod 如果使用了 serviceaccount,对应的 secret 会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中。
小结:无论是ConfigMap,Secret,还是DownwardAPI,都是通过ProjectedVolume实现的,可以通过APIServer将信息放到Pod中进行使用。
三、Controller进阶学习之路
既然学习了Pod进阶,对于管理Pod的Controller肯定也要进阶一下,之前我们已经学习过的Controller有RC、RS和Deployment,除此之外还有吗?
官网
:https://kubernetes.io/docs/concepts/architecture/controller/
3.1 短暂性Pod:Job & CronJob
一次任务(主动触发) 完成了就是 completed 0/1 表示停止了,结束了。
持久性Pod 与 短暂性Pod
持久性Pod:就是启动之后,只要不销毁,就一直是Running,对这种Pod的管理,包括Deployment(无状态)、StatefulSet(有状态),其正常状态是Running
短暂性Pod:就是启动之后,先Running,Running完成之后就是Completed,对这种Pod的管理,包括Job,其正常状态是Completed
其中,Job也分为两种, 一次任务(主动触发) 就是 Job,定时任务(定时被动触发) 就是 CronJob。
3.1.1 Job
官网
:https://kubernetes.io/docs/concepts/workloads/controllers/jobs-run-to-completion/A Job creates one or more Pods and ensures that a specified number of them successfully terminate. As pods successfully complete, the Job tracks the successful completions. When a specified number of successful completions is reached, the task (ie, Job) is complete. Deleting a Job will clean up the Pods it created.
对于RS,RC之类的控制器,能够保持Pod按照预期数目持久地运行下去,它们针对的是持久性的任务,比如web服务。
而有些操作其实不需要持久,比如压缩文件,我们希望任务完成之后,Pod就结束运行,不需要保持在系统中,此时就需要用到Job。
所以可以这样理解,Job是对RS、RC等持久性控制器的补充。
负责批量处理短暂的一次性任务,仅执行一次,并保证处理的一个或者多个Pod成功结束。
Have a try
Here is an example Job config. It computes π to 2000 places and prints it out. It takes around 10s to complete.
vi job.yaml
kubectl apply -f job.yaml # 运行
kubectl describe jobs/pi # 日志
kubectl logs pod-name # 日志
- 非并行Job:
- 通常只运行一个Pod,Pod成功结束Job就退出。
- 固定完成次数的并行Job:
- 并发运行指定数量的Pod,直到指定数量的Pod成功,Job结束。
- 带有工作队列的并行Job:
- 用户可以指定并行的Pod数量,当任何Pod成功结束后,不会再创建新的Pod
- 一旦有一个Pod成功结束,并且所有的Pods都结束了,该Job就成功结束。
- 一旦有一个Pod成功结束,其他Pods都会准备退出。
3.1.2 CronJob
官网
:https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/cronJob是基于时间进行任务的定时管理。
- 在特定的时间点运行任务
- 反复在指定的时间点运行任务:比如定时进行数据库备份,定时发送电子邮件等等。
3.2 有状态的Pod:StatefulSet
Nginx 是平等的,无状态的,如下:
因为nginx是不存储数据的,只是做路由转发,做负载均衡,即使是运行服务端的tomcat也是无状态的。
官网
:https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/
- Stable, unique network identifiers.
- Stable, persistent storage.
- Ordered, graceful deployment and scaling.
- Ordered, automated rolling updates.
之前接触的Pod的管理对象比如RC、Deployment、DaemonSet和Job都是面向无状态的服务,但是现实中有很多服务是有状态的,比如MySQL集群、MongoDB集群、ZK集群等,都是存储数据的,它们都有以下共同的特点:
- 每个节点都有固定的ID,通过该ID,集群中的成员可以互相发现并且通信(不平等,每个id不同)
- 集群的规模是比较固定的,集群规模不能随意变动
- 集群里的每个节点都是有状态的,通常会持久化数据到永久存储中(持久化存储)
- 如果磁盘损坏,则集群里的某个节点无法正常运行,集群功能受损
而之前的RC/Deployment没办法满足要求,所以从Kubernetes v1.4版本就引入了PetSet资源对象,在v1.5版本时更名为StatefulSet。从本质上说,StatefulSet可以看作是Deployment/RC对象的特殊变种
- StatefulSet里的每个Pod都有稳定、唯一的网络标识,可以用来发现集群内其他的成员(不平等,每个id不同)
- Pod的启动顺序是受控的,操作第n个Pod时,前n-1个Pod已经是运行且准备好的状态
- StatefulSet里的Pod采用稳定的持久化存储卷,通过PV/PVC来实现,删除Pod时默认不会删除与StatefulSet相关的存储卷
- StatefulSet需要与Headless Service配合使用
日志监控每个pv pvc 会报错,找不到bound pv
pv pvc 是持久化存储 statefulSet是有状态,其完成持久化存储必须借助pv pvc
deployment 无法满足,因为deployment里面的pod都是没有状态的
集群内唯一标识id + pod启动顺序受控制 + 持久化存储
Have a try
vi nginx-st.yaml
kubectl apply nginx-st.yaml
watch kubectl get pods # 观察pod的创建顺序,以及pod的名字(重要)
3.3 每个Node都有的Pod:DaemonSet
官网
:https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/DaemonSet应用场景
- 运行集群存储 daemon,例如在每个节点上运行
glusterd
、ceph
。- 在每个节点上运行日志收集 daemon,例如
fluentd
、logstash
。- 在每个节点上运行监控 daemon,例如Prometheus Node Exporter、
collectd
、Datadog 代理、New Relic 代理,或 Gangliagmond
。
效果:就是pod在每个node节点上都运行,如下:
应用场景:普罗米修斯的日志收集,node-operator,需要pod在每个node节点上都运行。
四、Resource和Dashboard
4.1 Resource
Pod资源两要素: cpu + 内存
Pod共享两要素:网络+磁盘持久化
因为K8S的最小操作单元是Pod,所以这里主要讨论的是Pod的资源
官网
:https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/在K8S的集群中,Node节点的资源信息会上报给APIServer
requests&limits
可以通过这两个属性设置cpu和内存
limits 是上限,request是最小需要(即下限)
4.2 Dashboard
可视化:dashboard是简单的,普罗米修斯是复杂的
官网
:https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/Dashboard is a web-based Kubernetes user interface. You can use Dashboard to deploy containerized applications to a Kubernetes cluster, troubleshoot your containerized application, and manage the cluster resources. You can use Dashboard to get an overview of applications running on your cluster, as well as for creating or modifying individual Kubernetes resources (such as Deployments, Jobs, DaemonSets, etc). For example, you can scale a Deployment, initiate a rolling update, restart a pod or deploy new applications using a deploy wizard.
(1)根据yaml文件创建资源
vi dashboard.yaml (比较大,放在CSDN资源文件中下载)
kubectl apply -f dashboard.yaml
(2)查看资源
(3)使用火狐浏览器访问 (因为k8s中使用的是https 443,所以宿主机需要 https://宿主机ip:3008/)
特别注意1:在chrome浏览器中输入时,如果输入 https://192.168.100.151:30018 而不是 192.168.100.151:30018 ,即需要手动补上 https://
特别注意2:输入 https://192.168.100.151:30018 ,遇到这种情况,如下:
当前页面点击任意空白处,直接键盘输入“thisisunsafe”即可解决(不是在chrome浏览器搜索栏输入,而是选中网页,然后输入)。
原理是chrome认为这个网站是不安全的,不让你访问。而你输入了这句话,就类似于签了生死状,了解了风险。chrome就放你进去,但那之后再出问题也就没有责任了。
(4)生成登录需要的token
效果演示:
这里注意,dashboard.yaml 需要一个镜像 k8s.gcr.io/kubernetes-dashboard-amd64:v1.8.3 ,这个在国外,我一般是使用 docker load -i xxx.tar(或者xxx.tar.gz) 导入进去的,然后docker tag + docker push放到自己的阿里云镜像仓库,修改一下 dashboard.yaml 的 images 字段就可以使用了。
五、尾声
Kubernetes第七篇:Pod进阶、Controller进阶、Resource和Dashboard,完成了。
天天打码,天天进步!!