輕松構(gòu)建微服務(wù)之docker和高效發(fā)布

docker

我們先來(lái)了解下docker的原理,如何才能制造出一個(gè)真正隔離的軟件運(yùn)行環(huán)境.

namespace

docker在創(chuàng)建容器進(jìn)程的時(shí)候可以指定一組namespace參數(shù),這樣容器就只能看到當(dāng)前namespace所限定的資源,文件,設(shè)備,網(wǎng)絡(luò)。用戶(hù),配置信息,而對(duì)于宿主機(jī)和其他不相關(guān)的程序就看不到了,PID namespace讓進(jìn)程只看到當(dāng)前namespace內(nèi)的進(jìn)程,Mount namespace讓進(jìn)程只看到當(dāng)前namespace內(nèi)的掛載點(diǎn)信息,Network namespace讓進(jìn)程只看到當(dāng)前namespace內(nèi)的網(wǎng)卡和配置信息,

docker利用namespace機(jī)制隔離出一個(gè)軟件執(zhí)行環(huán)境,我們可以用下圖來(lái)將docker和虛擬機(jī)技術(shù)做一個(gè)對(duì)比

image

一個(gè)centOS的KVM啟動(dòng)起來(lái)后,即使什么不做也需要消耗200M的內(nèi)存,而且用戶(hù)進(jìn)程運(yùn)行在虛擬機(jī)里,對(duì)宿主機(jī)操作系統(tǒng)的調(diào)用不可避免會(huì)受到虛擬化軟件的攔截,而容器化的應(yīng)用依然是宿主機(jī)上的一個(gè)普通進(jìn)程.

cgroup

全名 linux control group,用來(lái)限制一個(gè)進(jìn)程組能夠使用的資源上限,如CPU,內(nèi)存,網(wǎng)絡(luò)等,另外Cgroup還能夠?qū)M(jìn)程設(shè)置優(yōu)先級(jí)和將進(jìn)程掛起和恢復(fù),cgroup對(duì)用戶(hù)暴露的接口是一個(gè)文件系統(tǒng),/sys/fs/cgroup下 這個(gè)目錄下面有 cpuset,memery等文件,每一個(gè)可以被管理的資源都會(huì)有一個(gè)文件,如何對(duì)一個(gè)進(jìn)程設(shè)置資源訪問(wèn)上限呢?在/sys/fs/cgroup目錄下新建一個(gè)文件夾,系統(tǒng)會(huì)默認(rèn)創(chuàng)建上面一系列文件,然后docker容器啟動(dòng)后,將進(jìn)程ID寫(xiě)入taskid文件中,在根據(jù)docker啟動(dòng)時(shí)候傳人的參數(shù)修改對(duì)應(yīng)的資源文件

$ docker run -it --cpu-period=100000 --cpu-quota=20000 ubuntu /bin/bash

Linux Cgroup的設(shè)計(jì)還是比較易用的,簡(jiǎn)單理解就是一個(gè)子系統(tǒng)目錄加上一組資源限制文件,而對(duì)docker等linux容器項(xiàng)目而言,只需要在每個(gè)子系統(tǒng)下面,為每個(gè)容器創(chuàng)建一個(gè)控制組也就是一個(gè)文件夾,讓后在容器啟動(dòng)后寫(xiě)入進(jìn)程PID.

文件系統(tǒng)

即使開(kāi)啟了Mount Namespace,容器進(jìn)程看到的文件系統(tǒng)還是和宿主機(jī)一樣的,mount namespace修改的時(shí)容器進(jìn)程對(duì)掛載點(diǎn)的認(rèn)知,他對(duì)容器進(jìn)程視圖的改變,一定伴隨掛載操作才生效,但是作為一個(gè)普通用戶(hù),我們希望在容器內(nèi)看到的文件系統(tǒng)就是一個(gè)獨(dú)立的隔離環(huán)境,而不是繼承自宿主機(jī)上的文件系統(tǒng).

