setup †
Kubernetes †
ハードウェア †
Kubernetes Cluster | Kubernetes システム |
Master Node | 管理ノード。ここが死ぬとKubernetes全体が死ぬので、本番システムでは3台以上で冗長化する |
Node | 計算ノード |
Kubernetes全体の管理 †
kubectl | 管理コマンド。RancherではWebから実行できる |
kube apiserver | kuberctlからの処理依頼を受付 |
kube scheduler | Nodeを管理して、どの Node で Pod を動かすかを制御 |
kube control management | Kubernetes の資産を管理 |
etcd | 分散KVS。Kubernetes自体の設定内容を格納 |
アプリコンテナ †
namespace | Podの論理的な管理単位。初期設定で Default が作られている |
Pod | Containerの論理的な単位。Nodeをまたぐことはない |
Service | Pod (内の Container 上で動くアプリ) 同士で通信する場合に、パケットのルーティングを行う |
Podの構成 †
Service †
Cluster IP Serice | Pod間で通信をするための Service。通常 Service と言ったら Cluster IP Service |
Node Port IP Service | あるノード(物理マシン)の Port 経由で Pod にアクセスするための Service |
External Name Service | Pod から namespace 外のサービスを呼び出すための Serivce |
Load Balancer Service | 大規模 Kubernetes で、物理 Load Balancer と連携するための Service の総称。AWS とか Google Cloud Platform のうらで動いている Service |
- 冗長化
Replica Set | 同一構成のPodの組。並列性能の向上、障害対応のために用いる |
Deployment | 本番サービスでは Deployment でアプリを管理。過去の Replica Set をもっていて、Replica Set に対してダウンタイムがないようにバージョンアップやロールバックを行える |
- Podへの外部からのアクセスは Service (L4 Switch相当) が振り分ける
- Pod はそれぞれラベルを持っていて、ラベルに従ってパケットを振り分ける。(そういうふうに Service を設定する)
- Replica Set 内の Pod はすべて同じラベルを持っていて、Service はそのことを知っているので、負荷分散がおこなわれる
こんなかんじ
IN Port | Label |
4848ポートに来たパケットは | "本番環境の管理アプリ" ラベルのPodにルーティング |
8080ポートに来たパケットは | "本番環境" ラベルのPodにルーティング |
14848ポートに来たパケットは | "テスト環境の管理アプリ" ラベルのPodにルーティング |
18080ポートに来たパケットは | "テスト環境" ラベルのPodにルーティング |
- "本番環境"ラベルのPodが3つあったら順繰りに呼ばれる。
- パケット単位なんでアプリのセッションごとに振り分け先 Pod を固定するなんてことはできない → Ingress を使う
Ingress †
- クラスタ全体の HTTP Reverse Poxy (L7 Switch相当)
- 内部的には、外部からの HTTP Request を受け付けて、Service (Cluster IP Serice) 経由で Pod に HTTP パケットを投げなおしている
- 中身は Nginx
永続化領域 †
- Pod 内で動く Docker Container の データ永続化領域(Volume)をどう確保するか
PV (Persistent Volume) | Kubernetes 上で動くアプリケーションのデータを格納する領域。まとめて確保して PVC に切り出す |
PVC (Persistent Volume Claim) | Pod が必要とするデータ領域のスペックと容量の要求(Claim)。Claim をもとに自動的に適切な PV が選ばれて PVC のデータ領域が作られる。通常は Volume Container が作られる |
Pod | Pod では、PVC の name とアプリケーションからのマウントポイントを決める |
- PVCの例
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-data
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 8Gi
storageClassName: ssd
- PVの例
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs001
spec:
capacity:
storage: 500Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Recycle
storageClassName: ssd
mountOptions:
- hard
nfs:
path: /opt/nfs
server: ai-chan.local
- accessMode
ReadWriteOnce? | 1つのPodから読み書きできる |
ReadOnlyMany? | 複数のPodから読み取りができる |
ReadWriteMany? | 複数のPodから読み書きができる |
- persistentVolumeReclaimPolicy?
Retain | PVCが削除されても、データ領域(Volume Container)を残す |
Recycle | PVCが削除されたら、データ領域(Volume Container)の中身を削除する |
Delete | PVCが削除されたら、データ領域(Volume Container)を削除する |
- storageClassName?
- 任意に設定可能。Rancher ではデフォルトで何も登録されていない
kubectl †
参考文献 †
コマンド補完 †
$ sudo apt install bash-completion
$ echo "source <(kubectl completion bash)" >> ~/.bashrc
これで、kubectl のサブコマンドの補完が効くようになる
kubectl create (作成) †
$ kubectl create -f 定義ファイル
- apply は前回の設定内容との差分が適用される。create は同名の設定があったらまるまる上書きする
- 初回にも apply を使えるので、create よりも apply を使うほうが良い
kubectl apply (更新) †
$ kubectl apply -f 定義ファイル
kubectl get (一覧表示) †
$ kubectl get nodes
$ kubectl get services
$ kubectl get pods
kubectl describe (詳細表示) †
$ kubectl describe services [service名]
$ kubectl describe pods [pod名]
kubectl delete (削除) †
$ kubectl delete service [service名]
$ kubectl delete pod [pod名]
kubectl log (標準出力) †
$ kubectl log [pod名] -f
kubectl exec (podでコマンド実行) †
$ kubectl exec [pod名] -- [command]
対話Shellを実行する場合は
$ kubectl exec [pod名] -it -- /bin/bash
kubectrl cp (ファイルコピー) †
$ touch a.txt
$ kubectl cp ./a.txt hello-gpu:~/
$ kubectl cp hello-gpu:~/a.txt ./b.txt
双方向でコピーが可能
kubectl edit (設定変更) †
$ kubectl edit 資産種別('service'など) 資産名
viが起動し、設定内容を変更することができる。(ファイルの保存(:wq) で設定反映)
microK8s †
- kubernetes本体系
サービス | (由来) | 機能 |
dashboard | | kubernetesの稼働状況レポート |
dns | | PodやServiceの名前解決 |
ingress | (入口) | HTTP Reverse Proxy |
metalb | | ロードバランサ― |
metrics-server | | Podの性能情報の記録 |
rbac | | ユーザ認証・認可 |
- マイクロサービス
サービス | (由来) | 機能 |
cilium | (繊毛) | Pod間通信のパケットフィルタリング |
istio | | 同じ機能のPodを複数ノードに配置したときの負荷分散 (linkerdと同じ位置づけ) |
linkerd | | 同じ機能のPodを複数ノードに配置したときの負荷分散 (istioと同じ位置づけ) |
jaeger | (トウゾクカモメ) | 同じ機能のPodを複数ノードに配置したときの負荷分散レポート |
knative | | サーバレス基盤 |
fluentd | | ログとりまとめ |
prometheus | | サービス監視 |
- パッケージマネージャ
サービス | (由来) | 機能 |
helm | (舵) | Podのマーケットプレイス。定義ファイルは Chart(海図)。Kubernetes のyaml地獄を緩和 |
helm3 | (舵) | |
- 機械学習
サービス | (由来) | 機能 |
gpu | | gpuサポート |
kubeflow | | tensorflow JOBの実行 |
- docker
サービス | (由来) | 機能 |
registry | | private docker registory。microK8s.kubectl で Pod を作るときに、ここに Docker Image を格納する |
storage | | Persistent Volume。storageClassName?: microk8s-hostpath で /var/snap/microk8s/common/default-storage 以下に PV が作られる |
dashboard †
- https://microk8s.io/docs/addon-dashboard
- インストール (有効化)
$ microk8s enable dashboard
- アクセストークンの取得
$ token=$(microk8s kubectl -n kube-system get secret | grep default-token | cut -d " " -f1)
$ microk8s kubectl -n kube-system describe secret $token
- microk8s が動いているマシンから firefox でアクセス
$ microk8s kubectl port-forward -n kube-system service/kubernetes-dashboard 10443:443
とすると
https://127.0.0.1:10443
で dashboard にアクセスできる
- 外部からアクセスできるようにする
$ kubectl -n kube-system edit service kubernetes-dashboard
で spec を変更する
spec:
clusterIP: 10.152.183.133
externalTrafficPolicy: Cluster
ports:
- nodePort: 32410
port: 443
protocol: TCP
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard
sessionAffinity: None
type: NodePort
type を NodePort? に変えて保存する。nodePort は 30000 番台が割り振られる(設定してもよい)。
cf. https://ponteru.hatenablog.com/entry/2020/01/15/220830
- Chromeからアクセスできるようにする
- Chrome から dashboard にアクセスしようとすると、証明書エラー「保護されていません」でアクセスできない
- [詳細設定] を押すとでてくる「192.168.10.32にアクセスする(安全ではありません)」リンクもない
- どうやら SAN(Subject Alternative Name) が組み込まれていないオレオレ証明書では一切アクセスできないらしい
- これまでの証明書は、サーバ単位で発行する必要があったが、SANではドメイン指定で、その配下のサーバ全てに有効な証明書を作れる
- でも、うちのLANにDNSなんてないんでどうしよう・・・💡ピコーん nip.io をドメインにしてしまえ
- nip.io は、ドメイン名(nio.ip)の前に指定した ip アドレスを返す。つまり、192.168.10.32.nip.io というURLを名前解決すると、IPアドレス 192.168.10.32 が返ってくる cf. https://nip.io/
- ということで、新しく証明書を作り直して差し替える
$ mkdir certs
$ echo 'subjectAltName = DNS:nip.io' > certs/san.txt
$ openssl req -nodes -newkey rsa:2048 -keyout certs/dashboard.key -out certs/dashboard.csr -subj "/CN=kubernetes-dashboard"
$ openssl x509 -req -sha256 -days 3650 -in certs/dashboard.csr -signkey certs/dashboard.key -out certs/dashboard.crt -extfile certs/san.txt
検証
$ openssl x509 -in certs/dashboard.crt -text -noout
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
34:0c:a0:9b:7b:27:4d:5d:0e:fc:6e:34:cc:29:57:f8:50:07:ee:88
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN = kubernetes-dashboard
Validity
Not Before: Apr 16 15:28:44 2020 GMT
Not After : Apr 14 15:28:44 2030 GMT
Subject: CN = kubernetes-dashboard
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:d7:2f:7c:91:ca:dc:62:de:43:8e:5d:db:44:a1:
(略)
71:8f
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:nip.io
Signature Algorithm: sha256WithRSAEncryption
be:0d:79:ea:6f:4e:20:7d:fe:f6:8e:eb:43:6a:07:b6:b5:8a:
(略)
b4:3c:2c:9f
ミソは、X509v3 Subject Alternative Name: DNS:nip.io。ちゃんと SAN が効いている。
kubernetes管理下の証明書(cert)差し替え
$ kubectl delete secret kubernetes-dashboard-certs -n kube-system
$ kubectl create secret generic kubernetes-dashboard-certs --from-file=certs -n kube-system
$kubectl -n kube-system rollout restart deployment kubernetes-dashboard
これで、https://192.168.10.32.nip.io:32410/ で、Chrome からアクセスできるようになる。
dns †
storage †
- インストール (有効化)
$ microk8s enable storage
- jenkins-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: jenkins-pvc
labels:
app: jenkins
spec:
storageClassName: microk8s-hostpath
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
- microk8s の storage には hostpath が入っていて、pvc だけ作れば、そこから pv を作ってくれる
- pv は、/var/snap/microk8s/common/default-storage に作られる
- pvc の作成
$ kubectl apply -f jenkins-pvc.yaml
persistentvolumeclaim/jenkins-pvc created
$ kubectl get persistentvolumeclaims
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
jenkins-pvc Bound pvc-383c9bc9-c5c8-45b9-a622-fc9f389ac730 10Gi RWO microk8s-hostpath 2m3s
$ kubectl get persistentvolumes
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-383c9bc9-c5c8-45b9-a622-fc9f389ac730 10Gi RWO Delete Bound default/jenkins-pvc microk8s-hostpath 2m17s
pvc-873e09fc-37e5-4c28-8947-b76a60725e3e 20Gi RWX Delete Bound container-registry/registry-claim microk8s-hostpath 23d
$ ls /var/snap/microk8s/common/default-storage
container-registry-registry-claim-pvc-873e09fc-37e5-4c28-8947-b76a60725e3e
default-jenkins-pvc-pvc-383c9bc9-c5c8-45b9-a622-fc9f389ac730
今宵はココまで †
gpu †
ingress †
Deep Learning