Docker筆記 - 更改Container的Configuration
在 上一篇-進入Container 的文章中我們說明了如何使用 docker exec 操作 Container,在建立 Container 的同時,就會同時一起設定 Container 的 Configuration,然而該如何更改已經建立好的 Container 的 Configuration 呢?
這篇文章將主要會說明該如何修改 Configuration,另外也會提出其他更好的做法。
文章架構
- 甚麼情況會想要修改 Container 的 Configuration
- 查看 Container 的 Configuration
- Docker VM — Hyper-V Virtual Hard Disk
- 進入 Docker VM — 使用 justincormack/nsenter1
- 修改 Configuration
- 其他建議 — 使用 Docker Volume
甚麼情況會想要修改 Container 的 Configuration
假設已經跑了一個服務在 Docker 中,但有時候我們可能會想要讓外部可以連接的 Port 改為其他號,例如 8080 改為 80。
但是!Docker 沒有提供給我們直接修改已經建立好的 Container 的 Configuration 的方法,所以當如果我們真的想要修改,那麼要怎麼做呢?
在開始討論如何修改之前,我們先來看一下該如何查看 Configuration。
查看 Container 的 Configuration
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
透過 docker inspect,就可以查詢 Docker 物件的 Configuration。所謂的 Docker 物件代表的就是像 Image、Container 等等的物件,這些物件都會有自己的 Id 或 Name,我們就能透過這些 Id 或 Name 來進行查詢。
例如:
# 啟動一個 httpd 的 container
$ docker run -d --name my-http -p 8080:80 httpd# 查詢 container 的 configuration
$ docker inspect my-http...
"HostsPath": "/var/lib/docker/containers/a572e.../hosts",
...
"PortBindings": {
"80/tcp": [
{
"HostIp": "",
"HostPort": "8080"
}
]
},
...
在這裡面可以找到 HostsPath
的關鍵字,這代表了相關 Configuration 都放在這個路徑中。
可是這個路徑是在哪裡?如果你用 Mac,你沒辦法找到對應的路徑在 Mac 裡。如果你用 Windows 的 Linux Containers,你也沒辦法在對應的路徑找到他。所以這個路徑到底在哪裡?(謎之路徑)
Docker VM — Hyper-V Virtual Hard Disk
這個謎之路徑其實就在這個 VM 中。如果你的 Docker 是在 Windows 的 Linux Containers,你可以打開你的 Docker Dashboard,接著進入設定的 Resources,可以找到「Disk Image Location」的路徑。
進入這個路徑內,你可以找到一個 DockerDesktop.vhdx
的檔案,這個就是 Docker 掛載虛擬機的地方。而這個 DockerDesktop.vhdx
也就是存放了所有跟 Docker 相關的東西,例如存放的 Image、存放的 Container 等。
我們剛剛看到的 HostsPath
其實就是掛載在這個 vhdx 的虛擬機的路徑。如果我們想要可以修改 Configuration,那我們就要先想辦法可以進入到這個掛載的虛擬機內。
進入 Docker VM — 使用 justincormack/nsenter1
如果要在 Windows 中進入這個掛載的 VM 會很麻煩。而在 Mac 或 Unix 系統的環境中有 screen
指令可以進入 VM,但也會遇到一些問題,例如下方這篇文章:
這裡提供一個通用作法,也就是在 Windows 環境中,或者是 Mac 的環境中,都可以成功的方法 — 使用 justincormack/nsenter1。使用方式如下:
$ docker run -it --rm --privileged --pid=host justincormack/nsenter1
這就是在 Docker 內掛上一個可以讓你使用 nsenter
來進入 PID 1 的空間的 Container。透過這個方式,我們就可以直接進入到 VM 中。
接著我們就可以 cd 到 HostsPath
的路徑了!
修改 Configuration
在開始修改之前,我必須先說真的非常非常不建議這麼做,比較建議的做法會在後續提到,這小節的內容則可以當作參考,大概知道可以這樣改就好。
回到重點,如果要修改一個已經建立的 Container 的 Port 應該怎麼做呢?
- 先停止要修改的 Container
- 查詢要修改的 Container 的 Config,並記得如
HostsPath
的路徑 - 進入 Docker VM
- cd 至如
HostsPath
的路徑 - 開始修改 Config,修改
hostconfig.json
(參考下方) - 離開 Docker VM,重啟 Docker (重啟很重要,不然修改的內容會被還原)
- 執行修改後的 Container
hostconfig.json
要修改的內容如下:
將
"PortBindings":{"80/tcp":[{"HostIp":"","HostPort":"8080"}]}
改為
"PortBindings":{"80/tcp":[{"HostIp":"","HostPort":"<其他Port號>"}]}
進入 Docker VM 後如果要修改文件,只有 Vi 可以用 (連 Vim 都沒有),這裡簡單提一下怎麼使用 Vi 編輯 hostconfig.json
:
/var/lib/docker/containers/<container-id># vi hostconfig.json進入 Vi 的編輯頁面後,先按一下「i」(代表編輯)
編輯完後按一下 Esc,輸入「:w」後按 Enter (代表儲存)
再輸入「:q!」離開 Vi 的編輯頁面
是不是覺得要改個 Port 號很麻煩呢?改了其中一個 Container 的 Config 還要重啟 Docker 其實也非常不合乎邏輯。
其他建議 — 使用 Docker Volume
其實 Docker 會這樣設計也是有原因的,對於 Container 來說,有幾個宗旨:
- Containers are immutable,是不可變動的
所有相關的東西,都被好好的打包在 Container 中,不想讓任何東西或設定被變動的原因是因為希望可以達到開發、測試環境能與生產環境盡可能有一樣的環性或行為 - Containers are lightweight,輕量化
Docker 在設計 Container 時,希望 Container 能夠輕量化,讓 Container 能夠好好的分配記憶體的使用 - Containers are fast,運行快速
綜合以上因素,Docker 希望 Container 能夠在建立或執行等動作上不需要花太多時間,就如同啟動一個傳統的、標準的 Linux Process 一樣快
就如同這些原因,所以 Docker 不希望我們去修改已經建立好的 Container 的 Config。縱使在 Container 中有想要保留的資料,也不要使用這樣的方式來修改 Config。因為 Container 占用資源少、重新建立的耗費便宜等特性,所以如果想要修改 Config,那麼就重新建立一個就好。
但是重新建立不就代表之前寫在 Container 的內容都會不見嗎?其實在使用 Container 的建議中有提到以下幾點:
- Don’t store data in containers,不要儲存資料在裡面
- Don’t ship your application in two pieces,不要佈署你的服務在已經正在執行的 Container 上
- Don’t run more than one process in a single container,不要執行多個 Process 在一個 Container 上
在 Container 的使用建議中有提到資料最好不要儲存在 Container 中,因為這會造成重新建立 Container 的資料遺失。另外也會造成 Container 的體積太過龐大,而失去了 Container Lightweight 的特性。
那麼替代方案是甚麼呢?那就是 Docker Volume。
原先 Container 與 Container 是相互獨立,並沒有關聯的,但為了想要共用資料,就可以將資料獨立存放在另外一個地方,而這個地方就是 Volume。因為篇幅的關係,這裡就先拋磚引玉一下,Volume 的部分則會在下一篇說明如何使用。
文末
本篇說明了如何暴力修改 Container 的 Configuration,雖然這不是一個推薦的好辦法,但會想要寫這一篇主要是希望可以幫助了解 Docker VM 是甚麼,以及有甚麼工具能幫助我們進入到 Docker VM 中,同時釐清關於 Docker VM 的相關細節。
這一篇文章的尾端有提到了 Volume,相關說明則會寫在下一篇。
前往
上一篇
下一篇
其他參考連結