[Kubernetes] イメージリポジトリなしでローカル開発する方法

スポンサーリンク

Kubernetesはその役割的に「Dockerfileからイメージのビルド」などの下準備部分は担当範囲ではなく、yaml書かれたimage名に応じてどこかからpullして動かすような前提に立っているため、事前にイメージが準備できていないと
Error: ErrImagePull
みたいなのが出て動きません。
Docker Hubにパブリック公開したくない、でもAWS ECRなど準備するのはめんどい…ということもあると思います。
そんなときローカルだけで開発する方法です。

概要

MinikubeのDocker環境に対してイメージをビルドし、imagePullPolicyをNeverにすることでMinikube環境にあるイメージを使うようにする。

前提条件

ローカル環境にはMinikubeを使用します。(それ以外のは知りません)

Dockerイメージビルド

Dockerfile

これはなんでもいいので適当な例です。

FROM busybox

CMD ["sleep", "10"]

10秒sleepして終わるだけです。終わるコマンドなのでJobにします。

事前準備

dockerコマンドの対象をMinikube内のDocker環境に向くようにする。(イメージもMinikube内にできる)

eval $(minikube docker-env)

$()の中身のminikube docker-envを実行してみればわかりますが、環境変数を設定しているだけです。
なのでターミナルウィンドウ1つ単位での設定となるので、ビルドを行いたいターミナルで毎回上記が先に実行することを忘れないでください。
(これを忘れてホストマシンのDocker上にイメージを作っても意味がありません)

ビルド

仮にfoo/barというイメージ名(タグ)にしたいとします。

docker image build -t foo/bar .
# . はDockerfileのあるディレクトリ

docker image lsで確認するとKubernetes関連イメージと並んでfoo/barが表示されると思います。
またここで他のターミナルウィンドウを開いてdocker image lsをしてもfoo/barが無いことからイメージはMinikube環境内にビルドされたことがわかります。

このままだとyamlにimage: foo/barと書いてもFailed to pull imageと言われて動かないのでyamlにも設定を追加します。

yaml設定

yamlにimagePullPolicy: Neverを設定します。
そうするとK8sはイメージをpullしにいかず、ローカルにあるものを使おうとします。ローカルというのはMinikube VM内にあるイメージです。
今回の例は10秒sleepして終わるのでJobとします。

apiVersion: batch/v1
kind: Job
metadata:
  name: example-job
spec:
  backoffLimit: 0
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: bar
        image: foo/bar # これが自作イメージ
        imagePullPolicy: Never # ローカルにあるイメージを使う

ダッシュボードのPodのイベントでもContainer image “foo/bar” already present on machineみたいなローカルからイメージ使いました的な意味のログが確認できると思います。

この手段とは別にskaffoldというツールを使うことでもローカル開発はできますが、「Pod内からyamlテンプレートを使って別のJobを作成したい」みたいな複雑なことをしようとすると対応しきれない気がします。

コメント