kWatanabe 記事一覧へ

kWatanabe の 技術帖

某企業でOSや仮想化の研究をやっているインフラ系エンジニア。オンプレとクラウドのコラボレーションなど、興味ある技術を綴る。

ブラウザで管理できる自分用コンテナレジストリを作る

  • Kubernetes の学習用に無制限に使えるコンテナレジストリが欲しくなった
  • ブラウザから、ユーザやリポジトリの作成・破棄が可能な harbor を構築した

学習用に登録し放題のコンテナレジストリが欲しい

Kubernetes の構築および活用方法を学習するにあたり、プライベートで無制限に登録できるコンテナレジストリが欲しくなった。 コンテナレジストリの構築方法も一緒に学ぶ機会だととらえて、ローカル環境に構築してみることにした。

コンテナレジストリを構成する最も簡単な方法は、公式の registry イメージを使うことだと思う。

hub.docker.com

registry はグラフィカルなユーザインタフェースを持たない。学習にあたりユーザやリポジトリを作ったり壊したりすることが予想されるので、もう少しリッチなものが欲しい。調べてみると harbor というものを見つけた。CNCF の Graduated になっているので、品質も問題ないと思う。

goharbor.io

検証環境

  • Debian 13.5 (trixie) amd64
  • harbor 2.14.4
  • docker-ce 29.5.2-1~debian.13~trixie
  • harbor 用のストレージとして /srv/harbor に後付けのディスクをマウント

手順

Docker のインストール

Dockerの公式リポジトリを追加し、Dockerをインストールする。

$ sudo wget https://download.docker.com/linux/debian/gpg -O /etc/apt/keyrings/docker.asc
$ sudo chmod a+r /etc/apt/keyrings/docker.asc
$ sudo vim /etc/apt/sources.list.d/docker.sources 
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: trixie
Components: stable
Architectures: amd64
Signed-By: /etc/apt/keyrings/docker.asc
$ sudo apt update
$ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

HTTPS通信用の証明書を作成

harborとhttps通信するための証明書を作成する。いつものことながら、自己署名証明書でお茶を濁す。今は Let's Encrypt! も運用しやすくなったのでそちらを使っても良いと思う。

ここでは、対象のサーバのホスト名が harbor.example.com であると仮定する。

$ openssl genrsa -out ca.key 4096
$ openssl req -x509 -new -nodes -sha512 -days 3650 -subj "/C=JP/ST=example/L=example/O=example/OU=example/CN=harbor.example.com" -key ca.key -out ca.crt
$ openssl genrsa -out harbor.example.com.key 4096
$ openssl req -sha512 -new -subj "/C=JP/ST=example/L=example/O=example/OU=example/CN=harbor.example.com" -key harbor.example.com.key -out harbor.example.com.csr
$ vim v3.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1=harbor.example.com
DNS.2=example.com
DNS.3=harbor
$ openssl x509 -req -sha512 -days 3650 -extfile v3.ext -CA ca.crt -CAkey ca.key -CAcreateserial -in harbor.example.com.csr -out harbor.example.com.crt

Docker用のクライアント証明書を作成する。Docker は拡張子 .cert のファイルをクライアント証明書として認識する。

$ openssl x509 -inform PEM -in harbor.example.com.crt -out harbor.example.com.cert

作った各種証明書を /etc/certs に集めておく。

$ sudo mkdir -p /etc/certs
$ sudo cp ca.crt harbor.example.com.crt harbor.example.com.key harbor.example.com.cert /etc/certs

harbor のインストール

Githubからリリースファイルをダウンロードする。後々の運営を楽にするためにオフライン版をダウンロードし /opt/harbor として展開する。

$ wget https://github.com/goharbor/harbor/releases/download/v2.14.4/harbor-offline-installer-v2.14.4.tgz
$ sudo tar xf harbor-offline-installer-v2.14.4.tgz -C /opt

インストール設定ファイルを編集する。

$ cd /opt/harbor
$ sudo cp harbor.yml.tmpl harbor.yml
$ sudo vim harbor.yml

今回変更したパラメータは以下。

変更したパラメータ 概要 変更後
hostname harborを実行するホスト名 harbor.example.com
https.certificate 証明書 /etc/certs/harbor.example.com.crt
https.private_key 秘密鍵 /etc/certs/harbor.example.com.key
harbor_admin_password ログインパスワード P@ssw0rd
database.password データベースのパスワード P@ssw0rd
data_volume Harborのデータを保管するディレクトリ /srv/harbor

インストールスクリプトを実行する。裏で Docker Compose が動作する。

$ sudo ./prepare
$ sudo ./install.sh
...
✔ ----Harbor has been installed and started successfully.----

harbor の起動確認

data_volume にて指定したディレクトリに、データファイルが展開されていることを確認する。

$ sudo ls /srv/harbor
...

諸々のコンテナが動作していることを確認する。

