Docker Hubのようにコンテナイメージを格納し、Dockerにてイメージをダウンロード(Pull)して利用できるようにするサービスをコンテナリポジトリと呼ぶ。
Docker Hubはインターネット上で公開されたサービスとなり、誰でも自由に使える一方、インターネット環境であることからセキュリティ面におけるリスクも大きい。
そのような状況をふまえ、自宅検証環境にプライベートのコンテナレジストリを構築することにした。本記事では、OSSのコンテナレジストリ「Harbor」をインストールする手順を記載する。
なお、今回はHarborへのアクセスをHTTPによる構成としたが、自己署名証明書を使ってHTTPSにて通信させる場合は、以下記事を参照いただきたい。
環境
Harbor自体はDockerコンテナとして動作する。Harbor及びDockerが動作するOSとしてはAlmaLinuxを使用した。
- OS : AlmaLinux release 8.6
 - Docker : 20.10.21
 - Docker Compose : v2.12.2
 - Harbor : v2.6.2
 
Dockerインストール
1. Dockerインストール
Harbor自体もDockerコンテナとして動作するため、まずはDockerのインストールを行う。
# dnf install yum-utils -y
# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# dnf install docker-ce docker-ce-cli containerd.io -y
プロキシ環境の場合は、インターネット接続できるようにsystemdに環境変数の設定を行う。
# sed -ie '/\[Service\]/a Environment="http_proxy=http://192.168.33.23:8080" "https_proxy=http://192.168.33.23:8080" "no_proxy=192.168.0.0/16"' /usr/lib/systemd/system/docker.service
# systemctl start docker
# systemctl enable docker
2. Docker composeのインストール
Harborはインストール時にDocker composeを利用するため、こちらもインストールする。Docker composeは以下の通りdnfコマンドでインストールすることができる。
# dnf install docker-compose-plugin -y
Docker composeのバージョンを確認しておく。
# docker compose version
Docker Compose version v2.12.2
本題とは逸れるが、Docker composeはもともとdocker-composeといったコマンド体系となっていたが、現在のDocker compose V2系では、dockerコマンドに統合されており、docker composeというハイフンなしのコマンド体系になっている。たとえば、docker-compose up -dはdocker compose up -dで実行する必要があるので覚えておくとよいだろう。
Compose V2 integrates compose functions into the Docker platform, continuing to support most of the previous
docker-composefeatures and flags. You can run Compose V2 by replacing the hyphen (-) with a space, usingdocker compose, instead ofdocker-compose.
Harborインストール
1. Harborのインストーラをダウンロード
Harborのインストーラは、オンラインインストーラとオフラインインストーラの2種類が用意されている。今回はオフラインインストーラを用いる。ダウンロードは以下URLからダウンロードすることができる。
名前に-rcN(Nは数字1桁)が付与されているものは、リリース候補版となる。今回はlatestタグの付与されているバージョン2.6.2をインストールすることにした。オフラインインストーラの容量は約760MBとなる。
2. インストーラを解凍
インストーラはtgz圧縮されているので解凍する。ファイル容量は大きいが、ファイル数自体は多くない。
# tar zxvf harbor-offline-installer-v2.6.2.tgz
harbor/harbor.v2.6.2.tar.gz
harbor/prepare
harbor/LICENSE
harbor/install.sh
harbor/common.sh
harbor/harbor.yml.tmpl
# ls -l harbor
合計 792320
-rw-r--r-- 1 root root     11347 11月  9 18:35 LICENSE
-rw-r--r-- 1 root root      3639 11月  9 18:35 common.sh
-rw-r--r-- 1 root root 811298774 11月  9 18:36 harbor.v2.6.2.tar.gz
-rw-r--r-- 1 root root     10649 11月  9 18:35 harbor.yml.tmpl
-rwxr-xr-x 1 root root      3171 11月  9 18:35 install.sh
-rwxr-xr-x 1 root root      1881 11月  9 18:35 prepare
3. インストール設定ファイル(YAML)を修正
Harborはインストールの設定ファイルとして、harbor.ymlというYAMLファイルの作成が必要となる。
解凍したインストーラ内部に、harbor.yml.tmplというテンプレートが存在するため、これをコピーしてharbor.ymlを作成する。
# cd harbor
# cp harbor.yml.tmpl harbor.yml
以下★箇所を最低限設定しておく。通常Harborへの接続としては、セキュリティの観点からHTTP通信ではなくHTTPS通信を使用すべきであるが、今回は手順簡略化のためHTTP通信による設定を行う。
その他のパラメータについては、公式ドキュメントを参照いただきたい。
harbor.yml
# Configuration file of Harbor
# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: 192.168.11.54 ←★ホスト名を設定する。DNSなどで名前解決できる場合はFQDN設定が望ましいが、今回はIPアドレスで設定する
# http related config
http:
  # port for http, default is 80. If https enabled, this port will redirect to https port
  port: 80
