概述

出现

一款产品需要开发&上线 两套环境
java —jar(环境) —打包项目带上环境(镜像) —docker仓库(商店) —直接下载镜像即可运行

概念

镜像(image)

  • 类比模板,通过这个模板来创建容器服务
  • 可以创建多个容器
  • 最终服务运行或者项目运行是在容器中的
    eg.tomcat镜像->run->tomcat01容器(提供服务器)

容器(container)

独立运行一个或者一个组应用 ->通过镜像来创建

仓库(repository)

存放镜像的地方


底层原理

如何工作?

Docker是一个 Client-Server 结构的系统,Docker守护进程在主机中,通过Socket从客户端访问

从客户端发出指令,DockerServer收到指令后去执行


使用

基本命令

1
2
3
4
5
查看状态: systemctl status docker 
拉取镜像: docker run hello-world
查看所有镜像: docker images
卸载: yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker

Docker常用命令

帮助命令

docker info:显示docker系统信息,包括镜像和容器


镜像命令

1
2
3
4
5
6
7
查看镜像: docker images
搜索镜像: docker search eg.docker search mysql
拉取镜像: docker pull 镜像名[:tag] eg.docker pull mysql
删除镜像:
删除单个: docker rmi -f 所删镜像ID
删除多个镜像: docker rmi -f 所删镜像ID 所删镜像ID 所删镜像ID
全部删除: docker rmi -f $(docker images -aq)

容器命令

1
新建容器并启动: docker run [可选参数] image

参数说明:
--name="Name" 容器名称 mysql01 mysql02 … 区分容器
-d:后台运行
-it:交互式运行
-p 主机端口号:容器端口号:映射端口
-p ip:端口号:容器端口号
-p 容器端口
-P:随机映射端口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
列出当前正在运行的容器: docker ps 命令
列出所有容器: docker ps -a

容器停止并退出: exit
容器停止但不退出: ctrl+p+q

删除容器: docker rm 容器ID
删除所有容器: docker rm -f $(docker ps -aq)
删除所有容器: docker ps -a -q | xargs docker rm

docker start 容器ID
若要交互式的 -> docker start 后 docker attach或docker exec(该命令后面参数和docker run一样)
docker exec -it 容器ID/名 /bin/bash
docker stop 容器ID
docker restart 容器ID
docker kill 容器ID

栗子

创建并启动

docker run -it --name="Centos" centos /bin/bash
exit

进入容器

docker start Centos
docker exec Centos /bin/bash


常用其他命令

后台启动容器

docker run -d 镜像名
docker使用后台运行就必须要有一个前台进程,否则会自动停止

查看日志

docker logs -f 容器ID
自己写个shell脚本 监控日志
docker run -d centos /bin/bash -c "while true;do echo $(date);sleep 1;done"

查看容器进程信息

docker top 容器ID

查看镜像元数据

docker inspect 镜像ID

进入容器

容器通常都是后台运行的
docker exec -it 容器ID /bin/bash:开启新的终端
docker attach 容器ID:进入正在执行的终端

从容器中拷贝文件到主机

docker cp 容器ID:容器路径 主机路径


commit镜像

docker commit提交容器成为一个新的副本
docker commit -m "提交的描述信息" -a "作者" 容器ID 目标的镜像名:[Tag]

栗子

创建tomcat_latest后,官方镜像默认webapps下没有文件,我自己拷贝进去了基本文件
docker commit -m "add webapps app" -a "Assass1n" 7d8012f2142d tomcat_addwebapps:1.0
提交为一个修改了的镜像

若想保存当前容器状态,即可通过commit提交来获取一个镜像


容器数据卷

实现容器之间的共享技术,使数据持久化,不因删除容器而使数据丢失
同步数据到本地 -> 将容器内目录挂载到linux

使用卷

docker run -it -v 主机目录:容器目录 镜像名 /bin/bash
容器一旦创建就无法挂载卷
通过docker inspect 容器ID查看容器的卷信息
docker volume ls查看所有卷的情况


Source:主机内地址
Destination:容器内地址

具名挂载&匿名挂载

匿名

只写容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx

具名 卷名:容器内路径(常用)

docker run -d -P --name nginx02 -v nginx_name:/etc/nginx nginx
查看一下这个卷可以知道在主机的路径docker volume inspect nginx_name
所有的docker容器内的卷,没有指定目录的情况下一般都存在主机/var/lib/docker/volumes/volume_name/_data

-v 容器内路径:ro / rw
改变读写权限
一旦设定该权限,容器被挂载的内容就设定了

docker run -d -P --name nginx02 -v nginx_name:/etc/nginx:ro nginx

手动挂载:-v 卷名:容器目录
ro:这个路径只能通过宿主机来操作,容器内部不可操作


数据卷挂载

容器间的同步
先创一个父容器,docker01->数据卷容器
docker run -it --name docker01 dockerfile/centos:1.0

挂载子容器docker02
docker run -it --name docker02 --volume-from docker01 dockerfile/centos:1.0
docker run -it --name docker03 --volume-from docker01 dockerfile/centos:1.0
删掉docker01,docker02和docker03的数据仍然保存且同步


