当前位置: 首页 > news >正文

docker-镜像

docker-镜像

  • 一、镜像的本质与特性
  • 二、镜像的原理
    • 2.1 分层结构
    • 2.2 写时复制(Copy-on-Write)机制
  • 三、为什么要制作镜像
  • 四、制作镜像
    • 第1步:编辑Dockerfile
    • 第2步:编辑requirements.txt文件
    • 第3步:编辑app.py程序文件
    • 第4步:生成镜像文件
    • 第5步:使用镜像,启动容器
    • 第6步: 启动redis容器
    • 第7步: 再次启动一个自己制作镜像的容器,链接到redis容器
    • 第8步:访问容器的web服务
  • 五、Dockfile 的指令
  • 六、以 busybox 为基础镜像
  • 七、go 语言制作镜像


一、镜像的本质与特性

1.镜像的本质
Docker 镜像本质上是一个只读的二进制文件包,包含了运行应用所需的完整环境:

  • 应用程序代码
  • 运行时的环境(如 JRE、Python 解释器)
  • 库文件(如 .so、.dll 文件)
  • 环境变量
  • 配置文件
  • 操作系统内核的部分文件(并非完整内核)

它就像一个静态模板,是创建容器的 “蓝图”,容器则是镜像的动态运行实例

2.核心特性

  • 只读性:镜像一旦构建完成就不可修改,确保了环境的一致性
  • 可移植性:相同的镜像在任何支持 Docker 的环境中运行结果一致
  • 自包含:包含应用运行所需的所有依赖,无需外部依赖
  • 版本化:通过标签(Tag)实现版本管理
  • 轻量性:相比虚拟机镜像体积更小,启动更快

二、镜像的原理

2.1 分层结构

在这里插入图片描述

分层原理

  • 每个镜像由多个只读层(Layer)叠加而成
  • 每层对应 Dockerfile 中的一条指令(如 RUN、COPY 等)
  • layers 按照构建顺序依次堆叠,共同构成完整的文件系统
  • 底层为base镜像,提供的是最小安装的 Linux 发行版(如 Debian、Ubuntu),上层为应用相关内容
  • 所有的容器都是共享宿主机的内核kernel

在这里插入图片描述

分层优势

  • 共享复用:不同镜像可共享相同的底层,节省存储空间
  • 增量更新:修改仅影响顶层,底层不变
  • 缓存加速:构建镜像时可利用缓存,加速构建过程
  • 版本控制:每层都有唯一标识,便于追踪和回滚

2.2 写时复制(Copy-on-Write)机制

写时复制是 Docker 实现高效存储和隔离的关键技术

1.读取操作:

  • 当容器需要读取一个文件时,Docker 会从顶层开始逐层查找该文件
  • 找到第一个包含该文件的层后,直接读取该层的文件

2.修改操作:

  • 当容器需要修改一个文件时,Docker 会先从底层找到该文件
  • 将文件复制到最上层的可写层(容器层)
  • 只修改容器层中的副本,不影响原只读层

3.删除操作:

  • 容器删除文件时,并不会真正删除底层只读层的文件
  • 而是在可写层创建一个特殊的 “删除标记”(whiteout 文件)
  • 后续访问该文件时,系统会识别这个标记并返回文件不存在

优势:

  • 多个容器可共享底层镜像,节省存储空间
  • 容器启动快速,无需复制整个文件系统
  • 保持镜像的只读性和一致性

所有对容器的改动 - 无论添加、删除、还是修改文件都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的

容器启动的时候,内核启动bootfs后直接将基础镜像加载,然后一层一层的加载–》自下而上
容器运行后访问文件的时候,从上而下,从可写层,一层一层往下访问


三、为什么要制作镜像

docker hub上有很多镜像,为什么还要制作呢?
1.不能满足我们的需要
2.不够安全,有安全隐患

制作镜像的必要性:

  1. 解决 “环境不一致”的经典难题
    Docker 镜像通过将应用程序及其所有依赖(运行时、库、配置)打包成一个不可变的文件,确保了无论在哪个环境,只要运行该镜像,就能获得完全一致的执行环境

  2. 简化依赖管理
    镜像通过在构建时一次性固化所有依赖,避免了重复安装和版本冲突问题

  3. 标准化部署流程,提高效率
    镜像将部署流程简化为 “拉取镜像 → 启动容器” 两步,且这个流程对所有应用完全一致。开发人员只需专注于构建镜像,运维人员只需负责运行镜像,实现了开发与运维的协作标准化

  4. 轻量高效,资源利用率更高

  5. 支持版本控制与回滚

  6. 便于集成到自动化流程(CI/CD)
    在持续集成 / 持续交付(CI/CD)流水线中,镜像扮演着 “交付单元” 的角色:

    • 代码提交后,CI 工具(如 Jenkins、GitHub Actions)自动构建镜像并运行测试
    • 测试通过后,镜像被推送到仓库,作为可部署的 “成品”
    • CD 工具从仓库拉取镜像,自动部署到测试 / 生产环境

    这种模式实现了从代码到部署的全自动化,减少了人工干预,提高了交付速度


四、制作镜像

第1步:编辑Dockerfile

[root@docker ~]# mkdir /mydocker
[root@docker ~]# cd /mydocker/
[root@docker mydocker]# vim Dockerfile
FROM python:2.7-slim	
WORKDIR /app	
ADD . /app
RUN pip install --trusted-host  pypi.python.org -r requirements.txt
EXPOSE 80
ENV NAME World
ENV AUTHOR cali
CMD ["python","app.py"]

第2步:编辑requirements.txt文件

[root@docker mydocker]# vim requirements.txt
Flask
Redis

第3步:编辑app.py程序文件

[root@docker mydocker]# vim app.py
from flask import Flask
from redis import Redis, RedisError
import os
import socket# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)app = Flask(__name__)@app.route("/")
def hello():try:visits = redis.incr("counter")except RedisError:visits = "<i>cannot connect to Redis, counter disabled</i>"html = "<h3>Hello {name}!</h3>" \"<b>Hostname:</b> {hostname}<br/>" \"<b>Visits:</b> {visits}"return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)if __name__ == "__main__":app.run(host='0.0.0.0', port=80)

第4步:生成镜像文件

[root@docker mydocker]# docker build -t mywebapp:1.0 .
[+] Building 117.2s (9/9) FINISHED                                                                                                                     docker:default=> [internal] load build definition from Dockerfile                                                                                                             0.1s=> => transferring dockerfile: 274B                                                                                                                             0.0s=> [internal] load metadata for docker.io/library/python:2.7-slim                                                                                              15.6s=> [internal] load .dockerignore                                                                                                                                0.0s=> => transferring context: 2B                                                                                                                                  0.0s=> [1/4] FROM docker.io/library/python:2.7-slim@sha256:6c1ffdff499e29ea663e6e67c9b6b9a3b401d554d2c9f061f9a45344e3992363                                        19.5s=> => resolve docker.io/library/python:2.7-slim@sha256:6c1ffdff499e29ea663e6e67c9b6b9a3b401d554d2c9f061f9a45344e3992363                                         0.0s=> => sha256:eeb27ee6b89303f04a917e457eda70d032b1574ec80d0b4ea410d478a714538f 7.95kB / 7.95kB                                                                   0.0s=> => sha256:123275d6e508d282237a22fefa5aef822b719a06496444ea89efa65da523fc4b 27.10MB / 27.10MB                                                                 4.2s=> => sha256:dd1cd66375238ded36eeaea07567a1997f7fd76611a517119ec39fee9b9e887f 2.75MB / 2.75MB                                                                   3.9s=> => sha256:0c4e6d630f2cb5403efb04352c40ed72f1884355253a0cc15486c4e6ca998111 19.66MB / 19.66MB                                                                 7.3s=> => sha256:6c1ffdff499e29ea663e6e67c9b6b9a3b401d554d2c9f061f9a45344e3992363 1.86kB / 1.86kB                                                                   0.0s=> => sha256:b68d40df862ac07e8955ea0fc0c5454cb4245b6165e79bc8ea2cc69170d9ba62 1.16kB / 1.16kB                                                                   0.0s=> => sha256:13e9cd8f0ea14403e44c745ea5212658b6600021f6beb6fc484f2570db89b143 2.18MB / 2.18MB                                                                   5.1s=> => extracting sha256:123275d6e508d282237a22fefa5aef822b719a06496444ea89efa65da523fc4b                                                                        8.6s=> => extracting sha256:dd1cd66375238ded36eeaea07567a1997f7fd76611a517119ec39fee9b9e887f                                                                        0.8s=> => extracting sha256:0c4e6d630f2cb5403efb04352c40ed72f1884355253a0cc15486c4e6ca998111                                                                        3.7s=> => extracting sha256:13e9cd8f0ea14403e44c745ea5212658b6600021f6beb6fc484f2570db89b143                                                                        1.2s=> [internal] load build context                                                                                                                                0.1s=> => transferring context: 1.15kB                                                                                                                              0.0s=> [2/4] WORKDIR /app                                                                                                                                           0.5s=> [3/4] ADD . /app                                                                                                                                             0.1s=> [4/4] RUN pip install --trusted-host  pypi.python.org -r requirements.txt                                                                                   80.5s=> exporting to image                                                                                                                                           0.8s => => exporting layers                                                                                                                                          0.8s => => writing image sha256:8331ce7fbacbd03b4f6e7773debf59c7bd0ff93e573b6b17d6091d609b0db048                                                                     0.0s => => naming to docker.io/library/mywebapp:1.0                                                                                                                  0.0s 2 warnings found (use docker --debug to expand):                                                                                                                     - LegacyKeyValueFormat: "ENV key=value" should be used instead of legacy "ENV key value" format (line 6)- LegacyKeyValueFormat: "ENV key=value" should be used instead of legacy "ENV key value" format (line 7)# 查看镜像
[root@docker mydocker]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
mywebapp     1.0       8331ce7fbacb   47 seconds ago   159MB