# https related config
#https: ←★原則はHTTPSによる通信が望ましいが、今回は手順簡略化のためHTTPを使用するためコメントアウト
  # https port for harbor, default is 443
#  port: 443 ←★原則はHTTPSによる通信が望ましいが、今回は手順簡略化のためHTTPを使用するためコメントアウト
  # The path of cert and key files for nginx
#  certificate: /your/certificate/path ★←SSLサーバ証明書を使用しないためコメントアウト
#  private_key: /your/private/key/path ★←SSLサーバ証明書を使用しないためコメントアウト
~(以下略)~
4. インストールスクリプトの実行
harbor.ymlの準備が整ったら、インストールスクリプトを実行する。[Step 0]から[Step 5]まで処理が順に実行される。最後の[Step 5]において、Docker composeによるコンテナ起動がされていることがわかる。
# ./install.sh
[Step 0]: checking if docker is installed ...
Note: docker version: 20.10.21
[Step 1]: checking docker-compose is installed ...
Note: Docker Compose version v2.12.2
[Step 2]: loading Harbor images ...
Loaded image: goharbor/harbor-jobservice:v2.6.2
Loaded image: goharbor/trivy-adapter-photon:v2.6.2
Loaded image: goharbor/chartmuseum-photon:v2.6.2
Loaded image: goharbor/redis-photon:v2.6.2
Loaded image: goharbor/nginx-photon:v2.6.2
Loaded image: goharbor/notary-signer-photon:v2.6.2
Loaded image: goharbor/harbor-core:v2.6.2
Loaded image: goharbor/harbor-db:v2.6.2
Loaded image: goharbor/harbor-registryctl:v2.6.2
Loaded image: goharbor/harbor-exporter:v2.6.2
Loaded image: goharbor/prepare:v2.6.2
Loaded image: goharbor/registry-photon:v2.6.2
Loaded image: goharbor/notary-server-photon:v2.6.2
Loaded image: goharbor/harbor-portal:v2.6.2
Loaded image: goharbor/harbor-log:v2.6.2
[Step 3]: preparing environment ...
[Step 4]: preparing harbor configs ...
prepare base dir is set to /root/harbor
WARNING:root:WARNING: HTTP protocol is insecure. Harbor will deprecate http protocol in the future. Please make sure to upgrade to https
Generated configuration file: /config/portal/nginx.conf
Generated configuration file: /config/log/logrotate.conf
Generated configuration file: /config/log/rsyslog_docker.conf
Generated configuration file: /config/nginx/nginx.conf
Generated configuration file: /config/core/env
Generated configuration file: /config/core/app.conf
Generated configuration file: /config/registry/config.yml
Generated configuration file: /config/registryctl/env
Generated configuration file: /config/registryctl/config.yml
Generated configuration file: /config/db/env
Generated configuration file: /config/jobservice/env
Generated configuration file: /config/jobservice/config.yml
Generated and saved secret to file: /data/secret/keys/secretkey
Successfully called func: create_root_cert
Generated configuration file: /compose_location/docker-compose.yml
Clean up the input dir
Note: stopping existing Harbor instance ...
[Step 5]: starting Harbor ...
[+] Running 10/10
 ? Network harbor_harbor        Created                                    0.0s
 ? Container harbor-log         Started                                    0.3s
 ? Container harbor-db          Started                                    0.9s
 ? Container registry           Started                                    1.0s
 ? Container registryctl        Started                                    0.9s
 ? Container harbor-portal      Started                                    1.0s
 ? Container redis              Started                                    1.0s
 ? Container harbor-core        Started                                    1.4s
 ? Container nginx              Started                                    2.2s
 ? Container harbor-jobservice  Started                                    2.1s
