為什么要構建自定義的鏡像?
- 官方鏡像使用的都是默認配置,比如mysql容器使用的官網的mysql,需要自己修改mysql的配置文件、設置用戶名和密碼
- 部署服務,比如在tomcat容器中部署用戶服務,把部署好的tomcat容器打包為一個鏡像,部署用戶服務集群時,直接拉取這個鏡像即可,不需要一個一個部署用戶服務
docker制作鏡像的2種方式
- Docker Commit
- dockerfile 主流方式
Docker Commit方式制作鏡像
修改好容器之后:
docker commit -a "chy xxxxxxx@qq.com" -m "做了哪些修改" id|name imageName:version
-a指定作者信息,-m指定鏡像信息,一般是說明做了哪些修改、這個鏡像的功能用途。如果值是不帶空格的字符串,可以不引,帶了空格就要引起來。
-a、-m均可選,如果配置了,使用docker inspect id|name 查看該鏡像創建的容器的信息時會看到這2個參數的值
id|name指定要使用哪個容器制作鏡像
imageName:version指定鏡像的名稱、版本號,版本號任意,可以是test、v1這種字符串,也可以是1、1.1這種數字
dockerfile方式制作鏡像
(1)vim dockerfile #文件名必須是dockerfile
(2)在里面寫指令:
FROM imageName:version
MAINTAINER chy xxxxxxx@qq.com
RUN each "image is building..."
(3)docker build -t mytomcat:v1 . #構建鏡像,mytomcat:v1是自定義的鏡像名稱、版本號,后面是dockerfile文件所在目錄,.表示當前目錄
dockerfile常用指令
FROM imageName:version #基於哪個鏡像構建
MAINTAINER chy xxxxx@qq.com #作者信息
COPY 1.txt /usr/local/ #將文件從宿主機復制到鏡像,宿主機的路徑寫相對路徑,鏡像的路徑寫絕對路徑
ADD 1.txt /usr/local/ #和COPY相似,不同點:如果是.tar.gz文件,ADD復制之后會自動解壓
WORKDIR /usr/local/tomcat 指定應用的工作目錄,如果此目錄不存在,會自動創建
ENV JAVA_HOME=/usr/local/jdk #設置環境變量
EXPOSE 8080 #開放防火牆端口
RUN echo "image is building..." #作用於鏡像層面,在構建鏡像時執行;如果有多條RUN命令,都會執行
ENTRYPOINT yum install xxx -y #作用於容器層,在容器啟動的時候執行;如果有多條ENTRYPOINT命令,只執行最后一條ENTRYPOINT命令
CMD yum install xxx -y #作用於容器層,在容器啟動的時候執行;如果有多條CMD命令,只執行最后一條CMD命令。
ENTRYPOINT、CMD的區別:
CMD可以在容器啟動時傳遞參數,參數是默認參數,可以被覆蓋,ENTRYPOINT不可以傳參數。
如果要用CMD傳參數,需要搭配ENTRYPOINT使用,示例:
CMD ["-ef"]
ENTRYPOINT ["ps"]
docker run或docker start 啟動容器時,可以向ps命令傳遞參數,eg. docker start id|name -ef
比如傳遞-ef,比如傳遞-aux,傳遞的參數會覆蓋默認的-ef,如果不向ps命令傳遞參數,使用默認的-ef
命令格式
RUN、ENTRYPOINT、CMD運行的命令可以是下面的2種格式
- shell命令格式 RUN echo "....",RUN yum install xxx -y
- exec命令格式 RUN [ "yum","install" ,"xxx" ,"-y"] 命令寫成字符串數組
Docker Commit方式要啟動鏡像的一個容器,對容器進行修改,打包為鏡像,再停止、刪除這個容器,頗為麻煩;
dockerfile是在宿主機上新建文件dockerfile,在dockerfile文件中寫指令,不需要操作容器,更簡便,用得也更多;
但dockerfile難度也要大得多,比如制作redis鏡像,在dockerfile中修改redis conf中的配置項,記住配置項的名字還是有點麻煩的。
創建鏡像時可以基於官方鏡像創建,也可以基於CentOS的進行進行創建。比如tomcat,
- 可以在tomcat官方鏡像的基礎上改,鏡像體積相對小一些,進入容器后只能執行一些簡單的命令,比如文件的增刪改;不能執行yum install xxx之類的命令
- 也可以在CentOS鏡像的基礎上改,自己裝jdk、tomcat、配置環境變量,得到的鏡像就是一個完整的CentOS系統
構建自定義的tomcat鏡像
tomcat很常用,包含了jdk環境,運行java -jar、部署war都行。
官方的tomcat鏡像包含了jdk環境,但自帶的jdk環境往往不符合需求,且tomcat本身的配置也需要修改一下,所以tomcat的鏡像一般都要自己構建。
比如docker inspect tomcat:9 | grep jdk 看到tomcat9自帶的是jdk11,我們需要的是jdk8。
dockerfile:
FROM centos:7 ADD jdk-8u211-linux-x64.tar.gz /usr/local RUN mv /usr/local/jdk1.8.0_211 /usr/local/jdk ENV JAVA_HOME=/usr/local/jdk ENV JRE_HOME=$JAVA_HOME/jre ENV CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH ENV PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH ADD apache-tomcat-8.5.35.tar.gz /usr/local RUN mv /usr/local/apache-tomcat-8.5.35 /usr/local/tomcat EXPOSE 8080 ENTRYPOINT ["/usr/local/tomcat/bin/catalina.sh","run"]
在docker容器中使用startup.sh啟動tomcat,tomcat剛啟動就會自動退出,需要使用catalina.sh來啟動tomcat
啟動容器時需要將容器端口映射到宿主機端口:
docker run -itd -p 8080:8080 -v /usr/local/tomcat/tomcat1:/usr/local/tomcat/webapps --name=tomcat1
-p指定端口映射,宿主機端口:容器端口,2個端口可以不一致,訪問時以宿主機的ip:port來訪問
-v指定容器掛載
部署集群時,不推薦把集群節點都部署在同一個宿主機上,雖然容器之間是隔離的,容器故障時互不影響,但宿主機故障時整個集群就不可用了。
構建自定義的mysql鏡像
https://hub.docker.com/_/mysql