kubernetes基础--pod
一、kubernetes架构
上图为kubernete官方网站提供的架构图,该图中,主要涉及多个组件,各个组件功能如下:
- kube-apiserver:kubernetes的api接口服务,集群中所有的组件都通过该服务进行相关操作,如创建pod、创建svc等。kube-apiserver部署在控制平面节点。
- kube-controller-manager:kubernetes控制器,该服务是多组控制器的集合,比如实现副本功能的ReplicaController、用于节点管理的NodeController以及用于服务账号管理的ServiceAccount controller等。
- kube-scheduler:kubernetes的调度服务,需要创建pod时,kube-scheduler会根据算法对节点的资源或者根据用户配置的策略选择节点
- etcd:kubernete所使用的数据库。该数据库只有kube-apiserver操作,其他服务都通过kube-apiserver来完成数据的读取和写入。
- kubelet:kubernetes用来管理容器的服务,以确认容器处于正常运行的健康状态。
- CRI:container runtime interface,由kubelet管理的容器运行时。kubernetes支持多个容器运行时,如containerd、CRI-O等
- kube-proxy:kubernetes代理服务,可以为kubernetes的服务提供网络代理和负载均衡功能。
上图没有的:
- CNI:container network interface,容器网络的规范和接口,由kubelet管理。CNI用于实现容器集群的网络管理,解决容器网络的复杂性问题。它是kubernetes的重要组成部分,是构建完整集群的重要一环。常用的CNI插件有calico、flannel以及cilium等。
- CSI:container storage interface,存储接口,由kubelet管理。CSI用于对接第三方存储,以便满足实际环境下各种存储需求,它也是kubernetes集群中重要组成部分。
- coredns:kubernetes中,默认的域名解析服务。容器运行可能会随时重启,此时ip就会发生变化。使用DNS来可以很好的应对这种情况。
其他重要的kubernetes add-ons:
ingress controller:ingress是k8s集群外部访问k8s内部服务资源的重要实现,本质上可以认为是一个代理服务,把内网的服务代理到外网方便外网访问。ingress controller是实现ingress资源的控制器
metrics server:节点、容器等指标的数据的收集服务,便于人们了解容器和节点的资源使用情况或者健康状态等。比如使用kubectl top命令来获取节点或pod的资源使用情况就需要metrics server服务。
监控服务:如prometheus。metrics server无法保存数据,部署外部监控系统是一个很好解决方案。
日志集中存储插件:如ELK或PLG。节点数量过多或容器数量过多时,集中日志可以便于查询以及故障处理等。PLG是promtail+loki+grafana的缩写,是轻量级的日志集中存储方案。
负载均衡插件:metalLB或者openELB等,他们都是适用于非云端k8s负载均衡的实现。LoadBalancer是service资源的一种特殊类型,可以直接对外暴露service访问接口,不需要通过nodePort或者ingress等资源的介入。
kubernetes中,存在各种各样资源概念,其中的核心,便是pod。pod是一组容器的集合,是k8s的最小的可部署的计算单元。pod的运行,可以通过kubectl命令行创建,也可以使用yaml文件运行。在运行过程中,可以实现很多配置,以保证pod或者集群的稳定运行。比如探活、可用、内存以及cpu的请求和限制、副本数、标签等。
本节,主要学习整理pod的部分配置。上面用来完善一下k8s架构方面的认识。
二、pod资源使用示例
这里直接运行一个示例,后面再展开讲示例的配置。这个示例用于运行一个mysql和wordpress,yaml如下:
apiVersion: v1
kind: Pod
metadata:
name: wordpressmysql
namespace: default
spec:
containers:
- name: mysql
image: mysql:8.0
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: "UIzo_0920984+45"
- name: MYSQL_USER
value: "test"
- name: MYSQL_PASSWORD
value: "Teac-92094+092"
- name: MYSQL_DATABASE
value: "test"
ports:
- name: mysql
containerPort: 3306
resources:
requests:
memory: "1024Mi"
cpu: "200m"
limits:
memory: "1024Mi"
cpu: "400m"
startupProbe:
tcpSocket:
port: mysql
initialDelaySeconds: 20
failureThreshold: 3
periodSeconds: 5
livenessProbe:
tcpSocket:
port: mysql
periodSeconds: 5
initialDelaySeconds: 5
readinessProbe:
exec:
command: ["sh", "-c", "mysql -u$(MYSQL_USER) -p$(MYSQL_PASSWORD) -e 'SELECT 1'"]
initialDelaySeconds: 5
timeoutSeconds: 1
periodSeconds: 5
- name: wordpress
image: wordpress
imagePullPolicy: IfNotPresent
env:
- name: WORDPRESS_DB_HOST
value: "127.0.0.1"
- name: WORDPRESS_DB_USER
value: "test"
- name: WORDPRESS_DB_PASSWORD
value: "Teac-92094+092"
- name: WORDPRESS_DB_NAME
value: "test"
resources:
requests:
memory: "1024Mi"
cpu: "200m"
limits:
memory: "1024Mi"
cpu: "400m"
startupProbe:
tcpSocket:
port: 80
initialDelaySeconds: 20
failureThreshold: 3
periodSeconds: 5
livenessProbe:
httpGet:
path: '/readme.html'
port: 80
scheme: HTTP
periodSeconds: 5
initialDelaySeconds: 5
readinessProbe:
httpGet:
path: '/readme.html'
port: 80
scheme: HTTP
initialDelaySeconds: 5
timeoutSeconds: 1
periodSeconds: 5
上面的内容保存成yaml文件,如wordpress.yaml。然后使用kubectl apply -f ./wordpress.yaml
命令来运行它,运行结果如下:
其中,STATUS列表示运行状态,Running表示正常的运行状态。STATUS列还有其他比较常见的状态,如下:
- Pending:正在调度。如果一直pending,那可能是集群没有满足运行要求的节点。一般通过kubectl describe命令可以很好的了解Pending的原因。
- ImagePullBackOff:表示镜像下载失败。可能镜像名配置错误,或者网络故障等。
- Error:容器启动过程发生错误。一般是容器启动命令、参数配置等错误导致。
- CrashLoopBackOff:表示pod发生错误,正在重启。
- Completed:运行完成,进程已经终止。
- Terminating:正在删除。如果时间太久,则需要借助强制删除的手段。如借助
--grace-period=0 --force
指令快速删除pod,或者删除finalizers字段来实现删除卡在terminating状态的namespace等。 - Evicted:表示该pod被节点驱逐。
- Unkown: 未知异常。可以查看节点状态信息是否节点异常导致。
除了通过kubectl get pods查看pod的运行状态外,还可以通过kubectl describe获取pod的详细信息,或者使用kubectl logs获取pod中容器的日志等。
#查看pods,可以通过-n 指定特定namespace的名称,默认是default;通过-o 指定显示的格式
kubectl get pods [-n NAMESPACE] [-o yaml|json|wide......]
#查看pod的详细状态
kubectl describe -f FILENAME
kubectl describe pods POD [options]
#查看pod的日志
kubectl logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER] [options]
查看详细信息,这里可以看到启动过程。如果出现异常,“Message”列往往能提供比较大的帮助。
查看日志:
三、pod资源文件解析
从上面的示例中,我们可以提取重要的5个模块。如下所示:
apiVersion: v1 #指定api所属群组及版本
kind: Pod #指定资源类别
metadata: #资源元数据信息
name: example
namespace: default
....
spec: #资源期望状态,由用户定义
....
status: #资源运行状态,由k8s生成
....
1、apiVersion
kubernetes的中,资源的操作都通过apiserver来完成。kube-apiserver存在各种各样的api,不同的api也有不同的版本,比如beta、alpha等。apiVersion字段的构成,一般是<apiGroup>/<version>,即<所属群组>/<api版本>。kubernetes中的所有支持的apiVersion可以通过命令kubectl api-versions
来查询。
如上图所示,这里列出了目前我部署的集群中,所有的apiVersion信息。上图中,没有apiGroup的v1是核心群组,该群组的资源皆是k8s的核心资源,如namespace、services、pods等。
2、kind
kind字段定义apiVersion中所使用的资源类型。资源类型相关命令如下:
kubectl api-resources --api-group='<群组名>' #其中核心群组为空
#相关资源的使用示例可以通过以下命令获取帮助信息
kubectl expain <resource_name>[.<field_name>.<field_name>.. ]
#示例:查询pod的资源的配置帮助
kubectl explain pod
#示例:查询pod的资源中metadata的配置帮助
kubectl explain pod.metadata
查询核心api资源群组所拥有的资源信息:
查询pods的配置帮助信息:
每个字段的详细配置,需要加在资源类型后面进行查询,子字段名加在父字段后面,如kubectl explain pod.metadata.labels
3、metadata
metadata字段用来定义资源的元数据。常用的元数据主要有:
- name:资源名称
- namespace:资源所属命名空间
- labels:资源的标签
- annotations:注解,说明。有时候,服务会通过该项来完成配置的修改。
下图中,我们创建的wordpress中的metadata信息。这里面,除了name和namespace是我们自己定义的外,其他的都是k8s自己生成的。
这个示例中,我们没有使用labels。不过,其实labels是非常重要的配置项,实际中会经常用到。
4、spec和status
spec是定义资源的期望结果,status字段,则由k8s自动生成,表明资源的实际运行结果。我们只需要定义spec即可。
spec设计较多配置,再起一节。
三、pod.spec
spec字段中,有很多配置项,这里以上面的示例做出说明。以后再扩展,整理其他字段信息。
spec:
#定义要运行的容器信息
containers:
#一个pod可以运行多个容器,每个容器都有一个格式对齐的‘-’标识
#name表示这个容器的名称
- name: mysql
#image表示容器的镜像
image: mysql:8.0
#这里指定下载策略,其他还有Always和Never两种类型
imagePullPolicy: IfNotPresent
#定义容器所使用的环境变量
env:
......
#可以在这里列出要暴露的端口
ports:
......
#这里配置的是资源的请求和限制
resources:
......
#启动探测
startupProbe:
......
#存活探测
livenessProbe:
......
#就绪探测
readinessProbe:
......
下面,整理以下env、resources、startupProbe、livenessProbe以及readinessProbe的配置信息。
1、env
容器构建时,往往会定义很多环境变量,便于实际运行时,对容器的服务进行配置。k8s中,使用env字段来完成环境变量的传递和配置。env的配置,有多种方式,如下所示:
env:
#1)获取pod信息作为环境变量
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
#2)定义键值对来传递环境变量
- name: DEMO_FAREWELL
value: "Such a sweet sorrow"
#3)从secret中读取key的值作为变量的值
#secret创建示例:kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: backend-user
key: backend-username
#这种形式,也是读取secret,不过这里传递的时键值对,而不是纯粹的值。
envFrom:
- secretRef:
name: test-secret
这里只介绍了四种定义形式,实际上,我们还可以通过volume挂载文件的方式来传递。不过这样,我们需要读取文件的信息来完成环境变量配置。
2、resources
resources用来定义资源配额,它有两大配置项,requests和limits。requests用来定义资源请求的数量,limits则是限制资源的使用。目前,k8s支持三种资源的请求和限制:内存、cpu和hugepages。
resources:
requests:
memory: "1024Mi"
cpu: "200m"
limits:
memory: "1024Mi"
cpu: "400m"
本例中,我们定义了内存和cpu的请求和限制。实际工作中,cpu的使用会变化,时大时小;内存就不一样,一但用了,除非重启否则不会释放。所以,配置cpu,limits可以大于requests;但配置内存,建议两者一样。避免内存不足导致oom故障。
3、startupProbe、livenessProbe和readinessProbe
startupProbe是k8s用来检测容器是否启动完成的配置项。之所以有这个配置项,而不是使用livenessProbe,是因为livenessProbe用来检测pod是否存活的,一旦pod启动时间太久,那么,我们通过livenessprobe发现故障的时间就越晚。通过startupProbe,我们可以把容器的启动状态和容器的运行状态分离看,更好的了解容器的运行状况。startupProbe首次检测成功后即退出,满足失败阈值会导致容器重启。
livenessProbe,探测容器是否存活。定义了startupProbe,会在startupProbe检测完成后开始,满足失败阈值的话会导致容器重启。
readinessProbe,检测容器是否已经准备好提供服务。满足失败阈值的话,会导致服务剔除该pod,但该pod不会重启。检测成功后,会再次加入。readiness探针使用时,要避免配置失误,导致容器一直存在,但又无法提供服务,最好导致资源被消耗完毕的情况出现。
readinessProbe:
exec:
command: ["sh", "-c", "mysql -u$(MYSQL_USER) -p$(MYSQL_PASSWORD) -e 'SELECT 1'"]
initialDelaySeconds: 5
timeoutSeconds: 1
periodSeconds: 5
......
......
......
startupProbe:
tcpSocket:
port: 80
initialDelaySeconds: 20
failureThreshold: 3
periodSeconds: 5
livenessProbe:
httpGet:
path: '/readme.html'
port: 80
scheme: HTTP
periodSeconds: 5
initialDelaySeconds: 5
上面的示例中,我们有三种检测方式,分别是http、tcp和exec。官方网站里,还有gRPC的方式,不过我们这里没有用到。三种检测方式,这三个探测配置都可以使用。
相关参数解析:
- initialDelaySeconds:初始化延迟时间,表示该Probe在多长时间后进行首次探测。
- failureThreshold:失败的阈值。一旦到达该失败次数,根据不同的Probe触发对应的策略
- periodSeconds:检测的间隔。默认10s,最小1s。
- timeoutSeconds:超时时间。像http和tcp检测,可以设置超时时间。默认1s,最小1s。
- successThreshold:成功的阈值。默认1次,有需要的可以设置多次。
- terminationGracePeriodSeconds:终止服务到强制停止容器的宽限期,默认30s。该配置不能用于readinessProbe探针。
- 点赞
- 收藏
- 关注作者
评论(0)