Kustomize入门
通过动手示例对 Kubernetes 资源进行声明式管理
Kubernetes 是著名的容器编排器之一,并导致了围绕它的整个生态系统的发展。它允许组织通过单个 API 接口提供多种资源来管理容器部署、副本、扩展、服务发现和网络,从而轻松管理其容器应用程序。
大多数组织在将这些应用程序部署到生产环境之前,都有多个环境来开发和测试这些应用程序。这些环境之间的配置可能有所不同,并且可能需要调整几个方面。
有多种方法可以管理多个环境的 Kubernetes 资源,例如 Helm 和 Kustomize。Helm 是最动态的基于模板的 Kubernetes 资源管理器。但是,您可能不需要 Helm 来完成所有事情。Kustomize 是一种 Kubernetes 原生方法,用于管理多个环境的 Kubernetes 资源清单。它根据覆盖原则来做到这一点。让我们在下一节中了解这两种方法。
模板与叠加
基于模板的引擎的工作原理是用值替换变量。Helm 是基于模板的引擎,允许您通过在通用清单的特定位置声明变量占位符来定义基于模板的通用清单。然后,使用变量文件将变量替换为值。
基于覆盖的引擎基于查找和替换的原则工作,即它搜索清单中的特定部分,并使用基于查找、替换和合并的策略将它们替换为所需的值。这允许您创建基本清单文件,这些文件几乎是标准的 Kubernetes 资源定义文件,可以自行部署。然后,可以使用 Kustomize 根据您的要求进一步自定义这些文件。
Kustomiz如何工作
Kustomize 使用一个名为的文件,该文件包含声明性规范,说明需要从哪些清单文件导入哪些资源以及需要进行哪些更改。一旦它处理了资源,它就会将它们发送到标准输出中,标准输出可以存储在文件中或直接与 kubectl 一起使用以将其应用于特定集群。kustomization.yaml
Kustomize 的一个优秀用例是管理多个环境的 Kubernetes 资源。要使 Kustomize 在这种情况下正常工作,您需要一个目录,该目录将包含包含所有常见元素的所有清单文件,以及一个包含特定环境的所有差异的目录。baseoverlays
为了更好地理解,让我们看一个动手示例。
先决条件
Kubernetes1.14版本以上并且有kubectl命令
我们还需要安装 Kustomize
安装 Kustomize
安装
csharp
[root@k8s-master ~]# curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
[root@k8s-master ~]# sudo mv kustomize /usr/bin/
在安装 Kustomize 时,让我们了解问题陈述以及我们计划实现的内容。
问题陈述
我们有一个要在多个环境中部署的 Web 应用程序。它具有以下特定于环境的差异:
- 它应包含与部署它的环境(即开发、测试和生产)相对应的标签。
env
- 它应该部署在与环境(即开发、测试和生产)对应的命名空间上。
- 开发环境中的副本数应为 1、2 个在测试中和 3 个在生产中。
- 在生产环境中,我们将实施具有 1 和 1 的滚动更新策略。
maxSurgemaxUnavailable
因此,让我们继续查看目录结构。
目录结构
我们将在两个文件中创建一个 a 和一个资源 --- 和 。目录结构如下所示:DeploymentServicedeployment.yamlservice.yaml
csharp
kustomize-example-app/
├── base
│ ├── deployment.yaml
│ ├── kustomization.yaml
│ └── service.yaml
└── overlays
├── dev
│ ├── deployment.yaml
│ ├── kustomization.yaml
│ ├── namespace.yaml
│ └── service.yaml
├── prod
│ ├── deployment.yaml
│ ├── kustomization.yaml
│ ├── namespace.yaml
│ └── service.yaml
└── test
├── deployment.yaml
├── kustomization.yaml
├── namespace.yaml
└── service.yaml
该目录包含基本清单和一个包含三个环境之间所有常见元素的文件。该目录包括 、 和 各一个目录。由于我们只是在开发、测试和生产环境中更改两者和资源的属性,因此我们为每个环境提供了一个清单。但是,清单将仅包含资源之间的差异。basekustomization.yamloverlaysdevtestprodDeploymentService
让我们先看一下目录。base
基本配置
在目录中,该文件如下所示:base deployment.yaml
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
该文件如下所示:service.yaml
yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
name: http
type: LoadBalancer
selector:
app: nginx
现在,为了使 Kustomize 正常工作,我们需要创建一个如下所示的文件:kustomization.yaml
makefile
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
正如我们所看到的,Kustomization 文件像任何其他 Kubernetes 资源一样包含 and 属性。该文件还可以包含多个部分,具体取决于您计划执行的操作。在这种情况下,由于我们只是尝试导入 和 在 Kustomization中,我们使用部分来执行此操作。apiVersion kind Deployment Service resources
当我们在目录上运行命令时,Kustomize 会发出一个清单 yaml,它是两者的组合。kustomize build base
yaml
[root@k8s-master kustomize-example-app]# kustomize build base
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
name: nginx-service
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
name: nginx-deployment
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
现在,让我们继续看一下特定于环境的配置。
特定于环境的配置
现在,我们将专注于目录。我们在目录中有 、 和 环境的目录。让我们先看一下目录的内容overlays下的 test prod dev
目录
dev配置
该文件如下所示:namespace.yaml
vbnet
apiVersion: v1
kind: Namespace
metadata:
name: dev
现在,这在基本配置中不存在,因为命名空间将随环境而变化。
现在让我们看一下文件:kustomization.yaml
vbnet
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../../base
commonLabels:
env: dev
resources:
- namespace.yaml
namespace: dev
在这里,您可以看到有几个部分。让我们详细看看它们中的每一个:
bases
--- 本节包含对目录的引用。base
commonLables
--- 本节定义了我们要应用于 Kustomize 生成的所有资源的任何通用标签。根据我们的要求,我们给出了标签。env:dev
resources
--- 此部分包含我们要添加到 Kustomize 配置的任何其他资源。由于我们将该文件作为我们在此处指定的附加清单文件。namespace.yaml
namespace
--- 本节定义应在其中部署资源的任何公共命名空间。在本例中,它是 .dev
现在,让我们在目录上运行,看看我们得到了什么:kustomize build dev
yaml
[root@k8s-master kustomize-example-app]# kustomize build overlays/dev
# Warning: 'bases' is deprecated. Please use 'resources' instead. Run 'kustomize edit fix' to update your Kustomization automatically.
apiVersion: v1
kind: Namespace
metadata:
labels:
env: dev
name: dev
---
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
env: dev
name: nginx-service
namespace: dev
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
env: dev
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
env: dev
name: nginx-deployment
namespace: dev
spec:
replicas: 1
selector:
matchLabels:
app: nginx
env: dev
template:
metadata:
labels:
app: nginx
env: dev
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
而且,正如我们所看到的,它满足了我们的所有要求。
应用于 Kubernetes 集群,我们可以使用以下 kubectl 命令:
bash
[root@k8s-master kustomize-example-app]# kubectl apply -k overlays/dev
namespace/dev created
service/nginx-service created
deployment.apps/nginx-deployment created
如我们所见,所有三个资源都已创建。让我们使用以下方法列出命名空间中的所有资源:dev
ini
[root@k8s-master kustomize-example-app]# kubectl get all -n dev --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod/nginx-deployment-555db98ddf-sn6gw 1/1 Running 0 24s app=nginx,env=dev,pod-template-hash=555db98ddf
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELS
service/nginx-service LoadBalancer 10.104.190.68 192.168.26.21 80:31671/TCP 24s app=nginx,env=dev
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
deployment.apps/nginx-deployment 1/1 1 1 24s app=nginx,env=dev
NAME DESIRED CURRENT READY AGE LABELS
replicaset.apps/nginx-deployment-555db98ddf 1 1 1 24s app=nginx,env=dev,pod-template-hash=555db98ddf
创建的内容如上,并包含标签 。Deployment Pod Service dev env:dev
现在,下面创建test
配置
test配置
在目录中,我们有以下文件:test namespace.yaml
vbnet
apiVersion: v1
kind: Namespace
metadata:
name: test
除此之外,我们还有以下文件:deployment.yaml
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment # necessary for Kustomize identification
spec:
replicas: 2
之所以在这里有一个文件,是因为我们想将测试环境中的副本数从 1 更改为 2。deployment.yaml
现在,让我们看一下文件:kustomization.yaml
vbnet
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../../base
commonLabels:
env: test
resources:
- namespace.yaml
namespace: test
patchesStrategicMerge:
- deployment.yaml
大多数部分类似于开发文件。但是,我们在这里还有一个附加部分,即。在其中,我们声明了仅包含增量配置(补丁)的文件,即副本数。将修补与资源 、 匹配的所有资源,并使用修补程序 yaml 文件中声明的配置。kustomization.yaml patchesStrategicMerge deployment.yaml patchesStrategicMergename kind apiVersion
yaml
[root@k8s-master kustomize-example-app]# kustomize build overlays/test/
# Warning: 'bases' is deprecated. Please use 'resources' instead. Run 'kustomize edit fix' to update your Kustomization automatically.
# Warning: 'patchesStrategicMerge' is deprecated. Please use 'patches' instead. Run 'kustomize edit fix' to update your Kustomization automatically.
apiVersion: v1
kind: Namespace
metadata:
labels:
env: test
name: test
---
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
env: test
name: nginx-service
namespace: test
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
env: test
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
env: test
name: nginx-deployment
namespace: test
spec:
replicas: 2
selector:
matchLabels:
app: nginx
env: test
template:
metadata:
labels:
app: nginx
env: test
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
当我们在目录上运行 kustomize 构建时,我们将得到以下内容:test
现在,让我们 Kubernetes 集群:
bash
[root@k8s-master kustomize-example-app]# kubectl apply -k overlays/test/
namespace/test created
service/nginx-service created
deployment.apps/nginx-deployment created
同样,让我们使用以下命令获取命名空间中部署的所有资源的详细信息:test
bash
[root@k8s-master kustomize-example-app]# kubectl get all -n test --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod/nginx-deployment-7c77bd687d-b8tck 1/1 Running 0 22s app=nginx,env=test,pod-template-hash=7c77bd687d
pod/nginx-deployment-7c77bd687d-k8xxg 1/1 Running 0 22s app=nginx,env=test,pod-template-hash=7c77bd687d
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELS
service/nginx-service LoadBalancer 10.103.91.192 192.168.26.22 80:31759/TCP 23s app=nginx,env=test
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
deployment.apps/nginx-deployment 2/2 2 2 23s app=nginx,env=test
NAME DESIRED CURRENT READY AGE LABELS
replicaset.apps/nginx-deployment-7c77bd687d 2 2 2 22s app=nginx,env=test,pod-template-hash=7c77bd687d
正如我们所看到的,这次我们有两个正在运行的副本。Deployment
现在让我们转到 prod 示例。
prod配置
prod 目录包含类似于 和 的配置:namespace.yaml test dev
vbnet
apiVersion: v1
kind: Namespace
metadata:
name: prod
它还包含以下修补程序清单:deployment.yaml
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment # necessary for Kustomize identification
spec:
replicas: 3
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
此修补程序包含三个副本,以及类型为 、1 和 1 的部署部分。Deployment strategy RollingUpdate maxSurge maxUnavailable
现在让我们看一下文件:kustomization.yaml
vbnet
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../../base
commonLabels:
env: prod
resources:
- namespace.yaml
namespace: prod
patchesStrategicMerge:
- deployment.yaml
这个类似于我们在.现在,让我们继续运行,看看如果应用它会得到什么。test kustomize build
yaml
[root@k8s-master kustomize-example-app]# kustomize build overlays/prod
# Warning: 'bases' is deprecated. Please use 'resources' instead. Run 'kustomize edit fix' to update your Kustomization automatically.
# Warning: 'patchesStrategicMerge' is deprecated. Please use 'patches' instead. Run 'kustomize edit fix' to update your Kustomization automatically.
apiVersion: v1
kind: Namespace
metadata:
labels:
env: prod
name: prod
---
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx
env: prod
name: nginx-service
namespace: prod
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
env: prod
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx
env: prod
name: nginx-deployment
namespace: prod
spec:
replicas: 3
selector:
matchLabels:
app: nginx
env: prod
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
labels:
app: nginx
env: prod
spec:
containers:
- image: nginx
name: nginx
ports:
- containerPort: 80
正如我们所看到的,和部分已正确填充。现在,让我们继续使用以下命令应用它:replicasstrategy
bash
[root@k8s-master kustomize-example-app]# kubectl apply -k overlays/prod
namespace/prod created
service/nginx-service created
deployment.apps/nginx-deployment created
现在,让我们列出命名空间中的所有资源,并亲自查看:prod
ini
[root@k8s-master kustomize-example-app]# kubectl get all -n prod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod/nginx-deployment-644c4874df-89gxh 0/1 ContainerCreating 0 20s app=nginx,env=prod,pod-template-hash=644c4874df
pod/nginx-deployment-644c4874df-d9c8d 0/1 ContainerCreating 0 20s app=nginx,env=prod,pod-template-hash=644c4874df
pod/nginx-deployment-644c4874df-mgstm 0/1 ContainerCreating 0 20s app=nginx,env=prod,pod-template-hash=644c4874df
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE LABELS
service/nginx-service LoadBalancer 10.101.189.133 192.168.26.23 80:32332/TCP 21s app=nginx,env=prod
NAME READY UP-TO-DATE AVAILABLE AGE LABELS
deployment.apps/nginx-deployment 0/3 3 0 20s app=nginx,env=prod
NAME DESIRED CURRENT READY AGE LABELS
replicaset.apps/nginx-deployment-644c4874df 3 3 0 20s app=nginx,env=prod,pod-template-hash=644c4874df
而且,正如我们所看到的,我们现在有三个副本正在运行。Pod
让我们尝试使用 来访问端点,看看我们得到什么:Service curl
xml
[root@k8s-master kustomize-example-app]# curl 192.168.26.23
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Nginx正常响应
结论
显然,这是对Kustomize是什么以及我们如何有效地使用它的先睹为快。还有很多其他的方法和方式可以使用Kustomize,我认为这将是未来故事中探索的有趣作品。