Help us understand the problem. What is going on with this article?

EKSにデプロイしたNexusのblob storeをEBSからS3に移行させる

はじめに

Sonatype Nexusはmaven, gradle, npm, dockerなどに対応したプライベートリポジトリマネージャーです。
リポジトリ内のファイルの保存方式はFILEとS3のどちらかを選ぶことができ、前者はEBSなどに、後者はその名の通りS3に保存されます。
ディスク容量の監視を不要とし料金も安くしたいときにはS3にしておいた方がいいです。

今回はEBSにFILE方式で保存されている既存データをS3に移行させる方法を説明します。
NexusはEKSにデプロイすることを前提としています。

環境

macOS Mojave 10.14.1
Helm: 3.0.1
EKS: 1.14
Nexus Helm Chart: 1.22.0

前準備

データ移行の前にNexusデプロイ、リポジトリ作成、データ格納を行います。
EKS、S3などのAWSリソースやALB Ingress Controller、kube2iamなどのKubernetesリソースはすでにデプロイ済みであることを前提とします。

Nexusのデプロイ

Helmを使ってNexusをデプロイします。
templateを少し修正する必要があるのでhelm fetchで公式Helm Chartをローカルに落とします。

$ helm fetch stable/sonatype-nexus --version 1.22.0
$ tar -xvzf sonatype-nexus-1.22.0.tgz

Nexus Helm Chartのディレクトリ構造は下記となります。
valuesには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 *

ingress.yamlの編集箇所はspec.rules[].http.paths[].pathを消去するだけです。
デフォルトではpath: /となっていますがこれだとjsファイルを読み込むことができなくなるので除く必要があります。

template/ingress.yaml
{{- if .Values.ingress.enabled -}}
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: {{ template "nexus.fullname" . }}
  labels:
{{ include "nexus.labels" . | indent 4 }}
  annotations:
    {{- range $key, $value := .Values.ingress.annotations }}
    {{ $key }}: {{ $value | quote }}
    {{- end }}
spec:
  rules:
{{- if .Values.nexusProxy.env.nexusHttpHost }}
    - host: {{ .Values.nexusProxy.env.nexusHttpHost }}
      http:
        paths:
          - backend:
            {{- if .Values.nexusProxy.svcName }}
              serviceName: {{ .Values.nexusProxy.svcName }}
            {{- else }}
              serviceName: {{ template "nexus.fullname" . }}
            {{- end }}
{{- if .Values.nexusProxy.enabled }}
              servicePort: {{ .Values.nexusProxy.port }}
{{- else }}
              servicePort: {{ .Values.nexus.nexusPort }}
{{- end }}
{{- end }}
{{- if .Values.nexusProxy.enabled -}}
{{- if .Values.nexusProxy.env.nexusDockerHost }}
    - host: {{ .Values.nexusProxy.env.nexusDockerHost }}
      http:
        paths:
          - backend:
            {{- if .Values.nexusProxy.svcName }}
              serviceName: {{ .Values.nexusProxy.svcName }}
            {{- else }}
              serviceName: {{ template "nexus.fullname" . }}
            {{- end }}
              servicePort: {{ .Values.nexusProxy.port }}
{{- end }}
{{- end -}}
{{- with .Values.ingress.rules  }}
{{ toYaml . | indent 2 }}
  {{- end -}}
{{- if .Values.ingress.tls.enabled }}
  tls:
    - hosts:
      {{- if .Values.nexusProxy.env.nexusHttpHost }}
        - {{ .Values.nexusProxy.env.nexusHttpHost }}
      {{- end }}
      {{- if .Values.nexusProxy.env.nexusDockerHost }}
        - {{ .Values.nexusProxy.env.nexusDockerHost }}
      {{- end }}
      {{- if .Values.ingress.tls.secretName }}
      secretName: {{ .Values.ingress.tls.secretName | quote }}
      {{- end }}
{{- end -}}
{{- end }}

my-values.yamlは下記となります。
すでに述べた通りALB Ingress Controllerとkube2iamがデプロイされていることを前提としていて、PodにはS3FullAccessPolicyが与えられたIAM Roleを付与します。

my-values.yaml
statefulset:
  enabled: true
nexus:
  dockerPort: 5003
  nexusPort: 8081
  service:
    type: NodePort
  podAnnotations:
    iam.amazonaws.com/role: s3-full-access-role
nexusProxy:
  enabled: true
  env:
    nexusDockerHost: registry.sample.com
    nexusHttpHost: nexus.sample.com
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

次のコマンドでnexusをデプロイします。

$ helm install --values my-values.yaml sonatype-nexus ./

あとはアクセスするときに名前解決できるようにRoute53等で設定を加えれば良いです。

