一、Docker快速入门
1、Docker 的概述
(1)基本介绍
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
(2)应用场景
- Web 应用的自动化打包和发布。
- 自动化测试和持续集成、发布。
- 在服务型环境中部署和调整数据库或其他的后台应用。
- 从头编译或者扩展现有的 OpenShift 或 Cloud Foundry 平台来搭建自己的 PaaS 环境。
(3)Docker 的优势
1、快速,一致地交付您的应用程序。Docker 允许开发人员使用您提供的应用程序或服务的本地容器在标准化环境中工作,从而简化了开发的生命周期。
2、响应式部署和扩展
Docker 是基于容器的平台,允许高度可移植的工作负载。Docker 容器可以在开发人员的本机上,数据中心的物理或虚拟机上,云服务上或混合环境中运行。
Docker 的可移植性和轻量级的特性,还可以使您轻松地完成动态管理的工作负担,并根据业务需求指示,实时扩展或拆除应用程序和服务。
3、在同一硬件上运行更多工作负载
Docker 轻巧快速。它为基于虚拟机管理程序的虚拟机提供了可行、经济、高效的替代方案,因此您可以利用更多的计算能力来实现业务目标。Docker 非常适合于高密度环境以及中小型部署,而您可以用更少的资源做更多的事情。
- 虚拟化技术和容器化技术
虚拟化技术特点:1.资源占用多 2.冗余步骤多 3.启动很慢
容器化技术:容器化技术不是模拟的一个完整的操作系统
比较Docker和虚拟机的不同:
1.传统虚拟机,虚拟出硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件。
2.Docker容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟硬件。
3.每个容器都是相互隔离的,每个容器都有属于自己的文件系统,互不影响。
2.Docker的基本组成
3.Docker 的安装
查看系统配置
cat /etc/os-release
[root@iZwz99sm8v95sckz8bd2c4Z ~]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
Docker的安装步骤:
(1)卸载旧的版本
1 yum remove docker \
2 docker-client \
3 docker-client-latest \
4 docker-common \
5 docker-latest \
6 docker-latest-logrotate \
7 docker-logrotate \
8 docker-engine
(2)下载需要的安装包
1 yum install -y yum-utils
(3)设置镜像的仓库
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo #国外的地址
# 设置阿里云的Docker镜像仓库
yum-config-manager \
--add-repo \
https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #国外的地址
(4)更新yum软件包索引
1 yum makecache fast
(5)安装docker相关的配置
docker-ce 是社区版,docker-ee 企业版
1 yum install docker-ce docker-ce-cli containerd.io
出现了completed即安装成功。
(6)启动Docker
systemctl start docker
#查看当前版本号,是否启动成功
docker version
#设置开机自启动
systemctl enable docker
3.1、Docker容器运行流程
启动一个容器,Docker的运行流程如下图:
3.2、底层原理
Docker是一个Client-Server结构的系统,Docker的守护进程运行在主机上,通过Socker从客户端访问!Docker Server接收到Docker-Client的指令,就会执行这个指令!
Docker为什么比VM Ware快?
1、Docker比虚拟机更少的抽象层
2、docker利用宿主机的内核,VM需要的是Guest OS
Docker新建一个容器的时候,不需要像虚拟机一样重新加载一个操作系统内核,直接利用宿主机的操作系统,而虚拟机是需要加载Guest OS。Docker和VM的对比如下:
4.Docker常用命令
4.1 基础指令
docker version #查看docker的版本信息
docker info #查看docker的系统信息,包括镜像和容器的数量
docker 命令 --help #帮助命令(可查看可选的参数)
docker COMMAND --help
命令的帮助文档地址:https://docs.docker.com/engine/reference/commandline/docker/
4.2 镜像命令
1、docker images 查看本地主机的所有镜像
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 11 months ago 13.3kB
#解释:
1.REPOSITORY 镜像的仓库源
2.TAG 镜像的标签
3.IMAGE ID 镜像的id
4.CREATED 镜像的创建时间
5.SIZE 镜像的大小
# 可选参数
-a/--all 列出所有镜像
-q/--quiet 只显示镜像的id
2、docker search 搜索镜像
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 10308 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3819 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 754 [OK]
percona Percona Server is a fork of the MySQL relati… 517 [OK]
centos/mysql-57-centos7 MySQL 5.7 SQL database server 86
mysql/mysql-cluster Experimental MySQL Cluster Docker images. Cr… 79
centurylink/mysql Image containing mysql. Optimized to be link… 60 [OK]
#可选参数
Search the Docker Hub for images
Options:
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print search using a Go template
--limit int Max number of search results (default 25)
--no-trunc Don't truncate output
#搜索收藏数大于3000的镜像
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker search mysql --filter=STARS=3000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 10308 [OK]
mariadb MariaDB is a community-developed fordockerk of MyS… 3819 [OK]
3、docker pull 镜像名[:tag] 下载镜像
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker pull mysql
Using default tag: latest #如果不写tag默认就是latest
latest: Pulling from library/mysql
6ec7b7d162b2: Pull complete #分层下载,docker image的核心-联合文件系统
fedd960d3481: Pull complete
7ab947313861: Pull complete
64f92f19e638: Pull complete
3e80b17bff96: Pull complete
014e976799f9: Pull complete
59ae84fee1b3: Pull complete
ffe10de703ea: Pull complete
657af6d90c83: Pull complete
98bfb480322c: Pull complete
6aa3859c4789: Pull complete
1ed875d851ef: Pull complete
Digest: sha256:78800e6d3f1b230e35275145e657b82c3fb02a27b2d8e76aac2f5e90c1c30873 #签名
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest #下载来源的真实地址 #docker pull mysql等价于docker pull docker.io/library/mysql:latest
4.3 容器命令
拉取一个centos镜像
docker pull centos
运行容器的命令说明:
docker run [可选参数] image
#参数说明
--name="名字" 指定容器名字
-d 后台方式运行
-it 使用交互方式运行,进入容器查看内容
-p 指定容器的端口
(
-p ip:主机端口:容器端口 配置主机端口映射到容器端口
-p 主机端口:容器端口
-p 容器端口
)
-P 随机指定端口(大写的P)
运行并进入容器centos
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker run -it centos /bin/bash
[root@bd1b8900c547 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
退出容器命令:
#exit 停止并退出容器(后台方式运行则仅退出)
#Ctrl+P+Q 不停止容器退出
[root@bd1b8900c547 /]# exit
exit
[root@iZwz99sm8v95sckz8bd2c4Z ~]#
列出运行过的容器命令:
#docker ps
# 列出当前正在运行的容器
-a # 列出所有容器的运行记录
-n=? # 显示最近创建的n个容器
-q # 只显示容器的编号
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bca129320bb5 centos "/bin/bash" 4 minutes ago Exited (0) 3 minutes ago optimistic_shtern
bd1b8900c547 centos "/bin/bash" 6 minutes ago Exited (0) 5 minutes ago cool_tesla
cf6adbf1b506 bf756fb1ae65 "/hello" 5 hours ago Exited (0) 5 hours ago optimistic_darwin
删除容器命令:
docker rm 容器id #删除指定的容器,不能删除正在运行的容器,强制删除使用 rm -f
docker rm -f $(docker ps -aq) #删除所有的容器
docker ps -a -q|xargs docker rm #删除所有的容器
启动和停止容器命令:
docker start 容器id #启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止当前运行的容器
docker kill 容器id #强制停止当前容器
4.4 其他常用命令
4.4.1 查看容器中进程信息
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker top c703b5b1911f
UID PID PPID C STIME TTY TIME
root 11156 11135 0 11:31 ? 00:00:00
root 11886 11156 0 11:43 ? 00:00:00
4.4.2 进入正在运行的容器
因为通常我们的容器都是使用后台方式来运行的,有时需要进入容器修改配置
方式一:
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker exec -it c703b5b1911f /bin/bash
[root@c703b5b1911f /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@c703b5b1911f /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 03:31 ? 00:00:00 /bin/sh -c while true;do echo hi;sleep 5;done
root 279 0 0 03:54 pts/0 00:00:00 /bin/bash
root 315 1 0 03:56 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 5
root 316 279 0 03:56 pts/0 00:00:00 ps -ef
方式二:
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker attach c703b5b1911f
docker exec 进入容器后开启一个新的终端,可以在里面操作
docker attach 进入容器正在执行的终端,不会启动新的进程
拷贝操作的命令如下:
#拷贝容器的文件到主机中
docker cp 容器id:容器内路径 目的主机路径
#拷贝宿主机的文件到容器中
docker cp 目的主机路径 容器id:容器内路径
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker exec -it c703b5b1911f /bin/bash
[root@c703b5b1911f /]# cd home
[root@c703b5b1911f home]# ls
#touch 新建文件
[root@c703b5b1911f home]# touch test.java
[root@c703b5b1911f home]# ls
test.java
[root@c703b5b1911f home]# exit
exit
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c703b5b1911f centos "/bin/sh -c 'while t…" 35 minutes ago Up 35 minutes pedantic_banach
[root@iZwz99sm8v95sckz8bd2c4Z ~]# docker cp c703b5b1911f:/home/test.java /home
[root@iZwz99sm8v95sckz8bd2c4Z ~]# ls /home
hai pan test.java
4.5提交镜像
使用docker commit 命令提交容器成为一个新的版本
docker commit -m=“提交的描述信息” -a="作者" 容器id 目标镜像名:[TAG]
MySQL部署
(1)下载并运行
#拉取并运行容器
docker run -d --name mysql-5.7 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
参数说明:
-p 3306:3306 :映射容器服务的 3306 端口到宿主机的 3306 端口,外部主机可以直接通过 宿主机ip:3306 访问到 MySQL 的服务。
MYSQL_ROOT_PASSWORD=123456:设置 MySQL 服务 默认账号root 用户的密码。
(2)进入容器查看MySQL服务
进入容器,并通过账号root查看MySQL服务能否正常连接。
docker exec -it 9b3aad6819ff /bin/bash
mysql -h localhost -u root -p
二、Dockerfile 详解
Dockerfile 基础知识
FROM #基础镜像,一切从这里开始构建
MAINTAINER #镜像是谁写的,姓名+邮箱
RUN #镜像构建的时候需要运行的命令
ADD #步骤,tomcat镜像,这个tomcat的压缩包!添加内容
WORKDIR #镜像的工作目录
VOLUME #挂载的目录
EXPOSE #暴露端口配置
CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD #当构建一个被继承 Dockerfile 这个时候就会运行ONBUILD 的指令
COPY #类似ADD,将我们文件拷贝到镜像中
ENV #构建的时候设置环境遍量
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kC13ZSIl-1657537206126)(…/AppData/Roaming/Typora/typora-user-images/image-20220711152222603.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tTzupdE4-1657537206126)(…/AppData/Roaming/Typora/typora-user-images/image-20220711152237181.png)]
docker build工作原理
docker build [选项] <上下文路径/URL/->
1、 FROM
指定基础镜像,必须为第一个命令
格式:
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
示例:
FROM mysql:5.6
注:
tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像
2、MAINTAINER(新版即将废弃)
维护者信息
格式:
MAINTAINER <name>
示例:
MAINTAINER bertwu
MAINTAINER xxx@163.com
MAINTAINER bertwu <xxx@163.com>
3、RUN
构建镜像时执行的命令
RUN用于在构建镜像时执行命令,其有以下两种命令执行方式:
shell执行
格式:
RUN <command>
exec执行
格式:
RUN ["executable", "param1", "param2"]
示例:
RUN ["executable", "param1", "param2"]
RUN apk update
RUN ["/etc/execfile", "arg1", "arg1"]
注:RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,
可以在构建时指定--no-cache参数,如:docker build --no-cache
4、ADD
将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
格式:
ADD <src>... <dest>
ADD ["<src>",... "<dest>"] 用于支持包含空格的路径
示例:
ADD hom* /mydir/ # 添加所有以"hom"开头的文件
ADD hom?.txt /mydir/ # ? 替代一个单字符,例如:"home.txt"
ADD test relativeDir/ # 添加 "test" 到 `WORKDIR`/relativeDir/
ADD test /absoluteDir/ # 添加 "test" 到 /absoluteDir/
5、COPY
功能类似ADD,但是是不会自动解压文件,也不能访问网络资源
6、CMD
构建镜像后调用,也就是在容器启动时才进行调用。
格式:
CMD ["executable","param1","param2"] (执行可执行文件,优先)
CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
CMD command param1 param2 (执行shell内部命令)
示例:
CMD echo "This is a test." | wc -l
CMD ["/usr/bin/wc","--help"]
注:CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。
7、ENTRYPOINT
配置容器,使其可执行化。配合CMD可省去"application",只使用参数。
格式:
ENTRYPOINT ["executable", "param1", "param2"] (可执行文件, 优先)
ENTRYPOINT command param1 param2 (shell内部命令)
示例:
FROM ubuntu
ENTRYPOINT ["ls", "/usr/local"]
CMD ["/usr/local/tomcat"]
之后,docker run 传递的参数,都会先覆盖cmd,然后由cmd 传递给entrypoint ,做到灵活应用
注:ENTRYPOINT与CMD非常类似,不同的是通过docker run执行的命令不会覆盖ENTRYPOINT,
而docker run命令中指定的任何参数,都会被当做参数再次传递给CMD。
Dockerfile中只允许有一个ENTRYPOINT命令,多指定时会覆盖前面的设置,
而只执行最后的ENTRYPOINT指令。
通常情况下, ENTRYPOINT 与CMD一起使用,ENTRYPOINT 写默认命令,当需要参数时候 使用CMD传参
8、LABEL
用于为镜像添加元数据
用于为镜像添加元数据
格式:
LABEL <key>=<value> <key>=<value> <key>=<value> ...
示例:
LABEL version="1.0" description="这是一个Web服务器" by="IT笔录"
注:
使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据
之间通过空格分隔。推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。
9、ENV
设置环境变量
格式:
ENV <key> <value> #<key>之后的所有内容均会被视为其<value>的组成部分,因此,一次只能设置一个变量
ENV <key>=<value> ... #可以设置多个变量,每个变量为一个"<key>=<value>"的键值对,如果<key>中包含空格,可以使用\来进行转义,也可以通过""来进行标示;另外,反斜线也可以用于续行
示例:
ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat=fluffy
10、EXPOSE
指定于外界交互的端口
格式:
EXPOSE <port> [<port>...]
示例:
EXPOSE 80 443
EXPOSE 8080
EXPOSE 11211/tcp 11211/udp
注: EXPOSE并不会让容器的端口访问到主机。要使其可访问,需要在docker run运行容器时通过-p来发布这些端口,或通过-P参数来发布EXPOSE导出的所有端口
如果没有暴露端口,后期也可以通过-p 8080:80方式映射端口,但是不能通过-P形式映射
11、VOLUME
用于指定持久化目录(指定此目录可以被挂载出去)
格式:
VOLUME ["/path/to/dir"]
示例:
VOLUME ["/data"]
VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"
注:一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:
1 卷可以容器间共享和重用
2 容器并不一定要和其它容器共享卷
3 修改卷后会立即生效
4 对卷的修改不会对镜像产生影响
5 卷会一直存在,直到没有任何容器在使用它
12、WORKDIR
工作目录,类似于cd命令
格式:
WORKDIR /path/to/workdir
示例:
WORKDIR /a (这时工作目录为/a)
WORKDIR b (这时工作目录为/a/b)
WORKDIR c (这时工作目录为/a/b/c)
注:
通过WORKDIR设置工作目录后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT、ADD、COPY
等命令都会在该目录下执行。在使用docker run运行容器时,可以通过-w参数覆盖构建时所设置的工作目录。
13、USER
指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户
格式:
USER user
USER user:group
USER uid
USER uid:gid
USER user:gid
USER uid:group
示例:
USER www
注:
使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。
镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户。
14、ARG
用于指定传递给构建运行时的变量(给dockerfile传参),相当于构建镜像时可以在外部为里面传参
格式:
ARG <name>[=<default value>]
示例:
ARG site
ARG build_user=www
From centos:7
ARG parameter
VOLUME /usr/share/nginx
RUN yum -y install $parameter
EXPOSE 80 443
CMD nginx -g "daemon off;"
# 可以这如下这样灵活传参
docker build --build-arg=parameter=net-tools -t nginx:01 .
15、ONBUILD
用于设置镜像触发器
格式:
ONBUILD [INSTRUCTION]
示例:
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
注:
NNBUID后面跟指令,当当前的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被钥触发
三、制作镜像
如果有多个RUN,自上而下依次运行,每次运行都会形成新的层,建议&& 放入一行运行
如果有多个CMD,只有最后一个运行
如果有多个Entrypoint,只有最后一个运行
如果CMD和entrypoint共存,只有entrypoint运行,且最后的CMD会当做entrypoint的参数
镜像制作分为两个阶段
docker build阶段 基于dockerfile制作镜像 (RUN,用于此阶段的运行命令)
docker run阶段 基于镜像运行容器 (CMD,基于image run容器时候,需要运行的命令)
docker build 基于第一阶段的镜像被别人from制作新镜像 (entrypoint 或onbuild 基于镜像重新构建新镜像时候在此阶段运行的命令)
tomcat镜像
1、准备镜像文件 tomcat压缩包 、jdk压缩包
apache-tomcat-9.0.22.tar.gz
jdk-8u11-linux-x64.tar.gz
2、编写dockerfile文件 官方命名 Dockerfile ,build会自动寻找这个文件 就不需要 -f 指定了
[root@root tomcat]# cat Dockerfile
FROM centos
MAINTAINER Hang<1754808103@qq.com>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u11-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.22.tar.gz /usr/local/
RUN yum -y install vim
ENV MYPATH /usr/local
WORKDIR $MYPATH
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_BASH /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.22/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out
3、构建镜像
# docker build -t diytomcat .
Removing intermediate container 8ae0bf3da639
---> 731ad02de5b7
Step 7/15 : ENV MYPATH /usr/local
---> Running in 096e09b9bc21
Removing intermediate container 096e09b9bc21
---> 4af21aee2224
Step 8/15 : WORKDIR $MYPATH
---> Running in 754abbc7213e
Removing intermediate container 754abbc7213e
---> b90b463448c6
Step 9/15 : ENV JAVA_HOME /usr/local/jdk1.8.0_11
---> Running in 8d88b767e5ba
Removing intermediate container 8d88b767e5ba
---> 8be538aa441f
Step 10/15 : ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
---> Running in 2d474aacec81
Removing intermediate container 2d474aacec81
---> d2a196f068ee
Step 11/15 : ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
---> Running in 57b51e71729c
Removing intermediate container 57b51e71729c
---> 82bc59fffad0
Step 12/15 : ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.22
---> Running in 132900cd06c0
Removing intermediate container 132900cd06c0
---> 26764aa6f6e6
Step 13/15 : ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
---> Running in dd532def866f
Removing intermediate container dd532def866f
---> 20a93b435b70
Step 14/15 : EXPOSE 8080
---> Running in 791216126e87
Removing intermediate container 791216126e87
---> 6187b918f77d
Step 15/15 : CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /url/local/apache-tomcat-9.0.22/bin/logs/catalina.out
---> Running in 1aee1676f7d3
Removing intermediate container 1aee1676f7d3
---> 0c58fc779b7a
Successfully built 0c58fc779b7a
Successfully tagged dirtomcat:latest
启动容器,出现错误
启动镜像,ID出来,可是docker ps 发现没有运行
使用docker logs 容器ID 查看报错内容
出现 /bin/startup.sh:Pemission denied
解决方法
进入容器
#启动容器
[root@root tomcat]# docker run -it -d dirtomcat /bin/bash
f6dfac5e79aedf94afb79c9797aebb3f198a0b17a297b94ba72e5a686d7a0741
#查看正在运行的容器
[root@root tomcat]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f6dfac5e79ae dirtomcat "/bin/bash" 2 seconds ago Up 1 second 8080/tcp strange_keller
#进入容器
[root@root tomcat]# docker exec -it f6dfac5e79ae /bin/bash
[root@f6dfac5e79ae local]# ls
apache-tomcat-9.0.22 bin etc games include jdk1.8.0_11 lib lib64 libexec readme.txt sbin share src
#使用 startup.sh 命令 发现报错 原因是权限不够
[root@f6dfac5e79ae local]# startup.sh
bash: /usr/local/apache-tomcat-9.0.22/bin/startup.sh: Permission denied
#赋权 再启动 发现 catalina.sh 权限不够
[root@f6dfac5e79ae local]# chmod 777 /usr/local/apache-tomcat-9.0.22/bin/startup.sh
[root@f6dfac5e79ae local]# startup.sh
Cannot find /usr/local/apache-tomcat-9.0.22/bin/catalina.sh
The file is absent or does not have execute permission
This file is needed to run this program
#继续给 catalina.sh 赋权
[root@f6dfac5e79ae /]# chmod 777 /usr/local/apache-tomcat-9.0.22/bin/catalina.sh
#再次启动 tomcat 启动成功
[root@f6dfac5e79ae /]# startup.sh
Using CATALINA_BASE: /usr/local/apache-tomcat-9.0.22
Using CATALINA_HOME: /usr/local/apache-tomcat-9.0.22
Using CATALINA_TMPDIR: /usr/local/apache-tomcat-9.0.22/temp
Using JRE_HOME: /usr/local/jdk1.8.0_11
Using CLASSPATH: /usr/local/apache-tomcat-9.0.22/bin/bootstrap.jar:/usr/local/apache-tomcat-9.0.22/bin/tomcat-juli.jar
那么我们修改一下dockerfile文件内容
[root@root tomcat]# cat Dockerfile
FROM centos
MAINTAINER root<1754808@qq.com>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u11-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.22.tar.gz /usr/local/
RUN yum -y install vim
RUN chmod 777 /usr/local/apache-tomcat-9.0.22/bin/startup.sh
RUN chmod 777 /usr/local/apache-tomcat-9.0.22/bin/catalina.sh
ENV MYPATH /usr/local
WORKDIR $MYPATH
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_BASH /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out
构建镜像
docker build -t . # docker 构建镜像 拉取文件
[root@root tomcat]# docker build -t lh_tomcat .
Sending build context to Docker daemon 169.9MB
Step 1/17 : FROM centos
---> 300e315adb2f
Step 2/17 : MAINTAINER root<1754808103@qq.com>
---> Using cache
---> f23b466173fb
Step 3/17 : COPY readme.txt /usr/local/readme.txt
---> Using cache
---> 5dfad04cae31
Step 4/17 : ADD jdk-8u11-linux-x64.tar.gz /usr/local/
---> Using cache
---> e15afd0717d9
Step 5/17 : ADD apache-tomcat-9.0.22.tar.gz /usr/local/
---> Using cache
---> 8b3b0b260f0c
Step 6/17 : RUN yum -y install vim
---> Using cache
---> 731ad02de5b7
Step 7/17 : RUN chmod 777 /usr/local/apache-tomcat-9.0.22/bin/startup.sh
---> Using cache
---> e60e5bb8d68d
Step 8/17 : RUN chmod 777 /usr/local/apache-tomcat-9.0.22/bin/catalina.sh
---> Using cache
---> 1bdadcf5f05c
Step 9/17 : ENV MYPATH /usr/local
---> Running in dc5f851a95aa
Removing intermediate container dc5f851a95aa
---> 567826b1db9b
Step 10/17 : WORKDIR $MYPATH
---> Running in a1b9fa1f25c8
Removing intermediate container a1b9fa1f25c8
---> f2da44f2566d
Step 11/17 : ENV JAVA_HOME /usr/local/jdk1.8.0_11
---> Running in 1525576adae9
Removing intermediate container 1525576adae9
---> 422a260a9854
Step 12/17 : ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
---> Running in ff3679d3d0d7
Removing intermediate container ff3679d3d0d7
---> 1f2fb5b405ce
Step 13/17 : ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
---> Running in c627139c2a0e
Removing intermediate container c627139c2a0e
---> 941804071257
Step 14/17 : ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.22
---> Running in 201a8d7d454b
Removing intermediate container 201a8d7d454b
---> 6a3edac3ea02
Step 15/17 : ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
---> Running in 5403ebe0c029
Removing intermediate container 5403ebe0c029
---> 3de5361ec881
Step 16/17 : EXPOSE 8080
---> Running in a1e4f56c1cb5
Removing intermediate container a1e4f56c1cb5
---> 98fd728337df
Step 17/17 : CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out
---> Running in 3b183e06aecd
Removing intermediate container 3b183e06aecd
---> 9fcc0d5c6a4e
Successfully built 9fcc0d5c6a4e
Successfully tagged lh_tomcat:latest
实战测试
Docker Hub 中 99% 镜像都是从这个基础镜像过来的 FROM scratch,然后配置需要的软件和配置来进行构建的
#创建一个自己的centos
#编写Dockerfile 文件
[root@root dockerfile01]# cat mydockerfile
FROM centos
MAINTAINER Hang<1754808@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
#通过这个文件构建镜像
#docker build -f dockerfile文件路径 -t 镜像名:[tag] .
[root@root dockerfile]# docker build -f mydockerfile -t mycentos1.0 .
Removing intermediate container 59cd03ecce3f
---> 89ba49a34e1e
Step 7/10 : EXPOSE 80
---> Running in a1efee3b0fe2
Removing intermediate container a1efee3b0fe2
---> e58f7bcccc27
Step 8/10 : CMD echo $MYPATH
---> Running in e882afef45eb
Removing intermediate container e882afef45eb
---> 906c0671d05c
Step 9/10 : CMD echo "----END----"
---> Running in f4ecc2caf6af
Removing intermediate container f4ecc2caf6af
---> 6f4bef42e0fc
Step 10/10 : CMD /bin/bash
---> Running in 44f884f709c9
Removing intermediate container 44f884f709c9
---> e6062ccf13fd
Successfully built e6062ccf13fd
Successfully tagged mycentos1.0:latest
#测试运行
[root@root dockerfile]# docker run -it mycentos1.0 /bin/bash
[root@f408b8773605 local]# pwd
/usr/local
我们可以列出本地镜像的变更历史
[root@root dockerfile]# docker history mycentos1.0
IMAGE CREATED CREATED BY SIZE COMMENT
e6062ccf13fd 6 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B
6f4bef42e0fc 6 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
906c0671d05c 6 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B
e58f7bcccc27 6 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B
89ba49a34e1e 6 minutes ago /bin/sh -c yum -y install net-tools 23.4MB
2ba5aff6da20 6 minutes ago /bin/sh -c yum -y install vim 58.1MB
e34dc5e2146b 7 minutes ago /bin/sh -c #(nop) WORKDIR /usr/local 0B
bd4017671eca 7 minutes ago /bin/sh -c #(nop) ENV MYPATH=/usr/local 0B
f23b466173fb 7 minutes ago /bin/sh -c #(nop) MAINTAINER root<175480… 0B
300e315adb2f 6 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 6 weeks ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 6 weeks ago /bin/sh -c #(nop) ADD file:bd7a2aed6ede423b7… 209MB
CMD 和 ENTRYPOINT 区别
CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代
ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令
测试cmd
# 编写dockerfile文件
[root@root dockerfile]# vi dockerfile-cmd
FROM centos
CMD ["ls","-a"]
# 构建镜像
[root@root dockerfile]# docker build -f dockerfile-cmd -t cmd .
Sending build context to Docker daemon 3.072kB
Step 1/2 : FROM centos
---> 300e315adb2f
Step 2/2 : CMD ["ls","-a"]
---> Running in 711a369ca8ce
Removing intermediate container 711a369ca8ce
---> 96c1a6a5a855
Successfully built 96c1a6a5a855
Successfully tagged cmd:latest
# run 运行 发现我们的 ls -a 命令生效
[root@root dockerfile]# docker run 96c1a6a5a855
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
# 想追加一个命令 -l ls -al
[root@root dockerfile]# docker run 96c1a6a5a855 -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:370: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
# cmd 的情况下 -l 替换了 CMD ["ls","-a"] 命令 -l 不是命令 所以报错
测试ENTRYPOINT
vi dockerfile-entrypoint
docker build -f dockerfile-entrypoint -t entrypoint .
# 编写dockerfile文件
[root@root dockerfile]# vi dockerfile-entrypoint
# 构建镜像
[root@root dockerfile]# docker build -f dockerfile-entrypoint -t entrypoint .
Sending build context to Docker daemon 4.096kB
Step 1/2 : FROM centos
---> 300e315adb2f
Step 2/2 : ENTRYPOINT ["ls","-a"]
---> Running in 198ab82ed16c
Removing intermediate container 198ab82ed16c
---> 951f0c5be0f2
Successfully built 951f0c5be0f2
Successfully tagged entrypoint:latest
# run 运行 发现我们的 ls -a 命令生效
[root@root dockerfile]# docker run 951f0c5be0f2
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
# 想追加一个命令 -l ls -al 发现生效
[root@root dockerfile]# docker run 951f0c5be0f2 -l
total 0
drwxr-xr-x. 1 root root 6 Jan 22 16:08 .
drwxr-xr-x. 1 root root 6 Jan 22 16:08 ..
-rwxr-xr-x. 1 root root 0 Jan 22 16:08 .dockerenv
lrwxrwxrwx. 1 root root 7 Nov 3 15:22 bin -> usr/bin
drwxr-xr-x. 5 root root 340 Jan 22 16:08 dev
drwxr-xr-x. 1 root root 66 Jan 22 16:08 etc
drwxr-xr-x. 2 root root 6 Nov 3 15:22 home
lrwxrwxrwx. 1 root root 7 Nov 3 15:22 lib -> usr/lib
lrwxrwxrwx. 1 root root 9 Nov 3 15:22 lib64 -> usr/lib64
drwx------. 2 root root 6 Dec 4 17:37 lost+found
drwxr-xr-x. 2 root root 6 Nov 3 15:22 media
drwxr-xr-x. 2 root root 6 Nov 3 15:22 mnt
drwxr-xr-x. 2 root root 6 Nov 3 15:22 opt
dr-xr-xr-x. 240 root root 0 Jan 22 16:08 proc
dr-xr-x---. 2 root root 162 Dec 4 17:37 root
drwxr-xr-x. 11 root root 163 Dec 4 17:37 run
lrwxrwxrwx. 1 root root 8 Nov 3 15:22 sbin -> usr/sbin
drwxr-xr-x. 2 root root 6 Nov 3 15:22 srv
dr-xr-xr-x. 13 root root 0 Jan 22 13:11 sys
drwxrwxrwt. 7 root root 145 Dec 4 17:37 tmp
drwxr-xr-x. 12 root root 144 Dec 4 17:37 usr
drwxr-xr-x. 20 root root 262 Dec 4 17:37 var
拓展:Docker 逃逸漏洞(CVE-2020-15257)
见博客:[(16条消息) Docker 容器逃逸漏洞(CVE-2020-15257)复现_天问_Herbert555的博客-CSDN博客_docker 漏洞复现](https://blog.csdn.net/qq_44657899/article/details/120584394?ops_request_misc=%7B%22request%5Fid%22%3A%22165753617016782390541727%22%2C%22scm%22%3A%2220140713.130102334.pc%5Fall.%22%7D&request_id=165753617016782390541727&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~hot_rank-1-120584394-null-null.142v32new_blog_pos_by_title,185v2tag_show&utm_term=Docker 容器逃逸漏洞(CVE-2020-15257)&spm=1018.2226.3001.4187)
漏洞库(vulhub)(使用docker-compose、dockerfile搭建)
http://github.com/vulhub/vulhub.git
wget https://github.com/vulhub/vulhub/archive/master.zip -O vulhub-master.zip
unzip vulhub-master.zip
wxr-xr-x. 11 root root 163 Dec 4 17:37 run
lrwxrwxrwx. 1 root root 8 Nov 3 15:22 sbin -> usr/sbin
drwxr-xr-x. 2 root root 6 Nov 3 15:22 srv
dr-xr-xr-x. 13 root root 0 Jan 22 13:11 sys
drwxrwxrwt. 7 root root 145 Dec 4 17:37 tmp
drwxr-xr-x. 12 root root 144 Dec 4 17:37 usr
drwxr-xr-x. 20 root root 262 Dec 4 17:37 var
拓展:Docker 逃逸漏洞(CVE-2020-15257)
见博客:[(16条消息) Docker 容器逃逸漏洞(CVE-2020-15257)复现_天问_Herbert555的博客-CSDN博客_docker 漏洞复现](https://blog.csdn.net/qq_44657899/article/details/120584394?ops_request_misc=%7B%22request%5Fid%22%3A%22165753617016782390541727%22%2C%22scm%22%3A%2220140713.130102334.pc%5Fall.%22%7D&request_id=165753617016782390541727&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allfirst_rank_ecpm_v1~hot_rank-1-120584394-null-null.142v32new_blog_pos_by_title,185v2tag_show&utm_term=Docker 容器逃逸漏洞(CVE-2020-15257)&spm=1018.2226.3001.4187)
漏洞库(vulhub)(使用docker-compose、dockerfile搭建)
http://github.com/vulhub/vulhub.git
wget https://github.com/vulhub/vulhub/archive/master.zip -O vulhub-master.zip
unzip vulhub-master.zip