k8s的YAML文件正确使用姿势

1,081 阅读4分钟

相信大家在安装 kubernetes 的时候应该使用过一些 YAML 文件来创建相关的资源,但是可能有部分小伙伴对 YAML 文件的语法和使用姿势还是一知半解。不过不要紧,今天就给大家讲下 kubernetes 的 YAML 文件的正确使用姿势。

下面我们先来简单看看 YAML 文件是如何使用的,先来用 YAML 文件定义并创建一个 kubernetes 的 pod 资源,然后再来定义一个 kubernetes 的 deployment 资源。

YAML 基础语法

YAML 的基本语法如下:

  • 首先是大小写敏感
  • 然后通常使用缩进来表示层级的关系
  • 记住缩进时只允许使用空格,不允许使用 Tab 键
  • 不过缩进的空格数量不重要,只要相同层级的元素左侧对齐就可以
  • 另外,注释的话使用#

在 kubernetes 中,一般掌握以下两种结构类型就 ok 了:

  • Maps 和 Lists

Maps

首先我们来看下 Maps,众所周知 Map 是字典的结构,即一个 key:value 的键值对,使用 Maps 可以写配置信息是比较方便的,例如:

---
apiVersion: v1
kind: Pod

第一行的---是分隔符,是可选的,在同一个文件中,可以用连续三个连字号---区分多个资源。这里我们可以看到,我们有两个键:apiVersion 和 kind,他们对应的值分别是:v1 和 Pod。如果将 YAML 文件转换成 JSON 格式的话,应该比较好理解,如下:

{
    "apiVersion": "v1",
    "kind": "pod"
}

再来看一个相对复杂一点的 YAML 文件,创建一个 KEY 对应的值不是字符串而是一个 Maps:

---
apiVersion: v1
kind: Pod
metadata:
  name: mypod
  labels:
    app: nginx

以上的 YAML 文件,metadata 这个 KEY 对应的值就是一个 Maps,而且嵌套的 labels 的 KEY 的值又是一个 Map,也就是可以根据情况进行多层嵌套。

上面说到的 YAML 文件的语法规则,YAML 处理器是根据行缩进来进行关联性处理。不得不说处理器还是比较厉害的。

可以看到 name 和 labels 是相同级别的缩进,所以 YAML 处理器就知道了他们属于同一个 MAP,而 app 是 labels 的值是因为 app 的缩进更大。

需要关注的是:在 YAML 文件中是不能使用 tab 键的。

同样的,如果将上面的 YAML 文件转换成 JSON 文件,会得到如下格式:

{
  "apiVersion": "v1",
  "kind": "Pod",
  "metadata": {
    "name": "kube100-site",
    "labels": {
      "app": "web"
    }
  }
}

Lists

Lists 就是我们不是所知道的列表,说白了就是数组的意思,在 YAML 文件中我们可以这样定义列表:

args
  - Apple
  - Banana
  - Pear

对应的 JSON 格式如下:

{
    "args": ["Apple", "Banana", "Pear"]
}

当然,list 的子项也可以是 Maps,Maps 的子项也可以是 list 如下所示:

---
apiVersion: v1
kind: Pod
metadata:
  name: mypod
  labels:
    app: nginx
spec:
  containers:
    - name: front-end
      image: nginx
      ports:
        - containerPort: 80
    - name: gin-demo
      image: routeman/gin
      ports:
        - containerPort: 5300

比如这个 YAML 文件,我们定义了一个叫 containers 的 List 对象,每个子项都由 name、image、ports 组成,每个 ports 都有一个 key 为 containerPort 的 Map 组成,同样的,我们可以转成如下 JSON 格式文件:

{
    "apiVersion": "v1",
    "kind": "Pod",
    "metadata": {
        "name": "mypod",
        "labels": {
            "app": "nginx"
        }
    },
    "spec": {
        "containers": [{
            "name": "front-end",
            "image": "nginx",
            "ports": [{
                "containerPort": 80
            }]
        }, {
            "name": "gin-demo",
            "image": "routeman/gin",
            "ports": [{
                "containerPort": 5300
            }]
        }]
    }
}

