声明:本文出自 CNCF,帖子最初发表于 ARMO,由研发副总裁兼联合创始人 Ben Hirschberg 撰写,已获得授权。
感谢 山河已无恙 整理, 西狩xs 校对。以下为翻译全文,分享给大家 。
尽管 Kubernetes 越来越受欢迎,但它仍然有一定的学习难度,这使得很难采用这项技术。在快节奏的软件开发领域中,那些不能克服初期障碍的人往往会被甩在身后。
本文将介绍 Kubernetes 对象配置的 YAML 文件。YAML 提供了一种以声明式配置 Kubernetes 应用程序的方法,这些声明性文件允许您有效地扩展和管理应用程序。如果不了解 Kubernetes 对象的基本配置,很容易陷入运行应用程序的陷阱,而无法了解他们是如何工作的。
需要注意的是,YAML 和 JSON 都可以用于 Kubernetes 的配置,尽管在某些情况下 YAML 被认为更难编写,但它更加紧凑。当考虑到需要为大型应用程序管理所有 YAML 文件时,这是一个很大的优势。
总的来说,YAML 更易于用户使用,紧凑的特性允许您对 相关的 Kubernetes 对象进行分组 ,从而减少所需文件的数量。这是因为 YAML 的设计目标是提高可读性并提供更完整的信息模型。它可以简单地看作是 JSON 的演变。
为了开始使用 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)。
该字段引用 API,用于创建要定义的 Kubernetes 对象。Kubernetes 提供了各种 API,使您能够创建不同的 Kubernetes 对象。例如:apiVersion: v1
包含了许多核心对象。
apiVersion: v1
通常被认为是 Kubernetes 发布的第一个稳定版本。另一个流行的API 版本是 apps/v1
,它采用了 v1
中的对象,并提供了 Deployments 和 ReplicaSets 等 关键功能。
因此,在我们的 YAML 文件中,定义 API 版本可以是:
apiVersion: v1
kind
允许您指定要定义的 Kubernetes 对象的类型。您在这个字段中要指定的对象将被链接到您之前指定的 apiVersion
,因为 API 版本字段允许你访问不同类型的对象及其特定的定义。可以定义的对象类型有 Pod、Service 和 DaemonSet。
因此,为了定义一个 pod 对象,在指定 apiVersion 之后,我们将指定 kind 字段,如下所示:
apiVersion: v1
kind: Pod
在指定要定义的对象类型之后,metadata
字段将为该特定对象提供唯一属性。这可能包括 name
、uuid
和 namespace
等字段。这些字段指定的值为我们提供了该对象的上下文,并且它们也可以被其他对象引用。因此,这个字段允许我们指定对象的标识符属性。
例如:如果我们正在构建一个 spring 应用程序,我们的 pod 的 name 值如下所示:
apiVersion: v1
kind: Pod
metadata:
name: spring-pod
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
。
下图比较了 JSON
和 YAML
中的配置。正如您所看到的,YAML更加简洁易读。
现在我们已经构建了 Kubernetes 的 YAML 文件,让我们看看进一步加速构建 Kubernetes 应用程序的一些策略。
如上所述,使用 YAML 字段允许您以声明方式管理 Kubernetes 应用程序。这些 YAML 文件可以存储在一个公共目录中,并且可以使用 kubectl apply -f
来应用它们。
这相当简单。但是,随着应用程序的演变和对 Kubernetes 对象定义的更改,您必须考虑当前部署的是哪个版本和更改。这是因为:如果没有版本控制,您可能无法回滚到之前的镜像,而之前的镜像可能会比新运行的映像更加稳定。
有几种方法可以实现 YAML 的版本控制,它们的复杂性和易管理性各不相同。这可能需要在 YAML 中使用简单的标记以及手动执行 kubectl 命令,或者需要使用特殊工具,如 Helm。受限于本文的讲解范围,无法详细介绍这些方法,但是值得一提的是:版本控制是一项重要的实践。
在应用程序的整个生命周期中,您可能需要利用隐私数据来支持其功能。这可能包括密码、用户信息,甚至信用卡详细信息。
在定义 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 模板的目的是通过在 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