静看光阴荏苒
不管不顾不问不说也不念

Debian11配置systemd-nspawn

systemd-nspawn是一个类似chroot的命令,但是比chroot更加强大。我们可以用systemd-nspawn创建容器来跑一些服务,或者用作测试环境。安装:

apt install systemd-container

安装完成后systemd-nspawn和machinectl就可以用了。但是在开始用之前,先修改一些基本配置,方便后续使用。

首先是关于网络这块的配置,默认情况下systemd-nspawn有一个开箱即用的网络:虚拟以太网链接(network-veth)。但是要用这个网络的话,前提是需要将系统的网络管理工具修改为使用systemd-networkd,下面介绍下如何修改。

debian系统默认的网络管理工具是ifupdown,我们先禁用ifupdown的开机自启:

systemctl disable networking

然后设置systemd-networkd的开机自启:

systemctl enable systemd-networkd

接下来看一下ifupdown的配置:

cat /etc/network/interfaces

我这台机器内的配置如下,可以看到基本就是用dhcp来获取ip的:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

auto eth1
iface eth1 inet dhcp

auto eth2
iface eth2 inet6 auto

eth0是公网ip,eth1是内网ip,eth2是公网ipv6:

知道目前机器的网络配置后,把这份配置文件重命名保存一下以便在配置systemd-networkd后不会使用它:

mv /etc/network/interfaces /etc/network/interfaces.save

接下来配置systemd-networkd,新建eth0.network文件:

nano /etc/systemd/network/eth0.network

写入如下配置:

[Match]
Name=eth0

[Network]
DHCP=yes

新建eth1.network文件

nano /etc/systemd/network/eth1.network

写入如下配置:

[Match]
Name=eth1

[Network]
DHCP=yes

新建eth2.network文件:

nano /etc/systemd/network/eth2.network

写入如下配置:

[Match]
Name=eth2

[Network]
DHCP=yes

做完这些配置之后,重启机器使修改生效:

reboot

重新登录到机器内后,现在的虚拟以太网链接(network-veth)就是可用的了,但是我不打算用这个网络,因为用这个网络创建的容器获取到的ip是不固定的,也就是说容器重启后又会获取另外一个与之前不同的ip,这样使用的话太不方便。为了解决这个问题,我们可以自己创建一个网桥,然后让容器都用网桥来联网。

新建br0.netdev文件:

nano /etc/systemd/network/br0.netdev

写入如下配置:

[NetDev]
Name=br0
Kind=bridge

新建br0.network文件:

nano /etc/systemd/network/br0.network

写入如下配置:

[Match]
Name=br0

[Network]
Address=10.50.0.1/24
DHCPServer=yes
IPMasquerade=yes
LLDP=yes

[DHCPServer]
EmitDNS=yes
DNS=8.8.8.8

这里着重解释一下br0.network的配置,由于我们的服务器上没有多个公网ip,所以ip地址就用保留地址,然后用IPMasquerade启用nat转发。另外systemd-networkd是有dhcp服务器功能的,使用DHCPServer参数来启动dhcp服务器,为容器自动分配ip地址。做完这些配置之后重启systemd-networkd使其生效:

systemctl restart systemd-networkd

网桥创建完成后,现在还需要让systemd-nspawn使用我们刚创建的网桥,编辑systemd-nspawn@服务的配置文件:

systemctl edit systemd-nspawn@

覆盖systemd-nspawn@服务默认的启动配置,去掉–network-veth,添加–network-bridge=br0:

[Service]
ExecStart=
ExecStart=systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --network-bridge=br0 -U --settings=override --machine=%i

现在来制作操作系统镜像。这里我用mkosi制作一个debian11的镜像来演示。

不要使用debian官方存储库内的mkosi,因为版本太旧有很多问题,这里安装最新版。先安装mkosi需要用到的依赖:

apt -y install arch-install-scripts btrfs-progs debootstrap dosfstools ovmf e2fsprogs squashfs-tools gnupg python3 tar cryptsetup-bin xfsprogs xz-utils zypper sbsigntool debian-archive-keyring python3-pip git

接下来安装mkosi:

python3 -m pip install git+https://github.com/systemd/mkosi.git@v13