リポジトリ作成

Nexusでリポジトリを作成する時にはblob storeを選択する必要があります。
今回はデフォルトで用意されているFILE方式のものを使用します。
このblob storeはEBSにマウントされています。

スクリーンショット 2020-02-10 18.56.03.png

docker(hosted)とraw(hosted)をリポジトリとして作成していきます。
前者はDockerレジストリ、後者は画像などの格納場所を用途としています。

①docker(hosted)

Repositoryからdocker(hosted)を選択します。
スクリーンショット 2020-02-10 18.56.53.png

NameとHTTPだけ埋めて作成します。
HTTP PortはNexusデプロイ時にDockerレジストリのために用意したポートを使用します。
ここでは5003です。

スクリーンショット 2020-02-10 18.58.21.png

問題なく作成されたことを画面で確認します。

スクリーンショット 2020-02-10 18.59.26.png

②raw(hosted)

Repositoryからraw(hosted)を選択する。
スクリーンショット 2020-02-10 19.00.16.png

Nameだけ埋めて作成します。
スクリーンショット 2020-02-10 19.01.42.png

問題なく作成されたことを画面で確認します。
スクリーンショット 2020-02-10 19.02.29.png

データ格納

Dockerイメージと画像をそれぞれdocker(hosted)、raw(hosted)に格納していきます。

①docker(hosted)

dockerコマンドでDockerイメージをアップロードします。
HTTPの場合はクライアント側にinsecure registryの設定を入れないといけないことに注意しましょう。

$ docker login registry.sample.com
$ docker push registry.sample.com/alpine:3.7

Nexus画面より、問題なくアップロードされていることを確認します。
スクリーンショット 2020-02-10 19.07.28.png

②raw(hosted)

Nexus画面からraw(hosted)を選択しUpload componentをクリックします。
スクリーンショット 2020-02-10 19.18.28.png

Browseからローカルの画像を選択しUploadします。
スクリーンショット 2020-02-10 19.20.46.png

こちらも問題なくアップロードされることを確認します。
スクリーンショット 2020-02-10 19.25.11.png

データ移行

EBSからS3へのデータ移行手順を説明していきます。

S3バケットの作成

事前にS3バケットを作成しておきます。
Nexusの設定でprefix指定ができるので既存のバケットを使用することも可能です。

$ aws s3 mb s3://sonatype-nexus-blobs

S3へのデータ転送

NexusコンテナにAWS CLIが入っていないのでローカルにコピーしてからS3へデータ転送します。

$ mkdir blobs
$ kubectl cp sonatype-nexus-0:/nexus-data/blobs ./blobs
$ aws s3 cp blobs/ s3://sonatype-nexus-blobs --recursive

NexusのDBの編集

NexusのDBを手動で変更しblobsの保存方式をFILEからS3にしていきます。
Nexusにアクセスできないよう事前にServiceの削除等をしておくことをおすすめします。

## Nexusコンテナ内にプロセスを起動させる
$ kubectl exec sonatype-nexus-0 -it /bin/bash

## NexusのDBに接続する
$ cd /opt/sonatype/nexus
$ java -jar lib/support/nexus-orient-console.jar
> connect plocal:/nexus-data/db/config admin admin

## 保存方式をS3に変更する
> update repository_blobstore set type="S3" where name="default"

## リージョンとS3バケット情報を入れる
> update repository_blobstore set attributes.s3={region: 'ap-northeast-1', bucket: 'sonatype-nexus-blobs', prefix: 'default', expiration: -1}  where name="default"

上記手順を終えたらPodの再起動をします。

$ kubectl delete pod sonatype-nexus-0

確認

Nexus画面でblob storeを確認します。
TypeがS3になっていることが分かります。
スクリーンショット 2020-02-10 19.57.36.png

Dockerレジストリを確認します。
docker pullできることが分かります。

$  docker pull registry.sample.com/alpine:3.7
3.7: Pulling from alpine
Digest: sha256:ab3fe83c0696e3f565c9b4a734ec309ae9bd0d74c192de4590fd6dc2ef717815
Status: Downloaded newer image for registry.moguta.ml/alpine:3.7

rawリポジトリは画面で確認します。
Pathから画像ファイルを選択します。
スクリーンショット 2020-02-15 17.27.12.png

別タブで画像が表示されます。
スクリーンショット 2020-02-15 17.28.03.png

おわりに

EKSにHelmでデプロイしたNexusのblob storeをEBSからS3へ移行させる手順を説明しました。
blob storeの中身が大きいとその分ローカルストレージの容量を確保しないといけないことに注意です。

参考

Nexus Repository Manager 3 Storage Guide
sonatype Nexusのblob store を FileからS3に変更する

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした