构建自定义镜像

docker目前镜像的制作有俩种方法:

  • 基于Docker Commit制作镜像
  • 基于dockerfile制作镜像,Dockerfile方式为主流的制作镜像方式

Commit构建镜像

使用 commit 构建自定义镜像:就是将 docker 容器构建成 docker 镜像。

1
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
  • 参数说明
    • -a 标注作者
    • -m 说明注释
  • 示例
1
docker commit -a "jye" -m "这是一个tomcat" tomcat-8080 tomcat:8080

Commit构建镜像

Dockerfile构建镜像

dockerfile构建自定义镜像示例

  • dockerfile
1
2
3
4
5
6
7
# this is a dockerfile
FROM centos:7
MAINTAINER XD 123456@qq.com
RUN echo "正在构建镜像!!!"
WORKDIR /home/xdclass
COPY 123.txt /home/xdclass
RUN yum install -y net-tools
  • 目录截图如下

Dockerfile目录结构

  • 在当前路径下,构建:docker build -t mycentos:v1 ./
  • 查看:docker images

构建结果

镜像分层结构剖析

镜像分层结构

  • 总结:
    • 共享资源
    • 对容器的任何改动都是发生容器层
    • 容器层是可写可读,而镜像层只读
    • 每次执行命令都是从容器层开始,自上而下查找
  • 查看docker镜像构建过程命令
1
2
3
4
5
6
docker history <镜像名称>:<TAG>
#或者
docker history <镜像ID>

# 示例
docker history mycentos:v1

镜像构建历史

Dockerfile基础指令

  • FROM:基于哪个镜像
  • MAINTAINER:注明作者
  • COPY:复制文件进入镜像(只能用相对路径,不能用绝对路径)
  • ADD:复制文件进入镜像(假如文件是.tar.gz文件会解压)
  • WORKDIR:指定工作目录,假如路径不存在会创建路径
  • ENV:设置环境变量
  • EXPOSE:暴露容器端口
  • RUN:在构建镜像的时候执行,作用于镜像层面
  • ENTRYPOINT:在容器启动的时候执行,作用于容器层,dockerfile里有多条时只允许执行最后一条
  • CMD:在容器启动的时候执行,作用于容器层,dockerfile里有多条时只允许执行最后一条,容器启动后执行默认的命令或者参数,允许被修改

命令格式:

  • shell命令格式:RUN yum install -y net-tools
  • exec命令格式:RUN [ "yum","install" ,"-y" ,"net-tools"]

Dockerfile构建实战

Dockerfile构建JAVA网站镜像

本地安装jdk验证是否成功

  • 将jdk包上传到服务器,解压到 /usr/local/jdk
  • 本地宿主机配置jdk,vi /etc/profile(在最后一行添加)
1
2
3
4
export JAVA_HOME=/usr/local/jdk
export JRE_HOME=$JAVA_HOME/jre
export CLASSPATH=$JAVA_HOME/lib:$JRE_HOME/lib:$CLASSPATH
export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH
  • source /etc/profile
  • 检验:java -version

JDK安装验证

构建JAVA网站镜像

  • vi dockerfile
1
2
3
4
5
6
7
8
9
10
11
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 build -t tomcat:8.5 ./
  • 启动容器
1
docker run -itd -p 8089:8080 -v /data/images/tomcat/ROOT:/usr/local/tomcat/webapps/ROOT tomcat:8.5 /bin/bash
  • /data/images/tomcat/ROOT 目录下,执行 echo 'hello wrold' > index.html
  • 打开浏览器访问虚拟机地址

JAVA网站访问

Dockerfile构建nginx镜像

构建nginx镜像

  • dockerfile
1
2
3
4
5
FROM centos:7
ADD nginx-1.16.0.tar.gz /usr/local
COPY nginx_install.sh /usr/local
RUN sh /usr/local/nginx_install.sh
EXPOSE 80
  • 安装nginx的shell脚本
1
2
3
4
#!/bin/bash
yum install -y gcc gcc-c++ make pcre pcre-devel zlib zlib-devel
cd /usr/local/nginx-1.16.0
./configure --prefix=/usr/local/nginx && make && make install
  • 构建:docker build -t mycentos:nginx ./
  • Nginx镜像启动注意
    • 在容器里nginx是以daemon方式启动,退出容器时,nginx程序也会随着停止:/usr/local/nginx/sbin/nginx
    • 使用前台方式永久运行:/usr/local/nginx/sbin/nginx -g "daemon off;"
  • 启动容器
1
docker run -itd -p 80:80 mycentos:nginx /usr/local/nginx/sbin/nginx -g "daemon off;"

Volume数据共享

dockerfile

1
2
FROM centos:7
VOLUME ["/usr/local"]
  • 注意:在dockerfile里设置volume是无法修改宿主机的挂载路径的

使用volume容器共享创建nginx集群

  • 使用 --volumes-from 实现容器与容器之间volume共享
  • 创建nginx1
1
docker run -itd -p 8080:80 -v /usr/local/nginx/html:/usr/local/nginx/html --name nginx1 mycentos:nginx /usr/local/nginx/sbin/nginx -g "daemon off;"
  • 创建nginx2
1
docker run -itd -p 8081:80 --volumes-from nginx1 --name nginx2 mycentos:nginx /usr/local/nginx/sbin/nginx -g "daemon off;"
  • 创建nginx3
1
docker run -itd -p 8082:80 --volumes-from nginx1 --name nginx3 mycentos:nginx /usr/local/nginx/sbin/nginx -g "daemon off;"
  • /usr/local/nginx/html/index.html 进行修改
  • 打开浏览器进行访问测试,使用 docker inspect <容器ID> 可以查看详细的挂载信息

Dockerfile构建redis镜像

构建redis镜像

  • 编写redis编译安装shell脚本 redis_install.sh
1
2
3
4
5
6
7
8
#!/bin/bash
yum install -y gcc gcc-c++ make openssl openssl-devel
cd /home/redis-4.0.9
make && make PREFIX=/usr/local/redis install
mkdir -p /usr/local/redis/conf/
cp /home/redis-4.0.9/redis.conf /usr/local/redis/conf/
sed -i '69s/127.0.0.1/0.0.0.0/' /usr/local/redis/conf/redis.conf
sed -i '88s/protected-mode yes/protected-mode no/' /usr/local/redis/conf/redis.conf
  • dockerfile
1
2
3
4
5
FROM centos:7
ADD redis-4.0.9.tar.gz /home
COPY redis_install.sh /home
RUN sh /home/redis_install.sh
ENTRYPOINT /usr/local/redis/bin/redis-server /usr/local/redis/conf/redis.conf
  • 测试redis:
    • 启动容器:docker run -itd -p 6380:6379 mycentos:redis(6380是宿主机端口,6379是容器的端口)
    • 进入容器:docker exec -it 9b402baeaba7 /bin/bash
    • 宿主机连接redis:/usr/local/redis/bin/redis-cli -p 6380
    • 验证:
1
2
3
4
5
6
[root@localhost home]# /usr/local/redis/bin/redis-cli -p 6380
127.0.0.1:6380> set name xdclass
OK
127.0.0.1:6380> get name
"xdclass"
127.0.0.1:6380>

Dockerfile构建SpringBoot镜像

  • dockerfile
1
2
3
4
FROM java:8
MAINTAINER www.junyie.com
ADD springboot.jar app.jar
CMD java -jar app.jar
  • 构建:docker build -t app:v1 ./