簡單瞭解一下K8S,並搭建本身的集羣

距離上次更新已經有一個月了,主要是最近工做上的變更有點頻繁,如今才暫時穩定下來。這篇博客的本意是帶你們從零開始搭建K8S集羣的。可是我後面一想,若是是我看了這篇文章,會收穫什麼?就是跟着步驟一步一走嗎?是個人話我會選擇拒絕,因此我加了關於K8S的簡單介紹,每一步的步驟都添加了解釋。因爲篇幅和時間緣由,我只介紹了K8S中較爲核心的Pod和Service。node

文章前半段會簡單的介紹一下K8S,後半段會介紹如何從零開始慢慢的搭建集羣。若是想直接開始着手搭建集羣,則能夠直接從第三章開始看。linux

1. K8S是什麼

K8S全稱kubernetes,是由Google在2014年開源的生產級別的容器編排系統,或者說是微服務和雲原平生臺。雖然說14年纔開源,但實際上K8S是Google內部的容器編排系統Borg的開源版本,在Google內部已經用了十多年了。下面是一個關於K8S的Logo來源的小插曲。git

Kubernetes由谷歌在2014年首次對外宣佈 。它的開發和設計都深受谷歌的Borg系統的影響,它的許多頂級貢獻者以前也是Borg系統的開發者。在谷歌內部,Kubernetes的原始代號曾經是Seven,即星際迷航中友好的Borg(博格人)角色。Kubernetes標識中舵輪有七個輪輻就是對該項目代號的致意。github

不過也有一個說法是,Docker的Logo是一個馱着集裝箱的鯨魚,也就是運輸船,K8S的Logo是一個船舵,旨在引領着Docker(或者說容器技術)走向遠方。算法

2. 簡單瞭解K8S

看了不少官方文章,是真官方。官方什麼意思呢,就是有可能看完了約等於沒有看,同樣的啥都不知道。docker

因此我想寫這樣一篇文章,給那些看完文檔仍然不太理解或者說徹底沒了解過K8S的老鐵一點小幫助。那麼讓咱們回到最初對K8S的定義,它是一個微服務框架。shell

說到微服務框架,咱們就不得不提一下目前業界十分主流的微服務框架,與這些你十分熟悉的框架進行對比,你就會很清晰的知道K8S能作什麼了。目前很主流的微服務框架和平臺有Spring Cloud、Dubbo和K8S。ubuntu

Spring Cloud來自Netflix,Dubbo來自阿里,而K8S則來自Google。說的直觀一點,這三個框架都是針對微服務的解決方案。可能有人會說,K8S不是一個容器編排系統嗎?怎麼跟Spring Cloud這種軟件層面上的微服務框架作起了對比呢?vim

老鐵別慌,等咱們慢慢深刻這個概念。服務器

咱們都知道,若是咱們須要使用微服務,那麼確定少不了一些底層的基礎設施的支撐,例如服務註冊與發現、負載均衡、日誌監控、配置管理、集羣自愈和容錯、彈性伸縮…等等。我沒有列舉完,如其實這些組件均可以統稱爲微服務的公共關注點。那咱們是否是能夠說,只要可以提供的這些功能,它就算一個微服務框架呢?

以上的大多數功能,K8S都是內置的。故咱們能夠說K8S是一個與Docker Swarm相相似的容器編排系統,可是因爲K8S內置了微服務的解決方案,它同時也是一個功能完備的微服務框架。

2.1 Pod的概念

在Docker Swarm中,調度的最小單位是容器,而在K8S中,調度的最小是Pod,那啥是Pod呢?

Pod是K8S設計的一個全新的概念,在英文中的原意是表達一羣鯨魚或者是一個豌豆莢的意思。換句話說,一個Pod中能夠運行一個或者多個容器。

在一個集羣中,K8S會爲每一個Pod都分配一個集羣內惟一的IP地址。由於K8S要求底層網絡支持集羣內的任意節點之間的兩個Pod可以直接通訊。這些容器共享當前Pod的文件系統和網絡。而這些容器之因此可以共享,是由於Pod中有一個叫Pause的根容器,其他的用戶業務容器都是共享這個根容器的IP和Volume。因此這些容器之間均可以經過localhost進行通訊。

有人可能會問,爲何要引入根容器這個概念?那是由於若是沒有根容器的話,當一個Pod中引入了多個容器的時候,咱們應該用哪個容器的狀態來判斷Pod的狀態呢?因此纔要引入與業務無關且不容易掛掉的Pause容器做爲根容器,用根容器的狀態來表明整個容器的狀態

熟悉Spring Cloud或者微服務的都知道,微服務中最忌諱的就是出現單點的狀況。

因此針對同一個服務咱們通常會部署2個或者更多個實例。在K8S中,則是會部署多個Pod副本,組成一個Pod集羣來對外提供服務。

