helm で Harbor
はじめに
今回はコンテナイメージを管理する Harbor についてです。
1年前にも Harbor をデプロイして試してみたのですが、Rancher の管理画面からパラメータをいれてのデプロイでした。今回は helm
を使ってデプロイし、コンテナイメージを push/ pull していこうと思います。
前回の記事はこちら。
環境情報
ubuntu:18.04.5 LTS
Kubernetes:v1.20.6
※PV に Cephを利用しています
helm:v3.5.4
docker(クライアント用):20.10
Harbor デプロイ
まずは helm
にリポジトリを登録します。
# helm にリポジトリ登録
$ helm repo add harbor https://helm.goharbor.io
"harbor" has been added to your repositories
# リポジトリ登録確認
$ helm repo list
NAME URL
harbor https://helm.goharbor.io
# リポジトリ情報更新
$ helm repo update
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "harbor" chart repository
Update Complete. ?Happy Helming!?
# コードを取得して、values.yaml を編集する
$ helm pull harbor/harbor --untar
$ cd harbor/
# パラメータ修正で使うノードの IP を取得
$ kubectl get nodes -o jsonpath="{.items[0].status.addresses[0].address}"
192.168.10.61
パラメータ変更のため、取得した values.yaml
を編集します。
今回は NodePort で公開するため、関連するパラメータを変更しています。
@@ -2,7 +2,7 @@
# Set the way how to expose the service. Set the type as "ingress",
# "clusterIP", "nodePort" or "loadBalancer" and fill the information
# in the corresponding section
- type: ingress
+ type: nodePort
tls:
# Enable the tls or not.
# Delete the "ssl-redirect" annotations in "expose.ingress.annotations" when TLS is disabled and "expose.type" is "ingress"
@@ -22,7 +22,7 @@
auto:
# The common name used to generate the certificate, it's necessary
# when the type isn't "ingress"
- commonName: ""
+ commonName: "192.168.10.61"
secret:
# The name of secret which contains keys named:
# "tls.crt" - the certificate
@@ -117,7 +117,7 @@
# the IP address of k8s node
#
# If Harbor is deployed behind the proxy, set it as the URL of proxy
-externalURL: https://core.harbor.domain
+externalURL: https://192.168.10.61:30003
# The internal TLS used for harbor components secure communicating. In order to enable https
# in each components tls cert files need to provided in advance.
早速デプロイします。
# namespace 作成
$ kubectl create ns harbor
# harbor デプロイ
$ helm install harbor -n harbor -f values.yaml harbor/harbor
NAME: harbor
LAST DEPLOYED: Sat Sep 18 21:27:38 2021
NAMESPACE: harbor
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Please wait for several minutes for Harbor deployment to complete.
Then you should be able to visit the Harbor portal at https://192.168.10.61:30003
For more details, please visit https://github.com/goharbor/harbor
# リソース確認
$ kubectl get svc,po -n harbor
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/harbor NodePort 10.104.241.37 <none> 80:30002/TCP,443:30003/TCP,4443:30004/TCP 31s
service/harbor-chartmuseum ClusterIP 10.108.128.15 <none> 80/TCP 32s
service/harbor-core ClusterIP 10.104.189.102 <none> 80/TCP 32s
service/harbor-database ClusterIP 10.109.171.244 <none> 5432/TCP 32s
service/harbor-jobservice ClusterIP 10.105.25.179 <none> 80/TCP 31s
service/harbor-notary-server ClusterIP 10.109.251.118 <none> 4443/TCP 32s
service/harbor-notary-signer ClusterIP 10.105.221.7 <none> 7899/TCP 31s
service/harbor-portal ClusterIP 10.107.233.75 <none> 80/TCP 31s
service/harbor-redis ClusterIP 10.104.83.185 <none> 6379/TCP 31s
service/harbor-registry ClusterIP 10.111.202.69 <none> 5000/TCP,8080/TCP 31s
service/harbor-trivy ClusterIP 10.108.112.117 <none> 8080/TCP 32s
NAME READY STATUS RESTARTS AGE
pod/harbor-chartmuseum-55f77977b9-42pd6 1/1 Running 0 31s
pod/harbor-core-598bd558d9-7bt5j 1/1 Running 0 31s
pod/harbor-database-0 1/1 Running 0 31s
pod/harbor-jobservice-6b98cbdd6c-plgn8 0/1 Running 0 31s
pod/harbor-nginx-7dd96757cc-px78s 1/1 Running 0 31s
pod/harbor-notary-server-5c7d686c69-wkmk2 0/1 Running 0 31s
pod/harbor-notary-signer-7455598c86-68hf4 1/1 Running 0 31s
pod/harbor-portal-665c85cf78-n8wvf 1/1 Running 0 31s
pod/harbor-redis-0 1/1 Running 0 31s
pod/harbor-registry-677cb9bd7d-slcl8 2/2 Running 0 31s
pod/harbor-trivy-0 1/1 Running 0 31s
Web UI アクセス & リポジトリ作成
まずは Web UI にアクセスしてリポジトリ(プロジェクト)を作成します。
ログインに使う管理者(admin)のパスワードは values.yaml
に設定されています。
・・・
# The initial password of Harbor admin. Change it from portal after launching Harbor
harborAdminPassword: "Harbor12345"
・・・
各サービスのポート情報は以下の values.yaml
の通りです。
・・・
nodePort:
name: harbor
ports:
http:
nodePort: 30002
https:
nodePort: 30003
notary:
nodePort: 30004
・・・
今回は https://192.168.10.61:30003/
にアクセスしてログインします。
Project 画面で「NEW PROJECT」ボタンを押し、新しいプロジェクトを作成します。
今回は以下のパラメータで作成しました。
- Project Name:sandbox
- Access Level:Public にチェックはしない
プロジェクトの一覧に作成したプロジェクトが表示されています。
docker push/pull 準備
クライアント準備
docker push/pull
するために、まずは docker
をインストールします。今回は最新の docker
をインストールするため、既存で入っているパッケージをアンインストールし、リポジトリ登録して docker
を再インストールします。
# 古い docker をアンインストール
$ apt-get remove docker docker-engine docker.io containerd runc
# 必要なソフトウェアをインストール
$ apt-get update
$ apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
# リポジトリ情報登録
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
(2行分、ここまでコマンド)
$ cat /etc/apt/sources.list.d/docker.list
deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu bionic stable
# リポジトリ情報を更新
$ apt-get update
# インストール対象のバージョンを確認
$ apt-cache madison docker-ce | grep 5.20
docker-ce | 5:20.10.8~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
docker-ce | 5:20.10.7~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
docker-ce | 5:20.10.6~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
docker-ce | 5:20.10.5~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
docker-ce | 5:20.10.4~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
docker-ce | 5:20.10.3~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
docker-ce | 5:20.10.2~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
docker-ce | 5:20.10.1~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
docker-ce | 5:20.10.0~3-0~ubuntu-bionic | https://download.docker.com/linux/ubuntu bionic/stable amd64 Packages
# インストール対象が最新版なのでバージョン指定なしでインストール
$ apt-get install docker-ce docker-ce-cli containerd.io
# docker の起動確認
$ systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2021-09-18 17:08:49 UTC; 2h 15min ago
Docs: https://docs.docker.com
Main PID: 1106 (dockerd)
Tasks: 8
CGroup: /system.slice/docker.service
mq1106 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
証明書準備(クライアント)
今回は自己署名証明書を利用しているため、クライアント・ノードそれぞれに証明書を配置します。まずは docker push
するためにクライアントに証明書を配置していきます。Secret から証明書を取得します。
# 証明書配置ディレクトリ作成
$ mkdir -p /usr/share/ca-certificates/harbor
# 証明書ファイル出力
$ kubectl get secrets -n harbor harbor-nginx -o jsonpath='{.data.ca\.crt}' | base64 -d > /usr/share/ca-certificates/harbor/harbor.crt
# 証明書確認
$ cat /usr/share/ca-certificates/harbor/harbor.crt
-----BEGIN CERTIFICATE-----
・・・
-----END CERTIFICATE-----
# ルート証明書一覧更新
$ echo harbor/harbor.crt >> /etc/ca-certificates.conf
# ルート証明書再読み込み
$ update-ca-certificates
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
# docker 再起動
$ systemctl restart docker
docker login
コマンドでアクセスできるか確認しましょう。
$ docker login -u admin https://192.168.10.61:30003
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
証明書準備(ノード)
今度はノード側です。Pod 作成時にノードから Harbor に対して pull
が行われるので、各ノードにルート証明書を配置しておきます。
前述のクライアントで行なった方法と一緒で、取得した証明書を各ノードに配置します。
$ ls -l /usr/share/ca-certificates/harbor/harbor.crt
$ echo harbor/harbor.crt >> /etc/ca-certificates.conf
$ update-ca-certificates
containerd を再起動します。
$ systemctl restart containerd
docker push
クライアント・ノードの準備ができたので、実際にイメージの登録とコンテナの作成を行なっていきます。まずはコンテナイメージを登録していきます。前述でも確認しましたが、再度 docker login
で Harbor にログインしてみます。
$ docker login -u admin https://192.168.10.61:30003
Password:
・・・
Login Succeeded
登録するコンテナイメージを準備します。今回は busybox
のコンテナイメージを Harbor に push します。
# busybox のコンテナイメージを pull
$ docker pull busybox:1.34.0
1.34.0: Pulling from library/busybox
35dacafcdad5: Pull complete
Digest: sha256:6502348b85ac820024584a459c0deeddf350db8ab3a6609f774483740511575a
Status: Downloaded newer image for busybox:1.34.0
docker.io/library/busybox:1.34.0
# リポジトリ用に名前・タグ付け
$ docker tag busybox:1.34.0 192.168.10.61:30003/sandbox/busybox:1.0
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
busybox 1.34.0 8336f9f1d094 4 days ago 1.24MB
192.168.10.61:30003/sandbox/busybox 1.0 8336f9f1d094 4 days ago 1.24MB
# Push !
$ docker push 192.168.10.61:30003/sandbox/busybox:1.0
The push refers to repository [192.168.10.61:30003/sandbox/busybox]
f6cb480bb44e: Pushed
1.0: digest: sha256:15f840677a5e245d9ea199eb9b026b1539208a5183621dced7b469f6aa678115 size: 527
Web UI で確認すると、push されたコンテナイメージを確認出来ます。
Pod デプロイ
登録したコンテナイメージを使って Pod をデプロイしていきます。
プロジェクト(リポジトリ)を Private で作成したので pull の際に認証情報が必要です。Secret で認証情報を作成します。今回は以下を参考に、docker login
した際のトークン情報を利用します。
# kubectl create secret generic < secret名 >
# --from-file:ホームディレクトリ配下の .docker/config.json を指定
$ kubectl create secret generic harborcred \
--type=kubernetes.io/dockerconfigjson \
--from-file=.dockerconfigjson=/root/.docker/config.json \
-n default
secret/harborcred created
# 登録した Secret 確認
$ kubectl describe secret -n default harborcred
Name: harborcred
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/dockerconfigjson
Data
====
.dockerconfigjson: 87 bytes
登録したコンテナイメージを使って Pod を作成します。マニフェストファイルは以下のとおりで、imagePullSecrets
に登録した Secret を設定しています。
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- command:
- sleep
- "3600"
image: 192.168.10.61:30003/sandbox/busybox:1.0
name: busybox
imagePullSecrets:
- name: harborcred
準備が出来たのでデプロイして確認します。
$ kubectl apply -f pod.yaml
pod/busybox created
$ kubectl describe po busybox -n default
Name: busybox
Namespace: default
・・・
Containers:
busybox:
・・・
Image: 192.168.10.61:30003/sandbox/busybox:1.0
・・・
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 15s default-scheduler Successfully assigned default/busybox to nd01
Normal Pulling 16s kubelet Pulling image "192.168.10.61:30003/sandbox/busybox:1.0"
Normal Pulled 16s kubelet Successfully pulled image "192.168.10.61:30003/sandbox/busybox:1.0" in 570.776627ms
Normal Created 16s kubelet Created container busybox
Normal Started 16s kubelet Started container busybox
無事に登録したコンテナイメージで Pod を起動することが出来ました。
まとめ
helm
での Harbor のデプロイはいかがでしたでしょうか。helm
を使うと導入がはかどりますね。Harbor はコンテナイメージの管理だけでなく、WebUI からの操作や Helm Chart の管理、コンテナイメージのスキャンなどのセキュリティ機能もあり、機能としても豊富かと思います。プライベートリポジトリとして是非活用していきたいと思います。
補足
ノードの設定で、今回はルート証明書を登録しました。記事を書く際に確認したのですが、以下を containerd に設定することで自己署名証明書での Pod 起動ができることを確認しました。docker
で言うところの /etc/docker/daemon.json
にリポジトリを登録するに近い形かと思います。ご参考まで。
[plugins]
[plugins.cri.registry]
[plugins.cri.registry.mirrors."192.168.10.61:30003"]
endpoint = [
"https://192.168.10.61:30003"
]
[plugins.cri.registry.configs]
[plugins.cri.registry.configs."192.168.10.61:30003".tls]
insecure_skip_verify = true
Discussion