Day 5: Kubernetes 基本架構及安裝
Day 6: 使用 kubectl 指令管理 Kubernetes 集群
Day 7: Kubernetes Pod 與 Deployment 深入解析
Day 8: Kubernetes Service 與負載均衡機制
Day 9: Kubernetes Persistent Volumes (PV) 與 Persistent Volume Claims (PVC)
Kubernetes 是一個開源的容器編排平台,旨在自動化應用程序的部署、擴展和管理。它最早由 Google 開發,後來捐贈給了 CNCF(Cloud Native Computing Foundation),現已成為容器化應用程序管理的業界標準。
Kubernetes 的基本架構由多個核心組件組成,每個組件都在系統中扮演著關鍵角色。
Master 節點
Master 節點是 Kubernetes 的控制平面,負責管理整個集群的狀態。它由以下幾個核心組件組成:
API Server:
Kubernetes 的前端,所有的操作請求都通過 API Server 來處理。它提供了 RESTful API,允許用戶、系統組件以及外部應用進行交互。
etcd:
分佈式鍵值存儲系統,用來保存整個集群的配置數據和狀態信息。所有的集群數據都存儲在 etcd 中,並且它保證數據的一致性。
Controller Manager:
負責管理集群中的各種控制器,這些控制器監控集群狀態並執行相應的操作來達到預期的狀態。例如,ReplicaSet Controller 確保某個應用有指定數量的 Pod 正在運行。
Scheduler:
負責將新創建的 Pod 安排到合適的工作節點(Node)上。Scheduler 根據資源使用情況、策略和約束條件來做出決策,將 Pod 分配給能夠滿足需求的節點。
Node 節點
Node 節點是 Kubernetes 集群中的工作節點,負責運行應用程序的 Pod。每個 Node 上都運行著以下組件:
Kubelet:
Node 上的主要代理程序,它負責監控 Pod 狀態並報告給 API Server,同時還會根據需要啟動和停止容器。
Container Runtime:
負責在 Node 上運行容器的軟體。常見的容器運行時包括 Docker、containerd 和 CRI-O。
Kube Proxy:
處理 Pod 網絡的負載均衡和網絡代理,確保集群中各個 Pod 之間以及 Pod 與外部之間的網絡通信。
Pod 和 Service
Pod:
Kubernetes 中最小的部署單位,一個 Pod 可以包含一個或多個容器,這些容器共享同一個網絡命名空間和存儲卷。
Service:
用於定義一組 Pod 的永久訪問策略,即使這些 Pod 隨時可能被創建或刪除。Service 提供一個穩定的網絡端點來訪問這些 Pod。
這些不用在當下馬上理解,等以後debug的時候就會理解了:)
cat << EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
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 modprobe overlay
sudo modprobe br_netfilter
sudo sysctl --system
sudo nano /etc/fstab
貼入以下內容
#將swap註解掉(如下)
# /swap.img none swap sw 0 0
並手動執行關閉
sudo swapoff -a
sudo apt install -y containerd
sudo mkdir -p /etc/containerd
sudo containerd config default|sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd
sudo apt-get install -y bridge-utils
sudo modprobe br_netfilter
echo "net.ipv4.ip_forward = 1"|sudo tee -a /etc/sysctl.conf
sudo sysctl -p
-(擇一)方案二:安裝cri-dockerd(範例是用這個)
#下載go和cri-dockerd
git clone https://github.com/Mirantis/cri-dockerd.git
cd cri-dockerd/
wget https://go.dev/dl/go1.21.3.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.21.3.linux-amd64.tar.gz
#指向環境變數
mkdir ~/.go
GOROOT=/usr/local/go
GOPATH=~/.go
PATH=$PATH:$GOROOT/bin:$GOPATH/bin
#檢查
go version
#編譯並安裝cri-dockerd
sudo apt install make
make cri-dockerd
#指向環境變數
mkdir -p /usr/local/bin
sudo install -o root -g root -m 0755 cri-dockerd /usr/local/bin/cri-dockerd
sudo install packaging/systemd/* /etc/systemd/system
sudo sed -i -e 's,/usr/bin/cri-dockerd,/usr/local/bin/cri-dockerd,' /etc/systemd/system/cri-docker.service
#重啟
sudo systemctl daemon-reload
sudo systemctl enable --now cri-docker.socket
#檢查是否active
systemctl status cri-docker.service
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo groupadd docker
sudo gpasswd -a $USER docker
sudo usermod -aG docker $USER
newgrp docker
#(擇一)方案一:直接安裝最新版
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
sudo apt-get update
sudo apt-get install -y kubectl kubelet kubeadm
#(擇一)方案二:安裝指定版本
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
sudo apt-get update
sudo apt install -y kubectl=1.26.3-00 kubelet=1.26.3-00 kubeadm=1.26.3-00
#(擇一)方案三:若上述操作提示PUBKEY失效
sudo mkdir -p /etc/apt/keyrings
echo "deb [signed-by=/etc/apt/keyrings/kubernetes.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes.gpg
sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
sudo apt-get update
sudo apt install -y kubectl=1.23.17-00 kubelet=1.23.17-00 kubeadm=1.23.17-00
sudo nano /etc/rc.local
貼入以下內容
#!/bin/sh -e
swapoff -a
export KUBECONFIG=$HOME/.kube/config
exit 0
加入執行權限
sudo chmod u+x /etc/rc.local
sudo apt-mark hold kubelet kubeadm kubectl
kubeadm config images list
sudo kubeadm config images pull
sudo kubeadm init --apiserver-advertise-address=<master ip> --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=Swap --cri-socket unix:///run/containerd/containerd.sock
-(擇一)cri-dockerd版本的初始化集群(只有master節點做)(範例是用這個)
只需修改master ip,不需要修改pod內網網段(除非必要)
sudo kubeadm init --kubernetes-version=v1.26.3 --apiserver-advertise-address=<master ip> --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=Swap --cri-socket unix:///var/run/cri-dockerd.sock
初始化完成之後螢幕上會打印join指令
到其他節點(node)上執行加入集群的指令
sudo kubeadm join <master ip>:6443 --token <剛才螢幕上給你的token> \
--discovery-token-ca-cert-hash sha256:<剛才螢幕上給你的cert> --cri-socket unix:///var/run/cri-dockerd.sock
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
mkdir -p $HOME/.kube
sudo scp /etc/kubernetes/admin.conf <user>@<節點ip>:~/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
kubectl get nodes
節點無法加入集群
請檢查conf文件是否有確實傳給node節點並且賦予權限
節點not ready
1.請檢查網路套件是否正常啟用
kubecte get pod --all-namespaces
2.請檢查初始化集群的init指令是否完整有帶上所有參數
#方案一:全部殺光(不建議)
sudo kubeadm reset --cri-socket unix:///var/run/cri-dockerd.sock
sudo apt-get purge kubeadm kubectl kubelet kubernetes-cni kube*
sudo apt-get autoremove
sudo rm -rf ~/.kube
#方案二:重新初始化集群(推薦)
#重置
sudo kubeadm reset --cri-socket unix:///var/run/cri-dockerd.sock
#刪除config
sudo rm $HOME/.kube/config
重建
sudo kubeadm init ... 參考上面步驟繼續往下做
小觀念:
集群間相認的是init時來自master節點產生的$HOME/.kube/config這個文件