我們可以在容器啟動(dòng)后馬上掛載他的整個(gè)根目錄,這個(gè)掛載對(duì)宿主機(jī)不可見(jiàn),然后通過(guò)chroot來(lái)更改change root file system更改進(jìn)程的根目錄到掛載的位置,一般會(huì)通過(guò)chroot掛載一個(gè)完整的linux的文件系統(tǒng),但是不包括linux內(nèi)核,這樣當(dāng)我們交付一個(gè)docker鏡像的時(shí)候不僅包含需要運(yùn)行的程序還包括這個(gè)程序依賴(lài)運(yùn)行的這個(gè)環(huán)境,因?yàn)槲覀兇虬苏麄€(gè)依賴(lài)的linux文件系統(tǒng),對(duì)一個(gè)應(yīng)用來(lái)說(shuō),操作系統(tǒng)才是他所依賴(lài)的最完整的依賴(lài)庫(kù),

這個(gè)掛載在容器根目錄下,用來(lái)為容器進(jìn)程提供隔離后的執(zhí)行環(huán)境的文件系統(tǒng),就是所謂的容器鏡像,它還有一個(gè)專(zhuān)業(yè)的名詞rootFS

由于rootfs里面打包的不僅僅是用戶(hù)程序,而是整個(gè)系統(tǒng)的文件目錄,也就是是應(yīng)用和應(yīng)用依賴(lài)的類(lèi)庫(kù)和環(huán)境變量都在里面.

增量層

docker在鏡像的設(shè)計(jì)中引入層的概念,也就是用戶(hù)在制作docker鏡像中的每一次修改都是在原來(lái)的rootfs上新增一層roofs,之后通過(guò)一種聯(lián)合文件系統(tǒng)union fs的技術(shù)進(jìn)行合并,合并的過(guò)程中如果兩個(gè)rootfs中有相同的文件則會(huì)用最外層的文件覆蓋原來(lái)的文件來(lái)進(jìn)行去重操作,舉個(gè)例子,我們從鏡像中心pull一個(gè)mysql的鏡像到本地,當(dāng)我們通過(guò)這個(gè)鏡像創(chuàng)建一個(gè)容器的時(shí)候,就在這個(gè)鏡像原有的層上新加了一個(gè)增roofs,這個(gè)文件系統(tǒng)只保留增量修改,包括文件的新增刪除,修改,這個(gè)增量層會(huì)借助union fs和原有層一起掛載到同一個(gè)目錄,這個(gè)增加的層可以讀寫(xiě),原有的其他層只能讀,這樣保證了所有對(duì)docker鏡像的操作都是增量,之后用戶(hù)可以commit這個(gè)鏡像將對(duì)這個(gè)鏡像的修改生成一個(gè)新的鏡像,新的鏡像就包含了原有的層和新增的層,只有最原始的層才是一個(gè)完整的linux fs, 那么既然只讀層不允許修改,那么我怎么刪除只讀層的文件呢,這個(gè)時(shí)候只需要在讀寫(xiě)層也就是最外層生成一個(gè)whiteout文件來(lái)遮擋原來(lái)的文件就可以了,

image
$ docker image inspect ubuntu:latest
...
     "RootFS": {
      "Type": "layers",
      "Layers": [
        "sha256:f49017d4d5ce9c0f544c...",
        "sha256:8f2b771487e9d6354080...",
        "sha256:ccd4d61916aaa2159429...",
        "sha256:c01d74f99de40e097c73...",
        "sha256:268a067217b5fe78e000..."
      ]
    }

dockerfile

可以通過(guò)docfile生成一個(gè)鏡像,docfile里面可以指定 from的原始鏡像,以及自定義操作例如拷貝文件等,容器啟動(dòng)命令等

