Ponz Dev Log

ゆるくてマイペースな開発日記

Nexus × HelmでプライベートMavenリポジトリをKubernetes上に立てる

MavenJavaのアプリをビルドすると、CIサーバーなどクリーンな環境ではライブラリのダウンロードに時間がかかります。 5分程度ならまだしも、正直10分を超えると気軽にビルドして検証するには支障が出るのでキツイ。特にプロキシ環境下。

そこでMaven Centralリポジトリのキャッシュレイヤとして Nexus Repository Manager 3のOSS版 (以下、Nexus) を立てちゃおうという話。

環境情報

この記事では以前の記事でも紹介したおうちクラウドKubernetesクラスタを使用します。 その他にもクライアントの開発端末を含めた環境情報は以下の通りです。

項目 バージョン
開発端末 macOS Monterey
Kubernetes v1.22.5
Helm CLI v3.8.0

また、Nexusのデプロイに使用するHelmチャートはSonatype公式のリポジトリが用意されているのでこれを使います。
2022/02/01時点で最新の Chart Version = 37.3.0, App Version = 3.37.3 を使用します。

github.com

artifacthub.io

事前準備

HelmチャートでデプロイしたNexusを開発端末から接続させるため、Ingressで外部公開できるようにします。

今回扱うおうちクラウドにはIngress Contollerが導入されていません。 NGINX Ingress Controllerを使用します。これもHelmチャートで導入可能です。

$ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

$ helm update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "ingress-nginx" chart repository

$ helm install ingress-nginx ingress-nginx \
    --repo https://kubernetes.github.io/ingress-nginx \
    --namespace ingress-nginx --create-namespace

Nexus Repository Managerを立てる

さて、本題です。Chartのパラメータを参照しながらIngressで外部公開したNexusをデプロイします。 しかし、Ingressで公開しようと ingress.enabled=true を指定しても今回扱うKubernetesクラスタではデプロイできませんでした。

$ helm install nexus-rm sonatype/nexus-repository-manager --namespace registry --create-namespace --set ingress.enabled=true
Error: INSTALLATION FAILED: unable to build kubernetes objects from release manifest: unable to recognize "": no matches for kind "Ingress" in version "networking.k8s.io/v1beta1"

デプロイしたバージョンのChartから生成されるマニフェスト上では、 networking.k8s.io/v1beta のバージョンのAPIを使ってIngressは作成します。(GitHubに載っているテンプレートだと networking.k8s.io/v1 になってる) しかし、デプロイ先のクラスタではこのバージョンのAPIは削除されていたためデプロイできなかったのです。

気を取り直して、Ingressだけ手動で作成する方針で進めます。

$ helm install nexus-rm sonatype/nexus-repository-manager --namespace registry --create-namespace

$ kubectl create ingress nexus-rm-nexus-repository-manager \
      --class=nginx \
      --default-backend=nexus-rm-nexus-repository-manager:8081 \
      -n registry

$ kubectl get ingress -n registry
NAME                                CLASS   HOSTS   ADDRESS         PORTS   AGE
nexus-rm-nexus-repository-manager   nginx   *       192.168.2.xxx   80      5h55m

今回はデプロイできました。 Ingressに払い出されたIPアドレスにブラウザからアクセスできるようになります。

実際に使ってみる

実際にアクセスしてadminユーザーでアクセスすると、既にMaven Centralのプロキシリポジトリ(maven-central)とグループリポジトリ(maven-public)が作成されています。 この後はグループリポジトリを使ってアクセスしてみます。

f:id:accelerk:20220201201244p:plain
Nexusリポジトリ一覧

MavenからプライベートMavenリポジトリを指定するには、以下のように settings.xml ファイルを準備します。 <url> パラメータに先ほどのグループリポジトリのURLを、 <server> 以下のパラメータには認証情報を指定すれば良いです。

<settings
  xmlns="http://maven.apache.org/SETTINGS/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">

  <mirrors>
    <mirror>
      <id>nexus</id>
      <mirrorOf>*</mirrorOf>
      <url>http://<NEXUS_IP_ADDRESS>/repository/maven-public/</url>
    </mirror>
  </mirrors>

  <profiles>
    <profile>
      <id>nexus</id>
      <repositories>
        <repository>
          <id>central</id>
          <url>http://central</url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>true</enabled></snapshots>
        </repository>
      </repositories>
      <pluginRepositories>
        <pluginRepository>
          <id>central</id>
          <url>http://central</url>
          <releases><enabled>true</enabled></releases>
          <snapshots><enabled>true</enabled></snapshots>
        </pluginRepository>
      </pluginRepositories>
    </profile>
  </profiles>

  <servers>
    <server>
      <id>nexus</id>
      <username>admin</username>
      <password>**********</password>
    </server>
  </servers>

  <activeProfiles>
    <activeProfile>nexus</activeProfile>
  </activeProfiles>

</settings>

あとは mvn コマンドのオプションでこの settings ファイルを渡せばNexusからライブラリを取得できます。

$ mvn clean package -DskipTests -s settings.xml
Downloading from nexus: http://<NEXUS_IP_ADDRESS>/repository/maven-public/...

以上。