Kubernetesやってみた:kustomize build を導入してサンプルを動かしてみよう

Kubernetesの管理運用に使えるツールの導入と動作確認を実践ベースで紹介します。

こんにちは、grasys社内一のハムスター愛好者と自負している高田です。 今回は、弊社のプロジェクトでも導入しているKubernetesのツール紹介と、実際に導入にツールのインストールやサンプルを動かしていきます。 コマンドの結果や実践中のエラーと対処も合わせて記載している都合、分かりづらい部分もあるかもしれませんが予めご了承ください。

Kubernetesのリソースをカスタムする便利ツールkustomize

kustomize とは

https://github.com/kubernetes-sigs/kustomize

コンテナを管理するためのソフトウェアKubernetesで扱えるツールです。 基盤となるファイルを用意して、オーバーレイする構成をディレクトリ別に分けて、サービスの機能を拡張させることがっできます。 以下のようなニーズにとても効果を発揮します。

  • 必要最小限に作ったPodやSeriviceを土台にして、機能追加したい
  • でも作ったyamlファイルをずっと更新しつづけるなんて非効率で現実的じゃない
  • 開発環境があって、本番環境があって、基本的な構成は同じにしつつ横展開や機能拡張したい

以下前提事項となります。予めご了承ください。

※この記事ではKubernetesの環境構築は割愛します ※ ツール導入ではGKE(Google Kubernetes Engine) on GCE(Google Compute Engine)を実行します ※ 実行環境のOSやClusterのバージョン情報は後ほど記載します

kustomize を導入して動かしてみよう

早速、Kubernetesツールkustomizeの導入方法をご紹介します。

kustomizeを動かすためのサンプルページがあり、そちらに沿って実際にインストールから環境構築、動作確認をしてみたいと思います。

今回私が試した環境・バージョン情報はこのようになっています。

$ cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)

$ docker version
Client:
 Version:         1.13.1
 API version:     1.26

$ kubectl version --short
Client Version: v1.19.3
Server Version: v1.16.13-gke.401

大まかな流れは以下の通りで動かしていきます。

  • kustomizeのインストール
  • baseのセットアップ
  • baseをデプロイして動作確認
  • kustomization.yamlを編集したときの動作確認
  • ovarlayセットアップ
  • ovarlayをデプロイして動作確認

kustomizeのインストール

インストール方法は4種類記載されていますが 今回はbinaryをダウンロードしてインストールします。

https://kubectl.docs.kubernetes.io/installation/kustomize/binaries/ 上記の記載にある通りですが、バイナリファイルを配置したいパスで以下を実行するだけです。

curl -s "https://raw.githubusercontent.com/\
kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"  | bash

バイナリインストールに記載されているコマンドを実行すると、以下のような結果になります。

$ curl -s "https://raw.githubusercontent.com/\
> kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"  | bash
{Version:kustomize/v3.8.7 GitCommit:ad092cc7a91c07fdf63a2e4b7f13fa588a39af4f BuildDate:2020-11-11T23:14:14Z GoOs:linux GoArch:amd64}
kustomize installed to current directory.

実際に動くか確認してみます。

./kustomize

都度都度フルパスで実行するのも面倒なので、パスを通しておきます。※ここからの手順は任意のものです

ログインユーザーの.bash_profileの最終行にkustomizeの実行ファイルパスを追記して保存します。 私のkustomizeのバイナリファイルのパスは/home/takada_grasys_ioですが適宜バイナリインストールしたパスに置き換えてください。

export PATH="/バイナリファイルのパスをフルパスで:$PATH"

保存を反映させます。

source ~/.bash_profile

これでパスが通ったので、こんな感じで実行すると、使い方についての確認結果が得られます。

$ kustomize

Manages declarative configuration of Kubernetes.
See https://sigs.k8s.io/kustomize

Usage:
  kustomize [command]

Available Commands:
  build                     Print configuration per contents of kustomization.yaml
  cfg                       Commands for reading and writing configuration.
  completion                Generate shell completion script
  create                    Create a new kustomization in the current directory
  edit                      Edits a kustomization file
  fn                        Commands for running functions against configuration.
  help                      Help about any command
  version                   Prints the kustomize version

Flags:
  -h, --help          help for kustomize
      --stack-trace   print a stack-trace on error

Additional help topics:
  kustomize docs-fn                   [Alpha] Documentation for developing and invoking Configuration Functions.
  kustomize docs-fn-spec              [Alpha] Documentation for Configuration Functions Specification.
  kustomize docs-io-annotations       [Alpha] Documentation for annotations used by io.
  kustomize docs-merge                [Alpha] Documentation for merging Resources (2-way merge).
  kustomize docs-merge3               [Alpha] Documentation for merging Resources (3-way merge).
  kustomize tutorials-command-basics  [Alpha] Tutorials for using basic config commands.
  kustomize tutorials-function-basics [Alpha] Tutorials for using functions.

