ここを読むような皆さんであれば、Kubernetesをご存知のことと思います。
Dockerなどのコンテナ環境のオーケストレーションツールと言えば良いのでしょうか、複数のコンテナで構成するサービスを提供する場合に威力を発揮します。
Kubernetesの本家サイトはこちら。
プロダクショングレードのコンテナ管理基盤
現在はパブリッククラウドが Kubernetesをホスティングしたサービスを提供していますが、これが世に出た頃はこんなに早く出回るとは思いもしませんでした。
そのせいでクラウドのサービスと勘違いしている人もいるかも知れませんが、出自はクラウドではなく今でもオンプレ環境にちゃんと構築することができます。
では早速 Kubernetes環境を作ってみましょ〜、と景気良く行きたい所ですが、ちゃんと作ろうとすると結構骨なのです。
Kubernetesは複数のノードに分散してコンテナを分散配置して、サービスとしての冗長性確保や負荷分散をするのが得意なツールなのです。
ですので、Kubernetesらしき環境を作るとなるとノードが最低3つ必要になります。
お勉強のためとは言っても、ホストOSとゲストOSx3だとメモリが 8GBのチョイ古ノートPCなどでは苦しいです。
今回は Kubernetesらしい 冗長性などは無視して、環境の構築とコンテナの配備の手順程度にしておきます。
では Kubernetes環境の構築からなんですが、素の Kubernetesでも良いのですが、せっかく Ubuntuを使っているので、MicroK8sを使おうと思います。
MicroK8sのサイトはこちら。
(K8sは Kubernetesのことです。長いから略されてしまっています。)
The lightweight Kubernetes
Ubuntuを制作している Canonicalが作った Kubernetes環境です。
元々は Kubernetesの簡易版という位置付けでスタートしたものですが、いつの間にやら Production Readyというレベルにまで昇華され、今ではその使い勝手の良さから、オンプレ界隈では人気を博しているようです。
それでは早速インストールしてみましょう。
と言いたいところですが、上にも書いた通りで、ある程度のメモリがあった方が良いですね。
一度 2GBメモリの仮想マシンにインストールしたんですが、反応が悪くて使い物にならなそうでしたので、8GBの仮想マシンでやり直しています。
検証しているPCのメモリが8GBしかない場合は苦しいかも知れません。
MicroK8sは Canonicalのブツですので、環境は Ubuntu Server 22.04.1にしますが、snapパッケージで配布されていますので、他のディストリでも問題なく動くはずです。
それにしても初めて「snapを使っても問題ないよな」って思えるものに出会いました。
インストール方法は以下にありますので、これに沿ってやっていきます。
snapパッケージなので、Ubuntuじゃなくても動くはず…ということになっています。
Install MicroK8s
では、インストールをば。
subro@UbuntuServer2204:~$ sudo snap install microk8s --classic
microk8s (1.24/stable) v1.24.3 from Canonical✓ installed
インストールできました。
2022年8月28日時点での最新バージョンは 1.24.3でした。
それにしても Kubernetes環境の構築としては驚異的な簡単さです。
昔あ〜でもないこ〜でもないと作ってた頃からすると信じがたい…。
MicroK8sの状態を確認します。
microk8sという独自コマンドを使うんですね。
subro@UbuntuServer2204:~$ sudo microk8s status --wait-ready
microk8s is running
high-availability: no
datastore master nodes: 127.0.0.1:19001
datastore standby nodes: none
addons:
enabled:
ha-cluster # (core) Configure high availability on the current node
disabled:
community # (core) The community addons repository
dashboard # (core) The Kubernetes dashboard
dns # (core) CoreDNS
gpu # (core) Automatic enablement of Nvidia CUDA
helm # (core) Helm 2 - the package manager for Kubernetes
helm3 # (core) Helm 3 - Kubernetes package manager
host-access # (core) Allow Pods connecting to Host services smoothly
hostpath-storage # (core) Storage class; allocates storage from host directory
ingress # (core) Ingress controller for external access
mayastor # (core) OpenEBS MayaStor
metallb # (core) Loadbalancer for your Kubernetes cluster
metrics-server # (core) K8s Metrics Server for API access to service metrics
prometheus # (core) Prometheus operator for monitoring and logging
rbac # (core) Role-Based Access Control for authorisation
registry # (core) Private image registry exposed on localhost:32000
storage # (core) Alias to hostpath-storage add-on, deprecated
ここに並んでいるサービスは、よく使われるサービスを MicroK8sがデフォルトインストールの状態で持って持っているのでしょう。
とりあえず ha-clusterだけは有効にしてありますが、ここでは1ノードでやっているので使われません。
この状態でMicroK8sに関係すると思われるプロセスはこんな感じです。
subro@UbuntuServer2204:~$ ps -ef | grep microk8s
root 4481 1 3 13:46 ? 00:00:27 /snap/microk8s/3597/bin/containerd --config /var/snap/microk8s/3597/args/containerd.toml --root /var/snap/microk8s/common/var/lib/containerd --state /var/snap/microk8s/common/run/containerd --address /var/snap/microk8s/common/run/containerd.sock
root 4615 1 0 13:46 ? 00:00:00 /bin/bash /snap/microk8s/3597/run-cluster-agent-with-args
root 4637 1 2 13:46 ? 00:00:20 /snap/microk8s/3597/bin/k8s-dqlite --storage-dir=/var/snap/microk8s/3597/var/kubernetes/backend/ --listen=unix:///var/snap/microk8s/3597/var/kubernetes/backend/kine.sock:12379
root 4654 1 0 13:46 ? 00:00:00 /bin/bash /snap/microk8s/3597/apiservice-kicker
root 4671 1 8 13:46 ? 00:00:58 /snap/microk8s/3597/kubelite --scheduler-args-file=/var/snap/microk8s/3597/args/kube-scheduler --controller-manager-args-file=/var/snap/microk8s/3597/args/kube-controller-manager --proxy-args-file=/var/snap/microk8s/3597/args/kube-proxy --kubelet-args-file=/var/snap/microk8s/3597/args/kubelet --apiserver-args-file=/var/snap/microk8s/3597/args/kube-apiserver --kubeconfig-file=/var/snap/microk8s/3597/credentials/client.config --start-control-plane=true
root 4789 4615 0 13:46 ? 00:00:01 /snap/microk8s/3597/bin/cluster-agent --bind 0.0.0.0:25000 --keyfile /var/snap/microk8s/3597/certs/server.key --certfile /var/snap/microk8s/3597/certs/server.crt --timeout 240
root 5392 1 0 13:46 ? 00:00:01 /snap/microk8s/3597/bin/containerd-shim-runc-v2 -namespace k8s.io -id 40de38b2fea5ba9369ef658d36804227b96263c0c4f4fc84e6c229d540774cd6 -address /var/snap/microk8s/common/run/containerd.sock
root 6869 1 0 13:47 ? 00:00:01 /snap/microk8s/3597/bin/containerd-shim-runc-v2 -namespace k8s.io -id 0f7dcb72f7f764300088135ada2097a4acd0b2b96d877efa4e444e80db3f7c00 -address /var/snap/microk8s/common/run/containerd.sock
subro 18413 2707 0 13:57 pts/0 00:00:00 grep --color=auto microk8s
Dockerではなく containerdが動いていました。
contaierdについては株式会社デージーネットさんのサイトの説明が一番わかりやすかったので勉強させてもらいました。
containerdとは
手順に沿って進めますと、次は dashboard・dns・registry・istio を有効化するようです。
subro@UbuntuServer2204:~$ sudo microk8s enable dashboard dns registry istio
Infer repository core for addon dashboard
Enabling Kubernetes Dashboard
Infer repository core for addon metrics-server
Enabling Metrics-Server
serviceaccount/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
service/metrics-server created
deployment.apps/metrics-server created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
clusterrolebinding.rbac.authorization.k8s.io/microk8s-admin created
Metrics-Server is enabled
Applying manifest
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-certs created
secret/kubernetes-dashboard-csrf created
secret/kubernetes-dashboard-key-holder created
configmap/kubernetes-dashboard-settings created
role.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
deployment.apps/kubernetes-dashboard created
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created
If RBAC is not enabled access the dashboard by creating a default token with:
microk8s kubectl create token -n kube-system default --duration=8544h
Use this token in the https login UI of the kubernetes-dashboard service.
In an RBAC enabled setup (microk8s enable RBAC) you need to create a user with restricted
permissions as shown in:
https://github.com/kubernetes/dashboard/blob/master/docs/user/access-control/creating-sample-user.md
istio(イスティオ)は上のリストにありませんし、私も初めて見るものです。
本家サイトがこちらです。
Istio
これはコンテナ同士の通信を仲介することで、コンテナからコンテナ同士の通信に関係する面倒を取り去ってやる効果があります。
これによりコンテナ内で動かしているプログラムの開発者は他のコンテナとの連携から開放されるとか、マイクロサービスを多数抱える Kubernetesクラスタではこの観念がないと管理しきれなくなる、などなどいくつかの効果がありますが、初心者がすぐに理解できる説明をしているサイトは見つけられませんでした。
実運用では結構重要な仕組みになりますが、コンテナ同士の通信をフックして透過的に使われているようなので、とりあえずは放っておいて良さげです。
Istioの存在意義というか効能の理解には、少し運用での苦労の経験が必要かも知れません。
手順を続きで、Kubernetesを起動します。
Kubernetesの管理コマンドである kubectlコマンドが microk8sコマンドのサブコマンドになっていますね。
手順には、「kubectl」としてエイリアスを切って「microk8s kubectl」を呼び出せるようにすると普通の Kubernetesと同じになって良いよ、と書いてあります。
subro@UbuntuServer2204:~$ sudo microk8s kubectl get all --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system pod/metrics-server-5f8f64cb86-865gq 0/1 Pending 0 15m
kube-system pod/calico-node-mv6jm 1/1 Running 0 33m
kube-system pod/calico-kube-controllers-5558fbf8bc-m7nsq 1/1 Running 0 33m
kube-system pod/kubernetes-dashboard-765646474b-lw7tg 0/1 Pending 0 13m
kube-system pod/dashboard-metrics-scraper-6b6f796c8d-fnt8z 0/1 Pending 0 13m
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default service/kubernetes ClusterIP 10.152.183.1 443/TCP 33m
kube-system service/metrics-server ClusterIP 10.152.183.108 443/TCP 15m
kube-system service/kubernetes-dashboard ClusterIP 10.152.183.29 443/TCP 15m
kube-system service/dashboard-metrics-scraper ClusterIP 10.152.183.219 8000/TCP 15m
NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-system daemonset.apps/calico-node 1 1 1 1 1 kubernetes.io/os=linux 33m
NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE
kube-system deployment.apps/calico-kube-controllers 1/1 1 1 33m
kube-system deployment.apps/metrics-server 0/1 1 0 15m
kube-system deployment.apps/kubernetes-dashboard 0/1 1 0 15m
kube-system deployment.apps/dashboard-metrics-scraper 0/1 1 0 15m
NAMESPACE NAME DESIRED CURRENT READY AGE
kube-system replicaset.apps/calico-kube-controllers-5558fbf8bc 1 1 1 33m
kube-system replicaset.apps/metrics-server-5f8f64cb86 1 1 0 15m
kube-system replicaset.apps/kubernetes-dashboard-765646474b 1 1 0 13m
kube-system replicaset.apps/dashboard-metrics-scraper-6b6f796c8d 1 1 0 13m
一通り立ち上がり、Kubernetesのダッシュボード(Webサーバーで見られる)を立ち上げてくれているようです。
Kubernetesクラスターが持つ内部(仮想)ネットワークには Calico が使われていることが分かりました。
ダッシュボードが動いているのですが、内部ネットワークの[10.152.183.29:443]で待ち受けていています。
Kubernetesの内部ネットワークは外のネットワークとは繋がっていませんので、次の作業でダッシュボードだけは外から見られるようにします。
subro@UbuntuServer2204:~$ sudo microk8s dashboard-proxy
Checking if Dashboard is running.
Infer repository core for addon dashboard
Waiting for Dashboard to come up.
Create token for accessing the dashboard
secret/microk8s-dashboard-proxy-token created
Waiting for secret token (attempt 0)
Dashboard will be available at https://127.0.0.1:10443
Use the following token to login:
eyJhbGciOiJSUzI1NiIsImtpZCI6IndiSlJ2M2dpQ3ZpVWFJ 〜〜〜以下省略〜〜〜 ←これがトークン
https://127.0.0.1:10443 がダッシュボードの URLと言っていますが、実際は 0.0.0.0:10443 で動いていますので、インストールした Ubuntu Serverとは別のクライアントからWEBアクセスしてみます。
我が家では https://UbuntuServer2204:10443 となります。
このような画面になります。
上の画面にあるトークンをコピペして、サインインを押します。
これがダッシュボードの画面です。
多分パブリッククラウドではこのダッシュボードは使われていないと思いますが、オンプレではこれを使うことになるんじゃないでしょうか。
これで一応の Kubernetes環境はできましたので、何かコンテナ(Pod)を作ってみたいのですが、MicroK8sの APIってどうなってんだろ?と思いましたので確認します。
kubectlコマンドの前に microk8s と入れてやれば、普通の Kubernetesと同じに動きそう。
subro@UbuntuServer2204:~$ sudo microk8s kubectl api-resources
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings v1 true Binding
componentstatuses cs v1 false ComponentStatus
configmaps cm v1 true ConfigMap
endpoints ep v1 true Endpoints
events ev v1 true Event
limitranges limits v1 true LimitRange
namespaces ns v1 false Namespace
nodes no v1 false Node
persistentvolumeclaims pvc v1 true PersistentVolumeClaim
persistentvolumes pv v1 false PersistentVolume
pods po v1 true Pod
podtemplates v1 true PodTemplate
replicationcontrollers rc v1 true ReplicationController
resourcequotas quota v1 true ResourceQuota
secrets v1 true Secret
serviceaccounts sa v1 true ServiceAccount
services svc v1 true Service
mutatingwebhookconfigurations admissionregistration.k8s.io/v1 false MutatingWebhookConfiguration
validatingwebhookconfigurations admissionregistration.k8s.io/v1 false ValidatingWebhookConfiguration
customresourcedefinitions crd,crds apiextensions.k8s.io/v1 false CustomResourceDefinition
apiservices apiregistration.k8s.io/v1 false APIService
controllerrevisions apps/v1 true ControllerRevision
daemonsets ds apps/v1 true DaemonSet
deployments deploy apps/v1 true Deployment
replicasets rs apps/v1 true ReplicaSet
statefulsets sts apps/v1 true StatefulSet
tokenreviews authentication.k8s.io/v1 false TokenReview
localsubjectaccessreviews authorization.k8s.io/v1 true LocalSubjectAccessReview
selfsubjectaccessreviews authorization.k8s.io/v1 false SelfSubjectAccessReview
selfsubjectrulesreviews authorization.k8s.io/v1 false SelfSubjectRulesReview
subjectaccessreviews authorization.k8s.io/v1 false SubjectAccessReview
horizontalpodautoscalers hpa autoscaling/v2 true HorizontalPodAutoscaler
cronjobs cj batch/v1 true CronJob
jobs batch/v1 true Job
certificatesigningrequests csr certificates.k8s.io/v1 false CertificateSigningRequest
leases coordination.k8s.io/v1 true Lease
bgpconfigurations crd.projectcalico.org/v1 false BGPConfiguration
bgppeers crd.projectcalico.org/v1 false BGPPeer
blockaffinities crd.projectcalico.org/v1 false BlockAffinity
caliconodestatuses crd.projectcalico.org/v1 false CalicoNodeStatus
clusterinformations crd.projectcalico.org/v1 false ClusterInformation
felixconfigurations crd.projectcalico.org/v1 false FelixConfiguration
globalnetworkpolicies crd.projectcalico.org/v1 false GlobalNetworkPolicy
globalnetworksets crd.projectcalico.org/v1 false GlobalNetworkSet
hostendpoints crd.projectcalico.org/v1 false HostEndpoint
ipamblocks crd.projectcalico.org/v1 false IPAMBlock
ipamconfigs crd.projectcalico.org/v1 false IPAMConfig
ipamhandles crd.projectcalico.org/v1 false IPAMHandle
ippools crd.projectcalico.org/v1 false IPPool
ipreservations crd.projectcalico.org/v1 false IPReservation
kubecontrollersconfigurations crd.projectcalico.org/v1 false KubeControllersConfiguration
networkpolicies crd.projectcalico.org/v1 true NetworkPolicy
networksets crd.projectcalico.org/v1 true NetworkSet
endpointslices discovery.k8s.io/v1 true EndpointSlice
events ev events.k8s.io/v1 true Event
flowschemas flowcontrol.apiserver.k8s.io/v1beta2 false FlowSchema
prioritylevelconfigurations flowcontrol.apiserver.k8s.io/v1beta2 false PriorityLevelConfiguration
nodes metrics.k8s.io/v1beta1 false NodeMetrics
pods metrics.k8s.io/v1beta1 true PodMetrics
ingressclasses networking.k8s.io/v1 false IngressClass
ingresses ing networking.k8s.io/v1 true Ingress
networkpolicies netpol networking.k8s.io/v1 true NetworkPolicy
runtimeclasses node.k8s.io/v1 false RuntimeClass
poddisruptionbudgets pdb policy/v1 true PodDisruptionBudget
podsecuritypolicies psp policy/v1beta1 false PodSecurityPolicy
clusterrolebindings rbac.authorization.k8s.io/v1 false ClusterRoleBinding
clusterroles rbac.authorization.k8s.io/v1 false ClusterRole
rolebindings rbac.authorization.k8s.io/v1 true RoleBinding
roles rbac.authorization.k8s.io/v1 true Role
priorityclasses pc scheduling.k8s.io/v1 false PriorityClass
csidrivers storage.k8s.io/v1 false CSIDriver
csinodes storage.k8s.io/v1 false CSINode
csistoragecapacities storage.k8s.io/v1 true CSIStorageCapacity
storageclasses sc storage.k8s.io/v1 false StorageClass
volumeattachments storage.k8s.io/v1 false VolumeAttachment
どうやら deployments のAPIバージョンは apps/v1 のようです。(ピンク行)
とりあえずお約束の NGINXでも動かしてみようと、Kubernetesのサイトにある yamlファイルをパクってきます。
Kubernetesオブジェクトを記述する
こんなファイルを作りました。
subro@UbuntuServer2204:~$ cat nginx.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
replicas: 2 # tells deployment to run 2 pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
このファイルで 2つの Nginxが動いているコンテナ(Pod)ができるはずです。
配備(deploy)します。
subro@UbuntuServer2204:~$ sudo microk8s kubectl apply -f nginx.yaml
deployment.apps/nginx-deployment created
エラーにはなりませんでした。
再度 Kubernetesクラスターの状態を取得します。
subro@UbuntuServer2204:~$ sudo microk8s kubectl get all --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system pod/calico-kube-controllers-5558fbf8bc-m7nsq 1/1 Running 3 (35m ago) 3h47m
kube-system pod/calico-node-mv6jm 1/1 Running 2 (35m ago) 3h47m
kube-system pod/dashboard-metrics-scraper-6b6f796c8d-fnt8z 1/1 Running 0 3h27m
kube-system pod/metrics-server-5f8f64cb86-865gq 1/1 Running 0 3h28m
kube-system pod/kubernetes-dashboard-765646474b-lw7tg 1/1 Running 0 3h27m
default pod/nginx-deployment-6595874d85-8f47z 1/1 Running 0 25s
default pod/nginx-deployment-6595874d85-z94dz 1/1 Running 0 25s
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default service/kubernetes ClusterIP 10.152.183.1 443/TCP 3h47m
kube-system service/metrics-server ClusterIP 10.152.183.108 443/TCP 3h28m
kube-system service/kubernetes-dashboard ClusterIP 10.152.183.29 443/TCP 3h28m
kube-system service/dashboard-metrics-scraper ClusterIP 10.152.183.219 8000/TCP 3h28m
NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-system daemonset.apps/calico-node 1 1 1 1 1 kubernetes.io/os=linux 3h47m
NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE
kube-system deployment.apps/calico-kube-controllers 1/1 1 1 3h47m
kube-system deployment.apps/dashboard-metrics-scraper 1/1 1 1 3h28m
kube-system deployment.apps/metrics-server 1/1 1 1 3h28m
kube-system deployment.apps/kubernetes-dashboard 1/1 1 1 3h28m
default deployment.apps/nginx-deployment 2/2 2 2 25s
NAMESPACE NAME DESIRED CURRENT READY AGE
kube-system replicaset.apps/calico-kube-controllers-5558fbf8bc 1 1 1 3h47m
kube-system replicaset.apps/dashboard-metrics-scraper-6b6f796c8d 1 1 1 3h27m
kube-system replicaset.apps/metrics-server-5f8f64cb86 1 1 1 3h28m
kube-system replicaset.apps/kubernetes-dashboard-765646474b 1 1 1 3h27m
default replicaset.apps/nginx-deployment-6595874d85 2 2 2 25s
想定通り、NGINXの Podが2つばかり増えています。
PodのIPが何か確認します。
subro@UbuntuServer2204:~$ sudo microk8s kubectl get pods -l app=nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deployment-6595874d85-8f47z 1/1 Running 0 37m 10.1.87.200 ubuntuserver2204
nginx-deployment-6595874d85-z94dz 1/1 Running 0 37m 10.1.87.201 ubuntuserver2204
[10.1.87.200][10.1.87.201]ですね。
では、WEBブラウザでアクセスすると NGINXの初期画面が! と行きたい所ですが、そうは行かないのが Kubernetes。
ですが、MicroK8sの導入はここまで。
別な所で外部から Kubernetesのサービスにアクセスする話を書こうと思います。
ただ、ここまでの構築で後は Kubernetesの書籍に載っているものが動くはずですから、そちらへ遷って頂いてもよいのではないかと思います。
2022/9/22に出ます。
最近新しい本が出てなかったので少し期待しています。