CKA 06_Kubernetes 工作负载与调度 Pod 管理 yaml 资源清单 标签 Pod 生命周期 容器探针

news2024/11/27 4:03:02

工作负载与调度

  • 1. Pod 管理
    • 1.1 kubectl 命令
  • 2. yaml 资源清单
    • 2.1 yaml 文件的格式
    • 2.2 编写 yaml 资源清单
  • 3. 标签
    • 3.1 节点标签选择器
  • 考试题目:pod 中运行 nginx 和 memcache 容器
  • 4. Pod 生命周期
    • 4.1 Init 容器
  • 5. 容器探针
    • 5.1 探测类型
    • 5.2 配置存活、就绪和启动探测器
    • 5.3 定义存活命令
    • 5.4 定义就绪探测器

官方文档:工作负载 | Pods

1. Pod 管理

  • 容器的本质是一个视图被隔离、资源受限的进程。

  • Pod 是一个逻辑单位,多个容器的组合,kubernetes 的原子调度单位。

  • 一个 pod 类似一个豌豆荚,包含一个或多个容器,多个容器间共享 IPC、Network 和 UTC namespace。

  • Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。

  • Pod (就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个) 容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。 Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。 Pod 所建模的是特定于应用的“逻辑主机”,其中包含一个或多个应用容器, 这些容器是相对紧密的耦合在一起的。 在非云环境中,在相同的物理机或虚拟机上运行的应用类似于 在同一逻辑主机上运行的云应用。

  • 什么是 Pod ?

    • Pod 的共享上下文包括一组 Linux 名字空间、控制组(cgroup)和可能一些其他的隔离 方面,即用来隔离 Docker 容器的技术。 在 Pod 的上下文中,每个独立的应用可能会进一步实施隔离。

    • 就 Docker 概念的术语而言,Pod 类似于共享名字空间和文件系统卷的一组 Docker 容器。
      在这里插入图片描述

  • pod 要解决的核心问题:

    容器之间是被 Linux namespace 和 cgroups 隔离的

  • pod 实现机制:
    共享网络:

    • 容器通过 infra 容器(汇编语言编写,永远处于暂停状态)共享同一个网络命名空间。
    • 容器之间使用 localhost 高速通信。
    • 一个 pod 只有一份网络资源,被该 pod 内的容器共享。
    • pod 的生命周期与 infra 容器一致,与其他容器无关。

    共享存储

    • 容器通过挂载共享的 volume 来实现共享存储

在这里插入图片描述

在这里插入图片描述

1.1 kubectl 命令

官方文档:Kubectl Reference Docs
官方文档:Kubectl 概述

-考试会考的命令:–sort-by=
使用名称排序的命令(官网)
使用CPU最高的排序(官网)

# 列出当前名字空间下所有 Services,按名称排序
kubectl get services --sort-by=.metadata.name

# 列出 Pods,按重启次数排序
kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'

# 列举所有 PV 持久卷,按容量排序
kubectl get pv --sort-by=.spec.capacity.storage
  1. 创建 Pod
  • 集群内部任意节点可以访问 Pod,但集群外部无法直接访问。
[root@k8s1 kubernetes]# kubectl run qian --image=nginx
pod/qian created
[root@k8s1 kubernetes]# kubectl get pod 
NAME   READY   STATUS              RESTARTS   AGE
qian   1/1     Running             0          30s
  1. 删除 Pod
  • 记得考试的时候,在命令后面加上 “ --force ”,这样删除会更快一些
[root@k8s1 kubernetes]# kubectl delete --force pod test
warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely.
pod "test" force deleted

2. yaml 资源清单

2.1 yaml 文件的格式

  • 格式如下:
apiVersion: group/version  //指明api资源属于哪个群组和版本

kind: 						//标记创建的资源类型,k8s主要支持以下资源类别
							//Pod,ReplicaSet,Deployment,StatefulSet,DaemonSet,Job,Cronjob
    
metadata:					//元数据
  name:					//对象名称
  namespace:				//对象属于哪个命名空间
  labels:					//指定资源标签,标签是一种键值数据

spec: 						//定义目标资源的期望状态
  • 查询帮助文档
kubectl explain pod

在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述

2.2 编写 yaml 资源清单

  • 考试的时候,为了方便可以通过 kubectl 的命令导出一个 yaml 资源清单
    这样节约时间
[root@k8s1 ~]# kubectl get pod test -o yaml > pod.yaml
[root@k8s1 ~]# vim pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: test
  name: test
  namespace: default
  resourceVersion: "8646"
  uid: a3836d42-9e54-4a8f-b219-a06a5556cc99
spec:
  containers:
  - image: nginx
    imagePullPolicy: Always
    name: test
  • 如果要查看 pod 的期望状态
kubectl exolain  pod.spec.containers 
  1. 一个 pod 中如果定义两个 nginx 容器,那么会发生冲突
[root@k8s1 ~]# vim pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: qianqian
  name: qianqian
  namespace: default
spec:
  containers:
  - image: nginx
    imagePullPolicy: Always
    name: qianqian
  - name: yao
    image: nginx
    imagePullPolicy: IfNotPresent		// 本地没有就拉取
