k8s-kubeadm搭建k8s集群(1)(centos7)
直接進入主題,采用kubeadm方式構建集群,一個master,2個node,1個鏡像倉庫,準備4臺機器,我用的虛擬機裝的centos7,2C2G。網絡配置好,保證虛擬機能訪問外網,虛擬機和宿主能互相訪問。
VMware安裝虛擬機及網絡配置
一、機器前置處理
配置一下幾臺機器的相關信息
我機器ip是192.168.255.101/104,計劃是101作為master,102,103 作為node,104作為私有鏡像倉庫
1. 主機名設置 方便互相訪問:
vim /etc/hosts 添加以下內容:所有機器192.168.255.101 k8s-master.taoyao.com k8s-master 192.168.255.102 k8s-node1.taoyao.com k8s-node1 192.168.255.103 k8s-node2.taoyao.com k8s-node2 192.168.255.104 k8s-harbor.taoyao.com k8s-harbor
2. 配置互相ssh免密
在101上操作 ssh-keygen -t rsa 生成密鑰對
執行腳本復制到其他機器:
for i in 102 103 104 do ssh-copy-id root@192.168.255.$i done
3. 設置對應機器的主機名和上面hosts文件中內容對應
hostnamectl set-hostname k8s-master hostnamectl set-hostname k8s-node1 hostnamectl set-hostname k8s-node2 hostnamectl set-hostname k8s-harbor
4. 機器參數調整(所有機器)
這里推薦使用mobaxterm,相比xshell這些,他可以批量操作,同時在多臺機器執行輸入相同的命令


4.1 禁用交換分區
vim /etc/selinux/config
將 SELINUX=enforcing 改為 SELINUX=disabled
reboot 重啟

