たとえば、デプロイメントyamlファイル:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: guestbook
spec:
replicas: 2
template:
metadata:
labels:
app: guestbook
spec:
container:
- name: guestbook
image: {{Here want to read value from config file outside}}
KubernetesにはConfigMap
機能がありますが、これはyamlファイルにキー/値も書き込みます。キーを環境変数に設定する方法はありますか?
Kubernetesの変数または構成マップを使用してイメージを設定することは不可能だと思います。しかし、たとえば Helm を使用して、展開をより柔軟で構成可能なものにすることができます。
自動的に実行することはできません。外部スクリプトを使用してテンプレートを「コンパイル」するか、@ Jakubが提案するhelmを使用する必要があります。
CIパイプラインと統合されたカスタムbashスクリプトを使用することもできます。
あなたが提供したものと非常によく似たdeploy.yml.template
というテンプレートymlファイルが与えられた場合、次のようなものを使用できます:
#!/bin/bash
# sample value for your variables
MYVARVALUE="nginx:latest"
# read the yml template from a file and substitute the string
# {{MYVARNAME}} with the value of the MYVARVALUE variable
template=`cat "deploy.yml.template" | sed "s/{{MYVARNAME}}/$MYVARVALUE/g"`
# apply the yml with the substituted value
echo "$template" | kubectl apply -f -
1行:
cat app-deployment.yaml | sed "s/{{BITBUCKET_COMMIT}}/$BITBUCKET_COMMIT/g" | kubectl apply -f -
Yamlの場合:
...
containers:
- name: ulisses
image: niceuser/niceimage:{{BITBUCKET_COMMIT}}
...
デプロイ時にenvsubst
を使用することもできます。
例えば.
cat $app/deployment.yaml | envsubst | kubectl apply ...
ファイル内のすべての変数をその値で置き換えます。複数の環境にデプロイする際にCIでこのアプローチを使用し、CI_TAGなどをデプロイメントに挿入することに成功しています。
私のアプローチ:
tools/jinja2-cli.py
:
#!/usr/bin/env python3
import os
import sys
from jinja2 import Environment, FileSystemLoader
sys.stdout.write(Environment(loader=FileSystemLoader('templates/')).from_string(sys.stdin.read()).render(env=os.environ) + "\n")
ルールを作る:
_GENFILES = $(basename $(TEMPLATES))
GENFILES = $(_GENFILES:templates/%=%)
$(GENFILES): %: templates/%.j2 $(MKFILES) tools/jinja2-cli.py .env
env $$(cat .env | xargs) tools/jinja2-cli.py < $< > $@ || (rm -f $@; false)
.j2
テンプレートファイル内では、任意のjinja構文構成を使用できます。 {{env.GUEST}}
は、.env
で定義されているGUEST
の値に置き換えられます
したがって、templates/deploy.yaml.j2
は次のようになります。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: guestbook
spec:
replicas: 2
template:
metadata:
labels:
app: guestbook
spec:
container:
- name: guestbook
image: {{env.GUEST}}
別のアプローチ(bash
ビルトインとxargs
のみを使用する)は、
env $(cat .env | xargs) cat <<EOF | kubectl create -f -
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: guestbook
spec:
replicas: 2
template:
metadata:
labels:
app: guestbook
spec:
container:
- name: guestbook
image: ${GUEST}
EOF
kubetpl を使用しています
3つの異なるテンプレートフレーバーがあり、ConfigMap/Secretフリーズをサポートしています。
kubectl_create
というスクリプトを作成し、それを使用してcreateコマンドを実行します。環境変数で参照されているテンプレートの値を置換します。
#!/bin/bash
set -e
eval "cat <<EOF
$(<$1)
EOF
" | kubectl create -f -
たとえば、テンプレートファイルに次のものがある場合:
apiVersion: v1
kind: Service
metadata:
name: nginx-external
labels:
app: nginx
spec:
loadBalancerIP: ${PUBLIC_IP}
type: LoadBalancer
ports:
- name: http
port: 80
targetPort: 80
- name: https
port: 443
targetPort: 443
selector:
app: nginx
kubectl_create nginx-service.yaml
を実行すると、実際のkubectl createコマンドを実行する前に、環境変数PUBLIC_IPが置き換えられます。
ヘルムはまさにそのようなことを目的としています。複雑な一連のリソース展開をグループなどとして処理します。
しかし、私たちがまだいくつかの簡単な代替案を探しているなら、antを使用してはどうでしょうか?
ビルドプロセスまたはテストプロセスの一部としてファイルを変更する場合は、antタスクを使用することもできます。
Antを使用すると、すべての環境値をプロパティとしてロードできます。または、次のようなプロパティファイルを単にロードできます。
<property environment="env" />
<property file="build.properties" />
次に、テンプレートファイルを目的のyamlファイルに変換するターゲットを設定できます。
<target name="generate_from_template">
<!-- Copy task to replaces values and create new file -->
<copy todir="${dest.dir}" verbose="true" overwrite="true" failonerror="true">
<!-- List of files to be processed -->
<fileset file="${source.dir}/xyz.template.yml" />
<!-- Mapper to transform filename. Removes '.template' from the file
name when copying the file to output directory -->
<mapper type="regexp" from="(.*).template(.*)" to="\1\2" />
<!-- Filter chain that replaces the template values with actual values
fetched from properties file -->
<filterchain>
<expandproperties />
</filterchain>
</copy>
</target>
もちろん、複数のファイル(ネストされたファイルなど)の値を動的に変更する場合は、fileset
の代わりにfile
を使用できます。
テンプレートファイルxyz.template.yml
は次のようになります。
apiVersion: v1
kind: Service
metadata:
name: ${XYZ_RES_NAME}-ser
labels:
app: ${XYZ_RES_NAME}
version: v1
spec:
type: NodePort
ports:
- port: ${env.XYZ_RES_PORT}
protocol: TCP
selector:
app: ${XYZ_RES_NAME}
version: v1
env.
プロパティは環境変数からロードされ、その他はプロパティファイルからロードされます
それが助けたことを願っています:)
Kubectl_applyというスクリプトを作成します。 .envから変数をロードし、ymlの$ {CUSTOMVAR}を置き換えてkubectlコマンドに渡します
#!/bin/bash
set -a
source .env
set +a
eval "cat <<EOF
$(<$1)
EOF
" | kubectl apply -f -