博文大纲:
一、Namespace
二、Pod详解
三、Pod的健康检查
本次博文主要介绍pod,不过在介绍pod之前需简单介绍以下Namespace!
Namespace是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的pods, services, replication controllers和deployments等都是属于某一个namespace的(默认是default),而node, persistentVolumes等则不属于任何namespace。
Namespace常用来隔离不同的用户,比如Kubernetes自带的服务一般运行在kube-system namespace中。
Kubernetes中的名称空间与docker中的名称空间不同。K8s中的名称空间只是做了一个逻辑上的隔离。
[root@master ~]# kubectl get namespaces
//查看K8s中存在的名称空间
NAME STATUS AGE
default Active 6d21h
kube-node-lease Active 6d21h
kube-public Active 6d21h
kube-system Active 6d21h
//namespace包含两种状态”Active”和”Terminating”。在namespace删除过程中,namespace状态被设置成”Terminating”。
[root@master ~]# kubectl describe namespaces default
//查看default名称空间的详细信息
[root@master ~]# kubectl get pod --namespace=default
[root@master ~]# kubectl get pod -n default
//查看default名称空间中的pod资源(两者都可以)
[root@master ~]# kubectl get pod
//如果不指定,则默认也是查看default名称空间中的资源
使用命令行创建
[root@master ~]# kubectl create namespace beijing
//创建一个名称空间,名称为beijing
//创建完成后,可以通过“kubectl get namespaces”命令查看到
[root@master ~]# kubectl delete namespace beijing
//删除新创建的名称空间
使用yaml文件创建
[root@master ~]# vim namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test
[root@master ~]# kubectl apply -f namespace.yaml
[root@master ~]# kubectl delete -f namespace.yaml
注意:
(1)删除一个名称空间时会自动删除所有属于该namespace的资源;
(2)default和kube-system名称空间不可以被删除;
(3)namespace资源对象仅用于资源对象的隔离,并不能隔绝不同名称空间的Pod之间的通信。如果需要隔离Pod之间的通信可以使用网络策略资源这项功能;
名称空间就先简单介绍这么多,如果以后有需要会更新的!
在Kubernetes中,最小的管理元素不是一个个独立的容器,而是Pod,Pod是管理,创建,计划的最小单元.
一个Pod就相当于一个共享context的配置组,在同一个context下,应用可能还会有独立的cgroup隔离机制,一个Pod是一个容器环境下的“逻辑主机”,它可能包含一个或者多个紧密相连的应用,这些应用可能是在同一个物理主机或虚拟机上。
Pod 的context可以理解成多个linux命名空间的联合:
- PID 命名空间(同一个Pod中应用可以看到其它进程);
- 网络 命名空间(同一个Pod的中的应用对相同的IP地址和端口有权限);
- IPC 命名空间(同一个Pod中的应用可以通过VPC或者POSIX进行通信);
- UTS 命名空间(同一个Pod中的应用共享一个主机名称);
Pod和相互独立的容器一样,Pod是一种相对短暂的存在,而不是持久存在的,正如我们在Pod的生命周期中提到的,Pod被安排到节点上,并且保持在这个节点上直到被终止(根据重启的设定)或者被删除,当一个节点死掉之后,节点上运行的所有Pod均会被删除。
Pod中的应用均使用相同的网络命称空间及端口,并且可以通过localhost发现并沟通其他应用,每个Pod都有一个扁平化的网络命称空间下IP地址,它是Pod可以和其他的物理机及其他的容器进行无障碍通信的关键。
除了定义了在Pod中运行的应用之外,Pod还定义了一系列的共享磁盘,磁盘让这些数据在容器重启的时候不会丢失并且可以将这些数据在Pod中的应用进行共享。
Pod通过提供一个高层次抽象而不是底层的接口简化了应用的部署及管理,Pod 作为最小的部署及管理单位,位置管理,拷贝复制,资源共享,依赖关系都是自动处理的。
1)透明:Pod中的容器对基础设施可见,使得基础设施可以给容器提供服务,例如线程管理和资源监控,这为用户提供很多便利;
2)解耦:解除软件依赖关系,独立的容器可以独立的进行重建和重新发布,Kubernetes 甚至会在将来支持独立容器的实时更新;
3)易用:用户不需要运行自己的线程管理器,也不需要关心程序的信号以及异常结束码等;
4)高效:因为基础设施承载了更多的责任,所以容器可以更加高效;
总之就是一句话:如果说运行多个服务,其中一个服务出现问题,那么就需重启整个Pod,与docker这种容器化的初衷是违背的!
创建pod时镜像获取策略:
- always:(默认使用)镜像标签为latest或镜像不存在时,总是会从指定的仓库中获取镜像;
- IfNotPresent:仅当本地镜像不存在时才会从目标仓库中下载;
- Never:禁止从仓库中下载镜像,即只使用本地镜像;
三种状态,在创建时可以任意指定!
[root@master ~]# kubectl create namespace test
//创建一个名为test的名称空间(不是必须的)
[root@master ~]# vim pod.yaml
kind: Pod
apiVersion: v1
metadata:
name: test-pod
namespace: test //指定其所在的名称空间
spec:
containers:
- name: test-app
image: 192.168.1.1:5000/httpd:v1
[root@master ~]# kubectl apply -f pod.yaml
//根据yaml文件生成所需的Pod
[root@master yaml]# kubectl get pod -n test
//需要指定名称空间进行查看(否则默认情况下在default名称空间下查找)
NAME READY STATUS RESTARTS AGE
test-pod 1/1 Running 0 11s
注意:对于标签为latest或者不存在时,其默认的下载策略为Always,而对于其他标签的镜像,默认策略为IfNotPresent。
[root@master ~]# vim pod.yaml
kind: Pod
apiVersion: v1
metadata:
name: test-pod
namespace: test
labels:
name: test-web
spec:
containers:
- name: test-app
image: 192.168.1.1:5000/httpd:v1
imagePullPolicy: IfNotPresent //指定pod镜像的策略
ports:
- protocol: TCP
containerPort: 80 //只是一个声明,没有任何作用
[root@master ~]# kubectl delete -f pod.yaml
//需要将原本的删除否则无法进行下载
[root@master ~]# kubectl apply -f pod.yaml
//重新指定yaml文件进行下载
创建一个service进行关联
[root@master ~]# vim pod-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: test-svc
namespace: test
spec:
selector:
name: test-web
ports:
- port: 80
targetPort: 80 //注意这个端口时生效的,即使是错误的
[root@master ~]# kubectl apply -f pod-svc.yaml
[root@master ~]# kubectl get svc -n test
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
test-svc ClusterIP 10.108.187.128 80/TCP 35s
[root@master ~]# curl 10.108.187.128 //访问测试
lvzhenjiang
如果访问不到,
[root@master ~]# kubectl describe svc -n test pod-svc
//查看service的详细信息,找到Endpoints字段即可发现
Pod的重启策略:
- Always:(默认情况下使用)只要Pod对象终止就将其重启;
- OnFailure:仅在Pod对象出现错误时才将其重启;
- Never:从不重启;
三种状态,在创建时可以任意指定!
通过一个小案例进行查看:
[root@master ~]# vim cache.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
test: healcheck
name: healcheck
spec:
restartPolicy: OnFailure //重启策略
containers:
- name: healcheck
image: busybox:latest
args: //启动pod时执行的命令
- /bin/sh
- -c
- sleep 10; exit 1
[root@master ~]# kubectl apply -f cache.yaml
//生成pod
[root@master ~]# kubectl get pod -w | grep healcheck
//动态检测pod的状态
healcheck 0/1 CrashLoopBackOff 1 35s
healcheck 1/1 Running 2 36s
healcheck 0/1 Error 2 46s
//此时可以看出指定的重启策略已经生效
为了确保容器在部署后确实处于正常运行状态,Kubernetes提供了两种探针来探测容器的状态:
- LivenessProbe: 存活探针,指容器是否正在运行。如果检测失败,则kubelet会杀死容器,并且容器会受重启策略的影响决定是否需要重启;
- ReadnessProbe: 就绪探针,指容器是否准备就绪,接受服务请求。如果就绪探针失败,端点控制器将从与Pod匹配的所有service的端点中移除该Pod的IP 地址;
[root@master yaml]# cat liveness.yaml
kind: Pod
apiVersion: v1
metadata:
name: liveness
labels:
test: liveness
spec:
restartPolicy: OnFailure
containers:
- name: liveness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/test; sleep 60; rm -rf /tmp/test; sleep 300
livenessProbe:
exec:
command:
- cat
- /tmp/test
initialDelaySeconds: 10
periodSeconds: 5
上述yaml文件中针对/tmp/test这个文件进行指定了健康检查策略为 livenessProbe,并且指定了重启策略为OnFailure。这样容器可以正常的运行,但是总是会重启。
如图:
配置几乎是一模一样的,只是健康检测的方式更换一下,如下:
[root@master yaml]# cat readiness.yaml
kind: Pod
apiVersion: v1
metadata:
name: readiness
labels:
test: readiness
spec:
restartPolicy: OnFailure
containers:
- name: readiness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/test; sleep 60; rm -rf /tmp/test; sleep 300
readinessProbe:
exec:
command:
- cat
- /tmp/test
initialDelaySeconds: 10
periodSeconds: 5
那么此时运行的pod状态如图:
查看的效果可能不是很明显,使用以下方法,便可查看具体的效果。
[root@master yaml]# cat hcscal.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: web
spec:
replicas: 3
template:
metadata:
labels:
run: web
spec:
containers:
- name: web
image: httpd
ports:
- containerPort: 80
readinessProbe:
httpGet:
scheme: HTTP
path: /healthy
port: 80
initialDelaySeconds: 10
periodSeconds: 5
---
kind: Service
apiVersion: v1
metadata:
name: web-svc
spec:
type: NodePort
selector:
run: web
ports:
- protocol: TCP
port: 90
targetPort: 80
nodePort: 30321
创建一个deployment资源、一个Service资源并且相互之间进行关联。
执行的结果如图:
ReadinessProbe探针的使用场景livenessProbe稍有不同,有的时候应用程序可能暂时无法接受请求,比如Pod已经Running了,但是容器内应用程序尚未启动成功,在这种情况下,如果没有ReadinessProbe,则Kubernetes认为它可以处理请求了,然而此时,我们知道程序还没启动成功是不能接收用户请求的,所以不希望kubernetes把请求调度给它,则使用ReadinessProbe探针。
每种探针都支持以下三种探测方式:
- exec:通过执行命令来检查服务是否正常,针对复杂检测或无HTTP接口的服务,命令返回值为0则表示容器健康;
- httpGet:通过发送http请求检查服务是否正常,返回200-399状态码则表明容器健康;
- tcpSocket:通过容器的IP和Port执行TCP检查,如果能够建立TCP连接,则表明容器健康;
(1)liveness和readiness是两种健康检查机制,如果不特意配置,K8s将两种探测采用相同的默认行为,即通过判断容器启动进程的返回值是否为零,来判断探测是否成功;
(2)两种探测配置完全一样。不同之处在于探测失败后的行为:
liveness探测是根据Pod重启策略操作容器,大多数是重启容器;
readiness则是将容器设置为不可用,不接受service转发的请求;
(3)两种探测方法可以独立存在,也可同时使用;比如使用liveness判断容器是否需要重启实现自愈;用readiness判断容器是否已经准备好对外提供服务。
主要应用是在scale(扩容、缩容)、更新(升级)过程中使用。
下面通过一个简单的小实验进行验证:
[root@master yaml]# cat app.v1.yaml
//版本1的yaml文件创建10个副本使用busybox镜像,如下
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: app
spec:
replicas: 10
template:
metadata:
labels:
run: app
spec:
containers:
- name: app
image: busybox
args:
- /bin/sh
- -c
- sleep 10; touch /tmp/healthy; sleep 3000
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 5
[root@master yaml]# kubectl apply -f app.v1.yaml --record
//使用yaml文件生成相应的资源,并且记录历史版本信息
查看pod信息,如图:
[root@master yaml]# cat app.v2.yaml
//版本2的yaml文件创建10个副本使用busybox镜像
//并模拟(代码中有问题,并进行升级),如下:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: app
spec:
strategy:
rollingUpdate:
maxSurge: 2
maxUnavailable: 2
replicas: 10
template:
metadata:
labels:
run: app
spec:
containers:
- name: app
image: busybox
args:
- /bin/sh
- -c
- sleep 3000
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 10
periodSeconds: 5
//maxSurge:此参数控制滚动更新过程中,副本总数超过预期数的值,可以是整数,也可以是百分比。默认是1
maxUnavailable:不可用Pod的值,默认为1,可以是整数,也可以是百分比
[root@master yaml]# kubectl apply -f app.v2.yamll --record
查看pod信息,如图:
[root@master yaml]# cat app.v3.yaml
//版本2的yaml文件创建10个副本使用busybox镜像
//并且不使用健康检查机制,如下:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: app
spec:
replicas: 10
template:
metadata:
labels:
run: app
spec:
containers:
- name: app
image: busybox
args:
- /bin/sh
- -c
- sleep 3000
[root@master yaml]# kubectl apply -f app.v3.yamll --record
再次查看pod的状态信息,如图:
[root@master yaml]# kubectl rollout history deployment app
//查看记录的历史版本
[root@master yaml]# kubectl rollout undo deployment app --to-revision=1
//回滚到可用的版本
再次查看pod的运行状态,如图:
——————————————本文到此为止,感谢阅读——————————————