はじめに
これまでのデプロイメントに関する実験では、レジストリやクラスターキャッシュに既に存在するイメージを使用してきました。アプリケーション開発者は、ローカルでのイメージワークフローを理解しておく必要があります。つまり、アプリケーションファイルからイメージをビルドし、そのイメージを Kubernetes ノードで利用可能にし、Deployment に対してそのイメージを使用するように指示するプロセスです。
この実験では、Minikube を使用して小規模な Web アプリケーションイメージをローカルでビルドし、imagePullPolicy: Never を指定してデプロイします。その後、ローリングアップデートのためにアプリケーションを別のイメージタグとして再ビルドします。これは、アプリケーションの成果物をそれを実行する Kubernetes ワークロードに接続するという、CKAD 試験でよく見られるタスクを再現したものです。
ローカルイメージ用ワークスペースの準備
このステップでは、クリーンな名前空間を準備し、イメージのビルドパスが利用可能であることを確認します。
/home/labex/project から開始します。このディレクトリ内にアプリケーションファイル、イメージビルドファイル、および Kubernetes マニフェストを作成します。
mkdir -p /home/labex/project
cd /home/labex/project
Kubernetes API サーバーに到達可能であることを確認します。VM が起動した直後でノードの準備ができていない場合は、数秒待ってから再度コマンドを実行してください。
kubectl get nodes --request-timeout=5s
期待される出力例:
NAME STATUS ROLES AGE VERSION
labex-v135 Ready control-plane ... v1.35...
クラスターネットワーキングの Pod が「Ready」になるまで待ちます。アプリケーションは Service 経由でテストされるため、ネットワークが正常である必要があります。
kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s
期待される出力:
pod/calico-node-... condition met
ckad-prep-local-image という名前の名前空間を作成し、現在の名前空間として設定します。
kubectl create namespace ckad-prep-local-image
kubectl config set-context --current --namespace=ckad-prep-local-image
名前空間を確認し、Minikube のイメージコマンドを確認します。minikube image build コマンドは、Minikube プロファイルに対して直接イメージをビルドするため、レジストリにプッシュすることなく Pod から使用できます。
kubectl config view --minify --output 'jsonpath={..namespace}'; echo
minikube image build --help | sed -n '1,4p'
期待される出力例:
ckad-prep-local-image
Build a container image...
最初のローカルイメージのビルド
このステップでは、小規模な Web アプリケーションを作成し、local-message-app:v1 としてビルドします。
このイメージは、BusyBox の httpd を使用して 1 つの静的ファイルを提供します。ファイルの内容は目に見えるアプリケーションのバージョンであり、後で Kubernetes でどのイメージタグが実行されているかを証明するために使用します。
アプリケーションディレクトリと最初の Web ページを作成します。
mkdir -p local-message-app/www
cat > local-message-app/www/index.html <<'EOF'
local-image-v1
EOF
Dockerfile を作成します。COPY 命令はローカルの www/index.html ファイルをイメージ内に配置し、CMD はイメージからコンテナが実行されたときにポート 8080 で BusyBox Web サーバーを起動します。
cat > local-message-app/Dockerfile <<'EOF'
FROM busybox:1.36
COPY www/index.html /www/index.html
EXPOSE 8080
CMD ["httpd", "-f", "-p", "8080", "-h", "/www"]
EOF
アクティブな Minikube プロファイル用にイメージをビルドします。-t オプションはイメージにローカルタグを付与し、最後のパスはビルドコンテキストディレクトリを指定します。
minikube image build --profile labex-v135 -t local-message-app:v1 ./local-message-app
期待される出力例:
naming to docker.io/library/local-message-app:v1 done
Minikube が認識しているイメージを一覧表示し、新しいタグを探します。
minikube image ls --profile labex-v135 | grep local-message-app
期待される出力:
docker.io/library/local-message-app:v1
ローカルイメージのデプロイ
このステップでは、Kubernetes でローカルイメージを実行します。
local-message-app:v1 はリモートレジストリにプッシュされていないため、Deployment では imagePullPolicy: Never を使用します。これにより、kubelet はネットワークからイメージをプルしようとせず、ノード上に既に存在するイメージを使用するようになります。
local-image-app.yaml を作成します。
cat > local-image-app.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: local-message-app
spec:
replicas: 2
selector:
matchLabels:
app: local-message-app
template:
metadata:
labels:
app: local-message-app
spec:
terminationGracePeriodSeconds: 0
containers:
- name: web
image: local-message-app:v1
imagePullPolicy: Never
ports:
- containerPort: 8080
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 1
periodSeconds: 2
---
apiVersion: v1
kind: Service
metadata:
name: local-message-app
spec:
selector:
app: local-message-app
ports:
- port: 80
targetPort: 8080
EOF
マニフェストを適用し、Deployment の完了を待ちます。
kubectl apply -f local-image-app.yaml
kubectl rollout status deployment/local-message-app --timeout=120s
期待される出力例:
deployment.apps/local-message-app created
service/local-message-app created
deployment "local-message-app" successfully rolled out
クライアント Pod を作成し、Service をテストします。
kubectl run image-client --image=busybox:1.36 --restart=Never --command -- sleep 3600
kubectl wait --for=condition=Ready pod/image-client --timeout=120s
kubectl exec image-client -- wget -qO- http://local-message-app
期待される出力:
local-image-v1
新しいローカルイメージの再ビルドとロールアウト
このステップでは、アプリケーションを 2 番目のイメージタグとして再ビルドし、Deployment をそのタグにロールアウトします。
ディスク上のファイルを変更しても、実行中のイメージは変更されません。新しいイメージタグをビルドし、Kubernetes がそのタグから新しい Pod を開始するように Deployment を更新する必要があります。これにより、バージョン変更が可視化され、変更可能なローカルイメージの内容に依存することを回避できます。
Web ページの内容をバージョン 2 に置き換えます。
cat > local-message-app/www/index.html <<'EOF'
local-image-v2
EOF
2 番目のイメージタグをビルドします。
minikube image build --profile labex-v135 -t local-message-app:v2 ./local-message-app
期待される出力例:
naming to docker.io/library/local-message-app:v2 done
Deployment のイメージを更新し、ロールアウトを待ちます。
kubectl set image deployment/local-message-app web=local-message-app:v2
kubectl rollout status deployment/local-message-app --timeout=120s
期待される出力例:
deployment.apps/local-message-app image updated
deployment "local-message-app" successfully rolled out
イメージタグとアプリケーションの応答の両方を確認します。
kubectl get deployment local-message-app -o jsonpath='{.spec.template.spec.containers[0].image}'; echo
kubectl exec image-client -- wget -qO- http://local-message-app
期待される出力:
local-message-app:v2
local-image-v2
まとめ
Minikube プロファイル用に小規模なアプリケーションイメージをビルドし、imagePullPolicy: Never を指定してデプロイし、Kubernetes Service 経由でテストしました。その後、アプリケーションを新しいイメージタグとして再ビルドし、Deployment を更新しました。重要なワークフローは、Pod が実行される前に、ノードでイメージを利用可能にすることです。



