ビビリフクロウの足跡

いつもお世話になっているインターネットへの恩返し

Portusでプライベートなコンテナイメージレジストリを立ててみる

Dockerを使う際にまずお世話になるのがパブリックなコンテナイメージレジストリサービスであるDocker Hubかと思うのですが、業務で本格的にDockerを使うとなった際にはクローズドなネットワークセグメントでしかDockerホストを実行できなかったりして、プライベートなイメージレジストリが欲しくなりますよね?

そんなときのためにDocker側でプライベートレジストリサーバ用のコンテナイメージが用意されているのですが、UIがないのでイメージを一覧や削除などの管理をしようとすると、直にAPIを叩かなくてはならず辛みがあります。そこでUI付きのプライベートレジストリを探すと、プライベートGitリポジトリでも有名なGitLabが引っかかるのですが、あれってリポジトリだけでなく、CIやKubernetes連携など、いろいろな機能がついているじゃないですか。そこまで仰々しくしたくないんですよね…

シンプルにレジストリとUIと認証周りの機能がついていればいいのよ! というモチベーションで再度探すと、ありました! PortusというOSSが…!

が、例のごとく構築に少しつまずいたので、構築・設定方法を残しておきたいと思います。今後Portusを構築する人のために、つまづきポイントを共有できればと思います。

Portusとは

SUSEが開発している、プライベートレジストリに認証機能とWeb UIを提供するOSSです。 ざっくりとどんなものか知りたい方はCyberAgentの青山さんが記事にしてくれているので、そちらをご参照。

構築手順

では、本題に入っていきましょう。

前提

まず前提を示していきますが、以下のとおりです。

  • OS: CentOS 7
  • IP: 192.168.0.100
  • 作業ユーザ: root
  • 構築方法: docker-composeを利用

PortusもDockerコンテナで動作するので、パッケージの導入手順くらいを置き換えていただければ、Dockerが動作するどんなLinuxでも動作するかと思います。

Dockerのインストール

MinimalのCentOS 7のマシンにログインしたら、まずDockerをインストールします。

yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce docker-ce-cli containerd.io

インストールしたらサービスを設定しましょう。

systemctl enable docker
systemctl start docker

docker-composeのインストール

docker-composeを使ってPortusを構築するので、インストールしておきます。

curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/bin/docker-compose
chmod +x /usr/bin/docker-compose

Gitのインストール

Portusのソースコードの中にサンプルのdocker-compose.ymlが入っています。これをDLするためにGitをインストールします。

yum install -y git

Portusのソースコードを取得

Portusのソースコードを取得します。ソースコード/etc/docker/に置くことにします。

cd /etc/docker
git clone https://github.com/SUSE/Portus.git

今回はVer 2.4をデプロイしたいと思います。

cd Portus
git checkout remotes/origin/v2.4
git checkout -b v2.4

以降の作業は/etc/docker/Portus/example/composeで行いますので、移動しておきます。

cd /etc/docker/Portus/examples/compose

証明書群の作成

PortusのWeb UIおよびプライベートレジストリに使われるSSL証明書を作成します。今回は自己署名認証局(CA)を同ホスト内に作り、証明書を発行します。

まずはCAを作成します。

cd secrets
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=192.168.0.100" -days 7305 -out ca.crt

次にサーバの秘密鍵を作ります。

openssl genrsa -out portus.key 2048

CSRを発行して、CAで署名付き証明書を作ります。

cat <<EOF > csr.conf
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn

[ dn ]
C = JP
ST = Tokyo
L = Shinjuku
#O = <organization>
#OU = <organization unit>
CN = 192.168.0.100

[ req_ext ]
subjectAltName = @alt_names

[ alt_names ]
IP.1 = 192.168.0.100

[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=@alt_names
EOF

openssl req -new -key portus.key -out portus.csr -config csr.conf
openssl x509 -req -in portus.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out portus.crt -days 10000 -extensions v3_ext -extfile csr.conf
cd ..

.envファイルの修正

docker-composeに読み込ませる.envファイルを修正します。

cat <<EOF > .env
MACHINE_FQDN=192.168.0.100

SECRET_KEY_BASE=$(openssl rand -hex 64)
PORTUS_PASSWORD=password
DATABASE_PASSWORD=p@ssw0rd
EOF

nginx.confの修正

nginxの設定ファイルnginx.conf内のserver_nameパラメータを修正します。

sed -i 's/server_name.*/server_name 192.168.0.100;/g' nginx/nginx.conf

initスクリプトの修正

今回作成したCAをプライベートレジストリに信頼させるため、以下の記述をregistry/initに追加します。

#!/bin/sh

set -x

cp /secrets/portus.crt /usr/local/share/ca-certificates
# here!!
cp /secrets/ca.crt /usr/local/share/ca-certificates

update-ca-certificates
registry serve /etc/docker/registry/config.yml

Portusの起動

あとはdocker-composeで起動するだけです。

docker-compose up -d

以上で、構築は完了です。あとはPortus上で初期設定をしていきましょう。

設定手順

Portus上で設定を行うためにhttps://192.168.0.100にアクセスしましょう!

管理ユーザ設定

まずは管理ユーザであるadminユーザを作ります。

f:id:bbrfkr:20190202203426p:plain

レジストリサーバ登録

レジストリサーバ登録をして…

f:id:bbrfkr:20190202203457p:plain

ユーザ作成

一般ユーザbbrfkrを作ります。

f:id:bbrfkr:20190202203511p:plain f:id:bbrfkr:20190202203540p:plain

再ログイン

そして再ログイン。

f:id:bbrfkr:20190202203553p:plain f:id:bbrfkr:20190202203605p:plain f:id:bbrfkr:20190202203636p:plain

実際にイメージをプッシュしてみる

作ったレジストリサーバにログインするためにはCA証明書をクライアントマシンの適切な場所に置く必要があります。以下の場所に置きましょう。

/etc/docker/certs.d/192.168.0.100/ca.crt

その後レジストリサーバにログインして、nginx:latestをプライベートレジストリにプッシュしてみます。

docker login 192.168.0.100
docker pull nginx:latest
docker tag nginx:latest 192.168.0.100/bbrfkr/nginx:v1.0
docker push 192.168.0.100/bbrfkr/nginx:v1.0

プッシュが成功すると、Portus上で確認できるようになります。

f:id:bbrfkr:20190202203652p:plain