例如下面的dockerfile,FROM原語(yǔ)指定了原始鏡像是python:2.7-slim,避免了先從一個(gè)原始的ubantu鏡像,然后通過(guò)apt-get install按照python

WORDIR 切換工作目錄

ADD拷貝文件

RUN 在容器里執(zhí)行shell

CMD 指定容器進(jìn)程,相當(dāng)于 docker rum python app.py

# 使用官方提供的 Python 開(kāi)發(fā)鏡像作為基礎(chǔ)鏡像
FROM python:2.7-slim

# 將工作目錄切換為 /app
WORKDIR /app

# 將當(dāng)前目錄下的所有內(nèi)容復(fù)制到 /app 下
ADD . /app

# 使用 pip 命令安裝這個(gè)應(yīng)用所需要的依賴(lài)
RUN pip install --trusted-host pypi.python.org -r requirements.txt

# 允許外界訪問(wèn)容器的 80 端口
EXPOSE 80

# 設(shè)置環(huán)境變量
ENV NAME World

# 設(shè)置容器進(jìn)程為:python app.py,即:這個(gè) Python 應(yīng)用的啟動(dòng)命令
CMD ["python", "app.py"]

容器網(wǎng)絡(luò)

從之前的章節(jié)中我們可以看到,容器只是一個(gè)被隔離的進(jìn)程,這個(gè)進(jìn)程只能看到他自己network namespace下的網(wǎng)絡(luò)棧,所謂的網(wǎng)絡(luò)棧包括了
網(wǎng)卡(network interface),回環(huán)設(shè)備(loopback device),路由表(route table),iptables規(guī)則,這些已經(jīng)可以構(gòu)成這個(gè) 進(jìn)程和外界進(jìn)行網(wǎng)絡(luò)通訊的基本環(huán)境.

容器作為宿主機(jī)內(nèi)的一個(gè)進(jìn)程,在不設(shè)置network namespace的情況下,可以使用宿主機(jī)的網(wǎng)絡(luò)棧.

$ docker run –d –net=host --name nginx-host nginx

以上例子,就是容器采用宿主機(jī)的網(wǎng)絡(luò),當(dāng)容器啟動(dòng)后監(jiān)聽(tīng)的是宿主機(jī)上的80端口

采用宿主機(jī)網(wǎng)絡(luò)可以為容器提供最好的網(wǎng)絡(luò)性能,但是我們希望容器有一個(gè)完全被隔離的環(huán)境,包括網(wǎng)絡(luò)環(huán)境,她應(yīng)該有自己的IP地址和端口,這樣就不會(huì)和其他進(jìn)程有端口沖突,例如我運(yùn)行4個(gè)ngnx容器進(jìn)程,我希望他們是完全一樣的,向運(yùn)行在4臺(tái)宿主機(jī)里面一樣,都監(jiān)聽(tīng)80端口.所以我們希望容器進(jìn)程運(yùn)行在自己的network namespace內(nèi).

我們現(xiàn)在把容器看成,一臺(tái)主機(jī),兩臺(tái)主機(jī)之間想要通信,就需要拉一條網(wǎng)線,多個(gè)主機(jī)之間想要通信,就需要一個(gè)交換機(jī)用網(wǎng)線把他們連起來(lái),在linux上,能夠啟到虛擬交換作用的設(shè)備就是網(wǎng)橋(Bridge),他是一個(gè)工作在數(shù)據(jù)鏈路層的設(shè)備,我們可以把它當(dāng)成一個(gè)二層交換機(jī),而二層設(shè)備主要靠學(xué)習(xí)MAC地址對(duì)應(yīng)的端口,并將數(shù)據(jù)包轉(zhuǎn)發(fā)到對(duì)應(yīng)的端口上去.

