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

 

上一篇:pycharm连接服务器运行时提示Can‘t get remote credentials for deployment server


下一篇:关于kubernetes的十七个实验(一)