第5步:使用镜像,启动容器

[root@docker mydocker]# docker run -d -p 5080:80 --name web-1 mywebapp:1.0
39219ff1e4a9d864d6436996a28118544c7dc6c0faf29b370f5d1611cf8d29f4
redis        latest    f1285ef3611d   3 weeks ago      137MB

访问容器的web服务

在这里插入图片描述

因为redis数据库容器没有启动,flask web服务不能连接到redis数据库

第6步: 启动redis容器

[root@docker mydocker]# docker run -d -p 6379:6379 --name sc-redis-1 redis
ba927f84f0826d1c55a90ce7a4fb1dbc7d2692d24d13c0fc9839a9671007da6a

第7步: 再次启动一个自己制作镜像的容器,链接到redis容器

[root@docker mydocker]# docker run -d -p 5081:80 --name web-2 --link sc-redis-1:redis mywebapp:1.0
2514bc3fbee99abaa2b86397484c94c8bc1569989959e45a7c90253586a0d065

第8步:访问容器的web服务

在这里插入图片描述

如何让镜像尽可能的小?

  1. 使用比较小的基础镜像
    -> busybox、Ubuntu、oraclelinux、centos、
    alpine(是一个比较小的linux系统)

  2. 尽量减少使用RUN、COPY、ADD、ENV等新增数据的操作 -> 减少对镜像里的数据改动

  3. 尽量不把数据拷贝到容器里,当容器启动起来后,可以使用挂载卷的方法,减少镜像的数据


五、Dockfile 的指令

FROM python:2.7-slim	# 指定基础镜像
WORKDIR /app	# 指定进入容器的时候默认进入的目录 --》docker exec
COPY . /app # 拷贝宿主机当前目录下的所有文件到容器的/app目录里
ADD . /app	# 如果复制的是压缩文件,拷贝到容器里会自动解压RUN pip install --trusted-host  pypi.python.org -r requirements.txt # 制作镜像的时候,会启动一个临时的容器,在容器里的微型系统里执行命令EXPOSE 80	# 声明容器开放的端口
ENV NAME World	# 在容器的微型系统里定义环境变量,进入系统可以看到
ENV AUTHOR cali
CMD ["python","app.py"] 	# 容器启动的时候执行的第一个命令

官方文档:https://docs.docker.com/reference/dockerfile/

