🕶️

KWOK (Kubernetes WithOut Kubelet)を触ってみた

2023/03/14に公開

背景

kubernetesの公式ブログにKWOKの紹介記事が載っていたので、試しに触ってみる。

KWOKとは

KWOK (Kubernetes WithOut Kubelet)という名の通り、kubeletを模倣するsimulatorです。
そもそもkubeletとは、各Nodeで実行されるagentであり、kube-apiserverと通信しながらPodやNodeの状態を監視・管理します。

KWOKはkubeletをsimulateすることで、NodeやPodを実際に作成せずともいい感じにkube-apiserverと通信して、リソースの状態を管理してくれます。

環境

MacBook Air (M2 2022)
macOS Monterey v12.6.2

Getting Started

公式ページのGetting Startedに従って進める。

Install

Homebrewでkwokコマンドとkwokctlコマンドをインストールする。

% brew install kwok

Cluster構築

kwokctlでkubernetes Clusterを構築する。

# cluster作成
% kwokctl create cluster --name=kwok

# kubeconfigを設定
% kubectl config use-context kwok-kwok

Node作成

kwokctlでCluster構築すると、kwok-controllerというコンポーネントが作成される。
kwok-controllerはkubeletをsimulateするコンポーネントであり、Nodeを作成すると自動的にkube-apiserverからのheartbeatsを処理してくれる。
そのため、kubeletが存在せずともNodeのStatusがReadyになる。

# nodeを作成する
% kubectl apply -f - <<EOF
apiVersion: v1
kind: Node
metadata:
  annotations:
    node.alpha.kubernetes.io/ttl: "0"
    kwok.x-k8s.io/node: fake
  labels:
    beta.kubernetes.io/arch: amd64
    beta.kubernetes.io/os: linux
    kubernetes.io/arch: amd64
    kubernetes.io/hostname: kwok-node-0
    kubernetes.io/os: linux
    kubernetes.io/role: agent
    node-role.kubernetes.io/agent: ""
    type: kwok
  name: kwok-node-0
spec:
  taints: # Avoid scheduling actual running pods to fake Node
    - effect: NoSchedule
      key: kwok.x-k8s.io/node
      value: fake
status:
  allocatable:
    cpu: 32
    memory: 256Gi
    pods: 110
  capacity:
    cpu: 32
    memory: 256Gi
    pods: 110
  nodeInfo:
    architecture: amd64
    bootID: ""
    containerRuntimeVersion: ""
    kernelVersion: ""
    kubeProxyVersion: fake
    kubeletVersion: fake
    machineID: ""
    operatingSystem: linux
    osImage: ""
    systemUUID: ""
  phase: Running
EOF      

# nodeのStatusがReadyになっている
% kubectl get nodes         
NAME          STATUS   ROLES   AGE   VERSION
kwok-node-0   Ready    agent   57s   fake

Node追加

Nodeの実体が存在する訳ではなく、kwok-controllerがうまく誤魔化しているだけなので、リソースを気にせずいくらでもNodeを追加できてしまう。

# nodeをたくさん増やせる
% kubectl get nodes
NAME          STATUS   ROLES   AGE     VERSION
kwok-node-0   Ready    agent   6m10s   fake
kwok-node-1   Ready    agent   63s     fake
kwok-node-2   Ready    agent   60s     fake
kwok-node-3   Ready    agent   44s     fake
kwok-node-4   Ready    agent   40s     fake
kwok-node-5   Ready    agent   33s     fake
kwok-node-6   Ready    agent   30s     fake
kwok-node-7   Ready    agent   27s     fake
kwok-node-8   Ready    agent   24s     fake
kwok-node-9   Ready    agent   21s     fake

Pod作成

このNode上にPodを追加すると、同様にkwok-controllerがpodのlifecycleをsimulateしてくれるため、kubeletなしでもPodのStatusがRunningになる。
Nodeにtaintsを設定しているため、Podにはtolerationを設定することに注意する。

# podを作成する
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: fake-pod
  namespace: default
