kubeadm部署K8S集群
- 2021 年 1 月 18 日
- 筆記
- Docker/Kubernetes, Linux運維
1. Kubernetes概述
1.1 Kubernetes是什麼
- Kubernetes是Google在2014年開源的一個容器集群管理系統,Kubernetes簡稱K8S。
- K8S用於容器化應用程式的部署,擴展和管理。
- K8S提供了容器編排,資源調度,彈性伸縮,部署管理,服務發現等一系列功能。
- Kubernetes目標是讓部署容器化應用簡單高效。
1.2 Kubernetes的特性
1)自我修復
- 在節點故障時重新啟動失敗的容器,替換和重新部署,保證預期的副本數量;
- 殺死健康檢查失敗的容器,並且在未準備好之前不會處理客戶端請求,確保線上服務不中斷;
2)彈性伸縮
- 使用命令、UI或者基於CPU使用情況自動快速擴容和縮容應用程式實例,保證應用業務高峰並發時的高可用性;
- 業務低峰時回收資源,以最小成本運行服務
3)自動部署和回滾
- Kubernetes採用滾動跟新策略更新應用,一次更新一個Pod,而不是同時刪除所有的Pod,如果更新過程中出現問題,將回滾更改,確保升級不影響業務。
4)服務發現和負載均衡
- K8S為多個容器提供一個統一訪問入口(內部IP地址和一個DNS名稱),並且負載均衡關聯的所有容器,使得用戶無需考慮容器IP問題。
5)機密和配置管理
- 管理機密數據和應用程式配置,而不需要把敏感數據暴露在鏡像里,提高敏感數據安全性。並可以將一些常用的配置存儲在K8S中,方便應用程式使用。
6)存儲編排
- 掛載外部存儲系統,無論是來自本地存儲,公有雲(AWS),還是網路存儲(NFS、GlusterFS、Ceph)都作為集群資源的一部分使用,極大提高存儲使用靈活性
7)批處理
- 提供一次性服務,定時任務;滿足批量數據處理和分析的場景
1.3 Kubernetes集群架構組件
1)Master組件
- kube-apiserver
- (Kubernetes API)集群的統一入口,各組件協調者,以RESTful API提供介面服務,所有對象資源的增刪改查和監聽操作都交給APIServer處理後再提交給Etcd存儲。
- kube-controller-manager
- 處理集群中常規後台任務,一個資源對應一個控制器,而ControllerManager就是負責管理這些控制器的
- kube-schedule
- 根據調度演算法為新創建的Pod選擇一個Node節點,可以任意部署,可以部署在同一個節點上,也可以部署在不同的節點上
- etcd
- 分散式鍵值存儲系統。用於保存集群狀態數據,比如Pod、Service等對象資訊。
2)Node組件
- kubelet
- kubelet是Master在Node節點上的Agent,管理本機運行容器的生命周期,比如創建容器、Pod掛載數據卷、下載secret、獲取容器和節點狀態等工作。kubelet將每個Pod轉換成一組容器
- kube-proxy
- 在Node節點上實現Pod網路代理,維護網路規則和四層負載均衡工作。
- docker 或 rocket
- 容器引擎,運行容器
1.4 Kubernetes核心概念
1)Pod
- 最小部署單元
- 一組容器的集合
- 一個Pod中的容器共享網路命名空間
- Pod是短暫的
2)Controller
- ReplicaSet:確保預期的Pod副本數量
- Deployment:無狀態應用部署
- StatefulSet:有狀態應用部署
- DaemonSet:確保所有Node運行同一個Pod
- Job:一次性任務
- Cronjob:定時任務
3)更高級層次對象,部署和管理Pod
- Service:
- 防止Pod失聯;定義一次Pod的訪問策略
- Service抽象層不過是iptables或者ipvs中的規則而已
- Label:標籤,附加到某個資源上,用於關聯對象、查詢和篩選
- Namespaces:命名空間,將對象邏輯上隔離
- Annotations:注釋
4)網路解決方案
- K8S通過CNI插件體系來接入外部網路服務解決方案
- 常見的有:
- flannel:網路配置相關
- calico:網路配置、網路策略
- canel:flannel的網路配置 + calico的網路策略
5)三種網路
- Pod網路:Pod的地址是配置在Pod內部的網路名稱空間上的,是能ping通的,就像正常主機上的地址一樣
- Service網路(集群網路):Service的地址是虛擬的,它只存在於iptables或者ipvs的規則之中
- 節點網路:各個節點也應該有一個網路
各個Pod運行在同一個網路中,而service是另外一個網路;Pod和service的地址是不同網段的。
接入外部訪問時,先接入節點網路,然後由節點網路代理至集群網路,再由集群網路代理至Pod網路。
同一Pod內的多個容器之間通過 lo 介面進行通訊。
兩個Pod之間可以直接進行通訊:通過隧道的方式(Overlay疊加網路)來轉發二層報文,使得它們雖然擴主機但是好像工作在同一個二層網路中。訪問對方Pod所在節點的位置,然後再代理到Pod內部的容器上。
2. 使用kubeadm部署K8S集群
2.1 Kubernetes的三種部署方式
1)minikube
- Minikube是一個工具,可以在本地快速運行一個單點的Kubernetes,僅用於嘗試Kubernetes或日常開發的用戶使用。
- 部署地址://kubernetes.io/docs/setup/minikube/
2)kubeadm
- Kubeadm是一個工具,提供kubeadm init 和 kubeadm join,用於快速部署Kubernetes集群。
- 部署地址://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/
3)二進位包
- 從官方下載發行版的二進位包,手動部署每個組件,組成Kubernetes集群。
- 下載地址://github.com/kubernetes/kubernetes/releases
2.2 K8S集群的部署規劃
1)環境需求
- 系統:CentOS7.4
- 記憶體 > 1.7G
- CPU > 2核
2)角色規劃
3)網路模型
- 節點網路:172.18.0.0/16
- Pod網路:10.244.0.0/16
- Service網路:10.96.0.0/12
2.3 環境初始化
- 在所有節點上都執行
1)關閉防火牆、SELinux
# 關閉防火牆並設置開機禁止啟動 systemctl stop firewalld && systemctl disable firewalld # 關閉SELinux sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config && setenforce 0
2)關閉swap分區
# 臨時關閉所有swap swapoff -a # 在/etc/fstab中機制掛載swap sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
3)設置主機名並配置hosts
# 為各個主機配置主機名 hostnamectl set-hostname k8s-master01 hostnamectl set-hostname k8s-node01 hostnamectl set-hostname k8s-node02 # 配置好主機名後將以下內容寫入到所有節點的 /etc/hosts 文件中 172.18.0.67 k8s-master01 172.18.0.68 k8s-node01 172.18.0.69 k8s-node02
4)內核調整
- 將橋接的 IPv4 的流量傳遞到 iptables的鏈
# 設置 net.bridge.bridge-nf-call-ip6tables = 1 # 設置 net.bridge.bridge-nf-call-iptables = 1 cat > /etc/sysctl.d/k8s.conf << EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF sysctl --system # Load settings from all system configuration files
5)為各個主機做時間同步
- 啟動chrony服務同步時間即可
2.4 開始安裝
- 在所有節點上執行
1)配置安裝源
- 配置docker-ce的源
cd /etc/yum.repos.d/ && wget -c //mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo # 注意要修改下載下來的這個repo文件中的地址,將其指向為清華的源的地址
- 配置Kubernetes的源
cat > /etc/yum.repos.d/kubernetes.repo << EOF [kubernetes] name=Kubernetes baseurl=//mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=0 repo_gpgcheck=0 gpgkey=//mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg //mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF
2)安裝docker-ce
yum install -y docker-ce systemctl start docker && systemctl enable docker docker info # 安裝完成之後注意要為docker配置好鏡像加速
3)安裝kubeadm、kubelet 和 kubectl
yum install kubelet kubeadm kubectl -y # 注意,要讓kubelet開機自啟,現在還不能去手動啟動它 systemctl enable kubelet
4)為kubelet配置額外參數
# 可以在 /etc/sysconfig/kubelet 這個文件中添加額外的參數 # 如關閉swap功能 KUBELET_EXTRA_ARGS="--fail-swap-on=false"
2.5 部署 K8S Master
- 只需要在 k8s-master節點上執行
1)初始化master
kubeadm init \ --kubernetes-version v1.20.2 \ --pod-network-cidr=10.244.0.0/16 \ --service-cidr=10.96.0.0/12 \ --apiserver-advertise-address=172.18.0.67 \ --ignore-preflight-errors=Swap \ --image-repository registry.aliyuncs.com/google_containers # apiserver要修改成自己的master節點的地址,默認apiserver監聽在所有地址的6443埠上 # 如果swap報錯,可以加上選項--ignore-preflight-errors=Swap,但是注意那個Swap的S要大寫 # 由於默認拉取鏡像地址k8s.gcr.io中國無法訪問,這裡指定阿里雲鏡像倉庫地址
# 注意kubernetes的版本要和之前安裝的kubelet的版本一致
2)根據回顯提示操作
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config
3)測試
# 獲取組件狀態資訊 kubectl get cs # cs是kubectl get componentstatus的簡寫,獲取組件狀態資訊 # 查看k8s集群的節點資訊 kubectl get nodes
4)token失效解決
因為默認 token 的有效期為24小時,過期之後該token就不可用了,所以如果後續有node節點加入,可以重新生成新的token
- 重新生成新的token
[root@master01 ~]# kubeadm token create salxe7.gnlwtozqxxsf4uu7 [root@master01 ~]# kubeadm token list TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS he4ugm.z537h1g7taugguco 23h 2021-01-19T15:53:34+08:00 authentication,signing <none> system:bootstrappers:kubeadm:default-node-token salxe7.gnlwtozqxxsf4uu7 23h 2021-01-19T15:53:48+08:00 authentication,signing <none> system:bootstrappers:kubeadm:default-node-token t4xdcj.5vgr19ymj4g6y7hm 6h 2021-01-18T22:31:08+08:00 authentication,signing <none> system:bootstrappers:kubeadm:default-node-token [root@master01 ~]#
- 獲取ca證書sha256編碼hash值
[root@master01 ~]# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //' 19060b637433363db284e831fce4bd567f82d8070b2744741dbe2f1cfa804d53
- 節點加入集群
kubeadm join 172.18.0.67:6443 --token t4xdcj.5vgr19ymj4g6y7hm --discovery-token-ca-cert-hash sha256:19060b637433363db284e831fce4bd567f82d8070b2744741dbe2f1cfa804d53 --ignore-preflight-errors=Swap
2.6 加入K8S Node
- 在兩個Node節點執行
註冊Node節點到Master
# kubeadm join 的內容,在上面kubeadm init 已經生成好了 kubeadm join 172.18.0.67:6443 --token t4xdcj.5vgr19ymj4g6y7hm --discovery-token-ca-cert-hash sha256:19060b637433363db284e831fce4bd567f82d8070b2744741dbe2f1cfa804d53 --ignore-preflight-errors=Swap
2.7 安裝網路插件flannel
- 在master節點上安裝即可,其他節點加入k8s集群後會自動安裝
1)安裝flannel
# 這個地址可能訪問不到,可以開小飛機手動把這個文件下載下來,然後再apply kubectl apply -f //raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml # 執行的成功與否要看docker image ls中是否有flannel的鏡像,慢慢等待它下載即可
# 要確保能夠訪問到 quay.io 這個registery
# 如果無法訪問,可以將此文件中image項後面的地址修改成可以訪問到的地址
2)查看是否安裝成功
# 注意,要確保狀態為全1/1時,才可進行後續操作 [root@k8s-master01 ~]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE coredns-7f89b7bc75-9zxjz 1/1 Running 0 12m coredns-7f89b7bc75-n8p4s 1/1 Running 0 12m etcd-k8s-master01 1/1 Running 0 12m kube-apiserver-k8s-master01 1/1 Running 0 12m kube-controller-manager-k8s-master01 1/1 Running 0 12m kube-flannel-ds-b5ljk 1/1 Running 0 7m58s kube-proxy-cwzkw 1/1 Running 0 12m kube-scheduler-k8s-master01 1/1 Running 0 12m # 確保所有節點為Ready狀態 [root@k8s-master01 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master01 Ready control-plane,master 93m v1.20.2 k8s-node01 Ready <none> 49m v1.20.2
3)flannel安裝失敗後重裝
- 如果flannel因為網路問題安裝失敗,需要進行重新安裝
kubectl delete -f kube-flannel.yml # 然後重新安裝 kebectl apply -f kube-flannel.yml
3. Kubernetes集群資訊查看及管理
3.1 Pod的創建與查看
1)資訊查看
# 查看k8s集群的整體資訊 kubectl cluster-info # 查看當前系統上已經被創建的控制器 kubectl get deployment # 查看pod的相關資訊 kubectl get pods kubectl get pods -o wide # 查看更詳細的資訊 # 查看services的相關資訊 kubectl get services kubectl get svc # 查看kube-system名稱空間中service的相關資訊 kubectl get svc -n kube-system
2)創建一個pod
# 創建並運行一個特定的鏡像,暴露80埠,並且只創建1個副本,干跑模式需要再加上--dry-run=true kubectl run nginx-deploy --image=nginx:1.14 --port=80 --replicas=1
# 如果要鏡像中運行其他程式,可以寫成這樣(注意前面要加 -- ) kubectl run nginx-deploy --image=nginx:1.14 --port=80 --replicas=1 -- /bin/sh
3)對剛剛創建的pod進行查看並訪問
[root@k8s-master01 ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deploy 1/1 Running 0 3m6s 10.244.1.2 k8s-node01 <none> <none> [root@k8s-master01 ~]# curl 10.244.1.2
3.2 創建pod並暴露埠
- 在Kubernetes集群中創建一個pod,然後暴露埠,驗證其是否可以正常訪問
1)創建deployment
# 創建一個deployment控制器,這個控制器的名字就叫nginx-deploy kubectl create deployment nginx-deploy --image=nginx
2)創建service並暴露埠
kubectl expose deployment nginx-deploy --name=nginx --port=80 --target-port=80 --protocol=TCP # 將nginx-deploy這個控制器(deployment )相關的pod資源都創建為一個服務,服務名叫nginx # --name 是service的名稱 # --port 是service暴露到外部的埠 # --target-port 是pod暴露的埠 # --protocol 使用的協議,默認就是TCP # --type 是service的類型,service有多種類型,可kubectl expose --help來查看--type選項,Defaultis 'ClusterIP'
3)查看相關資訊並訪問
# 查看pod和service的相關資訊 [root@k8s-master01 ~]# kubectl get pods,svc NAME READY STATUS RESTARTS AGE pod/nginx-deploy-8588f9dfb-t8wzr 1/1 Running 0 11m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 78m service/nginx ClusterIP 10.99.193.184 <none> 80/TCP 34s # 查看kube-system名稱空間中service的相關資訊 kubectl get svc -n kube-system # 訪問://NodeIP:PORT,只有在集群內部的節點上才能被訪問到 curl //10.99.193.184
參考:
- //www.cnblogs.com/jiangwenhui/p/11792519.html
- //www.cnblogs.com/double-dong/p/11483670.html