Docker (三) : 基本操作Volume & Net

LUFOR129
8 min readSep 13, 2021

Docker 資料保存

Docker內空間的資料能不能保存下來? 當我關閉一個Container後下次重開一個新的Container能不能夠承接之前的檔案? 其實這些都是可以的。接下來介紹一下Docker Volume,這是docker資料持久層。

  • docker volume create <VolName> 建立新的保存空間並命名 (可以用-d來指定位置)
  • docker volume ls 列出本機上所有的volume
  • docker volume inspect <VolName> 查看該volume相關
  • docker volume prune 刪除所有未被container使用到的volume
  • docker volume rm <VolName> 刪除volume

如下圖,建立一個名字叫做myvol的空間。用inspect可以看到空間的路徑。

要是不-d指定特定空間,系統會自動幫你生成空間,然而具體會在電腦的哪裡呢?

  • Windows 版會在 \\wsl$\docker-desktop-data\version-pack-data\community\docker\volumes
  • Linux 版會在 /var/lib/docker/volumes/

windows版:

將Volume掛載到container

在container run時加上-v就能掛載了,參數為 -v <VolName>:<內部絕對路徑>,要是VolName不存在Docker會自動幫你建立一個。舉昨天例子來說,我們將myvol掛載到新建立的Web_App_Vol Container中,myvol空間會保存/usr/local/apache2/htdocs/目錄下的資料夾。

  • docker run -it -d -p 8081:80 -v myvol:/usr/local/apache2/htdocs/ --name Web_App_Vol httpd:2.4

現在進入修改並刪除container,然後重新掛載新的container

# 進入container
docker exec -it Web_App_Vol bash
# 改寫index.html
echo "<h1>Hello Docker Vol</h1>" > /usr/local/apache2/htdocs/index.html
# 離開container
exit
# 停下並刪除container
docker stop Web_App_Vol
docker rm Web_App_Vol
# 重新掛載新的Container
docker run -it -d -p 8082:80 -v myvol:/usr/local/apache2/htdocs/ --name Web_App_Vol2 httpd:2.4

可以發現重新掛載的Container,繼承了之前修改的東西

內外資料映射

但是每次修改container內的資料都要用exec進去,很麻煩。有沒有能夠在container外面改好裡面自動修改的方式呢? 有,就是volume (廢話,不然我就不會放在Volume章節了)
-v指令本質上就是內外空間映射。

舊版本Window版的坑

window版不能直接掛載,要先調一下設定。

  1. 選擇要掛載的目錄
  2. 打開Docker Desktop
  3. General > share dirve 掛載相應路徑,該路徑底下的資料夾才能被掛載

新版本window desktop可以直接掛載,指令:

  • docker run -v <外部絕對路徑>:<內部路徑> <ImageName>

舉例來說,我在windows電腦//e/program/ITBAN/DockerExample下放了index.html要映射給/usr/local/apache2/htdocs

docker run -it -d --name Web_Vol -p 8081:80 -v //e/program/ITBAN/DockerExample:/usr/local/apache2/htdocs httpd:2.4

現在在外部修改就能直接影響到Container內部了。

前幾天我們講了如何建立Container,每個Container會包含一項服務,如前端、後端、資料庫,Container之間能不能互相溝通藉此串聯起一個更大的服務應用呢? 可以的,以下講解Docker Network的簡單原理。

  • docker network ls 查看所有網路
  • docker network inspect <NetworkName> 檢視細部網路設定

查看所有網路可以發現默認有分成host與bridge,Bridge是Linux的虛擬網路橋接技術,將Bridge打開可以發現裡面包含兩個Container,也就是我上一個章節建立的Web_App與Web_Vol,ip位置分別是172.17.0.2、172.17.0.3,詳細網路架構圖如下:

安裝docker後會新增一個docker網卡默認IP為172.17.0.1/16 (host),他會接收來自本網卡(eth0)的轉發封包。新建立的Container則是會自動生成IP172.17.X.X依序排列下去。

Container互相訪問

那Container的互相訪問很簡單,直接訪問172.17.X.X的IP就好了,我們來實驗看看:

# 進入container
docker exec -it Web_APP bash
# 查看docker 網路
cat /etc/hosts
# 安裝相關網路工具
apt-get update
apt-get install curl
# 測試去抓其他Container
curl 172.17.0.3

如下圖,本docker IP為172.17.0.2,可以成功抓到其他Container的資料。

Network映射

但是Container的IP為自動生成,我們的程式在部屬的時候不可能部屬上去後才改IP。有一個好方法,做網路映射--link

  • docker run --link <外部Container>:<內部Network名稱> <ImageName>
# 建立新的有聯結的APP叫做Web_Network
docker run -it -d --name Web_Network -p 8082:80 --link Web_APP:Web_APP --link Web_Vol:Web_Vol httpd:2.4
# 進入Container
docker exec -it Web_Network bash
# 查看Network
cat /etc/hosts

可以看到Network自動多了兩個網路IP,Web_APP與Web_Vol

直接透過名稱抓抓看

curl Web_APP
curl Web_Vol

成功獲得:

實務上也不會透過 — link的方式來建立Network映射。更常使用的會是docker-compose,等之後再慢慢來講解吧 !

文章同步於IT鐵人賽 Lufor

--

--