Dockerfile
可想Nginx,tomcat,mysql 這些鏡像都是哪里來的?官方能寫,我們不能寫嗎?
我們要研究自己如何做一個鏡像,而且我們寫的微服務項目以及springboot打包上雲部署,Docker就是最方便的
微服務打包成鏡像,任何裝了Docker的地方,都可以下載使用,極其的方便。
流程:開發應用 ——> DockerFile ——> 打包為鏡像 ——> 上傳到倉庫(私有倉庫,公有倉庫)——> 下載鏡像 ——> 啟動運行
還可以方便移植!
什么是Dockerfile
dockerfile是用來構建Docker鏡像的構建文件,是由一系列命令和參數構成的腳本。
構建步驟:
1、編寫DockerFile文件
2、docker build 構建鏡像
3、docker run 運行鏡像
4、docker push 發布鏡像(DockerHub或阿里雲鏡像倉庫)
官方地址:https://hub.docker.com/
DockerFile構建過程
- 基礎知識:
1、每條保留字指令都必須為大寫字母且后面要跟隨至少一個參數
2、指令按照從上到下,順序執行
3、# 表示注釋
4、每條指令都會創建一個新的鏡像層,並對鏡像進行提交 - 流程:
1、docker從基礎鏡像運行一個容器
2、執行一條指令並對容器做出修改
3、執行類似 docker commit 的操作提交一個新的鏡像層
4、Docker再基於剛提交的鏡像運行一個新容器
5、執行dockerfile中的下一條指令直到所有指令都執行完成! - 說明:
從應用軟件的角度來看,DockerFile,docker鏡像與docker容器分別代表軟件的三個不同階段。
DockerFile:構建文件,定義了一切步驟,是軟件的原材料 (代碼)
Docker鏡像(images):則是通過Dockerfile構建生成的鏡像,是軟件的交付品 (.apk)
Docker容器:則是鏡像運行起來提供服務器 (客戶下載安裝執行)
DockerFile 面向開發,Docker鏡像成為交付標准,Docker容器則涉及部署與運維,三者缺一不可!
DockerFile:需要定義一個DockerFile,DockerFile定義了進程需要的一切東西。DockerFile涉及的內容包括執行代碼或者是文件、環境
變量、依賴包、運行時環境、動態鏈接庫、操作系統的發行版、服務進程和內核進程(當引用進行需要和系統服務和內核進程打交道,這時
需要考慮如何設計namespace的權限控制)等等。
Docker鏡像:在DockerFile 定義了一個文件之后,Docker build 時會產生一個Docker鏡像,當運行Docker 鏡像時,會真正開始提供服務;
Docker容器:容器是直接提供服務的。
DockerFile指令
文件配置關鍵字:
FROM #基礎鏡像,當前新鏡像是基於哪個鏡像的
MAINTAINER #鏡像是誰寫的 鏡像維護者的姓名混合郵箱地址
RUN #容器構建時需要運行的命令
EXPOSE #當前容器對外保留出的端口
ADD #將宿主機目錄下的文件拷貝進鏡像且ADD命令會自動處理URL和解壓tar壓縮包
WORKDIR #指定在創建容器后,終端默認登錄的進來工作目錄,一個落腳點
ENV #用來在構建鏡像過程中設置環境變量
COPY #類似ADD,拷貝文件和目錄到鏡像中!
VOLUME #掛載的目錄,容器數據卷,用於數據保存和持久化工作
CMD #指定一個容器啟動時要運行的命令,dockerFile中可以有多個CMD指令,但只有最后一個生效!
ENTRYPOINT #指定一個容器啟動時要運行的命令!可以追加命令,和CMD一樣
ONBUILD #當構建一個被繼承的DockerFile時運行命令,父鏡像在被子鏡像繼承后,父鏡像的ONBUILD被觸發
實戰測試
Docker Hub 中99% 的鏡像都是通過在base鏡像(FROM Scratch)中安裝和配置需要的軟件構建出來的
自定義一個centos
1,編寫DockerFile
我們自己的鏡像具備如下:登陸后的默認路徑、vim編輯器、查看網絡配置ifconfig支持
[root@zheng home]# mkdir dockerfile-test
[root@zheng home]# ls
ceshi dockerfile-test docker-test-volume f1
[root@zheng home]#
[root@zheng home]# vim mydockerfile-centos # 編輯文件
[root@zheng home]# cat mydockerfile-centos
FROM centos
MAINTAINER zzz<3208732554@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
2、通過文件構建鏡像
docker build -f dockerfile地址 -t 新鏡像名字:TAG .
docker build 命令最后有一個 .
"." 表示當前目錄
[root@zheng home]# docker build -f mydockerfile-centos -t mycentos:0.1 .
看到Successfully built 18888023317c
Successfully tagged mycentos:0.1 就成功了
3、運行
docker run -it 新鏡像名字:TAG
docker run -it mycentos:0.1
使用pwd,ifconfig,vim test
可以看到,我們自己的新鏡像已經支持 vim/ifconfig的命令,擴展OK!
4、列出鏡像地的變更歷史
docker history 鏡像名可以查看當前鏡像構建過程
CMD 和 ENTRYPOINT 的區別
兩個命令都是指定一個容器啟動時要運行的命令
CMD:Dockerfile 中可以有多個CMD 指令,但只有最后一個生效,CMD 會被 docker run 之后的參數替換!
ENTRYPOINT: docker run 之后的參數會被當做參數傳遞給 ENTRYPOINT,之后形成新的命令組合!
- 測試
CMD命令
# 1、構建dockerfile
[root@zheng home]# vim dockerfile-cmd-test
[root@zheng home]# cat dockerfile-cmd-test
FROM centos
CMD [ "ls", "-a" ]
# 2、build 鏡像
[root@zheng home]# docker build -f dockerfile-cmd-test -t cmdtest .
Sending build context to Docker daemon 22.02kB
Step 1/2 : FROM centos
---> 470671670cac
Step 2/2 : CMD [ "ls", "-a" ]
---> Running in a3072987de38
Removing intermediate container a3072987de38
---> 554bc6952657
Successfully built 554bc6952657
Successfully tagged cmdtest:latest
# 3、執行
[root@zheng home]# docker run 554bc6952657 #此時已經執行了 ls -a
.docker
bin
dev
# 4、追加一個命令;如果我們希望用 -l 列表展示信息,我們就需要加上 -l參數
[root@zheng home]# docker run cmdtest -l
docker: Error response from daemon: OCI runtime create failed:
container_linux.go:349: starting container process caused "exec: \"-l\":
executable file not found in $PATH": unknown.
# 問題:我們可以看到可執行文件找不到的報錯,executable file not found
# 之前我們說過,跟在鏡像名后面的是 command,運行時會替換 CMD 的默認值
# 因此這里的 -l 替換了原來的 CMD,而不是添加在原來的 ls -a 后面,而 -l 根本不是命令,所以自然找不到。
# 那么如果我們希望加入 -l 這參數,我們就必須重新完整的輸入這個命令:
docker run cmdtest ls -al
ENTRYPOINT命令
# 1、構建dockerfile
[root@zheng home]# vim dockerfile-entrypoint-test
[root@zheng home]# cat dockerfile-entrypoint-test
FROM centos
ENTRYPOINT [ "ls", "-a" ]
# 2、build 鏡像
[root@zheng home]# docker build -f dockerfile-entrypoint-test -t entrypointtest .
Sending build context to Docker daemon 23.04kB
Step 1/2 : FROM centos
---> 470671670cac
Step 2/2 : ENTRYPOINT [ "ls", "-a" ]
---> Running in bac4ae055630
Removing intermediate container bac4ae055630
---> ae07199f9144
Successfully built ae07199f9144
Successfully tagged entrypointtest:latest
# 3、執行
[root@zheng home]# docker run ae07199f9144
.dockerenv
bin
dev
# 4、測試-l參數,發現可以直接使用,這里就是一種追加,
我們可以明顯的知道 CMD 和 ENTRYPOINT 的區別了
[root@zheng home]# docker run entrypointtest -l
total 56
drwxr-xr-x 1 root root 4096 May 12 04:21 .
drwxr-xr-x 1 root root 4096 May 12 04:21 ..
自定義鏡像 tomcat
- 1、mkdir -p zheng/build/tomcat
- 2、在上目錄下 touch read.txt
- 3、將 JDK 和 tomcat 安裝的壓縮包拷貝進tomcat目錄下
(壓縮包網上找,apache-tomcat-9.0.22.tar.gz 和 jdk-8ull-linux-x64.tar.gz) - 4、在 /zheng/build/tomcat 目錄下新建一個Dockerfile文件
(官方命令為Dockerfile,當你build的時候會自己去尋找dockerfile,不用再去-f指定)
# vim Dockerfile
FROM centos
MAINTAINER zzz<3208732554@qq.com>
#把宿主機當前上下文的read.txt拷貝到容器/usr/local/路徑下
COPY read.txt /usr/local/cincontainer.txt
#把java與tomcat添加到容器中
ADD jdk-8u11-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.22.tar.gz /usr/local/
#安裝vim編輯器
RUN yum -y install vim
#設置工作訪問時候的WORKDIR路徑,登錄落腳點
ENV MYPATH /usr/local
WORKDIR $MYPATH
#配置java與tomcat環境變量
ENV JAVA_HOME /usr/local/jdk1.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器運行時監聽的端口
EXPOSE 8080
#啟動時運行tomcat
# ENTRYPOINT ["/usr/local/apache-tomcat-9.0.22/bin/startup.sh" ]
# CMD ["/usr/local/apache-tomcat-9.0.22/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F
/usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out
- 5、構建鏡像
[root@zheng tomcat]# docker build -t diytomcat .
.....
Successfully built ffdf6529937d
Successfully tagged diytomcat:latest # 構建完成
# 查看確定構建完畢!
[root@zheng tomcat]# docker images
REPOSITORY TAG IMAGE ID CREATED
SIZE
diytomcat latest ffdf6529937d 20 seconds ago
636MB
- 6,運行啟動 run
docker run -d -p 9090:8080 --name mydiytomcat -v
/home/zheng/build/tomcat/test:/usr/local/apache-tomcat- 9.0.22/webapps/test -v
/home/zheng/build/tomcat/tomcat9logs/:/usr/local/apache-tomcat-9.0.22/logs --privileged=true diytomcat
ll查看即有test和tomcat9logs
備注:Docker掛載主機目錄Docker訪問出現cannot open directory .: Permission denied
解決辦法:在掛載目錄后多加一個--privileged=true參數即可
- 7,驗證測試訪問!
curl localhost:9090
- 8,結合前面學習的容器卷將測試的web服務test發布
cd /home/zheng/build/tomcat/test
mkdir WEB-INF
cd WEB-INF/
vim web.xml
#寫入:(可百度搜)
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>test</display-name>
</web-app>
#保存退出
cd ..
vim a.jsp (html也可以)
#寫入:(可百度搜)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>hello,this is my images</title>
</head>
<body>
-------welcome-------
<%=" my docker tomcat,zzz666 "%>
<br>
<br>
<% System.out.println("-------my docker tomcat-------");%>
</body>
</html>
#保存退出
9,測試
curl local:9090/test/a.jsp
# 查看日志
[root@zheng tomcat]# cd tomcat9logs/
[root@zheng tomcat9logs]# ll
total 24
-rw-r----- 1 root root 6993 May 12 12:50 catalina.2020-05-12.log
-rw-r----- 1 root root 7024 May 12 12:53 catalina.out
-rw-r----- 1 root root 0 May 12 12:47 host-manager.2020-05-12.log
-rw-r----- 1 root root 408 May 12 12:47 localhost.2020-05-12.log
-rw-r----- 1 root root 150 May 12 12:53 localhost_access_log.2020-05-12.txt
-rw-r----- 1 root root 0 May 12 12:47 manager.2020-05-12.log
[root@zheng tomcat9logs]# cat catalina.out
....
-------my docker tomcat------- # 看到這即可看到別人訪問
發布鏡像
發布至DockerHub
注冊dockerhub https://hub.docker.com/signup,需要有一個賬號
注冊完成登錄即可
其注冊中心相關操作可查看鏈接(https://www.cnblogs.com/zhengyan6/p/16081439.html)
# 1、查看登錄命令
[root@zheng tomcat]# docker login --help
Usage: docker login [OPTIONS] [SERVER]
# 2、登錄
[root@zheng tomcat]# docker login -u 用戶名
Password:
WARNING! Your password will be stored unencrypted in
/root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-
store
Login Succeeded
# 3、將鏡像發布出去
[root@zheng tomcat]# docker push 自定義用戶名/diytomcat:1.0
The push refers to repository [docker.io/library/diytomcat]
0f02399c6fdf: Preparing
e79ea0c3a34e: Preparing
09281fa8fe38: Preparing
b56a902b0aef: Preparing
0683de282177: Preparing
# 拒絕:請求的資源訪問被拒絕
denied: requested access to the resource is denied
# 問題:本地鏡像名無帳號信息,解決加 tag即可
docker tag 251ca4419332 自定義用戶名/diytomcat:1.0
# 再 次 push, ok
[root@zheng tomcat]# docker push 自定義用戶名/diytomcat:1.0
The push refers to repository [docker.io/用戶名/diytomcat]
0f02399c6fdf: Pushing [========>
9.729MB/59.76MB
e79ea0c3a34e: Pushing [==========>
3.188MB/15.41MB
09281fa8fe38: Pushing [>
3.823MB/324MB
b56a902b0aef: Pushed
0683de282177: Pushing [=>
5.997MB/237.1MB
#提交的時候也是按照鏡像的層級來進行提交的
發布至阿里雲鏡像服務
1、登錄阿里雲
2、找到容器鏡像服務
3、創建命名空間
4、創建鏡像倉庫
5、點擊進入這個鏡像倉庫,可以看到所有的信息
6、測試推送發布
具體步驟查看官方文檔
# (1)、登錄阿里雲
[root@zheng tomcat]# docker login --username=18225148644 registry.cn-
beijing.aliyuncs.com
Password:
WARNING! Your password will be stored unencrypted in
/root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-
store
Login Succeeded
# (2)、設置 tag
docker tag [ImageId] registry.cn-beijing.aliyuncs.com/命名空間名稱/zheng-test:[鏡像版本號]
[root@zheng tomcat]# docker tag 251ca4419332 registry.cn-
beijing.aliyuncs.com/命名空間名稱/zheng-test:v1.0
# (3)、推送命令
docker push registry.cn-beijing.aliyuncs.com/命名空間名稱/zheng-
test:[鏡像版本號]
[root@zheng tomcat]# docker push registry.cn-
beijing.aliyuncs.com/命名空間名稱/zheng-test:v1.0
7、在阿里雲鏡像倉庫查看效果!
總結
全流程圖