Kubeadm部署K8S(kubernetes)集群(測試、學習環境)-單主雙從
- 2022 年 1 月 28 日
- 筆記
- K8S(kubernetes)
1. kubernetes介紹
1.1 kubernetes簡介
kubernetes的本質是一組伺服器集群,它可以在集群的每個節點上運行特定的程式,來對節點中的容器進行管理。目的是實現資源管理的自動化,主要提供了如下的主要功能:
自我修復:一旦某一個容器崩潰,能夠在1秒中左右迅速啟動新的容器
彈性伸縮:可以根據需要,自動對集群中正在運行的容器數量進行調整
服務發現:服務可以通過自動發現的形式找到它所依賴的服務
負載均衡:如果一個服務起動了多個容器,能夠自動實現請求的負載均衡
版本回退:如果發現新發布的程式版本有問題,可以立即回退到原來的版本
存儲編排:可以根據容器自身的需求自動創建存儲卷
1.2 kubernetes組件
一個kubernetes集群主要是由控制節點(master)、工作節點(node)構成,每個節點上都會安裝不同的組件。
master:集群的控制平面,負責集群的決策(管理)
ApiServer:資源操作的唯一入口,接收用戶輸入的命令,提供認證、授權、API註冊和發現等機制
Scheduler:負責集群資源調度,按照預定的調度策略將Pod調度到相應的node節點上
ControllerManager:負責維護集群的狀態,比如程式部署安排、故障檢測、自動擴展、滾動更新等
Etcd:負責存儲集群中各種資源對象的資訊
node:集群的數據平面,負責為容器提供運行環境(幹活)
Kubelet:負責維護容器的生命周期,即通過控制docker,來創建、更新、銷毀容器
KubeProxy:負責提供集群內部的服務發現和負載均衡
Docker:負責節點上容器的各種操作
舉例:以部署一個nginx服務來說明kubernetes系統各個組件調用關係
- 首先要明確,一旦kubernetes環境啟動之後,master和node都會將自身的資訊存儲到etcd資料庫中,
- 一個nginx服務的安裝請求會首先被發送到master節點的apiServer組件,
- apiServer組件會調用scheduler組件來決定到底應該把這個服務安裝到哪個node節點上,在此時,它會從etcd中讀取各個node節點的資訊,然後按照一定的演算法進行選擇,並將結果告知apiServer,
- apiServer調用controller-manager去調度Node節點安裝nginx服務,
- kubelet接收到指令後,會通知docker,然後由docker來啟動一個nginx的pod,pod是kubernetes的最小操作單元,容器必須跑在pod中至此,
- 一個nginx服務就運行了,如果需要訪問nginx,就需要通過kube-proxy來對pod產生訪問的代理,
最後,外界用戶就可以訪問集群中的nginx服務了。
1.3 kubernetes概念
Master:集群控制節點,每個集群需要至少一個master節點負責集群的管控
Node:工作負載節點,由master分配容器到這些node工作節點上,然後node節點上的docker負責容器的運行
Pod:kubernetes的最小控制單元,容器都是運行在pod中的,一個pod中可以有1個或者多個容器
Controller:控制器,通過它來實現對pod的管理,比如啟動pod、停止pod、伸縮pod的數量等等
Service:pod對外服務的統一入口,下面可以維護者同一類的多個pod
Label:標籤,用於對pod進行分類,同一類pod會擁有相同的標籤
NameSpace:命名空間,用來隔離pod的運行環境
2. kubernetes集群
目前生產部署Kubernetes 集群主要有兩種方式:
Kubeadm:
Kubeadm 是一個K8s 部署工具,提供kubeadm init 和kubeadm join,用於快速部署Kubernetes 集群。
官方地址://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/
二進位包:
從github 下載發行版的二進位包,手動部署每個組件,組成Kubernetes 集群。
Kubeadm 降低部署門檻,但屏蔽了很多細節,遇到問題很難排查。如果想更容易可控,推薦使用二進位包部署Kubernetes 集群,雖然手動部署麻煩點,期間可以學習很多工作原理,也利於後期維護。
3. Kubeadm方式部署(一主多從)
3.1 kubeadm介紹
kubeadm是官方社區推出的一個用於快速部署 kubernetes集群的工具,這個工具能通過兩條指令完成一個 kubernetes 集群的部署:
第一、創建一個 Master 節點 kubeadm init
第二、將 Node 節點加入到當前集群中 # kubeadm join <Master節點的 IP和埠 >
3.2 安裝要求
在開始之前,部署 Kubernetes集群機器需要滿足以下幾個條件:
– 一台或多台機器,作業系統 CentOS7.x-86_x64
– 硬體配置:2GB或更多 RAM,2 個 CPU或更多 CPU,硬碟 30GB或更多
– 集群中所有機器之間網路互通
– 可以訪問外網,需要拉取鏡像
– 禁止 swap分區
3.3 實現目標
(1)在所有節點上安裝 Docker 和 kubeadm
(2)部署 Kubernetes Master
(3)部署容器網路插件
(4)部署 Kubernetes Node,將節點加入 Kubernetes 集群中
(5)部署 Dashboard Web頁面,可視化查看 Kubernetes資源
3.4 環境準備
角色 |
IP |
組件 |
master |
10.27.134.250 |
docker、kubectl、kubeadm、kubelet |
node1 |
10.27.134.251 |
docker、kubectl、kubeadm、kubelet |
node2 |
10.27.134.252 |
docker、kubectl、kubeadm、kubelet |
3.5 系統初始化(所有節點均需操作)
3.5.1 主機名解析
##修改主機名
[root@jss-k8s-1 ~]# hostnamectl set-hostname master #master節點
[root@jss-k8s-2 ~]# hostnamectl set-hostname node1 #node1節點
[root@jss-k8s-3 ~]# hostnamectl set-hostname node2 #node2節點
##三台伺服器的地址和主機名添加到三個節點的/etc/hosts文件中
[root@master ~]# cat >> /etc/hosts << EOF
10.27.134.250 master
10.27.134.251 node1
10.27.134.252 node2
EOF
3.5.2 時間同步
kubernetes要求集群中的節點時間必須精確一直,這裡使用chronyd服務從網路同步時間
# 啟動chronyd服務並設置開機啟動
# systemctl start chronyd && systemctl enable chronyd
# 核驗時間
# date
3.5.3 禁用iptable和firewalld服務
kubernetes和docker 在運行的中會產生大量的iptables規則,為了不讓系統規則跟它們混淆,直接關閉系統的規則
##關閉firewalld服務
# systemctl stop firewalld && systemctl disable firewalld
##關閉iptables服務
# systemctl stop iptables && systemctl disable iptables
3.5.4 禁用selinux
selinux是linux系統下的一個安全服務,如果不關閉它,在安裝集群中會產生各種各樣的奇葩問題
# 永久關閉
# sed -i ‘s/enforcing/disabled/’ /etc/selinux/config
# 臨時關閉
# setenforce 0
3.5.5 禁用swap分區
swap分區指的是虛擬記憶體分區,它的作用是物理記憶體使用完,之後將磁碟空間虛擬成記憶體來使用,啟用swap設備會對系統的性能產生非常負面的影響,因此kubernetes要求每個節點都要禁用swap設備,但是如果因為某些原因確實不能關閉swap分區,就需要在集群安裝過程中通過明確的參數進行配置說明
# 永久關閉
# vim /etc/fstab
# 臨時關閉
# swapoff -a
3.5.6 將橋接的 IPv4流量傳遞到 iptables的鏈上
##載入網橋過濾模組
# cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
##修改內核參數
# cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
##配置生效
# sysctl –system
##建議重啟下系統,讓配置徹底生效
# reboot
3.5.7 配置yum源
# curl -o /etc/yum.repos.d/Centos-7.repo //mirrors.aliyun.com/repo/Centos-7.repo
# curl -o /etc/yum.repos.d/docker-ce.repo //mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 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
# yum clean all && yum makecache
3.6 所有節點安裝 docker
##查看所有的可用版本
# yum list docker-ce –showduplicates | sort -r
##安裝舊版本(穩定性問題)
yum install docker-ce-cli-18.09.9-3.el7 docker-ce-18.09.9-3.el7
##安裝源里最新版本
# yum install docker-ce
##配置docker加速
# mkdir -p /etc/docker
cat > /etc/docker/daemon.json << EOF
{
“insecure-registries”: [
“10.27.134.250:5000”
],
“registry-mirrors” : [
“//8xpk5wnt.mirror.aliyuncs.com”
]
}
EOF
##啟動docker
# systemctl enable docker && systemctl start docker
3.7 部署kubernetes master
(1)安裝 kubeadm, kubelet 和 kubectl,操作節點:所有的節點需要執行
##可以指定版本,不指定即安裝最新
# yum install -y kubelet-1.16.2 kubeadm-1.16.2 kubectl-1.16.2 –disableexcludes=Kubernetes
##查看kubeadm 版本
# kubeadm version
##設置kubelet開機啟動
# systemctl enable kubelet
(2)初始化配置文件,操作節點: 只在master節點執行
# kubeadm config print init-defaults > kubeadm.yaml
##修改kubeadm的yaml文件
# vim kubeadm.yaml
(3)下載鏡像
操作節點:只在master節點執行
##查看需要使用的鏡像列表,若無問題,將得到如下列表
# kubeadm config images list –config kubeadm.yaml
##提前下載鏡像到本地
# kubeadm config images pull –config kubeadm.yaml
(4)初始化master節點
操作節點:只在master節點執行
kubeadm init –config kubeadm.yaml
##按照上述提示資訊操作,配置kubectl客戶端的認證
mkdir -p #HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf #HOME/.kube/config
sudo chown #(id -u):#(id -g) #HOME/.kube/config
##此時查看節點應該處於notReady狀態,因為還未配置網路插件。
若執行初始化過程中出錯,根據錯誤資訊調整後,執行kubeadm reset後再次執行init操作即可
# kubectl get nodes
3.8 添加node節點到集群中
操作節點:所有的node節點需要執行
在每台node節點,執行如下命令,該命令是在kubeadm init成功後提示資訊中列印出來的,需要替換成實際init後列印出的命令。
kubeadm join 10.27.134.250:6443 –token abcdef.0123456789abcdef \
–discovery-token-ca-cert-hash sha256:99006ec72f04c1e61ebd6d9037eec86c5dad7e239164e4928902e46ad7887d16
3.9 安裝flannel網路插件
操作節點:只在master節點(k8s-master)執行
(1)下載flannel的yaml文件
wget //raw.githubusercontent.com/coreos/flannel/2140ac876ef134e0ed5af15c65e414cf26827915/Documentation/kube-flannel.yml
##若是無法進行下載,可以本地瀏覽器打開地址後複製網頁內容粘貼到本地,修改文件名和格式後再導入到master節點底層。
(2)修改flannel插件yml文件,新增一行配置指定網卡名稱
(3)執行安裝
##先拉取鏡像,此過程中國速度比較慢
# docker pull quay.io/coreos/flannel:v0.11.0-amd64
##執行flannel安裝
# kubectl create -f kube-flannel.yml
##若是網頁複製粘貼的方式,安裝出現下面報錯,建議使用notepad打開轉換為unix格式
3.10 集群驗證
(1)操作節點: 在master節點執行
# kubectl get nodes #觀察集群節點是否全部Ready
(2)創建一個nginx服務進行測試
# kubectl run test-nginx –image=nginx:alpine
(3)查看pod是否創建成功,並訪問pod ip測試是否可用
# kubectl get pods -o wide
# curl 10.244.1.2
3.11(可選)設置master節點參與pod調度
操作節點:master
##默認部署成功後,master節點無法調度業務pod,如需設置master節點也可以參與pod的調度,需執行:
# kubectl taint node k8s-master node-role.kubernetes.io/master:NoSchedule-
3.12 部署dashboard可視化模組
(1)服務部署
##下載yml文件
# wget //raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-rc5/aio/deploy/recommended.yaml
##修改yam文件,service改為NodePort類型
##創建服務
# kubectl create -f recommended.yaml
##查看服務對外暴露的埠號
# kubectl get svc -n kubernetes-dashboard
(2)訪問測試
##使用瀏覽器訪問
(3)創建ServiceAccount進行登錄
##創建admin.conf配置文件
# cat > /opt/kubernetes/cfg/admin.conf << EOF
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: admin
annotations:
rbac.authorization.kubernetes.io/autoupdate: “true”
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
subjects:
– kind: ServiceAccount
name: admin
namespace: kubernetes-dashboard
—
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin
namespace: kubernetes-dashboard
EOF
##查看命名空間內的加密資訊是否有token和名稱
# kubectl get secret -n kubernetes-dashboard
##使用該命令拿到token,替換上條命令查詢的名稱admin-token-qt24k,然後粘貼到瀏覽器中進行登錄
# kubectl -n kubernetes-dashboard get secret admin-token-qt24k -o jsonpath={.data.token}|base64 -d
##使用token登錄dashboard
3.13 環境重置
如果在集群安裝過程中遇到了其他問題,也可以使用下面的命令來進行重置:
# kubeadm reset
# ifconfig cni0 down && ip link delete cni0
# ifconfig flannel.1 down && ip link delete flannel.1
# rm -rf /var/lib/cni/