而咱們前面提過,K8S會爲每個Pod提供一個惟一的IP地址,客戶端就須要經過每一個Pod的惟一IP+容器端口來訪問到具體的Pod,這樣一來,若是客戶端把調用地址寫死,服務器就沒有辦法作負載均衡,並且,Pod重啓以後IP地址是會變的,難道每次重啓都要通知客戶端IP變動嗎?

爲了解決這個問題,就要引出Service的概念了。

2.2 Service

Service是K8S中最核心的資源對象之一,就是用於解決上面提到的問題。我我的認爲與Swarm中的Service概念沒有太大的區別。

一旦Service被建立,K8S會爲其分配一個集羣內惟一的IP,叫作ClusterIP,並且在Service的整個生命週期中,ClusterIP不會發生變動,這樣一來,就能夠用與Docker Swarm相似的操做,創建一個ClusterIP到服務名的DNS域名映射便可。

值得注意的是,ClusterIP是一個虛擬的IP地址,沒法被Ping,僅僅只限於在K8S的集羣內使用。

而Service對客戶端,屏蔽了底層Pod的尋址的過程。而且由kube-proxy進程將對Service的請求轉發到具體的Pod上,具體到哪個,由具體的調度算法決定。這樣以來,就實現了負載均衡。

而Service是怎麼找到Pod的呢?這就須要繼續引入另一個核心概念Label了。

2.3 Label

Lable本質上是一個鍵值對,具體的值由用戶決定。Lable就是標籤,能夠打在Pod上,也能夠打到Service上。總結來講,Label與被標記的資源是一個一對多的關係。

例如,咱們給上面所描述的Pod打上了role=serviceA的標籤,那麼只須要在Service中的Label Selector中加入剛剛那個標籤,這樣一來,Service就能夠經過Label Selector找到打了同一Label的Pod副本集了。

接下來,再簡單的介紹一下其餘的K8S核心概念。

2.4 Replica Set

上面提到過部署多個Pod,是怎麼一回事呢?K8S最開始有一個概念叫Replication Controller,不過如今已經慢慢的被Replica Set所替代,RS也叫下一代的RC。簡單來講Replica Set定義了一種指望的場景,即讓任什麼時候候集羣內的Pod副本數量都符合預期的值。

一旦被建立,集羣就會按期的檢測當前存活的Pod數量,若是多了,集羣就會停掉一些Pod。相反,若是少了就會建立一些Pod。這樣一來能夠避免什麼問題呢?假設某個服務有兩個實例在運行,其中一個意外掛掉了,若是咱們設置了副本數量是2,那麼集羣就會自動建立一個Pod,以保證集羣內始終有兩個Pod在運行。

K8S的東西就簡單的介紹這麼多,接下來讓咱們進入集羣的搭建環節。

3. 搭建K8S的準備工做

不知道從哪篇博客開始,不是很願意寫這種純TODO類的博文,可是我本身躺坑以後發現,我本身這個還真是我目前見過最簡單的。

我看到的有些安裝分了不少種狀況,可是當一個初學者來看的時候,可能反而會讓他看懵逼。因此接下來的安裝會有些硬核。不分狀況,就只有一種狀況,一把梭安裝就完事。

系統 版本 Ubuntu 18.04

K8S 版本 v1.16.3

Docker 版本 v19.03.5

Flannel 版本 v0.11.0

若是你問我,若是沒有機器看了你的文章也能的擁有本身的集羣嗎?那麼請看下圖…

3.1 準備工做

咱們先假設如下的狀況成立。

機器:有2-3臺物理機或虛擬機

系統:Ubuntu 18.04 且已換好國內的源

若是以上基本不成立,本篇文章到此結束,謝謝觀看…

3.2 安裝Docker

我也不須要介紹各類狀況了,直接登上機器,建立一個shell腳本,例如叫install_docker.sh,一把梭代碼以下。

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates 
curl gnupg-agent software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
sudo apt-get update
sudo apt-get -y install docker-ce docker-ce-cli containerd.io
複製代碼

而後執行sh install_docker.sh,等待命令跑完,驗證docker是否安裝好便可。直接敲docker + 回車。

3.3 安裝Kubernetes

同理,新建一個shell腳本,例如install_k8s.sh。一把梭代碼以下。

sudo curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
sudo apt-get update
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://apt.kubernetes.io/ kubernetes-xenial main
EOF
sudo apt-get install -y kubelet kubeadm kubectl --allow-unauthenticated
複製代碼

而後執行sh install_k8s.sh,等待命令跑完,驗證k8s是否安裝好便可。直接敲kubectl + 回車。

3.4 關閉Swap

先給出一把梭,不要耽誤了正在安裝的老鐵。爲何要關閉後面再說。

  • 暫時關閉 直接使用命令sudo swapoff -a,可是重啓以後會生效。會致使k8s沒法正常運行。
  • 永久關閉 建議一勞永逸sudo vim /etc/fstab將有swap.img那行註釋掉,保存便可。