? ----Harbor has been installed and started successfully.----
もし、インストールスクリプト実行後にharbor.ymlを修正した場合は、再度インストールスクリプトを実行することで設定反映ができる。再実行の場合は、一度コンテナが削除されたのち、新しいコンテナが起動される。
# ./install.sh
[Step 0]: checking if docker is installed ...
Note: docker version: 20.10.21
[Step 1]: checking docker-compose is installed ...
Note: Docker Compose version v2.12.2
~(中略)~
Note: stopping existing Harbor instance ...
[+] Running 10/9
 ? Container nginx              Removed                                    0.1s
 ? Container harbor-jobservice  Removed                                    0.1s
 ? Container registryctl        Removed                                   10.1s
 ? Container harbor-portal      Removed                                    0.1s
 ? Container harbor-core        Removed                                    0.1s
 ? Container redis              Removed                                    0.3s
 ? Container harbor-db          Removed                                    0.3s
 ? Container registry           Removed                                    0.3s
 ? Container harbor-log         Removed                                   10.1s
 ? Network harbor_harbor        Removed                                    0.0s
[Step 5]: starting Harbor ...
[+] Running 10/10
 ? Network harbor_harbor        Created                                    0.0s
 ? Container harbor-log         Started                                    0.3s
 ? Container registryctl        Started                                    0.6s
 ? Container harbor-portal      Started                                    1.1s
 ? Container registry           Started                                    1.0s
 ? Container redis              Started                                    1.1s
 ? Container harbor-db          Started                                    1.0s
 ? Container harbor-core        Started                                    1.2s
 ? Container harbor-jobservice  Started                                    1.7s
 ? Container nginx              Started                                    1.7s
? ----Harbor has been installed and started successfully.----
5. DockerをHTTP接続に対応させる設定
Dockerは標準では、コンテナレジストリに対してHTTPSによる接続を行うため、HTTPによる接続をできるよう、/etc/docker/daemon.jsonのファイルを新規作成する。
記載しているIPアドレスは、harbor.ymlのhostnameの設定と合わせればよく、IPアドレスまたはFQDNで設定することができる。
# ls -l /etc/docker/daemon.json
ls: '/etc/docker/daemon.json' にアクセスできません: そのようなファイルやディレクトリはありません
# cat << EOF > /etc/docker/daemon.json
{
  "insecure-registries": [
    "192.168.11.54"
  ]
}
EOF
設定後は、Docker及びHarborの再起動が必要となるため、以下の通り再起動を行う。
# systemctl restart docker
# docker compose down -v
# docker compose up -d
6. Web管理画面にログイン
HarborのWeb管理画面にログインする。
- ユーザ : admin
 - 初期パスワード : Harbor12345
 - 接続先 : 
