1. 程式人生 > >程式設計師修神之路--打通Docker映象釋出容器執行流程

程式設計師修神之路--打通Docker映象釋出容器執行流程


菜菜哥,我看了一下docker相關的內容,但是還是有點迷糊

還有哪不明白呢?

如果我想用docker實現所謂的雲原生,我的專案該怎麼釋出呢?

這還是要詳細介紹一下docker了

Docker 是一個開源的應用容器引擎,基於 Go 語言 並遵從 Apache2.0 協議開源。Docker 可以讓開發者打包他們的應用以及依賴包到一個輕量級、可移植的容器中,然後釋出到任何流行的 Linux 機器上,也可以實現虛擬化。

容器是完全使用沙箱機制,相互之間不會有任何介面(類似 iPhone 的 app),更重要的是容器效能開銷極低。Docker 從 17.03 版本之後分為 CE(Community Edition: 社群版) 和 EE(Enterprise Edition: 企業版),我們用社群版就可以了。

正如以上所說,Docker誕生的意義不僅僅實現了類似虛擬機器的隔離性,最主要的是它可以把應用程式以及應用程式的執行環境整個打包在一起。注意:是整個環境哦,不僅僅是一些依賴庫。這個劃時代的進步,直接把docker映象和宿主分離開來,使得docker映象只要公佈出來,就能使任何人在任何地方任何時間都可以隨意執行,換句話說,docker映象可以被分發到任何執行docker的伺服器上。

說重點,架構呢?

看你心急的和猴一樣....

Docker 架構

在docker的架構中,主要有三個主要概念:

映象

Docker 映象可以看作是一個特殊的檔案系統,除了提供容器執行時所需的程式、庫、資源、配置等檔案外,還包含了一些為執行時準備的一些配置引數(如匿名卷、環境變數、使用者等)。映象不包含任何動態資料,其內容在構建之後也不會被改變。

docker映象由多層組成,不同的映象都能使用相同的父映象作為他們的基礎映象,這些相同的基礎映象在docker的角度來看就是完全相同的層。在docker映象的傳輸過程中,當某些相同的層已經存在的時候,就完全不需要重新傳輸了,這大大提高了映象在網路上的傳輸效率。

分層的設計不僅使映象分發更高效,也有利於減少映象的儲存空間。每一層僅僅被儲存一次,就算基於相同基礎層的映象被建立兩個容器的時候,這兩個容器也是互相隔離的,雖然他們能讀到相同的檔案,但是卻看不到對方檔案的修改。一個容器被建立的時候,會建立一個新的可寫層,容器中的修改會反應到這個新的可寫層中。就算了容器修改了底層的檔案,此檔案的修改內容會copy到頂層,底層依然不會發生變化。

容器

映象(Image)和容器(Container)的關係,就像是面向物件程式設計中的類和例項一樣,映象是靜態的定義,容器是映象執行時的實體。容器可以被建立、啟動、停止、刪除、暫停等。docker的容器通常是一個linux容器,它是執行在宿主機上的一個程序,但是和其他宿主程序是隔離的,並且所用的資源是受限的(只能訪問特定的資源,比如網路介面,檔案系統)

映象倉庫

映象倉庫和它的字面意思一致,是很多映象的集合,它的作用就是把映象共享給每個人,當然這裡順便提一下,映象倉庫也可以有私人倉庫。當你的應用程式被打包之後,如果想在另外一個機器上執行,你就可以把你的應用映象上傳到映象倉庫,然後開放這個倉庫,這樣網路上的任何機器都能夠下載你的映象,然後執行。

通常,一個倉庫會包含同一個軟體不同版本的映象,而標籤就常用於對應該軟體的各個版本 。我們可以通過<倉庫名>:<標籤>的格式來指定具體是這個軟體哪個版本的映象。如果不給出標籤,將以 latest 作為預設標籤.。

倉庫又可以分為兩種形式:

public(公有倉庫)

private(私有倉庫)

