はじめに
Sonatype Nexusはmaven, gradle, npm, dockerなどに対応したプライベートリポジトリマネージャーです。
権限制御も充実しているのでこれを採用している企業も多いようです。
公式Helm ChartもあるのでKubernetes上に簡単にデプロイすることができます。
しかしながらデフォルトのChartではDockerレジストリを1つしか作成することができません。
そこで今回はNexus Helm Chartを改変して複数のDockerレジストリに対応できるようにします。
使用したコードはGitHubにあげてあります。
環境情報
macOS Mojave 10.14.1
Helm: 3.0.1
EKS: 1.14
Nexus Helm Chart: 1.22.0
アーキテクチャ構成
公式のNexus Helm Chartをそのままデプロイすると下図の構成になります。
nexus.sample.com
はHTTPでNexusにアクセスする際のドメインでdocker.sample.com
はDockerレジストリにアクセスする際のドメインです。
また、ALB Ingress Controllerは独自にデプロイしたものでありNexus Helm Chartには含まれません。
Podの中にはNexusのコンテナに加えてNexus Proxyというコンテナが含まれます。
Nexus Proxyはその名の通りプロキシとして機能し、下記の環境変数を設定することでHTTPホストとDockerホストのルーティングを行います。
NEXUS_HTTP_HOST
UPSTREAM_HTTP_PORT
NEXUS_DOCKER_HOST
UPSTREAM_DOCKER_PORT
使用する環境変数が定められているのでDockerレジストリは1つに限られてしまうのが問題となります。
実際の業務においてはリリース用や開発用のレジストリで分けて誤リリースを避けたいというケースもあるかと思います。
今回は公式のHelm Chartを改修して下図のような構成にします。
至って普通の構成です。(そもそも何故公式ではプロキシコンテナ使ってるのか謎)
Helm Chart改修
まずはNexus Helm Chartを取得します。templateを編集するためローカルに持って来る必要があります。
$ helm fetch stable/sonatype-nexus --version 1.22.0
$ tar -xvzf sonatype-nexus-1.22.0.tgz
ディレクトリ構成は以下になります。デプロイ時はvalues.yaml
を使わず自分で作成したmy-values.yaml
を使います。
*
が付いているファイルを今回編集していきます。
.
├── Chart.yaml
├── README.md
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── backup-pv.yaml
│ ├── backup-pvc.yaml
│ ├── backup-secret.yaml
│ ├── configmap.yaml
│ ├── deployment-statefulset.yaml *
│ ├── ingress.yaml *
│ ├── proxy-ks-secret.yaml
│ ├── proxy-route.yaml
│ ├── proxy-svc.yaml *
│ ├── pv.yaml
│ ├── pvc.yaml
│ ├── route.yaml
│ ├── secret.yaml
│ ├── service.yaml *
│ └── serviceaccount.yaml
├── values.yaml
└── my-values.yaml *
values
まずはmy-values.yaml
を作成します。
statefulset:
enabled: true
nexus:
livenessProbe:
port: 8081
readinessProbe:
port: 8081
hosts:
- host: nexus.sample.com
port: 8081
- host: docker-dev.sample.com
port: 5003
- host: docker-release.sample.com
port: 15003
nexusProxy:
enabled: false
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}]'
tls:
enabled: false
service:
enabled: true
serviceType: NodePort
nexus.livenessProbe.port
、nexus.readinessProbe.port
、nexus.hosts
は自分で定義したkeyとなります。Ingress、Service、StatefulSetに使われます。
Ingress ControllerにはALB Ingress Controllerを使用します。これはデプロイされている前提として進めます。
template
続いてtemplateを編集していきます。
proxy-svc.yaml
は.Values.nexusProxy.enabled=false
にするだけでプロキシ用のServiceが作成されないようにします。
- {{- if or .Values.nexusProxy.enabled .Values.ingress.enabled }}
+ {{- if .Values.nexusProxy.enabled }}
ingress.yaml
は自分で定義した.Values.nexus.hosts
が同一のServiceにルーティングされるように下記内容を追記します。
spec:
rules:
+ {{- range .Values.nexus.hosts }}
+ - host: {{ .host }}
+ http:
+ paths:
+ - backend:
+ serviceName: {{ template "nexus.name" $ }}-service
+ servicePort: {{ .port}}
+ {{- end }}
service.yaml
も同様に自分で定義した.Values.nexus.hosts
の値が反映されるように編集します。
spec:
ports:
- {{- with .Values.service.ports }}
- {{ toYaml . | indent 2 }}
- {{- end }}
+ {{- range .Values.nexus.hosts }}
+ - name: port-{{ .port }}
+ port: {{ .port }}
+ targetPort: {{ .port }}
+ {{- end }}
deployment-statefulset.yaml
でも同様です。既存のcontainerPort
は不要なので取り除きます。
spec:
template:
spec:
containers:
- name: nexus
ports:
- - containerPort: {{ .Values.nexus.dockerPort }}
- name: nexus-docker-g
- - containerPort: {{ .Values.nexus.nexusPort }}
- name: nexus-http
+ {{- range .Values.nexus.hosts }}
+ - name: port-{{ .port }}
+ containerPort: {{ .port }}
+ {{- end }}
livenessProbe:
httpGet:
- port: {{ .Values.nexus.nexusPort }}
+ port: {{ .Values.nexus.livenessProbe.port }}
readinessProbe:
httpGet:
- port: {{ .Values.nexus.nexusPort }}
+ port: {{ .Values.nexus.readinessProbe.port }}
デプロイ
あとはhelmコマンドでデプロイするだけです。
$ helm install --values ./my-values.yaml sonatype-nexus ./
Ingressで定義したドメインについて名前解決できるようRoute53等で設定すればNexusにアクセスできるようになります。
Dockerレジストリ作成
Dockerレジストリ作成はNexusの画面から行う必要があります。
adminユーザでログインし、Repositories設定画面からリポジトリ作成をします。
詳細設定はNameとHTTP Portだけ入力して他はデフォルトで問題ありません。
「Create repository」を押せば完了です。Dockerレジストリが作成されていることが確認できます。
開発時用のDockerレジストリを作成したので同様の手順でリリース用のものも作成します。
検証
実際に2つのDockerレジストリを検証します。
まずはローカルにDockerイメージを落とします。
$ docker pull alpine:3.9
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
alpine 3.9 82f67be598eb 2 weeks ago 5.53MB
タグ付けしてdocker pushします。
HTTPの場合はinsecure registryに登録することに注意しましょう。
$ docker tag 82f67be598eb docker-dev.sample.com/alpine:3.7
$ docker push docker-dev.sample.com/alpine:3.7
$ docker tag 82f67be598eb docker-release.sample.com/alpine:3.7
$ docker push docker-release.sample.com/alpine:3.7
画面から2種類のDockerレジストリにイメージが格納されていることが確認できます。
おわりに
公式のNexus Helm Chartを改修して複数Dockerレジストリに対応できることを確認しました。
Helm Chartのtemplateの編集箇所が多いとバージョンが上がったときに都度対応しなくてはならないのが面倒ですが、今回についてはしょうがないかなと思います。