イメージ ダイジェストを使用してコンテナ イメージをデプロイすると、イメージタグを使用する場合と比べていくつかのメリットがあります。イメージ ダイジェストの詳細については、このチュートリアルに進む前に、コンテナ イメージ ダイジェストの使用についての付属ドキュメントをご覧ください。
Kubernetes Pod 仕様のコンテナの image
引数は、ダイジェスト付きのイメージを受け入れます。この引数は、Deployment、StatefulSet、DaemonSet、ReplicaSet、Job リソースの template
セクションなど、Pod の仕様を使用するすべての場所に適用されます。
ダイジェストを使用してイメージをデプロイするには、イメージ名に続けて @sha256:
とダイジェスト値を指定します。次に、ダイジェスト付きのイメージを使用する Deployment リソースの例を示します。
apiVersion: apps/v1 kind: Deployment metadata: name: echo-deployment spec: selector: matchLabels: app: echo template: metadata: labels: app: echo spec: containers: - name: echoserver image: gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229 ports: - containerPort: 8080
イメージ ダイジェストを使用するデメリットの 1 つは、イメージをレジストリに公開するまでダイジェスト値がわからないことです。新しいイメージをビルドすると、ダイジェスト値が変わるため、デプロイのたびに Kubernetes マニフェストを更新しなければなりません。
このチュートリアルでは、Skaffold、kpt、digester、kustomize、gke-deploy
、ko
、Bazel などのツールを利用して、マニフェストでイメージ ダイジェストを使用する方法について説明します。
推奨事項
このドキュメントでは、Kubernetes Deployment でイメージ ダイジェストを使用する方法をいくつか説明します。このドキュメントで説明するツールは、他のツールと組み合わせて使用します。たとえば、さまざまな環境のバリアントを作成するために kustomize で kpt 関数の出力を使用できます。Skaffold では、kpt や kustomize を使用してイメージを Kubernetes クラスタにデプロイするために、Bazel を使用してイメージをビルドできます。
これらのツールが補完的な関係にあるのは、これらのツールが Kubernetes リソースモデル(KRM)に基づいて構造化された編集を行うためです。このモデルではツールがプラグイン可能なため、これらのツールを活用して、アプリやサービスのデプロイに役立つプロセスとパイプラインを構築できます。
最初の段階では、既存のツールとプロセスに最適なアプローチをおすすめします。
Kubernetes クラスタで、変更用アドミッション Webhook として digester ツールを使用すると、コンテナ イメージの現在のビルドとデプロイのプロセスへの影響を最小限に抑えながら、すべてのデプロイメントにダイジェストを追加できます。また、digester Webhook では、Namespace にラベルを追加することのみが必要とされ、Binary Authorization の導入も簡素化されます。
kpt は、Kubernetes マニフェストを操作する柔軟なツールが必要な場合に最適です。ダイジェスト ツールは、kpt パイプラインでクライアント側の KRM 関数として使用できます。
Skaffold は、イメージ参照にダイジェストを追加するために使用できます。この機能は、構成に小さな変更を加えて有効にします。Skaffold を採用すると、さまざまなツールがコンテナ イメージをビルドしてデプロイする仕組みを抽象化するなど、追加のメリットがあります。
すでに kustomize を使用して環境間で Kubernetes マニフェストを管理している場合は、イメージ トランスフォーマーを利用して、ダイジェストによってイメージをデプロイすることをおすすめします。
Go アプリのイメージをビルドして公開する場合は
ko
が最適です。これは、Knative や Tekton や sigstore などのオープンソース プロジェクトで使用されています。すでに Bazel を使用してアプリを作成している場合は、
rules_docker
ルールセットを追加してイメージをビルドし、rules_k8s
ルールセットを使用して Kubernetes マニフェストにイメージ ダイジェストを挿入することをおすすめします。
このドキュメントで説明するツールを使用していない場合は、Skaffold と digester Webhook から使い始めることをおすすめします。Skaffold は、デベロッパー チームとリリースチームの双方でよく使用されているツールで、このチュートリアルで説明する他のツールと統合されて機能します。こうした統合の選択肢は、要件の変化に合わせて活用できます。Kubernetes の digester Webhook は、組織全体に対してダイジェスト ベースのデプロイを有効にすることで、Skaffold を補完します。
目標
- Skaffold を使用してイメージのビルドと push を行い、イメージ名とダイジェストを Kubernetes マニフェストに挿入する。
- kpt セッターを使用して、Kubernetes マニフェストのイメージタグをイメージ ダイジェストに置き換える。
- digester クライアント側関数と変更用アドミッション Webhook を使用して、Kubernetes Pod と Pod テンプレートのイメージにダイジェストを追加する。
- kustomize を使用して、イメージ ダイジェストを含む Kubernetes マニフェストを生成する。
gke-deploy
を使用して、Kubernetes マニフェストでイメージタグをダイジェストに変更する。ko
を使用してイメージのビルドと push を行い、Kubernetes マニフェストにイメージとダイジェストを挿入する。- Bazel を使用してイメージのビルドと push を行い、Kubernetes マニフェストにイメージとダイジェストを挿入する。
費用
このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
このドキュメントに記載されているタスクの完了後、作成したリソースを削除すると、それ以上の請求は発生しません。詳細については、クリーンアップをご覧ください。
始める前に
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Container Registry API.
-
In the Google Cloud console, activate Cloud Shell.
Skaffold の使用
Skaffold は、Kubernetes クラスタに対するアプリケーションの継続的な開発とデプロイを行うためのコマンドライン ツールです。
Skaffold を使用してイメージを作成し、そのイメージを Container Registry に push します。Kubernetes マニフェスト テンプレートの image
プレースホルダ値を、push されたイメージの名前、タグとダイジェストで置き換えます。
Cloud Shell で、このセクションで作成したファイルを保存するディレクトリを作成し、そのディレクトリに移動します。
mkdir -p ~/container-image-digests-tutorial/skaffold cd ~/container-image-digests-tutorial/skaffold
Skaffold Git リポジトリのクローンを作成します。
git clone https://github.com/GoogleContainerTools/skaffold.git
getting-started
のサンプルのあるディレクトリに移動します。cd skaffold/examples/getting-started
Skaffold のバージョンと一致する Git タグをチェックアウトします。
git checkout $(skaffold version)
skaffold.yaml
構成ファイルを表示します。cat skaffold.yaml
ファイルは、次のような形式です。
apiVersion: skaffold/v2beta26 kind: Config build: artifacts: - image: skaffold-example deploy: kubectl: manifests: - k8s-*
build.artifacts
セクションには、イメージのコンテキスト(この場合はプレースホルダ名)が含まれています。Skaffold は、入力のマニフェスト ファイルで、このプレースホルダを検索します。このセクションでは、Skaffold がイメージのビルドに使用するコンテキスト ディレクトリも定義します。デフォルトでは、Skaffold はビルド コンテキストとして現在のディレクトリを使用します。deploy
セクションでは、現在のディレクトリで名前がk8s-*
パターンに一致する入力マニフェストを読み取り、レンダリングされたマニフェストをkubectl apply
でデプロイすることを Skaffold に指示しています。使用可能なすべてのオプションの概要については、
skaffold.yaml
リファレンス ドキュメントをご覧ください。Kubernetes マニフェスト テンプレートを表示します。
cat k8s-pod.yaml
次のようなファイルが表示されます。
apiVersion: v1 kind: Pod metadata: name: getting-started spec: containers: - name: getting-started image: skaffold-example
image
フィールドのskaffold-example
プレースホルダ値は、skaffold.yaml
ファイル内のimage
フィールドの値と一致します。このプレースホルダ値は、レンダリングされた出力の完全なイメージ名とダイジェストで置き換えられます。イメージをビルドし、コンテナ レジストリにプッシュする
skaffold build \ --default-repo=gcr.io/$(gcloud config get-value core/project) \ --file-output=artifacts.json \ --interactive=false \ --push=true \ --update-check=false
このコマンドは、次のフラグを使用しています。
--file-output
フラグは、Skaffold がビルドされたイメージに関する情報(ダイジェスト値など)を保存するファイルを指定します。--push
フラグは、ビルドされたイメージを--default-repo
フラグで指定されたコンテナ イメージ レジストリに push するように Skaffold に指示します。--interactive
フラグと--update-check
フラグはどちらもfalse
に設定されています。ビルド パイプラインなどの非対話環境では、これらのフラグをfalse
に設定しますが、ローカル開発ではデフォルト値(両方のフラグでtrue
)のままにしておきます。
Google Cloud Deploy を使用して GKE にデプロイする場合は、リリースを作成する際に
--file-output
フラグを--build-artifacts
フラグの数値として使用してください。前の手順のコンテナ イメージの名前、タグ、ダイジェストを使用して、拡張された Kubernetes マニフェストをレンダリングします。
skaffold render \ --build-artifacts=artifacts.json \ --digest-source=none \ --interactive=false \ --offline=true \ --output=rendered.yaml \ --update-check=false
このコマンドは、次のフラグを使用しています。
--build-artifacts
フラグは、前の手順のskaffold build
コマンドからの出力ファイルを参照します。--digest-source=none
フラグは、Container Registry からのダイジェストを解決する代わりに、Skaffold が--build-artifacts
フラグで提供されるファイルのダイジェスト値を使用することを意味します。--offline=true
フラグを使用すると、Kubernetes クラスタにアクセスせずにコマンドを実行できます。--output
フラグは、レンダリングされたマニフェストの出力ファイルを指定します。
レンダリングされたマニフェストを表示します。
cat rendered.yaml
出力は次のようになります。
apiVersion: v1 kind: Pod metadata: name: getting-started spec: containers: - image: gcr.io/YOUR_PROJECT_ID/skaffold-example:TAG@sha256:DIGEST name: getting-started
この出力には次の値が含まれています。
YOUR_PROJECT_ID
: 実際の Cloud プロジェクトの IDTAG
: Skaffold がイメージに割り当てたタグ。DIGEST
: イメージ ダイジェストの値
kpt セッターの使用
kpt は、Kubernetes リソース マニフェストを管理、操作、カスタマイズ、適用するためのコマンドライン ツールです。
新しいイメージをビルドするときに kpt 関数カタログの create-setters
および apply-setters
KRM 関数を使用することで、Kubernetes マニフェストのイメージ ダイジェストを更新できます。
Cloud Shell で、このセクションで作成したファイルを保存するディレクトリを作成し、そのディレクトリに移動します。
mkdir -p ~/container-image-digests-tutorial/kpt cd ~/container-image-digests-tutorial/kpt
kpt をダウンロードします。
mkdir -p ${HOME}/bin curl -L https://github.com/GoogleContainerTools/kpt/releases/download/v1.0.0-beta.1/kpt_linux_amd64 --output ${HOME}/bin/kpt chmod +x ${HOME}/bin/kpt export PATH=${HOME}/bin:${PATH}
現在のディレクトリに kpt パッケージを作成します。
kpt pkg init --description "Container image digest tutorial"
イメージ
gcr.io/google-containers/echoserver
を参照する Kubernetes Pod マニフェストを、タグ1.10
を使用して作成します。cat << EOF > pod.yaml apiVersion: v1 kind: Pod metadata: name: echo spec: containers: - name: echoserver image: gcr.io/google-containers/echoserver:1.10 ports: - containerPort: 8080 EOF
kpt を使用して、そのマニフェスト フィールド用に
echoimage
という名前のセッターを作成します。ここで、既存の値はgcr.io/google-containers/echoserver:1.10
です。kpt fn eval . \ --image gcr.io/kpt-fn/create-setters:v0.1@sha256:0220cc87f29ff9abfa3a3b5643aa50f18d355d5e9dc9e1f518119633ddc4895c \ -- "echoimage=gcr.io/google-containers/echoserver:1.10"
マニフェストを確認します。
cat pod.yaml
次のようなファイルが表示されます。
apiVersion: v1 kind: Pod metadata: name: echo spec: containers: - name: echoserver image: gcr.io/google-containers/echoserver:1.10 # kpt-set: ${echoimage} ports: - containerPort: 8080
コンテナ イメージのダイジェストの値を取得します。
DIGEST=$(gcloud container images describe \ gcr.io/google-containers/echoserver:1.10 \ --format='value(image_summary.digest)')
新しいフィールド値を設定します。
kpt fn eval . \ --image gcr.io/kpt-fn/apply-setters:v0.2@sha256:4d4295727183396f0c3c6a75d2560254c2f9041a39e95dc1e5beffeb49cc1a12 \ -- "echoimage=gcr.io/google-containers/echoserver:1.10@$DIGEST"
このコマンドを実行すると、kpt はマニフェスト内の
image
フィールド値のインプレース置換を実行します。更新されたマニフェストを表示します。
cat pod.yaml
次のようなファイルが表示されます。
apiVersion: v1 kind: Pod metadata: name: echo spec: containers: - name: echoserver image: gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229 # kpt-set: ${echoimage} ports: - containerPort: 8080
digester の使用
digester は、Kubernetes Pod と Pod テンプレートの仕様のコンテナ イメージと init コンテナ イメージにダイジェストを追加します。タグを使用するコンテナ イメージの参照が、digester によって置き換えられます。
spec:
containers:
- image: gcr.io/google-containers/echoserver:1.10
イメージのダイジェストを使用する参照は、次のようになります。
spec:
containers:
- image: gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
digester は、Kubernetes クラスタで変更用アドミッション Webhook として実行するか、kpt や kustomize コマンドライン ツールを使用してクライアント側の KRM 関数として実行できます。
digester KRM 関数の使用
Cloud Shell で、このセクションで作成したファイルを保存するディレクトリを作成し、そのディレクトリに移動します。
mkdir -p ~/container-image-digests-tutorial/digester-fn cd ~/container-image-digests-tutorial/digester-fn
digester バイナリをダウンロードします。
DIGESTER_VERSION=v0.1.7 mkdir -p ${HOME}/bin curl -L "https://github.com/google/k8s-digester/releases/download/${DIGESTER_VERSION}/digester_$(uname -s)_$(uname -m)" --output ${HOME}/bin/digester chmod +x ${HOME}/bin/digester export PATH=${HOME}/bin:${PATH}
イメージ
gcr.io/google-containers/echoserver
を参照する Kubernetes Pod マニフェストを、タグ1.10
を使用して作成します。cat << EOF > pod.yaml apiVersion: v1 kind: Pod metadata: name: echo spec: containers: - name: echoserver image: gcr.io/google-containers/echoserver:1.10 ports: - containerPort: 8080 EOF
kpt を使用して digester の KRM 関数を実行します(現在のディレクトリ(
.
)にあります)。kpt fn eval . --exec digester
このコマンドを実行すると、kpt は現在のディレクトリでマニフェストのインプレース更新を行います。マニフェスト ファイルは変更せずに、kpt による更新後のマニフェストをコンソールに表示する場合は、
--output unwrap
フラグを追加します。更新されたマニフェストを表示します。
cat pod.yaml
次のようなファイルが表示されます。
apiVersion: v1 kind: Pod metadata: name: echo spec: containers: - name: echoserver image: gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229 ports: - containerPort: 8080
digester アドミッション Webhook を使用する
Cloud Shell で、このセクションで作成したファイルを保存するディレクトリを作成し、そのディレクトリに移動します。
mkdir -p ~/container-image-digests-tutorial/digester-webhook cd ~/container-image-digests-tutorial/digester-webhook
kind をダウンロードします。
KIND_VERSION=v0.11.1 mkdir -p ${HOME}/bin curl -L "https://github.com/kubernetes-sigs/kind/releases/download/${KIND_VERSION}/kind-linux-amd64" --output ${HOME}/bin/kind chmod +x ${HOME}/bin/kind export PATH=${HOME}/bin:${PATH}
kind は、Docker を使用してローカルの Kubernetes クラスタを実行するためのコマンドライン ツールです。
ローカルの Kubernetes クラスタを作成します。
kind create cluster
ダイジェスト Webhook kpt パッケージをダウンロードして、
manifests
というディレクトリに保存します。DIGESTER_VERSION=v0.1.7 kpt pkg get https://github.com/google/k8s-digester.git/manifests@${DIGESTER_VERSION} manifests
digester Webhook をデプロイします。
kpt live init manifests kpt live apply manifests --reconcile-timeout=3m --output=table
kind クラスタに
digester-demo
という Kubernetes Namespace を作成します。kubectl create namespace digester-demo
digest-resolution: enabled
ラベルをdigester-demo
Namespace に追加します。kubectl label namespace digester-demo digest-resolution=enabled
digester Webhook は、このラベルを持つ名前空間の Pod にダイジェストを追加します。
イメージ
gcr.io/google-containers/echoserver
を参照する Kubernetes Deployment マニフェストをタグ1.10
を使用して作成します。cat << EOF > deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: echo-deployment spec: selector: matchLabels: app: echo template: metadata: labels: app: echo spec: containers: - name: echoserver image: gcr.io/google-containers/echoserver:1.10 ports: - containerPort: 8080 EOF
digester-demo
Namespace にマニフェストを適用します。kubectl apply --filename deployment.yaml --namespace digester-demo \ --output jsonpath='{.spec.template.spec.containers[].image}{"\n"}'
--output
フラグは、kubectl
にイメージ名をコンソールに出力するように指示します。次のような出力が表示されます。gcr.io/google-containers/echoserver:1.10@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
この出力は、digester Webhook がイメージのダイジェストを Deployment リソースの Pod テンプレート仕様に追加したことを示しています。
種類クラスタを削除して、Cloud Shell セッションでリソースを解放します。
kind delete cluster
Kustomize イメージ トランスフォーマーの使用
kustomize は、オーバーレイ、パッチ、トランスフォーマーを使用して Kubernetes マニフェストをカスタマイズできるコマンドライン ツールです。
kustomize イメージ トランスフォーマーを使用すると、既存のマニフェストに含まれているイメージ名、タグ、ダイジェストを更新できます。
次の kustomization.yaml
スニペットは、Pod 仕様の image
値がトランスフォーマーの name
値と一致するイメージにトランスフォーマーの digest
値を使用するように、イメージ トランスフォーマーを構成します。
images: - name: gcr.io/google-containers/echoserver digest: sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
kustomize イメージ トランスフォーマーでイメージ ダイジェストを使用するには、次の操作を行います。
Cloud Shell で、このセクションで作成したファイルを保存するディレクトリを作成し、そのディレクトリに移動します。
mkdir -p ~/container-image-digests-tutorial/kustomize cd ~/container-image-digests-tutorial/kustomize
kustomization.yaml
ファイルを作成します。kustomize init
タグ
1.10
を使用して、イメージgcr.io/google-containers/echoserver
を参照する Pod 仕様を含む Kubernetes マニフェストを作成します。cat << EOF > pod.yaml apiVersion: v1 kind: Pod metadata: name: echo spec: containers: - name: echoserver image: gcr.io/google-containers/echoserver:1.10 ports: - containerPort: 8080 EOF
kustomization.yaml
ファイルで、リソースとしてマニフェストを追加します。kustomize edit add resource pod.yaml
イメージ トランスフォーマーを使用して、イメージのダイジェストを更新します。
kustomize edit set image \ gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229
kustomization.yaml
ファイルでイメージ トランスフォーマーを表示します。cat kustomization.yaml
次のようなファイルが表示されます。
apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - pod.yaml images: - digest: sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229 name: gcr.io/google-containers/echoserver
作成されたマニフェストを表示します。
kustomize build .
次のような出力が表示されます。
apiVersion: v1 kind: Pod metadata: name: echo spec: containers: - image: gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229 name: echoserver ports: - containerPort: 8080
作成されたマニフェストを Kubernetes クラスタに適用するには、
--kustomize
フラグを指定したkubectl apply
を使います。kubectl apply --kustomize .
出力を後で適用する場合は、
kustomize build
コマンドの出力をファイルにリダイレクトします。kustomize には、このドキュメントでは範囲外の他の機能も備わっています。詳細については、kustomize のドキュメントをご覧ください。また、kustomize は、Cloud Build コミュニティ ビルダー イメージとしても利用できます。
gke-deploy
の使用
gke-deploy
は、Google Kubernetes Engine(GKE)とともに使用するコマンドライン ツールです。gke-deploy
は、kubectl
コマンドライン ツールをラップし、Google が推奨する方法に従って作成するリソースを変更できます。
gke-deploy
のサブコマンド(prepare
または run
)を使用すると、gke-deploy
はイメージタグの代わりにダイジェストを使用し、イメージ ダイジェストで拡張したマニフェストをデフォルトで output/expanded/aggregated-resources.yaml
ファイルに保存します。
gke-deploy run
を使用すると、イメージタグをダイジェストに置き換え、拡張されたマニフェストを GKE クラスタに適用できます。このコマンドは便利ですが、デプロイ時にイメージタグが置換されます。タグに関連付けられたイメージが実際にデプロイされるまでに変更されていると、予期しないイメージがデプロイされる場合があります。本番環境のデプロイでは、マニフェストの生成と適用は別の手順で行うことをおすすめします。
Kubernetes Deployment マニフェストのイメージタグをイメージ ダイジェストに置き換えるには、次の操作を行います。
Cloud Shell で、このセクションで作成したファイルを保存するディレクトリを作成し、そのディレクトリに移動します。
mkdir -p ~/container-image-digests-tutorial/gke-deploy cd ~/container-image-digests-tutorial/gke-deploy
gke-deploy
をインストールします。go install github.com/GoogleCloudPlatform/cloud-builders/gke-deploy@latest
イメージ
gcr.io/google-containers/echoserver
を参照する Kubernetes Deployment マニフェストをタグ1.10
を使用して作成します。cat << EOF > deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: echo-deployment spec: selector: matchLabels: app: echo template: metadata: labels: app: echo spec: containers: - name: echoserver image: gcr.io/google-containers/echoserver:1.10 ports: - containerPort: 8080 EOF
deployment.yaml
マニフェストに基づいて拡張されたマニフェストを生成します。gke-deploy prepare \ --filename deployment.yaml \ --image gcr.io/google-containers/echoserver:1.10 \ --version 1.10
拡張されたマニフェストを表示します。
cat output/expanded/aggregated-resources.yaml
次のような出力が表示されます。
apiVersion: apps/v1 kind: Deployment metadata: labels: app.kubernetes.io/managed-by: gcp-cloud-build-deploy app.kubernetes.io/version: "1.10" name: echo-deployment namespace: default spec: selector: matchLabels: app: echo template: metadata: labels: app: echo app.kubernetes.io/managed-by: gcp-cloud-build-deploy app.kubernetes.io/version: "1.10" spec: containers: - image: gcr.io/google-containers/echoserver@sha256:cb5c1bddd1b5665e1867a7fa1b5fa843a47ee433bbb75d4293888b71def53229 name: echoserver ports: - containerPort: 8080
拡張されたマニフェストでは、イメージタグがダイジェストに置き換えられます。
gke-deploy
コマンドで使用した--version
引数により、デプロイで推奨されるapp.kubernetes.io/version
ラベルと拡張されたマニフェストの Pod テンプレートのメタデータの値が設定されます。gke-deploy
ツールは、Cloud Build のビルド済みイメージとしても利用できます。Cloud Build でgke-deploy
を使用する方法については、Cloud Build のドキュメントでgke-deploy
をご覧ください。
ko
の使用
ko
は、Go コンテナ イメージをビルドして Kubernetes クラスタにデプロイするコマンドライン ツールです。ko
は、Docker デーモンを使用せずにイメージをビルドするため、Docker をインストールできない環境でもイメージを使用できます。
ko
サブコマンド publish
は、イメージをビルドして、Container Registry に公開するか、ローカルの Docker デーモンにロードします。
ko
サブコマンド resolve
は、次の処理を行います。
--filename
引数に指定した Kubernetes マニフェストのimage
フィールドでプレースホルダを検索し、ビルドするイメージを確認します。- イメージをビルドして公開します。
image
値のプレースホルダを、ビルドされたイメージの名前とダイジェストに置き換えます。- 拡張されたマニフェストを出力します。
ko
サブコマンドの apply
、create
、run
は、resolve
と同じ手順を実行した後、拡張されたマニフェストを使用して kubectl apply
、create
、または run
を実行します。
Go ソースコードからイメージをビルドし、イメージのダイジェストを Kubernetes Deployment マニフェストに追加するには、次の操作を行います。
Cloud Shell で、このセクションで作成したファイルを保存するディレクトリを作成し、そのディレクトリに移動します。
mkdir -p ~/container-image-digests-tutorial/ko cd ~/container-image-digests-tutorial/ko
ko
をダウンロードしてPATH
に追加します。mkdir -p ${HOME}/bin curl -L https://github.com/google/ko/releases/download/v0.9.3/ko_0.9.3_$(uname -s)_$(uname -m).tar.gz | tar -zxC ${HOME}/bin ko export PATH=${HOME}/bin:${PATH}
app
と呼ばれる新しいディレクトリに、example.com/hello-world
というモジュール名で Go アプリを作成します。mkdir -p app/cmd/ko-example cd app go mod init example.com/hello-world cat << EOF > cmd/ko-example/main.go package main import "fmt" func main() { fmt.Println("hello world") } EOF
ko
がイメージの公開に使用するイメージ リポジトリを定義します。export KO_DOCKER_REPO=gcr.io/$(gcloud config get-value core/project)
このサンプルでは Container Registry を使用しますが、別のレジストリを使用することもできます。
アプリのイメージをビルドして公開するには、次のいずれかの手順を行います。
Go メイン パッケージのパスを指定してアプリのイメージをビルドし、公開します。
ko publish --base-import-paths ./cmd/ko-example
オプションの引数
--base-import-paths
を使用すると、ko
はイメージ名としてメイン パッケージ ディレクトリの短縮名を使用します。ko
は、イメージ名とダイジェストをstdout
に次の形式で出力します。gcr.io/YOUR_PROJECT_ID/ko-example@sha256:DIGEST_VALUE
この出力で:
YOUR_PROJECT_ID
: 実際の Cloud プロジェクトの IDDIGEST_VALUE
: イメージ ダイジェストの値
ko
を使用して、マニフェストのプレースホルダを、ビルドして公開するイメージの名前とダイジェストに置き換えます。Kubernetes Pod マニフェストを作成します。このマニフェストでは、
image
フィールドの値としてプレースホルダko://IMPORT_PATH_OF_YOUR_MAIN_PACKAGE
を使用します。cat << EOF > ko-pod.yaml apiVersion: v1 kind: Pod metadata: name: ko-example spec: containers: - name: hello-world image: ko://example.com/hello-world/cmd/ko-example EOF
ko resolve
を使用してアプリのイメージをビルドして公開し、マニフェストのプレースホルダをイメージ名とダイジェストに置き換えます。ko resolve --base-import-paths --filename ko-pod.yaml
ko
は、イメージ名とダイジェストを含むマニフェストをstdout
に出力します。apiVersion: v1 kind: Pod metadata: name: ko-example spec: containers: - name: hello-world image: gcr.io/YOUR_PROJECT_ID/ko-example@sha256:DIGEST
この出力で:
YOUR_PROJECT_ID
: 実際の Cloud プロジェクトの IDDIGEST
: イメージ ダイジェストの値
Bazel の使用
Bazel は、Google の内部 Blaze ビルドシステムをベースとしたオープンソースの多言語ビルドツールです。
rules_docker
は、コンテナ イメージをビルドして push するための Bazel ルールセットです。このルールにより、Docker デーモンを使用せずに再現可能なイメージをビルドできます。Bazel のキャッシュを使用することで、イメージのビルドとレジストリへの push の両方が高速化されます。
rules_k8s
は、Kubernetes マニフェストとクラスタで動作する Bazel ルールセットです。
イメージをビルドして push し、イメージ ダイジェストを含む Kubernetes マニフェストを挿入するには、次の操作を行います。
Cloud Shell で、このセクションで作成したファイルを保存するディレクトリを作成し、そのディレクトリに移動します。
mkdir -p ~/container-image-digests-tutorial/bazel cd ~/container-image-digests-tutorial/bazel
rules_k8s
Git リポジトリのクローンを作成するgit clone https://github.com/bazelbuild/rules_k8s.git
Git リポジトリのディレクトリに移動します。
cd rules_k8s
Git タグを確認します。
git checkout v0.6
WORKSPACE
ファイルで、Bazel がイメージを push するベースイメージ リポジトリ名を、イメージの push 権限のあるリポジトリに置き換えます。sed -i~ "s/image_chroot.*/image_chroot = \"gcr.io\/$(gcloud config get-value core\/project)\",/" WORKSPACE
このサンプルでは Container Registry を使用しますが、別のレジストリを使用することもできます。
ビルドで使用する Bazel のバージョンをインストールします。
sudo apt-get install -y bazel-$(cat .bazelversion)
Kubernetes Deployment マニフェスト テンプレートのサンプルで
apiVersion
フィールドを修正します。sed -i~ 's/v1beta1/v1/' examples/hellohttp/deployment.yaml
Kubernetes Deployment マニフェスト テンプレートを表示します。
cat examples/hellohttp/deployment.yaml
次のようなファイルが表示されます。
apiVersion: apps/v1 kind: Deployment metadata: name: hello-http-staging spec: replicas: 1 template: metadata: labels: app: hello-http-staging spec: containers: - name: hello-http image: hello-http-image:latest imagePullPolicy: Always ports: - containerPort: 8080
hellohttp
サンプルの Java イメージをビルドして Container Registry に push します。Kubernetes Deployment マニフェスト テンプレートのimage
値を、push されたイメージの名前とダイジェストに置き換えます。stdout
出力をリダイレクトして、拡張されたマニフェストをdeployment.yaml.out
という新しいファイルにキャプチャします。bazel --output_user_root=/tmp/bazel \ run //examples/hellohttp/java:staging > deployment.yaml.out
このコマンドを初めて実行する場合、数分かかります。これは、ルールセット、コンパイラ、依存関係がダウンロードされるためです。
--output_user_root
引数により、ホーム ディレクトリ外の一時ディレクトリをディスクベースのキャッシュに使用することを Bazel に指示します。この一時ディレクトリは、Cloud Shell でホーム ディレクトリ ボリュームの占有を防ぐために必要になります。拡張されたマニフェストを表示します。
cat deployment.yaml.out
ファイルは、次のような形式です。
apiVersion: apps/v1 kind: Deployment metadata: name: hello-http-staging spec: replicas: 1 template: metadata: labels: app: hello-http-staging spec: containers: - image: gcr.io/YOUR_PROJECT_ID/hello-http-image@sha256:b9d0a4643e9f11efe7cd300dd219ad691077ddfaccc118144cd83b7c472a8e86 imagePullPolicy: Always name: hello-http ports: - containerPort: 8080
Bazel が Container Registry に push したイメージを確認します。
gcloud container images describe \ gcr.io/$(gcloud config get-value core/project)/hello-http-image
クリーンアップ
課金を停止する最も簡単な方法は、チュートリアル用に作成した Cloud プロジェクトを削除することです。また、リソースを個別に削除することもできます。
プロジェクトの削除
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
リソースの削除
このチュートリアルで使用した Cloud プロジェクトを保持する場合は、個々のリソースを削除します。
Container Registry 内のイメージを削除します。
for IMG in hello-http-image ko-example skaffold-example ; do \ gcloud container images list-tags \ gcr.io/$(gcloud config get-value core/project)/$IMG \ --format 'value(digest)' | xargs -I {} gcloud container images \ delete --force-delete-tags --quiet \ gcr.io/$(gcloud config get-value core/project)/$IMG@sha256:{} done
このチュートリアルで作成したファイルを削除します。
cd rm -rf ~/container-image-digests-tutorial
次のステップ
- コンテナ イメージ ダイジェストについて学習する。
- digester クライアント側の KRM 関数と Kubernetes Mutation Webhook について学習する。
- Cloud Build を使用した GitOps スタイルの継続的デリバリーの詳細を確認する。
- コンテナのビルドに関するベスト プラクティスを確認する。
- コンテナ運用に関するベスト プラクティスを確認する。
- Google Cloud に関するリファレンス アーキテクチャ、図、チュートリアル、ベスト プラクティスについて確認する。Cloud Architecture Center を確認する。