https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/
一级字段: apiVersion(group/version), kind, metadata(name,namespace,labels,annotations, ...), spec, status(只读)
1 Pod 模板
Pod 是K8s中最小的资源单位,在应用中 Pod通常与Pod控制器组合使用。在Pod 模板中定义了 Pod的配置属性,这些属性在Pod控制器中的配置也是一样使用的。而控制器决定了Pod如何被使用。Pod控制器可以是 Replication Controllers, Jobs, and DaemonSets 等。
简单 Pod 模板例子:
apiVersion: extensions/v1beta1 kind: Pod metadata: name: pod-demo namespace: default labels: app: myapp tier: frontend spec: containers: - name: myapp image: ikubernetes/myapp:v1
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
imagePullPolicy: IfNotPresent command: ["/bin/sh"] args: ["-c", "while true; do echo hello; sleep 10;done"]
nodeSelector:
disktype: ssd # only the node with label "disktype=ssd"
2. 元数据 Metadata.
2.1 labels:
https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
https://kubernetes.io/docs/concepts/overview/working-with-objects/common-labels/#labels
kubectl 和 dashboard 都是展示k8s 的工具,在使用工具时常会用到 Labels 来筛选被展示的 Pod。
总体来讲你可以用用label做:
- 得到资源信息类似于数据库中的 SQL select * from resource where label = / != / not in / in / etc. label-name
- 部署应用到特定label的节点上 (比如部署深度学习到标记有 GPU的节点上)
Labels 是键值对:
- 键只可以包括字母,数字和 _, -, .
- 值可以包括空值,且首字母必须为字母或数字,其它和键规则一样
pod.metadata.labels
例:
apiVersion: apps/v1 kind: StatefulSet metadata: labels: app.kubernetes.io/name: mysql app.kubernetes.io/instance: wordpress-abcxzy app.kubernetes.io/version: "5.7.21" app.kubernetes.io/component: database app.kubernetes.io/part-of: wordpress app.kubernetes.io/managed-by: helm
一些有实际应用的命令:
kubectl label pods pod-demo release=stable --overwrite # label pod with name pod-demo with label "release", which is stable. If label already exists, should be overwrite
kubectl get pods -l release --show-labels # show all pods with label "release" kubectl get pods -l release=stable # show all pods with label "release = stable" kubectl get pods -l release=stable,app=myapp # show all pods with labels release=stable,app=myapp
kubectl get pods -l "release in (canary,beta,alpha,app) # show all pods with label release, which release contains one from canary,beta,alpha,app
kubectl get pods -l "release notin (alpha, beta) # show all pods with label release, which dont contain alpha, beta
如上所说,用户可以部署应用到特殊选定的节点上,比如部署某应用到有SSD 硬盘上的节点:
# part of deployment template
...
spec:
selector:
matchLabels:
disktype: SSD
...
选择器(selector): 用来选择设定好的标签,比如 Deployment selector:
-> deployment.spec.selector:
matchLabels:直接给定键值
matchExpressions:基于给定的表达式来定义使用标签选择器,{key:"KEY", operator:"OPERATOR", values:[VAL1,VAL2,...]}
操作符:
In, NotIn:values字段的值必须为非空列表;
Exists, NotExists:values字段的值必须为空列表;
2.2 Annotations
用户也可以使用注释来补充metadata 信息。客户端也可以使用特定API调取annotation信息。详见:https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
Labels 可以用于选择一组满足特定定义条件的操作对象。相反 annotations 则不是应用在选择器这种场景。
Annotations 也是键值类型:
"metadata": { "annotations": { "key1" : "value1", "key2" : "value2" } }
apiVersion: extensions/v1beta1 kind: Pod metadata: name: pod-demo namespace: default labels: app: myapp tier: frontend
annotations:
created-by: "cluster admin" spec: containers: - name: myapp image: ikubernetes/myapp:v1 ports: - name: http containerPort: 80 - name: https containerPort: 443 imagePullPolicy: IfNotPresent command: ["/bin/sh"] args: ["-c", "while true; do echo hello; sleep 10;done"] nodeSelector: disktype: ssd # only the node with label "disktype=ssd"
3. Spec
spec 是定义 Pod 期望达到的状态,下面是一些常用的 pod spec 字段:
pod.spec.containers <[] object>(requried)
pod.spec.containers.name
pod.spec.containers.image
pod.spec.nodeSelector
pod.spec.nodeName
pod.spec.containers.command/args <[] string>
pod.spec.containers.ports <[] object> -> only a additional information for user, it is not a real expose of port number
pod.spec.containers.imagePullPolicy
- Always -> 始终远程资源 中下载镜像。 (比如本地nginx image latest version 是14.1 且 Docker Hub 中latest nginx 为 14.3。由于配置为 Alway 在启动新Pod 的时候 Kubernetes会自动从 Docker Hub 中拉取最新的 14.3 镜像到本地)
- Never -> 仅从本地镜像仓库拉取镜像
- ifNotPresent -> 如果本地已有需要被拉镜像则从本地拉取,如果没有则访问远程镜像仓库拉取资源
对于开发者来说,如果一直都需要最后版本则应该设置imagePullPolicy 为Always. 如果你只想要特定版本的资源则设置 imagePullPolicy 为 ifNotPresent (详见: https://kubernetes.io/docs/concepts/containers/images/#updating-images)
4. Pod 生命周期
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/
用户在Kubernetes中创建Pod时会发生如下操作:
用户首先发送"create pod"请求到 apiserver, apiserver 将该请求(目标Pod状态)储存于 etcd 之中。然后apiserver 将请求 Scheduler (Scheduler知道节点上资源占用情况)调度一个新作业且将作业返回结果(哪个节点完成了该调度任务)存入etcd中。在该操作结束之后,调度了这个作业的节点的kubelet 服务会抓取变更信息,且根据提交到apiserver的Pod目标状态建立新的Pod资源。最后返回结果(pod 成功被启动或者是被)给 apiserver。Aipserver最终将该结果储存到 etcd中。
下面会继续探讨在Pod 建立的过程中会经理哪些步骤:
- 首先容器会逐次被初始化
- PostStart hook 在容器初始化之后会立刻自动执行 https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/
- 在 PostStart hook 执行之后主容器会执行两种探测(probes) -> liveness probe, readiness probe ( see: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes) * liveness (容器中所有定义的服务都必须为健康状态); readiness (表示容器已经准备好对外提供服务)
- PreStop hook 会在容器结束之前被调用
5 Pod restartPolicy
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy
pod spec 字段中包含了restartPolicy 字段,该字段可以赋三种不同的值Always, OnFailure, and Never。在默认状态下该值为 Always,restartPolicy 会按这个值决定何时重启容器,且restartPolicy 只通过该容器运行的节点上的 kubelet服务来重新启动容器。重启周期不是马上执行,而是带有一定延迟(10s,20s,40s 。。。5分钟),且该延迟在正常启动的10分钟后回置为10s 的初始状态。且不会与其他节点关联 见Pods document,
- Always (default): 当容器终止退出后,总是重启容器,默认策略
- OnFailure: 当容器异常退出(退出状态码非0)时,才重启容器
- Never: 容器不会被重启
例如容器在 "sleep 10" 后重启:
-> Always: 这个容器会每隔10秒重新启动 (正常结束)
-> OnFailure: 不会发生任何事因为状态码为 0
-> Never: 什么也不会发生