docker在安裝的時(shí)候會(huì)在宿主機(jī)上創(chuàng)建一個(gè)叫docker0的網(wǎng)橋,而容器可用通過(guò)Veth Pair的虛擬設(shè)備,連接到這個(gè)網(wǎng)橋,Veth Pair這種設(shè)備在創(chuàng)建的時(shí)候會(huì)有兩張?zhí)摂M網(wǎng)卡,從一個(gè)網(wǎng)卡里面發(fā)出的數(shù)據(jù)包會(huì)到達(dá)另外一個(gè)網(wǎng)卡里,并且這兩個(gè)網(wǎng)卡可以跨network namespace,這樣Veth Pair可以理解為連接不同namespace的網(wǎng)線.

下圖是我啟動(dòng)了兩個(gè)nginx容器,分別為nginx-1 ,nginx-2,我們用ifconfig查看宿主機(jī)上的網(wǎng)卡信息

$ docker run –d --name nginx-1 nginx
$ docker run –d --name nginx-2 nginx
image

被插在網(wǎng)橋上的虛擬網(wǎng)卡,不會(huì)調(diào)用網(wǎng)絡(luò)協(xié)議中棧處理數(shù)據(jù)包,只會(huì)像一個(gè)端口一樣,將數(shù)據(jù)包交給網(wǎng)橋,由網(wǎng)橋進(jìn)行轉(zhuǎn)發(fā).

下面我們分析下一個(gè)宿主機(jī)內(nèi)的兩個(gè)容器之間的網(wǎng)絡(luò)怎么通訊?

當(dāng)我們?cè)谌萜鱪ginx-1內(nèi)去ping一下nginx-2的ip,默認(rèn)下是通的

image
  • 1.宿主機(jī)內(nèi)的兩個(gè)主機(jī)通過(guò)二層網(wǎng)絡(luò)相通,nginx-1會(huì)先發(fā)一個(gè)ARP包來(lái)獲取nginx-2的MAC地址
  • 2.nginx-1只能看到他自己network namespace內(nèi)的網(wǎng)卡 nginx-1-eth-0 ,所以數(shù)據(jù)包從這個(gè)網(wǎng)卡發(fā)出,但是這個(gè)網(wǎng)卡是一個(gè)Veth Pair設(shè)備,這個(gè)設(shè)備的另外一端在宿主機(jī)上默認(rèn)的namespace內(nèi),并且是插在網(wǎng)橋docker-0上
  • 3.由于Veth Pair設(shè)備的作用,宿主機(jī)的虛擬網(wǎng)卡收到數(shù)據(jù)包后,直接交給網(wǎng)橋docker-0進(jìn)行轉(zhuǎn)發(fā),而docker-0會(huì)把數(shù)據(jù)包廣播給插在這個(gè)網(wǎng)橋上的其他虛擬網(wǎng)卡
  • 4.這樣數(shù)據(jù)就會(huì)被廣播到宿主機(jī)上的另外一個(gè)虛擬網(wǎng)卡上了,這個(gè)虛擬網(wǎng)卡也是一個(gè)Veth Pair,他的另外一端是nginx-2容器的namespace內(nèi)的虛擬網(wǎng)卡,這個(gè)網(wǎng)卡將自己MAC地址回復(fù)
  • 5.這樣nginx-1的namespace內(nèi)的虛擬網(wǎng)卡就獲取到了nginx-2的namespace內(nèi)的網(wǎng)卡的MAC地址了,就可以組裝數(shù)據(jù)包將請(qǐng)求發(fā)給nginx-2了
  • 6.同樣數(shù)據(jù)包先根據(jù)Veth Pair設(shè)備到達(dá)宿主機(jī)namespace內(nèi)的網(wǎng)卡,然后交給docker-0進(jìn)行轉(zhuǎn)發(fā),由于此時(shí)docker-0網(wǎng)橋已經(jīng)學(xué)習(xí)到了nginx-2的mac地址對(duì)應(yīng)的端口了,只需要查CAM表查一下記錄,轉(zhuǎn)發(fā)到另外一塊宿主機(jī)的虛擬網(wǎng)卡,然后到達(dá)nginx-2的namespace內(nèi)的網(wǎng)卡

