docker 学习
docker 安装
# 开机启动 docker
systemctl enable docker
# 启动 docker
systemctl start docker
配置阿里云加速
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["这里替换成自己的阿里云镜像加速器地址"]
}
EOF
systemctl daemon-reload
systemctl restart docker
docker 核心概念
镜像:images
定义:一个镜像代表一个软件。
特点:只读
容器:container
定义:基于某个镜像启动的一个实例称为一个容器。一个镜像可以产生多个容器。
特点:可读可写
仓库:repository
定义:用来存储docker中的所有镜像具体位置。
远程仓库:docker在世界范围维护一个唯一远程仓库
本地仓库:当前自己机器中下载镜像存储位置
docker常见命令
辅助命令
# 安装完成辅助命令
docker version # 查看docker的信息
docker info # 查看更详细的信息
docker --help # 帮助命令
Images镜像命令
1. 查看本机中的所有命令
docker images -a # 列出所有镜像
-q # 只显示镜像id
2. 搜索镜像
docker search 镜像名
-s 指定值 # 列出收藏数不少于指定值的镜像
--no-trunc # 显示完整的镜像信息
3. 从仓库下载镜像
docker pull 镜像名[:TAG|@DIGEST] # 下载镜像
4. 删除镜像
docker rmi 镜像名 # 删除镜像
-f # 强制删除
Container 容器基本操作(一)
# 1. 运行容器
docker run 镜像名 # 镜像名新建并启动容器
--name # 别名为容器起一个名字
-d # 启动守护式容器(在后台启动容器)
-p # 映射端口号:原始端口号 指定端口号启动
例:
docker run -it --name myTomcat -p 8888:8080 tomcat
docker run -d --name myTomcat -p tomcat
# 2. 查看当前运行的容器
docker ps 查看正在运行容器
docker ps -a 查看所有容器(运行 & 非运行)
docker ps -q 查看正在运行容器id
docker ps -qa 查看所有容器id(运行 & 非运行)
# 3. 停止,重启容器的命令
docker start 容器名字或容器id
docker restart 容器名或者容器id
docker stop 容器名或者容器id
docker kill 容器名或者容器id
Container 容器基本操作(二)
# 1. 删除容器
docker rm 容器名称或者容器id # 删除停止的容器
docker rm -f 容器名称或者容器id # 强制删除容器
docker rm -f $(docker ps -aq) # 删除所有容器
# 2. 查看容器内服务运行日志
docker logs 容器id或者容器名称
docker logs -f 容器id或者容器名称 # 实时展示日志
docker logs -tf 容器id或者容器名称 # 加入时间戳
docker logs --tail n(5) 容器id或者容器名称 # 显示日志最后n行
# 3. 查看容器内进程
docker top 容器id或者容器名称 # 查看容器内运行的进程
# 4. 与容器内部进行交互
docker exec -it 容器id或者容器名称 bash # 进入容器
exit # 退出容器
# 5. 操作系统与容器的传输文件
docker cp 文件或者目录 容器id:容器路径 # 将宿主机复制到容器内部
docker cp 容器id:容器内资源路径 宿主机目录路径 # 将容器内资源拷贝到主机上
Container 容器基本操作(三)
# 1. 查看容器内部细节
docker inspect 容器id或者容器名称
# 2. 数据卷 Volume
作用:实现宿主机系统与容器之前的文件共享(对宿主机的改变可以直接改变容器中的内容)
数据卷的使用:
1. 自定义数据卷目录
docker run -d -p 映射端口:原始端口 --name 容器名称 -v 宿主机目录(必须绝对):容器内目录 镜像:版本号
2. 自动数据卷目录
docker run -d -p 映射端口:原始端口 --name 容器名称 -v aa:容器内目录 镜像:版本号
# aa代表一个数据卷名字,名称可以随便写,docker在不存在时自动创建这个数据卷同时自动映射主机某个目录
# 同时在启动容器时会将aa对应容器目录中全部内容复制到aa映射目录中
# 查找aa目录时,可以通过命令:find / -name aa。
例:
1.
docker run -d -p 8080:8080 --name tomcat01
-v /root/apps/:/usr/local/tomcat/webapps
tomcat:8.0-jre8
2.
docker run -d -p 8080:8080 --name tomcat01
-v aa:/usr/local/tomcat/webapps
tomcat:8.0-jre8 # aa目录如果没有,会自动创建
# 4. 将容器打包成新的镜像
docker commit -m "描述信息" -a "作者信息" (容器id或名称) 打包的镜像名称:标签
docker save 打包的镜像名称:标签 -o 发布的镜像名称.tar
docker load -i 发布的镜像名称.tar # 将上述发布的镜像下载到docker
docker 的镜像原理
镜像是什么
镜像是一种轻量级的,可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时所需的库、环境变量和配置文件。
镜像为什么这么大
docker 底层分层镜像原理设计
原因:一个软件镜像不仅仅是原来的软件包,包含软件包所需要的操作系统依赖 软件自身依赖 以及软件包组成
docker 中容器之间的网络配置
为什么提供网络功能
Docker 允许通过外部访问容器或容器互联的方式来提供网络服务。
docker 容器与操作系统通信机制
docker 网络使用
注意:一般在使用docker 网桥(bridge)实现容器与容器通信时,都是站在一个应用角度进行容器通信。
# 1. 查看docker 网桥配置
docker network ls
# 2. 创建自定义网桥
docker network # 查看命令
connect Connect a container to a network # 连接容器到网桥
create Create a network # 创建一个网桥
disconnect Disconnect a container from a network # 断开连接
inspect Display detailed information on one or more networks # 查看信息
ls List networks # 列出所有网桥
prune Remove all unused networks # 移除未使用的网桥
rm Remove one or more networks # 移除网桥
docker network create ems(网桥名称ems)
docker run -d -p 8081:8080 --network ems --name myTomcat01 tomcat:8.0-jre8
docker run -d -p 8082:8080 --network ems --name myTomcat02 tomcat:8.0-jre8
运行容器时加上 -- network+网桥名称即可。
# 注意:一旦在启动容器时指定了网桥名称,日后可以在任何这个网桥网联的容器中,使用容器名字进行与其他的容器通信。容器名称==ip地址。
# 注意:使用docker run 指定 --network网桥时网桥必须存在
高级数据卷配置
数据卷:Volume
数据卷作用
用来实现容器与宿主机之间的数据共享
数据卷特点
- 数据卷可以在容器之间共享和重用
- 对数据卷的修改会立即影响到对应容器
- 对数据卷的更新修改,不会影响镜像
- 数据卷默认会一直存在,即使容器被删除
数据卷操作
自定义数据卷目录:
docker run -v 绝对路径:容器内路径
自动创建数据卷:
docker run -v 卷名(例:aa):容器内路径
docker 操作数据卷指令
查看数据卷:
docker volume ls
查看某个数据卷细节:
docker volume inspect 卷名
创建数据卷:
docker volume create 卷名
删除数据卷:
docker volume prune # 删除未使用的数据卷
docker rm 卷名 # 删除指定数据卷
docker 核心架构图
docker安装常用服务
很多基本的安装都可以参考mall项目的环境配置文档。
mall在Linux环境下的部署(基于Docker容器) - Document (macrozheng.com)
安装mysql
docker pull mysql:5.7 # 拉取5.7版本
# 启动mysql服务,后台运行,指定root密码,容器名称,使用数据卷持久化,以修改之后的配置文件启动
docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456
-v mydata/mysql/data:/var/lib/mysql
-v mydata/mysql/conf:/etc/mysql
--name mysql mysql:5.7
安装redis
# 下载redis镜像
docker pull redis:5.0
# 启动redis,开启持久化
docker run -d -p 6379:6379
-v mydata/redis/data:/data # 挂载
-v mydata/redis/conf:/usr/local/etc/redis
# 配置文件先从官网下载,放到mydata/redis/conf
--name redis redis:5.0
redis-server /usr/local/etc/redis/redis.conf # 启动的时候带上配置文件
--appendonly yes
# 一旦开启持久化,持久化生成的aof文件会放到/data目录中
安装ES&Logstash&Kibana
参考mall在Linux环境下的部署(基于Docker容器) - Document (macrozheng.com)
中的安装。
如果需要将配置挂载,只需加上
-v /mydata/elasticsearch/conf:/usr/share/elasticsearch/conf
kibana安装时,可以将配置文件挂载,以配置文件方式启动。
docker run --name kibana -p 5601:5601 \
-v mydata/kibana/conf:/usr/share/kibana/conf # 修改mydata/kibana/conf下的配置
-d kibana:7.6.2
之后进入配置文件进行修改es的端口即可。和下述启动方式差不多:
docker run --name kibana -p 5601:5601 \
--link elasticsearch:es \
-e "elasticsearch.hosts=http://es:9200" \
-d kibana:7.6.2
Dockerfile
什么是Dockerfile
用来帮助我们自己构建一个自定义镜像,Dockerfile成为镜像构建文件 描述文件
为什么要存在Dockerfile
问题:在dockerhub中官方提供了很多镜像已经能满足我们的服务了,为什么还需要自定义镜像?
核心作用:日后用户可以将自己的应用打包成镜像,可以容器运行。
Dockerfile 构建镜像原理
基本指令
指令必须大写。
FROM命令
FROM <image>
FROM <image>[:<tag>] # 使用版本不为latest,自定义版本 例如:From centos:7
FROM <image>[@<digest>] # 使用摘要(不怎么用)
第一个Dockerfile,首先拉取并启动测试镜像。
docker pull centos:7 # 下载镜像
docker run centos:7 # 启动镜像
接下来创建专门存放Dockerfile的目录。
mkdir dockerfile/centos # 创建centos镜像的Dockerfile
cd /dockerfile/centos # 在构建之前需要进入到该目录
vim Dockerfile # 编写Dockerfile
Dockerfile的内容
FROM centos:7
构建Dockerfile。
docker build -t mycentos7:01 . # -t 镜像名:版本号 .表示当前目录(因此构建之前先进入到Dockerfile存放的目录)
RUN命令(构建镜像时需要执行的命令)
在上述例子中的Dockerfile文件中加入
RUN yum install -y vim # 下载vim
RUN ["yum","install","-y","vim"] # 第二种书写格式
构建Dockerfile
docker build -t mycentos7:01 . # 可以直接覆盖
EXPOSE(向外暴露的端口)
EXPOSE 8080
只有这样容器启动的时候才能加上-p去映射端口。
WORKDIR(工作目录)
如果WORKDIR后面的目录不存在,也会自动创建。
WORKDIR /a # 第一次为绝对路径,进入该容器后会切换到 /a 下
WORKDIR b # 相对路径 /a/b
WORKDIR c # 相对路径 /a/b/c
ADD
用来从context上下文复制新文件、目录或远程文件url,并将它们添加到位于指定路径映射文件系统中。
ADD test.txt /a/b/c # /a/b/c 是上述我们指定WORKDIR的目录
此外,ADD还可以复制远程url,例如tomcat
ADD https://dlcdn.apache.org/tomcat/tomcat-8/v8.5.73/bin/apache-tomcat-8.5.73.tar.gz /a/b/c
COPY
用来将context目录中指定文件复制到镜像的指定目录中,例如作为测试,我们在存放Dockerfile的目录下创建一个test.txt,在里面写上Hello Docker。
在Dockerfile中加上下述指令。
COPY test.txt /a/b/c # /a/b/c 是上述我们指定WORKDIR的目录
VOLUME
用来定义容器运行时可以挂载到宿主机的目录。
VOLUME /a/b/c/tomcat/webapps
这个时候/data才能被挂载
docker run -it -v /root/apps:/a/b/c/tomcat/webapps mycentos7:13
ENV
用来为构建镜像设置环境变量,这个值出现在构建阶段中所有后续指令的环境中。
用$符号作为识别。
例如,我们在写Dockerfile中公共的东西比较多,比如/a/b/c。
# 在使用 /a/b/c 目录之前定义ENV
ENV BASE_DIR /a/b/c
之后上述的
VOLUME /a/b/c/tomcat/webapps
# 可以替换为
VOLUME $BASE_DIR/tomcat/webapps
ENTRYPOINT
用来指定容器启动时执行的命令和CMD类似。
ENTRYPOINT指令往往用于设置容器启动后的第一个命令,这对一个容器来说往往是固定的。
CMD指令,往往用于设置容器启动的第一个命令的默认参数,这对一个容器来说可以是固定的。
Dockerfile构建springboot应用
在服务器中创建Dockerfile上下文目录context。
mkdir demo # 这个目录作为上下文目录
在demo目录中创建Dockerfile文件。
touch Dockerfile
之后上传应用jar包到context目录。
编写Dockerfile。
vim Dockerfile # 编辑Dockerfile
FROM openjdk:8-jdk-alpine # 基于哪个镜像进行构建
WORKDIR /app # 定义进入容器时的默认位置,接下来后续操作的工作位置
ADD demo-0.0.1-SNAPSHOT.jar app.jar
# 将上下文中的名字复制到工作目录,修改名称为app.jar
EXPOSE 8081 # 当前容器暴露端口
ENTRYPOINT ["java","-jar","app.jar"] # 启动应用的固定命令
执行构建
docker build -t demo:01 .
运行容器
docker run -d -p 8081:8081 --name demo demo:01
开发环境下Dockerfile构建应用(实际使用)
因为实际开发环境中,我们使用的是IDEA进行开发,因此我们不可能总是去服务器操作更新代码,下面我们将介绍开发中经常使用的方法。
- 下载docker插件
在idea设置中的plugins中搜索docker,下载插件并且重启idea。
- 配置docker证书并让idea连接上docker
方法如下链接:
https://blog.csdn.net/hon_vin/article/details/108058339
- IDEA配置docker
首先如下图编辑配置。
接下来,选择到docker,使用Dockerfile
- 填写相关信息
- 编写Dockerfile
FROM openjdk:8-jdk-alpine # jdk版本
WORKDIR /app # 进入容器时的目录
ADD /target/demo-0.0.1-SNAPSHOT.jar app.jar # jar包位置
EXPOSE 8081 # 端口
ENTRYPOINT ["java","-jar","app.jar"] # 执行的命令 java-jar app.jar
- 运行
- 测试
@RestController
@Slf4j
public class HelloController {
@GetMapping("test")
public String test(){
System.out.println("hello docker");
return "hello docker";
}
@GetMapping("hello")
public String hello(){
log.info("你好{}","docker");
return "hello,docker";
}
}