DockerFile

栗子

构建docker镜像的构建文件
命令脚本 -> 通过命令生成镜像
在主机上写一个命令脚本(若dockerfile1 <- 命名)
docker build -f dockerfile1 -t 自定义镜像名:tag .

dockerfile内容:指令(大写) 参数
每一个命令就是镜像的一层

eg.

1
2
3
4
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "hello world"
CMD /bin/bash

docker run -it 镜像id /bin/bash


在主机上查看该路径,同步成功


DockerFile构建过程 ->可看作源代码

基础

  • 指令必须为大写字母
  • 从上到下顺序执行
  • ‘#’ ->注释
  • 每个指令都会创建一个新的镜像并提交

指令

1
2
3
4
5
6
7
8
9
10
11
12
13
FROM   # 基础镜像 eg. centos:latest
MAINTAINER # 镜像是谁写的 name+email
RUN # 镜像构建是需要执行的命令 eg. RUN yum install -y nginx
ADD # 添加文件或目录
WORKDIR # 设置工作目录
COPY # 复制文件或目录
VOLUME # 挂载的目录
EXPOSE # 暴露端口
CMD # 指定容器启动时要运行的命令 只有最后一个会生效,可被替代
ENTRYPOINT # 指定容器启动时要运行的命令 可以追加命令
ONBUILD # 当构建其他镜像时,基础镜像为有此命令的镜像时触发
COPY # 类似ADD 将文件拷贝到镜像
ENV # 构建时设置环境变量

栗子

部署Tomcat

docker pull tomcat
docker run -d -p 3355:8080 --name="tomcat_latest" tomcat

进入容器

docker exec -it tomcat_latest /bin/bash

构建自己的Centos

mydockerfile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
FROM centos
MAINTAINER Assass1n<1783921974@qq.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH

RUN cd /etc/yum.repos.d/ && mkdir backup && mv *repo backup/
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-8.repo
RUN sed -i -e "s|mirrors.cloud.aliyuncs.com|mirrors.aliyun.com|g " /etc/yum.repos.d/CentOS-*
RUN sed -i -e "s|releasever|releasever-stream|g" /etc/yum.repos.d/CentOS-*
RUN yum clean all && yum makecache

RUN yum -y install vim
RUN yum -y install net-tools

EXPOSE 80

CMD echo $MYPATH
CMD echo "----end----"
CMD /bin/bash

利用Dockerfile创建Tomcat镜像

Dockerfile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
FROM centos
MAINTAINER Assass1n<1783921974@qq.com>

COPY readme.txt /usr/local/readme.txt

ADD jdk-8u441-linux-x64.tar.gz /usr/local
ADD apache-tomcat-9.0.102.tar.gz /usr/local

RUN cd /etc/yum.repos.d/ && mkdir backup && mv *repo backup/
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-8.repo
RUN sed -i -e "s|mirrors.cloud.aliyuncs.com|mirrors.aliyun.com|g " /etc/yum.repos.d/CentOS-*
RUN sed -i -e "s|releasever|releasever-stream|g" /etc/yum.repos.d/CentOS-*
RUN yum clean all && yum makecache

RUN yum -y install vim
RUN chmod +x /usr/local/apache-tomcat-9.0.102/bin/startup.sh

ENV MYPATH /usr/local
WORKDIR $MYPATH

ENV JAVA_HOME /usr/local/jdk1.8.0_441
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.102
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.102
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin

EXPOSE 8080

CMD /usr/local/apache-tomcat-9.0.102/bin/startup.sh run && tail -f /usr/local/apache-tomcat-9.0.102/logs/catalina.out

启动容器

1
docker run -dit -p 9090:8080 --name tomcatitest -v /home/dockerLearn/project/tomcat/test:/usr/local/apache-tomcat-9.0.102/webapps/test -v /home/dockerLearn/project/tomcat/tomcatlogs:/usr/local/apache-tomcat-9.0.102/logs mytomcat

进入容器

1
docker exec -it tomcatitest /bin/bash

访问

1
2
3
4
5
|--webapps
|--test
|--WEB-INF
|--web.xml
|--index.jsp

web.xml的内容要与index.jsp的内容对应,否则会访问不到。

index.jsp样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Assass1n's tomcat</title>
</head>
<body>
Hello World!<br/>
<%
System.out.println("Success!Here is your flag!");
%>
</body>
</html>

web.xml样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">

<!-- Servlet 定义 -->
<servlet>
<servlet-name>jsp</servlet-name>
<jsp-file>/index.jsp</jsp-file>
</servlet>

<!-- Servlet 映射 -->
<servlet-mapping>
<servlet-name>jsp</servlet-name>
<url-pattern>/index.jsp</url-pattern>
</servlet-mapping>

<!-- 会话超时设置(分钟) -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>

<!-- 欢迎文件列表 -->
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>

<!-- 错误页面 -->
<error-page>
<error-code>404</error-code>
<location>/error404.html</location>
</error-page>

<error-page>
<error-code>500</error-code>
<location>/error500.html</location>
</error-page>

</web-app>