ksaitoの日記

日々試したことの覚え書き

テンプレートに環境変数を埋め込む。

Dockerコンテナを作るときに環境変数を使ってテンプレートから設定ファイルを作成します。

やりたいことは、次の2つなのですが、手軽な方法が見つかりません。

結局、ansibleのJinja2を使って次のようにしました。

テンプレートとplaybook

下記のようにテンプレートのtest.cfgとplaybookのmain.yamlを準備します。

$ cat templates/test.cfg
test={{ aaa }}
$ cat main.yaml
---
- name: setup proxy
  hosts: all
  vars:
    aaa: "{{ lookup('env', 'AAA') | ternary(lookup('env', 'AAA'), 'default value') }}"
  tasks:
    - name: test
      debug: msg="value is {{ aaa }}"
    - template:
        src: test.cfg
        dest: /tmp/test.cfg
$

動作確認

環境変数がなければ、ternaryのfalse側の値がデフォルト値として採用され、環境変数が定義されていれば、環境変数の値が埋め込まれます。

$ ansible-playbook -i "localhost," -c local main.yaml > /dev/null  && cat /tmp/test.cfg
test=default value
$ AAA="env value" ansible-playbook -i "localhost," -c local main.yaml > /dev/null  && cat /tmp/test.cfg
test=env value
$

下記のような不満は、ちょっとありますが、一番良さそう。

  • 環境変数の表現が長い(lookup(env, "環境変数")には省略形がほしい)
  • デフォルト値のternaryには、ちょっと馴染めない。
  • varsへの設定ではなく、テンプレート側に埋め込みたい

他に試した方法

envsubst

envsubstコマンドは、aptでインストール可能で、環境変数を${変数名}で置換するので最有力でしたが、デフォルト値が設定できなかったり、エスケープの問題が解決できず断念しまいた。

entrykit

DockerのEntrypointのための専用ツール、Jinja2風のテンプレート表記でデフォルト値の設定も可能と機能的には申し分なしでしたが、パッケージからのインストールができず、curl + tarが残念、また、Entrypointの表記が、ちょっと受け入れられなかった。

以上

kubectlのデフォルト環境

kubernetesで複数のクラスタを作成すると、kubectlコマンドで操作対象にするクラスタやネームスペースを選択するのが煩雑になります。

kubectl config set-contextでコンテキストにクラスタとネームスペースの組み合わせに名前をつけて切り替えられるようになるので便利です。

最初の環境

下記のように、最初に作成したクラスタとdefaultネームスペースが捜査の対象になります。

$ kubectl config get-contexts 
CURRENT   NAME      CLUSTER   AUTHINFO     NAMESPACE
*         sandbox   sandbox   user-6ds5r

コンテキストの作成

kubectl config set-contextコマンドで、クラスタとネームスペースの組み合わせに名前をつけます。

下記のようにsandboxクラスタのjenkinsネームスペースにjenkinsというコンテキスト名を付けます。

kubectl config set-context jenkins --cluster=sandbox --namespace=jenkins --user=user-6ds5r
$ kubectl config get-contexts 
CURRENT   NAME      CLUSTER   AUTHINFO     NAMESPACE
          jenkins   sandbox   user-6ds5r   jenkins
*         sandbox   sandbox   user-6ds5r
$

コンテキストの使用

kubectl config use-contextでコンテキストを切り替えます。

これで、kubectlコマンドの操作対象がsandboxクラスタのjenkinsネームスペースになります。

$ kubectl config use-context jenkins 
Switched to context "jenkins".
$ kubectl config current-context 
jenkins
$ kubectl config get-contexts 
CURRENT   NAME      CLUSTER   AUTHINFO     NAMESPACE
*         jenkins   sandbox   user-6ds5r   jenkins
          sandbox   sandbox   user-6ds5r 
$

以上

kubernetesのclusterとnamespaceとcontextの操作を整理

clusternamespacecontextの操作について整理します。

cluster

クラスタを一覧します。

kubectl config get-clusters

クラスタは、サーバの集まりなので、同じクラスタで動くワークロードはサーバリソースを共有します。負荷テスト用、開発用、本番用など、負荷とコストのバランスを考慮してクラスタを考える必要があります。

namespace

ネームスペースを一覧します。

$ kubectl get namespaces 
NAME            STATUS    AGE
default         Active    27m
ingress-nginx   Active    26m
kube-public     Active    27m
kube-system     Active    27m
$

ネームスペースは、クラスタに作成するリソースを入れるフォルダのようなものです。システム毎に作成して、他のシステムのリソースと分離することができます。

コンテキスト

コンテキストの一覧を表示します。

