《精通Docker第三版》完整目錄:
第一章 Docker概覽
第二章 創(chuàng)建容器鏡像
第三章 存儲(chǔ)和發(fā)布鏡像
第四章 管理容器
第五章 Docker Compose
第六章 Windows容器
第七章 Docker Machine
第八章 Docker Swarm
第九章 Docker和Kubernetes
第十章 在公有云上運(yùn)行Docker
第十一章 Portainer - 一個(gè)Docker的GUI
第十二章 Docker安全
第十三章 Docker工作流
第十四章 Docker進(jìn)階
本章中惠呼,我們一起來(lái)看Kubernetes。和Docker Swarm相似,我們可以使用Kubernetes來(lái)創(chuàng)建和管理用于運(yùn)行基于容器的應(yīng)用集群瞧哟。
本章涵蓋的主要內(nèi)容有:
- Kubernetes的介紹
- 啟動(dòng)Kubernetes
- 使用Kubernetes
- Kubernetes和其它Docker工具
技術(shù)準(zhǔn)備
Docker中的Kubernetes只支由Docker for Mac和Docker for Windows支持紫岩。和此前章節(jié)一樣,作者將使用自己偏好的操作系統(tǒng)macOS。同樣棘劣,其中極少數(shù)據(jù)的支持命令可能只在macOS中使用山宾。
Kubernetes簡(jiǎn)介
如果你有了解容器至扰,那么總會(huì)在某個(gè)地方碰到Kubernetes,在Docker桌面軟件中啟動(dòng)它之前资锰,我們先花點(diǎn)時(shí)間了解下Kubernetes的前世今身敢课。
Kubernetes(音koo-ber-net-eez)來(lái)自給予舵手或船長(zhǎng)的希臘名稱。Kubernetes(也稱為K8s)绷杜,是一個(gè)起源于Google的開源項(xiàng)目直秆,允許我們自動(dòng)化部署、管理和擴(kuò)容容器化應(yīng)用鞭盟。
Google的容器簡(jiǎn)史
Google對(duì)于Linux容器解決方案的研究歷時(shí)已久圾结。2016年邁出了第一步,開發(fā)Linux內(nèi)核稱作控制組(cgroups)的功能齿诉。這一功能于2008年合并到了Linux發(fā)行版2.6.24的內(nèi)核中筝野。該功能讓我們可以隔離資源,如CPU粤剧、RAM歇竟、網(wǎng)絡(luò)和磁盤I/O,或一個(gè)或多個(gè)進(jìn)程抵恋』酪椋控制組仍然是Linux容器的核心組成并為Docker及其它容器工具所使用。
Google接著以名為lmctfy的容器棧涉足容器領(lǐng)域馋记,它是Let Me Contain That For You的縮寫号坡。這是LXC的工具集和庫(kù)的一個(gè)替代。這是 Google 內(nèi)部在自己應(yīng)用內(nèi)用于管理容器的工具的一個(gè)開源版本梯醒。
譯者注:LXC 表示 Linux Container宽堆,即 Linux 容器。
接著Google再次成為容器使用新聞熱點(diǎn)是在2014年5月的Gluecon上Joe Beda進(jìn)行講話之后 茸习。在講話期間畜隶,Beda透露Google當(dāng)時(shí)幾乎所有業(yè)務(wù)都基于容器,以及他們每周會(huì)啟動(dòng)近20億個(gè)容器。并聲稱這一數(shù)字并不包含長(zhǎng)期運(yùn)行的容器籽慢,也就是說(shuō)這些容器都是供短期使用的浸遗。但是進(jìn)行快速的數(shù)學(xué)計(jì)算之后,這表示Google平均每秒會(huì)啟動(dòng)3000個(gè)容器箱亿。
在講話的后半段蒋伦,Beda提及Google使用了調(diào)度器這樣他們無(wú)需每周手動(dòng)管理20億個(gè)容器赐劣,或擔(dān)心容器在哪里啟動(dòng)乃至容器的可用性。
Google還發(fā)布了一篇名為L(zhǎng)arge-scale cluster management at Google with Borg(Google 使用 Borg 進(jìn)行大規(guī)模集群的管理)的論文。該論文不僅讓Google以外的人知道了他們使用的調(diào)度器的名稱渊啰,Borg荣病,還深入到了在設(shè)計(jì)調(diào)度器時(shí)做設(shè)計(jì)決策的細(xì)節(jié)坐慰。
該論文也提到了他們的內(nèi)部工具馁蒂,Google在容器運(yùn)行集群中運(yùn)行面向用戶的應(yīng)用,如 Google Docs瘩欺、Gmail和Google 搜索必盖,都是由Borg進(jìn)行管理。
Borg使用電視節(jié)目星際迷航:下一代的外星種族Borg來(lái)進(jìn)行命名俱饿。在電視節(jié)目中歌粥,Borg是一種半機(jī)械生物,它們的文明基于稱為“集合體”的集體意識(shí)稍途。這使他們不僅可以共享相同的想法阁吝,同時(shí)通過(guò)子空間網(wǎng)絡(luò),確保每個(gè)集合體的成員透過(guò)集體意識(shí)給予指導(dǎo)和監(jiān)督械拍。相信你也會(huì)同意突勇,Borg種族的特征與我們希望運(yùn)行的容器集群匹配度極高。
Borg在Google內(nèi)部使用了好幾年坷虑,最終由名為Omega的調(diào)試器替代甲馋。大約是這個(gè)時(shí)候Google聲明會(huì)拿出一些Borg的核心功能,將其重塑為一個(gè)開源項(xiàng)目迄损。這個(gè)項(xiàng)目?jī)?nèi)部稱之為Seven定躏,由多名Borg的核心貢獻(xiàn)人員操刀。目標(biāo)在于創(chuàng)建一個(gè)版本更為友好的Borg芹敌,脫離Google自己的內(nèi)部流程和工作方式痊远。
Seven,取名自星際迷航:航海家號(hào)中的人物氏捞,九之七(Seven of Nine)是從集合體中解放出來(lái)的博格個(gè)體碧聪,最終在首次對(duì)外提交時(shí)使用了Kubernetes這一名稱。
Kubernetes概覽
那么液茎,現(xiàn)在我們知道了Kubernetes的由來(lái)逞姿,可以更深入的挖掘Kubernetes是什么了辞嗡。該項(xiàng)目的大部分,確切地說(shuō)是88.5%滞造,由 Go 語(yǔ)言編寫续室,這不足為奇,因?yàn)镚o在2011年開源之前是由Google內(nèi)部開發(fā)的一種編程語(yǔ)言谒养。此項(xiàng)目的其它部分文件由Python和Shell幫助腳本和HTML文檔組成挺狰。
一個(gè)典型的Kubernetes集群由角色為master或node服務(wù)器組成。你可以對(duì)這兩種角色的節(jié)點(diǎn)進(jìn)行單獨(dú)安裝蝴光。
master角色是神奇發(fā)生的地方她渴,同時(shí)也是集群的大腦达址。它負(fù)責(zé)決定在何處啟動(dòng)pod蔑祟,并且監(jiān)控集群本身以及集群內(nèi)運(yùn)行的pod的健康狀況。我們?cè)诹私饬诉@兩個(gè)角色之后會(huì)來(lái)討論pod沉唠。
通常疆虚,核心組件會(huì)部署到角色分配為master的主機(jī)上:
- kube-apiserver:這個(gè)組件暴露主Kubernetes API。它設(shè)計(jì)為橫向擴(kuò)展满葛,這表示你可以持續(xù)添加更多的實(shí)例來(lái)讓集群保持高可用径簿。
- etcd:這是一個(gè)高可用一致性鍵值存儲(chǔ)。用于存儲(chǔ)集群的狀態(tài)嘀韧。
- kube-scheduler:這個(gè)組件負(fù)責(zé)決定pod在哪里啟動(dòng)篇亭。
- kube-controller-manager:這一組件運(yùn)行控制器。這些控制器在Kubernetes中有多個(gè)功能锄贷,如監(jiān)控節(jié)點(diǎn)译蒂,監(jiān)測(cè)應(yīng)用、管理端點(diǎn)(endpoint)以及生成服務(wù)賬號(hào)和令牌谊却。
- cloud-controller-manager:這一組件管理處個(gè)控制器柔昼,與第三方去進(jìn)行交互來(lái)啟動(dòng)和配置支持服務(wù)。
上面講解了管理組件炎辨,下面需要討論它們所管理的內(nèi)容是什么捕透。node由如下組件構(gòu)成:
- kubelet:這個(gè)代理(agent)運(yùn)行在集群內(nèi)的node上,它是管理節(jié)點(diǎn)與node進(jìn)行交互的方式碴萧。也負(fù)責(zé)管理各個(gè)pod乙嘀。
- kube-proxy::這個(gè)組件管理所有的請(qǐng)求路由以及node和pod的通訊。
- container runtime:可以是Docker RKT或任意遵循OCI(Oracle Call Interface)的運(yùn)行時(shí)破喻。
你可能注意到了到此我們沒提到容器虎谢。這是因?yàn)镵ubernetes實(shí)際上不直接與容器進(jìn)行交互,它與pod進(jìn)行通訊低缩。把pod看作一個(gè)完整的應(yīng)用嘉冒,有點(diǎn)像我們使用Docker Compose啟動(dòng)多個(gè)容器的應(yīng)用曹货。
Kubernetes和Docker
Kubernetes最早被視作Docker自己的集群技術(shù)Docker Swarm的競(jìng)品。但通過(guò)這幾年的發(fā)展讳推,Kubernetes實(shí)際上已成為容器編排的標(biāo)準(zhǔn)了顶籽。
所有主流云提供商都提供Kubernetes即服務(wù)。有如下這些:
- 谷歌云: Google Kubernetes引擎(GKE)
- Microsoft Azure: Azure Kubernetes服務(wù)(AKS)
- Amazon Web Services: Amazon的Kubernetes彈性容器服務(wù) (EKS)
- IBM: IBM云Kubernetes服務(wù)
- 甲骨文云: Oracle的Kubernetes容器引擎
- DigitalOcean: DigitalOcean上的Kubernetes
表面上银觅,所有這些主流玩家支持Kubernetes可能并沒有什么了不起的礼饱。但別忘了我們可以在跨多平臺(tái)部署容器化應(yīng)用并保持一致性。以前究驴,這些平臺(tái)被稱作后花園镊绪,與它們交互的方式非常的不同。
在Docker在2017年10月初次發(fā)表聲明時(shí)普遍表示驚訝洒忧,但塵埃落定時(shí)又是那么的理所當(dāng)然蝴韭。使用Docker for Mac和Docker for Windows為開發(fā)人員提供可以在本地操作應(yīng)用,然后使用Docker企業(yè)版來(lái)部署和管理自己的Kubernetes集群熙侍,甚至是使用前述的一種云服務(wù)榄鉴,與我們?cè)?a target="_blank" rel="nofollow">第一章 Docker概覽中討論的“像在本機(jī)操作”非常契合。
下面我們來(lái)看如何在Docker軟件中啟動(dòng)Kubernetes支持并進(jìn)一步的進(jìn)行使用蛉抓。
啟動(dòng)Kubernetes
Docker上Kubernetes的安裝過(guò)程極為簡(jiǎn)單庆尘。啟動(dòng)Kubernetes支持,我們只需要打開Preferences并點(diǎn)擊Kubernetes選項(xiàng)卡:
可以看到巷送,有三個(gè)主選項(xiàng)驶忌。勾選Enable Kubernetes復(fù)選框,然后選擇Deploy Docker Stacks to Kubernetes by default笑跛。先不勾選Show systems containers付魔,我們會(huì)在啟動(dòng)服務(wù)后再來(lái)看更多的細(xì)節(jié)。點(diǎn)擊Apply會(huì)彈出如下信息:
點(diǎn)擊Install按鈕會(huì)下載所需的容器來(lái)在Docker軟件上啟動(dòng)Kubernetes的支持:
像前面的一個(gè)對(duì)話框中所提示的那樣堡牡,Docker會(huì)需要不些時(shí)間來(lái)進(jìn)行下載抒抬、配置和啟動(dòng)該集群。完成后晤柄,你會(huì)看到Kubernetes is running旁邊有綠點(diǎn):
打開Terminal并運(yùn)行如下命令:
$ docker container ls -a
正常運(yùn)行后不會(huì)顯示任何容器擦剑。運(yùn)行如下命令:
$ docker image ls
這會(huì)列出Kubernetes相關(guān)的鏡像:
k8s.gcr.io/kube-proxy-amd64
k8s.gcr.io/kube-apiserver-amd64
k8s.gcr.io/kube-controller-manager-amd64
k8s.gcr.io/kube-scheduler-amd64
docker/kube-compose-controller
docker/kube-compose-api-server
k8s.gcr.io/etcd-amd64
k8s.gcr.io/k8s-dns-dnsmasq-nanny-amd64
k8s.gcr.io/k8s-dns-sidecar-amd64
k8s.gcr.io/k8s-dns-kube-dns-amd64
k8s.gcr.io/pause-amd64
這些鏡像的源為Docker和Google容器倉(cāng)庫(kù)(k8s.gcr.io)所提供的官方Kubernetes。
你可能已經(jīng)猜到芥颈,勾選Show system containers (advanced)復(fù)選框惠勒,然后運(yùn)行以下命令會(huì)列出在本地Docker軟件上啟動(dòng)Kubernetes服務(wù)所有運(yùn)行的容器:
$ docker container ls -a
因?yàn)檫\(yùn)行上述命令會(huì)有大量輸出,以下僅顯示容器的名稱爬坑。通過(guò)運(yùn)行如下命令來(lái)進(jìn)行實(shí)現(xiàn):
$ docker container ls --format {{.Names}}
運(yùn)行該命令會(huì)得到如下輸出:
$ docker container ls --format {{.Names}}
k8s_compose_compose-74649b4db6-j4t8r_docker_184e337c-658d-11e9-9fe6-025000000001_0
k8s_compose_compose-api-79c95fc7d6-gbkq4_docker_18464718-658d-11e9-9fe6-025000000001_0
k8s_POD_compose-74649b4db6-j4t8r_docker_184e337c-658d-11e9-9fe6-025000000001_0
k8s_POD_compose-api-79c95fc7d6-gbkq4_docker_18464718-658d-11e9-9fe6-025000000001_0
k8s_sidecar_kube-dns-86f4d74b45-mjtp8_kube-system_f0ce645a-658c-11e9-9fe6-025000000001_0
k8s_dnsmasq_kube-dns-86f4d74b45-mjtp8_kube-system_f0ce645a-658c-11e9-9fe6-025000000001_0
k8s_kubedns_kube-dns-86f4d74b45-mjtp8_kube-system_f0ce645a-658c-11e9-9fe6-025000000001_0
k8s_kube-proxy_kube-proxy-jsf94_kube-system_f0c7ceb6-658c-11e9-9fe6-025000000001_0
k8s_POD_kube-dns-86f4d74b45-mjtp8_kube-system_f0ce645a-658c-11e9-9fe6-025000000001_0
k8s_POD_kube-proxy-jsf94_kube-system_f0c7ceb6-658c-11e9-9fe6-025000000001_0
k8s_kube-scheduler_kube-scheduler-docker-for-desktop_kube-system_ecf299f4fa454da5ab299dffcd70c70f_0
k8s_kube-apiserver_kube-apiserver-docker-for-desktop_kube-system_7fbb107871a3c31e9b65e5e5aa8427e9_0
k8s_kube-controller-manager_kube-controller-manager-docker-for-desktop_kube-system_5fd9f57b2e532f401708dfe8a8bcc3c2_0
k8s_etcd_etcd-docker-for-desktop_kube-system_37c1035b2a8313813aad96455cd61937_0
k8s_POD_kube-scheduler-docker-for-desktop_kube-system_ecf299f4fa454da5ab299dffcd70c70f_0
k8s_POD_kube-controller-manager-docker-for-desktop_kube-system_5fd9f57b2e532f401708dfe8a8bcc3c2_0
k8s_POD_kube-apiserver-docker-for-desktop_kube-system_7fbb107871a3c31e9b65e5e5aa8427e9_0
k8s_POD_etcd-docker-for-desktop_kube-system_37c1035b2a8313813aad96455cd61937_0
有18個(gè)運(yùn)行中的容器纠屋,這也是存在隱藏它們的原因《芗疲可以看到幾乎所有我們?cè)谇耙徊糠钟懻摰慕M件以及其它一些提供Docker集成的組件售担。我會(huì)推薦不勾選Show system containers的選項(xiàng)赁遗,因?yàn)槲覀儾恍枰诿看尾榭催\(yùn)行中的容器時(shí)看到這18個(gè)容器。
這里另一件需要注意的事情是Kubernetes的菜單項(xiàng)中有內(nèi)容了族铆。這一菜單可用于在Kubernetes集群間進(jìn)行切換岩四。因?yàn)楫?dāng)前我們只有一個(gè)活躍的集群,因此只列出了一個(gè):
現(xiàn)在我們本地的Kubernetes已啟動(dòng)并運(yùn)行哥攘,下面就開始使用它吧剖煌。
使用Kubernetes
我們已經(jīng)在Docker桌面軟件上啟動(dòng)和運(yùn)行了Kubernetes集群,可以開始與其進(jìn)行交互了逝淹。先來(lái)看與Docker桌面組件一起安裝的命令kubectl耕姊。
前面已提到,kubectl同時(shí)進(jìn)行了安裝栅葡。如下命令會(huì)顯示客戶端及其所連接到的集群的相關(guān)信息:
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"12", GitVersion:"v1.12.2", GitCommit:"17c77c7898218073f14c8d573582e8d2313dc740", GitTreeState:"clean", BuildDate:"2018-11-26T13:25:32Z", GoVersion:"go1.11.2", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.11", GitCommit:"637c7e288581ee40ab4ca210618a89a555b6e7e9", GitTreeState:"clean", BuildDate:"2018-11-26T14:25:46Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"}
接下來(lái)運(yùn)行如下命令來(lái)看kubectl是否能識(shí)別到我們的node:
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
docker-for-desktop Ready master 1h v1.10.11
既然我們已經(jīng)有了與node進(jìn)行交互的客戶端茉兰,就可以通過(guò)運(yùn)行如下命令來(lái)查看在Kubernetes中默認(rèn)配置的命名空間:
$ kubectl get namespaces
然后通過(guò)如下命令來(lái)在命名空間中查看pod:
$ kubectl get --namespace kube-system pods
$ kubectl get namespaces
NAME STATUS AGE
default Active 1h
docker Active 1h
kube-public Active 1h
kube-system Active 1h
$ kubectl get --namespace kube-system pods
NAME READY STATUS RESTARTS AGE
etcd-docker-for-desktop 1/1 Running 0 1h
kube-apiserver-docker-for-desktop 1/1 Running 0 1h
kube-controller-manager-docker-for-desktop 1/1 Running 0 1h
kube-dns-86f4d74b45-mjtp8 3/3 Running 0 1h
kube-proxy-jsf94 1/1 Running 0 1h
kube-scheduler-docker-for-desktop 1/1 Running 0 1h
Kubernetes中的命名空間是集群內(nèi)隔離資源的一種很好的方式⊥孜罚可以在Terminal的輸出中看到邦邦,集群內(nèi)有四個(gè)命名空間。有default命名空間醉蚁,通常為空。兩個(gè)主Kubernetes服務(wù)的命名空間:docker和kube-system鬼店。這些包含組成我們集群的pod以及最后一個(gè)命名空間网棍,kube-public,類似default妇智,為空滥玷。
在我們啟動(dòng)自己的pod之前,先快速地查看下如何與我們運(yùn)行的pod進(jìn)行交互巍棱,首先了解如何查找我們pod的更多信息:
$ kubectl describe --namespace kube-system pods kube-scheduler-docker-for-desktop
以上命令會(huì)打印出kube-scheduler-docker-for-desktop這一pod的明細(xì)信息惑畴。你可能注意到我們需要使用--namespace 來(lái)傳遞命名空間。如果不傳遞航徙,那么kubectl會(huì)默認(rèn)使用沒有名為kube-scheduler-docker-for-desktop在運(yùn)行的default命名空間如贷。
該命令的完整輸出如下所示:
Name: kube-scheduler-docker-for-desktop
Namespace: kube-system
Node: docker-for-desktop/192.168.65.3
Start Time: Tue, 23 Apr 2019 15:00:43 +0800
Labels: component=kube-scheduler
tier=control-plane
Annotations: kubernetes.io/config.hash: ecf299f4fa454da5ab299dffcd70c70f
kubernetes.io/config.mirror: ecf299f4fa454da5ab299dffcd70c70f
kubernetes.io/config.seen: 2019-04-23T05:56:03.9921627Z
kubernetes.io/config.source: file
scheduler.alpha.kubernetes.io/critical-pod:
Status: Running
IP: 192.168.65.3
Containers:
kube-scheduler:
Container ID: docker://ceb5a8dbb3b984f785d0c96a98e41a662b2dfb2eb52fb241bf3edd62a98ed717
Image: k8s.gcr.io/kube-scheduler-amd64:v1.10.11
Image ID: docker-pullable://k8s.gcr.io/kube-scheduler-amd64@sha256:3f40a5beec15fe39300d5bac56d6d7b72957afca51d3353aeb77a563f889973c
Port: <none>
Host Port: <none>
Command:
kube-scheduler
--leader-elect=true
--kubeconfig=/etc/kubernetes/scheduler.conf
--address=127.0.0.1
State: Running
Started: Tue, 23 Apr 2019 15:00:44 +0800
Ready: True
Restart Count: 0
Requests:
cpu: 100m
Liveness: http-get http://127.0.0.1:10251/healthz delay=15s timeout=15s period=10s #success=1 #failure=8
Environment: <none>
Mounts:
/etc/kubernetes/scheduler.conf from kubeconfig (ro)
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
kubeconfig:
Type: HostPath (bare host directory volume)
Path: /etc/kubernetes/scheduler.conf
HostPathType: FileOrCreate
QoS Class: Burstable
Node-Selectors: <none>
Tolerations: :NoExecute
Events: <none>
可以看到有關(guān)這一pod的大量信息,包含容器列表到踏,我們只有一個(gè)杠袱,名為kube-scheduler。我們還可以看到鏡像所使用的容器ID窝稿,容器啟動(dòng)使用的標(biāo)記楣富,以及Kubernetes調(diào)度器用于啟動(dòng)和維護(hù)該pod的數(shù)據(jù)。
我們已經(jīng)知道了容器名伴榔,可以開始與其進(jìn)行交互纹蝴。例如庄萎,運(yùn)行如下命令會(huì)打印出我們這一容器的日志:
$ kubectl logs --namespace kube-system kube-scheduler-docker-for-desktop -c kube-scheduler
W0423 07:00:44.837759 1 server.go:163] WARNING: all flags other than --config are deprecated. Please begin using a config file ASAP.
I0423 07:00:44.844505 1 server.go:555] Version: v1.10.11
I0423 07:00:44.844928 1 server.go:574] starting healthz server on 127.0.0.1:10251
E0423 07:00:51.126897 1 reflector.go:205] k8s.io/kubernetes/cmd/kube-scheduler/app/server.go:594: Failed to list *v1.Pod: pods is forbidden: User "system:kube-scheduler" cannot list pods at the cluster scope
E0423 07:00:51.127282 1 reflector.go:205] k8s.io/kubernetes/vendor/k8s.io/client-go/informers/factory.go:87: Failed to list *v1.StorageClass: storageclasses.storage.k8s.io is forbidden: User "system:kube-scheduler" cannot list storageclasses.storage.k8s.io at the cluster scope
E0423 07:00:51.140152 1 reflector.go:205] k8s.io/kubernetes/vendor/k8s.io/client-go/informers/factory.go:87: Failed to list *v1beta1.ReplicaSet: replicasets.extensions is forbidden: User "system:kube-scheduler" cannot list replicasets.extensions at the cluster scope
...
運(yùn)行如下命令會(huì)獲取pod中的每個(gè)容器的日志:
$ kubectl logs --namespace kube-system kube-scheduler-docker-for-desktop
類似Docker,你還可以對(duì)pod和容器執(zhí)行命令塘安。例如惨恭,如下命令會(huì)運(yùn)行uname -a 命令:
小貼士:確保在如下兩個(gè)命令的 -- 后添加空格。不加的話會(huì)產(chǎn)生報(bào)錯(cuò)耙旦。
$ kubectl exec --namespace kube-system kube-scheduler-docker-for-desktop -c kube-scheduler -- uname -a
$ kubectl exec --namespace kube-system kube-scheduler-docker-for-desktop -- uname -a
同樣脱羡,我們可以對(duì)指定名稱的容器或pod中的所有容器運(yùn)行該命令:
$ kubectl exec --namespace kube-system kube-scheduler-docker-for-desktop -c kube-scheduler -- uname -a
Linux linuxkit-025000000001 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 GNU/Linux
我們?cè)賮?lái)通過(guò)安裝和向基于 web 的儀表盤記錄日志來(lái)進(jìn)一步了解Kubernetes。雖然Docker默認(rèn)并不包含免都,通過(guò)Kubernetes項(xiàng)目提供的定義文件來(lái)安裝非常之簡(jiǎn)單锉罐。我們只需要運(yùn)行如下命令:
$ kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended/kubernetes-dashboard.yaml
secret/kubernetes-dashboard-certs created
secret/kubernetes-dashboard-csrf created
serviceaccount/kubernetes-dashboard created
role.rbac.authorization.k8s.io/kubernetes-dashboard-minimal created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard-minimal created
deployment.apps/kubernetes-dashboard created
service/kubernetes-dashboard created
服務(wù)和部署創(chuàng)建之后,會(huì)需要幾分鐘來(lái)進(jìn)行啟動(dòng)绕娘。你可以通過(guò)運(yùn)行如下命令來(lái)查看狀態(tài):
$ kubectl get deployments --namespace kube-system
$ kubectl get services --namespace kube-system
在輸出像下面這樣時(shí)脓规,儀表盤就安裝并準(zhǔn)備好了:
$ kubectl get deployments --namespace kube-system
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
kube-dns 1 1 1 1 1h
kubernetes-dashboard 1 1 1 1 3m
$ kubectl get services --namespace kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 1h
kubernetes-dashboard ClusterIP 10.103.58.114 <none> 443/TCP 3m
此時(shí)我們的儀表盤已處于運(yùn)行中,我們要找到一種訪問它的方式险领。這可以通過(guò)kubectl中內(nèi)置的proxy服務(wù)侨舆。僅需運(yùn)行如下命令來(lái)將其啟動(dòng):
$ kubectl proxy
Starting to serve on 127.0.0.1:8001
這會(huì)啟動(dòng)proxy,打開瀏覽器訪問http://127.0.0.1:8001/version/會(huì)顯示集群的相關(guān)信息:
但我們想要看的是儀表盤绢陌“は拢可通過(guò)http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/來(lái)進(jìn)行訪問。
首次在瀏覽器中打開這個(gè)URL時(shí)會(huì)出現(xiàn)登錄界面脐湾。因?yàn)槲覀兪峭ㄟ^(guò)proxy來(lái)訪問儀表盤的臭笆,僅需點(diǎn)擊SKIP按鈕:
譯者注:新版的 Kubernetes 強(qiáng)制要求輸出驗(yàn)證信息,沒有再發(fā)現(xiàn) SKIP 按鈕秤掌,可通過(guò)如下命令來(lái)進(jìn)行測(cè)試的 Token
$ kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')
登錄之后愁铺,就可以看到集群上的很多信息了:
現(xiàn)在我們的集群已經(jīng)啟動(dòng)并運(yùn)行了,我們可以啟動(dòng)一些示例應(yīng)用闻鉴。
Kubernetes和其它Docker工具
在啟動(dòng)Kubernetes時(shí)茵乱,我們選擇了將Kubernetes作為Docker的stack命令的默認(rèn)編排器。前一章中孟岛,Docker的stack會(huì)在Docker Swarm中啟動(dòng)我們的Docker Compose文件瓶竭。我們所使用的Docker Compose文件像下面這樣:
version: "3"
services:
cluster:
image: russmckendrick/cluster
ports:
- "80:80"
deploy:
replicas: 6
restart_policy:
condition: on-failure
placement:
constraints:
- node.role == worker
我們?cè)贙ubernetes上啟動(dòng)應(yīng)用之前,需要做一些微調(diào)并刪除placement蚀苛,修改后文件的內(nèi)容如下:
version: "3"
services:
cluster:
image: russmckendrick/cluster
ports:
- "80:80"
deploy:
replicas: 6
restart_policy:
condition: on-failure
編輯了該文件之后在验,運(yùn)行如下命令就會(huì)啟動(dòng)棧:
$ docker stack deploy --compose-file=docker-compose.yml cluster
Waiting for the stack to be stable and running...
cluster: Pending [pod status: 0/1 ready, 1/1 pending, 0/1 fail
cluster: Pending [pod status: 0/2 ready, 2/2 pending, 0/2 fail
cluster: Pending [pod status: 0/3 ready, 3/3 pending, 0/3 fail
cluster: Pending [pod status: 0/4 ready, 4/4 pending, 0/4 fail
cluster: Pending [pod status: 0/5 ready, 5/5 pending, 0/5 fail
cluster: Pending [pod status: 0/6 ready, 6/6 pending, 0/6 fail
cluster: Ready [pod status: 1/6 ready, 5/6 pending, 0/6 failed]
Stack cluster is stable and running
可以看到,Docker會(huì)等待椂挛矗可用后再回到命令提示符腋舌。我們還可以運(yùn)行在Docker Swarm上啟動(dòng)棧后查看棧相關(guān)信息相同的命令:
$ docker stack ls
$ docker stack services cluster
$ docker stack ps cluster
$ docker stack ls
NAME SERVICES ORCHESTRATOR NAMESPACE
cluster 1 Kubernetes default
$ docker stack services cluster
ID NAME MODE REPLICAS IMAGE PORTS
90fb7c7b-65a cluster_cluster replicated 4/6 russmckendrick/cluster *:80->80/tcp
$ docker stack ps cluster
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
90fe64f2-65a cluster_cluster-84879989d7-d4wrd russmckendrick/cluster docker-for-desktop Running Running 54 seconds ago *:0->80/tcp
9100830d-65a cluster_cluster-84879989d7-gqk52 russmckendrick/cluster docker-for-desktop Running Running 54 seconds ago *:0->80/tcp
90ff3630-65a cluster_cluster-84879989d7-jpvlr russmckendrick/cluster docker-for-desktop Running Running 54 seconds ago *:0->80/tcp
90ff33ef-65a cluster_cluster-84879989d7-rrmht russmckendrick/cluster docker-for-desktop Running Running 54 seconds ago *:0->80/tcp
91008a63-65a cluster_cluster-84879989d7-rvpnl russmckendrick/cluster docker-for-desktop Running Running 54 seconds ago *:0->80/tcp
9100924e-65a cluster_cluster-84879989d7-zdpwk russmckendrick/cluster docker-for-desktop Running Running 54 seconds ago *:0->80/tcp
我們還可以使用kubectl來(lái)查看一些細(xì)節(jié):
$ kubectl get deployments
$ kubectl get services
$ kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
cluster 6 6 6 6 1m
n$ kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
cluster ClusterIP None <none> 55555/TCP 1m
cluster-published LoadBalancer 10.96.156.192 localhost 80:31662/TCP 1m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 28m
你可能注意到我們并不需要提供命名空間。這是因?yàn)槲覀兊臈T谀J(rèn)命名空間中啟動(dòng)渗蟹。同時(shí)块饺,在列出服務(wù)時(shí)赞辩,會(huì)列出集群棧的集群 ClusterIP和LoadBalancer。查看LoadBalancer授艰,你可以看到其外部 IP 為localhost辨嗽、端口為80。
在瀏覽器中打開http://localhost/會(huì)顯示該應(yīng)用:
如果你的儀表盤還在打開的話淮腾,可以查看棧糟需,甚至是打開其中一個(gè)容器的Terminal:
你可以通過(guò)運(yùn)行如下命令來(lái)刪除該棧:
$ docker stack rm cluster
最后再提一點(diǎn),你可能會(huì)想谷朝,太好了洲押,我可以在Kubernetes集群的任何地方運(yùn)行我的 Docker Compose文件了。額圆凰,嚴(yán)格意義上說(shuō)并不是這樣的杈帐。我們說(shuō)到,在第一次啟動(dòng)Kubernetes時(shí)专钉,啟動(dòng)了一些Docker組件挑童。它們確保Docker盡可能緊密地進(jìn)行集成。但是跃须,這些組件在非Docker管理的集群中并不存在站叼,因此你會(huì)無(wú)法使用docker stack命令。
并非沒有補(bǔ)救措施回怜。Kubernetes項(xiàng)目中提供了一個(gè)名為Kompose工具大年,可接收一個(gè)Docker Compose 文件并將其實(shí)時(shí)轉(zhuǎn)化為一個(gè)Kubernetes定義文件。
要在macOS上安裝Kompose玉雾,運(yùn)行如下命令:
$ curl -L https://github.com/kubernetes/kompose/releases/download/v1.18.0/kompose-darwin-amd64 -o /usr/local/bin/kompose
$ chmod +x /usr/local/bin/kompose
Windows 10的用戶可以使用 Chocolatey來(lái)安裝這一二進(jìn)制:
??Chocolatey是一個(gè)基于命令行的包管理器,可用于在Windows機(jī)器上安裝各類軟件包轻要,與在Linux機(jī)器上使用yum或apt-get或者macOS上使用brew相似复旬。
$ choco install kubernetes-kompose
最后,Linux用戶可以運(yùn)行如下命令:
$ curl -L https://github.com/kubernetes/kompose/releases/download/v1.18.0/kompose-linux-amd64 -o /usr/local/bin/kompose
$ chmod +x /usr/local/bin/kompose
安裝完成后冲泥,可以通過(guò)運(yùn)行如下命令來(lái)啟動(dòng)你的Docker Compose文件:
$ kompose up
你會(huì)得到類似下面的輸出:
$ kompose up
INFO We are going to create Kubernetes Deployments, Services and PersistentVolumeClaims for your Dockerized application. If you need different kind of resources, use the 'kompose convert' and 'kubectl create -f' commands instead.
INFO Deploying application in "default" namespace
INFO Successfully created Service: cluster
INFO Successfully created Pod: cluster
Your application has been deployed to Kubernetes. You can run 'kubectl get deployment,svc,pods,pvc' for details.
根據(jù)輸出中的提示驹碍,運(yùn)行如下命令會(huì)給出剛剛啟動(dòng)的服務(wù)和pod的細(xì)節(jié)信息:
$ kubectl get deployment,svc,pods,pvc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/cluster ClusterIP 10.111.18.21 <none> 80/TCP 40s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8h
NAME READY STATUS RESTARTS AGE
pod/cluster 1/1 Running 0 40s
你可以通過(guò)運(yùn)行如下命令來(lái)刪除這些服務(wù)和pod:
$ kompose down
INFO Deleting application in "default" namespace
INFO Successfully deleted Service: cluster
INFO Successfully deleted Pod: cluster
雖然你可以使用kompose up和kompose down,我會(huì)建議生成Kubernetes定義文件并對(duì)它們按需進(jìn)行修改凡恍。只需運(yùn)行如下命令:
$ kompose convert
這會(huì)生成pod和服務(wù)文件:
$ kompose convert
INFO Kubernetes file "cluster-service.yaml" created
INFO Kubernetes file "cluster-pod.yaml" created
你會(huì)看到Docker Compose文件和生成的兩個(gè)文件之間有相當(dāng)大的不同志秃。cluster-pod.yaml文件類似下面這樣:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
io.kompose.service: cluster
name: cluster
spec:
containers:
- image: russmckendrick/cluster
name: cluster
ports:
- containerPort: 80
resources: {}
restartPolicy: OnFailure
status: {}
cluster-service.yaml文件類似下面這樣:
apiVersion: v1
kind: Service
metadata:
annotations:
kompose.cmd: kompose convert
kompose.version: 1.18.0 (06a2e56)
creationTimestamp: null
labels:
io.kompose.service: cluster
name: cluster
spec:
ports:
- name: "80"
port: 80
targetPort: 80
selector:
io.kompose.service: cluster
status:
loadBalancer: {}
然后你可以通過(guò)運(yùn)行如下命令來(lái)啟動(dòng)這些文件:
$ kubectl create -f cluster-pod.yaml
$ kubectl create -f cluster-service.yaml
$ kubectl get deployment,svc,pods,pvc
$ kubectl create -f cluster-pod.yaml
pod/cluster created
$ kubectl create -f cluster-service.yaml
service/cluster created
$ kubectl get deployment,svc,pods,pvc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/cluster ClusterIP 10.100.207.92 <none> 80/TCP 5s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8h
NAME READY STATUS RESTARTS AGE
pod/cluster 1/1 Running 0 10s
要?jiǎng)h除該集群的pod和服務(wù),我們只需要運(yùn)行如下命令即可:
$ kubectl delete service/cluster pod/cluster
雖然在后面的章節(jié)還會(huì)使用到Kubernetes嚼酝,建議還是先在Docker桌面軟件中先取消對(duì)Kubernetes的集成浮还,因?yàn)樗诳臻e時(shí)會(huì)帶來(lái)一些系統(tǒng)資源占用。只需取消勾選Enable Kubernetes即可闽巩。點(diǎn)擊Apply時(shí)钧舌,Docker會(huì)停止所有運(yùn)行Kubernetes所需的容器担汤,但它不會(huì)刪除這些鏡像,這樣在你重新啟動(dòng)它時(shí)可以很快的完成洼冻。
總結(jié)
本章中崭歧,我們通過(guò)Docker桌面軟件來(lái)學(xué)習(xí)了Kubernetes。Kubernetes的內(nèi)容遠(yuǎn)不止本章中所講解的這些撞牢,所以千萬(wàn)不要覺得它只有這些率碾。在討論了Kubernetes起源之后,我們看了如何使用Docker for Mac或Docker for Windows在本地機(jī)器上啟動(dòng)它屋彪。
然后我們討論了kubectl的基本使用所宰,接著學(xué)習(xí)像Docker Swarm那樣使用docker stack啟動(dòng)并運(yùn)行應(yīng)用。
本章的最后撼班,我們討論了Kompose歧匈,它是Kubernetes項(xiàng)目下的一個(gè)工具。幫助我們將Docker Compose文件轉(zhuǎn)化為Kubernetes所用的文件砰嘁,讓我們可以將應(yīng)用遷移到純Kubernetes上件炉。
下一章中,我們將來(lái)學(xué)習(xí)公有云上的Docker矮湘,比如Amazon Web Services斟冕,并簡(jiǎn)短地再次使用Kubernetes。
課后問題
- 是非題:勾選了Show system containers (advanced)之后缅阳,你就看不到用于啟動(dòng)Kubernetes的鏡像了磕蛇。
- 哪四個(gè)命名空間托管用于運(yùn)行Kubernetes和在Docker中啟動(dòng)支持的容器?
- 你會(huì)運(yùn)行哪個(gè)命令來(lái)查看pod中運(yùn)行的容器的詳細(xì)信息十办?
- 你會(huì)使用哪個(gè)命令來(lái)啟動(dòng)Kubernetes的YAML定義文件秀撇?
- 通常,kubectl proxy命令會(huì)在本地機(jī)器上打開哪個(gè)端口向族?
- Google的容器編排平臺(tái)的最初名稱是什么呵燕?
擴(kuò)展閱讀
本章開始處提及的一些Google工具、PPT 和白皮書參見如下鏈接:
- cgroups: http://man7.org/linux/man-pages/man7/cgroups.7.html
- lmctfy: https://github.com/google/lmctfy/
- Joe Beda在GluCon上的幻燈片 擴(kuò)展中的容器 : https://pdfs.semanticscholar.org/presentation/4df0/b2bcd39b7757867b1ead3009a628e07d8b57.pdf
- Google 使用 Borg 進(jìn)行大規(guī)模集群的管理: https://ai.google/research/pubs/pub43438
- LXC - https://linuxcontainers.org/
本章說(shuō)涉及到的云服務(wù)的詳細(xì)信息參見:
- Google Kubernetes引擎(GKE): https://cloud.google.com/kubernetes-engine/
- Azure Kubernetes服務(wù) (AKS): https://azure.microsoft.com/en-gb/services/kubernetes-service/
- Amazon的Kubernetes彈性容器服務(wù)(Amazon EKS): https://aws.amazon.com/eks/
- IBM云Kubernetes服務(wù): https://www.ibm.com/cloud/container-service
- Oracler的Kubernetes容器引擎: https://cloud.oracle.com/containers/kubernetes-engine
- DigitalOcean上的Kubernetes: https://www.digitalocean.com/products/kubernetes/
以下可以查看到Docker有關(guān)對(duì)于Kubernetes支持的聲明:
- Docker Enterprise的Kubernetes聲明:https://blog.docker.com/2017/10/docker-enterprise-edition-kubernetes/
- Kubernetes穩(wěn)定版發(fā)布: https://blog.docker.com/2018/07/kubernetes-is-now-available-in-docker-desktop-stable-channel/
最后件相,Kompose的主頁(yè)為:
- Kompose - http://kompose.io/