微服务学习(一):Docker · 夯到爆的一个工具 本篇为微服务学习的前置篇学习docker的实操〇、引子 · 从一次跑不起来说起“我本地能跑服务器跑不了。”这句话几乎每个程序员都说过。有没有一种东西能把代码 环境 依赖一起打包放到哪都能直接跑于是Docker出现了。一、Docker 是什么用一句话说清楚Docker 是一个把应用 依赖 运行环境打包成一个标准化容器来运行的运维工具。更直白一点Docker 把你的代码、JDK、MySQL 驱动、配置文件全部塞进一个集装箱里这个箱子在任何装好 Docker 的机器上都能直接打开运行。传统部署就像搬家时把家具一件一件搬装 JDK、配环境变量、改配置文件Docker 就像直接把整个房间打包成一个集装箱搬过去就能住。二、为什么 Docker 这么夯2.1 环境不一致的终结者以前最头疼的问题“我本地明明是好的啊”原因通常很无聊系统不同Windows vs LinuxJDK 版本不同11 vs 17依赖版本不一致MySQL 驱动版本差一位环境变量没配Docker 的解决方案粗暴而有效把应用运行所需的一切——操作系统层、运行时、依赖库、代码——全部打包成镜像。运行时不依赖宿主机环境只依赖 Docker 本身。2.2 轻量级 · 比虚拟机快一个维度虚拟机VM模拟的是整个硬件CPU、内存、硬盘所以启动时间分钟级占用空间GB 级一台机器能跑几十个Docker 容器共享的是宿主机的内核只隔离进程空间所以启动时间毫秒级占用空间MB 级一台机器能跑成百上千个类比虚拟机 ≈ 买一栋楼每个房间都是独立的房子Docker ≈ 在一栋楼里隔出多个独立公寓共享水电基础设施。三、核心概念镜像 · 容器 · 仓库 镜像Image镜像是一个只读的模板相当于程序的安装包。举个例子MySQL 的镜像包含了Ubuntu 底层系统MySQL 二进制文件默认配置文件启动脚本镜像 ≈ 下载好的 .exe 安装包还没安装 容器Container容器是镜像运行后的实例。镜像是静态的存硬盘上的文件容器是动态的运行在内存里的进程容器 ≈ 双击安装包后正在运行的程序你可以从一个镜像启动无数个容器每个容器相互隔离。 仓库Repository仓库是存放镜像的地方类似 GitHub 之于代码。Docker Hub官方的公共镜像仓库类似 GitHub 公开仓库阿里云镜像仓库 / 私有仓库企业内部使用类似 GitLab 私有仓库常用的docker pull mysql就是从 Docker Hub 把 MySQL 的镜像下载到本地。四、镜像的分层机制Docker 高效的秘密Docker 镜像不是一个大块头而是由**多层Layer**堆叠而成FROM ubuntu:20.04 # Layer 1: 基础操作系统 RUN apt update # Layer 2: 系统依赖 RUN apt install python # Layer 3: 安装 Python COPY app.py /app/ # Layer 4: 复制代码分层的威力在哪里复用多个镜像共用同一层不重复存储比如 10 个 Python 应用都共用ubuntu python那两层缓存修改代码后重新构建只需要重建 Layer 4Layer 1-3 直接用缓存推送/拉取效率拉取镜像时只下载本地没有的层面试常问Docker 镜像是怎么做到轻量且高效的答分层存储 UnionFS 联合文件系统 写时复制。五、实操最常用的 Docker 命令5.1 镜像相关# 拉取镜像dockerpull nginx:latestdockerpull mysql:8.0.40# 查看本地镜像dockerimages# 删除镜像dockerrmi镜像ID5.2 容器相关最常用的几个# 启动容器-d 后台运行-p 端口映射--name 指定名字dockerrun-d-p8080:80--namemynginx nginx# 查看运行中的容器dockerps# 查看所有容器含已停止的dockerps-a# 停止 / 启动 / 重启dockerstop mynginxdockerstart mynginxdockerrestart mynginx# 删除容器dockerrmmynginx# 查看日志dockerlogs-fmynginx# 进入容器内部调试用dockerexec-itmynginxbash5.3 关键理解端口映射-p容器是一个隔离环境它有自己的网络空间。比如 Nginx 容器内部监听80端口但宿主机访问localhost:80是访问不到的——因为容器是隔离的。所以需要端口映射dockerrun-p8080:80 nginx含义把容器内的80端口映射到宿主机的8080端口。访问宿主机:8080等价于访问容器的80。六、数据持久化容器删了数据还在吗容器的文件系统是临时的。如果容器被删除容器内部的所有文件包括 MySQL 的数据都会被清空。这显然不能接受。Docker 提供了**挂载Volume**来解决这个问题6.1 Bind Mount绑定挂载把宿主机的目录挂载到容器内部dockerrun-d\--namemysql\-p3306:3306\-eMYSQL_ROOT_PASSWORD123\-v/root/mysql/data:/var/lib/mysql\mysql解释-v /root/mysql/data:/var/lib/mysql宿主机目录/root/mysql/data容器内目录/var/lib/mysqlMySQL 存数据的地方两者绑定后容器向/var/lib/mysql写数据 → 实际存到了宿主机的/root/mysql/data容器删除 → 宿主机目录里的数据还在下次再启动挂载同一个目录 → 数据自动恢复6.2 VolumeDocker 管理的卷Bind Mount 的宿主机路径是手动指定的而 Volume 是 Docker 管理的存储空间# 创建卷dockervolume create mysql_data# 使用卷挂载的时候直接写卷名dockerrun-vmysql_data:/var/lib/mysql mysql存储方式位置谁管理适用场景Bind Mount宿主机任意目录用户开发环境、配置文件注入Volume/var/lib/docker/volumes/Docker生产环境、数据库持久化面试常问Docker 的数据持久化方案有哪些答Bind Mount、Volume、tmpfs mount分别适用什么场景。七、Dockerfile把应用打包成镜像Dockerfile 是一个文本文件描述了一个镜像应该如何构建。7.1 一个最简单的 Spring Boot 项目 Dockerfile# 基础镜像包含 JDK FROM openjdk:11-jre-slim # 作者 MAINTAINER xxx # 把 JAR 包复制进镜像 COPY target/demo.jar /app.jar # 暴露端口只是声明实际运行还要 -p EXPOSE 8080 # 启动命令 ENTRYPOINT [java, -jar, /app.jar]7.2 构建镜像dockerbuild-tmyapp:v1.八、容器网络容器之间怎么通信8.1 默认 Bridge 网络Docker 默认有一个bridge网络所有容器都在这个网络里每个容器分配一个内部 IP如172.17.0.2。痛点容器重启后 IP 会变不能写死。8.2 自定义网络推荐# 创建网络dockernetwork create hm-net# 启动容器时指定网络dockerrun-d--networkhm-net--namemysql mysqldockerrun-d--networkhm-net--nameredis redisdockerrun-d--networkhm-net--namemyapp myapp好处同一个网络里的容器可以通过容器名互相访问Docker 自带 DNS 解析。比如在myapp的配置文件里连接数据库可以直接写spring.datasource.url:jdbc:mysql://mysql:3306/demo而不是写jdbc:mysql://172.17.0.2:3306/demo。8.3 Host 网络容器直接使用宿主机的网络栈适合性能敏感的场景dockerrun-d--networkhostnginx不需要-p端口映射容器直接暴露在宿主机端口上。九、Docker Compose一键启动整个微服务集群当你的项目依赖 MySQL、Redis、Nacos、你的微服务 A、微服务 B……你不可能每次都用docker run敲 10 条命令。Docker Compose 用一个 YAML 文件管理所有容器version:3services:mysql:image:mysql:8.0environment:MYSQL_ROOT_PASSWORD:123volumes:-mysql_data:/var/lib/mysqlports:-3306:3306redis:image:redis:7.0ports:-6379:6379user-service:build:./user-service# 用 Dockerfile 构建ports:-8081:8080depends_on:-mysql-redisenvironment:SPRING_DATASOURCE_URL:jdbc:mysql://mysql:3306/demovolumes:mysql_data:一条命令启动所有容器dockercompose up-d常用命令dockercompose up-d# 后台启动所有dockercompose down# 停止并删除所有容器dockercompose logs-f# 查看所有日志dockercomposeps# 查看状态十、我踩过的坑避坑指南坑 1CentOS 7 装 Docker 报 404原因CentOS 7 已经停止维护官方源不可用。解决换阿里云 Vault 源。坑 2Docker 拉取镜像超时 / connection reset原因Docker 默认从 Docker Hub国外拉取网络不通。解决配置阿里云镜像加速器或给 Docker 配置 HTTP 代理。坑 3容器启动失败报 “port already allocated”原因端口被占用了。解决换一个宿主机端口比如-p 3307:3306。坑 4挂载目录报错 “not a directory”原因宿主机上存在同名文件挡住了目录创建。解决rm -f /root/xxx删掉文件重新mkdir -p。十一、Docker 在微服务里的定位传统部署Docker 部署手动装 JDK / MySQL / Redis镜像拉下来直接跑环境不一致“我本地能跑”镜像保证环境完全一致上线发 JAR 包 配环境上线发镜像服务器直接跑多服务部署麻烦Compose 一键启动一句话总结 Docker 的价值Docker 是一次构建到处运行的现代版——把环境依赖也打包进镜像里从根本上解决了环境不一致的问题。附录常用命令速查表# 镜像dockerpull镜像名# 拉取镜像dockerimages# 查看本地镜像dockerrmi镜像ID# 删除镜像# 容器dockerrun-d-p8080:80--namexxx镜像# 启动容器dockerps# 查看运行中的容器dockerps-a# 查看所有容器dockerstop/start/restart# 管理容器dockerrm-f容器名# 删除容器dockerlogs-f容器名# 查看日志dockerexec-it容器名bash# 进入容器内部# 网络dockernetwork create网络名# 创建网络dockernetworkls# 查看所有网络dockernetwork connect网络名容器名# 将容器加入网络# Composedockercompose up-d# 启动所有服务dockercompose down# 停止并删除dockercompose logs-f# 查看日志dockercompose restart# 重启所有服务

