通過實例快速掌握k8s(Kubernetes)核心概念

容器技術(shù)是微服務(wù)技術(shù)的核心技術(shù)之一疼约,并隨著微服務(wù)的流行而迅速成為主流。Docker是容器技術(shù)的先驅(qū)和奠基者果正,它出現(xiàn)之后迅速占領(lǐng)市場炎码,幾乎成了容器的代名詞。但它在開始的時候并沒有很好地解決容器的集群問題秋泳。Kubernetes抓住了這個機遇,以容器編排者(Container Orchestration)的身份出現(xiàn)攒菠,對容器集群進行管理和調(diào)度迫皱,現(xiàn)在已經(jīng)打敗了Docker成為了容器技術(shù)事實上的標(biāo)準(zhǔn)。當(dāng)然K8s內(nèi)部還是需要Docker的辖众,但它的功能范圍被大大壓縮了卓起,只是負責(zé)底層的容器引擎和鏡像(Docker Image)管理,成為了容器體系中不可缺少, 但沒有存在感的一部分凹炸。而絕大部分的對外接口都是由k8s來負責(zé)戏阅。

K8s核心對象:

相對于簡單易學(xué)的Docker來說,k8s系統(tǒng)龐雜而且概念眾多啤它,同一個功能有很多不同方法來完成奕筐,讓你無所適從,學(xué)習(xí)起來要困難的多变骡。對于普通碼農(nóng)來講不需要建立完整的生產(chǎn)環(huán)境离赫,只需要搭建一個本地開發(fā)環(huán)境,這時你只需要了解k8s的核心概念就夠了塌碌,這樣可以大大縮短學(xué)習(xí)時間渊胸。k8s的一切都是對象(Object),它的核心概念一共只有4個台妆,Pod翎猛,部署(Deployment),服務(wù)(Service)和節(jié)點(Node)接剩。另外再加上一個容器鏡像(Docker Image)切厘,這個是Docker引擎的核心。掌握了這五個核心概念搂漠,就對容器技術(shù)有了基本了解迂卢,打下了扎實的基礎(chǔ)。

Windows安裝環(huán)境:

Windows10的企業(yè)版, 專業(yè)版, 和教育版是可以支持直接安裝K8s的,但電腦是要支持Hyper-V的, 詳見這里而克。由于我的Windows是家庭版靶壮,只能先安裝虛擬機(VirtualBox),再在虛擬機上安裝k8s员萍。我用的k8s是Minikube腾降,是k8s的簡化版。另外還安裝了Vagrant(它是管理虛擬機的一個軟件)作為界面來管理VirtualBox碎绎。

容器鏡像(Docker Image):

任何程序都在容器中運行螃壤,k8s支持多種容器,其中Docker是最流行的筋帖。容器鏡像(Docker Image)是一個以文件形式存在的運行環(huán)境奸晴,它的里面是分層的,每一層都在上一層的基礎(chǔ)上不斷疊加新的功能日麸。容器鏡像是由Dockerfile創(chuàng)建的寄啼。Dockerfile是一個文件,里面包含一組已經(jīng)定義好的Docker命令(與Linux命令比較相似)代箭。當(dāng)運行Dockerfile時墩划,里面的命令被依次執(zhí)行,最后生成需要的容器鏡像嗡综。你再調(diào)用Docker命令(Docker run)運行容器鏡像來生成Docker容器乙帮,完成之后,應(yīng)用程序就已經(jīng)在容器里部署好了极景。這種方式能夠保證每次得到的環(huán)境都是一樣的察净。容器比虛擬機強的地方在于,它占用系統(tǒng)資源更少戴陡,生成時間更短塞绿。創(chuàng)建一個容器的耗時一般是秒級的,而虛擬機是分鐘級的恤批。容器鏡像的創(chuàng)建效率取決于它的大小异吻,一般來講容器鏡像越小,它的生成時間越短喜庞。
下面就是一個“nginx”的Dockerfile示例诀浪。