Docker Registry 公有倉庫是開放給使用者使用、允許使用者管理映象的 Registry 服務。一般這類公開服務允許使用者免費上傳、下載公開的映象,並可能提供收費服務供使用者管理私有映象。

除了使用公開服務外,使用者還可以在本地搭建私有 Docker Registry 。Docker 官方提供了 Docker Registry映象,可以直接使用做為私有 Registry 服務。當用戶建立了自己的映象之後就可以使用 push 命令將它上傳到公有或者私有倉庫,這樣下次在另外一臺機器上使用這個映象時候,只需要從倉庫上 pull 下來就可以了。

構建分發執行映象

開發人員首先構建一個映象,然後把映象推到映象倉庫中。因此,任何可以訪問映象倉庫的人都可以使用該映象。然後,他們可以將映象拉取到任何執行著Docker的機器上並執行映象。Docker會基於映象建立一個獨立的容器,並執行二進位制可執行檔案指定其作為映象的一部分。


docker的缺陷

就像所有的技術解決方案,docker也不是完美的。docker的缺陷在於執行的核心,由於它直接執行在宿主機的核心之上,所以如果docker容器的執行核心版本和宿主機的核心不匹配就會出現問題。追根到底,還是硬體架構設計上的差異,不僅僅是docker容器,幾乎所有的軟體都會有核心架構不同而不能執行的問題。除此之外,由於docker是基於linux的容器技術,所以在windows下執行並不令人滿意,雖然這些年docker在windows上也進步了很多。

來一個具體釋出流程的例子唄?

可以呀,那我就以netcore為例吧

docker映象釋出

docker映象的倉庫有很多,這裡以官方網站https://hub.docker.com/ 為例,首先你要在官網建立一個賬號,然後可以在Account Settings=》Security中設定一個AccessToken ,這裡為了演示,沒有在官網顯示建立倉庫。因為我是本身是C#出身,這裡利用vs2019來做演示。

開啟vs2019新建一個netcore的專案,我這裡建立一個控制檯程式,程式很簡單

static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
            while (true)
            {
                Console.WriteLine("Hello World22222!");
                System.Threading.Thread.Sleep(1000);
            }
        }

然後在專案右鍵 新增=》docker支援,會根據當前專案自動生成dockerfile檔案。就算沒有ide的支援,也可以自己手擼一個dockerfile檔案,然後利用docker的命令打包,當然語法和以下是一樣的

FROM mcr.microsoft.com/dotnet/core/runtime:3.0-buster-slim AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/core/sdk:3.0-buster AS build
WORKDIR /src
COPY ["netcoretest/netcoretest.csproj", "netcoretest/"]
RUN dotnet restore "netcoretest/netcoretest.csproj"
COPY . .
WORKDIR "/src/netcoretest"
RUN dotnet build "netcoretest.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "netcoretest.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "netcoretest.dll"]


然後專案右鍵 釋出=》容器登錄檔=》docker hub 建立釋出選項,會彈出輸入docker hub賬號密碼彈窗,然後輸入賬號密碼,最後點擊發布按鈕,本地必須要安裝docker哦,我這裡為了演示,在windows上安裝的docker for windows。和以上類似,就算沒有ide的支援,我們一樣可以利用docker命令把映象推送到指定倉庫。這裡只是演示流程,所以不要糾結。

如果環境沒有錯誤的話,釋出過程中會彈出黑視窗

釋出完成,在docker hub中重新整理頁面回發現新倉庫已經被建立好了

接下來就是在裝有docker的機器上,拉取進行並執行容器了,這裡以我本地windows 和測試伺服器linux為例,分別演示,但是其實在兩個作業系統中命令是一模一樣的

docker run chenhongyu/netcoretest

無論是在windows上還是在linux上,容器成功被拉取執行

雖然只是一個小小的測試程式,確把業務程式之外的最大雲原生流程擼了一遍,希望對大家有幫助。大家可以拉取以下映象是否可以執行呢?