kustomize是sig-cli的一个子项目,它的设计目的是给kubernetes的用户提供一种可以重复使用同一套配置的声明式应用管理,从而在配置工作中用户只需要管理和维护kubernetes的API对象,而不需要学习或安装其它的配置管理工具,也不需要通过复制粘贴来得到新的环境的配置。
当我们运行一个kubernetes环境的时候,我们需要一些含有API对象的YAML文件,这些文件中规定了要部署什么样的应用,需要多少份副本,开辟多大的存储空间,分配多少内存和CPU等信息。通过修改这些YAML文件的内容我们可以对这些信息进行相应的改动,比如我们需要增加一个副本,就需要修改对应YAML文件的replica数值;如果我们需要部署最新版本的docker镜像,就需要修改对应YAML文件中的docker镜像的版本或标签。我们可以把所有这些为了满足需求而进行的修改成为自定义kubernetes的配置。
在我们开发一个微服务架构的应用的过程中,我们会创建一些YAML文件来部署一个开发的环境,在这个环境下,我们需要进行各种测试。一旦所有的测试达到了我们的预期,我们就会把这个应用部署到生产环境。因为我们已经有了一套开发环境的配置,我们可以通过复制这些配置,再进行生产环境下的自定义,就可以得倒一套用于生产环境的配置。
然而这种方法的可扩展性并不好,当我们的微服务数量很多或者环境数量很多时,我们就有许多套的配置,这些配置只有细微的差别,而在很大程度上都一样。当我们对配置进行改动或者升级的时候,就非常容易漏掉一些改动或者实施了额外的甚至是错误的改动。我们来看两个简单的例子。
假如我们有一个应用,我们已经把它部署在十个不同的环境中,每一个环境的配置都是通过复制,粘贴和修改得到的。每个环境中所运行的应用版本号都是1.0,现在我们想把所有环境中的版本号升级到2.0。我们就需要修改对应每一个环境下该应用的版本号。这不是一个复杂的改动,我们可以对每一个环境依次进行修改,所有的改动很快就可以完成。但是在这个过程中我们很有可能只修改了其中的九个环境而漏掉了一个;我们也很有可能把其中一个版本号改成2,0。
我们再来看另外一个例子。在小王通过复制,粘贴和修改所得到的一个配置中,小李是没有办法区分哪些值是保持不变,而哪些值是被修改过的。当小李想要修改这个新的配置时,他不知道哪些可以安全地改动而那些可能会影响的当前环境的正确运行。
kustomize允许用户将不同环境所共享的配置放在一个文件目录下,而将其他不同的配置放在另外的目录下。这样用户就可以很容易的区分那些值是当前环境所特有的,从而在修改的时候会额外关注。kustomize可以非常好地解决这些问题。
重要概念
kustomization:kustomization.yaml文件,一个含有kustomization.yaml的目录可以运行 kustomize build。kustomization.yaml的一个例子如下
bases:
- /config/myapp1/base
- /config/myapp2/base
resources:
- service.yaml
- deployment.yaml
patches:
- patch.yaml
namePrefix: my-
base:含有一个kustomization.yaml文件的目录,可以被其他的kustomization.yaml来引用
resource:文件路径,指向一个声明了kubernetes API对象的YAML文件
patch: 文件路径,指向一个声明了kubernetes API patch的YAML文件
variant: 含有同一组bases的不同kustomization
安装
你可以通过如下两种不同方式来安装kustomize, kustomize只包含有一个二进制可执行文件,所以可以非常容易地安装和使用。
下载压缩包,kustomize提供Linux,Darwin,和windows三个版本的压缩包。
如果你的Go的版本在1.10.1以上,你可以通过 go get来直接安装
go get github.com/kubernetes-sigs/kustomize
使用
Kustomize 命令行包含build, diff, edit, version,help等子命令,其中最常使用的是build子命令。
kustomize --help
kustomize manages declarative configuration of Kubernetes.
See https://github.com/kubernetes-sigs/kustomize
Usage:
kustomize [command]
Available Commands:
build Print current configuration per contents of kustomization.yaml
diff diff between customized resources and uncustomized resources
edit Edits a kustomization file
help Help about any command
version Prints the kustomize vers\
下面我们来用kustomize连建立一个LDAP的base和用于开发环境与生产环境的两个不同的variants。
首先我们来创建一个工作空间,用来存储base和两个不同的variants。
DEMO_HOME=$(mktemp -d)
BASE=$DEMO_HOME/base
mkdir -p $BASE
OVERLAYS=$DEMO_HOME/overlays
mkdir -p $OVERLAYS/dev
mkdir -p $OVERLAYS/production
创建base
我们从kustomize的repo中下载一些YAML文件到base目录
CONTENT="https://raw.githubusercontent.com\
/kubernetes-sigs/kustomize\
/master/examples/ldap"
curl -s -o "$BASE/#1" "$CONTENT/base\
/{deployment.yaml,kustomization.yaml,service.yaml,env.startup.txt}"
现在base目录包含如下的文件
/tmp/tmp.IyYQQlHaJP
└── base
├── deployment.yaml
├── env.startup.txt
├── kustomization.yaml
└── service.yaml
其中的自定义文件kustomization.yaml包含如下内容
resources:
-deployment.yaml
-service.yaml
configmapGenerator:
-name: ldap-configmap
files:
-env.startup.txt
从这个内容上可以看出这个配置包含一个deployment的对象,一个service对象和一个configmap的对象,configmap的数据是从文件env.startup.txt中读取。我们可以运行如下kustomize命令来看完整的配置
Kustomize build $BASE
我们还可以通过如下命令来部署这个base环境到kubernertes集群上
Kustomize build $BASE | kubectl apply -f -
下面我们将两个适用于不同环境的自定义,这两个自定义都是基于同一个base。
创建开发环境的自定义
下载开发环境对应的布丁及文件
curl -s -o “$OVERLAYS/dev/#1” “$CONTENT/overlays/staging\
/{config.env,deployment.yaml,kustomization.yaml}”
开发环境的dev目录包含如下文件
/tmp/tmp.IyYQQlHaJP
└── overlays
└── dev
├── config.env
├── deployment.yaml
└── kustomization.yaml
这里的kustomization.yaml文件包含如下内容
bases:
- ../../base
patches:
- deployment.yaml
nameprefix: dev-
configmapGenerator:
- name: env-config
files:
config.env
这个自定义是在base的基础上添加一个名字前缀,添加了一个configmap,并且还通过补丁修改了deployment对象,这里进行的改动是将副本增加到2个
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: ldap
spec:
replicas: 2
我们可以运行如下kustomize命令来看完整的开发环境的配置
kustomize build $OVERLAYS/dev
我们还可以通过如下命令来将这个开发环境部署到kubernertes集群上
kustomize build $OVERLAYS/dev | kubectl apply -f -
创建生产环境的自定义
下载生产环境对应的补丁及文件
curl -s -o "$OVERLAYS/production/#1" "$CONTENT/overlays/production\
/{deployment.yaml,kustomization.yaml}"
生产环境的production目录包含如下文件
/tmp/tmp.IyYQQlHaJP1
└── overlays
├── production
├── deployment.yaml
└── kustomization.yaml
这里的kustomization.yaml文件包含如下内容
bases:
- ../../base
patches:
- deployment.yaml
namePrefix: production-
这里的自定义是在base的基础上添加一个名字前缀,并且通过补丁修改了deployment对象,所进行的改动有两个: 将副本增加到6个; 添加了一个持久存储
apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: ldap
spec:
replicas: 6
template:
spec:
volumes:
- name: ldap-data
emptyDir: null
gcePersistentDisk:
pdName: ldap-persistent-storage
类似的,我们可以运行如下kustomize命令来看完整的生产环境的配置
kustomize build $OVERLAYS/production
我们还可以通过如下命令来将这个生产环境部署到kubernertes集群上
kustomize build $OVERLAYS/production | kubectl apply -f -
比较不同环境
我们还可以通过 kustomize build 来比较不同环境下的配置,命令如下
diff \
<(kustomize build $OVERLAYS/dev) \
<(kustomize build $OVERLAYS/production) |\
more
我们将看到如下输出
(...truncated)
< name: dev-ldap-configmap-kftftt474h
---
> name: production-ldap-configmap-k27f7hkg4f
85c75
< name: dev-ldap-service
---
> name: production-ldap-service
97c87
< name: dev-ldap
---
> name: production-ldap
99c89
< replicas: 2
---
参考资料
introducing-kustomize-template-free-configuration-customization-for-kubernetes
github.com/kubernetes-sigs/kustomize