コンテナレジストリ(Lab)でDockerイメージを保存・配布する方法


概要

このチュートリアルでは、さくらのクラウド「コンテナレジストリ」の概念を学んだ後、レジストリの作成やイメージのアップロードやダウンロード、ユーザ認証を設定する方法を学びます。

説明

コンテナレジストリとは?

Docker イメージを保管・配布できるのは Docker Hub だけだと思っていませんか? さくらのクラウド「コンテナレジストリ」でもイメージの保管・配布だけでなく、複数の保存場所(レジストリ)を作ったり、必要に応じてユーザ認証も設定したりできます。Dockerイメージを保管・配布できる「コンテナレジストリ(Lab)」は 2020年12月から提供開始 しました。コンテナレジストリは国内のデータセンタ内にあり、通信 暗号化にも対応(Let's Encrypt)した、Docker Hub とプロトコルに互換性を持つレジストリ・サービスです。

※捕捉: Docker Hub は公開レジストリであり、docker コマンド操作時、pull や push が自動的に行われるデフォルトのレジストリです。

ちなみに、コンテナレジストリは「グローバルリソース」の扱いです。通常、サーバやネットワーク用スイッチなどのリソースは、「東京」や「石狩」といったゾーンに紐付く形で作成されますが、「グローバル」に相当する DNS や監視については、全ゾーン共通のリソースとして利用できます。

コンテナレジストリのリソース作成手順

Docker イメージを置くには、まずはじめにコンテナレジストリの作成が必要です。さくらのクラウド コントロールパネルにログイン後、左メニューにある「 Lab 」→「 コンテナレジストリ 」をクリックします。

画面右上の 「 追加 」 をクリックします。

次の追加画面では、必要項目を入力していきます。

今回は「初めてのレジストリ」と言う名前で、コンテナレジストリ名には好きな任意の名称(他人と重複できません)、公開設定は「非公開」にしましょう。

  • 「名前」…コントロールパネル上で表示する名前です
  • 「コンテナレジストリ名」… レジストリへの接続は *「入力した名前」.sakuracr.jp * で行います
  • 「公開設定」…レジストリに 認証を設けるかどうか を設定します
    • 「Push & Pull」…誰でもイメージを送受信できます(認証なし)
    • 「Pull のみ」…イメージをアップロード(push)時に認証を必要とします(Docker Hubと同じ)
    • 「非公開」…イメージのアップロード(push)とダウンロード(pull)の両方に認証をかけます

なお、もしドメイン名をお持ちの場合は「独自ドメイン」に FQDN を入力すると、その名前でもアクセスが可能になります。その際、DNS サーバでは CNAME 設定をコンテナレジストリ名にする作業が必要です。詳しくは ドキュメントをご覧ください。

入力内容の確認後、画面右下の「 作成 」をクリックします。

次の「操作確認」ダイアログでは、内容を確認の後、「 同意して作成 」をクリックします。

ダイアログ画面で「成功」にステータスが切り替わったら、「 閉じる 」をクリックします。

それから再び、左メニューの「コンテナレジストリ」をクリックすると、先ほど作成したレジストリが画面上に表示されます。

レジストリのユーザ作成

レジストリの「公開設定」を「Push&&Pull」にした場合は、このユーザ作成の手順は不要です。このチュートリアルでは「非公開」を選択しましたので、利用する前にレジストリに接続可能なユーザを作成します。

まず、レジストリ一覧から、対象のレジストリ名をダブルクリックします。

次の画面ではレジストリの情報が表示されています。ここでは「 ユーザ 」のタブをクリックします。

それから、右下にある「 追加 」をクリックします。

その次の「ユーザ」ダイアログでは、任意の「 ユーザ名 」(コンテナレジストリへのログイン時に必要です)、「 パスワード 」を入力し、ユーザ権限設定を「All」(push や pull 以外にも削除等を含む全ての権限)のまま、「 作成 」をクリックします。

正常に処理が完了すると、画面上にユーザが作成されています。

これでコンテナレジストリ側の準備は調いました。

自分の Docker イメージをアップロードする方法

ポイント:アップロード時に気を付けるのは、イメージ名を「 <コンテナレジストリ名>.sakuracr.jp/<イメージ名> 」の形式にする必要があること。

まずはイメージを準備

ここでは、簡単なサンプルイメージを作成します。

何らかのディレクトリを作成し、移動します。

$ mkdir mynginx
$ cd mynginx

それから、次の内容の「Dockerfile」という名称のファイルを作成します。

FROM nginx:alpine
RUN echo '<h1>Hello world with Docker!</h1>' > /usr/share/nginx/html/index.html

そして、この Dockerfile をもとに、イメージを構築(ビルド)します。実行するコマンドは docker build -t <作成したレジストリ名>.sakuracr.jp/hello-nginx:latest . です。

$ docker build -t registry-example.sakuracr.jp/hello-nginx:latest .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM nginx:alpine
alpine: Pulling from library/nginx
4167d3e14976: Pull complete
bb292c78f105: Pull complete
Digest: sha256:abe5ce652eb78d9c793df34453fddde12bb4d93d9fbf2c363d0992726e4d2cad
Status: Downloaded newer image for nginx:alpine
 ---> 377c0837328f
Step 2/2 : RUN echo '<h1>Hello world with Docker!</h1>' > /usr/share/nginx/html/index.html
 ---> Running in 1951f21abaa7
Removing intermediate container 1951f21abaa7
 ---> 5636fb0f6dad
Successfully built 5636fb0f6dad
Successfully tagged registry-example.sakuracr.jp/hello-nginx:latest

このように表示されていれば問題ありません。ここでローカルにあるイメージ一覧を表示する「docker images」を実行します。

$ docker images
REPOSITORY                                 TAG                 IMAGE ID            CREATED             SIZE
registry-example.sakuracr.jp/hello-nginx   latest              5636fb0f6dad        35 seconds ago      19.7MB
nginx                                      alpine              377c0837328f        38 hours ago        19.7MB

このように作成されていれば問題ありません。

今回はチュートリアルのため、ビルド時のタイミングでイメージ名にレジストリのホスト名も含めました。ビルド時でなくとも、イメージの作成後に、「docker tag」コマンドでイメージ名にホスト名を含めても構いません。

レジストリにログイン

イメージを送信する前に「docker login <レジストリ名>」コマンドでレジストリにログインします。

$ docker login registry-example.sakuracr.jp
Username: example
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

このような表示になれば、正常にログインできました。

エラー「Error response from daemon: Get https://registry-example.sakuracr.jp/v2/: unauthorized: authentication required」が表示された場合は、認証するユーザ名かパスワードが違います。正しいかどうかご確認ください。

イメージのアップロード

イメージを送信するには、認証後、「docker push」コマンドでイメージを送信します。送信時には、イメージにレジストリ名が付いている必要があるのを、忘れないでください。

$ docker push registry-example.sakuracr.jp/hello-nginx
The push refers to repository [registry-example.sakuracr.jp/hello-nginx]
f3dd4fec699b: Pushed
6f23cf4d16de: Pushed
531743b7098c: Pushed
latest: digest: sha256:b0e20778aef9dde51c6f0101b3ea50908d6165c66df51c5422b5e75a9ff09262 size: 946

特にエラーが出なければ送信完了です。

動作確認

イメージをアップロードしたので、ローカルのイメージは削除できます。「docker rmi」コマンドでイメージを削除しましょう。

# docker rmi registry-example.sakuracr.jp/hello-nginx
Untagged: registry-example.sakuracr.jp/hello-nginx:latest
Untagged: registry-example.sakuracr.jp/hello-nginx@sha256:b0e20778aef9dde51c6f0101b3ea50908d6165c66df51c5422b5e75a9ff09262
Deleted: sha256:5636fb0f6dadb2f17a413e092f1625ddbbe48237ef7cac39fe39ad08275216ad
Deleted: sha256:80240c8ed42d58137142581c30f34fd594e9a4dbf23c54d98787398ebcbf9431

「docker images」コマンドを実行すると、イメージ作成の元になった「nginx:alpine」のみが残ったままです。

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               alpine              377c0837328f        38 hours ago        19.7MB

この状態で、レジストリからイメージをダウンロードします。今度は「docker push」の逆で、「docker pull」を使います。

$ docker pull registry-example.sakuracr.jp/hello-nginx
Using default tag: latest
latest: Pulling from hello-nginx
4167d3e14976: Already exists
bb292c78f105: Already exists
619bae5a1971: Pull complete
Digest: sha256:b0e20778aef9dde51c6f0101b3ea50908d6165c66df51c5422b5e75a9ff09262
Status: Downloaded newer image for registry-example.sakuracr.jp/hello-nginx:latest
registry-example.sakuracr.jp/hello-nginx:latest

そして「docker images」を実行しましょう。ダウンロードされていれば、イメージ名が表示されているはずです。

あとは、このイメージを使ってコンテナを実行しましょう。

$ docker run --rm -p 8080:80 registry-example.sakuracr.jp/hello-nginx

コマンド実行後、 Docker を実行している <ホストのIP> を確認し、ブラウザで http:/IPアドレス:8080/ を開きます。先ほどビルドした、改変済みのウェブサイトのトップページ Hello world with Docker! が表示されていれば大丈夫です!

実行中の Nginx コンテナは「Ctrl+C」で中断・停止できます。

レジストリからログアウト

最後に [docker logout <レジストリ名>.sakuracr.jp]を実行してログアウト(正確には、ローカルに保存している認証情報の削除)します。

$ docker logout registry-example.sakuracr.jp
Removing login credentials for registry-example.sakuracr.jp

そして、ログアウト後は権限がありませんので、再度イメージを取得しようとしても次の様にエラーが出ます。

$ docker pull registry-example.sakuracr.jp/hello-nginx
Using default tag: latest
Error response from daemon: Get https://registry-example.sakuracr.jp/v2/hello-nginx/manifests/latest: unauthorized: authentication required

まとめ&振り返り

さくらのクラウドで Docker イメージを共有できる「コンテナレジストリ」を操作するための基本的な概念と、操作方法を学びました。また、コマンドを実行しながら、レジストリへのログインや、自分でカスタマイズした Nginx イメージ共有を行いました。Docker Hub と異なり、複数のレジストリの作成や、こまかなユーザ権限の設定もできますので、ぜひ色々とお試しくださいね。

参考情報