轉自聲明
ASP.NET Core on K8S深入學習(1)K8S基礎知識與集群搭建
1.K8S環境搭建的幾種方式
搭建K8S環境有幾種常見的方式如下:
(1)Minikube
Minikube是一個工具,可以在本地快速運行一個單點的K8S,供初步嘗試K8S或日常開發的用戶使用,不能用於生產環境。
(2)Kubeadm
Kubeadm是K8S官方社區推出的一套用於簡化快速部署K8S集群的工具,Kubeadm的設計目的是為新用戶開始嘗試K8S提供一種簡單的方法。
(3)二進制包
除了以上兩種方式外,我們還可以通過從官方下載二進制包,手動部署每個組件組成K8S集群,這也是目前企業生產環境中廣為使用的方式,但對K8S管理人員的要求較高。
本次學習實踐我們主要借助Kubeadm工具搭建K8S集群,以便后續實踐部署ASP.NET Core應用集群。
2.搭建前的准備工作
(1)准備三台Linux服務器
這里我選擇通過VMware Workstaion來搭建3個虛擬機,每個配置2CPU和2G內存,如下圖:
(2)配置主機名與靜態IP地址如下表所示:
角色 | 主機名 | IP地址 |
Master | centos-master | 192.168.198.111 |
Node | centos-node1 | 192.168.198.112 |
Node | centos-node2 | 192.168.198.113 |
安裝vim
yum -y install vim*
然后,更改hosts文件添加主機名與IP映射關系
# vim /etc/hosts
192.168.198.111 CentOS-Master 192.168.198.112 CentOS-Node1 192.168.198.113 CentOS-Node2
(3)關閉防火牆
systemctl stop firewalld systemctl disable firewalld
(4)校正系統時間
系統時間不一致,會導致node節點無法加入集群
查看系統時間
date
安裝ntp
yum install -y ntp
同步時間
ntpdate cn.pool.ntp.org
(5)關閉selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config setenforce 0
(6)關閉swap => K8S中不支持swap分區
vim /etc/fstab #/dev/mapper/centos-swap swap swap defaults 0 0
*.編輯etc/fstab將swap那一行注釋掉或者刪除掉
(7)將橋接的IPv4流量傳遞到iptables的鏈
# cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF # sysctl --system
3.安裝Docker&Kubeadm&Kubelet
以下步驟請在所有節點中都操作:
3.1安裝Docker
# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo # yum -y install docker-ce-18.06.1.ce-3.el7 # systemctl enable docker && systemctl start docker # docker --version Docker version 18.06.1-ce, build e68fc7a
如報錯,請注意:
安裝wget
yum -y install wget
這里安裝的是18.06社區版,如果你之前有安裝低版本的Docker,為了配合本次實驗的K8S版本(1.13.x),建議先卸載掉,卸載過程可以參考這篇文章《CentOS7 Docker升級》
3.2添加阿里雲Yum軟件源
# cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes] name=Kubernetes baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg EOF
3.3安裝Kubeadm&Kubelet&Kubectl
注意:本次部署K8S版本號為1.13.3
yum install -y kubelet-1.13.3 kubeadm-1.13.3 kubectl-1.13.3 systemctl enable kubelet
遇到的一些坑如下:
① 碰到需要kubernetes-cni的問題:
#####錯誤:軟件包:kubelet-1.13.3-0.x86_64 (kubernetes)
需要:kubernetes-cni = 0.6.0 可用: kubernetes-cni-0.3.0.1-0.07a8a2.x86_64 (kubernetes) kubernetes-cni = 0.3.0.1-0.07a8a2 可用: kubernetes-cni-0.5.1-0.x86_64 (kubernetes) kubernetes-cni = 0.5.1-0 可用: kubernetes-cni-0.5.1-1.x86_64 (kubernetes) kubernetes-cni = 0.5.1-1 可用: kubernetes-cni-0.6.0-0.x86_64 (kubernetes) kubernetes-cni = 0.6.0-0 正在安裝: kubernetes-cni-0.7.5-0.x86_64 (kubernetes) kubernetes-cni = 0.7.5-0 您可以嘗試添加 --skip-broken 選項來解決該問題 您可以嘗試執行:rpm -Va --nofiles --nodigest
解決:手動安裝kubernetes-cni對應的版本
yum install -y kubelet-1.13.3 kubeadm-1.13.3 kubectl-1.13.3 kubernetes-cni-0.6.0
② 使用yum安裝程序時,提示xxx.rpm公鑰尚未安裝
從 https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg 檢索密鑰 導入 GPG key 0xA7317B0F: 用戶ID : "Google Cloud Packages Automatic Signing Key <gc-team@google.com>" 指紋 : d0bc 747f d8ca f711 7500 d6fa 3746 c208 a731 7b0f 來自 : https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg e3438a5f740b3a907758799c3be2512a4b5c64dbe30352b2428788775c6b359e-kubectl-1.13.3-0.x86_64.rpm 的公鑰尚未安裝 失敗的軟件包是:kubectl-1.13.3-0.x86_64 GPG 密鑰配置為:https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
解決:使用 yum install xxx.rpm --nogpgcheck 命令格式跳過公鑰檢查,比如跳過kubectl和kubeadm的公鑰檢查如下命令:
yum install kubectl-1.13.3-0.x86_64 --nogpgcheck yum install kubeadm-1.13.3-0.x86_64 --nogpgcheck
查看kubeadm、kubelet版本
kubelet --version
kubeadm version
3.4 部署Kubernetes Master
以下步驟請在k8s-master節點上操作:
kubeadm init \ --apiserver-advertise-address=192.168.198.111 \ --image-repository registry.aliyuncs.com/google_containers \ --kubernetes-version v1.13.3 \ --service-cidr=10.1.0.0/16 \ --pod-network-cidr=10.244.0.0/16
PS:由於默認拉取鏡像地址k8s.gcr.io國內無法訪問,這里指定阿里雲鏡像倉庫地址(registry.aliyuncs.com/google_containers)。官方建議服務器至少2CPU+2G內存,當然內存1G也是可以的,但是會出Warning,建議還是老老實實升2G內存把。
kubeadm join 192.168.198.111:6443 --token 0mruyg.dz1zman6uufgh5vt --discovery-token-ca-cert-hash sha256:0eac9042e16b8e410bb8b8e3a34afea5fe7bbd48591a2205d5eb47c1cce6bc32
接下來,為了順利使用kubectl命令,執行以下命令:
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config # kubectl get nodes
這時你可以使用kubectl了,當你執行完kubectl get nodes之后,你會看到如下狀態:
kubectl get nodes
常見錯誤:
the kubelet version is higher than the control plane version.
yum -y remove kubelet
yum install kubeadm-1.13.3-0.x86_64 --nogpgcheck
yum install -y kubelet-1.13.3 --nogpgcheck
3.5 部署Pod網絡插件(CNI)
同樣,繼續在k8s-master上操作:
kubectl apply -f \ https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml
然后通過以下命令驗證:全部為Running則OK,其中一個不為Running,比如:Pending、ImagePullBackOff都表明Pod沒有就緒
kubectl get pod --all-namespaces
如果其中有的Pod沒有Running,可以通過以下命令查看具體錯誤原因,比如這里我想查看kube-flannel-ds-amd64-8bmbm這個pod的錯誤信息:
kubectl describe pod kube-flannel-ds-amd64-xpd82 -n kube-system
在此過程中可能會遇到無法從qury.io拉取flannel鏡像從而導致無法正常Running,解決辦法如下:
使用國內雲服務商提供的鏡像源然后通過修改tag的方式曲線救國
docker pull quay-mirror.qiniu.com/coreos/flannel:v0.11.0-amd64 docker tag quay-mirror.qiniu.com/coreos/flannel:v0.11.0-amd64 quay.io/coreos/flannel:v0.10.0-amd64 docker rmi quay-mirror.qiniu.com/coreos/flannell:v0.11.0-amd64
這時,我們再看看master節點的狀態就會從NotReady變為Ready:
kubectl get nodes
那么,恭喜你,Master節點部署結束了。如果你只想要一個單節點的K8S,那么這里就完成了部署了。
3.6 加入Kubernetes Node
在兩台Node節點上執行join命令:
kubeadm join 192.168.2.100:6443 --token ekqxk2.iiu5wx5bbnbdtxsw --discovery-token-ca-cert-hash \sha256:c50bb83d04f64f4a714b745f04682b27768c1298f331e697419451f3550f2d05
這里需要注意的就是,帶上在Master節點Init成功后輸出的Token。如果找不到了,沒關系,可以通過以下命令來查看:
kubeadm token list
注:token默認有效期24小時,過期后使用該命令無法查看,可通過下面到方法修改。
kubeadm token create
獲取ca證書sha256編碼hash值
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
Node節點上成功join之后會得到以下信息:
這時,我們在master節點上執行以下命令可以看到集群各個節點的狀態了:
常見問題:
證書已存在
解決辦法:刪除相應目錄下的證書文件,重新執行命令
Downloading configuration for the kubelet from the "kubelet-config-1.15" ConfigMap in the kube-system namespace
configmaps "kubelet-config-1.15" is forbidden: User "system:bootstrap:6w889o" cannot get resource "configmaps" in API group "" in the namespace "kube-system"
這種提示一般是kubelet版本與kubeadm版本不一致導致,重新安裝kubelet即可
yum remove kubelet
yum install -y kubelet-1.13.3 kubeadm-1.13.3 kubectl-1.13.3 kubernetes-cni-0.6.0
kubectl get nodes
如果看到兩個Node狀態不是Ready,那么可能需要檢查哪些Pod沒有正常運行:
kubectl get pod --all-namespaces
然后按照3.5中的檢查方式進行檢查並修復,最終kubectl get nodes效果應該狀態都是Running。注意的是在檢查時需要注意是哪個Node上的錯誤,然后在對應的Node進行修復,比如拉取flannel鏡像。
至此,一個最小化的K8S集群已經搭建完畢。
常見異常:
[Get https://192.168.198.111:6443/api/v1/namespaces/kube-public/configmaps/cluster-info: x509: certificate has expired or is not yet valid]
更新系統時間,見第一步基本配置
3.7 測試Kubernetes集群
這里為了快速地驗證一下我們的K8S集群是否可用,創建一個示例Pod:
kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get pod,svc
如果想要看到更多的信息,比如pod被部署在了哪個Node上,可以通過 kubectl get pods,svc -o wide來查看。
kubectl get pods,svc -o wide
因為是NodePort方式,因此其映射暴露出來的端口號會在30000-32767范圍內隨機取一個,我們可以直接通過瀏覽器輸入IP地址訪問,比如這時我們通過瀏覽器來訪問一下任一Node的IP地址加端口號,例如172.30.10.91:31063或172.30.10.92:31063
如果能夠成功看到,那么恭喜你,你的K8S集群能夠成功運行了