❤️作者简介:2022新星计划第三季云原生与云计算赛道Top5、华为云享专家、云原生领域潜力新星
博客首页:C站个人主页
作者目的:如有错误请指正,将来会不断的完善笔记,帮助更多的Java爱好者入门,共同进步!
Pivotal公司的Matt Stine于2013年首次提出云原生(Cloud-Native)的概念;2015年,云原生刚推广时,Matt Stine在《迁移到云原生架构》一书中定义了符合云原生架构的几个特征:12因素、微服务、自敏捷架构、基于API协作、扛脆弱性;到了2017年,Matt Stine在接受InfoQ采访时又改了口风,将云原生架构归纳为模块化、可观察、可部署、可测试、可替换、可处理6特质;而Pivotal最新官网对云原生概括为4个要点:DevOps+持续交付+微服务+容器。
总而言之,符合云原生架构的应用程序应该是:采用开源堆栈(K8S+Docker)进行容器化,基于微服务架构提高灵活性和可维护性,借助敏捷方法、DevOps支持持续迭代和运维自动化,利用云平台设施实现弹性伸缩、动态调度、优化资源利用率。
(此处摘选自《知乎-华为云官方帐号》)
kubernetes,简称K8s,是用8代替8个字符"ubernete"而成的缩写。是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效,Kubernetes提供了应用部署,规划,更新,维护的一种机制。
传统的应用部署方式:是通过插件或脚本来安装应用。这样做的缺点是应用的运行、配置、管理、所有生存周期将与当前操作系统绑定,这样做并不利于应用的升级更新/回滚等操作,当然也可以通过创建虚拟机的方式来实现某些功能,但是虚拟机非常重,并不利于可移植性。
新的部署方式:是通过部署容器方式实现,每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。相对于虚拟机,容器能快速部署,由于容器与底层设施、机器文件系统解耦的,所以它能在不同云、不同版本操作系统间进行迁移。
容器占用资源少、部署快,每个应用可以被打包成一个容器镜像,每个应用与容器间成一对一关系也使容器有更大优势,使用容器可以在build或release 的阶段,为应用创建容器镜像,因为每个应用不需要与其余的应用堆栈组合,也不依赖于生产环境基础结构,这使得从研发到测试、生产能提供一致环境。类似地,容器比虚拟机轻量、更"透明",这更便于监控和管理。
Kubernetes是Google开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以便对应用请求进行负载均衡。
在Kubernetes中,我们可以创建多个容器,每个容器里面运行一个应用实例,然后通过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需要运维人员去进行复杂的手工配置和处理。
(此处摘选自《百度百科》)
apiVersion: v1 #必选,版本号,例如v1
kind: Pod #必选,资源类型,例如 Pod
metadata: #必选,元数据
name: string #必选,Pod名称
namespace: string #Pod所属的命名空间,默认为"default"
labels: #自定义标签列表
- name: string
spec: #必选,Pod中容器的详细定义
containers: #必选,Pod中容器列表
- name: string #必选,容器名称
image: string #必选,容器的镜像名称
imagePullPolicy: [ Always|Never|IfNotPresent ] #获取镜像的策略,Always是一直从DockerHub上拉取、Never只拉取本机Docker镜像、IfNotPresent是如果本地有这个镜像则拉取本地的镜像,如果本地没有则去DockerHub上拉取
command: [string] #容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: [string] #容器的启动命令参数列表
workingDir: string #容器的工作目录
volumeMounts: #挂载到容器内部的存储卷配置
- name: string #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符
readOnly: boolean #是否为只读模式
ports: #需要暴露的端口库号列表
- name: string #端口的名称
containerPort: int #容器需要监听的端口号
hostPort: int #容器所在主机需要监听的端口号,默认与Container相同
protocol: string #端口协议,支持TCP和UDP,默认TCP
env: #容器运行前需设置的环境变量列表
- name: string #环境变量名称
value: string #环境变量的值
resources: #资源限制和请求的设置
limits: #资源限制的设置(也就是资源的最大值)
cpu: string #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
memory: string #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
requests: #资源请求的设置(也就是资源的最小值)
cpu: string #Cpu请求,容器启动的初始可用数量
memory: string #内存请求,容器启动的初始可用数量
lifecycle: #生命周期钩子
postStart: #容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启
preStop: #容器终止前执行此钩子,无论结果如何,容器都会终止
livenessProbe: #对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器
exec: #对Pod容器内检查方式设置为exec方式
command: [string] #exec方式需要制定的命令或脚本
httpGet: #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
path: string
port: number
host: string
scheme: string
HttpHeaders:
- name: string
value: string
tcpSocket: #对Pod内个容器健康检查方式设置为tcpSocket方式
port: number
initialDelaySeconds: 0 #容器启动完成后首次探测的时间,单位为秒
timeoutSeconds: 0 #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
periodSeconds: 0 #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
successThreshold: 0
failureThreshold: 0
securityContext:
privileged: false
restartPolicy: [Always | Never | OnFailure] #Pod的重启策略,Always是一直都会重启,知道成功。Never是永不重启。
nodeName: > #设置NodeName表示将该Pod调度到指定到名称的node节点上
nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上
imagePullSecrets: #Pull镜像时使用的secret名称,以key:secretkey格式指定
- name: string
hostNetwork: false #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
volumes: #在该pod上定义共享存储卷列表
- name: string #共享存储卷名称 (volumes类型有很多种)
emptyDir: {} #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
hostPath: string #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
path: string #Pod所在宿主机的目录,将被用于同期中mount的目录
secret: #类型为secret的存储卷,挂载集群与定义的secret对象到容器内部
scretname: string
items:
- key: string
path: string
configMap: #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
name: string
items:
- key: string
path: string
查看k8s各种资源的yaml配置项
kubectl explain 资源名称
[root@k8s-master ~]# kubectl explain pod
KIND: Pod
VERSION: v1
DESCRIPTION:
Pod is a collection of containers that can run on a host. This resource is
created by clients and scheduled onto hosts.
FIELDS:
apiVersion <string>
APIVersion defines the versioned schema of this representation of an
object. Servers should convert recognized schemas to the latest internal
value, and may reject unrecognized values. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
kind <string>
Kind is a string value representing the REST resource this object
represents. Servers may infer this from the endpoint the client submits
requests to. Cannot be updated. In CamelCase. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
metadata <Object>
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
spec <Object>
Specification of the desired behavior of the pod. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
status <Object>
Most recently observed status of the pod. This data may not be up to date.
Populated by the system. Read-only. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
[root@k8s-master ~]# kubectl explain pod.metadata
KIND: Pod
VERSION: v1
RESOURCE: metadata <Object>
DESCRIPTION:
Standard object's metadata. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
ObjectMeta is metadata that all persisted resources must have, which
includes all objects users must create.
FIELDS:
annotations t need to set or understand this field. A workflow
can be the user's name, a controller's name, or the name of a specific
apply path like "ci-cd". The set of fields is always in the version that
the workflow used when modifying the object.
name <string>
Name must be unique within a namespace. Is required when creating
resources, although some resources may allow a client to request the
generation of an appropriate name automatically. Name is primarily intended
for creation idempotence and configuration definition. Cannot be updated.
More info: http://kubernetes.io/docs/user-guide/identifiers#names
namespace <string>
Namespace defines the space within each name must be unique. An empty
namespace is equivalent to the "default" namespace, but "default" is the
canonical representation. Not all objects are required to be scoped to a
namespace - the value of this field for those objects will be empty. Must
be a DNS_LABEL. Cannot be updated. More info:
http://kubernetes.io/docs/user-guide/namespaces
ownerReferences <[]Object>
List of objects depended by this object. If ALL objects in the list have
been deleted, this object will be garbage collected. If this object is
managed by a controller, then an entry in this list will point to this
controller, with the controller field set to true. There cannot be more
than one managing controller.
resourceVersion <string>
An opaque value that represents the internal version of this object that
can be used by clients to determine when objects have changed. May be used
for optimistic concurrency, change detection, and the watch operation on a
resource or set of resources. Clients must treat these values as opaque and
passed unmodified back to the server. They may only be valid for a
particular resource or set of resources. Populated by the system.
Read-only. Value must be treated as opaque by clients and . More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
selfLink <string>
SelfLink is a URL representing this object. Populated by the system.
Read-only. DEPRECATED Kubernetes will stop propagating this field in 1.20
release and the field is planned to be removed in 1.21 release.
uid <string>
UID is the unique in time and space value for this object. It is typically
generated by the server on successful creation of a resource and is not
allowed to change on PUT operations. Populated by the system. Read-only.
More info: http://kubernetes.io/docs/user-guide/identifiers#uids
vim pod01.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test
---
apiVersion: v1
kind: Pod
metadata:
labels:
app: pod01-label
name: pod01
namespace: test
spec:
containers:
- image: nginx:1.17
name: nginx-container
- image: ubuntu:22.10
name: ubuntu-container
[root@k8s-master ~]# kubectl apply -f pod01.yaml
namespace/test created
pod/pod01 created
[root@k8s-master ~]# kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
pod01 1/2 CrashLoopBackOff 2 36s
[root@k8s-master ~]# kubectl describe pod pod01 -n test
Name: pod01
Namespace: test
Priority: 0
Node: k8s-slave02/192.168.184.102
Start Time: Wed, 08 Jun 2022 21:43:47 +0800
Labels: app=pod01-label
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"labels":{"app":"pod01-label"},"name":"pod01","namespace":"test"},"spec":{"co...
Status: Running
IP: 10.244.2.3
IPs:
IP: 10.244.2.3
Containers:
nginx-container:
Container ID: docker://1994d2e990528ead9b5066be055a17f46748084f8f92bdb6379b4e7e7a0be664
Image: nginx:1.17
Image ID: docker-pullable://nginx@sha256:6fff55753e3b34e36e24e37039ee9eae1fe38a6420d8ae16ef37c92d1eb26699
Port:
Host Port:
State: Running
Started: Wed, 08 Jun 2022 21:43:48 +0800
Ready: True
Restart Count: 0
Environment:
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-wpxp2 (ro)
ubuntu-container:
Container ID: docker://040e054a760cbb99943f41c52cb362bd2177e1f8f5f438261fd5cb8fe6d3e664
Image: ubuntu:22.10
Image ID: docker-
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 56s default-scheduler Successfully assigned test/pod01 to k8s-slave02
Normal Pulled 55s kubelet, k8s-slave02 Container image " nginx:1.17" already present on machine
Normal Created 55s kubelet, k8s-slave02 Created container nginx-container
Normal Started 55s kubelet, k8s-slave02 Started container nginx-container
Normal Pulled 10s (x4 over 55s) kubelet, k8s-slave02 Container image "ubuntu:22.10" already present on machine
Normal Created 10s (x4 over 55s) kubelet, k8s-slave02 Created container ubuntu-container
Normal Started 10s (x4 over 55s) kubelet, k8s-slave02 Started container ubuntu-container
Warning BackOff 8s (x6 over 53s) kubelet, k8s-slave02 Back-off restarting failed container
我们发现Ubuntu容器启动失败了(Back-off restarting failed container),k8s系统采取了默认的重启策略。上面也可以看到Pod的RESTARTS为2,说明已经重启了2次。
imagePullPolicy(镜像拉取策略),kubernetes目前支持3种拉取策略:
镜像拉取策略注意点:
如果镜像tag指定为具体的版本号例如:nginx:1.17,默认策略是IfNotPresent。
如果镜像tag为latest(最终版本)例如:nginx:latest,默认策略是Always。
创建yaml文件
vim pod02.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test
---
apiVersion: v1
kind: Pod
metadata:
labels:
app: pod02-label
name: pod02
namespace: test
spec:
containers:
- image: nginx:1.17
name: nginx-container2
imagePullPolicy: Always
- image: ubuntu:22.10
name: ubuntu-container2
imagePullPolicy: IfNotPresent #写不写都是一样,默认就是这个模式
[root@k8s-master ~]# kubectl apply -f pod02.yaml
namespace/test created
pod/pod02 created
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 20s default-scheduler Successfully assigned test/pod02 to k8s-slave02
Normal Pulling 20s kubelet, k8s-slave02 Pulling image "nginx:1.17"
Normal Pulled 4s kubelet, k8s-slave02 Successfully pulled image "nginx:1.17"
Normal Created 4s kubelet, k8s-slave02 Created container nginx-container1
Normal Started 4s kubelet, k8s-slave02 Started container nginx-container1
Normal Pulled 2s (x2 over 4s) kubelet, k8s-slave02 Container image "ubuntu:22.10" already present on machine
Normal Created 2s (x2 over 4s) kubelet, k8s-slave02 Created container ubuntu-container1
Normal Started 2s (x2 over 3s) kubelet, k8s-slave02 Started container ubuntu-container1
Warning BackOff 0s (x2 over 1s) kubelet, k8s-slave02 Back-off restarting failed container
可以看到我们的nginx镜像是重新从dockerhub上面拉取,而Ubuntu由于我们本地有所以就会从本地拉取。
为什么在前面我们Ubuntu容器无法启动成功?
创建yaml文件
vim pod03.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test
---
apiVersion: v1
kind: Pod
metadata:
labels:
app: pod03-label
name: pod03
namespace: test
spec:
containers:
- image: nginx:1.17
name: nginx-container3
- image: ubuntu:22.10
name: ubuntu-container3
command: ["/bin/sh","-c","touch /tmp/timelog.txt;while true;do echo $(date +%T) >> /tmp/timelog.txt ;sleep 3;done;"]
[root@k8s-master ~]# kubectl apply -f pod03.yaml
namespace/test created
pod/pod03 created
格式:
kubectl exec -it pod的名称 -n 命名空间 --container=容器名称 /bin/sh
[root@k8s-master ~]# kubectl exec -it pod03 --container=ubuntu-container3 --namespace=test /bin/sh
# tail -f /tmp/timelog.txt
15:25:24
15:25:27
15:25:30
15:25:33
15:25:36
15:25:39
15:25:42
15:25:45
15:25:48
15:25:51
注意点:
如果command和args均没有写,那么用Dockerfile的配置。
如果command写了,但是args没有写,那么Dockerfile默认的配置会被忽略,执行注入的command。
如果command没有写,但是args写了,那么Dockerfile中配置的ENTRYPOINT命令会被执行,使用当前args的参数。
如果command和args都写了,那么Dockerfile中的配置会被忽略,执行command并追加上args参数。
作用如下:(不推荐使用)
创建yaml文件
vim pod04.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test
---
apiVersion: v1
kind: Pod
metadata:
labels:
app: pod04-label
name: pod04
namespace: test
spec:
containers:
- image: nginx:1.17
name: nginx-container4
- image: ubuntu:22.10
name: ubuntu-container4
env:
- name: "username"
value: "root"
- name: "password"
value: "123456"
command: ["/bin/sh","-c","touch /tmp/timelog.txt;while true;do echo $(date +%T) >> /tmp/timelog.txt ;sleep 3;done;"]
kubectl apply -f pod04.yaml
格式:
[root@k8s-master ~]# kubectl exec -it pod04 --container=ubuntu-container4 --namespace=test /bin/sh
# echo $username
root
# echo $password
123456
此种方式不推荐,推荐将这些配置单独存储在配置文件中。
格式(只展示常用的):
KIND: Pod
VERSION: v1
RESOURCE: ports <[]Object>
FIELDS:
name > # 端口名称,如果指定,必须保证name在pod中是唯一的,可以不指定。
containerPort > # 容器要监听的端口(0->65536)。
protocol > # 端口协议。必须是UDP、TCP或SCTP。默认为“TCP”
vim pod05.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test
---
apiVersion: v1
kind: Pod
metadata:
labels:
app: pod05-label
name: pod05
namespace: test
spec:
containers:
- image: nginx:1.17
name: nginx-container5
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
kubectl apply -f pod05.yaml
root@k8s-master ~]# kubectl get pods -n test -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod05 1/1 Running 0 11s 10.244.2.9 k8s-slave02 <none> <none>
[root@k8s-master ~]# curl 10.244.2.9:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
为什么kubernetes会出现一个资源配额机制?
资源配额:
[root@k8s-master ~]# kubectl explain pods.spec.containers.resources
KIND: Pod
VERSION: v1
RESOURCE: resources <Object>
DESCRIPTION:
Compute Resources required by this container. Cannot be updated. More info:
https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
ResourceRequirements describes the compute resource requirements.
FIELDS:
limits <map[string]string>
Limits describes the maximum amount of compute resources allowed. More
info:
https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
requests <map[string]string>
Requests describes the minimum amount of compute resources required. If
Requests is omitted for a container, it defaults to Limits if that is
explicitly specified, otherwise to an implementation-defined value. More
info:
https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
vim pod06.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test
---
apiVersion: v1
kind: Pod
metadata:
labels:
app: pod06-label
name: pod06
namespace: test
spec:
containers:
- image: nginx:1.17
name: nginx-container6
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
resources:
limits: #最高
cpu: "2"
memory: "30Mi"
requests: #最低
cpu: "1"
memory: "5Mi"
---
apiVersion: v1
kind: Service
metadata:
name: service06
namespace: test
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: pod06-label
type: NodePort
[root@k8s-master ~]# kubectl apply -f pod06.yaml
namespace/test created
pod/pod06 created
service/service06 created
如果资源达不到启动的要求时(启动需要资源大于requests设置的值时,会创建失败容器):
[root@k8s-master ~]# kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
pod06 0/1 CreateContainerError 0 15s
什么是Pod的生命周期?
Pod的生命周期过程有哪些:
在整个Pod的生命周期中,Pod会出现如下几种状态:
概述:初始化容器执行的优先级是最高的。说白了就是初始化容器全部运行完成之后,才会运行主容器(pod.spec.containers定义的容器)。
初始化容器的场景:
创建yaml文件
vim pod07.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test
---
apiVersion: v1
kind: Pod
metadata:
labels:
app: pod07-label
name: pod07
namespace: test
spec:
containers:
- image: nginx:1.17
name: nginx-container7
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
initContainers: # 初始化容器配置
- name: init-container01
image: ubuntu:22.10
command: ["sh","-c","sleep 3;"]
securityContext:
privileged: true # 使用特权模式运行容器
- name: init-container02
image: ubuntu:22.10
command: ["sh","-c","sleep 3;"]
[root@k8s-master ~]# kubectl get pods -n test -w
kubectl apply -f pod07.yaml
[root@k8s-master ~]# kubectl get pods -n test -w
NAME READY STATUS RESTARTS AGE
pod07 0/1 Pending 0 0s
pod07 0/1 Pending 0 1s
pod07 0/1 Init:0/2 0 1s
pod07 0/1 Init:0/2 0 2s
pod07 0/1 Init:1/2 0 5s
pod07 0/1 Init:1/2 0 7s
pod07 0/1 PodInitializing 0 10s
pod07 1/1 Running 0 11s
[root@k8s-master ~]# kubectl describe pod pod07 -n test
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 18s default-scheduler Successfully assigned test/pod07 to k8s-slave02
Normal Pulled 18s kubelet, k8s-slave02 Container image "ubuntu:22.10" already present on machine
Normal Created 18s kubelet, k8s-slave02 Created container init-container01
Normal Started 18s kubelet, k8s-slave02 Started container init-container01
Normal Pulled 14s kubelet, k8s-slave02 Container image "ubuntu:22.10" already present on machine
Normal Created 13s kubelet, k8s-slave02 Created container init-container02
Normal Started 13s kubelet, k8s-slave02 Started container init-container02
Normal Pulled 9s kubelet, k8s-slave02 Container image "nginx:1.17" already present on machine
Normal Created 9s kubelet, k8s-slave02 Created container nginx-container7
Normal Started 9s kubelet, k8s-slave02 Started container nginx-container7
可以看到是先执行init-container01再到init-container02最后到主容器。
[root@k8s-master ~]# kubectl explain pods.spec.containers.lifecycle
KIND: Pod
VERSION: v1
RESOURCE: lifecycle <Object>
DESCRIPTION:
Actions that the management system should take in response to container
lifecycle events. Cannot be updated.
Lifecycle describes actions that the management system should take in
response to container lifecycle events. For the PostStart and PreStop
lifecycle handlers, management of the container blocks until the action is
complete, unless the container process fails, in which case the handler is
aborted.
FIELDS:
postStart <Object>
PostStart is called immediately after a container is created. If the
handler fails, the container is terminated and restarted according to its
restart policy. Other management of the container blocks until the hook
completes. More info:
https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks
preStop <Object>
PreStop is called immediately before a container is terminated due to an
API request or management event such as liveness/startup probe failure,
preemption, resource contention, etc. The handler is not called if the
container crashes or exits. The reason for termination is passed to the
handler. The Pod's termination grace period countdown begins before the
PreStop hooked is executed. Regardless of the outcome of the handler, the
container will eventually terminate within the Pod's termination grace
period. Other management of the container blocks until the hook completes
or until the termination grace period is reached. More info:
https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks
posrStart
……
lifecycle:
postStart:
exec:
command:
- cat
- /tmp/hello.txt
……
……
lifecycle:
postStart:
tcpSocket:
port: 80
……
……
lifecycle:
postStart:
httpGet:
path: / #URI地址
port: 80 #端口号
host: 192.168.184.100 #主机地址
scheme: HTTP #支持的协议,http或者https
……
preStop
……
lifecycle:
preStop:
exec:
command:
- cat
- /tmp/hello.txt
……
……
lifecycle:
preStop:
tcpSocket:
port: 80
……
……
lifecycle:
preStop:
httpGet:
path: / #URI地址
port: 80 #端口号
host: 192.168.184.100 #主机地址
scheme: HTTP #支持的协议,http或者https
……
案例:
vim pod08.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test
---
apiVersion: v1
kind: Pod
metadata:
labels:
app: pod08-label
name: pod08
namespace: test
spec:
containers:
- image: nginx:1.17
name: nginx-container8
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
lifecycle: #配置生命周期
postStart: # 容器创建之后执行,如果失败会重启容器
exec: # 在容器启动的时候,执行一条命令,修改掉Nginx的首页内容
command: ["/bin/sh","-c","echo lifecycle-postStart ... > /usr/share/nginx/html/index.html"]
preStop: # 容器终止之前执行,执行完成之后容器将成功终止,在其完成之前会阻塞删除容器的操作
exec: # 在容器停止之前停止Nginx的服务
command: ["/usr/sbin/nginx","-s","quit"]
kubectl apply -f pod08.yaml
[root@k8s-master ~]# kubectl get pods -n test -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod08 1/1 Running 0 2s 10.244.1.12 k8s-slave01 <none> <none>
[root@k8s-master ~]# curl 10.244.1.12:80
lifecycle-postStart ...
livenessProbe:
[root@k8s-master ~]# kubectl explain pods.spec.containers.livenessProbe
KIND: Pod
VERSION: v1
RESOURCE: livenessProbe <Object>
DESCRIPTION:
Periodic probe of container liveness. Container will be restarted if the
probe fails. Cannot be updated. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
Probe describes a health check to be performed against a container to
determine whether it is alive or ready to receive traffic.
FIELDS:
exec <Object>
One and only one of the following should be specified. Exec specifies the
action to take.
failureThreshold <integer>
Minimum consecutive failures for the probe to be considered failed after
having succeeded. Defaults to 3. Minimum value is 1.
httpGet <Object>
HTTPGet specifies the http request to perform.
initialDelaySeconds <integer>
Number of seconds after the container has started before liveness probes
are initiated. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
periodSeconds <integer>
How often (in seconds) to perform the probe. Default to 10 seconds. Minimum
value is 1.
successThreshold <integer>
Minimum consecutive successes for the probe to be considered successful
after having failed. Defaults to 1. Must be 1 for liveness and startup.
Minimum value is 1.
tcpSocket <Object>
TCPSocket specifies an action involving a TCP port. TCP hooks not yet
supported
timeoutSeconds <integer>
Number of seconds after which the probe times out. Defaults to 1 second.
Minimum value is 1. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
……
livenessProbe:
exec:
command:
- cat
- /tmp/probe.txt
……
[root@k8s-master ~]# kubectl explain pods.spec.containers.livenessProbe.tcpSocket
KIND: Pod
VERSION: v1
RESOURCE: tcpSocket <Object>
DESCRIPTION:
TCPSocket specifies an action involving a TCP port. TCP hooks not yet
supported
TCPSocketAction describes an action based on opening a socket
FIELDS:
host <string>
Optional: Host name to connect to, defaults to the pod IP.
port <string> -required-
Number or name of the port to access on the container. Number must be in
the range 1 to 65535. Name must be an IANA_SVC_NAME.
可以看到host默认是Pod的IP地址。
……
livenessProbe:
tcpSocket:
port: 8080
……
[root@k8s-master ~]# kubectl explain pods.spec.containers.livenessProbe.httpGet
KIND: Pod
VERSION: v1
RESOURCE: httpGet <Object>
DESCRIPTION:
HTTPGet specifies the http request to perform.
HTTPGetAction describes an action based on HTTP Get requests.
FIELDS:
host <string>
Host name to connect to, defaults to the pod IP. You probably want to set
"Host" in httpHeaders instead.
httpHeaders <[]Object>
Custom headers to set in the request. HTTP allows repeated headers.
path <string>
Path to access on the HTTP server.
port <string> -required-
Name or number of the port to access on the container. Number must be in
the range 1 to 65535. Name must be an IANA_SVC_NAME.
scheme <string>
Scheme to use for connecting to the host. Defaults to HTTP.
……
livenessProbe:
httpGet:
path: / #URI地址
port: 80 #端口号
host: 192.168.184.100 #主机地址
scheme: HTTP #支持的协议,http或者https
……
readinessProbe:
[root@k8s-master ~]# kubectl explain pods.spec.containers.readinessProbe
KIND: Pod
VERSION: v1
RESOURCE: readinessProbe <Object>
DESCRIPTION:
Periodic probe of container service readiness. Container will be removed
from service endpoints if the probe fails. Cannot be updated. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
Probe describes a health check to be performed against a container to
determine whether it is alive or ready to receive traffic.
FIELDS:
exec <Object>
One and only one of the following should be specified. Exec specifies the
action to take.
failureThreshold <integer>
Minimum consecutive failures for the probe to be considered failed after
having succeeded. Defaults to 3. Minimum value is 1.
httpGet <Object>
HTTPGet specifies the http request to perform.
initialDelaySeconds <integer>
Number of seconds after the container has started before liveness probes
are initiated. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
periodSeconds <integer>
How often (in seconds) to perform the probe. Default to 10 seconds. Minimum
value is 1.
successThreshold <integer>
Minimum consecutive successes for the probe to be considered successful
after having failed. Defaults to 1. Must be 1 for liveness and startup.
Minimum value is 1.
tcpSocket <Object>
TCPSocket specifies an action involving a TCP port. TCP hooks not yet
supported
timeoutSeconds <integer>
Number of seconds after which the probe times out. Defaults to 1 second.
Minimum value is 1. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes
……
readinessProbe:
exec:
command:
- cat
- /tmp/probe.txt
……
……
readinessProbe:
tcpSocket:
port: 8080
……
……
readinessProbe:
httpGet:
path: / #URI地址
port: 80 #端口号
host: 192.168.184.100 #主机地址
scheme: HTTP #支持的协议,http或者https
……
方式1:exec案例
vim pod09.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test
---
apiVersion: v1
kind: Pod
metadata:
labels:
app: pod09-label
name: pod09
namespace: test
spec:
containers:
- image: nginx:1.17
name: nginx-container9
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
livenessProbe:
exec:
command: ["/bin/sh",'-c','cat /tmp/probe.txt']
kubectl apply -f pod09.yaml
[root@k8s-master ~]# kubectl describe pods pod09 -n test
Name: pod09
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 43s default-scheduler Successfully assigned test/pod09 to k8s-slave02
Normal Pulled 17s (x2 over 43s) kubelet, k8s-slave02 Container image "nginx:1.17" already present on machine
Normal Created 17s (x2 over 43s) kubelet, k8s-slave02 Created container nginx-container9
Normal Started 17s (x2 over 42s) kubelet, k8s-slave02 Started container nginx-container9
Normal Killing 17s kubelet, k8s-slave02 Container nginx-container9 failed liveness probe, will be restarted
Warning Unhealthy 7s (x4 over 37s) kubelet, k8s-slave02 Liveness probe failed: cat: /tmp/probe.txt: No such file or directory
可以看到下面的Liveness probe failed: cat: /tmp/probe.txt: No such file or directory。
[root@k8s-master ~]# kubectl get pods -n test -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod09 1/1 Running 3 101s 10.244.2.24 k8s-slave02 <none> <none>
可以看到RESTARTS为3,说明Pod被重启了3次。
方式2:tcpSocket案例
vim pod10.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test
---
apiVersion: v1
kind: Pod
metadata:
labels:
app: pod10-label
name: pod10
namespace: test
spec:
containers:
- image: nginx:1.17
name: nginx-container10
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
livenessProbe:
tcpSocket: #本质上就是访问:Pod的IP:8081
port: 8081
kubectl apply -f pod10.yaml
[root@k8s-master ~]# kubectl describe pod pod10 -n test
Name: pod10
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 19s default-scheduler Successfully assigned test/pod10 to k8s-slave01
Normal Pulled 18s kubelet, k8s-slave01 Container image "nginx:1.17" already present on machine
Normal Created 18s kubelet, k8s-slave01 Created container nginx-container10
Normal Started 18s kubelet, k8s-slave01 Started container nginx-container10
Warning Unhealthy 5s (x2 over 15s) kubelet, k8s-slave01 Liveness probe failed: dial tcp 10.244.1.13:8081: connect: connection refused
可以看到下面的Liveness probe failed: dial tcp 10.244.1.13:8081: connect: connection refused。
方式3:httpGet案例
vim pod11.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test
---
apiVersion: v1
kind: Pod
metadata:
labels:
app: pod11-label
name: pod11
namespace: test
spec:
containers:
- image: nginx:1.17
name: nginx-container11
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
livenessProbe:
httpGet: # 下面的httpGet本质上就是去请求http://192.168.184.101:80/probe
host: 192.168.184.101
path: /probe
port: 80
scheme: HTTP
kubectl apply -f pod11.yaml
和上面测试方式一样。
livenessProbes和readinessProbes下一级可配置的选项。
exec
tcpSocket
httpGet
上面三个已经讲解过了
initialDelaySeconds 容器启动后等待多少秒执行第一次探测
timeoutSeconds 探测超时时间。默认1秒,最小1秒
periodSeconds 执行探测的频率。默认是10秒,最小1秒
failureThreshold 连续探测失败多少次才被认定为失败。默认是3。最小值是1
successThreshold 连续探测成功多少次才被认定为成功。默认是1
[root@k8s-master ~]# kubectl explain pods.spec
KIND: Pod
FIELDS:
restartPolicy <string>
Restart policy for all containers within the pod. One of Always, OnFailure,
Never. Default to Always. More info:
https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy
vim pod12.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test
---
apiVersion: v1
kind: Pod
metadata:
labels:
app: pod12-label
name: pod12
namespace: test
spec:
containers:
- image: nginx:1.17
name: nginx-container12
ports:
- name: nginx-port
containerPort: 80
protocol: TCP
livenessProbe:
httpGet: # 下面的httpGet本质上就是去请求http://192.168.184.101:80/probe
host: 192.168.184.101
path: /probe
port: 80
scheme: HTTP
restartPolicy: Never #永不重启Pod
kubectl apply -f pod12.yaml
[root@k8s-master ~]# kubectl describe pod pod12 -n test
Name: pod12
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 42s default-scheduler Successfully assigned test/pod12 to k8s-slave02
Normal Pulled 41s kubelet, k8s-slave02 Container image "nginx:1.17" already present on machine
Normal Created 41s kubelet, k8s-slave02 Created container nginx-container12
Normal Started 41s kubelet, k8s-slave02 Started container nginx-container12
Warning Unhealthy 10s (x3 over 30s) kubelet, k8s-slave02 Liveness probe failed: Get http://192.168.184.101:80/probe: dial tcp 192.168.184.101:80: connect: connection refused
Normal Killing 10s kubelet, k8s-slave02 Stopping container nginx-container12
可以看到最下面的Stopping container nginx-container12,说明Pod没有发生重启。
❤️本章结束,我们下一章见❤️