Kubernetes中内建了很多controller (控制器) ,这些相当于一个状态机,用来控制Pod的具体状态和行为
Pod 的分类
# 自主式的pod: 单独定义一个pod,这个没有没有副本控制器管理,也没有对应deployment
#init-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: init-pod
labels:
app: myapp
spec:
containers:
- name: myapp
image: hub.kaikeba.com/library/myapp:v1
#注意事项
#总结
#k8s资源对象(所有的k8s管理的资源,都叫做资源对象),都可以独立存在,但是需要根据相应原理,需求结合使用。
ReplicationController (RC)用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的Pod来替代;而如果异常多出来的容器也会自动回收;
在新版本的Kubernetes中建议使用Replicaset来取代ReplicationController. ReplicaSet跟 ReplicationController没有本质的不同,只是名字不一样,并且ReplicaSet支持集合式的selector;
apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
name: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: Java-nginx
image: hub.kaikeba.com/library/myapp:v1
env:
- name: GET_HOSTS_FROM
value: dns
ports:
- containerPort: 80
Deployment为Pod和ReplicaSet提供了一个声明式定义(declarative)方法,用来替代以前的 ReplicationController来方便的管理应用。典型的应用场景包括;
#1)、部署一简单的Nginx应用
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
Deployment更新策略
Deployment可以保证在升级时只有一定数量的Pod是down的。默认的,它会确保至少有比期望的Pod数量少一个是up状态(最多一个不可用)
Deployment同时也可以确保只创建出超过期望数量的一定数量的Pod,默认的,它会确保最多比期望的Pod数量多一个的Pod是up的(最多1个surge )
未来的Kuberentes版本中,将从1-1变成25%-25%
kubect1 describe deployments
#确保只运行一个副本,运行在集群中每一个节点上。(也可以部分节点上只运行一个且只有一个pod副本,如监控ssd硬盘)
# kubectl explain ds
# vim filebeat.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: my-deamon
namespace: default
labels:
app: daemonset
spec:
selector:
matchLabels:
app: my-daemonset
template:
metadata:
labels:
app: my-daemonset
spec:
containers:
- name: daemon-app
image: hub.kaikeba.com/library/myapp:v1
Job
负责处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod
成功结束。而CronJob
则就是在Job
上加上了时间调度。
# 我们用Job这个资源对象来创建一个任务,我们定一个Job来执行一个倒计时的任务,定义YAML文件:
apiVersion: batch/v1
kind: Job
metadata:
name: job-demo
spec:
template:
metadata:
name: job-demo
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox
command:
- "bin/sh"
- "-c"
- "for i in 9 8 7 6 5 4 3 2 1; do echo $i; done"
# 创建
kubectl apply -f xx.yaml
# 查询日志
kubectl logs
注意Job
的RestartPolicy
仅支持Never
和OnFailure
两种,不支持Always
,我们知道Job
就相当于来执行一个批处理任务,执行完就结束了,如果支持Always
的话是不是就陷入了死循环了?
CronJob
其实就是在Job
的基础上加上了时间调度,我们可以:在给定的时间点运行一个任务,也可以周期性地在给定时间点运行。这个实际上和我们Linux
中的crontab
就非常类似了。
一个CronJob
对象其实就对应中crontab
文件中的一行,它根据配置的时间格式周期性地运行一个Job
,格式和crontab
也是一样的。
crontab
的格式如下:
分 时 日 月 星期 要运行的命令 第1列分钟0~59 第2列小时0~23) 第3列日1~31 第4列月1~12 第5列星期0~7(0和7表示星期天) 第6列要运行的命令
# 现在,我们用CronJob来管理我们上面的Job任务
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cronjob-demo
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: hello
image: busybox
args:
- "bin/sh"
- "-c"
- "for i in 9 8 7 6 5 4 3 2 1; do echo $i; done"
# 创建cronjob
kubctl apply -f xx.yaml
# 查询cronjob
kubectl get cronjob
# 查询jon ,cronjon会循环多个job
kubectl get job
# 实时监控查询job
kubectl get job -w
我们这里的Kind
是CronJob
了,要注意的是.spec.schedule
字段是必须填写的,用来指定任务运行的周期,格式就和crontab
一样,另外一个字段是.spec.jobTemplate
, 用来指定需要运行的任务,格式当然和Job
是一致的。还有一些值得我们关注的字段.spec.successfulJobsHistoryLimit
Pod是kubernetes中你可以创建和部署的最⼩也是最简的单位。 ⼀个Pod代表着集群中运⾏的⼀个进程。
Pod中封装着应⽤的容器(有的情况下是好⼏个容器) , 存储、 独⽴的⽹络IP, 管理容器如何运⾏的策略选项。 Pod代
表着部署的⼀个单位: kubernetes中应⽤的⼀个实例, 可能由⼀个或者多个容器组合在⼀起共享资源。
在Kubrenetes集群中Pod有如下两种使⽤⽅式:
每个Pod都是应⽤的⼀个实例。 如果你想平⾏扩展应⽤的话(运⾏多个实例) , 你应该运⾏多个Pod, 每个Pod都是⼀个应⽤实例。 在Kubernetes中, 这通常被称为replication。
服务如何部署:
1、建议一个pod中部署一个容器(通常情况下都是这样的)
2、有一些业务上紧密耦合的服务,可以部署在一个容器,通信效率比较高。
Pod 的 status
属性是一个 PodStatus 对象,拥有一个 phase
字段。它简单描述了 Pod 在其生命周期的阶段。
阶段 | 描述 |
---|---|
Pending | Pod 已被 Kubernetes 接受,但尚未创建一个或多个容器镜像。这包括被调度之前的时间以及通过网络下载镜像所花费的时间,执行需要一段时间。 |
Running | Pod 已经被绑定到了一个节点,所有容器已被创建。至少一个容器正在运行,或者正在启动或重新启动。 |
Succeeded | 所有容器成功终止,也不会重启。 |
Failed | 所有容器终止,至少有一个容器以失败方式终止。也就是说,这个容器要么已非 0 状态退出,要么被系统终止。 |
Unknown | 由于一些原因,Pod 的状态无法获取,通常是与 Pod 通信时出错导致的。 |
使用命令查询pod的状态:
#查询pod的详细状态
kubectl describe pods test1 -n kube-system
Pod 的重启策略有 3 种,默认值为 Always。
- Always : 容器失效时,kubelet 自动重启该容器;
- OnFailure : 容器终止运行且退出码不为0时重启;
- Never : 不论状态为何, kubelet 都不重启该容器。
失败的容器由 kubelet 以五分钟为上限的指数退避延迟(10秒,20秒,40秒…)重新启动,并在成功执行十分钟后重置。
pod生命周期示意图(初始化容器,post start,main container…,pre stop):
说明:
- 初始化容器阶段初始化pod中每一个容器,他们是串行执行的,执行完成后就退出了
- 启动主容器main container
- 在main container刚刚启动之后可以执行post start命令
- 在整个main container执行的过程中可以做两类探测:liveness probe(存活探测)和readiness probe(就绪探测)
- 在main container结束前可以执行pre stop命令
配置启动后钩子(post start)和终止前钩子(pre stop)
- post start:容器创建之后立即执行,如果失败了就会按照重启策略重启容器
- pre stop:容器终止前立即执行,执行完成之后容器将成功终止
可以使用以下命令查看post start和pre stop的设置格式:
- kubectl explain pod.spec.containers.lifecycle.preStop
- kubectl explain pod.spec.containers.lifecycle.postStart
Pod能够持有多个容器,应用运行在容器里面,但是它也可能有一个或多个先于应用容器启动的Init容器
Init容器与普通的容器非常像,除了如下两点:
如果Pod的Init容器失败,Kubernetes会不断地重启该Pod,直到Init容器成功为止。然而,如果Pod对应的restartPolicy为Never,它不会重新启动
因为Init容器具有与应用程序容器分离的单独镜像,所以它们的启动相关代码具有如下优势:
#init-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: init-pod
labels:
app: myapp
spec:
containers:
- name: myapp
image: hub.kaikeba.com/library/busybox:v1
command: ['sh', '-c', 'echo -n "running at " && date +%T && sleep 600']
initContainers:
- name: init-mydb
image: hub.kaikeba.com/library/busybox:v1
command: ['sh', '-c', 'until nslookup init-db; do echo waiting for init-db;date +%T; sleep 2;echo; done;']
#init-db.yaml
kind: Service
apiVersion: v1
metadata:
name: init-db
spec:
ports:
- protocol: TCP
port: 80
targetPort: 3366
#创建
kubectl create -f init-pod.yaml
#查看pod状态 init没成功
kubectl get pod
#查看log
kubectl logs init-pod -c init-mydb
#创建svr
kubectl create -f init-db.yaml
#查看
kubectl get svc
#svc有ip地址,等待init容器运行成功
kubectl get pod
#删除
kubectl delete -f init-pod.yaml
kubectl delete -f init-db.yaml
① 在Pod启动过程中,Init容器会按顺序在网络和数据卷初始化之后启动。每个容器必须在下一个容器启动之前成功退出(网络和数据卷初始化是在pause)
② 如果由于运行时或失败退出,将导致容器启动失败,它会根据Pod的restartPolicy指定的策略进行重试。然而,如果Pod的restartPolicy设置为Always,Init容器失败时会使用RestartPolicy策略
③ 在所有的Init容器没有成功之前,Pod将不会变成Ready状态。Init容器的端口将不会在Service中进行聚集。正在初始化中的Pod处于Pending状态,但应该会将Initializing状态设置为true
④ 如果Pod重启,所有Init容器必须重新执行
⑤ 对Init容器spec的修改被限制在容器image字段,修改其他字段都不会生效。更改Init容器的image字段,等价于重启该Pod
⑥ Init容器具有应用容器的所有字段。除了readinessProbe(就绪检测),因为Init容器无法定义不同于完成(completion)的就绪(readiness)之外的其他状态。这会在验证过程中强制执行
⑦ 在Pod中的每个app和Init容器的名称必须唯一;与任何其它容器共享同一个名称,会在验证时抛出错误
探针是由kubelet对容器执行的定期诊断。要执行诊断,kubelet调用由容器实现的Handler。有三种类型的处理程序:
每次探测都将获得以下三种结果之一:
探测方式
检测探针 - 就绪检测
#readinessProbe-httpget
apiVersion: v1
kind: Pod
metadata:
name: readiness-httpget-pod
namespace: default
spec:
containers:
- name: readiness-httpget-container
image: hub.kaikeba.com/library/myapp:v1
imagePullPolicy: IfNotPresent
readinessProbe:
httpGet:
port: 80
path: /index1.html
initialDelaySeconds: 1
periodSeconds: 3
检测探针 - 存活检测
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec-pod
namespace: default
spec:
containers:
- name: liveness-exec-container
image: hub.kaikeba.cn/library/busybox:v1
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","touch /tmp/live;sleep 60;rm -rf /tmp/live;sleep 3600"]
livenessProbe:
exec:
command: ["test","-e","/tmp/live"]
initialDelaySeconds: 1
periodSeconds: 3
livenessProbe-Httpget方式
存活检测
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget-pod
namespace: default
spec:
containers:
- name: liveness-httpget-container
image: hub.kaikeba.com/library/myapp:v1
imagePu11Policy: IfNotPresent
ports:
- name: http
containerPort: 80
livenessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 10
apiVersion: v1
kind: Pod
metadata:
name: probe-tcp
spec:
containers:
- name: nginx
image: hub.kaikeba.com/library/myapp:v1
livenessProbe:
initialDelaySeconds: 5
timeoutSeconds: 1
tcpSocket:
port: 80
periodSeconds: 3
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget-pod
namespace: default
spec:
containers:
- name: liveness-httpget-container
image: hub.kaikeba.com/library/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 80
readinessProbe:
httpGet:
port: 80
path: /index1.html
initialDelaySeconds: 1
periodSeconds: 3
livenessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 10
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-startstop
spec:
containers:
- name: lifecycle-container
image: nginx
lifecycle:
poststart:
exec:
command: ["/bin/sh","-c","echo Hello from the postStart handler > /usr/share/message"]
prestop:
exec:
command: ["/bin/sh","-c","echo Hello container stop"]
venessProbe:
httpGet:
port: http
path: /index.html
initialDelaySeconds: 1
periodSeconds: 3
timeoutSeconds: 10
* **启动及退出动作**
```yaml
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-startstop
spec:
containers:
- name: lifecycle-container
image: nginx
lifecycle:
poststart:
exec:
command: ["/bin/sh","-c","echo Hello from the postStart handler > /usr/share/message"]
prestop:
exec:
command: ["/bin/sh","-c","echo Hello container stop"]