如何使用docker构建我自己的自定义Ubuntu ISO

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用docker构建我自己的自定义Ubuntu ISO相关的知识,希望对你有一定的参考价值。

作为背景,我有一个自定义的Ubuntu LiveUSB将自动启动到“试用”,操作系统将预装了我已经烧入ISO本身的应用程序。

它工作得很好,但我一直遇到自动化过程的问题。

而不是每次都手工完成,(因为我的bash脚本在我第一次尝试的时候会不断得到不同的结果)我正在考虑使用ISO中的解压缩文件生成一个docker镜像,以便进行修改,然后运行一个容器,其中包含一个卷中的脚本(docker run -v $(pwd)/ bin:/ data myimage /data/myscript.sh),它将修改内容,将其打包回ISO并将ISO保存在/中数据供我抓取和分发。

FROM ubuntu:16.04

MAINTAINER Myself

ENV ISO_FILE="ubuntu-16.04.3-desktop-amd64.iso" 
    OS_VERSION="16.04.3"

RUN apt-get update && apt-get install -y curl

RUN curl -sL https://deb.nodesource.com/setup_8.x | bash -
RUN apt-get install -y squashfs-tools genisoimage gnupg2 
                       nodejs rsync build-essential libc6-dev-i386 
                       wget

# Make directories
RUN mkdir /data
RUN mkdir -p /root/workspace

# Download ubuntu iso
WORKDIR /root/workspace
RUN wget http://releases.ubuntu.com/$OS_VERSION/$ISO_FILE
RUN wget http://releases.ubuntu.com/$OS_VERSION/SHA256SUMS
RUN wget http://releases.ubuntu.com/$OS_VERSION/SHA256SUMS.gpg

# Check hash (default /bin/sh errors out)
RUN /bin/bash -c "sha256sum -c <(grep $ISO_FILE SHA256SUMS)"

# Check signatures
RUN gpg2 --keyserver hkp://keyserver.ubuntu.com --recv-keys 0xFBB75451 0xEFE21092
RUN gpg2 --verify SHA256SUMS.gpg SHA256SUMS

# Create mount
RUN mkdir mnt

# Here is where the docker build fails
RUN mount -o loop $ISO_FILE mnt

# Extract official DVD
RUN mkdir extract-cd
RUN rsync --exclude=/casper/filesystem.squashfs -a mnt/ extract-cd
RUN unsquashfs mnt/casper/filesystem.squashfs
RUN mv squashfs-root edit
RUN umount mnt

# Insert buildscript and make it executable
COPY bin/buildscript.sh /root/workspace/edit/buildscript.sh
RUN chmod +x edit/buildscript.sh

# Prepare to chroot into unsquashed ubuntu image, and run buildscript.sh
RUN mount -o bind /run/ edit/run
RUN mount --bind /dev/ edit/dev
RUN chroot edit/ ./buildscript.sh

# unmount the mountpoints and delete the buildscript.
RUN umount edit/dev
RUN umount edit/run
RUN rm edit/buildscript.sh

而buildcript.sh我在构建器内运行chroot(或无法运行)是:

#!/bin/bash

mount -t proc none /proc
mount -t sysfs none /sys
mount -t devpts none /dev/pts
export HOME=/root
export LC_ALL=C
add-apt-repository "deb http://archive.ubuntu.com/ubuntu $(lsb_release -sc) universe multiverse"
curl -sL https://deb.nodesource.com/setup_8.x | bash -
apt install -y nodejs
apt upgrade -y
apt install -y chromium-browser git
apt install -y language-pack-ja language-pack-gnome-ja language-pack-ja-base language-pack-gnome-ja-base
localectl set-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"
source /etc/default/locale
mkdir src
apt autoclean
rm -rf /tmp/* ~/.bash_history
umount /proc || umount -lf /proc
umount /sys
umount /dev/pts
exit

由于这不起作用,我在网上发现build-run-commit方法可能有效...所以我将dockerfile的结尾更改为以下

# Create mount
RUN mkdir mnt
RUN mkdir extract-cd
COPY bin/buildscript.sh /root/workspace/buildscript.sh
COPY bin/build_run_step2.sh /root/workspace/build_run_step2.sh
RUN chmod +x buildscript.sh
RUN chmod +x build_run_step2.sh

然后构建运行提交的“运行”步骤是build_run_step2.sh,其中包含以下内容(使用--privileged运行)

#!/bin/bash

cd /root/workspace

mount -o loop $ISO_FILE mnt

# Extract official DVD
rsync --exclude=/casper/filesystem.squashfs -a mnt/ extract-cd
unsquashfs mnt/casper/filesystem.squashfs
mv squashfs-root edit
umount mnt

mv ./buildscript.sh edit/buildscript.sh

# Prepare to chroot into unsquashed ubuntu image, and run buildscript.sh
mount -o bind /run/ edit/run
mount --bind /dev/ edit/dev
chroot edit/ ./buildscript.sh

# unmount the mountpoints and delete the buildscript.
umount edit/dev
umount edit/run
rm edit/buildscript.sh

哪个有效......但后来我遇到了一个问题:

运行apt-get update会出错:

W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/xenial/InRelease  Temporary failure resolving 'archive.ubuntu.com'
W: Failed to fetch http://security.ubuntu.com/ubuntu/dists/xenial-security/InRelease  Temporary failure resolving 'security.ubuntu.com'
W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/xenial-updates/InRelease  Temporary failure resolving 'archive.ubuntu.com'

并且在chrooted时检查ping让我“找不到主机”。

所以一个主要问题和一个较小的问题(如果主要问题没有答案):

  1. 如何使用docker创建一个已打开的liveCD图像,可以自定义,然后在该图像上使用docker run来chroot,修改,重新打包和提取新的iso? (我知道通常这样做的命令,所以更确切地说,我想知道是否/为什么所有这些东西都不能在docker中工作...也就是在docker中chrooting的限制是什么?)
  2. 如何让容器内的chroot系统到达dns,以便它可以通过URLS运行更新? (我尝试从容器中的chroot内ping 8.8.8.8并且ping回来很好。)

提前致谢。

答案

如果您尚未更新源列表,则可能会发生这种情况。尝试:

sudo apt update

以上是关于如何使用docker构建我自己的自定义Ubuntu ISO的主要内容,如果未能解决你的问题,请参考以下文章

Cloudbuild - 使用来自不同步骤的自定义变量构建 docker 映像

如何在 Wordpress 中实现我的自定义登录页面?

自己构建一个Spring自定义标签以及原理讲解

Docker:Dockerfile自定义镜像

如何在 Docker 中使用 Grafana 的自定义 ini 文件?

docker 容器上 Parse-server 的自定义身份验证 (OAuth2)