iT邦幫忙

2023 iThome 鐵人賽

DAY 6
0

我們已經完成了開發API後,接著我們就需要先用Docker將服務容器化,在那之前我們先解釋一下什麼是Docker,而我們為什麼需要把服務容器化?

容器化技術 與 Docker

容器化技術,是一種虛擬化技術,它允許多個容器共享同一個作業系統核心,這些容器在作業系統層上被隔離運行。

舉例來說:
想像一家餐廳,餐廳的餐桌代表著一台實體主機,每張餐桌上有一個大盤子,這個大盤子就是該主機的作業系統核心。

現在,假設這家餐廳的目標是為客人提供不同種類的食物,而不必為每道菜都提供一個獨立的餐桌(主機)。這就是作業系統層虛擬化的概念。

傳統虛擬化(虛擬機器):如果使用傳統虛擬化技術,每道菜(應用程式)都需要有自己的獨立餐桌(主機)和盤子(作業系統核心)。這意味著每道菜都需要獨立的硬體資源,例如桌子和盤子。

容器化(作業系統層虛擬化):如果使用容器化,多個菜(應用程式)可以共享同一個餐桌(主機),而且它們各自的盤子(容器)放在同一個餐桌上。雖然它們在同一個餐桌上共享空間,但它們是相互隔離的,每道菜都不會影響其他菜的食材。這樣可以節省空間(硬體資源)並實現更高的效率。

容器化技術簡單來說就是,將所有你服務需要的程式碼、套件、執行環境,全部都料理好之後,裝盤就可以上菜了,每個服務都是一道料理。從過去每個服務需要另外準備獨立的作業系統與主機,到現今的每個服務可以共用作業系統與主機。

https://ithelp.ithome.com.tw/upload/images/20230904/20140874sLQCGr0wd9.png
圖片取自於Docker官方網站

那容器化有什麼好處呢?
以上述的例子來說,容器化之後我們想要換個地方用餐就很方便,將料理打包之後,就可以換到其他地方,使用該地方的餐桌與餐盤,不需要換個地方還要帶著餐桌、餐盤走。
因為作業系統虛擬化,可以共用作業系統核心
1. 未來即使跨系統,也不用再擔心做好的東西,到別人的電腦會不會就壞了。
2. 相較於傳統虛擬機,只有將硬體虛擬化,每台虛擬機都還是要裝作業系統,容器化就輕量許多
還有其他優點我就不一一列出,以上是我比較有感的優點。

再來我們談談什麼是Docker,Docker與容器化技術又有什麼相關聯?

簡單來說Docker就是應用容器化的一個平台,方便我們打包容器、管理容器等等,透過將任何程式打包成可獨立執行的映像檔,發布到任何可執行 Docker 的平台上執行,如此一來,應用程式等於是可以透過 Docker映象檔或甚至只需要 Dockerfile,就能將程式執行環境帶著走,甚至能夠佈置上雲端。

要進入Docker 的世界裡,首先我們有三個主要的概念要認識:

  • 映像檔(image)
  • 容器(container)
  • 倉庫(repository)

「image」 包裝了一個服務執行,環境所需要的資源,如同上面所說可以任何程式打包成可獨立執行的映像檔,打包帶走,打包完就變成了一個「container」,而「repository」就是存放我們image的地方。

Dockerfile

接著我們就要撰寫Dockerfile,撰寫完之後才能夠做成image,我們可以參考官方的寫法

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /<Project Name>

# Restore as distinct layers
COPY ./<Project Name> /<Project Name>
RUN dotnet restore

# Build and publish a release
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /<Project Name>
COPY --from=build-env /<Project Name>/out .

ENTRYPOINT ["dotnet", "<Project Name>.dll"]

FROM: 我們使用mcr.microsoft.com/dotnet/sdk:6.0 這個sdk的image作為我們的基本環境
WORKDIR: 在容器內新增一個資料夾
COPY: 複製本機文件到容器資料夾內
RUN: build image 時運行的指令

  • dotnet store是用於還原專案的相依性,確保建置所需的所有函式庫和套件都可使用
  • dotnet publish用於將應用程式打包並準備好部署,以在生產環境中執行

ENTRYPOINT: run container 固定一定會執行的指令

在打包服務之前,我們需要先將當初var connectionString = builder.Configuration.GetConnectionString("TestDatabase") ?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.");?? throw new InvalidOperationException("Connection string 'DefaultConnection' not found.")以及app.UseHttpsRedirection();先去除掉,因為在打包的時候,沒有連接本地資料庫,會發生例外錯誤,後續我們打包完確定除了資料庫沒問題後,會改成公有雲的資料庫服務,然後後者會強制使用https導致無法正常運行。

接著我們可以透過docker build -t <image_name> .這行指令將Dockerfile build成image,而-t的參數是可以加上tag也可以當成你image的名字,後面沒有指定路徑的話,「.」就是當前目錄搜尋Dockerfile。

https://ithelp.ithome.com.tw/upload/images/20230906/20140874WZRPNn5loc.png

build完之後使用docker run -it -p 7242:80 <image_name>這行指令將image run起來

接著我們就可以到 http://localhost:7242/swagger/index.html 看到服務有在運行,這樣就代表Dockerfile沒有寫錯,run起來後,容器也可以正常執行。

明天我們明天要進入CICD的世界了。

參考資料:
什麼是容器?
作業系統層虛擬化
docker-what is container
10個Q&A快速認識Docker
微軟-建立Dockerfile
微軟-ASP.NET Core 的 Docker 映像(我覺得上面那篇比較好)


上一篇
Day 05 實作ASP.NET Core API
下一篇
Day 07 介紹gitlab cicd
系列文
你累了嗎,今天來點克勞內提夫!31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言