精通Docker第三版 – 第九章 Docker和Kubernetes

《精通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 和白皮書參見如下鏈接:

本章說(shuō)涉及到的云服務(wù)的詳細(xì)信息參見:

以下可以查看到Docker有關(guān)對(duì)于Kubernetes支持的聲明:

最后件相,Kompose的主頁(yè)為:

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末再扭,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子夜矗,更是在濱河造成了極大的恐慌泛范,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件紊撕,死亡現(xiàn)場(chǎng)離奇詭異罢荡,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門柠傍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)麸俘,“玉大人,你說(shuō)我怎么就攤上這事惧笛〈用模” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵患整,是天一觀的道長(zhǎng)拜效。 經(jīng)常有香客問我,道長(zhǎng)各谚,這世上最難降的妖魔是什么紧憾? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮昌渤,結(jié)果婚禮上赴穗,老公的妹妹穿的比我還像新娘。我一直安慰自己膀息,他們只是感情好般眉,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著潜支,像睡著了一般甸赃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上冗酿,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天埠对,我揣著相機(jī)與錄音,去河邊找鬼裁替。 笑死项玛,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的弱判。 我是一名探鬼主播稍计,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼裕循!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起净刮,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤剥哑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后淹父,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體株婴,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了困介。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片大审。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖座哩,靈堂內(nèi)的尸體忽然破棺而出徒扶,到底是詐尸還是另有隱情,我是刑警寧澤根穷,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布姜骡,位于F島的核電站,受9級(jí)特大地震影響屿良,放射性物質(zhì)發(fā)生泄漏圈澈。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一尘惧、第九天 我趴在偏房一處隱蔽的房頂上張望康栈。 院中可真熱鬧,春花似錦喷橙、人聲如沸啥么。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)饥臂。三九已至,卻和暖如春似踱,著一層夾襖步出監(jiān)牢的瞬間隅熙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工核芽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留囚戚,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓轧简,卻偏偏與公主長(zhǎng)得像驰坊,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子哮独,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

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

  • Kubernetes 系統(tǒng)架構(gòu)初探\簡(jiǎn)單介紹 一拳芙、前言 by Urs H?lzle, Google 翻譯出來(lái)的意思...
    Impassable_time閱讀 661評(píng)論 0 3
  • 原文:https://www.cnblogs.com/xhyan/p/6656062.html?Kubernete...
    laosijikaichele閱讀 1,165評(píng)論 0 8
  • 一、Kubernetes整體架構(gòu) Kubernetes屬于主從分布式架構(gòu)皮璧,主要由Master Node和Worke...
    粥一樣溫柔閱讀 1,386評(píng)論 0 1
  • 圖片發(fā)自簡(jiǎn)書App 母雞 文/繭中人 姑父的刀又快又狠母雞第一次虔誠(chéng)地低下了頭雙眼慢慢的閉上試圖發(fā)出的吶喊卻變成了...
    繭中人閱讀 449評(píng)論 3 6
  • 過(guò)去不能回來(lái)舟扎,我們能擁有的只有此刻。 未來(lái)還太遙遠(yuǎn)悴务,我們能控制的只有現(xiàn)在睹限。 這個(gè)世界上,能引進(jìn)潮流的人永遠(yuǎn)是走...
    西子晴閱讀 158評(píng)論 0 1