[root@k8s1 ~]# kubectl apply -f pod.yaml 
pod/qianqian created
  • 通过 kubectl describe pod qianqian 命令查看 pod 的运行日志,发现第一个容器 qianqian 在 k8s2 上成功运行,第二个容器 yao 是失败的状态
  1. 一个 pod 中如果定义两个容器,分别是 nginx 和 busybox,没有发生冲突
[root@k8s1 ~]# vim pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: aaa 
  name: aaa
  namespace: default
spec:
  containers:
  - image: nginx
    imagePullPolicy: Always
    name: aaa
  - image: busybox
    name: bbb 
    stdin: true
    tty: true
  tolerations:
  - key: "example-key"
    operator: "Exists"
    effect: "NoSchedule"
[root@k8s1 ~]# kubectl apply -f pod.yaml 
pod/aaa created
[root@k8s1 ~]# kubectl get pod
NAME   READY   STATUS    RESTARTS   AGE
aaa    2/2     Running   0          2m46s
  • 查看 pod 创建的过程
[root@k8s1 ~]# kubectl describe pod aaa
......
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  6m35s  default-scheduler  Successfully assigned default/aaa to k8s2
  Normal  Pulling    6m34s  kubelet            Pulling image "nginx"
  Normal  Pulled     6m25s  kubelet            Successfully pulled image "nginx" in 8.639223366s
  Normal  Created    6m24s  kubelet            Created container aaa
  Normal  Started    6m24s  kubelet            Started container aaa
  Normal  Pulling    6m24s  kubelet            Pulling image "busybox"
  Normal  Pulled     6m3s   kubelet            Successfully pulled image "busybox" in 21.40434676s
  Normal  Created    6m3s   kubelet            Created container bbb
  Normal  Started    6m2s   kubelet            Started container bbb
  • 交互式打开 busybox 容器的 shell
[root@k8s1 ~]# kubectl attach -it aaa -c bbb
If you don't see a command prompt, try pressing enter.
/ # 
/ # 
Session ended, resume using 'kubectl attach aaa -c bbb -i -t' command when the pod is running
  • 交互式打开 nginx 的容器 aaa
    退出后,容器关闭,但是,不影响容器的运行
[root@k8s1 ~]# kubectl exec -it aaa -c aaa -- bash
root@aaa:/# cd /etc/nginx/
root@aaa:/etc/nginx# ls
conf.d	fastcgi_params	mime.types  modules  nginx.conf  scgi_params  uwsgi_params
root@aaa:/etc/nginx#     
exit

【【【实验有问题,18883】】】】】

3. 标签

  1. 查看集群节点的标签
[root@k8s1 ~]# kubectl get nodes --show-labels 
NAME   STATUS   ROLES                  AGE    VERSION   LABELS
k8s1   Ready    control-plane,master   2d2h   v1.23.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s1,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=
k8s2   Ready    <none>                 2d2h   v1.23.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s2,kubernetes.io/os=linux
k8s3   Ready    <none>                 2d2h   v1.23.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s3,kubernetes.io/os=linux

3.1 节点标签选择器

  1. 在工作节点 k8s3 标记 ssd 的标签
[root@k8s1 ~]# kubectl label nodes k8s3 disktype=ssd
node/k8s3 labeled
[root@k8s1 ~]# kubectl get nodes --show-labels 
NAME   STATUS   ROLES                  AGE    VERSION   LABELS
k8s1   Ready    control-plane,master   2d3h   v1.23.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s1,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=
k8s2   Ready    <none>                 2d3h   v1.23.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s2,kubernetes.io/os=linux
k8s3   Ready    <none>                 2d3h   v1.23.1   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disktype=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s3,kubernetes.io/os=linux
  1. 编写 yaml 资源清单,在其中增加标签选择器。将名为 aaa 的 pod 运行在具有标签 ssd 的工作节点 k8s3 上
  • yaml 资源清单如下:
[root@k8s1 ~]# vim pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: aaa
  name: aaa
  namespace: default
spec:
  containers:
  - image: nginx
    imagePullPolicy: Always
    name: aaa
  nodeSelector:
    disktype: ssd
  tolerations:
  - key: "example-key"
    operator: "Exists"
    effect: "NoSchedule"
  • 生效
[root@k8s1 ~]# kubectl apply -f pod.yaml 
pod/aaa created
  • 查看 pod 运行的状态,发现 pod aaa 按照 yaml 清单中期望状态的要求,在 k8s3 上运行
[root@k8s1 ~]# kubectl get pod -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP           NODE   NOMINATED NODE   READINESS GATES
aaa    1/1     Running   0          22s   10.244.2.9   k8s3   <none>           <none>
  1. 假如删除了 k8s3 上的标签 ssd,那么 pod aaa 将无法就位,因为它在找具有标签 ssd 的工作节点
  • 删除标签
[root@k8s1 ~]# kubectl label nodes k8s3 disktype-
node/k8s3 unlabeled
  • 删除之前的 pod 后,再生效资源清单
[root@k8s1 ~]# kubectl apply -f pod.yaml 
pod/aaa created
  • 查看 pod 的运行状态,发现是处于 Pending 的状态
[root@k8s1 ~]# kubectl get pod 
NAME   READY   STATUS    RESTARTS   AGE
aaa    0/1     Pending   0          4s
  • 通过 kubectl describe 命令查看 pod 创建的过程