指令功能示例
FROM指定基础镜像FROM alpine:3.18
WORKDIR指定进入容器的时候默认进入的目录WORKDIR /app
COPY拷贝宿主机当前目录下的所有文件到容器的/app目录里COPY . /app
ADD如果复制的是压缩文件,拷贝到容器里会自动解压ADD ./app
RUN制作镜像的时候,会启动一个临时的容器,在容器里的微型系统里执行命令RUN apt update && apt install -y python3
CMD容器启动的时候执行的第一个命令CMD [“python3”, “app.py”]
ENTRYPOINT容器启动时的入口命令,与 CMD 类似,但不可被容器启动命令直接覆盖ENTRYPOINT [“python3”]
EXPOSE声明开放的端口EXPOSE 8080
ENV在容器的微型系统里定义环境变量,进入系统可以看到ENV APP_ENV production
ARG构建参数ARG VERSION=1.0
VOLUME定义数据卷VOLUME [“/data”]

ENTRYPOINT和CMD的区别

  • docker run 启动容器的时候,可以传递参数进入给ENTRYPOINT 里面的命令

  • 当2者都存在的时候,CMD里的内容会成为ENTRYPOINT里的参数(位置参数)

ENTRYPOINT 配合set指令能设置所使用shell的执行方式,可依照不同的需求来做设置

语法 set [±abCdefhHklmnpPtuvx]
参数说明:
-e  若指令传回值不等于0,则立即退出shell
-u 当执行时使用到未定义过的变量,则显示错误信息
-x  执行指令后,会先显示该指令的执行过程及所下的参数


六、以 busybox 为基础镜像

创建 Dockerfile 和脚本文件

[root@docker mydocker]# cd busybox/
[root@docker busybox]# vim Dockerfile
FROM busybox
WORKDIR /
COPY . /
RUN touch sc.txt && mkdir -p sc && sleep 5
ENTRYPOINT ["/bin/sh","/while.sh"][root@docker busybox]# vim while.sh 
#!/bin/sh
i=1
while true
doecho "hello,world,sc $i"let i++sleep 1
done

构建 Docker 镜像

[root@docker busybox]# docker build -t scbusybox:1.0 .
[+] Building 5.8s (8/8) FINISHED                                                                                                                       docker:default=> [internal] load build definition from Dockerfile                                                                                                             0.0s=> => transferring dockerfile: 204B                                                                                                                             0.0s=> [internal] load metadata for docker.io/library/busybox:latest                                                                                                0.0s=> [internal] load .dockerignore                                                                                                                                0.0s=> => transferring context: 2B                                                                                                                                  0.0s=> [internal] load build context                                                                                                                                0.0s=> => transferring context: 376B                                                                                                                                0.0s=> [1/4] FROM docker.io/library/busybox:latest                                                                                                                  0.0s=> [2/4] COPY . /                                                                                                                                               0.0s=> [3/4] RUN touch sc.txt && mkdir -p sc && sleep 5                                                                                                             5.6s=> exporting to image                                                                                                                                           0.0s=> => exporting layers                                                                                                                                          0.0s=> => writing image sha256:7db9b723913b464e94cceb59e582a26fb7da00eef2dbadb4969534e3f978f82b                                                                     0.0s=> => naming to docker.io/library/scbusybox:1.0                                                                                                                 0.0s[root@docker busybox]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
scbusybox    1.0       7db9b723913b   26 seconds ago   4.26MB

七、go 语言制作镜像

准备代码文件,解压

[root@docker go]# ls
go+html+mysql+redis.zip
[root@docker go]# yum install unzip -y
[root@docker go]# unzip go+html+mysql+redis.zip 
[root@docker go]# ls
go+html+mysql+redis.zip  go.mod  go.sum  info.sql  Readme.md  server.go  static  templates

启动 mysql 容器并初始化数据库

[root@docker go]# docker run -d --name go-mysql-1 -p 33061:3306 -e MYSQL_ROOT_PASSWORD='sc123456' mysql:5.7.41
3564a1626f8bc8adff35603aae15a2571973a2def7ecfa7c5268dfe5fa9687ec
[root@docker go]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS                                                      NAMES
3564a1626f8b   mysql:5.7.41   "docker-entrypoint.s…"   4 seconds ago   Up 4 seconds   33060/tcp, 0.0.0.0:33061->3306/tcp, [::]:33061->3306/tcp   go-mysql-1
# 将数据库脚本复制到 MySQL 容器内
[root@docker go]# docker cp info.sql go-mysql-1:/
Successfully copied 4.61kB to go-mysql-1:/

进入容器内部,创建user表,然后导入表和基础的数据