http://[HarborをインストールしたOSのIPアドレス] 
動作確認
1. プロジェクトを作成
Harborではプロジェクトを作成し、そこにコンテナイメージを保存して管理する構成となっている。デフォルトでlibraryという名称のプロジェクトが存在するが、今回はあえて新規にmyprojectという名称のプロジェクトを作成した。
プロジェクトを作成の際の設定値は以下の通り。
| 設定項目 | 設定値 | 説明 | 
|---|---|---|
| Project Name | myproject | 任意の名前で設定する。 | 
| Access Level | Public | アクセス権はPublicとする。Publicの場合は、Pullする際にdocker loginコマンドによる認証が不要となる。逆にPublicにしない場合(Privateにする場合)は、Pullの際にdocker loginコマンドによる認証が必要となる。なお、Pushの際はいずれの権限においても事前の認証が必要となる。 | 
| Storage Quota | -1 GiB | 容量の制限(クォータ)の設定となる。今回はデフォルトの無制限(-1)とする。 | 
| Proxy Cache | 無効 | プロキシキャッシュの機能は無効化する。プロキシキャッシュの詳細は、公式マニュアルを参照いただきたい。 | 
2. テスト用コンテナイメージのPull
それでは、Harborを使ってコンテナイメージのアップロード(Push)とダウンロード(Pull)ができることを確認しよう。なお、Push及びPullを行うDockerは、Harborとは別のサーバにインストールしたものとする。
テスト用のコンテナイメージはoraclelinux:8.7を用いる。このコンテナイメージをHarborへPushし、その後一度コンテナイメージを削除してから、HarborよるPullできることを確認する。
まずは、oraclelinux:8.7のコンテナイメージをDocker HubよりPullする。
# docker pull oraclelinux:8.7
8.7: Pulling from library/oraclelinux
4c770e098606: Pull complete
Digest: sha256:07a995ecaf9db1ce613648a08facc162de69f26c39712f1acc93629c2e6c4e73
Status: Downloaded newer image for oraclelinux:8.7
docker.io/library/oraclelinux:8.7
# docker images
REPOSITORY    TAG       IMAGE ID       CREATED       SIZE
oraclelinux   8.7       b0045ea7bbde   10 days ago   225MB
3. DockerをHTTP接続に対応させる設定
Dockerは標準では、コンテナレジストリに対してHTTPSによる接続を行うため、HTTPによる接続をできるよう、/etc/docker/daemon.jsonのファイルを新規作成する。
# ls -l /etc/docker/daemon.json
ls: '/etc/docker/daemon.json' にアクセスできません: そのようなファイルやディレクトリはありません
# cat << EOF > /etc/docker/daemon.json
{
  "insecure-registries": [
    "192.168.11.54"
  ]
}
EOF
設定後は、Dockerの再起動が必要となるため、以下の通り再起動を行う。
# systemctl restart docker
4. Harborへの認証
Pushする場合は、事前にdocker loginコマンドにてHarborに対して認証を成功させておく必要がある。ここで入力するユーザ名とパスワードは、Web管理画面と同じadmin / Harbor12345となる。
# docker login 192.168.11.54
Username: admin
Password: ←★"Harbor12345"を入力
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
5. コンテナイメージをPush
Pushするコンテナイメージに対して、タグの設定を行う。タグは以下の形式で設定する。
[HarborのIPアドレスまたはFQDN]/[プロジェクト名]:[タグ名]
実行結果を以下に記載する。
# docker tag oraclelinux:8.7 192.168.11.54/myproject/oraclelinux:8.7
# docker images
REPOSITORY                            TAG       IMAGE ID       CREATED       SIZE
192.168.11.54/myproject/oraclelinux   8.7       b0045ea7bbde   10 days ago   225MB
oraclelinux                           8.7       b0045ea7bbde   10 days ago   225MB
タグを付与したコンテナイメージをPushする。
# docker push 192.168.11.54/myproject/oraclelinux:8.7
The push refers to repository [192.168.11.54/myproject/oraclelinux]
d8c569c85182: Pushed
8.7: digest: sha256:89787c72978339a100b1855de3ab7749f29752fc83302456bfac6ba209008401 size: 529
特に問題が発生しなければ、HarborのWeb管理画面からも、Pushしたコンテナイメージを確認することができるはずだ。
6. コンテナイメージを削除
次に、先ほどPushしたコンテナイメージをPullしてみよう。
まずは、ローカルに存在するコンテナイメージを削除する。
# docker images
REPOSITORY                            TAG       IMAGE ID       CREATED       SIZE
192.168.11.54/myproject/oraclelinux   8.7       b0045ea7bbde   10 days ago   225MB
oraclelinux                           8.7       b0045ea7bbde   10 days ago   225MB
# docker rmi b0045ea7bbde -f
Untagged: 192.168.11.54/myproject/oraclelinux:8.7
Untagged: 192.168.11.54/myproject/oraclelinux@sha256:89787c72978339a100b1855de3ab7749f29752fc83302456bfac6ba209008401
Untagged: oraclelinux:8.7
Untagged: oraclelinux@sha256:07a995ecaf9db1ce613648a08facc162de69f26c39712f1acc93629c2e6c4e73
Deleted: sha256:b0045ea7bbde263d0543ac9efb749e588d3538bc673f98fe00a73006838a9b89
Deleted: sha256:d8c569c851824688f0f55d46d659a8eef6b8af3ed0a20f389b066f16a4a250e5
# docker images
REPOSITORY   TAG       IMAGE ID   CREATED   SIZE
7. HarborよりコンテナイメージをPull
HarborよりコンテナイメージをPullする。
# docker pull 192.168.11.54/myproject/oraclelinux:8.7
8.7: Pulling from myproject/oraclelinux
4c770e098606: Pull complete
Digest: sha256:89787c72978339a100b1855de3ab7749f29752fc83302456bfac6ba209008401
Status: Downloaded newer image for 192.168.11.54/myproject/oraclelinux:8.7
192.168.11.54/myproject/oraclelinux:8.7
# docker images
REPOSITORY                            TAG       IMAGE ID       CREATED       SIZE
192.168.11.54/myproject/oraclelinux   8.7       b0045ea7bbde   10 days ago   225MB
Pullに成功すると、Harbor上でもPullが実行された回数が更新される。
以上で、OSSのコンテナレジストリ「Harbor」をインストールする手順は完了となる。



