以上就是同一個(gè)宿主機(jī)內(nèi)的不同docker容器通過(guò)Veth Pair設(shè)備和docker-0網(wǎng)橋通信的流程,與此類(lèi)似,容器和其他宿主機(jī)進(jìn)行通信,docker-0網(wǎng)橋在轉(zhuǎn)發(fā)的時(shí)候會(huì)根據(jù)宿主機(jī)的路由規(guī)則,將數(shù)據(jù)轉(zhuǎn)發(fā)給宿主機(jī)上的eth-0網(wǎng)卡,然后在由宿主機(jī)上德etho-進(jìn)行轉(zhuǎn)發(fā).

那么容器怎么和其他宿主機(jī)內(nèi)的網(wǎng)絡(luò)通信呢?

在docker默認(rèn)配置下,一臺(tái)宿主機(jī)內(nèi)的docker-0網(wǎng)橋和另外一個(gè)宿主機(jī)內(nèi)的docker-0網(wǎng)橋沒(méi)有任何關(guān)聯(lián),它們之間沒(méi)辦法相互關(guān)聯(lián),所以連在不同網(wǎng)橋上的容器沒(méi)有辦法進(jìn)行連通.我們可以通過(guò)軟件的方式,創(chuàng)建一整個(gè)集群共用的網(wǎng)橋,集群內(nèi)所有的容器都連到這個(gè)網(wǎng)橋上,這個(gè)就是覆蓋網(wǎng)絡(luò)(overlay),為了實(shí)現(xiàn)這個(gè)網(wǎng)橋,我們需要了解FLANNEL技術(shù),以及他的量種實(shí)現(xiàn):UDP,VXLAN

UDP的模式是在宿主機(jī)內(nèi)增加一個(gè)軟件進(jìn)程,通過(guò)TUN設(shè)備,將數(shù)據(jù)包發(fā)給上層應(yīng)用,然后在由應(yīng)用層判斷如何進(jìn)行轉(zhuǎn)發(fā),目前UDP模式已經(jīng)被淘汰,主要因?yàn)樾阅芴?涉及太多次數(shù)據(jù)包從內(nèi)核態(tài)到用戶(hù)態(tài)的轉(zhuǎn)發(fā).

image

VXLAN是linux內(nèi)核本身就支持的一種網(wǎng)絡(luò)虛擬化技術(shù),VXLAN維護(hù)一個(gè)虛擬的局域網(wǎng),使在這個(gè)LAN以?xún)?nèi)的容器可以相互通信.

image

從上圖可以看出,為了能讓二層網(wǎng)絡(luò)能夠打通,VXLAN需要在宿主機(jī)上設(shè)置一個(gè)特殊的設(shè)備作為隧道的兩端,這個(gè)設(shè)備就是VTEP (Vxlan Tunnel Endpoin ) 虛擬隧道端點(diǎn).而VTEP的作用和上面UDP的應(yīng)用程序類(lèi)似,他會(huì)拆包和封包,只不過(guò)他在數(shù)據(jù)鏈路層而不是涉及用戶(hù)太和內(nèi)核態(tài)的轉(zhuǎn)換.

kubernetes

k8s是一個(gè)做容器編排和調(diào)度的工具,kubernets的最小調(diào)度單元是POD,一個(gè)POD可以管理一組同生命周期的容器,k8s提供一個(gè)restful的客戶(hù)端api供用戶(hù)使用,所以會(huì)有一個(gè)APIserver來(lái)接受請(qǐng)求,通過(guò)etcd作為數(shù)據(jù)庫(kù)來(lái)存儲(chǔ)請(qǐng)求中得CRUD操作,而其他模塊例如控制器中的調(diào)度單元,會(huì)掃描數(shù)據(jù)庫(kù)中的記錄,如果有新的POD還沒(méi)有分配物理節(jié)點(diǎn),則會(huì)執(zhí)行調(diào)度動(dòng)作,如果發(fā)現(xiàn)新增了副本數(shù)量,就會(huì)增加POD副本,如果修改了POD相關(guān)配置就去執(zhí)行,而每一個(gè)節(jié)點(diǎn)上面都會(huì)允許一個(gè)kube-proxy用來(lái)接收外部請(qǐng)求后轉(zhuǎn)發(fā),而docker采用的插拔容器,可以使用docker引擎,也可以用其他的引擎。

