【04】Kubernets:资源清单(pod)

写在前面的话

前面我们提到过,纯手敲 K8S 名称管理 K8S 服务只是作为我们了解 K8S 的一种方案,而我们最终管理 K8S 的方法还是通过接下来的资源清单的方式进行管理。

所以从本章节开始,将会迎来 K8S 的重中之重,我们能否说我们会 K8S 就看就看接下来的学习。

另外,在 K8S 中,我们需要树立一个这样的概念,几乎能用到的东西都可以把它称作资源,而这个定义了规则的 yaml 文件就是资源清单。

资源清单格式

资源清单格式:

apiVersion: group/apiversion  # 如果没给定 group 名称,默认 core,可使用 kubectl api-versions 查看当前所有
kind:           # 资源类别
metadata:       # 资源元素据
    name
    namespace   # K8S 自身的 namespace
    labels      # 标签,键值对
    annotations # 资源注解
spec:           # 期望的状态(最重要)
status:         # 当前状态,用户不用定义

查看支持的 apiVersion:

获取资源清单一级字段:

kubectl explain pod

结果如图:

获取资源清单二级字段:

kubectl explain pod.metadata

结果如图:

同理,查看三级字段继续使用 . 加关键字就行了。

创建第一个 Pod 资源清单

创建一个简单的 Pod 资源清单:

vim pod-demo.yaml

内容如下:

apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: default
  labels:
    app: pod-demo
    tier: frontend
spec:
  containers:
  - name: app-container
    image: ikubernetes/myapp:v1
  - name: busy-container
    image: busybox:latest
    command: ["/bin/sh", "-c", "sleep 3600"]

简单说明:在我们 explain 查看某个关键字下面的关键字的时候,如果关键字的值类型是:<[]Object>,则代表是列表对象,需要使用 -,如果是:<map[string]string>,则是键值对,不需要 -

在上面的 yaml 中,containers 就是列表对象,而 labels 就是键值对。

我们可以定义多个容器组成一个 Pod,之前我们说过 Pod 由一个或者多个容器组成,同时我们也可以使用 command 指令来修改 Pod 中容器的初始运行命令。可以以列表的形式,也可以是 yaml 格式。我这里为例阅读性,选用的是列表的形式。

根据文件创建 Pod:

# 创建
kubectl create -f pod-demo.yaml

# 查看
kubectl get pods -o wide

# 查看详情
kubectl describe pod pod-demo

结果如图:

我们可以在 describe 中看到我们在 yaml 中定义的所有信息。甚至更多的包括系统给我们补全的一些默认信息。

此时我们可以内部访问一下我们这个 Pod:

同时,资源清单 yaml 文件还给我们提供了一个方便之处在于,我们删除变得更为简单:

kubectl delete -f pod-demo.yaml

结果如图:可能会出现稍微卡一下

标签选择

我们在这里补充一个知识点,在上面我们定义的资源清单中,在 metadata 中提到了 labels 标签选项,那么对于这个标签我们应该如何利用:

# 查看 pod 的标签
kubectl get pods --show-labels 

结果如图:

标签筛选:在判断关系的时候,标签的关系可以是 =,!=,in,notin

# 显示指定标签的值
kubectl get pods -L app

# 显示包含指定标签的 pod
kubectl get pods -l app --show-labels

# 显示指定标签为指定值的 pod
kubectl get pods -l app=pod-demo,tier=frontend --show-labels

# 关系筛选
kubectl get pods -l "app in (pod-demo,pod-test,pod-dev)"

结果如图:

给 Pod 打标签或者修改标签:

# 给 pod 打标签
kubectl label pods pod-demo tag=v1.0

# 修改 pod 标签
kubectl label pods pod-demo tag=v2.0 --overwrite

查看结果:

给节点打标签:

kubectl label nodes node2 serverType=app

查看同理。

pod.spec 字段

对于 yaml 资源清单,我们需要知道的是,其主要配置都在 spec 字段中。我们这里就针对 Pod 资源的 spec 里面常用的方法做个说明:

pod.spec
containers     容器相关配置
  name   容器名称
  image   容器镜像
  imagePullPolicy   容器获取策略,Always / Never / IfNotPresent,镜像版本是 latest 默认 Always
  ports   说明端口。并非暴露端口
    name 给这个端口命名,后面可以根据这个名字调用这个端口
    containerPort 说明具体端口。并非暴露端口
    protocol 协议,UDP / TCP / SCTP,默认 TCP
    hostIP 绑定端口,意义不大,一般默认 0.0.0.0
  command   运行指定命令,替代 docker 中默认定义的
  args   参数,如果有配置,docker 中默认的参数将被改配置取代
  livenessProbe   存活性检测
    exec command <[]string>,通过命令来直接探测
    httpGet HTTP 探测,host 主机一般不配置,port 请求端口,path
    tcpSocket tcp 检测
    failureThreshold 探测失败次数,默认 3 次
    periodSeconds 每次间隔时间,默认 10 秒
    timeoutSeconds 超时时间,默认 1 秒
    initialDelaySeconds 容器启动后多久开始探测
  readinessProbe   就绪性检测
  lifecycle   生命周期
    postStart 启动前,方法和 livenessProbe 类似
    preStop 启动后,方法和 livenessProbe 类似
