- 一.Docker镜像
- 1.镜像
- 1.准备docker服务器
- 2.下载镜像
- 3.镜像的名称
- 4.导出和导入镜像
- 二.从镜像运行启动容器
- 1.从镜像运行启动容器
- 2.容器启动后运行的命令
- 3.ENTRYPOINT 和 CMD
- 4.启动容器时覆盖 ENTRYPOINT 和 CMD
- 5.-d 后台运行
- 6.docker exec 进入容器,运行指定命令
- 7.--name 和 --restart=always
- 8.--rm 和 docker cp
- 三.文件挂载
- 1.-v 目录挂载
- 2.数据卷挂载
- 四.网络
- 1.端口映射
- 2.虚拟网络
- 六.构建镜像
- 1.构建镜像
- 2.准备必要的文件
- 3.Dockerfile
- 4.执行构建
- 5.查看构建结果:
- 6.启动容器
- 七.docker案例
- 1.关闭防火墙
- 2.启动或重启docker
- 3.redis
- 3.jedis 连接测试
- 3.1新建测试项目
- 3.2pom.xml
- 3.2编写测试类
- 3.4在容器中查看数据
- 3.5启动多个 redis 容器
Docker 镜像是一组静态磁盘文件,可以任意下载、复制、分发。从镜像可以运行启动容器(Docker的虚拟计算机)。
-
克隆 docker-base: docker
-
设置ip
./ip-static ip: 192.168.64.150 ifconfig
-
上传文件到 /root/
- docker-images.gz
- tomcat 文件夹
-
导入镜像:
docker load -i docker-images.gz docker images
从镜像仓库 https://hub.docker.com 下载镜像:
# 下载 redis 镜像, 默认下载 redis:latest docker pull redis:5.0.12 # 查看镜像列表 docker images3.镜像的名称
镜像的名称由两部分组成:repository:tag,其中的 tag 一般用来表示版本,默认的 tag 是 latest,表示最近的版本。
镜像的名称相当于在镜像上贴的一个标签,在一个镜像上可以贴多个标签:
添加名称:
# 镜像可以起另一个名称,名称格式: repository:tag # 默认的 tag 是 latest docker tag redis:5.0.12 tedu/redis:v5012 # 查看镜像 # 可以看到同一个镜像(ID相同)可以有多个名称 docker images | grep redis
删除:
镜像的名称可以被删除,只有唯一的一个名称时会删除镜像:
docker rmi redis:5.0.12
# 查看镜像 # 可以看到镜像名称已经被删除 docker images | grep redis
只有唯一的一个名称时会删除镜像:
docker rmi tedu/redis:v50124.导出和导入镜像
导出镜像并压缩到压缩文件:
# 把两个镜像 redis:latest 和 centos:8 导出,并压缩到 imgs.gz docker save redis centos:8 | gzip > imgs.gz
导入镜像:
docker load -i imgs.gz二.从镜像运行启动容器 1.从镜像运行启动容器
从一个镜像可以运行启动一个或多个容器。
所谓容器,我们可以理解为是一个虚拟的计算机,其中运行着操作系统,操作系统中运行着我们部署的应用。
从 tomcat 镜像启动容器:
docker run tomcat
容器启动后在容器中运行了 tomcat 应用。
这样启动会占用命令行,可以用 ctrl+c 退出 tomcat 应用。当容器中没有任何应用运行时,容器也会自动关闭退出。
查看容器:
docker ps -a2.容器启动后运行的命令
容器启动后需要运行指定的命令来启动一个应用。
在镜像中指定的默认运行命令:
docker history tomcat
tomcat 镜像中设置的 CMD 指令指定了容器启动后默认运行的命令: catalina.sh run。
再来看看其他镜像中设置的默认命令:
docker history redis --------------------------------------------------------------------------------- [root@localhost ~]# docker history redis IMAGE CREATED CREATED BY SIZE bc8d70f9ef6c 3 weeks ago /bin/sh -c #(nop) CMD ["redis-server"] 0B3.ENTRYPOINT 和 CMD3 weeks ago /bin/sh -c #(nop) EXPOSE 6379 0B 3 weeks ago /bin/sh -c #(nop) ENTRYPOINT ["docker-entry… 0B docker history mariadb --------------------------------------------------------------------------------- [root@localhost ~]# docker history mariadb IMAGE CREATED CREATED BY SIZE eff629089685 13 days ago /bin/sh -c #(nop) CMD ["mysqld"] 0B 13 days ago /bin/sh -c #(nop) EXPOSE 3306 0B 13 days ago /bin/sh -c #(nop) ENTRYPOINT ["docker-entry… 0B docker history centos:8 ---------------------------------------------------------------------------------- [root@localhost ~]# docker history centos:8 IMAGE CREATED CREATED BY SIZE 300e315adb2f 6 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
这两向设置都是用来设置容器中运行的命令。
只设置 CMD 来执行 ls -a -l:
CMD ["ls", "-a", "-l"]
只设置 CMD 是常见的用法。
用 ENTRYPOINT 和 CMD 两个一起设置来执行 ls -a -l:
ENTRYPOINT [“ls”]
CMD ["-a", “-l”]
1
2
两项一起设置时,会把两项设置的内容连接起来作为一个完整的命令。
覆盖 CMD:
以 tomcat 镜像为例,镜像中设置的默认命令是 catalina.sh run,可以任意指定命令覆盖这个默认命令,这里执行 ls -a -l 来测试:
docker run tomcat ls -a -l
覆盖 ENTRYPOINT:
–entrypoint:设置运行的命令,不许写在镜像名称 tomcat 的前面。注意,这里不能添加命令的参数;
镜像名称 tomcat 后面的内容会覆盖 CMD
docker run --entrypoint ls tomcat -a -l
5.-d 后台运行后台运行启动 tomcat 容器:
docker run -d tomcat
查看后台运行的容器:
# 只查看运行的容器 docker ps # 查看所有容器,包括已停止的容器 docker ps -a # 仅列出容器的 id docker ps -aq
查看容器的日志:
可以使用容器的名称或 id,使用id是允许至少写三位,能与其他id区分即可
docker logs 4d36.docker exec 进入容器,运行指定命令
绝大多数情况下一个容器中只运行一个应用。
容器中也允许运行启动多个应用,可以进入已经启动的容器, 在里面运行启动其他应用:
# 进入容器,运行指定的命令 docker exec -it 4d3 pwd docker exec -it 4d3 touch f1.txt docker exec -it 4d3 ls -l # 启动 top 查看进程列表 # ctrl+c 可以退出top docker exec -it 4d3 top # 启动bash命令行 # exit 可以退出bash docker exec -it 4d3 bash7.–name 和 --restart=always
–name:
每个启动的容器都可以指定一个名称,方便使用名称来操作容器。
–restart=always:
docker系统服务重启,或者操作系统重启,容器可以随系统自动启动。
# cat1容器可以随系统启动 docker run -d --name cat1 --restart=always tomcat # cat2系统重启后默认是关闭状态,不会自动启动 docker run -d --name cat2 tomcat # 查看容器 docker logs cat1 docker inspect cat1 # 重启docker系统服务 systemctl restart docker # 查看容器,可以看到 cat1 自动重启了,而 cat2 处于关闭状态 docker ps -a8.–rm 和 docker cp
–rm:
有时候我们会临时使用一个容器之后这个容器就不再使用,添加 --rm 参数可以在容器停止时自动删除容器
docker cp:
在容器和宿主机之间复制文件
下面来看一个实际的例子,这个例子中我们从 tomcat 的一个临时容器复制配置文件 server.xml 到宿主机,然后在 server.xml 中修改端口号,把 8080 改成 80。
# 启动一个临时容器 docker run -d --rm --name tmp tomcat # 把 tomcat 的 server.xml 复制到宿主机的 /root/ 目录下 docker cp tmp:/usr/local/tomcat/conf/server.xml /root/ # 停止临时容器,会自动删除 docker stop tmp docker ps -a # 修改 server.xml 中的8080端口,改成80 vim server.xml # -v 把宿主机路径挂载到容器的一个路径 # 挂载的路径可以是文件,也可以是文件夹 # 这里把修改过的 server.xml 挂载到新启动的容器中 docker run -d --name cat2 -v /root/server.xml:/usr/local/tomcat/conf/server.xml tomcat # 查看启动日志,确认使用 80 端口启动 docker logs cat2三.文件挂载 1.-v 目录挂载
上面例子中用到 -v 参数,他可以将宿主机的路径挂载到容器指定路径,通过 -v 参数可以挂载文件、目录和数据卷。
挂载目录:
# 清理容器 docker rm -f $(docker ps -aq) # -v 宿主机路径:容器路径 # 挂载的可以是文件,也可以是文件夹 # -v 可以在宿主机自动新建目录 docker run -d --name cat1 -v /usr/app:/opt/app tomcat # 进入容器,在 /opt/app 下新建文件 f1.txt docker exec -it cat1 bash touch /opt/app/f1.txt # 退出容器的命令行 exit # 访问宿主机的文件夹 cd /usr/app ls2.数据卷挂载
# 新建数据卷 docker volume create my-vol # 查看 my-vol 数据卷的信息 docker volume ls # /var/lib/docker/volumes/my-vol/_data docker inspect my-vol # 挂载 my-vol 数据卷到容器的 /opt/app 路径 docker run -d --name cat2 -v my-vol:/opt/app tomcat # 在容器的 /opt/app 下新建 f2.txt docker exec -it cat2 bash touch /opt/app/f2.txt # 退出容器的命令行 exit # 进入 my-vol 数据卷的真实目录,查看 f2.txt cd /var/lib/docker/volumes/my-vol/_data ls四.网络 1.端口映射
客户端要访问宿主机内部运行的容器时,可以在宿主机打开一个端口,当客户单访问这个端口时,可以将访问转发到内部的容器。
-p 参数:
通过 -p 参数设置,可以在宿主机上选择一个端口映射到容器的端口。
# 清理容器 docker rm -f $(docker ps -aq) # 端口映射 # -p 宿主机端口:容器端口 docker run -d --name cat1 -p 80:8080 tomcat
浏览器访问宿主机映射的端口 80
http://192.168.64.150
看到 tomcat 返回的 404 页,说明已经正常访问到 tomcat 容器
2.虚拟网络
容器键互联可以使用 Docker 的虚拟网络来连接。
在 Docker 中可以创建任意多个虚拟网络,容器之间可以通过虚拟网络互联互通。创建虚拟网络时宿主机也会连接到虚拟网络。
# 新建虚拟网络 my-net docker network create my-net # 查看虚拟网络 docker network ls # 查看网络描述信息 docker inspect my-net # 查看宿主机新建的虚拟网卡 ifconfig # 清理容器 docker rm -f $(docker ps -aq) # 新建两个容器 cat1 和 cat2 # 连接到虚拟网络 my-net docker run -d --name cat1 --net my-net tomcat docker run -d --name cat2 --net my-net tomcat # 查看两个容器的虚拟网络ip docker inspect cat1 docker inspect cat2 # 测试网络能否互联互通 # 从宿主机ping两个容器 ping 172.18.0.2 ping 172.18.0.3 # 进入cat1,ping宿主机和cat2 docker exec -it cat1 ping 172.18.0.1 docker exec -it cat1 ping 172.18.0.3 # 从容器访问另一个容器,可以使用容器名称访问,容器内部实现了解析环境 docker exec -it cat1 ping cat2六.构建镜像
文件下载
构建镜像类似于一台电脑的装机过程,添加文件、安装软件、配置环境…
例如构建一个 tomcat 10 镜像流程,就像在一台电脑上安装配置 tomcat 环境一样:
选择基础镜像 centos:8(相当于一台新电脑,只有操作系统)
添加 jdk 和 tomcat 文件
设置环境变量
设置开机启动 tomcat
下面来演示构建 tomcat 10 镜像的过程:
jdk 和 tomcat 10 的压缩文件放入一个文件夹中,这个文件夹不应该包含其他无关文件:
[/root/tomcat/]
- jdk-8u291-linux-x64.tar.gz
- apache-tomcat-10.0.6.tar.gz
3.Dockerfile
Dockerfile 类似于一个批处理文件,用来设置镜像的构建流程
在上一步的 tomcat 文件夹下创建 Dockerfile 文件:
[/root/tomcat/]
- jdk-8u291-linux-x64.tar.gz
- apache-tomcat-10.0.6.tar.gz
- Dockerfile
编辑 Dockerfile 文件
cd /root/tomcat vim Dockerfile
在文件中添加以下内容:
# 选择基础镜像
FROM centos:8
# jdk 和 tomcat 文件添加到镜像的 /usr/local/ 目录下
# ADD 指令会自动解压文件
ADD jdk-8u291-linux-x64.tar.gz apache-tomcat-10.0.6.tar.gz /usr/local/
# 切换到镜像中指定的文件夹下
WORKDIR /usr/local/apache-tomcat-10.0.6/
# 设置环境变量
ENV JAVA_HOME=/usr/local/jdk1.8.0_291
CATALINA_HOME=/usr/local/apache-tomcat-10.0.6
PATH=/usr/local/jdk1.8.0_291/bin:/usr/local/apache-tomcat-10.0.6/bin:$PATH
# EXPOSE 8080 只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务
# 这个声明有两个好处:
# 1.帮助镜像使用者理解这个镜像服务的端口,以方便配置映射
# 2.在运行时使用随机端口映射时,也就是 docker run -P时,会自动随机映射 EXPOSE 的端口
EXPOSE 8080
# 设置启动命令
CMD ["catalina.sh", "run"]
Dockerfile 指令参考手册:
进入 tomcat 文件夹,并在当前文件夹下找到 Dockerfile 和其他需要的文件,来构建镜像:
cd /root/tomcat # 使用当前文件夹中的 Dockerfile 文件进行构建 # 新构建的镜像命名为 tomcat:10 docker build -t tomcat:10 ./5.查看构建结果:
docker images docker history tomcat:10 docker inspect tomcat:106.启动容器
docker run -d --name cat1 -p 8080:8080 tomcat:10 docker ps -a docker logs cat1
浏览器访问测试:
# 关闭防火墙 systemctl stop firewalld.service # 禁止防火墙开机启动 systemctl disable firewalld.service2.启动或重启docker
# 启动docker systemctl start docker # 重启docker systemctl restart docker3.redis
加载镜像
docker load < redis-docker-image.gz
启动容器
docker run -d --name redis7000 -p 7000:6379 redis
用 tomcat:10 运行 helloworld web应用
- 准备 jsp 文件
mkdir /opt/web
vim /opt/web/index.jsp
添加内容:
Hello wolrd!
Hello ${param.name}!
-
启动 tomcat:10 容器
docker run -d --name web
–restart=always
-p 80:8080
-v /opt/web:/usr/local/apache-tomcat-10.0.6/webapps/ROOT
tomcat:10 -
访问 http://192.168.64.150 、 http://192.168.64.150/?name=zhangsan
添加 redis 和 junit 依赖
3.2编写测试类4.0.0 cn.tedu docker 0.0.1-SNAPSHOT redis.clients jedis 2.9.0 junit junit 4.12
package test;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
import java.util.ArrayList;
import java.util.List;
public class Test1 {
public static void main(String[] args) {
// 服务器地址列表
List list = new ArrayList<>();
list.add(new JedisShardInfo("192.168.64.150", 7000));
list.add(new JedisShardInfo("192.168.64.150", 7001));
list.add(new JedisShardInfo("192.168.64.150", 7002));
// 配置对象
GenericObjectPoolConfig cfg = new JedisPoolConfig();
// 新建 ShardedJedisPool
ShardedJedisPool pool = new ShardedJedisPool(cfg, list);
// 使用连接池创建一个数据操作对象
ShardedJedis j = pool.getResource();
// 循环添加100条数据
for (int i = 0; i < 100; i++) {
j.set("k"+i, "v"+i);
}
}
}
3.4在容器中查看数据
# 进入容器 docker exec -it redis7000 bash # 运行redis客户端工具 redis-cli
127.0.0.1:6379> keys * 1) "key1" 127.0.0.1:6379> get key1 "value1"3.5启动多个 redis 容器
启动三个redis容器,将端口分别映射到7000,7001和7002端口
# 如果7000已经启动,不必重复启动 docker run -d --name redis7000 -p 7000:6379 redis docker run -d --name redis7001 -p 7001:6379 redis docker run -d --name redis7002 -p 7002:6379 redis # 查看容器 docker ps -a
[root@localhost ~]# docker ps -a ConTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 756f5227dd64 redis "docker-entrypoint.s…" 6 seconds ago Up 4 seconds 0.0.0.0:7001->6379/tcp redis7001 bc87e35664c8 redis "docker-entrypoint.s…" 13 seconds ago Up 11 seconds 0.0.0.0:7002->6379/tcp redis7002 c3700e3e4c73 redis "docker-entrypoint.s…" 2 hours ago



