CentOS7で簡易的なDocker Registryの構築

# はじめに

プライベートなdockerイメージの管理に使えるのがdocker-registryです。
コンテナとして動作し、イメージが無償で配布されています。

Docker Hub
https://hub.docker.com/_/registry/

公式ドキュメント
https://docs.docker.com/registry/

docker-registryとクライアント側（docker daemon）はhttpsがデフォルトなので、証明書が必要になります。
ここでは簡易的な構築ということで、オレオレ証明書を用意して構築を進めます。
また、httpの場合の手順も併記します。

作業環境
- ホスト名 : my_hostname
- CentOS 7.4
- docker 18.03.0-ce
- docker registry 2.6.2

# HTTPS(オレオレ証明書)
https://my_hostname
id : hoge
password : fuga
で待ち受けすることが目標。
とりあえず/opt/docker-registry以下で作業します。

### firewalld
```
firewall-cmd --add-port=443/tcp --zone=public --permanent
```

### htpasswd作成
docker-registryにhtpasswdを作らせる

```
docker run --rm --entrypoint htpasswd \
registry:2.6.2 -Bbn hoge fuga > /opt/docker-registry/auth/htpasswd
```

### オレオレ証明書
```
# 秘密鍵
openssl genrsa -out /opt/docker-registry/cert/registry.key

# 署名要求
openssl req -new \
 -key /opt/docker-registry/cert/registry.key \
 -out /opt/docker-registry/cert/registry.csr \
 -subj '/C=JP/ST=Tokyo/L=Tokyo/O=xxx Ltd./OU=yyy/CN=my_hostname/subjectAltName=zzz'

# 自己署名
openssl x509 -req \
 -days 3650 \
 -in /opt/docker-registry/cert/registry.csr \
 -signkey /opt/docker-registry/cert/registry.key \
 -out /opt/docker-registry/cert/registry.crt
```

### 起動
作っておいたhtpasswdと証明書をマウントする

```
docker run -d \
 --name registry \
 --restart=always \
 -p 443:443 \
 -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
 -e REGISTRY_AUTH=htpasswd \
 -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
 -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry.crt \
 -e REGISTRY_HTTP_TLS_KEY=/certs/registry.key \
 -v /opt/docker-registry/auth:/auth \
 -v /opt/docker-registry/cert:/certs \
 -v /opt/docker-registry/images:/var/lib/registry \
 registry:2.6.2
```

### クライアント側
オレオレ証明書を信頼させるために、
registryの証明書をクライアント側の`/etc/docker/certs.d/hostname/ca.crt`に配置する。
それでもエラーが出る場合、OSレベルで信頼させるとうまくいくはず。

```
cp registry.crt /etc/pki/ca-trust/source/anchors/my_hostname.crt
update-ca-trust
```

# HTTP
http://my_hostname:5000
id : hoge
password : fuga
で待ち受けすることが目標。

### firewall
```
firewall-cmd --add-port=5000/tcp --zone=public --permanent
```

### htpasswd作成
```
docker run --rm --entrypoint htpasswd \
registry:2.6.2 -Bbn hoge fuga > /opt/docker-registry/auth/htpasswd
```

### 起動
```
docker run -d \
 --name registry \
 --restart=always \
 -e REGISTRY_AUTH=htpasswd \
 -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
 -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
 -p 5000:5000 \
 -v /opt/docker-registry/auth:/auth \
 -v /opt/docker-registry/images:/var/lib/registry \
 registry:2.6.2
```

### クライアント側
`docker login`したときにデフォルトでhttpsで繋ぎにいこうとするので、httpで接続を許可する設定が必要。
/etc/docker/daemon.jsonという設定ファイルを作り、次のように記述する。

```
{
  "insecure-registries" : ["my_hostname:5000"]
}
```
作り終わったら、`systemctl restart docker`で再起動。

# 利用
ログイン

```
docker login my_hostname
# httpの場合は my_hostname:5000
```

`docker pull`でmy_hostnameからもイメージを検索するようになり、
`docker push`でmy_hostnameに対してイメージのアップロードが可能になる。

ログアウト

```
docker logout my_hostname
```

# 参考
[docker docs : Native basic auth](https://docs.docker.com/registry/deploying/#native-basic-auth)
[docker docs : Use self-sined certificates](https://docs.docker.com/registry/insecure/#use-self-signed-certificates)
[docker docs : Test an insecure registry](https://docs.docker.com/registry/insecure/)
[Qiita : プライベートなDockerレジストリサーバーをコンテナで立てる](https://qiita.com/rsakao/items/617f54579278173d3c20)