image

下面我們分析下k8s下相關(guān)的概念

  • 1.POD POD是kubernate的最小可操作單元,如果我們把容器看成一個(gè)特殊的進(jìn)程,那POD就是一個(gè)有相同生命周期的進(jìn)程組,POD里的所有容器共享一個(gè)Network namespace,并且可以共享一個(gè)Volume,那么kubernate怎么實(shí)現(xiàn)呢? k8s會(huì)在容器創(chuàng)建的時(shí)候先創(chuàng)建一個(gè)中間容器infra,然后其他的容器和這個(gè)容器共享namespace來(lái)實(shí)現(xiàn).這樣一個(gè)POD內(nèi)的多個(gè)容器可以通過(guò)localhost進(jìn)行通信,一個(gè)POD只有一個(gè)IP地址,POD的生命周期和infra相關(guān),和容器A和B無(wú)關(guān).

  • 2.MASTER Kubernatis集群中的master節(jié)點(diǎn),可以部署在物理機(jī)或者虛擬機(jī)上,master節(jié)點(diǎn)負(fù)責(zé)維護(hù)集群的狀態(tài),以及對(duì)外提供API服務(wù),master節(jié)點(diǎn)上部署以下3種組件

  • 2.1 API SERVER,作為kubernatis系統(tǒng)的入口,封裝了核心對(duì)象的增刪改查操作以及配置操作,以RESTFUL api的方式以及命令行的方式kubectl將接口暴露給外部客戶(hù)和內(nèi)部組件使用,維護(hù)的對(duì)象會(huì)被持久化到etcd中.

  • 2.2 Schedule 調(diào)度器:為新建的POD選擇NODE,也就是分配機(jī)器,這個(gè)調(diào)度器也是可以插拔的,可以換成其他調(diào)度器,調(diào)度器可以考慮根據(jù)NODE的負(fù)載以及物理位置等參數(shù)設(shè)計(jì)調(diào)度算法.

  • 2.3 Controller 控制器:所有資源的自動(dòng)化控制中心,是一個(gè)大總管,例如Node Controller 用于管理NODE對(duì)象,接收NODE節(jié)點(diǎn)的使用情況,和NODE生命周期的管理即:創(chuàng)建和銷(xiāo)毀,以及心跳檢查等,Replication Controller ,副本控制器,監(jiān)測(cè)業(yè)務(wù)集群中POD數(shù)量是否符合預(yù)期,如果不夠會(huì)創(chuàng)建,多余會(huì)銷(xiāo)毀,當(dāng)管理員修改了預(yù)期的值后,該進(jìn)程就會(huì)進(jìn)行響應(yīng).

  • 3.NODE 節(jié)點(diǎn)是kubernatis集群中,相對(duì)于master而言的工作主機(jī),這些主機(jī)可以說(shuō)物理機(jī),也可以是虛擬機(jī),POD容器都運(yùn)行在這些工作節(jié)點(diǎn)上,每個(gè)Node上都運(yùn)行著一個(gè)叫kublet的進(jìn)程,用來(lái)啟動(dòng)和管理POD,NODE被master管理,一個(gè)NODE宕機(jī)后,master會(huì)將這臺(tái)node上部署的POD在其他NODE上重新創(chuàng)建并部署起來(lái),NODE節(jié)點(diǎn)上部署有以下組件.

  • 3.1 kubelet,作為一個(gè)單獨(dú)進(jìn)程運(yùn)行在NODE節(jié)點(diǎn)上,主要功能是:容器的管理,鏡像的管理,數(shù)據(jù)卷的管理,同時(shí)kubelet也提供restful接口服務(wù),當(dāng)master節(jié)點(diǎn)的控制器可以下發(fā)請(qǐng)求到node上的kubelet進(jìn)程,進(jìn)行某個(gè)POD的創(chuàng)建,啟動(dòng)容器和銷(xiāo)毀,并監(jiān)聽(tīng)容器運(yùn)行狀態(tài)匯報(bào)給master.

  • 3.2 kube-proxy,負(fù)責(zé)為POD創(chuàng)建代理對(duì)象,用來(lái)實(shí)現(xiàn)訪問(wèn)POD提供服務(wù)的網(wǎng)絡(luò)請(qǐng)求的路由和轉(zhuǎn)發(fā),該proxy可以提供一定的負(fù)載均衡和SDN的功能

  • 3.3 容器環(huán)境,可以是docker也可以是其他容器技術(shù)

  • 4.etcd作為一個(gè)鍵值數(shù)據(jù)庫(kù),存儲(chǔ)集群的元數(shù)據(jù),以及POD的配置信息,并具有消息訂閱功能,所以,當(dāng)用戶(hù)修改了POD預(yù)期副本數(shù)量,Replication Controller就可以感知到, etcs采用raft協(xié)議來(lái)保證集群環(huán)境下的數(shù)據(jù)一致性,并提供restful的api來(lái)供客戶(hù)端使用,kubernatis中的網(wǎng)絡(luò)配置信息,以及操作記錄和各個(gè)對(duì)象的狀態(tài)都存儲(chǔ)在etcd中,多個(gè)組件間的交互都需要用到etcd,所以etcs對(duì)整個(gè)k8s集群特別重要,所以etcd必須保證高可用.

