1. Dockerfile介紹
Dockerfile是用來構建Docker鏡像的檔案,它是一個文本檔案,也可以說是命令引數腳本,Dcoker根據該檔案生成二進制的image檔案,
Docker鏡像發布的步驟:
1、撰寫一個dockerfile檔案
2、docker build 構建成為一個鏡像
3、docker run 鏡像
4、docker push 鏡像(發布鏡像到DockerHub、阿里云鏡像倉庫)
示例一個鏡像的結構圖:

2. Dockerfile指令說明
| 指令 | 說明 |
|---|---|
| FROM | 指定基礎鏡像 |
| MAINTAINER | 鏡像是誰寫的,姓名+郵箱 |
| RUN | 鏡像構建的時候需要運行的命令 |
| ADD | 添加構建步驟,如添加一個tomcat鏡像 |
| WORKDIR | 鏡像的作業目錄 |
| VOLUME | 掛載的目錄 |
| EXPOSE | 保留埠配置 |
| CMD | 指定這個容器啟動的時候要運行的命令(只有最后一個會生效) |
| EMTRYPOINT | 指定這個容器啟動的時候要運行的命令,可以追加命令 |
| ONBUILD | 當構建一個被繼承DockerFile,這個時候就會運行ONBUILD的指令,觸發指令 |
| COPY | 類似于ADD ,將我們檔案拷貝到鏡像中 |
| ENV | 構建的時候設定環境變數 |
一個形象的解釋各個指令作用的圖:

