GIG

赴くままに技術を。

プライベートコンテナレジストリ(Harbor)を構築

Azure CLIベースでHarborの構築メモ。 流れとしては以下となります。

  1. コンテナレジストをデプロイするVNetを作成 2.コンテナレジストリを構築 3.踏み台サーバにGUI環境を構築しHarborにアクセス 4.DockerイメージをHarborにプッシュ
1. コンテナレジストをデプロイするVNetを作成

リソースグループを作成

az group create --name labprivcr --location japaneast

次に仮想ネットワークとサブネットを作成

$ az network vnet create --resource-group labprivcr --name vnetforprivcr --address-prefixes 10.0.0.0/16 --subnet-name subnet1 --subnet-prefixes 10.0.0.0/24
2.コンテナレジストリを構築

要件を見ると、4 CPU / メモリ 8GB / ディスク 160 GB とあるので、B4ms サイズ (4 vCPU / 16 Gib メモリ) を選択 Harbor docs | Harbor Installation Prerequisites

Harbor 用に仮想マシンを作成 ローカルでのみ利用する想定なので、パブリックIPアドレスは付与していません。

$ az vm create --resource-group labprivcr --name privcr --image UbuntuLTS --vnet-name vnetforprivcr --subnet subnet1 --admin-username azureuser --ssh-key-values ~/.ssh/id_rsa.pub --public-ip-address "" --size Standard_B4ms

プライベートDNSゾーンを設定し、仮想ネットワークにリンク。 az network private-dns link vnet create の際に、--registration-enabled false としているのは、後々 VNetピアリングしたとき、そこにデプロイしたAKSノードも登録されてしまうため、必要なものだけ登録するよう、falseを設定しています。

$ az network private-dns zone create --resource-group labprivcr --name labprivcr.com
$ az network private-dns link vnet create --resource-group labprivcr --name labprivcrlink --zone-name labprivcr.com --virtual-network vnetforprivcr --registration-enabled false
$ az network private-dns record-set a add-record --resoruce-group labprivcr --zone-name labprivcr.com --record-set-name privcr --ipv4-address 10.0.0.4

踏み台サーバをデプロイ こちらはパブリックIPアドレスを付与します。

$ az vm create --resource-group labprivcr --name jumpbox --image UbuntuLTS --vnet-name vnetforprivcr --subnet subnet1 --admin-username azureuser --ssh-key-values ~/.ssh/id_rsa.pub

踏み台サーバがデプロイできたら、踏み台サーバ→プライベートコンテナレジストリVMSSH接続します。

$ scp -p ~/.ssh/id_rsa azureuser@xxx.xxx.xxx.xxx:/home/azureuser/.ssh/
$ ssh azureuser@xxx.xxx.xxx.xxx
$ ssh azureuser@privcr

Dockerをインストール

参考; Install Docker Engine on Ubuntu | Docker Documentation

$ sudo apt-get update
$ sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
0e03bdcc26d7: Pull complete 
Digest: sha256:1a523af650137b8accdaed439c17d684df61ee4d74feac151b5b337bd29e7eec
Status: Downloaded newer image for 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コマンドが実行できるよう、dockerグループに追加

$ sudo usermod -aG docker `whoami`
azureuser@privcr:~$ exit
azureuser@privcr:~$ docker ps -a
CONTAINER ID   IMAGE         COMMAND    CREATED          STATUS                      PORTS     NAMES
218ed82c7541   hello-world   "/hello"   55 seconds ago   Exited (0) 51 seconds ago             brave_agnesi

Docker-composeをインストール

参考; Install Docker Compose | Docker Documentation

$ sudo curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker-compose --version
docker-compose version 1.27.4, build 40524192

HarborをHTTPSアクセス可能なように自己証明書を作成

これもほとんど公式ドキュメント通り

参考; Harbor docs | Configure HTTPS Access to Harbor

CA証明書の秘密鍵 ca.key を作成

$ mkdir cert && cd cert
$ openssl genrsa -out ca.key 4096

CA証明書 ca.crt を作成

$ openssl req -x509 -new -nodes -sha512 -days 3650 -subj "/C=JP/ST=Tokyo/L=Tokyo/O=lab/OU=lab/CN=privcr.labprivcr.com" -key ca.key -out ca.crt

このとき、Can't load /home/azureuser/.rnd into RNG とエラーになったので、以下の情報に沿って、/etc/ssl/openssl.cnfRANDFILE 行をコメントアウト

参考; Can't load ./.rnd into RNG · Issue #7754 · openssl/openssl · GitHub

サーバ証明書秘密鍵 privcr.labprivcr.com.key を作成

$ openssl genrsa -out privcr.labprivcr.com.key 4096

証明書署名要求 privcr.labprivcr.com.csr を作成

$ openssl req -sha512 -new -subj "/C=JP/ST=Tokyo/L=Tokyo/O=lab/OU=lab/CN=privcr.labprivcr.com" -key privcr.labprivcr.com.key -out privcr.labprivcr.com.csr

