如何为Kubernetes编写YAML文件

2022-05-05

1026

作者:行云创新 老蒋


尽管Kubernetes越来越受欢迎,但它仍然有一个陡峭的学习曲线。

本文将介绍Kubernetes对象配置的YAML文件。YAML提供了一种以声明方式配置Kubernetes应用程序的方法,这些声明文件允许您有效地扩展和管理应用程序。如果不了解Kubernetes对象的基本配置,就很容易陷入运行应用程序而不真正了解它们如何工作的陷阱。

需要注意的是,YAML和JSON可以在Kubernetes的配置中互换使用。然而,尽管在某些情况下YAML被认为更难编写,但它要紧凑得多。考虑到大型应用程序需要管理的所有YAML文件时,这种紧凑的特性是一个很大的优势。

总的来说,YAML倾向于对用户更加友好和易于使用,紧凑的特性允许您对相关的Kubernetes对象进行分组,从而减少所需的文件数量。这是因为YAML的设计目标是提高可读性并提供更完整的信息模型。它可以简单地看作是JSON的一种演变。


Kubernetes的YAML

为了开始使用Kubernetes的YAML,我们将回顾YAML的基本结构类型,你可以在下表中看到:


当为Kubernetes编写YAML文件时,必须有四个字段。APIVersion, Kind, Metadata, Specifications。


APIVersion

这个字段引用API,它被用来创建定义的Kubernetes对象。Kubernetes提供了各种api,使您能够创建不同的Kubernetes对象。例如,apiVersion: v1包含许多核心对象。

apiVersion: v1通常被认为是Kubernetes的第一个稳定版本。另一个流行的APIVersion是apps/v1,它采用了来自v1的对象,并提供了关键的功能,如部署和replicaset。

因此,在我们的YAML文件中,定义APIVersion可以是:

apiVersion: v1


Kind

kind允许您指定要定义的Kubernetes对象类型。您将在此字段中指定的对象将链接到您之前指定的apiVersion,因为它是apiVersion字段,使您能够访问不同类型的对象及其特定定义。可以定义的对象类型包括pods、服务和daemonset。

因此,要定义一个pod对象,在指定apiVersion之后,我们将指定kind字段,如下所示:

apiVersion: v1

kind: pod


Metadata

在指定要定义的对象类型之后,元数据字段为该特定对象提供惟一属性。这可能包括name、uuid和namespace字段。为这些字段指定的值为我们提供了对象的上下文,它们可以被其他对象引用。这个字段允许我们指定对象的标识符属性。

例如,如果我们正在构建一个spring应用程序,我们的pod可以有如下所示的name值:

apiVersion: v1

kind: Pod

metadata:

    name: spring-pod


Specifications

spec字段允许我们定义对所构建的对象的期望。它由所有特定于定义对象操作的键值对组成。就像对象本身一样,对象的规范依赖于之前指定的apiVersions。因此,不同的apiversion可能包含相同的对象,但是可以定义的对象的规范可能会不同。

如果我们继续构建spring应用程序的pod对象的示例,我们的spec字段可能类似于如下所示:

apiVersion: v1

kind: Pod

metadata:

    name: spring-pod

    containers:

    – image: armo/springapp:example

spec:

      name: spring-app

      ports:

      – containerPort: 80

        protocol: TCP

在上面的最后一个示例文件中,我们使用API v1创建了一个Pod对象,我们将其命名为spring-pod。根据规范,我们将使用80端口,使用的镜像是armo/springapp:example。

下图比较了JSON和YAML中的配置。正如您所看到的,YAML更加简洁和易读。



图1:比较JSON和YAML


管理YAML文件的策略

现在我们已经构建了Kubernetes YAML文件,让我们看看进一步加速构建Kubernetes应用程序的一些策略。


YAML 版本控制

如上所述,使用YAML字段允许您以声明的方式管理Kubernetes应用程序。这些YAML文件可以存储在一个公共目录中,可以使用kubectl apply -f 应用所有这些文件。

