###### 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
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up