我对docker技术的理解:docker容器像一个小巧的“操作系统”,可以安装需要的服务,将应用放进去之后可以在里面运行,镜像就是创建容器的蓝图,规定了需要安装那些基础环境包。从镜像创建了容器之后,就可以导出镜像为一个文件进行传输,可以放在任意一个docker托管环境下运行。
1. Docker在Centos7服务器上的安装
1.1. 卸载旧版本docker
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
1.2. 安装docker
yum install -y docker-ce
yum是centos默认的软件包管理器,-y选项是直接安装不询问,docker-ce是docker的社区免费版本
1.3. 启动docker
sudo systemctl start docker // 启动docker
sudo systemctl enable docker // 设置开机启动docker
sudo systemctl status docker // 查看docker运行状态
2. 制作image
制作步骤:
1. 编写Dockerfile
2. docker build构建镜像
3. 实例化为容器
2.1. Dockerfile
制作image需要用到Dockerfile文件,需要自己创建,用来指定镜像要安装哪些软件包
Dockerfile主要包含以下的部分:
- 基础镜像:使用
FROM
指定,作为构建镜像的起点,基础镜像通常包含了操作系统和一些预装的软件和工具
- 构建过程指令:比如
RUN
用来执行命令,安装软件包等、COPY
用来拷贝文件和目录等、WORKDIR
用来设置工作目录等
- 容器启动指令:在最后的时候要在容器中将服务启动起来使用
CMD
或者ENTRYPOINT
常用格式:
FROM openjdk:17-jdk-slim
MAINTAINER XGSS
WORKDIR ./app
# 从主机当前目录复制文件到容器当前目录,即WORKDIR指定的目录
COPY app.jar .
# 可以不用指定
EXPOSE 8080
CMD ["java", "-jar", "app.jar"]
2.2. Docker image 创建
使用当前目录下的Dockerfile构建image
docker build -f Dockerfile -t my-java-image .
2.3. 查看image
docker image ls
docker images
2.4. 常用操作
- 删除镜像:
docker rmi image-name
- 强制删除镜像:
docker rmi -f image-name
- 查看镜像详细信息:
docker inspect image-name
- 给镜像打标签:
docker tag image-old image-new-name
打了标签之后,可以使用rmi删除原来的标签
- 重命名镜像:
docker tag image-old-name image-new-name
docker rmi image-old-name
3. 创建容器
docker run -d -p 8080:8080 --name container-name image-name
-d
:后台运行
-p
:指定端口映射规则,宿主机端口 : 容器端口(如果dockerfile中指定了expose的端口,就要用这个端口)
--name
:为容器取一个名字
-it
:以交互模式运行容器,并附加一个终端,如 docker run -it --name container image-name /bin/bash
--env / -e
:指定容器的环境变量,我用来连接其他的服务容器,如Redis、MySQL docker run -d --name container-name --env REDIS_SERVER=redis-server -p 80:8080
进入已经在运行的容器: docker exec -it container-name /bin/bash
3.1. 常用容器操作
- 启动容器:
docker start container-name
- 停止容器:
docker stop container-name
- 查看容器:
docker ps / docker ps -a
- 删除容器:
docker rm container-name
- 查看容器日志:
docker logs container-name
- 查看容器详细信息:
docker inspect container-name
- 容器重命名:
docker rename old-name new-name
4. 容器管理
4.1. Docker网络
Docker网络一般用到Bridge
模式,另外几个叫什么忘了,暂时用不上
- 创建网络:
docker network create -d bridge network-name
-d参数指定网络类型
- 查看所有网络:
docker network ls
- 查看网络详情:
docker network inspect network-name
- 创建容器的时候指定网络名:
docker run -d --name container-name --network network-name
创建容器的时候指定了网络参数等,就会持久化到该容器中,再次启动的时候就会使用创建时候指定的参数
- 将已存在的容器加入网络:
docker network connect network-name container-name
4.2. 环境变量的使用
如果需要多容器部署,需要在项目yml配置文件中指定需要用到的服务容器,如Redis、MySQL等容器的名字,如:
data:
redis:
host: ${redis-server}
port: 6379
然后将jar包打包成镜像后,创建容器时需要指定环境变量: docker run -d --name container-name --network network-name --env redis-server=redis-container-name
总结:需要使用-e
或--env
来指定环境变量的值,环境变量的占位符=目标容器名字
前提是能够找到这个容器,意思就是需要在同一个网络中
4.3. 自定义shell启动脚本
为了一键启动所有的服务,我手写了一个shell脚本,用来解决问题。其实更好的方案是交给docker compose
管理,但是目前就使用shell脚本也能完成需求:
#!/bin/bash
echo "Stopping running container..."
docker stop mysql-server redis-server rabbit-server baby-project-v3-container
echo "Starting database container..."
docker start mysql-server
sleep 3
echo "Starting redis container..."
docker start redis-server
echo "Starting rabbit container..."
docker start rabbit-server
echo "Starting application container..."
docker start baby-project-v3-container
echo "Application runs successfully!"
4.4. docker compose
4.5 docker镜像和容器的导入导出
因为近期服务器没法访问docker镜像源,所以需要进行镜像的迁移,就用到了容器和镜像的导入和导出
docker的导入导出操作命令都是成对的,主要的导入导出命令有两对:
save
/load
:导入导出镜像,一般用这个,但是保存完整记录,体积大。包括镜像的层和元数据都在里面,还有历史记录
export
/imoprt
:导入导出容器,一般不用,但是丢弃所有历史记录和元数据,及保存快照,导入的时候可以重新指定标签等元数据,体积较小。只导出容器的文件系统,没有层和元数据,甚至没有启动命令,所以在导入的时候需要手动指定启动命令,不然会报:
docker: Error response from daemon: no command specified.
See 'docker run --help'.
save和load
- 导出:有两种方式:一种是使用
-o
参数,另一种是使用重定向 >
运算符导入:
docker save -o image.tar image1_name image2_name // 可以将多个镜像打包成一个文件
docker save image_name > image.tar
- 导入:有两种导入方式:一种是使用
-i
参数,另一种是使用重定向运算符<
docker load -i image.tar
docker load < image.tar
eport和import
docker export <容器名> > <保存路径>
docker export container_name > container.tar
docker export -o <保存路径> 容器名
docker export -o container.tar container_name
- 导入:导入之后是一个镜像,import没有
-i
参数,只能用重定向。因为export
只导出容器的文件系统,不会导出元数据,所以需要手动添加启动命令/bin/bash
docker import - new_image < container.tar // 这个 - 表示从标准输入读取数据
docker run -itd new_image /bin/bash