构建自己的docker基础镜像
构建一个完全定制的基础镜像意味着您需要从一个非常小的镜像(例如 scratch
镜像)开始,然后逐步添加您需要的所有内容。scratch
镜像是一个空白的基础镜像,可以用来创建高度定制的容器环境。
创建一个基础镜像
构建debian基础镜像
- 准备根文件系统:
要构建一个基础镜像,您需要一个最小的根文件系统。这可以通过使用 debootstrap
等工具来创建。debootstrap
是debian/ubuntu下的一个工具,用来构建一套基本的根文件系统,其生成的目录符合Linux文件系统标准(FHS),即包含了/boot、/etc、/bin、/usr等等目录,但它比发行版本的Linux体积小很多,当然功能也没那么强大,因此,只能说是“基本的系统”。
首先,在一个干净的 Linux 环境中,安装 debootstrap
:
sudo apt-get update
sudo apt-get install -y debootstrap
然后,使用 debootstrap
创建一个最小的 Debian
根文件系统:
# 创建Debian rootfs,测试使用官方源较慢,可以改为国内源https://mirrors.aliyun.com/debian
root@ubuntu:~/mydebian# sudo debootstrap --arch=amd64 stable ./my-rootfs http://deb.debian.org/debian/
root@ubuntu:~/mydebian# du -sh ./my-rootfs/
360M ./my-rootfs/
root@ubuntu:~/mydebian# ls ./my-rootfs/
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
# 设置阿里云镜像源,对rootfs下面的镜像源文件进行修改
root@ubuntu:~/mydebian# cat my-rootfs/etc/apt/sources.list
deb http://mirrors.aliyun.com/debian/ stable main contrib non-free
deb http://mirrors.aliyun.com/debian/ stable-updates main contrib non-free
deb http://mirrors.aliyun.com/debian/ stable-backports main contrib non-free
deb http://mirrors.aliyun.com/debian-security stable-security main contrib non-free
这将会在当前目录下创建一个名为 my-rootfs
的目录,其中包含了最小的 Debian
文件系统。
说明:
debootstrap
支持的发行版本可以在/usr/share/debootstrap/scripts/
查看,而各发行版代号可以到http://en.wikipedia.org/wiki/List_of_Ubuntu_releases
查看。如果是在arm环境下构建容器镜像,
ARMv8
架构设置--arch=arm64
,ARMv7
架构设置--arch=armhf
,同时镜像源指向对应架构的源地址。例如:
sudo debootstrap --verbose --arch=arm64 xenial ./ubuntu-rootfs https://mirrors.aliyun.com/ubuntu-ports/
-
创建
Dockerfile
:创建一个
Dockerfile
,并使用scratch
作为基础镜像,然后将您的根文件系统复制到其中。
# 使用 scratch 作为基础镜像
FROM scratch
# 复制最小的 Debian 根文件系统到镜像中
COPY ./my-rootfs/ /
# 设置环境变量
ENV DEBIAN_FRONTEND=noninteractive
# 设置时区
RUN ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone
# 安装基本工具
RUN apt-get update && \
apt-get install -y --no-install-recommends \
ca-certificates \
curl \
vim \
git \
wget \
net-tools \
iputils-ping \
dnsutils \
unzip \
&& rm -rf /var/lib/apt/lists/*
# 设置工作目录
WORKDIR /root
# 设置镜像作者信息
LABEL maintainer="[email protected]"
说明:
scratch
是Docker保留镜像,镜像名字避免使用该保留字,使用FROM scratch
表示构建镜像中的第一个文件层。
-
构建基础镜像:
在
Dockerfile
所在目录下,使用以下命令构建镜像:
docker build -t mybasedebian:12.0 .
# 构建成功后查看镜像列表
root@ubuntu:~/mydebian# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mybasedebian 12.0 8b7f616a56d2 2 minutes ago 612MB
构建ubuntu基础镜像
这次我以构建一个ubuntu
amd64
架构xenial
版本的容器镜像为例:
sudo debootstrap --verbose --arch=amd64 xenial ./ubuntu-rootfs https://mirrors.aliyun.com/ubuntu/
编写Dockerfile
:
# 使用 scratch 作为基础镜像
FROM scratch
# 复制最小的 Debian 根文件系统到镜像中
COPY ./ubuntu-rootfs/ /
# 设置环境变量
ENV DEBIAN_FRONTEND=noninteractive
# 设置时区
RUN ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo "Asia/Shanghai" > /etc/timezone
# 安装基本工具
RUN apt-get update && \
apt-get install -y --no-install-recommends \
ca-certificates \
curl \
wget \
net-tools \
iputils-ping \
dnsutils \
&& rm -rf /var/lib/apt/lists/*
# 设置工作目录
WORKDIR /root
# 设置镜像作者信息
LABEL maintainer="[email protected]"
构建测试镜像:
# 构建
docker build -t mybaseubuntu:1.0 .
# 测试
root@ubuntu:~/build/ubuntu# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myubuntubase 16.4 9d65bb9e40f8 5 minutes ago 301MB
root@ubuntu:~/build/ubuntu# docker run -it myubuntubase:16.4 bash
root@de5c43a4acfe:~# cat /etc/issue
Ubuntu 16.04 LTS \n \l
root@de5c43a4acfe:~# wget
wget: missing URL
Usage: wget [OPTION]... [URL]...
Try `wget --help' for more options.
构建centos
基础镜像
# 创建文件夹存放rootfs
$ export centos_root='/centos_image/rootfs'
$ mkdir -p $centos_root
# 初始化rpm数据库
$ rpm --root $centos_root --initdb
# 下载安装centos-release包,包括镜像仓库
$ yum reinstall --downloadonly --downloaddir . centos-release
$ rpm --root $centos_root -ivh centos-release*.rpm
$ rpm --root $centos_root --import $centos_root/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
# 修改yum源
$ sed -i "s/^mirrorlist/#mirrorlist/g" $centos_root/etc/yum.repos.d/CentOS-*.repo
$ sed -i "s/^#baseurl/baseurl/g" $centos_root/etc/yum.repos.d/CentOS-*.repo
$ sed -i "s/mirror.centos.org/mirrors.aliyun.com/g" $centos_root/etc/yum.repos.d/CentOS-*.repo
# 安装yum,不安装docs
$ yum -y --installroot=$centos_root --setopt=tsflags='nodocs' install yum
# 配置yum以避免安装文档和其他非英语语言的文件。
$ sed -i "/distroverpkg=centos-release/a override_install_langs=en_US.utf8\ntsflags=nodocs" $centos_root/etc/yum.conf
# 安装工具
$ cp /etc/resolv.conf $centos_root/etc
# 挂载设备树
$ mount -o bind /dev $centos_root/dev
# 切换根目录并安装工具。
$ chroot $centos_root /bin/bash <<EOF
yum install -y procps-ng iputils
yum clean all
EOF
$ rm -f $centos_root/etc/resolv.conf
$ umount $centos_root/dev
# 安装配置docker
$ yum install -y docker
...
$ systemctl start docker
# 创建容器镜像
$ tar -C $centos_root -c . | docker import - centos
sha256:aab86dea3b579ac24906bfe99ab0fb051a848c9c6f9cce664242dbf8b772c6be
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest aab86dea3b57 20 seconds ago 335 MB
# 测试容器镜像
$ docker run --rm centos cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
构建alpine
基础镜像
也可以直接下载官方发布的rootfs
,以 alpine为例,官方提供了rootfs
下载,downloads | Alpine Linux
# 下载官方rootfs
root@ubuntu:~/build/alpine# wget https://dl-cdn.alpinelinux.org/alpine/v3.20/releases/x86_64/alpine-minirootfs-3.20.1-x86_64.tar.gz
# 编写Dockerfile
root@ubuntu:~/build/alpine# cat Dockfile
FROM scratch
# 维护者信息
LABEL maintainer="[email protected]"
# 添加根文件系统,可解压格式文件,会自动解压
ADD alpine-minirootfs-3.20.1-x86_64.tar.gz /
# 设置阿里云镜像源,注意与rootfs版本匹配
RUN echo 'https://mirrors.aliyun.com/alpine/v3.20/main' > /etc/apk/repositories \
&& echo 'https://mirrors.aliyun.com/alpine/v3.20/community' >> /etc/apk/repositories
# 更新软件包并安装常用测试工具
RUN apk update && apk upgrade \
&& apk add --no-cache iproute2 iputils busybox-extras net-tools bind-tools \
&& apk add --no-cache curl wget tcpdump nmap vim iperf iperf3
# 设置启动Container时默认执行的命令,这个可以在启动容器时覆盖
CMD ["/bin/sh"]
# 构建镜像
docker build -t myalpine:3.20.1 .
构建完成后进行测试:
root@ubuntu:~/build/alpine# docker run -it docker.io/library/myalpine:3.20.1 sh
/ # cat /etc/issue
Welcome to Alpine Linux 3.20
Kernel \r on an \m (\l)
/ # ls
bin dev etc home lib media mnt opt proc root run sbin srv sys tmp usr var
使用基础镜像构建应用镜像
验证镜像
以debian为例,构建完成后,运行以下命令来验证镜像:
docker run -it mybasedebian:12.0 /bin/bash
# 测试镜像正常
root@ubuntu:~/mydebian# docker run -it mybasedebian:12.0 /bin/bash
root@37fe3bb4abb5:~# cat /etc/issue
Debian GNU/Linux 12 \n \l
root@37fe3bb4abb5:~# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
root@37fe3bb4abb5:~# curl
curl: try 'curl --help' or 'curl --manual' for more information
root@37fe3bb4abb5:~# wget
wget: missing URL
Usage: wget [OPTION]... [URL]...
Try `wget --help' for more options.
使用基础镜像构建其他镜像
创建一个新的 Dockerfile
,并以上面构建的基础镜像进一步制作应用容器镜像:
FROM mybasedebian:12.0
# 安装nginx
RUN apt-get update && \
apt-get install -y --no-install-recommends \
nginx \
&& rm -rf /var/lib/apt/lists/*
# 暴露端口
EXPOSE 80
# 设置启动命令
CMD ["nginx", "-g", "daemon off;"]
构建新的镜像:
# 镜像构建
docker build -t mynginx:1.0 .
# 查看镜像
root@ubuntu:~/build/nginx# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mynginx 1.0 792378cbb840 About a minute ago 698MB
测试镜像
# 基于构建的应用镜像运行容器
root@ubuntu:~/build/nginx# docker run -d mynginx:1.0
c35bd83ef7f1971594db47c01245822af3f76d86b9b801aeb62fd3ef9fb0bd2b
# 查询容器ip
root@ubuntu:~/build/nginx# docker inspect c35bd83ef7f19 | grep -i ipadd
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAddress": "172.17.0.2",
# 测试nginx响应正常
root@ubuntu:~/build/nginx# curl 172.17.0.2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
参考资料
- Base images | Docker Docs
- downloads | Alpine Linux
- Creating container base image of CentOS
- Creating minimal CentOS docker image from scratch