Use "kustomize [command] --help" for more information about a command.

うまく行かない場合には、「追記したパス情報が誤っている」「sourceし忘れている」などの可能性があるので確認してリトライしてください。 ※任意の手順はここまでです

kustomizeのサンプル例があります( https://github.com/kubernetes-sigs/kustomize/tree/master/examples/helloWorld )この手順に沿って実際にやっていきます。

baseのセットアップ

まずは構築場所の定義ということで ホームディレクトリ 配下で以下を実行します。

DEMO_HOME=~/hello

※DEMO_HOME=$(mktemp -d)か上記いずれか実行で良いのですが ホームディレクトリ/helloディレクトリ の変数定義のほうが分かりやすそうだったので上記にしました。

続いサンプルのベース側をセットアップしていきます。

#base変数の定義
BASE=$DEMO_HOME/base
#定義変数からディレクトリを作成
mkdir -p $BASE
# サンプルyamlファイルを作成ディレクトリ配下にダウンロード
curl -s -o "$BASE/#1.yaml" "https://raw.githubusercontent.com\
/kubernetes-sigs/kustomize\
/master/examples/helloWorld\
/{configMap,deployment,kustomization,service}.yaml"

以下もサンプルの通りですが、エラーに遭遇しました。

tree $DEMO_HOME
-bash: tree: command not found

今回は上記エラーの対処としてyumのinstall状況を確認し、なければyum install を実行しました。

$ yum list installed | grep tree

#結果が何も出力されてない=インストールされていない

$ yum install -y tree
Loaded plugins: fastestmirror, product-id, search-disabled-repos, subscription-manager

...
(省略)
...

Installed:
  tree.x86_64 0:1.6.0-10.el7

Complete!

改めてサンプルのコマンドを実行すると、今度はうまく表示できました。

$ tree $DEMO_HOME
/root/hello
└── base
    ├── configMap.yaml
    ├── deployment.yaml
    ├── kustomization.yaml
    └── service.yaml

上記のコマンド結果はbase配下のディレクトリ構成を示しています。

baseをデプロイして動作確認

サンプルのこのコマンドで、セットアップしたbase配下のyamlファイルを指定してapplyします。

$ kubectl apply -k $DEMO_HOME/base
configmap/the-map created
service/the-service created
deployment.apps/the-deployment created

configmap, service, deploymentがそれぞれデプロイされた内容も出ていますね。

以下はサンプルに無いのですが実際にyamlファイルがそれぞれデプロイされたのをkubectl get でそれぞれ確認してみます。

#configmapを確認。 cm=configmapの略
$ kubectl get cm
NAME      DATA   AGE
the-map   2      81s

#serviceを確認。 svc=serviceの略
$ kubectl get svc
NAME          TYPE           CLUSTER-IP    EXTERNAL-IP      PORT(S)          AGE
kubernetes    ClusterIP      10.3.240.1    <none>           443/TCP          30d
the-service   LoadBalancer   10.3.250.21   35.221.103.195   8666:30774/TCP   4m1s

#deploymentを確認
$ kubectl get deployment
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
the-deployment   3/3     3            3           4m38s

サンプル(https://github.com/monopole/hello)のコマンドの通りにkustomization.yamlの内容を確認してみます。

$ more $BASE/kustomization.yaml

# Example configuration for the webserver
# at https://github.com/monopole/hello
commonLabels:
  app: hello

resources:
- deployment.yaml
- service.yaml
- configMap.yaml

それぞれのフィールドについてざっくりですが説明します。

  • commonLabels:

base, overlays共通のラベルを設定します。ここの値がkustomizeにおける重要な値となります。 サンプルでは全てのyamlファイルのラベルはapp:helloとなっています。

  • resources:とその配下

デプロイ時の対象のリソースを設定します。 具体的にはbaseに作ったhelloサービスがデプロイする時に含むyamlファイルを指定することができます。

引き続きサンプルのを実行していきます。 kustomizeコマンドによってbaseのリソースをstdoutに送信させることで、これからデプロイされるmanifestを一括で確認できます。

$ kustomize build $BASE
apiVersion: v1
data:
  altGreeting: Good Morning!
  enableRisky: "false"
kind: ConfigMap
metadata:
  labels:
    app: hello
  name: the-map
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: hello
  name: the-service
spec:
  ports:
  - port: 8666
    protocol: TCP
    targetPort: 8080
  selector:
    app: hello
    deployment: hello
  type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: hello
  name: the-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: hello
      deployment: hello
  template:
    metadata:
      labels:
        app: hello
        deployment: hello
    spec:
      containers:
      - command:
        - /hello
        - --port=8080
        - --enableRiskyFeature=$(ENABLE_RISKY)
        env:
        - name: ALT_GREETING
          valueFrom:
            configMapKeyRef:
              key: altGreeting
              name: the-map
        - name: ENABLE_RISKY
          valueFrom:
            configMapKeyRef:
              key: enableRisky
              name: the-map
        image: monopole/hello:1
        name: the-container
        ports:
        - containerPort: 8080

kustomization.yamlを編集したときの動作確認

引き続きサンプルの次の手順にあるコマンドにて、baseのkustomize.yaml を編集しましょう。

#"app: hello" を"app: my-hello" に置換させています
sed -i.bak 's/app: hello/app: my-hello/' \
    $BASE/kustomization.yaml

もう一度kustomize build するの部分です。 パイプしている部分はgrepコマンドにて差分をカラーでピックアップしてくれます。

$ kustomize build $BASE | grep -C 3 app:
kind: ConfigMap
metadata:
  labels:
    app: my-hello
  name: the-map
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: my-hello
  name: the-service
spec:
  ports:
--
    protocol: TCP
    targetPort: 8080
  selector:
    app: my-hello
    deployment: hello
  type: LoadBalancer
---
--
kind: Deployment
metadata:
  labels:
    app: my-hello
  name: the-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-hello
      deployment: hello
  template:
    metadata:
      labels:
        app: my-hello
        deployment: hello
    spec:
      containers:

kustomization.yamlで編集した内容によってデプロイ時のlabel情報が追加されていることが確認できます。 これはkustomize機能によるものです。

サンプル外ですが、以下のようにdeployment.yamlのapp:を確認してみるとmy-helloの記載は無いことを確認できます。

$ cat $BASE/deployment.yaml | grep hello
      deployment: hello
        deployment: hello
        image: monopole/hello:1
        command: ["/hello",

ovarlayセットアップ

いよいよ、拡張機能側をセットアップしていきます。

サンプルに倣ってコマンドを実行していきます。 ※ただし今回は、productio部分はスキップします。

# 新しく変数を定義
OVERLAYS=$DEMO_HOME/overlays

#stagingディレクトリ、productionディレクトリがそれぞれ作成
mkdir -p $OVERLAYS/staging

サンプルのStaging Kustomizationのコマンド部分も一気にコピペして実行しちゃいましょう。

cat <<'EOF' >$OVERLAYS/staging/kustomization.yaml
namePrefix: staging-
commonLabels:
  variant: staging
  org: acmeCorporation
commonAnnotations:
  note: Hello, I am staging!
bases:
- ../../base
patchesStrategicMerge:
- map.yaml
EOF

上記のコマンドによってoverlays/staging/ 配下にkustomization.yamlのmanifestが構成されました。

$ tree $OVERLAYS
/root/hello/overlays
└── staging
    └── kustomization.yaml

続いてconfigMapのmanifestを構成します。 ここでサンプルとちょっと文言を変えつつ、enableRisly:はtrueに合わせてみます。

cat <<EOF >$OVERLAYS/staging/map.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: the-map
data:
  altGreeting: "Welcome to grasys blog!"
  enableRisky: "true"
EOF

サンプルではproduction patchの手順がありますが、まずはstaging側だけ進めていくので今回はスキップします。 サンプル通りproduction側も進めることで、diffコマンドによるstagingとproductionそれぞれの比較を試すことができます。

さて、サンプルに倣ってstaging環境のkustomize buildコマンドを実行してみます。

kustomize build $OVERLAYS/staging
$ kustomize build $OVERLAYS/staging
apiVersion: v1
data:
  altGreeting: Welcome to grasys blog!
  enableRisky: "true"
kind: ConfigMap
metadata:
  annotations:
    note: Hello, I am staging!
  labels:
...(省略)...

先ほど私が指定したaltGreeting: Welcome to grasys blog!も出力されていることが確認できました。

最後に

実際に導入しているプロジェクトでは ビルドしたDockerイメージをstaging, productiom別でタグ付し、overlays配下のstagingやproductionで横展開して拡張実装したり ingressなどのbackend設定やCronjobでの機能拡張・横展開して活用しています。

活用目線の注意点としては 今回、サンプル中にはconfigMapの内容を書き換えて動作確認しましたが 運用が長期化したりプロジェクトの規模が拡大してくるに連れてconfigMapが必要以上に肥大化してしまう、といったケースがありました。 kustomization.yamlに含めるresourceは、長期的に利用する場合には運用面を考慮した使い方と、定期的なメンテナンスを行う必要がありそうです。

もっと詳しく・他にできることについて知りたい場合は kustomizeの専用リファレンスがありますのでそちらをどうぞ。

https://kubectl.docs.kubernetes.io/references/

それでは今回この辺で。