您好,登錄后才能下訂單哦!
這篇文章主要介紹“怎么理解前端領(lǐng)域的Docker與Kubernetes”,在日常操作中,相信很多人在怎么理解前端領(lǐng)域的Docker與Kubernetes問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”怎么理解前端領(lǐng)域的Docker與Kubernetes”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
Docker 安裝
Linux Debian/Ubuntu, 安裝 社區(qū)版DockerCE
Windows 一鍵安裝
如果是 Windows10, Windows7 將會(huì)使用 VirtualBox 安裝 Linux 作為 Docker 的宿主機(jī)。
Windows10 Pro 會(huì)使用 Hyper-V 安裝 Linux 作為 Docker 的宿主機(jī)。
macOS 一鍵安裝
Docker 基本信息
默認(rèn) Docker 存儲(chǔ)位置為 /var/lib/docker,所有的鏡像,容器,卷都會(huì)在這里,如果你使用了多硬盤(pán),或者掛載了 SSD 不在 / 上,需要修改默認(rèn)路徑(graph)到合適位置,配置文件為 /etc/docker/daemon.json, 例如
{ "bip": "192.168.0.1/16", "graph": "/mnt/ssd/0/docker" }
Docker 在安裝過(guò)程中會(huì)自動(dòng)創(chuàng)建好 docker0 網(wǎng)卡,并分配 ip 給他。
上面指定的 bip 是指定了 docker0 網(wǎng)卡的 ip , 如果不指定那么在創(chuàng)建 docker0 時(shí)會(huì)自動(dòng)根據(jù)主機(jī) ip 選取一個(gè)合適的 ip,不過(guò)由于網(wǎng)絡(luò)的復(fù)雜性,特別是機(jī)房網(wǎng)絡(luò)內(nèi)很容易發(fā)現(xiàn)地址選取沖突,這時(shí)候就需要手動(dòng)指定 bip 為一個(gè)合適的值。docker 的 ip 選取規(guī)則這篇文章分析的很好, 可以參考 https://blog.csdn.net/longxin... 。
安裝并啟動(dòng)后可以通過(guò) docker info 查看Docker的一些配置信息。
Docker hello world
Docker 檢查安裝是否正常的第一個(gè)測(cè)試命令很簡(jiǎn)單。
docker run hello-world
首先他會(huì)去 Docker Hub 上下載 hello-world 這個(gè)鏡像,然后在本地運(yùn)行這個(gè)鏡像,啟動(dòng)后的這個(gè) Docker 服務(wù)稱(chēng)之為容器。容器創(chuàng)建后就會(huì)執(zhí)行規(guī)定的入口程序,程序執(zhí)行向流中輸出了一些信息后退出,容器也會(huì)隨著這個(gè)入口程序的結(jié)束而結(jié)束。
查看所有容器
docker ps -a
輸出如下:
cf9a6bc212f9 hello-world "/hello" 28 hours ago Exited (0) 3 min
第一列為容器 id, 很多針對(duì)容器的操作都需要這個(gè) id, 例如下面一些常用的操作。
docker rm container_id docker stop container_id docker start container_id docker describe container_id
這里有個(gè)docker start container_id, 啟動(dòng)一個(gè)容器,說(shuō)明容器即使退出后其資源依然存在,還可以使用docker start重啟這個(gè)容器。要想讓容器退出后自動(dòng)刪除可以在docker run時(shí)指定--rm參數(shù)。
當(dāng)我們運(yùn)行這個(gè)命令時(shí) Docker 會(huì)去下載 hello-world 這個(gè)鏡像緩存到本地,這樣當(dāng)下次再運(yùn)行這條命令時(shí)就不需要去源中下載。
查看本地鏡像
docker images
運(yùn)行 Nginx
Nginx 作為使用廣泛的 Web 服務(wù)器在 Docker 世界里也是同樣流行, 常常用來(lái)啟動(dòng)一個(gè)網(wǎng)絡(luò)服務(wù)驗(yàn)證網(wǎng)絡(luò)配置情況, 使用下面這條命令啟動(dòng) Nginx 容器 docker run --rm -p 80:80 nginx。
訪問(wèn) localhost:80 端口即可看到 Nginx 服務(wù)啟動(dòng), 控制臺(tái)中可以看到 Nginx 服務(wù)的日志輸出。
因?yàn)?Docker 內(nèi)的網(wǎng)絡(luò)與外部世界是隔離的,所以我們需要手動(dòng)指定端口轉(zhuǎn)發(fā) -p 80:80 來(lái)顯式將宿主機(jī)的80(前)轉(zhuǎn)發(fā)到容器的80端口, 暴露端口是我們提供服務(wù)最常用的使用方式之一。 也有一些其他類(lèi)型的服務(wù),例如日志處理,數(shù)據(jù)收集需要共享數(shù)據(jù)卷才能提供服務(wù),所有這些都需要我們?cè)趩?dòng)容器時(shí)顯式指定。
一些常見(jiàn)的啟動(dòng)參數(shù):
-p 本機(jī)端口:容器端口 映射本地端口到容器
-P 將容器端口映射為本機(jī)隨機(jī)端口
-v 本地路徑或卷名:容器路徑 將本地路徑或者數(shù)據(jù)卷掛載到容器的指定位置
-it 作為交互式命令啟動(dòng)
-d 將容器放在后臺(tái)運(yùn)行
--rm 容器退出后清除資源
Docker是如何工作的
Docker 的底層核心原理是利用了 Linux 內(nèi)核的 namespace 以及 cgroup 特性,其中 namespace 進(jìn)行資源隔離,cgroup 進(jìn)行資源配額, 其中 Linux 內(nèi)核中一共有 6 種 namespace,分別對(duì)應(yīng)如下。
Namespace | 系統(tǒng)調(diào)用函數(shù) | 隔離內(nèi)容 |
---|---|---|
UTS | CLONE_NEWUTS | 主機(jī)與域名 |
IPC | CLONE_NEWIPC | 信號(hào)量、消息隊(duì)列和共享內(nèi)存 |
PID | CLONE_NEWPID | 進(jìn)程編號(hào) |
Network | CLONE_NEWNET | 網(wǎng)絡(luò)設(shè)備、網(wǎng)絡(luò)棧、端口等 |
Mount | CLONE_NEWNS | 掛載點(diǎn)(文件系統(tǒng)) |
User | CLONE_NEWUSER | 用戶和用戶組 |
在系統(tǒng)調(diào)用中有三個(gè)與namespace有關(guān)的函數(shù):
clone http://man7.org/linux/man-pag...
如果我想讓子進(jìn)程擁有獨(dú)立的網(wǎng)絡(luò)地址,TCP/IP 協(xié)議棧,可以下面這樣指定。
clone(cb, *stack , CLONE_NEWNET, 0)
unshare http://man7.org/linux/man-pag...
將當(dāng)前進(jìn)程轉(zhuǎn)移到新的 namespace 中, 例如使用 fork 或 vfork 創(chuàng)建的進(jìn)程將默認(rèn)共享父級(jí)資源,使用 unshare 將子進(jìn)程從父級(jí)取消共享。
setns http://man7.org/linux/man-pag...
給指定的PID指定 namespace, 通常用于共享 namespace。
Linux 在內(nèi)核層支持了在系統(tǒng)調(diào)用中隔離 namespace, 通過(guò)給一個(gè)進(jìn)程分配單獨(dú)的 namespace 從而讓其在各個(gè)資源維度進(jìn)行隔離,每個(gè)進(jìn)程都能獲取到自己的主機(jī)名,IPC, PID, IP, 根文件系統(tǒng),用戶組等信息,就像在一個(gè)獨(dú)占系統(tǒng)中,不過(guò)雖然資源進(jìn)行了隔離,但是內(nèi)核還是共享同一個(gè),這也是比傳統(tǒng)虛擬機(jī)輕量的原因之一。
另外只有資源進(jìn)行隔離還不夠,要想保證真正的故障隔離,互不影響, 還需要對(duì)針對(duì) CPU, 內(nèi)存,GPU 等進(jìn)行限制,因?yàn)槿绻粋€(gè)程序出現(xiàn)死循環(huán)或者內(nèi)存泄露也會(huì)導(dǎo)致別的程序無(wú)法運(yùn)行。 資源配額是使用內(nèi)核的 cgroup 特性來(lái)完成,想了解細(xì)節(jié)的同學(xué)可以
(另外強(qiáng)烈推薦在 Linux 4.9 以上的內(nèi)核跑容器,Linux 3.x 中有已知內(nèi)核不穩(wěn)定導(dǎo)致主機(jī)重啟的問(wèn)題)
Docker 網(wǎng)絡(luò)
一個(gè)容器要想提供服務(wù),就需要將自身的網(wǎng)絡(luò)暴露出去。Docker 是與宿主機(jī)上的環(huán)境是隔離的,要想暴露服務(wù)就需要顯示告訴 Docker 哪些端口允許外部訪問(wèn),在運(yùn)行 docker run -p 80:80 nginx 時(shí)這里就是將容器內(nèi)部的 80 端口暴露到宿主機(jī)的 80 端口上,具體的端口轉(zhuǎn)發(fā)下面會(huì)具體分析一下。容器的網(wǎng)絡(luò)部分是容器中最重要的部分,也是構(gòu)建大型集群的基石,在我們部署 Docker 的應(yīng)用時(shí),需要要對(duì)網(wǎng)絡(luò)有個(gè)基本的了解。
Docker 提供了四種網(wǎng)絡(luò)模式,分別為 Host, Container, None, Bridge 使用 --net 進(jìn)行指定
Host 模式:
docker run --net host nginx
Host 模式不會(huì)單獨(dú)為容器創(chuàng)建 network namespace, 容器內(nèi)部直接使用宿主機(jī)網(wǎng)卡,此時(shí)容器內(nèi)獲取 ip 為宿主機(jī) ip,端口綁定直接綁在宿主機(jī)網(wǎng)卡上,優(yōu)點(diǎn)是網(wǎng)絡(luò)傳輸時(shí)不用經(jīng)過(guò) NAT 轉(zhuǎn)換,效率更高速度更快。
Container 模式:
docker run --net container:xxx_containerid nginx
和指定的 container 共享 network namespace, 共享網(wǎng)絡(luò)配置,ip 地址和端口,其中無(wú)法共享網(wǎng)絡(luò)模式為 Host 的容器。
None 模式:
docker run --net none busybox ifconfig
指定為 None 模式的容器內(nèi)將不會(huì)分配網(wǎng)卡設(shè)備,僅有內(nèi)部 lo 網(wǎng)絡(luò)。
Bridge 模式
docekr run --net bridge busybox ifconfig
該模式為默認(rèn)模式,容器啟動(dòng)時(shí)會(huì)被分配一個(gè)單獨(dú)的 network namespace,同時(shí) Docker 在安裝/初始化時(shí)會(huì)在宿主機(jī)上創(chuàng)建一個(gè)名為 docker0 的網(wǎng)橋,該網(wǎng)橋也作為容器的默認(rèn)網(wǎng)關(guān),容器網(wǎng)絡(luò)會(huì)在該網(wǎng)關(guān)網(wǎng)段內(nèi)進(jìn)行 ip 的分配。
當(dāng)我執(zhí)行 docker run -p 3000:80 nginx 時(shí),Docker 會(huì)在宿主機(jī)上創(chuàng)建下面一條 iptable 轉(zhuǎn)發(fā)規(guī)則。
最底下的規(guī)則顯示當(dāng)外部請(qǐng)求主機(jī)網(wǎng)卡 3000 端口時(shí)將它進(jìn)行目的地址轉(zhuǎn)換(DNAT), 目的地址修改為 172.18.0.2,端口修改為 80,修改好目的地址后流量會(huì)從本機(jī)默認(rèn)網(wǎng)卡經(jīng)過(guò) docker0 轉(zhuǎn)發(fā)到對(duì)應(yīng)的容器,這樣當(dāng)外部請(qǐng)求宿主機(jī)的 3000 端口,內(nèi)部會(huì)將流量轉(zhuǎn)發(fā)給內(nèi)部容器服務(wù),從而實(shí)現(xiàn)服務(wù)的暴露。
同樣 Docker 內(nèi)部訪問(wèn)外部接口也會(huì)進(jìn)行源地址轉(zhuǎn)換(SNAT), 容器內(nèi)部請(qǐng)求 google.com, 服務(wù)器上收到的將是主機(jī)網(wǎng)卡的 ip。
Bridge 模式由于多了一層 NAT 轉(zhuǎn)換所以效率會(huì)比 Host 模式差一些,但是能夠很好的隔離外部網(wǎng)絡(luò)環(huán)境,讓容器獨(dú)享 ip 且具有完整的端口空間。
上面四種網(wǎng)絡(luò)模式是 Docker 自帶的幾種工作方式,但是部署 Kubernetes 需要所有的容器都工作在一個(gè)局域網(wǎng)中,所以在部署集群時(shí)需要多主機(jī)網(wǎng)絡(luò)插件的支持。
Flannel
多主機(jī)網(wǎng)絡(luò)解決方案有 CNCF 推出的 CNI 規(guī)范以及 Docker 自帶的 CNM 方案,但是目前大家用的最多的還是 CNI 規(guī)范,其中一種實(shí)現(xiàn)就是 Flannel。
Flannel 使用了報(bào)文嵌套技術(shù)來(lái)解決多主機(jī)網(wǎng)絡(luò)互通問(wèn)題,將原始報(bào)文進(jìn)行封包,指定包ip為目的主機(jī)地址,等包到達(dá)主機(jī)后再進(jìn)行拆包傳送到對(duì)應(yīng)的容器。下圖顯示 flannel 使用效率更高的 UDP 協(xié)議來(lái)在主機(jī)間傳輸報(bào)文。
目前主流跨主機(jī)通信目前常用的有三種,各有優(yōu)缺,視場(chǎng)景選擇:
overlay, 即上面的報(bào)文嵌套。
hostgw 通過(guò)修改主機(jī)路由表實(shí)現(xiàn)轉(zhuǎn)發(fā),不需要拆包和封包,效率更高,但同樣限制比較多,只適合在相同局域網(wǎng)中的主機(jī)使用。
使用軟件實(shí)現(xiàn)的 BGP(邊界網(wǎng)關(guān)協(xié)議)以此向網(wǎng)絡(luò)中的路由器廣播路由規(guī)則。和 hostgw 一樣不需要拆包,但是實(shí)現(xiàn)成本較高。
有了CNI才能在此基礎(chǔ)上構(gòu)建 Kubernetes 集群。
Kubernetes 介紹
在小規(guī)模場(chǎng)景下使用 Docker 可以一鍵部署應(yīng)用確實(shí)很方便,達(dá)到了一鍵部署的目的,但是當(dāng)出現(xiàn)需要在幾百臺(tái)主機(jī)上進(jìn)行多副本部署,需要管理這么多主機(jī)的運(yùn)行狀態(tài)以及服務(wù)的故障時(shí)需要在其他主機(jī)重啟服務(wù),想象一下就知道手動(dòng)的方式不是一種可取的方案,這時(shí)候就需要利用 Kubernetes 這種更高維度的編排工具來(lái)管理了。Kubernetes 簡(jiǎn)稱(chēng) K8S, 簡(jiǎn)單說(shuō) K8S 就是抽象了硬件資源,將 N 臺(tái)物理機(jī)或云主機(jī)抽象成一個(gè)資源池,容器的調(diào)度交給 K8S 就像親媽一樣照顧我們的容器,CPU 不夠用就調(diào)度到一臺(tái)足夠使用的機(jī)器上,內(nèi)存不滿足要求就會(huì)尋找一臺(tái)有足夠內(nèi)存的機(jī)器在上面創(chuàng)建對(duì)應(yīng)的容器,服務(wù)因?yàn)槟承┰驋炝耍?K8S 還會(huì)幫我們自動(dòng)遷移重啟, 簡(jiǎn)直無(wú)微不至,至尊享受。我們作為開(kāi)發(fā)者只關(guān)心自己的代碼,應(yīng)用的健康由 K8S 保證。
這里就不介紹具體的安裝方式了,如果使用 Windows 或者 MacOS 可以直接使用 Docker Desktop 下的 Kubernetes 選項(xiàng)一鍵安裝單主機(jī)集群,也可以使用 kind 工具 在本地模擬多集群 K8S。
K8S 調(diào)度的基本單位為 pod, 一個(gè) pod 表示一個(gè)或多個(gè)容器。引用一本書(shū)里所說(shuō)
之所以沒(méi)有使用容器作為調(diào)度單位,是因?yàn)閱我坏娜萜鳑](méi)有構(gòu)成服務(wù)的概念;例如 Web 應(yīng)用做了前后端分例,需要一個(gè) NodeJS 與 Tomcat 才能組成一個(gè)完整的服務(wù),這樣就需要部署兩個(gè)容器來(lái)實(shí)現(xiàn)一個(gè)完整的服務(wù),雖然也可以把他們都放到一個(gè)容器里,但這顯然違反了一個(gè)容器即一個(gè)進(jìn)程的核心思想 --《Service Mesh實(shí)戰(zhàn) - 用 istio軟負(fù)載實(shí)現(xiàn)服務(wù)網(wǎng)格》
K8S 與傳統(tǒng) IaaS 系統(tǒng)的不同:
IaaS 就是 Infrastructure as a service, 所謂基礎(chǔ)設(shè)施即服務(wù),開(kāi)發(fā)者想要上線一個(gè)新應(yīng)用需要申請(qǐng)主機(jī),ip, 域名等一系列資源,然后登錄主機(jī)自行搭建所需環(huán)境,部署應(yīng)用上線,這樣不僅不利于大規(guī)模操作,而且還增加了出錯(cuò)的可能,運(yùn)維或開(kāi)發(fā)這常常自己寫(xiě)腳本自動(dòng)化完成,遇到一些差異再手動(dòng)修改腳本,非常痛苦。
K8S 則是將基礎(chǔ)設(shè)施可編程化,由原來(lái)的人工申請(qǐng)改為一個(gè)清單文件自動(dòng)創(chuàng)建,開(kāi)發(fā)者只需要提交一份文件,K8S 將會(huì)自動(dòng)為你分配創(chuàng)建所需的資源。對(duì)這些設(shè)施的 CRUD 都可以通過(guò)程序的方式自動(dòng)化操作。
為了了解 K8S 的基礎(chǔ)概念,下面來(lái)部署一個(gè) Node SSR 應(yīng)用:
初始化應(yīng)用模板
npm install create-next-app npx create-next-app next-app cd next-app
創(chuàng)建好工程后給添加一個(gè) Dockerfile 用來(lái)構(gòu)建服務(wù)的鏡像
Dockerfile
FROM node:8.16.1-slim as build COPY ./ /app WORKDIR /app RUN npm install RUN npm run build RUN rm -rf .git FROM node:8.16.1-slim COPY --from=build /app / EXPOSE 3000 WORKDIR /app CMD ["npm", "start"]
這個(gè) Dockerfile 做了兩部分優(yōu)化
使用精簡(jiǎn)版的 node 基礎(chǔ)鏡像, 大大減少鏡像體積
使用分步構(gòu)建的方式, 能夠減少鏡像層數(shù)以及移除臨時(shí)文件從而減少了鏡像體積。
構(gòu)建鏡像
docker build . --tag next-app
之后我們就可以向 Kubernetes 提出我們應(yīng)用的要求了。為了保證高可用,服務(wù)至少創(chuàng)建兩個(gè)副本,我們還需要一個(gè)應(yīng)用的域名當(dāng)這個(gè)域名請(qǐng)求到我們集群上時(shí)自動(dòng)轉(zhuǎn)發(fā)到我們的服務(wù)上。那么我們對(duì)應(yīng)的配置文件就可以這么寫(xiě)
Deployment.yaml
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: app-ingress spec: rules: - host: next-app-server http: paths: - backend: serviceName: app-service servicePort: 80 --- kind: Service apiVersion: v1 metadata: name: app-service spec: selector: app: web ports: - port: 80 targetPort: 3000 --- apiVersion: apps/v1 kind: Deployment metadata: name: app-deployment spec: replicas: 2 selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - image: next-app name: next-app imagePullPolicy: IfNotPresent ports: - containerPort: 3000
上面這個(gè)清單告訴 K8S:
首先需要一個(gè) Deployment 控制器,鏡像為 next-app, 服務(wù)端口為 3000,給我創(chuàng)建兩個(gè)副本。
還需要?jiǎng)?chuàng)建一個(gè) Service, 這個(gè) Service 指向由副本控制器創(chuàng)建的幾個(gè) next-app。
申請(qǐng)一個(gè) Ingress 入口, 域名為 next-app-server, 其指向剛剛的 Service。
提交這份申請(qǐng)給 K8S。
kubectl apply -f ./Deployment.yaml
接著就可以看到已經(jīng)部署的 pod。
sh-4.4$ kubectl get pod NAME READY STATUS RESTARTS AGE app-deployment-594c48dbdb-4f4cg 1/1 Running 0 1m app-deployment-594c48dbdb-snj54 1/1 Running 0 1m
然后瀏覽器打開(kāi) Ingress 里配置的域名即可訪問(wèn)對(duì)應(yīng)的應(yīng)用(前提是這個(gè)域名能夠打到你的 K8S 集群節(jié)點(diǎn)上)。
上面的清單主要?jiǎng)?chuàng)建了三種最常見(jiàn)資源來(lái)保證服務(wù)的運(yùn)行, 這也是 Kubernetes 的最主要的三類(lèi)資源。
Ingress
L7層負(fù)載均衡配置, 可以根據(jù)不同的域名或者路徑等信息指向不同的 Service, Ingress 和 Nginx 很像,實(shí)際上 Ingress 的一種實(shí)現(xiàn)就是 Nginx, 所以可以將 Ingress 來(lái)當(dāng)成 Nginx 來(lái)用,只 不過(guò)我們不需要手動(dòng)修改 nginx.conf,也不用手動(dòng)重啟 Nginx 服務(wù)。
Service
一組 pod 的抽象,用來(lái)選擇提供同一服務(wù)的 pod。 由于 pod 是不穩(wěn)定的,銷(xiāo)毀重建經(jīng)常發(fā)生,pod 的 ip 經(jīng)常發(fā)生變化,所以需要一種抽象的資源 Service 來(lái)表示 pod 的位置。 Service 也 是K8S內(nèi)部服務(wù)發(fā)現(xiàn)機(jī)制,會(huì)自動(dòng)將 Service 名稱(chēng)寫(xiě)入內(nèi)部 DNS 記錄中。
Deployment
副本控制器,用來(lái)管理維護(hù) pod 的一種機(jī)制。通過(guò) Deployment 可以指定副本數(shù)量,發(fā)布策略, 記錄發(fā)布日志并支持回滾。
應(yīng)用發(fā)布系統(tǒng)
K8S 僅僅負(fù)責(zé)容器的編排,實(shí)際上如果部署應(yīng)用還需要外部 Pipeline 的支持,代碼的構(gòu)建,靜態(tài)檢查,鏡像的打包由 Pipeline 完成.
;
目前國(guó)內(nèi)用的比較多的發(fā)布系統(tǒng)常常由下面幾個(gè)服務(wù)組成: GitLab/GitHub, Jenkins, Sonar, Harbor。
K8S 在前端的優(yōu)勢(shì)
首先前端應(yīng)用和 Java 不同,一個(gè)小型 NodeJS 服務(wù)占用內(nèi)存僅 40M 左右,這意味著如果我們有很多 NodeJS 應(yīng)用,使用 K8S 將節(jié)省大量的硬件資源。
使用容器的思想進(jìn)行非侵入式日志,性能指標(biāo)收集。
由于容器即是一個(gè)進(jìn)程,所以對(duì)容器的監(jiān)控可以看作對(duì)我們 NodeJS 進(jìn)程的監(jiān)控,K8S 生態(tài)里已經(jīng)有很多成熟的容器監(jiān)控方案,例如 Prometheus + Grafana, 使用此可以達(dá)到應(yīng)用的非侵入 式性能指標(biāo)的收集包括: 網(wǎng)絡(luò)IO / 磁盤(pán)IO / CPU / MEM。
同樣對(duì)于日志收集,我們?cè)诖a中可以直接使用console的方式輸出, 在容器維度再使用日志收集服務(wù)進(jìn)行日志收集,同樣的非侵入式, 代碼層無(wú)感知,對(duì)開(kāi)發(fā)者更加友好,將日志和服務(wù)解耦。
前端微服務(wù)架構(gòu)基礎(chǔ)設(shè)施層。
微服務(wù)架構(gòu)是近兩年越來(lái)越流行的一種前端架構(gòu)組織方式,微服務(wù)架構(gòu)需要有一種更加彈性靈活的部署方式。 使用 Docker 讓我們?cè)趶?fù)雜架構(gòu)中抽象服務(wù)的最小單元,K8S 給自動(dòng)維護(hù)大規(guī)模集群提供了可能??梢哉f(shuō)微服務(wù)架構(gòu)天然適合使用 K8S。
K8S 新玩法, 流量分配
K8S 中使用 Service 來(lái)抽象一組 pod,而 Service 的選擇器可以動(dòng)態(tài)變更,所以了我們很多可能的玩法, 比如藍(lán)綠發(fā)布系統(tǒng)。
藍(lán)綠發(fā)布是指發(fā)布過(guò)程中新應(yīng)用發(fā)布測(cè)試通過(guò)后,通過(guò)切換網(wǎng)關(guān)流量, 一鍵升級(jí)應(yīng)用的發(fā)布方式, 在 K8S 中通過(guò)動(dòng)態(tài)更新 Service 的選擇器實(shí)現(xiàn)不同版本的一鍵切換
下面使用上面的 Next.js 應(yīng)用來(lái)演示一下藍(lán)綠發(fā)布,倉(cāng)庫(kù)地址
git clone https://github.com/Qquanwei/test-ab-deploy cd test-ab-deploy docker build . --tag next-app:stable kubectl apply -f ./Deployment.yaml
這里會(huì)將 next-app:stable 這個(gè)鏡像部署到集群中,并且給 pod 打上 version: stable 的tag。
部署后打開(kāi)顯示如下。
接著,我們部署 test 分支, 這個(gè)分支我們會(huì)構(gòu)建為 next-app:test 的鏡像,并且部署時(shí)給這個(gè)pod打上 version: test 的標(biāo)簽。
git checkout test docker build . --tag next-app:test kubectl apply -f ./Deployment.yaml
這時(shí)候我們一共部署了兩個(gè)版本的應(yīng)用,而且都已經(jīng)就緒狀態(tài)。
但是由于我們的 Service 為 version=stable, 所以所有的請(qǐng)求并不會(huì)打到 test 版本上,仍然都會(huì)請(qǐng)求 stable 的服務(wù)。
當(dāng)我們用其他的方式已經(jīng)驗(yàn)證 test 版本服務(wù)可用時(shí), 例如配另外一個(gè) Service 用來(lái)測(cè)試(Good), 這時(shí)候可以下面一條指令切換當(dāng)前的 Service 到 test 應(yīng)用上。
kubectl apply -f ./switch-to-test.yaml
執(zhí)行完這條命令后,刷新頁(yè)面可以看到如下。
通過(guò)切換 Service 的方式很輕松就實(shí)現(xiàn)了藍(lán)綠發(fā)布的功能,而且是瞬間完成,因?yàn)?Service 是 K8S 里比較輕量的資源,不會(huì)和隔壁 Nginx 一樣修改配置就要重啟服務(wù)影響整個(gè)線上服務(wù)。當(dāng)然實(shí)際生產(chǎn)環(huán)境會(huì)比演示更加嚴(yán)謹(jǐn),可能有專(zhuān)門(mén)的平臺(tái)以及審核人員進(jìn)行每個(gè)操作的二次驗(yàn)證。
對(duì)于藍(lán)綠, 灰度發(fā)布方式,使用 K8S 可以較為輕松地實(shí)現(xiàn),讓我們能夠有更多的方式去驗(yàn)證想法。不過(guò)如果想實(shí)現(xiàn)更加高級(jí)的流量分配方案(例如A/B發(fā)布),需要復(fù)雜的流量管理策略 (鑒權(quán),認(rèn)證),就需要用到服務(wù)網(wǎng)格了。
Istio 是目前比較流行的服務(wù)網(wǎng)格框架,相比于 K8S 注重運(yùn)行容器的管理, Istio 則是更注重容器之間組成的服務(wù)網(wǎng)格的流量傳輸。
下圖是 Istio 捕獲的官方示例的 bookinfo 微服務(wù)中服務(wù)的拓?fù)浣Y(jié)構(gòu)和一些數(shù)據(jù)指標(biāo)。
使用 Istio 有兩個(gè)明顯的好處:
Istio 能夠捕捉到服務(wù)間的調(diào)用鏈路,而且不入侵用戶代碼。
Istio 能夠?qū)γ恳粭l連接,進(jìn)行單獨(dú)的管理。
例如,我們可以輕松對(duì)的不同版本的 review 應(yīng)用的 v1, v2, v3 版本進(jìn)行動(dòng)態(tài)權(quán)重分配。
不僅僅可以對(duì)流量權(quán)重分配,而且還可以制定一些A/B方案,例如根據(jù) URL 是否匹配請(qǐng)求不同的版本應(yīng)用,或者根據(jù) Header 種下的 Cookie 進(jìn)行用戶的區(qū)分,從而請(qǐng)求不同的應(yīng)用。當(dāng)然,面對(duì)行業(yè)場(chǎng)景不同,Istio 還會(huì)誕生很多有趣的玩法。
不過(guò)缺點(diǎn)同樣存在,Istio 實(shí)際上也是一個(gè)很復(fù)雜的系統(tǒng),會(huì)對(duì)性能造成影響,而且會(huì)占用不小的系統(tǒng)資源。
到此,關(guān)于“怎么理解前端領(lǐng)域的Docker與Kubernetes”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。