-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
441 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,230 @@ | ||
[overlay]: ../docs/glossary.md#overlay | ||
[target]: ../docs/glossary.md#target | ||
|
||
# 示例:devops和开发配合管理配置数据 | ||
|
||
场景:你在生产环境中有一个基于 Java 由多个内部开发团队(注册、结账和搜索等)开发的商店。 | ||
|
||
这个服务在不同的环境中运行:_development_、 _testing_、 _staging_ 和 _production_,从 Java 的 properties 文件中读取配置。 | ||
|
||
为每个环境维护一个大的 properties 文件时很困难的。这个文件需要频繁的修改,并且这些修改都需要由 devops 工程师来进行,因为: | ||
|
||
1. 这个文件包含 devops 工程师需要知道,而开发人员不必知道的值 | ||
2. 比如生产环境的 properties 包含敏感数据,比如生产数据库的登录凭据。 | ||
|
||
## Property sharding | ||
|
||
通过一些研究,我们注意到属性可以分为不同的类别。 | ||
|
||
### Property sharding | ||
|
||
例如:国际化数据、物理常量,外部服务位置等静态数据。 | ||
|
||
_这些无论哪个环境,都一样的配置。_ | ||
|
||
这些都只需要一组配置。将这组配置放在一个文件中: | ||
|
||
* `common.properties` | ||
|
||
### Plumbing properties | ||
|
||
例如:静态资源(HTML、CSS、JavaScript)的位置,产品和用户的数据表,负载均衡的端口,日志收集等。 | ||
|
||
_这些属性的不同,恰恰是环境的不同之处。_ | ||
|
||
DevOps 或 SRE 工程师需要完全控制生产环境中的这些配置;测试需要调整数据库来支持测试;而开发则希望尝试开发中遇到的各种不同的情景。 | ||
|
||
将这些值放入 | ||
|
||
* `development/plumbing.properties` | ||
* `staging/plumbing.properties` | ||
* `production/plumbing.properties` | ||
|
||
|
||
### Secret properties | ||
|
||
例如:用户表的位置、数据库凭证、解密密钥等。 | ||
|
||
_这些需要 devops 工程师控制,其他人没有访问权限。_ | ||
|
||
将这些值放入 | ||
|
||
* `development/secret.properties` | ||
* `staging/secret.properties` | ||
* `production/secret.properties` | ||
|
||
[kubernetes secret]: https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/ | ||
|
||
例如使用 unix 文件权限和模式来限制访问控制,或者使用更好的方法-使用专门用于存储密码的服务,并且使用 kustomize 中的 `secretGenerator` 字段在 Kubernetes 中创建 secret 来存储密码。 | ||
|
||
<!-- | ||
secretGenerator: | ||
- name: app-tls | ||
files: | ||
tls.crt=tls.cert | ||
tls.key=tls.key | ||
type: "kubernetes.io/tls" | ||
EOF | ||
--> | ||
|
||
## 混合管理方法 | ||
|
||
基于相同的 base 创建 _n_ 个 overlays 来创建 _n_ 个集群环境的方法。 | ||
|
||
在本例的其余部分,我们将使用 _n==2_,这里只使用 _development_ 和 _production_ ,可以使用相同的方法来增加更多的环境。 | ||
|
||
运行 `kustomize build` 基于 [overlay] 的 [target] 来创建集群环境。 | ||
|
||
[helloworld]: helloWorld.md | ||
|
||
以下示例将执行此操作,但将侧重于 configMap 构建,而不用担心如何将 configMaps 关联到 Deployment([helloworld] 示例中介绍的)。 | ||
|
||
所有文件(包括共享 property 文件)都将在目录树中创建,目录中包含 base 和 overlay 文件的目录,这些都与 [helloworld] 中演示的一致。 | ||
|
||
它将全部存在于此工作目录中: | ||
|
||
<!-- @makeWorkplace @test --> | ||
```bash | ||
DEMO_HOME=$(mktemp -d) | ||
``` | ||
|
||
### 创建 base | ||
|
||
<!-- kubectl create configmap BOB --dry-run -o yaml --from-file db. --> | ||
|
||
创建放置 base 配置的路径: | ||
|
||
<!-- @baseDir @test --> | ||
```bash | ||
mkdir -p $DEMO_HOME/base | ||
``` | ||
|
||
向 base 中的插入数据,base 中应该包含所有环境共有的资源,这里我们只定义一个 java properties 文件,以及一个引用他们的 `kustomization` 文件。 | ||
|
||
<!-- @baseKustomization @test --> | ||
```bash | ||
cat <<EOF >$DEMO_HOME/base/common.properties | ||
color=blue | ||
height=10m | ||
EOF | ||
|
||
cat <<EOF >$DEMO_HOME/base/kustomization.yaml | ||
configMapGenerator: | ||
- name: my-configmap | ||
files: | ||
- common.properties | ||
EOF | ||
``` | ||
|
||
### 创建并使用 overlay 用于 _开发_ | ||
|
||
创建一个 overlays 目录: | ||
|
||
<!-- @overlays @test --> | ||
```bash | ||
OVERLAYS=$DEMO_HOME/overlays | ||
``` | ||
|
||
创建 _development_ overlay: | ||
|
||
<!-- @developmentFiles @test --> | ||
```bash | ||
mkdir -p $OVERLAYS/development | ||
|
||
cat <<EOF >$OVERLAYS/development/plumbing.properties | ||
port=30000 | ||
EOF | ||
|
||
cat <<EOF >$OVERLAYS/development/secret.properties | ||
dbpassword=mothersMaidenName | ||
EOF | ||
|
||
cat <<EOF >$OVERLAYS/development/kustomization.yaml | ||
resources: | ||
- ../../base | ||
namePrefix: dev- | ||
nameSuffix: -v1 | ||
configMapGenerator: | ||
- name: my-configmap | ||
behavior: merge | ||
files: | ||
- plumbing.properties | ||
- secret.properties | ||
EOF | ||
``` | ||
|
||
现在可以生成开发使用的 configMaps : | ||
|
||
<!-- @runDev @test --> | ||
```bash | ||
kustomize build $OVERLAYS/development | ||
``` | ||
|
||
#### 检查 ConfigMap 名称 | ||
|
||
可以在输出中看到生成的 `ConfigMap` 名称。 | ||
|
||
名称应该是这样的:`dev-my-configmap-v1-2gccmccgd5`: | ||
|
||
* `"dev-"` 来自 `namePrefix` 字段 | ||
* `"my-configmap"` 来自 `configMapGenerator/name` 字段 | ||
* `"-v1"` 来自 `nameSuffix` 字段 | ||
* `"-2gccmccgd5"` 为哈希值,是 `kustomize` 根据 configMap 的内容计算的 | ||
|
||
哈希后缀很关键,如果 configMap 内容发生变化, configMap 的名称也会发生变化,以及从 `kustomize` 出现在 YAML 输出中的对该名称的所有引用。 | ||
|
||
名称更改意味着如果使用类似命令将此 YAML 应用于群集,则 Deployment 将执行滚动更新重启以获取新数据。 | ||
|
||
> ```bash | ||
> kustomize build $OVERLAYS/development | kubectl apply -f - | ||
> ``` | ||
Deployment 无法自动感知 configMap 是否发生改变。 | ||
|
||
如果更改 configMap 而不更改其名称以及对该名称的所有引用,则必须重新启动以获取更改。 | ||
|
||
最佳的做法就是将 configMap 视为不变的。 | ||
|
||
不去编辑 configMap ,而是使用 _新_ 的名称的 _新_ configMap,并在 Deployment 中引用新的 configMap 。而 `kustomize` 使用 `configMapGenerator` 指令和相关的命名控件使这很容易。k8s master 中的 GC 则会回收并且删除未使用的 configMap 。 | ||
|
||
### 创建并且使用 overlay 用于 _生产_ | ||
|
||
接下来创建 _production_ overlay 的文件: | ||
|
||
<!-- @productionFiles @test --> | ||
```bash | ||
mkdir -p $OVERLAYS/production | ||
|
||
cat <<EOF >$OVERLAYS/production/plumbing.properties | ||
port=8080 | ||
EOF | ||
|
||
cat <<EOF >$OVERLAYS/production/secret.properties | ||
dbpassword=thisShouldProbablyBeInASecretInstead | ||
EOF | ||
|
||
cat <<EOF >$OVERLAYS/production/kustomization.yaml | ||
resources: | ||
- ../../base | ||
namePrefix: prod- | ||
configMapGenerator: | ||
- name: my-configmap | ||
behavior: merge | ||
files: | ||
- plumbing.properties | ||
- secret.properties | ||
EOF | ||
``` | ||
|
||
现在可以生成用于生产的 configMap: | ||
|
||
<!-- @runProd @test --> | ||
```bash | ||
kustomize build $OVERLAYS/production | ||
``` | ||
|
||
可以直接在 CI/CD 流程中执行如下命令,将应用部署到集群: | ||
|
||
> ```bash | ||
> kustomize build $OVERLAYS/production | kubectl apply -f - | ||
> ``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# Generator Options | ||
|
||
Kustomize 提供了修改 ConfigMapGenerator 和 SecretGenerator 行为的选项,这些选项包括: | ||
|
||
- 不再将内容生成的哈希后缀添加到资源名称后 | ||
- 为生成的资源添加 labels | ||
- 为生成的资源添加 annotations | ||
|
||
这个示例将展示如何运用这些选项,首先创建一个工作空间: | ||
```bash | ||
DEMO_HOME=$(mktemp -d) | ||
``` | ||
|
||
创建 kustomization 并且为其添加一个 ConfigMapGenerator | ||
|
||
<!-- @createCMGenerator @test --> | ||
```bash | ||
cat > $DEMO_HOME/kustomization.yaml << EOF | ||
configMapGenerator: | ||
- name: my-configmap | ||
literals: | ||
- foo=bar | ||
- baz=qux | ||
EOF | ||
``` | ||
|
||
添加如下 generatorOptions | ||
<!-- @addGeneratorOptions @test --> | ||
```bash | ||
cat >> $DEMO_HOME/kustomization.yaml << EOF | ||
generatorOptions: | ||
disableNameSuffixHash: true | ||
labels: | ||
kustomize.generated.resource: somevalue | ||
annotations: | ||
annotations.only.for.generated: othervalue | ||
EOF | ||
``` | ||
运行 `kustomize build` 并且确定生成的 ConfigMap 。 | ||
|
||
- 确定没有名称后缀 | ||
<!-- @verify @test --> | ||
``` | ||
test 1 == \ | ||
$(kustomize build $DEMO_HOME | grep "name: my-configmap$" | wc -l); \ | ||
echo $? | ||
``` | ||
- 确定 label `kustomize.generated.resource: somevalue` | ||
``` | ||
test 1 == \ | ||
$(kustomize build $DEMO_HOME | grep -A 1 "labels" | grep "kustomize.generated.resource" | wc -l); \ | ||
echo $? | ||
``` | ||
- 确定 annotation `annotations.only.for.generated: othervalue` | ||
``` | ||
test 1 == \ | ||
$(kustomize build $DEMO_HOME | grep -A 1 "annotations" | grep "annotations.only.for.generated" | wc -l); \ | ||
echo $? | ||
``` | ||
|
Oops, something went wrong.