准备工作目录:

mkdir debian
mkdir debian/mkosi.cache
mkdir debian/mkosi.extra

进入工作目录,新建mkosi.default配置文件:

cd debian
nano mkosi.default

写入如下配置,修改Password后面的值来设置root密码:

[Distribution]
Distribution=debian
Release=bullseye

[Output]
Format=directory
Output=/var/lib/machines/debian
Bootable=no
Hostname=imlala

[Content]
BasePackages=yes
Packages=locales,tzdata,procps,dialog,iproute2,iputils-ping,lsof,net-tools,nano,curl,git
Password=rootpassword

新建mkosi.prepare脚本文件:

nano mkosi.prepare

对镜像做一些基本的配置修改,并设置镜像内的systemd-networkd为开机自启:

#!/bin/sh
systemctl enable systemd-networkd
sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
dpkg-reconfigure --frontend=noninteractive locales
update-locale LANG=en_US.UTF-8
rm -rf /etc/apt/sources.list.d/bullseye-security.list
rm -rf /etc/apt/sources.list.d/bullseye-updates.list

给脚本执行权限:

chmod +x mkosi.prepare

进入到之前创建好的mkosi.extra目录,这个目录的作用是向镜像内添加文件或者替换文件:

cd mkosi.extra

这里替换掉镜像内的存储库配置,创建相应的目录:

mkdir -p etc/apt

新建sources.list:

nano etc/apt/sources.list

写入如下配置:

deb http://deb.debian.org/debian bullseye main contrib non-free
deb-src http://deb.debian.org/debian bullseye main contrib non-free

deb http://deb.debian.org/debian-security/ bullseye-security main contrib non-free
deb-src http://deb.debian.org/debian-security/ bullseye-security main contrib non-free

deb http://deb.debian.org/debian bullseye-updates main contrib non-free
deb-src http://deb.debian.org/debian bullseye-updates main contrib non-free

这是mkosi.extre目录的正确结构:

root@debian-1cpu-1gb-sg-sin1:~/debian/mkosi.extra# tree
.
└── etc
    └── apt
        └── sources.list

回到上级目录执行mkosi命令即可开始构建镜像:

cd ../
mkosi

构建完成后即可使用machinectl启动:

machinectl start debian

登录到系统内,要登出的话就按键盘组合键ctrl+]]]:

machinectl login debian

设置容器开机自启,或者禁用开机自启:

machinectl enable debian
machinectl disable debian

重启、关机、杀掉容器:

machinectl reboot debian
machinectl poweroff debian
machinectl kill debian

列出全部正在运行的容器,查看某一个容器的状态:

machinectl list
machinectl status

下面介绍个比较实用的功能:端口映射(Port mapping)

使用端口映射可以把宿主机的端口映射到容器内的端口,比如容器内装了一个nginx使用了80端口,宿主机有一个8080端口空闲,我们就可以把宿主机的8080端口映射到容器内的80端口,这样通过外部网络就能访问到容器内的nginx服务了。

在之前我们已经通过machinectl启动了一个名为debian的容器,实际上machinectl也是调用的systemd-nspawn@服务,所以要配置某一个容器的端口映射,只需要编辑相应的systemd服务:

systemctl edit systemd-nspawn@debian

覆盖配置,添加–port参数,有多个端口就添加多个–port参数:

[Service]
ExecStart=
ExecStart=systemd-nspawn --quiet --keep-unit --boot --link-journal=try-guest --network-bridge=br0 --port=tcp:8080:80 -U --settings=override --machine=%i

要使配置生效,必须先关闭容器再启动,直接reboot是不行的:

machinectl poweroff debian
machinectl start debian
赞(22)
未经允许不得转载:荒岛 » Debian11配置systemd-nspawn
分享到: 更多 (0)

评论 2

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
  1. #1

    在容器使用網橋通過外部物理網絡DHCP獲取到地址後,還需要nspawn service 中的port forward來轉發端口嗎?

    JohnConnor2年前 (2023-01-20) Google Chrome 108.0.0.0 Google Chrome 108.0.0.0 Android 10 Android 10回复

分享创造快乐

广告合作资源投稿