image

Devops

Devops用來(lái)保證,開(kāi)發(fā),運(yùn)維,測(cè)試之間的高效溝通和協(xié)作,是軟件發(fā)布更加簡(jiǎn)單和便捷.我們可以簡(jiǎn)單的將Devops思想抽象成兩個(gè)產(chǎn)品,一個(gè)產(chǎn)品用來(lái)做項(xiàng)目管理,一個(gè)產(chǎn)品用來(lái)做軟件發(fā)布和集成.

我們可以嘗試簡(jiǎn)單思考下一個(gè)項(xiàng)目管理的系統(tǒng)需要提供哪些功能:

  • 1.支持看板視圖,讓團(tuán)隊(duì)可以快速做信息同步,面板信息應(yīng)該包括:項(xiàng)目描述,項(xiàng)目進(jìn)度以及碰到的問(wèn)題,而項(xiàng)目進(jìn)度可以根據(jù)時(shí)間列出:需求立項(xiàng),需求評(píng)審,設(shè)計(jì)評(píng)審,技術(shù)方案評(píng)審,開(kāi)發(fā),測(cè)試,發(fā)布.

  • 2.項(xiàng)目迭代管理,提供各種維度報(bào)表,用來(lái)分析和預(yù)估后期項(xiàng)目周期.

  • 3.代碼關(guān)聯(lián),可以將需求在gitlab上關(guān)聯(lián)代碼

