Kubernetes的yaml文件使用语法及简单操作
本文中主要说明在编写k8s的yaml文件的一些必要格式,仅供参考。新手建议观看,也不是很全,老手要参考格式写,还是得多百度/google来写,本文可参考的资源有限。
apiVersion版本
当编写一个yml文件时,第一行必须先写入apiVersion的版本
不同的apiVersion可以实现不同的功能,或者配合不同的组件去使用
官方文档也没有给出一个充分的解释
使用kubectl api-version查看当前系统下的k8s支持的apiVersion有那些
apiVersion版本分类
alpha
apiVersion版本名称中包含alpha的,这是k8s准备出的一些新功能会包含在这个版本中,很有可能会出现未知无法解决的错误,仅用于测试的版本。测试没有问题,
很有可能会纳入之后的新版本中。不建议使用
beta
名称中包含beta的是基于alpha测试成功,被默认启用,会保留在后续版本中
stable
这是一个稳定版本,命名方式为v1/v2诸如类似,可以放心使用
Kubernetes的官方文档中并没有对apiVersion的详细解释,而且因为K8S本身版本也在快速迭代,有些资源在低版本还在beta阶段,到了高版本就变成了stable。
如: Deployment
1.6版本之前:extensions/v1beta1 1.6-1.9之间:apps/v1beta1同时保留旧版本 1.9-1.16之间:apps/v1同时保留旧版本 1.17以上:apps/v1,不保留extensions/v1beta1和apps/v1beta1
个别版本介绍
v1
Kubernetes API的稳定版本,包含了多核心对象Pod、service
apps/v1beta2
在kubernetes1.8版本中,新增加了apps/v1beta2的概念,apps/v1beta1同理
DaemonSet,Deployment,ReplicaSet 和 StatefulSet的当时版本迁入apps/v1beta2,兼容原有的extensions/v1beta1
apps/v1
在kubernetes1.9版本中,引入apps/v1,deployment等资源从extensions/v1beta1, apps/v1beta1 和 apps/v1beta2迁入apps/v1,原来的v1beta1等被废弃。
apps/v1代表:包含一些通用的应用层的api组合,如:Deployments, RollingUpdates, 和ReplicaSets
batch/v1
代表job相关的api组合
在kubernetes1.8版本中,新增了batch/v1beta1,后CronJob 已经迁移到了 batch/v1beta1,然后再迁入batch/v1
autoscaling/v1
代表自动扩缩容的api组合,kubernetes1.8版本中引入。
这个组合中后续的alpha 和 beta版本将支持基于memory使用量、其他监控指标进行扩缩容
extensions/v1beta1
deployment等资源在1.6版本时放在这个版本中,后迁入到apps/v1beta2,再到apps/v1中统一管理
certificates.k8s.io/v1beta1
安全认证相关的api组合
authentication.k8s.io/v1
资源鉴权相关的api组合
k8s的yaml文件语法
大小写敏感
使用缩进表示层级关系
缩进时不允许使用Tab键,只允许使用空格。
缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
# 表示注释,从这个字符一直到行尾,都会被解析器忽略。
直接编写使用一个文件做示例
[root@node1 ~]# vim nginx.yml apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment spec: selector: matchLabels: app: nginx replicas: 2 template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80
yaml文件的固定结构
每个文件必须的结构如下: apiVersion: apps/v1 # api版本 kind: xxxx # 要创建的资源类型,如Deployment/Pod/ReplicaSet/StatefulSet/DaemonSet/Job/Cronjob/Service/Ingress... metadata: # 元数据对象,该资源的基本属性和信息 name: xxx # 定义该资源的名称 namespace: xxx # 命名空间,默认放到default空间 lables: # 标签,在下一行定义键值对,可以是多对键值对 xxx: xxxx xxx: xxxx annotations # 资源注解 xxx: xxxx spec: # 定义期望状态,详细的创建信息 containers: # 容器列表 - name: xxx # 容器名 image: xxxx # 容器镜像 status: # 当前状态,由k8s集群维护,不可以自定义
拆分实例文件结构
Controller定义部分
必须定义名字 ------------------------------------------ apiVersion: apps/v1 # api版本(必须的) kind: Deployment # 表示要创建的Controller资源类型 metadata: # 元数据对象,该资源的基本属性和信息(必须的) name: nginx-deployment # 定义该资源的名称(必须的),同一命名空间内,必须唯一 namespace: xxxx # 命名空间,默认放到default空间(可选) labels: # 标签,用来定位一个或多个资源,键值对方式进行定义,下方使用的selector会与这里的键值对对应,作为selector的挑选条件 app: nginx # 设置key为app,value为nginx ------------------------------------------
资源的特点
也就是kind所创建的资源的信息
------------------------------------------ spec: # 描述该资源的创建信息,对应kind资源类型的信息 revisionHistoryLimit: 10 # 回滚时会用到,用来保留最近10的版本 replicas: 2 # 创建2个应用实例 selector: # 标签选择器,与上面的标签共用,这个部分是17版本开始加的,必须与上面的labels对应 matchLabels: # 选择包含标签app:nginx的资源 # 正确的Deployment,让matchLabels 和template.metadata.lables完全匹配才能不报错 # 直接不写spec.mathlabels创建直接报错缺少缺少必要字段selector # 当把matchLables匹配的和下面pod模板不相对应,也会直接报错:选择的标签和模板标签不匹配 # matchLabel是pod的标签选择器。 由此选择其pod的现有ReplicaSet(副本集)将受此部署影响的副本。 app: nginx ------------------------------------------
matchLabels总结
1、在Deployment中必须写matchLabels 2、在定义模板的时候必须定义labels,因为Deployment.spec.selector是必须字段,而又必须和template.labels对应 3、templdate里面定义的内容会应用到下面所有的副本集里面,在template.spec.containers里面不能定义labels标签
Pod的模板
必须定义labels ------------------------------------------ template: # 选择或创建的Pod模板 metadata: # Pod的元数据,Pod的信息 labels: # Pod标签 app: nginx ------------------------------------------
Container的模板
------------------------------------------ spec: # 期望Pod实现的功能(在Pod中部署什么) strategy: # 在滚动更新Pod时的启动Pod数量比值 rollingUpdate: maxSurge: 35% maxUnavailable: 35% nodeSelector: # 指定pod运行在哪个集群节点 restartPolicy: # 容器重启策略(Never/Always/OnFailure) hostNetwork: true # 表示直接使用节点中的主机网络,相当于docker的host网络 containers: # 在Pod中生成容器,容器列表,可写入多个镜像的实例 - name: xxxx # 定义容器名 image: xxxx # 容器使用的镜像 - name: xxxx image: xxxx imagePullPolicy: # 镜像下载策略(IfNotPresent/Never/Always) # 分别代表,没有镜像时下载,从不下载,总是下载 command: # 运行程序==dockerfile中的ENTRYPOINT,或者docker run时最后跟的/bin/bash等命令,会替代dockerfile中cmd和ENTRYPOINT执行的命令 - echo - 'hello world' args: # 向docker镜像中传递命令,通常用来给command传参,也可以单独使用,与dockerfile中的CMD作用一样,如果yml中只写了args,将会给dockerfile中的ENTRYPOINT传参,dockerfile中的CMD会失效。 - xxx - xxx ports: # 用来暴露端口,并不是端口映射,仅仅为了可以看到容器中使用了哪两个端口 - name: xxx containerPort: 80 # 容器中提供服务的端口 protocol: TCP/UDP # 默认是tcp - name: xxx containerPort: 443 volumeMounts: # 用来指定容器内的路径 - name: nginxconf mountPath: /usr/local/nginx/conf - name: nginxhtml mountPath: /usr/local/nginx/html readOnly: True # 设置容器内只读,默认是读写 volumes: # 指定对应name的物理机路径,缩进与上方的containers对齐 - name: nginxconf hostPath: path: /nginx/conf - name: nginxhtml hostPath: path: /nginx/html - name: xxx emptyDir: {} - name: xxx persistentVolumeClaim: # 使用PVC存储资源 claimName: xxxxx-xxx LivenessProbe: # 存活检测,判断文件是否存在,检测失败重启容器 exec: command: - cat - /tmp/healthy readinessProbe: # 读取检测,判断文件是否存在,检测失败,标记为不可用,将不会被Service所负载 exec: command: - cat - /tmp/healthy ------------------------------------------
其他的一些参数功能,在后面的使用过程中会提到,也回去解释
大致结构是这样的
Labels的重要性
在新版的k8s中labels是非常重要的
注意: 必须在 Deployment 中指定适当的选择器和 Pod 模板标签(在本例中为app: nginx)。不要与其他控制器(包括其他 Deployments 和状态设置)重叠标签或选择器。
Kubernetes 不会阻止重叠,如果多个控制器具有重叠的选择器,这些控制器可能会冲突并运行意外。
matchLabels/matchExpression作用
matchLabels用于定义一组Label,与直接写在Selector中作用相同,直接给定键值; matchExpression用于定义一组基于集合的筛选条件,基于表达式来定义使用标签选择器,
`{key: KEY
matchLabels使用场景
1.kube-controller进程通过资源对象ReplicaSet上定义的Label Selector来筛选要监控的Pod副本的数量,从而实现Pod副本的数量始终符合预期设定的全自动控制流程
2.kube-proxy进程通过Service的Label Selector来选择对应的Pod,自动建立器每个Service到对应Pod的请求转发路由表,从而实现Service的智能负载均衡机制
3.通过对某些Node定义特定的Label,并且在Pod定义文件中使用NodeSelector这种标签调度策略,Kube-scheduler进程可以实现Pod定向调度的特性
Pod 选择器
.spec.selector
字段是一个标签选择器。 ReplicationController 管理标签与选择器匹配的所有 Pod。 它不区分它创建或删除的 Pod 和其他人或进程创建或删除的 Pod。 这允许在不影响正在运行的 Pod 的情况下替换 ReplicationController。
如果指定了 .spec.template.metadata.labels
,它必须和 .spec.selector
相同,否则它将被 API 拒绝。 如果没有指定 .spec.selector
,它将默认为 .spec.template.metadata.labels
。
另外,通常不应直接使用另一个 ReplicationController 或另一个控制器(例如 Job)来创建其标签与该选择器匹配的任何 Pod。如果这样做,ReplicationController 会认为它创建了这些 Pod,就会产生冲突, Kubernetes 并没有阻止你这样做。
使用文件部署Deployment
[root@node1 ~]# kubectl apply -f nginx.yml
deployment.apps/nginx-deployment created
查看创建的Deployment
[root@node1 ~]# kubectl get deployments.apps NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 2/2 2 2 46s
查看Deployment创建的ReplicaSet
[root@node1 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-deployment-5bf87f5f59 2 2 2 24s
查看已运行的pod
[root@node1 ~]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE nginx-deployment-5bf87f5f59-8rrjv 1/1 Running 0 11m 10.244.1.4 node2 nginx-deployment-5bf87f5f59-cxjdm 1/1 Running 0 11m 10.244.2.4 node3
查看pod的labels标签
[root@node1 ~]# kubectl get pod --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-deployment-5bf87f5f59-8rrjv 1/1 Running 0 11m app=nginx,pod-template-hash=5bf87f5f59 nginx-deployment-5bf87f5f59-cxjdm 1/1 Running 0 11m app=nginx,pod-template-hash=5bf87f5f59
删除使用文件创建的deployment的方法
[root@node1 ~]# kubectl delete -f nginx.yml
多Deployment环境中快速确定Pod的归属
如果在生产环境中有大量的Deployment的话,无法快速确定哪些Pod是属于哪个Deployment,这个是就体现了label标签的重要性
基于以上的nginx-deployment
,在运行一个httpd-deployment
的Deployment
[root@node1 ~]# vim httpd.yml apiVersion: apps/v1 kind: Deployment metadata: name: httpd-deployment spec: replicas: 3 selector: matchLabels: run: httpd template: metadata: labels: run: httpd spec: containers: - name: httpd image: httpd:latest ports: - containerPort: 80
运行httpd-deployment
[root@node1 ~]# kubectl apply -f httpd.yml
deployment.apps/httpd-deployment created
这时候再来查看Pod,直接看到了两个Deployment中的所有pod
[root@node1 ~]# kubectl get pod NAME READY STATUS RESTARTS AGE httpd-deployment-5dd67c6b75-mdnsz 1/1 Running 0 77s httpd-deployment-5dd67c6b75-v2pmt 1/1 Running 0 77s httpd-deployment-5dd67c6b75-zfrgb 1/1 Running 0 77s nginx-deployment-5bf87f5f59-8rrjv 1/1 Running 0 39m nginx-deployment-5bf87f5f59-cxjdm 1/1 Running 0 39m
想要查看某个Deployment中的pod,可以根据各自的标签来查看,如下:
[root@node1 ~]# kubectl get pods -l run=httpd NAME READY STATUS RESTARTS AGE httpd-deployment-5dd67c6b75-mdnsz 1/1 Running 0 2m29s httpd-deployment-5dd67c6b75-v2pmt 1/1 Running 0 2m29s httpd-deployment-5dd67c6b75-zfrgb 1/1 Running 0 2m29s [root@node1 ~]# kubectl get pods -l app=nginx NAME READY STATUS RESTARTS AGE nginx-deployment-5bf87f5f59-8rrjv 1/1 Running 0 41m nginx-deployment-5bf87f5f59-cxjdm 1/1 Running 0 41m