K8s 三節點 + KubeVirt 常用指令

分類:commands

初始化 Cluster

安裝基礎套件(全部節點)

# 安裝 CRI-O(版本對應 K8s v1.31)
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings

KUBERNETES_VERSION=v1.31
curl -fsSL https://pkgs.k8s.io/addons:/cri-o:/stable:/${KUBERNETES_VERSION}/deb/Release.key | \
  sudo gpg --dearmor -o /etc/apt/keyrings/cri-o-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/cri-o-apt-keyring.gpg] \
  https://pkgs.k8s.io/addons:/cri-o:/stable:/${KUBERNETES_VERSION}/deb/ /" | \
  sudo tee /etc/apt/sources.list.d/cri-o.list
sudo apt-get update
sudo apt-get install -y cri-o
sudo systemctl start crio
sudo systemctl enable crio

# 安裝 kubeadm / kubelet / kubectl
sudo apt-get install -y apt-transport-https ca-certificates curl
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key \
  | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' \
  | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

Master: 初始化 Control Plane

# 初始化(替換 <MASTER_IP>,即 mansion_kubevirt_node_subnet 上的 10.10.10.11)
sudo kubeadm init \
  --pod-network-cidr=10.244.0.0/16 \
  --apiserver-advertise-address=<MASTER_IP>

# 設定 kubectl
mkdir -p $HOME/.kube
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 安裝 Cilium CNI
CILIUM_VER=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
curl -L --remote-name \
  https://github.com/cilium/cilium-cli/releases/download/${CILIUM_VER}/cilium-linux-amd64.tar.gz
sudo tar xzf cilium-linux-amd64.tar.gz -C /usr/local/bin
rm cilium-linux-amd64.tar.gz
cilium install --set ipam.mode=kubernetes
cilium status --wait

Infra & Worker: 加入 Cluster

# 使用 kubeadm init 輸出的 join 指令
sudo kubeadm join <MASTER_IP>:6443 \
  --token <TOKEN> \
  --discovery-token-ca-cert-hash sha256:<HASH>

# 若 token 已過期(24hr),重新產生
kubeadm token create --print-join-command

設定 Node 角色(Option A)

# Master: 維持 control-plane taint,不讓一般 workload 與 KubeVirt 管理面排入
# (kubeadm init 預設已加 control-plane taint,無需額外操作)

# Infra: 跑基礎設施 Pod 與 KubeVirt 管理面
kubectl label nodes infra node-role.kubernetes.io/infra=
kubectl label nodes infra kubevirt-management=true
kubectl taint nodes infra node-role.kubernetes.io/infra=:NoSchedule

# Worker: 跑 virt-handler + VM workload
kubectl label nodes worker node-role.kubernetes.io/worker=
kubectl label nodes worker kubevirt-workload=true

# 驗證節點狀態
kubectl get nodes -o wide
kubectl get nodes --show-labels

KubeVirt 管理面元件 — NodeSelector / Toleration(Option A)

安裝 KubeVirt 後,透過 KubeVirt CR 的 infra 欄位指定管理面元件位置

# kubevirt-cr-optiona.yaml
apiVersion: kubevirt.io/v1
kind: KubeVirt
metadata:
  name: kubevirt
  namespace: kubevirt
spec:
  # 讓 virt-operator / virt-api / virt-controller 排到 Infra
  infra:
    nodePlacement:
      nodeSelector:
        kubevirt-management: "true"
      tolerations:
      - key: node-role.kubernetes.io/infra
        operator: Exists
        effect: NoSchedule
  # 讓 virt-handler DaemonSet 只跑在 Worker
  workloads:
    nodePlacement:
      nodeSelector:
        kubevirt-workload: "true"
kubectl apply -f kubevirt-cr-optiona.yaml

# 確認管理面元件在 Infra
kubectl get pods -n kubevirt -o wide | grep -E 'virt-operator|virt-api|virt-controller'

# 確認 virt-handler 在 Worker
kubectl get pods -n kubevirt -o wide | grep virt-handler

安裝 KubeVirt

# 取得最新版本
export VERSION=$(curl -s https://api.github.com/repos/kubevirt/kubevirt/releases/latest \
  | grep tag_name | cut -d '"' -f4)
echo "Installing KubeVirt $VERSION"

# 安裝 Operator 和 CR
kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-operator.yaml
kubectl apply -f https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-cr.yaml

# 等待就緒
kubectl wait --for=condition=Available kubevirt/kubevirt \
  -n kubevirt --timeout=5m

# 驗證
kubectl get kubevirt -n kubevirt
kubectl get pods -n kubevirt

安裝 virtctl

export VERSION=$(kubectl get kubevirt -n kubevirt -o jsonpath='{.status.observedKubeVirtVersion}')
curl -Lo virtctl https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/virtctl-${VERSION}-linux-amd64
chmod +x virtctl
sudo mv virtctl /usr/local/bin/

建立 Ubuntu 24.04 VM

VirtualMachine YAML

apiVersion: kubevirt.io/v1
kind: VirtualMachine
metadata:
  name: ubuntu24
spec:
  running: true
  template:
    spec:
      domain:
        cpu:
          cores: 2
        memory:
          guest: 4Gi
        devices:
          disks:
          - name: containerdisk
            disk:
              bus: virtio
          - name: cloudinitdisk
            disk:
              bus: virtio
      volumes:
      - name: containerdisk
        containerDisk:
          image: quay.io/containerdisks/ubuntu:24.04
      - name: cloudinitdisk
        cloudInitNoCloud:
          userData: |
            #cloud-config
            password: ubuntu
            chpasswd: { expire: False }
            ssh_pwauth: True

套用與操作

# 建立 VM
kubectl apply -f ubuntu24-vm.yaml

# 查看 VM 狀態
kubectl get vm ubuntu24
kubectl get vmi ubuntu24

# 進入 VM console
virtctl console ubuntu24

# 開/關 VM
virtctl start ubuntu24
virtctl stop ubuntu24

# SSH(需先設定 Service 或 port-forward)
virtctl ssh ubuntu24

常用診斷指令

# 查看全部節點
kubectl get nodes -o wide

# 查看所有 namespace 的 Pod
kubectl get pods -A

# 查看 KubeVirt 狀態
kubectl get kubevirt -n kubevirt -o yaml

# 查看 VM 事件
kubectl describe vm ubuntu24
kubectl describe vmi ubuntu24

# 查看節點資源使用
kubectl top nodes

# 查看 etcd 健康(在 Master 執行)
kubectl exec -n kube-system etcd-master -- \
  etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  endpoint health

參考資料