声明:本文出自 CNCF,帖子最初发表于 ARMO,由研发副总裁兼联合创始人 Ben Hirschberg 撰写,已获得授权。

感谢 山河已无恙 整理, 西狩xs 校对。以下为翻译全文,分享给大家 。

尽管 Kubernetes 越来越受欢迎,但它仍然有一定的学习难度,这使得很难采用这项技术。在快节奏的软件开发领域中,那些不能克服初期障碍的人往往会被甩在身后。

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

需要注意的是,YAML 和 JSON 都可以用于 Kubernetes 的配置,尽管在某些情况下 YAML 被认为更难编写,但它更加紧凑。当考虑到需要为大型应用程序管理所有 YAML 文件时,这是一个很大的优势。

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

Kubernetes 的 YAML

为了开始使用 Kubernetes 的 YAML,我们将回顾 YAML 的基本结构类型,如下表所示:

键/字段-值 对(Key/Field-Value Pair)列表(List)集合(Map)
app: redis
role: replica
tier: backend
containers:
– name: webserver1
– name: database-server
– name: rss-reader
containers:
– name: webserver1
image: nginx:1.6
ports:
– containerPort:80
– name: database-server
image: mysql-3.2
ports:
– containerPort:3306
– name: rss-reader
image: rss-php-nginx:2.8
ports:
– containerPort:86

在为 Kubernetes 编写 YAML 文件时,必须存在四个必需的字段:API 版本(apiVersion)、类型(kind)、元数据(metadata)和规范(spec)。

apiVersion

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

apiVersion: v1 通常被认为是 Kubernetes 发布的第一个稳定版本。另一个流行的API 版本是 apps/v1,它采用了 v1 中的对象,并提供了 Deployments 和 ReplicaSets 等 关键功能

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

apiVersion: v1

kind

kind 允许您指定要定义的 Kubernetes 对象的类型。您在这个字段中要指定的对象将被链接到您之前指定的 apiVersion,因为 API 版本字段允许你访问不同类型的对象及其特定的定义。可以定义的对象类型有 Pod、Service 和 DaemonSet。

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

apiVersion: v1
kind: Pod

metadata

在指定要定义的对象类型之后,metadata 字段将为该特定对象提供唯一属性。这可能包括 nameuuidnamespace 等字段。这些字段指定的值为我们提供了该对象的上下文,并且它们也可以被其他对象引用。因此,这个字段允许我们指定对象的标识符属性。

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

apiVersion: v1
kind: Pod
metadata:
    name: spring-pod

spec

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

如果我们继续我们构建 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

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

管理 YAML 文件的策略

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

YAML 的版本控制

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

这相当简单。但是,随着应用程序的演变和对 Kubernetes 对象定义的更改,您必须考虑当前部署的是哪个版本和更改。这是因为:如果没有版本控制,您可能无法回滚到之前的镜像,而之前的镜像可能会比新运行的映像更加稳定。

有几种方法可以实现 YAML 的版本控制,它们的复杂性和易管理性各不相同。这可能需要在 YAML 中使用简单的标记以及手动执行 kubectl 命令,或者需要使用特殊工具,如 Helm。受限于本文的讲解范围,无法详细介绍这些方法,但是值得一提的是:版本控制是一项重要的实践。

管理 Secrets

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

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

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

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

下面是一个定义 Secrets 对象的示例:

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm

一定要注意 Secret 类型。在上面的示例中,我们将 Secrets 类型指定为 Opaque(不透明)。这是 Secret 对象的默认类型。另一种 Secrets 类型是 kubernetes.io/service-account-token,用于存储服务帐户 token。

更多关于 如何管理 Kubernetes 隐私 的详细信息可以参考 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: eu-west-1
      value: postgres://db_url:5432

这个 pod 位于 eu-west-1 区域。但是,如果我们想为美国的客户部署 us-west-1,我们将不得不编写一个新的 YAML 文件,因为我们使用的是硬编码值。

这个问题的解决方案是 YAML 模板,它允许我们使用不同的值复用 YAML 文件。YAML 模板有几种方法,但最基本的方法是搜索并替换我们在 YAML 文件中使用占位符来表示一些值的地方。

因此,回到最初的例子,我们将添加一个占位符值,如 env 字段下所示:

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 应用程序的过程。


聚焦云原生新技术、新实践,帮助开发者群体赢在开发范式转移的新时代。欢迎关注CSDN云原生微信公众号:csdn-cloud

Logo

开源、云原生的融合云平台

更多推荐