[root@k8s1 ~]# kubectl describe pod aaa 
......
Events:
  Type     Reason            Age   From               Message
  ----     ------            ----  ----               -------
  Warning  FailedScheduling  33s   default-scheduler  0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 2 node(s) didn't match Pod's node affinity/selector.
  1. 恢复工作节点 k8s3 上的标签 ssd,这时候就会发现 pod 运行成功了
  • 添加标签
[root@k8s1 ~]# kubectl label nodes k8s3 disktype=ssd
node/k8s3 labeled
  • 不需要再次生效 yaml 资源清单,只需要检查 pod 的运行状态,发现 pod 状态恢复正常,处于 running 状态
[root@k8s1 ~]# kubectl get pod 
NAME   READY   STATUS    RESTARTS   AGE
aaa    1/1     Running   0          2m13s
  • 查看 pod aaa 的创建过程
[root@k8s1 ~]# kubectl describe pod aaa
......
Events:
  Type     Reason            Age                  From               Message
  ----     ------            ----                 ----               -------
  Warning  FailedScheduling  84s (x2 over 2m30s)  default-scheduler  0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 2 node(s) didn't match Pod's node affinity/selector.
  Normal   Scheduled         34s                  default-scheduler  Successfully assigned default/aaa to k8s3
  Normal   Pulling           32s                  kubelet            Pulling image "nginx"
  Normal   Pulled            26s                  kubelet            Successfully pulled image "nginx" in 6.39076152s
  Normal   Created           25s                  kubelet            Created container aaa
  Normal   Started           25s                  kubelet            Started container aaa

考试题目:pod 中运行 nginx 和 memcache 容器

  • 这里我选用了 nginx 和 redis

  • 题目要求:

    在一个 pod 内创建一个 nginx 和 memcache 的容器,还需要调度在指定的主机上(3min)

  • 思路:

    完成这道题目,只需要做到两点,分别是,在期望状态 spec 中写入两个指定的容器,和通过标签实现调度到指定主机

  1. 首先要快速得到一个 yaml 资源清单的模板
  • 通过 -o yaml 的参数导出模板
[root@k8s1 ~]# kubectl run ccc --image=nginx --dry-run=client -o yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: ccc
  name: ccc
spec:
  containers:
  - image: nginx
    name: ccc
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
[root@k8s1 ~]# kubectl run ccc --image=nginx --dry-run=client -o yaml > pod-2.yaml
  1. 根据题目要求修改模板
[root@k8s1 ~]# vim pod-2.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: ccc
  name: ccc
spec:
  containers:
  - image: nginx
    name: nginx		//第一个容器
  - name: redis		//第二个容器
    image: redis
  nodeSelector:		//节点标签选择器
    disktype: ssd
  tolerations:
  - key: "example-key"
    operator: "Exists"
    effect: "NoSchedule"
  1. 需要提取拉取 redis 镜像
[root@k8s4 ~]# docker pull redis
[root@k8s4 ~]# docker tag docker.io/library/redis:latest reg.westos.org/k8s/redis:latest
[root@k8s4 ~]# docker push reg.westos.org/k8s/redis:latest
  1. 镜像准备好后,生效 yaml 资源清单
  • 生效
[root@k8s1 ~]# kubectl apply -f pod-2.yaml 
pod/ccc created
  • 查看 pod 运行状态
[root@k8s1 ~]# kubectl get pod ccc -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP            NODE   NOMINATED NODE   READINESS GATES
ccc    2/2     Running   0          48s   10.244.2.12   k8s3   <none>           <none>
  • 查看 pod 的创建过程
[root@k8s1 ~]# kubectl describe pod ccc
......
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  25s   default-scheduler  Successfully assigned default/ccc to k8s3
  Normal  Pulling    24s   kubelet            Pulling image "nginx"
  Normal  Pulled     19s   kubelet            Successfully pulled image "nginx" in 4.325708968s
  Normal  Created    19s   kubelet            Created container nginx
  Normal  Started    19s   kubelet            Started container nginx
  Normal  Pulling    19s   kubelet            Pulling image "redis"
  Normal  Pulled     11s   kubelet            Successfully pulled image "redis" in 7.279734329s
  Normal  Created    11s   kubelet            Created container redis
  Normal  Started    11s   kubelet            Started container redis

4. Pod 生命周期

官方文档:工作负载 | Pods | Pod 的生命周期

  • Pod 遵循一个预定义的生命周期,起始于 Pending 阶段,如果至少 其中有一个主要容器正常启动,则进入 Running,之后取决于 Pod 中是否有容器以 失败状态结束而进入 Succeeded 或者 Failed 阶段。

    在 Pod 运行期间,kubelet 能够重启容器以处理一些失效场景。 在 Pod 内部,Kubernetes 跟踪不同容器的状态 并确定使 Pod 重新变得健康所需要采取的动作。

    在 Kubernetes API 中,Pod 包含规约部分和实际状态部分。 Pod 对象的状态包含了一组 Pod 状况(Conditions)。 如果应用需要的话,你也可以向其中注入自定义的就绪性信息。

    Pod 在其生命周期中只会被调度一次。 一旦 Pod 被调度(分派)到某个节点,Pod 会一直在该节点运行,直到 Pod 停止或者 被终止。

  • Pod 可以包含多个容器,应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动的 Init 容器。

  • Init 容器与普通的容器非常像,除了如下两点:

    • 它们总是运行到完成。
    • Init 容器不支持 Readiness,因为它们必须在 Pod 就绪之前运行完成,每个 Init 容器必须运行成功,下一个才能够运行。
  • 如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的 restartPolicy 值为 Never,它不会重新启动

