一、概念1.1 安装Docker卸载旧版本执行语句sudoyum removedocker返回结果2.安装新版本工具执行语句sudoyuminstall-yyum-utils返回结果3.配置yum源执行语句sudoyum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo返回结果4.安装docker执行语句sudoyuminstall-ydocker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin返回结果5.查看docker版本执行语句docker-v返回结果6.查看docker是否安装成功执行语句dockerimages执行结果说明docker没有连接上docker没有启动7.启动docker执行语句systemctl startdocker执行完成后通过使用docker images 命令来验证是否启动成功配置镜像加速注册阿里云账号https://www.aliyun.com/注册一个账号开通镜像服务首页—产品—容器镜像服务ACR—管理控制台—验证配置是否生效如果能看到你配置的那个阿里云地址说明配置成功了。sudodockerinfo|grep-A1Registry Mirrors验证返回结果8.停止docker执行语句systemctl stopdocker重启docker执行语句systemctl restartdocker设置开机自启动执行语句systemctlenabledocker执行docker ps命令如果不报错说明安装启动成功执行语句dockerps1.2 docker的使用镜像和容器当我们利用docker安装应用时Docker会自动搜索并下载应用镜像image镜像不仅包含应用本身还包含应用运行所需要的环境、配置、系统函数库。Docker会在运行镜像时创建一个隔离环境称为容器。镜像仓库存储和管理镜像的平台Docker官方维护了一个公共仓库Docker Hub;1.2.1 部署MySQL先停掉虚拟机中的MySQL确保虚拟机已经安装Docekr且网络开通的情况下执行命令即可安装MySQLdockerrun-d--namemysql-p3306:3306-eTZAsia/Shanghai-eMYSQL_ROOT_PASSWORD123mysql返回结果以上问题是由于镜像加速器没有配置成功使用一下命令重新配置镜像加速器# 1. 创建/写入配置文件sudomkdir-p/etc/dockersudotee/etc/docker/daemon.json-EOF { registry-mirrors: [ https://docker.1ms.run, https://docker.xuanyuan.me ] } EOF# 2. 重启 Dockersudosystemctl daemon-reloadsudosystemctl restartdocker# 3. 验证配置是否生效应该能看到镜像地址dockerinfo|grep-A5Registry Mirrors在navicat上连接MySQL1.2.2 命令解读dockerrun-d--namemysql-p3306:3306-eTZAsia/Shanghai-eMYSQL_ROOT_PASSWORD123mysqldocker run创建并运行一个容器-d是让容器在后台运行–name mysql给容器起个名字必须唯一-p 3306:3306设置端口映射前面端口是宿主机端口只能用一次后面端口是容器内端口-e KEYVALUE是设置环境变量KEY官方查找VALUE自定义值通过镜像制作者制定使用官网中的定义的mysql指定运行的镜像的名字默认为最新版本的镜像镜像命名规范镜像名称一般分成两部分组成[repository]:[tag]repository就是镜像名tag是镜像的版本正常应该mysql5.7在没有指定tag时默认是latest代表最新版本的镜像二、Docker基础2.1 常见命令Docker最常见的命令就是操作镜像、容器的命令官方文档https://docs.docker.com/案例查看DockerHub拉取Nginx镜像创建并运行Nginx容器需求在DockerHub中搜索Nginx镜像查看镜像的名称官方网址https://hub.docker.com/拉取Nginx镜像执行命令dockerpull nginx返回结果报错无法连接到位于国外的 Docker Hub 官方仓库解决方法使用一键配置脚本在终端中直接执行下面这行命令。它会自动完成所有配置并重启Dockerbash(wget-qO- https://xuanyuan.cloud/docker.sh)验证配置是否成功脚本执行完毕后运行下面的命令如果能看到你配置的镜像加速器地址就代表成功了dockerinfo|grepRegistry Mirrors-A5再次尝试拉取镜像dockerpull nginx以上报错根据一下方法解决# 配置单个稳定源推荐使用 DaoCloud 或 USTCsudomkdir-p/etc/dockersudotee/etc/docker/daemon.json-EOF { registry-mirrors: [https://docker.m.daocloud.io] } EOF# 重启 Dockersudosystemctl daemon-reloadsudosystemctl restartdocker# 验证配置dockerinfo|grep-A3Registry Mirrors# 如果验证输出显示 https://docker.m.daocloud.io说明配置成功dockerpull nginx查看本地镜像列表dockerimages保存镜像包docker save -o 镜像包名 镜像名:版本号dockersave-onginx.tar nginx:latest查看本地镜像ll删除镜像docker rmi 镜像名:版本号dockerrmi nginx:latest将本地镜像重新加载到dockerdocker load当不知道docker命令如何使用时可以在命令后面加上--help,查看对象的讲解dockerload-inginx.tar创建并运行Nginx容器执行命令dockerrun-d--namenginx-p8080:80 nginx返回结果查看容器执行命令dockerps返回结果指定输出命令dockerps--formattable {{.ID}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}\t{{.Ports}}\t{{.Names}}返回结果停止容器执行命令dockerstop nginx返回结果再次启动容器执行命令dockerstart nginx返回结果查看日志dockerstart-fnginx返回结果进入Nginx容器执行命令dockerexec-itnginxbash返回结果退出容器exit删除容器先确保容器是关闭状态docker stop 容器名称再删除docker rm 容器名称 -f[可选强制删除]执行命令dockerrmmysql-f命令别名vi~/.bashrc使别名文件生效source~/.bashrc2.2 数据卷数据卷volume是一个虚拟目录是容器内目录与宿主机目录之间映射的桥梁使用docker volume --help命令查看数据卷相关的命令案例1—利用Nginx容器部署静态资源需求创建Nginx容器修改nginx容器内的html目录下的index.html文件查看变化将静态资源部署到nginx的html目录提示在执行docker run命令是使用-v 数据卷:容器内目录可以完成数据卷挂载当创建容器时如果挂载了数据卷且数据卷不存在会自动创建数据卷创建容器并创建数据卷dockerrun-d--namenginx-p8080:80-vhtml:/usr/share/nginx/html nginx删除数据卷dockervolumerm查看数据卷dockervolumels查看数据卷的详细信息dockervolume inspect html返回结果删除未使用的数据卷dockervolume prune案例2—mysql容器的数据挂载需求查看mysql容器判断是否有数据卷挂载基于宿主机目录实现MySQL数据目录、配置文件、初始化脚本的挂载查阅官方镜像文档挂载/root/mysql/data到容器内的/var/lib/mysql目录挂载/root/mysql/init到容器内的/docker-entrypoint-initdb.d目录挂载/root/mysql/conf到容器内的/etc/mysql/conf.d目录提示在执行docker run命令时使用-v本地目录:容器内目录可以完成本地目录挂载本地目录必须以/或”./开头如果直接以名称开头会被识别为数据卷而非本地目录–-v mysql:/var/lib/mysql会被识别为一个数据卷叫mysql–-v./mysql:/var/lib/mysql会被识别为当前目录下的mysql目录查看容器中是否有数据卷dockerinspect mysql2.3 自定义镜像镜像就是包含了应用程序、程序运行的系统函数库、运行配置等文件的文件包。构建镜像的过程其实就是把文件打包的过程。Dockerfile语法Dockerfile 是一个文本文件里面包含了一系列构建镜像的指令。可以把它理解为镜像的配方或制作说明书。自定义镜像将jdk.tar包复制到根目录下如yueyue/目录——执行docker load -i jdk.tar命令载入镜像——执行cd demo/命令进入demo目录——执行docker build -t docker-demo .构建基础镜像——基础镜像构建完成使用docker images查看——执行docker run -d --name dd -p 8080:8080 docker-demo命令启动该镜像执行docker build -t docker-demo【基础镜像构建完成】执行docker run -d --name dd -p 8081:8080 docker-demo【启动镜像】执行docker logs -f dd【查看jdk镜像日志】在浏览器中使用http://192.168.19.128:8081/hello/count路径访问2.4 网络查看容器执行docker inspect mysql查看【mysql】容器详情执行docker inspect dd查看【jdk】容器详情执行docker inspect nginx查看【nginx】容器详情发现以上容器IP地址均在同一网段则这些容器之间可以互相访问网络默认情况下所有容器都是以bridge方式连接到Docker的一个虚拟网桥上使用网络可以将容器加入同一个自定义网络可以通过容器名互相访问三、项目部署3.1 部署Java应用需求 将hmall项目打包为镜像并部署镜像名为hmallidea工具打开项目——maven中package打包注意要取消test用例——打包项目在target中.jar包——将对应的src中的Dockerfile和target中的jar包放入虚拟机——浏览器中访问http://192.168.19.128:8081/hi3.2 部署前端需求创建一个新的nginx容器将nginx.conf、html目录与容器挂载打开前端文件nginx——复制到虚拟机——执行命名1报nginx名已存在——执行命令2删除重名容器nginx——再次执行命令1——# 命令1dockerrun-d\--namenginx\-p18080:18080\-p18081:18081\-v/home/yueyue/nginx/html:/usr/share/nginx/html\-v/home/yueyue/nginx/nginx.conf:/etc/nginx/nginx.conf:ro\--networkyue\nginx# 命令2dockerrm-fnginx浏览器中访问http://192.168.19.128:18080/部署一个完整的项目步骤创建一个自定义网络docker在自定义网络中部署mysql、java后端代码、nginx前端代码形成同一个自定义网络下的不同容器docker启动容器Java后端数据库的连接、前端与后端接口的连接3.3 DockerComposeDocker Compose通过一个单独的docker-compose.yml模板文件YAML格式来定义一组相关联的应用容器帮助我们实现多个相互关联的Docker容器的快速部署。部署mysql部署项目——docker-compose将项目中所有使用到的容器全部写入到docker-compose文件中yaml格式——将docker-compose文档上传的虚拟机——执行命令docker rm -f nginx hm mysql将之前部署的容器删除——执行命令docker compose up -d实现一键部署如下图——执行docker compose ps查看项目下的所有进程——列出所有启动的容器查看虚拟机中的所有的镜像停止并移除所有容器、网络Docker Compose文件模板# 版本声明新版可省略version:3.8# 服务定义必需services:service1:# 服务配置...service2:# 服务配置...# 网络定义可选networks:my-network:# 数据卷定义可选volumes:my-volume:hmall示例项目docker-compose文件name:hmallservices:mysql:image:mysql:8.0container_name:mysqlrestart:unless-stoppedports:-3306:3306environment:MYSQL_ROOT_PASSWORD:123TZ:Asia/Shanghaivolumes:-mysql_data:/var/lib/mysqlnetworks:-hmall-networkbackend:build:./hmallcontainer_name:hmall-backendrestart:unless-stoppedports:-8081:8080depends_on:mysql:condition:service_healthyenvironment:DB_HOST:mysqlDB_PORT:3306DB_PASSWORD:123networks:-hmall-networkfrontend:image:nginx:alpinecontainer_name:hmall-nginxrestart:unless-stoppedports:-18080:18080-18081:18081volumes:-./nginx/html:/usr/share/nginx/html-./nginx/nginx.conf:/etc/nginx/nginx.conf:rodepends_on:-backendnetworks:-hmall-networknetworks:hmall-network:driver:bridgevolumes:mysql_data:标准化的部署流程准备阶段确保代码在虚拟机上进入项目目录# 1. 确保代码在虚拟机上任选一种方式# 方式AGit拉取推荐gitclone https://github.com/your/project.git# 方式B手动上传scp-r./project user192.168.19.128:/home/user/# 2. 进入项目目录cd/home/user/project准备Docker相关文件在项目根目录创建文件Dockerfile、docker-compose.yml;# Dockerfile FROM openjdk:17-jdk-alpine COPY target/*.jar app.jar EXPOSE 8080 ENTRYPOINT [java, -jar, /app.jar]# docker-compose.ymlservices:mysql:image:mysql:8.0environment:MYSQL_ROOT_PASSWORD:123456volumes:-mysql_data:/var/lib/mysqlbackend:build:.# 使用当前目录的Dockerfileports:-8080:8080depends_on:-mysqlnginx:image:nginx:alpineports:-80:80volumes:-./nginx.conf:/etc/nginx/nginx.conf:rovolumes:mysql_data:构建和部署构建镜像使用Dockerfile、一键启动所有服务使用Compose、验证部署是否成功# 1. 构建镜像如果使用Dockerfiledockerbuild-tmyapp:latest.# 2. 一键启动所有服务使用Composedockercompose up-d# 3. 验证部署是否成功dockercomposeps# 查看容器状态dockercompose logs-f# 查看日志curlhttp://localhost:8080# 测试接口维护更新更新代码后重新部署或者更简单的热更新、停止项目、停止并删除数据卷会丢失数据# 更新代码后重新部署gitpull# 拉取新代码dockercompose build# 重新构建镜像dockercompose up-d--force-recreate# 强制重建容器# 或者更简单的热更新开发环境用dockercompose restart backend# 停止项目dockercompose down# 停止并删除数据卷⚠️会丢失数据dockercompose down-v四、Docker容器化部署 - 面试问答汇总序号分类面试问题参考答案1Docker基础什么是Docker镜像和容器的区别是什么Docker是一个开源的应用容器引擎可以将应用及其依赖打包成轻量级、可移植的镜像然后在任何Linux机器上运行。镜像与容器的区别•镜像Image是只读模板包含了应用程序及运行所需的环境、配置、依赖库相当于类•容器Container是镜像的运行实例有独立的进程空间和文件系统相当于对象类比镜像代码容器进程镜像类容器实例2Docker基础Docker与虚拟机的区别是什么3Docker安装Docker安装后为什么要配置镜像加速器Docker Hub镜像仓库位于国外国内拉取镜像速度慢甚至超时失败。解决方案配置国内镜像加速器如阿里云、中科大、DaoCloud等配置步骤1. 创建/修改/etc/docker/daemon.json2. 添加镜像地址如https://docker.m.daocloud.io3. 重启Dockersystemctl restart docker4. 验证docker info4Docker命令docker run命令中-d、-p、-v、-e、–name分别代表什么•-d后台运行容器detach•-p 宿主机端口:容器端口端口映射外部通过宿主机端口访问容器服务•-v 宿主机目录:容器目录数据卷挂载实现数据持久化或配置共享•-e KEYVALUE设置环境变量常用于配置数据库密码、时区等•–name给容器命名必须唯一示例docker run -d --name mysql -p 3306:3306 -v /data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD123 mysql5数据卷为什么要使用数据卷数据卷有哪几种挂载方式原因容器删除后内部数据会丢失通过数据卷实现数据持久化。三种挂载方式•数据卷挂载-v 数据卷名:容器目录Docker自动创建和管理•宿主机目录挂载-v /宿主机绝对路径:容器目录手动指定便于修改配置•匿名挂载-v 容器目录不指定名称由Docker自动命名常用命令docker volume ls、docker volume inspect 卷名、docker volume prune清理未使用卷6数据卷MySQL容器怎么实现数据持久化官方MySQL镜像提供了多个可挂载目录•数据目录/var/lib/mysql数据库文件•配置文件/etc/mysql/conf.d自定义配置•初始化脚本/docker-entrypoint-initdb.d启动时执行的SQL脚本示例bashbrdocker run -d --name mysql \br -v /root/mysql/data:/var/lib/mysql \br -v /root/mysql/conf:/etc/mysql/conf.d \br -v /root/mysql/init:/docker-entrypoint-initdb.d \br -e MYSQL_ROOT_PASSWORD123 mysqlbr这样容器删除后重新创建数据依然存在配置和初始化脚本也能自动生效7自定义镜像什么是Dockerfile常用的指令有哪些Dockerfile是构建镜像的文本文件包含了一系列指令。常用指令8镜像构建构建Java应用镜像的Dockerfile怎么写dockerfilebr# 1. 基础镜像包含JDKbrFROM openjdk:11-jre-slimbrbr# 2. 设置工作目录brWORKDIR /appbrbr# 3. 复制jar包brCOPY target/hmall.jar app.jarbrbr# 4. 暴露端口brEXPOSE 8080brbr# 5. 启动命令brENTRYPOINT [java, -jar, app.jar]br优化建议• 使用更小的基础镜像如alpine版• 利用多阶段构建减小镜像体积• 将依赖层和业务代码层分离利用缓存加速构建9容器网络容器间如何通信为什么要自定义网络默认网络Docker安装后会创建三个网络bridge、host、none默认所有容器连接到bridge网络通过IP地址通信。问题容器的IP是动态分配的重启后可能变化且无法通过容器名访问。自定义网络bashbr# 创建网络brdocker network create yue-netbrbr# 容器指定网络brdocker run --network yue-net --name mysql ...brdocker run --network yue-net --name backend ...br优势同一自定义网络中的容器可以通过容器名互相访问内置DNS解析无需关心IP变化10项目部署如何用Docker部署一个完整的微服务项目前端后端数据库标准流程1.创建自定义网络docker network create app-net2.部署MySQL挂载数据卷加入网络3.部署后端编写Dockerfile构建镜像加入网络通过容器名连接数据库4.部署前端使用nginx镜像挂载html目录和配置文件加入网络5.验证访问http://宿主机IP:端口关键点• 所有容器加入同一网络通过容器名通信• 数据库密码等敏感信息通过环境变量传递• 前后端分离部署nginx代理后端API请求11Docker Compose什么是Docker Compose解决了什么问题Docker Compose是定义和运行多容器Docker应用的工具通过一个docker-compose.yml文件配置所有服务。解决的问题• 手动管理多个容器时命令复杂、容易出错• 容器启动顺序无法控制• 网络、数据卷需要单独创建• 环境迁移需要重复执行所有命令优势•一键部署docker compose up -d•声明式配置YAML文件即文档即配置•启动顺序控制通过depends_on指定依赖•环境一致性开发、测试、生产环境配置相同12Docker Composedocker-compose.yml文件的核心结构是什么yamlbr# 版本声明新版可省略brversion: 3.8brbr# 服务定义核心brservices:br mysql: # 服务名br image: mysql:8.0br container_name: mysqlbr ports:br - 3306:3306br environment:br MYSQL_ROOT_PASSWORD: 123br volumes:br - mysql_data:/var/lib/mysqlbr networks:br - app-networkbrbr backend:br build: ./backend # 使用Dockerfile构建br depends_on: # 依赖关系br - mysqlbr ports:br - 8080:8080brbr# 网络定义brnetworks:br app-network:br driver: bridgebrbr# 数据卷定义brvolumes:br mysql_data:br三个顶层元素services必需、networks可选、volumes可选13Docker ComposeCompose常用命令有哪些14生产实践一套完整的Docker部署流程是怎样的1. 准备阶段bashbrgit clone 项目brcd 项目br2. 编写Dockerfile后端项目3. 编写docker-compose.yml定义所有服务4. 构建并启动bashbrdocker compose build # 构建镜像brdocker compose up -d # 一键启动brdocker compose ps # 检查状态br5. 验证部署bashbrcurl http://localhost:8080/healthbrdocker compose logs -fbr6. 更新代码bashbrgit pullbrdocker compose build backendbrdocker compose up -d --force-recreate backendbr7. 清理维护bashbrdocker system prune # 清理未使用资源brdocker compose down -v # 完全清理慎重br15面试实战如果让你把公司项目用Docker部署你怎么做回答框架1.先评估项目结构判断是单体还是微服务有哪些依赖MySQL、Redis、Nginx等2.编写Dockerfile为每个需要构建的服务编写Dockerfile如Java后端3.编写docker-compose.yml- 定义数据库服务使用官方镜像数据卷挂载- 定义后端服务使用Dockerfile构建环境变量配置- 定义前端服务nginx镜像配置文件挂载- 创建自定义网络配置服务依赖关系4.创建自定义网络所有服务加入同一网络通过容器名互相访问5.配置数据持久化数据库等有状态服务必须挂载数据卷6.启动验证docker compose up -d检查各服务日志7.编写部署文档记录环境变量、端口、挂载点等关键配置加分项提到使用.env文件管理环境变量、多环境配置区分、健康检查、资源限制等