K8S基础概念
- Kubernetes
- 2024-11-01
- 858热度
- 2评论
K8S基础概念
组件说明
控制节点组件:
APIServer:整个集群的控制中枢,提供集群中各个模块之间的数据交换,并将集群状态和信息存储到分布式键-值存储系统Etcd集群中。同时它也是集群管理、资源配额、提供完备的集群安全机制的入口,为集群各类资源对象提供增删改查以及Watch的REST API接口。
Scheduler:集群Pod的调度中心,主要是通过各类调度算法将Pod分配到最佳的Node节点,它通过APIServer监听所有Pod的状态,一旦发现新的未被调度到任何Node节点的Pod(PodSpec.NodeName为空),就会根据一系列策略选择最佳节点进行调度。
Controller Manager:集群状态管理器,以保证Pod或其他资源达到期望值。当集群中某个Pod的副本数或其他资源因故障和错误导致无法正常运行,没有达到设定的值时,Controller Manager会尝试自动修复并使其达到期望状态。
Etcd:可靠地存储集群的配置,是一种持久化、轻量型、分布式的键-值(key-value)数据存储组件、作为K8S集群的持久化存储系统
工作节点组件:
Kubelet:负责与Master通信协作,管理该节点上的Pod,对容器进行健康检查及监控,同时负责上报节点和节点上面Pod的状态
Kube-Proxy:负责各Pod之间的通信和负载均衡,将指定的流量分发到后端正确的机器上
Runtime:负责容器的管理
CoreDNS:用于Kubernetes集群内部的Service的解析,可以让Pod把Service名称解析成Service的IP,然后通过Service的IP地址进行连接到对应的应用上
Calico:符合CNI标准的一个网络插件,它负责给每个Pod分配一个不会重复的IP,并且把每个节点当做一个"路由器",这样一个节点的Pod就可以通过IP地址访问到其他节点的Pod
创建一个Pod(通过配置文件创建)
[root@master-01 ~]# vim pod.yaml
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: registry.cn-guangzhou.aliyuncs.com/caijxlinux/nginx:v1 # 必选,容器所用的镜像的地址
ports: # 可选,容器需要暴露的端口号列表
- containerPort: 80 # 端口号
通过命令查询yaml文件内语法,可以理解每种资源的字段及其含义。下面例子显示 Pod 的各个字段及其详细说明,读者还可以深入到特定字段
[root@master-01 ~]# kubectl explain pod
[root@master-01 ~]# kubectl explain pod.spec
[root@master-01 ~]# kubectl explain pod.spec.restartPolicy
查看各资源类型支持的版本,可以查看资源名称的缩写
[root@master-01 ~]# kubectl api-resources
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings v1 true Binding
componentstatuses cs v1 false ComponentStatus
configmaps cm v1 true ConfigMap
endpoints ep v1 true Endpoints
events ev v1 true Event
limitranges limits v1 true LimitRange
...省略部分输出...
创建Pod,并查看Pod状态
[root@master-01 ~]# kubectl create -f pod.yaml
pod/nginx created
[root@master-01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 4s
Pod状态及Pod故障排查命令
状态 | 说明 |
---|---|
Pending(挂起) | Pod已被K8S系统接收,但仍有一个或多个容器未被创建,可以通过kubectl describe $Pod_Name查看处于Pending状态的原因 |
Running(运行中) | Pod已被绑定到一个节点上,并且所有的容器都已经被创建,而且至少有一个是运行状态,或者是正在启动或重启,可以通过kebectl logs $Pod_Name查看Pod的日志 |
Succeeded(成功) | 所有容器执行成功并终止,并且不会再次重启,可以通过kebectl logs $Pod_Name查看Pod的日志 |
Failed(失败) | 所有容器都已终止,并且至少有一个容器以失败的方式终止,也就是说这个容器要么以非零状态退出,要么被系统终止,可以通过logs和describe命令查看具体原因 |
CrashLoopBackOff(崩溃/循环回退) | 容器启动失败,可以通过logs命令查看具体原因,一般为启动命令不正确,健康检查不通过等 |
Unknown(未知) | 通常是由于通信问题造成的无法获取Pod的状态 |
ImagePullBackOff/ErrImagePull(镜像拉取失败) | 镜像拉取失败,一般是由于镜像不存在、网络无法连接或者需要登录认证引起的,可以使用describe命令查看具体原因 |
OOMKilled(内存不足) | 容器内存溢出,一般是容器的内存Limit设置的过小,或者程序本身有内存溢出,可以通过logs查看程序启动日志 |
Terminating(终止) | Pod正在被删除,K8S已经接收到了删除容器的请求,可能是因为用户发出删除申请、节点故障、扩容缩等原因,可以通过Describe查看具体原因 |
SysctlFrobidden(路由禁止) | Pod自定义了内核配置,但Kubelet没有添加内核配置或配置的内核参数不支持,可以通过describe查看具体原因 |
Completed(完成) | 容器内部主进程退出,一般计划任务执行结束会显示该状态,此时可以通过logs查看容器日志 |
ContainerCreating(容器创建) | Pod正在创建,一般为正在下载镜像,或者有配置不当的地方,可以通过describe查看具体原因 |
通过decribe、logs、-oyaml的方法可以查询容器的信息和排查容器故障
[root@master-01 ~]# kubectl describe pod nginx
Name: nginx
Namespace: default
Priority: 0
Service Account: default
Node: node-02/192.168.132.173
Start Time: Thu, 31 Oct 2024 15:30:22 +0800
Labels: <none>
Annotations: cni.projectcalico.org/containerID: 85c8e525f70bfa8ff2da7b87e95554333e2cf55b197ba98198eb1ca6ee3e2e9a
cni.projectcalico.org/podIP: 172.16.184.4/32
cni.projectcalico.org/podIPs: 172.16.184.4/32
Status: Running
IP: 172.16.184.4
IPs:
IP: 172.16.184.4
Containers:
nginx:
Container ID: containerd://e9a32b319dfa3d3c8acc538c3429614f34ac098a600c3cea0e0c397fbe0406a9
Image: registry.cn-guangzhou.aliyuncs.com/caijxlinux/nginx:v1
Image ID: registry.cn-guangzhou.aliyuncs.com/caijxlinux/nginx@sha256:9a821cadb1b13cb782ec66445325045b2213459008a41c72d8d87cde94b33c8c
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Thu, 31 Oct 2024 15:30:23 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-5hz2b (ro)
Conditions:
Type Status
PodReadyToStartContainers True
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-5hz2b:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 97s default-scheduler Successfully assigned default/nginx to node-02
Normal Pulled 96s kubelet Container image "registry.cn-guangzhou.aliyuncs.com/caijxlinux/nginx:v1" already present on machine
Normal Created 96s kubelet Created container nginx
Normal Started 96s kubelet Started container nginx
[root@master-01 ~]# kubectl logs nginx
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2024/10/31 07:30:23 [notice] 1#1: using the "epoll" event method
2024/10/31 07:30:23 [notice] 1#1: nginx/1.23.3
2024/10/31 07:30:23 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2024/10/31 07:30:23 [notice] 1#1: OS: Linux 4.19.12-1.el7.elrepo.x86_64
2024/10/31 07:30:23 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2024/10/31 07:30:23 [notice] 1#1: start worker processes
2024/10/31 07:30:23 [notice] 1#1: start worker process 29
2024/10/31 07:30:23 [notice] 1#1: start worker process 30
[root@master-01 ~]# kubectl get pods -oyaml
apiVersion: v1
items:
- apiVersion: v1
kind: Pod
metadata:
annotations:
cni.projectcalico.org/containerID: 85c8e525f70bfa8ff2da7b87e95554333e2cf55b197ba98198eb1ca6ee3e2e9a
cni.projectcalico.org/podIP: 172.16.184.4/32
cni.projectcalico.org/podIPs: 172.16.184.4/32
creationTimestamp: "2024-10-31T07:30:22Z"
name: nginx
namespace: default
resourceVersion: "5882"
uid: 50ab84ee-edc0-450a-9b06-79b798087b73
spec:
containers:
- image: registry.cn-guangzhou.aliyuncs.com/caijxlinux/nginx:v1
imagePullPolicy: IfNotPresent
name: nginx
ports:
- containerPort: 80
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /var/run/secrets/kubernetes.io/serviceaccount
name: kube-api-access-5hz2b
readOnly: true
dnsPolicy: ClusterFirst
enableServiceLinks: true
nodeName: node-02
preemptionPolicy: PreemptLowerPriority
priority: 0
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: default
serviceAccountName: default
terminationGracePeriodSeconds: 30
tolerations:
- effect: NoExecute
key: node.kubernetes.io/not-ready
operator: Exists
tolerationSeconds: 300
- effect: NoExecute
key: node.kubernetes.io/unreachable
operator: Exists
tolerationSeconds: 300
volumes:
- name: kube-api-access-5hz2b
projected:
defaultMode: 420
sources:
- serviceAccountToken:
expirationSeconds: 3607
path: token
- configMap:
items:
- key: ca.crt
path: ca.crt
name: kube-root-ca.crt
- downwardAPI:
items:
- fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
path: namespace
status:
conditions:
- lastProbeTime: null
lastTransitionTime: "2024-10-31T07:30:24Z"
status: "True"
type: PodReadyToStartContainers
- lastProbeTime: null
lastTransitionTime: "2024-10-31T07:30:22Z"
status: "True"
type: Initialized
- lastProbeTime: null
lastTransitionTime: "2024-10-31T07:30:24Z"
status: "True"
type: Ready
- lastProbeTime: null
lastTransitionTime: "2024-10-31T07:30:24Z"
status: "True"
type: ContainersReady
- lastProbeTime: null
lastTransitionTime: "2024-10-31T07:30:22Z"
status: "True"
type: PodScheduled
containerStatuses:
- containerID: containerd://e9a32b319dfa3d3c8acc538c3429614f34ac098a600c3cea0e0c397fbe0406a9
image: registry.cn-guangzhou.aliyuncs.com/caijxlinux/nginx:v1
imageID: registry.cn-guangzhou.aliyuncs.com/caijxlinux/nginx@sha256:9a821cadb1b13cb782ec66445325045b2213459008a41c72d8d87cde94b33c8c
lastState: {}
name: nginx
ready: true
restartCount: 0
started: true
state:
running:
startedAt: "2024-10-31T07:30:23Z"
hostIP: 192.168.132.173
hostIPs:
- ip: 192.168.132.173
phase: Running
podIP: 172.16.184.4
podIPs:
- ip: 172.16.184.4
qosClass: BestEffort
startTime: "2024-10-31T07:30:22Z"
kind: List
metadata:
resourceVersion: ""
查看网络插件在系统的表现形式
[root@master-01 ~]# kubectl get pods -l k8s-app=calico-node -n kube-system
NAME READY STATUS RESTARTS AGE
calico-node-65ps2 1/1 Running 1 (21m ago) 2d2h
calico-node-7t4mc 1/1 Running 1 (21m ago) 2d2h
calico-node-r77r2 1/1 Running 1 (20m ago) 2d2h
calico-node-r7fcd 1/1 Running 1 (21m ago) 2d2h
calico-node-v95fz 1/1 Running 1 (21m ago) 2d2h
[root@master-01 ~]# kubectl logs -n kube-system calico-node-65ps2
Defaulted container "calico-node" out of: calico-node, upgrade-ipam (init), install-cni (init), mount-bpffs (init)
2024-10-31 07:16:33.077 [INFO][8] startup/startup.go 445: Early log level set to info
2024-10-31 07:16:33.077 [INFO][8] startup/utils.go 126: Using NODENAME environment for node name master-02
2024-10-31 07:16:33.077 [INFO][8] startup/utils.go 138: Determined node name: master-02
查看CoreDNS在容器内的表现形式
[root@master-01 ~]# kubectl get pods -n kube-system -l k8s-app=kube-dns
NAME READY STATUS RESTARTS AGE
coredns-6d58d46f65-4vs6g 1/1 Running 1 (24m ago) 2d2h
coredns-6d58d46f65-tv25r 1/1 Running 1 (24m ago) 2d2h
[root@master-01 ~]# kubectl logs -n kube-system coredns-6d58d46f65-4vs6g
.:53
[INFO] plugin/reload: Running configuration SHA512 = 591cf328cccc12bc490481273e738df59329c62c0b729d94e8b61db9961c2fa5f046dd37f1cf888b953814040d180f52594972691cd6ff41be96639138a43908
CoreDNS-1.11.3
linux/amd64, go1.21.11, a6338e9
Pod镜像拉取策略
通过 spec.containers[].imagePullPolicy 参数可以指定镜像的拉取策略,目前支持的策略如下
参数 | 说明 |
---|---|
Always | 总是拉取,当镜像 tag 为 latest 时,且 imagePullPolicy 未配置,默认为 Always |
Never | 不管是否存在都不会拉取 |
IfNotPresent | 镜像不存在时拉取镜像,如果 tag 为非 latest,且 imagePullPolicy 未配置,默认为 IfNotPresent |
更改更改镜像拉取策略为 IfNotPresent
[root@master-01 ~]# vim pod-imagepullpolicy
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: nginx:1.15.12 # 必选,容器所用的镜像的地址
imagePullPolicy: IfNotPresent # 可选,镜像拉取策略
ports: # 可选,容器需要暴露的端口号列表
- containerPort: 80 # 端口号
Pod重启策略
使用 spec.restartPolicy 指定容器的重启策略
参数 | 说明 |
---|---|
Always | 默认策略。容器失效时,自动重启该容器 |
OnFailure | 容器以不为 0 的状态码终止,自动重启该容器 |
Never | 无论何种状态,都不会重启 |
指定重启策略为 Never
[root@master-01 ~]# vim pod-imagerestartpolicy
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: nginx:1.15.12 # 必选,容器所用的镜像的地址
imagePullPolicy: IfNotPresent # 可选,镜像拉取策略
ports: # 可选,容器需要暴露的端口号列表
- containerPort: 80 # 端口号
restartPolicy: Never
Pod的三种探针
Pod探针(Probes)是 Kubernetes 中的一种机制,用于监控容器的健康状况和可用性。
使用探针的优点:
- 提高稳定性:可以自动检测并处理故障,确保应用程序的可用性。
- 更精细的控制:允许你自定义健康检查的逻辑,以适应不同类型的应用程序。
- 减少停机时间:通过快速重启不健康的容器,可以减少服务的停机时间。
种类 | 说明 |
---|---|
startupProbe | Kubernetes1.16 新加的探测方式,用于判断容器内的应用程序是否已经启动。如果配置了 startupProbe,就会先禁用其他探测,直到它成功为止。如果探测失败,Kubelet会杀死容器,之后根据重启策略进行处理,如果探测成功,或没有配置 startupProbe,则状态为成功,之后就不再探测 |
livenessProbe | 用于探测容器是否在运行,如果探测失败,kubelet 会“杀死”容器并根据重启策略进行相应的处理。如果未指定该探针,将默认为 Success |
readinessProbe | 一般用于探测容器内的程序是否健康,即判断容器是否为就绪(Ready)状态。如果是,则可以处理请求,反之 Endpoints Controller 将从所有的 Service 的 Endpoints中删除此容器所在 Pod 的 IP 地址。如果未指定,将默认为 Success |
Pod探针的实现方式
实现方式 | 说明 |
---|---|
ExecAction | 在容器内执行一个指定的命令,如果命令返回值为 0,则认为容器健康 |
TCPSocketAction | 通过 TCP 连接检查容器指定的端口,如果端口开放,则认为容器健康 |
HTTPGetAction | 对指定的 URL 进行 Get 请求,如果状态码在 200~400 之间,则认为容器健康 |
配置就绪探针和存活探针
[root@master-01 ~]# vim probe.yaml
apiVersion: v1 # 必选,API 的版本号
kind: Pod # 必选,类型 Pod
metadata: # 必选,元数据
name: nginx # 必选,符合 RFC 1035 规范的 Pod 名称
spec: # 必选,用于定义 Pod 的详细信息
containers: # 必选,容器列表
- name: nginx # 必选,符合 RFC 1035 规范的容器名称
image: registry.cn-guangzhou.aliyuncs.com/caijxlinux/nginx:v1 # 必选,容器所用的镜像的地址
imagePullPolicy: IfNotPresent # 可选,镜像拉取策略
command: # 可选,容器启动执行的命令
- sh
- -c
- sleep 10; nginx -g "daemon off;"
readinessProbe: # 可选,健康检查
httpGet: # 接口检测方式
path: /index.html # 检查路径
port: 80 # 端口
scheme: HTTP # HTTP 或 HTTPS
initialDelaySeconds: 10 # 初始化时间
timeoutSeconds: 2 # 超时时间
periodSeconds: 5 # 检测间隔
successThreshold: 1 # 检查成功为 1 次表示就绪
failureThreshold: 2 # 检查失败 2 次表示未就绪
livenessProbe: # 可选,健康检查
tcpSocket: # 端口检测方式
port: 80 # 端口
initialDelaySeconds: 10 # 初始化时间
timeoutSeconds: 2 # 超时时间
periodSeconds: 5 # 检测间隔
successThreshold: 1 # 检查成功为 1 次表示就绪
failureThreshold: 2 # 检查失败 2 次表示未就绪
ports: # 可选,容器需要暴露的端口号列表
- containerPort: 80 # 端口号
restartPolicy: Never # 重启策略
创建资源并查看资源状态,可以观察到创建后READY字段为0/1,通过日志可以看出,探针正在进行健康检查,完成健康检查后,READY字段为1/1,STATUS为Running
[root@master-01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 0/1 Running 0 14s
[root@master-01 ~]# kubectl logs nginx
2024/10/31 08:10:36 [notice] 8#8: using the "epoll" event method
2024/10/31 08:10:36 [notice] 8#8: nginx/1.23.3
2024/10/31 08:10:36 [notice] 8#8: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2024/10/31 08:10:36 [notice] 8#8: OS: Linux 4.19.12-1.el7.elrepo.x86_64
2024/10/31 08:10:36 [notice] 8#8: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2024/10/31 08:10:36 [notice] 8#8: start worker processes
2024/10/31 08:10:36 [notice] 8#8: start worker process 9
2024/10/31 08:10:36 [notice] 8#8: start worker process 10
192.168.132.173 - - [31/Oct/2024:08:10:40 +0000] "GET /index.html HTTP/1.1" 200 615 "-" "kube-probe/1.30" "-"
[root@master-01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 36s
登录容器,删除index.html,存活探针在10S后,探测到服务不可用,READY字段重新变为0/1,由于重启策略和探测方法的原因,容器无法重启。需要修改重启策略为Always或OnFailure。
[root@master-01 ~]# kubectl exec -it nginx -- rm -rf /usr/share/nginx/html/index.html
[root@master-01 ~]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
[root@master-01 ~]# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 22s
nginx 0/1 Running 0 31s
preStop 和 postStart
preStop 和 postStart 是 Kubernetes 中容器生命周期钩子(Lifecycle Hooks)的两种类型,用于在容器的特定阶段执行命令。它们提供了在容器启动或停止时运行自定义操作的能力。
postStart 钩子:
postStart 钩子在容器启动后立即执行。它适用于需要在容器启动后进行一些初始化操作的场景。一些使用情景和案例包括: 1、数据库连接:在容器启动后,可以使用 postStart 钩子来建立数据库连接,并确保应用程序在启动时可以正常访问数据库。 2、文件下载:容器启动后,可以使用 postStart 钩子从外部下载文件,并将其放置在容器内部以供应用程序使用。 3、 启动后台任务:在容器启动后,可以使用 postStart 钩子来启动或触发后台任务,例如数据同步、日志收集等。
preStop 钩子:
preStop 钩子在容器终止之前执行。它适用于在容器终止之前执行一些清理或收尾操作的场景。一些使用情景和案例包括: 1、优雅终止:在容器终止之前,可以使用 preStop 钩子发送信号或通知给应用程序,让应用程序优雅地处理未完成的请求或任务,并进行清理操作。 2、数据持久化:在容器终止之前,可以使用 preStop 钩子将容器中的数据持久化到外部存储,以确保数据不会丢失。 3、 日志上传:在容器终止之前,可以使用 preStop 钩子将容器中的日志上传到中央日志系统,以便进一步分析和存档。
这些钩子提供了在容器的生命周期中执行自定义操作的机制。它们可以通过在容器的配置中指定 lifecycle 字段来定义。
编写yaml文件测试效果
[root@master-01 ~]# vim hook.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: registry.cn-guangzhou.aliyuncs.com/caijxlinux/nginx:v1
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo 'Hello initContainers' >> /1.txt"]
preStop:
exec:
command: ["/bin/sh", "-c", "echo 'Container stopping...' >> /1.txt;sleep 10"]
创建资源并查看资源状态
[root@master-01 ~]# kubectl create -f hook.yaml
pod/my-pod created
[root@master-01 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
my-pod 1/1 Running 0 1s
查看1.txt文件的内容,可以观察到容器创建后已经写入
[root@master-01 ~]# kubectl exec -it my-pod -- cat /1.txt
Hello initContainers
删除容器,再次查看1.txt文件,观察到容器写入1.txt文件后,等待了10s,才删除容器
[root@master-01 ~]# kubectl delete pod my-pod
pod "my-pod" deleted
[root@master-01 ~]# kubectl exec -it my-pod -- cat /1.txt
Hello initContainers
Container stopping...
[root@master-01 ~]# kubectl exec -it my-pod -- cat /1.txt
Error from server (NotFound): pods "my-pod" not found
gRPC
gRPC 探测可以通过 Kubernetes 的 livenessProbe 和 readinessProbe 来实现,确保你的服务在容器内可以正常工作。要使用 gRPC 探针,必须配置 port 属性。 如果要区分不同类型的探针和不同功能的探针,可以使用 service 字段。 你可以将 service 设置为 liveness,并使你的 gRPC 健康检查端点对该请求的响应与将 service 设置为 readiness 时不同。 这使你可以使用相同的端点进行不同类型的容器健康检查而不是监听两个不同的端口。 如果你想指定自己的自定义服务名称并指定探测类型,Kubernetes 项目建议你使用使用一个可以关联服务和探测类型的名称来命名。
[root@master-01 ~]# vim grpc.yaml
apiVersion: v1
kind: Pod
metadata:
name: etcd-with-grpc
spec:
containers:
- name: etcd
image: registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:3.5.1-0
command: ["/usr/local/bin/etcd",
"--data-dir", "/var/lib/etcd",
"--listen-client-urls", "http://0.0.0.0:2379",
"--advertise-client-urls", "http://127.0.0.1:2379",
"--log-level", "debug"]
ports:
- containerPort: 2379
livenessProbe:
grpc:
port: 2379
initialDelaySeconds: 10
创建资源
[root@master-01 ~]# kubectl create -f grpc.yaml
pod/etcd-with-grpc created
15 秒钟之后,查看 Pod 事件确认存活性检查并未失败
[root@master-01 ~]# kubectl describe pod my-pod
...省略部分输出...
{"level":"debug","ts":"2024-10-31T18:19:54.832Z","caller":"v3rpc/interceptor.go:182","msg":"request stats","start time":"2024-10-31T18:19:54.832Z","time spent":"81.936µs","remote":"192.168.132.173:36712","response type":"/grpc.health.v1.Health/Check","request count":-1,"request size":-1,"response count":-1,"response size":-1,"request content":""}
{"level":"info","ts":"2024-10-31T18:19:54.833Z","caller":"zapgrpc/zapgrpc.go:174","msg":"[transport] transport: loopyWriter.run returning. connection error: desc = \"transport is closing\""}
{"level":"debug","ts":"2024-10-31T18:20:04.833Z","caller":"v3rpc/interceptor.go:182","msg":"request stats","start time":"2024-10-31T18:20:04.833Z","time spent":"10.246µs","remote":"192.168.132.173:36726","response type":"/grpc.health.v1.Health/Check","request count":-1,"request size":-1,"response count":-1,"response size":-1,"request content":""}
{"level":"info","ts":"2024-10-31T18:20:04.833Z","caller":"zapgrpc/zapgrpc.go:174","msg":"[transport] transport: loopyWriter.run returning. connection error: desc = \"transport is closing\""}
{"level":"debug","ts":"2024-10-31T18:20:14.836Z","caller":"v3rpc/interceptor.go:182","msg":"request stats","start time":"2024-10-31T18:20:14.836Z","time spent":"11.239µs","remote":"192.168.132.173:36742","response type":"/grpc.health.v1.Health/Check","request count":-1,"request size":-1,"response count":-1,"response size":-1,"request content":""}
{"level":"info","ts":"2024-10-31T18:20:14.836Z","caller":"zapgrpc/zapgrpc.go:174","msg":"[transport] transport: loopyWriter.run returning. connection error: desc = \"transport is closing\""}
{"level":"debug","ts":"2024-10-31T18:20:24.832Z","caller":"v3rpc/interceptor.go:182","msg":"request stats","start time":"2024-10-31T18:20:24.832Z","time spent":"13.43µs","remote":"192.168.132.173:36756","response type":"/grpc.health.v1.Health/Check","request count":-1,"request size":-1,"response count":-1,"response size":-1,"request content":""}
当使用 gRPC 探针时,需要注意以下一些技术细节:
- 这些探针运行时针对的是 Pod 的 IP 地址或其主机名。 请一定配置你的 gRPC 端点使之监听于 Pod 的 IP 地址之上。
- 这些探针不支持任何身份认证参数(例如
-tls
)。 - 对于内置的探针而言,不存在错误代码。所有错误都被视作探测失败。
- 如果
ExecProbeTimeout
特性门控被设置为false
,则grpc-health-probe
不会考虑timeoutSeconds
设置状态(默认值为 1s), 而内置探针则会在超时时返回失败。
好好学习