TOC
伏線回収
NanoPi M4V2にSonatype Nexus3をセットアップして、Dockerのプライベートリポジトリを作る
元々VMware内で使われていたらしい かなり評価が高い arm用のバイナリがなかったため今回は見送り。
以前DockerのプライベートのコンテナレジストリとしてSonatype Nexusを構築した時はHarborはamd64でしかパッケージを提供していなかったので、Raspberry Pi 4(当時使っていたのはNanoPi M4V2ですが)での構築を諦めていました。
ところが、BitnamiがHarborのdockerイメージとしてamd64用とarm64用を公開してくれていることに気付いたので早速構築することに。arm64用は2023/02/24から提供していたみたいです。
動作前提条件としては
- Docker Engine 1.10.0
- Docker compose 1.6.0以降推奨
ということになっています。今回もRaspberry Pi 4(RAM8GB)、Ubuntu Server 22.04LTSで構築します。また、今回はプルスルー型のプロキシとしての使い方をメインに扱い、上流をDockerhubとします。
Harbor構築
今回はBitnamiのパッケージを使うので、Harbor本体とは違う設定をする必要がある箇所がありますが、ひとまずBitnamiでの構築方法のページを見てみます。
containers/bitnami/harbor-portal at main · bitnami/containers · GitHub
$ mkdircd docker-harbor # 作業ディレクトリをmkdirして移動します
$ curl -LO https://raw.githubusercontent.com/bitnami/containers/main/bitnami/harbor-portal/docker-compose.yml
$ curl -L https://github.com/bitnami/containers/archive/main.tar.gz | tar xz --strip=2 containers-main/bitnami/harbor-portal && cp -RL harbor-portal/config . && rm -rf harbor-portal
手順ではここまでやったあとにいつも通りdocker-compose up
することになっていますが、これで構築すると設定箇所が足りないので変更が必要な箇所をまとめます。
コンテナを動かす前にやること
最低限必要な設定変更をしたdocker-compose.yml
とオリジナルとの差分は以下の通りです。
$ diff -u docker-compose.yml{.org,}
--- docker-compose.yml.org 2023-05-05 12:03:55.668467218 +0900
+++ docker-compose.yml 2023-05-05 13:53:20.131499710 +0900
@@ -40,7 +40,7 @@
- _REDIS_URL_REG=redis://redis:6379/1
- PORT=8080
- LOG_LEVEL=info
- - EXT_ENDPOINT=http://reg.mydomain.com
+ - EXT_ENDPOINT=http://192.168.1.210:8088
- DATABASE_TYPE=postgresql
- REGISTRY_CONTROLLER_URL=http://registryctl:8080
- POSTGRESQL_HOST=postgresql
@@ -65,6 +65,7 @@
- REGISTRY_CREDENTIAL_PASSWORD=harbor_registry_password
- READ_ONLY=false
- RELOAD_KEY=
+ - PERMITTED_REGISTRY_TYPES_FOR_PROXY_CACHE=docker-hub
volumes:
- core_data:/data
- ./config/core/app.conf:/etc/core/app.conf:ro
@@ -101,7 +102,8 @@
volumes:
- ./config/proxy/nginx.conf:/opt/bitnami/nginx/conf/nginx.conf:ro
ports:
- - '80:8080'
+ #- '80:8080'
+ - '8088:8080'
depends_on:
- postgresql
- registry
変更箇所は以下の通りです。
- Harborを動かすホストを
EXT_ENDPOINT
として設定 - Proxy Cacheとして動かす場合に上位リポジトリとして設定するレジストリの種類を
PERMITTED_REGISTRY_TYPES_FOR_PROXY_CACHE
として設定 - Harborがbindする実ポート番号を8088に変更
また、ログイン時のadminユーザーのパスワードをデフォルトのbitnami
から変更する場合はHARBOR_ADMIN_PASSWORD=bitnami
を変更します。
ボリュームマウントしているファイル・ディレクトリは以下の通りです。必要に応じて書き換えます。
サービス | ファイル・ディレクトリ | コンテナ内マッピング |
---|---|---|
registry | registry_data | /storage |
./config/registry/ | /etc/registry/:ro | |
registryctl | registry_data | /storage |
./config/registry/ | /etc/registry/:ro | |
./config/registryctl/config.yml | /etc/registryctl/config.yml:ro | |
postgresql | postgresql_data | /bitnami/postgresql |
core | core_data | /data |
./config/core/app.conf | /etc/core/app.conf:ro | |
./config/core/private_key.pem | /etc/core/private_key.pem:ro | |
portal | jobservice_data | /var/log/jobs |
./config/jobservice/config.yml | /etc/jobservice/config.yml:ro | |
harbor-nginx | ./config/proxy/nginx.conf | /opt/bitnami/nginx/conf/nginx.conf:ro |
chartmuseum | chartmuseum_data | /bitnami/data |
コンテナの起動と設定
docker-compose.ymlの変更が終わったら、docker-compose up -d
でコンテナを起動します。初回は結構時間がかかります。
EXT_ENDPOINT
で設定したURLにブラウザからアクセスしてまずadmin
ユーザーでログインします。パスワードは変更していなければbitnami
です。
レジストリの作成
プロキシキャッシュとして使う場合はプロジェクトの前にレジストリを作成します。左側のメニューのAdministrationの下にあるRegistriesを選択します。
NEW ENDPOINTとしてDockerhubを追加します。
ProviderはDocker Hubを選択します。Nameはプロジェクトから選択するのでわかりやすい名前にした方が良いでしょう。Endpoint URLはProviderを選択すると自動で入力され、変更不可能です。
TEST CONNECTIONを押すと、繋がるかどうかを確認できます。
OKを押すとRegistriesにDocker Hubが追加されます。
プロジェクトの作成
レジストリを追加したらプロジェクトを作成します。左側のメニューからProjectsを選択し、NEW PROJECTを選択します。
New Projectの入力項目は込み入っています。
- Project Nameは小文字のみ使用可→コンテナレジストリのURLとして使われる
- Access Level→Publicの場合、
docker login
による事前ログインが不要 - Storage Quota→-1の場合無制限
- Proxy Cache→有効にした場合、作成したレジストリからプルダウンで選ぶのでプロキシキャッシュとして使う場合はレジストリの作成が必須
OKを押すとプロジェクトが作成されます。
(備考)docker-compose.ymlでPERMITTED_REGISTRY_TYPES_FOR_PROXY_CACHEを指定しなかった場合
プロキシキャッシュとしてのHarborは執筆時点で上位リポジトリに
- Alibaba ACR
- Artifact Hub
- Aws ECR
- Azure ACR
- Docker Hub
- Docker Registry
- DTR
- Github GHCR
- Google GCR
- Harbor
- Huawei SWR
- JFrog Artifactory
- Quay
- Tencent TCR
を使えるようですが、環境変数PERMITTED_REGISTRY_TYPES_FOR_PROXY_CACHE
に使用する上位リポジトリを指定しないとエラーが出ます。特にBitnamiのHarborイメージの場合docker-compose.yml
に設定する行がないので、行ごと追加する必要があります。
Dockerクライアントの設定
クライアント(Dockerを使う側)はコンテナのダウンロード元としてHarborを指定する必要があるので、特に今回平文アクセスするので追加の設定が必要です。
また、今回構築したHarborのリポジトリのURLは192.168.1.210:8088/proxy/
で、Dockerイメージ名はhello-world
の場合192.168.1.210:8088/proxy/hello-world
になります。このproxyはHarborで作成したプロジェクトの名前です。
Dockerのインストール方法によって参照するファイルが違う可能性がありますが、Rootless Dockerの場合はDockerを実行するユーザーの~/.config/docker/daemon.json
に設定を記述します。1
HTTP許容設定前に動作確認をするとこうなります。
$ docker run 192.168.1.210:8088/proxy/hello-world
Unable to find image '192.168.1.210:8088/proxy/hello-world:latest' locally
docker: Error response from daemon: Get "https://192.168.1.210:8088/v2/": http: server gave HTTP response to HTTPS client.
See 'docker run --help'.
~/.config/docker
ディレクトリがない場合はディレクトリを作成します。
$ mkdir -p ~/.config/docker
~/.config/docker/daemon.json
を以下の内容で作成します。
{
"insecure-registries" : [
"192.168.1.210:8088"
]
}
Rootless Dockerに設定を反映させるため、systemdで再起動します。Harborを構築したホストで動作確認をしている場合、docker-composeで起動したコンテナも終了するので、コマンド実行後にdocker-compose up -d
を実行してしばらく待ちます。
$ systemctl --user restart docker.service
改めて動作確認。
$ docker run 192.168.1.210:8088/proxy/hello-world
Unable to find image '192.168.1.210:8088/proxy/hello-world:latest' locally
latest: Pulling from proxy/hello-world
Digest: sha256:9eabfcf6034695c4f6208296be9090b0a3487e20fb6a5cb056525242621cf73d
Status: Downloaded newer image for 192.168.1.210:8088/proxy/hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
イメージの取得元を確認します。
$ docker image ls -a
REPOSITORY TAG IMAGE ID CREATED SIZE
192.168.1.210:8088/proxy/hello-world latest 9c7a54a9a43c 39 hours ago 13.3kB
動作確認が終わりました。Harbor側のWebでキャッシュしたリポジトリを確認します。
Harborの自動起動
正常動作が確認できた場合は、docker-compose.yml
を書き換えてOSの再起動時に自動的にHarborが起動するように各サービスのrestart
にalways
やunless-stopped
を指定すると良いでしょう。最終的なデフォルトからの差分は以下のようになります。
$ diff -u docker-compose.yml{.org,}
--- docker-compose.yml.org 2023-05-05 12:03:55.668467218 +0900
+++ docker-compose.yml 2023-05-06 18:27:04.629054298 +0900
@@ -8,6 +8,7 @@
volumes:
- registry_data:/storage
- ./config/registry/:/etc/registry/:ro
+ restart: unless-stopped
registryctl:
image: docker.io/bitnami/harbor-registryctl:2
environment:
@@ -18,6 +19,7 @@
- registry_data:/storage
- ./config/registry/:/etc/registry/:ro
- ./config/registryctl/config.yml:/etc/registryctl/config.yml:ro
+ restart: unless-stopped
postgresql:
image: docker.io/bitnami/postgresql:13
container_name: harbor-db
@@ -26,6 +28,7 @@
- POSTGRESQL_DATABASE=registry
volumes:
- postgresql_data:/bitnami/postgresql
+ restart: unless-stopped
core:
image: docker.io/bitnami/harbor-core:2
container_name: harbor-core
@@ -40,7 +43,7 @@
- _REDIS_URL_REG=redis://redis:6379/1
- PORT=8080
- LOG_LEVEL=info
- - EXT_ENDPOINT=http://reg.mydomain.com
+ - EXT_ENDPOINT=http://192.168.1.210:8088
- DATABASE_TYPE=postgresql
- REGISTRY_CONTROLLER_URL=http://registryctl:8080
- POSTGRESQL_HOST=postgresql
@@ -65,15 +68,18 @@
- REGISTRY_CREDENTIAL_PASSWORD=harbor_registry_password
- READ_ONLY=false
- RELOAD_KEY=
+ - PERMITTED_REGISTRY_TYPES_FOR_PROXY_CACHE=docker-hub
volumes:
- core_data:/data
- ./config/core/app.conf:/etc/core/app.conf:ro
- ./config/core/private_key.pem:/etc/core/private_key.pem:ro
+ restart: unless-stopped
portal:
image: docker.io/bitnami/harbor-portal:2
container_name: harbor-portal
depends_on:
- core
+ restart: unless-stopped
jobservice:
image: docker.io/bitnami/harbor-jobservice:2
container_name: harbor-jobservice
@@ -90,23 +96,27 @@
volumes:
- jobservice_data:/var/log/jobs
- ./config/jobservice/config.yml:/etc/jobservice/config.yml:ro
+ restart: unless-stopped
redis:
image: docker.io/bitnami/redis:7.0
environment:
# ALLOW_EMPTY_PASSWORD is recommended only for development.
- ALLOW_EMPTY_PASSWORD=yes
+ restart: unless-stopped
harbor-nginx:
image: docker.io/bitnami/nginx:1.23
container_name: nginx
volumes:
- ./config/proxy/nginx.conf:/opt/bitnami/nginx/conf/nginx.conf:ro
ports:
- - '80:8080'
+ #- '80:8080'
+ - '8088:8080'
depends_on:
- postgresql
- registry
- core
- portal
+ restart: unless-stopped
chartmuseum:
container_name: chartmuseum
image: docker.io/bitnami/chartmuseum:0
@@ -122,6 +132,7 @@
- INDEX_LIMIT=0
volumes:
- chartmuseum_data:/bitnami/data
+ restart: unless-stopped
volumes:
registry_data:
driver: local
(余談)動作確認が終わったところで気付いたこと
無事にRaspberry Pi 4でHarborを動かすという目標は達成できましたが、dockerは通常docker-composeで動かします。docker-composeでダウンロードするDockerイメージはdocker-compose.ymlの中に書きますが、大抵の場合ホスト名を省略します。例えばNextcloudを構築した時はこんなふうになっています。
services:
db:
image: mariadb
restart: always
指定したimageを処理する場合にホスト名がないのでDockerhubからイメージをダウンロードするのがデフォルト動作になっている事自体は自然なことですが、dockerではどんな手を使ってもホスト名を省略した場合に参照するデフォルトのコンテナレジストリをDockerhub以外に変更できなさそうな仕様であることを知り、結構愕然としています。Dockerhubが落ちたりクラックされたら全てのimage行を書き換えるという作業が発生し、それが終わるまで何もできなくなります。
How to set a default registry to pull from in docker machine? - Stack Overflow
例外として、Redhatがフォークしたdockerは--add-repository
を指定することでデフォルトのコンテナレジストリを変更できたようですが、ご存知の通りRHEL8からdockerは削除され、Redhatとしてはpodmanを使うという方針のようなので、この仕様を踏襲したdockerのフォークが広く普及しない限りはDockerhubが落ちないことを祈りながら使うしかないという状況です。
このことを考えるとダウンロード元や検索先としてホスト名を変更できるpodmanに軸足を移すべきなのかなという必然性を感じており、また現在のpodmanはdocker-composeからも操作できるようなのでできることとできないことを確認してみたいと考えています。
スポンサーリンク
- Dockerの起動引数に”–insecure-registry ドメイン:ポート番号”で指定することもできますがsystemdではなくファイルに書いた方がわかりやすいかなと個人的には思います [return]
comments powered by Disqus