nodeSelector     节点标签选择器,可以限定 Pod 运行的节点
nodeName     直接指定运行节点
restartPolicy     重启策略,Always / OnFailure / Never,默认 Always

资源清单示例 

在这之前我们先给一个节点打标签:

kubectl label nodes node2 serverType=app-server --overwrite

【1】普通的较为完整的资源清单:

apiVersion: v1
kind: Pod
metadata:
  name: pod-normal-demo
  namespace: default
  labels:
    app: erp
    tier: frontend
    release: stable
  annotations:
    ezops.cn/create-by: "Dylan"
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    - name: https
      containerPort: 443
  - name: busybox-demo
    image: busybox:latest
    imagePullPolicy: Always
    command: ["/bin/sh", "-c", "sleep 3600"]
    #args: ["-f", "-h /tmp"]
  nodeSelector:
    serverType: app-server
  restartPolicy: Never

我们这里修改了容器内部运行的默认命令。并通过标签选择器选择了指定节点。配置了重启规则。

kubectl create -f pod-normal-demo.yaml

查看创建结果:

可以看到已经成功在我们选择的 Node 2 节点上面运行起来,查看详情:(由于内容太多,我直接贴处理

Name:               pod-normal-demo
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               node2/192.168.100.102
Start Time:         Wed, 29 May 2019 09:56:11 +0800
Labels:             app=erp
                    release=stable
                    tier=frontend
Annotations:        ezops.cn/create-by: Dylan
Status:             Running
IP:                 10.1.1.14
Containers:
  myapp:
    Container ID:   docker://e4e97361c6cc533a4533080f06f7b596e0bc0caa954f7f2ef503d6d9a2aae631
    Image:          ikubernetes/myapp:v1
    Image ID:       docker-pullable://ikubernetes/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30d513
    Ports:          80/TCP, 443/TCP
    Host Ports:     0/TCP, 0/TCP
    State:          Running
      Started:      Wed, 29 May 2019 09:56:12 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-jr9rz (ro)
  busybox-demo:
    Container ID:  docker://0cce3f9dcc16b40aabcceb94c44be49e3434bff28dfc6800c7769cd8d1d5948f
    Image:         busybox:latest
    Image ID:      docker-pullable://busybox@sha256:4b6ad3a68d34da29bf7c8ccb5d355ba8b4babcad1f99798204e7abb43e54ee3d
    Port:          <none>
    Host Port:     <none>
    Command:
      /bin/sh
      -c
      sleep 3600
    State:          Running
      Started:      Wed, 29 May 2019 09:56:14 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-jr9rz (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-jr9rz:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-jr9rz
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  serverType=app-server
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  18m   default-scheduler  Successfully assigned default/pod-normal-demo to node2
  Normal  Pulled     18m   kubelet, node2     Container image "ikubernetes/myapp:v1" already present on machine
  Normal  Created    18m   kubelet, node2     Created container myapp
  Normal  Started    18m   kubelet, node2     Started container myapp
  Normal  Pulling    18m   kubelet, node2     Pulling image "busybox:latest"
  Normal  Pulled     18m   kubelet, node2     Successfully pulled image "busybox:latest"
  Normal  Created    18m   kubelet, node2     Created container busybox-demo
  Normal  Started    18m   kubelet, node2     Started container busybox-demo

其中红色部分就是这次我们特别定义的一些规则。 

【2】存活性检测资源清单:

apiVersion: v1
kind: Pod
metadata:
  name: liveness-pod
  namespace: default
  labels:
    app: erp
    tier: frontend
    release: stable
  annotations:
    ezops.cn/create-by: "Dylan"
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    - name: https
      containerPort: 443
    livenessProbe:
      httpGet:
        port: http
        path: /index.html
      initialDelaySeconds: 10
      periodSeconds: 3
  restartPolicy: Always

我们这里有两个知识点:

1. ports 里面定义的 name 我们在后面是可以引用的,如 httpGet 的 port 我们就直接些上面定义的 http。

2. livenessProbe 的应用,再配合 restartPolicy 完成程序自检和维护。

如果用 exec 命令样式,可以用来检测文件是否存在,如:

livenessProbe:
  exec:
    command: ["/bin/test" "-e /tmp/1.txt"]

另外,就绪性检测和存活性检测类似。

【3】生命周期 poststart:

apiVersion: v1
kind: Pod
metadata:
  name: poststart-demo
  namespace: default
  labels:
    app: erp
  annotations:
    ezops.cn/create-by: "Dylan"
spec:
  containers:
  - name: httpd-server
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    lifecycle:
      postStart:
        exec:
          command: ["mkdir", "-p"," /data/web/html"]
 command: ["/bin/sh","-c","sleep 3600"]

小结

本章节初步使用了资源清单,这些关键不要求死记硬背,但是一定得知道个大概,基础得框架我们得记住。至于其他详细得则可以通过 explain 查询。

另外我们之前提了自主式 Pod,我们这里建立的都是自主式 Pod,没有上级管理,因为着删除了这个 Pod 不会自动重建。 

原文地址:https://www.cnblogs.com/Dy1an/p/10823724.html