こんにちは。
株式会社クラスアクト インフラストラクチャ事業部の大塚です。
前回DjangoのコンテナイメージをHarborにpushしました。
今回は上記で作成したDjangoイメージを使ってkubernetesにpod(正確にはDaemonSet)をデプロイしていき、NodePortを使いアクセスをしていきたいと思います。
環境イメージ
今回の環境構築イメージはざっくり以下となります。
kubernetes上に構築したRook-Ceph + Harbor環境からDjangoイメージをpullし、そのイメージを使用してDaemonSetとして全ノードにpodをデプロイしていきたいと思います。HarborからイメージをpullするためにcontainerdにHarborの証明書を認識させる必要があるため、併せて実施します。また、これらのpodに対してはNodePortを使いアクセスしていきたいと思います。
Rook-Ceph + Harborの構築は以下をご覧ください。
参考サイト
以下サイトを参考にしました。
用語
コンテナランタイム
難しく聞こえてしまいそうですが、下記にも書いている通りkubernetes上でコンテナを走らせたり管理するためのソフトウェアです。dockerもコンテナランタイムの1つです。dockerのほかにもcontainerdやcri-o、podmanなどもこれに該当します。
コンテナ ランタイムは、Kubernetes ノード上のコンテナとコンテナ イメージを管理するソフトウェアです。
構築
各ノードで稼働しているcontainerdにHarborの証明書を認識させる
まず、今のkubernetesクラスタのコンテナランタイムを確認します。kubectl get node -o wideで確認することができます。kubeadmでkubernetesクラスタをデプロイしている場合、基本的にはcontainerdかと思います。
root@k8s-master:~# kubectl get node -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
k8s-ceph01 Ready <none> 17d v1.27.3 192.168.2.37 <none> Ubuntu 22.04.2 LTS 5.15.0-75-generic containerd://1.6.21
k8s-ceph02 Ready <none> 17d v1.27.3 192.168.2.38 <none> Ubuntu 22.04.2 LTS 5.15.0-75-generic containerd://1.6.21
k8s-ceph03 Ready <none> 17d v1.27.3 192.168.2.39 <none> Ubuntu 22.04.2 LTS 5.15.0-75-generic containerd://1.6.21
k8s-master Ready control-plane 31d v1.27.2 192.168.2.30 <none> Ubuntu 22.04.2 LTS 5.15.0-76-generic containerd://1.6.21
k8s-worker01 Ready <none> 31d v1.27.2 192.168.2.31 <none> Ubuntu 22.04.2 LTS 5.15.0-73-generic containerd://1.6.21
k8s-worker02 Ready <none> 31d v1.27.2 192.168.2.32 <none> Ubuntu 22.04.2 LTS 5.15.0-73-generic containerd://1.6.21
k8s-worker03 Ready <none> 31d v1.27.2 192.168.2.33 <none> Ubuntu 22.04.2 LTS 5.15.0-73-generic containerd://1.6.21
次にkubernetesのmaster nodeで以下のコマンドを実行してharbor-nginxというSecretから証明書を取得します。
root@k8s-master:~/yaml/harbor# mkdir -p /usr/share/ca-certificates/harbor
root@k8s-master:~/yaml/harbor# kubectl get secrets -n harbor harbor-nginx -o jsonpath='{.data.ca\.crt}' | base64 -d > /usr/share/ca-certificates/harbor/harbor.crt
root@k8s-master:~/yaml/harbor# cat /usr/share/ca-certificates/harbor/harbor.crt
-----BEGIN CERTIFICATE-----
MIIDEzCCAfugAwIBAgIQXYj6XTtDZV6pP1KVd/6nvDANBgkqhkiG9w0BAQsFADAU
MRIwEAYDVQQDEwloYXJib3ItY2EwHhcNMjMwNzA5MDQ1MjA5WhcNMjQwNzA4MDQ1
MjA5WjAUMRIwEAYDVQQDEwloYXJib3ItY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQCmFplfRJUbXkHUgKcRCOAModVzpLHnQpvxi54mGgxgt2h+dFeh
VwFYLWwe53Lyu3IRqjGvvTU07QVK627W/cP1rTXgeN6W8dkN3vVWyMwR75CXwsn8
kQMVZxMwEh3Knh5Hc81snCGatzKOmPoFXMLXoq+bo5j2MM5BZXJQTZxGFRceXhSq
r1J05bLwfIjgNJURP+zEMMB/X/xb0ROJM9oIQhSQmRMBePM33b2lWI9mVN1vH+rw
fVrLUpp1sIkbp/S5ynRGjpjF7ScRBEXHjTL9ZOk1OBFI5QyB+jN26IDcgGVEHGny
+S0lvxVigYGCzGk3DGofPm3jx2SzyvKzjTxLAgMBAAGjYTBfMA4GA1UdDwEB/wQE
AwICpDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUw
AwEB/zAdBgNVHQ4EFgQUSiAwyZYykvbDD5ToAhsfoFS+BYwwDQYJKoZIhvcNAQEL
BQADggEBAHgaDDryqU4RRrpeZhOv8Vi6+A/MGqaNsSLaWSn8zFe31lCRI1a7vhxC
+jXRNRs6fBPyGNfrGKDqoVGlr7sTL3iRDrhWHBzb2rcIWt1r++AkluTwVa7rp4RO
848A1rh8lDZ10CN25gPZmGCk7AYYZGFo0ITZYf13FdyH+GqWlWovbWFVL3ZHfTjR
4yliGWKMN7GeQVySJ4i0rpT0oGnvZphZ/hNlvTuByIYm0XB3tpIhJEH96yku2K69
d+KI5llKjPk7eLUnf3KaK6iJnp0x1h2L8ZjSqHojzYs/SoKgexPUUswEKSajEalV
FCN+HZUp61bgZxWpECiFYOUEfXJnIi0=
-----END CERTIFICATE-----
或いはHarborのWebUIからも証明書をインストールできます。
Project内のREGISTRY CERTIFICATEを押下することでインストールできます。
この証明書をHarborからイメージをpullしたいnodeに配置します。配置する方法はscpコマンドでも良いですし、WinSCPでもいいですし、なんでもOKです。
今回はscpコマンドを使ってみました。
root@k8s-master:~/yaml/harbor# scp /usr/share/ca-certificates/harbor/harbor.crt
k8s-worker03:/tmp
The authenticity of host 'k8s-worker03 (192.168.2.33)' can't be established.
ED25519 key fingerprint is SHA256:ASvtbwzNVzCXidwxa8h3uqe5SnINTkeZB44Ty97mgac.
This key is not known by any other names
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'k8s-worker03' (ED25519) to the list of known hosts.
root@k8s-worker03's password:
harbor.crt 100% 1127 614.7KB/s 00:00
各nodeのコンテナランタイムのcontainerdに証明書を認識させます。
以下のコマンドを実行します。update-ca-certificatesコマンドでharbor.crtを認識させた後、containerdを再起動しています。これでcontainerdはHarborからコンテナイメージをpull出来るようになるはずです。
root@k8s-worker01:/usr/share/ca-certificates/harbor# ls -ltr
total 4
-rw-r--r-- 1 root root 1127 Jul 9 08:16 harbor.crt
root@k8s-worker01:/usr/share/ca-certificates/harbor# cat harbor.crt
-----BEGIN CERTIFICATE-----
MIIDEzCCAfugAwIBAgIQXYj6XTtDZV6pP1KVd/6nvDANBgkqhkiG9w0BAQsFADAU
MRIwEAYDVQQDEwloYXJib3ItY2EwHhcNMjMwNzA5MDQ1MjA5WhcNMjQwNzA4MDQ1
MjA5WjAUMRIwEAYDVQQDEwloYXJib3ItY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IB
DwAwggEKAoIBAQCmFplfRJUbXkHUgKcRCOAModVzpLHnQpvxi54mGgxgt2h+dFeh
VwFYLWwe53Lyu3IRqjGvvTU07QVK627W/cP1rTXgeN6W8dkN3vVWyMwR75CXwsn8
kQMVZxMwEh3Knh5Hc81snCGatzKOmPoFXMLXoq+bo5j2MM5BZXJQTZxGFRceXhSq
r1J05bLwfIjgNJURP+zEMMB/X/xb0ROJM9oIQhSQmRMBePM33b2lWI9mVN1vH+rw
fVrLUpp1sIkbp/S5ynRGjpjF7ScRBEXHjTL9ZOk1OBFI5QyB+jN26IDcgGVEHGny
+S0lvxVigYGCzGk3DGofPm3jx2SzyvKzjTxLAgMBAAGjYTBfMA4GA1UdDwEB/wQE
AwICpDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDwYDVR0TAQH/BAUw
AwEB/zAdBgNVHQ4EFgQUSiAwyZYykvbDD5ToAhsfoFS+BYwwDQYJKoZIhvcNAQEL
BQADggEBAHgaDDryqU4RRrpeZhOv8Vi6+A/MGqaNsSLaWSn8zFe31lCRI1a7vhxC
+jXRNRs6fBPyGNfrGKDqoVGlr7sTL3iRDrhWHBzb2rcIWt1r++AkluTwVa7rp4RO
848A1rh8lDZ10CN25gPZmGCk7AYYZGFo0ITZYf13FdyH+GqWlWovbWFVL3ZHfTjR
4yliGWKMN7GeQVySJ4i0rpT0oGnvZphZ/hNlvTuByIYm0XB3tpIhJEH96yku2K69
d+KI5llKjPk7eLUnf3KaK6iJnp0x1h2L8ZjSqHojzYs/SoKgexPUUswEKSajEalV
FCN+HZUp61bgZxWpECiFYOUEfXJnIi0=
-----END CERTIFICATE-----
root@k8s-worker01:/usr/share/ca-certificates/harbor# update-ca-certificates
Updating certificates in /etc/ssl/certs...
0 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
root@k8s-worker01:/usr/share/ca-certificates/harbor# systemctl restart containerd
DjangoイメージをHarborからpullしてpodを走らせる
yamlをベースにDjango環境をデプロイしていきたいと思います。今回用意したyamlファイルは以下となります。1つのyamlでDjango pod(正確にはDaemonSet)をデプロイするins-env namespaceとDjangoのDaemonSet、DaemonSetにWebブラウザで接続する為のNodePortを定義し、一斉にデプロイしていきます。
kind: Namespace
apiVersion: v1
metadata:
name: ins-env
labels:
name: ins-env
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: django-rs
namespace: ins-env
labels:
app: django-web
spec:
selector:
matchLabels:
name: django
template:
metadata:
labels:
name: django
spec:
containers:
- name: django-pod
image: 192.168.2.37:30003/ins-env/django:1.1
ports:
- containerPort: 8000
command: ["python3", "/home/testProject/manage.py", "runserver", "0.0.0.0:8000"]
---
apiVersion: v1
kind: Service
metadata:
name: django-nodeport
namespace: ins-env
spec:
ports:
- name: django-nodeport
port: 8000
protocol: TCP
targetPort: 8000
nodePort: 30080
selector:
name: django
type: NodePort
デプロイしていきます。
root@k8s-master:~/yaml/ins-env# kubectl apply -f ds-django.yaml
結果を確認します。podがrunningステートになっていれば、DjangoコンテナイメージをHarborからpull出来ている。つまり証明書をcontainerdが認識しているということを示しています。
root@k8s-master:~/yaml/ins-env# kubectl get all -n ins-env -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/django-rs-2b59h 1/1 Running 0 50s 172.16.39.248 k8s-worker03 <none> <none>
pod/django-rs-nmbbg 1/1 Running 0 50s 172.16.93.180 k8s-ceph02 <none> <none>
pod/django-rs-s85vw 1/1 Running 0 50s 172.16.69.246 k8s-worker02 <none> <none>
pod/django-rs-s87bk 1/1 Running 0 50s 172.16.79.100 k8s-worker01 <none> <none>
pod/django-rs-wg6dm 1/1 Running 0 50s 172.16.148.36 k8s-ceph03 <none> <none>
pod/django-rs-zfd46 1/1 Running 0 50s 172.16.114.142 k8s-ceph01 <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/django-nodeport NodePort 10.96.87.188 <none> 8000:30080/TCP 50s name=django
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR
daemonset.apps/django-rs 6 6 6 6 6 <none> 50s django-pod 192.168.2.37:30003/ins-env/django:1.1 name=django
Webブラウザを使ってアクセス出来ることを確認します。Harborを使いkubernetesにpodをデプロイ出来ました。
ちなみに
「Harborからコンテナイメージをpush/pullするサーバにdockerをインストールしないといけないんだなぁ」と思い、Harbor環境構築時に脳死でdockerをインストールしてしまったのですが、よくよく考えるとkubernetesのコンテナランタイムはcontainerdだから必要ないよな~と思いました。
私の環境だとコンテナを走らせたりHarborにpush/pullするためにk8s-master上のdockerを使い、kubernetes上でpod(コンテナ)を走らせるためにcontainerdを使っているような若干歪な形になってしまっていると思います。
また、master nodeでHarbor構築時にインストールしてしまったdockerとcontainerdが走っていますが、それぞれに対して証明書を認識させないとHarborにアクセス出来ない点が注意な気がします。dockerに証明書を認識させたとしてもcontainerdは認識していない点には注意かと思いました。私はそこに気付けず暫くkubernetesのイメージpullでエラーを吐かれ、悩みました。