- 视频操作 https://www.bilibili.com/video/BV1RG4y1U7qi/
- 版本
-
主机系统 Ubuntu 22.04.1 LTS
https://releases.ubuntu.com/22.04.1/ubuntu-22.04.1-live-server-amd64.iso
-
Linux 内核 linux-6.1.8
https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.1.8.tar.xz
-
常用命令工具集 busybox-1.36.0
-
实现ssh远程登录工具 openssl-3.0.7、openssh-9.1p1
https://github.com/openssl/openssl/archive/refs/tags/openssl-3.0.7.tar.gz
https://ftp.riken.jp/pub/OpenBSD/OpenSSH/portable/openssh-9.1p1.tar.gz
-
提供web服务 nginx-1.23.3
-
java环境 1.8.0_301
-
-
添加硬盘
虚拟机中再添加一块磁盘(sdb(40G))
-
磁盘分区(fdisk /dev/sdb)
- 使用o命令清除分区信息
- 使用n命令分三个区,+200M +4G +剩余空间,200M用于boot分区,4G用于交换分区,剩余空间用于程序和数据存储;
- 使用a命令设置1分区为活动分区;
- 使用t命令设置2分区为82交换分区;
- 使用w命令保存并退出;
#列出当前磁盘 fdisk -l #使用fdisk /dev/sdb进入fdisk界面 fdisk /dev/sdb #按照以下操作进行磁盘分区(红色字是需输入的命令) [root@208 ~]# fdisk /dev/sdb Welcome to fdisk (util-linux 2.37.2). Changes will remain in memory only, until you decide to write them. Be careful before using the write command. Command (m for help): **o** Created a new DOS disklabel with disk identifier 0xcbe6a294. Command (m for help): **n** Partition type p primary (0 primary, 0 extended, 4 free) e extended (container for logical partitions) Select (default p): Using default response p. Partition number (1-4, default 1): First sector (2048-83886079, default 2048): Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-83886079, default 83886079): **+200M** Created a new partition 1 of type 'Linux' and of size 200 MiB. Command (m for help): **n** Partition type p primary (1 primary, 0 extended, 3 free) e extended (container for logical partitions) Select (default p): Using default response p. Partition number (2-4, default 2): First sector (411648-83886079, default 411648): Last sector, +/-sectors or +/-size{K,M,G,T,P} (411648-83886079, default 83886079): **+4G** Created a new partition 2 of type 'Linux' and of size 4 GiB. Command (m for help): **n** Partition type p primary (2 primary, 0 extended, 2 free) e extended (container for logical partitions) Select (default p): Using default response p. Partition number (3,4, default 3): First sector (8800256-83886079, default 8800256): Last sector, +/-sectors or +/-size{K,M,G,T,P} (8800256-83886079, default 83886079): Created a new partition 3 of type 'Linux' and of size 35.8 GiB. Command (m for help): **a** Partition number (1-3, default 3): **1** The bootable flag on partition 1 is enabled now. Command (m for help): **t** Partition number (1-3, default 3): **2** Hex code or alias (type L to list all): **82** Changed type of partition 'Linux' to 'Linux swap / Solaris'. Command (m for help): **w** The partition table has been altered. Calling ioctl() to re-read partition table. Syncing disks.
#验证 fdisk -l Disk /dev/sdb: 40 GiB, 42949672960 bytes, 83886080 sectors Disk model: VMware Virtual S Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xcbe6a294 Device Boot Start End Sectors Size Id Type /dev/sdb1 * 2048 411647 409600 200M 83 Linux /dev/sdb2 411648 8800255 8388608 4G 82 Linux swap / Solaris /dev/sdb3 8800256 83886079 75085824 35.8G 83 Linux
-
格式化磁盘
mkfs.ext3 /dev/sdb1 mkfs.ext4 /dev/sdb3
-
挂载磁盘
#临时根文件系统 mkdir /mnt/rootfs mount /dev/sdb1 /mnt/rootfs #真实根文件系统 mkdir /mnt/root mount /dev/sdb3 /mnt/root #可以修改主机配置文件实现开机自动挂载(在最后添加两行) vim /etc/fstab /dev/sdb3 /mnt/root /dev/sdb1 /mnt/rootfs
-
编译kernel
将下载好的kernel解压,使用tar -xvf ./linux-6.1.8.tar.xz;然后进入到kernel目录cd linux-6.1.8,下面开始编译
tar -xf linux-5.8.9.tar.xz cd linux-5.8.9 make x86_64_defconfig make menuconfig #调整编译参数 (1)General setup ---> **[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support** (2)Device Drivers ---> **[*] Block devices ---> <*> RAM block device support (16) Default number of RAM disks (8196) Default RAM disk size (kbytes)** (3) File systems ---> **<*> Second extended fs support <*> The Extended 3 (ext3) filesystem** #编译 make #复制编译好后的文件 cp arch/x86/boot/bzImage /mnt/rootfs/vmlinux
-
编译busybox
tar -xf busybox-1.36.0.tar.bz2 cd busybox-1.36.0 make menuconfig #调整编译参数 Settings ---> --- Build Options [*] Build static binary (no shared libs) [*] Build static binary (no shared libs) #设置支持中文 Settings ---> [*] Support Unicode [*] Check $LC_ALL, $LC_CTYPE and $LANG environment variables (63) Character code to substitute unprintable characters with (0) Range of supported Unicode characters [*] Allow wide Unicode characters on output Editors ---> [*] vi (22 kb) [*] Allow to display 8-bit chars (otherwise shows dots) #编译 make make install
-
制作临时根文件系统
- 在电脑上创建一个目录用来制作initrd文件系统,mkdir homeDir
- 将busybox生成的_install目录下的所有内容拷贝到homeDIr目录
- 将homeDIr中的linuxrc改名为init
- 在homeDir目录下创建一个脚本,用来生成initrd文件
mkdir homeDir cd homeDir mkdir -p etc dev lib mnt/sysroot proc sys root cp -ra /linux/busybox-1.36.0/_install/* . cp -ra /linux/busybox-1.36.0/examples/bootfloppy/etc . mv linuxrc init
vim make.sh #!/bin/sh rootDir=/mnt/rootfs rm -rf $rootDir/initrd find .|cpio -o -H newc |gzip -9 > $rootDir/initrd echo “create initrd successed !!” #授权并执行 chmod +x make.sh ./make.sh
-
安装并配置grub
#安装grub到临时根文件系统 grub-install --root-directory=/mnt/rootfs /dev/sdb #创建grub配置文件 vim /mnt/rootfs/boot/grub/grub.cfg set timeout=3 menuentry 'LysLinux' --class ubuntu --class gnu-linux --class gnu { insmod gzio insmod ext2 search --no-floppy --fs-uuid --set=root 539f8eeb-0d3e-490a-ad9f-8f89f6afc9c4 linux /vmlinux initrd /initrd } #其中uuid查看方法是使用blkid命令找到对应的启动分区的编号。 root@app4:/mnt/rootfs# blkid /dev/mapper/ubuntu--vg-ubuntu--lv: UUID="c6ec9669-1d32-430c-acf4-aa2869dd9940" BLOCK_SIZE="4096" TYPE="ext4" /dev/sda2: UUID="0508b523-010f-4b28-9139-4671a667b052" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="db671554-279e-41b9-9f3c-a4397cdfb2af" /dev/sda3: UUID="e8saWC-06v4-a9OE-DuJF-fesr-CFTf-OtmGE2" TYPE="LVM2_member" PARTUUID="6706a2de-19ea-4c49-8cd2-7f8512849e22" /dev/sdb3: UUID="b4e500e4-dea6-40af-91eb-24c70bf9e997" BLOCK_SIZE="4096" TYPE="ext4" PARTUUID="cbe6a294-03" /dev/sdb1: UUID="**539f8eeb-0d3e-490a-ad9f-8f89f6afc9c4**" BLOCK_SIZE="4096" TYPE="ext3" PARTUUID="cbe6a294-01" /dev/sdb2: PARTUUID="cbe6a294-02" /dev/sda1: PARTUUID="b93c6491-c576-4e3d-87bd-1370cf3a00ab"
同步磁盘数据并关闭主机
sync sync sync poweroff
-
创建虚拟机并测试新系统
新建虚拟机并挂载前面在主机内新增的硬盘,挂载磁盘时,选择IDE磁盘,否则进入系统后可能认不到磁盘。正常的话应该可以进入系统,但是所有操作在重启后将不保存,因为目前操作系统运行在临时的根文件目录。
-
建立真实根文件系统
cd /mnt/root cp -R /linux/homeDir/* . rm init make.sh mkdir /mnt/root/etc/rc.d/ #修改下fstab和rcS,使用fstab添加sysfs的挂载,使用rcS自动创建设备结点 vim etc/fstab proc /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0 devpts /dev/pts devpts defaults 0 0 #创建配置文件设置主机名 mkdir -p /mnt/root/etc/sysconfig vim /mnt/root/etc/sysconfig/network #设置主机名 HOSTNAME=www #修改启动脚本 vim etc/init.d/rcS #!/bin/sh /bin/mount -a mdev -s mkdir /dev/pts ifconfig lo 127.0.0.1 ifconfig eth0 192.168.1.87 route add default gw 192.168.1.1 sleep 5 [ -r /etc/sysconfig/network ] && source /etc/sysconfig/network [ -z "$HOSTNAME" -o "$HOSTNAME" == '(none)' ] && hostname localhost || hostname $HOSTNAME for i in /etc/rc.d/*.sh;do $i done
-
修改临时跟文件系统,自动切换到真实文件系统
进入到homeDIr目录,重建init文件
cd homeDIr rm init vim init #!/bin/sh # echo "exec initramfs init" echo "mounting proc and sys" mount -t proc proc /proc mount -t sysfs sysfs /sys echo "detect and export hardware info" mdev -s #echo "start /bin/sh" #exec /bin/sh echo "Mount real rootfs to /mnt/sysroot..." mount -t ext4 /dev/sda3 /mnt/sysroot echo "Switch to read rootfs..." exec switch_root /mnt/sysroot /sbin/init #添加可执行权限 chmod +x init #重新生成临时文件目录启动文件 ./make.sh
验证真实根文件系统
#同步磁盘数据并关闭主机 sync sync sync poweroff
此时应该可以进入真实的根文件目录,所有文件修改都会生效,重启后依然保留
-
配置本地用户登录功能(在主机中进行)
- 创建用户数据库文件:passwd,密码影子文件:shadow,用户组文件:group
- 修改启动配置
#创建用户数据库文件:passwd,密码影子文件:shadow,用户组文件:group vim /mnt/root/etc/passwd root:x:0:0:root:/root:/bin/sh #生成用户密码 openssl passwd -1 -salt `openssl rand -hex 4` Password: $1$c4a375d4$e53cXyHuwv4E3O.MI07de0 vim /mnt/root/etc/shadow root:$1$c4a375d4$e53cXyHuwv4E3O.MI07de0:16690:0:99999:7::: #修改文件权限 chmod go= /mnt/root/etc/shadow vim /mnt/root/etc/group root:x:0:
#修改启动配置 #修改启动配置,如果放开 # ::respawn:-/bin/sh 则不需要登录直接进入系统 vim /mnt/root/etc/inittab ::sysinit:/etc/init.d/rcS # ::respawn:-/bin/sh ::respawn:/sbin/getty 19200 tty1 ::respawn:/sbin/getty 19200 tty2 ::respawn:/sbin/getty 19200 tty3 ::respawn:/sbin/getty 19200 tty4 ::respawn:/sbin/getty 19200 tty5 ::respawn:/sbin/getty 19200 tty6 ::ctrlaltdel:/bin/reboot ::shutdown:/bin/umount -a -r
这时登录新的系统时,将需要输入账号密码登录,由于第1个tty1无法登录,我们需要等待60秒超时后再次登录即可,或者按ctrl+c。
-
创建可执行程序和类库移植脚本
#创建类库移植脚本 #此脚本回移植对应的可执行文件和依赖的类库 vim /linux/bincp.sh #!/bin/bash # target=/mnt/root clearCmd() { if which $cmd &> /dev/null; then cmdPath=`which $cmd` else echo "No such command" return 5 fi } cmdCopy() { cmdDir=`dirname $1` [ -d ${target}${cmdDir} ] || mkdir -p ${target}${cmdDir} [ -f ${target}${1} ] || cp $1 ${target}${cmdDir} echo "cp $1 ${target}${cmdDir}" } libCopy() { for lib in `ldd $1 | grep -o "/[^[:space:]]\\{1,\\}"`; do libDir=`dirname $lib` [ -d ${target}${libDir} ] || mkdir -p ${target}${libDir} [ -f ${target}${lib} ] || cp $lib ${target}${libDir} echo "cp $lib ${target}${libDir}" done } while true; do read -p "Enter a command: " cmd if [ "$cmd" == 'quit' ] ;then echo "quit" exit 0 fi clearCmd $cmd [ $? -eq 5 ] && continue cmdCopy $cmdPath libCopy $cmdPath done #此脚本回移植类库和依赖的类库 vim /linux/socp.sh #!/bin/bash # target=/mnt/root clearCmd() { cmdPath=$cmd # if which $cmd &> /dev/null; then # cmdPath=`which $cmd` # else # echo "No such command" # return 5 # fi } cmdCopy() { cmdDir=`dirname $1` [ -d ${target}${cmdDir} ] || mkdir -p ${target}${cmdDir} [ -f ${target}${1} ] || cp $1 ${target}${cmdDir} echo "cp $1 ${target}${cmdDir}" } libCopy() { for lib in `ldd $1 | grep -o "/[^[:space:]]\\{1,\\}"`; do libDir=`dirname $lib` [ -d ${target}${libDir} ] || mkdir -p ${target}${libDir} [ -f ${target}${lib} ] || cp $lib ${target}${libDir} echo "cp $lib ${target}${libDir}" done } while true; do read -p "Enter a command: " cmd if [ "$cmd" == 'quit' ] ;then echo "quit" exit 0 fi clearCmd $cmd [ $? -eq 5 ] && continue cmdCopy $cmdPath libCopy $cmdPath done
-
编译安装OpenSSH (在主机操作)
OpenSSH用于ssh登录操作系统
由于 OpenSSH 依赖 OpenSSL,所有首先下载编译 OpenSSL 然后再编译 OpenSSH
由于编译时指定了安装的目录,所以在主机安装时不会影响主机的ssh登录
mkdir -p /usr/local/ssl /usr/local/ssh #编译并安装 oppenssl ./config --prefix=/usr/local/ssl shared make make install #编译并安装 openssh ./configure --prefix=/usr/local/ssh --sysconfdir=/usr/local/ssh/etc --with-ssl-dir=/usr/local/ssl --with-pam --without-openssl-header-check make make install #移植到子虚拟机 mkdir -p /var/empty/ mkdir -p /mnt/root/usr/local/ cp -ra /usr/local/ssl /mnt/root/usr/local cp -ra /usr/local/ssh /mnt/root/usr/local #移植相关类库 /linux/bincp.sh Enter a command:bash Enter a command:/usr/local/ssh/sbin/sshd #修改文件(允许root登录) vim /mnt/root/usr/local/ssh/etc/sshd_config PermitRootLogin yes #修改文件,添加ssh用户登录支持 vim /mnt/root/etc/passwd sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin #配置启动脚本 vim /mnt/root/etc/rc.d/sshd.sh /usr/local/ssh/sbin/sshd chmod +x /mnt/root/etc/rc.d/sshd.sh
关闭主机,启动子虚拟机
sync sync sync poweroff
在外部使用ssh工具登录子虚拟机
-
编译安装nginx
# 在主机中编译nginx,不需要安装 tar xf nginx-1.23.3.tar.gz cd nginx-1.23.3 ./configure --prefix=/usr/local --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --without-pcre --without-http_rewrite_module --without-http_geo_module --without-http_uwsgi_module --without-http_fastcgi_module --without-http_scgi_module --without-http_memcached_module make #移植到子虚拟机 mkdir -p /mnt/root/etc/nginx/ mkdir -p /mnt/root/var/log/nginx/ mkdir -p /mnt/root/usr/local/logs/ cp /linux/nginx-1.23.3/conf/* /mnt/root/etc/nginx/ cp /linux/nginx-1.23.3/objs/nginx /mnt/root/usr/local/sbin/ #创建测试网页 vim /mnt/sysroot/usr/local/html/index.html <h1>Welcome to my web!!</h1> #修改配置文件 vim /mnt/root/etc/nginx/nginx.conf user root; #设置开机启动 vim /mnt/root/etc/init.d/rcS #添加此行 /usr/local/sbin/nginx
挂起主机,启动子虚拟机
sync sync sync poweroff
在外部使用浏览器访问子主机
-
配置java运行环境
从主机复制jdk到子虚拟机磁盘
配置虚拟机环境变量
移植缺失的共享库
mkdir /mnt/root/usr/jdk8 cd /mnt/root/usr/jdk8 cp /usr/jdk8/jdk8.tar.gz /mnt/root/usr/jdk8 tar -xf jdk8.tar.gz mv jdk8/* . #配置环境变量 vim /mnt/root/etc/profile export JAVA_HOME=/usr/jdk8 export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar export PATH=$PATH:$JAVA_HOME/bin
在子虚拟机中运行 java -version 根据错误信息返回主机中移植共享库,这个过程会反复执行多次。
#首先移植可以通过java命令找到的共享库 /linux/bincp.sh Enter a command: /usr/jdk8/bin/java #报此错误代表缺失 libm.so.6 ,需要到主机中移植 java -version Error: dl failure on line 893 Error: failed /usr/jdk8/jre/lib/amd64/server/libjvm.so, because libm.so.6: cannot open shared object file: No such file or directory #在主机中执行 查找要移植的库的绝对路径 find / -name libm.so.6 /usr/lib/x86_64-linux-gnu/libm.so.6 #使用前面创建的脚本移植 /linux/socp.sh Enter a command:/usr/lib/x86_64-linux-gnu/libm.so.6 #这个报错是由于缺失 librt.so.1 同样从主机移植即可 java -version Java HotSpot(TM) 64-Bit Server VM warning: No monotonic clock was available - timed services may be adversely affected if the time-of-day clock changes java version "1.8.0_301" Java(TM) SE Runtime Environment (build 1.8.0_301-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.301-b09, mixed mode)
#出现类似以下内容说明java环境没有问题了 java -version java version "1.8.0_301" Java(TM) SE Runtime Environment (build 1.8.0_301-b09) Java HotSpot(TM) 64-Bit Server VM (build 25.301-b09, mixed mode)
-
其他设置
#设置DNS echo 'nameserver 192.168.1.1'>> /etc/resolv.conf