docker 入门
一、安装docker
1 更新yum源
sudo yum update
2 安装需要的软件包
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
3 设置yum源(阿里云镜像)
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
4 安装docker
sudo yum install -y docker-ce docker-ce-cli containerd.io
5 启动docker、设置开机自启
sudo systemctl start docker
sudo systemctl enable docker
6 验证docker
docker version
7 卸载docker
# 停止运行
sudo systemctl stop docker
# 卸载软件包
sudo yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
# 移出镜像、容器、卷和配置文件
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
二、镜像操作
1 下载nginx镜像
docker pull nginx:latest
2 查看镜像
docker images
3 删除镜像命令
docker rmi nginx:latest
三、容器操作
1 启动容器
# -p 80:80 本地端口:容器端口
# docker run -d(后台运行) --name(运行容器的名称) --network(加入docker网络) 镜像名
docker run -d -p 80:80 --name mynginx nginx
2 查看运行中的容器
docker ps
# 查看所有运行过的镜像,包括停止的镜像
docker ps -a
3 进入容器操作
# docker exec -it 容器名|容器id bash
docker exec -it mynginx bash
4 停止运行中容器
# docker stop 容器名|容器id
docker stop mynginx
5 启动已停止的容器
# docker start 容器名|容器id
docker start mynginx
6 重启容器
# docker restart 容器名|容器id
docker restart mynginx
7 查看容器状态
# docker status 容器名|容器id
docker status mynginx
8 查看容器日志
# docker logs [-f] 容器名|容器id
docker logs mynginx
9 删除容器
# docker rm 容器名|容器id
docker rm mynginx
四、目录挂载
通过-v
参数来挂载容器和主机的目录(主机目录:
容器目录)
docker run -d -p 80:80 --name mynginx -v /data/nginx/html:/usr/share/nginx/html nginx:latest
五、卷映射
通过-v
参数,卷名:
容器目录
docker run -d -p 80:80 --name mynginx -v nginxconfig:/etc/nginx nginx:latest
:
左边的如果不以/
开头,不是一个目录格式,则认为是一个卷映射docker会将映射的卷统一创建在
/var/lib/docker/volumes/<volume-name>
- 目录挂载是容器以主机的目录为准,主机的目录是空的,容器内部的目录就是空的
- 卷映射以容器为准,会自动将容器的内容映射到对应的卷名称目录下
六、自定义网络
- docker会为每个容器分配唯一ip,使用容器ip+容器端口可以互相访问。但是每次启动容器,ip地址可能会发生变化。
- 可以创建一个docker容器可以互相通信的自定义网络,通过自定义网络每次就可以访问(类似于域名)
1 创建docker一个网络
docker network create mynet
2 查看已有docker网络
docker network ls
3 使用自定义网络
在启动时,通过--network
参数指定自定义网络。
docker run -d -p 80:80 --network mynet --name mynginx nginx:latest
在容器内需要互相通信时,就可以通过容器名访问。如http://mynginx:80
七、分享镜像
1 保存镜像
1.1 提交
# docker commit [options] 容器名称 镜像名:版本
docker commit -m "update message" mynginx mynginx01:v1.0
1.2 保存
# docker save -o filename.tar 镜像名:版本
docker save -o mynginx01.tar mynginx01:v1.0
1.3 加载
# docker load -i filename.tar
docker load -i mynginx01.tar
2 推送镜像到dockerhub
2.1 登陆
docker login
2.2 命名镜像
docker tag mynginx01:v1.0 cqsiri/mynginx:v1.0
2.3 推送镜像
docker push cqsiri/mynginx:v1.0
3 推送镜像到阿里云
3.1 阿里云创建docker镜像仓库
登录阿里云进入控制台-->容器镜像服务-->个人实例
创建命名空间
创建镜像仓库(仓库信息选择本地仓库)
创建完成后,会显示操作指南
3.2 推送镜像到阿里云镜像仓库
登录
# docker login --username=用户名 阿里云镜像仓库地址 docker login --username=cqsiri registry.cn-chengdu.aliyuncs.com
命名
# docker tag [镜像id] registry.cn-chengdu.aliyuncs.com/cqsiri/mytest:[镜像版本号] docker tag 72aa971801a3 registry.cn-chengdu.aliyuncs.com/cqsiri/mytest:1.0
推送
# docker push registry.cn-chengdu.aliyuncs.com/cqsiri/mytest:[镜像版本号] docker push registry.cn-chengdu.aliyuncs.com/cqsiri/mytest:1.0
阿里云查看镜像
八、DockerFile 构建镜像
1 DockerFile
FROM
基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是fromMAINTAINER
镜像维护者的姓名和邮箱地址RUN
容器构建时需要运行的命令,RUN是docker build时运行,有两种格式- shell格式,等同于在终端执行shell命令。例:RUN cat test.txt
- exec命令,例:RUN ["cat","test.txt"]
EXPOSE
当前容器暴漏的端口WORKDIR
指定登录容器终端的默认目录USER
指定该镜像以什么样的用户去执行,如果都不指定,默认是rootENV
运行时环境变量这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;也可以在其它指令中直接使用这些环境变量,
ADD
将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包COPY
类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置VOLUME
容器数据卷,用于数据持久化CMD
指定容器启动后要执行的命令。格式和RUN一致。Dockerfile 中可以有多个CMD指令,但只有最后一个生效,CMD 会被 docker run之后的参数替换。指定了ENTRYPOINT
后,CMD的内容会作为参数传递给ENTRYPOINT指令ENTRYPOINT
也是用来指定一个容器启动时要运行的命令,类似于 CMD指令。但是ENTRYPOINT不会被docker run后面的命令覆盖而且这些命令行参数会被当作参数送给ENTRYPOINT指令指定的程序
2 准备一个SpringBoot服务的jar包
2.1 简单的测试代码
@SpringBootApplication
public class DockerApplication {
public static void main(String[] args) {
SpringApplication.run(DockerApplication.class, args);
}
}
@RestController
class DockerController {
@GetMapping("/docker")
public String hello() {
return "docker-hello-" + LocalDateTime.now();
}
}
2.2 打包后传到docker所在的服务器
3 创建Dockerfile文件
# 基础镜像
FROM openjdk:8u111-jdk
# 镜像作者
MAINTAINER cqsiri
# 指定临时文件目录/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp
# 将jar包复制到容器内,并改名为docker-app.jar
ADD docker-app-1.0-SNAPSHOT.jar docker-app.jar
# 运行jar包
RUN bash -c 'touch /docker-app.jar'
# 运行jar包
ENTRYPOINT ["java","-jar","docker-app.jar"]
# 对外暴露8080端口
EXPOSE 8080
4 构建镜像
# docker build -t <镜像名称:版本号> .
# 最后一个点代表当前目录
# 执行前确保Dockerfile和jar包是在同一个目录的,因为Dockerfile文件里面复制jar包时的ADD没有指定目录
docker build -t docker-springboot-app:1.0 .
5 启动容器
docker run -d -p 8080:8080 docker-springboot-app:1.0
6 验证
curl localhost:8080/docker
7 将镜像推送到阿里云仓库
7.1 创建新的镜像仓库 docker-springboot-app

