PrivateなネットワークでConcourse CIを立てたくてDocker Registryを置いたときの設定メモ。
Docker Registryは公式のものではなくて、Nexus Repository OSSを使った。理由としては、Concourse CIでビルドするアプリがMavenを使っているので、Mavenレポジトリも立てる必要があり、Nexusは両方を含んでいたから。同じようなプロダクトにはJFrogのArtifactoryにがあるけど、ArtifactoryはOSS版にDocker Registryが含まれていない。とりあえず、検証したかったのでNexus Repository OSSを選んだ。(Artifactory好きなら、Artifactory Pro買ってもいいと思う)
今回は、Docker Registry(とMaven Repository)のあるサーバーからはインターネットにアクセスしていいけど、Concourse CIのあるネットワーク(BOSHでインストール)からインターネットにアクセスできないという環境なので、PublicなDockerイメージを取ってくるのにProxyサーバーを用意すれば良い。
Nexusのインストール
ドキュメントの通り。
Ubuntu 16.04でインストールした。
sudo apt-get install -y openjdk-8-jdk-headless
sudo mkdir /opt
sudo chown -R `whoami`:`whoami` /opt
cd /opt
wget http://download.sonatype.com/nexus/3/latest-unix.tar.gz
tar xzvf latest-unix.tar.gz
mv nexus-3.1.0-04 nexus
HTTPSの有効化
Docker RegistryはHTTPS推奨なので、HTTPSコネクタの設定をしておく。
ドキュメントの通り。
Keystoreを設定。
$ cd /opt/nexus/etc/ssl
$ keytool -keystore keystore.jks -alias nexus -genkey -keyalg RSA -sigalg SHA256withRSA
Enter keystore password: hoge
Re-enter new password: hoge
What is your first and last name?
\[Unknown]: repo.example.com
What is the name of your organizational unit?
\[Unknown]: foo
What is the name of your organization?
\[Unknown]: dev
What is the name of your City or Locality?
\[Unknown]: Adachi-ku
What is the name of your State or Province?
\[Unknown]: Tokyo
What is the two-letter country code for this unit?
\[Unknown]: JP
Is CN=repo.example.com, OU=foo, O=dev, L=Adachi-ku, ST=Tokyo, C=JP correct?
\[no]: yes
Enter key password for <nexus>
(RETURN if same as keystore password):
/opt/nexus/etc/nexus-default.properties
にapplication-port-ssl
を設定して、nexus-args
に${jetty.etc}/jetty-https.xml
を追加。
# Jetty section
application-port=8081
##### add application-port-ssl
application-port-ssl=8443
application-host=0.0.0.0
##### add ,${jetty.etc}/jetty-https.xml
nexus-args=${jetty.etc}/jetty.xml,${jetty.etc}/jetty-http.xml,${jetty.etc}/jetty-https.xml,${jetty.etc}/jetty-requestlog.xml
nexus-context-path=/
# Nexus section
nexus-edition=nexus-pro-edition
nexus-features=\
nexus-pro-feature
/opt/nexus/etc/jetty/jetty-https.xml
にKeystoreのパスワードを設定。とりあえず生で。
<!-- ... -->
<New id="sslContextFactory" class="org.eclipse.jetty.util.ssl.SslContextFactory">
<Set name="KeyStorePath"><Property name="ssl.etc"/>/keystore.jks</Set>
<!-- Change -->
<Set name="KeyStorePassword">foo</Set>
<!-- Change -->
<Set name="KeyManagerPassword">foo</Set>
<!-- ... -->
</New>
<!-- ... -->
/opt/nexus/bin/nexus start
で実行。起動に少し時間がかかる。
/opt/sonatype-work/nexus3/log/nexus.log
に次のログが出ていれば起動成功。
2016-12-07 02:08:11,530+0900 INFO [jetty-main-1] *SYSTEM org.eclipse.jetty.server.ServerConnector - Started ServerConnector@4ad403e3{HTTP/1.1,[http/1.1]}{0.0.0.0:8081}
2016-12-07 02:08:11,554+0900 INFO [jetty-main-1] *SYSTEM org.eclipse.jetty.util.ssl.SslContextFactory - x509=X509@6ab9b13e(nexus,h=[repo.example.com],w=[]) for SslContextFactory@987c91(file:///opt/nexus/etc/ssl/keystore.jks,file:///opt/nexus/etc/ssl/keystore.jks)
2016-12-07 02:08:11,769+0900 INFO [jetty-main-1] *SYSTEM org.eclipse.jetty.server.ServerConnector - Started ServerConnector@430beed0{SSL,[ssl, http/1.1]}{0.0.0.0:8443}
2016-12-07 02:08:11,769+0900 INFO [jetty-main-1] *SYSTEM org.eclipse.jetty.server.Server - Started @205803ms
2016-12-07 02:08:11,770+0900 INFO [jetty-main-1] *SYSTEM org.sonatype.nexus.bootstrap.jetty.JettyServer -
-------------------------------------------------
Started Sonatype Nexus OSS 3.1.0-04
-------------------------------------------------
https://[nexusサーバーのホスト名]:8443
でアクセスできる。右上の"Sign in"でログイン。
デフォルトのユーザーはadmin
/admin123
.
Docker HubのProxyサーバー作成
プライベートネットワークからDocker Hubで管理されているイメージを取得できるように、Proxyサーバーを作成する。ログイン後にヘッダーバー出てくる歯車アイコンをクリックして、"Repositories"を選択。
"Create Repository"をクリック。
"docker (proxy)"を選択。
フォームに次の値を記入。
- Name: docker-hub
- Remote storage: https://registry-1.docker.io
- Docker Index: Use Docker Hub
"Create Repository"ボタンをクリックして作成。
Docker Registryの集約グループを作成する。後でPrivate Hosted Registryを作成したときとか、他のRegistryのProxyを作ったときに同じURLで透過的にアクセスできるように。
再び"Create Repository"をクリックして、今度は"docker (group)"を選択。
フォームに次の値を記入。
- Name: docker-all
- HTTPS: 18443
- Member repositories: docker-hub
"Create Repository"ボタンをクリックして作成。
これでhttps://[nexusサーバーのホスト名]:18443
にPrivate Docker Registryが立ち上がった。
以下のコマンドで疎通確認。
$ curl -v -k https://repo.example.com:18443/v2/_catalog
> GET /v2/_catalog HTTP/1.1
> Host: repo.example.com:18443
> User-Agent: curl/7.43.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Tue, 06 Dec 2016 17:31:54 GMT
< Server: Nexus/3.1.0-04 (OSS)
< X-Frame-Options: SAMEORIGIN
< X-Content-Type-Options: nosniff
< Docker-Distribution-Api-Version: registry/2.0
< Content-Type: application/json
< Content-Length: 19
<
{"repositories":[]}
docker
コマンドでPrivate Registryにアクセス
やってもやらなくてもいいけど、docker
コマンドでこのDocker Registryを触ってみる。
オレオレ証明書を使っているので、Insecure Registriesの設定が必要だが、この設定方法はOSによって違う。Docker for Macの場合は、Preferencesから次のような設定して"Apply & Restart"が必要。
alpine
イメージをProxy経由でpullしてみる。
$ docker login repo.example.com:18443
Username: admin
Password:
Login Succeeded
$ docker pull repo.example.com:18443/alpine
Using default tag: latest
latest: Pulling from alpine
Digest: sha256:1354db23ff5478120c980eca1611a51c9f2b88b61f24283ee8200bf9a54f2e5c
Status: Downloaded newer image for repo.example.com:18443/alpine:latest
$ docker images | grep example.com
repo.example.com:18443/alpine latest baa5d63471ea 6 weeks ago 4.803 MB
Nexusの管理画面で箱のアイコンをクリック。
"Components"をクリック。
"docker-hub"をクリック。
library/alpine
がいることを確認。
Concourse CIでPrivate Docker Registryを使う
ようやく本題。Concourse CIでPrivate Docker Registryを使うには、パイプラインのYAMLにPrivate Registryの設定を追加すれば良い。
最も簡単なパイプラインである、次のhello.yml
を例に説明する。次の例はPrivate Docker Registryを使いっていない普通のパイプライン。
jobs:
- name: hello-world
plan:
- task: say-hello
config:
platform: linux
image_resource:
type: docker-image
source:
repository: ubuntu
tag: latest
run:
path: bash
args:
- -c
- |
echo "Hello World!"
これをPrivate Docker Registryにアクセスするようには次のようにイメージ名にRegistry情報を追加して、Nexusのアカウント情報も追加すれば良い。insecure_registries
の設定も必要な点に注意。
jobs:
- name: hello-world
plan:
- task: say-hello
config:
platform: linux
image_resource:
type: docker-image
source:
repository: repo.example.com:18443/ubuntu
tag: latest
insecure_registries:
- repo.example.com:18443
username: {{nexus-username}}
password: {{nexus-password}}
run:
path: bash
args:
- -c
- |
echo "Hello World!"
Nexusのアカウント情報はcredentials.yml
に外だしするのが良い。
nexus-username: admin
nexus-password: admin123
あとは次のようにパイプラインをセットすればOK
$ fly -t main sp -p hello -c hello.yml -l credentials.yml -n dev
$ fly -t main up -p hello
$ fly -t main tj -j hello/hello-world -w
started hello/hello-world #1
initializing
Login Succeeded
Pulling repo.example.com:18443/ubuntu@sha256:3b64c309deae7ab0f7dbdd42b6b326261ccd6261da5d88396439353162703fb5...
sha256:3b64c309deae7ab0f7dbdd42b6b326261ccd6261da5d88396439353162703fb5: Pulling from ubuntu
af49a5ceb2a5: Pulling fs layer
8f9757b472e7: Pulling fs layer
e931b117db38: Pulling fs layer
47b5e16c0811: Pulling fs layer
9332eaf1a55b: Pulling fs layer
47b5e16c0811: Waiting
9332eaf1a55b: Waiting
e931b117db38: Verifying Checksum
e931b117db38: Download complete
8f9757b472e7: Download complete
47b5e16c0811: Download complete
9332eaf1a55b: Download complete
af49a5ceb2a5: Verifying Checksum
af49a5ceb2a5: Download complete
af49a5ceb2a5: Pull complete
8f9757b472e7: Pull complete
e931b117db38: Pull complete
47b5e16c0811: Pull complete
9332eaf1a55b: Pull complete
Digest: sha256:3b64c309deae7ab0f7dbdd42b6b326261ccd6261da5d88396439353162703fb5
Status: Downloaded newer image for repo.example.com:18443/ubuntu@sha256:3b64c309deae7ab0f7dbdd42b6b326261ccd6261da5d88396439353162703fb5
Successfully pulled repo.example.com:18443/ubuntu@sha256:3b64c309deae7ab0f7dbdd42b6b326261ccd6261da5d88396439353162703fb5.
running bash -c echo "Hello World!"
Hello World!
succeeded
できた。
https://github.com/pivotalservices/concourse-pipeline-samples/tree/master/private-docker-registry
も参考にした。
Private Docker Registryを作成
ここまでの例はPublicなDockerイメージをPrivateな環境で使う例でしたが、PrivateなDockerイメージを扱いたい場合は、Private Registryが必要。
再び"Create Repository"をクリックして、今度は"docker (hosted)"を選択。
フォームに次の値を記入。
- Name: docker-private
- HTTPS: 28443
"Create repository"ボタンをクリックして作成。
docker-allの方にこのdocker-privateも追加しておく。
Docker for Macからdocker-privateにpushするにはinsecure registriesを追加する必要がある。
あとは次のようにhttps://[nexusサーバーのホスト名]:28443
にログインすればdocker-privaterイメージをpushできる。
$ docker login repo.example.com:28443
Username: admin
Password:
Login Succeeded
$ docker build . -t repo.example.com:28443/foo/bar
$ docker push repo.example.com:28443/foo/bar
pullする方は、docker-allを見れば良いので、https://[nexusサーバーのホスト名]:18443
のままでOK。
これで不自由なネットワーク内でもそこそこ快適なConcourse CIライフが送れる ✈️