文章目录
pod
- 资源清单
- 明称空间级别
- pod
- 集群级别
- role、namespace、node、role、clusterRole、roleBinding、ClusterRoleBinding
- 元数据
- HPA
- 明称空间级别
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L33TYpAW-1576315971384)(E:\OneDrive\笔记\markdown\picture\image-20191118220148390.png)]
容器初始化
-
pod能有多个容器,应用运行在容器里面,但是他也有可能有一个或多个先于容器启动的Init容器。
-
init容器与普通容器非常像,除了以下两点:
- 1.inti容器总是运行到成功完成为止
- 2.每个init容器都必须在下一个init容器启动之前成功完成
如果pod的init容器启动失败,kubernetes会不断重启该pod,直到init容器成功为止。然而,如果pod对应的restartPolicy为Never,他不会重新启动
InitC
Pod能够具有多个容器,应用运行在容器里面,但是他也有一个或多个先于应用容器启动的Init容器。
Init容器与普通容器非常像,除了以下两点:
- Init容器总是运行到成功完成为止
- 每个Init容器都必须在下一个Init容器启动之前成功完成
如果Pod的Init容器容器失败,Kubernetes会不断重启该Pod,直到Init容器启动成功为止。然而,如果Pod对应的restartPolicy为Never,他不会重新启动。
Init容器的作用:
因为Init容器具有与应用程序容器分离的单独镜像,所以他们的启动相关代码具有如下优势:
- 他们可以包含并运行实用工具,但是出于安全考虑,是不建议在应用容器镜像中包含这些实用工具的
- 他们可以包含实用工具或定制化代码来安装,但是不能出现在应用程序镜像中。例如,创建镜像没必要FROM另一个镜像,只需要在安装过程中实用类似sed、awk、python、dig这样的工具
- 应用程序镜像可以分离出创建和部署的角色,而没有必要联合他们构件一个单独的镜像
- Init容器使用Linux Namespace,所以相对应用程序容器来说具有不同的文件系统视图。因此,他们能够具有访问Secrit的权限,而应用程序容器则不能。
- 他们必须在应用程序容器启动之前运行完成,而应用程序容器是并行运行的,所以Init容器能够提供一种简单的阻塞或延迟应用容器的启动的方法,知道满足了一组先决条件。
特殊说明:
- Init容器具有应用容器的所有字段。除了readinessProbe,因为Init容器无法定义不同于完成(completion)的就绪(readiness)之外的其他状态。这会在验证过程中强制执行
- 在Pod中的每个app和Init容器的名称必须唯一;与任何其他容器共享同一个名称,会在验证时抛出错误。
init模板:
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh','-c','echo The app is running! && sleep 3600']
initContainers:
- name: init-myservice
image: busybox
command: ['sh','-c','until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
- name: init-mydb
image: busybox
command: ['sh','-c','until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 1111
---
apiVersion: v1
kind: Service
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 1112
容器探针
探针是由kubelet对容器执行的定期诊断。要执行诊断,kubelet调用由容器实现的Handler。
有三种类型的处理程序:
-
ExecAction:在容器内执行指定命令。如果命令退出时返回码为0,则认为诊断成功。
-
TCPSocketAction:对指定端口上的容器的IP地址进行TCP检查。如果端口打开,则诊断被认为是成功的
-
HTTPGetAction:对指定的端口和路径上的容器的IP地址执行HTTP Get请求。如果(200<=状态码<400),则诊断被认为是成功的
HTTP probe中可以给httpGet设置以下配置项:
host
: 连接的主机名,默认连接到pod的ipscheme
: 支持的协议,http、https,默认httppath
:访问的HTTP server的pathhttpHeaders
:自定义请求的headerport
:访问的容器的端口名字或者端口号,端口号必须介于1和65525之间
每次探测都将获得以下三种结果之一:
- 成功:容器通过了诊断
- 失败:容器未通过诊断
- 未知:诊断失败,因此不会采取任何行动
???Probe中的精切配置,可以更精确的配置liveness和readiness检测:
periodSeconds: 3
每3秒执行一次探测。执行探测的频率,默认是10秒,最小1秒initialDelaySeconds: 3
容器初始化完成后延迟3秒执行探测timeoutSeconds
:探测超时时间,默认1秒,最小1秒successThreshold
:探测失败后,最少连续探测成功多少次才被认定为成功。默认1,最小值是1。对于liveness必须是1failureThreshold
:探测成功后,最少连续探测失败多少次才被认定为失败。默认是3,最小值是1
探测方式
- 以下就绪检测和存活检测可以同时设置
- 就绪检测和存货检测均支持以上三种检测方式
livenessProbe
存活探针:指示容器是否正在运行。如果存活探测失败,则kubelet会杀死容器,并且容器会受其重启策略的影响。如果容器不提供存活探针,则默认状态为SuccessreadinessProbe
就绪探针:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与Pod匹配的所有Service的端点中删除该Pod的IP地址。初始延迟之前的就绪状态默认为Failure。如果容器不提供就绪探针,则默认状态为Success
检测探针-就绪检测
readinessProbe-httpget
apiVersion: v1
kind: Pod
metadata:
name: readiness-httpget-pod
namespace: default
spec:
containers:
- name: readiness-httpget-container
image: tomcat:v1 #镜像名称
imagePullPolicy: Never #镜像拉去策略,IfNotPresent:本地docker没有时从仓库拉取
readinessProbe:
httpGet: #httpget方式的探针诊断类型
port: 8080 #访问的端口
path: /docs/index.html #httpget请求的路径
initialDelaySeconds: 1 #容器初始化完成后延时几秒再探测
periodSeconds: 3 #每3秒检测一次
检测探针-存活检测
如果不符合存活条件就销毁pod再创建新的pod,与上面的就绪检测有一定差别
livenessProbe-exec
说明:以下容器启动时会先创建一个live文件,然后过60秒再删除这个文件。存活检测每三秒检测一次这个文件是否存在,如果不存在会直接销毁容器,重新创建。最后的现象就是pod会隔段时间不断重启
apiVersion: v1
kind: Pod
metadata:
name: liveness-exec-pod
namespace: default
spec:
containers:
- name: liveness-exec-container
image: busybox #不写镜像tag默认是latest
imagePullPolicy: IfNotPresent #镜像拉去策略,IfNotPresent:本地docker没有时从仓库拉取
command: ["bin/sh","-c","touch /tmp/live;sleep 60;rm -rf /tmp/live;sleep 60"] #容器创建完后先创建一个live文件,睡60秒,删除文件再睡60秒
livenessProbe:
exec:
command: ["test","-e","/tmp/live"] #测试文件是否存在,不存在就重启
initialDelaySeconds: 1 #容器初始化完成后延时几秒再探测
periodSeconds: 3 #每3秒检测一次
livenessProbe-httpget
说明:启动是正常的,进到容器内删除tomcat中的webapps/docs/index.html后,就会探活失败,pod会重启。
apiVersion: v1
kind: Pod
metadata:
name: liveness-httpget-pod
namespace: default
spec:
containers:
- name: liveness-httpget-container
image: tomcat
imagePullPolicy: IfNotPresent
ports:
- name: haha
containerPort: 8080 #pod暴露的端口,此端口仅是额外的信息,对端口是否被暴露没有影响,不太理解
livenessProbe:
httpGet:
port: haha #试探时发现要与上面的ports中的haha相对应才行,否则要直接写一个具体的端口号。
path: /docs/index.html #访问的HTTP server的path
initialDelaySeconds: 1 #容器初始化完成后延时几秒再探测
periodSeconds: 3 #每3秒检测一次
timeoutSeconds: 10 #超时时间
livenessProbe-tcp
说明:tcp探活探测端口9090是否有监听,本处是没有的,探测9090端口时没返回,而且超时时间设置为1秒,直接超时导致认为pod是挂的,会不断重启pod
apiVersion: v1
kind: Pod
metadata:
name: liveness-tcp-pod
namespace: default
spec:
containers:
- name: liveness-tcp-container
image: tomcat
imagePullPolicy: IfNotPresent
livenessProbe:
initialDelaySeconds: 5 #容器初始化完成后延时几秒再探测
periodSeconds: 3 #每3秒检测一次
timeoutSeconds: 1 #超时时间
tcpSocket: #tcp探测端口是否开启,如果没有监听则认为容器是挂的,就会重启pod
port: 9090
启动退出动作
也即当容器启动时要做的事情,与容器停止时要做的事情。
apiVersion: v1
kind: Pod
metadata:
name: lifecycle-pod #pod名称
namespace: default
spec:
containers:
- name: lifecycle-demo-container #容器名称
image: tomcat
lifecycle:
postStart: #启动容器后的操作
exec:
command: ["/bin/sh","-c","echo Hello postStart handler > /home/msg.txt"]
preStop: #停止容器前的操作
exec:
command: ["/bin/sh","-c","echo bye~ postStop handler > /home/msg.txt"]
pod phase(相位):状态
- 挂起(pending):Pod已被Kubernetes系统接受,但有一个或多个容器镜像尚未创建。等待时间包括调度Pod的时间和通过网络下载镜像的时间,这可能需要花点时间
- 运行中(Running):该Pod已经绑定到了一个节点上,Pod中所有的容器都已经被创建。至少有一个容器在运行,或者正在 处于启动或停止的状态
- 成功(Succeeded):Pod中所有的容器都被成功终止,并且不会再重启
- 失败(Failed):Pod中所有的容器都已经终止,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止
- 未知(Unknown):因为某些原因无法取得Pod的状态,通常是因为与Pod所在主机通信失败
资源控制器
Pod控制器
什么是控制器
Kubernetes 中内建了很多 controller(控制器),这些相当于一个状态机,用来控制 Pod 的具体状态和行为
控制器类型
- ReplicationController 和 ReplicaSet
- Deployment
- DaemonSet
- StateFulSet
- Job/CronJob
- Horizontal Pod Autoscaling
ReplicationController 和 ReplicaSet
ReplicationController(RC)用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的 Pod 来替代;而如果异常多出来的容器也会自动回收;
在新版本的 Kubernetes 中建议使用 ReplicaSet 来取代 ReplicationController 。ReplicaSet 跟ReplicationController 没有本质的不同,只是名字不一样,并且 ReplicaSet 支持集合式的 selector;RC已经被逐渐废弃!
Deployment
Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义 (declarative) 方法,用来替代以前的ReplicationController 来方便的管理应用。典型的应用场景包括;
- 定义 Deployment 来创建 Pod 和 ReplicaSet
- 滚动升级和回滚应用
- 扩容和缩容
- 暂停和继续 Deployment
DaemonSet
DaemonSet 确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod
使用 DaemonSet 的一些典型用法:
- 运行集群存储 daemon,例如在每个 Node 上运行
glusterd
、ceph
- 在每个 Node 上运行日志收集 daemon,例如
fluentd
、logstash
- 在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter、collectd 、Datadog 代理、[[New Relic 代理,或 Ganglia gmond
- New Relic 代理,或 Ganglia
gmond
Job
Job 负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束
CronJob
Cron Job 管理基于时间的 Job,即:
- 在给定时间点只运行一次
- 周期性地在给定时间点运行
使用前提条件:
当前使用的 Kubernetes 集群,版本 >= 1.8(对 CronJob)。对于先前版本的集群,版本 <1.8,启动 API Server时,通过传递选项--runtime-config=batch/v2alpha1=true
可以开启 batch/v2alpha1API
典型的用法如下所示:
- 在给定的时间点调度 Job 运行
- 创建周期性运行的 Job,例如:数据库备份、发送邮件
StatefulSet
StatefulSet 作为 Controller 为 Pod 提供唯一的标识。它可以保证部署和 scale 的顺序
StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计),其应用场景包括:
- 稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现
- 稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现
- 有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现
- 有序收缩,有序删除(即从N-1到0)
Horizontal Pod Autoscaling
应用的资源使用率通常都有高峰和低谷的时候,如何削峰填谷,提高集群的整体资源利用率,让service中的Pod个数自动调整呢?这就有赖于Horizontal Pod Autoscaling了,顾名思义,使Pod水平自动缩放
Deployment控制器
RS 与 RC 与 Deployment 关联
RC (ReplicationController )主要的作用就是用来确保容器应用的副本数始终保持在用户定义的副本数 。即如果有容器异常退出,会自动创建新的Pod来替代;而如果异常多出来的容器也会自动回收
Kubernetes 官方建议使用 RS(ReplicaSet ) 替代 RC (ReplicationController ) 进行部署,RS 跟 RC 没有本质的不同,只是名字不一样,并且 RS 支持集合式的 selector
apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
name: replicaset-demo #注意名字不能有大写字母
spec:
replicas: 3
selector:
matchLabels: #标签选择器
app: tomcat
template:
metadata:
labels:
app: tomcat
spec:
containers:
- name: my-tomcat
image: tomcat
env:
- name: yc #环境变量key
value: yangche #环境变量value
ports:
- containerPort: 80 #容器暴露的端口
RS 与 Deployment 的关联
Deployment
Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController 来方便的管理应用。典型的应用场景包括:
- 定义Deployment来创建Pod和ReplicaSet
- 滚动升级和回滚应用
- 扩容和缩容
- 暂停和继续Deployment
Ⅰ、部署一个简单的 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
kubectl create -f https://kubernetes.io/docs/user-guide/nginx-deployment.yaml --record
## --record参数可以记录命令,我们可以很方便的查看每次 revision 的变化
Ⅱ、扩容