一、yaml文件的语法规则
大小写敏感
使用缩进表示层级关系
缩进时不允许使用Tal键,只允许使用空格
缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
”#” 表示注释,从这个字符一直到行尾,都会被解析器忽略
注:- - - 为可选的分隔符 ,当需要在一个文件中定义多个结构的时候需要使用
二、结构类型
在Kubernetes中,只需要知道两种结构类型即可
Lists
Maps
1、YAML Maps
Map顾名思义指的是字典,即一个Key:Value 的键值对信息。
例如:
---
apiVersion: v1
kind: Pod
注:
上述内容表示有两个键apiVersion和kind,分别对应的值为v1和Pod。
Maps的value既能够对应字符串也能够对应一个Maps。
例如:
---
apiVersion: v1
kind: Pod
metadata:
name: kube100-site
labels:
app: web
注:
上述的YAML文件中,metadata这个KEY对应的值为一个Maps,而嵌套的labels这个KEY的值又是一个Map。实际使用中可视情况进行多层嵌套。
YAML处理器根据行缩进来知道内容之间的关联。上述例子中,使用两个空格作为缩进,但空格的数据量并不重要,只是至少要求一个空格并且所有缩进保持一致的空格数 。例如,name和labels是相同缩进级别,因此YAML处理器知道他们属于同一map;它知道app是lables的值因为app的缩进更大。
2、YAML Lists
List即列表,说白了就是数组。
例如:
args
-beijing
-shanghai
-shenzhen
-guangzhou
注:
可以指定任何数量的项在列表中,每个项的定义以破折号(-)开头,并且与父元素之间存在缩进。
当然Lists的子项也可以是Maps,Maps的子项也可以是List。
例如:
---
apiVersion: v1
kind: Pod
metadata:
name: kube100-site
labels:
app: web
spec:
containers:
- name: front-end
image: nginx
ports:
- containerPort: 80
- name: flaskapp-demo
image: jcdemo/flaskapp
ports: 8080
注:
如上述文件所示,定义一个containers的List对象,每个子项都由name、image、ports组成,每个ports都有一个KEY为containerPort的Map组成。
三、YAML常见语法
1、apiversion
#查看apiversion版本
kubectl apiversions
#列出集群中所有可用的api资源
kubectl api-resources
常用apiversion
v1:Kubernetes API的稳定版本,包含很多核心对象:pod、service等。
apps/v1:包含一些通用的应用层的api组合,如:Deployments, RollingUpdates, and ReplicaSets。
batch/v1:包含与批处理和类似作业的任务相关的对象,如:job、cronjob。
autoscaling/v1:允许根据不同的资源使用指标自动调整容器。
networking.k8s.io/v1:用于Ingress。
rbac.authorization.k8s.io/v1:用于RBAC。
2、kind
kind指定这个资源对象的类型,如 pod、deployment、statefulset、job、cronjob
#可以使用kubectl api-resources查看有那些资源对象类型
3、metadata(Pod的元数据)
metadata常用的配置项有 name,namespace,即配置其显示的名字与归属的命名空间。
常用以下选项
annotations:添加注释信息
creationTimestamp:创建时间戳
name: pod名称
namespace:名称空间
labels:标签
例如:
vim my-tomcat.yaml
---
apiVersion: v1
kind: Pod #Pod的P必须大写
metadata:
annotations:
version: v1.0.0 #设置注释信息为版本
name: my-tomcat #设置pod的名称
namespace: default #设置命名空间为默认的,即kubectl get pods不需要加-n=
labels: #设置标签
a: b #设置标签的键值对,可以使用kubectl describe pod 查看
spec
containers:#设置容器参数
- name: tomcat-pod #设置容器名字
ports:
- containerPort:8080 #设置容器要映射的端口
image: docker.io/library/tomcat:8.5-jre-alpine #设置镜像名字
imagePullPolicy: IfNotPresent #设置镜像拉取策略
四、spec(规格)
因为这个比较多,所以我就单列一大段
1、常用
一个嵌套字典与列表的配置项,也是主要的配置项,支持的子项非常多,根据资源对象的不同,子项会有不同的配置。
字段详解:
activeDeadlineSecond:定义了Pod的最长运行时间,一旦Pod超过这个时间,Pod就会自动终止
dnsConfig: dnsConfig 字段用于设置Pod内部DNS解析的相关参数
dnsPolicy:值为 Default、ClusterFirst、ClusterFirstWithHostNet、None
Default:继承自所在Node的DNS配置
ClusterFirst:优先使用K8S的DNS配置,如果失败在用Node的DNS配置
ClusterFirstWithHostNet:优先使用K8S的DNS配置,如果失败在用主机上的DNS配置
None:禁用DNS配置
hostAliases:允许在pod内部定义一个主机别名列表,类似于hosts文件
hostNetwork: 如果参数设置为True时,那么这个Pod中的容器将会和宿主机共享网络命名空间,即它们将会使用宿主机网络配置
containers:containers是一个对象列表,containers下的字段需要用-连接
字段必填:name、image
name:容器名称
image: 容器所需的镜像
imagePullPolicy:镜像拉取策略,值为IfNotPresent、Always、Never
IfNotPresent:如果本地镜像有,则用本地的,没有则去镜像仓库拉取
Never: 从不拉取,如果本地没有镜像,则进入等待
Always:总是拉取,无论本地有没有这个镜像
command:自定义容器内需要允许的cmd命令
2、节点选择器和nodeName
nodeName:
nodename是每个node节点的唯一标识符,他是一个字符串,通常是节点的主机名(hostname)。所以在创建Pod的时候可以指定nodeName字段来将Pod调度到特定的Node节点上
例:
vim pod-node.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: pod-name
namespace: default
spec:
nodeName: lx252 #指定调度到的主机名为lx252的node节点
containers:
- name: pod-name-containers
image:tomcat:8.5-jre-alpine
imagePullPolicy: IfNotPresent
验证:
kubectl get pods -owide
-owide: 查看pod的IP,调度到的节点等信息
节点选择器:
节点选择器(NodeSelector)是用来将Pod调度到特定节点的一种机制,它基于Node节点的标签(node labels)来进行筛选和匹配,从而使pod能够被分配到满足其要求的节点上
例:
给节点打标签
kubectl label nodes "节点名字" 标签键=标签值
给节点lx252打memory=high的标签
kubectl label nodes lx252 memory=high
编写yaml
vim pod-label.yaml
---
apiVersion: v1
kind: Pod
metadata:
name: pod-name
namespace: default
spec:
nodeSelector:
memory: high #将Pod调度到拥有memory=high标签的节点
containers:
- name: pod-name-containers
image:tomcat:8.5-jre-alpine
imagePullPolicy: IfNotPresent
3、亲和性和反亲和性
亲和性
节点亲和性: nodeAffinity
查看帮助:
kubectl explain pod.spec.affinity.nodeAffinity
preferredDuringSchedulingIgnoreDuringExecution(软亲和性)
它允许用户指定Pod调度器尽可能讲Pod调度到与指定节点亲和的节点上,但是如果没有可用的这样的节点,Pod也可以调度到其他节点上
硬亲和性
requireDuringSchedulingIgnoredDuringExecution(硬亲和性)
它只能被调度到满足这个节点选择器的节点上,如果没有节点满足这个要求,Pod就无法被调度
例:
---
apiVersion: v1
kind: Pod
metadata:
name: affinity
spec:
containers:
- name:pod-affinity
image: tomcat:8.5-jre-alpine
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: a
operator: In
values:
- b
如果没有找到拥有标签a=b的node,那pod会一直是pending状态
给node节点增加a=b标签
kubectl label node lx253 a=b
就会发现调度到了lx253 node节点上
查看:
kubectl get pods -owide
Pod亲和性
pod亲和性分为两种
Podaffinity(pod亲和性)是指一组Pod可以被调度到同一节点上,即它们互相吸引,倾向于被调度在同一台节点上
Podunaffinity(Pod反亲和性):Pod反亲和性是一组Pod不应该被调度到同一节点上,即它们互相排斥,避免被调度到同一节点上
requiredDuringSchedulingIgnoredDuringExecution(软亲和性)
preferredDuringSchedulingIgnoredDuringExecution(硬亲和性)
例:
定义两个Pod调度到同一个位置
pod1:
---
apiVersion: v1
kind: pod
metadata:
name: first
labels:
app: first #以这个标签进行亲和
spec:
containers:
- name: first
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
pod2:
---
apiVersion: v1
kind: pod
metadata:
name: second
labels:
app: second
spec:
containers:
- name: second
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
affinity:
podAffinity:
requiredDuringSchedulingIgnoreDuringExecution
- labelSelector:
matchExpressions:
- {key: app, operator: In, Values: ["first"]}
topologyKey: kubernetes.io/hostname
kubectl get pods -owide #会发现两个Pod(first、second)在一个主机上
pod反亲和性
例:
定义两个Pod调度到不同位置
Pod1:
vim podunaffinity-1.yaml
---
apiVersion: v1
kind: pod
metadata:
name: first-1
labels:
app: first-1 #以这个标签进行反亲和
spec:
containers:
- name: first-1
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
Pod2:
---
apiVersion: v1
kind: pod
metadata:
name: second-1
labels:
app: second-1
spec:
containers:
- name: second-1
image: ikubernetes/myapp:v1
imagePullPolicy: IfNotPresent
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoreDuringExecution
- labelSelector:
matchExpressions:
- {key: app, operator: In, Values: ["first-1"]}
topologyKey: kubernetes.io/hostname
kubectl get pods -owide #会发现两个Pod(first-1、second-1)不在一个主机上