TOC
コンテナが多いHarbor
Harborはrootless dockerで構築しましたが、これもPodmanで動かします。
ただ、これまでPodman(systemd)で動かしてきたNginxやNavidromeと違って、Harborはdocker-compose.ymlに定義されているコンテナが多いので今までとは毛色の違う作業になりました。
Podmanシリーズとしては前回記事の続きです。
LAN上のMinIOからRcloneで曲データを引っ張りながらNavidromeを題材に、Docker Compose風運用をPodmanで動かす
rootless dockerでHarborを動かした時の記事はこちら。
コンテナレジストリHarborをRaspberry Pi 4で動かす
以前の記事を参照くださいと言いたいところですがRPi4で構築した時からdocker-compose.ymlがガラッと変わっていたのでお気を付け下さい。具体的にはchartmuseumが全部なくなっていました。
[bitnami/harbor-portal] Release 2.8.1-debian-11-r9 (#34966) · bitnami/containers@510a9a3 · GitHub
podman-composeで動かす
いつも通り、podman-composeでHarborを動かします。
$ mkdir -p ~/podmancompose/harbor
$ cd ~/podmancompose/harbor
$ 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
$ tree .
.
├── config
│ ├── core
│ │ ├── app.conf
│ │ └── private_key.pem
│ ├── jobservice
│ │ └── config.yml
│ ├── proxy
│ │ └── nginx.conf
│ ├── registry
│ │ ├── config.yml
│ │ ├── passwd
│ │ └── root.crt
│ └── registryctl
│ └── config.yml
└── docker-compose.yml
6 directories, 9 files
docker-compose.ymlを以下の内容で作成。
# Copyright VMware, Inc.
# SPDX-License-Identifier: APACHE-2.0
version: '2'
services:
registry:
image: docker.io/bitnami/harbor-registry:2
environment:
- REGISTRY_HTTP_SECRET=CHANGEME
volumes:
- /var/containers/harbor_registry_data:/storage
- /var/containers/harbor_config/registry/:/etc/registry/:ro
registryctl:
image: docker.io/bitnami/harbor-registryctl:2
environment:
- CORE_SECRET=CHANGEME
- JOBSERVICE_SECRET=CHANGEME
- REGISTRY_HTTP_SECRET=CHANGEME
volumes:
- /var/containers/harbor_registry_data:/storage
- /var/containers/harbor_config/registry/:/etc/registry/:ro
- /var/containers/harbor_config/registryctl/config.yml:/etc/registryctl/config.yml:ro
postgresql:
image: docker.io/bitnami/postgresql:13
container_name: harbor-db
environment:
- POSTGRESQL_PASSWORD=bitnami
- POSTGRESQL_DATABASE=registry
volumes:
- /var/containers/harbor_postgresql_data:/bitnami/postgresql
core:
image: docker.io/bitnami/harbor-core:2
container_name: harbor-core
depends_on:
- registry
environment:
- CORE_KEY=change-this-key
- _REDIS_URL_CORE=redis://redis:6379/0
- SYNC_REGISTRY=false
- CHART_CACHE_DRIVER=redis
- _REDIS_URL_REG=redis://redis:6379/1
- PORT=8080
- LOG_LEVEL=info
- EXT_ENDPOINT=http://192.168.1.114:8088
- DATABASE_TYPE=postgresql
- REGISTRY_CONTROLLER_URL=http://registryctl:8080
- POSTGRESQL_HOST=postgresql
- POSTGRESQL_PORT=5432
- POSTGRESQL_DATABASE=registry
- POSTGRESQL_USERNAME=postgres
- POSTGRESQL_PASSWORD=bitnami
- POSTGRESQL_SSLMODE=disable
- REGISTRY_URL=http://registry:5000
- TOKEN_SERVICE_URL=http://core:8080/service/token
- HARBOR_ADMIN_PASSWORD=bitnami
- CORE_SECRET=CHANGEME
- JOBSERVICE_SECRET=CHANGEME
- ADMIRAL_URL=
- WITH_NOTARY=False
- CORE_URL=http://core:8080
- JOBSERVICE_URL=http://jobservice:8080
- REGISTRY_STORAGE_PROVIDER_NAME=filesystem
- REGISTRY_CREDENTIAL_USERNAME=harbor_registry_user
- REGISTRY_CREDENTIAL_PASSWORD=harbor_registry_password
- READ_ONLY=false
- RELOAD_KEY=
- PERMITTED_REGISTRY_TYPES_FOR_PROXY_CACHE=docker-hub,github-ghcr
volumes:
- /var/containers/harbor_core_data:/data
- /var/containers/harbor_config/core/app.conf:/etc/core/app.conf:ro
- /var/containers/harbor_config/core/private_key.pem:/etc/core/private_key.pem:ro
portal:
image: docker.io/bitnami/harbor-portal:2
container_name: harbor-portal
depends_on:
- core
jobservice:
image: docker.io/bitnami/harbor-jobservice:2
container_name: harbor-jobservice
depends_on:
- redis
- core
environment:
- CORE_SECRET=CHANGEME
- JOBSERVICE_SECRET=CHANGEME
- CORE_URL=http://core:8080
- REGISTRY_CONTROLLER_URL=http://registryctl:8080
- REGISTRY_CREDENTIAL_USERNAME=harbor_registry_user
- REGISTRY_CREDENTIAL_PASSWORD=harbor_registry_password
volumes:
- /var/containers/harbor_jobservice_data:/var/log/jobs
- /var/containers/harbor_config/jobservice/config.yml:/etc/jobservice/config.yml:ro
redis:
image: docker.io/bitnami/redis:7.0
environment:
# ALLOW_EMPTY_PASSWORD is recommended only for development.
- ALLOW_EMPTY_PASSWORD=yes
harbor-nginx:
image: docker.io/bitnami/nginx:1.25
container_name: nginx
volumes:
- /var/containers/harbor_config/proxy/nginx.conf:/opt/bitnami/nginx/conf/nginx.conf:ro
ports:
- '8088:8080'
depends_on:
- postgresql
- registry
- core
- portal
volumes:
registry_data:
driver: local
core_data:
driver: local
jobservice_data:
driver: local
postgresql_data:
driver: local
オリジナルからの差分は以下。
--- docker-compose.yml.org 2023-08-23 18:59:58.126100661 +0900
+++ docker-compose.yml 2023-08-23 19:05:31.019270215 +0900
@@ -9,8 +9,8 @@
environment:
- REGISTRY_HTTP_SECRET=CHANGEME
volumes:
- - registry_data:/storage
- - ./config/registry/:/etc/registry/:ro
+ - /var/containers/harbor_registry_data:/storage
+ - /var/containers/harbor_config/registry/:/etc/registry/:ro
registryctl:
image: docker.io/bitnami/harbor-registryctl:2
environment:
@@ -18,9 +18,9 @@
- JOBSERVICE_SECRET=CHANGEME
- REGISTRY_HTTP_SECRET=CHANGEME
volumes:
- - registry_data:/storage
- - ./config/registry/:/etc/registry/:ro
- - ./config/registryctl/config.yml:/etc/registryctl/config.yml:ro
+ - /var/containers/harbor_registry_data:/storage
+ - /var/containers/harbor_config/registry/:/etc/registry/:ro
+ - /var/containers/harbor_config/registryctl/config.yml:/etc/registryctl/config.yml:ro
postgresql:
image: docker.io/bitnami/postgresql:13
container_name: harbor-db
@@ -28,7 +28,7 @@
- POSTGRESQL_PASSWORD=bitnami
- POSTGRESQL_DATABASE=registry
volumes:
- - postgresql_data:/bitnami/postgresql
+ - /var/containers/harbor_postgresql_data:/bitnami/postgresql
core:
image: docker.io/bitnami/harbor-core:2
container_name: harbor-core
@@ -42,7 +42,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.114:8088
- DATABASE_TYPE=postgresql
- REGISTRY_CONTROLLER_URL=http://registryctl:8080
- POSTGRESQL_HOST=postgresql
@@ -65,10 +65,11 @@
- REGISTRY_CREDENTIAL_PASSWORD=harbor_registry_password
- READ_ONLY=false
- RELOAD_KEY=
+ - PERMITTED_REGISTRY_TYPES_FOR_PROXY_CACHE=docker-hub,github-ghcr
volumes:
- - core_data:/data
- - ./config/core/app.conf:/etc/core/app.conf:ro
- - ./config/core/private_key.pem:/etc/core/private_key.pem:ro
+ - /var/containers/harbor_core_data:/data
+ - /var/containers/harbor_config/core/app.conf:/etc/core/app.conf:ro
+ - /var/containers/harbor_config/core/private_key.pem:/etc/core/private_key.pem:ro
portal:
image: docker.io/bitnami/harbor-portal:2
container_name: harbor-portal
@@ -88,8 +89,8 @@
- REGISTRY_CREDENTIAL_USERNAME=harbor_registry_user
- REGISTRY_CREDENTIAL_PASSWORD=harbor_registry_password
volumes:
- - jobservice_data:/var/log/jobs
- - ./config/jobservice/config.yml:/etc/jobservice/config.yml:ro
+ - /var/containers/harbor_jobservice_data:/var/log/jobs
+ - /var/containers/harbor_config/jobservice/config.yml:/etc/jobservice/config.yml:ro
redis:
image: docker.io/bitnami/redis:7.0
environment:
@@ -99,9 +100,9 @@
image: docker.io/bitnami/nginx:1.25
container_name: nginx
volumes:
- - ./config/proxy/nginx.conf:/opt/bitnami/nginx/conf/nginx.conf:ro
+ - /var/containers/harbor_config/proxy/nginx.conf:/opt/bitnami/nginx/conf/nginx.conf:ro
ports:
- - '80:8080'
+ - '8088:8080'
depends_on:
- postgresql
- registry
ボリュームについて、相対パスで書かれているので絶対パスに変更しています。
サービス | ファイル・ディレクトリ | コンテナ内マッピング |
---|---|---|
registry | /var/containers/harbor_registry_data | /storage |
/var/containers/harbor_config/registry/ | /etc/registry/:ro | |
registryctl | /var/containers/harbor_registry_data | /storage |
/var/containers/harbor_config/registry/ | /etc/registry/:ro | |
/var/containers/harbor_config/registryctl/config.yml | /etc/registryctl/config.yml:ro | |
postgresql | /var/containers/harbor_postgresql_data | /bitnami/postgresql |
core | /var/containers/harbor_core_data | /data |
/var/containers/harbor_config/core/app.conf | /etc/core/app.conf:ro | |
/var/containers/harbor_config/core/private_key.pem | /etc/core/private_key.pem:ro | |
portal | /var/containers/harbor_jobservice_data | /var/log/jobs |
/var/containers/harbor_config/jobservice/config.yml | /etc/jobservice/config.yml:ro | |
harbor-nginx | /var/containers/harbor_config/proxy/nginx.conf | /opt/bitnami/nginx/conf/nginx.conf:ro |
ボリュームで使用するディレクトリ(config)は使用する場所に移動します。移動先の所有者はrootなので以下の作業はrootユーザーでやります。
# mv /home/hogehoge/podmancompose/harbor/config /var/containers/harbor_config
上表のコンテナ内マッピングでroが付いていないファイルはharborコンテナから生成するものと思われるので、ディレクトリを作ります。
ディレクトリを作る際に、今回のrootless podmanで使うことになるUIDは166536、GIDは166537なので、オーナーのUIDとGIDはこれで作ります。
# cd /var/containers/
# install -d -m 755 -o 166536 -g 166537 harbor_registry_data harbor_postgresql_data harbor_core_data harbor_jobservice_data
podman-composeでコンテナを起動します。
$ ~/podmancompose/harbor
$ podman-compose up -d
今回はエンドポイントを http://192.168.1.114:8088 にしているので、ブラウザからHarborのログイン画面が表示できることを確認したらコンテナを落とします。
$ podman-compose down
systemdのユニットファイルを生成
HarborをOS起動時に起動したいのでもう一回Harborを上げます。
$ podman-compose up -d
$ podman-compose ps
podman-compose version: 1.0.6
['podman', '--version', '']
using podman version: 3.4.4
podman ps -a --filter label=io.podman.compose.project=harbor
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dd386831b04b docker.io/bitnami/harbor-registry:2 /opt/bitnami/scri... 2 minutes ago Up 2 minutes ago harbor_registry_1
a229d4ac970f docker.io/bitnami/harbor-registryctl:2 /opt/bitnami/scri... 2 minutes ago Up 2 minutes ago harbor_registryctl_1
abfa45cc746d docker.io/bitnami/postgresql:13 /opt/bitnami/scri... 2 minutes ago Up 2 minutes ago harbor-db
894910c11a99 docker.io/bitnami/redis:7.0 /opt/bitnami/scri... 2 minutes ago Up 2 minutes ago harbor_redis_1
892e85a7bc3a docker.io/bitnami/harbor-core:2 /opt/bitnami/scri... 2 minutes ago Up 2 minutes ago harbor-core
0e6164b7fc45 docker.io/bitnami/harbor-portal:2 /opt/bitnami/scri... 2 minutes ago Up 2 minutes ago harbor-portal
f32487978a09 docker.io/bitnami/harbor-jobservice:2 /opt/bitnami/scri... 2 minutes ago Up 2 minutes ago harbor-jobservice
7e4064016cba docker.io/bitnami/nginx:1.25 /opt/bitnami/scri... 2 minutes ago Up 2 minutes ago 0.0.0.0:8088->8080/tcp nginx
exit code: 0
systemdで起動する時の起動順序を確認します。
docker-compose.ymlのservicesとdepends_onの関係は以下の表の通り。
service | depends_on | コンテナ名 |
---|---|---|
registry | harbor_registry_1 | |
registryctl | harbor_registryctl_1 | |
postgresql | harbor-db | |
core | registry | harbor-core |
portal | core | harbor-portal |
jobservice | redis core | harbor-jobservice |
redis | harbor_redis_1 | |
harbor-nginx | postgresql registry core portal | nginx |
何も考えずにユニットファイル生成→全然ダメ
podman generate systemd
がこれらの依存関係を汲み取ってユニットファイルを生成してくれると期待して生成してみます。
$ podman generate systemd --new --files --name nginx
$ cat container-nginx.service
# container-nginx.service
# autogenerated by Podman 3.4.4
# Wed Aug 30 18:15:15 JST 2023
[Unit]
Description=Podman container-nginx.service
Documentation=man:podman-generate-systemd(1)
Wants=network-online.target
After=network-online.target
RequiresMountsFor=%t/containers
[Service]
Environment=PODMAN_SYSTEMD_UNIT=%n
Restart=on-failure
TimeoutStopSec=70
ExecStartPre=/bin/rm -f %t/%n.ctr-id
ExecStart=/usr/bin/podman run --cidfile=%t/%n.ctr-id --cgroups=no-conmon --rm --sdnotify=conmon --replace --name=nginx -d --requires=harbor-portal,harbor_registry_1,harbor-db,harbor-core --label io.podman.compose.config-hash=c290d564c40fa6c1d633731cd80b143fe71352c4bc065646f3adae1db6ad5682 --label io.podman.compose.project=harbor --label io.podman.compose.version=1.0.6 --label PODMAN_SYSTEMD_UNIT=podman-compose@harbor.service --label com.docker.compose.project=harbor --label com.docker.compose.project.working_dir=/home/hogehoge/podmancompose/harbor --label com.docker.compose.project.config_files=docker-compose.yml --label com.docker.compose.container-number=1 --label com.docker.compose.service=harbor-nginx -v /home/hogehoge/podmancompose/harbor/config/proxy/nginx.conf:/opt/bitnami/nginx/conf/nginx.conf:ro --net harbor_default --network-alias harbor-nginx -p 8088:8080 docker.io/bitnami/nginx:1.25
ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id
Type=notify
NotifyAccess=all
[Install]
WantedBy=default.target
んー。どうなんでしょうこれ。とりあえずやってみる。
$ podman-compose down
$ mv container-nginx.service ~/.config/systemd/user/
$ systemctl --user enable container-nginx.service
$ systemctl --user start container-nginx.service
Job for container-nginx.service failed because the control process exited with error code.
See "systemctl --user status container-nginx.service" and "journalctl --user -xeu container-nginx.service" for details.
エラーで終わってるのでjournalctl --user -xeu container-nginx.service
でどんなエラーか確認したらこんなのでした。
Aug 30 18:22:58 ubuntu podman[24993]: Error: "harbor-portal" is not a valid container, cannot be used as a dependency: no container with name or ID "harbor-portal" found: no such container
Aug 30 18:22:59 ubuntu systemd[791]: container-nginx.service: Main process exited, code=exited, status=125/n/a
Aug 30 18:22:59 ubuntu podman[25171]: Error: error reading CIDFile: open /run/user/1001/container-nginx.service.ctr-id: no such file or directory
Aug 30 18:22:59 ubuntu systemd[791]: container-nginx.service: Control process exited, code=exited, status=125/n/a
これが5回表示されてフィニッシュです。とりあえずsystemdから無効化してユニットファイルを削除します。
$ systemctl --user stop container-nginx
$ systemctl --user disable container-nginx
Removed /home/hogehoge/.config/systemd/user/default.target.wants/container-nginx.service.
$ rm ~/.config/systemd/user/container-nginx.service
ちゃんとコンテナの起動順を適用して解決するまで持っていく試み
従前の表をもう一度よく見てみると、起動したコンテナ名nginx
はdepends_onとしてpostgresql
とregistry
とcore
とportal
が書かれているので、docker-compose/podman-composeでコンテナを起動した場合は事前にこの4つのサービスの起動が終わってる状態でnginxは起動するように設定されていて、エラーログも「harbor-portalがない」と書かれている。ということから考えると、nginxよりも先にharbor-portalを起動すればこのエラーは出なくなりそうです。
ということで、depends_onが色々設定されているので8個のサービスの依存関係を整理するとこんな感じになるのでは。
字に起こすとこうなるんですが、
- registryを最初に起動
- coreをregistryの後に起動
- redisを起動
- coreとredisの後にjobserviceを起動
- coreの後にportalを起動
- postgresqlを起動
- registryとcoreとportalとpostgresqlの後にharbor-nginxを起動
- registructlを起動(いつでもいい)
冗長な依存を減らします。
- coreの起動前にregistryは起動しているので、harbor-nginxからregistryの依存を削除
- portalの前にcoreは起動しているので、harbor-nginxからcoreへの依存を削除
これを元にそれぞれのSystemdのユニットファイルを生成して起動してみます。podmanが4.0.0以降であればpodman generate systemd
コマンドは--requires
で依存systemdユニットを指定できます。--wants
も同じ様に依存systemdユニットを指定する引数ですが、Wantsは指定ユニットの起動に失敗しても起動をするオプションらしく、今回の用途では依存ユニットが起動失敗したらシステムとしての用をなさないのでRequiresで依存ユニットを指定します。また、起動順の指定は--requires
とは別に--after
で指定します。Afterで指定しないと、Requiresで指定したユニットの起動終了を待たずに並行して起動します(systemdの仕様)。
とpodmanの機能を書いたところですが、今回使っているUbuntu 22.04のpodmanは3.4.4なのでrequiresもafterも手で書き込みます。
まずはpodman-composeでharborサービスを起動します。
$ podman-compose up -d
依存ユニットのないコンテナのユニットファイル生成
registryctl、registry、redis、postgresqlは依存ユニットがないのでサクッと行きます。
$ podman generate systemd --new --files --name harbor_registryctl_1
/home/hogehoge/podmancompose/harbor/container-harbor_registryctl_1.service
$ podman generate systemd --new --files --name harbor_registry_1
/home/hogehoge/podmancompose/harbor/container-harbor_registry_1.service
$ podman generate systemd --new --files --name harbor_redis_1
/home/hogehoge/podmancompose/harbor/container-harbor_redis_1.service
$ podman generate systemd --new --files --name harbor-db
/home/hogehoge/podmancompose/harbor/container-harbor-db.service
依存ユニットのあるコンテナのユニットファイル生成
coreはregistryが依存ユニットです。
$ podman generate systemd --new --files --name harbor-core
/home/hogehoge/podmancompose/harbor/container-harbor-core.service
以下の様に書き換えます。Requires/After行を変更します。
--- container-harbor-core.service.org 2023-09-01 23:31:01.459048829 +0900
+++ container-harbor-core.service 2023-09-01 23:38:47.853545922 +0900
@@ -5,8 +5,8 @@
[Unit]
Description=Podman container-harbor-core.service
Documentation=man:podman-generate-systemd(1)
-Wants=network-online.target
-After=network-online.target
+Requires=container-harbor_registry_1.service
+After=network-online.target container-harbor_registry_1.service
After=network-online.target
RequiresMountsFor=%t/containers
portalはcoreが依存ユニットです。
$ podman generate systemd --new --files --name harbor-portal
/home/hogehoge/podmancompose/harbor/container-harbor-portal.service
以下の様に書き換えます。Requires/After行を変更します。
--- container-harbor-portal.service.org 2023-09-01 23:31:28.594740677 +0900
+++ container-harbor-portal.service 2023-09-01 23:34:18.792200193 +0900
@@ -5,8 +5,8 @@
[Unit]
Description=Podman container-harbor-portal.service
Documentation=man:podman-generate-systemd(1)
-Wants=network-online.target
-After=network-online.target
+Requires=container-harbor-core.service
+After=network-online.target container-harbor-core.service
After=network-online.target
RequiresMountsFor=%t/containers
jobserviceはredisとcoreが依存ユニットです。
$ podman generate systemd --new --files --name harbor-jobservice
/home/hogehoge/podmancompose/harbor/container-harbor-jobservice.service
以下の様に書き換えます。Requires/After行を変更します。
--- container-harbor-jobservice.service.org 2023-09-01 23:31:56.750408062 +0900
+++ container-harbor-jobservice.service 2023-09-01 23:35:46.015990350 +0900
@@ -5,8 +5,8 @@
[Unit]
Description=Podman container-harbor-jobservice.service
Documentation=man:podman-generate-systemd(1)
-Wants=network-online.target
-After=network-online.target
+Requires=container-harbor_redis_1.service container-harbor-core.service
+After=network-online.target container-harbor_redis_1.service container-harbor-core.service
After=network-online.target
RequiresMountsFor=%t/containers
harbor-nginxはportalとpostgresqlが依存ユニットです。
$ podman generate systemd --new --files --name nginx
/home/hogehoge/podmancompose/harbor/container-nginx.service
以下の様に書き換えます。Requires/After行を変更します。
--- container-nginx.service.org 2023-09-01 23:32:13.729811161 +0900
+++ container-nginx.service 2023-09-01 23:36:51.647207502 +0900
@@ -5,8 +5,8 @@
[Unit]
Description=Podman container-nginx.service
Documentation=man:podman-generate-systemd(1)
-Wants=network-online.target
-After=network-online.target
+Requires=container-harbor-portal.service container-harbor-db.service
+After=network-online.target container-harbor-portal.service container-harbor-db.service
After=network-online.target
RequiresMountsFor=%t/containers
全部終わったらpodman-composeでコンテナを落とします。
$ podman-compose down
Systemdへのユニットファイルの登録
作った8ファイルをsystemdに登録します。
$ mv container-harbor-core.service container-harbor-db.service container-harbor-jobservice.service container-harbor-portal.service container-harbor_redis_1.service container-harbor_registry_1.service container-harbor_registryctl_1.service container-nginx.service ~/.config/systemd/user/
enableとstartは依存を壊さない順序で行います。
$ systemctl --user enable container-harbor_registryctl_1.service
Created symlink /home/hogehoge/.config/systemd/user/default.target.wants/container-harbor_registryctl_1.service → /home/hogehoge/.config/systemd/user/container-harbor_registryctl_1.service.
$ systemctl --user start container-harbor_registryctl_1.service
$ systemctl --user enable container-harbor_registry_1.service
Created symlink /home/hogehoge/.config/systemd/user/default.target.wants/container-harbor_registry_1.service → /home/hogehoge/.config/systemd/user/container-harbor_registry_1.service.
$ systemctl --user start container-harbor_registry_1.service
$ systemctl --user enable container-harbor_redis_1.service
Created symlink /home/hogehoge/.config/systemd/user/default.target.wants/container-harbor_redis_1.service → /home/hogehoge/.config/systemd/user/container-harbor_redis_1.service.
$ systemctl --user start container-harbor_redis_1.service
$ systemctl --user enable container-harbor-db.service
Created symlink /home/hogehoge/.config/systemd/user/default.target.wants/container-harbor-db.service → /home/hogehoge/.config/systemd/user/container-harbor-db.service.
$ systemctl --user start container-harbor-db.service
$ systemctl --user enable container-harbor-core.service
Created symlink /home/hogehoge/.config/systemd/user/default.target.wants/container-harbor-core.service → /home/hogehoge/.config/systemd/user/container-harbor-core.service.
$ systemctl --user start container-harbor-core.service
$ systemctl --user enable container-harbor-portal.service
Created symlink /home/hogehoge/.config/systemd/user/default.target.wants/container-harbor-portal.service → /home/hogehoge/.config/systemd/user/container-harbor-portal.service.
$ systemctl --user start container-harbor-portal.service
$ systemctl --user enable container-harbor-jobservice.service
Created symlink /home/hogehoge/.config/systemd/user/default.target.wants/container-harbor-jobservice.service → /home/hogehoge/.config/systemd/user/container-harbor-jobservice.service.
$ systemctl --user start container-harbor-jobservice.service
$ systemctl --user enable container-nginx.service
Created symlink /home/hogehoge/.config/systemd/user/default.target.wants/container-nginx.service → /home/hogehoge/.config/systemd/user/container-nginx.service.
$ systemctl --user start container-nginx.service
エラーが表示されずに終了したら、各ユニットの状態を確認します。(関係のないものは削除しています)
$ systemctl --user list-dependencies
default.target
● ├─container-harbor-core.service
● ├─container-harbor-db.service
● ├─container-harbor-jobservice.service
● ├─container-harbor-portal.service
● ├─container-harbor_redis_1.service
● ├─container-harbor_registry_1.service
● ├─container-harbor_registryctl_1.service
● ├─container-nginx.service
ブラウザからHarborの管理画面にアクセスできることを確認したらOSを再起動して同じ様にブラウザからHarborの管理画面にアクセスできることを確認します。
OS再起動した結果
Systemdの設定でOSの起動時にも起動するようになっているので、試しにOSを再起動してみます。
$ systemctl --user list-dependencies
default.target
● ├─container-harbor-core.service
● ├─container-harbor-db.service
● ├─container-harbor-jobservice.service
● ├─container-harbor-portal.service
● ├─container-harbor_redis_1.service
● ├─container-harbor_registry_1.service
● ├─container-harbor_registryctl_1.service
● ├─container-navidrome_navidrome_1.service
● ├─container-nginx.service
全て色付きの●になっていればOKです。
DockerHubとGitHub Container Registryをキャッシュするように設定する
OCI準拠のコンテナをダウンロードするときにDockerHubは今でも最もよく使われるコンテナレジストリですが、他にGitHub Container Registry(ghcr.io)もかなりよく見ます。GitHubのCI/CDからできるからという理由だと思うのですが。
なので、この2つのレジストリに対してPodman等のコンテナランタイムからアクセスする際はイメージをHarborにキャッシュするように設定します。
画像は以前のHarbor構築にあるものと同じなので、画像は省略します。
レジストリの作成
左側のメニューのAdministrationの下にあるRegistriesを選択します。
NEW ENDPOINTとしてDockerHubとGHCRを追加します。Registries画面から「NEW ENDPOINT」を選択し、New Registry Endpoint画面で以下の設定値で作成します。
- Provider Docker Hub
- Name 任意(入力必須)
- Endpoint URL 自動入力のまま
- Access ID/Access Secret 空欄のまま
Verify Remote Cert ☑のまま(デフォルト)
Provider Github GHCR
Name 任意(入力必須)
Endpoint URL 自動入力のまま
Access ID/Access Secret 空欄のまま
Verify Remote Cert ☑のまま(デフォルト)
プロジェクトの作成
左側のメニューからProjectsを選択し、NEW PROJECTを選択します。以下の情報をDockerHubとGHCRそれぞれに作ります。
- Project Name 任意(URLの一部になる。小文字のみ入力可) 今回は dockerhub と ghcr で作成
- Access Level ☑Public
- Storage Quota -1のまま(無設定)
- Proxy Cache トグルボタンを有効にして右のプルダウンから作成したレジストリを選択。Endpointは自動入力される
プロジェクトを作成した場合、HarborのリポジトリURLは192.168.1.114:8088/dockerhub となり、hello-worldのDockerイメージURLは http://192.168.1.114:8088/dockerhub/hello-world になります。
リポジトリのテスト・podmanクライアントの設定
試しにdockerhubのhello-worldを実行してみます。
$ podman run 192.168.1.114:8088/dockerhub/hello-world
Trying to pull 192.168.1.114:8088/dockerhub/hello-world:latest...
Error: initializing source docker://192.168.1.114:8088/dockerhub/hello-world:latest: pinging container registry 192.168.1.114:8088: Get "https://192.168.1.114:8088/v2/": http: server gave HTTP response to HTTPS client
はい。ということでエラーが出ましたので対応します。(Harborはhttpsの設定をしていないため)
コンテナレジストリの定義を設定
久しぶりにPodmanとUbuntuでの現状(2023年7月)
httpとしてコンテナレジストリを指定できるよう、コンテナレジストリの定義を設定しますが、Podmanではシステムワイドに設定を適用する場合とpodmanコマンド実行ユーザーだけに設定を適用する場合で編集するべき設定ファイルが違います。
- システムワイド /etc/containers/registries.conf /etc/containers/registries.conf.d/*.conf
- ユーザー単位 ~/.config/containers/registries.conf ~/.config/containers/registries.conf.d/*.conf
今回はユーザー単位の設定として~/.config/containers/registries.conf.d/harbor.conf
に設定を書き込むことにします。普通はディレクトリがないのでディレクトリを作成してから。
$ mkdir ~/.config/containers/registries.conf.d
[[registry]]
location = "192.168.1.114:8088"
insecure = true
これでもう一回podman run
を実行してみます。
$ podman run 192.168.1.114:8088/dockerhub/hello-world
Trying to pull 192.168.1.114:8088/dockerhub/hello-world:latest...
Getting image source signatures
Copying blob 70f5ac315c5a done
Copying config b038788ddb done
Writing manifest to image destination
Storing signatures
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.
(arm64v8)
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/
無事にARM64v8のイメージをダウンロードして実行できていることが確認できました。
いちいちコンテナレジストリをHarborに向けるのが面倒なので、DockerHubにアクセスしようとしたらHarborからイメージをダウンロードするように設定
ここからはもう一歩踏み込んだ設定です。Podmanの機能を使ってDockerHub(docker.io)にアクセスしようとしたら別のコンテナレジストリにアクセスするように設定します。
先程と同じ様にコンテナレジストリの定義を変更します。今回は~/.config/containers/registries.conf.d/dockerhub_routing.conf
というファイルに設定を書き込むことにします。
unqualified-search-registries = ["docker.io"]
[[registry]]
prefix = "docker.io"
location = "192.168.1.114:8088/dockerhub"
insecure = true
なお、registries.conf.dの下のファイルはファイル名がAlphanumericの順に読み込まれます。
$ podman pull alpine --log-level debug
(snip)
DEBU[0000] Pulling image alpine (policy: always)
DEBU[0000] Looking up image "alpine" in local containers storage
DEBU[0000] Trying "alpine" ...
DEBU[0000] Loading registries configuration "/etc/containers/registries.conf"
DEBU[0000] Loading registries configuration "/etc/containers/registries.conf.d/shortnames.conf"
DEBU[0000] Loading registries configuration "/home/hogehoge/.config/containers/registries.conf.d/harbor.conf"
DEBU[0000] Loading registries configuration "/home/hogehoge/.config/containers/registries.conf.d/dockerhub_routing.conf"
DEBU[0000] Trying "docker.io/library/alpine:latest" ...
DEBU[0000] parsed reference into "[overlay@/var/containers/storage_hogehoge+/run/user/1001:overlay.mount_program=/usr/bin/fuse-overlayfs,overlay.mount_program=/usr/bin/fuse-overlayfs]@5053b247d78b5e43b5543fec77c856ce70b8dc705d9f38336fa77736f25ff47c"
DEBU[0000] Found image "alpine" as "docker.io/library/alpine:latest" in local containers storage
DEBU[0000] Found image "alpine" as "docker.io/library/alpine:latest" in local containers storage ([overlay@/var/containers/storage_hogehoge+/run/user/1001:overlay.mount_program=/usr/bin/fuse-overlayfs,overlay.mount_program=/usr/bin/fuse-overlayfs]@5053b247d78b5e43b5543fec77c856ce70b8dc705d9f38336fa77736f25ff47c)
DEBU[0000] Image alpine resolved to local image docker.io/library/alpine:latest which will be used for pulling
DEBU[0000] Attempting to pull candidate docker.io/library/alpine:latest for docker.io/library/alpine:latest
DEBU[0000] parsed reference into "[overlay@/var/containers/storage_hogehoge+/run/user/1001:overlay.mount_program=/usr/bin/fuse-overlayfs,overlay.mount_program=/usr/bin/fuse-overlayfs]docker.io/library/alpine:latest"
Trying to pull docker.io/library/alpine:latest...
DEBU[0000] Copying source image //alpine:latest to destination image [overlay@/var/containers/storage_hogehoge+/run/user/1001:overlay.mount_program=/usr/bin/fuse-overlayfs,overlay.mount_program=/usr/bin/fuse-overlayfs]docker.io/library/alpine:latest
DEBU[0000] Trying to access "192.168.1.114:8088/dockerhub/library/alpine:latest"
DEBU[0000] No credentials for 192.168.1.114:8088 found
DEBU[0000] Using registries.d directory /etc/containers/registries.d for sigstore configuration
DEBU[0000] No signature storage configuration found for 192.168.1.114:8088/dockerhub/library/alpine:latest, using built-in default file:///home/hogehoge/.local/share/containers/sigstore
DEBU[0000] Looking for TLS certificates and private keys in /etc/docker/certs.d/192.168.1.114:8088
DEBU[0000] GET https://192.168.1.114:8088/v2/
DEBU[0000] Ping https://192.168.1.114:8088/v2/ err Get "https://192.168.1.114:8088/v2/": http: server gave HTTP response to HTTPS client (&url.Error{Op:"Get", URL:"https://192.168.1.114:8088/v2/", Err:(*errors.errorString)(0x400063acd0)})
DEBU[0000] GET http://192.168.1.114:8088/v2/
DEBU[0000] Ping http://192.168.1.114:8088/v2/ status 401
DEBU[0000] GET http://192.168.1.114:8088/service/token?scope=repository%3Adockerhub%2Flibrary%2Falpine%3Apull&service=harbor-registry
DEBU[0000] GET http://192.168.1.114:8088/v2/dockerhub/library/alpine/manifests/latest
DEBU[0003] Content-Type from manifest GET is "application/vnd.docker.distribution.manifest.list.v2+json"
DEBU[0003] Using blob info cache at /home/hogehoge/.local/share/containers/cache/blob-info-cache-v1.boltdb
DEBU[0003] Source is a manifest list; copying (only) instance sha256:b312e4b0e2c665d634602411fcb7c2699ba748c36f59324457bc17de485f36f6 for current system
DEBU[0003] GET http://192.168.1.114:8088/v2/dockerhub/library/alpine/manifests/sha256:b312e4b0e2c665d634602411fcb7c2699ba748c36f59324457bc17de485f36f6
DEBU[0004] Content-Type from manifest GET is "application/vnd.docker.distribution.manifest.v2+json"
DEBU[0004] IsRunningImageAllowed for image docker:docker.io/library/alpine:latest
DEBU[0004] Using default policy section
DEBU[0004] Requirement 0: allowed
DEBU[0004] Overall: allowed
DEBU[0004] Downloading /v2/dockerhub/library/alpine/blobs/sha256:f6648c04cd6ce95adc05b3aa55265007b95d64d508755be8506cee652792952c
DEBU[0004] GET http://192.168.1.114:8088/v2/dockerhub/library/alpine/blobs/sha256:f6648c04cd6ce95adc05b3aa55265007b95d64d508755be8506cee652792952c
Getting image source signatures
(snip)
ということで、ホスト名を省略→dockerhub.io→LAN内のHarbor(192.168.1.114:8088/dockerhub)と変換されていって、ホスト名を省略した場合でもLAN内のHarborをProxyとして使うことができました。
これで将来DockerHubがドメイン名移転orサービス停止して別会社が移転してイメージが一括で移転しても設定ファイルの書き換えで対応できますね。
スポンサーリンク
comments powered by Disqus