臨時禁用: swapoff -a
永久禁用:sed -i 's/.*swap.*/#&/' /etc/fstab
4.2 k8s相關的內核參數調整:
cat >> /etc/sysctl.d/k8s.conf << EOF vm.swappiness=0 EOF
4.3 網絡參數調整
依次執行
modprobe br_netfilter
modprobe overlay
cat >> /etc/sysctl.d/k8s.conf << EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 net.ipv4.ip_forward = 1 EOF
sysctl -p /etc/sysctl.d/k8s.conf 二、安裝容器引擎----docker相關
1.docker安裝(所有機器)
CentOS 7 已于 2024 年 6 月 30 日停止維護(EOL - End of Life),官方鏡像站 mirrorlist.centos.org 已經下線,導致 yum 無法獲取軟件包列表,所以這里我們換成阿里的yum
# 1. 備份原配置 sudo cp -r /etc/yum.repos.d /etc/yum.repos.d.backup # 2. 下載阿里云鏡像配置 sudo wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo # 3. 清理緩存并測試 sudo yum clean all sudo yum makecache
使用阿里云yum鏡像:https://developer.aliyun.com/mirror/docker-ce
按上面地址的指引操作即可,默認下載的時最新的,或者選擇指定的版本安裝:
我選擇安裝的24.0.4-1.el7
# step 1: 安裝必要的一些系統工具 yum install -y yum-utils # Step 2: 添加軟件源信息 yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #查看docker 版本 yum list docker-ce --showduplicates | sort -r # Step 3: 安裝Docker 24.0.4-1.el7 yum install -y docker-ce-24.0.4-1.el7 #設置開啟自啟動 systemctl enable docker # 開啟Docker服務 service docker start
2. docker相關配置修改
(1)cgroup改為systemd (參考:https://kubernetes.io/zh-cn/docs/setup/production-environment/container-runtimes/)
(2)鏡像倉庫修改(國內的更快)
(3)使用私有鏡像倉庫(104這臺機器)

除了倉庫節點其他都執行以下腳本(101,102,103)機器執行:
cat >> /etc/docker/daemon.json <<-EOF { "registry-mirrors":[ "https://docker.211678.top", "https://docker.1panel.live", "https://hub.rat.dev", "https://docker.m.daocloud.io", "https://do.nark.eu.org", "https://dockerpull.com", "https://dockerproxy.cn", "https://docker.awsl9527.cn" ], "insecure-registries":["k8s-harbor.taoyao.com"],#和上面主機名的倉庫機器對應 "exec-opts":["native.cgroupdriver=systemd"] } EOF
# 重新加載 systemd 配置
systemctl daemon-reload
# 重啟 Docker
systemctl restart docker
docker info 查看配置是否修改成功

3. cri環境 搭建
CRI(Container Runtime Interface)是Kubernetes定義的與容器運行時交互的標準接口,而Docker是一種流行的容器管理工具。兩者在容器生態中的關系如下:
CRI與Docker的協作機制
- ?CRI的作用?:CRI允許Kubernetes通過標準化接口與不同的容器運行時(如containerd、CRI-O)交互,實現容器的生命周期管理12。
- ?Docker的適配?:Docker本身不直接實現CRI,但可通過
cri-dockerd(原Dockershim的替代方案)作為適配層,將Docker的API轉換為CRI兼容的接口,從而支持Kubernetes調度。
技術演進與現狀
- ?歷史依賴?:早期Kubernetes依賴Docker作為默認運行時,但Docker的封閉生態與Kubernetes的開源理念沖突,促使Kubernetes推出CRI標準以解耦依賴
下載cri-dockerd (除倉庫機器,都需要)
mkdir /data/softs
cd /data/softs 我是下載到這個目錄
wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.2/cri-dockerd-0.3.2.amd64.tgz
可能需要梯子,如果無法直接下載就單獨下載了上傳到上去,先傳了一臺然后復制到其他去,或者分別上傳
之前就做了免密直接復制到另外兩臺去
for i in 102 103; do scp cri-dockerd-0.3.2.amd64.tgz root@192.168.255.$i:/data/softs/; done
解壓軟件 tar xf cri-dockerd-0.3.2.amd64.tgz
mv cri-dockerd/cri-dockerd /usr/local/bin/
檢查效果 cri-dockerd --version
將 cri-dockerd 通過配置文件制作成服務方面開機啟動:
cat > /etc/systemd/system/cri-dockerd.service<<-EOF [Unit] Description=CRI Interface for Docker Application Container Engine Documentation=https://docs.mirantis.com After=network-online.target firewalld.service docker.service Wants=network-online.target [Service] Type=notify ExecStart=/usr/local/bin/cri-dockerd --pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.9 --network-plugin=cni --cni-conf-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin --container-runtime-endpoint=unix:///var/run/cri-dockerd.sock --cri-dockerd-root-directory=/var/lib/dockershim --docker-endpoint=unix:///var/run/docker.sock --cri-dockerd-root-directory=/var/lib/docker ExecReload=/bin/kill -s HUP $MAINPID TimeoutSec=0 RestartSec=2 Restart=always StartLimitBurst=3 StartLimitInterval=60s LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity TasksMax=infinity Delegate=yes KillMode=process [Install] WantedBy=multi-user.target EOF
cat >/etc/systemd/system/cri-dockerd.socket <<-EOF [Unit] Description=CRI Docker Socket for the API Partof=cri-docker.service [socket] Listenstream=/var/run/cri-dockerd.sock SocketMode=0660 Socketuser=root SocketGroup-docker [Install] wantedBy-sockets.target EOF
設置服務并機自啟動
systemctl daemon-reload
systemctl enable cri-dockerd.service
systemctl restart cri-dockerd.service
狀態查看: systemctl status cri-dockerd
systemctl is-active cri-dockerd
4. harbor倉庫配置(104 倉庫機器操作)
虛擬機網絡不行可以使用宿主機下載相應的版本后上傳到虛擬機再操作,可能需要用梯子
tar xf harbor-offline-installer-v2.14.0.tgz
解壓進入harbor目錄 加載harbor中的本地鏡像
docker load < harbor.v2.14.0.tar.gz
修改harbor中的配置文件模板:

基于模版復制一份正式出來修改:
cp harbor.yml.tmpl harbor.yml
vim harbor.yml
hostname修改前面設置harbor機器的域名
https的配置去掉
admin密碼修改

執行 ./prepare 腳本 生成相應docker-compose.yml內容
執行 ./install 啟動harbor腳本,會使用prepare之后生成的docker-compose.yml文件啟動

docker compose ps 命令用于列出當前目錄下由 docker-compose.yml 文件定義的所有容器的運行狀態

將harbor配置成服務,并設置開機自啟動:
cat > /etc/systemd/system/harbor.service<<-EOF [Unit] Description=Harbor After=docker.service systemd-networkd.service systemd-resolved.service Requires=docker.service Documentation=http://github.com/viware/harbor [Service] Type=simple Restart=on-failure RestartSec=5 ExecStart=/usr/bin/docker compose --file /data/softs/harbor/docker-compose.yml up ExecStop=/usr/bin/docker compose --file /data/softs/harbor/docker-compose.yml down [Install] WantedBy=multi-user.target EOF
ExecStart=/usr/bin/docker compose --file /data/softs/harbor/docker-compose.yml up ExecStop=/usr/bin/docker compose --file /data/softs/harbor/docker-compose.yml down
這兩個要注意和自己的安裝目錄對應上
systemctl daemon-reload 重新加載
systemctl start harbor 重啟
systemctl status harbor 狀態查看
systemctl enable harbor 開機自啟動
訪問104機器的IP 使用admin登錄harbor,然后創建一個個人賬戶,再登錄個人賬戶,創建一個公共項目用于存放我們自己鏡像

向harbor倉庫提交鏡像:
1.鏡像打標簽
必須攜帶harbor主機地址:
docker tag 鏡像 新鏡像標簽名(主機名/項目/鏡像名:版本)
2.登錄harbor
docker login harbor倉庫
3.提交鏡像
docker push 具體鏡像標簽
切換到101(192.168.255.101)機器上面嘗試操作 打一個鏡像并推送到104(192.168.255.104)機器harbor倉庫:
我們拉取一個nginx:docker pull nginx:1.29.1 (拉取速度會很慢)
將拉取的nginx鏡像打成自己的鏡像:
docker tag 鏡像 新鏡像標簽名(主機名/項目/鏡像名:版本)
docker tag nginx:1.29.1 k8s-harbor.taoyao.com/nijunyang/my-nginx:1.29.1

docker login k8s-harbor.taoyao.com 登錄harbor倉庫 輸入前面創建的個人賬號信息
推送鏡像: docker push k8s-harbor.taoyao.com/nijunyang/my-nginx:1.29.1
推送成功之后倉庫里面就已經可以看到這個鏡像了
可以去102(192.168.255.102)機器拉取這個鏡像:
docker pull k8s-harbor.taoyao.com/nijunyang/my-nginx:1.29.1 三、k8s集群搭建(101,102,103 機器操作)
使用kubeadm 方式搭建集群
步驟:軟件源定制——>安裝軟件——>鏡像獲取——>主節點初始化——>工作節點加入集群
cat <<EOF | tee /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/rpm/ enabled=1 gpgcheck=1 gpgkey=https://mirrors.aliyun.com/kubernetes-new/core/stable/v1.28/rpm/repodata/repomd.xml.key exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni EOF
yum makecache fast 刷新yum源
安裝軟件:
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes 我用的生產的那種 禁用了更新的(exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni) 所以使用這條命令,注意上面有兩個使用對應的即可
systemctl enable kubelet && systemctl start kubelet
kubeadm:集群管理使用
kubelet:采集節點數據匯報給master
kubectl:管理集群資源對象
kubeadm version 查看k8s 版本
kubeadm config images list 查看所需的鏡像版本
registry.k8s.io/kube-apiserver:v1.28.15
registry.k8s.io/kube-controller-manager:v1.28.15
registry.k8s.io/kube-scheduler:v1.28.15
registry.k8s.io/kube-proxy:v1.28.15
registry.k8s.io/pause:3.9
registry.k8s.io/etcd:3.5.15-0
registry.k8s.io/coredns/coredns:v1.10.1
registry.k8s.io google的地址國內可能無法訪問
可以使用阿里云的:路徑如下:
registry.aliyuncs.com/google_containers/kube-apiserver:v1.28.15
registry.aliyuncs.com/google_containers/kube-controller-manager:v1.28.15
registry.aliyuncs.com/google_containers/kube-scheduler:v1.28.15
registry.aliyuncs.com/google_containers/kube-proxy:v1.28.15
registry.aliyuncs.com/google_containers/pause:3.9
registry.aliyuncs.com/google_containers/etcd:3.5.15-0
registry.aliyuncs.com/google_containers/coredns/coredns:v1.10.1
拉取以上鏡像推送到自己的harbor倉庫:
去harbor創建google_containers 項目
k8s-harbor.taoyao.com/google_containers/xxxx
登錄harbor: docker login k8s-harbor.taoyao.com
執行以下腳本: 拉取鏡像,打標簽,推送到私有倉庫,以免后面集群節點創建時因為網絡問題無法獲取到鏡像
注意鏡像版本得和kubeadm config images list 里面顯示的一致
images=('kube-apiserver:v1.28.15' 'kube-controller-manager:v1.28.15' 'kube-scheduler:v1.28.15' 'kube-proxy:v1.28.15' 'pause:3.9' 'etcd:3.5.15-0' 'coredns/coredns:v1.10.1') for i in "${images[@]}"; do docker pull registry.aliyuncs.com/google_containers/$i docker tag registry.aliyuncs.com/google_containers/$i k8s-harbor.taoyao.com/google_containers/$i docker push k8s-harbor.taoyao.com/google_containers/$i docker rmi registry.aliyuncs.com/google_containers/$i done
阿里云的倉庫中沒有 registry.aliyuncs.com/google_containers/coredns/coredns:v1.10.1 。。。。。尷尬
直接去docker的倉庫拉了做成自己的:
docker pull coredns/coredns:1.10.1 docker tag coredns/coredns:1.10.1 k8s-harbor.taoyao.com/google_containers/coredns:v1.10.1 docker push k8s-harbor.taoyao.com/google_containers/coredns:v1.10.1 docker rmi coredns/coredns:1.10.1
鏡像準備完畢就可以進行master節點初始化了
101(192.168.255.101) master機器執行初始化
--kubernetes-version 指定版本
--apiserver-advertise-address master節點ip
--image-repository 鏡像倉庫 使用我自己harbor倉庫上面準備的鏡像
--pod-network-cidr pod 網段 可以自己設置
--service-cidr service 網段 可以自己設置 default "10.96.0.0/12"
--ignore-preflight-errors 忽略某些錯誤
--cri-socket cri-socket 我們用docker引擎,配置docker對應的

kubeadm init --kubernetes-version=1.28.15 --apiserver-advertise-address=192.168.255.101 --image-repository=k8s-harbor.taoyao.com/google_containers --pod-network-cidr="10.244.0.0/16" --service-cidr="10.96.0.0/12" --ignore-preflight-errors=Swap --cri-socket=unix:///var/run/cri-dockerd.sock

圈起來的內容 后面都要用到,尤其是最后帶hash的,不要著急清理頁面,最后先復制下來
我們先讓node 加入集群,把最后一個復制下來
去102,103 node節點上面執行,加入集群, 加一下 --cri-socket參數:
kubeadm join 192.168.255.101:6443 --token w1oman.yjkcx7ay5adz6vop \ --discovery-token-ca-cert-hash sha256:db24e4cf5576d752f34a011f522907a4a827c5272604125d303ac98f3efb0b54 --cri-socket=unix:///var/run/cri-dockerd.sock

再看master初始化之后有兩段操作:
非root用戶部署按一個操作,root用戶部署按第二個 我是用root操作的:

就用的 export KUBECONFIG=/etc/kubernetes/admin.conf
現在可以使用: kubectl get nodes 查看node信息了,如果不行的話就把上面兩個操作都執行了吧

配置 kubeadm kubectl 配置命令使用tab鍵自動補齊
加入以下內容:
source <(kubeadm completion bash)
source <(kubectl completion bash)
刷新配置: source ~/.bashrc
集群網絡配置:
現在節點所有節點的狀態都是 NotReady的
還是上面那個master初始化結果頁面中的網絡操作

打開它給的鏈接:https://kubernetes.io/docs/concepts/cluster-administration/addons/ 里面多種網絡解決方案,選擇合適的操作。


問了下AI,那我就用的Flannel 操作起來比較簡單,跟著網址里面的指引走。


考慮到網絡問題,我還是直接把 https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml 到本地,然后把里面的鏡像,通過宿主機下載好,做成自己的 私有鏡像推到harbor倉庫,再執行。如果網絡沒問題那就直接執行 這個就行了 kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
grep image: kube-flannel.yml 可以看到這個文件里面有兩個鏡像,我們把這兩個鏡像下載下來,做成自己的之后推送到自己的harbor倉庫,修改這個文件中的鏡像為我們自己的私有鏡像:

注意版本和自己kube-flannel.yml 里面的對應
docker pull ghcr.io/flannel-io/flannel:v0.27.4 docker tag ghcr.io/flannel-io/flannel:v0.27.4 k8s-harbor.taoyao.com/nijunyang/flannel:v0.27.4 docker push k8s-harbor.taoyao.com/nijunyang/flannel:v0.27.4 docker pull ghcr.io/flannel-io/flannel-cni-plugin:v1.8.0-flannel1 docker tag ghcr.io/flannel-io/flannel-cni-plugin:v1.8.0-flannel1 k8s-harbor.taoyao.com/nijunyang/flannel-cni-plugin:v1.8.0-flannel1 docker push k8s-harbor.taoyao.com/nijunyang/flannel-cni-plugin:v1.8.0-flannel1
修改kube-flannel.yml文件里面的 鏡像為自己harbor倉庫的鏡像:

kubectl apply -f kube-flannel.yml 運行把資源部署起來

所以節點的狀態都是ready了
至此k8s集群基本搭建完畢。
kubectl docker cri-dockered 必須設置為開機自啟動,否則重啟機器會導致服務有問題。
kubectl docker cri-dockered 必須設置為開機自啟動,否則重啟機器會導致服務有問題。
kubectl docker cri-dockered 必須設置為開機自啟動,否則重啟機器會導致服務有問題。
kubeadm方式部署集群其實是將各個組件以pod的形式部署在k8s中:
kubectl get pods -A 查看所有pods

四、k8s組件介紹

控制平面組件(Control Plane)
控制平面負責管理整個集群,通常部署在 Master 節點。
kube-apiserver(API 服務器)
- 功能:集群的“前端”,所有組件都通過它通信
- 作用:
- 暴露 REST API(
kubectl、UI、其他組件) - 認證、授權、準入控制
- 集群狀態的唯一入口
- 暴露 REST API(
- 特點:無狀態,可水平擴展(通過負載均衡)
etcd(分布式鍵值存儲)
- 功能:存儲集群所有狀態數據(Pod、Service、ConfigMap 等)
- 特點:
- 強一致性(Raft 算法)
- 高可用(3/5/7 節點集群)
- 唯一真相來源
- 重要:必須定期備份!
kube-scheduler(調度器)
- 功能:決定 Pod 在哪個節點上運行
- 調度策略:
- 資源需求(CPU、內存)
- 親和性/反親和性
- 污點/容忍(Taints/Tolerations)
- 節點選擇器(NodeSelector)
- 特點:可插拔調度器框架
kube-controller-manager(控制器管理器)
- 功能:運行各種控制器,維護集群期望狀態
- 內置控制器:
- Node Controller:節點故障檢測
- Replication Controller:Pod 副本管理
- Deployment Controller:滾動更新
- DaemonSet Controller:守護進程集
- StatefulSet Controller:有狀態應用
- Service Controller:負載均衡、路由
- 特點:可水平擴展,高可用
節點組件(Node Components)
節點組件運行在每個 Worker 節點上,管理 Pod。
kubelet
- 功能:節點上的“代理”,管理 Pod 和容器
- 職責:
- 從 apiserver 獲取 Pod 配置
- 啟動/停止/監控容器
- 向 apiserver 上報節點狀態
- 執行健康檢查(Liveness/Readiness)
- 特點:每個節點必須運行一個
kube-proxy(服務代理)
- 功能:實現 Service 的網絡代理和負載均衡
- 工作模式:
- iptables:通過 iptables 規則轉發
- ipvs:性能更好,基于 LVS
- userspace:舊模式,已廢棄
- 作用:實現 Service 的 ClusterIP、NodePort 等
Container Runtime(容器運行時)
- 功能:實際運行容器的軟件
- 支持的運行時:
- Docker(通過 cri-docker-shim,已棄用)
- containerd(推薦)
- CRI-O(Red Hat 開發)
- gVisor(安全沙箱)
- 要求:必須符合 CRI(Container Runtime Interface)
可選組件(Addons)
DNS(CoreDNS)
- 功能:為 Service 提供域名解析
- 作用:
my-service.namespace.svc.cluster.local
Web UI(Dashboard)
- 功能:圖形化管理界面
Container Resource Monitoring(Prometheus + Grafana)
- 功能:監控容器和節點資源使用
Cluster-level Logging(EFK/Elasticsearch-Fluentd-Kibana)
- 功能:集中日志收集和分析
組件交互流程(以創建 Pod 為例)



浙公網安備 33010602011771號