<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Kubernetes 從入門(mén)到進(jìn)階實(shí)戰(zhàn)教程 (2021 最新萬(wàn)字干貨版)

          共 21196字,需瀏覽 43分鐘

           ·

          2021-01-09 14:30

          公眾號(hào)關(guān)注“杰哥的IT之旅”,

          選擇“星標(biāo)”,重磅干貨,第一時(shí)間送達(dá)!


          作者:oonamao 毛江云,騰訊 CSIG 應(yīng)用開(kāi)發(fā)工程師
          原文:來(lái)源騰訊技術(shù)工程,https://tinyurl.com/ya3ennxf


          寫(xiě)在前面

          筆者今年 9 月從端側(cè)開(kāi)發(fā)轉(zhuǎn)到后臺(tái)開(kāi)發(fā),第一個(gè)系統(tǒng)開(kāi)發(fā)任務(wù)就強(qiáng)依賴(lài)了 K8S,加之項(xiàng)目任務(wù)重、排期緊,必須馬上對(duì) K8S 有概念上的了解。然而,很多所謂“K8S 入門(mén)\概念”的文章看的一頭霧水,對(duì)于大部分新手來(lái)說(shuō)并不友好。經(jīng)歷了幾天痛苦地學(xué)習(xí)之后,回顧來(lái)看,K8S 根本不復(fù)雜。于是,決心有了這一系列的文章:一方面希望對(duì)新手同學(xué)有幫助;另一方面,以文會(huì)友,希望能夠有機(jī)會(huì)交流討論技術(shù)。

          本文組織方式:

          1. K8S 是什么,即作用和目的。涉及 K8S 架構(gòu)的整理,Master 和 Node 之間的關(guān)系,以及 K8S 幾個(gè)重要的組件:API Server、Scheduler、Controller、etcd 等。
          2. K8S 的重要概念,即 K8S 的 API 對(duì)象,也就是常常聽(tīng)到的 Pod、Deployment、Service 等。
          3. 如何配置 kubectl,介紹kubectl工具和配置辦法。
          4. 如何用kubectl 部署服務(wù)。
          5. 如何用kubectl 查看、更新/編輯、刪除服務(wù)。
          6.?如何用kubectl?排查部署在K8S集群上的服務(wù)出現(xiàn)的問(wèn)題

          I. K8S 概覽

          1.1 K8S 是什么?

          K8S 是Kubernetes的全稱(chēng),官方稱(chēng)其是:

          Kubernetes is an open source system for managing?containerized applications?across multiple hosts. It provides basic mechanisms for deployment, maintenance, and scaling of applications.

          用于自動(dòng)部署、擴(kuò)展和管理“容器化(containerized)應(yīng)用程序”的開(kāi)源系統(tǒng)。

          翻譯成大白話就是:“K8S 是 負(fù)責(zé)自動(dòng)化運(yùn)維管理多個(gè) Docker 程序的集群”。那么問(wèn)題來(lái)了:Docker 運(yùn)行可方便了,為什么要用 K8S,它有什么優(yōu)勢(shì)?

          插一句題外話:

          • 為什么 Kubernetes 要叫 Kubernetes 呢?維基百科已經(jīng)交代了(老美對(duì)星際是真的癡迷):

            Kubernetes(在希臘語(yǔ)意為“舵手”或“駕駛員”)由 Joe Beda、Brendan Burns 和 Craig McLuckie 創(chuàng)立,并由其他谷歌工程師,包括 Brian Grant 和 Tim Hockin 等進(jìn)行加盟創(chuàng)作,并由谷歌在 2014 年首次對(duì)外宣布 。該系統(tǒng)的開(kāi)發(fā)和設(shè)計(jì)都深受谷歌的 Borg 系統(tǒng)的影響,其許多頂級(jí)貢獻(xiàn)者之前也是 Borg 系統(tǒng)的開(kāi)發(fā)者。在谷歌內(nèi)部,Kubernetes 的原始代號(hào)曾經(jīng)是Seven,即星際迷航中的 Borg(博格人)。Kubernetes 標(biāo)識(shí)中舵輪有七個(gè)輪輻就是對(duì)該項(xiàng)目代號(hào)的致意。

          • 為什么 Kubernetes 的縮寫(xiě)是 K8S 呢?我個(gè)人贊同Why Kubernetes is Abbreviated k8s中說(shuō)的觀點(diǎn)“嘛,寫(xiě)全稱(chēng)也太累了吧,不如整個(gè)縮寫(xiě)”。其實(shí)只保留首位字符,用具體數(shù)字來(lái)替代省略的字符個(gè)數(shù)的做法,還是比較常見(jiàn)的。

          1.2 為什么是 K8S?

          試想下傳統(tǒng)的后端部署辦法:把程序包(包括可執(zhí)行二進(jìn)制文件、配置文件等)放到服務(wù)器上,接著運(yùn)行啟動(dòng)腳本把程序跑起來(lái),同時(shí)啟動(dòng)守護(hù)腳本定期檢查程序運(yùn)行狀態(tài)、必要的話重新拉起程序。

          有問(wèn)題嗎?顯然有!最大的一個(gè)問(wèn)題在于:**如果服務(wù)的請(qǐng)求量上來(lái),已部署的服務(wù)響應(yīng)不過(guò)來(lái)怎么辦?**傳統(tǒng)的做法往往是,如果請(qǐng)求量、內(nèi)存、CPU 超過(guò)閾值做了告警,運(yùn)維馬上再加幾臺(tái)服務(wù)器,部署好服務(wù)之后,接入負(fù)載均衡來(lái)分擔(dān)已有服務(wù)的壓力。

          問(wèn)題出現(xiàn)了:從監(jiān)控告警到部署服務(wù),中間需要人力介入!那么,有沒(méi)有辦法自動(dòng)完成服務(wù)的部署、更新、卸載和擴(kuò)容、縮容呢?

          這,就是 K8S 要做的事情:自動(dòng)化運(yùn)維管理 Docker(容器化)程序

          1.3 K8S 怎么做?

          我們已經(jīng)知道了 K8S 的核心功能:自動(dòng)化運(yùn)維管理多個(gè)容器化程序。那么 K8S 怎么做到的呢?這里,我們從宏觀架構(gòu)上來(lái)學(xué)習(xí) K8S 的設(shè)計(jì)思想。首先看下圖,圖片來(lái)自文章Components of Kubernetes Architecture:

          K8S 是屬于主從設(shè)備模型(Master-Slave 架構(gòu)),即有 Master 節(jié)點(diǎn)負(fù)責(zé)核心的調(diào)度、管理和運(yùn)維,Slave 節(jié)點(diǎn)則在執(zhí)行用戶(hù)的程序。但是在 K8S 中,主節(jié)點(diǎn)一般被稱(chēng)為Master Node 或者 Head Node(本文采用 Master Node 稱(chēng)呼方式),而從節(jié)點(diǎn)則被稱(chēng)為Worker Node 或者 Node(本文采用 Worker Node 稱(chēng)呼方式)。

          要注意一點(diǎn):Master Node 和 Worker Node 是分別安裝了 K8S 的 Master 和 Woker 組件的實(shí)體服務(wù)器,每個(gè) Node 都對(duì)應(yīng)了一臺(tái)實(shí)體服務(wù)器(雖然 Master Node 可以和其中一個(gè) Worker Node 安裝在同一臺(tái)服務(wù)器,但是建議 Master Node 單獨(dú)部署),所有 Master Node 和 Worker Node 組成了 K8S 集群,同一個(gè)集群可能存在多個(gè) Master Node 和 Worker Node。

          首先來(lái)看Master Node都有哪些組件:

          • API Server。K8S 的請(qǐng)求入口服務(wù)。API Server 負(fù)責(zé)接收 K8S 所有請(qǐng)求(來(lái)自 UI 界面或者 CLI 命令行工具),然后,API Server 根據(jù)用戶(hù)的具體請(qǐng)求,去通知其他組件干活。
          • Scheduler。K8S 所有 Worker Node 的調(diào)度器。當(dāng)用戶(hù)要部署服務(wù)時(shí),Scheduler 會(huì)選擇最合適的 Worker Node(服務(wù)器)來(lái)部署。
          • Controller Manager。K8S 所有 Worker Node 的監(jiān)控器。Controller Manager 有很多具體的 Controller,在文章Components of Kubernetes Architecture中提到的有 Node Controller、Service Controller、Volume Controller 等。Controller 負(fù)責(zé)監(jiān)控和調(diào)整在 Worker Node 上部署的服務(wù)的狀態(tài),比如用戶(hù)要求 A 服務(wù)部署 2 個(gè)副本,那么當(dāng)其中一個(gè)服務(wù)掛了的時(shí)候,Controller 會(huì)馬上調(diào)整,讓 Scheduler 再選擇一個(gè) Worker Node 重新部署服務(wù)。
          • etcd。K8S 的存儲(chǔ)服務(wù)。etcd 存儲(chǔ)了 K8S 的關(guān)鍵配置和用戶(hù)配置,K8S 中僅 API Server 才具備讀寫(xiě)權(quán)限,其他組件必須通過(guò) API Server 的接口才能讀寫(xiě)數(shù)據(jù)(見(jiàn)Kubernetes Works Like an Operating System)。

          接著來(lái)看Worker Node的組件,筆者更贊同HOW DO APPLICATIONS RUN ON KUBERNETES文章中提到的組件介紹:

          • KubeletWorker Node 的監(jiān)視器,以及與 Master Node 的通訊器。Kubelet 是 Master Node 安插在 Worker Node 上的“眼線”,它會(huì)定期向 Worker Node 匯報(bào)自己 Node 上運(yùn)行的服務(wù)的狀態(tài),并接受來(lái)自 Master Node 的指示采取調(diào)整措施。
          • Kube-Proxy。K8S 的網(wǎng)絡(luò)代理。私以為稱(chēng)呼為 Network-Proxy 可能更適合?Kube-Proxy 負(fù)責(zé) Node 在 K8S 的網(wǎng)絡(luò)通訊、以及對(duì)外部網(wǎng)絡(luò)流量的負(fù)載均衡。
          • Container Runtime。Worker Node 的運(yùn)行環(huán)境。即安裝了容器化所需的軟件環(huán)境確保容器化程序能夠跑起來(lái),比如 Docker Engine。大白話就是幫忙裝好了 Docker 運(yùn)行環(huán)境。
          • Logging LayerK8S 的監(jiān)控狀態(tài)收集器。私以為稱(chēng)呼為 Monitor 可能更合適?Logging Layer 負(fù)責(zé)采集 Node 上所有服務(wù)的 CPU、內(nèi)存、磁盤(pán)、網(wǎng)絡(luò)等監(jiān)控項(xiàng)信息。
          • Add-Ons。K8S 管理運(yùn)維 Worker Node 的插件組件。有些文章認(rèn)為 Worker Node 只有三大組件,不包含 Add-On,但筆者認(rèn)為 K8S 系統(tǒng)提供了 Add-On 機(jī)制,讓用戶(hù)可以擴(kuò)展更多定制化功能,是很不錯(cuò)的亮點(diǎn)。

          總結(jié)來(lái)看,K8S 的 Master Node 具備:請(qǐng)求入口管理(API Server),Worker Node 調(diào)度(Scheduler),監(jiān)控和自動(dòng)調(diào)節(jié)(Controller Manager),以及存儲(chǔ)功能(etcd);而 K8S 的 Worker Node 具備:狀態(tài)和監(jiān)控收集(Kubelet),網(wǎng)絡(luò)和負(fù)載均衡(Kube-Proxy)、保障容器化運(yùn)行環(huán)境(Container Runtime)、以及定制化功能(Add-Ons)。

          到這里,相信你已經(jīng)對(duì) K8S 究竟是做什么的,有了大概認(rèn)識(shí)。接下來(lái),再來(lái)認(rèn)識(shí)下 K8S 的 Deployment、Pod、Replica Set、Service 等,但凡談到 K8S,就繞不開(kāi)這些名詞,而這些名詞也是最讓 K8S 新手們感到頭疼、困惑的。

          II. K8S 重要概念

          2.1 Pod 實(shí)例

          官方對(duì)于Pod的解釋是:

          Pod是可以在 Kubernetes 中創(chuàng)建和管理的、最小的可部署的計(jì)算單元。

          這樣的解釋還是很難讓人明白究竟 Pod 是什么,但是對(duì)于 K8S 而言,Pod 可以說(shuō)是所有對(duì)象中最重要的概念了!因此,我們必須首先清楚地知道“Pod 是什么”,再去了解其他的對(duì)象。

          從官方給出的定義,聯(lián)想下“最小的 xxx 單元”,是不是可以想到本科在學(xué)校里學(xué)習(xí)“進(jìn)程”的時(shí)候,教科書(shū)上有一段類(lèi)似的描述:資源分配的最小單位;還有”線程“的描述是:CPU 調(diào)度的最小單位。什么意思呢?”最小 xx 單位“要么就是事物的衡量標(biāo)準(zhǔn)單位,要么就是資源的閉包、集合。前者比如長(zhǎng)度米、時(shí)間秒;后者比如一個(gè)”進(jìn)程“是存儲(chǔ)和計(jì)算的閉包,一個(gè)”線程“是 CPU 資源(包括寄存器、ALU 等)的閉包。

          同樣的,Pod 就是 K8S 中一個(gè)服務(wù)的閉包。這么說(shuō)的好像還是有點(diǎn)玄乎,更加云里霧里了。簡(jiǎn)單來(lái)說(shuō),Pod 可以被理解成一群可以共享網(wǎng)絡(luò)、存儲(chǔ)和計(jì)算資源的容器化服務(wù)的集合。再打個(gè)形象的比喻,在同一個(gè) Pod 里的幾個(gè) Docker 服務(wù)/程序,好像被部署在同一臺(tái)機(jī)器上,可以通過(guò) localhost 互相訪問(wèn),并且可以共用 Pod 里的存儲(chǔ)資源(這里是指 Docker 可以掛載 Pod 內(nèi)的數(shù)據(jù)卷,數(shù)據(jù)卷的概念,后文會(huì)詳細(xì)講述,暫時(shí)理解為“需要手動(dòng) mount 的磁盤(pán)”)。筆者總結(jié) Pod 如下圖,可以看到:同一個(gè) Pod 之間的 Container 可以通過(guò) localhost 互相訪問(wèn),并且可以掛載 Pod 內(nèi)所有的數(shù)據(jù)卷;但是不同的 Pod 之間的 Container 不能用 localhost 訪問(wèn),也不能掛載其他 Pod 的數(shù)據(jù)卷。

          對(duì) Pod 有直觀的認(rèn)識(shí)之后,接著來(lái)看 K8S 中 Pod 究竟長(zhǎng)什么樣子,具體包括哪些資源?

          K8S 中所有的對(duì)象都通過(guò) yaml 來(lái)表示,筆者從官方網(wǎng)站摘錄了一個(gè)最簡(jiǎn)單的 Pod 的 yaml:

          apiVersion:?v1
          kind:?Pod
          metadata:
          ??name:?memory-demo
          ??namespace:?mem-example
          spec:
          ??containers:
          ??-?name:?memory-demo-ctr
          ????image:?polinux/stress
          ????resources:
          ??????limits:
          ????????memory:?"200Mi"
          ??????requests:
          ????????memory:?"100Mi"
          ????command:?["stress"]
          ????args:?["--vm",?"1",?"--vm-bytes",?"150M",?"--vm-hang",?"1"]
          ????volumeMounts:
          ????-?name:?redis-storage
          ??????mountPath:?/data/redis
          ??volumes:
          ??-?name:?redis-storage
          ????emptyDir:?{}

          看不懂不必慌張,且耐心聽(tīng)下面的解釋?zhuān)?/p>

          • apiVersion記錄 K8S 的 API Server 版本,現(xiàn)在看到的都是v1,用戶(hù)不用管。
          • kind記錄該 yaml 的對(duì)象,比如這是一份 Pod 的 yaml 配置文件,那么值內(nèi)容就是Pod。
          • metadata記錄了 Pod 自身的元數(shù)據(jù),比如這個(gè) Pod 的名字、這個(gè) Pod 屬于哪個(gè) namespace(命名空間的概念,后文會(huì)詳述,暫時(shí)理解為“同一個(gè)命名空間內(nèi)的對(duì)象互相可見(jiàn)”)。
          • spec記錄了 Pod 內(nèi)部所有的資源的詳細(xì)信息,看懂這個(gè)很重要:
            • containers記錄了 Pod 內(nèi)的容器信息,containers包括了:name容器名,image容器的鏡像地址,resources容器需要的 CPU、內(nèi)存、GPU 等資源,command容器的入口命令,args容器的入口參數(shù),volumeMounts容器要掛載的 Pod 數(shù)據(jù)卷等。可以看到,上述這些信息都是啟動(dòng)容器的必要和必需的信息。
            • volumes記錄了 Pod 內(nèi)的數(shù)據(jù)卷信息,后文會(huì)詳細(xì)介紹 Pod 的數(shù)據(jù)卷。

          2.2 Volume 數(shù)據(jù)卷

          K8S 支持很多類(lèi)型的 volume 數(shù)據(jù)卷掛載,具體請(qǐng)參見(jiàn)K8S 卷。前文就“如何理解 volume”提到:“需要手動(dòng) mount 的磁盤(pán)”,此外,有一點(diǎn)可以幫助理解:數(shù)據(jù)卷 volume 是 Pod 內(nèi)部的磁盤(pán)資源。

          其實(shí),單單就 Volume 來(lái)說(shuō),不難理解。但是上面還看到了volumeMounts,這倆是什么關(guān)系呢?

          volume 是 K8S 的對(duì)象,對(duì)應(yīng)一個(gè)實(shí)體的數(shù)據(jù)卷;而 volumeMounts 只是 container 的掛載點(diǎn),對(duì)應(yīng) container 的其中一個(gè)參數(shù)。但是,volumeMounts 依賴(lài)于 volume,只有當(dāng) Pod 內(nèi)有 volume 資源的時(shí)候,該 Pod 內(nèi)部的 container 才可能有 volumeMounts。

          2.3 Container 容器

          本文中提到的鏡像 Image、容器 Container,都指代了 Pod 下的一個(gè)container。關(guān)于 K8S 中的容器,在 2.1Pod 章節(jié)都已經(jīng)交代了,這里無(wú)非再啰嗦一句:一個(gè) Pod 內(nèi)可以有多個(gè)容器 container

          在 Pod 中,容器也有分類(lèi),對(duì)這個(gè)感興趣的同學(xué)歡迎自行閱讀更多資料:

          • 標(biāo)準(zhǔn)容器 Application Container。
          • 初始化容器 Init Container。
          • 邊車(chē)容器 Sidecar Container
          • 臨時(shí)容器 Ephemeral Container。

          一般來(lái)說(shuō),我們部署的大多是標(biāo)準(zhǔn)容器( Application Container)

          2.4 Deployment 和 ReplicaSet(簡(jiǎn)稱(chēng) RS)

          除了 Pod 之外,K8S 中最常聽(tīng)到的另一個(gè)對(duì)象就是 Deployment 了。那么,什么是 Deployment 呢?官方給出了一個(gè)要命的解釋?zhuān)?/p>

          一個(gè)?Deployment?控制器為 Pods 和 ReplicaSets 提供聲明式的更新能力。

          你負(fù)責(zé)描述 Deployment 中的?目標(biāo)狀態(tài),而 Deployment 控制器以受控速率更改實(shí)際狀態(tài), 使其變?yōu)槠谕麪顟B(tài)。你可以定義 Deployment 以創(chuàng)建新的 ReplicaSet,或刪除現(xiàn)有 Deployment,并通過(guò)新的 Deployment 收養(yǎng)其資源。

          翻譯一下:Deployment 的作用是管理和控制 Pod 和 ReplicaSet,管控它們運(yùn)行在用戶(hù)期望的狀態(tài)中。哎,打個(gè)形象的比喻,Deployment 就是包工頭,主要負(fù)責(zé)監(jiān)督底下的工人 Pod 干活,確保每時(shí)每刻有用戶(hù)要求數(shù)量的 Pod 在工作。如果一旦發(fā)現(xiàn)某個(gè)工人 Pod 不行了,就趕緊新拉一個(gè) Pod 過(guò)來(lái)替換它。

          新的問(wèn)題又來(lái)了:那什么是 ReplicaSets 呢?

          ReplicaSet 的目的是維護(hù)一組在任何時(shí)候都處于運(yùn)行狀態(tài)的 Pod 副本的穩(wěn)定集合。因此,它通常用來(lái)保證給定數(shù)量的、完全相同的 Pod 的可用性。

          再來(lái)翻譯下:ReplicaSet 的作用就是管理和控制 Pod,管控他們好好干活。但是,ReplicaSet 受控于 Deployment。形象來(lái)說(shuō),ReplicaSet 就是總包工頭手下的小包工頭。

          筆者總結(jié)得到下面這幅圖,希望能幫助理解:

          新的問(wèn)題又來(lái)了:如果都是為了管控 Pod 好好干活,為什么要設(shè)置 Deployment 和 ReplicaSet 兩個(gè)層級(jí)呢,直接讓 Deployment 來(lái)管理不可以嗎?

          回答:不清楚,但是私以為是因?yàn)橄扔?ReplicaSet,但是使用中發(fā)現(xiàn) ReplicaSet 不夠滿(mǎn)足要求,于是又整了一個(gè) Deployment(有清楚 Deployment 和 ReplicaSet 聯(lián)系和區(qū)別的小伙伴歡迎留言啊)。

          但是,從 K8S 使用者角度來(lái)看,用戶(hù)會(huì)直接操作 Deployment 部署服務(wù),而當(dāng) Deployment 被部署的時(shí)候,K8S 會(huì)自動(dòng)生成要求的 ReplicaSet 和 Pod。在K8S 官方文檔中也指出用戶(hù)只需要關(guān)心 Deployment 而不操心 ReplicaSet:

          This actually means that you may never need to manipulate ReplicaSet objects: use a Deployment instead, and define your application in the spec section.

          這實(shí)際上意味著您可能永遠(yuǎn)不需要操作 ReplicaSet 對(duì)象:直接使用 Deployments 并在規(guī)范部分定義應(yīng)用程序。

          補(bǔ)充說(shuō)明:在 K8S 中還有一個(gè)對(duì)象 ---?ReplicationController(簡(jiǎn)稱(chēng) RC),官方文檔對(duì)它的定義是:

          ReplicationController?確保在任何時(shí)候都有特定數(shù)量的 Pod 副本處于運(yùn)行狀態(tài)。換句話說(shuō),ReplicationController 確保一個(gè) Pod 或一組同類(lèi)的 Pod 總是可用的。

          怎么樣,和 ReplicaSet 是不是很相近?在Deployments, ReplicaSets, and pods教程中說(shuō)“ReplicationController 是 ReplicaSet 的前身”,官方也推薦用 Deployment 取代 ReplicationController 來(lái)部署服務(wù)。

          2.5 Service 和 Ingress

          吐槽下 K8S 的概念/對(duì)象/資源是真的多?。?strong style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">前文介紹的 Deployment、ReplicationController 和 ReplicaSet 主要管控 Pod 程序服務(wù);那么,Service 和 Ingress 則負(fù)責(zé)管控 Pod 網(wǎng)絡(luò)服務(wù)。

          我們先來(lái)看看官方文檔中 Service 的定義:

          將運(yùn)行在一組 Pods 上的應(yīng)用程序公開(kāi)為網(wǎng)絡(luò)服務(wù)的抽象方法。

          使用 Kubernetes,您無(wú)需修改應(yīng)用程序即可使用不熟悉的服務(wù)發(fā)現(xiàn)機(jī)制。Kubernetes 為 Pods 提供自己的 IP 地址,并為一組 Pod 提供相同的 DNS 名, 并且可以在它們之間進(jìn)行負(fù)載均衡。

          翻譯下:K8S 中的服務(wù)(Service)并不是我們常說(shuō)的“服務(wù)”的含義,而更像是網(wǎng)關(guān)層,是若干個(gè) Pod 的流量入口、流量均衡器。

          那么,為什么要 Service 呢?

          私以為在這一點(diǎn)上,官方文檔講解地非常清楚:

          Kubernetes Pod 是有生命周期的。它們可以被創(chuàng)建,而且銷(xiāo)毀之后不會(huì)再啟動(dòng)。如果您使用 Deployment 來(lái)運(yùn)行您的應(yīng)用程序,則它可以動(dòng)態(tài)創(chuàng)建和銷(xiāo)毀 Pod。

          每個(gè) Pod 都有自己的 IP 地址,但是在 Deployment 中,在同一時(shí)刻運(yùn)行的 Pod 集合可能與稍后運(yùn)行該應(yīng)用程序的 Pod 集合不同。

          這導(dǎo)致了一個(gè)問(wèn)題:如果一組 Pod(稱(chēng)為“后端”)為群集內(nèi)的其他 Pod(稱(chēng)為“前端”)提供功能, 那么前端如何找出并跟蹤要連接的 IP 地址,以便前端可以使用工作量的后端部分?

          補(bǔ)充說(shuō)明:K8S 集群的網(wǎng)絡(luò)管理和拓?fù)湟灿刑貏e的設(shè)計(jì),以后會(huì)專(zhuān)門(mén)出一章節(jié)來(lái)詳細(xì)介紹 K8S 中的網(wǎng)絡(luò)。這里需要清楚一點(diǎn):K8S 集群內(nèi)的每一個(gè) Pod 都有自己的 IP(是不是很類(lèi)似一個(gè) Pod 就是一臺(tái)服務(wù)器,然而事實(shí)上是多個(gè) Pod 存在于一臺(tái)服務(wù)器上,只不過(guò)是 K8S 做了網(wǎng)絡(luò)隔離),在 K8S 集群內(nèi)部還有 DNS 等網(wǎng)絡(luò)服務(wù)(一個(gè) K8S 集群就如同管理了多區(qū)域的服務(wù)器,可以做復(fù)雜的網(wǎng)絡(luò)拓?fù)洌?/p>

          此外,筆者推薦k8s 外網(wǎng)如何訪問(wèn)業(yè)務(wù)應(yīng)用對(duì)于 Service 的介紹,不過(guò)對(duì)于新手而言,推薦閱讀前半部分對(duì)于 service 的介紹即可,后半部分就太復(fù)雜了。我這里做了簡(jiǎn)單的總結(jié):

          Service 是 K8S 服務(wù)的核心,屏蔽了服務(wù)細(xì)節(jié),統(tǒng)一對(duì)外暴露服務(wù)接口,真正做到了“微服務(wù)”。舉個(gè)例子,我們的一個(gè)服務(wù) A,部署了 3 個(gè)備份,也就是 3 個(gè) Pod;對(duì)于用戶(hù)來(lái)說(shuō),只需要關(guān)注一個(gè) Service 的入口就可以,而不需要操心究竟應(yīng)該請(qǐng)求哪一個(gè) Pod。優(yōu)勢(shì)非常明顯:一方面外部用戶(hù)不需要感知因?yàn)?Pod 上服務(wù)的意外崩潰、K8S 重新拉起 Pod 而造成的 IP 變更,外部用戶(hù)也不需要感知因升級(jí)、變更服務(wù)帶來(lái)的 Pod 替換而造成的 IP 變化,另一方面,Service 還可以做流量負(fù)載均衡。

          但是,Service 主要負(fù)責(zé) K8S 集群內(nèi)部的網(wǎng)絡(luò)拓?fù)?。那么集群外部怎么訪問(wèn)集群內(nèi)部呢?這個(gè)時(shí)候就需要 Ingress 了,官方文檔中的解釋是:

          Ingress 是對(duì)集群中服務(wù)的外部訪問(wèn)進(jìn)行管理的 API 對(duì)象,典型的訪問(wèn)方式是 HTTP。

          Ingress 可以提供負(fù)載均衡、SSL 終結(jié)和基于名稱(chēng)的虛擬托管。

          翻譯一下:Ingress 是整個(gè) K8S 集群的接入層,復(fù)雜集群內(nèi)外通訊。

          最后,筆者把 Ingress 和 Service 的關(guān)系繪制網(wǎng)絡(luò)拓?fù)潢P(guān)系圖如下,希望對(duì)理解這兩個(gè)概念有所幫助:

          2.6 namespace 命名空間

          和前文介紹的所有的概念都不一樣,namespace 跟 Pod 沒(méi)有直接關(guān)系,而是 K8S 另一個(gè)維度的對(duì)象?;蛘哒f(shuō),前文提到的概念都是為了服務(wù) Pod 的,而 namespace 則是為了服務(wù)整個(gè) K8S 集群的。

          那么,namespace 是什么呢?

          上官方文檔定義:

          Kubernetes 支持多個(gè)虛擬集群,它們底層依賴(lài)于同一個(gè)物理集群。這些虛擬集群被稱(chēng)為名字空間。

          翻譯一下:namespace 是為了把一個(gè) K8S 集群劃分為若干個(gè)資源不可共享的虛擬集群而誕生的。

          也就是說(shuō),可以通過(guò)在 K8S 集群內(nèi)創(chuàng)建 namespace 來(lái)分隔資源和對(duì)象。比如我有 2 個(gè)業(yè)務(wù) A 和 B,那么我可以創(chuàng)建 ns-a 和 ns-b 分別部署業(yè)務(wù) A 和 B 的服務(wù),如在 ns-a 中部署了一個(gè) deployment,名字是 hello,返回用戶(hù)的是“hello a”;在 ns-b 中也部署了一個(gè) deployment,名字恰巧也是 hello,返回用戶(hù)的是“hello b”(要知道,在同一個(gè) namespace 下 deployment 不能同名;但是不同 namespace 之間沒(méi)有影響)。前文提到的所有對(duì)象,都是在 namespace 下的;當(dāng)然,也有一些對(duì)象是不隸屬于 namespace 的,而是在 K8S 集群內(nèi)全局可見(jiàn)的,官方文檔提到的可以通過(guò)命令來(lái)查看,具體命令的使用辦法,筆者會(huì)出后續(xù)的實(shí)戰(zhàn)文章來(lái)介紹,先貼下命令:

          #?位于名字空間中的資源
          kubectl?api-resources?--namespaced=true

          #?不在名字空間中的資源
          kubectl?api-resources?--namespaced=false

          不在 namespace 下的對(duì)象有:

          在 namespace 下的對(duì)象有(部分):

          2.7 其他

          K8S 的對(duì)象實(shí)在太多了,2.1-2.6 介紹的是在實(shí)際使用 K8S 部署服務(wù)最常見(jiàn)的。其他的還有 Job、CronJob 等等,在對(duì) K8S 有了比較清楚的認(rèn)知之后,再去學(xué)習(xí)更多的 K8S 對(duì)象,不是難事。

          III. 配置 kubectl

          3.1 什么是 kubectl?

          官方文檔中介紹 kubectl 是:

          Kubectl 是一個(gè)命令行接口,用于對(duì) Kubernetes 集群運(yùn)行命令。Kubectl 的配置文件在$HOME/.kube 目錄。我們可以通過(guò)設(shè)置 KUBECONFIG 環(huán)境變量或設(shè)置命令參數(shù)--kubeconfig 來(lái)指定其他位置的 kubeconfig 文件。

          也就是說(shuō),可以通過(guò) kubectl 來(lái)操作 K8S 集群,基本語(yǔ)法:

          使用以下語(yǔ)法?kubectl?從終端窗口運(yùn)行命令:

          kubectl?[command]?[TYPE]?[NAME]?[flags]

          其中?command、TYPE、NAME?和?flags?分別是:

          • command:指定要對(duì)一個(gè)或多個(gè)資源執(zhí)行的操作,例如?create、get、describe、delete。

          • TYPE:指定資源類(lèi)型。資源類(lèi)型不區(qū)分大小寫(xiě),可以指定單數(shù)、復(fù)數(shù)或縮寫(xiě)形式。例如,以下命令輸出相同的結(jié)果:

          ```shell
          kubectl?get?pod?pod1
          kubectl?get?pods?pod1
          kubectl?get?po?pod1

          -?`NAME`:指定資源的名稱(chēng)。名稱(chēng)區(qū)分大小寫(xiě)。如果省略名稱(chēng),則顯示所有資源的詳細(xì)信息?`kubectl get pods`。

          在對(duì)多個(gè)資源執(zhí)行操作時(shí),您可以按類(lèi)型和名稱(chēng)指定每個(gè)資源,或指定一個(gè)或多個(gè)文件:

          -?要按類(lèi)型和名稱(chēng)指定資源:
          ??-?要對(duì)所有類(lèi)型相同的資源進(jìn)行分組,請(qǐng)執(zhí)行以下操作:`TYPE1 name1 name2 name<#>`。
          ?例子:`kubectl get pod example-pod1 example-pod2`
          ??-?分別指定多個(gè)資源類(lèi)型:`TYPE1/name1 TYPE1/name2 TYPE2/name3 TYPE<#>/name<#>`。
          ?例子:`kubectl get pod/example-pod1 replicationcontroller/example-rc1`
          -?用一個(gè)或多個(gè)文件指定資源:`-f file1 -f file2 -f file<#>`
          ??-?[使用?YAML?而不是?JSON](https://kubernetes.io/zh/docs/concepts/configuration/overview/#general-config-tips)?因?yàn)?YAML 更容易使用,特別是用于配置文件時(shí)。
          ?例子:`kubectl get -f ./pod.yaml`
          -?`flags`:?指定可選的參數(shù)。例如,可以使用?`-s`?或?`-server`?參數(shù)指定 Kubernetes API 服務(wù)器的地址和端口。

          就如何使用 kubectl 而言,官方文檔已經(jīng)說(shuō)得非常清楚。不過(guò)對(duì)于新手而言,還是需要解釋幾句:

          1. kubectl 是 K8S 的命令行工具,并不需要 kubectl 安裝在 K8S 集群的任何 Node 上,但是,需要確保安裝 kubectl 的機(jī)器和 K8S 的集群能夠進(jìn)行網(wǎng)絡(luò)互通。
          2. kubectl 是通過(guò)本地的配置文件來(lái)連接到 K8S 集群的,默認(rèn)保存在$HOME/.kube 目錄下;也可以通過(guò) KUBECONFIG 環(huán)境變量或設(shè)置命令參數(shù)--kubeconfig 來(lái)指定其他位置的 kubeconfig 文件【官方文檔】。

          接下來(lái),一起看看怎么使用 kubectl 吧,切身感受下 kubectl 的使用。

          請(qǐng)注意,如何安裝 kubectl 的辦法有許多非常明確的教程,比如《安裝并配置 kubectl》,本文不再贅述。

          3.2 怎么配置 kubectl?

          第一步,必須準(zhǔn)備好要連接/使用的 K8S 的配置文件,筆者給出一份杜撰的配置:

          apiVersion:?v1
          clusters:
          -?cluster:
          ????certificate-authority-data:?thisisfakecertifcateauthoritydata00000000000
          ????server:?https://1.2.3.4:1234
          ??name:?cls-dev
          contexts:
          -?context:
          ????cluster:?cls-dev
          ????user:?kubernetes-admin
          ??name:?kubernetes-admin@test
          current-context:?kubernetes-admin@test
          kind:?Config
          preferences:?{}
          users:
          -?name:?kubernetes-admin
          ??user:
          ????token:?thisisfaketoken00000

          解讀如下:

          • clusters記錄了 clusters(一個(gè)或多個(gè) K8S 集群)信息:
            • name是這個(gè) cluster(K8S 集群)的名稱(chēng)代號(hào)
            • server是這個(gè) cluster(K8S 集群)的訪問(wèn)方式,一般為 IP+PORT
            • certificate-authority-data是證書(shū)數(shù)據(jù),只有當(dāng) cluster(K8S 集群)的連接方式是 https 時(shí),為了安全起見(jiàn)需要證書(shū)數(shù)據(jù)
          • users記錄了訪問(wèn) cluster(K8S 集群)的賬號(hào)信息:
            • name是用戶(hù)賬號(hào)的名稱(chēng)代號(hào)
            • user/token是用戶(hù)的 token 認(rèn)證方式,token 不是用戶(hù)認(rèn)證的唯一方式,其他還有賬號(hào)+密碼等。
          • contexts是上下文信息,包括了 cluster(K8S 集群)和訪問(wèn) cluster(K8S 集群)的用戶(hù)賬號(hào)等信息:
            • name是這個(gè)上下文的名稱(chēng)代號(hào)
            • cluster是 cluster(K8S 集群)的名稱(chēng)代號(hào)
            • user是訪問(wèn) cluster(K8S 集群)的用戶(hù)賬號(hào)代號(hào)
          • current-context記錄當(dāng)前 kubectl 默認(rèn)使用的上下文信息
          • kindapiVersion都是固定值,用戶(hù)不需要關(guān)心
          • preferences則是配置文件的其他設(shè)置信息,筆者沒(méi)有使用過(guò),暫時(shí)不提。

          第二步,給 kubectl 配置上配置文件。

          1. --kubeconfig參數(shù)。第一種辦法是每次執(zhí)行 kubectl 的時(shí)候,都帶上--kubeconfig=${CONFIG_PATH}。給一點(diǎn)溫馨小提示:每次都帶這么一長(zhǎng)串的字符非常麻煩,可以用 alias 別名來(lái)簡(jiǎn)化碼字量,比如alias k=kubectl --kubeconfig=${CONFIG_PATH}。
          2. KUBECONFIG環(huán)境變量。第二種做法是使用環(huán)境變量KUBECONFIG把所有配置文件都記錄下來(lái),即export KUBECONFIG=$KUBECONFIG:${CONFIG_PATH}。接下來(lái)就可以放心執(zhí)行 kubectl 命令了。
          3. $HOME/.kube/config 配置文件。第三種做法是把配置文件的內(nèi)容放到$HOME/.kube/config 內(nèi)。具體做法為:
            1. 如果$HOME/.kube/config 不存在,那么cp ${CONFIG_PATH} $HOME/.kube/config即可;
            2. 如果如果 $HOME/.kube/config已經(jīng)存在,那么需要把新的配置內(nèi)容加到 $HOME/.kube/config 下。單只是cat ${CONFIG_PATH} >> $HOME/.kube/config是不行的,正確的做法是:KUBECONFIG=$HOME/.kube/config:${CONFIG_PATH} kubectl config view --flatten > $HOME/.kube/config?。解釋下這個(gè)命令的意思:先把所有的配置文件添加到環(huán)境變量KUBECONFIG中,然后執(zhí)行kubectl config view --flatten打印出有效的配置文件內(nèi)容,最后覆蓋$HOME/.kube/config 即可。

          請(qǐng)注意,上述操作的優(yōu)先級(jí)分別是 1>2>3,也就是說(shuō),kubectl 會(huì)優(yōu)先檢查--kubeconfig,若無(wú)則檢查KUBECONFIG,若無(wú)則最后檢查$HOME/.kube/config,如果還是沒(méi)有,報(bào)錯(cuò)。但凡某一步找到了有效的 cluster,就中斷檢查,去連接 K8S 集群了。

          第三步:配置正確的上下文

          按照第二步的做法,如果配置文件只有一個(gè) cluster 是沒(méi)有任何問(wèn)題的,但是對(duì)于有多個(gè) cluster 怎么辦呢?到這里,有幾個(gè)關(guān)于配置的必須掌握的命令:

          • kubectl config get-contexts。列出所有上下文信息。

          • kubectl config current-context。查看當(dāng)前的上下文信息。其實(shí),命令 1 線束出來(lái)的*所指示的就是當(dāng)前的上下文信息。

          • kubectl config use-context ${CONTEXT_NAME}。更改上下文信息。

          • kubectl config set-context ${CONTEXT_NAME}|--current --${KEY}=${VALUE}。修改上下文的元素。比如可以修改用戶(hù)賬號(hào)、集群信息、連接到 K8S 后所在的 namespace。

            關(guān)于該命令,還有幾點(diǎn)要啰嗦的:

            • config set-context可以修改任何在配置文件中的上下文信息,只需要在命令中指定上下文名稱(chēng)就可以。而--current 則指代當(dāng)前上下文。

            • 上下文信息所包括的內(nèi)容有:cluster 集群(名稱(chēng))、用戶(hù)賬號(hào)(名稱(chēng))、連接到 K8S 后所在的 namespace,因此有config set-context嚴(yán)格意義上的用法:

              kubectl config set-context [NAME|--current] [--cluster=cluster_nickname] [--user=user_nickname] [--namespace=namespace] [options]

              (備注:[options]可以通過(guò) kubectl options 查看)

          綜上,如何操作 kubectl 配置都已交代。

          IV. kubectl 部署服務(wù)

          K8S 核心功能就是部署運(yùn)維容器化服務(wù),因此最重要的就是如何又快又好地部署自己的服務(wù)了。本章會(huì)介紹如何部署 Pod 和 Deployment。

          4.1 如何部署 Pod?

          通過(guò) kubectl 部署 Pod 的辦法分為兩步:1). 準(zhǔn)備 Pod 的 yaml 文件;2). 執(zhí)行 kubectl 命令部署

          第一步:準(zhǔn)備 Pod 的 yaml 文件。關(guān)于 Pod 的 yaml 文件初步解釋?zhuān)鞠盗猩弦黄恼隆禟8S 系列一:概念入門(mén)》已經(jīng)有了初步介紹,這里再?gòu)?fù)習(xí)下:

          apiVersion:?v1
          kind:?Pod
          metadata:
          ??name:?memory-demo
          ??namespace:?mem-example
          spec:
          ??containers:
          ??-?name:?memory-demo-ctr
          ????image:?polinux/stress
          ????resources:
          ??????limits:
          ????????memory:?"200Mi"
          ??????requests:
          ????????memory:?"100Mi"
          ????command:?["stress"]
          ????args:?["--vm",?"1",?"--vm-bytes",?"150M",?"--vm-hang",?"1"]
          ????volumeMounts:
          ????-?name:?redis-storage
          ??????mountPath:?/data/redis
          ??volumes:
          ??-?name:?redis-storage
          ????emptyDir:?{}

          繼續(xù)解讀:

          • metadata,對(duì)于新入門(mén)的同學(xué)來(lái)說(shuō),需要重點(diǎn)掌握的兩個(gè)字段:

            • name。這個(gè) Pod 的名稱(chēng),后面到 K8S 集群中查找 Pod 的關(guān)鍵字段。
            • namespace。命名空間,即該 Pod 隸屬于哪個(gè) namespace 下,關(guān)于 Pod 和 namespace 的關(guān)系,上一篇文章已經(jīng)交代了。
          • spec記錄了 Pod 內(nèi)部所有的資源的詳細(xì)信息,這里我們重點(diǎn)查看containers下的幾個(gè)重要字段:

            • name。Pod 下該容器名稱(chēng),后面查找 Pod 下的容器的關(guān)鍵字段。

            • image。容器的鏡像地址,K8S 會(huì)根據(jù)這個(gè)字段去拉取鏡像。

            • resources。容器化服務(wù)涉及到的 CPU、內(nèi)存、GPU 等資源要求??梢钥吹接?code style="margin-right: 2px;margin-left: 2px;padding: 2px 4px;max-width: 100%;border-radius: 4px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);word-break: break-all;font-family: 'Microsoft YaHei';box-sizing: border-box !important;overflow-wrap: break-word !important;">limits和requests兩個(gè)子項(xiàng),那么這兩者有什么區(qū)別嗎,該怎么使用?在What's the difference between Pod resources.limits and resources.requests in Kubernetes?回答了:

              limits是 K8S 為該容器至多分配的資源配額;而requests則是 K8S 為該容器至少分配的資源配額。打個(gè)比方,配置中要求了 memory 的requests為 100M,而此時(shí)如果 K8S 集群中所有的 Node 的可用內(nèi)存都不足 100M,那么部署服務(wù)會(huì)失敗;又如果有一個(gè) Node 的內(nèi)存有 16G 充裕,可以部署該 Pod,而在運(yùn)行中,該容器服務(wù)發(fā)生了內(nèi)存泄露,那么一旦超過(guò) 200M 就會(huì)因?yàn)?OOM 被 kill,盡管此時(shí)該機(jī)器上還有 15G+的內(nèi)存。

            • command。容器的入口命令。對(duì)于這個(gè)筆者還存在很多困惑不解的地方,暫時(shí)挖個(gè)坑,有清楚的同學(xué)歡迎留言。

            • args。容器的入口參數(shù)。同上,有清楚的同學(xué)歡迎留言。

            • volumeMounts。容器要掛載的 Pod 數(shù)據(jù)卷等。請(qǐng)務(wù)必記住:Pod 的數(shù)據(jù)卷只有被容器掛載后才能使用!

          第二步:執(zhí)行 kubectl 命令部署。有了 Pod 的 yaml 文件之后,就可以用 kubectl 部署了,命令非常簡(jiǎn)單:kubectl create -f ${POD_YAML}。

          隨后,會(huì)提示該命令是否執(zhí)行成功,比如 yaml 內(nèi)容不符合要求,則會(huì)提示哪一行有問(wèn)題:

          修正后,再次部署:

          4.2 如何部署 Deployment?

          第一步:準(zhǔn)備 Deployment 的 yaml 文件。首先來(lái)看 Deployment 的 yaml 文件內(nèi)容:

          ?apiVersion:?extensions/v1beta1
          ?kind:?Deployment
          ?metadata:
          ???name:?rss-site
          ???namespace:?mem-example
          ?spec:
          ???replicas:?2
          ???template:
          ?????metadata:
          ???????labels:
          ?????????app:?web
          ?????spec:
          ??????containers:
          ???????-?name:?memory-demo-ctr
          ?????????image:?polinux/stress
          ?????????resources:
          ?????????limits:
          ???????????emory:?"200Mi"
          ?????????requests:
          ???????????memory:?"100Mi"
          ?????????command:?["stress"]
          ?????????args:?["--vm",?"1",?"--vm-bytes",?"150M",?"--vm-hang",?"1"]
          ?????????volumeMounts:
          ?????????-?name:?redis-storage
          ???????????mountPath:?/data/redis
          ?????volumes:
          ?????-?name:?redis-storage
          ???????emptyDir:?{}

          繼續(xù)來(lái)看幾個(gè)重要的字段:

          • metadata同 Pod 的 yaml,這里提一點(diǎn):如果沒(méi)有指明 namespace,那么就是用 kubectl 默認(rèn)的 namespace(如果 kubectl 配置文件中沒(méi)有指明 namespace,那么就是 default 空間)。
          • spec,可以看到 Deployment 的spec字段是在 Pod 的spec內(nèi)容外“包了一層”,那就來(lái)看 Deployment 有哪些需要注意的:
            • metadata,新手同學(xué)先不管這邊的信息。
            • spec,會(huì)發(fā)現(xiàn)這完完全全是上文提到的 Pod 的spec內(nèi)容,在這里寫(xiě)明了 Deployment 下屬管理的每個(gè) Pod 的具體內(nèi)容。
            • replicas。副本個(gè)數(shù)。也就是該 Deployment 需要起多少個(gè)相同的 Pod,如果用戶(hù)成功在 K8S 中配置了 n(n>1)個(gè),那么 Deployment 會(huì)確保在集群中始終有 n 個(gè)服務(wù)在運(yùn)行
            • template。

          第二步:執(zhí)行 kubectl 命令部署。Deployment 的部署辦法同 Pod:kubectl create -f ${DEPLOYMENT_YAML}。由此可見(jiàn),K8S 會(huì)根據(jù)配置文件中的kind字段來(lái)判斷具體要?jiǎng)?chuàng)建的是什么資源。

          這里插一句題外話:部署完 deployment 之后,可以查看到自動(dòng)創(chuàng)建了 ReplicaSet 和 Pod,如下圖所示:

          還有一個(gè)有趣的事情:通過(guò) Deployment 部署的服務(wù),其下屬的 RS 和 Pod 命名是有規(guī)則的。讀者朋友們自己總結(jié)發(fā)現(xiàn)哦。

          綜上,如何部署一個(gè) Pod 或者 Deployment 就結(jié)束了。

          V. kubectl 查看、更新/編輯、刪除服務(wù)

          作為 K8S 使用者而言,更關(guān)心的問(wèn)題應(yīng)該是本章所要討論的話題:如何通過(guò) kubectl 查看、更新/編輯、刪除在 K8S 上部署著的服務(wù)。

          5.1 如何查看服務(wù)?

          請(qǐng)務(wù)必記得一個(gè)事情:在 K8S 中,一個(gè)獨(dú)立的服務(wù)即對(duì)應(yīng)一個(gè) Pod。即,當(dāng)我們說(shuō)要 xxx 一個(gè)服務(wù)的就是,也就是操作一個(gè) Pod。而與 Pod 服務(wù)相關(guān)的且需要用戶(hù)關(guān)心的,有 Deployment。

          通過(guò) kubectl 查看服務(wù)的基本命令是:

          $?kubectl?get|describe?${RESOURCE}?[-o?${FORMAT}]?-n=${NAMESPACE}
          #?${RESOURCE}有:?pod、deployment、replicaset(rs)

          在此之前,還有一個(gè)需要回憶的事情是:Deployment、ReplicaSet 和 Pod 之間的關(guān)系 - 層層隸屬;以及這些資源和 namespace 的關(guān)系是 - 隸屬。如下圖所示。

          因此,要查看一個(gè)服務(wù),也就是一個(gè) Pod,必須首先指定 namespace!那么,如何查看集群中所有的 namespace 呢?kubectl get ns

          于是,只需要通過(guò)-n=${NAMESPACE}就可以指定自己要操作的資源所在的 namespace。比如查看 Pod:kubectl get pod -n=oona-test,同理,查看 Deployment:kubectl get deployment -n=oona-test

          問(wèn)題又來(lái)了:如果已經(jīng)忘記自己所部屬的服務(wù)所在的 namespace 怎么辦?這么多 namespace,一個(gè)一個(gè)查看過(guò)來(lái)嗎?

          kubectl get pod --all-namespaces

          這樣子就可以看到所有 namespace 下面部署的 Pod 了!同理,要查找所有的命名空間下的 Deployment 的命令是:kubectl get deployment --all-namespaces。

          于是,就可以開(kāi)心地查看 Pod:kubectl get pod [-o wide] -n=oona-test,或者查看 Deployment:kubectl get deployment [-o wide] -n=oona-test

          哎,這里是否加-o wide有什么區(qū)別嗎?實(shí)際操作下就明白了,其他資源亦然:

          哎,我們看到之前部署的 Pod 服務(wù) memory-demo 顯示的“ImagePullBackOff”是怎么回事呢?先不著急,我們慢慢看下去。

          5.2 如何更新/編輯服務(wù)?

          兩種辦法:1). 修改 yaml 文件后通過(guò) kubectl 更新;2). 通過(guò) kubectl 直接編輯 K8S 上的服務(wù)。

          方法一:修改 yaml 文件后通過(guò) kubectl 更新。我們看到,創(chuàng)建一個(gè) Pod 或者 Deployment 的命令是kubectl create -f ${YAML}。但是,如果 K8S 集群當(dāng)前的 namespace 下已經(jīng)有該服務(wù)的話,會(huì)提示資源已經(jīng)存在:

          通過(guò) kubectl 更新的命令是kubectl apply -f ${YAML},我們?cè)賮?lái)試一試:

          (備注:命令kubectl apply -f ${YAML}也可以用于首次創(chuàng)建一個(gè)服務(wù)哦)

          方法二:通過(guò) kubectl 直接編輯 K8S 上的服務(wù)。命令為kubectl edit ${RESOURCE} ${NAME},比如修改剛剛的 Pod 的命令為kubectl edit pod memory-demo,然后直接編輯自己要修改的內(nèi)容即可。

          但是請(qǐng)注意,無(wú)論方法一還是方法二,能修改的內(nèi)容還是有限的,從筆者實(shí)戰(zhàn)下來(lái)的結(jié)論是:只能修改/更新鏡像的地址和個(gè)別幾個(gè)字段。如果修改其他字段,會(huì)報(bào)錯(cuò):

          The Pod "memory-demo" is invalid: spec: Forbidden: pod updates may not change fields other than?spec.containers[*].image,?spec.initContainers[*].image,?spec.activeDeadlineSeconds?or?spec.tolerations?(only additions to existing tolerations)

          如果真的要修改其他字段怎么辦呢?恐怕只能刪除服務(wù)后重新部署了。

          5.3 如何刪除服務(wù)?

          在 K8S 上刪除服務(wù)的操作非常簡(jiǎn)單,命令為kubectl delete ${RESOURCE} ${NAME}。比如刪除一個(gè) Pod 是:kubectl delete pod memory-demo,再比如刪除一個(gè) Deployment 的命令是:kubectl delete deployment ${DEPLOYMENT_NAME}。但是,請(qǐng)注意:

          • 如果只部署了一個(gè) Pod,那么直接刪除該 Pod 即可;

          • 如果是通過(guò) Deployment 部署的服務(wù),那么僅僅刪除 Pod 是不行的,正確的刪除方式應(yīng)該是:先刪除 Deployment,再刪除 Pod

          關(guān)于第二點(diǎn)應(yīng)該不難想象:僅僅刪除了 Pod 但是 Deployment 還在的話,Deployment 定時(shí)會(huì)檢查其下屬的所有 Pod,如果發(fā)現(xiàn)失敗了則會(huì)再拉起。因此,會(huì)發(fā)現(xiàn)過(guò)一會(huì)兒,新的 Pod 又被拉起來(lái)了。

          另外,還有一個(gè)事情:有時(shí)候會(huì)發(fā)現(xiàn)一個(gè) Pod 總也刪除不了,這個(gè)時(shí)候很有可能要實(shí)施強(qiáng)制刪除措施,命令為kubectl delete pod --force --grace-period=0 ${POD_NAME}。

          VI. kubectl 排查服務(wù)問(wèn)題

          上文說(shuō)道:部署的服務(wù) memory-demo 失敗了,是怎么回事呢?本章就會(huì)帶大家一起來(lái)看看常見(jiàn)的 K8S 中服務(wù)部署失敗、服務(wù)起來(lái)了但是不正常運(yùn)行都怎么排查呢?

          首先,祭出筆者最?lèi)?ài)的一張 K8S 排查手冊(cè),來(lái)自博客《Kubernetes Deployment 故障排除圖解指南》:

          哈哈哈,對(duì)于新手同學(xué)來(lái)說(shuō),上圖還是不夠友好,下面我們簡(jiǎn)單來(lái)看兩個(gè)例子:

          6.1 K8S 上部署服務(wù)失敗了怎么排查?

          請(qǐng)一定記住這個(gè)命令:kubectl describe ${RESOURCE} ${NAME}。比如剛剛的 Pod 服務(wù) memory-demo,我們來(lái)看:

          拉到最后看到Events部分,會(huì)顯示出 K8S 在部署這個(gè)服務(wù)過(guò)程的關(guān)鍵日志。這里我們可以看到是拉取鏡像失敗了,好吧,大家可以換一個(gè)可用的鏡像再試試。

          一般來(lái)說(shuō),通過(guò)kubectl describe pod ${POD_NAME}已經(jīng)能定位絕大部分部署失敗的問(wèn)題了,當(dāng)然,具體問(wèn)題還是得具體分析。大家如果遇到具體的報(bào)錯(cuò),歡迎分享交流。

          6.2 K8S 上部署的服務(wù)不正常怎么排查?

          如果服務(wù)部署成功了,且狀態(tài)為running,那么就需要進(jìn)入 Pod 內(nèi)部的容器去查看自己的服務(wù)日志了:

          • 查看 Pod 內(nèi)部某個(gè) container 打印的日志:kubectl log ${POD_NAME} -c ${CONTAINER_NAME}
          • 進(jìn)入 Pod 內(nèi)部某個(gè) container:kubectl exec -it [options] ${POD_NAME} -c ${CONTAINER_NAME} [args],嗯,這個(gè)命令的作用是通過(guò) kubectl 執(zhí)行了docker exec xxx進(jìn)入到容器實(shí)例內(nèi)部。之后,就是用戶(hù)檢查自己服務(wù)的日志來(lái)定位問(wèn)題。

          顯然,線上可能會(huì)遇到更復(fù)雜的問(wèn)題,需要借助更多更強(qiáng)大的命令和工具。

          寫(xiě)在后面

          本文希望能夠幫助對(duì) K8S 不了解的新手快速了解 K8S。筆者一邊寫(xiě)文章,一邊查閱和整理 K8S 資料,過(guò)程中越發(fā)感覺(jué) K8S 架構(gòu)的完備、設(shè)計(jì)的精妙,是值得深入研究的,K8S 大受歡迎是有道理的。


          本文轉(zhuǎn)載自:「騰訊技術(shù)工程」,原文:https://tinyurl.com/ya3ennxf,版權(quán)歸原作者所有。

          往期資源回顧 需要可自取

          推薦閱讀

          點(diǎn)個(gè)[在看],是對(duì)杰哥最大的支持!
          瀏覽 180
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  婷婷五月综合久久 | 影音先锋色噜噜av | 天天精品 | 久草手机在线视频 | 亚洲综合娱乐视频播放 |