kubernetes的pod管理、资源清单、pod生命周期、控制器
前言
kubernetes的简单部署这篇博客将kubernetes基本的部署出来接下来就开始深入的学习kubernetes的相关知识。
学习的过程中主要多看以下两个网站进行知识的补充。
- Kubernetes中文手册 .kubernetes的中文社区,里面对一些名词的解释比较详细。
- kubernetes的官方文档.教你一些简单的应用实例。
pod管理
kubectl命令参考文档.
在Kubernetes中,最小的管理元素不是一个个独立的容器,而是Pod,Pod是最小的,管理,创建,计划的最小单元.
Pod是可以创建和管理Kubernetes计算的最小可部署单元一个Pod代表着集群中运行的一个进程(相当于一个容器,之前的docker相当与单机管理,k8s相当于集群管理),每个pod都有一个唯一的ip。
一个pod类似一个豌豆荚(相当于一个资源共享池,一个pod内多个容器共享),包含一个或多个容器(通常是docker),多个容器间共享IPC、Network和UTC namespace。
[root@server1 ~]# cd harbor/
[root@server1 harbor]# docker-compose start
[root@server1 harbor]# docker-compose ps
[root@server1 docker]# docker logout reg.westos.org
Removing login credentials for reg.westos.org
[root@server1 docker]# docker login reg.westos.org
[root@server1 harbor]# docker search busyboxplus
[root@server1 harbor]# docker pull rickiechina/busyboxplus
[root@server1 docker]# docker tag rickiechina/busyboxplus:latest reg.westos.org/library/busyboxplus:latest ##改名
[root@server1 docker]# docker push reg.westos.org/library/busyboxplus:latest ##上传
创建pod应用
[root@server2 ~]# kubectl run -h ##查看创建pod帮助
[root@server2 ~]# kubectl run nginx --image=myapp:v1 ##创建一个pod应用,nginx是pod的名字,myapp是镜像
#--replicas=2 扩容参数 --record 记录参数
# kubectl run nginx --image=nginx --replicas=2 --record #参数使用方法
[root@server2 ~]# kubectl get pod ##查看pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 9s
[root@server2 ~]# kubectl get pod -n default ##查看指定namespace的节点
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 74s
[root@server2 ~]# kubectl get pod -o wide ##查看节点的具体信息
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 81s 10.244.1.7 server4 <none> <none>
[root@server2 ~]# curl 10.244.1.7
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@server2 ~]# kubectl run demo --image=busyboxplus -it ##交互式界面运行一个pod,ctrl+p+q退出可以通过kubectl attach demo -c demo -i -t重新进入
[root@server2 ~]# kubectl run demo --image=busyboxplus -it ##再次进入
#ip addr
上面建立的pod只能在集群内部(集群节点及容器)访问
pod相当于环境,真正连接的是容器
kubectl attach demo -c demo -it ##当pod内有多个容器时,-c 指定容器
删除pod
[root@server2 ~]# kubectl delete pod nginx ##删除pod
pod "nginx" deleted
[root@server2 ~]# kubectl describe pod demo ##查看详细描述
[root@server2 ~]# kubectl logs demo ##查看日志
deployment控制器
[root@server2 ~]# kubectl create deployment nginx --image=myapp:v1 ##创建一个pod
deployment.apps/nginx created ##生成一个新的deployment控制器的pod,删除之后会自动重新生成不同id的pod
[root@server2 ~]# kubectl get all
[root@server2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 0 6m28s
nginx-67f9d9c97f-xjg2n 1/1 Running 0 28s
[root@server2 ~]# kubectl delete pod nginx-67f9d9c97f-xjg2n ##删除pod后在查看
pod "nginx-67f9d9c97f-xjg2n" deleted ##生成新的id的pod
[root@server2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 0 9m9s
nginx-67f9d9c97f-bt9k5 1/1 Running 0 116s
[root@server2 ~]# kubectl delete deployment nginx ##彻底删除deployment
[root@server2 ~]# kubectl get pod ##删除成功
当进行删除操作,控制器通过rs会自动重新创建pod
彻底删除deployment
pod的扩容与缩容
[root@server2 ~]# kubectl create deployment nginx --image=myapp:v1
deployment.apps/nginx created
[root@server2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 0 13m
nginx-67f9d9c97f-649gg 1/1 Running 0 3s
[root@server2 ~]# kubectl scale deployment --replicas=2 nginx
deployment.apps/nginx scaled
[root@server2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 0 13m
nginx-67f9d9c97f-649gg 1/1 Running 0 13s
nginx-67f9d9c97f-sq7qn 1/1 Running 0 6s
[root@server2 ~]# kubectl scale deployment --replicas=4 nginx
deployment.apps/nginx scaled
[root@server2 ~]# kubectl get pod -o wide
service微服务
将pod看为一个service ,暴露出去,让别人访问,能实现负载均衡
service是一个抽象概念,定义了一个服务的多个pod逻辑合集和访问pod的策略,一般把service称为微服务。
- 创建service
$ kubectl expose deployment(控制器) nginx --port=80 --target-port=80
此时pod客户端可以通过service的名称访问后端的两个Pod
ClusterIP: 默认类型,自动分配一个仅集群内部可以访问的虚拟IP
当进行拉伸时,会自动出现在svc中
使用NodePort类型暴露端口,让外部客户端访问Pod
使用NodePort类型暴露端口,让外部客户端访问Pod(即真机也可以访问)
$ kubectl edit svc nginx //修改service的type为NodePort
$ kubectl expose deployment nginx --port=80 --target-port=80 --type=NodePort //也可以在创建service时指定类型
NodePort: 在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过 NodeIP:NodePort 来访问该服务
[root@server2 ~]# kubectl get svc ##查看TYPE
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 27d
nginx ClusterIP 10.97.0.120 <none> 80/TCP 9m54s
[root@server2 ~]# kubectl edit svc nginx ##TYPE改成NodePort
service/nginx edited
[root@server2 ~]# kubectl get svc ##80映射31572端口
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 27d
nginx NodePort 10.97.0.120 <none> 80:31572/TCP 10m
以节点ip+对外端口的方式访问
更新pod镜像
[root@server2 ~]# kubectl set image deployment nginx myapp=myapp:v2 ##更新到v2
[root@server2 ~]# kubectl rollout history deployment nginx ##查看更新记录
[root@server2 ~]# kubectl describe deployments.apps nginx
[root@localhost~]# curl 192.168.0.2:31572
Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a>
回滚
[root@server2 ~]# kubectl get pod ##rs值变成版本2的rs值
[root@server2 ~]# kubectl rollout undo deployment nginx --to-revision=1 //回滚版本
deployment.apps/nginx rolled back
[root@server2 ~]# kubectl rollout history deployment nginx //查看历史版本
deployment.apps/nginx
REVISION CHANGE-CAUSE
2 <none>
3 <none>
[root@foundation50 Desktop]# curl 192.168.0.2:31572
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@server2 ~]# kubectl get pod ##rs值变成版本1的rs值
资源清单
- 格式如下:
apiVersion: group/version //指明api资源属于哪个群组和版本,同一个组可以有多个版本
$ kubectl api-versions //查询命令
kind: //标记创建的资源类型,k8s主要支持以下资源类别
Pod,ReplicaSet,Deployment,StatefulSet,DaemonSet,Job,Cronjob
metadata: //元数据
name: //对像名称
namespace: //对象属于哪个命名空间
labels: //指定资源标签,标签是一种键值数据
spec: //定义目标资源的期望状态
$ kubectl explain pod //查询帮助文档
查看资源清单的书写模板
## 方法一:书写时候的查找方法,可以之直接通过explain一步一步查找参数内容用法
[root@server2 ~]# kubectl explain pod ##查看pod所有参数,-required-带有required是必须存在的参数
[root@server2 ~]# kubectl explain pod.apiVersion ##查看api对应需要添加的参数
## 方法二: 直接打开一个已经有的deployment,然后生成相应的yaml文件,进行参考
[root@server2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 0 3h51m
[root@server2 ~]# kubectl get pod demo -o yaml ##生成一个yaml文件
kubectl explain pod //查询帮助文档
kubectl explain pod.metadata 继续查看
自主式Pod资源清单
删掉之前的所有部署
[root@server2 ~]# vim pod.yml
[root@server2 ~]# kubectl apply -f pod.yml
[root@server2 ~]# kubectl get pod
[root@server2 ~]# kubectl describe pod nginx
[root@server2 ~]# kubectl delete -f pod.yml
[root@server2 ~]# kubectl get pod
[root@server2 ~]# vim pod.yml ##编写yml文件,可用性较高
[root@server2 ~]# cat pod.yml
apiVersion: apps/v1
kind: Deployment ##设置为deployment
metadata:
name: nginx
namespace: default ##设置命名空间
spec:
replicas: 1
selector:
matchLabels:
run: nginx
template: ##模板
metadata:
labels: ##标签
run: nginx
spec:
#nodeSelector: ##指定运行节点的俩种方法(方法一)
# kubernetes.io/hostname: server4
#nodeName: server3 ##指定运行节点的俩种方法(方法二)
#hostNetwork: true ##可以通过直接访问节点ip的方式访问,hostNetwork继承主机网络[root@westos Desktop]# curl 172.25.13.4
containers:
- name: nginx
image: myapp:v1
imagePullPolicy: IfNotPresent
resources: ##资源限制
requests:
cpu: 100m #1/10的cpu
memeory: 100Mi #至少有
limits:
cpu: 0.5 #0.5个
memory: 512Mi #最多有
#- name: busyboxplus
# image: busyboxplus
# imagePullPolicy: IfNotPresent ##本地有镜像,优先本地拉取,没有就需要联网拉取
# stdin: true ##stdin和tty是为了保证交互式,相当于执行参数-it
# tty: true
[root@server2 ~]# kubectl apply -f pod.yml ##deployment使用apply,会自动更新修改内容
## $ kubectl create -f demo.yaml ##不是deployment使用create,不会自动更新修改内容
deployment.apps/nginx created
[root@server2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 0 4h49m
nginx-79cc587f-lq6k9 1/1 Running 0 4m15s
nginx-79cc587f-mdcz7 1/1 Running 0 4m10s
[root@server2 ~]# kubectl describe pod nginx-79cc587f-lq6k9 | less
留着旧的pod是为了回滚
restartpolicy 默认总是always, 当退出的时候,默认重启
[root@server2 ~]# kubectl attach demo -it
Defaulting container name to demo.
Use 'kubectl describe pod/demo -n default' to see all of the containers in this pod.
If you don't see a command prompt, try pressing enter.
/ # Session ended, resume using 'kubectl attach demo -c demo -i -t' command when the pod is running
[root@server2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 4 3h15m
如果俩个镜像使用的是同一个端口,只有一个可以成功
[root@server2 ~]# kubectl apply -f pod.yml
deployment.apps/nginx configured
[root@server2 ~]# kubectl get pod
标签
## 1.修改节点标签
[root@server2 ~]# kubectl get node --show-labels ##查看节点标签
[root@server2 ~]# kubectl label nodes server3 app=nginx ##打标签
node/server3 labeled
[root@server2 ~]# kubectl get nodes server3 --show-labels ##查看节点server3的标签
NAME STATUS ROLES AGE VERSION LABELS
server3 Ready <none> 27d v1.20.2 app=nginx,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=server3,kubernetes.io/os=linux
[root@server2 ~]# kubectl label nodes server3 app=myapp --overwrite ##重新覆盖
node/server3 labeled
[root@server2 ~]# kubectl get nodes server3 --show-labels ##查看修改内容
NAME STATUS ROLES AGE VERSION LABELS
server3 Ready <none> 27d v1.20.2 app=myapp,beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=server3,kubernetes.io/os=linux
[root@server2 ~]# kubectl label nodes server3 app- #删除标签
node/server3 labeled
[root@server2 ~]# kubectl get nodes server3 --show-labels
NAME STATUS ROLES AGE VERSION LABELS
server3 Ready <none> 27d v1.20.2 beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=server3,kubernetes.io/os=linux
## 2. 修改pod标签
[root@server2 ~]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
demo 1/1 Running 0 6h12m run=demo
nginx-79cc587f-cr7vs 1/1 Running 0 15m pod-template-hash=79cc587f,run=nginx
nginx-79cc587f-hc9lz 1/1 Running 0 15m pod-template-hash=79cc587f,run=nginx
[root@server2 ~]# kubectl label pod demo run=demo2 --overwrite
pod/demo labeled
[root@server2 ~]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
demo 1/1 Running 0 6h12m run=demo2
nginx-79cc587f-cr7vs 1/1 Running 0 15m pod-template-hash=79cc587f,run=nginx
nginx-79cc587f-hc9lz 1/1 Running 0 15m pod-template-hash=79cc587f,run=nginx
##3.查看有相应标签的项
[root@server2 ~]# kubectl get pod -L run
节点标签选择器
$ kubectl label nodes server2 disktype=ssd
node/server2 labeled
$ kubectl get nodes -l disktype
NAME STATUS ROLES AGE VERSION
server2 Ready <none> 6d v1.17.2
在yaml文件中增加标签选择器
清理deployment
pod生命周期
Pod 遵循一个预定义的生命周期,起始于 Pending 阶段,如果至少 其中有一个主要容器正常启动,则进入 Running,之后取决于 Pod 中是否有容器以 失败状态结束而进入 Succeeded 或者 Failed 阶段。
- 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内的所有的应用容器会并行启动。
三种探针(livenessProbe、readinessProbe、startupProbe)
关于探针更多详见官网的参考文档.
重启策略
PodSpec 中有一个 restartPolicy 字段,可能的值为 Always、OnFailure 和 Never。默认为 Always。
Pod 的生命
一般Pod 不会消失,直到人为销毁他们,这可能是一个人或控制器。
建议创建适当的控制器来创建 Pod,而不是直接自己创建 Pod。因为单独的 Pod 在机器故障的情况下没有办法自动复原,而控制器却可以。
三种可用的控制器:
使用 Job 运行预期会终止的 Pod,例如批量计算。Job 仅适用于重启策略为 OnFailure 或 Never 的 Pod。
对预期不会终止的 Pod 使用 ReplicationController、ReplicaSet 和 Deployment ,例如 Web 服务器。 ReplicationController 仅适用于具有 restartPolicy 为 Always 的 Pod。
提供特定于机器的系统服务,使用 DaemonSet 为每台机器运行一个 Pod 。
liveness存活探针
指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其 重启策略 的影响。如果容器不提供存活探针,则默认状态为 Success。
[root@server2 ~]# vim live.yml ##编辑示例文件
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: busyboxplus
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 2
periodSeconds: 3
[root@server2 ~]# kubectl create -f live.yml ##创建
[root@server2 ~]# kubectl get pod ##查看创建的pod,执行成功不会报错。执行错误会一直重启.
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 0 7h44m
liveness-exec 1/1 Running 0 12s
[root@server2 ~]# kubectl describe pod liveness-exec
[root@server2 ~]# kubectl delete -f live.yml
pod "liveness-exec" deleted
readiness就绪探针
指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为 Success。
定义一个存活态 HTTP 请求接口
[root@server2 ~]# cat live.yml
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: myapp:v1
livenessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 2 #启动需要2秒
periodSeconds: 3 #间隔3秒
readinessProbe:
httpGet:
path: /hostname.html #文件存在
port: 80
initialDelaySeconds: 3 #启动需要3秒
periodSeconds: 3 #间隔3秒
[root@server2 ~]# kubectl create -f live.yml
[root@server2 ~]# kubectl get pod
[root@server2 ~]# kubectl describe pod liveness-exec ##查看详细信息,发现启动成功
文件不存在就一直请求服务
[root@server2 ~]# kubectl delete -f live.yml
pod "liveness-exec" deleted
[root@server2 ~]# vim live.yml
path: /test.html #没有这个文件就一直请求服务
[root@server2 ~]# kubectl create -f live.yml
pod/liveness-exec created
[root@server2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 0 8h
liveness-exec 0/1 Running 0 33s
[root@server2 ~]# kubectl describe pod liveness-exec
[root@server2 ~]# kubectl exec -it liveness-exec -- sh
/ # cd usr/share/nginx/
/usr/share/nginx # ls
html
/usr/share/nginx # cd html/
/usr/share/nginx/html # ls
50x.html index.html
/usr/share/nginx/html # touch test.html
/usr/share/nginx/html # ls
50x.html index.html test.html
/usr/share/nginx/html # exit
[root@server2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 0 8h
liveness-exec 1/1 Running 0 95s
端口错误
[root@server2 ~]# cat pod3.yml
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: myapp:v1
livenessProbe:
tcpSocket:
port: 8080 ###端口错误
initialDelaySeconds: 2 #启动需要2秒
periodSeconds: 3 #间隔3秒
readinessProbe:
httpGet:
path: /hostname.html
port: 80
initialDelaySeconds: 3 #启动需要3秒
periodSeconds: 3 #间隔3秒
初始化容器+service
创建service后会提供dns解析
service.yml就是创建一个svc
没有endpoint
访问不到,但可以解析。进入Demo,nslookup myserice通过域名会更加简单,
myapp一个应用容器,plus,初始化容器,一直nslook解析,解析过才能退出,才能运行myapp,
所以不能先创建svc,先创建初始化,正在初始化,init contaoners,没有得到相应的解析,看日志,一直停在初始化,
此时创建svc,可以解析到
初始化容器优先于普通容器myapp,而且必须运行成功后才能完成,解析到域名,退出,结束,此时才能运行应用容器myapp
[root@server2 ~]# cat service.yml
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
[root@server2 ~]# cat init.yml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: myapp:v1
initContainers:
- name: init-myservice
image: busyboxplus
command: ['sh', '-c', "until nslookup myservice.default.svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
[root@server2 ~]# kubectl create -f service.yml
[root@server2 ~]# kubectl get svc
[root@server2 ~]# kubectl describe svc myservice
##测试解析myservice
[root@server2 ~]# kubectl attach demo -it
/ # nslookup myservice ##可以解析到myservice
/ # nslookup mydb ##解析不到mydb / #
[root@server2 ~]# kubectl delete -f service.yml ##删除myservice服务 service "myservice" deleted
[root@server2 ~]# kubectl create -f init.yml ##创建pod
[root@server2 ~]# kubectl get pod ##查看pod,发现初始化失败
[root@server2 ~]# kubectl create -f service.yml
[root@server2 ~]# kubectl get pod
[root@server2 ~]# kubectl delete -f init.yml ##实验做完之后删除,保证环境的纯净
pod "myapp-pod" deleted
查看日志
kubectl logs myapp-pod -c init-myservice # 查看第一个 Init 容器
控制器
几种控制器的参考文档.
Pod 的分类:
- 自主式 Pod:Pod 退出后不会被创建(没有控制器)
- 控制器管理的 Pod:在控制器的生命周期里,始终要维持 Pod 的副本数目
ReplicaSet控制器
- Replication Controller(rc)和ReplicaSet(rs)
ReplicaSet 是下一代的 Replication Controller,官方推荐使用ReplicaSet。
ReplicaSet 和 Replication Controller 的唯一区别是选择器的支持,
ReplicaSet 支持新的基于集合的选择器需求。
ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。
虽然 ReplicaSets 可以独立使用,但今天它主要被Deployments 用作协调 Pod 创建、删除和更新的机制。
[root@server2 ~]# cat rs.yml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replicaset-example
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: myapp:v1
[root@server2 ~]# vim rs.yml
[root@server2 ~]# kubectl apply -f rs.yml
replicaset.apps/replicaset-example created
[root@server2 ~]# kubectl get rs ##查看rs
NAME DESIRED CURRENT READY AGE
replicaset-example 3 3 1 5s
[root@server2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 1 9h
liveness-exec 1/1 Running 0 63m
replicaset-example-4hdkg 1/1 Running 0 27s
replicaset-example-85rxq 1/1 Running 0 27s
replicaset-example-n7tp2 1/1 Running 0 27s
[root@server2 ~]# kubectl delete rs replicaset-example
replicaset.apps "replicaset-example" deleted
[root@server2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 1 9h
liveness-exec 1/1 Running 0 64m
控制副本数
Deployment
Deployment 为 Pod 和 ReplicaSet 提供了一个申明式的定义方法。
典型的应用场景:
用来创建Pod和ReplicaSet
滚动更新和回滚
扩容和缩容
暂停与恢复
deployment 连rs ,rs控制副本数
本身rs也是一个控制器,deployment主要更新,灰度发布
[root@server2 ~]# cat deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment
spec:
replicas: 3
selector:
matchLabels: ###pod 上匹配标签是nginx,才会进行操作
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: myapp:v1
[root@server2 ~]# vim rs.yml
[root@server2 ~]# kubectl apply -f rs.yml
deployment.apps/deployment created
[root@server2 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
demo 1/1 Running 1 9h
deployment-6456d7c676-856mr 1/1 Running 0 39s
deployment-6456d7c676-mbx72 1/1 Running 0 39s
deployment-6456d7c676-tt6ld 1/1 Running 0 39s
liveness-exec 1/1 Running 0 71m
[root@server2 ~]# kubectl get pod --show-labels ##显示所有标签
[root@server2 ~]# kubectl label pod deployment-6456d7c676-856mr app=myapp --overwrite
pod/deployment-6456d7c676-856mr labeled
[root@server2 ~]# kubectl get pod
[root@server2 ~]# kubectl get pod --show-labels #控制器副本定义的是3个,通过标签匹配3个副本,标签被改变后会重新创建副本。
[root@server2 ~]# kubectl get pod -L app
当把文件里面的镜像myapp:v1改变为myapp:v2时
回收rs里面所有的副本,创建新的rs,在新的rs创建新的pod,原本的rs不会删除,以便回滚,除非删除控制器, 通过标签匹配pod,一旦改变标签,不受管控,因为控制器已经定义了标签
[root@server2 ~]# vim rs.yml
image: myapp:v2 #滚动更新
[root@server2 ~]# kubectl apply -f rs.yml
deployment.apps/deployment configured
[root@server2 ~]# kubectl get pod -L app
[root@server2 ~]# kubectl delete pod deployment-6456d7c676-856mr
pod "deployment-6456d7c676-856mr" deleted
[root@server2 ~]# kubectl get pod -L app
[root@server2 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
deployment-6456d7c676 0 0 0 10m
deployment-6d4f5bf58f 3 3 3 2m21s
之前的rs并不会被删除deployment-6456d7c676
回滚
[root@server2 ~]# vim rs.yml
image: myapp:v1
[root@server2 ~]# kubectl apply -f rs.yml
deployment.apps/deployment configured
[root@server2 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
deployment-6456d7c676 3 3 3 12m
deployment-6d4f5bf58f 0 0 0 4m38s
[root@server2 ~]# kubectl get pod
创建svc
[root@server2 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 27d
myservice ClusterIP 10.109.37.8 <none> 80/TCP 73m
[root@server2 ~]# kubectl describe svc myservice
[root@server2 ~]# kubectl delete -f service.yml
service "myservice" deleted
[root@server2 ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 27d
[root@server2 ~]# kubectl expose deployment deployment --port=80 ##暴露80端口 service/deployment exposed
[root@server2 ~]# kubectl get svc
[root@server2 ~]# kubectl describe svc deployment ##查看详细信息,有三个pod节点ip
[root@server2 ~]# kubectl svc deployment -o yaml | less
标签
[root@server2 ~]# kubectl get pod
[root@server2 ~]# kubectl get pod -L app
[root@server2 ~]# kubectl label pod deployment-6456d7c676-cbj6j app=myapp --overwrite
pod/deployment-6456d7c676-cbj6j labeled
[root@server2 ~]# kubectl get pod
[root@server2 ~]# kubectl get pod --show-labels #控制器副本定义的是3个,通过标签匹配3个副本,标签被改变后会重新创建副本。
[root@server2 ~]# kubectl get pod -L app
[root@server2 ~]# kubectl edit svc deployment
selector:
app: myapp
[root@server2 ~]# kubectl describe svc deployment #根据标签选择受控主机
[root@server2 ~]# kubectl delete -f rs.yml
[root@server2 ~]# kubectl delete svc deployment
[root@server2 ~]# kubectl get all #查看是否清理干净
[root@server2 ~]# kubectl delete pod/deployment-6456d7c676-cbj6j ##不属于deployment:nginx
DaemonSet控制器
DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。当有节点加入集群时, 也会为他们新增一个 Pod 。当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
DaemonSet 的典型用法:
在每个节点上运行集群存储 DaemonSet,例如 glusterd、ceph。
在每个节点上运行日志收集 DaemonSet,例如 fluentd、logstash。
在每个节点上运行监控 DaemonSet,例如 Prometheus Node Exporter、zabbix agent等
一个简单的用法是在所有的节点上都启动一个 DaemonSet,将被作为每种类型的 daemon 使用。
一个稍微复杂的用法是单独对每种 daemon 类型使用多个 DaemonSet,但具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求。
[root@server1 harbor]# docker search zabbix-agent
[root@server1 harbor]# docker pull zabbix/zabbix-agent
[root@server1 harbor]# docker tag zabbix/zabbix-agent:latest reg.westos.org/library/zabbix-agent:latest
[root@server1 harbor]# docker push reg.westos.org/library/zabbix-agent:latest
The push refers to repository [reg.westos.org/library/zabbix-agent]
[root@server2 ~]# vim daemonset.yml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: daemonset-example
labels:
k8s-app: zabbix-agent
spec:
selector:
matchLabels:
name: zabbix-agent
template:
metadata:
labels:
name: zabbix-agent
spec:
containers:
- name: zabbix-agent
image: zabbix-agent
[root@server2 ~]# kubectl apply -f daemonset.yml ##执行之后会在每一个节点上都运行一个zabbix
[root@server2 ~]# kubectl get pod
[root@server2 ~]# kubectl get pod -o wide ##发现server3和server4上都运行有zabbix
[root@server2 ~]# kubectl delete -f daemonset.yml
StatefulSet
StatefulSet 是用来管理有状态应用的工作负载 API 对象。实例之间有不对等关系,以及实例对外部数据有依赖关系的应用,称为“有状态应用”
StatefulSet 用来管理 Deployment 和扩展一组 Pod,并且能为这些 Pod 提供序号和唯一性保证。
StatefulSets 对于需要满足以下一个或多个需求的应用程序很有价值:
稳定的、唯一的网络标识符。
稳定的、持久的存储。
有序的、优雅的部署和缩放。
有序的、自动的滚动更新。
job控制器
执行批处理任务,仅执行一次任务,保证任务的一个或多个Pod成功结束
[root@server1 harbor]# docker pull perl
[root@server1 harbor]# docker tag perl:latest reg.westos.org/library/perl:latest
[root@server1 harbor]# docker push reg.westos.org/library/perl:latest
[root@server2 ~]# vim job.yml
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl ##server1上拉取上传到仓库
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] ##显示pi后面2000位小数
restartPolicy: Never ##不会重启
backoffLimit: 4 ##出错次数限制为4次
[root@server2 ~]# kubectl create -f job.yml
job.batch/pi created
[root@server2 ~]# kubectl get pod
[root@server2 ~]# kubectl describe pod pi-hjkcl
[root@server2 ~]# kubectl logs pi-hjkcl ##查看生成的日志信息
[root@server2 ~]# kubectl delete -f job.yml
CronJob
Cron Job 创建基于时间调度的 Jobs。
一个 CronJob 对象就像 crontab (cron table) 文件中的一行,它用 Cron 格式进行编写,并周期性地在给定的调度时间执行 Job。
Cron 时间表语法
# ┌───────────── 分钟 (0 - 59)
# │ ┌───────────── 小时 (0 - 23)
# │ │ ┌───────────── 月的某天 (1 - 31)
# │ │ │ ┌───────────── 月份 (1 - 12)
# │ │ │ │ ┌───────────── 周的某天 (0 - 6) (周日到周一;在某些系统上,7 也是星期日)
# │ │ │ │ │
# │ │ │ │ │
# │ │ │ │ │
# * * * * *
[root@server2 ~]# vim cronjob.yml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busyboxplus
imagePullPolicy: IfNotPresent
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
[root@server2 ~]# kubectl create -f cronjob.yml
cronjob.batch/hello created
[root@server2 ~]# kubectl get all
[root@server2 ~]# kubectl get pod ##发生了调度
[root@server2 ~]# kubectl get all
[root@server2 ~]# kubectl logs hello-1614693060-dmcfw
Tue Mar 2 13:51:04 UTC 2021
Hello from the Kubernetes cluster
[root@server2 ~]# kubectl delete -f cronjob.yml ##也可以通过文件删除
cronjob.batch "hello" deleted