那麼,swap是啥呢?它是系統的交換分區,你能夠理解爲虛擬內存。當系統內存不足的時候,會將一部分硬盤空間虛擬成內存使用。那爲何K8S須要將其關掉呢?能夠從下圖看看訪問內存和訪問硬盤速度上的差別就知道了。

總的來講是爲了性能考慮,因此就須要避免開啓swap交換,K8S但願全部的服務都不該該超過集羣或節點CPU和內存的限制。

4. 初始化Master節點

到這,準備工做就完成了,能夠開始安裝K8S的master節點了,登上要做爲master節點的機器。

4.1 設置HostName

老規矩,先上命令,再說爲何要設置。

sudo hostnamectl set-hostname master-node
複製代碼

自定義修改了主機名,在以後查看集羣內節點時,每一個節點的名字就不會顯示K8S自動生成的名字,便於查看和記憶。例如,在其餘的Node節點你能夠將master-node改成slave-node-1worker-node-2,效果以下。

4.2 初始化集羣

在機器上執行以下命令。

sudo kubeadm init --pod-network-cidr=10.244.0.0/16
複製代碼

而後,抱起吉他,等待命令執行完。

這裏須要特別注意一下。這個命令執行完成以後,會打印一個有kubeadm join的命令,須要保存下來。

大概長這樣。

kubeadm join 你的IP地址:6443 --token 你的TOKEN --discovery-token-ca-cert-hash sha256:你的CA證書哈希

顧名思義,這個命令用於其餘節點加入到集羣中,並且Token是有時效性的,過時時間通常是86400000毫秒

若是失效,就須要從新生成。若是你真的又沒有保存,又失效了…我仍是給你準備了兩個補救措施。若是命令保存下來了,那麼請直接跳過這兩個補救措施。

token. 經過命令Kubeadm token list找回

ca-cert. 執行命令openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'找回

4.3 普通用戶可執行

把下面的指令一把梭便可。

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
複製代碼

主要是,爲了避免那麼麻煩,在控制節點上執行kubectl這類的命令時,不用每次都sudo。

4.4 安裝網絡通訊插件

執行以下命令,安裝網絡插件Flannel。

sudo kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
複製代碼

能夠看到,若是不安裝Flannel,咱們剛剛Init好的Master節點會處於NOT_READY的狀態。安裝好以後,能夠經過命令kubectl get nodes來查看全部的節點的狀態。也能夠經過kubectl get pods --all-namespaces來查看當前集羣中全部Pod的狀態。這裏須要注意的是,只有在master節點是READY,全部Pod的狀態是RUNNING以後,才能夠進行下一步。

爲何要裝網絡插件呢?

那是由於K8S要求集羣內的全部節點之間的Pod網絡是互通的。換句話說,Flannel可讓集羣內不一樣節點上的容器都有一個在當前集羣內惟一的虛擬IP地址。這樣以來,就能夠實現,跨節點的Pod與Pod直接通訊。

這樣一來,將複雜的網絡通訊,簡單的變成了兩個IP地址之間的通訊。這主要是經過虛擬二層網絡實現的。看似是這個節點的Pod直接和另外一個節點上的Pod進行了通訊,最終仍是經過節點的物理網卡流出的。

5. Slave節點加入集羣

到此,一個單點的集羣就已經搭建好了。如今咱們要作的是,登陸準備好的另外一臺(我只有兩臺,若是你有3臺或者4天,把這個章節反覆走幾回就行了)服務器。

5.1 設置HostName

執行以下命令。

sudo hostnamectl set-hostname slave-node
複製代碼

由於當前節點不是master了,因此主機名設置成了slave-node。

5.2 加入集羣

重點來了,執行上一章節生成的kubeadm join命令便可。等待執行完畢以後,就能夠在master節點上經過命令kubectl get nodes看到slave-node已經加入了集羣。

對於Slave節點的操做就沒了。

6. 感謝閱讀

關於K8S就簡單的介紹到這裏,因爲篇幅和時間的緣由,不少概念都沒有介紹,例如Deployment、Volume、ConfigMap等等。僅僅只介紹了較爲核心的Pod和Service,以及相關的東西。畢竟,若是想要把K8S的核心理念介紹完,一篇博客的篇幅是確定不夠的,後面我再單獨詳細的介紹吧。

第一次在博客裏求贊啊,以前徹底是隨緣。不過我後來發現,打開博客看到你們的點贊和留言,這對我來講是一種莫大的鼓勵

若是你以爲這篇文章對你有幫助,還麻煩點個贊關個注分個享留個言

也能夠微信搜索公衆號【SH的全棧筆記】,固然也能夠直接掃描二維碼關注

拜了個拜

相關文章
相關標籤/搜索