本章概述
- 手动制作yum版nginx镜像
- DockerFile 制作编译版 nginx 1.16.1 镜像
- 自定义tomcat业务镜像
- 构建haproxy镜像
- 基于官方 alpine 基础镜像制作自定义镜像
- 基于官方 Ubuntu 基础镜像制作自定义镜像
- 本地镜像上传至官方 docker 仓库
- 本地镜像上传到阿里云镜像仓库
Docker 镜像有没有内核?
从镜像大小上面来说,一个比较小的镜像只有十几 MB,而内核文件需要一百多兆, 因此镜像里面是没有内核的,镜像在被启动为容器后将直接使用宿主机的内核,而镜像本身则只提供相应的 rootfs,即系统正常运行所必须的用户空间的文件系统,比如/dev/,/proc,/bin,/etc 等目录,所以容器当中基本是没有/boot目录的,而/boot 当中保存的就是与内核相关的文件和目录。
为什么没有内核?
由于容器启动和运行过程中是直接使用了宿主机的内核,所以没有直接调用过物理硬件,所以也不会涉及到硬件驱动,因此也用不上内核和驱动,另外有内核的那是虚拟机。
制作镜像需要先熟悉以下命令:
docker commit #将一个修改过的容器提交为一个镜像,不过很少用这种方式制作镜像
Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
Create a new image from a container's changes
Aliases:
docker container commit, docker commit
Options:
-a, --author string #指定镜像制作者,一般会留下作者邮箱,便于联系作者
-c, --change list #在镜像制作过程中可以执行dockerfile中的一些指令,dockerfile是另一种指定镜像的方式,后面会提到
-m, --message string #提交信息,类似于描述信息
-p, --pause #在提交镜像时暂时容器运行,避免在提交镜像过程中,容器产生新的数据,该选项默认启用,即使不加该选项,也会暂停容器运行
2.1 手动制作yum版nginx镜像
注意:制作镜像一般是通过dockerfile的方式进行,手动制作镜像的方式并不常用,这里了解即可
Docker 制作类似于虚拟机的模板制作,即按照公司的实际业务务求将需要安装的软件、相关配置等基础环境配置完成,然后将虚拟机再提交为模板,最后再批量从模板批量创建新的虚拟机,这样可以极大的简化业务中相同环境的虚拟机运行环境的部署工作,Docker 的镜像制作分为手动制作和自动制作(基于DockerFile),企业通常都是基于 Dockerfile 制作镜像,其中手动制作镜像步骤具体如下:
2.1.1 下载基础镜像并初始化系统
基于某个基础镜像之上重新制作,因此需要先有一个基础镜像,本次使用官方提供的 centos 镜像为基础:
root@docker_server01:~# docker pull centos:7.9.2009 #使用centos7.9.2009版本的镜像作为基础镜像
root@docker_server01:~# docker run -it centos:7.9.2009 /bin/bash #拉起镜像
#以下命令在容器内执行
[root@b7e7763fbace /]# yum -y install wget
[root@b7e7763fbace /]# cd /etc/yum.repos.d/
[root@b7e7763fbace yum.repos.d]# rm -rf ./* #更改 yum 源
[root@b7e7763fbace yum.repos.d]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
[root@b7e7763fbace yum.repos.d]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
2.1.2 yum安装并配置nginx
1、安装nginx
[root@b7e7763fbace yum.repos.d]# yum install nginx -y #安装nginx
[root@b7e7763fbace yum.repos.d]# yum install -y vim wget pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop #安装常用命令
2、关闭 nginx 后台运行
[root@b7e7763fbace yum.repos.d]# vim /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
daemon off; #关闭nginx后台运行,处于前台运行
3、自定义 web 页面
[root@b7e7763fbace yum.repos.d]# rm -rf /usr/share/nginx/html/index.html
[root@b7e7763fbace yum.repos.d]# echo "Docker Yum Nginx"> /usr/share/nginx/html/index.html #自定义 web 界面内容
2.1.3 提交为镜像
以下命令在宿主机上执行
1、在宿主机基于容器 ID 提交为镜像
先获取修改的容器ID,然后根据容器ID,把容器提交为镜像
root@docker_server01:~# docker ps #获取容器ID
root@docker_server01:~# docker commit -a "957464230@qq.com" -m "nginx yum v1" --change="EXPOSE 80 443" b7e7763fbace centos-nginx:v1 # b7e7763fbace是指上一步获取到的容id
注意:--change="EXPOSE 80 443"中的EXPOSE 80 443是指声明要暴露80和443端口,这里只是声明,真正暴露端口需要在docker创建容器时,使用-p参数来指定
查看本地镜像:
2.1.4 带tag的镜像提交
提交的时候标记 tag 号:
标记 tag 号,在生产环境比较常用,后期可以根据 tag 标记创建不同版本的镜像以及创建不同版本的容器。
root@docker_server01:~# docker commit -m "nginx image" b7e7763fbace jack/centos-nginx:v1 #这里的v1就是镜像tag号,可以通过修改tag号区分不同的镜像版本
查看本地镜像
2.1.5 用制作的镜像创建容器
1、用自制镜像创建容器
docker run -d -p 80:80 --name my-centos-nginx jack/centos-nginx:v1 /usr/sbin/nginx
备注: -name 是指定容器的名称,-d 是后台运行,-p 是端口映射,jack/centos-nginx:v1 是 xx 仓库下的 xx 镜像的 v1 版本,可以不加版本,不加版本默认是使用latest,最后面的 nginx 是运行的命令,即镜像里面要运行一个 nginx 命令。
2、查看容器
3、验证:
通过浏览器访问nginx服务,可以看到nginx返回的内容就是自定义的web页面内容
2.2 DockerFile 制作编译版 nginx 1.16.1 镜像
DockerFile 可以说是一种可以被 Docker 程序解释的脚本,DockerFile 是由一条条的命令组成的,每条命令对应 linux 下面的一条命令,Docker 程序将这些 DockerFile 指令再翻译成真正的 linux 命令,其有自己的书写方式和支持的命令,Docker 程序读取 DockerFile 并根据指令生成 Docker 镜像,相比手动制作镜像的方式,DockerFile 更能直观的展示镜像是怎么产生的,有了写好的各种各样 DockerFile 文件,当后期某个镜像有额外的需求时,只要在之前的DockerFile 添加或者修改相应的操作即可重新生成新的 Docke 镜像,避免了重复手动制作镜像的麻烦,具体如下:
https://docs.docker.com/engine/reference/builder/
2.2.1 Dockerfile指令用法
Dockerfile常用指令:FROM、LABEL、MAINTANIER 、ADD、COPY、ENV、EXPOSE、USER、VOLUME、WORKDIR、RUN、STOPSIGNAL、CMD、ENTRYPOINT
FROM #用于指定基本镜像(父镜像),是dockerfile文件中除注释行之外的第一行,用于为映像文件构建过程指定基准镜像,后续的指令运行于此基准镜像所提供的运行环境
LABEL #设置镜像的属性标签,可以添加更多不属于镜像自身的信息(如镜像制作时间,制作者信息)
语法:LABEL <key>=<value> <key>=<value>
示例:
LABEL maintainer= "jack 123456@qq.com"
LABEL version= "2.1.2"
MAINTANIER #用于让Dockerfile制作者提供本人的详细信息(该指令即将被丢弃,不推荐使用)
示例: MAINTAINER "jack 123456@qq.com"
ADD #用于把添加宿主机本地的文件、目录、压缩包等资源到镜像中
COPY #用于把添加宿主机本地的文件、目录、压缩包等资源到镜像中
ADD和COPY这两个指令功能类似,二者的区别在于,ADD会自动解压tar.gz格式的压缩包(但不会自动解压zip格式的压缩包),COPY不会解压任何格式的压缩包
ENV #用于为镜像定义所需的环境变量,可以被Dockerfile文件中位于其后的其它指令(如ENV、ADD、COPY等)所调用
EXPOSE #用于声明容器映射到宿主机的端口,这里只用于说明,实际的端口映射是在创建容器时通过docker命令的-p参数指定
USER #指定运行操作的用户,存在先后关系,如果指定了某用户,那该指令后的程序都会以该用户运行,如果不指定,则默认以root用户运行
VOLUME #定义存储卷,指定后会自动创建目录挂载网络存储或者宿主机的目录到容器中,避免数据丢失,可一次性创建多个
语法:VLOUME [“/data1”,”/data2”,”/data3”]
WORKDIR #指定工作目录,用于切换目录,类似于cd
RUN #用于执行SHELL命令(如果是python或go命令则不能运行),必须以非交互式的方式运行
STOPSIGNAL #终止信号,一般不用指定
CMD #镜像启用为一个容器时的默认命令或脚本(容器启动后,需要一个进程在前台运行,这个进程可以通过命令、服务进程或脚本启动)
以运行nginx容器为例:
命令
CMD [“tail”,“-f”,“/etc/hosts”] #只需一个进程处于前台运行保持容器不退出
服务进程
CMD [“nginx”,“-g”,“daemon off;”] #该命令是指将nginx进程后台关闭,处于前台运行
脚本
CMD [“/apps/nginx/run_nginx.sh”] #/apps/nginx/run_nginx.sh是指运行nginx进程脚本,在脚本中可以编写运行nignx进程的命令。使用脚本启动时,需要将该脚本复制到容器中,且该脚本必须具有执行权限(chmod +x run_nginx.sh),否则运行容器时会提示脚本没有执行权限
ENTRYPOINT #类似CMD指令的功能,用于为容器指定默认运行程序
如果在dockerfile文件中即有ENTRYPOINT和CMD,则CMD指令会被作为ENTRYPOINT的参数传递给ENTRYPOINT执行
示例:让nginx处于前台运行的命令是:nginx -g daemon off
CMD指令的写法是:
CMD ["nginx","-g","daemon off;"]
ENTRYPOINT和CMD混用,可以写为:
ENTRYPOINT ["nginx"]
CMD ["-g","daemon off;"]
知识延伸
1、使用dockerfile制作镜像,需要创建Dockerfile文件,这是因为使用docker build命令构建镜像时,会在当前目录下查找Dockerfile文件,根据该文件构建镜像
2、docker制作镜像有两个阶段:
(1)docker build 从Dockerfile制作为镜像
(2)docker run 从镜像文件启动为容器
3、在制作镜像过程中,会启动一个临时的容器进行相应的指令操作,操作完成后再把此容器转换为 image镜像。
2.2.2 准备工作
1、创建存放镜像的目录
目录结构按照业务类型或系统类型等方式划分,方便后期镜像比较多的时候进行分类。
root@docker_server01:~# cd /opt
root@docker_server01:~# mkdir dockerfile/{web/{nginx,tomcat,jdk,apache},system/{centos,ubuntu,redhat}} -pv
查看目录结构:
在opt目录下创建dockerfile目录用于存放所有的镜像,然后创建system目录和web目录
system目录用于存放基础镜像,然后根据不同的操作系统,创建相应的目录
web目录用于存放web服务类镜像,然后根据不同类型,创建相应的目录
2、下载centos 7.9.2009镜像
[root@docker-server1 nginx]# docker pull centos:7.9.2009
3、下载nginx 1.16.1版本的源码包
进入到指定的 Dockerfile 目录:
[root@docker-server1 opt]# cd /opt/dockerfile/web/nginx/
root@docker_server01:/opt/dockerfile/web/nginx# wget https://nginx.org/download/nginx-1.16.1.tar.gz
4、准备nginx配置文件
可以使用其它服务器编译安装相同版本的 nginx 配置文件,而且配置文件中关闭 Nginx 进程后台运行
root@docker_server01:/opt/dockerfile/web/nginx# vim nginx.conf
user nginx; #指定启动nginx的用户,需要创建nginx用户
worker_processes auto;
error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /data/nginx/html; #指定存放代码的目录
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
include /etc/nginx/conf.d/*.conf;
}
2.2.3 编写dockerfile
docker在构建镜像过程中,会启动一个容器,在容器内运行dockerfile文件中的指令,运行完成后把容器提交为一个镜像
dockerfile指令在执行命令时,所处的目录和Dockerfile文件处于同一级目录
1、编写dockerfile
root@docker_server01:/opt/dockerfile/web/nginx# vim Dockerfile
#nginx image from centos:7.9.2009
#"#"为注释,等于 shell 脚本的中#
#除了注释行之外的第一行,必须是 From xxx (xxx 是基础镜像)
From centos:7.9.2009
#镜像维护者的信息
MAINTAINER Jack 123456@qq.com
#执行的命令,将编译安装 nginx 的步骤执行一遍
#RUN yum -y install wget
#RUN wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
#RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
RUN yum -y install epel-release
RUN yum install -y vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop
ADD nginx-1.16.1.tar.gz /usr/local/src/
RUN cd /usr/local/src/nginx-1.16.1 && ./configure --prefix=/apps/nginx --with-http_sub_module && make && make install
ADD nginx.conf /apps/nginx/conf/nginx.conf
RUN useradd nginx -u 2023
RUN ln -sv /apps/nginx/sbin/nginx /usr/sbin/nginx
RUN mkdir -p /data/nginx/html && echo "test nginx page" > /data/nginx/html/index.html
#向外开放的端口,多个端口用空格做间隔,启动容器时候-p需要使用此端向外映射,如: -p 8081:80,则 80 就是这里的 80
EXPOSE 80 443
#运行的命令,每个 Dockerfile 只能有一条,如果有多条则只有最后一条被执行
CMD ["nginx","-g","daemon off;"]
注意:nginx的某些配置我们可以添加到nginx配置文件中,添加后,dockerfile的CMD中就无需在运行该命令,这样可以简化命令。
如:daemon off;是指让nginx处于后台运行,我们可以在nginx的配置文件中添加
vim /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
daemon off; #关闭nginx后台运行
添加后,dockerfile的CMD指令中只需运行nginx即可:
CMD [“nginx”]
2.2.4 构建镜像
root@docker_server01:/opt/dockerfile/web/nginx# docker build -t nginx:v1 . #注意,在命令最后要加上“.”,表示在当前目录查找构建镜像的文件,如果不加,将会报错
2.2.5 启动容器并验证
1、查看本地镜像
2、运行容器并查看
root@docker_server01:/opt/dockerfile/web/nginx# docker run -it -d -p 8088:80 nginx:v1 #注意,由于nginx镜像已经指定了默认的运行命令,因此在运行容器时无需再添加bash作为容器默认运行命令
查看容器
3、通过浏览器访问nginx服务
2.3 自定义tomcat业务镜像
基于官方提供的 centos、debain、ubuntu、alpine 等基础镜像构建 JDK(Java 环境),然后再基于自定义的 JDK 镜像构建出业务需要的 tomcat 镜像。
2.3.1 构建基础镜像
先基于官方提供的基础镜像,制作出安装了常用命令的自定义基础镜像
2.3.1.1 准备工作
1、创建存放镜像的目录
root@docker_server01:~# mkdir /opt/dockerfile/{web/{nginx,tomcat,jdk,apache},system/{centos,ubuntu,redhat}} -pv
2、拉取centos官方镜像作为底层镜像
root@docker_server01:~# docker pull centos:7.9.2009
3、切换目录
root@docker_server01:~# cd /opt/dockerfile/system/centos/
2.3.1.2 编写dockerfile
1、编写dockerfile
root@docker_server01:/opt/dockerfile/system/centos# vim Dockerfile
FROM centos:7.9.2009
LABEL maintainer="jack 123456@qq.com"
LABEL version="v1"
RUN yum -y install epel-release && yum install -y vim wget tree lrzsz gcc gcc-c++ automake pcre pcre-devel zlib zlib-devel openssl openssl-devel iproute net-tools iotop
#添加系统账号
RUN groupadd www -g 2023 && useradd www -u 2023 -g www
2.3.1.3 创建镜像
1、为了便于镜像的提交,编写以下脚本:
root@docker_server01:/opt/dockerfile/system/centos# vim build-command.sh
#!/bin/bash
docker build -t centos_base:v1 .
root@docker_server01:/opt/dockerfile/system/centos# chmod a+x build-command.sh
2、执行脚本,提交镜像
root@docker_server01:/opt/dockerfile/system/centos# bash build-command.sh
3、查看本地镜像
知识延伸:
注意:由于镜像版本不是一成不变的,为了区分不同版本的镜像,可以在脚本中添加位置变量作为TAG号
#!/bin/bash
TAG=$1 #添加位置变量,方便区分不同版本的镜像
docker build -t centos_base:${TAG} .
在执行脚本时可以把执行命令时的时间戳作为TAG号,区分不同版本
如:bash build-command.sh 2023-05-19_15_14_30
2.3.2 构建JDK镜像
2.3.2.1 准备工作
1、下载JDK
由于要构建jdk镜像,因此要先下载jdk安装包,本次实验采用jdk-8u212版本,可以去oracle官网下载jdk:https://www.oracle.com/java/technologies/javase/javase8u211-later-archive-downloads.html
oracle官网下载jdk需要登录账号,如果没有账号,可以使用以下百度网盘中的jdk安装包
链接:https://pan.baidu.com/s/1Xkf2cU0y3Lf3cvnOkd0Aew 提取码:nbfk
2、切换目录,将jdk上传到该目录下
cd /opt/dockerfile/web/jdk/
mkdir -p jdk-8u-212 && cd jdk-8u-212
3、准备profile文件
可以运行一个容器,把容器中/etc/profile文件复制出来,把以下标红部分内容放在profile文件最后
或者直接使用以下文件
root@docker_server01:/opt/dockerfile/web/jdk/jdk-8u-212# vim profile
# /etc/profile
# System wide environment and startup programs, for login setup
# Functions and aliases go in /etc/bashrc
# It's NOT a good idea to change this file unless you know what you
# are doing. It's much better to create a custom.sh shell script in
# /etc/profile.d/ to make custom changes to your environment, as this
# will prevent the need for merging in future updates.
pathmunge () {
case ":${PATH}:" in
*:"$1":*)
;;
*)
if [ "$2" = "after" ] ; then
PATH=$PATH:$1
else
PATH=$1:$PATH
fi
esac
}
if [ -x /usr/bin/id ]; then
if [ -z "$EUID" ]; then
# ksh workaround
EUID=`/usr/bin/id -u`
UID=`/usr/bin/id -ru`
fi
USER="`/usr/bin/id -un`"
LOGNAME=$USER
MAIL="/var/spool/mail/$USER"
fi
# Path manipulation
if [ "$EUID" = "0" ]; then
pathmunge /usr/sbin
pathmunge /usr/local/sbin
else
pathmunge /usr/local/sbin after
pathmunge /usr/sbin after
fi
HOSTNAME=`/usr/bin/hostname 2>/dev/null`
HISTSIZE=1000
if [ "$HISTCONTROL" = "ignorespace" ] ; then
export HISTCONTROL=ignoreboth
else
export HISTCONTROL=ignoredups
fi
export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL
# By default, we want umask to get set. This sets it for login shell
# Current threshold for system reserved uid/gids is 200
# You could check uidgid reservation validity in
# /usr/share/doc/setup-*/uidgid file
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
umask 002
else
umask 022
fi
for i in /etc/profile.d/*.sh /etc/profile.d/sh.local ; do
if [ -r "$i" ]; then
if [ "${-#*i}" != "$-" ]; then
. "$i"
else
. "$i" >/dev/null
fi
fi
done
unset i
unset -f pathmunge
#添加java相关变量
export JAVA_HOME=/usr/local/jdk
export TOMCAT_HOME=/apps/tomcat
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$TOMCAT_HOME/bin:$PATH
export CLASSPATH=.$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$JAVA_HOME/lib/tools.jar
2.3.2.2 编写dockerfile
1、编写dockerfile
root@docker_server01:/opt/dockerfile/web/jdk/jdk-8u-212# vim Dockerfile
#JDK Base Image
FROM centos_base:v1
LABEL maintainer="jack 123456@qq.com"
ADD jdk-8u212-linux-x64.tar.gz /usr/local/src/
RUN ln -sv /usr/local/src/jdk1.8.0_212 /usr/local/jdk
ADD profile /etc/profile
#容器启动时不会读取/etc/profile文件,在容器启动后,root用户没有java环境,因此需要把java环境变量设置为全局变量,root用户才会有java环境。而普通用户在切换用户时,会读取/etc/profile文件,因此普通用户具有java环境。
ENV JAVA_HOME /usr/local/jdk
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/:$JRE_HOME/lib/
ENV PATH $PATH:$JAVA_HOME/bin
#由于容器自身的时间不是东八区时间,因此需要设置容器时间
RUN rm -rf /etc/localtime && ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2.3.2.3 创建镜像
1、创建提交镜像的脚本
root@docker_server01:/opt/dockerfile/web/jdk/jdk-8u-212# vim build-command.sh
#!/bin/bash
docker build -t jdk-base:v8.212 .
root@docker_server01:/opt/dockerfile/web/jdk/jdk-8u-212# chmod a+x build-command.sh
2、执行脚本创建镜像
root@docker_server01:/opt/dockerfile/web/jdk/jdk-8u-212# bash build-command.sh
3、查看本地镜像
2.3.2.4 验证JDK环境
1、进入容器查看java版本
root@docker_server01:/opt/dockerfile/web/jdk/jdk-8u-212# docker run -it jdk-base:v8.212 bash
[root@6e0c0edce46f /]#
[root@6e0c0edce46f /]# java -version
java version "1.8.0_212"
Java(TM) SE Runtime Environment (build 1.8.0_212-b10)
Java HotSpot(TM) 64-Bit Server VM (build 25.212-b10, mixed mode)
2.3.3 基于JDK构建tomcat8镜像
基于自定义的 JDK 基础镜像,构建出通用的自定义 Tomcat 基础镜像,此镜像后期会被多个业务的多个服务共同引用(相同的 JDK 版本和 Tomcat 版本)。
2.3.3.1 准备工作
1、下载tomcat 8版本的安装包
root@docker_server01:/opt/dockerfile/web/jdk/jdk-8u-212# cd /opt/dockerfile/web/tomcat/
root@docker_server01:/opt/dockerfile/web/tomcat# mkdir tomcat-8.5.88-base
root@docker_server01:/opt/dockerfile/web/tomcat# cd tomcat-8.5.88-base/
root@docker_server01:/opt/dockerfile/web/tomcat/tomcat-8.5.88-base# wget https://dlcdn.apache.org/tomcat/tomcat-8/v8.5.88/bin/apache-tomcat-8.5.88.tar.gz
2.3.3.2 编写dockerfile
1、编写dockerfile
root@docker_server01:/opt/dockerfile/web/tomcat/tomcat-8.5.88-base# vim Dockerfile
#Tomcat Base Image
FROM jdk-base:v8.212
LABEL maintainer="jack 123456@qq.com"
LABEL version="8.5.88"
#env
ENV TZ "Asia/Shanghai"
ENV LANG en_US.UTF-8
ENV TERM xterm
ENV TOMCAT_MAJOR_VERSION 8
ENV TOMCAT_MINOR_VERSION 8.5.88
ENV CATALINA_HOME /apps/tomcat
ENV APP_DIR ${CATALINA_HOME}/webapps
#tomcat
RUN mkdir /apps
ADD apache-tomcat-8.5.88.tar.gz /apps
RUN ln -sv /apps/apache-tomcat-8.5.88 /apps/tomcat
2.3.3.3 创建镜像
1、编写构建镜像的脚本
root@docker_server01:/opt/dockerfile/web/tomcat/tomcat-8.5.88-base# vim build-command.sh
#!/bin/bash
docker build -t tomcat-base:v8.5.88 .
root@docker_server01:/opt/dockerfile/web/tomcat/tomcat-8.5.88-base# chmod a+x build-command.sh
2、执行脚本,创建镜像
root@docker_server01:/opt/dockerfile/web/tomcat/tomcat-8.5.88-base# bash build-command.sh
3、查看本地镜像
2.3.3.4 验证
1、启动容器,并进入容器手动启动tomcat
root@docker_server01:/opt/dockerfile/web/tomcat# docker run -it -p 8080:8080 tomcat-base:v8.5.88 bash
[root@e1b73894a0d2 /]# chown -R www.www /apps #修改目录权限
[root@e1b73894a0d2 /]# su - www -c "/apps/tomcat/bin/catalina.sh start " #通过www用户启动tomcat
Using CATALINA_BASE: /apps/tomcat
Using CATALINA_HOME: /apps/tomcat
Using CATALINA_TMPDIR: /apps/tomcat/temp
Using JRE_HOME: /usr/local/jdk
Using CLASSPATH: /apps/tomcat/bin/bootstrap.jar:/apps/tomcat/bin/tomcat-juli.jar
Using CATALINA_OPTS:
Tomcat started.
[root@e1b73894a0d2 /]#
2、通过浏览器访问tomcat
2.3.4 构建业务镜像
2.3.4.1 准备工作
1、创建存放业务镜像的目录
mkdir -p /opt/dockerfile/web/tomcat/{tomcat-app1,tomcat-app2}
cd /opt/dockerfile/web/tomcat/tomcat-app1
2、准备自定义 myapp 页面,模拟业务代码
root@docker_server01:/opt/dockerfile/web/tomcat/tomcat-app1# mkdir myapp
root@docker_server01:/opt/dockerfile/web/tomcat/tomcat-app1# echo "Tomcat Web Page" > myapp/index.html
root@docker_server01:/opt/dockerfile/web/tomcat/tomcat-app1# tar -zcvf myapp.tar.gz myapp/
3、准备server.xml文件 #该文件可以运行一个tomcat容器,然后将容器中的server.xml文件复制出来,注意tomcat版本要一样
vim server.xml #修改tomcat代码目录,关闭自动解压和自动部署
<Host name="localhost" appBase="/data/tomcat/webapps" unpackWARs="false" autoDeploy="false">
4、准备tomcat启动脚本
root@docker_server01:/opt/dockerfile/web/tomcat/tomcat-app1# vim run_tomcat.sh
#!/bin/bash
echo "1.1.1.1 abc.test.com" >> /etc/hosts
echo "nameserver 223.5.5.5" > /etc/resolv.conf
#使用start启动tomcat会处于后台运行,因此需要添加一个在前台运行的程序tail -f /etc/hosts
su - www -c "/apps/tomcat/bin/catalina.sh start"
su - www -c "tail -f /etc/hosts"
root@docker_server01:/opt/dockerfile/web/tomcat/tomcat-app1# chmod a+x run_tomcat.sh
2.3.4.2 编写dockerfile
1、编写dockerfile
root@docker_server01:/opt/dockerfile/web/tomcat/tomcat-app1# vim Dockerfile
#Tomcat Web Image
FROM tomcat-base:v8.5.88
LABEL maintainer="jack 123456@qq.com"
ADD run_tomcat.sh /apps/tomcat/bin/run_tomcat.sh
ADD server.xml /apps/tomcat/conf/server.xml
RUN mkdir -p /data/tomcat/webapps
ADD myapp.tar.gz /data/tomcat/webapps/
RUN chown -R www.www /apps/ /data/
EXPOSE 8080 8009
#通过脚本启动tomcat
CMD ["/apps/tomcat/bin/run_tomcat.sh"]
2.3.4.3 构建镜像
1、编写创建镜像的脚本
vim build-command.sh
#!/bin/bash
docker build -t tomcat-web:app1 .
chmod a+x build-command.sh
2、执行脚本创建镜像
root@docker_server01:/opt/dockerfile/web/tomcat/tomcat-app1# bash build-command.sh
3、查看本地镜像
2.3.4.4 验证
1、启动容器
root@docker_server01:/opt/dockerfile/web/tomcat/tomcat-app1# docker run -it -d -p 8088:8080 tomcat-web:app1
2、通过浏览器访问
(1)访问自定义页面
172.31.7.150:8088/myapp/
2.4 构建haproxy镜像
构建出 haproxy 镜像,将 haproxy 通过容器的方式运行。
2.4.1 准备工作
1、创建存放dockerfile的目录
mkdir -p /opt/dockerfile/web/haproxy
cd /opt/dockerfile/web/haproxy
2、下载haproxy安装包
haproxy源码包下载网站地址:https://src.fedoraproject.org/repo/pkgs/haproxy/
直接使用命令下载2.4.22版本的haproxy源码包:
root@docker_server01:/opt/dockerfile/web/haproxy# wget https://src.fedoraproject.org/repo/pkgs/haproxy/haproxy-2.4.22.tar.gz/sha512/c22ad38046e3c70beb3bf57a62e4e74db329559059e2f36d2f801768c26b1f1222631702e83e9839fab4396c1b78089a807750ff743b4192da06c751cf9f0779/haproxy-2.4.22.tar.gz
3、准备haproxy配置文件
root@docker_server01:/opt/dockerfile/web/haproxy# vim haproxy.cfg
global
chroot /apps/haproxy
#stats socket /var/lib/haproxy/haproxy.sock mode 600 level admin
uid 99
gid 99
daemon
nbproc 1
pidfile /apps/haproxy/run/haproxy.pid
log 127.0.0.1 local3 info
defaults
option http-keep-alive
option forwardfor
mode http
timeout connect 300000ms
timeout client 300000ms
timeout server 300000ms
#haproxy状态页,配置状态页url以及登录的账号密码
listen stats
mode http
bind 0.0.0.0:9999
stats enable
log global
stats uri /haproxy-status
stats auth haadmin:123456
#haproxy后端应用,加上tomcat容器的地址和端口
listen web_port
bind 0.0.0.0:80
mode http
log global
balance roundrobin
server web1 172.31.7.150:8080 check inter 3000 fall 2 rise 5
4、准备haproxy启动脚本
root@docker_server01:/opt/dockerfile/web/haproxy# vim run_haproxy.sh
#!/bin/bash
/apps/haproxy/sbin/haproxy -f /etc/haproxy/haproxy.cfg
tail -f /etc/hosts
root@docker_server01:/opt/dockerfile/web/haproxy# chmod a+x run_haproxy.sh
2.4.2 编写Dockerfile
1、编写dockerfile
root@docker_server01:/opt/dockerfile/web/haproxy# vim Dockerfile
#haproxy image
FROM centos_base:v1
LABEL maintainer="jack 123456@qq.com"
RUN yum -y install libtermcap-devel ncurses-devel libevent-devel readline-devel gcc gcc-c++ glibc glibc-devel pcre pcre-devel openssl openssl-devel systemd-devel net-tools vim iotop bc zip unzip zlib-devel lrzsz tree screen lsof tcpdump wget ntpdate
ADD haproxy-2.4.22.tar.gz /usr/local/src/
RUN cd /usr/local/src/haproxy-2.4.22 && make ARCH=x86_64 TARGET=linux-glibc USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 USE_SYSTEMD=1 USE_CPU_AFFINITY=1 PREFIX=/apps/haproxy && make install PREFIX=/apps/haproxy
#将二进制文件放到/usr/sbin目录
RUN /apps/haproxy/sbin/cp haproxy /usr/sbin/
#创建存放pid文件的目录
RUN mkdir -p /apps/haproxy/run
ADD haproxy.cfg /etc/haproxy/
ADD run_haproxy.sh /usr/bin/
EXPOSE 80 9999
CMD ["/usr/bin/run_haproxy.sh"]
2.4.3 构建镜像
1、准备构建镜像的脚本
root@docker_server01:/opt/dockerfile/web/haproxy# vim build-command.sh
#!/bin/bash
docker build -t haproxy:v2.4.22 .
2、执行脚本,构建镜像
root@docker_server01:/opt/dockerfile/web/haproxy# bash build-command.sh
3、查看本地镜像
2.4.4 验证
1、根据haproxy镜像启动容器
root@docker_server01:/opt/dockerfile/web/haproxy# docker run -it -p 80:80 -p 9999:9999 haproxy:v2.4.22
2、通过浏览器访问
(1)访问haproxy状态页http://172.31.7.150:9999/haproxy-status
(2)访问tomcat页面http://172.31.7.150/myapp/
2.5 基于官方 alpine 基础镜像制作自定义镜像
由于alipine发行版操作系统比较小(镜像文件6M左右),因此有些公司为了缩小镜像文件,会使用alpine作为基础镜像打镜像。
下面基于官方alpine基础镜像制作nginx编译镜像
2.5.1 准备工作
1、创建存放dockerfile的目录
mkdir -p /opt/dockerfile/web/nginx-alpine/
cd /opt/dockerfile/web/nginx-alpine/
2、准备镜像源
由于alpine镜像安装软件连接的是官网镜像仓库,下载比较慢,因此要修改为国内镜像源(这里使用阿里云镜像源)
root@docker_server01:/opt/dockerfile/web/nginx-alpine# vim repositories
https://mirrors.aliyun.com/alpine/v3.15/main
https://mirrors.aliyun.com/alpine/v3.15/community
3、下载nginx源码包
root@docker_server01:/opt/dockerfile/web/nginx-alpine# wget https://nginx.org/download/nginx-1.16.1.tar.gz
4、准备nginx配置文件
root@docker_server01:/opt/dockerfile/web/nginx-alpine# vim nginx.conf
user nginx; #指定启动nginx的用户,需要创建nginx用户
worker_processes auto;
error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /data/nginx/html; #指定存放代码的目录
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
include /etc/nginx/conf.d/*.conf;
}
5、准备代码文件static.tar.gz
root@docker_server01:/opt/dockerfile/web/nginx-alpine# mkdir -p myapp
root@docker_server01:/opt/dockerfile/web/nginx-alpine# echo "alpine test web" > myapp/index.html
root@docker_server01:/opt/dockerfile/web/nginx-alpine# tar -zcvf static.tar.gz myapp/
2.5.2 编辑Dockerfile
1、编写dockerfile
root@docker_server01:/opt/dockerfile/web/nginx-alpine# vim Dockerfile
FROM alpine
LABEL maintainer="jack 123456@qq.com"
COPY repositories /etc/apk/repositories
RUN apk update && apk add iotop gcc libgcc libc-dev libcurl libc-utils pcre-dev zlib-dev libnfs make pcre pcre2 zip unzip net-tools pstree wget libevent libevent-dev iproute2 openssl openssl-dev
ADD nginx-1.16.1.tar.gz /opt/
RUN cd /opt/nginx-1.16.1 && ./configure --prefix=/apps/nginx && make && make install && ln -sv /apps/nginx/sbin/nginx /usr/bin/ && rm -f /opt/nginx-1.16.1
RUN addgroup -g 2023 -S nginx && adduser -s /sbin/nologin -S -D -u 2023 -G nginx nginx
COPY nginx.conf /apps/nginx/conf/nginx.conf
RUN mkdir -p /data/nginx/html
ADD static.tar.gz /data/nginx/html/index.html
RUN chown nginx.nginx /data/nginx/ /apps/nginx/ -R
EXPOSE 80 443
CMD ["nginx"]
注意:alpine系统中安装软件包命令是:apk add,添加用户的命令是:adduser,创建组的命令是:addgroup
2.5.3 构建镜像
1、编写构建镜像的脚本
root@docker_server01:/opt/dockerfile/web/nginx-alpine# vim build-command.sh
#!/bin/bash
docker build -t nginx-alpine:1.16.1 .
2、构建镜像
root@docker_server01:/opt/dockerfile/web/nginx-alpine# bash build-command.sh
3、查看本地镜像
2.5.4 验证
1、根据自定义镜像创建容器
root@docker_server01:/opt/dockerfile/web/nginx-alpine# docker run -it -d -p 80:80 nginx-alpine:1.16.1
2、通过浏览访问web页面
2.6 基于官方 Ubuntu 基础镜像制作自定义镜像
下面基于官方ubuntu基础镜像制作nginx编译镜像
2.6.1 准备工作
1、创建存放dockerfile的目录
mkdir -p /opt/dockerfile/web/nginx-ubuntu/
cd /opt/dockerfile/web/nginx-ubuntu/
2、准备镜像源
由于alpine镜像安装软件连接的是官网镜像仓库,下载比较慢,因此要修改为国内镜像源(这里使用阿里云镜像源)
root@docker_server01:/opt/dockerfile/web/nginx-alpine# vim sources.list
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
# deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
# deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
注意:apt仓库如果使用https协议需要安装ssl相关的包,这里没有安装,因此使用http协议
3、下载nginx源码包
root@docker_server01:/opt/dockerfile/web/nginx-alpine# wget https://nginx.org/download/nginx-1.16.1.tar.gz
4、准备nginx配置文件
root@docker_server01:/opt/dockerfile/web/nginx-alpine# vim nginx.conf
user nginx; #指定启动nginx的用户,需要创建nginx用户
worker_processes auto;
error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root /data/nginx/html; #指定存放代码的目录
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
include /etc/nginx/conf.d/*.conf;
}
5、准备代码文件static.tar.gz
root@docker_server01:/opt/dockerfile/web/nginx-ubuntu# mkdir -p myapp
root@docker_server01:/opt/dockerfile/web/nginx-ubuntu# echo "alpine test web" > myapp/index.html
root@docker_server01:/opt/dockerfile/web/nginx-ubuntu# tar -zcvf static.tar.gz myapp/
2.6.2 编辑Dockerfile
1、编写dockerfile
root@docker_server01:/opt/dockerfile/web/nginx-alpine# vim Dockerfile
FROM ubuntu:18.04
LABEL maintainer="jack 123456@qq.com"
COPY sources.list /etc/apt/sources.list
RUN apt update && apt install -y iproute2 ntpdate tcpdump telnet traceroute nfs-kernel-server nfs-common lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute gcc openssh-server lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute iotop unzip zip make
ADD nginx-1.16.1.tar.gz /usr/local/src
RUN cd /usr/local/src/nginx-1.16.1 && ./configure --prefix=/apps/nginx && make && make install && ln -sv /apps/nginx/sbin/nginx /usr/bin && rm -rf /usr/local/src/nginx-1.16.1
ADD nginx.conf /apps/nginx/conf/nginx.conf
RUN mkdir -p /data/nginx/html
ADD static.tar.gz /data/nginx/html
RUN groupadd -g 2023 nginx && useradd -g nginx -s /usr/sbin/nologin -u 2023 nginx && chown -R nginx.nginx /apps/nginx /data/nginx
EXPOSE 80 443
CMD ["nginx","-g","daemon off;"]
注意:alpine系统中安装软件包命令是:apk add,添加用户的命令是:adduser,创建组的命令是:addgroup
2.6.3 构建镜像
1、编写构建镜像的脚本
root@docker_server01:/opt/dockerfile/web/nginx-ubuntu# vim build-command.sh
#!/bin/bash
docker build -t nginx-ubuntu_1804:1.16.1 .
2、构建镜像
root@docker_server01:/opt/dockerfile/web/nginx-ubuntu# bash build-command.sh
3、查看本地镜像
2.6.4 验证
1、根据自定义镜像创建容器
root@docker_server01:/opt/dockerfile/web/nginx-alpine# docker run -it -d -p 80:80 nginx-ubun_1804:1.16.1
2、通过浏览访问web页面
2.7 本地镜像上传至官方 docker 仓库
将自制的镜像上传至 docker 仓库;https://hub.docker.com/,实现镜像跨主机备份。
2.7.1 创建账号并登录
1、登录到 docker hub 创建官网注册账号
登录成功后,创建组织(team),类似于项目名称
然后创建镜像仓库,即镜像名称
2、创建完成后,在客户端使用命令行登录
登录镜像仓库时,需要指定登录哪个镜像仓库,如果不指定是哪个仓库,会默认登录docker官方镜像仓库
root@docker_server01:~# docker login docker.io #显示“Login Succeeded”表示登录成功
登录成功之后会在当前目录生成一个隐藏文件用于保存登录认证信息
root@docker_server01:~# cat /root/.docker/config.json
2.7.2 上传镜像到官方镜像仓库
1、为本地镜像打tag(tag格式:仓库名/账号名/镜像名:版本号)
root@docker_server01:~# docker tag nginx:1.18.0 docker.io/magedutest/nginx:1.18.0
2、上传镜像到官方镜像仓库
root@docker_server01:~# docker push docker.io/magedutest/nginx:1.18.0
3、在官方镜像仓库查看镜像
2.7.3 在其他服务器下载上传的镜像
1、登录官网镜像仓库
root@docker_server02:~# docker login docker.io
2、下载镜像
root@docker_server02:~# docker pull docker.io/magedutest/nginx:1.18.0
3、使用镜像启动容器
root@docker_server02:~# docker run -it -p 8088:80 magedutest/nginx:1.18.0
2.8 本地镜像上传到阿里云镜像仓库
docker官方镜像仓库由于在国外,有时候无法访问,我们可以将镜像上传到国内镜像仓库,不仅可以正常访问,而且上传速度比较快。
2.8.1 登录阿里云镜像仓库
将本地镜像上传至阿里云,实现镜像备份与统一分发的功能。
登录阿里云镜像仓库:https://cr.console.aliyun.com
操作步骤:注册账号(如果没有阿里云账号),然后创建namespace、创建仓库、修改镜像tag以及上传镜像
1、登录阿里云镜像仓库,注册账号后进入以下页面,点击右侧个人实例
2、创建namespace,这里的namespace,类似于项目名称,用于区分不同项目的镜像
3、创建镜像仓库,这里的镜像仓库是指哪个应用,如:nginx、tomcat等
4、以nginx为例,创建完成后,点击进入后,查看操作指南(包括登录、打tag、上传镜像)
5、根据上一步操作指南,在客户端通过命令行登录阿里云镜像仓库
root@docker_server01:~# docker login --username=yuandangsheng registry.cn-hangzhou.aliyuncs.com
登录时需要输入密码,显示“Login Succeeded”即登录成功
登录成功后,会在客户端本地生成认证文件
root@docker_server01:~# cat /root/.docker/config.json
2.8.2 将本地镜像上传阿里云镜像仓库
1、为镜像打tag(为本地镜像的打上阿里云镜像仓库的tag)
root@docker_server01:~# docker tag nginx:1.18.0 registry.cn-hangzhou.aliyuncs.com/docker_image01/nginx:1.18.0
2、上传镜像
root@docker_server01:~# docker push registry.cn-hangzhou.aliyuncs.com/docker_image01/nginx:1.18.0
3、在阿里云镜像仓库查看镜像
小知识:
docker镜像仓库中,公有仓库和私有仓库的区别:
私有镜像仓库:上传和下载镜像都需要登录成功后,才可以进行
公有镜像仓库:上传镜像需要登录,下载镜像则不需要
文章评论