web-dev-qa-db-ja.com

Kubernetes yamlファイルで動的な値を設定する方法は?

たとえば、デプロイメント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ファイルにキー/値も書き込みます。キーを環境変数に設定する方法はありますか?

25
online

Kubernetesの変数または構成マップを使用してイメージを設定することは不可能だと思います。しかし、たとえば Helm を使用して、展開をより柔軟で構成可能なものにすることができます。

11
Jakub

自動的に実行することはできません。外部スクリプトを使用してテンプレートを「コンパイル」するか、@ 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 -
25
whites11

1行:

cat app-deployment.yaml | sed "s/{{BITBUCKET_COMMIT}}/$BITBUCKET_COMMIT/g" | kubectl apply -f -

Yamlの場合:

  ...
  containers:
  - name: ulisses
    image: niceuser/niceimage:{{BITBUCKET_COMMIT}}
  ...
9
CelinHC

デプロイ時にenvsubstを使用することもできます。

例えば.

cat $app/deployment.yaml | envsubst | kubectl apply ...

ファイル内のすべての変数をその値で置き換えます。複数の環境にデプロイする際にCIでこのアプローチを使用し、CI_TAGなどをデプロイメントに挿入することに成功しています。

5
M U

私のアプローチ:

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
2
nyet

kubetpl を使用しています

3つの異なるテンプレートフレーバーがあり、ConfigMap/Secretフリーズをサポートしています。

1
Jingshao Chen

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が置き換えられます。

1
Jerry Bowman

ヘルムはまさにそのようなことを目的としています。複雑な一連のリソース展開をグループなどとして処理します。

しかし、私たちがまだいくつかの簡単な代替案を探しているなら、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.プロパティは環境変数からロードされ、その他はプロパティファイルからロードされます

それが助けたことを願っています:)

0
Vikas Tawniya

Kubectl_applyというスクリプトを作成します。 .envから変数をロードし、ymlの$ {CUSTOMVAR}を置き換えてkubectlコマンドに渡します

  #!/bin/bash
  set -a
  source .env
  set +a
  eval "cat <<EOF
  $(<$1)
  EOF
  " | kubectl apply -f -
0