Kubernetes(3) Pod 配置详解

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 ControllersJobs, 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 <map[string]string>

例:

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 <string> (requried)

  pod.spec.containers.image <string>

  pod.spec.nodeSelector <map[string]string>  # deploy pod on the node with predefined label (see example)

  pod.spec.nodeName <string>  # deploy pod on the node with predefined label. Syntax is the same as nodeSelector

  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 <string>

  • 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: 什么也不会发生

 

posted on 2019-01-07 04:43  mad_baix  阅读(821)  评论(0编辑  收藏  举报

导航