📝 BLOG.IK.AM

@making's memo
(🗃 Categories 🏷 Tags)

Nexus RepositoryのDocker Registryを使ってオフラインでConcourse CIを使う

🗃 {Dev/CI/ConcourseCI}

🏷 Concourse CI 🏷 Docker 🏷 Docker Registry 🏷 Nexus Repository

🗓 Updated at 2016-12-08T16:22:15+09:00 by Toshiaki Maki  🗓 Created at 2016-12-08T16:22:15+09:00 by Toshiaki Maki  {✒️️ Edit  ⏰ History}


🚨 Warning: This content is old. Please don't trust too much.

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サーバーを用意すれば良い。

image

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.propertiesapplication-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 [email protected]{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 - [email protected](nexus,h=[repo.example.com],w=[]) for [email protected](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 [email protected]{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"でログイン。

image

デフォルトのユーザーはadmin/admin123.

image

Docker HubのProxyサーバー作成

プライベートネットワークからDocker Hubで管理されているイメージを取得できるように、Proxyサーバーを作成する。ログイン後にヘッダーバー出てくる歯車アイコンをクリックして、"Repositories"を選択。

image

"Create Repository"をクリック。

image

"docker (proxy)"を選択。

image

フォームに次の値を記入。

image

"Create Repository"ボタンをクリックして作成。

image

Docker Registryの集約グループを作成する。後でPrivate Hosted Registryを作成したときとか、他のRegistryのProxyを作ったときに同じURLで透過的にアクセスできるように。

再び"Create Repository"をクリックして、今度は"docker (group)"を選択。

image

フォームに次の値を記入。

  • Name: docker-all
  • HTTPS: 18443
  • Member repositories: docker-hub

image

"Create Repository"ボタンをクリックして作成。

image

これで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"が必要。

image

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の管理画面で箱のアイコンをクリック。

image

"Components"をクリック。

image

"docker-hub"をクリック。

image

library/alpineがいることを確認。

image

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/[email protected]: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/[email protected]:3b64c309deae7ab0f7dbdd42b6b326261ccd6261da5d88396439353162703fb5

Successfully pulled repo.example.com:18443/[email protected]:3b64c309deae7ab0f7dbdd42b6b326261ccd6261da5d88396439353162703fb5.

running bash -c echo "Hello World!"

Hello World!
succeeded

できた。

image

image

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)"を選択。

image

フォームに次の値を記入。

  • Name: docker-private
  • HTTPS: 28443

image

"Create repository"ボタンをクリックして作成。

docker-allの方にこのdocker-privateも追加しておく。

image

Docker for Macからdocker-privateにpushするにはinsecure registriesを追加する必要がある。

image

あとは次のように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ライフが送れる