【Docker】容器端口暴露+镜像生成实战

【Docker】容器端口暴露+镜像生成实战

博主有话说

在完成了之前博文专栏对linux和docker指令的介绍后,接下来开始对docker的应用进行实战。本博文主要对容器端口暴露、镜像生成进行要点的记录与实战。

容器端口暴露

在之前【Docker】常用帮忙、镜像、容器、其他命令合集(2)的博文中,有介绍过docker run指令,以nginx为例,通过docker run -d nginx进行后台运行,成功后,通过 curl localhost:80去进行访问,结果没通。

对容器端口向主机CenOS7进行暴露,重新采用docker run -d -p 3344:80 nginx进行启动,可以发现通过 curl localhost:3344去进行访问,可以正常访问nginx。

在理解这部分端口暴露内容之前,可以先回顾一下虚拟机、容器之间的关系!

虚拟机、容器

容器和虚拟机(VM)都是实现 "资源隔离与环境一致性" 的技术,但底层原理和适用场景有本质区别,核心差异在于隔离粒度、资源效率和启动速度

隔离粒度是 "隔离强度 " 与 "资源效率 " 的权衡工具 ------粒度越粗,隔离越安全,但资源浪费越多、成本越高;粒度越细,资源利用率越高、成本越低,但安全性依赖更精细的软件 / 技术控制

  • 粗粒度隔离:如物理服务器级隔离;
  • 中粒度隔离:如虚拟机级隔离;
  • 细粒度隔离:如容器级隔离。

一、核心原理对比

用一个直观的比喻理解:

  • 虚拟机 像 "独立的房子":每套房子(VM)有自己的 "地基(硬件模拟)""墙体(操作系统)" 和 "家具(应用)",完全独立,互不干扰。

  • 容器 像 "同一套房子里的独立房间":房子(宿主机)只有一个地基(物理硬件)和一个墙体(宿主机操作系统),每个房间(容器)共享房子的基础设施,但通过门(namespace)和墙(cgroups)隔离,只放自己的家具(应用)。

1. 虚拟机(VM)的工作方式

  • 多层结构:
    物理硬件 → Hypervisor(虚拟机监控器,如 VMware、KVM)→ 虚拟机操作系统(Guest OS,如 Linux、Windows)→ 应用程序。
  • 核心特点:
    Hypervisor 会模拟完整的硬件环境 (CPU、内存、磁盘、网络卡等),每个虚拟机都需要安装独立的操作系统,应用程序运行在虚拟机的 OS 中。
    虚拟机与宿主机、虚拟机之间完全隔离(硬件级隔离),一个虚拟机崩溃不会影响其他虚拟机或宿主机。

2. 容器(Container)的工作方式

  • 单层结构:
    物理硬件 → 宿主机操作系统(如 Linux)→ 容器引擎(如 Docker、containerd)→ 容器(应用 + 依赖库)。
  • 核心特点:
    容器不模拟硬件,而是通过宿主机 OS 的内核隔离技术 (Linux 的 namespace 和 cgroups)实现隔离:
    • namespace:让容器拥有独立的 "进程、网络、文件系统" 等视图(比如容器内的进程看不到宿主机的进程);
    • cgroups:限制容器的资源使用(如最多用 2 核 CPU、4GB 内存)。
      所有容器共享宿主机的操作系统内核,容器内只需包含应用程序及其依赖的库(无需完整 OS)。

二、关键差异对比表

端口暴露分析

通过以上的分析,可以清楚,多个容器用的其实是同一套操作系统、物理硬件等。那么联系到刚刚实战上,可以认识到,docker run -d nginx虽然对容器的端口进行了暴露,但是并未对linux系统的进行暴露;而docker run -d -p 3344:80 nginx将容器的80端口映射到宿主机即cenos7的3344端口,实现了端口暴露,从而让外网正常访问,如下图所示。由于是虚拟机,因此不需要进行安全组的设置 ;如果用的第三方云平台,则还需要再进行安全组的设置 ,实现端口的暴露。

由于虚拟机与主机桥接,虚拟机ip是192.168.1.9,因此,在主机中用http://192.168.1.9:3344 进行访问,同样可以正常访问!

ps: 学到这里,想到最初学习docker的目的,是为了用docker实现内网穿透。有点眉目了,此时感觉有点类似向日葵,2台主机a、b都安装向日葵软件,a、b都由软件公司控制,然后a将识别码给b,b就可以访问a。这里软件公司就类似于docker,a 就类似于nginx,b类似于虚拟机外面的主机。只是肤浅的理解,随着后面继续学习,对错见知晓!

镜像生成

bash 复制代码
# 提交容器成为一个新的副本
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]

在tomcat容器的可写层进行写入,且运行容器

在指令测试前,先对tomcat进行运行,可以发现docker run -d --name=tomcat -p 8080:8080 tomcat后,curl localhost:8080无法访问。

这个因为库里面的tomcat是阉割版的,比官网下载的少了很多配置文件,需要进行配置文件的增加 。由于之前已经对容器进行了tomcat的命名,通过docker exec -it tomcat /bin/bash进行bash交互页面,用cp -r ./webapps.dist/* webappswebapps.dist里面的文件全部复制到webapps里面即可

tomcat新镜像生成

完成了容器可写层的写入后,通过docker commit -a="haitao" -m="add wwbapps" tomcat tomcatfinal:1.0完成新镜像的生成。

新镜像文件的放置路径可以通过docker info进行查询,里面Docker Root Dir 的路径就是放置路径,默认是/var/lib/docker。但是由于是docker是联合文件系统,一层层的导致很难找!如果有镜像仓库,建议docker push/pull最方便;如果是本地,可以采用docker save 导出为 tar文件,该文件会保存在当前执行命令的工作目录下。故用docker save -o tomcatfinaltar.tar tomcatfinal:1.0进行保存,然后在xshell中打开xftp,可以将tar文件进行复制即可。

后续要用了,再用docker load -i tomcatfinaltar.tar导入即可。

相关推荐
小蒜学长1 天前
springboot多功能智能手机阅读APP设计与实现(代码+数据库+LW)
java·spring boot·后端·智能手机
蜀山雪松1 天前
全网首先 Docker Compose 启动Postgresql18
运维·docker·容器
你的人类朋友1 天前
【Docker】说说卷挂载与绑定挂载
后端·docker·容器
zizisuo1 天前
解决在使用Lombok时maven install 找不到符号的问题
java·数据库·maven
笨蛋少年派1 天前
JAVA基础语法
java·开发语言
Haooog1 天前
654.最大二叉树(二叉树算法)
java·数据结构·算法·leetcode·二叉树
我真的是大笨蛋1 天前
依赖倒置原则(DIP)
java·设计模式·性能优化·依赖倒置原则·设计规范
邂逅星河浪漫1 天前
【RabbitMQ】docker-compose编排部署RabbitMQ容器——CentOS
分布式·docker·centos·rabbitmq·docker-compose
zrande1 天前
Docker经典安装命令失效排查:Ubuntu/CentOS多系统测试与解决方案
ubuntu·docker·centos
东方芷兰1 天前
JavaWeb 课堂笔记 —— 20 SpringBootWeb案例 配置文件
java·开发语言·笔记·算法·log4j·intellij-idea·lua