在K8S中,K8S将所有的操作对象都当做资源来进行管理,K8S为我们提供了一个叫APIserver
的组件,这个组件提供了一系列的RESTful
风格的接口,通过这些接口就可以实现对资源的增删改查等操作。
而所谓的资源配置清单就是我们用来创建和管理资源的配置文件。在了解资源配置清单前,我们需要先了解一下K8S中有哪些资源。
一、资源类型
1、工作负载型资源
这些资源就是K8S中承载具体的工作的一些资源,常见的类型有:Pod,ReplicaSet,Deployment,StatefulSet,DaemonSet,Job,Cronjon,...
2、服务发现及均衡型资源
这种类型的资源主要和服务相关,负责服务发现,调度等,常见的类型有:Service,Ingress,...
3、配置与存储相关资源:
这类型的资源主要和存储相关,常见类型有:Volume,CSI,ConfigMap,Secret,DownwardAPI,...
4、集群级资源
这类型资源主要提供集群的管理相关的功能,常见类型有:Namespace,Node,Role,ClusteRole,RoleBinding,ClusterRoleBinding
5、元数据型资源
这类型的资源主要提供元数据相关的功能,常见类型有:HPA,PodTemplate,LimitRange, ....
二、创建资源配置清单
K8S中的APIServer在创建资源时采用JSON格式的数据,我们可以通过使用yaml格式的配置文件来提供配置,然后K8S内部自动帮我们转换为JSON格式,然后再提交。
资源配置清单关键字
, 在一个配置清单中,有五个一级字段及多个下级字段组成,我们先来看下这几个一级字段:
1. apiVersion:[group]/version
APIServer使用分组来管理api,在创建资源配置清单的时候要指定此api属于哪个组,属于core组的资源,在定义时可以省略组名,使用kubectl api-server
命令可以来获取api版本。
2、kind:资源类型
kind字段用来指定要管理的资源类型,资源类型如上所述。
3、metadata:元数据
metadata字段用来指定部分元数据,其有多个二级字段:
name:资源名称,在同一个类别中这个名称必须是唯一的
namespace:名称空间,资源所属的名称空间
labels:标签,每个标签都是一对键值对,一个资源可以拥有多个标签,一个标签也可以对应多个资源。标签可以在资源创建时指定,也可以在资源创建之后来管理标签。
标签定义格式:key=value,键名和键值最长长度为63个字符,其中:
key:由字母、数字、_、-、.组成,必须以字母开头
value:可以为空,只能以字母或数字开头或结尾,中间可以使用_、-、.
kubectl get pods --show-labels # 查看pods资源时显示标签
kubectl get pods -l app # 查看拥有app标签的pods资源
kubectl label pod pod-demo release=canary # 给名为pod-demo的pod资源新增一个标签release=canary
kubectl label pod pod-demo release=stable --overwrite # 修改pod-demo的release标签release=stable,不加--overwrite会报错
在K8S中,通过标签选择器来筛选资源,其中,标签除了可以指定具体的键值外,还有如下类型:
等值关系:=,==,!=
,集合关系:
KEY in (value1,value2,...) :KEY键值在某些集合中
KEY notin (value1,value2,...):KEY键值不在某些集合中
KEY: 存在键KEY
!KEY: 不存在键KEY
annotations:注解,其与label不同的地方在于,它不能用于挑选资源对象,仅用于为对象提供元数据,其键和值没有长度限制
4、spec:规则字段
spec字段用于定义用户期望的状态,在这个字段下有多个二级字段,用于定义容器相关期望状态等,接下来我们将介绍部分字段。
spec
containers:指定容器相关配置,此字段是必填的,部分二级字段如下:
- name:容器名称
image:启动容器的镜像
imagePullPolicy: 拉取镜像策略,其有三个值可选:Always | Never | IfNotPresent
Always: 表示无论本地是否有镜像文件,每次创建资源时都去镜像仓库中拉取镜像
Never: 表示从不自动从镜像仓库中拉取镜像,启动时需要手动拉取镜像到本地
IfNotPresent: 表示如果本地有镜像时就使用本地镜像,本地没有时就自动去拉取
当不指定此配置时,如果镜像标签是 :latest 的时候,默认采用Always的方式拉取镜像,否则默认采用IfNotPresent方式拉取镜像。
ports:容器暴露的端口信息。在此处暴露端口可为系统提供有关容器使用的网络连接的信息,但仅仅是参考信息。如果在此处没有指定端口,也并不能保证容器没有暴露端口。任何监听容器中“0.0.0.0”地址的端口都可以被访问到。其下级还有如下字段:
- name:暴露端口的名字
containerPort:必填字段,暴露的容器端口号
protocol:协议栈,默认TCP协议,可选UDP,TCP,SCTP
command:容器运行的命令,用来指定替换容器默认的命令,command相当于Dockerfile中的Entrypoint,如果不指定该参数,那么就会采用镜像文件中的ENTRYPOINT指令。
args:entrypoint指令的参数列表,如果不指定这个参数,则使用镜像中的CMD指令
** command和args参数分别对应镜像中的ENTRYPOINT和CMD指令,此时就出现如下几种情况:
a、command和args都未指定:运行镜像中的ENTRYPOINT和CMD指令
b、command指定而args未指定:只运行command指令,镜像中的ENTRYPOINT和CMD指令都会被忽略
c、command未指定而args指定:运行镜像中的ENTRYPOINT指令且将args当做参数传给ENTRYPOINT指令且镜像中的CMD指令被忽略
d、command和args都指定:运行command指令,并把args当做参数传递给command,镜像中的ENTRYPOINT和CMD指令都会被忽略
livenessProbe:POD容器存活状态监测,检测探针有三种,ExecAction、TCPSockerAction、HttpGetAction
exec:命令类型探针
command:执行的探测命令,命令运行路径是容器内系统的/,且命令并不会运行在shell中,所以,需要我们手动指定运行的shell,当命令返回值是0时表示状态正常,反之表示状态异常
httpGet:http请求型探针
host:请求的主机地址,默认是POD IP
httpHeaders:HTTP请求头
path:请求的URL
port:请求的端口,必填项
scheme:请求协议,默认是http
tcpSocket:TCP socket型探针
host:请求的主机地址,默认是POD IP
port:请求的端口号,端口范围是1-65535
failureThreshold:连续错误次数,默认3次,即默认连续3次检测错误才表示探测结果为异常
successThreshold:连续成功次数,默认1次,即当出现失败后,出现连续1次检测成功就认为探测结果是正常
periodSeconds:探测时间间隔,默认10秒
timeoutSeconds:探测超时时间,默认1秒
initialDelaySeconds:起始探测时间间隔,表示pod启动后,该间隔之后才开始进行探测
readinessProbe:主容器内进程状态监测,其可用的检测探针类型和livenessProbe是一致的
此检测和service调度有很强的关联性,
当新调度一个pod时,如果没有指定就绪性检测,此时一旦pod创建就会立即被注册到service的后端
如果此时pod内的程序尚无法对外提供服务,就会造成部分请求失败
所以,我们应该让一个pod在注册到service中区之前,已经通过了可用性检测,保证可以对外提供服务
lifecycle:生命周期钩子方法
postStart:容器启动后执行的命令,可用检测探针和livenessProbe是一致的
preStop:容器启动前执行的命令
restartPolicy:重启策略,Always, OnFailure,Never. Default to Always.
nodeSelector:node选择器,可以根据node的标签选择POD运行在某些指定的node上
nodeName:使pod运行在指定nodeName的节点之上
5、status:状态字段
status字段描述了当前状态信息,本字段由k8s集群维护
资源配置清单有很多字段,无法一一介绍,K8S也为我们提供了查看这些字段的命令:kubectl explain 资源类别[.字段名]
,此命令可以为我们提供当前资源类别的定义方式,如果需要知道具体的某一个字段如何定义,可以使用kubectl explain
资源类别.字段名,如:
[root@k8s7-22 ~]# kubectl explain pod.metadata.clusterName
KIND: Pod
VERSION: v1
FIELD: clusterName <string>
DESCRIPTION:
The name of the cluster which the object belongs to. This is used to
distinguish resources with same name and namespace in different clusters.
This field is not set anywhere right now and apiserver is going to ignore
it if set in create or update request.
三、编写一个自定义配置清单
有了上述的介绍,我们来自己编写一个自定义配置清单,然后根据这个配置清单启动一个pod资源
[root@k8s7-200 manifests]# pwd
/data/k8s-yaml/manifests
[root@k8s7-200 manifests]# cat pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-demo # pod名称
namespace: default # pod资源所属的namespace
labels: # 标签
app: myapp
tier: frontend
spec:
containers: # 定义容器
- name: myapp # 启动第一个容器,名为myapp
image: harbor.od.com/public/myapp:v1 # 启动容器需要使用的镜像文件
- name: busybox # 启动第二个容器为busybox
image: harbor.od.com/public/busybox:latest # 第二个容器的镜像
command: # 自定义在第二个容器中执行的命令
- "/bin/sh"
- "-c"
- "sleep 3600"
然后使用这个资源配置清单来创建资源,我们的资源配置清单可以放在服务器本地,也可以放在资源站上,创建的时候直接指定这个资源配置清单的URL即可:
[root@k8s7-22 ~]# kubectl create -f http://k8s-yaml.od.com/manifests/pod-demo.yaml
pod/pod-demo created
此时,就根据这个资源配置清单去创建资源了,如果创建资源时报错,那么我们可以使用如下信息来查看具体的报错信息:
[root@k8s7-22 ~]# kubectl describe pod pod-demo