docker ubuntu 文件同步_Docker 的数据管理--Docker从入门到精通摘记
Docker 數據管理
用戶在使用 Docker 的過程中,??往往需要能夠查看容器內應用產生的數據,??或者說??需要把容器內的數據進行備份,??再或者說??多個容器之間需要進行數據的共享,??那么這些就必然涉及到容器的數據管理操作。??
在容器中管理數據主要有兩種方式,??第一種是通過數據卷來管理,??第二種是通過數據件容器來管理
本章我們首先來介紹??如何在容器內創建數據卷,??并且把本地的目錄或者文件掛載到容器中的數據卷中。??接下來??我會給大家介紹??如何使用數據卷容器,??在容器和主機??容器和容器之間共享數據,??并且實現數據的備份和恢復。??
5.1 數據卷-1
首先我們來了解數據卷,??數據卷是一個可供容器使用的特殊目錄,??它繞過文件系統??可以提供很多有用的特性。?? - 首先??數據卷可以在容器之間共享和重用,?? - 對數據卷的修改??會立馬生效。?? - 對數據卷的更新??不會影響鏡像,?? - 卷會一直存在,??直到沒有容器使用。??## 第一步, 查看幫助文檔# sudo docker run --help-v, --volume list Bind mount a volume--volume-driver string Optional volume driver for the container--volumes-from list Mount volumes from the specified container(s)--name string Assign a name to the container應用:
## 實際掛載一個鏡像.# sudo docker run -d -P -ti --name volume_demo_1 -v /data_1 busybox a41e30838125c0255161949f02cdb431cca93e47b639c1d215d3ed6312b06a6b ### 執行的反饋.### -P 參數 允許外部訪問容器內需要暴露的端口.## 檢查容器是否啟動成功 # sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a41e30838125 busybox "sh" 13 minutes ago Up 13 minutes volume_demo_1## 檢查數據卷是否掛載成功. root@ubuntu-xenial:/home/vagrant# sudo docker attach a41e30(容器6 位縮寫) / # ls bin data_1 dev etc home proc root sys tmp usr var### 可以看到上面有 data_1這個數據卷, 說明掛載成功那么這個掛載點它在我們本機上的目錄映射到什么位置呢???我們可以通過 Docker 的 inspect 命令來查看一下。??Inspect命令我在之前的課程給大家講過,??是用來查看這個容器??相關維度的信息,??那么它會返回??比較詳盡的關于容器的一些信息,我們現在關心的是掛載點的信息,所以我們來找一下
## 使用 Docker 的 inspect 命令查看掛載點映射的具體目錄.# sudo docker inspect a41e ### 返回巨多內容, 因此下面使用精簡命令.巨多命令見文末. # sudo docker inspect a41e | grep Mounts -A 10 ### 打印匹配行以及匹配行后的 10 行內容"Mounts": [{"Type": "volume","Name": "102d3cd7ac8bb138751db24d4b8aabe4edc2a9870f6796e40e337f9f7a5e5139","Source": "/var/lib/docker/volumes/102d3cd7ac8bb138751db24d4b8aabe4edc2a9870f6796e40e337f9f7a5e5139/_data","Destination": "/data_1","Driver": "local","Mode": "","RW": true,"Propagation": ""} ### 可以看到 Source 是映射的目錄, Destination 是我們的數據卷./var/lib/docker/volumes/102d3cd7ac8bb138751db24d4b8aabe4edc2a9870f6796e40e337f9f7a5e5139/_data
在 Source 位置創建一個文件, 檢查是否出現.
## # sudo touch /var/lib/docker/volumes/102d3cd7ac8bb138751db24d4b8aabe4edc2a9870f6796e40e337f9f7a5e5139/_data/1.test## 檢查是否出現1.test # sudo docker attach a41e30 / # ls bin data_1 dev etc home proc root sys tmp usr var / # cd data_1/ /data_1 # ls ### 可以看到 1.test 1.test /data_1 # ?Volume 的作用,它可以讓我們本機和我們的容器??實現目錄的映射,??從而達到數據共享的目的,手動映射容器數據卷到本地目錄
-v 命令也可以讓我們指定??我們本機的哪一個目錄映射到我們容器的什么目錄。??
在之前我們使用-v的時候,大家回憶一下,??我們只是??指定了容器內的掛載點,??那么它對應到本機的什么地址,實際上是由Docker??自動幫我們來決定的。???
## 把本機目錄的data2目錄??映射到??新建的容器的 data2 目錄。??## 窗口1 操作容器 # sudo docker run --rm -it -v ~/data_2:/data_2 busybox ### 命令會后直接進入容器 / # ls bin data_2 dev etc home proc root sys tmp usr var / # cd data_2/ ### 進入容器中的 data2目錄 /data_2 # ls test.2 /data_2 # ## 窗口2 操作本地 root@ubuntu-xenial:~# cd data_2/ root@ubuntu-xenial:~/data_2# ls ### 窗口 1 創建完test.2文件后查看本地 root@ubuntu-xenial:~/data_2# touch test.2 ### 本地 data2 目錄里已經有這個文件## 同理, 在 docker 中的 data2中創建一個 test.3 文件, 三個都可以看到.接下來??我會給大家介紹??如何使用數據卷容器,??在容器和主機??容器和容器之間共享數據,??并且實現數據的備份和恢復。??首先我們來了解數據卷
Docker的數據管理-數據卷容器
如果用戶需要在容器之間共享一些持續更新的數據,最簡單的方式就是使用數據卷容器。
概念: 數據卷容器顧名思義,??它其實是一個普通的容器,??只不過它的目的就是專門提供數據卷供其他的容器來使用
首先我會創建一個數據卷容器,??我給它起一個名字? dbdata1,并且我會在其中創建一個數據卷,??掛載到? dbdata_1 數據卷容器的根目錄下. 然后分別創建兩個普通容器, 這兩個容器通過參數 --volume-from 使用 dabdata_1 容器作為數據卷容器. 最后分別在如上三個容器中分別創建 test.1, test.2, test.3, 通過 ls 命令觀察同步成功的情況.
#### 一共三個窗口, 通過創建三個文件以便觀察數據同步的情況 ## 窗口1. 數據卷容器 dbdata_1$ sudo docker run -it -v /dbdata --name dbdata_1 busybox $ ls bin dbdata dev etc home proc root sys tmp usr var $ cd dbdata/ ### 三個窗口同時進入數據卷容器的目錄 $ /dbdata # touch test.1 ### 三個窗口分別創建一個測試文件 test.1 $ /dbdata # ls test.1 test.2 test.3 ### 最終看到分別創建的文件同時出現在每個窗口/dbdata # #### 窗口 2 和窗口 3 是數據容器, 這兩者將把窗口1 的容器作為數據卷 二者操作完全相同, 可以實時展現數據的同步## 窗口 2 普通容器 db1 $sudo docker run -it --volumes-from dbdata_1 --name db1 busybox ### 參數- -volujmes-from 是告知db1容器要使用 dbdata_1 容器作為一個數據卷$ # ls bin dev home root tmp var dbdata etc proc sys usr $ # cd dbdata/ ### 三個窗口同時進入數據卷容器的目錄 $ /dbdata # touch test.2 ### 三個窗口分別創建一個測試文件 test.2 $ /dbdata # ls test.1 test.2 test.3 ### 最終看到分別創建的文件同時出現在每個窗口## 窗口 3 普通容器 db2 $sudo docker run -it --volumes-from dbdata_1 --name db2 busybox$ # ls bin dev home root tmp var dbdata etc proc sys usr $ # cd dbdata/ ### 三個窗口同時進入數據卷容器的目錄 $ /dbdata # touch test.3 ### 三個窗口分別創建一個測試文件 test.3 $ /dbdata # ls test.1 test.2 test.3 ### 最終看到分別創建的文件同時出現在每個窗口本章完畢.
6 端口映射實現訪問容器
由于使用的是 vagrant 虛擬機, 因此需要二次映射, 8080-8080, 8080:8288(物理機端口)
sudo docker port 容器名
7. Docker File
Docker File是什么???實際上它是一個文本格式的配置文件,??我們的用戶可以使用Docker File 來快速創建自定義的鏡像。??在實際工作中我們經常會遇到現有的鏡像,并不能滿足我們需求這樣的情況,??這種情況下就比較適合我們使用Docker file??來自己快速的構建鏡像
我們首先會大致的講一下 Docker File 有哪些組成部分。??然后我們針對Docker file的命令進行一個詳細的解釋。??最后我們再給大家展示一些??經典的案例。?
Docker 命令參考連接: Docker 命令詳解
Github 案例鏈接: 使用 From scratch 從零開始構建 ubuntu Docker 鏡像
本章節目錄結構:Dockerfile 創建在 /vagrant/data 目錄中
簡單來說, From 命令常用方法是, 引用的 Docker 鏡像源頭來自哪里.
Run 命令是構建 docker 中運行的命令, 比如 apt-get update 或者 yum install..
Docker File 指令
FROM
FROM <image> --- Docker Image 的 ID.
FROM FROM <image>:<tag>
FROM <image>:<digest>
通過 FROM 指定的鏡像,可以是任何有效的基礎鏡像。FROM 有以下限制:
- FROM 必須 是 Dockerfile 中第一條非注釋命令.
- 在一個 Dockerfile 文件中創建多個鏡像時,FROM 可以多次出現。只需在每個新命令 FROM 之前,記錄提交上次的鏡像 ID。
- tag 或 digest 是可選的,如果不使用這kkkkkkkkkk兩個值時,會使用 latest 版本的基礎鏡像
創建一個鏡像, 基于最小的 linux docker image: Alpine.
## 創建一個基于 alpine 的鏡像$ FROM alpine:3.4
2 RUN 執行命令
在鏡像的構建過程中執行特定的命令,并生成一個中間鏡像。格式:
#shell格式 RUN <command> #exec格式 RUN ["executable", "param1", "param2"]- RUN 命令將在當前 image 中執行任意合法命令并提交執行結果。命令執行提交后,就會自動執行 Dockerfile 中的下一個指令。
- 層級 RUN 指令和生成提交是符合 Docker 核心理念的做法。它允許像版本控制那樣,在任意一個點,對 image 鏡像進行定制化構建。
- RUN 指令創建的中間鏡像會被緩存,并會在下次構建中使用。如果不想使用這些緩存鏡像,可以在構建時指定 --no-cache 參數,如:docker build --no-c創建上述實驗中的
自定義一個鏡像
基于國情, 我們構建鏡像時, 會遇到速度過慢的問題, 解決方案有兩個:1. 換中科大源, 這里在 dockerfile 中添加了一條 RUN命令.
`RUN sed -i 's/http://dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories `
2. 使用代理: 具體參考 Segmentfault--在國內 docker build 的正確姿勢## 基礎工作: ##在 vagrant 目錄中創建 data 目錄, 使用 touch 命令創建 vagrant file. ssh 登錄 vagrant $ cd /vagrant $ mkdir data $ cd data $ touch Dockerfile ### Dockerfile 第一個字母 D 大小寫均可 $ vim Dockerfile ### dockerfile 文件名是創建 docker 默認的名字## Dockerfile 寫入如下內容:FROM alpine:3.4 RUN apk update RUN apk add vim RUN apk add curl## 使用 Docker build 命令創建鏡像 $ sudo docker build . -t test/apline-master:v1.0
我們在虛擬機環境里來構建,??首先我們必須要處于 Docker file 的目錄下,?然后我們可以使用Docker的build命令,??-t 用來打 tag. tag 名為: test/apline-master:v1.0 的版本??, 敲擊回車 。??這里我還需要加上一個點表示,??在當前我們的目錄下去尋找?? docker file 文件,?? 回車,??可以看到我們的構建已經開始了,??這里大家可以看有 step的信息.
命令 sudo docker build . -t test/apline-master:v1.0 解析: 點的意思是在當前目錄下查找 Dockerfile文件, -t 的意思是打標簽.vagrant@ubuntu-xenial:/vagrant/data$ sudo docker build . -t test/apline-master:v1.0 Sending build context to Docker daemon 2.048kB Step 1/4 : FROM alpine:3.4 3.4: Pulling from library/alpine ### 第一步是下載, 因為本地目錄沒有 alpine 鏡像. c1e54eec4b57: Pull complete Digest: sha256:b733d4a32c4da6a00a84df2ca32791bb03df95400243648d8c539e7b4cce329c Status: Downloaded newer image for alpine:3.4---> b7c5ffe56db7 Step 2/4 : RUN apk update---> Running in 70cba0f959b7 fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/main/x86_64/APKINDEX.tar.gz fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/community/x86_64/APKINDEX.tar.gz v3.4.6-316-g63ea6d0 [http://dl-cdn.alpinelinux.org/alpine/v3.4/main] v3.4.6-160-g14ad2a3 [http://dl-cdn.alpinelinux.org/alpine/v3.4/community] OK: 5973 distinct packages available Removing intermediate container 70cba0f959b7---> 0c582eedd507 Step 3/4 : RUN apk add vim---> Running in d42d3c2565d4 (1/5) Installing lua5.2-libs (5.2.4-r2) (2/5) Installing ncurses-terminfo-base (6.0_p20171125-r0) (3/5) Installing ncurses-terminfo (6.0_p20171125-r0) (4/5) Installing ncurses-libs (6.0_p20171125-r0) (5/5) Installing vim (7.4.1831-r3) Executing busybox-1.24.2-r14.trigger OK: 37 MiB in 16 packages Removing intermediate container d42d3c2565d4---> 4f37142301d3 Step 4/4 : RUN apk add curl---> Running in 6b2cb98ee1a8 (1/4) Installing ca-certificates (20161130-r0) (2/4) Installing libssh2 (1.7.0-r0) (3/4) Installing libcurl (7.60.0-r1) (4/4) Installing curl (7.60.0-r1) Executing busybox-1.24.2-r14.trigger Executing ca-certificates-20161130-r0.trigger OK: 38 MiB in 20 packages Removing intermediate container 6b2cb98ee1a8---> e4f2fa044d6a Successfully built e4f2fa044d6a Successfully tagged test/apline-master:v1.0## 查看剛剛創建的鏡像
## 查看剛剛創建的鏡像$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE test/apline-master v1.0 e4f2fa044d6a 3 minutes ago 32.2MB為什么要把這個文件名字??命名為Dockerfile,??可以看到??在??我們的構建命令中,??我并沒有顯示的指定??去??執行哪一個,去構建哪一個Dockerfile 文件。??那么默認情況下,它會在我們當前的目錄??去尋找?名字為 Dockefile 的這么一個構建文件。??如果存在構建就開始?.?如果我們把構件文件改成其他的名字,??那么我們這個構建指令就會失效。??我們??就必須要顯示的指定,??我們要使用我們要構建哪一個Dockerfile,??所以說這就是為什么??我們把配置文件命名為Dockerfile.
鏡像分層的概念
先接上一節, 檢查我們只做好的鏡像
## 進入test/apline鏡像并檢查$ sudo docker run --rm -it e4f2fa044d6a /bin/sh / # vim --v ### 加上 --rm參數在執行完畢之后,我們就刪除這個容器 VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Feb 16 2017 11:25:35) Unknown option argument: "--v" More info with: "vim -h" / # curl --version curl 7.60.0 (x86_64-alpine-linux-musl) libcurl/7.60.0 OpenSSL/1.0.2n zlib/1.2.11 libssh2/1.7.0 Release-Date: 2018-05-16 Protocols: dict file ftp ftps gopher http https imap imaps pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp Features: AsynchDNS IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP UnixSockets HTTPS-proxy5. 鏡像分層和Cache
## -a 參數vagrant@ubuntu-xenial:/vagrant/data$ sudo docker images -a REPOSITORY TAG IMAGE ID CREATED SIZE test/apline-master v1.0 e4f2fa044d6a 23 minutes ago 32.2MB <none> <none> 4f37142301d3 23 minutes ago 30.6MB <none> <none> 0c582eedd507 23 minutes ago 5.58MB### 上面兩個 none 標簽的 image,就是過渡 image好,接下來我們來談一下鏡像分層的概念。??剛才我們在提到 run 指令的時候,??我說了??每執行 run 指令,我們的鏡像就會提交一次?. 當我們去執行 Docker image -a, -a 參數會羅列出我們當前??當前本地鏡像庫所有的鏡像,??包括最終鏡像和中間鏡像。??
我們 Dockerfile 中有三個run指令,也就是說他提交了三次,??也就是說在整個構建的過程中??會構建出三個鏡像。??大家可以看從5.58, 30.6 32.2M,??這就是我們構建出來的三個鏡像。??每一個鏡像??都和前面的鏡像有關系。??比如說大小為30.6兆的鏡像,??就保存了??和下面5.58兆鏡像不同的信息。??那么上面的32.2兆的鏡像??就保存了??和30.6兆?鏡像不同的信息。??那么最終我們看到的實際上是??最上面的鏡像,??但是這兩個鏡像實際上在我們??整個構建過程中也是被構建出來了。??
那么Docker 為什么要保留??這樣兩個鏡像???其實剛才我基本上也說到了,??他只會保留和前一個鏡像,也只是所謂副?鏡像不一樣的信息,??這個和我們在使用版本控制軟件的概念其實是一樣的,??我們每一次的提交只提交了變動而已,而不是提交整個文件,??這樣的話會節省我們的空間。??另外有一點 Dockerfile 會利用 Docker 里面有一個叫做鏡像緩存的機制,??既然是緩存,顧名思義??就是為了復用。??我們如果這次比方說這里有一次構建,??它就要構建出三層,??那么他發現前兩層在我們的緩存里已經存在了,??那就會直接從我們的緩存中取出已經構建好的鏡像,??避免重復構建,??然后把不同的地方再單獨構建一次,??加速構建效率。??
通過再構建一個鏡像, 觀察 Docker Cache 的復用效果
## 更改 Dockerfile 內容$ vim Dockerfile### 內容如下 FROM alpine:3.4 RUN apk update RUN apk add curl RUN apk add vim RUN apk add git## 創建新鏡像 v2.0 $ sudo docker build . -t test/apline-master:v2.0 ## 創建 v2.0 過程 sudo docker build . -t test/apline-master:v2.0 Sending build context to Docker daemon 3.072kB Step 1/5 : FROM alpine:3.4---> b7c5ffe56db7 Step 2/5 : RUN apk update---> Using cache ### 直接使用 b7c5ff 的 cache 鏡像(中間鏡像)---> 0c582eedd507 Step 3/5 : RUN apk add curl---> Running in 87c9cfc43f98 (1/4) Installing ca-certificates (20161130-r0) (2/4) Installing libssh2 (1.7.0-r0) (3/4) Installing libcurl (7.60.0-r1) (4/4) Installing curl (7.60.0-r1) Executing busybox-1.24.2-r14.trigger Executing ca-certificates-20161130-r0.trigger OK: 6 MiB in 15 packages Removing intermediate container 87c9cfc43f98---> 0661fdb17dd1 Step 4/5 : RUN apk add vim---> Running in e626c02651bd (1/5) Installing lua5.2-libs (5.2.4-r2) (2/5) Installing ncurses-terminfo-base (6.0_p20171125-r0) (3/5) Installing ncurses-terminfo (6.0_p20171125-r0) (4/5) Installing ncurses-libs (6.0_p20171125-r0) (5/5) Installing vim (7.4.1831-r3) Executing busybox-1.24.2-r14.trigger OK: 38 MiB in 20 packages Removing intermediate container e626c02651bd---> 3f7373634309 Step 5/5 : RUN apk add git---> Running in 18507f2b4abc (1/3) Installing expat (2.2.0-r1) (2/3) Installing pcre (8.38-r1) (3/3) Installing git (2.8.6-r0) Executing busybox-1.24.2-r14.trigger OK: 54 MiB in 23 packages Removing intermediate container 18507f2b4abc---> 757844a1c97f Successfully built 757844a1c97f Successfully tagged test/apline-master:v2.0### 由于 Dockerfile 中更改了同樣兩條命令的順序, 因此它并不能使用 cache 鏡像, 而是直接重新創建中間鏡像, 并刪除了重復的鏡像(理解如此, 未檢查)### 如何實現一次提交
## 同時提交多條 RUN 命令## 第一種 FROM alpine:3.4 RUN apk update && apk add vim && apk add git && apk add curl## 第二種FROM alpine:3.4 RUN apk update && apk add vim git curl ## 在 ubuntu 下安裝 docker 環境并創建 v3.0sudo docker build . -t test/apline-master:v3.0 Sending build context to Docker daemon 3.072kB Step 1/2 : FROM alpine:3.4---> b7c5ffe56db7 Step 2/2 : RUN apk update && apk add curl vim git---> Running in e965f7dc4913 fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/main/x86_64/APKINDEX.tar.gz fetch http://dl-cdn.alpinelinux.org/alpine/v3.4/community/x86_64/APKINDEX.tar.gz v3.4.6-316-g63ea6d0 [http://dl-cdn.alpinelinux.org/alpine/v3.4/main] v3.4.6-160-g14ad2a3 [http://dl-cdn.alpinelinux.org/alpine/v3.4/community] OK: 5973 distinct packages available (1/12) Installing ca-certificates (20161130-r0) (2/12) Installing libssh2 (1.7.0-r0) (3/12) Installing libcurl (7.60.0-r1) (4/12) Installing curl (7.60.0-r1) (5/12) Installing expat (2.2.0-r1) (6/12) Installing pcre (8.38-r1) (7/12) Installing git (2.8.6-r0) (8/12) Installing lua5.2-libs (5.2.4-r2) (9/12) Installing ncurses-terminfo-base (6.0_p20171125-r0) (10/12) Installing ncurses-terminfo (6.0_p20171125-r0) (11/12) Installing ncurses-libs (6.0_p20171125-r0) (12/12) Installing vim (7.4.1831-r3) Executing busybox-1.24.2-r14.trigger Executing ca-certificates-20161130-r0.trigger OK: 54 MiB in 23 packages Removing intermediate container e965f7dc4913---> 72527ccfc4ef Successfully built 72527ccfc4ef Successfully tagged test/apline-master:v3.0使用命令檢查
## 檢查 $ sudo docker images -a ### 可以看到只有一層, 因為我們只進行了一次提交 REPOSITORY TAG IMAGE ID CREATED SIZE test/apline-master v3.0 72527ccfc4ef 45 seconds ago 48.5MB test/apline-master v2.0 757844a1c97f 13 minutes ago 48.7MB <none> <none> 3f7373634309 13 minutes ago 32MB <none> <none> 0661fdb17dd1 13 minutes ago 7.01MB test/apline-master v1.0 e4f2fa044d6a 12 hours ago 32.2MB <none> <none> 4f37142301d3 12 hours ago 30.6MB <none> <none> 0c582eedd507 12 hours ago 5.58MBAPI 鏡像的構建
## 構建鏡像# This is used for building Restful API FROM fabric8/java-alpine-openjdk8-jdk ### 第一句非注釋語句必須是 FROM 指令 LABEL maintainer ="test.docker@test.com" version="1.0" ### 維護作者信息的指令, 通過 inspect 命令查看 COPY target/dockerdemo1-8.0.1-SNAPSHOT.jar /app.jar EXPOSE 8080 ENTRYPOINT ["java","-jar","/app.jar"構建鏡像
## 構建鏡像 sudo docker build . -t restful_api:v6REPOSITORY TAG IMAGE ID CREATED SIZE <none> <none> 83ea132f3063 40 seconds ago 108MB <none> <none> 9f2873387662 11 minutes ago 108MB ### 命令構建完成, 無法打上標簽, 原因不明## 檢查鏡像完成情況$ sudo docker images -a REPOSITORY TAG IMAGE ID CREATED SIZE <none> ### 這行的鏡像廢了 <none> 83ea132f3063 40 seconds ago 108MB <none> <none> 9f2873387662 11 minutes ago 108MB## 檢查 Label 命令的結果$ sudo docker inspect 9f2873387662 | grep Labels -A 3"Labels": {"maintainer": "=test.docker@test.com version=1.0"}}, --"Labels": {"maintainer": "=test.docker@test.com version=1.0"}},移除 COPY 指令, 創建 V8
## 創建 V8$ sudo docker build . -t restful_api:v8 Sending build context to Docker daemon 3.072kB Step 1/4 : FROM fabric8/java-alpine-openjdk8-jdk---> 2b7844efe720 Step 2/4 : LABEL maintainer="SvenDowideit@home.org.au" version="1.0"---> Running in 59ba789c8740 Removing intermediate container 59ba789c8740---> c90062fc7580 Step 3/4 : EXPOSE 8080---> Running in 6cd4713a80d2 Removing intermediate container 6cd4713a80d2---> 7bbb1fa1b39e Step 4/4 : ENTRYPOINT ["java","-jar","/app.jar"---> Running in 3dc9bf9295ce Removing intermediate container 3dc9bf9295ce---> 8d1c8d2fa5fe Successfully built 8d1c8d2fa5fe Successfully tagged restful_api:v8## 檢查 V8, 終于正常的打上了標簽. 不知為何生成了兩個中間鏡像 sudo docker images -a REPOSITORY TAG IMAGE ID CREATED SIZE <none> <none> 7bbb1fa1b39e 53 seconds ago 108MB <none> <none> c90062fc7580 53 seconds ago 108MB restful_api v8 8d1c8d2fa5fe 53 seconds ago 108MB <none> <none> 9f2873387662 17 hours ago 108MB## 通過 Inspect 觀察指令 sudo docker inspect 8d1c8d2fa5fe | grep Labels -A 3"Labels": {"maintainer": "SvenDowideit@home.org.au","version": "1.0"} --"Labels": {"maintainer": "SvenDowideit@home.org.au","version": "1.0"}maintainer 僅限于作者, Label 可以有多重信息
## Dockerfile 內容# Thi is used for building Restful API FROM fabric8/java-alpine-openjdk8-jdk # MAINTAINER SvenDowideit@home.org.au LABEL maintainer="SvenDowideit@home.org.au" version="1.0" name="SvenDovideit" EXPOSE 8080 ENTRYPOINT ["java","-jar","/app.jar"COPY 和 ADD 指令
一般不推薦使用 ADD 指令, 大的原則是越原始的命令, 越可靠. 實際工作中, 你不知道 ADD 指令執行了什么, 卡在什么地方了. 對于排查問題很困難.
## 標準格式## COPY 命令 COPY <源路徑>... <目標路徑> COPY ["<源路徑1>",... "<目標路徑>"]## ADD 命令ADD <源路徑>... <目標路徑> ADD ["<源路徑>",... "<目標路徑>"] ADD 指令和 COPY 的格式和性質基本一致。但是在 COPY 基礎上增加了一些功能。比如<源路徑>可以是一個 URL,這種情況下,Docker 引擎會試圖去下載這個鏈接的文件放到<目標路徑>去。COPY 指令是用來??把我們本地的文件復制到我們容器中
## 鏡像中存在一條 COPY 命令的示例: COPY target/dockerdemo1-0.0.1-SNAPSHOT.jar /app.jar### 在我們這個例子里,??我們把我們本地target目錄下的??jar 包,??dockerdemo,?復制到了我們的容器根目錄下,并且??我們給 jar 包重新起了一個名字叫做 app.jarWORKDIR 命令, 指定工作目錄
WORKDIR用于在容器內設置一個工作目錄:
## 格式 WORKDIR /path/to/workdir 通過WORKDIR設置工作目錄后,Dockerfile 中其后的命令 RUN、CMD、ENTRYPOINT、ADD、COPY 等命令都會在該目錄下執行。# Dockerfile 示例# Thi is used for building Restful API FROM fabric8/java-alpine-openjdk8-jdk # MAINTAINER SvenDowideit@home.org.au LABEL maintainer="SvenDowideit@home.org.au" version="1.0" name="SvenDovideit"WORKDIR / COPY target/dockerdemo1-0.0.1-SNAPSHOT.jar ./app.jar ### 增加了一個點, 意思是復制到當前目錄下, 當前目錄由于 WORKDIR定義, 當前目錄為根目錄. 因此, 實現的效果和下面被井號注釋掉的 COPY 命令一樣效果. 但是如果 WORKDIR/home , 那么 當前目錄就為 /home 了.# COPY target/dockerdemo1-0.0.1-SNAPSHOT.jar /app.jarEXPOSE 8080 ENTRYPOINT ["java","-jar","/app.jar"EXPOSE 命令
為構建的鏡像設置監聽端口,使容器在運行時監聽。格式:
## 格式 EXPOSE <port> [<port>...]Stackoverflow 的 Docker 開放3000, 443, 22, 80 4個端口的例子
需要注意的是我們 expose端口不僅僅能發布一個端口,??我們同樣可以發布多個端口,那么這里大家可以看在stackoverflow上有這么一個例子,??在這個例子里它發布了4個端口,??它這4個端口也是根據??應用內部的需要來發布的。??比如說如果我們開放了22端口,??我們就可以通過ssh來訪問這個容器,??
再比如說我們容器的內部安裝了阿帕奇的這么一個外部服務器,??那么阿帕奇的外部服務器默認端口為80,??所以這里有意識的把鏡像的80端口??可以暴露出去,??以此類推端暴露哪些端口,就可以根據??我們用戶的需求??來定制
當我們使用-p參數, -小p參數的時候來指定的時候,??我們可以顯示的指定??我們本機的哪個端口??和我們容器的哪一個端口來進行映射。??
當我們使用-大P參數的時候,??我們就讓我們的 Docker 給我們隨機分配本地端口去映射我們容器的端口。??
參考上一節: 端口映射實現訪問容器的課程
## 7 VOLUME 定義匿名卷
VOLUME用于創建掛載點,即向基于所構建鏡像創始的容器添加卷:
## 格式 VOLUME ["/data"]指定本機特定目錄到容器目錄
## 首先 build 這個容器 $ sudo docker build . -t restful_api:v13## 在dockerfile 中創建 工作目錄$ vagrant@ubuntu-xenial:/vagrant/data/data$ vim Dockerfile ## 查看 vim 的內容 # This is used for building Restful API FROM fabric8/java-alpine-openjdk8-jdk# MAINTAINER SvenDowideit@home.org.au LABEL maintainer="SvenDowideit@home.org.au" version="1.0" name="SvenDovideit"WORKDIR /COPY target/dockerdemo1-0.0.1-SNAPSHOT.jar ./app.jarVOLUME ["/data1"]EXPOSE 8080CMD java -jar /app.jar# ENTRYPOINT ["java","-jar","/app.jar"]運行并檢查
## 根據創建的 Dockerfile 生成鏡像 $ vagrant@ubuntu-xenial:/vagrant/data/data$ sudo docker build . -t restful_api:v13## 檢查 image 的創建結果 $ vagrant@ubuntu-xenial:/vagrant/data/data$ sudo docker images -a vagrant@ubuntu-xenial:/vagrant/data/data$ sudo docker images -a REPOSITORY TAG IMAGE ID CREATED SIZE <none> <none> 91abb9ac9f50 11 seconds ago 125MB restful_api v13 6f46f73ccd15 11 seconds ago 125MB## 通過 image 的 ID 運行容器 $ sudo docker run -it -v /tmp/localdata:/data1 6f46f73ccd15 /bin/sh## 檢查容器的 ID. 可以看到容器和鏡像都有各自的 ID: $ vagrant@ubuntu-xenial:/vagrant/data/data$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 85e97f37db33 6f46f73ccd15 "/bin/sh" 2 minutes ago Exited (0) 10 seconds ago sharp_ellis## 檢查容器中 data1 的源目錄 -- 即在本機中的位置 $ vagrant@ubuntu-xenial:/vagrant/data/data$ sudo docker inspect 85e97f37db33 | grep Mounts -A 10## 使用 grep Mounts -A 10 找到 Mounts 關鍵字后的 10 行, 注意區分大小寫"Mounts": [{"Type": "bind","Source": "/tmp/localdata","Destination": "/data1","Mode": "","RW": true,"Propagation": "rprivate"}],"Config": {## 這個地址是由?? Docker 自動給我們生成的這么一個地址 ## 指定 data1 的本地目錄命令 $ sudo docker run -it -v /tmp/localdata:/data1 6f46f73ccd15 /bin/sh ## -v 參數是 volume, 指定本地 /tmp/localdat 的目錄為 6f46f73ccd15 鏡像的 data1 的目錄在 data1 目錄中創建一個 test.txt 文檔, 檢查是否在對應的本地目錄 /tmp/localdata 中出現
## 檢查 test.txt 的存在 vagrant@ubuntu-xenial:/vagrant/data/data$ sudo docker run -it -v /tmp/localdata:/data1 6f46f73ccd15 /bin/sh / # ls app.jar data1 dev home media opt root sbin sys usr bin deployments etc lib mnt proc run srv tmp var / # cd data1/ /data1 # ls /data1 # touch test.txt /data1 # ls test.txt /data1 # exit vagrant@ubuntu-xenial:/vagrant/data/data$ ls /tmp/localdata/ test.txt ## 可以看到在 data1 中創建的文件, 出現在本地目錄/tmp/localdata 下.## 在本地目錄中創建一個文件, 看是否可以出現在容器的/data1 目錄下 $ vagrant@ubuntu-xenial:/vagrant/data/data$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3f4519766cca 6f46f73ccd15 "/bin/sh" 3 minutes ago Exited (0) 2 minutes ago silly_grothendieck ### 容器的 ID 為 3f4519766cca $ vagrant@ubuntu-xenial:/vagrant/data/data$ sudo docker exec -it 3f4519766cca /bin/sh / # ls /data1 test.txt test2.txt ### 通過 exec 命令進入容器, 并檢查 /data1 中, 發現 test2.txt存在.上圖是視頻截圖.
ENV 指令
env 指令,這個指令是用來設置環境變量的,??這個環境變量被設置好了之后,??無論是我們在構建鏡像的過程中,還是在容器啟動的過程中,??它都是存在的,我們都可以來引用.
ENV AUTHOR="SvenDovideit"
創建V14鏡像
## 創建容器$ vagrant@ubuntu-xenial:/vagrant/data/data$ sudo docker build . -t restful_api:v14 查看得知 images ID 為 28d0 $ sudo docker run -it 28d03fe91988 /bin/sh## 進入容器查看 ENV 指令內容 $ vagrant@ubuntu-xenial:/vagrant/data/data$ sudo docker run -it 28d03fe91988 /bin/sh / # echo $AUTHOR SvenDovideit / #環境變量之 ARG 指令
ARG 指令和 ENV 指令是非常相像的,??它們唯一的不同就在于ARG 指令是用在構建時候的變量,??也就是說當我們構建完成之后,??我們通過 ARG 指令設定的環境變量就無法再訪問了。??
從下圖實驗可以看出, 創建完成后, 無法訪問 ARG 創建的 build_user, 它僅僅在創建 docker 時使用, 過后無法訪問. (和 ENV太像, 未做測試, 下圖為他人實驗截圖)
ENTRYPOINT 指令
## 兩種格式, 第一種格式叫做?? EXEC 格式。??第二種格式叫做 SHELL 格式. ENTRYPOINT ["executable", "param1", "param2"] ENTRYPOINT command param1 param2ENTRYPOINT 指令,??這個指令用于給我們的容器配置一個可執行的程序。??也就是說每次我們在使用鏡像創建容器的時候,??我們是通過ENTRYPOINT指定的程序來設置我們的默認啟動程序。??
Dockerfile 中可以有多個 ENTRYPOINT 指令,??但??而只有最后一條 ENTRYPOINT會執行,前面的都會被覆蓋
### 完整構建代碼:
# Version: 0.0.3 FROM ubuntu:16.04 MAINTAINER 何民三 "cn.liuht@gmail.com" RUN apt-get update RUN apt-get install -y nginx RUN echo 'Hello World, 我是個容器' > /var/www/html/index.html ENTRYPOINT ["/usr/sbin/nginx"] EXPOSE 80#### 使用docker build構建鏡像,并將鏡像指定為 itbilu/test:
docker build -t="itbilu/test" .#### 構建完成后,使用itbilu/test啟動一個容器:
docker run -i -t itbilu/test -g "daemon off;"在運行容器時,我們使用了 -g "daemon off;",這個參數將會被傳遞給 ENTRYPOINT,最終在容器中執行的命令為 /usr/sbin/nginx -g "daemon off;"。CMD 指令
## CMD 指令的有三種格式,? ?## 第一種叫做exec格式和 ENTRYPOINT 是一樣的,?? ## 第二種叫做parameter格式,??也就是所謂的參數格式。? ?## 第三種叫做shell格式,??也就是所謂的命令行格式,??CMD ["executable","param1","param2"] CMD ["param1","param2"] CMD command param1 param2第二種格式可以使我們的cmd中的參數??被當作 ENTRYPOINT的默認參數,??此時的ENTRYPOINT必須得是exec格式,??也就是說他們兩個之間有一些微妙的搭配
CMD ["-jar","/app.jar"] ## CMD 參數格式下, 會默認傳遞參數給下一行的 ENTRYPOINT 命令 ENTRYPOINT ["java"]## Github 案例1講解: 使用 From scratch 從零開始構建 ubuntu Docker 鏡像
CMD ["/bin/bash"]在我們實際的工作中,我們一般不會從零開始來構建鏡像,??我們一般會選做選一個鏡像作為我們的基礎鏡像,??在它之上我們來進行一些構建。??比如說我們想構建一個基于 ubuntu 的??一個開發環境,??我們不會使用from scratch,??我們會使用from ubuntu 然后選定一個版本,??然后在這個已經安裝好的安裝和 ubuntu 操作系統的鏡像里,??我們執行一些操作,比如說安裝一個?? tomcat的軟件,安裝get 安裝Docker等等。??然后我們把制作好的鏡像作為??基礎鏡像分發出去,供我們?? team內部的成員使用,??然后大家在這個基礎上進行開發工作,??最后我們把鏡像??分發給我們的測試人員和運維人員,??基本上是這樣一個流程
## Github 案例 2講解: 一個TOMCAT 容器構建
## 如下內容和 tomcat 服務器相關, 非關注重點 # let "Tomcat Native" live somewhere isolated ENV TOMCAT_NATIVE_LIBDIR $CATALINA_HOME/native-jni-lib ENV LD_LIBRARY_PATH ${LD_LIBRARY_PATH:+$LD_LIBRARY_PATH:}$TOMCAT_NATIVE_LIBDIR# see https://www.apache.org/dist/tomcat/tomcat-$TOMCAT_MAJOR/KEYS # see also "update.sh" (https://github.com/docker-library/tomcat/blob/master/update.sh) ENV GPG_KEYS 05AB33110949707C93A279E3D3EFE6B686867BA6 07E48665A34DCAFAE522E5E6266191C37C037D42 47309207D818FFD8DCD3F83F1931D684307A10A5 541FBE7D8F78B25E055DDEE13C370389288584E7 61B832AC2F1C5A90F0F9B00A1C506407564C17A3 79F7026C690BAA50B92CD8B66A3AD3F4F22C4FED 9BA44C2621385CB966EBA586F72C284D731FABEE A27677289986DB50844682F8ACB77FC2E86E29AC A9C5DF4D22E99998D9875A5110C01C5A2F6059E7 DCFD35E0BF8CA7344752DE8B6FB21E8933C60243 F3A04C595DB5B6A5F1ECA43E3B7BBB100D811BBE F7DA48BB64BCB84ECBA7EE6935CD23C10D498E23ENV TOMCAT_MAJOR 9 ENV TOMCAT_VERSION 9.0.31 ENV TOMCAT_SHA512 75045ce54ad1b6ea66fd112e8b2ffa32a0740c018ab9392c7217a6dd6b829e8645b6810ab4b28dd186c12ce6045c1eb18ed19743c5d4b22c9e613e76294f22f5這個文件末尾
EXPOSE 8080 CMD ["catalina.sh", "run"]全文完, 后續視情況更新.
錯誤:
restful風格的API, openjdk:8-jdk-alpine 已不存在,
替代鏡像:fabric8/java-alpine-openjdk8-jdk
改進:
在鏡像中加入 RUN 命令, 替換國內源.
未知:
dockerdemo1-0.0.1-SNAPSHOT.jar 是啥, 相關的使用 8080 端口的程序是啥
問題:
1. vagrant 中 copy 文件的問題
## 解決拷貝文件到 vagrant 環境的問題方法 1: 在 vagrant up 之后的環境中運行如下命令 $ vagrant plugin install vagrant-scp## 使用方法 vagrant scp <some_local_file_or_dir> [vm_name]:<somewhere_on_the_vm>## 方法 2: 在 macOS 默認 Terminal 環境下即可 cp -R 遞歸目錄拷貝. 通過 pwd 找到 vagrantfile 所在文件夾(目標文件夾)的位置. 通過 FINDer 中直接拖曳目錄到 Terminal 中的方式獲得源文件夾的位置$ cp -R cp -R /Users/mask/Documents/需要copy 的文件夾/1. 介紹/1.1 Archive.zip/env/data /Users/mask#### 檢查 copy 的結果$ vagrant ssh $ vagrant@ubuntu-xenial:/vagrant/data$ pwd /vagrant/data ## 當前目錄 , 這個目錄就是虛擬機運行時,vagrant 的目錄2. 無法運行 localhost:8280/hi
## Dockerfile 文件內容如下 # This is used for building Restful API FROM fabric8/java-alpine-openjdk8-jdk# MAINTAINER SvenDowideit@home.org.au LABEL maintainer="SvenDowideit@home.org.au" version="1.0" name="SvenDovideit" WORKDIR / COPY target/dockerdemo1-0.0.1-SNAPSHOT.jar ./app.jar VOLUME ["/data1"] EXPOSE 8080ENTRYPOINT ["java","-jar","/app.jar"]創建 V7版 image 并查看 image ID 為2ee2b7f5a817
$ vagrant@ubuntu-xenial:/vagrant/data/data$ sudo docker build . -t restful_api:v7 $ vagrant@ubuntu-xenial:/vagrant/data/data$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE restful_api v7 2ee2b7f5a817 14 seconds ago 125MB restful_api v13 6f46f73ccd15 3 hours ago 125MB運行 2ee2b7f5a817 的容器之后可以看到 java 啟動的信息, 但是無法通過http://localhost:8080/hi 或者http://localhost:8280/hi, 或者http://localhost:8080, 或者 http://localhost:8280, 均無法打開網頁
$ vagrant@ubuntu-xenial:/vagrant/data/data$ sudo docker run -p 8080:8080 2ee2b7f5a817. ____ _ __ _ _/ / ___'_ __ _ _(_)_ __ __ _ ( ( )___ | '_ | '_| | '_ / _` | / ___)| |_)| | | | | || (_| | ) ) ) )' |____| .__|_| |_|_| |___, | / / / /=========|_|==============|___/=/_/_/_/:: Spring Boot :: (v2.1.6.RELEASE)2020-09-03 10:23:32.133 INFO 1 --- [ main] c.a.dockerdemo1.Dockerdemo1Application : Starting Dockerdemo1Application v0.0.1-SNAPSHOT on e17e19a2e114 with PID 1 (/app.jar started by root in /) 2020-09-03 10:23:32.138 INFO 1 --- [ main] c.a.dockerdemo1.Dockerdemo1Application : No active profile set, falling back to default profiles: default 2020-09-03 10:23:33.490 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2020-09-03 10:23:33.520 INFO 1 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2020-09-03 10:23:33.520 INFO 1 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.21] 2020-09-03 10:23:33.605 INFO 1 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2020-09-03 10:23:33.606 INFO 1 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1396 ms 2020-09-03 10:23:33.826 INFO 1 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2020-09-03 10:23:33.989 INFO 1 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2020-09-03 10:23:33.991 INFO 1 --- [ main] c.a.dockerdemo1.Dockerdemo1Application : Started Dockerdemo1Application in 2.319 seconds (JVM running for 2.833)Docker 官網 Docker File指令集
總結
以上是生活随笔為你收集整理的docker ubuntu 文件同步_Docker 的数据管理--Docker从入门到精通摘记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数据仓库之元数据管理
- 下一篇: Ubuntu16.04安装搜狗输入法后有