在kubernetes中,所有的内容都抽象为资源,用户需要通过操作资源来管理kubernetes
资源管理方式
- 命令式对象管理:直接使用命令去操作 kubernetes 资源
- 命令式对象配置:通过命令配置和配置文件去操作 kubernetes 资源
- 声明式对象配置:通过apply命令和配置文件去操作 kubernetes 资源
类型 | 适用环境 | 优点 | 缺点 |
---|---|---|---|
命令式对象管理 | 测试 | 简单 | 只能操作活动对象,无法审计、跟踪 |
命令式对象配置 | 开发 | 可以审计、追踪 | 项目大时,配置文件多,操作麻烦 |
声明式对象配置 | 开发 | 支持目录操作 | 意外情况下,难以调试 |
命令式对象管理
kubectl 是 kubernetes 集群的命令行工具,通过它能够对集群本身进行管理,并能够在集群上进行容器化应用的安装部署
# kubectl 命令语法
kubectl [command][type][name][flags]
# comand:指定要对资源执行的操作,例如create、get、delete
# type:指定资源类型,比如deployment、pod、service
# name:指定资源的名称,名称大小写敏感
# flags:指定额外的可选参数
常用命令
基本命令
# 显示集群版本
[root@k8s-master ~]# kubectl version
# 显示集群信息
[root@k8s-master ~]# kubectl cluster-info
# 创建控制器
[root@k8s-master ~]# kubectl create deployment name --image nginx
deployment.apps/name created
# 查看控制器
[root@k8s-master ~]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
name 1/1 1 1 20s
# 查看控制器帮助
[root@k8s-master ~]# kubectl explain deployment
...
spec <DeploymentSpec>
Specification of the desired behavior of the Deployment.
...
# 查看控制器参数帮助
[root@k8s-master ~]# kubectl explain deployment.spec
# 编辑控制器配置
# 通过补丁更改控制器配置
# 删除资源
[root@k8s-master ~]# kubectl delete deployments.apps name
deployment.apps "name" deleted
[root@k8s-master ~]# kubectl get deployments.apps
No resources found in default namespace.
运行和调试命令
# 运行Pod
[root@k8s-master ~]# kubectl run name --image nginx
# 端口暴漏
[root@k8s-master ~]# kubectl get service
# 服务列表中并没有NAME:name的Pod
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
[root@k8s-master ~]# kubectl expose pod name --port 80 --target-port 80
# 将容器的80端口映射到主机的80端口,通过本机80端口访问容器服务
service/name exposed
[root@k8s-master ~]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
name ClusterIP 10.109.100.128 <none> 80/TCP 12s
# CLUSTER-IP 是 访问服务的入口
[root@k8s-master ~]# curl 10.109.100.128
...
<h1>Welcome to nginx!</h1>
...
# 查看资源信息
[root@k8s-master ~]# kubectl describe pods name
# 包括运行节点、日志、IP、标签、状态等
# 查看资源日志
[root@k8s-master ~]# kubectl logs pods/name
...
10.244.0.0 - - [08/Oct/2024:06:59:00 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.76.1" "-"
...
# 运行交互Pod
[root@k8s-master ~]# kubectl run -it zhang3 --image busybox
If you don't see a command prompt, try pressing enter
/ #
/ #
# CTRL + P + Q 键退出Pod而不停止Pod
# 运行非交互Pod,不加参数--it即可
# 交互方式进入(正在运行)容器(允许交互)
[root@k8s-master ~]# kubectl attach pods/zhang3 -it
If you don\'t see a command prompt, try pressing enter.
/ #
/ #
# 容器运行指定命令
[root@k8s-master ~]# kubectl exec -it pods/name -- /bin/bash
# 本机文件到Pod
[root@k8s-master ~]# echo "name:zhang3" > userlist
[root@k8s-master ~]# kubectl cp userlist name:/
[root@k8s-master ~]# kubectl exec -it pods/name -- /bin/bash
root@name:/# cat userlist
name:zhang3
# Pod文件到本机
root@name:/# echo "name:moon" > sun
[root@k8s-master ~]# kubectl cp name:/sun /root/sun.txt
[root@k8s-master ~]# cat sun.txt
name:moon
高级命令
# 命令生成Yaml模板文件
[root@k8s-master ~]# kubectl create deployment --image nginx li4 --dry-run=client -o yaml > li4.yaml
# 利用Yaml文件生成资源
[root@k8s-master ~]# vim li4.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: li4
name: li4
spec:
replicas: 2
selector:
matchLabels:
app: li4
template:
metadata:
labels:
app: li4
spec:
containers:
- image: nginx
name: nginx
[root@k8s-master ~]# kubectl apply -f li4.yaml
deployment.apps/li4 created
[root@k8s-master ~]# kubectl get deployments.apps
NAME READY UP-TO-DATE AVAILABLE AGE
li4 2/2 2 2 20s
# 删除资源
[root@k8s-master ~]# kubectl delete -f li4.yaml
deployment.apps "li4" deleted
# 管理资源标签
[root@k8s-master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
name 1/1 Running 0 30m run=name
# 添加标签
[root@k8s-master ~]# kubectl label pods name app=moon
pod/name labeled
[root@k8s-master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
name 1/1 Running 0 32m app=moon,run=name
# 更改标签
[root@k8s-master ~]# kubectl label pods name app=sun --overwrite
pod/name labeled
[root@k8s-master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
name 1/1 Running 0 33m app=sun,run=name
# 删除标签
[root@k8s-master ~]# kubectl label pods name app-
pod/name unlabeled
[root@k8s-master ~]# kubectl get pods name --show-labels
NAME READY STATUS RESTARTS AGE LABELS
name 1/1 Running 0 34m run=name
# 当删除控制器运行Pod的标签时,控制器会启动新Pod,并保留旧的Pod
[root@k8s-master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
li4-5c67b55f5-nfr5j 1/1 Running 0 2m54s app=li4,pod-template-hash=5c67b55f5
li4-5c67b55f5-zvjrl 1/1 Running 0 2m54s app=li4,pod-template-hash=5c67b55f5
[root@k8s-master ~]# kubectl label pods li4-5c67b55f5-nfr5j app-
pod/li4-5c67b55f5-nfr5j unlabeled
[root@k8s-master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
li4-5c67b55f5-jnlvw 1/1 Running 0 2s app=li4,pod-template-hash=5c67b55f5
li4-5c67b55f5-nfr5j 1/1 Running 0 3m17s pod-template-hash=5c67b55f5
li4-5c67b55f5-zvjrl 1/1 Running 0 3m17s app=li4,pod-template-hash=5c67b55f5
# 当删除控制器时,旧的Pod不会随着被删除
[root@k8s-master ~]# kubectl delete -f li4.yaml
[root@k8s-master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
li4-5c67b55f5-nfr5j 1/1 Running 0 7m1s pod-template-hash=5c67b55f5
# 还原干净的环境
[root@k8s-master ~]# kubectl delete pods name
[root@k8s-master ~]# kubectl delete pods zhang3 --force
# --force:强制删除不需要确认
[root@k8s-master ~]# kubectl delete pods li4-5c67b55f5-nfr5j
Pod
- Pod是可以创建和管理 Kubernetes 计算的最小可部署单元
- 一个Pod代表着集群中运行的一个进程,每个 Pod 都有一个唯一的 IP
- 一个pod类似一个豌豆荚,包含一个或多个容器
- 多个容器间共享IPC、Network 和 UTC namespace
创建自主式Pod
优点
-
灵活性高
- 可以精确控制 Pod 的各种配置参数,包括容器的镜像、资源限制、环境变量、命令和参数等,满足特定的应用需求
-
学习和调试方便
- 对于学习 Kubernetes 的原理和机制非常有帮助,通过手动创建 Pod 可以深入了解 Pod 的结构和配置方式。在调试问题时,可以更直接地观察和调整 Pod 的设置
-
适用于特殊场景
- 在一些特殊情况下,如进行一次性任务、快速验证概念或在资源受限的环境中进行特定配置时,手动创建 Pod 可能是一种有效的方式
缺点
-
管理复杂
- 如果需要管理大量的 Pod,手动创建和维护会变得非常繁琐和耗时。难以实现自动化的扩缩容、故障恢复等操作
-
缺乏高级功能
- 无法自动享受 Kubernetes 提供的高级功能,如自动部署、滚动更新、服务发现等。这可能导致应用的部署和管理效率低下
-
可维护性差
- 手动创建的 Pod 在更新应用版本或修改配置时需要手动干预,容易出现错误,并且难以保证一致性。相比之下,通过声明式配置或使用 Kubernetes 的部署工具可以更方便地进行应用的维护和更新
简单使用
# 查看Pod具体信息
[root@k8s-master ~]# kubectl run nginx --image nginx
pod/nginx created
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 23s
[root@k8s-master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 36s 10.244.1.29 k8s-node1.org <none> <none>
[root@k8s-master ~]# kubectl delete pods nginx
pod "nginx" deleted
利用控制器管理Pod(推荐)
-
高可用性和可靠性
- 自动故障恢复:如果一个 Pod 失败或被删除,控制器会自动创建新的 Pod 来维持期望的副本数量。确保应用始终处于可用状态,减少因单个 Pod 故障导致的服务中断
- 健康检查和自愈:可以配置控制器对 Pod 进行健康检查(如存活探针和就绪探针)如果 Pod 不健康,控制器会采取适当的行动,如重启 Pod 或删除并重新创建它,以保证应用的正常运行
-
可扩展性
- 轻松扩缩容:可以通过简单的命令或配置更改来增加或减少 Pod 的数量,以满足不同的工作负载需求。例如,在高流量期间可以快速扩展以处理更多请求,在低流量期间可以缩容以节省资源
- 水平自动扩缩容(HPA):可以基于自定义指标(如 CPU 利用率、内存使用情况或应用特定的指标)自动调整 Pod 的数量,实现动态的资源分配和成本优化
-
版本管理和更新
- 滚动更新:对于 Deployment 等控制器,可以执行滚动更新来逐步替换旧版本的 Pod 为新版本,确保应用在更新过程中始终保持可用。可以控制更新的速率和策略,以减少对用户的影响
- 回滚:如果更新出现问题,可以轻松回滚到上一个稳定版本,保证应用的稳定性和可靠性
-
声明式配置
- 简洁的配置方式:使用 YAML 或 JSON 格式的声明式配置文件来定义应用的部署需求
- 期望状态管理:只需要定义应用的期望状态(如副本数量、容器镜像等),控制器会自动调整实际状态与期望状态保持一致。无需手动管理每个 Pod 的创建和删除,提高了管理效率
-
服务发现和负载均衡
- 自动注册和发现:Kubernetes 中的服务(Service)可以自动发现由控制器管理的 Pod,并将流量路由到它们。这使得应用的服务发现和负载均衡变得简单和可靠,无需手动配置负载均衡器
- 流量分发:可以根据不同的策略(如轮询、随机等)将请求分发到不同的 Pod,提高应用的性能和可用性。
-
多环境一致性
- 一致的部署方式:在不同的环境(如开发、测试、生产)中,可以使用相同的控制器和配置来部署应用,确保应用在不同环境中的行为一致。这有助于减少部署差异和错误,提高开发和运维效率
简单使用
# 建立控制器并运行Pod
[root@k8s-master ~]# kubectl create deployment zhang3 --image nginx
deployment.apps/zhang3 created
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
zhang3-5fcf4477f7-tjvq9 1/1 Running 0 7s
# 扩容
[root@k8s-master ~]# kubectl scale deployment zhang3 --replicas 6
deployment.apps/zhang3 scaled
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
vol1 1/1 Running 1 (4d22h ago) 4d23h
zhang3-5fcf4477f7-2hjs9 1/1 Running 0 5s
zhang3-5fcf4477f7-5sck5 1/1 Running 0 5s
zhang3-5fcf4477f7-9lvhn 1/1 Running 0 5s
zhang3-5fcf4477f7-fl8cm 1/1 Running 0 5s
zhang3-5fcf4477f7-mlh62 1/1 Running 0 5s
zhang3-5fcf4477f7-tjvq9 1/1 Running 0 36s
# 缩容
[root@k8s-master ~]# kubectl scale deployment zhang3 --replicas 3
deployment.apps/zhang3 scaled
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
vol1 1/1 Running 1 (4d22h ago) 4d23h
zhang3-5fcf4477f7-9lvhn 1/1 Running 0 15s
zhang3-5fcf4477f7-mlh62 1/1 Running 0 15s
zhang3-5fcf4477f7-tjvq9 1/1 Running 0 46s
[root@k8s-master ~]# kubectl delete deployments.apps zhang3
deployment.apps "zhang3" deleted
进阶使用
# 控制器建立Pod
[root@k8s-master ~]# kubectl create deployment moon --image myapp:v1 --replicas 2
deployment.apps/moon created
# 暴漏端口
[root@k8s-master ~]# kubectl expose deployment moon --port 80 --target-port 80
service/moon exposed
# 访问服务
[root@k8s-master ~]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
moon ClusterIP 10.110.91.79 <none> 80/TCP 6s
[root@k8s-master ~]# curl 10.110.91.79
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
# 查看历史版本
[root@k8s-master ~]# kubectl rollout history deployment moon
deployment.apps/moon
REVISION CHANGE-CAUSE
1 <none>
# 更新控制器镜像版本
[root@k8s-master ~]# kubectl set image deployments/moon myapp=myapp:v2
deployment.apps/moon image updated
[root@k8s-master ~]# kubectl rollout history deployment moon
deployment.apps/moon
REVISION CHANGE-CAUSE
1 <none>
2 <none>
# 访问服务
[root@k8s-master ~]# curl 10.110.91.79
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
# 版本回滚
[root@k8s-master ~]# kubectl rollout undo deployment moon --to-revision 1
deployment.apps/moon rolled back
[root@k8s-master ~]# curl 10.110.91.79
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s-master ~]# kubectl delete deployments.apps moon
利用Yaml文件部署应用
-
声明式配置:
- 清晰表达期望状态:以声明式的方式描述应用的部署需求,包括副本数量、容器配置、网络设置等。这使得配置易于理解和维护,并且可以方便地查看应用的预期状态
- 可重复性和版本控制:配置文件可以被版本控制,确保在不同环境中的部署一致性。可以轻松回滚到以前的版本或在不同环境中重复使用相同的配置
- 团队协作:便于团队成员之间共享和协作,大家可以对配置文件进行审查和修改,提高部署的可靠性和稳定性
-
灵活性和可扩展性:
- 丰富的配置选项:可以通过 YAML 文件详细地配置各种 Kubernetes 资源,如 Deployment、Service、ConfigMap、Secret 等。可以根据应用的特定需求进行高度定制化
- 组合和扩展:可以将多个资源的配置组合在一个或多个 YAML 文件中,实现复杂的应用部署架构。同时,可以轻松地添加新的资源或修改现有资源以满足不断变化的需求
-
与工具集成:
- 与 CI/CD 流程集成:可以将 YAML 配置文件与持续集成和持续部署(CI/CD)工具集成,实现自动化的应用部署
- 命令行工具支持:Kubernetes 的命令行工具 kubectl 对 YAML 配置文件有很好的支持,可以方便地应用、更新和删除配置。同时,还可以使用其他工具来验证和分析 YAML 配置文件,确保其正确性和安全性
简单使用
运行单个容器Pod
[root@k8s-master ~]# kubectl run moon --image myapp:v1 --dry-run=client -o yaml > zhang3.yml
[root@k8s-master ~]# vim zhang3.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: moon # Pod标签
name: moon # Pod名称
spec:
containers:
- image: myapp:v1 # Pod镜像
name: moon # Pod容器名称
[root@k8s-master ~]# kubectl apply -f zhang3.yml
[root@k8s-master ~]# kubectl get pods moon
NAME READY STATUS RESTARTS AGE
moon 1/1 Running 0 9s
[root@k8s-master ~]# kubectl delete -f zhang3.yml
pod "moon" deleted
[root@k8s-master ~]# kubectl get pods moon
Error from server (NotFound): pods "moon" not found
运行多个容器Pod
[root@k8s-master ~]# vim zhang3.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: moon
name: moon
spec:
containers:
- image: nginx:latest
name: moon
- image: nginx:latest
name: sun
[root@k8s-master ~]# kubectl apply -f zhang3.yml
[root@k8s-master ~]# kubectl get pods moon
# 多个容器运行在一个Pod中,资源共享的同时,也在使用相同的资源,比如端口,导致相互干扰
NAME READY STATUS RESTARTS AGE
moon 1/2 Error 1 (8s ago) 12s
[root@k8s-master ~]# kubectl logs moon sun
# 按Yaml语句顺序建立Pod,端口冲突,则靠后的Pod不能建立
...
[notice] 1#1: try again to bind() after 500ms
[emerg] 1#1: still could not bind()
[emerg] still could not bind()
[root@k8s-master ~]# kubectl delete -f zhang3.yml
pod "moon" deleted
进阶使用
理解Pod间网络整合,即同在一个Pod中的容器共用一个网络
[root@k8s-master ~]# vim zhang3.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: moon
name: moon
spec:
containers:
- image: myapp:v1
name: moon
- image: busyboxplus:latest
name: sun
command: ["/bin/sh","-c","sleep 1000000"]
[root@k8s-master ~]# kubectl apply -f zhang3.yml
[root@k8s-master ~]# kubectl get pods moon
NAME READY STATUS RESTARTS AGE
moon 2/2 Running 0 14s
[root@k8s-master ~]# kubectl exec moon -c sun -- curl -s localhost
# 在sun容器访问本地,显示moon容器的内容,说明同一个Pod中的容器共用一个网络
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
端口映射
[root@k8s-master ~]# kubectl delete -f zhang3.yml --force
[root@k8s-master ~]# vim zhang3.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: moon
name: moon
spec:
containers:
- image: myapp:v1
name: moon
ports:
- name: http
containerPort: 80
hostPort: 80
protocol: TCP
[root@k8s-master ~]# kubectl apply -f zhang3.yml
[root@k8s-master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
moon 1/1 Running 0 9s 10.244.1.39 k8s-node1.org <none> <none>
[root@k8s-master ~]# curl k8s-node1.org:80
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
设定环境变量
[root@k8s-master ~]# kubectl delete -f zhang3.yml
[root@k8s-master ~]# vim zhang3.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: moon
name: moon
spec:
containers:
- image: myapp:v1
name: moon
command: ["/bin/sh","-c","echo $NAME;sleep 3000000"]
env:
- name: NAME
value: sun
[root@k8s-master ~]# kubectl apply -f zhang3.yml
[root@k8s-master ~]# kubectl logs pods/moon moon
sun
资源限制
资源限制会影响 Pod 的 Qos Class资源优先级
资源优先级分为Guaranteed > Burstable > BestEffort
QoS(Quality of Service)即服务质量
资源设定 | 优先级类型 |
---|---|
资源限定未设定 | BestEffort |
资源限定设定且最大和最小不一致 | Burstable |
资源限定设定且最大和最小一致 | Guaranteed |
[root@k8s-master ~]# kubectl delete -f zhang3.yml --force
[root@k8s-master ~]# vim zhang3.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: moon
name: moon
spec:
containers:
- image: myapp:v1
name: moon
resources:
limits:
cpu: 500m
memory: 100M
requests:
cpu: 500m
memory: 100M
[root@k8s-master ~]# kubectl apply -f zhang3.yml
[root@k8s-master ~]# kubectl describe pods moon
...
Limits:
cpu: 500m
memory: 100M
Requests:
cpu: 500m
memory: 100M
...
容器启动管理
[root@k8s-master ~]# kubectl delete -f zhang3.yml
[root@k8s-master ~]# vim zhang3.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: moon
name: moon
spec:
restartPolicy: Always
# 当容器遇到退出时,总是重启容器;只要容器终止就自动重启容器
containers:
- image: myapp:v1
name: moon
[root@k8s-master ~]# kubectl apply -f zhang3.yml
[root@k8s-master ~]# kubectl get pods moon -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
moon 1/1 Running 0 6m52s 10.244.1.42 k8s-node1.org <none> <none>
# 在对应的运行节点,进行操作
[root@k8s-node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
a6c23ab003a5 d4a5e0eaa84f "nginx -g 'daemon of…" 8 minutes ago Up 8 minutes
[root@k8s-node1 ~]# docker rm -f a6c23ab003a5
[root@k8s-node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS
5842ee80be0d d4a5e0eaa84f "nginx -g 'daemon of…" 16 seconds ago Up 16 seconds
选择运行节点
[root@k8s-master ~]# kubectl delete -f zhang3.yml
[root@k8s-master ~]# vim zhang3.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: moon
name: moon
spec:
nodeSelector:
kubernetes.io/hostname: k8s-node2.org
restartPolicy: Always
containers:
- image: myapp:v1
name: moon
[root@k8s-master ~]# kubectl apply -f zhang3.yml
[root@k8s-master ~]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
moon 1/1 Running 0 3s 10.244.2.27 k8s-node2.org <none> <none>
共享宿主机网络(宿主机:运行节点)
[root@k8s-master ~]# kubectl delete -f zhang3.yml
[root@k8s-master ~]# vim zhang3.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: moon
name: moon
spec:
hostNetwork: true
restartPolicy: Always
containers:
- image: busybox:latest
name: busybox
command: ["/bin/sh","-c","sleep 100000"]
[root@k8s-master ~]# kubectl apply -f zhang3.yml
[root@k8s-master ~]# kubectl get pods -o wide moon
NAME READY STATUS RESTARTS AGE IP NODE
moon 1/1 Running 0 3m48s 172.25.254.10 k8s-node1.org
[root@k8s-master ~]# kubectl exec -it pods/moon -c busybox -- /bin/sh
/ # ifconfig
...
eth0:inet addr:172.25.254.10 Bcast:172.25.254.255 Mask:255.255.255.0
...
[root@k8s-master ~]# kubectl delete -f zhang3.yml --force
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 zhang3.yml
apiVersion: v1
kind: Pod
metadata:
labels:
name: moon
name: moon
spec:
containers:
- image: myapp:v1
name: moon
initContainers:
- image: busybox
name: sun
command: ["sh","-c","until test -e /testfile;do echo wating for myservice; sleep 2;done"]
# 不存在/testfile,则sun容器(INIT容器)无法启动,导致moon容器不能启动
[root@k8s-master ~]# kubectl apply -f zhang3.yml
[root@k8s-master ~]# kubectl get pods moon
NAME READY STATUS RESTARTS AGE
moon 0/1 Init:0/1 0 9s
[root@k8s-master ~]# kubectl logs pods/moon sun
wating for myservice
wating for myservice
wating for myservice
[root@k8s-master ~]# kubectl exec pods/moon -c sun -- /bin/sh -c "touch /testfile"
[root@k8s-master ~]# kubectl get pods moon
NAME READY STATUS RESTARTS AGE
moon 1/1 Running 0 87s
[root@k8s-master ~]# kubectl delete -f zhang3.yml --force
探针
-
探针是由 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 zhang3.yml
apiVersion: v1
kind: Pod
metadata:
labels:
name: moon
name: moon
spec:
containers:
- image: myapp:v1
name: moon
livenessProbe:
tcpSocket:
port: 8080
# 容器是否存在8080端口,若不存在则无法启动容器
initialDelaySeconds: 3
periodSeconds: 1
timeoutSeconds: 1
[root@k8s-master ~]# kubectl apply -f zhang3.yml
[root@k8s-master ~]# kubectl get pods moon
NAME READY STATUS RESTARTS AGE
moon 0/1 CrashLoopBackOff 3 (7s ago) 39s
[root@k8s-master ~]# kubectl describe pods moon
Warning Unhealthy 75s (x9 over 87s) kubelet Liveness probe failed: dial tcp 10.244.1.44:8080: connect: connection refused
[root@k8s-master ~]# kubectl delete -f zhang3.yml
[root@k8s-master ~]# vim zhang3.yml
...
port: 80
...
[root@k8s-master ~]# kubectl apply -f zhang3.yml
[root@k8s-master ~]# kubectl get pods moon
NAME READY STATUS RESTARTS AGE
moon 1/1 Running 0 5s
[root@k8s-master ~]# kubectl delete -f zhang3.yml
就绪探针
[root@k8s-master ~]# vim zhang3.yml
apiVersion: v1
kind: Pod
metadata:
labels:
name: moon
name: moon
spec:
containers:
- image: myapp:v1
name: moon
readinessProbe:
httpGet:
path: /sun.html
# 就绪探针条件;不满足条件,将无法暴漏端口
port: 80
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 1
[root@k8s-master ~]# kubectl apply -f zhang3.yml
[root@k8s-master ~]# kubectl get pods moon
NAME READY STATUS RESTARTS AGE
moon 0/1 Running 0 10s
[root@k8s-master ~]# kubectl expose pod moon --port 80 --target-port 80
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
moon 0/1 Running 0 48s
[root@k8s-master ~]# kubectl describe pods moon
Warning Unhealthy 22s (x22 over 84s) kubelet Readiness probe failed: HTTP probe failed with statuscode: 404
[root@k8s-master ~]# kubectl describe services moon
...
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints:
# 容器并没有对外暴露端口
...
kubectl exec pods/moon -c moon -- /bin/sh -c "echo sun > /usr/share/nginx/html/sun.html"
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
moon 1/1 Running 0 3m14s
[root@k8s-master ~]# kubectl describe services moon
...
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.1.49:80
# 当存在/usr/share/nginx/html/sun.html文件后,满足条件并暴漏端口
...
[root@k8s-master ~]# kubectl delete -f zhang3.yml