關于DockerFile檔案的腳本注意點有:
1、每個保留關鍵字(指令)都必須是大寫字母
2、檔案中的指令從上到下順序執行
3、# 號表示注釋
4、每一個指令都會創建提交一個新的鏡像層,并提交!
3. 制作Centos鏡像
下面通過撰寫Dockerfile檔案來制作Centos鏡像,并在官方鏡像的基礎上添加vim和net-tools工具,首先在/home/dockfile 目錄下新建檔案mydockerfile-centos,然后使用上述指令撰寫該檔案,
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# cat mydockerfile-centos
FROM centos
MAINTAINER ethan<1258398543@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "---end---"
CMD /bin/bash
逐行解釋該Dockerfile檔案的指令:
- FROM centos:該image檔案繼承官方的centos,后面加冒號如centos:7,用于指定鏡像的版本
- ENV MYPATH /usr/local:設定環境變數MYPATH ,后面有用到
- WORKDIR $MYPATH:直接使用上面設定的環境變數,指定/usr/local為作業目錄
- RUN yum -y install vim和RUN yum -y install net-tools:在/usr/local目錄下,運行yum -y install vim和yum -y install net-tools命令安裝工具,注意安裝后的所有依賴和工具都會打包到image檔案中
- EXPOSE 80:將容器80埠暴露出來,允許外部連接這個埠
- CMD:指定容器啟動的時候運行命令
通過這個dockerfile構建鏡像,構建鏡像命令:docker build -f dockerfile檔案路徑 -t 鏡像名[:版本號] .(這里有個小點.)
上面命令中,-t引數用來指定 image 檔案的名字,后面還可以用冒號指定標簽,如果不指定,默認的標簽就是latest,最后的那個點表示 Dockerfile 檔案所在的路徑,上例是當前路徑,所以是一個點,
下面執行build命令生成image檔案,如果執行成功,可以通過docker images來查看新生成的鏡像檔案,
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker build -f mydockerfile-centos -t mycentos:1.0 .
Sending build context to Docker daemon 2.048kB
Step 1/10 : FROM centos
---> 300e315adb2f
Step 2/10 : MAINTAINER ethan<1258398543@qq.com>
---> Running in bbfd1a4949e1
Removing intermediate container bbfd1a4949e1
---> b2b6851e55fa
Step 3/10 : ENV MYPATH /usr/local
---> Running in 7cd8c84a5b70
Removing intermediate container 7cd8c84a5b70
---> e27a56b5247b
Step 4/10 : WORKDIR ${MYPATH}
---> Running in 770e175260c4
Removing intermediate container 770e175260c4
---> 7d46880ef0fd
Step 5/10 : RUN yum -y install vim
Step 7/10 : EXPOSE 80
---> Running in 24cfcfa56460
Removing intermediate container 24cfcfa56460
---> 2064c1540e8e
Step 8/10 : CMD echo ${MYPATH}
---> Running in 83dd9766da3c
Removing intermediate container 83dd9766da3c
---> 9b8661c812c4
Step 9/10 : CMD echo "---end---"
---> Running in 974afa805b27
Removing intermediate container 974afa805b27
---> 83459c404586
Step 10/10 : CMD /bin/bash
---> Running in 4fba3174f9d8
Removing intermediate container 4fba3174f9d8
---> 1185a46e3a12
Successfully built 1185a46e3a12
Successfully tagged mycentos:1.0
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 1.0 1185a46e3a12 4 minutes ago 291MB
下面生成容器,測驗相關命令,查看默認作業目錄是否設定成功,vim和net-tools工具是否下載成功,
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker run -it mycentos:1.0
[root@e548efe82b30 local]# pwd
/usr/local
#net-tools工具提供ifconfig命令
[root@e548efe82b30 local]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.3 netmask 255.255.0.0 broadcast 172.17.255.255
ether 02:42:ac:11:00:03 txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@e548efe82b30 local]# vi test.txt
[root@e548efe82b30 local]# cat test.txt
Hello world!
另外,我們通過docker history 容器id命令來查看鏡像的構建步驟
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker history 1185a46e3a12
IMAGE CREATED CREATED BY SIZE COMMENT
1185a46e3a12 13 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B
83459c404586 13 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
9b8661c812c4 13 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
2064c1540e8e 13 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
1b15d4a1fd5e 13 minutes ago /bin/sh -c yum -y install net-tools 23.3MB
9336c20f0b6d 13 minutes ago /bin/sh -c yum -y install vim 58MB
7d46880ef0fd 14 minutes ago /bin/sh -c #(nop) WORKDIR /usr/local 0B
e27a56b5247b 14 minutes ago /bin/sh -c #(nop) ENV MYPATH=/usr/local 0B
b2b6851e55fa 14 minutes ago /bin/sh -c #(nop) MAINTAINER ethan<12583985… 0B
300e315adb2f 3 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 3 weeks ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ADD file:bd7a2aed6ede423b7… 209MB
4. RUN,CMD和ENTRYPOINT的區別
RUN命令與CMD命令的區別在哪里?
簡單說,RUN命令在 image 檔案的構建階段執行,執行結果都會打包進入 image 檔案;CMD命令則是在容器啟動后執行,另外,一個 Dockerfile 可以包含多個RUN命令,但是只能有一個CMD命令,
注意,指定了CMD命令以后,docker container run命令就不能附加命令了(比如前面的/bin/bash),否則它會覆寫CMD命令,
CMD和ENTRYPOINT的區別在哪里?
-
CMD :指定容器啟動的時候要運行的命令,只有最后一個會生效
-
ENTRYPOINT :指定容器啟動的時候要運行的命令,命令可以追加
首先是使用CMD指令
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# cat dockerfile-cmd-test
FROM centos
CMD ["ls","-a"]
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest:1.0 .
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM centos
---> 300e315adb2f
Step 2/2 : CMD ["ls","-a"]
---> Running in 6d4d0112322f
Removing intermediate container 6d4d0112322f
---> b6ec5224d2ac
Successfully built b6ec5224d2ac
Successfully tagged cmdtest:1.0
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker run cmdtest:1.0
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
#由于使用的是 CMD指令,命令無追加,-l取代了原本的ls -a,而-l命令不存在所以報錯,
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker run cmdtest:1.0 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
可以看到追加命令-l 出現了報錯,
下面使用ENTRYPOINT來構建一個鏡像
#1.修改dockerfile檔案
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# cat dockerfile-cmd-test
FROM centos
ENTRYPOINT ["ls","-a"]
#2.構建鏡像
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker build -f dockerfile-cmd-test -t cmdtest:2.0 .
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM centos
---> 300e315adb2f
Step 2/2 : ENTRYPOINT ["ls","-a"]
---> Running in 61389c0c1967
Removing intermediate container 61389c0c1967
---> ac7b7e83ff88
Successfully built ac7b7e83ff88
Successfully tagged cmdtest:2.0
#3.運行鏡像
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker run cmdtest:2.0
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
#4.追加鏡像再次運行
[root@iZwz99sm8v95sckz8bd2c4Z dockerfile]# docker run cmdtest:2.0 -l
total 56
drwxr-xr-x 1 root root 4096 Jan 1 03:55 .
drwxr-xr-x 1 root root 4096 Jan 1 03:55 ..
-rwxr-xr-x 1 root root 0 Jan 1 03:55 .dockerenv
lrwxrwxrwx 1 root root 7 Nov 3 15:22 bin -> usr/bin
drwxr-xr-x 5 root root 340 Jan 1 03:55 dev
drwxr-xr-x 1 root root 4096 Jan 1 03:55 etc
drwxr-xr-x 2 root root 4096 Nov 3 15:22 home
lrwxrwxrwx 1 root root 7 Nov 3 15:22 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 15:22 lib64 -> usr/lib64
drwx------ 2 root root 4096 Dec 4 17:37 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 15:22 media
drwxr-xr-x 2 root root 4096 Nov 3 15:22 mnt
drwxr-xr-x 2 root root 4096 Nov 3 15:22 opt
dr-xr-xr-x 106 root root 0 Jan 1 03:55 proc
dr-xr-x--- 2 root root 4096 Dec 4 17:37 root
drwxr-xr-x 11 root root 4096 Dec 4 17:37 run
lrwxrwxrwx 1 root root 8 Nov 3 15:22 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 15:22 srv
dr-xr-xr-x 13 root root 0 Dec 29 15:41 sys
drwxrwxrwt 7 root root 4096 Dec 4 17:37 tmp
drwxr-xr-x 12 root root 4096 Dec 4 17:37 usr
drwxr-xr-x 20 root root 4096 Dec 4 17:37 var
5. 制作Tomcat鏡像并發布鏡像
5.1 制作Tomcat鏡像
1.準備鏡像檔案tomcat、jdk壓縮包
[root@iZwz99sm8v95sckz8bd2c4Z tomcat]# vi readme.txt
[root@iZwz99sm8v95sckz8bd2c4Z tomcat]# ll
total 200700
-rw-r--r-- 1 root root 10371538 Jan 1 16:11 apache-tomcat-8.5.55.tar.gz
-rw-r--r-- 1 root root 195132576 Jan 1 16:13 jdk-8u251-linux-x64.tar.gz
-rw-r--r-- 1 root root 20 Jan 1 16:14 readme.txt
2.撰寫dockerfile檔案,檔案名使用官方命名:Dockerfile ,build的時候會默認尋找當前目錄下的檔案,不需要使用-f引數指定
[root@iZwz99sm8v95sckz8bd2c4Z tomcat]# vim Dockerfile
[root@iZwz99sm8v95sckz8bd2c4Z tomcat]# cat Dockerfile
FROM centos
MAINTAINER ethan<1258398543@qq.com>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u251-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.55.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_251
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.55
ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.55
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-8.5.55/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.55/bin/logs/catalina.out
3.使用該Dockerfile構建鏡像
[root@iZwz99sm8v95sckz8bd2c4Z tomcat]# docker build -t diytomcat:1.0 .
4.啟動生成的鏡像,構建Tomcat容器.
這里設定了資料卷,宿主機的/home/dockerfile/tomcat/test對應該容器的/usr/local/apache-tomcat-8.5.55/webapps/test,這樣關于test專案的修復只需要在宿主機上修改就可以了,不需要進入到容器中修改,
[root@iZwz99sm8v95sckz8bd2c4Z tomcat]# docker run -d -p 8088:8080 --name diytomcat -v /home/dockerfile/tomcat/test:/usr/local/apache-tomcat-8.5.55/webapps/test diytomcat:1.0
5.在/home/dockerfile/tomcat/test的目錄下,新建index.html 測驗Tomcat是否能正常使用,
因為設定了卷掛載所以可以直接在宿主機中進行操作,
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<title>這是個標題</title>
</head>
<body>
<h1>這是一個一個簡單的HTML</h1>
<p>Hello World!</p>
</body>
</html>
6.訪問測驗,瀏覽器訪問查看是否能正常訪問