这相当简单。然而,随着应用程序的发展和Kubernetes对象定义的更改,您将不得不考虑当前部署的版本和更改。这是因为,如果没有版本控制,您可能无法回滚到以前的镜像,而以前的镜像可能比新的当前部署的镜像更稳定。

有几种方法可以实现YAML的版本控制,它们的复杂性和管理的便利性各不相同。这可能需要在YAML中使用简单的标记和手动kubectl命令,或者需要使用诸如Helm这样的特殊工具。详细介绍这些方法超出了本文的范围,但值得一提的是,版本控制是一项重要的实践。


管理Secrets

在应用程序的整个生命周期中,您可能需要利用机密数据来支持其功能。这可能包括密码、用户信息,甚至信用卡详细信息。

在定义Kubernetes对象时,可以将这些数据作为变量直接放到YAML文件中。然而,这可能导致重大的安全漏洞,并增加了这些数据落入坏人手中的可能性。因此,建议将Kubernetes提供的Secrets对象与Secrets管理工具一起使用。

当利用Secret对象时,pod必须引用Secret。这就是我们使用元数据字段的地方。pod将使用Secret name字段,其中Secret对象的名称将是有效的DNS子域名。

定义的Secrets对象的示例如下所示:

apiVersion: v1

kind: Secret

metadata:

  name: mysecret

type: Opaque

data:

  username: YWRtaW4=

  password: MWYyZDFlMmU2N2Rm

一定要注明“Secrets”类型。在上面的例子中,我们将Secrets类型指定为Opaque。这是Secret对象的默认类型。另一种Secret类型是kubernetes.io/service-account-token,用于存储服务帐户的标识符令牌。

更多关于如何管理Kubernetes中的Secrets的详细信息可以在ARMO的资源对象中找到。


YAML 模板

YAML模板旨在通过在Kubernetes应用程序中重用YAML文件来减少我们必须编写和管理的YAML文件的数量。例如,让我们考虑下面的pod定义:

apiVersion: v1

kind: Pod

metadata:

  name: spring-pod

spec:

  containers:

  – image: armo/springapp:example

    name: spring-app

    env:

    – name: sz-1

      value: postgres://db_url:5432

这个Pod将在sz-1区。然而,如果我们想要为我们的上海客户部署到sh-1,我们将不得不编写一个新的YAML文件,因为我们使用的是硬编码的值。

这个问题的解决方案是使用YAML模板,它允许我们使用不同的值重用YAML文件。有几种实现YAML模板的方法,但最基本的方法是在利用占位符的地方搜索和替换YAML文件中的值。

apiVersion: v1

kind: Pod

metadata:

  name: spring-pod

spec:

  containers:

  – image: armo/springapp:example

    name: spring-app

    env:

    – name: ENV

      value: %DEPLOYMENT_ENV%

通过利用bash中的sed,我们可以在处理YAML文件之前搜索和替换这些值。但是,这是最基本、最不方便的方法,因为您必须手动执行占位符的硬编码。

更方便的方法是利用像Helm这样的工具来构建和管理模板。


结论

由于YAML的结构方式和它的设计目标,它是Kubernetes配置的最佳解决方案。增加的可读性和简洁的结构允许您伸缩您的Kubernetes配置,而不会迷失在一堆配置文件中。

此外,通过理解如何以声明方式构建Kubernetes应用程序,我们还可以理解Kubernetes应用程序如何运行以及为什么运行的机制。考虑像YAML模板这样的高级功能可以帮助简化定义和构建Kubernetes应用程序的过程。


--------------------

CloudOS,一站式云原生开发平台

免费体验地址>

技术交流
我们建立了多个云原生技术交流群,其中有来自Oracle、Citrix、华为、腾讯等国内外云计算专家,立即扫码,拉你进群。目前已有2000+开发者加入我们......
云原生厂商 云原生技术服务商
在云原生时代,行云创新致力于通过赋能开发者,实现企业快速迭代与交付,大幅提升创新效率。
产品下载