FROM alpine:3.2
EXPOSE 80 443
RUN apk add --update nginx && \
rm -rf /var/cache/apk/* && \
mkdir -p /tmp/nginx/client-body
COPY ./nginx.conf /etc/nginx/nginx.conf
VOLUME ["/etc/nginx/sites-enabled", "/etc/nginx/certs", "/etc/nginx/conf.d"]
CMD ["nginx", "-g", "daemon off;"]

任何Dockerfile的第一句總是“FROM 。延都。雷猪。”晰房,就是要創(chuàng)建一個Linux的運行環(huán)境求摇。一般有以下幾種:

  • FROM ubuntu:18.04: 按照Linux的具體版本來創(chuàng)建鏡像射沟,這樣的Linux運行環(huán)境是比較完整的,鏡像的大小是百兆級別的与境。
  • FROM alpine:latest : alpine是一個 精簡了的Linux運行環(huán)境验夯,它的大小是十兆級別的。
  • FROM scratch : scratch是最小Linux運行環(huán)境摔刁,創(chuàng)建非郴幼快,但它的問題是你不能通過shell登錄到容器內(nèi)部共屈,因此我一般不用它绑谣。

當(dāng)用Vagrant管理虛擬機時,可以先用Vagrant命令啟動虛擬機拗引,然后敲入vagrant ssh借宵,進入虛擬機,系統(tǒng)顯示:

PS E:\app2\kub> vagrant ssh
Last login: Sat Sep 28 06:56:11 2019 from 10.0.2.2

然后鍵入“docker run --name docker-nginx -p 8001:80 nginx”運行Nginx鏡像寺擂。"docker-nginx"是容器的名字暇务,“--name”是名字的參數(shù)選項≌恚“-p”表示端口映射,把虛擬機的“8001”端口映射到容器的“80”端口(Nginx的缺省端口)择镇〉脖疲“nginx”是鏡像的名字,如果本地沒有找到“Nginx”鏡像腻豌,系統(tǒng)會自動從Docker鏡像庫里下載Nginx鏡像到本地家坎,然后再運行,這個鏡像有比較完整的Linux系統(tǒng)吝梅,因此文件比較大(100M)虱疏,但也可以湊活著用。命令運行之后苏携,顯示:

vagrant@ubuntu-xenial:~$ docker run --name docker-nginx -p 8001:80 nginx

這時Nginx已經(jīng)運行做瞪,但還沒有任何請求,控制臺沒有輸出右冻。如果名字為“docker-nginx”的容器以前已經(jīng)被運行装蓬,那么你需要刪除原來的,再運行上面命令纱扭‰怪悖可以先敲入“docker ps -a”找到所有運行過的容器,再敲入“docker rm 1ec2e3d63537”進行刪除乳蛾,其中“ 1ec2e3d63537”是容器ID.

切換到另一個虛擬機窗口暗赶,敲入curl localhost:8001鄙币,顯示:

vagrant@ubuntu-xenial:/usr/bin$ curl localhost:8001
...
<h1>Welcome to nginx!</h1>
...

這時就出現(xiàn)了Nginx的首頁,表示Docker容器中的Nginx已經(jīng)正常運行蹂随。

換回原容器顯示窗口十嘿,這時有了請求,控制臺輸出Nginx日志糙及。

vagrant@ubuntu-xenial:~$ docker run --name docker-nginx -p 8001:80 nginx
172.17.0.1 - - [28/Sep/2019:07:02:25 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.47.0" "-"

這時已驗證Docker鏡像是好的详幽,敲入“CTRL-C”退出。

Pod:

Pod是k8是的最基本概念浸锨,你可以把它看成是對容器(container)的一個封裝唇聘,用來管理容器。一個Pod里可以有一個或多個容器柱搜,但一般是一個迟郎。Pod里的所有容器都共享Pod的資源和網(wǎng)絡(luò)。當(dāng)一個Pod不能滿足用戶需求時聪蘸,你可以把Pod作為復(fù)制的最小單元來復(fù)制出一個同樣的Pod來處理用戶請求宪肖。Pod支持多種容器,不過一般是用Docker健爬。你可以用單獨的Pod配置文件創(chuàng)建Pod, 也可以把Pod的配置信息放在其他的對象(例如Deployment)的配置文件里面控乾,并與其他對象一起創(chuàng)建,后者更為常見娜遵。每一個Pod都有一個唯一的IP地址蜕衡,Pod一旦生成就可以通過IP地址進行訪問。但一般不這么做设拟,而是通過服務(wù)(Service)去間接地去訪問慨仿。下面就是Pod的配置文件。它的解釋放在后面的Deployment里面纳胧。

kind: Pod
apiVersion: v1
metadata:
  labels:
        app: nginx-app
spec:
  containers:
    - name: nginx-container
      image: nginx:latest
  restartPolicy: Never  

Pod模板(Pod Templates)

Pod模板是嵌入在其他K8s對象(Object)中的Pod的配置說明镰吆,例如Replication Controllers, Jobs, 和DaemonSets. 這時,Pod不是單獨創(chuàng)建的跑慕,而是由其它對象來創(chuàng)建万皿,其中最常用的是Deployment。

部署(Deployment):

Deployment是比Pod更高一層的對象相赁,它的主要作用是管理Pod集群相寇,它里面可以有一個或多個Pod, 每一個Pod在功能上都是等同的。一般在Deployment里配置多個Pod以實現(xiàn)負載均衡和容錯钮科。在配置Deployment時唤衫,你需要指定Pod拷貝的個數(shù),Deployment會自動管理它里面的Pod绵脯。當(dāng)某個Pod宕機時佳励,Deployment能自動復(fù)制一個新的Pod并替換宕機的Pod休里,

下面就是Deployment的配置文件(nginx-deployment.yaml)。在正方形灰框內(nèi)(從template開始)的是嵌入在Deployment里的Pod的設(shè)置赃承,灰框上面的是部署(Deployment)的設(shè)置妙黍。當(dāng)你運行這個配置文件時,它會創(chuàng)建一個Deployment瞧剖,同時也會創(chuàng)建嵌入在里面的Pod拭嫁。這就是為什么我們一般不需要單獨的Pod的配置文件,因為已經(jīng)把它嵌入在了Deployment里了抓于。

file

鍵入“kubectl create -f nginx-deployment.yaml”來運行這個部署做粤,顯示:

vagrant@ubuntu-xenial:~/dockerimages/kubernetes/nginx$ kubectl create -f nginx-deployment.yaml
deployment.apps/nginx-deployment created

這時部署已經(jīng)成功,現(xiàn)在就可以訪問它了捉撮。每個Pod都有自己的k8s集群內(nèi)部IP地址怕品,我們這時只能在K8s內(nèi)部用IP地址進行訪問。鍵入下面命令查看Pod地址巾遭,里面有兩個“Nginx”Pod肉康,因為Deployment里面是兩個Pod的集群。

vagrant@ubuntu-xenial:~/nginx$ kubectl get pods -o=custom-columns=NAME:.metadata.name,IP:.status.podIP
NAME                                IP
hello-minikube-856979d68c-74c65     172.17.0.3
nginx-deployment-77fff558d7-bhbbt   172.17.0.10
nginx-deployment-77fff558d7-v6zqw   172.17.0.9

打開另一個窗口灼舍,連入虛擬機吼和,然后鍵入以下命令“kubectl exec -ti hello-minikube-856979d68c-74c65 -- /bin/sh”登錄到k8s集群內(nèi)部,就能訪問Nginx了骑素。這里“hello-minikube-856979d68c-74c65”是"Minikube"Pod的名字纹安。“172.17.0.10”是其中一個Pod的內(nèi)部IP地址砂豌。

vagrant@ubuntu-xenial:~$ kubectl exec -ti hello-minikube-856979d68c-74c65 -- /bin/sh
# curl 172.17.0.10

服務(wù)(Service):

Service是最上層的k8s的對象,可以看成我們平常說的微服務(wù)光督。對服務(wù)來講最重要的就是服務(wù)注冊和發(fā)現(xiàn)阳距。在k8s中,Service就是用來實現(xiàn)這個功能的结借。下面就是Service的配置文件(nginx-service.yaml)筐摘。一般來說調(diào)用服務(wù)需要知道三個東西,IP地址船老,協(xié)議和端口咖熟,例如"http://10.0.2.1:80". 但我們不想用IP,而是用名字來尋址柳畔,這就需要DNS馍管。DNS在k8s集群內(nèi)部實現(xiàn)了基于服務(wù)名的尋址。下面是Service的配置文件薪韩。Service通過“selector”來與Pod進行綁定确沸,這里它把請求轉(zhuǎn)發(fā)給標(biāo)簽“app”是“nginx-app”的Pod捌锭。“nodePort”給服務(wù)創(chuàng)建了一個外部可以訪問的端口罗捎,這樣在虛擬機上就可以直接訪問服務(wù)观谦,而不必登錄到k8s集群里。

file

運行以下命令“kubectl create -f nginx-service.yaml”創(chuàng)建服務(wù)桨菜。

vagrant@ubuntu-xenial:~/$ kubectl create -f nginx-service.yaml
service/nginx-service created

服務(wù)創(chuàng)建完成之后豁状,運行以下命令顯示當(dāng)前的所有服務(wù), 現(xiàn)在就有了“nginx-service”服務(wù)倒得⌒汉欤“80”是服務(wù)的內(nèi)部端口,“30163”是服務(wù)的外部端口屎暇。

vagrant@ubuntu-xenial:~/$ kubectl get services
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kubernetes      ClusterIP   10.96.0.1      <none>        443/TCP        35d
nginx-service   NodePort    10.109.7.249   <none>        80:30163/TCP   18s

因為已經(jīng)通過“NodePort”對外開放了端口承桥,現(xiàn)在不必登錄到k8s內(nèi)部,在虛擬機上就可以訪問服務(wù)了. 你可以鍵入“l(fā)ocalhost”

curl localhost:30163

Service 和Deployment的區(qū)別:

Deployment是用來管理集群的根悼,與Pod綁定凶异,但你不能直接訪問Deployment。服務(wù)(Service)是為了方便用名字(而不是IP地址)訪問挤巡。但這也只是在集群內(nèi)部剩彬。你可以登錄k8s集群內(nèi)部,然后鍵入下面命令訪問服務(wù)矿卑。

# curl nginx-service

但在虛擬機上(k8s外面)就不行, 這時只能用IP地址喉恋。因為DNS只是在k8s內(nèi)部才起作用。

節(jié)點(Node):

Node剛開始接觸時容易和Pod搞混母廷,但它相當(dāng)于虛擬機或物理機轻黑,而Pod相當(dāng)于容器。所有的的Pod或容器都是部署在Node上面琴昆。Minikube只支持單Node氓鄙,但你可以在它里面部署多個Pod。下面是Node示意圖业舍。

file

圖片來源

k8s核心概念之間的關(guān)系:

對象間關(guān)系:

下面是k8s的一個簡單結(jié)構(gòu)圖:

file

圖片來源

圖中每個菱形是一個Node抖拦,中間的Node是Master Node,其余三個是Worker Node舷暮。Master Node負責(zé)管理Worker Node态罪。 Worker Node是真正干活的Node。Master Node里有各種控制器下面,Deployment就是由控制器來管理的复颈,它在中間的管理Node里,他里面有兩個部署诸狭,A和B券膀,分別對應(yīng)服務(wù)A和服務(wù)B君纫。“服務(wù)A”部署在最下面的Node里芹彬,它里面只有一個Pod蓄髓。“服務(wù)B”部署在上面的兩個Node里舒帮,左邊的Node只有一個Pod会喝,右邊的Node有兩個Pod,這是一個有三個Pod的集群玩郊。當(dāng)一個部署里有多個Pod時肢执,一般是把它們部署在不同的Node上,這樣即使一個Node宕機译红,Deployment仍然可用预茄。

對象綁定:

下圖是介紹對象之間如何綁定的關(guān)系圖。

file

圖片來源

每個對象都有多個標(biāo)簽(Label)侦厚,“app”就是一個用來標(biāo)識Pod對象的標(biāo)簽耻陕。圖里有兩個Pod,它們的“app”標(biāo)簽的值分別為“A”和“B”刨沦,其中Pod “B”是集群诗宣,而Pod “A”不是。服務(wù)(Service)和部署(Deployment)都通過標(biāo)簽選擇器(Label Selector)來綁定與之匹配的Pod想诅。

附錄:

你最好是已經(jīng)安裝了k8s和Docker環(huán)境召庞,那就可以依次運行本文中的示例。如果你沒有環(huán)境来破,新建一個也不難篮灼。如果你不愿意創(chuàng)建環(huán)境, k8s的官網(wǎng)有一個練習(xí)環(huán)境,可以直接用來運行命令徘禁,詳見這里

索引:

  1. Kubernetes
  2. Docker
  3. Windows
  4. Minikube
  5. Kubernetes Basics

本文由博客一文多發(fā)平臺 OpenWrite 發(fā)布穿稳!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市晌坤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌旦袋,老刑警劉巖骤菠,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異疤孕,居然都是意外死亡商乎,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門祭阀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來鹉戚,“玉大人鲜戒,你說我怎么就攤上這事∧ǖ剩” “怎么了遏餐?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長赢底。 經(jīng)常有香客問我失都,道長,這世上最難降的妖魔是什么幸冻? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任粹庞,我火速辦了婚禮,結(jié)果婚禮上洽损,老公的妹妹穿的比我還像新娘庞溜。我一直安慰自己,他們只是感情好碑定,可當(dāng)我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布流码。 她就那樣靜靜地躺著,像睡著了一般不傅。 火紅的嫁衣襯著肌膚如雪旅掂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天访娶,我揣著相機與錄音商虐,去河邊找鬼。 笑死崖疤,一個胖子當(dāng)著我的面吹牛秘车,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播劫哼,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼叮趴,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了权烧?” 一聲冷哼從身側(cè)響起眯亦,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎般码,沒想到半個月后妻率,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡板祝,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年宫静,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡孤里,死狀恐怖伏伯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情捌袜,我是刑警寧澤说搅,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站琢蛤,受9級特大地震影響蜓堕,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜博其,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一套才、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧慕淡,春花似錦背伴、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至携兵,卻和暖如春疾掰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背徐紧。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工静檬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人并级。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓拂檩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親嘲碧。 傳聞我的和親對象是個殘疾皇子稻励,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內(nèi)容