到目前爲止,已經介紹瞭如何啓動一個簡單的容器,並與之進行交互。同時也知道了如何中止、重啓以及刪除一個容器。接下來將展現一個Linux Web服務示例。html
筆者將介紹經過docker command 以及 Dockerfile方式部署Linux Web服務。java
Linux中主流的web服務有nginx、tomcat、apache、weblogic。由於筆者負責的java項目,這裏web服務以tomcat爲示例。nginx
在該示例中,會使用到tomcat鏡像。這個鏡像會在"8888"端口啓動一個至關簡單爲Web服務。web
這一節只部署web服務,不會講解容器共享數據卷存儲、容器網絡等要點,後續在作相關說明。docker
[root@doc03 ~]# docker run -itd --name tomcat-v1.0 -p 8888:8080 tomcat Unable to find image 'tomcat:latest' locally .... Digest: sha256:a655be865e9f62d6d2ed3823c7382a2d77d0a034eb17714bbf2a514c3f620717 Status: Downloaded newer image for tomcat:latest 264ba249d3b6ce9eb0174a57f1f00cfc50f2417a30173ab3c02062815d427647
● -pshell
Docker物理機的端口映射到容器內,端口信息按照 "host-port:container-port"格式顯示,這一點很重要apache
將Docker物理機的"8888"端口映射到容器內的"8080"(tomcat默認)端口。這意味着當有流量訪問主機的"8888"端口的時候,流量會直接映射到容器內的"8080"端口tomcat
[root@doc03 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 264ba249d3b6 tomcat "catalina.sh run" 3 minutes ago Up 3 minutes 0.0.0.0:8888->8080/tcp tomcat-v1.0
當host不指名時,默認使用"0.0.0.0"全部地址bash
獲取請求本機http://$ip:8888的http狀態碼網絡
[root@doc03 ~]# curl -o /dev/null -s -w %{http_code} http://10.125.7.74:8888 && echo "" 404
http狀態碼404通常是2種狀況
● 請求的地址不存在(tomcat默認項目路徑爲webapps/ROOT)
● 請求的地址沒有權限訪問
[root@doc03 ~]# docker exec -it tomcat-v1.0 /bin/bash root@264ba249d3b6:/usr/local/tomcat# cd webapps root@264ba249d3b6:/usr/local/tomcat/webapps# ls root@264ba249d3b6:/usr/local/tomcat/webapps
發現"webapps"下沒有任何項目路徑
root@264ba249d3b6:/usr/local/tomcat/webapps# mkdir -pm 755 ROOT root@264ba249d3b6:/usr/local/tomcat/webapps# echo "Hi, Docker Daemon" > ROOT/index.html
建立Web首頁,注意目錄、文件權限
[root@doc03 ~]# curl -o /dev/null -s -w %{http_code} http://10.125.7.74:8888 200 [root@doc03 ~]# curl http://10.125.7.74:8888 Hi, Docker Daemon
http狀態碼爲200且主頁地址正常訪問
筆者作過一個嘗試,將"tomcat-v1.0"容器導出爲鏡像,再基於此鏡像建立2個容器"tomcat-v1.1"、"tomcat-v1.2",啓動時拋出"沒法找到java環境"致使啓動失敗。
"export" 和 "import" 導出的是一個容器當時的快照, 不是鏡像自己, 也就是說沒有鏡像分層(依賴鏡像)。快照文件將丟棄全部的歷史記錄和元數據信息,例如工做目錄(workdir)、啓動命令(entrypoint)、歷史提交信息(commit)等都會丟失。因此啓動時會拋出"Neither the JAVA_HOME nor the JRE_HOME environment variable is defined"
對此筆者有個疑問,"import"的做用是什麼?nginx、apache的Web服務是否會受此限制,後續試驗一下。
相比於"save"、"load",最大的區別於如下四點:
● docker save 保存的是鏡像(image),docker export 保存的是容器(container)
● docker load 用來載入鏡像包,docker import 用來載入容器包,但二者都會恢復爲鏡像
● docker load 不能對載入的鏡像重命名,而 docker import 能夠爲鏡像指定新名稱
● docker load 保存鏡像完整記錄,包含分層鏡像,因此文件體積會比docker export的更大一些
Dockerfile 是一個用來構建鏡像的文本文件,文本內容包含了一條條構建鏡像所需的指令和說明。
這裏僅講解如何運行 Dockerfile 文件來定製一個鏡像,具體 Dockerfile 文件內指令詳解,將在下一節中介紹,這裏你只要知道構建的流程便可。
[root@doc03 ~]# cat tomcat_dockerfile FROM tomcat MAINTAINER wangtianci<13623650548@163.com> WORKDIR /usr/local/tomcat RUN mkdir -pm 755 ./webapps/ROOT COPY ./index.html ./webapps/ROOT EXPOSE 8080 CMD ["./bin/catalina.sh", "run"] [root@doc03 ~]# cat index.html Dcoerkfile make image
● FROM
下載目標鏡像,每一個Dockerfile文件一行都是FORM指令,當前應用的剩餘內容會做爲新增鏡像層添加到基礎鏡像層之上
● MAINTAINER
做者信息,做爲鏡像的元數據信息,不構建鏡像
● WORKDIR
爲Dockerfile中還沒有執行的指令設置工做目錄,該目錄與鏡像相關,而且會做爲元數據記錄到鏡像配置中,但不會建立新的鏡像層,筆者理解相似於家目錄
● RUN
執行shell command,進入容器後執行的命令
● COPY
拷貝文件,host_file_path:container_file_path,將應用相關文件從構建上下文複製到了當前鏡像中
筆者測試時 "host_file_path"文件必須與dockerfile文件在同一目錄
● EXPOSE
指定容器內監聽的tcp端口,做爲元數據被保存下來,不會產生新的鏡像層
● CMD
爲啓動的容器指定默認要運行的程序,程序運行結束,容器也就結束。CMD 指令指定的程序可被 docker run 命令行參數中指定要運行的程序所覆蓋。若是 Dockerfile 中若是存在多個 CMD 指令,僅最後一個生效
● 鏡像分層圖能夠理解以下
其餘參數可參考
https://www.runoob.com/docker/docker-dockerfile.html
[root@doc03 ~]# docker build -f /root/tomcat_dockerfile -t tomcat_dockerfile:v1 . Sending build context to Docker daemon 216.6MB Step 1/7 : FROM tomcat ---> bd431ca8553c Step 2/7 : MAINTAINER wangtianci<13623650548@163.com> ---> Running in 4683fbd16a41 Removing intermediate container 4683fbd16a41 ---> ee23a3dedb31 Step 3/7 : WORKDIR /usr/local/tomcat ---> Running in 665b3f0e6185 Removing intermediate container 665b3f0e6185 ---> d297b25ac4d8 Step 4/7 : RUN mkdir -pm 755 ./webapps/ROOT ---> Running in 055a60198fcf Removing intermediate container 055a60198fcf ---> 5a00a1e6bb7d Step 5/7 : COPY ./index.html ./webapps/ROOT ---> ceede2153756 Step 6/7 : EXPOSE 8080 ---> Running in a94bc7fcbf1b Removing intermediate container a94bc7fcbf1b ---> d89243858b42 Step 7/7 : CMD ["./bin/catalina.sh", "run"] ---> Running in 7358b3ea7e21 Removing intermediate container 7358b3ea7e21 ---> 5af688cf0cdd Successfully built 5af688cf0cdd Successfully tagged tomcat_dockerfile:v1
● -f
指明Dockerfile文件路徑,能夠是絕對路徑或者是目標目錄
● -t
制定鏡像生成的標籤,格式爲<REPOSITORY>:<TAG>
● .
注意末尾的".",這個很是重要,必定要在目錄最後包含這個"."。命令最後的"."表示Dockerfile在進行構建的時候,使用當前目錄做爲構建上下文
[root@doc03 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE tomcat_dockerfile v1 5af688cf0cdd 49 seconds ago 667MB tomcat_cp tomcat_v1.0 1fe040a4a939 20 hours ago 659MB tomcat latest bd431ca8553c 5 days ago 667MB [root@doc03 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 264ba249d3b6 tomcat "catalina.sh run" 20 hours ago Up 20 hours 0.0.0.0:8888->8080/tcp tomcat-v1.0
[root@doc03 ~]# docker run -d --name tomcat_dockerfile-v1.0 -p 9999:8080 tomcat_dockerfile:v1 13d20727b68c95da939416943b120e09d8b2a900e5d3bf447a9fe9e58a602f81 [root@doc03 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 13d20727b68c tomcat_dockerfile:v1 "./bin/catalina.sh r…" 3 seconds ago Up 1 second 0.0.0.0:9999->8080/tcp tomcat_dockerfile-v1.0 264ba249d3b6 tomcat "catalina.sh run" 20 hours ago Up 20 hours 0.0.0.0:8888->8080/tcp tomcat-v1.0 [root@doc03 ~]# curl http://10.125.7.74:9999 Dcoerkfile make image