Phần 2 — Cài đặt cluster: minikube, kind, kubeadm và kubectl
Ý kiến
0
Chưa có ý kiến nào. Hãy là người đầu tiên chia sẻ!
Chưa có ý kiến nào. Hãy là người đầu tiên chia sẻ!
Phần cuối series K8s: Cluster API (CAPI) quản lý cluster bằng K8s API, FinOps với OpenCost + Karpenter + right-sizing, AI/ML workloads (GPU, Kubeflow, KServe, vLLM, Argo Workflows, gang scheduling), Edge K8s và WebAssembly.
Multi-tenancy K8s (soft: namespace+RBAC+Quota, HNC, Capsule, vCluster; hard: cluster riêng) và multi-cluster: management cluster, GitOps ApplicationSet, Cluster API, Karmada, Crossplane, observability liên cluster.
Service Mesh chuyên sâu cho K8s: Istio (sidecar + ambient), Linkerd (proxy Rust nhẹ), Cilium Service Mesh (eBPF sidecarless) — mTLS, VirtualService, AuthorizationPolicy, canary, mirror, multi-cluster, đo overhead, khi không nên dùng mesh.
Series Kubernetes Toàn Tập — 13 phần:
Phần 2 — Cài đặt cluster: minikube, kind, kubeadm và kubectl ← bạn đang đọc
Để học K8s, bạn cần một cluster. Có ba hướng chính:
| Mục đích | Công cụ | Đặc điểm |
|---|---|---|
| Học local 1 máy | minikube, kind, k3d | Cài 1 phút, đủ để học hầu hết feature |
| Self-managed production / on-prem | kubeadm, k3s, RKE2, Talos | Bạn tự cài, tự upgrade, tự backup etcd |
| Managed cloud | EKS (AWS), GKE (GCP), AKS (Azure) | Cloud lo control plane, bạn lo workload |
Phần này tập trung minikube, kind và kubeadm — vì hai cái đầu thuận tiện cho mọi người tự tay làm trên máy mình, còn kubeadm là cách cài chuẩn upstream mà tài liệu chính thức khuyến nghị.
kubectl là CLI mọi K8s user cần. Khuyến nghị cài phiên bản chênh tối đa ±1 minor so với cluster (vd. cluster 1.30 thì kubectl 1.29/1.30/1.31 đều OK).
brew install kubectl
kubectl version --client
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/
kubectl version --client
# PowerShell (winget)
winget install -e --id Kubernetes.kubectl
# Hoặc chocolatey
choco install kubernetes-cli
# bash
echo 'source <(kubectl completion bash)' >> ~/.bashrc
echo 'alias k=kubectl' >> ~/.bashrc
echo 'complete -F __start_kubectl k' >> ~/.bashrc
# zsh
echo 'source <(kubectl completion zsh)' >> ~/.zshrc
echo 'alias k=kubectl' >> ~/.zshrc
minikube chạy một cluster K8s đơn-node (hoặc multi-node giả lập) trong VM hoặc container. Phù hợp khi bạn muốn trải nghiệm gần với production nhất (có dashboard, addon, LoadBalancer giả lập…).
# macOS
brew install minikube
# Linux (amd64)
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# Windows
winget install minikube
# Driver tốt nhất hiện nay: docker (cần Docker Desktop hoặc Docker Engine)
minikube start --driver=docker --cpus=4 --memory=8g --kubernetes-version=v1.31.0
# Multi-node giả lập
minikube start --nodes=3 --driver=docker
# Pin K8s version cụ thể
minikube start --kubernetes-version=v1.30.5
Sau khi start xong:
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# minikube Ready control-plane 60s v1.31.0
minikube status # Xem trạng thái cluster
minikube ssh # SSH vào node
minikube dashboard # Mở K8s dashboard
minikube addons list # Liệt kê addon (metrics-server, ingress, …)
minikube addons enable ingress
minikube addons enable metrics-server
minikube tunnel # Giả lập LoadBalancer (cần sudo)
minikube stop # Dừng cluster, giữ data
minikube delete # Xoá hẳn cluster
kind = Kubernetes IN Docker. Mỗi node là một Docker container, control plane và worker đều là container. Cực kỳ nhanh, thường được dùng cho CI và development.
# macOS
brew install kind
# Linux
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.24.0/kind-linux-amd64
chmod +x kind
sudo mv kind /usr/local/bin/
# Windows
choco install kind
kind create cluster --name dev
kubectl cluster-info --context kind-dev
Tạo file kind-config.yaml:
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 80
hostPort: 80
- containerPort: 443
hostPort: 443
- role: worker
- role: worker
kind create cluster --name multi --config kind-config.yaml
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# multi-control-plane Ready control-plane 2m v1.31.0
# multi-worker Ready <none> 2m v1.31.0
# multi-worker2 Ready <none> 2m v1.31.0
Vì các node là container, image bạn build trên máy chưa auto có trong cluster. Đây là gotcha lớn nhất với kind:
# Build image
docker build -t myapp:dev .
# Push vào tất cả node kind
kind load docker-image myapp:dev --name dev
kubeadm là công cụ chính thức của K8s để bootstrap cluster theo best practice. Nó không lo phần OS provisioning, không lo CNI, không lo monitoring — chỉ lo dựng cụm an toàn.
Linux (Ubuntu 22.04 / 24.04, Debian 12, RHEL/Rocky 9 đều ổn).
Mỗi node ≥ 2 CPU, ≥ 2GB RAM (control plane khuyến nghị 2 CPU + 4GB).
Đồng bộ thời gian (chrony hoặc systemd-timesyncd).
MAC/UUID khác nhau giữa các node.
Mạng phẳng, các node ping được nhau.
Disable swap hoặc cấu hình kubelet để chấp nhận swap (1.28+).
Mở các port theo tài liệu chính thức (xem mục 4.4).
Disable swap:
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab
Load module kernel và sysctl cho networking:
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
# Ubuntu / Debian
sudo apt-get update
sudo apt-get install -y containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# Bật SystemdCgroup
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd
sudo systemctl enable containerd
Lưu ý: cgroup driver phải khớp giữa kubelet và containerd. Cả hai phải là
systemdtrên hệ thống dùng systemd. Đây là lỗi install lần đầu hay gặp nhất.
# Ubuntu / Debian — repo chính thức (lưu ý URL theo version)
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
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 # pin version, không tự upgrade
| Node | Port | Mục đích |
|---|---|---|
| Control plane | 6443/tcp | kube-apiserver |
| Control plane | 2379-2380/tcp | etcd |
| Control plane | 10250/tcp | kubelet API |
| Control plane | 10257/tcp | kube-controller-manager |
| Control plane | 10259/tcp | kube-scheduler |
| Worker | 10250/tcp | kubelet API |
| Worker | 10256/tcp | kube-proxy |
| Worker | 30000-32767/tcp | NodePort Services |
sudo kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=<IP_PRIVATE_OF_CONTROL_PLANE>
Sau khi xong, kubeadm in ra:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 10.0.0.10:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:...
Lưu lại lệnh kubeadm join — bạn sẽ paste lên worker. Nếu lỡ quên, sinh lại:
kubeadm token create --print-join-command
Cluster vừa init chưa có Pod network, mọi pod sẽ ở trạng thái Pending. Bạn phải cài một CNI plugin. Phổ biến:
Cilium — eBPF-based, performance cao, có thể thay kube-proxy. Khuyến nghị cho production hiện đại.
Calico — production-tested, hỗ trợ NetworkPolicy tốt, dễ debug.
Flannel — đơn giản, nhẹ, không có NetworkPolicy (cần Calico-as-policy đi kèm).
Ví dụ với Cilium qua CLI:
# Cài cilium CLI
CILIUM_CLI_VERSION=$(curl -s https://raw.githubusercontent.com/cilium/cilium-cli/main/stable.txt)
curl -L --remote-name-all https://github.com/cilium/cilium-cli/releases/download/$CILIUM_CLI_VERSION/cilium-linux-amd64.tar.gz
sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
# Install Cilium vào cluster
cilium install --version 1.16.0
cilium status --wait
Trên mỗi worker đã chuẩn bị xong (containerd, kubeadm, kubelet):
sudo kubeadm join 10.0.0.10:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:...
Trên control plane:
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# cp-01 Ready control-plane 5m v1.31.0
# worker-1 Ready <none> 1m v1.31.0
# worker-2 Ready <none> 30s v1.31.0
Production thật cần ≥ 3 control plane node để etcd có quorum. Sơ đồ:
┌──────────────┐
│ LoadBalancer │ (HAProxy / kube-vip / cloud LB)
│ VIP :6443 │
└──────┬───────┘
│
┌──────────┼──────────┐
▼ ▼ ▼
┌─────┐ ┌─────┐ ┌─────┐
│ CP1 │ │ CP2 │ │ CP3 │
└─────┘ └─────┘ └─────┘
└──────────┴──────────┘
worker pool
Khởi đầu giống bình thường nhưng thêm --control-plane-endpoint:
sudo kubeadm init \
--control-plane-endpoint="k8s-api.example.com:6443" \
--upload-certs \
--pod-network-cidr=10.244.0.0/16
Join thêm control plane node:
sudo kubeadm join k8s-api.example.com:6443 \
--token ... \
--discovery-token-ca-cert-hash sha256:... \
--control-plane \
--certificate-key <KEY>
Mặc định kubectl đọc file ~/.kube/config. Nội dung gồm 3 phần:
apiVersion: v1
kind: Config
clusters: # các cluster có thể kết nối
- name: prod
cluster:
server: https://k8s-api.example.com:6443
certificate-authority-data: LS0tLS1CRUd...
users: # credentials
- name: alex
user:
client-certificate-data: LS0tLS1...
client-key-data: LS0tLS1...
contexts: # cluster + user + namespace = context
- name: prod-admin
context:
cluster: prod
user: alex
namespace: default
current-context: prod-admin
Các lệnh quan trọng:
kubectl config get-contexts # list contexts
kubectl config current-context # context hiện tại
kubectl config use-context prod-admin # đổi context
kubectl config set-context --current --namespace=team-a # đổi namespace default
# Merge nhiều file kubeconfig
KUBECONFIG=~/.kube/config:~/.kube/staging:~/.kube/prod kubectl get nodes
Hai công cụ rất hữu ích nên cài thêm:
kubectx — đổi context nhanh: kubectx prod
kubens — đổi namespace: kubens team-a
brew install kubectx
Sau khi cluster lên, chạy bộ kiểm tra cơ bản:
# Mọi node Ready?
kubectl get nodes -o wide
# Toàn bộ pod hệ thống Running?
kubectl get pods -n kube-system
# CoreDNS chạy ổn?
kubectl get pods -n kube-system -l k8s-app=kube-dns
# Tạo Deployment test
kubectl create deployment hello --image=nginx:1.27
kubectl expose deployment hello --port=80 --type=ClusterIP
kubectl get pods,svc -o wide
# Test DNS từ trong cluster
kubectl run -it --rm debug --image=busybox:1.36 --restart=Never -- nslookup hello
# Test connectivity
kubectl run -it --rm debug --image=curlimages/curl --restart=Never -- curl hello
# Dọn dẹp
kubectl delete svc hello
kubectl delete deploy hello
Không có metrics-server thì kubectl top và HPA không hoạt động.
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
Với cluster local hoặc kubeadm self-signed, thường phải patch thêm --kubelet-insecure-tls:
kubectl -n kube-system patch deployment metrics-server --type='json' \
-p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]'
kubectl top nodes
kubectl top pods -A
Ngoài kubeadm còn nhiều distribution gọn nhẹ, mỗi cái có thế mạnh riêng:
| Distro | Đặc điểm | Khi nên dùng |
|---|---|---|
| k3s | Single binary, gọn, SQLite mặc định | Edge, IoT, lab, ARM |
| RKE2 | k3s thân thiện FIPS, security default tốt | On-prem regulated |
| Talos Linux | OS read-only thuần K8s, không SSH | Immutable infrastructure |
| k0s | Mirantis, single binary giống k3s | On-prem nhỏ |
| kubespray | Ansible scripts dùng kubeadm | Tự động hoá cluster lớn on-prem |
Khi dùng EKS/GKE/AKS, bạn không phải cài control plane, chỉ cần lấy kubeconfig:
# EKS
aws eks update-kubeconfig --name my-cluster --region us-east-1
# GKE
gcloud container clusters get-credentials my-cluster --zone us-central1-a
# AKS
az aks get-credentials --resource-group my-rg --name my-cluster
Sau đó kubectl get nodes như bình thường.
kubelet không start. Thường do cgroup driver không khớp containerd. Check journalctl -u kubelet -f, đảm bảo cả hai dùng systemd.
CoreDNS pod ở trạng thái Pending. Bạn chưa cài CNI. Áp dụng Cilium/Calico/Flannel.
Pod ở trạng thái CrashLoopBackOff với CNI Cilium. Thường do kernel quá cũ, hoặc thiếu BPF filesystem. Yêu cầu kernel ≥ 5.4 cho hầu hết feature.
Worker join thất bại với x509: certificate has expired. Token mặc định chỉ sống 24h, sinh lại bằng kubeadm token create --print-join-command.
kubectl báo connection refused. Kiểm tra ~/.kube/config trỏ đúng cluster đang chạy, và port 6443 mở trên control plane.
Pod kẹt Pending với lý do 0/3 nodes are available: 3 node(s) had untolerated taint. Control plane mặc định có taint node-role.kubernetes.io/control-plane:NoSchedule. Cluster đa node thì không sao. Cluster 1 node muốn chạy workload trên control plane, gỡ taint:
kubectl taint nodes --all node-role.kubernetes.io/control-plane-
Học K8s: bắt đầu với minikube hoặc kind — 1 lệnh là có cluster.
Production self-managed: kubeadm + CNI (Cilium/Calico) + HA control plane qua LoadBalancer.
Production managed: EKS/GKE/AKS — đỡ vận hành control plane.
kubectl + kubeconfig là cách bạn nói chuyện với mọi cluster.
Sau khi cluster lên, cài metrics-server, set autocomplete, set alias k=kubectl.
Trong Phần 3, ta sẽ deploy workload thực sự đầu tiên: từ Pod, ReplicaSet đến Deployment, StatefulSet, DaemonSet, Job và CronJob.
← Phần 1 | Phần 3: Workloads — Pod, Deployment, StatefulSet… →