相关新闻

最新新闻

解析参数并构建值变量

解析参数并构建值变量

字符串和缓存区这些格式准许凭借连续的内存块形态来对对象予以访问, 你并无必要去提供返回的字符或者字节区的原本数据存储。一般说来, 当有一个表达式, 其设置了一个指针, 该指针指向一个缓冲区, 此缓冲区能够被对应的对象进行管理, 而且这个缓冲区会共享该对象的生存周期, 你…

2026/9/2 17:38:47
编译器的工作过程

编译器的工作过程

源码要运行,必须先转成二进制的机器码。这是编译器的任务。比如,下面这段源码(假定文件名叫做test.c)。#include int main(void) {fputs("Hello, world!\n", stdout);return 0; }要先用编译器处理一下,才能…

2026/9/2 17:38:47
python 函数的使用

python 函数的使用

函数作为一种极具用处的工具, 能够处理诸多重复性工作, 它类似于我们时常从事的一项事务, 即将一些频繁会用到的物品制作成模板, 随后在每一回使用之际, 创建一个副本便可。当中, 我们叫其封装, 相关操作更便利点, 因无需再创建副本, 是直接调用, 具体这般调用该咋做呢, 文中将…

2026/9/2 17:38:47
Spring Boot实战:构建业务系统二级密码安全验证功能

Spring Boot实战:构建业务系统二级密码安全验证功能

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/2 17:38:47
Python学习【183】:深度解析:Java与Python的“跨平台”真相

Python学习【183】:深度解析:Java与Python的“跨平台”真相

一、学前花絮于编程语言领域里, Java 以及 无疑是两座难以逾越的高峰。它们均宣称自身乃“跨平台”的佼佼者, 然而要是你深入钻研它们的底层运作机理, 便会发觉这朝向跨平台的两条路径, 在设计理念方面存在着本质性的不同。今日, 我们便从虚拟器跟解释器的工作机理, 以及程序的…

2026/9/2 17:38:47
LLM应用工程化:摒弃无效人性化,构建稳健结构化输出

LLM应用工程化:摒弃无效人性化,构建稳健结构化输出

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/2 17:33:47