如果頁面顯示亂碼,就需要修改tomcat的server.xml檔案
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8" />
這里是添加了一個屬性:URIEncoding,將該屬性值設定為UTF-8,即可讓Tomcat(默認ISO-8859-1編碼)以UTF-8的編碼處理get請求,
5.2 發布鏡像到DockerHub
1.登錄https://hub.docker.com/ DockerHub官網進行注冊
2.進行登錄,docker login -u 用戶名
登錄命令
[root@iZwz99sm8v95sckz8bd2c4Z test]# docker login --help
Usage: docker login [OPTIONS] [SERVER]
Log in to a Docker registry.
If no server is specified, the default is defined by the daemon.
Options:
-p, --password string Password
--password-stdin Take the password from stdin
-u, --username string Usernames
3.使用docker push命令推送鏡像到DockerHub上的倉庫
[root@iZwz99sm8v95sckz8bd2c4Z test]# docker tag 0975df661526 ethanhuang824/diytomcat:1.0
[root@iZwz99sm8v95sckz8bd2c4Z test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
diytomcat 1.0 0975df661526 About an hour ago 688MB
ethanhuang824/diytomcat 1.0 0975df661526 About an hour ago 688MB
cmdtest 2.0 ac7b7e83ff88 6 hours ago 209MB
cmdtest 1.0 b6ec5224d2ac 6 hours ago 209MB
ethan/centos 1.0 1df90e6fd790 2 days ago 209MB
mytomcat 1.0 f189aac861de 3 days ago 653MB
mysql 5.7 f07dfa83b528 10 days ago 448MB
tomcat latest feba8d001e3f 2 weeks ago 649MB
nginx latest ae2feff98a0c 2 weeks ago 133MB
centos latest 300e315adb2f 3 weeks ago 209MB
elasticsearch 7.6.2 f29a1ee41030 9 months ago 791MB
[root@iZwz99sm8v95sckz8bd2c4Z test]# docker push ethanhuang824/diytomcat:1.0
因為push的時候,鏡像名前面需要加上用戶名(ethanhuang824是我的用戶名,如果用戶名不是當前登錄用戶則會拒絕push請求),所以需要使用命令docker tag 鏡像名 新的鏡像名復制出一份鏡像重新打個Tag,
5.3 發布鏡像到阿里云容器服務
1.登錄阿里云,找到容器鏡像服務
2.創建命名空間

4.與上面DockerHub的操作類似,按官方提供的操作指南操作即可,

.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/302232.html
標籤:其他
上一篇:2021-09-22
下一篇:《啊哈!演算法》的筆記
