0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

k3dでローカルDockerレジストリを使えるようにする

Posted at

概要

k3dで、ローカルのDockerレジストリに格納されているコンテナイメージをデプロイする方法について説明します。
私自身たまにk3dを触るのですが、そのたびに自分で作ったコンテナイメージの扱いに困っていたので、備忘録として残すことにしました。

※ 本記事は、Ubuntu 22.04 で動作検証しています。

手順の概要

以下がおおまかな手順です。

  • k3dで利用するコンテナレジストリを作成
  • 作成したコンテナレジストリにコンテナイメージをpush。今回はbusyboxを利用
  • k3dでクラスターの作成
  • ローカルレジストリのコンテナイメージをpullしてPodが立ち上がることを確認

余談

最初は作成済みのクラスターにローカルレジストリを追加したかったのですが、それは困難または不可能ということがわかったので、「k3dで新たにクラスターを作る」前提で説明していきます。

手順

コンテナレジストリの作成

k3dのコマンドで、以下のように簡単にコンテナレジストリを作成できます。

k3d registry create registry --port 5000

コマンド実行後、k3d-registry という名前のコンテナレジストリがDockerコンテナとして作成されていることを確認できます。(k3d registry create の後の文字列 registry が、 k3d- の後ろに付与されるようです)

$ docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}"
NAMES                 IMAGE                         PORTS
k3d-registry          registry:2                    0.0.0.0:5000->5000/tcp

k3dのコマンドでも、以下のように確認可能です。

$ k3d registry ls
NAME           ROLE       CLUSTER   STATUS
k3d-registry   registry             running

--port 5000 を指定しない場合は、ホストOSの任意のポート番号(例:40787)が割り当てられてしまうのでご注意ください。

コンテナイメージをpush

作成したコンテナレジストリに、コンテナイメージをpushします。今回はサンプルとしてbusyboxのイメージを使います。

最初に、docker.ioからbusyboxのコンテナイメージを取得します。

docker pull busybox:1.37

"ローカルレジストリのホスト名:ポート番号" という形式で、新しいタグを付与します。

docker tag busybox:1.37 localhost:5000/busybox:1.37

ローカルレジストリにbusyboxのコンテナイメージをpushします。

docker push localhost:5000/busybox:1.37

以下のコマンドで、ローカルレジストリにbusyboxのコンテナイメージが追加されているのを確認できます。

$ curl -k http://localhost:5000/v2/_catalog
{"repositories":["busybox"]}

$ curl -k http://localhost:5000/v2/busybox/tags/list
{"name":"busybox","tags":["1.37"]}

コンテナイメージのpushに失敗する場合は、/etc/docker/daemon.json の設定変更が必要な可能性があります。筆者の記事になりますがdocker pushとpullを可能にするための設定などを参考に、Dockerが http://localhost:5000 に対してコンテナイメージをpushできるように設定してください。

クラスターの作成

事前準備

k3dコマンドでクラスターを作成する前に、次のようなコンテナレジストリの設定ファイルを用意します。

registries.yaml
mirrors:
  "localhost:5000":
    endpoint:
      - http://k3d-registry:5000

設定ファイルが必要な理由

先ほど localhost:5000 というホスト名でbusyboxのコンテナイメージをpushしましたが、次に作成するクラスターでPodをデプロイする際、ホスト名 localhost:5000 でイメージをpullしようとしてもレジストリにアクセスできません。これは、クラスターが作られるDockerのネットワークがホストOSのネットワークとは異なるためです。Dockerのネットワーク内では、レジストリに k3d-registry:5000 というホスト名でアクセスできます。そこで、この設定ファイルでは「localhost:5000 へのリクエストを http://k3d-registry:5000 に転送する」ように設定しています。

k3dコマンドでクラスターを作成

以下のコマンドで、k3dを使って(k3sの)クラスターを作成します。

k3d cluster create \
--registry-config registries.yaml \
--registry-use k3d-registry

k3s-default という名前のk3sクラスターが作成されます。

$ k3d cluster ls
NAME          SERVERS   AGENTS   LOADBALANCER
k3s-default   1/1       0/0      true

デフォルトでは k3s-default という名前のクラスターが作成されますが、クラスター名をカスタマイズしたい場合は、k3d cluster create の後に任意のクラスター名を指定します。

k3d cluster create [cluster-name] \
--registry-config registries.yaml \
--registry-use k3d-registry

ローカルレジストリのコンテナイメージをpullしてPodが立ち上がることを確認

先ほどpushしたコンテナイメージを使ってPodを起動できるかを確認します。

kubectl -n default run busybox \
--rm -it \
--image=localhost:5000/busybox:1.37

問題なくbusyboxをpullできれば、以下のようにコンテナ内に入れるはずです。

/ # date
Tue Sep 23 07:26:07 UTC 2025
/ # 

別のターミナルを開くと、busyboxのPodが立ち上がっているのを確認できます。

$ kubectl get po -n default
NAME      READY   STATUS    RESTARTS   AGE
busybox   1/1     Running   0          3s

ついでに、コンテナイメージが正常にpullできていることも確認してみます。

$ kubectl describe po -n default busybox | grep -A 32 ^Events:
Events:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  4m7s  default-scheduler  Successfully assigned default/busybox to k3d-k3s-default-server-0
  Normal  Pulling    4m7s  kubelet            Pulling image "localhost:5000/busybox:1.37"
  Normal  Pulled     4m7s  kubelet            Successfully pulled image "localhost:5000/busybox:1.37" in 97ms (97ms including waiting). Image size: 2283988 bytes.
  Normal  Created    4m7s  kubelet            Created container busybox
  Normal  Started    4m7s  kubelet            Started container busybox

補足: コンテナレジストリを "k3d registry create" を使わずに作った場合の対応

コンテナレジストリを k3d registry create コマンドではなく、Docker Composeなどで自前で作成している場合、k3dでクラスターを作成する手順が若干異なります。
例えば、以下のように自前でコンテナレジストリを起動している状況を考えます。

$ docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}"
NAMES                 IMAGE                         PORTS
docker-registry       registry:2                    0.0.0.0:5000->5000/tcp, [::]:5000->5000/tcp

クラスター作成前に、以下の registries.yaml を用意する点は同じです。(ホスト名が docker-registry に変わっている点に注意してください)

registries.yaml
mirrors:
  "localhost:5000":
    endpoint:
      - http://docker-registry:5000

クラスターを作成するコマンドは先ほどと異なり、--registry-use のオプションなしで実行します。

k3d cluster create \
--registry-config registries.yaml

この状態だとk3sクラスターから http://docker-registry:5000 へのリクエストが通らないため、docker-registry コンテナを k3d-k3s-default のDockerネットワークに追加する必要があります。

最初に以下のコマンドで、k3sのネットワーク名を特定します。

$ docker network ls | grep k3s
22e23f936ef6   k3d-k3s-default           bridge    local

特定したネットワークに、docker-registry のコンテナを追加します。

docker network connect k3d-k3s-default docker-registry

これで、k3sクラスターからローカルレジストリのコンテナイメージをpullできるようになるはずです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?