前段使用使用boot2docker.iso来制作一个超级精简的、带有docker环境的虚拟机。 最近又来的新的需要,需要在虚拟机上安装pptpd相关的服务,发现docker pull回来的pptpd相关的镜像,都拉不起来。

大致提示的错误:

Couldn't open the /dev/ppp device: No such device or address
Please load the ppp_generic kernel module.

尝试安装内核模块:

1
2
$ modprobe ppp_generic
modprobe: module ppp_generic not found in modules.dep

那说明这个内核模块并不存在~

解铃还须系铃人,尝试找到boot2docker.iso镜像的制作方式,在Github/master/.github/workflows/ci.yml看到段:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
jobs:
  build-test:
    runs-on: ubuntu-latest
    steps:
      - ...
      - name: Build ISO
        run: |
          set -Eeuo pipefail -x
          docker build -t boot2docker/boot2docker .
          docker run --rm boot2docker/boot2docker > boot2docker.iso          

说明最终是由boot2docker/boot2docker这个镜像制作的boot2docker.iso文件,那么我们再去hub.docker.com去追寻一下踪迹:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
$ docker search boot2docker
NAME                                  DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
boot2docker/boot2docker               WARNING: this image is huge and is only usef…   27                                      [OK]
ahbeng/boot2docker-experimental       Builds customized Boot2Docker ISO containing…   5                                       [OK]
mbonato/boot2docker-urandom           boot2docker.iso image (based on boot2docker/…   1                                       [OK]
jrotter/boot2docker-automounter       Container that mounts shared Virtualbox fold…   1                                       [OK]
nematix/boot2docker-tool              Boot2Docker Post Installation Tools             1
vrakfall/boot2docker-nfs                                                              1                                       [OK]
boot2docker/boot2docker-cli                                                           1                                       [OK]
willoucom/boot2docker-provisionning   Automatic provisionning for boot2docker         0                                       [OK]
nanobox/boot2docker                   Custom boot2docker                              0                                       [OK]
yungsang/boot2docker                  boot2docker(+ NFS) + util-linux for nsenter     0                                       [OK]
soriyath/boot2docker_swiss            boot2docker image with Swiss timezone (Europ…   0                                       [OK]
sshillo/boot2docker-experimental      boot2docker-experimental                        0                                       [OK]
davidmnoriega/boot2docker-sysdig      boot2docker-sysdig                              0                                       [OK]
steeve/boot2docker-base                                                               0
giorg/boot2docker-nfs                 Boot2docker custom iso for nfs share            0                                       [OK]
land/boot2docker                      custom boot2docker                              0                                       [OK]
matthieume/boot2docker-tools          A container with every tools needs with Boot…   0
rabbit52/boot2docker                                                                  0                                       [OK]
onerhao/boot2docker                   boot2docker, support accessing hardware on h…   0                                       [OK]
danimal/boot2docker-qemu                                                              0                                       [OK]
qiankunli/boot2docker                 add features like sharedfolder,fig and modif…   0                                       [OK]
wolfs/boot2docker                                                                     0                                       [OK]
dongjinmedia/boot2docker                                                              0                                       [OK]
xforty/boot2docker-9p                                                                 0                                       [OK]
ferest/boot2docker                    A boot2docker folk that removes all hypervis…   0®

可以看到,第一个就是我们所需要的boot2docker/boot2docker镜像,将它pull下来,稍后有用。

一、进入boot2docker/boot2docker

1
2
docker pull boot2docker/boot2docker
docker run --rm -it -v $PWD:/work boot2docker/boot2docker bash

接下来,我们继续在github上搜索bzImage,得到内核的编译方式:

1
2
3
4
RUN make -C /usr/src/linux -j "$(nproc)" bzImage modules; \
	make -C /usr/src/linux INSTALL_MOD_PATH="$PWD" modules_install
RUN mkdir -p /tmp/iso/boot; \
	cp -vLT /usr/src/linux/arch/x86_64/boot/bzImage /tmp/iso/boot/vmlinuz

同时通过分析Dockerfile文件,nproc表示是有多少CPU核心数,$PWD表示/rootfs文件目录,接下来就有意思了~

二、检查ppp_generic所需要的依赖

找到一个正常的ubuntu/centos7环境,执行以下的命令:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
$ zcat /proc/config.gz  | grep -i ppp
CONFIG_PPP=m
CONFIG_PPP_BSDCOMP=m
CONFIG_PPP_DEFLATE=m
CONFIG_PPP_FILTER=y
CONFIG_PPP_MPPE=m
CONFIG_PPP_MULTILINK=y
CONFIG_PPPOE=m
CONFIG_PPPOL2TP=m
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m

就这样子,我们就知道PPP相关的配置了,但这还是不够的,我们还需要PPTP的支持,同样的操作:

1
2
3
4
$ zcat /proc/config.gz  | grep -i pptp
CONFIG_NF_CONNTRACK_PPTP=y
CONFIG_NF_NAT_PPTP=y
CONFIG_PPTP=m

接下来,把这些配置写入 /usr/src/linux/.config 文件中,再进行编译:

1
2
make -C /usr/src/linux olddefconfig
make -C /usr/src/linux -j4 bzImage modules

但此时此刻,你会发现PPTP模块并会不正常的编译出来,为什么?

因为PPTP还需要其他的依赖,这个依赖的分析,就需要make menuconfig出场了:

1
2
3
apt update
apt install libncursesw5-dev
make -C /usr/src/linux menuconfig # 用于查看依赖关系

可以看到,还需要再打开一个 CONFIG_NET_IPGRE_DEMUX=y 的配置。

三、完整的编译步骤如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 配置PPTP 和 PPP
cat << EOF >> /usr/src/linux/.config
CONFIG_NF_CONNTRACK_PPTP=y
CONFIG_NF_NAT_PPTP=y
CONFIG_NET_IPGRE_DEMUX=y
CONFIG_PPTP=m
CONFIG_PPP=m
CONFIG_PPP_BSDCOMP=m
CONFIG_PPP_DEFLATE=m
CONFIG_PPP_FILTER=y
CONFIG_PPP_MPPE=m
CONFIG_PPP_MULTILINK=y
CONFIG_PPPOE=m
CONFIG_PPPOL2TP=m
CONFIG_PPP_ASYNC=m
CONFIG_PPP_SYNC_TTY=m
EOF

# 编译内核
make -C /usr/src/linux olddefconfig
make -C /usr/src/linux -j4 bzImage modules

# 安装内核模块
make -C /usr/src/linux INSTALL_MOD_PATH="$PWD" modules_install

# 拷贝vmlinuz
cp -vLT /usr/src/linux/arch/x86_64/boot/bzImage /tmp/iso/boot/vmlinuz

# 制作ISO文件
time make-b2d-iso.sh
du -hs /tmp/boot2docker.iso
cp -v /tmp/boot2docker.iso /work/boot2docker_tmp.iso

接下来把 /work/boot2docker_tmp.iso 拷贝出来就可以了。

四、最后可以制作虚拟机了

1
2
3
4
docker-machine create \                                                                                                                                                                     
  --driver virtualbox \
  --virtualbox-boot2docker-url='/path/to/boot2docker_tmp.iso' \
  vm-test

根据boot2docker来制作虚拟机,之前的文章使用boot2docker.iso来搭建一个超小的VM虚拟机环境有描述过,这里就不罗嗦了~