而一個(gè)軟件發(fā)布的系統(tǒng)應(yīng)該提供以下功能

  • 1.代碼管理,代碼提交可以關(guān)聯(lián)對(duì)應(yīng)的需求,支持代碼在線review

  • 2.持續(xù)集成,支持每日定時(shí),或者代碼提交自動(dòng)觸發(fā)構(gòu)建動(dòng)作

  • 3.支持從gitlab上拉取最新的代碼,然后在特定環(huán)境下打包,然后根據(jù)dockerfile生成鏡像并提交

  • 4.支持鏡像管理

  • 5.支持自動(dòng)化單元測(cè)試,接口測(cè)試,性能測(cè)試

  • 6.持續(xù)部署,支持根據(jù)生成的鏡像自動(dòng)部署測(cè)試環(huán)境和開(kāi)發(fā)環(huán)境,使開(kāi)發(fā)環(huán)境可以隨時(shí)訪問(wèn)

  • 7.灰度發(fā)布,可以灰度發(fā)布到生產(chǎn)環(huán)境和預(yù)發(fā)布環(huán)境

我們?nèi)绾卫胟8s做到自動(dòng)化打包和發(fā)布?

  • 1.創(chuàng)建pileline 指定項(xiàng)目名稱(chēng)和對(duì)應(yīng)的tag,以及依賴(lài)工程,一個(gè)pipeline指一個(gè)完整的項(xiàng)目生命周期(開(kāi)發(fā)提交代碼到代碼倉(cāng)庫(kù),打包,部署到開(kāi)發(fā)環(huán)境,自動(dòng)化測(cè)試,部署到測(cè)試環(huán)境,部署到生產(chǎn)環(huán)境)
  • 2.根據(jù)項(xiàng)目名稱(chēng)和tag去gitlab上拉取最新的代碼(利用java里的Runtime執(zhí)行shell腳本)
  • 3.利用maven進(jìn)行打包,這個(gè)時(shí)候可以為maven創(chuàng)建一個(gè)單獨(dú)的workspace(shell腳本)
  • 4.根據(jù)預(yù)先寫(xiě)好的docfile,拷貝maven打的包生成鏡像,并上傳鏡像 (shell腳本)
  • 5.通過(guò)k8s的api在測(cè)試環(huán)境發(fā)布升級(jí)
  • 6.通過(guò)灰度等方案發(fā)布到生產(chǎn)環(huán)境

藍(lán)綠發(fā)布

一般在反向代理層,例如nginx,的配置文件做一個(gè)軟連接,分別指向兩套環(huán)境,我們將這兩套環(huán)境分別稱(chēng)為生產(chǎn)環(huán)境和預(yù)發(fā)布環(huán)境,正常情況下配置文件的軟連接指向生成環(huán)境,這個(gè)時(shí)候流量都會(huì)進(jìn)入到生成環(huán)境的集群,發(fā)布的時(shí)候先發(fā)布預(yù)發(fā)布環(huán)境的機(jī)器,由于沒(méi)有流量進(jìn)入,所以機(jī)器重啟沒(méi)有太大影響,機(jī)器發(fā)布完成后,可以通過(guò)其他入口,例如內(nèi)部修改host或者其他流量入口進(jìn)行內(nèi)部測(cè)試,如果內(nèi)部測(cè)試通過(guò),就可以修改軟連接指向預(yù)發(fā)布環(huán)境的集群,然后在進(jìn)行驗(yàn)證當(dāng)外部流量進(jìn)來(lái)后,是否正常,如果不正??梢灾苯釉诎蚜髁壳谢厝?如果正常就可以升級(jí)生成環(huán)境的機(jī)器,然后在把流量切到生產(chǎn)環(huán)境

灰度發(fā)布

灰度發(fā)布可以在發(fā)布前,將一部分比例的機(jī)器的流量切走,然后進(jìn)行軟件升級(jí),升級(jí)完成后把流量切回來(lái),然后進(jìn)行驗(yàn)證,驗(yàn)證有問(wèn)題在把流量掐掉,沒(méi)有問(wèn)題可以慢慢按比例對(duì)外,這種方式需要新老版本的服務(wù)同時(shí)對(duì)外提供服務(wù),有些情況下我們把通過(guò)白名單或者固定用戶(hù)的形式開(kāi)發(fā)服務(wù)也叫灰度.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容