$ kubectl config get-contexts 
CURRENT   NAME      CLUSTER   AUTHINFO     NAMESPACE
*         Default   local     kube-admin
$

コンテキストでデフォルトで利用するクラスタとネームスペースを指定できます。

jenkins用の環境を作る場合には、次のようにします。

$ kubectl create namespace jenkins
namespace/jenkins created
$ kubectl config set-context my-jenkins --cluster=local --namespace=jenkins
Context "my-jenkins" created.
$ kubectl config use-context my-jenkins 
Switched to context "my-jenkins".
$ kubectl config get-contexts 
CURRENT   NAME         CLUSTER   AUTHINFO     NAMESPACE
          Default      local     kube-admin   
*         my-jenkins   local                  jenkins
$ kubectl config current-context 
my-jenkins
$

以上

kubbectl cluster-info dumpのエラー

kubectl cluster-info dumpしたらエラーになりました。

$ kubectl cluster-info dump
error: missing apiVersion or kind and cannot assign it; no kind is registered for the type core.NodeList

バージョンは以下の通り

$ kubectl version --short
Client Version: v1.11.1
Server Version: v1.11.1
$

バージョンアップしたらエラーはなくなりました。

$ kubectl version --short
Client Version: v1.11.3
Server Version: v1.11.1
$ kubectl cluster-info dump | head -3
{
    "kind": "NodeList",
    "apiVersion": "v1",
$

docker buildkit

dockerのbuildkitを使ってみました。

試した環境は、下記の環境で、手持ちのDockerfileをビルドして、時間とサイズを比較してみました。

$ docker --version
Docker version 18.06.0-ce, build 0ffa825
$ 

従来のビルド

$ time docker build -t test --no-cache .
... 中略...

real    9m52.781s
user    0m1.090s
sys     0m0.760s
$ docker images | grep test
test  latest  a5b8c348f848  About a minute ago   1.92GB
$ 

BuildKitを使ったビルド

$ export DOCKER_BUILDKIT=1
$ time docker build -t test --no-cache .
... 中略...

real    9m24.446s
user    0m2.170s
sys     0m4.190s
$ docker images | grep test
test  latest  2e612a3380d0  About a minute ago   1.92GB
$

DockerfileにADDでURLから取得する処理が多かったので若干早くなった程度でした。 ビルドの経過がステップごとに表示され、可能な部分は並列で実行していることがわかります。 ステップごとの処理時間がわかりやすく表示されるので、Dockerfileから削除しても良さそうな処理に気が付きやすいです。

デフォルトで使っていこう。

Amazon Linux 2のdocker環境をすばやく立ち上げる

EC2Launch Templatesを使ってAmazon Linux 2docker環境をすばやく立ち上げます。

設定は、次の項目です。

ユーザデータは、下記のような感じです。

$ curl http://169.254.169.254/latest/user-data/
#! /bin/bash

echo Install docker-ce
amazon-linux-extras install docker
systemctl start docker
systemctl enable docker
usermod -aG docker ec2-user

echo AWS_DEFAULT_REGION=ap-northeast-1
$

30秒で支度できます。

$ tail -1 /var/log/cloud-init-output.log 
Cloud-init v. 18.2-72.amzn2.0.6 finished at Wed, 05 Sep 2018 09:48:05 +0000. Datasource DataSourceEc2.  Up 30.52 seconds
$ 

バージョン管理もでき、地味に便利なのですが、下記は改善してほしいです。

  • 設定のエクスポートが部分的にしかできない(他のアカウントやリージョンと共有したい)
  • デフォルトバージョンを指定してもバージョンの指定が必要

以上

githubのpull requestをローカルにチェックアウトする

githubのpull requestをローカルにチェックアウトします。 オフシャルの手順は、下記のリンクです。

github.com

maven-scmの#31のpull requestをチェックアウトしました。

最初にgithubmaven-scmのリポジトリをforkします。 その後で、次のような手順で#31のpull requestがを

  • forkしたリポジトリをcloneする
  • upstreamを追加する
  • pull requestをfetchする
  • fetchしたpull requestをチェックアウトする
git clone https://github.com/githubユーザ/maven-scm.git
git remote add upstream https://github.com/apache/maven-scm.git
git fetch upstream pull/31/head:pr31-maven-scm
git checkout pr31-maven-scm

#31mavenのローカルリポジトリにインストールします。

mvn install -DskipTests=true

1.9.5-SNAPSHOTが作成されました。

$ ls -t ~/.m2/repository/org/apache/maven/plugins/maven-scm-plugin | head -1
1.9.5-SNAPSHOT
$

以上