x509 v3 拡張属性向けの設定ファイルを生成

$ cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1=privcr.labprivcr.com
DNS.2=privcr
IP.1=10.0.0.4
EOF

サーバ証明書 privcr.labprivcr.com.crt を作成

$ openssl x509 -req -sha512 -days 3650 -extfile v3.ext -CA ca.crt -CAkey ca.key -CAcreateserial -in privcr.labprivcr.com.csr -out privcr.labprivcr.com.crt

サーバ証明書秘密鍵を配置

$ sudo mkdir -p /data/cert
$ sudo cp privcr.labprivcr.com.crt /data/cert/
$ sudo cp privcr.labprivcr.com.key /data/cert/

Docker向けに privcr.labprivcr.com.crt を privcr.labprivcr.com.cert に変換し、配置

$ openssl x509 -inform PEM -in privcr.labprivcr.com.crt -out privcr.labprivcr.com.cert
$ sudo mkdir -p /etc/docker/certs.d/privcr.labprivcr.com
$ sudo cp privcr.labprivcr.com.cert /etc/docker/certs.d/privcr.labprivcr.com/
$ sudo cp privcr.labprivcr.com.key /etc/docker/certs.d/privcr.labprivcr.com/
$ sudo cp ca.crt /etc/docker/certs.d/privcr.labprivcr.com/

更新を反映させるため、dockerを再起動

$ sudo systemctl restart docker

Harborをインストール

$ wget https://github.com/goharbor/harbor/releases/download/v2.1.2/harbor-online-installer-v2.1.2.tgz
$ tar xvf harbor-online-installer-v2.1.2.tgz 
$ cd harbor
$ cp harbor.yml.tmpl harbor.yml
$ vi harbor.yml
diff harbor.yml harbor.yml.tmpl
5c5
< hostname: privcr.labprivcr.com
---
> hostname: reg.mydomain.com
17,18c17,18
<   certificate: /etc/docker/certs.d/privcr.labprivcr.com/privcr.labprivcr.com.cert
<   private_key: /etc/docker/certs.d/privcr.labprivcr.com/privcr.labprivcr.com.key
---
>   certificate: /your/certificate/path
>   private_key: /your/private/key/path

インストール

$ sudo ./install.sh
...
Creating harbor-log ... done
Creating registryctl   ... done
Creating harbor-portal ... done
Creating registry      ... done
Creating redis         ... done
Creating harbor-db     ... done
Creating harbor-core   ... done
Creating harbor-jobservice ... done
Creating nginx             ... done
✔ ----Harbor has been installed and started successfully.----

ログイン可能か確認。デフォルトのパスワードは、harbor.yml に記載のある通り、 Harbor12345

$ docker login privcr.labprivcr.com
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /home/yuri/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
3.踏み台サーバにGUI環境を構築しHarborにアクセス

Web UIがあるので、踏み台サーバにGUI環境を構築し確認

UbuntuはAzureのドキュメント通り

参考; Azure の Linux VM にリモート デスクトップを使用する - Azure Virtual Machines | Microsoft Docs

$ sudo apt-get update
$ sudo apt-get install xfce4

$ sudo apt-get install xrdp
$ sudo systemctl enable xrdp

$ echo xfce4-session >~/.xsession
$ sudo systemctl restart xrdp

ログインユーザのパスワードを設定

sudo passwd azureuser
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully

Webブラウザが入っていないので、Firefoxをインストール

$ sudo apt-get install firefox

3389/TCPを踏み台サーバのNSGなどで許可 その後、RDP接続にてGUI環境が利用できます。

先に作成したCA証明書を踏み台サーバにコピーし、Firefoxにインポートします。

  • Settings > Privacy & Security > View Certificates...
  • Import...

あとはFirefoxからhttps://privcr.labprivcr.comにアクセス

f:id:hermesian:20210120220408p:plain
harbor1

4.DockerイメージをHarborにプッシュ

次にHarborにDockerイメージをプッシュしてみます。

踏み台サーバに、プライベートコンテナレジストリと同様の手順でDockerをインストール

CA証明書をインストール

$ scp yuri@privcr:/home/yuri/cert/ca.crt .
$ sudo cp ca.crt /usr/local/share/ca-certificates/
$ sudo update-ca-certificates

Harborにログインし、Dockerイメージをプッシュ libraryというプロジェクトはプリセットのものらしいです。

$ docker login privcr.labprivcr.com
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /home/azureuser/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
$ docker tag hello-world:latest privcr.labprivcr.com/library/hello-world:v1
$ docker push privcr.labprivcr.com/library/hello-world:v1
The push refers to repository [privcr.labprivcr.com/library/hello-world]
9c27e219663c: Pushed
v1: digest: sha256:90659bf80b44ce6be8234e6ff90a1ac34acbeb826903b02cfa0da11c82cbc042 size: 525

Web UIからも確認できました。

f:id:hermesian:20210120220751p:plain
harbor2