2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

k8s上にプライベートなコンテナイメージレジストリをデプロイする(Harbor on k8s)

Posted at

Kubernetes上にプライベートなコンテナリポジトリを建てる時の自分用メモ

  • https対応
    • Ingressでssl/tlsの終端を行う
  • 自己署名証明書を使用
    • 証明書はcert-managerで発行&管理
  • コンテナリポジトリはHarborを使用

前提

  • 作業端末にhelmがインストール済み
  • k8sクラスタ内にcert-managerがデプロイ済み
  • k8sクラスタ内にIngress Controller(筆者環境ではNGINX Ingress Controllerを使用)がデプロイ済み

手順

namespace作成

コンテナリポジトリ(Harbor)をデプロイするnamespaceを準備しておく

kubectl create ns harbor

自己署名証明書の作成

ここではcert-managerを使って作成
cert-managerを使わない場合は、opensslコマンド等でCA証明書作成 → k8s secret化という流れでも同じことができる

まずは自己署名用の認証局(CA)を作成する
cert-managerはIssuer(またはcluster-issuer)というカスタムリソースによって認証局を管理する

# 認証局(自己署名用)のマニフェスト
$ cat issuer.yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
 name: harbor-issuer
 namespace: harbor
spec:
 selfSigned: {}

# 認証局作成
$ kubectl apply -f issuer.yaml

つぎに作成した認証局を使ってCA証明書を発行する
cert-managerはCertificateというカスタムリソースによって証明書を管理する

# CA証明書のマニフェスト
$ cat cert.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: harbor-cert
  namespace: harbor
spec:
  secretName: harbor-tls
  commonName: core.harbor.yourdomain.com #後ほど作成するingressのホスト名と合わせておく
  dnsNames:
    - core.harbor.yourdomain.com #後ほど作成するingressのホスト名と合わせておく
  issuerRef:
    name: harbor-issuer # 前の手順で作成した認証局の名前を指定
    kind: Issuer
    group: cert-manager.io

# 証明書作成
$ kubectl apply -f cert.yaml

Certificateリソースのspec内で指定した名前で、CA証明書を含むsecretリソースが作成される

$ kubectl get secret -n harbor harbor-tls
NAME         TYPE                DATA   AGE
harbor-tls   kubernetes.io/tls   3      65m

Harborのデプロイ

ここではhelmを使ってデプロイする。こちらのドキュメントを参照。

# helmチャートをダウンロードして展開
$ helm repo add harbor https://helm.goharbor.io
$ helm fetch harbor/harbor --untar
$ cd harbor

# パラメータファイルを編集
$ cp values.yaml values-custom.yaml
$ vim values-custom.yaml
$ diff values.yaml values-custom.yaml
19c19
<     certSource: auto
---
>     certSource: secret # 前の手順にてcert-managerで作成した証明書(secretリソース)を利用するため、"secret"を指定
28c28
<       secretName: ""
---
>       secretName: "harbor-tls" #Certificateリソースによって作成されたsecretリソース名
36,37c36,37
<       core: core.harbor.domain
<       notary: notary.harbor.domain
---
>       core: core.harbor.yourdomain.com #自環境のドメイン名に書き換え(CertificateリソースのdnsNameに合わせる)
>       notary: notary.harbor.yourdomain.com #自環境のドメイン名に書き換え
47c47
<     className: ""
---
>     className: "nginx" #自環境におけるIngress Classの名称に書き換え
127c127
< externalURL: https://core.harbor.domain
---
> externalURL: https://core.harbor.yourdomain.com #自環境のドメイン名に書き換え(CertificateリソースのdnsNameに合わせる)

# helmを使用してHarborをインストール
$ helm install my-harbor . -n harbor -f values-custom.yaml

# 各podの稼働確認
$ kubectl get pod -n harbor
NAME                                       READY   STATUS    RESTARTS       AGE
my-harbor-chartmuseum-765c5f5845-vq6v8     1/1     Running   0              143m
my-harbor-core-7f6fbdcb7d-82jkm            1/1     Running   0              143m
my-harbor-database-0                       1/1     Running   0              143m
my-harbor-jobservice-6f5dc8655b-drkv9      1/1     Running   3 (143m ago)   143m
my-harbor-notary-server-697b5d79d9-m4kfm   1/1     Running   1 (143m ago)   143m
my-harbor-notary-signer-788cf6c74c-tjq9t   1/1     Running   1 (143m ago)   143m
my-harbor-portal-97c89d9b4-tfp5r           1/1     Running   0              143m
my-harbor-redis-0                          1/1     Running   0              143m
my-harbor-registry-5886497567-gnltv        2/2     Running   0              143m
my-harbor-trivy-0                          1/1     Running   0              143m

# ingressリソースの確認
$ kubectl get ingress -n harbor
NAME                       CLASS   HOSTS                         ADDRESS          PORTS     AGE
my-harbor-ingress          nginx   core.harbor.yourdomain.com     10.128.213.144   80, 443   144m
my-harbor-ingress-notary   nginx   notary.harbor.yourdomain.com   10.128.213.144   80, 443   144m

デプロイ完了後、https://(my-harbor-ingressのホスト名)にアクセスすると、HarborのGUIが表示される。初期パスはadmin/Harbor12345。
スクリーンショット 2023-02-20 13.37.27.png

証明書のインストール

この時点でdockerコマンドでのリポジトリへのアクセスや、k8sノードからのイメージプルを試みるとX509エラーが出力される。

$ sudo docker login core.harbor.yourdomain.com
Username: admin
Password:
Error response from daemon: Get "https://core.harbor.yourdomain.com/v2/": x509: certificate signed by unknown authority

回避するために下記のマシンにCA証明書をインストールする。

  • docker pushを実行するクライアント
  • k8sクラスタ内の各ノード

手順はOSによって異なるが今回の環境では全てUbuntu 20.04 LTSを使用している。

まずはcert-managerで管理されているCA証明書をエクスポートする

# k8s secretからCA証明書をエクスポート
$ kubectl get secret -n harbor harbor-tls -o jsonpath='{.data.ca\.crt}' | base64 -d > harbor.crt

エクスポートしたCA証明書をSCP等で各マシンにコピーした上で、以下を実施

# 証明書を格納
# 格納先は/usr/share/ca-certificatesではないことに注意
$ cp harbor.crt /usr/local/share/ca-certificates

# 証明書を適用
$ sudo update-ca-certificates
Updating certificates in /etc/ssl/certs...
rehash: warning: skipping ca-certificates.crt,it does not contain exactly one certificate or CRL
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.

# dockerデーモン再起動
$ sudo snap stop docker
$ sudo snap start docker

これで設定は完了。あとは適宜リポジトリへのアクセス確認などを行う。

$ sudo docker login core.harbor.yourdomain.com
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /root/snap/docker/2343/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?