<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>

          K8S 上手指南!

          共 4756字,需瀏覽 10分鐘

           ·

          2022-03-10 15:58

          在下方公眾號(hào)后臺(tái)回復(fù):JGNB,可獲取杰哥原創(chuàng)的 PDF 手冊(cè)。

          為了用好基于容器技術(shù)的各種工具、更好地熟悉云產(chǎn)品形態(tài),程序員們很有必要了解一下容器相關(guān)技術(shù),以下是正文。

          K8S 是什么

          在回答這個(gè)問題之前,讓我們一起先了解下 web 應(yīng)用部署方式的演化過程。

          宿主機(jī)模式

          在我剛接觸軟件開發(fā)的時(shí)候,人們部署應(yīng)用的方式通常是這樣的:

          首先需要一臺(tái)服務(wù)器,然后在服務(wù)器上安裝 Web Server (例如:Nginx 或者 Apache Server)。接著,根據(jù)應(yīng)用的運(yùn)行時(shí)要求,安裝對(duì)應(yīng)的軟件包(例如:如果代碼是用 Node.js 編寫,就需要安裝 Node.js 運(yùn)行時(shí)環(huán)境)。最后,根據(jù)應(yīng)用的其他功能,安裝對(duì)應(yīng)的軟件,如數(shù)據(jù)庫之類的。

          應(yīng)用部署的同時(shí),宿主機(jī)上也多了各種軟件程序。此時(shí),這個(gè) web 應(yīng)用提供的服務(wù)如下圖所示:

          隨著 web 應(yīng)用的日趨復(fù)雜,這種部署方式的弊端逐漸出現(xiàn)了。

          現(xiàn)代服務(wù)器性能非常強(qiáng)悍,如果一臺(tái)主機(jī)上僅運(yùn)行幾個(gè)程序,就可能造成機(jī)器資源利用率偏低。而且,由于程序是直接運(yùn)行在宿主機(jī)上的,程序之間存在資源競(jìng)爭(zhēng)關(guān)系,會(huì)互相影響。如果某個(gè)程序造成宿主機(jī)卡頓或掛掉,那么其他程序也無法正常工作了。

          在 2013 年出現(xiàn) Docker 容器技術(shù)之后,這種部署方式逐漸被淘汰了。

          容器

          容器技術(shù)有多種實(shí)現(xiàn)方式,比較主流的是 Docker。

          其 logo 很好的體現(xiàn)了“容器”的特點(diǎn)——程序就像一個(gè)個(gè)集裝箱,彼此隔離的運(yùn)行在宿主機(jī)上。

          區(qū)別于傳統(tǒng)的宿主機(jī)部署模式,容器化技術(shù)提供了一個(gè)隔離環(huán)境。程序之間既不會(huì)互相影響,也不會(huì)影響宿主機(jī)的穩(wěn)定。

          Docker 方式運(yùn)行的容器,可以理解為一個(gè)虛擬機(jī)(但和虛擬機(jī)還是有區(qū)別的,虛擬機(jī)是對(duì)硬件的虛擬化;Docker 是操作系統(tǒng)層的虛擬化)。它包含了運(yùn)行程序所需的運(yùn)行時(shí)環(huán)境和程序代碼,啟動(dòng)后能夠以端口映射的方式,將容器自身的服務(wù)暴露給宿主機(jī)和外部用戶。

          容器之間除了彼此隔離之外,也能夠通過 Docker 引擎實(shí)現(xiàn)互聯(lián)。容器之間的訪問通常是以內(nèi)部 IP 的方式進(jìn)行的。

          隨著 Web 應(yīng)用規(guī)模的繼續(xù)擴(kuò)大,單主機(jī)不再能滿足性能要求?,F(xiàn)在的部署是基于多主機(jī)、多容器進(jìn)行的。那么,如何對(duì)這些主機(jī)資源和應(yīng)用容器進(jìn)行管理?這個(gè)問題的答案指向了本文的主角—— K8S。

          開源的容器管理平臺(tái)

          K8S 的全稱是Kubernetes,因?yàn)樵谑鬃帜竗和尾字母s中間有8個(gè)字母,因此被簡寫為 K8S(類似的還有i18n等)。它是由谷歌開源的,主流的容器管理平臺(tái)。

          它的 logo 也很有意思,K8S 就像一個(gè)舵一樣,讓用戶能夠在茫茫大海中將滿載集裝箱的大船駛向成功的彼岸。

          借助 K8S 提供的能力,運(yùn)維人員——甚至是前端開發(fā)人員——能夠很容易地在集群環(huán)境中部署和管理容器。并且,對(duì)于以下功能,K8S 也能夠很好地支持:

          • 負(fù)載均衡

          • 高可用

          • 高并發(fā)(多實(shí)例)

          • 集群管理

          K8S 環(huán)境需要先被安裝和運(yùn)行起來。由于這部分的操作需要服務(wù)器支持,這里就不做介紹了。下文的全部內(nèi)容都基于讀者能夠連接到任一 K8S 系統(tǒng)這個(gè)前提之上。

          K8S 核心知識(shí)點(diǎn)

          在 K8S 中,所有資源都是通過聲明式配置進(jìn)行管理的,它們被稱作 K8S 對(duì)象。以 namespace 為例:

          ?apiVersion:?v1
          ?kind:?Namespace
          ?metadata:
          ???name:?demo-space
          ?spec:
          ???finalizers:
          ???-?kubernetes
          ?status:
          ???phase:?Active

          不同類型的對(duì)象所需的配置不完全相同,但他們都應(yīng)有如下幾個(gè)基礎(chǔ)配置:

          • apiVersion - 創(chuàng)建該對(duì)象所使用的 Kubernetes API 的版本,不同的版本,對(duì)于 yaml 中可使用配置項(xiàng)的字段、格式有不同的要求。

          • kind - 想要?jiǎng)?chuàng)建的對(duì)象的類別

          • metadata - 幫助唯一性標(biāo)識(shí)對(duì)象的一些數(shù)據(jù)

          • spec - 你所期望的該對(duì)象的狀態(tài)

          更詳細(xì)的文檔,請(qǐng)移步 K8S 官網(wǎng)。

          常見的 K8S 對(duì)象包括 Namespace、Ingress、Sevice、Development、Pod。其中,Namespace 是一個(gè)虛擬的概念,用來對(duì)集群劃分不同的命名空間。通常,同一個(gè) Namespace 中的資源,其命名應(yīng)該是唯一的。其他幾種類型的資源的關(guān)系如下圖所示:

          Ingress

          通常一個(gè)集群會(huì)包含數(shù)臺(tái)物理主機(jī),它們都是集群的節(jié)點(diǎn),這些節(jié)點(diǎn)需要一個(gè)統(tǒng)一的 IP 進(jìn)行訪問。Ingress 提供了這項(xiàng)能力,它是整個(gè)集群的流量入口。

          Ingress 控制器有多種實(shí)現(xiàn),比較常見的是基于 Nginx 實(shí)現(xiàn)的。

          Ingress-nginx 文檔:

          https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/

          Sevice

          流量從 Ingress 進(jìn)入集群之后,應(yīng)該被分配給不同的容器處理。但通常來說,容器的 IP 不是固定的,這是因?yàn)樵?K8S 中,可以隨時(shí)增減容器的數(shù)量,此時(shí)容器 IP 就是動(dòng)態(tài)的。

          Service 是一個(gè)抽象概念,它的作用是在 Ingress 和 Pod 之間解藕它們二者的關(guān)聯(lián)。它會(huì)動(dòng)態(tài)獲取可用的 Pod 的信息,傳遞給 Ingress,以保證進(jìn)行正確的負(fù)載均衡。

          不論是正常的增減容器數(shù)量(擴(kuò)縮容)還是容器自身因?yàn)橐馔庵貑?,流量總?huì)被分配到可用的容器上。

          Development

          Development 是用于管理副本集和容器配置的。K8S 不建議用戶直接操作副本集配置,所以 Development 通常是用戶所需要接觸的最基礎(chǔ)的配置。

          副本集一組以期望的規(guī)模穩(wěn)定運(yùn)行的容器集合。

          通過 Development,可以實(shí)現(xiàn)如下功能:

          • 修改副本數(shù)量,然后副本集會(huì)以修改后的數(shù)量自動(dòng)增刪容器

          • 修改容器配置,此時(shí)會(huì)采用先啟動(dòng)新的容器,然后關(guān)閉舊的容器的方式,依次更新容器。這個(gè)階段,服務(wù)一直會(huì)處于可用的狀態(tài)。

          Pod

          Pod 是 K8S 中最小的部署單元,它包含了一組容器(可以是一個(gè)或多個(gè))。同一個(gè) Pod 中的不同容器之間可以通過localhost:的方式互相訪問對(duì)方暴露出來的服務(wù),同時(shí),容器之間可以訪問共同的數(shù)據(jù)卷。多容器的使用場(chǎng)景通常是一個(gè)主容器加上多個(gè) sidecar,他們彼此配合,共同實(shí)現(xiàn)功能需求。

          以下是多容器配合的一個(gè)實(shí)例:

          上圖中的 Web Server 容器可以對(duì)外提供資源訪問的服務(wù),同時(shí),F(xiàn)ile Puller 作為一個(gè) sidecar 容器,可以同時(shí)將遠(yuǎn)端的內(nèi)容更新到本地存儲(chǔ)中,以保證 Web Server 提供的內(nèi)容是最新的。

          kubectl 工具介紹

          kubectl 是 K8S 提供的命令行工具,使得用戶可以在本地對(duì) K8S 集群發(fā)送操作指令。

          MacOS 下的安裝教程:

          https://kubernetes.io/zh/docs/tasks/tools/install-kubectl-macos/

          安裝完成后,創(chuàng)建配置文件:

          touch?$HOME/.kube/config

          然后在文件中加入集群配置:

          下面的配置僅做參考,連接集群的時(shí)候需要改為對(duì)應(yīng)的配置。

          ?apiVersion:?v1
          ?#?集群配置,可以是多個(gè);集群必須包含 server 字段
          ?clusters:
          ???-?cluster:
          ???????server:?https://dami.net
          ?????name:?dami-c3
          ?#?上下文配置,可以是多個(gè),每個(gè)上下文必須包含集群名稱、namespace?名稱、用戶名
          ?contexts:
          ???-?context:
          ???????cluster:?dami-c3
          ???????namespace:?demo-space
          ???????user:?manooog
          ?????name:?c3-demo-space-context
          ?#?當(dāng)前默認(rèn)的上下文配置,所有?kubectl?命令,都會(huì)默認(rèn)使用這個(gè)上下文
          ?current-context:?c3-demo-space-context
          ?kind:?Config
          ?#?用戶信息,包含用戶名和對(duì)應(yīng)的權(quán)限信息,可能是?token
          ?users:
          ???-?name:?manooog
          ?????user:
          ???????token:?

          保存好配置之后,就可以是使用 kubectl 命令對(duì)集群進(jìn)行操作了。eg:

          kubectl?get?ingress?#?獲取當(dāng)前?context?中對(duì)應(yīng)的?namespace?中的?Ingress?配置

          kubectl 功能比較多,根據(jù)使用習(xí)慣的不同,同一個(gè)功能也有不同的使用方式。下面列舉一些我使用得比較多的命令。

          查看配置

          kubectl?get?service/?-o?yaml

          以上命令的含義是,獲取名稱為xxx的 service 對(duì)應(yīng)的配置文件,并且以 yaml 格式輸出。對(duì)于不同的資源,通常是以<類型>/<名稱>進(jìn)行區(qū)分的。

          應(yīng)用配置文件

          上面提到過,K8S 中一切資源都可以從聲明式配置中得到。當(dāng)我們想創(chuàng)建一個(gè)資源的時(shí)候,可以先創(chuàng)建對(duì)應(yīng)的配置文件。然后使用以下命令使配置生效:

          kubectl?create?-f?service.yaml
          kubectl?apply?-f?service.yaml

          以上命令都可以應(yīng)用配置文件,區(qū)別就在在于,create 通常用于第一次創(chuàng)建,apply則用于修改已存在的配置文件。我更傾向于使用 apply 命令。

          二者在使用上的區(qū)別:

          https://stackoverflow.com/questions/47369351/kubectl-apply-vs-kubectl-create

          查看 Pod 輸出

          kubectl?logs?<pod>?<conteiner-name>

          獲取 Pod 中對(duì)應(yīng)的容器的輸出信息。如果 Pod 中只有一個(gè)容器,container-name 可以省略。

          進(jìn)入容器內(nèi)部命令行環(huán)境

          在容器運(yùn)行過程中,可能會(huì)出現(xiàn)異常情況,這個(gè)時(shí)候需要進(jìn)入容器內(nèi)部進(jìn)行檢查。這個(gè)時(shí)候可以使用以下命令:

          kubectl?exec?-it?demo-5b7846d65b-nvnnm?--?sh

          如果 Pod 包含多個(gè)容器,同樣需要使用 -c參數(shù),指定需要進(jìn)入的容器名稱。

          DEMO

          這個(gè) demo 的目標(biāo)是啟動(dòng)一個(gè) 3 實(shí)例的 Node.js 后端程序,并實(shí)現(xiàn)以下效果:

          curl?demo-20211215.io/20211215
          //?->?Hello?World

          http://demo-20211215.io 域名指向的是集群 Ip,當(dāng)請(qǐng)求/20211215這個(gè)路徑的時(shí)候,期望能收到 Node.js 后端返回的字符串:Hello World。

          由于這個(gè)示例域名是不存在的,因此我們這里利用 Hosts 進(jìn)行配置。在本地 Hosts 增加一條記錄,將域名直接綁定到測(cè)試集群的 Ingress IP上:

          ?demo-20211215.io

          現(xiàn)在執(zhí)行測(cè)試命令,將會(huì)得到下面的提示:

          $?curl?-v?demo-20211215.io/2021215
          *???Trying?<Ingress?IP>...
          *?TCP_NODELAY?set
          *?Connected?to?demo-20211215.io?(<Ingress?IP>)?port?80?(#0)
          >?GET?/2021215?HTTP/1.1
          >?Host:?demo-20211215.io
          >?User-Agent:?curl/7.64.1
          >?Accept:?*/*
          >?

          Server:?nginx/1.19.2
          Date:
          ?Tue,?14?Dec?2021?07:10:59?GMT
          Content-Type:?text/plain;?charset=utf-8
          Content-Length:?21
          Connection:?keep-alive

          目前集群還不能響應(yīng)對(duì)于 /20211215 這個(gè) path 的請(qǐng)求。接下來,讓我們一起試著將這個(gè)服務(wù)部署起來。

          ingress 創(chuàng)建

          首先,我們需要?jiǎng)?chuàng)建一條 Ingress 規(guī)則,并保存為ingress.yml:

          apiVersion:?extensions/v1beta1
          kind:?Ingress
          metadata:
          ??name:?demo-20211215
          ??annotations:
          ????nginx.ingress.kubernetes.io/ssl-redirect:?"false"
          spec:
          ??rules:
          ????-?host:?demo-20211215.io
          ??????http:
          ????????paths:
          ??????????-?path:?/20211215
          ????????????backend:
          ??????????????serviceName:?demo-service-20211215
          ??????????????servicePort:?80

          執(zhí)行創(chuàng)建命令:

          kubectl?apply?-f?ingress.yaml

          接著再執(zhí)行:

          kubectl?get?ingress?????????????????????????????
          NAME???????????????????HOSTS??????????????????????????????????????????????????????????????????????????ADDRESS???????????????????????????????????????????????????????????????????????PORTS?????AGE
          demo-20211215??????????demo-20211215.io?????????????????????????????????????????????????????10.136.3.47,10.136.3.48,10.136.32.44,10.136.32.45,10.136.35.53,10.136.37.54???80????????2m13s

          就可以看到剛才創(chuàng)建的那條 ingress 規(guī)則了。這個(gè)時(shí)候,再嘗試訪問demo-20211215.io/20211215,返回結(jié)果已經(jīng)有了變化:

          $?curl?demo-20211215.io/20211215
          1.1?503?Service?Temporarily?Unavailable
          1.19.2
          Date:?Tue,?14?Dec?2021?07:20:28?GMT
          text/html
          197

          目前服務(wù)仍不可訪問,但配置已生效。

          配置解析:

          metadata.name?//?這條 ingress 的規(guī)則名稱,同一個(gè) namespace 中,name 字段是唯一的。
          metadata.annotations?//?這個(gè)是對(duì)?ingress?控制器的配置,視具體情況而定
          spec.rules?//?匹配規(guī)則

          在這個(gè)配置中,有一條規(guī)則。即:響應(yīng)對(duì) http://demo-20211215.io/20211215 這個(gè) URL 的請(qǐng)求,并且將請(qǐng)求轉(zhuǎn)發(fā)給名為 demo-service-20211215的這個(gè) service 的 80 端口。

          注意,這個(gè)時(shí)候尚未創(chuàng)建對(duì)應(yīng)的 Service,但 K8S 并沒有提示創(chuàng)建 ingress 失敗。這是因?yàn)镵8S提供的服務(wù)發(fā)現(xiàn)的能力,如果后期對(duì)應(yīng)的服務(wù)被創(chuàng)建了,那么自然會(huì)被 ingress 識(shí)別,并分配流量過去。

          service 創(chuàng)建

          創(chuàng)建service.yaml并貼入以下內(nèi)容:

          apiVersion:?v1
          kind:?Service
          metadata:
          ??name:?demo-service-20211215
          spec:
          ??selector:
          ????app:?demo-app-20211215
          ??ports:
          ????-?protocol:?TCP
          ??????port:?80
          ??????targetPort:?3000

          執(zhí)行創(chuàng)建命令:

          kubectl?apply?-f?service.yaml

          創(chuàng)建好之后通過以下命令查看:

          kubectl?get?service/demo-service-20211215???????????????
          NAME????????????TYPE????????CLUSTER-IP??????EXTERNAL-IP???PORT(S)???AGE
          demo-service-20211215???ClusterIP???10.254.40.168???<none>????????80/TCP????51s

          配置解析:

          metadata.name?//?service?的名稱,在同一個(gè)?namespace?中,該字段是唯一的
          spec.selector.app?//?這是一個(gè)選擇器,可以選擇?labels?中包含?app=demo-app-20211215?的?pod?加入這個(gè)?service?中

          deployment 創(chuàng)建

          將下面的配置內(nèi)容保存為deployment.yaml:

          apiVersion:?apps/v1
          kind:?Deployment
          metadata:
          ??name:?demo-deployment-20211215
          spec:
          ??replicas:?3
          ??selector:
          ????matchLabels:
          ??????app:?demo-app-20211215
          ??template:
          ????metadata:
          ??????labels:
          ????????app:?demo-app-20211215
          ????spec:
          ??????containers:
          ????????-?name:?demo-20211215
          ??????????image:?rxh1212/demo-20211215
          ??????????ports:
          ????????????-?containerPort:?3000

          創(chuàng)建以及查看的命令就不再舉例了。

          配置解析:

          metadata.name?//?deployment?的名稱,也是?namespace?中必須要唯一的
          spec.replicas?//?pod?的實(shí)例個(gè)數(shù),這里是?3,表示將會(huì)部署三個(gè)應(yīng)用實(shí)例
          spec.selector.matchLabels?//?應(yīng)該與 spec.template.metadata.labels 相同,表示的是 pod 的 labels。
          spec.template.spec.containers?//?是一個(gè)數(shù)組,表示這個(gè) deployment 所使用的容器。

          在這里我使用了名為 rxh1212/demo-20211215 鏡像,它是我單獨(dú)編譯的,包含一個(gè) Node.js 應(yīng)用。代碼如下:

          "use?strict"

          const?express?=?require("express")

          //?Constants
          const?PORT?=?3000
          const?HOST?=?"0.0.0.0"

          //?App
          const?app?=?express()
          app.get("/20211215",?(req,?res)?=>?{
          ??res.send("Hello?World")
          })

          app.listen(PORT,?HOST)
          console.log(`Running?on?http://${HOST}:${PORT}`)

          鏡像啟動(dòng)之后,會(huì)在 3000 端口提供一個(gè) Http 服務(wù)。如果訪問 /20211215,會(huì)收到Hello World的響應(yīng)。

          言歸正傳,deployment 創(chuàng)建好之后,再對(duì)demo-20211215.io/20211215進(jìn)行訪問,即可得到以下響應(yīng):

          $?curl?demo-20211215.io/20211215
          1.1?200?OK
          1.19.2
          Date:?Tue,?14?Dec?2021?07:25:54?GMT
          text/html;?charset=utf-8
          11
          By:?Express
          "b-Ck1VqNd45QIvq3AZd8XYQLvEhtA"
          *?Connection?#0?to?host?demo-20211215.io?left?intact
          Hello?World*?Closing?connection?0

          至此,我們完成了一個(gè)簡單的 K8S 部署流程。

          源碼

          以上 Demo 使用的配置代碼,已上傳至 github 中:https://github.com/manooog/K8S-demo-20211215

          寫在后面

          為什么寫容器相關(guān)文章?容器技術(shù)在前端開發(fā)中經(jīng)常會(huì)遇到,例如:Gitlab CI/CD 使用的容器技術(shù)作為構(gòu)建中的一環(huán)、開源或者公司自建的容器平臺(tái)產(chǎn)品都是以容器技術(shù)作為支撐的。為了用好基于容器技術(shù)的各種工具、更好地熟悉云產(chǎn)品形態(tài),前端開發(fā)工程師們很有必要了解一下容器相關(guān)技術(shù)。本文以 K8S 為引子,介紹了軟件開發(fā)中應(yīng)用部署方式的迭代變化、K8S 中的基礎(chǔ)概念以及 kubectl 工具的用法,希望能夠?yàn)槌鯇W(xué)容器技術(shù)的小伙伴提供一點(diǎn)幫助。

          看完之后能讓讀者得到什么?看完本文后,我希望讀者能夠掌握以下知識(shí)點(diǎn):K8S 是什么、掌握配置和使用 kubectl 工具的方法、熟悉 K8S 的核心概念、對(duì)“基于 K8S 部署的服務(wù)“進(jìn)行簡單的故障排查和系統(tǒng)恢復(fù)

          來自:知乎,作者:阮大蒙
          鏈接:https://zhuanlan.zhihu.com/p/445217118

          推薦閱讀

          16個(gè)概念帶你入門 Kubernetes


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

          瀏覽 39
          點(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>
                  秋霞午夜 | 天堂操逼 | 国产精品视频成人 | 婷婷一区二区三区 | 蜜桃成人无码区免费视频网站 |