在这里插入图片描述

4.1 Init 容器

官方文档:工作负载 | Pods | Init 容器

  • Init 容器能做什么?

    • Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。
    • Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。
    • 应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。
    • Init 容器能以不同于 Pod 内应用容器的文件系统视图运行。因此,Init 容器可具有访问 Secrets 的权限,而应用容器不能够访问。
    • 由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod 内的所有的应用容器会并行启动。
  • Pod会起一个Pause容器(为其他容器提供网络和存储的)
    初始化容器很重要,它主要是为 Main C做一些 tar 包
    (初始化容器按照严格的顺序执行,第一个失败则第二个也不能运行)

  • Init C 退出后,Main C 才能开始

  • Liveness 会一直检测

  1. 编写 yaml 资源清单,定义两个初始化容器
[root@k8s1 ~]# vim pod-2.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: ccc
  name: ccc
spec:
  initContainers:
  - name: init-myservice 
    image: busybox
    command: ['sh', '-c', "until nslookup myservice.default.svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
  - name: init-mydb
    image: busybox
    command: ['sh', '-c', "until nslookup mydb.default.svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
  containers:
  - image: nginx
    name: nginx
  tolerations:
  - key: "example-key"
    operator: "Exists"
    effect: "NoSchedule"
  1. 生效 yaml 资源清单,创建 pod 失败
  • 生效
[root@k8s1 ~]# kubectl apply -f pod-2.yaml 
pod/ccc created
  • 查看 Pod 的运行状态,发现 初始化容器 没有运行成功
[root@k8s1 ~]# kubectl get pod ccc
NAME   READY   STATUS     RESTARTS   AGE
ccc    0/1     Init:0/2   0          17s
  • 查看构建过程,找到原因
  • 原因是 Init C 没有运行,需要单独创建它们
[root@k8s1 ~]# kubectl describe pod ccc
......
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  51s   default-scheduler  Successfully assigned default/ccc to k8s2
  Normal  Pulling    49s   kubelet            Pulling image "busybox"
  Normal  Pulled     39s   kubelet            Successfully pulled image "busybox" in 10.183866119s
  Normal  Created    38s   kubelet            Created container init-myservice
  Normal  Started    38s   kubelet            Started container init-myservice
  1. 查看 Init C 的运行状态
  • 查看第一个 Init C 的日志,发现它一直在解析
[root@k8s1 ~]# kubectl logs ccc -c init-myservice
waiting for myservice
Server:		10.96.0.10
Address:	10.96.0.10:53

** server can't find myservice.default.svc.cluster.local: NXDOMAIN

*** Can't find myservice.default.svc.cluster.local: No answer

waiting for myservice
  • 第二个 Init C 更没有就位
[root@k8s1 ~]# kubectl logs ccc -c init-mydb
Error from server (BadRequest): container "init-mydb" in pod "ccc" is waiting to start: PodInitializing
  1. 编写第一个 Init C 的 yaml资源清单
[root@k8s1 ~]# vim service.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
  • 生效
[root@k8s1 ~]# kubectl apply -f service.yaml 
service/myservice created
  • 查看状态
[root@k8s1 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   2d3h
myservice    ClusterIP   10.103.125.44   <none>        80/TCP    7s
  • 再次查看 Pod 的运行状态,发现 Pod 依旧没有就位,但是已经有一个 Init C 运行成功并结束了
[root@k8s1 ~]# kubectl get pod ccc
NAME   READY   STATUS     RESTARTS   AGE
ccc    0/1     Init:1/2   0          7m16s
[root@k8s1 ~]# kubectl logs ccc -c init-myservice
waiting for myservice
Server:		10.96.0.10
Address:	10.96.0.10:53


*** Can't find myservice.default.svc.cluster.local: No answer
  1. 编写第二个 Init C 的资源清单
  • 查看第二个 Init C 的日志
[root@k8s1 ~]# kubectl logs ccc -c init-mydb
waiting for mydb
Server:		10.96.0.10
Address:	10.96.0.10:53

** server can't find mydb.default.svc.cluster.local: NXDOMAIN

*** Can't find mydb.default.svc.cluster.local: No answer
  • 编写 Init C 的资源清单
[root@k8s1 ~]# vim service.yaml 
---
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9377
  • 生效
[root@k8s1 ~]# kubectl apply -f service.yaml 
service/myservice unchanged
service/mydb created
  • 查看 service
[root@k8s1 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   2d3h
mydb         ClusterIP   10.97.3.214     <none>        80/TCP    10s
myservice    ClusterIP   10.103.125.44   <none>        80/TCP    4m
  1. 验证 Pod 的运行状态
[root@k8s1 ~]# kubectl get pod ccc
NAME   READY   STATUS    RESTARTS   AGE
ccc    1/1     Running   0          10m
  • 查看 Pod 的创建过程
[root@k8s1 ~]# kubectl describe pod ccc
......
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  11m    default-scheduler  Successfully assigned default/ccc to k8s2
  Normal  Pulling    11m    kubelet            Pulling image "busybox"
  Normal  Pulled     11m    kubelet            Successfully pulled image "busybox" in 10.183866119s
  Normal  Created    11m    kubelet            Created container init-myservice
  Normal  Started    11m    kubelet            Started container init-myservice
  Normal  Pulling    4m1s   kubelet            Pulling image "busybox"
  Normal  Created    3m54s  kubelet            Created container init-mydb
  Normal  Pulled     3m54s  kubelet            Successfully pulled image "busybox" in 7.059943166s
  Normal  Started    3m53s  kubelet            Started container init-mydb
  Normal  Pulling    39s    kubelet            Pulling image "nginx"
  Normal  Pulled     31s    kubelet            Successfully pulled image "nginx" in 7.459692664s
  Normal  Created    31s    kubelet            Created container nginx
  Normal  Started    30s    kubelet            Started container nginx

5. 容器探针

官方文档: 工作负载 | Pods | Pod 的生命周期

  • probe 是由 kubelet 对容器执行的定期诊断。 要执行诊断,kubelet 既可以在容器内执行代码,也可以发出一个网络请求。

5.1 探测类型

  • 针对运行中的容器,kubelet 可以选择是否执行以下三种探针,以及如何针对探测结果作出反应:

    • livenessProbe
      指示容器是否正在运行。如果存活态探测失败,则 kubelet 会杀死容器, 并且容器将根据其重启策略决定未来。如果容器不提供存活探针, 则默认状态为 Success。
    • readinessProbe
      指示容器是否准备好为请求提供服务。如果就绪态探测失败, 端点控制器将从与 Pod 匹配的所有服务的端点列表中删除该 Pod 的 IP 地址。 初始延迟之前的就绪态的状态值默认为 Failure。 如果容器不提供就绪态探针,则默认状态为 Success。
    • startupProbe
      指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被 禁用,直到此探针成功为止。如果启动探测失败,kubelet 将杀死容器,而容器依其 重启策略进行重启。 如果容器没有提供启动探测,则默认状态为 Success。

5.2 配置存活、就绪和启动探测器

官方文档: 任务 | 配置 Pods 和容器

  • 给容器配置活跃(Liveness)、就绪(Readiness)和启动(Startup)探测器。

    • kubelet 使用存活探测器来确定什么时候要重启容器。 例如,存活探测器可以探测到应用死锁(应用程序在运行,但是无法继续执行后面的步骤)情况。 重启这种状态下的容器有助于提高应用的可用性,即使其中存在缺陷。

    • kubelet 使用就绪探测器可以知道容器何时准备好接受请求流量,当一个 Pod 内的所有容器都就绪时,才能认为该 Pod 就绪。 这种信号的一个用途就是控制哪个 Pod 作为 Service 的后端。 若 Pod 尚未就绪,会被从 Service 的负载均衡器中剔除。

    • kubelet 使用启动探测器来了解应用容器何时启动。 如果配置了这类探测器,你就可以控制容器在启动成功后再进行存活性和就绪态检查, 确保这些存活、就绪探测器不会影响应用的启动。 启动探测器可以用于对慢启动容器进行存活性检测,避免它们在启动运行之前就被杀掉。

5.3 定义存活命令

  • 许多长时间运行的应用最终会进入损坏状态,除非重新启动,否则无法被恢复。 Kubernetes 提供了存活探测器来发现并处理这种情况。
  1. 在这个 yaml 资源清单中,可以看到 Pod 中只有一个 Container。 periodSeconds 字段指定了 kubelet 应该每 5 秒执行一次存活探测。 initialDelaySeconds 字段告诉 kubelet 在执行第一次探测前应该等待 5 秒。
[root@k8s1 ~]# vim pod-3.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: nginx
  name: ccc
spec:
  containers:
  - image: nginx
    name: nginx
    livenessProbe:
      tcpSocket:
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 5
  tolerations:
  - key: "example-key"
    operator: "Exists"
    effect: "NoSchedule"
  1. 生效资源清单
[root@k8s1 ~]# kubectl apply -f pod-3.yaml 
pod/ccc created
[root@k8s1 ~]# kubectl get pod ccc
NAME   READY   STATUS    RESTARTS   AGE
ccc    1/1     Running   0          89s
  1. 修改资源清单,将 port 改成 8080,正确的应该是 80。出现错误后,会每隔 5s 重启,探测 3 次
  • 将80设置成错误的8080
[root@k8s1 ~]# vim pod-3.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: nginx
  name: ccc
spec:
  containers:
  - image: nginx
    name: nginx
    livenessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 5
      periodSeconds: 5
  tolerations:
  - key: "example-key"
    operator: "Exists"
    effect: "NoSchedule"
  • 生效
[root@k8s1 ~]# kubectl apply -f pod-3.yaml 
pod/ccc created
  • watch 命令每隔 1s 监控 Pod 的运行状态
  • 发现重启了 3 次
[root@k8s1 ~]# watch -n 1 'kubectl get pod ccc'
Every 1.0s: kubectl get pod ccc                                                              Sun Apr 24 01:05:13 2022

NAME   READY   STATUS    RESTARTS      AGE
ccc    1/1     Running   1 (21s ago)   50s

Every 1.0s: kubectl get pod ccc                                                              Sun Apr 24 01:05:52 2022

NAME   READY   STATUS    RESTARTS      AGE
ccc    1/1     Running   2 (34s ago)   88s

very 1.0s: kubectl get pod ccc                                                              Sun Apr 24 01:06:25 2022

NAME   READY   STATUS    RESTARTS      AGE
ccc    1/1     Running   3 (31s ago)   2m
  • 再查看 Pod 的创建过程
[root@k8s1 ~]# kubectl describe pod ccc
......
Events:
  Type     Reason     Age                  From               Message
  ----     ------     ----                 ----               -------
  Normal   Scheduled  2m28s                default-scheduler  Successfully assigned default/ccc to k8s2
  Normal   Pulled     2m17s                kubelet            Successfully pulled image "nginx" in 10.996320247s
  Normal   Pulled     112s                 kubelet            Successfully pulled image "nginx" in 5.251596219s
  Normal   Pulled     79s                  kubelet            Successfully pulled image "nginx" in 14.180982639s
  Normal   Created    78s (x3 over 2m16s)  kubelet            Created container nginx
  Normal   Started    78s (x3 over 2m16s)  kubelet            Started container nginx
  Warning  Unhealthy  59s (x9 over 2m9s)   kubelet            Liveness probe failed: dial tcp 10.244.1.14:8080: connect: connection refused
  Normal   Killing    59s (x3 over 119s)   kubelet            Container nginx failed liveness probe, will be restarted
  Normal   Pulling    58s (x4 over 2m28s)  kubelet            Pulling image "nginx"

5.4 定义就绪探测器

  • 有时候,应用会暂时性地无法为请求提供服务。 例如,应用在启动时可能需要加载大量的数据或配置文件,或是启动后要依赖等待外部服务。 在这种情况下,既不想杀死应用,也不想给它发送请求。 Kubernetes 提供了就绪探测器来发现并缓解这些情况。 容器所在 Pod 上报还未就绪的信息,并且不接受通过 Kubernetes Service 的流量。

  • 就绪探测器在容器的整个生命周期中保持运行状态。

  • 活跃探测器 不等待 就绪性探测器成功。 如果要在执行活跃探测器之前等待,应该使用 initialDelaySeconds 或 startupProbe。

  • 就绪探测器的配置和存活探测器的配置相似。 唯一区别就是要使用 readinessProbe 字段,而不是 livenessProbe 字段。

  1. 编写 yaml 资源清单
  • 注意,这里一定会出现问题的,因为我设定了一个 test.html,虽然 Pod 是处于 running 的,但是,不能存活
[root@k8s1 ~]# vim pod-3.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: nginx 
  name: ccc
spec:
  containers:
  - image: nginx
    name: nginx
    livenessProbe:
      tcpSocket:
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 5
    readinessProbe:
      httpGet:
        path: /test.html
        port: 80
      initialDelaySeconds: 3
      periodSeconds: 3
      timeoutSeconds: 1
  tolerations:
  - key: "example-key"
    operator: "Exists"
    effect: "NoSchedule"
  1. 生效资源清单
  • 生效
[root@k8s1 ~]# kubectl apply -f pod-3.yaml 
pod/ccc created
  • 通过 watch 命令监控 Pod 的运行状态
  • 发现 Pod 处于 running 的状态,也不会 restart,只会一直 ready 0
[root@k8s1 ~]# watch -n 1 'kubectl get pod ccc'
Every 1.0s: kubectl get pod ccc                                                              Sun Apr 24 01:12:24 2022

NAME   READY   STATUS    RESTARTS   AGE
ccc    0/1     Running   0          52s
  • 查看创建过程
  • 出现 404 报错,找不到 test.html 文件
[root@k8s1 ~]# kubectl describe pod ccc
......
Events:
  Type     Reason     Age                 From               Message
  ----     ------     ----                ----               -------
  Normal   Scheduled  101s                default-scheduler  Successfully assigned default/ccc to k8s2
  Normal   Pulling    100s                kubelet            Pulling image "nginx"
  Normal   Pulled     96s                 kubelet            Successfully pulled image "nginx" in 4.905888547s
  Normal   Created    95s                 kubelet            Created container nginx
  Normal   Started    95s                 kubelet            Started container nginx
  Warning  Unhealthy  30s (x21 over 90s)  kubelet            Readiness probe failed: HTTP probe failed with statuscode: 404

删除不需要的服务
[root@k8s1 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 2d4h
mydb ClusterIP 10.97.3.214 80/TCP 18m
myservice ClusterIP 10.103.125.44 80/TCP 22m
[root@k8s1 ~]# kubectl delete svc mydb
service “mydb” deleted
[root@k8s1 ~]# kubectl delete svc myservice
service “myservice” deleted
[root@k8s1 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 443/TCP 2d4h

  1. 暴露 80 端口服务
[root@k8s1 ~]# kubectl expose pod demo --port=80 --target-port=80
[root@k8s1 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
ccc          ClusterIP   10.110.34.32   <none>        80/TCP    22s
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   2d4h
[root@k8s1 ~]# kubectl describe svc ccc
Name:              ccc
Namespace:         default
Labels:            run=nginx
Annotations:       <none>
Selector:          run=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.110.34.32
IPs:               10.110.34.32
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         				// 此处为空
Session Affinity:  None
Events:            <none>
  1. 解决问题,进入 Pod 的容器,创建 test.html 文件
[root@k8s1 ~]# kubectl exec ccc -- touch /usr/share/nginx/html/test.html
[root@k8s1 ~]# kubectl exec ccc -- ls /usr/share/nginx/html/
50x.html
index.html
test.html
  1. 最后验证 Pod 的运行状态
  • 成功啦!
[root@k8s1 ~]# kubectl get pod ccc
NAME   READY   STATUS    RESTARTS   AGE
ccc    1/1     Running   0          6m59s
  1. 查看 service 的状态,发现 EndPoint 不再是空的
[root@k8s1 ~]# kubectl describe svc ccc
Name:              ccc
Namespace:         default
Labels:            run=nginx
Annotations:       <none>
Selector:          run=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.110.34.32
IPs:               10.110.34.32
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.15:80		//成功
Session Affinity:  None
Events:            <none>
  1. 假如又删除了 test.html 文件,发现 Pod 又处于运行存活但是不能就绪的状态
[root@k8s1 ~]# kubectl exec ccc -- rm -f /usr/share/nginx/html/test.html
[root@k8s1 ~]# kubectl get pod ccc 
NAME   READY   STATUS    RESTARTS   AGE
ccc    0/1     Running   0          8m23s
[root@k8s1 ~]# kubectl describe svc ccc
Name:              ccc
Namespace:         default
Labels:            run=nginx
Annotations:       <none>
Selector:          run=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.110.34.32
IPs:               10.110.34.32
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         
Session Affinity:  None
Events:            <none>
  1. 恢复文件就能解决问题,并通过 IP 访问到服务
[root@k8s1 ~]# kubectl exec ccc -- touch /usr/share/nginx/html/test.html
[root@k8s1 ~]# kubectl exec ccc -- ls /usr/share/nginx/html/test.html
/usr/share/nginx/html/test.html
[root@k8s1 ~]# kubectl get pod ccc
NAME   READY   STATUS    RESTARTS   AGE
ccc    1/1     Running   0          9m26s
[root@k8s1 ~]# kubectl describe svc ccc
Name:              ccc
Namespace:         default
Labels:            run=nginx
Annotations:       <none>
Selector:          run=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.110.34.32
IPs:               10.110.34.32
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.1.15:80
Session Affinity:  None
Events:            <none>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/629287.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

驱动进化之路:总线设备驱动模型

了解总线设备驱动模型之前&#xff0c;可以先了解常规驱动程序的编写&#xff1a; LED驱动程序框架 驱动设计的思想&#xff1a;面向对象/分层/分离&#xff08;以LED操作为例&#xff09; 此次总线设备驱动模型程序的编写基于上述两种框架。 1. 总线设备驱动模型框架 在led_d…

STM32开发——串口通讯(非中断+中断)

目录 1.串口简介 2.非中断接收发送字符 3.中断接收字符 1.串口简介 通过中断的方法接受串口工具发送的字符串&#xff0c;并将其发送回串口工具。 串口发送/接收函数&#xff1a; HAL_UART_Transmit(); 串口发送数据&#xff0c;使用超时管理机制HAL_UART_Receive(); 串口…

虚拟机中Ubuntu不知root密码时设置唯一的非root用户为sudo管理员

刚才在虚拟机中玩Ubuntu的时候&#xff0c;在Cockpit管理页面把账号“服务器管理员”的选项给取消了&#xff0c;然后重新登录之后&#xff0c;就不能执行sudo指令了&#xff0c;所有需要root权限才能访问的文件&#xff08;目录&#xff09;、执行的命令全部都不行了。 执行s…

数据传输中的数据转换与处理的常用方法-物联网开发-单片机通信

目录 一、前言 二、实践与代码 1.Unsigned Char 2.memset 3.sprintf 4.atoi 5.atof 6.strcmp 7.strtok 8.strlen 9.strcpy 10.strcat 三、总结 一、前言 本文将以STM32单片机为基础&#xff0c;使用Keil5环境展示以下方法。 在单片机通信、载波通信中&#xff0c;常常涉及数…

【Laravel 6】安装需要什么环境?又怎么安装呢

服务器要求 服务器满足以下要求&#xff1a; PHP > 7.2.5BCMath PHP 拓展Ctype PHP 拓展JSON PHP 拓展Mbstring PHP 拓展OpenSSL PHP 拓展PDO PHP 拓展Tokenizer PHP 拓展XML PHP 拓展 安装Laravel Laravel 使用 Composer 来管理项目依赖。因此&#xff0c;在使用 Larav…

JDK动态代理和cglib代理

文章目录 前言1.JDK动态代理1.1 定义一个接口1.2 实现接口1.3 自定义MyInvocationHandler去实现InvocationHandler接口1.4 测试jdk代理1.5 输出代理类 2.cglib代理2.1 代理接口类2.2 代理普通类2.3 设置属性生成cglib代理类 前言 动态代理在平时的开发中用的也很多&#xff0c…

算法与数据结构(五)

一、c二叉树结构 typedef struct BiNode {int data; //结点内值域struct BiNode* lchild, * rchild; //左孩子 右孩子 } BiNode, * BiTree;或者&#xff1a; class Node { public:char data;// data表示该节点代表的内容&#xff1b;Node* L;//左子树Node* R;//右子树 }; No…

深度学习之卷积神经网络识别图片验证码实战案例(十)

案例背景&#xff1a;程序自动化的爬虫而无需人工介入是我们的最终目标。自动化爬虫避免不了自动登录的问题&#xff0c;在爬取XX数据的过程中&#xff0c;遇到登录图形验证码的识别的问题&#xff0c;那我们该如何攻破这种验证码呢&#xff1f; 字符验证码图片如下&#xff1a…

facenet, dlib人脸识别,人体检测,云数据库mysql,QQ邮箱,手机验证码,语音播报

目录 部分代码展示&#xff1a; 录入部分 识别部分​编辑 活体检测部分​编辑 同步到云数据库MySQL 其他操作 部分图片展示&#xff1a; 完整代码加ui链接&#xff1a; 涉及到的一些知识点的文章 部分代码展示&#xff1a; 录入部分 识别部分 活体检测部分 同步到云数…

峰终定律原理

峰终定律 峰终定律&#xff08; Peak–End Rule&#xff09;&#xff0c;是由丹尼尔卡尼曼&#xff08;2002年诺贝尔经济学奖获得者&#xff0c;心理学家&#xff09;提出的。 模型介绍 峰终定律是指如果在一段体验的高峰和结尾&#xff0c;体验是愉悦的&#xff0c;那么对整个…

走进机器学习

作者简介&#xff1a;本人是一名大二学生&#xff0c;就读于人工智能专业&#xff0c;学习过c&#xff0c;c&#xff0c;java&#xff0c;python&#xff0c;Mysql等编程知识&#xff0c;现在致力于学习人工智能方面的知识&#xff0c;感谢CSDN让我们相遇&#xff0c;我也会致力…

javaScript蓝桥杯---传送门

目录 一、介绍二、准备三、目标四、代码五、知识点六、完成 一、介绍 日常浏览网页的时候&#xff0c;我们会发现一个问题&#xff0c;当页面太长、内容太多的时候我们很难快速浏览到心仪的内容。为了解决这个烦恼&#xff0c;优秀的产品研发团队发明了一种类似传送门的功能&a…

对比分析:黑盒测试 VS 白盒测试

一、引言 在软件开发过程中&#xff0c;测试是确保产品质量的关键环节。其中&#xff0c;黑盒测试和白盒测试是两种常见的测试方法。本文将详细解析这两种测试方法的定义、特点&#xff0c;同时通过具体示例进行对比分析。 二、黑盒测试 黑盒测试&#xff0c;又称功能测试&…

2023最新性能测试面试题合集含答案,看完拿个20Koffer不是问题

1、描述一下你们公司的性能测试流程&#xff1f; 1&#xff09;分析性能需求&#xff08;用户使用最频繁的场景进行测试&#xff09;确定性能指标&#xff08;例如&#xff1a;事务通过率100%&#xff0c;top99%是5秒&#xff0c;最大并发是2000&#xff0c;CPU和内存都是70%以…

Git教程笔记

概念 Git是一个分布式版本控制工具&#xff0c;主要用于管理开发过程中的源代码文件&#xff08;Java类、xml文件、html页面等&#xff09;在软件开发过程中被广泛使用。 Git常用命令 Git全局设置 获取Git仓库 工作区、暂存区、版本库 概念 Git工作区中文件的状态 工作区中…

ROS EKF 机器人位姿估计功能包:robot_pose_ekf | 仿真环境实践

ROS EKF 机器人位姿估计功能包&#xff1a;robot_pose_ekf | 仿真环境实践 在仿真下使用robot_pose_ekf 在仿真下使用robot_pose_ekf 仿真环境为 一个无人机&#xff0c;具备3D POSE里程计数据&#xff0c;和imu数据。 将robot_pose_ekf.launch文件进行如下更改 <launc…

C++ unordered_map 性能优化

一 插入加速 unordered_map 在桶满时自动进行 rehash 操作。手动调用 rehash 函数可以手动调整 桶数量。 rehash 函数被调用时&#xff0c;需要注意以下几点&#xff1a; rehash 函数可能会造成 unordered_map 的迭代器失效。如果我们在重新哈希后仍需要继续迭代 unordered_…

机器学习实战六步法之数据预处理(五)

要落地一个机器学习的项目&#xff0c;是有章可循的&#xff0c;通过这六个步骤&#xff0c;小白也能搞定机器学习。 看我闪电六连鞭&#xff01;&#x1f923; 数据的预处理通常包括 5 个步骤&#xff0c;如下&#xff1a;这个是比较完整的一个步骤&#xff0c;不同的算法可能…

内网隧道代理技术(一)之内网隧道代理概述

内网隧道代理技术 内网转发 在渗透测试中&#xff0c;当我们获得了外网服务器&#xff08;如web服务器&#xff0c;ftp服务器&#xff0c;mali服务器等等&#xff09;的一定权限后发现这台服务器可以直接或者间接的访问内网。此时渗透测试进入后渗透阶段&#xff0c;一般情况…

FreeRTOS(8)----任务通知

一&#xff0c;任务通知的简介 相对于之前的信号量&#xff0c;事件组等&#xff0c;所谓的任务通知核心就是一个32位的无符号整数和8位的通知状态 任务通知可以通过如下方法更新接收任务的通知值&#xff1a; ● 不覆盖接收任务的通知值 ( 如果上次发送给接收任务的通知还没…