$ sudo docker ps
CONTAINER ID   IMAGE                                 COMMAND                   CREATED         STATUS                                  PORTS                                                                                NAMES
61762a470add   goharbor/harbor-jobservice:v2.14.4    "/harbor/entrypoint.…"   9 seconds ago   Restarting (2) Less than a second ago                                                                                        harbor-jobservice
b5617832551f   goharbor/nginx-photon:v2.14.4         "nginx -g 'daemon of…"   9 seconds ago   Up 8 seconds (health: starting)         0.0.0.0:80->8080/tcp, [::]:80->8080/tcp, 0.0.0.0:443->8443/tcp, [::]:443->8443/tcp   nginx
bc7257c45572   goharbor/harbor-core:v2.14.4          "/harbor/entrypoint.…"   9 seconds ago   Up 8 seconds (health: starting)                                                                                              harbor-core
db9c9784d0ae   goharbor/registry-photon:v2.14.4      "/home/harbor/entryp…"   9 seconds ago   Up 8 seconds (health: starting)                                                                                              registry
57b3c3d6344d   goharbor/redis-photon:v2.14.4         "redis-server /etc/r…"   9 seconds ago   Up 8 seconds (health: starting)                                                                                              redis
689bff94704d   goharbor/harbor-portal:v2.14.4        "nginx -g 'daemon of…"   9 seconds ago   Up 8 seconds (health: starting)                                                                                              harbor-portal
74d9584bcc2f   goharbor/harbor-registryctl:v2.14.4   "/home/harbor/start.…"   9 seconds ago   Up 8 seconds (health: starting)                                                                                              registryctl
f36d5e937dd9   goharbor/harbor-db:v2.14.4            "/docker-entrypoint.…"   9 seconds ago   Up 8 seconds (health: starting)                                                                                              harbor-db
0ed3ef3386ec   goharbor/harbor-log:v2.14.4           "/bin/sh -c /usr/loc…"   9 seconds ago   Up 8 seconds (health: starting)         127.0.0.1:1514->10514/tcp                                                            harbor-log

ブラウザでアクセスできることを確認する。

harborの画面

Docker からの接続確認

Dockerから接続できることを確認する。まず、作成しておいたCA証明書とクライアント証明書を Docker の証明書置き場に配置する。

$ sudo mkdir -p /etc/docker/certs.d/harbor.example.com
$ cd /etc/certs
$ sudo cp ca.crt harbor.example.com.cert harbor.example.com.key /etc/docker/certs.d/harbor.example.com

配置した証明書を読み込ませるために、一度 harbor と Docker を停止させたのちに再起動する。

$ cd /opt/harbor
$ sudo docker compose down
$ sudo systemctl restart docker
$ sudo docker compose up -d

Docker から harbor_admin_password で指定したパスワードを用いて、admin ユーザでログインできることを確認する。

$ sudo docker login harbor.example.com
Username: admin
Password: 
...
Login Succeeded

確認できれば、いったんログアウトし、harbor も終了させる。

$ sudo docker logout harbor.example.com
$ cd /opt/harbor
$ sudo docker compose down

systemd 管理にする

docker compose をそのまま使っていると運用しづらいので、systemd unit を作成して、systemd の管理下に置く。

$ sudo systemctl edit -f --full harbor.service
[Unit]
Description=harbor
Requires=docker.service
After=docker.service

[Service]
Type=simple
ExecStart=docker compose up
ExecStop=docker compose down
WorkingDirectory=/opt/harbor
KillSignal=SIGUSR1
Restart=on-abort
RestartSec=3

[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload

systemd からの起動と終了を確認する。

$ sudo systemctl start harbor
$ sudo systemctl status harbor
● harbor.service - harbor
     Loaded: loaded (/etc/systemd/system/harbor.service; disabled; preset: enabled)
     Active: active (running) since Sun 2026-06-07 17:15:21 JST; 1min 1s ago
...
$ sudo docker ps
CONTAINER ID   IMAGE                                 COMMAND                   CREATED              STATUS                        PORTS                                                                                NAMES
ab4103c5a0cf   goharbor/harbor-jobservice:v2.14.4    "/harbor/entrypoint.…"   About a minute ago   Up About a minute (healthy)                                                                                        harbor-jobservice
1ca0c3f1a7c5   goharbor/nginx-photon:v2.14.4         "nginx -g 'daemon of…"   About a minute ago   Up About a minute (healthy)   0.0.0.0:80->8080/tcp, [::]:80->8080/tcp, 0.0.0.0:443->8443/tcp, [::]:443->8443/tcp   nginx
bc34b9b3c5e8   goharbor/harbor-core:v2.14.4          "/harbor/entrypoint.…"   About a minute ago   Up About a minute (healthy)                                                                                        harbor-core
820a59b6548e   goharbor/harbor-registryctl:v2.14.4   "/home/harbor/start.…"   About a minute ago   Up About a minute (healthy)                                                                                        registryctl
d732a658b703   goharbor/registry-photon:v2.14.4      "/home/harbor/entryp…"   About a minute ago   Up About a minute (healthy)                                                                                        registry
b7e264677859   goharbor/redis-photon:v2.14.4         "redis-server /etc/r…"   About a minute ago   Up About a minute (healthy)                                                                                        redis
fa32490578a1   goharbor/harbor-portal:v2.14.4        "nginx -g 'daemon of…"   About a minute ago   Up About a minute (healthy)                                                                                        harbor-portal
64a4dd3333eb   goharbor/harbor-db:v2.14.4            "/docker-entrypoint.…"   About a minute ago   Up About a minute (healthy)                                                                                        harbor-db
8684d4f0408c   goharbor/harbor-log:v2.14.4           "/bin/sh -c /usr/loc…"   About a minute ago   Up About a minute (healthy)   127.0.0.1:1514->10514/tcp                                                            harbor-log
$ sudo systemctl stop harbor
$ sudo docker ps
CONTAINER ID   IMAGE                                 COMMAND                   CREATED              STATUS                        PORTS                                                                                NAMES

問題なければ自動起動サービスとして登録する。

$ sudo systelctl enable harbor
Created symlink '/etc/systemd/system/multi-user.target.wants/harbor.service''/etc/systemd/system/harbor.service'.

まとめ

  • Kubernetes の学習用に無制限に使えるコンテナレジストリが欲しくなったので、harbor を用いてローカルに構築した
  • systemd 管理下におき、通常のサービスと同様に管理できるように整えた
  • 今後、Kuberenetes クラスタからも利用できるように構成していく

参考