资源管理介绍
- 在kubernetes中,所有的内容都抽象为资源,用户需要通过操作资源来管理kubernetes。
- kubernetes的本质上就是一个集群系统,用户可以在集群中部署各种服务
- 所谓的部署服务,其实就是在kubernetes集群中运行一个个的容器,并将指定的程序跑在容器中。
- kubernetes的最小管理单元是pod而不是容器,只能将容器放在
Pod
中, - kubernetes一般也不会直接管理Pod,而是通过
Pod控制器
来管理Pod的。 - Pod中服务的访问是由kubernetes提供的
Service
资源来实现。 - Pod中程序数据的持久化是由kubernetes提供的各种
存储系统
来实现的
资源管理方式
1、命令式对象管理:直接使用命令去操作kubernetes资源
kubectl run nginx-pod --image=nginx:latest --port=80
2、命令式对象配置:通过命令配置和配置文件去操作kubernetes资源
kubectl create/patch -f nginx-pod.yaml
3、声明式对象配置:通过apply命令和配置文件去操作kubernetes资源
kubectl apply -f nginx-pod.yaml
类型 | 适用环境 | 优点 | 缺点 |
---|---|---|---|
命令式对象管理 | 测试 | 简单 | 只能操作活动对象,无法审计、跟踪 |
命令式对象配置 | 开发 | 可以审计、跟踪 | 项目大时,配置文件多,操作麻烦 |
声明式对象配置 | 开发 | 支持目录操作 | 意外情况下难以调试 |
命令式对象管理
kubectl是kubernetes集群的命令行工具,通过它能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署
kubectl命令的语法如下:
kubectl [command] [type] [name] [flags]
comand:指定要对资源执行的操作,例如create、get、delete
type:指定资源类型,比如deployment、pod、service
name:指定资源的名称,名称大小写敏感
flags:指定额外的可选参数
# 查看所有pod
kubectl get pod
# 查看某个pod
kubectl get pod pod_name
# 查看某个pod,以yaml格式展示结果
kubectl get pod pod_name -o yaml
资源类型
kubernetes中所有的内容都抽象为资源
kubectl api-resources
常用资源类型:
资源分类 | 资源名称 | 缩写 | 资源作用 |
---|---|---|---|
集群级别资源 | nodes | no | 集群组成部分 |
namespaces | ns | 隔离pod | |
pod资源 | pods | po | 装载容器 |
pod资源控制器 | replicationcontrollers | rc | 控制pod资源 |
replicasets | rs | 控制pod资源 | |
deployments | deploy | 控制pod资源 | |
daemonsets | ds | 控制pod资源 | |
jobs | 控制pod资源 | ||
cronjobs | cj | 控制pod资源 | |
horizontalpodautoscalers | hpa | 控制pod资源 | |
statefulsets | sts | 控制pod资源 | |
服务发现资源 | services | svc | 统一pod对外接口 |
ingress | ing | 统一pod对外接口 | |
存储资源 | volumeattachments | 存储 | |
persistentvolumes | pv | 存储 | |
persistentvolumeclaims | pvc | 存储 | |
配置资源 | configmaps | cm | 配置 |
secrets | 配置 |
kubect 常见命令操作:
命令分类 | 命令 | 翻译 | 作用 |
---|---|---|---|
基本命令 | create | 创建 | 创建一个资源 |
edit | 编辑 | 编辑一个资源 | |
get | 获取 | 获取一个资源 | |
patch | 更新 | 更新一个资源 | |
delete | 删除 | 删除一个资源 | |
explain | 解释 | 展示文档资源 | |
运行和调试 | run | 运行 | 在集群中运行一个指定的镜像 |
expose | 暴露 | 暴露资源为service | |
describe | 描述 | 显示资源内部信息 | |
logs | 日志 | 输出容器在pod中的日志 | |
attach | 缠绕 | 进入运行中的容器 | |
exec | 执行 | 执行容器中的命令 | |
cp | 复制 | 在pod内外复制文件 | |
rollout | 首次展示 | 管理资源的发布 | |
scale | 规模 | 扩(缩)容pod的数量 | |
autoscale | 自动调整 | 自动扩(缩)容pod的数量 | |
高级命令 | apply | 应用 | 通过文件对资源进行配置 |
label | 标签 | 更新资源上的标签 | |
其它命令 | cluster-info | 集群信息 | 显示集群信息 |
version | 版本 | 显示当前的server和client版本 |
基本命令
kubectl的详细说明地址:
https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands
1、显示集群版本
[root@k8s-master ~]# kubectl version
Client Version: v1.30.0
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.30.0
2、显示集群信息
[root@k8s-master ~]# kubectl cluster-info
Kubernetes control plane is running at https://172.25.254.100:6443
CoreDNS is running at https://172.25.254.100:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
3、创建一个web控制器,控制器中pod数量为2
[root@k8s-master ~]# kubectl create deployment web --image nginx --replicas 2
4、查看控制器
[root@k8s-master ~]# kubectl get deployments.apps
5、查看资源帮助
[root@k8s-master ~]# kubectl explain deployment
GROUP: apps
KIND: Deployment
VERSION: v1
......
6、查看控制器参数帮助
[root@k8s-master ~]# kubectl explain deployment.spec
GROUP: apps
KIND: Deployment
VERSION: v1
7、编辑控制器配置
[root@k8s-master ~]# kubectl edit deployments.apps web
......
spec:
progressDeadlineSeconds: 600
replicas: 3 #运行的pod数量为3个
8、利用补丁更改控制器配置
[root@k8s-master ~]# kubectl patch deployments.apps web -p '{"spec":{"replicas":4}}'
deployment.apps/web patched
9、删除资源
[root@k8s-master ~]# kubectl delete deployments.apps web
deployment.apps "web" deleted
运行/调试命令
1、运行pod
[root@k8s-master ~]# kubectl run testpod --image nginx
pod/testpod created
2、暴露端口
查看服务:
[root@k8s-master ~]# kubectl get services
暴露端口:
[root@k8s-master ~]# kubectl expose pod testpod --port 80 --target-port 80
service/testpod exposed
测试:
3、查看资源详细信息
[root@k8s-master ~]# kubectl describe pods testpod
4、查看资源日志
[root@k8s-master ~]# kubectl logs pods/testpod
5、运行交互pod
[root@k8s-master ~]# kubectl run -it testpod --image busybox
#ctrl+pq退出不停止pod
#进入到已经运行的容器,且容器有交互环境
[root@k8s-master ~]# kubectl attach pods/testpod -it
6、在已经运行的pod中运行指定命令
[root@k8s-master ~]# kubectl exec -it pods/nginx /bin/bash
7、复制文件到pod中
[root@k8s-master ~]# kubectl cp anaconda-ks.cfg nginx:/
[root@k8s-master ~]# kubectl exec -it pods/nginx /bin/bash
8、复制pod中的文件到本机
[root@k8s-master ~]# kubectl cp nginx:/anaconda-ks.cfg /root/test
#只能复制文本文件,且复制源应与目标源相对应,例如文本对文本,目录对目录
高级命令示例
1、利用目录生成yaml模版文件
[root@k8s-master ~]# kubectl create deployment --image nginx web --dry-run=client -o yaml > web.yml
2、利用yaml文件生成资源
[root@k8s-master ~]# vim web.yml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: web
name: web
spec:
replicas: 2 #标签为web的两个容器
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- image: nginx
name: nginx
[root@k8s-master ~]# kubectl apply -f web.yml
deployment.apps/web created
#生成容器
[root@k8s-master ~]# kubectl get deployments.apps
#获取该控制器下的信息
[root@k8s-master ~]# kubectl delete -f web.yml
deployment.apps "webcluster" deleted
#删除该控制器及控制器下的容器
3、管理资源标签
查看其标签:
[root@k8s-master ~]# kubectl apply -f web.yml
[root@k8s-master ~]# kubectl get pods --show-labels
更改标签:
[root@k8s-master ~]# kubectl label pods nginx app=webcluster --overwrite
删除标签:
[root@k8s-master ~]# kubectl label pods nginx app-
当容器标签与控制器内的设定数量不符合时,控制器会自动生成新的容器或删除多余的容器:
[root@k8s-master ~]# kubectl get pods --show-labels
pod
- Pod是可以创建和管理Kubernetes计算的最小可部署单元
- 一个Pod代表着集群中运行的一个进程,每个pod都有一个唯一的ip。
- 一个pod类似一个豌豆荚,包含一个或多个容器(通常是docker)
- 多个容器间共享IPC、Network和UTC namespace。
创建自主式pod (生产不推荐)
优点:
灵活性高:
- 可以精确控制 Pod 的各种配置参数,包括容器的镜像、资源限制、环境变量、命令和参数等,满足特定的应用需求。
学习和调试方便:
- 对于学习 Kubernetes 的原理和机制非常有帮助,通过手动创建 Pod 可以深入了解 Pod 的结构和配置方式。在调试问题时,可以更直接地观察和调整 Pod 的设置。
适用于特殊场景:
- 在一些特殊情况下,如进行一次性任务、快速验证概念或在资源受限的环境中进行特定配置时,手动创建 Pod 可能是一种有效的方式。
缺点:
管理复杂:
- 如果需要管理大量的 Pod,手动创建和维护会变得非常繁琐和耗时。难以实现自动化的扩缩容、故障恢复等操作。
缺乏高级功能:
- 无法自动享受 Kubernetes 提供的高级功能,如自动部署、滚动更新、服务发现等。这可能导致应用的部署和管理效率低下。
可维护性差:
- 手动创建的 Pod 在更新应用版本或修改配置时需要手动干预,容易出现错误,并且难以保证一致性。相比之下,通过声明式配置或使用 Kubernetes 的部署工具可以更方便地进行应用的维护和更新。
#查看所有pods
[root@k8s-master ~]# kubectl get pods
#建立一个名为test的pod
[root@k8s-master ~]# kubectl run test --image nginx
pod/timinglee created
#查看所有pod
[root@k8s-master ~]# kubectl get pods
#显示pod的较为详细的信息
[root@k8s-master ~]# kubectl get pods -o wide
利用控制器管理 pod(推荐)
高可用性和可靠性:
自动故障恢复:
如果一个 Pod 失败或被删除,控制器会自动创建新的 Pod 来维持期望的副本数量。确保应用始终处于可用状态,减少因单个 Pod 故障导致的服务中断。
健康检查和自愈:
可以配置控制器对 Pod 进行健康检查(如存活探针和就绪探针)。如果 Pod 不健康,控制器会采取适当的行动,如重启 Pod 或删除并重新创建它,以保证应用的正常运行。
可扩展性:
轻松扩缩容:
可以通过简单的命令或配置更改来增加或减少 Pod 的数量,以满足不同的工作负载需求。例如,在高流量期间可以快速扩展以处理更多请求,在低流量期间可以缩容以节省资源。
水平自动扩缩容(HPA):
可以基于自定义指标(如 CPU 利用率、内存使用情况或应用特定的指标)自动调整 Pod 的数量,实现动态的资源分配和成本优化。
版本管理和更新:
滚动更新:
对于 Deployment 等控制器,可以执行滚动更新来逐步替换旧版本的 Pod 为新版本,确保应用在更新过程中始终保持可用。可以控制更新的速率和策略,以减少对用户的影响。
回滚:
如果更新出现问题,可以轻松回滚到上一个稳定版本,保证应用的稳定性和可靠性。
声明式配置:
简洁的配置方式:
使用 YAML 或 JSON 格式的声明式配置文件来定义应用的部署需求。这种方式使得配置易于理解、维护和版本控制,同时也方便团队协作。
期望状态管理:
只需要定义应用的期望状态(如副本数量、容器镜像等),控制器会自动调整实际状态与期望状态保持一致。无需手动管理每个 Pod 的创建和删除,提高了管理效率。
服务发现和负载均衡:
自动注册和发现:
Kubernetes 中的服务(Service)可以自动发现由控制器管理的 Pod,并将流量路由到它们。这使得应用的服务发现和负载均衡变得简单和可靠,无需手动配置负载均衡器。
流量分发:
可以根据不同的策略(如轮询、随机等)将请求分发到不同的 Pod,提高应用的性能和可用性。
多环境一致性:
一致的部署方式:
在不同的环境(如开发、测试、生产)中,可以使用相同的控制器和配置来部署应用,确保应用在不同环境中的行为一致。这有助于减少部署差异和错误,提高开发和运维效率。
扩(缩)容
1、建立控制器并自动运行pod
[root@k8s-master ~]# kubectl create deployment test --image nginx
2、扩容
[root@k8s-master ~]# kubectl scale deployment test --replicas 4
3、缩容
[root@k8s-master ~]# kubectl scale deployment test --replicas 2
应用版本的更新
1、利用控制器建立pod
[root@k8s-master ~]# kubectl create deployment test --image myapp:v1 --replicas 2
2、暴露端口
[root@k8s-master ~]# kubectl expose deployment test --port 80 --target-port 80
3、访问服务查看现版本
[root@k8s-master ~]# curl 10.107.184.152
4、更新控制器镜像版本
[root@k8s-master ~]# kubectl set image deployments/test myapp=myapp:v2
5、再次访问查看现版本
[root@k8s-master ~]# curl 10.107.184.152
6、查看容器内的历史版本
[root@k8s-master ~]# kubectl rollout history deployment test
7、版本回滚
[root@k8s-master ~]# kubectl rollout undo deployment test --to-revision 1
利用yaml文件部署应用
用yaml文件部署应用有以下优点
声明式配置:
- 清晰表达期望状态:以声明式的方式描述应用的部署需求,包括副本数量、容器配置、网络设置等。这使得配置易于理解和维护,并且可以方便地查看应用的预期状态。
- 可重复性和版本控制:配置文件可以被版本控制,确保在不同环境中的部署一致性。可以轻松回滚到以前的版本或在不同环境中重复使用相同的配置。
- 团队协作:便于团队成员之间共享和协作,大家可以对配置文件进行审查和修改,提高部署的可靠性和稳定性。
灵活性和可扩展性:
- 丰富的配置选项:可以通过 YAML 文件详细地配置各种 Kubernetes 资源,如 Deployment、Service、ConfigMap、Secret 等。可以根据应用的特定需求进行高度定制化。
- 组合和扩展:可以将多个资源的配置组合在一个或多个 YAML 文件中,实现复杂的应用部署架构。同时,可以轻松地添加新的资源或修改现有资源以满足不断变化的需求。
与工具集成:
- 与 CI/CD 流程集成:可以将 YAML 配置文件与持续集成和持续部署(CI/CD)工具集成,实现自动化的应用部署。例如,可以在代码提交后自动触发部署流程,使用配置文件来部署应用到不同的环境。
- 命令行工具支持:Kubernetes 的命令行工具
kubectl
对 YAML 配置文件有很好的支持,可以方便地应用、更新和删除配置。同时,还可以使用其他工具来验证和分析 YAML 配置文件,确保其正确性和安全性。
资源清单参数
参数名称 | 类型 | 参数说明 |
---|---|---|
version | String | 这里是指的是K8S API的版本,目前基本上是v1,可以用kubectl api-versions命令查询 |
kind | String | 这里指的是yaml文件定义的资源类型和角色,比如:Pod |
metadata | Object | 元数据对象,固定值就写metadata |
metadata.name | String | 元数据对象的名字,这里由我们编写,比如命名Pod的名字 |
metadata.namespace | String | 元数据对象的命名空间,由我们自身定义 |
Spec | Object | 详细定义对象,固定值就写Spec |
spec.containers[] | list | 这里是Spec对象的容器列表定义,是个列表 |
spec.containers[].name | String | 这里定义容器的名字 |
spec.containers[].image | string | 这里定义要用到的镜像名称 |
spec.containers[].imagePullPolicy | String | 定义镜像拉取策略,有三个值可选: (1) Always: 每次都尝试重新拉取镜像 (2) IfNotPresent:如果本地有镜像就使用本地镜像,没有则进行拉取 (3) )Never:表示仅使用本地镜像 |
spec.containers[].command[] | list | 指定容器运行时启动的命令,若未指定则运行容器打包时指定的命令 |
spec.containers[].args[] | list | 指定容器运行参数,可以指定多个 |
spec.containers[].workingDir | String | 指定容器工作目录 |
spec.containers[].volumeMounts[] | list | 指定容器内部的存储卷配置 |
spec.containers[].volumeMounts[].name | String | 指定可以被容器挂载的存储卷的名称 |
spec.containers[].volumeMounts[].mountPath | String | 指定可以被容器挂载的存储卷的路径 |
spec.containers[].volumeMounts[].readOnly | String | 设置存储卷路径的读写模式,ture或false,默认为读写模式 |
spec.containers[].ports[] | list | 指定容器需要用到的端口列表 |
spec.containers[].ports[].name | String | 指定端口名称 |
spec.containers[].ports[].containerPort | String | 指定容器需要监听的端口号 |
spec.containers[] ports[].hostPort | String | 指定容器所在主机需要监听的端口号,默认跟上面containerPort相同,注意设置了hostPort同一台主机无法启动该容器的相同副本(因为主机的端口号不能相同,这样会冲突) |
spec.containers[].ports[].protocol | String | 指定端口协议,支持TCP和UDP,默认值为 TCP |
spec.containers[].env[] | list | 指定容器运行前需设置的环境变量列表 |
spec.containers[].env[].name | String | 指定环境变量名称 |
spec.containers[].env[].value | String | 指定环境变量值 |
spec.containers[].resources | Object | 指定资源限制和资源请求的值(这里开始就是设置容器的资源上限) |
spec.containers[].resources.limits | Object | 指定设置容器运行时资源的运行上限 |
spec.containers[].resources.limits.cpu | String | 指定CPU的限制,单位为核心数,1=1000m |
spec.containers[].resources.limits.memory | String | 指定MEM内存的限制,单位为MIB、GiB |
spec.containers[].resources.requests | Object | 指定容器启动和调度时的限制设置 |
spec.containers[].resources.requests.cpu | String | CPU请求,单位为core数,容器启动时初始化可用数量 |
spec.containers[].resources.requests.memory | String | 内存请求,单位为MIB、GIB,容器启动的初始化可用数量 |
spec.restartPolicy | string | 定义Pod的重启策略,默认值为Always. (1)Always:Pod 一旦终止运行,无论容器是如何终止的,kubelet服务都将重启它 (2)OnFailure:只有Pod以非零退出码终止时,kubelet才会重启该容器。如果容器正常结束(退出码为0),则kubelet将不会重启它 (3) Never:Pod终止后,kubelet将退出码报告给Master,不会重启该容器 |
spec.nodeSelector | Object | 定义Node的Label过滤标签,以key:value格式指定 |
spec.imagePullSecrets | Object | 定义pull镜像时使用secret名称,以name:secretkey格式指定 |
spec.hostNetwork | Boolean | 定义是否使用主机网络模式,默认值为false。设置true表示使用宿主机网络,不使用docker网桥,同时设置了true将无法在同一台宿主机 上启动第二个副本 |
如何获得资源帮助
[root@k8s-master yaml]# kubectl explain pod.spec.containers
编写示例
示例1:运行简单的单个容器pod
用命令获取yaml模板
[root@k8s-master ~]# kubectl run test --image myapp:v1 --dry-run=client -o yaml > pod.yml
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: test #pod标签
name: test #pod名称
spec:
containers:
- image: myapp:v1 #pod镜像
name: myapp #容器名称
示例2:运行多个容器pod
注意如果多个容器运行在一个pod中,资源是共享的,如果同时使用相同的资源会产生干扰,比如端口
1、一个端口干扰示例:
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: timing
name: timinglee
spec:
containers:
- image: nginx:latest
name: web1
- image: nginx:latest
name: web2
[root@k8s-master ~]# kubectl apply -f pod.yml
pod/timinglee created
#使用yaml文件创建并运行pod
[root@k8s-master ~]# kubectl get pods -o wide
#查看容器的详细运行信息
查看pod内运行的容器日志信息:
[root@k8s-master yaml]# kubectl logs test web2
2、正确示例:
在一个pod中开启多个容器时一定要确保容器彼此不能互相干扰
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: test
name: test
spec:
containers:
- image: nginx:latest
name: web1
- image: busybox:latest
name: busybox
command: ["/bin/sh","-c","sleep 1000000"]
[root@k8s-master ~]# kubectl get pods
示例3:理解pod间的网络整合
同在一个pod中的容器公用一个网络
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: test
name: test
spec:
containers:
- image: myapp:v1
name: myapp1
- image: busyboxplus:latest
name: busyboxplus
command: ["/bin/sh","-c","sleep 1000000"]
[root@k8s-master ~]# kubectl apply -f pod.yml
pod/test created
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
test 2/2 Running 0 8s
效果演示:
[root@k8s-master ~]# kubectl exec test -c busyboxplus -- curl -s localhost
示例4:端口映射
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: test
name: test
spec:
containers:
- image: myapp:v1
name: myapp1
ports:
- name: http
containerPort: 80
hostPort: 80
protocol: TCP
#测试
[root@k8s-master ~]# kubectl apply -f pod.yml
pod/test created
[root@k8s-master yaml]# kubectl get pods -o wide
效果展示:
[root@k8s-master yaml]# curl k8s-node2
示例5:如何设定环境变量
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: test
name: test
spec:
containers:
- image: busybox:latest
name: busybox
command: ["/bin/sh","-c","echo $NAME;sleep 3000000"]
env:
- name: NAME
value: test
[root@k8s-master ~]# kubectl apply -f pod.yml
效果演示:
[root@k8s-master yaml]# kubectl logs pods/test myapp
示例6:资源限制
资源限制会影响pod的Qos Class资源优先级,资源优先级分为Guaranteed > Burstable > BestEffort
QoS(Quality of Service)即服务质量
资源设定 优先级类型 资源限定未设定 BestEffort 资源限定设定且最大和最小不一致 Burstable 资源限定设定且最大和最小一致 Guaranteed
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: test
name: test
spec:
containers:
- image: myapp:v1
name: myapp
resources:
limits: #pod使用资源的最高限制
cpu: 500m
memory: 100M
requests: #pod期望使用资源量,不能大于limits
cpu: 500m
memory: 100M
[root@k8s-master ~]# kubectl apply -f pod.yml
pod/test created
效果展示:
[root@k8s-master yaml]# kubectl describe pods test
示例7:容器启动管理
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: test
name: test
spec:
restartPolicy: Always
containers:
- image: myapp:v1
name: myapp
[root@k8s-master ~]# kubectl apply -f pod.yml
pod/test created
效果演示:
[root@k8s-master yaml]# kubectl get pods -o wide
#查看pod运行的详细信息,得知该pod在node2节点上
[root@k8s-node2 ~]# docker rm -f k8s_myapp_test_...
#在该工作节点上删除该容器
[root@k8s-node2 ~]# docker ps
#列出正在运行的容器
示例8:选择运行节点
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: test
name: test
spec:
nodeSelector:
kubernetes.io/hostname: k8s-node1
restartPolicy: Always
containers:
- image: myapp:v1
name: myapp
[root@k8s-master ~]# kubectl apply -f pod.yml
pod/test created
效果演示:
[root@k8s-master yaml]# kubectl get pods -o wide
示例9:共享宿主机网络
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: test
name: test
spec:
hostNetwork: true
restartPolicy: Always
containers:
- image: myapp:v1
name: myapp
[root@k8s-master ~]# kubectl apply -f pod.yml
pod/test created
效果演示:
[root@k8s-master yaml]# kubectl exec -it pods/test -c myapp -- /bin/sh
pod 的生命周期
INIT 容器
官方文档:https://kubernetes.io/zh/docs/concepts/workloads/pods/
-
Pod 可以包含多个容器,应用运行在这些容器里面,同时 Pod 也可以有一个或多个先于应用容器启动前的 Init 容器。
-
Init 容器与普通的容器非常像,除了以下两点:
-
它们总是运行到完成
-
init 容器不支持 Readiness,因为它们必须在 Pod 就绪之前运行完成,每个 Init 容器必须运行成功,下一个才能够运行。
-
-
如果Pod的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。但是,如果 Pod 对应的 restartPolicy 值为 Never,它不会重新启动。
INIT 容器的功能
- Init 容器可以包含一些安装过程中应用容器中不存在的实用工具或个性化代码。
- Init 容器可以安全地运行这些工具,避免这些工具导致应用镜像的安全性降低。
- 应用镜像的创建者和部署者可以各自独立工作,而没有必要联合构建一个单独的应用镜像。
- Init 容器能以不同于Pod内应用容器的文件系统视图运行。因此,Init容器可具有访问 Secrets 的权限,而应用容器不能够访问。
- 由于 Init 容器必须在应用容器启动之前运行完成,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod内的所有的应用容器会并行启动。
INIT 容器示例
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
name: initpod
name: initpod
spec:
containers:
- image: myapp:v1
name: myapp
initContainers: #init容器
- name: init-myservice
image: busybox
command: ["sh","-c","until test -e /testfile;do echo wating for myservice; sleep 2;done"]
[root@k8s-master ~]# kubectl apply -f pod.yml
pod/initpod created
pod的状态:
[root@k8s-master yaml]# kubectl get pods
#查看容器的状态
[root@k8s-master yaml]# kubectl logs initpod init-myservice
#查看init容器的日志信息
满足 init 容器条件,则容器正常运行:
[root@k8s-master ~]# kubectl exec pods/initpod -c init --- /bin/sh -c "touch /testfile"
探针
探针是由 kubelet 对容器执行的定期诊断:
- ExecAction:在容器内执行指定命令。如果命令退出时返回码为 0 ,则认为诊断成功。
- TCPSocketAction:对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的。
- HTTPGetAction:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的。
每次探测都将获得以下三种结果之一:
- 成功:容器通过了诊断。
- 失败:容器未通过诊断。
- 未知:诊断失败,因此不会采取任何行动。
Kubelet 可以选择是否执行在容器上运行的三种探针执行和做出反应:
- livenessProbe:指示容器是否正在运行。如果探测到容器存活失败,则 kubelet 会杀死容器,并且容器将受到其
重启策略
的影响。如果容器不提供存活探针,则默认状态为 Success。 - readinessProbe:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 该 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为 Success。
- startupProbe:指示容器中的应用是否已经启动。如果提供了启动探测(startup probe),则禁用所有其他探测,直到它成功为止。如果启动探测失败,kubelet 将杀死容器,容器服从其
重启策略
进行重启。如果容器没有提供启动探测,则默认状态为成功Success。
ReadinessProbe 与 LivenessProbe 的区别:
- ReadinessProbe 当检测失败后,将 Pod 的 IP:Port 从对应的 EndPoint 列表中删除。
- LivenessProbe 当检测失败后,将杀死容器并根据 Pod 的重启策略来决定作出对应的措施。
StartupProbe 与 ReadinessProbe、LivenessProbe 的区别
- 如果三个探针同时存在,先执行 StartupProbe 探针,其他两个探针将会被暂时禁用,直到 pod 满足 StartupProbe 探针配置的条件,其他 2 个探针启动,如果不满足按照规则重启容器。
- 另外两种探针在容器启动后,会按照配置,直到容器消亡才停止探测,而 StartupProbe 探针只在容器运行前进行探测,且探测成功后就停止探测,不参与后续容器运行。
探针示例
存活探针示例:
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
name: liveness
name: liveness
spec:
containers:
- image: myapp:v1
name: myapp
livenessProbe:
tcpSocket: #检测端口存在性
port: 8080
initialDelaySeconds: 3 #容器启动后要等待多少秒后就探针开始工作,默认是 0
periodSeconds: 1 #执行探测的时间间隔,默认为 10s
timeoutSeconds: 1 #探针执行检测请求后,等待响应的超时时间,默认为 1s
[root@k8s-master ~]# kubectl apply -f pod.yml
pod/liveness created
查看pod的状态:
[root@k8s-master yaml]# kubectl get pods
查看其pod的描述信息:
[root@k8s-master yaml]# kubectl describe pods liveness
将其端口号改为80端口,探测成功,则运行容器:
[root@k8s-master yaml]# kubectl describe pods liveness
就绪探针示例:
[root@k8s-master ~]# vim pod.yml
apiVersion: v1
kind: Pod
metadata:
labels:
name: readiness
name: readiness
spec:
containers:
- image: myapp:v1
name: myapp
readinessProbe:
httpGet:
path: /test.html
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
[root@k8s-master ~]# kubectl apply -f pod.yml
pod/liveness created
查看其pod状态:
[root@k8s-master yaml]# kubectl get pods
查看其pod详细描述信息:
root@k8s-master yaml]# kubectl describe pods readness
满足探测条件,则Pod运行成功:
[root@k8s-master ~]# kubectl exec pods/readiness -c myapp -- /bin/sh -c "echo test > /usr/share/nginx/html/test.html"