ASP.NET Core on K8S深入學習(1)K8S基礎知識與集群搭建
- 2019 年 10 月 3 日
- 筆記
本篇已加入《.NET Core on K8S學習實踐系列文章索引》,可以點擊查看更多容器化技術相關係列文章。
在上一個小系列文章《ASP.NET Core on K8S學習初探》中,通過在Windows上通過Docker for Windows搭建了一個單節點的K8S環境,並初步嘗試將ASP.NET Core WebAPI項目部署到了K8S,把玩了一下快速部署和實例伸縮。這個系列開始,會繼續學習K8S以及在Linux上搭建集群來深入把玩。本篇會回顧一下K8S的基本概念以及架構組成,然後會通過Kubeadm快速地搭建一個K8S集群供後續學習把玩之用。
一、K8S基礎概念回顧
1.Cluster 集群
2.Master
3.Node
4.Pod
5.Controller
6.Service
7.Namespace
二、K8S集群架構解析
1.Master節點
- API Server(kube-apiserver)
- 提供Restful API => Kubernetes API,供其他組件調用以管理Cluster的各種資源
- Scheduler(kube-scheduler)
- 負責決定將Pod放在哪個Node上Run起來
- 調度時會根據指定演算法選擇Pod(eg.集群拓撲結構、各節點負載情況、HA等等)
- Controller Manager(kube-controller-manager)
- 負責管理集群中的各種資源,保證資源處於預期的狀態
- 由多種Controller組成
- Replication Controller:管理Deployment、StatefuleSet、DaemonSet的生命周期
- Endpoints Controller
- Namespace Controller:管理Namespace資源
- Serviceaccounts Controller
- Etcd
- 負責保存K8S集群中的配置資訊和各種資源的狀態資訊
- 當數據發生變化時,會及時通知K8S相關組件
- Pod網路
- 保證Pod能夠相互通訊,Flannel是一個可選方案
2.Node節點
- kubelet
- Node的Agent,負責創建運行容器與向Master報告運行狀態
- kube-proxy
- 每個Node都會運行proxy,它負責請求轉發到後端的容器
- Pod網路
- 保證Pod能夠相互通訊,Flannel是一個可選方案
三、K8S集群環境搭建
3.1 K8S環境搭建的幾種方式
搭建K8S環境有幾種常見的方式如下:
(1)Minikube
Minikube是一個工具,可以在本地快速運行一個單點的K8S,供初步嘗試K8S或日常開發的用戶使用,不能用於生產環境。
(2)Kubeadm
Kubeadm是K8S官方社區推出的一套用於簡化快速部署K8S集群的工具,Kubeadm的設計目的是為新用戶開始嘗試K8S提供一種簡單的方法。
(3)二進位包
除了以上兩種方式外,我們還可以通過從官方下載二進位包,手動部署每個組件組成K8S集群,這也是目前企業生產環境中廣為使用的方式,但對K8S管理人員的要求較高。
本次學習實踐我們主要藉助Kubeadm工具搭建K8S集群,以便後續實踐部署ASP.NET Core應用集群。
3.2 搭建前的準備工作
(1)準備三台Linux伺服器
這裡我選擇通過VMware Workstaion來搭建3個虛擬機,每個配置2CPU和2G記憶體,如下圖:
(2)配置主機名與靜態IP地址如下表所示:
角色 | 主機名 | IP地址 |
Master | k8s-master | 192.168.2.100 |
Node | k8s-node1 | 192.168.2.101 |
Node | k8s-node2 | 192.168.2.102 |
然後,更改hosts文件添加主機名與IP映射關係
# vim /etc/hosts
192.168.2.100 k8s-master 192.168.2.101 k8s-node1 192.168.2.102 k8s-node2
(3)關閉防火牆
systemctl stop firewalld systemctl disable firewalld
(4)關閉selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config setenforce 0
(5)關閉swap => K8S中不支援swap分區
# vim /etc/fstab #/dev/mapper/centos-swap swap swap defaults 0 0
*.編輯etc/fstab將swap那一行注釋掉或者刪除掉
(6)將橋接的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.3 安裝Docker&Kubeadm&Kubelet
以下步驟請在所有節點中都操作:
(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
*.這裡安裝的是18.06社區版,如果你之前有安裝低版本的Docker,為了配合本次實驗的K8S版本(1.13.x),建議先卸載掉,卸載過程可以參考這篇文章《CentOS7 Docker升級》。
(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)安裝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 <[email protected]>" 指紋 : 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
3.4 部署Kubernetes Master
以下步驟請在k8s-master節點上操作:
kubeadm init --apiserver-advertise-address=192.168.2.100 --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記憶體把。
接下來,為了順利使用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之後,你會看到如下狀態:
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沒有就緒
如果其中有的Pod沒有Running,可以通過以下命令查看具體錯誤原因,比如這裡我想查看kube-flannel-ds-amd64-8bmbm這個pod的錯誤資訊:
kubectl describe pod kube-flannel-ds-amd64-8bmbm -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:
那麼,恭喜你,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
Node節點上成功join之後會得到以下資訊:
這時,我們在master節點上執行以下命令可以看到集群各個節點的狀態了:
如果看到兩個Node狀態不是Ready,那麼可能需要檢查哪些Pod沒有正常運行:
kubectl get pod --all-namespaces
然後按照3.5中的檢查方式進行檢查並修復,最終kubectl get nodes效果應該狀態都是Running。注意的是在檢查時需要注意是哪個Node上的錯誤,然後在對應的Node進行修復,比如拉取flannel鏡像。
至此,一個最小化的K8S集群已經搭建完畢。
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來查看。
因為是NodePort方式,因此其映射的埠號會在30000-32767範圍內隨機取一個,我們可以直接通過瀏覽器輸入IP地址訪問,比如這時我們通過瀏覽器來訪問一下任一Node的IP地址加埠號,例如192.168.2.101:31174或192.168.2.102:31174
如果能夠成功看到,那麼恭喜你,你的K8S集群能夠成功運行了,萬里長征走完了第一步!
四、小結
本文快速地介紹了一下Kubernetes的核心構成組件及其作用,然後通過在三台Linux主機上通過Kubeadm搭建了一個Master節點兩個Node節點的集群,最後通過部署一個Deployment來快速地驗證了一下集群是否可用。下一篇會通過一個ASP.NET Core的部署例子來演示和介紹一下各個組件之間是如何協作的,以及部署Dashboard。
參考資料
(1)CloudMan,《每天5分鐘玩轉Kubernetes》
(2)李振良,《一天入門Kubernets教程》
(3)李振良,《30分鐘部署一個Kubernetes集群》
(4)cao_xiaobo,《CentOS7 部署K8S集群》