mysql> create database users default character set utf8mb4;# 导入数据
bash-4.2# mysql -uroot -p'sc123456' users <info.sql[root@docker go]# docker run -d -p 6389:6379 --name sc-redis-2 redis
87306314727ec3ad934e2cfa6b861c110e9e79595bf671639c1dde4c605f7dd8

修改容器的IP地址和端口
[root@docker go]# vim server.go

编译go应用

[root@docker go]# yum install go -y
[root@docker go]# go version
go version go1.24.6 (Red Hat 1.24.6-1.el9_6) linux/amd64
# 重置 go 模块配置
[root@docker go]# mv go.mod go.sum /root
[root@docker go]# go mod init web
go: creating new go.mod: module web
go: to add module requirements and sums:go mod tidy
# 配置国内代理(加速依赖下载)
[root@docker go]# go env -w GOPROXY=https://goproxy.cn,direct
[root@docker go]# go mod tidy
# 编译
[root@docker go]# go build -o server server.go

构建 go 应用的 docker 镜像

[root@docker go]# vim Dockerfile
FROM golang
WORKDIR /go
COPY . /go
EXPOSE 8080
ENTRYPOINT ["/go/server"][root@docker go]# docker build -t goweb:1.0 .
[+] Building 1.7s (8/8) FINISHED                                                                                                      docker:default=> [internal] load build definition from Dockerfile                                                                                            0.1s=> => transferring dockerfile: 167B                                                                                                            0.0s=> [internal] load metadata for docker.io/library/golang:latest                                                                                0.0s=> [internal] load .dockerignore                                                                                                               0.0s=> => transferring context: 2B                                                                                                                 0.0s=> [1/3] FROM docker.io/library/golang:latest                                                                                                  0.3s=> [internal] load build context                                                                                                               0.9s=> => transferring context: 20.47MB                                                                                                            0.8s=> [2/3] WORKDIR /go                                                                                                                           0.1s=> [3/3] COPY . /go                                                                                                                            0.3s=> exporting to image                                                                                                                          0.3s=> => exporting layers                                                                                                                         0.2s=> => writing image sha256:b71b3d7827af85cd2d9689454073b8795917768594e45118c7de327f8527a992                                                    0.0s=> => naming to docker.io/library/goweb:1.0                                                                                                    0.0s[root@docker go]# docker run -d -p 8090:8080 --name goweb-1 goweb:1.0
93d03ae2c2af29acf497480e6a89811227f4bed5be5e505766893d8ece577166

访问8090端口

在这里插入图片描述

http://www.dtcms.com/a/408371.html

相关文章:

  • 常用外贸网站网站死链检测
  • 沈阳餐饮网站建设建设厅和住建厅有什么区别
  • 网站 app 哪个先做六安百度公司六安百度推广
  • 做外贸阿里巴巴有哪些网站大兴企业官方网站建设
  • 济南商务网站建设站长之家是什么
  • 网站模板之家官网制做网站首先应该怎么做
  • 有专业制作网站的公司吗郑州短视频运营
  • 做静态网站步骤浙江建站
  • 鲜花网站模板网站的内容和功能
  • 虚拟原型技术深度剖析:从基础原理到实战应用的全景指南
  • 网站一般用什么软件做的灰色行业推广渠道
  • 个人做的小网站需要备案个人公积金查询app下载
  • 烟台做网站多少钱wordpress 客户端管理
  • MySQL-数据库日志
  • 设备网站开发普通网站和营销型网站的区别是什么
  • 江阴网站制作设计江门网站开发公司
  • 【Math其他】博饼概率计算
  • 新电商网站中国装修公司排行榜
  • 电子网站商业策划书做外贸的人常用的网站
  • 深圳双语网站制作榆次网站建设公司
  • 海门做网站公司漯河网站开发
  • 第五章:技术深度与广度:构筑你的核心壁垒(4)
  • 宜宾网站制作公司黄页88登录入口
  • 网站制作方案有哪些100%上热门文案
  • 阿里云1M做网站云服务器 多个网站
  • 网上购物商城的背景与意义seo排名优化培训怎样
  • 山西省建设银行网站现在市场网站建设怎么样
  • wordpress建站入门心理咨询类微网站怎么做
  • 教做衣服的网站有哪些360指数查询工具
  • 哈尔滨工程建设信息网站企业官网设计规范