今天学写的内容是Dockerfile、镜像制作以及私有仓库的搭建和管理。
一、Dockerfile概述
1.1.Dockerfile是什么?
Dockerfile 是一个文本文件 ,其中包含了一系列指令,用户可以通过这些指令来定义如何自动构建 一个 Docker 镜像 。每条指令代表一个构建步骤,例如安装软件、复制文件、设置环境变量等。通过 docker build
命令,Docker 会按顺序执行这些指令,最终生成一个可运行的镜像。
1.2 Dockerfile的出现是为了解决哪些问题?
在没有 Dockerfile 之前,常见的做法是使用 docker commit
命令将运行中的容器保存为镜像。但这种方式存在诸多局限性
问题 | 描述 |
---|---|
不可重复性 | 手动操作易出错,难以保证每次构建的一致性。 |
缺乏版本控制 | 容器状态无法像代码一样进行版本追踪和审查。 |
难以协作 | 团队成员无法清晰了解镜像是如何构建的。 |
透明度差 | 镜像内部结构和配置不透明,不利于审计和维护。 |
效率低 | 每次都需要手动进入容器执行命令,流程繁琐。 |
Dockerfile 实现了"基础设施即代码(Infrastructure as Code)",提升了镜像构建的自动化、可复用性和可维护性。
1.3 Dockerfile的指令详解
指令 | 功能说明 | 注意事项 |
---|---|---|
FROM |
指定基础镜像 | 必须是第一条非注释指令 |
MAINTAINER (已弃用) |
指定作者信息 | 推荐使用 LABEL maintainer="..." |
LABEL |
添加元数据标签 | 如版本、描述等 |
RUN |
构建时执行命令 | 支持 shell 和 exec 模式 |
CMD |
容器启动时默认执行的命令 | 可被 docker run 覆盖 |
ENTRYPOINT |
容器启动时必执行的命令 | 更适合固定入口 |
COPY |
复制本地文件/目录到镜像中 | 只支持本地路径 |
ADD |
类似 COPY,支持解压和远程 URL | 不推荐用于远程资源 |
WORKDIR |
设置工作目录 | 若不存在则自动创建 |
ENV |
设置环境变量 | 后续指令可用 |
EXPOSE |
声明端口 | 仅说明用途,不实际暴露 |
VOLUME |
创建挂载点 | 用于数据持久化 |
USER |
切换用户 | 提升安全性 |
ARG |
构建参数 | 构建时传入,不保留在镜像中 |
最佳实践建议:
- 合并
RUN
指令以减少镜像层数 - 使用
.dockerignore
忽略无关文件 - 优先使用官方轻量基础镜像(如
alpine
,distroless
)
二、镜像的制作
2.1 上帝进程是什么?
在操作系统中,"上帝进程 "通常指 PID=1 的进程,也称为 init 进程。它是系统中所有其他进程的祖先,负责启动和管理其他进程,并处理僵尸进程的回收。
2.2 容器的上帝进程
在 Docker 容器中,启动命令所对应的进程就是 PID=1 的"上帝进程"。
- 如果该进程退出,容器也随之终止。
- 它需要具备一定的"init"能力,比如转发信号、回收子进程等。
⚠️ 问题示例: 若你启动了一个后台服务(如
nginx
),但未使用daemon off;
或前台模式运行,主进程可能立即退出,导致容器无法启动。
✅ 正确做法:
CMD ["nginx", "-g", "daemon off;"]
确保 nginx 以前台方式运行,成为容器的主进程。
如果有疑问,请看这篇文章:主进程生命周期决定容器生命周期,希望可以解决您的疑问。
2.3 Dockerfile 制作镜像案例(通用模板)
# 编辑Dockerfile
[root@docker ~]# vim myimg/Dockerfile
FROM mylinux:latest
COPY myfile.tar /tmp/
ADD myfile.tar /var/tmp/
RUN touch /tmp/file1
USER nobody
RUN touch /tmp/file2
ENV TZ="Asia/Shanghai"
EXPOSE 12345/tcp
WORKDIR /tmp # 新添加
CMD ["/bin/bash"]
构建命令:
docker build -t myimg:latest testimg/
运行测试:
docker run -it --rm myimg
三、镜像制作实战
3.1 httpd镜像制作
FROM ubuntu:20.04
LABEL maintainer="admin@company.com" \
service="Apache HTTP Server"
# 静默安装,避免交互
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
apt-get install -y apache2 && \
rm -rf /var/lib/apt/lists/*
EXPOSE 80
# 自定义首页
COPY index.html /var/www/html/
# 使用 exec 模式启动(前台运行)
CMD ["/usr/sbin/apache2ctl", "-D", "FOREGROUND"]
-D FOREGROUND
确保 Apache 不作为守护进程运行。
3.2 nginx镜像制作
FROM alpine:latest
RUN apk add --no-cache nginx && \
mkdir -p /run/nginx
# 添加自定义配置(可选)
COPY nginx.conf /etc/nginx/nginx.conf
# 添加网页内容
COPY ./html /var/www/html
EXPOSE 80
# 启动 nginx 前台进程
CMD ["nginx", "-g", "daemon off;"]
✅ 优势:Alpine 镜像小巧安全,适合生产环境。
3.3 php-fpm 镜像制作
FROM php:8.1-fpm-alpine
LABEL maintainer="php-team@example.com"
# 安装常用扩展
RUN docker-php-ext-install mysqli pdo pdo_mysql
# 可选:安装额外工具
RUN apk add --no-cache git vim
# 设置工作目录
WORKDIR /var/www/html
# 更改用户权限(可选)
USER www-data
# 默认启动 php-fpm
# CMD 自动继承自父镜像,无需重写
EXPOSE 9000
📦 使用场景:配合 Nginx 容器实现前后端分离架构。
四、私有镜像仓库的搭建
4.1 私有仓库的概述
私有镜像仓库(Private Registry) 是企业内部用于存储和分发 Docker 镜像的服务,相比公共仓库(如 Docker Hub),具有以下优势:
优势 | 说明 |
---|---|
安全性高 | 镜像不对外公开,防止敏感信息泄露 |
网络性能好 | 内网部署,拉取速度快 |
成本可控 | 避免公网流量费用 |
自主可控 | 可定制认证、权限、策略等 |
🛠️ 常见方案:
- Docker Registry(开源)
- Harbor(VMware 开源,功能更强大)
- Nexus Repository
- 云厂商服务(如阿里云 ACR、AWS ECR)
主流的私有仓库有docker Registry 和 vmware Harbor ,registry 提供仓库的核心能力,包括分层传输机制,web接口功能。 Habor是在registry上进行了相应的企业级拓展,包括:web界面,支持登录、搜索功能,区分私有、公有镜像,基于角色的访问控制,集成日志审计、支持水平拓展等功能。
4.2私有仓库的安装部署
# 在 registry 上安装私有仓库
[root@registry ~]# vim /etc/yum.repos.d/docker.repo
[Docker]
name=Rocky Linux $releasever - Docker Packages
baseurl="ftp://192.168.88.240/rpms" #另需搭建
enabled=1
gpgcheck=0
[root@registry ~]# dnf makecache
[root@registry ~]# dnf install -y docker-distribution
# 启动私有仓库,并设置开机自启动
[root@registry ~]# systemctl enable --now docker-distribution
所有 docker 节点都需要配置
[root@docker ~]# vim /etc/hosts
192.168.88.30 registry
# 修改配置文件
[root@docker ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["http://registry:5000", "其他镜像仓库"],
"insecure-registries":["registry:5000"]
}
# 重启服务生效
[root@docker ~]# systemctl restart docker
[root@docker ~]# docker info
4.3 私有仓库的管理
# 给镜像设置标签
[root@docker ~]# docker tag mylinux:latest registry:5000/img/mylinux:latest
# 上传镜像
[root@docker ~]# docker push registry:5000/img/mylinux:latest
# 查看仓库中所有镜像的名称
[root@docker ~]# curl http://registry:5000/v2/_catalog
# 查看某一镜像的所有标签
[root@docker ~]# curl http://registry:5000/v2/img/mylinux/tags/list
{"name":"img/mylinux","tags":["latest","8"]}
# 删除所有容器
[root@docker ~]# docker rm -f $(docker ps -aq)
# 删除所有镜像
[root@docker ~]# docker rmi $(docker images --format='{{.Repository}}:
# 下载镜像
[root@docker ~]# docker pull registry:5000/img/mylinux:latest
# 创建容器
[root@docker ~]# docker run -itd --rm registry:5000/library/myhttpd:latest
4.2 私有仓库的安装部署(以 Docker Registry 为例)
步骤 1:拉取并运行 Registry 镜像
docker run -d \
--name registry \
-p 5000:5000 \
-v /opt/registry:/var/lib/registry \
--restart=always \
registry:2
-p 5000:5000
:暴露本地 5000 端口-v
:持久化存储镜像数据registry:2
:使用 v2 版本
步骤 2:推送镜像到私有仓库
# 标记镜像
docker tag my-httpd:latest localhost:5000/my-httpd:v1
# 推送
docker push localhost:5000/my-httpd:v1
步骤 3:从其他主机拉取(需配置信任)
修改 /etc/docker/daemon.json
:
{
"insecure-registries": ["your-registry-ip:5000"]
}
重启 Docker:
systemctl restart docker
拉取镜像:
docker pull your-registry-ip:5000/my-httpd:v1
4.3 私有仓库的管理
✅ 安全加固(推荐)
功能 | 实现方式 |
---|---|
HTTPS 加密 | 配置 TLS 证书 |
身份认证 | 使用 htpasswd 或集成 LDAP/OAuth |
访问控制 | 设置用户权限(读/写) |
示例:添加基本认证
# 安装 apache2-utils
htpasswd -Bbn username password > auth/htpasswd
# 启动带认证的 registry
docker run -d \
--name registry \
-p 5000:5000 \
-v /opt/registry:/var/lib/registry \
-v ./auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
registry:2
✅ 镜像管理
-
查看仓库中的镜像:
curl http://localhost:5000/v2/_catalog
-
查看镜像标签:
curl http://localhost:5000/v2/my-httpd/tags/list
-
删除镜像 : 需启用
DELETE
API 并调用/v2/<name>/manifests/<digest>
,之后运行registry garbage-collect
清理空间。
✅ 日志与监控
-
查看日志:
docker logs registry
-
可结合 Prometheus + Grafana 实现监控。
✅ 推荐使用 Harbor(进阶选择)
Harbor 是企业级 Registry,提供:
- 图形化界面
- RBAC 权限控制
- 镜像扫描(漏洞检测)
- 复制同步(多站点)
- AD/LDAP 集成