1. 程式人生 > >ASP.NET Core on K8S深入學習(1)K8S基礎知識與叢集搭建

ASP.NET Core on K8S深入學習(1)K8S基礎知識與叢集搭建

在上一個小系列文章《ASP.NET Core on K8S學習初探》中,通過在Windows上通過Docker for Windows搭建了一個單節點的K8S環境,並初步嘗試將ASP.NET Core WebAPI專案部署到了K8S,把玩了一下快速部署和例項伸縮。這個系列開始,會繼續學習K8S以及在Linux上搭建叢集來深入把玩。本篇會回顧一下K8S的基本概念以及架構組成,然後會通過Kubeadm快速地搭建一個K8S叢集供後續學習把玩之用。

一、K8S基礎概念回顧

  1.Cluster 叢集

  計算、儲存和網路資源的集合,Kubernetes利用這些資源執行各種基於容器的應用。

  2.Master

  Master是Cluster的大腦,負責排程(決定將應用放在哪裡執行),一般為了實現高可用,會有多個Master。

  3.Node

  負責執行具體的容器,Node由Master管理,它會監控並彙報容器的狀態,同時根據Master的要求管理容器的生命週期。   eg. 在互動實驗中,這個Cluster中只有一個主機,它既是Master也是Node。

  4.Pod

  Kubernetes的最小工作單元,每個Pod包含一個或多個容器。Pod中的容器會被作為一個整體被Master排程到一個Node上執行。   (1)為何引入Pod?   一是方便管理:   有些容器天生聯絡緊密,需要在一起工作。Pod提供了比容器更高層次的抽象,將它們封裝到一個部署單元中。K8S以Pod為最小單位進行排程、擴充套件、共享資源、管理生命週期。   eg.正例:File Puller & Web Server => 需要部署在一起工作     反例:Tomecat & MySQL => 不需要部署在一起工作   二是可以共享資源和通訊:   Pod中所有容器使用同一個網路namespace,即相同的IP和埠空間,可以直接用localhost通訊,而且還可以共享儲存(本質是通過將Volume掛載到Pod中的每個容器)   (2)如何使用Pod?   執行單個容器:one-container-per-Pod,K8S中最常見的模型,即使這種情形下,K8S管理的也是Pod而不是單個容器。   執行多個容器:將聯絡非常緊密的多個容器部署到一個Pod中,可以直接共享資源。

  5.Controller

  K8S不會直接建立Pod,是通過Controller來管理Pod的。為了滿足不同業務場景,K8S提供了多種Controller:   (1)Deployment   最常見的Controller,可以管理Pod的多個副本,並確保Pod按照期望的狀態執行。   (2)ReplicaSet   實現了Pod的多副本管理,使用Deployment時會自動建立ReplicaSet。換句話說,Deployment是通過ReplicaSet來管理Pod的多個副本的,通常不需要直接使用ReplicaSet。   (3)DaemonSet   用於每個Node最多隻執行一個Pod副本的場景,DaemonSet通常用於執行daemon(守護程序、後臺程式)。   (4)StatefuleSet   用於保證Pod的每個副本在整個生命週期中名稱是不變的,而其他的Controller不提供這個功能。(非StatefuleSet下,當某個Pod發生故障需要刪除並重啟時,Pod的名稱是會變化的)   (5)Job   用於執行結束就刪除的應用,其他Controller下Pod通常是長期持續執行的。

  6.Service

  K8S定義了外界訪問一個或一組特定Pod的方式,就是Service。每個Service有自己的IP和埠,並且為Pod提供了負載均衡。   如果說K8S執行Pod的任務是交給了Controller去做,那麼訪問Pod的任務則是交給了Service去做。

  7.Namespace

  Namespace將一個物理的Cluster從邏輯上劃分為多個虛擬Cluster,每個虛擬Cluster就是一個Namespace,不同Namespace中的資源是完全隔離的。 K8S中會自動建立兩個Namespace:   (1)default:建立資源時如果不指定Namespace就會放到這裡   (2)kube-system: K8S自己建立的系統資源都會放到這個Namespace中

二、K8S叢集架構解析

  下面展示了一個最小化的K8S叢集,一個master節點和兩個node節點: *.master上也有kubelet和kube-proxy是因為master同時也是一個Node

  1.Master節點

  K8S叢集的“大腦”,執行以下多個Daemon服務:
  • 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節點

  執行Pod的主戰場,主要執行以下K8S元件:
  • 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叢集》

 

作者:周旭龍

出處:https://edisonchou.cnblogs.com

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。