spec:
  replicas: 10
  selector:
    matchLabels:
      app: fake-pod
  template:
    metadata:
      labels:
        app: fake-pod
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
              - matchExpressions:
                  - key: type
                    operator: In
                    values:
                      - kwok
      # A taints was added to an automatically created Node.
      # You can remove taints of Node or add this tolerations.
      tolerations:
        - key: "kwok.x-k8s.io/node"
          operator: "Exists"
          effect: "NoSchedule"
      containers:
        - name: fake-container
          image: fake-image
EOF

# podのStatusがRunningになっている
% kubectl get po -o wide
NAME                        READY   STATUS    RESTARTS   AGE   IP          NODE          NOMINATED NODE   READINESS GATES
fake-pod-5fc54c9c96-5xvkc   1/1     Running   0          29m   10.0.0.1    kwok-node-0   <none>           <none>
fake-pod-5fc54c9c96-695gh   1/1     Running   0          29m   10.0.0.8    kwok-node-0   <none>           <none>
fake-pod-5fc54c9c96-728tw   1/1     Running   0          29m   10.0.0.6    kwok-node-0   <none>           <none>
fake-pod-5fc54c9c96-8lrzj   1/1     Running   0          29m   10.0.0.7    kwok-node-0   <none>           <none>
fake-pod-5fc54c9c96-gv22d   1/1     Running   0          29m   10.0.0.2    kwok-node-0   <none>           <none>
fake-pod-5fc54c9c96-jb7pm   1/1     Running   0          29m   10.0.0.10   kwok-node-0   <none>           <none>
fake-pod-5fc54c9c96-prrzn   1/1     Running   0          29m   10.0.0.3    kwok-node-0   <none>           <none>
fake-pod-5fc54c9c96-qpbsx   1/1     Running   0          29m   10.0.0.4    kwok-node-0   <none>           <none>
fake-pod-5fc54c9c96-sm7vr   1/1     Running   0          29m   10.0.0.5    kwok-node-0   <none>           <none>
fake-pod-5fc54c9c96-w4phl   1/1     Running   0          29m   10.0.0.9    kwok-node-0   <none>           <none>

Node同様にPodの実体は存在しないため、アクセスすることはできない。

# podにはアクセス不可
% kubectl exec -it  fake-pod-5fc54c9c96-5xvkc -- /bin/sh
Error from server: no preferred addresses found; known addresses: []
% kubectl logs fake-pod-5fc54c9c96-5xvkc               
Error from server: no preferred addresses found; known addresses: []

Podの追加

Podの実体が存在しないため、リソースを気にせず迅速に大量のPodをデプロイすることができる。
1Nodeあたり110Podまでしかデプロイできない制限はあるので注意

# podの数を1000に増やしてみる
% kubectl scale --replicas=1000 deploy fake-pod
deployment.apps/fake-pod scaled

# 1分足らずでデプロイが完了する
% k get po | grep fake-pod | grep Running | wc -l 
    1000

お片付け

kwokctl delete clusterで簡単にClusterを削除できる。

# cluster削除
% kwokctl delete cluster --name=kwok

ユースケース

  • Node数千台レベルのClusterでも簡単に構築できるため、大規模クラスターのテストに最適。
  • リソースを消費せず迅速に動作するため、中規模以下のクラスターでもCI/CDの自動テストに採用可能か

注意点

  • 実際にNodeやPodを作成する訳ではないので、できることの幅は狭い
    • 学習用であれば、多少リソースを消費するもののminikubekindなどを使う方が圧倒的に適している
  • 公式ブログにも記載されているが、あくまでkubeletのsimulatorであるため、同等の機能性や正確性を求めてはいけない

その他の機能や設定

  • kwokコマンドをlocal実行したりkwok-controllerを個別デプロイすることで、既存Clusterにも実装することができる。
  • configを弄ればkwok管理の範囲を調整したり、NodeのIPを設定可能。
  • SnapshotAuditingの機能もあるらしい

Discussion