モチベーション
これをやり始めたのは以下の理由によります。
- 使えもしないのに、使う目的も特にないのに、なぜかkubernetesが好きだから。(なぜなのか)
今回やったこと
- k3sでクラスタ構築し、JupyterLabをデプロイしてネットワーク内から利用できるようにした。
参考にした記事
- 本稿は、主にこちらの記事を参考にしています。
https://qiita.com/otsukousan/items/5d7a786aa7a2e7335368 - 認証情報の扱いなどはこちらを参考にしています。
https://hassiweb.gitlab.io/memo/docs/memo/k3s/k3s-installation/ - コマンド補完設定はこちらを参考にしています。
https://unicorn.limited/jp/rd/kubernetes/20210527-shorthand.html
構成
ESXi基盤に、マスター1台、ノード2台を用意。それぞれUbuntu22.04を新規インストールした。(ストレージ16GB、メモリ4GB、CPUコア8個)
k3smaster
手順の概要
- 下準備
- マスターサーバにコントロールプレーン設定をする。
- ↑にノードを1台ずつ追加する。
- LoadBalancerをデプロイする。
- JupyterLabをデプロイする。
詳細な手順
1. 下準備
クライアントPCにkubectlをインストールする。
以下の手順はmacOSでHomebrewによるセットアップ手順になります。
brew install kubectl
クライアントPCでkubectlコマンドのタブ補完を有効にする。
# 以下を~/.zshrc
に追記してリロード(. ~/.zshrc
)。(macOSの場合)
source <(kubectl completion zsh)
クライアントの公開キーを対象サーバにコピーする。
クラスタを構築するまでに何度かサーバにログインするので、サーバログイン時にパスワードを入力しなくても済むようにしています。
ssh-copy-id 192.168.150.181 #これをそれぞれのサーバに実施する。
各サーバの/etc/hostsを編集
3台それぞれに同じ作業を実施します。
192.168.150.181 k3smaster
192.168.150.182 k3snode01
192.168.150.183 k3snode02
2. マスターサーバにコントロールプレーン設定
マスターサーバのログインし、以下のコマンドを実行します。
sudo curl -sfL https://get.k3s.io | sh -
正常にインストール完了したら/var/lib/rancher/k3s/server/token
の値をコピーしておきます。(次のノード追加で使います)
マスターサーバからはいったんログアウトします。
3. ノード追加
それぞれのノードで以下のコマンドを実行します。
K3S_TOKEN
のところに上でコピーした文字列が入ります。
curl -sfL https://get.k3s.io |\
K3S_TOKEN="Kxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx::server:xxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
K3S_URL=https://k3smaster:6443 sh -
動作確認
2台のノード追加が終わったら、いったん動作確認してみます。
マスターサーバにログインし、
sudo kubectl get node
以下のようにノードのステータスがReadyになっていれば成功です。
NAME STATUS ROLES AGE VERSION
k3snode01 Ready <none> 33h v1.27.7+k3s2
k3snode02 Ready <none> 33h v1.27.7+k3s2
k3smaster Ready control-plane,master 33h v1.27.7+k3s2
クレデンシャル情報のコピー
マスターノードで、以下のパスにあるファイルの中身をコピーします。
sudo cat /etc/rancher/k3s/k3s.yaml
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
server: https://127.0.0.1:6443
name: default
contexts:
- context:
cluster: default
user: default
name: default
current-context: default
kind: Config
preferences: {}
users:
- name: default
user:
client-certificate-data: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
client-key-data: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- name: username
user:
password: password
username: username
これはk3sクラスタへアクセスするためのクレデンシャル情報なので、本番では扱いを考えなければならないですが、ここではいったん置いておきます。
マスターサーバからログアウトし、クライアントPCに~/.kube/config
を新規作成して、上記クレデンシャル情報をペーストします。
ここで、IPアドレスを127.0.0.1からマスターサーバのIPアドレスに書き換えておきます。
- server: https://127.0.0.1:6443
+ server: https://192.168.150.181:6443
ここで、クライアントPCで以下のコマンドを実行します。
kubectl get node
以下のように表示されれば成功です。
NAME STATUS ROLES AGE VERSION
k3snode01 Ready <none> 34h v1.27.7+k3s2
k3snode02 Ready <none> 34h v1.27.7+k3s2
k3smaster Ready control-plane,master 34h v1.27.7+k3s2
ここからはクライアントPCのkubecltでクラスタを管理していくことになります。
4. LoadBalancerのデプロイ
k3sで、単純にLoadBalancerを指定してもうまくいかなかったので、手動でデプロイすることにします。(やり方はChatGPTに聞きました)
metallbをデプロイ
まずは以下を実行します。
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/namespace.yaml
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml
次にmetallb-config.yml
を以下のように作成します。
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: default
protocol: layer2
addresses:
- 192.168.150.170-192.168.150.179 # 使いたいIPアドレスの範囲
以下のコマンドを実行してデプロイします。
kubectl apply -f metallb-config.yml
これでLoadBalancerの準備ができたはずです。以下のコマンドを実行してみます。
kubectl get service
以下のようにTYPE LoadBalancerの EXTERNAL−IPが指定したIPアドレスになっていれば成功です。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 34h
jupyterlab-service LoadBalancer 10.43.74.148 192.168.150.171 80:32107/TCP 141m
5. JupyterLabのデプロイ
以下の2ファイルを作成します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: jupyterlab-deployment
spec:
replicas: 1
selector:
matchLabels:
app: jupyterlab
template:
metadata:
labels:
app: jupyterlab
spec:
containers:
- name: jupyterlab
image: jupyter/base-notebook:latest # JupyterLabが含まれたイメージを使用するか、カスタムイメージを指定する
ports:
- containerPort: 8888
name: jupyterlab
apiVersion: v1
kind: Service
metadata:
name: jupyterlab-service
spec:
selector:
app: jupyterlab
ports:
- protocol: TCP
port: 80
targetPort: 8888
type: LoadBalancer
上記2ファイルをapplyします。
kubectl apply -f jupyterlab-deployment.yml -f jupyterlab-service.yml
これでJupyterLabは起動しているはずです。確認してみましょう。
kubectl get pod
以下のように出力されればjupyterlabのpodが起動していることが分かります。
NAME READY STATUS RESTARTS AGE
jupyterlab-deployment-xxxxxxxx-xxxxx 1/1 Running 0 12h
ここで、NAME欄をコピーしておいて、以下のコマンドを実行します。
kubectl logs jupyterlab-deployment-xxxxxxxx-xxxxx
すると、以下のような出力がされているはずです。
[C 2023-11-21 11:46:00.954 ServerApp]
To access the server, open this file in a browser:
file:///home/jovyan/.local/share/jupyter/runtime/jpserver-7-open.html
Or copy and paste one of these URLs:
http://jupyterlab-deployment-bdf776574-mppdj:8888/lab?token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
http://127.0.0.1:8888/lab?token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
このtokenをコピーします。
これでやっとJupyterLabを使う準備ができました。
上の方でLoadBalancerのEXPTERNAL-IPが出力されていたはずです。そこにブラウザでアクセスしましょう。
以下のような画面が出てきているはずです。
Password or token
のところに、先程コピーしたTOKENを入れて[Log in]をクリックします。
お疲れ様でした。