深入理解Pod对象

作者: 风 哥 分类: Kubernetes 发布时间: 2019-01-29 14:58

Pod容器分类

最小部署单元

一组容器的集合

一个Pod中的容器共享网络命名空间

Pod是短暂的

 

• Infrastructure Container:基础容器
• 维护整个Pod网络空间
• InitContainers:初始化容器
• 先于业务容器开始执行
• Containers:业务容器
• 并行启动

镜像拉取策略

• IfNotPresent:默认值,镜像在宿主机上不存在时才拉取
• Always:每次创建 Pod 都会重新拉取一次镜像
• Never: Pod 永远不会主动拉取这个镜像

apiVersion: v1
kind: Pod
metadata:
  name: foo
  namespace: defalut
spec:
  containers:
    - name: foo
      image: janedoe/awesomeapp:v1 
      imagePullPolicy: IfNotPresent

对于拉取镜像时需要镜像仓库密码的时候的我们可以创建用户凭据,以便下次可以直接使用。参考官方文档:https://kubernetes.io/docs/concepts/containers/images/

在我们登录镜像仓库后,会在当前用户家目录下有个.docker/config.json文件,这里面存放了一些认证信息,可以通过base64转码后再存放到k8s Secret中进行加密保存

< 2  docker-release - [root]: ~ > # cd .docker/
< 3  docker-release - [root]: ~/.docker > # ll
total 4
-rw-------. 1 root root 306 2019-01-12 14:53 config.json
< 4  docker-release - [root]: ~/.docker > # cat config.json
{
  "auths": {
    "harbor.xxx.com": {
      "auth": "YWRtaW46SGFyYm9yMTIzNDU="
    },

    "harbor.srv.xxx.com": {
      "auth": "YWRtaW46SGFyYm9yMTIzNDUu"
    }
  },
  "HttpHeaders": {
    "User-Agent": "Docker-Client/18.06.1-ce (linux)"
  }

 

< 5  docker-release - [root]: ~/.docker > # base64  /root/.docker/config.json
ewoJImF1dGhzIjogewoJCSJoYXJib3IuZmx5YnljbG91ZC5jb20iOiB7CgkJCSJhdXRoIjogIllX
UnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9LAoJCSJoYXJib3IuZmx5Ynl0cmlwLmNvbSI6IHsK
CQkJImF1dGgiOiAiWVdSdGFXNDZTR0Z5WW05eU1USXpORFU9IgoJCX0sCgkJImhhcmJvci5zcnYu
Zmx5Ynljcy5jb20iOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVdSIKCQl9
Cgl9LAoJIkh0dHBIZWFkZXJzIjogewoJCSJVc2VyLUFnZW50IjogIkRvY2tlci1DbGllbnQvMTgu
MDYuMS1jZSAobGludXgpIgoJfQp9

将转码后的字符串放到 .dockerconfigjson: 字段下面,使用kubectl create -f  secret.yaml创建认证

apiVersion: v1
kind: Secret
metadata:
  name: myregistrykey
  namespace: awesomeapps
data:
  .dockerconfigjson: ewoJImF1dGhzIjogewoJCSJoYXJib3IuZmx5YnljbG91ZC5jb20iOiB7CgkJCSJhdXRoIjogIllX
UnRhVzQ2U0dGeVltOXlNVEl6TkRVPSIKCQl9LAoJCSJoYXJib3IuZmx5Ynl0cmlwLmNvbSI6IHsK
CQkJImF1dGgiOiAiWVdSdGFXNDZTR0Z5WW05eU1USXpORFU9IgoJCX0sCgkJImhhcmJvci5zcnYu
Zmx5Ynljcy5jb20iOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2U0dGeVltOXlNVEl6TkRVdSIKCQl9
Cgl9LAoJIkh0dHBIZWFkZXJzIjogewoJCSJVc2VyLUFnZW50IjogIkRvY2tlci1DbGllbnQvMTgu
MDYuMS1jZSAobGludXgpIgoJfQp9
type: kubernetes.io/dockerconfigjson

在pull image时加上imagePullSecrets: 参数, name对应上述创建的name值。

apiVersion: v1
kind: Pod
metadata:
  name: foo
  namespace: defalut
spec:
  containers:
    - name: foo
      image: janedoe/awesomeapp:v1

  imagePullSecrets:
    - name: myregistrykey

资源限制

Pod和Container的资源请求和限制:
• spec.containers[].resources.limits.cpu
• spec.containers[].resources.limits.memory
• spec.containers[].resources.requests.cpu
• spec.containers[].resources.requests.memory

以下 Pod 有两个容器。每个容器的请求为 0.25 cpu 和 64MiB(226 字节)内存,每个容器的限制为 0.5 cpu 和 128MiB 内存。该 Pod 请求 0.5 cpu 和 128 MiB 的内存,限制为 1 cpu 和 256MiB 的内存。

< 155  master01 - [root]: ~/yaml-test > # vim pod-cpu.yaml

apiVersion: v1
kind: Pod
metadata:
  name: frontend
spec:
  containers:
  - name: db
    image: mysql
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
  - name: wp
    image: wordpress
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"
< 156  master01 - [root]: ~/yaml-test > # kubectl apply -f pod-cpu.yaml
pod/frontend created

 

< 159  master01 - [root]: ~/yaml-test > # kubectl describe nodes
Name:               192.168.1.118
Roles:              <none>
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/hostname=192.168.1.118
Annotations:        node.alpha.kubernetes.io/ttl: 0
                    volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp:  Sat, 26 Jan 2019 15:15:27 +0800
Taints:             <none>
Unschedulable:      false
Conditions:
  Type             Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----             ------  -----------------                 ------------------                ------                       -------
  OutOfDisk        False   Mon, 28 Jan 2019 19:16:10 +0800   Mon, 28 Jan 2019 10:35:54 +0800   KubeletHasSufficientDisk     kubelet has sufficient disk space available
  MemoryPressure   False   Mon, 28 Jan 2019 19:16:10 +0800   Mon, 28 Jan 2019 10:35:54 +0800   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure     False   Mon, 28 Jan 2019 19:16:10 +0800   Mon, 28 Jan 2019 10:35:54 +0800   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure      False   Mon, 28 Jan 2019 19:16:10 +0800   Sat, 26 Jan 2019 15:15:27 +0800   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready            True    Mon, 28 Jan 2019 19:16:10 +0800   Mon, 28 Jan 2019 10:35:54 +0800   KubeletReady                 kubelet is posting ready status
Addresses:
  InternalIP:  192.168.1.118
  Hostname:    192.168.1.118
Capacity:
 cpu:                2
 ephemeral-storage:  21595852Ki
 hugepages-2Mi:      0
 memory:             3863536Ki
 pods:               110
Allocatable:
 cpu:                2
 ephemeral-storage:  19902737171
 hugepages-2Mi:      0
 memory:             3761136Ki
 pods:               110
System Info:
 Machine ID:                 a2292d03bc934f83989a1c39fca04278
 System UUID:                564D48C7-E279-D34E-76B5-CAC724CBD7EC
 Boot ID:                    b7ccabe3-d8d4-4c09-8765-fdb3fccbd826
 Kernel Version:             3.10.0-862.14.4.el7.x86_64
 OS Image:                   CentOS Linux 7 (Core)
 Operating System:           linux
 Architecture:               amd64
 Container Runtime Version:  docker://18.9.1
 Kubelet Version:            v1.12.4
 Kube-Proxy Version:         v1.12.4
Non-terminated Pods:         (4 in total)
  Namespace                  Name                                 CPU Requests  CPU Limits  Memory Requests  Memory Limits
  ---------                  ----                                 ------------  ----------  ---------------  -------------
  default                    frontend                             500m (25%)    1 (50%)     128Mi (3%)       256Mi (6%)
  default                    nginx-7b67cfbf9f-fbgmr               0 (0%)        0 (0%)      0 (0%)           0 (0%)
  default                    nginx-deployment-5d445489fb-jmpm7    0 (0%)        0 (0%)      0 (0%)           0 (0%)
  default                    nginx-deployment-5d445489fb-q2xgh    0 (0%)        0 (0%)      0 (0%)           0 (0%)
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource  Requests    Limits
  --------  --------    ------
  cpu       500m (25%)  1 (50%)
  memory    128Mi (3%)  256Mi (6%)
Events:     <none>

重启策略

• Always:当容器终止退出后,总是重启容器,默认策略。
• OnFailure:当容器异常退出(退出状态码非0)时,才重启容器。
• Never::当容器终止退出,从不重启容器

apiVersion: v1 
kind: Pod 
metadata: 
  name: foo 
  namespace: awesomeapps 

spec: 
  containers: 
    - name: foo 
      image: janedoe/awesomeapp:v1 
  restartPolicy: Always

示例1,创建busybox容器,在容器启动后暂停30秒然后退出

< 4  master01 - [root]: ~/yaml-test > # vim pod3.yaml

apiVersion: v1
kind: Pod
metadata:
  name : foo
spec:
  containers:
  - name: busybox
    image: busybox

    args:
    - /bin/sh
    - -c
    - sleep 30 ; exit 3

pod每隔30秒会重启一次,即销毁容器重新创建。

< 17  master01 - [root]: ~/yaml-test > # kubectl apply -f pod3.yaml
pod/foo created
< 18  master01 - [root]: ~/yaml-test > # kubectl get pods
NAME                                READY   STATUS             RESTARTS   AGE
foo                                 1/1     Running            1          42s

健康检查

Probe有以下两种类型:

livenessProbe

如果检查失败,将杀死容器,根据Pod的restartPolicy来操作。

readinessProbe

如果检查失败,Kubernetes会把Pod从service endpoints中剔除。

Probe支持以下三种检查方法:

httpGet

发送HTTP请求,返回200-400范围状态码为成功。

exec

执行Shell命令返回状态码是0为成功。

tcpSocket

发起TCP Socket建立成功。

< 33  master01 - [root]: ~/yaml-test > # vim pod4.yaml

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 25

    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

 

< 34  master01 - [root]: ~/yaml-test > # kubectl apply -f pod4.yaml
pod/liveness-exec created
< 35  master01 - [root]: ~/yaml-test > # kubectl get pods
NAME                                READY   STATUS             RESTARTS   AGE
foo                                 0/1     CrashLoopBackOff   12         47m
frontend                            1/2     CrashLoopBackOff   195        16h
liveness-exec                       1/1     Running            0          5s

当cat /tmp/healthy文件不存在时,命令返回1,健康检查则会出现异常,然后pod会进行重建。

< 65  master01 - [root]: ~/yaml-test > # kubectl get pods
NAME                                READY   STATUS             RESTARTS   AGE
foo                                 0/1     CrashLoopBackOff   12         48m
frontend                            1/2     CrashLoopBackOff   195        16h
liveness-exec                       1/1     Running            1          62s

describe命令会显示出详细的信息

< 66  master01 - [root]: ~/yaml-test > # kubectl describe pod/liveness-exec
Name:               liveness-exec
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               192.168.1.119/192.168.1.119
Start Time:         Tue, 29 Jan 2019 11:37:51 +0800
Labels:             test=liveness
Annotations:        kubectl.kubernetes.io/last-applied-configuration:
                      {"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"test":"liveness"},"name":"liveness-exec","namespace":"default"},"s...
Status:             Running
IP:                 172.17.37.7
Containers:
  liveness:
    Container ID:  docker://2d33a94876a6fe5734cb04a8e3183821caa3bdbb00aa348a075574653b557243
    Image:         busybox
    Image ID:      docker-pullable://busybox@sha256:7964ad52e396a6e045c39b5a44438424ac52e12e4d5a25d94895f2058cb863a0
    Port:          <none>
    Host Port:     <none>
    Args:
      /bin/sh
      -c
      touch /tmp/healthy; sleep 10; rm -rf /tmp/healthy; sleep 25
    State:          Running
      Started:      Tue, 29 Jan 2019 11:40:18 +0800
    Last State:     Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Tue, 29 Jan 2019 11:39:42 +0800
      Finished:     Tue, 29 Jan 2019 11:40:17 +0800
    Ready:          True
    Restart Count:  4
    Liveness:       exec [cat /tmp/healthy] delay=5s timeout=1s period=5s #success=1 #failure=3
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-l9bss (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  default-token-l9bss:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-l9bss
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type     Reason     Age                   From                    Message
  ----     ------     ----                  ----                    -------
  Normal   Scheduled  2m57s                 default-scheduler       Successfully assigned default/liveness-exec to 192.168.1.119
  Normal   Pulled     103s (x3 over 2m55s)  kubelet, 192.168.1.119  Successfully pulled image "busybox"
  Normal   Created    103s (x3 over 2m55s)  kubelet, 192.168.1.119  Created container
  Normal   Started    102s (x3 over 2m55s)  kubelet, 192.168.1.119  Started container
  Warning  Unhealthy  77s (x9 over 2m42s)   kubelet, 192.168.1.119  Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
  Normal   Pulling    67s (x4 over 2m56s)   kubelet, 192.168.1.119  pulling image "busybox"
  Normal   Killing    67s (x3 over 2m19s)   kubelet, 192.168.1.119  Killing container with id docker://liveness:Container failed liveness probe.. Container will be killed and recreated.

官方文档:https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/

调度约束

nodeName用于将Pod调度到指定的Node名称上

有时候我们需要将某个pod调度到其它的node节点,此时可以通过nodeName的方式来指定pod调度到哪一台node节点中。

< 68  master01 - [root]: ~/yaml-test > # vim pod5.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-example
  labels:
    app: nginx
spec:
  nodeName: 192.168.1.118
  containers:
  - name: nginx
    image: nginx:1.15
< 69  master01 - [root]: ~/yaml-test > # kubectl apply -f pod5.yaml
pod/pod-example created
< 70  master01 - [root]: ~/yaml-test > #
< 70  master01 - [root]: ~/yaml-test > # kubectl get pods -o wide
NAME                                READY   STATUS             RESTARTS   AGE     IP            NODE            NOMINATED NODE
foo                                 0/1     CrashLoopBackOff   49         4h16m   172.17.37.6   192.168.1.119   <none>
frontend                            1/2     CrashLoopBackOff   236        19h     172.17.75.5   192.168.1.118   <none>
liveness-exec                       1/1     Running            71         3h29m   172.17.37.7   192.168.1.119   <none>
nginx-7b67cfbf9f-qwhf6              1/1     Running            0          24h     172.17.37.2   192.168.1.119   <none>
pod-example                         1/1     Running            0          9s      172.17.75.6   192.168.1.118   <none>

 

• nodeSelector用于将Pod调度到匹配Label的Node上

< 73  master01 - [root]: ~/yaml-test > # vim pod6.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-example
spec:
  nodeSelector:
    env_role: dev
  containers:
  - name: nginx
    image: nginx:1.15

先给node打一标签以便可以更清晰知道是哪一台节点

kubectl label nodes 192.168.1.22 team=a

查看标签

< 72  master01 - [root]: ~/yaml-test > # kubectl get nodes --show-labels
NAME            STATUS   ROLES    AGE     VERSION   LABELS
192.168.1.118   Ready    <none>   2d23h   v1.12.4   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=192.168.1.118
192.168.1.119   Ready    <none>   2d23h   v1.12.4   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/hostname=192.168.1.119

故障排查

kubectl describe TYPE/NAME
kubectl logs TYPE/NAME [-c CONTAINER]
kubectl exec POD [-c CONTAINER] — COMMAND [args…]

 

官方文档:https://kubernetes.io/zh/docs/concepts/workloads/pods/pod-lifecycle/

发表评论

电子邮件地址不会被公开。 必填项已用*标注