7.2 命名新镜像
docker tag 46a51fedb041 registry.cn-chengdu.aliyuncs.com/cqsiri/docker-springboot-app:1.0
7.3 推送镜像到阿里云仓库
docker push registry.cn-chengdu.aliyuncs.com/cqsiri/docker-springboot-app:1.0
7.4 查看阿里云镜像仓库,是否推送成功

九、Docker Compose
docker建议我们每一个容器中只运行一个服务,因为dccker容器本身占用资源极少,所以最好是将每个服务单的分割开来但是这样我们又面临了一个问题?如果需要同时部署好多个服务,难道要每个服务单独Dockerfile然后在构建镜像,构建容器,这样就比较繁琐,步骤过多就容器出错。 Compose允许用户通过一个单独的docker-compose.yaml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project) 然后使用一条指令安装这个应用的所有依赖,完成构建,Docker-Compose 解决了容器与容器之间如何管理编排的问题。
1 Compose下载
# 下载
curl -SL https://github.com/docker/compose/releases/download/v2.30.3/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
# 赋权
chmod +x /usr/local/bin/docker-compose
# 查看安装是否成功
docker-compose --version
2 准备应用镜像(SpringBoot 服务)
构建一个简单的SpringBoot服务,通过redis统计到访问的人数
2.1 pom.xml
<!-- springboot-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- springboot-data-redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2.2 application.yaml
spring:
redis:
# 直接通过docker网络访问,同一网络通过容器名称就可以访问到
host: compose-redis
port: 6379
2.3 web层
@RestController
public class DockerController {
@Autowired
RedisTemplate redisTemplate;
@GetMapping("/count")
public String hello() {
String key = "account_number";
ValueOperations ops = redisTemplate.opsForValue();
Object obj = ops.get(key);
if (null == obj) {
obj = 1;
} else {
obj = (Integer) obj + 1;
}
ops.set(key, obj);
return "服务一共被访问:\t" + obj + "\t次。。。";
}
}
2.4 Dockerfile
# 基础镜像
FROM openjdk:8u111-jdk
# 镜像作者
MAINTAINER cqsiri
# 指定临时文件目录/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp
# 将jar包复制到容器内,并改名为docker-app.jar
ADD docker-app-1.0-SNAPSHOT.jar docker-app.jar
# 运行jar包
RUN bash -c 'touch /docker-app.jar'
# 运行jar包
ENTRYPOINT ["java","-jar","docker-app.jar"]
# 对外暴露8080端口
EXPOSE 8080
2.5 通过Dockerfile构建镜像
将应用jar包和Dockerfile传到服务器同一目录,执行构建命令
docker build -t docker-app:1.0 .
2.6 查看镜像是否构建成功
docker images docker-app
3 准备redis配置文件
7.0.13版本文件 https://github.com/redis/redis/blob/7.0.13/redis.conf
# 创建redis 配置文件目录
mkdir -p /data/docker/redis && cd /data/docker/redis
# 创建配置文件
touch redis.conf
# 编辑配置问及那
vim redis.conf
复制配置文件内容,并修改以下配置
# bind 127.0.0.1 -::1
protected-mode no
4 准备compose.yaml文件
version : "3"
services:
docker-app:
image: docker-app:1.0
container_name: compose-app
ports:
- "8080:8080"
networks:
- compose-net
depends_on:
- redis
redis:
image: redis:7.0.13
container_name: compose-redis
ports:
- "6379:6379"
volumes:
- /data/docker/redis/redis.conf:/etc/redis/redis.conf
networks:
- compose-net
command: redis-server /etc/redis/redis.conf
networks:
compose-net:
5 通过compose启动容器
docker-compose up -d
6 验证
# 查看容器是否启动成功
docker ps
# 查看docker网络是否创建
docker network ls
# 访问多次应用
curl localhost:8080/count
7 docker-compose 常用命令
- docker-compose -h # 查看帮助
- docker-compose up # 启动所有docker-compose服务
- # 启动所有docker-compose服务并后台运行
- # 停止并删除容器、网络、卷、镜像
- docker-compose exec yml里面的服务id #进入容器实例内部 docker-compose exec docker-compose.yml文件中写的服务id /bin/bash
- docker-compose ps #展示当前docker-compose编排过的运行的所有容器 docker-compose top #展示当前docker-compose编排过的容器进程
- docker-compose logs yml里面的服务id #查看容器输出日志
- #检查配置
- #检査配置,有问题才有输出
- docker-compose restart #重启服务
- docker-compose start #启动服务
- docker-compose stop #停止服务
十、portainer Docker可视化工具
1 安装
docker run -d -p 8000:8000 -p 9000:9000 \
--restart=always \
--name portainer \
# 加上这个才能识别到本机的docker
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest
2 登录
ip:9000
2.1 创建用户
2.2 进入dashborad


- Stacks:通过Componse编排的容器
- Containers:容器
- Images:镜像
- Volumes:挂载、数据卷
- Networks:网络