Day: March 18, 2024

  • [บันทึกกันลืม] K8S เอา node เดิม join กลับเข้ามาไม่ได้ เป็นปัญหาเพราะ CNI

    ปัญหา: ในบางกรณี เราต้อง delete node ออกไป แต่บางที join กลับได้ แต่ ไม่สามารถ allocate pod ไปได้

    sudo kubectl describe pod/thepod -n thenamespace

    แล้วพบว่า

    Error syncing pod, skipping: failed to "SetupNetwork" for "thepod" with SetupNetworkError: "Failed to setup network for pod \"...(...)\" using network plugins \"cni\": no IP addresses available in network: podnet; Skipping pod"

    ให้ทำดังต่อไปนี้ กับ nodeX ที่มีปัญหา (ดูจาก subnet ที่ปรากฏ) ด้วยคำสั่งต่อไปนี้

    เริ่มจากไปที่ control plane แล้ว delete nodeX ออกไป

    sudo kubectl delete node nodeX
    sudo kubeadm token create --print-join-command

    แล้ว copy คำสั่งที่ได้มา หน้าตาประมาณนี้

    kubeadm join ip.of.control.plane:6443 --token xxxxxxxxxx --discovery-token-ca-cert-hash sha256:yyyyyyyyyyyyyyyyyyyyyy

    จากนั้นไปที่ nodeX

    sudo systemctl stop containerd
    sudo systemctl stop kubelet
    sudo ip link set cni0 down
    sudo ip link set flannel.1 down
    sudo brctl delbr cni0
    rm -rf /run/flannel/subnet.env
    rm -rf /etc/kubernetes/kubelet.conf
    rm -rf /etc/kubernetes/pki/ca.crt
    sudo systemctl start containerd
    kubeadm join ip.of.control.plane:6443 --token xxxxxxxxxx --discovery-token-ca-cert-hash sha256:yyyyyyyyyyyyyyyyyyyyyy

    ก็จะใช้งานได้แล้ว

    Note: ถ้าพบปัญหา CNI อีก ให้ลองที่ node นั้น ด้วยคำสั่ง

     systemctl restart containerd 

    คาดหวังว่าจะได้ cni interface เกิดขึ้น จากการดูคำสั่ง

    ip addr | grep cni
  • [บันทึกกันลืม] ปัญหา Kubernetes มี Disk Pressure แล้วทำให้ pods อยู่ในสถานะ Evicted ค้างจำนวนมาก

    ปัญหา: เมื่อใช้คำสั่ง kubectl get pod -A แล้ว พบว่า มี pod แสดงสถานะ Evicted เป็นจำนวนมาก (จริง ๆ แล้วมีสถานะอื่นที่ไม่ใช่ Running จำนวนมาก)

    ตรวจสอบ: สันนิษฐานว่า Disk เต็ม ใช้คำสั่ง kubectl describe node | grep -i DiskPressure พบว่า KubeletHasDiskPressure แสดงว่า มีปัญหาอะไรสักอย่างกับ Storage และเมื่อดูด้วย kubectl logs -f pod/thepodname -n thenamespace พบว่า “attempting to reclaim ephemeral-storage”

    แนวทางการแก้ปัญหา: แต่ละ node ติดตั้งแบบแบ่ง Partition ให้ OS เป็น / (พื้นที่ 100 GB) และ พื้นที่ใช้งานจริง เป็น /data (2.5 TB) ตรวจสอบด้วยคำสั่ง df -h / พบว่า มีการใช้พื้นที่ เกิน 80%

    ปัญหานี้เคยเกิดขึ้นกับตอนใช้ Docker แก้ไขโดยการย้าย /var/lib/docker ไปไว้ที่ /data/docker ซึ่งมีพื้นที่มากกว่า แต่ในระบบ Kubernetes ใช้ containerd และ kubelet

    วิธีย้าย containerd ไปไว้ใน /data ตามลำดับ

    ที่ nodeX (ควรทำทีละ node)

    sudo mkdir /data/containerd
    sudo mkdir /data/containerd/var
    sudo mkdir /data/containerd/run
    sudo mkdir /data/kubelet

    กลับมาที่ control plane, ให้ทำการ drain ด้วยคำสั่ง ต่อไปนี้ แล้วรอจนเสร็จ

    sudo kubectl drain --delete-emptydir-data --ignore-daemonsets nodeX

    กลับมาที่ nodeX ทำการย้ายข้อมูลของ containerd และ kubelet มาไว้ที่ใหม่

    sudo systemctl stop containerd
    sudo systemctl stop kubelet
    sudo rsync -av /var/lib/containerd/ /data/containerd/var/
    sudo rsync -av /run/containerd/ /data/containerd/run/
    sudo rsync -av /var/lib/kubelet/ /data/kubelet/

    แก้ไข /etc/systemd/system/kubelet.service.d/10-kubeadm.conf เพิ่ม –root-dir=/data/kubelet

    # Note: This dropin only works with kubeadm and kubelet v1.11+
    [Service]
    Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --root-dir=/data/kubelet"
    Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
    # This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
    EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
    # This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
    # the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
    EnvironmentFile=-/etc/default/kubelet
    ExecStart=
    ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS

    สร้าง containerd configuration

    cd /etc/containerd/
    sudo containerd config default > /etc/containerd/config.toml

    แก้ไข containerd configuration ดังนี้

    root = "/data/containerd/var"
    state = "/data/containerd/run"

    จากนั้น start containerd และ kubelet กลับมา

    sudo systemctl start containerd
    sudo systemctl start kubelet

    กลับไปที่ control plane แล้วเอา nodeX กลับมาทำงานเหมือนเดิม

    sudo kubectl uncordon nodeX

    ตรวจสอบ nodeX ว่า DiskPressure มีสถานะเป็น KubeletHasNoDiskPressure หรือไม่ด้วยคำสั่ง

    sudo kubectl describe node nodeX

    ถ้าเรียบร้อยแล้ว กลับไปที่ nodeX เพื่อลบข้อมูลเก่า (เฉพาะ /var/lib/containerd/)

    sudo rm -rf /var/lib/containerd/*

    จากนั้นวนทำทีละ node จนครบ