使用 YAML 文件创建 pod

通过以上,相信大家应该对 YAML 文件有了一定的了解,接下来我们使用 YAML 文件来创建一个 pod 来练练手。

创建 Pod

---
apiVersion: v1
kind: Pod
metadata:
  name: mypod
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: routeman/nginx
      ports:
        - containerPort: 80
    - name: gin-demo
      image: routeman/gin
      ports:
        - containerPort: 5300

上面定义了一个普通的 pod 文件,我们先来简单分析下文件内容:

  • apiVersion,这里它的值是 v1,这个版本号需要根据我们安装的 kubernetes 版本和资源类型来做相应的修改,并不一定是写死的
  • kind,这里我们创建的是一个 Pod,当然根据你的实际情况,这里资源类型可以是 Deployment、Job、Service 等待资源。
  • metadata:包含了我们定义的 Pod 的一些 meta 信息,比如名称、namespace、标签等等信息。
  • spec:包括一些 containers,storage,volumes,或者其他 Kubernetes 需要知道的参数,以及诸如是否在容器失败时重新启动容器的属性。你可以在特定 Kubernetes API 找到完整的 Kubernetes Pod 的属性。

了解了 pod 如何定义后,我们将上面创建 pod 的 YAML 文件保存并命名为 mypod.yaml,然后在终端使用 kubectl 创建 pod:

$ kubectl create -f mypod.yaml
pod "mypod" created

使用 YAML 文件创建 Deployment

我们再使用 YAML 来创建一个完整的 Deployment。

在上面的例子中,我们只是单纯的创建了一个 pod 实例,但是如果这个 pod 出现了问题挂掉的话,相应的服务也会挂掉,因此 kubernetes 提供了 Deployment 的概念,可以让 kubernetes 去管理一组 pod 的副本,也就是我们所说的副本集,这样不但可以维持一定数量的副本保持一直可用的,而且还不会因为一个 pod 的挂掉而导致整个服务挂掉。

更多技术文章尽在公众号【Go键盘侠】,欢迎关注交流学习。

下面我们来定义这样一个 Deployment:

---
apiVersion: v1
kind: Deployment
metadata:
  name: mydeployment
spec:
  replicas: 2
...

注意这里的 kind 要指定为 Deployment,然后我们可以指定一些 meta 信息,比如名字或者标签之类的。其次,比较重要的是 spec 配置选项,比如这里我们定义了两个副本,当然还有很多可以设置的属性,这里就不一一赘述了。

我们可以在 k8syaml.com/ 中填写参数生成一个完整的 Depolyment。

定义一个完整的 Deployment 的 YAML 文件:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mydeployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: ngix
          image: nginx
          ports:
            - containerPort: 80
        - name: gin-demo
          image: routemna/gin
          ports:
            - containerPort: 5300

看起来是不是和我们上面的 pod.yaml 很类似,细心的同学可能注意到其中的 template,其实就是对 pod 对象的定义。将上面的 YAML 文件保存为 deployment.yaml,然后创建 Deployment:

$ kubectl create -f deployment.yaml
deployment "mydeployment" created

同样的,想要查看它的状态,我们可以检查 Deployment 的列表:

$ kubectl get deployments
NAME           DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
mydeployment   2         2         3            2           1m

可以看到所有的 Pods 都已经正常运行了。

好的,到这里我们使用 YAML 文件完成了 Kubernetes Deployment 的创建,也再次的了解了 YAML 文件的基础。

其实最主要的是要根据实际情况去定义相应的 YAML 文件,不过不要紧,可以通过查阅 Kubernetes 文档来写 YAML。

关注:可以使用 www.yamllint.com/ 去检验 YAML 文件的合法性。