###### tags: `教學` `Docker` `volume` `學習筆記` # Docker and Container 006 - Volume 資料管理 [TOC] --- ## Docker Volume:獨立於容器的檔案空間 > Volume 是 Docker 的元件,它提供 container 保存資料或共享資料的機制,我們把資料放在裡面,可以: 1. 與 host 共同存取 2. 提供其它 container 掛載(mount)使用,共享同樣的資料區 3. 它是獨立於 container,當 container 移除時,volume 裡的資料可以保留下來。 - `$ docker build -t kihifung/apache001 .`,建立image - `$ docker run -d -p 8080:80 kihifung/apache001`,啟動容器 - `$ docker ps` - `$ docker exec -it 6275a4cc08d7 /bin/sh`,進入容器 - 修改內容物 1. `$ cat index.html` 2. `$ touch index.html` 3. `$ echo "I made this many years ago." >> index.html` 4. `https://192.168.103.129:8080` ### 把容器關掉重開,看看修改後的東西是否保留 - `$ docker stop 6275a4cc08d7` - `$ docker rm 6275a4cc08d7` - `$ docker run -d -p 8080:80 kihifung/apache001`,啟動容器 - 到瀏覽器查看:`https://192.168.103.129:8080` - 結果顯示,先前修改的東西(存放在disk空間)在container關閉後不會保留 ### 以volume功能保存disk中的資料 - `$ docker volume ls` - `$ docker volume create mainpage-vol`,建立一個名為mainpage-vol的volume - `$ docker volume inspect mainpage-vol`,查看volume內容 -  - 其中`"Mountpoint": "/var/lib/docker/volumes/mainpage-vol/_data"`,代表的是vm linux的路徑 -`$ docker run -d -p 8081:80 -v mainpage-vol:/var/www/localhost/htdocs kihifung/apache001` - -v,volume - mainpage-vol,volume的名稱(自己取,如果不取會自動取) - `:`,前面是volume(vm linux disk的空間),後面是container(container disk的空間)。 - /var/www/localhost/htdocs,index.html的位置,在dockerfile裡設定的 - `$ docker exec -it 3e9a3483a54b /bin/sh`,進入容器 - 修改內容物 1. `$ cat index.html` 2. `$ echo "I made this things many years ago." >> index.html` 3. `https://192.168.103.129:8081` #### 關掉container後重新啟動 > 更改內容後,檢視volume是否可保存資料 * `$ docker stop 3e9a3483a54b` * `$ docker rm 3e9a3483a54b` * `$ docker container ls` * `$ docker run -d -p 8081:80 -v mainpage-vol:/var/www/localhost/htdocs kihifung/apache001` * `https://192.168.103.129:8081` ### Docker的掛載類型 - Docker 提供三種掛載類型(mount types): 1. bind mount:掛入現有的 host 檔案系統(filesystem),用在容器與 host 共享資料夾或檔案 2. volume:掛入 volume 物件 3. tmpfs mount:從 memory 掛載  --- ## SSH {**TODO**} --- ## 回顧 - [ ] 什麼是volume - [ ] volume怎麼作用?(管理資料) ## 課後複習/測驗 ### Q13:如何使用alpine映像檔執行容器,並將xy-products volume以唯讀模式,掛載到容器的/data目錄? * 可以使用下列的指令來完成: `$ docker container run -it --rm -v xy-products:/data:ro alpine /bin/sh` :::info **NOTE:** 如果volume以絕對路徑,便會在其路徑中新增目錄掛載到容器中:`$ docke run -it --rm -v /home/philipz/test:/data alpine sh` ::: --- ### Q34:請解釋一下Docker中所提供之各種不同的Volume掛載類型? Docker共有以下三種掛載類型: * Volumes:Volume儲存在執行Docker的主機,其管理之檔案系統的一個目錄中(Linux內的/var/lib/docker/volumes/),非Docker相關程序不允許修改此一部分的檔案系統,所以Volume是Docker保留資料的最佳方式 - `$ docker run -ti -v vol1:/app alpine sh` * Bind mount:綁定掛載可儲存在Host主機系統的任何位置,甚至它們可能是重要的系統文件或目錄,Docker主機中的非Docker程序或Docker容器內的程式隨時皆可以修改檔案 - `$ docker run -ti -v /home/philipz/vol1:/app alpine sh` * tmpfs mount:暫存掛載僅儲存在主機系統的記憶體中,永遠不會寫入主機系統的檔案系統 - `$ docker run -ti --tmpfs /app alpine sh` * 其實,掛載並不侷限只能是檔案,在Linux設計概念,所有事物皆是檔案系統,所以「/dev」底下的裝置也可掛載到容器中。 :::info * 因此Nvidia看上了容器的軟體包裝特性,把深度學習框架(cuDNN)和平行運算函式庫(CUDA)打包成容器映像檔,只要Host主機裝好GPU驅動程式,並將GPU裝置掛載到容器中,就可以在容器內執行需要GPU運算能力的深度學習等人工智慧相關系統(圖1)。  圖1 Nvidia-docker軟體架構圖。 Nvidia甚至推出nvidia-docker的Wrapper工具(https://github.com/NVIDIA/nvidia-docker),直接幫使用者掛載GPU裝置,不需要再輸入一堆「-v /dev/nvidia0」等掛載參數,所以容器也讓這波人工智慧研究熱潮更加便捷。 ::: --- ### Q35:如何在Docker Host主機之間共享資料? 在開發應用系統的時候,有多種達成此目的的方法,一種是為應用程式添加儲存邏輯,是將文件置放在Amazon S3等雲端對象儲存系統上,另一種方法則是建立Volume,使用可支援把文件寫入NFS或Amazon S3等外部儲存系統之驅動程式。 Volume驅動程式允許從應用程式的邏輯中去抽象化底層儲存系統,舉例來說,如果目前的服務使用具備NFS驅動程式的Volume,亦可更新底層服務以便使用其他驅動程式,例如在雲端中儲存資料,而無須修改應用程式的邏輯。 --- ### Q36:如何在Docker容器下備份、還原或搬移資料儲存Volume? * 備份容器的步驟,可分成以下三步驟: 1. 首先,已有執行中的容器dbstore,且掛載了Volume - `$ docker run -d --name dbstore -e MYSQL\_ROOT\_PASSWORD=XXXX -v dbdata:/var/lib/mysql mysql` 2. 接著啟動新容器,並且從dbstore容器載入Volume - `$ docker run -ti --rm --volumes-from dbstore -v $(pwd):/backup ubuntu bash` 3. 將MySQL資料庫的dbstore volume資料用tar指令壓縮備份 - `$ tar cvf /backup/backup.tar /var/lib/mysql`」 - 便可將「/var/lib/mysql」目錄備份到「/backup/backup.tar」,登出容器後,可在當下目錄看到backup.tar壓縮檔。 - 上述步驟2與步驟3可以合併成「`$ docker run --rm --volumes-from dbstore -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /var/lib/mysql`」。 * 備份還原到容器,共有以下四步驟: 1. 使用剛才建立的備份,可以將其還原到相同容器或在其他位置所建立的其他容器,舉例來說,先建立一個命名為「dbstore2」的新容器:`$ docker create -v newdbdata:/ var/lib/mysql --name dbstore2 mysql` 2. 然後,執行另一個新容器去掛載db2store2的Volume,並解壓縮那個備份檔案:`$ docker run -ti --rm --volumes- from dbstore2 -v $(pwd):/backup ubuntu:16.04 bash` 3. 緊接著,在容器中執行tar命令:`$ tar xvf /backup/backup.tar` 4. 完成後登出,再啟動db2store2容器,便完成資料還原:`$ docker start db2store2` - 上述步驟2與3亦可合併成「`$ docker run --rm --volumes-from dbstore2 -v $(pwd):/backup ubuntu:16.04 tar xvf /backup/backup.tar`」。 --- ### Q30:當容器登出或停止時,資料會消失嗎? 完全不會!在明確地刪除容器之前,應用程式寫入磁碟的任何資料都會保留在其容器中,即便容器停止,那容器的檔案系統仍然會存在。 --- ### Q31:如何在容器之間建立連線? (SSH) 1. 先建立第一個容器作為server-sshserver: - `$ docker run -i -t -p 2222:22 --name sshserver ubuntu bash` 2. 再建立第二個容器當成SSH客戶端: - `$ docker run -i -t --name sshclient --link sshserver:sshserver ubuntu bash` 3. Docker --link功能可在容器間建立私有通道,可使用docker inspect來檢查已串接的容器: - `$ docker inspect -f "{{ .HostConfig. Links }}" sshclient` 4. 執行之後,輸出結果如下:`/sshserver:/sshclient/sshserver` 5. 最後,以SSH藉由其IP進入SSH伺服器: - `$ ssh root@172.17.0.3 -p 22` --- --- - [回到目錄](https://hackmd.io/@Hualiteq/r1lye3M3d)
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.