docker
docker简介
Docker 是一款开源的容器化平台(基于Go语言开发),用于构建、打包、部署和运行应用程序及其所有依赖的环境(例如:java程序需要jdk环境才能运行,mysql的运行需要一些依赖库,如OpenSSL、ncurses和zlib…)。
通过使用 Docker,开发者可以将应用程序及其环境打包成一个称为容器的轻量级、独立的单元。
这些容器可以在任何支持 Docker 的环境中运行,确保应用在不同环境(开发环境,测试环境,生产环境…)之间具有一致的运行行为。
开发者可以在开发、测试和生产环境中使用相同的容器,减少了由环境差异引起的问题。
题外话:
集群的作用:
docker的优势
1、可移植性:docker容器可以在任何支持docker的环境中运行,包括本地开发环境、测试环境和生产环境,从而提高了应用程序的可移植性。
2、可伸缩性:docker容器可以根据负载的变化进行快速扩展和收缩,从而更好地满足应用程序的需求。
3、隔离性:docker容器提供了隔离的运行环境,从而使得不同容器中运行的应用程序互相隔离,避免了应用程序之间的干扰。
docker架构
docker基于 C/S 架构(客户端-服务器)。
docker客户端只需要向docker服务器(守护进程)发出请求,也就是输入命令,服务器解析执行命令并返回结果。
docker核心概念
镜像:Docker 镜像是一个只读的模板,它包含了应用程序运行所需的所有文件、依赖、环境变量等。镜像可以作为容器的基础,多个容器可以共享同一个镜像。
Docker 容器:容器是从镜像创建的实例,它是一个运行的进程,具有独立的命名空间、文件系统和资源限制。容器可以轻松地启动、停止、删除,可以在不同的主机和环境中移植,从而实现环境的一致性。
Docker Hub(官方镜像仓库):Docker Hub 是一个公共的镜像仓库(官方的),开发者可以在其中找到各种常用的镜像,也可以上传自己构建的镜像供他人使用。此外,Docker Hub 还支持私有镜像仓库,用于组织内部的镜像管理。
仓库又分为共有仓库和私有仓库:
- 公有仓库: 所有人都可以访问的仓库
- 私有仓库: 公司内部搭建的一个仓库 可以使用Harbor搭建一个私有仓库
容器: 利用镜像创建的一个动态的实例,就是容器,容器中存放的是运行的应用程序和依赖环境。
dockerfile 用于构建自定义镜像文件
- 例如:用户服务(springboot.jar)做成一个自定义的镜像,使用dockerfile进行构建
docker compose容器编排工具
- 当所需要的容器较多时,可以使用docker compose批量创建,并且可以指定容器之间的依赖关系。
第三方工具连接不上Linux的解决方案
1丶检查防火墙是否关闭
2丶检查容器是否启动
3丶检查服务器IP还有没有
如果没有IP,在根目录下执行该命令
docker操作
指定版本说明
搜索镜像
# 命令:
docker search 镜像关键字
# 示例:搜索镜像名称中包含redis关键字的镜像
docker search redis
列介绍:
1、name: 镜像仓库源名称
2、description: 镜像的描述
3、official: 是否 docker 官方发布
4、stars: 镜像的收藏数,收藏数越多表示此镜像的受欢迎程度越高
5、automated: 是否自动构建
拉取(下载)进项
# tag表示的镜像的标签,也可以理解为就是镜像的版本
docker pull 镜像名称[:tag]
# 示例1: 默认拉取的是最新的redis镜像
docker pull redis 等价于 docker pull redis:latest
# 示例2: 拉取redis7.0.10镜像,一个镜像到底存在哪些标签,需要上docker hub中进行查看
docker pull redis:7.0.10
查看本地镜像
# 命令:
docker images
列介绍:
1、repository:镜像来源仓库名称
2、tag: 镜像标签
3、image id: 镜像id
4、created: 创建时间
5、size: 镜像的大小
删除本地镜像
#根据镜像名称:tag删除
docker rmi 镜像名称:镜像tag
#根据镜像id删除
docker rmi 镜像id
注意:如果一个镜像存在对应的容器,此时这个镜像是无法进行删除的,需要先删除镜像,再删除容器。
查看帮助文档了解()
docker中提供了很多命令,每一个命令也可以加很多的参数选项。把一个命令以及对应的参数选项都记住很显然是不太现实的。
可以通过查看docker帮助文档来学习docker的常用命令以及参数选项的使用。
帮助文档的使用如下所示:
# 查询docker可以使用到的命令
docker --help
# 查询images命令的使用文档
docker images --help
容器操作
查询容器
# 查看本地正在运行的容器
docker ps
# 查询所有的容器包含未运行的容器
docker ps -a
创建容器
- 容器分类:
1丶交互型容器:具有和用户交互的输入和输出终端,容器创建后自动进入容器中,退出容器后,容器自动关闭。
创建交互式容器
docker run -it --name java01 java:latest /bin/bash
退出容器 exit
/bin/bash 打开命令窗口
从交互式容器退出后,交互式容器关闭,处于关闭状态
2、守护型容器:没有和用户交互终端,需要使用docker exec进入容器,退出后,容器不会关闭。没有和用户交互终端,需要使用docker exec进入容器,退出后,容器不会关闭。
创建守护式容器
docker run -id --name redis02 redis:latest
进入容器:
docker exec
docker exec -it java02 /bin/bash # 进入到容器中同时打开一个shell窗口
创建后不会打开命令窗口, 还是在宿主机命令
容器管理
docker stop 容器名称/容器id # 关闭容器
docker start 容器名称/容器id # 启动容器
docker restart 容器名称/容器id # 重启容器
删除容器
docker rm 容器名称/容器的id #删除一个已停止的容器
docker rm -f 容器名称/容器的id #强制删除一个正在运行的容器
注意:上述的命令只能删除已经关闭的容器,如果想删除正在运行的容器,可以通过添加 -f 参数进行实现。
进入容器
docker exec -it java02 /bin/bash # 进入到容器中同时打开一个shell窗口
其他命令(日志,拷贝,ip)
docker logs -f 容器名称/容器的id # 查询容器内进程日志,-f参数表示实时监控日志信息
docker inspect 容器名称/容器的id # 查看容器的详情信息
docker cp # 完成容器和宿主机之间的文件copy
示例1: docker logs -f redis01 # 实时查看redis01这个容器中的日志信息
示例2: docker inspect redis01 # 查看容器的详情信息,主要就是:目录映射情况、端口映射情况、ip地址
示例3: docker cp a.txt redis01:/root # 把宿主机中a.txt文件拷贝到redis01的root目录中
示例4: docker cp redis01:/root/a.txt . # 把容器中的root目录下的a.txt文件拷贝到宿主机中当前目录中
备份与迁移
//用法:
docker commit 容器名称/容器的id 镜像名称 # 把docker容器保存成一个镜像
docker save -o 镜像tar文件名称 镜像名称/镜像id # 把镜像保存为tar文件
docker load -i tar文件 # 把tar文件恢复成为一个镜像
//示例:
docker commit mycentos10 mycentos # 将mycentos10容器保存为一个镜像
docker save -o mycentos.tar mycentos # 将mycentos镜像保存为一个tar文件
docker rmi mycentos # 删除之前的mycentos镜像
docker load -i mycentos.tar # 将mycentos.tar恢复成一个镜像
迁移方式
自定义版本(安装时可以设置创建的版本)
端口映射 在创建容器时设置端口映射
用宿主机的端口映射容器的端口, 访问宿主机的端口 = 访问容器的端口
宿主机端口号 :
容器端口号
数据卷
思考问题:在Redis容器中存储的数据,如果Redis容器被删除了,数据是否还存在?
解决方案:将数据存储到Linux宿主机的磁盘目录中。
数据卷概述:数据卷是docker所提供的一个虚拟目录,这个虚拟目录会对应宿主机的一个真实目录。
在创建容器的时候就可以将这个数据卷挂载到容器中的某一个目录下,那么此时在该目录下所产生的数据就会存储到宿主机的目录下,实现了容器和宿主机之间的文件共享。
宿主机真实目录:
/var/lib/docker/volumes/redis-data/_data
创建数据卷
docker volume create redis-data
查看数据卷详情
docker volume inspect 数据卷名称
查看数据卷列表
docker volume ls
删除数据卷
docker volume rm redis-data
数据卷物理目录不能修改
数据卷挂载
容器中产生的数据会备份到宿主机文件中
虚拟的目录,指向宿主机的物理目录,
- 在创建容器时挂载
- 格式: -v 数据卷名称:容器目录
示例:docker run -id --name=redis02 -p 6379:6379 -v redis-data:/data redis
- 格式: -v 数据卷名称:容器目录
注意事项:
1、如果数据卷没有提前创建好,那么在创建容器的时候会自动创建对应的数据卷
2、数据卷挂载的时候数据卷名称前面没有/
3、容器目录不存在会自动创建
4、数据卷目录如果不为空,此时会使用数据卷目录内容覆盖容器目录内容
5、数据卷目录如果为空,容器目录不为空,此时就会使用容器目录内容覆盖数据卷目录
目录挂载
自定义目录和容器中的目录挂载
创建tomcat发现链接没有页面显示
原因是容器中目录没有index.jsp文件
创建index.html.文件传入方式:
- cp到目录下
- 挂载到目录下
两种挂载应用场景
Portainer工具
Portainer安装
上述对容器和镜像的管理都是基于docker客户端的命令来完成,不太方便。
为了方便的对docker中的一些对象(镜像、容器、数据卷…)来进行管理,可以使用Portainer来完成。
Portainer是一个可视化的容器镜像的图形管理工具,利用Portainer可以轻松构建,管理和维护docker环境。
Portainer安装:
# 拉取镜像
docker pull portainer/portainer
#创建并启动portainer容器
#通过-v,进行docker.sock文件的挂载,portainer容器会通过这个文件和docker守护进程进行通讯来管理docker的相关对象。
#--restart=always表示随着docker服务的启动而启动
docker run -id -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
随着docker服务启动而启动(前提:docker服务要设置开机自启 systemctl enable docker)
Portainer端口号为 9000
docterfile
docterfile简介
前面我们所使用的镜像都是别人构建好的,但是别人构建好的镜像不一定能满足我们的需求。
如何构建自定义镜像?使用dockerfile。
dockerfile就是一个文本文件,在这个文件中可以使用docker所提供的一些指令来指定我们构建镜像的细节,后期就可以使用这个dockerfile文件来构建自己的镜像。
dockerfile文件内容一般分为4部分:
1、基础镜像信息(必选)
2、维护者信息(可选)
3、镜像操作指令(可选)
4、容器启动时执行的指令(可选)
指令 | 用法 | 作用 |
---|---|---|
FROM | FROM image_name:tag | 指定一个构建镜像的基础源镜像,如果本地没有就会从公共库中拉取,没有指定镜像的标签会使用默认的latest标签,可以出现多次,如果需要在一个dockerfile中构建多个镜像。 |
MAINTAINER | MAINTAINER user_name | 描述镜像的创建者,名称和邮箱 |
RUN | RUN “command” “param1” “param2” | 用来执行一些命令,可以写多条 |
ENV | ENV key value | 设置容器的环境变量,可以写多条。 |
ADD | ADD source_dir/file | 将宿主机的文件复制到容器内,如果是压缩文件,则复制后自动解压 |
ENTRYPOINT | ENTRYPOINT “command” “param1” “param2” | 用来指定容器启动时所执行的命令 |
构建jdk17的容器
- 方式一
- docke pull 拉取了一个基础镜像centos.last
将容器设置为开机自启
docker update --restart=always 容器名
- 方式二通过dockerfile脚本制作
创建dockerfile文件
FROM centos:7
RUN mkdir -p /usr/local/java
ADD jdk-17.0.7_linux-x64_bin.tar.gz /usr/local/java/
ENV JAVA_HOME=/usr/local/java/jdk-17.0.7
ENV PATH=$PATH:$JAVA_HOME/bin
把dockerfile文件和tar包放在一起
使用命令
docker build -t 新镜像文件名 .
末尾的 .
的意思是使用当前目录下的自定义的镜像文件
创建mysql容器
下载mysql:8.0.30镜像
docker pull mysql:8.0.30
执行以下命令
# 创建容器。 -e: 设置环境变量 --privileged=true 它允许容器内的进程拥有访问宿主机的权限。
docker run -id --name=mysql -p 3306:3306 -v mysql_data:/var/lib/mysql -v mysql_conf:/etc/mysql --privileged=true -e MYSQL_ROOT_PASSWORD=1234 mysql:8.0.30
# 进入容器
docker exec -it mysql /bin/bash
mysql -uroot -p # 登录mysql
# 创建并切换数据库
create database docker;
use docker;
#创建表
CREATE TABLE `tb_school` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#添加测试数据
INSERT INTO `tb_school` VALUES (1, '尚硅谷-北京校区', '北京市昌平区宏福科技园2号楼3层');
INSERT INTO `tb_school` VALUES (2, '尚硅谷-上海校区', '上海市松江区谷阳北路166号大江商厦3层');
INSERT INTO `tb_school` VALUES (3, '尚硅谷-深圳校区', '深圳市宝安区西部硅谷大厦B座C区一层');
INSERT INTO `tb_school` VALUES (4, '尚硅谷-西安校区', '西安市雁塔区和发智能大厦B座3层');
INSERT INTO `tb_school` VALUES (5, '尚硅谷-成都校区', '成都市成华区北辰星拱青创园综合楼3层');
INSERT INTO `tb_school` VALUES (6, '尚硅谷-武汉校区', '武汉市东湖高新区东湖网谷6号楼4层');
部署springboot部署
springboot打包插件
如果没有这个插件,打出的jar包不是个完整的jar包,只包括当前工程的源码
jar可运行的jar包
original是单纯的代码文件
FROM centos7-jdk17
MAINTAINER atguigu
EXPOSE 8081
ADD ebuy-docker-1.0-SNAPSHOT.jar /ebuy-docker-1.0-SNAPSHOT.jar
WORKDIR /
ENTRYPOINT ["java" , "-jar" , "ebuy-docker-1.0-SNAPSHOT.jar"]