1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        寫給前端的 K8S 上手指南

        共 4846字,需瀏覽 10分鐘

         ·

        2022-02-09 21:48

        點擊上方?前端Q,關(guān)注公眾號

        回復(fù)加群,加入前端Q技術(shù)交流群


        大家好,我是 winty!

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

        作者:阮大蒙,
        鏈接:https://zhuanlan.zhihu.com/p/445217118 未經(jīng)作者允許,禁止轉(zhuǎn)載

        K8S 是什么

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

        宿主機模式

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

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

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

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

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

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

        容器

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

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

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

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

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

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

        開源的容器管理平臺

        K8S 的全稱是Kubernetes,因為在首字母k和尾字母s中間有8個字母,因此被簡寫為 K8S(類似的還有i18n等)。它是由谷歌開源的,主流的容器管理平臺。

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

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

        • 負載均衡
        • 高可用
        • 高并發(fā)(多實例)
        • 集群管理

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

        K8S 核心知識點

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

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

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

        • apiVersion - 創(chuàng)建該對象所使用的 Kubernetes API 的版本,不同的版本,對于 yaml 中可使用配置項的字段、格式有不同的要求。
        • kind - 想要創(chuàng)建的對象的類別
        • metadata - 幫助唯一性標識對象的一些數(shù)據(jù)
        • spec - 你所期望的該對象的狀態(tài)

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

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

        Ingress

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

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

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

        Sevice

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

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

        不論是正常的增減容器數(shù)量(擴縮容)還是容器自身因為意外重啟,流量總會被分配到可用的容器上。

        Development

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

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

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

        • 修改副本數(shù)量,然后副本集會以修改后的數(shù)量自動增刪容器
        • 修改容器配置,此時會采用先啟動新的容器,然后關(guān)閉舊的容器的方式,依次更新容器。這個階段,服務(wù)一直會處于可用的狀態(tài)。

        Pod

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

        以下是多容器配合的一個實例:

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

        kubectl 工具介紹

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

        MacOS 下的安裝教程:https://kubernetes.io/zh/docs/tasks/tools/install-kubectl-macos/

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

        ?touch?$HOME/.kube/config

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

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

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

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

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

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

        查看配置

        ?kubectl?get?service/?-o?yaml

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

        應(yīng)用配置文件

        上面提到過,K8S 中一切資源都可以從聲明式配置中得到。當我們想創(chuàng)建一個資源的時候,可以先創(chuàng)建對應(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 中對應(yīng)的容器的輸出信息。如果 Pod 中只有一個容器,container-name 可以省略。

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

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

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

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

        DEMO

        這個 demo 的目標是啟動一個 3 實例的 Node.js 后端程序,并實現(xiàn)以下效果:

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

        http://demo-20211215.io 域名指向的是集群 Ip,當請求/20211215這個路徑的時候,期望能收到 Node.js 后端返回的字符串:Hello World

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

          demo-20211215.io

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

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

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

        ingress 創(chuà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ī)則了。這個時候,再嘗試訪問demo-20211215.io/20211215,返回結(jié)果已經(jīng)有了變化:

        ?$?curl?demo-20211215.io/20211215
        ??????

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

        配置解析:

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

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

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

        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???????????80/TCP????51s

        配置解析:

         metadata.name // service 的名稱,在同一個 namespace 中,該字段是唯一的
        spec.selector.app // 這是一個選擇器,可以選擇 labels 中包含 app=demo-app-20211215 的 pod 加入這個 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ù),這里是 3,表示將會部署三個應(yīng)用實例
        spec.selector.matchLabels // 應(yīng)該與 spec.template.metadata.labels 相同,表示的是 pod 的 labels。
        spec.template.spec.containers // 是一個數(shù)組,表示這個 deployment 所使用的容器。

        在這里我使用了名為 rxh1212/demo-20211215 鏡像,它是我單獨編譯的,包含一個 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}`)

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

        這個鏡像的封裝、編譯過程,在此略過。感興趣的可以在評論區(qū)留言。

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

         $ curl demo-20211215.io/20211215
        < HTTP/1.1 200 OK
        < Server: nginx/1.19.2
        < Date: Tue, 14 Dec 2021 07:25:54 GMT
        < Content-Type: text/html; charset=utf-8
        < Content-Length: 11
        < Connection: keep-alive
        < X-Powered-By: Express
        < ETag: W/"b-Ck1VqNd45QIvq3AZd8XYQLvEhtA"
        <
        * Connection #0 to host demo-20211215.io left intact
        Hello World* Closing connection 0

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

        源碼

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

        寫在后面

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

        • 看完之后能讓讀者得到什么?看完本文后,我希望讀者能夠掌握以下知識點:


          • K8S 是什么
          • 掌握配置和使用 kubectl 工具的方法
          • 熟悉 K8S 的核心概念
          • 對“基于 K8S 部署的服務(wù)“進行簡單的故障排查和系統(tǒng)恢復(fù)


        往期推薦


        大廠面試官:我理想中的前端
        對話Svelte未來,Rust 編譯器?構(gòu)建大型應(yīng)用?
        收藏!史上最全 Vue 前端代碼風格指南

        最后


        • 歡迎加我微信,拉你進技術(shù)群,長期交流學習...

        • 歡迎關(guān)注「前端Q」,認真學前端,做個專業(yè)的技術(shù)人...

        點個在看支持我吧
        瀏覽 30
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            x7x7x7任意噪水 | 能看的黄色小说 | 成人性生交大片免费看无遮挡特黄 | 韩国一级淫片免费看 | 小黄片免费视频 | 91偷拍网站 | 韩国三级久久精品 | 91久久爽无码人妻AⅤ精品蜜桃 | 淫荡无码 | 国产美女精品精品喷水免费观看 |