第02关 安装并初始化虚拟机
大约 14 分钟
VMware网络设置

安装
选择English

选择最小安装
Tab键切换选项
空格选择

自动分配网络

回车

格式化硬盘
按照默认配置,回车

默认配置是分配硬盘一般空间,可以自行调整

用户名

跳过继续

安装SSH

继续

安装中

安装完成
选择重启

断开ISO镜像磁盘
登录

SSH连接
查看IP地址
ip r系统会显示当前主机的 IP 路由表,包括目的地址、网关、接口等信息

这是默认路由条目,指示任何目的地不在已知路由表中的数据包都应通过
ens32网络接口发送到网关10.0.1.2。proto dhcp表示该路由是通过 DHCP 自动获取的,metric 100是该路由的度量值(优先级)
初始化系统
安装vim
# 获取root权限
hong@hong:~$ sudo -i
[sudo] password for hong:
# 更新软件
root@hong:~# apt update
Hit:1 http://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy InRelease
Hit:2 http://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy-updates InRelease
Hit:3 http://mirrors.tuna.tsinghua.edu.cn/ubuntu jammy-backports InRelease
Hit:4 http://security.ubuntu.com/ubuntu jammy-security InRelease
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
9 packages can be upgraded. Run 'apt list --upgradable' to see them.
# 安装vim
root@hong:~# apt install vim创建脚本
root@hong:~# vim init.shvim界面输入
:set paste将 Vim 切换到“粘贴模式”,在这种模式下,Vim 将保持原样插入你粘贴的文本,不会执行自动缩进或其他解释操作
复制脚本代码,vim界面shift + insert 插入代码
root密码在echo 'root:bogeit'|chpasswd
echo 'root:123456' | sudo chpasswd
#!/bin/bash
# 这个脚本用于设置和配置Ubuntu系统
# 控制开关
# 防火墙 如果传入参数不为空,则使用传入的参数作为iptables_yn的值,否则默认值为'n'
iptables_yn="${1:-n}"
# 安装ssh并进行配置
echo "安装ssh"
apt-get install openssh-server -y
echo "允许root用户登录"
# 允许root用户登录
echo 'PermitRootLogin yes' >> /etc/ssh/sshd_config
# 设置root用户密码为'icurvestar@2024'
echo "设置root用户密码"
echo 'root:icurvestar@2024' | chpasswd
# 重启ssh服务并检查状态
echo "重启ssh服务并检查状态"
systemctl restart sshd && systemctl status ssh -l --no-pager
# 更改apt-get源列表
# 获取Ubuntu的版本代号
ubuntuCodename=$(lsb_release -a 2>/dev/null | awk 'END{print $NF}')
# https://developer.aliyun.com/mirror/ubuntu
# ubuntu 22.04: jammy
# ubuntu 20.04: focal
# ubuntu 18.04: bionic
# ubuntu 16.04: xenial
# 备份现有的源列表文件
echo "备份现有的软件源列表文件"
\cp /etc/apt/sources.list{,_bak}
# 设置新的源列表为阿里云的镜像源
echo "设置新的源列表为阿里云的镜像源"
echo "
deb https://mirrors.aliyun.com/ubuntu/ ${ubuntuCodename} main restricted universe multiverse
deb-src https://mirrors.aliyun.com/ubuntu/ ${ubuntuCodename} main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ ${ubuntuCodename}-security main restricted universe multiverse
deb-src https://mirrors.aliyun.com/ubuntu/ ${ubuntuCodename}-security main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ ${ubuntuCodename}-updates main restricted universe multiverse
deb-src https://mirrors.aliyun.com/ubuntu/ ${ubuntuCodename}-updates main restricted universe multiverse
deb https://mirrors.aliyun.com/ubuntu/ ${ubuntuCodename}-backports main restricted universe multiverse
deb-src https://mirrors.aliyun.com/ubuntu/ ${ubuntuCodename}-backports main restricted universe multiverse
" > /etc/apt/sources.list
# 更新包列表
echo "更新包列表"
apt-get update
# 安装所需的软件包
pkgList="dialog curl wget unzip gcc swig automake make perl cpio git libmbedtls-dev libudns-dev libev-dev python-pip python3-pip lrzsz iftop nethogs nload htop ifstat iotop iostat vim iptables cron rsyslog iputils-ping"
for Package in ${pkgList}; do
echo "正在安装 $Package"
apt-get -y install $Package
done
# 清理所有的包缓存
echo "清理包缓存"
apt-get clean all
systemctl enable cron
systemctl start cron
# 自定义配置文件
echo "自定义配置文件"
cat > /etc/profile.d/boge.sh << EOF
# 设置历史记录大小
HISTSIZE=10000
# 设置历史记录时间格式
HISTTIMEFORMAT="%F %T \$(whoami) "
# 定义常用别名
alias l='ls -AFhlt --color=auto'
alias lh='l | head'
alias ll='ls -l --color=auto'
alias ls='ls --color=auto'
alias vi=vim
# 设置grep命令自动加上--color参数
GREP_OPTIONS="--color=auto"
alias grep='grep --color'
alias egrep='egrep --color'
alias fgrep='fgrep --color'
EOF
# 修改vim配置文件以启用语法高亮
echo "修改vim配置文件以启用语法高亮"
sed -i 's@^"syntax on@syntax on@' /etc/vim/vimrc
# 配置PS1(命令行提示符)
echo "配置PS1(命令行提示符)"
# 方括号 [] 实际上代表的是 test 命令
# 效果:[$debian_chroot]亮绿色用户名@主机名:亮蓝色当前目录$
[ -z "$(grep ^PS1 ~/.bashrc)" ] && echo "PS1='\${debian_chroot:+(\$debian_chroot)}\\[\\e[1;32m\\]\\u@\\h\\[\\033[00m\\]:\\[\\033[01;34m\\]\\w\\[\\033[00m\\]\\$ '" >> ~/.bashrc
# 配置历史记录带有时间戳
[ -z "$(grep history-timestamp ~/.bashrc)" ] && echo "PROMPT_COMMAND='{ msg=\$(history 1 | { read x y; echo \$y; });user=\$(whoami); echo \$(date \"+%Y-%m-%d %H:%M:%S\"):\$user:\`pwd\`/:\$msg ---- \$(who am i); } >> /tmp/\`hostname\`.\`whoami\`.history-timestamp'" >> ~/.bashrc
# 配置/etc/security/limits.conf
# 如果存在*nproc.conf文件则重命名为*nproc.conf_bk
# 检查 /etc/security/limits.d/ 目录下是否有 nproc.conf 文件存在,并将其重命名为 nproc.conf_bk
# 在标准的 Linux 系统中,rename 通常不是一个内置命令或常用的命令,用于单个文件的重命名
[ -e /etc/security/limits.d/*nproc.conf ] && rename nproc.conf nproc.conf_bk /etc/security/limits.d/*nproc.conf
# 如果common-session文件中没有'session required pam_limits.so',则添加
[ -z "$(grep 'session required pam_limits.so' /etc/pam.d/common-session)" ] && echo "session required pam_limits.so" >> /etc/pam.d/common-session
# 删除/etc/security/limits.conf文件末尾的# End of file行及其之后的内容
sed -i '/^# End of file/,$d' /etc/security/limits.conf
echo "设置进程数量"
# 设置进程数量 (nproc) 和文件描述符数量 (nofile) 的软限制 (soft) 和硬限制 (hard)
# 在/etc/security/limits.conf文件末尾添加以下内容
cat >> /etc/security/limits.conf <<EOF
# End of file
* soft nproc 1000000
* hard nproc 1000000
* soft nofile 1000000
* hard nofile 1000000
root soft nproc 1000000
root hard nproc 1000000
root soft nofile 1000000
root hard nofile 1000000
EOF
# 设置ulimit
# 将当前 shell 会话中的文件描述符数量的软限制和硬限制都设置为 1000000
ulimit -SHn 1000000
echo "修改/etc/hosts文件"
# 修改/etc/hosts文件
# 如果主机的IP地址不是127.0.0.1,则添加127.0.0.1 <主机名>
[ "$(hostname -i | awk '{print $1}')" != "127.0.0.1" ] && sed -i "s@127.0.0.1.*localhost@&\n127.0.0.1 $(hostname)@g" /etc/hosts
# 设置时区为上海
echo "设置时区为上海"
rm -rf /etc/localtime
ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# /etc/sysctl.conf
# :<<BOGE:这是一种多行注释的语法,表示开始一个块注释,直到遇到标记BOGE为止。:是一个shell命令,它什么都不做,但其存在使得这段代码合法
:<<BOGE
fs.file-max = 1000000
这个参数定义了系统中最大的文件句柄数。文件句柄是用于访问文件的数据结构。增加这个值可以提高系统同时打开文件的能力。
fs.inotify.max_user_instances = 8192
inotify是Linux内核中的一个机制,用于监视文件系统事件。这个参数定义了每个用户可以创建的inotify实例的最大数量。
net.ipv4.tcp_syncookies = 1
当系统遭受SYN洪水攻击时,启用syncookies可以防止系统资源被耗尽。SYN cookies是一种机制,用于在TCP三次握手中保护服务器端资源。
net.ipv4.tcp_fin_timeout = 30
这个参数定义了TCP连接中,等待关闭的时间。当一端发送FIN信号后,等待对端关闭连接的超时时间。
net.ipv4.tcp_tw_reuse = 1
启用该参数后,可以允许将TIME-WAIT状态的TCP连接重新用于新的连接。这可以减少系统中TIME-WAIT连接的数量。
net.ipv4.ip_local_port_range = 1024 65000
这个参数定义了本地端口的范围,用于分配给发送请求的应用程序。它限制了可用于客户端连接的本地端口范围。
net.ipv4.tcp_max_syn_backlog = 16384
这个参数定义了TCP连接请求的队列长度。当系统处理不及时时,超过该队列长度的连接请求将被拒绝。
net.ipv4.tcp_max_tw_buckets = 6000
这个参数定义了系统同时保持TIME-WAIT状态的最大数量。超过这个数量的连接将被立即关闭。
net.ipv4.route.gc_timeout = 100
这个参数定义了内核路由表清理的时间间隔,单位是秒。它影响路由缓存的生命周期。
net.ipv4.tcp_syn_retries = 1
这个参数定义了在发送SYN请求后,等待对端回应的次数。超过指定次数后仍未响应,连接将被认为失败。
net.ipv4.tcp_synack_retries = 1
这个参数定义了在发送SYN+ACK回应后,等待对端发送ACK的次数。超过指定次数后仍未收到ACK,连接将被认为失败。
net.core.somaxconn = 32768
这个参数定义了监听队列的最大长度。当服务器正在处理的连接数超过此值时,新的连接请求将被拒绝。
net.core.netdev_max_backlog = 32768
这个参数定义了网络设备接收队列的最大长度。当接收队列已满时,新的数据包将被丢弃。
net.core.netdev_budget = 5000
这个参数定义了每个网络设备接收队列在每个时间间隔中可以处理的数据包数量。
net.ipv4.tcp_timestamps = 0
禁用TCP时间戳。时间戳可以用于解决网络中的数据包乱序问题,但在高负载环境下可能会增加开销。
net.ipv4.tcp_max_orphans = 32768
这个参数定义了系统中允许存在的最大孤立(没有关联的父连接)TCP连接数量。超过这个数量的孤立连接将被立即关闭。
BOGE
# 检查文件/etc/sysctl.conf中是否包含fs.file-max的设置,如果没有,则向该文件追加内容
echo "配置/etc/sysctl.conf"
[ -z "$(grep 'fs.file-max' /etc/sysctl.conf)" ] && cat >> /etc/sysctl.conf << EOF
fs.file-max = 1000000
fs.inotify.max_user_instances = 8192
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.core.somaxconn = 32768
net.core.netdev_max_backlog = 32768
net.core.netdev_budget = 5000
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_max_orphans = 32768
EOF
# 应用 /etc/sysctl.conf 文件中的新设置
sysctl -p
echo "设置语言环境"
# 安装 locales 包,用于支持本地化设置
apt-get -y install locales
# 设置语言环境为 en_US.UTF-8 并添加到 /etc/profile
echo 'export LANG=en_US.UTF-8'|tee -a /etc/profile && source /etc/profile
# TTY(Teletypewriter)是一个代表终端设备的概念,主要分为以下几种类型
# 物理终端(Physical Terminal):指连接到计算机的硬件终端,例如通过串口连接的终端设备。
# 虚拟控制台(Virtual Console):Linux内核提供的虚拟终端设备。
# 伪终端(Pseudo Terminal, PTY):虚拟终端的一种特殊形式,常用于图形界面终端模拟器(如 GNOME Terminal、xterm)以及远程登录工具(如 SSH)
# who
# root tty1 2024-07-25 17:22
# root pts/0 2024-07-25 16:45 (192.168.10.108)
# root pts/1 2024-07-25 17:19 (192.168.10.108)
# root pts/2 2024-07-25 17:19 (192.168.10.108)
# root pts/3 2024-07-25 17:21 (192.168.10.108)
echo "修改控制台设置,只激活第一个和第二个控制台"
# 修改控制台设置,只激活第一个和第二个控制台
sed -i 's@^ACTIVE_CONSOLES.*@ACTIVE_CONSOLES="/dev/tty[1-2]"@' /etc/default/console-setup
# 注释掉第3到第6个TTY的初始化配置文件(已注释)
#sed -i 's@^@#@g' /etc/init/tty[3-6].conf
# 生成 en_US.UTF-8 的语言环境
locale-gen en_US.UTF-8
# 将 en_US.UTF-8 添加到支持的语言列表中
mkdir -p /var/lib/locales/supported.d
echo "en_US.UTF-8 UTF-8" > /var/lib/locales/supported.d/local
# 配置默认的语言环境
cat > /etc/default/locale << EOF
LANG=en_US.UTF-8
LANGUAGE=en_US:en
EOF
# 注释掉控制-删除组合键的配置文件(已注释)
# 所有行的开头(^)添加一个 # 字符
#sed -i 's@^@#@g' /etc/init/control-alt-delete.conf
echo "更新系统时间,添加每 20 分钟同步一次时间的计划任务"
# 更新系统时间
# 检查 ntpdate 是否已安装,否则更新包列表并安装 ntpdate
which ntpdate || apt-get update;apt install ntpdate
# 同步时间到 NTP 服务器
ntpdate pool.ntp.org
# 如果根用户的 crontab 中没有 ntpdate 条目,则添加每 20 分钟同步一次时间的计划任务
[ ! -e "/var/spool/cron/crontabs/root" -o -z "$(grep ntpdate /var/spool/cron/crontabs/root 2>/dev/null)" ] && { echo "*/20 * * * * $(which ntpdate) pool.ntp.org > /dev/null 2>&1" >> /var/spool/cron/crontabs/root;chmod 600 /var/spool/cron/crontabs/root; }
# 配置 iptables 防火墙
if [ "${iptables_yn}" == 'y' ]; then
echo "配置 iptables 防火墙"
# 安装 debconf-utils 包 自动化配置管理
apt-get -y install debconf-utils
# 预设 iptables-persistent 的配置选项
# 设置 iptables-persistent 的自动保存选项为 true
echo iptables-persistent iptables-persistent/autosave_v4 boolean true | sudo debconf-set-selections
echo iptables-persistent iptables-persistent/autosave_v6 boolean true | sudo debconf-set-selections
# 安装 iptables-persistent 包
apt-get -y install iptables-persistent
# 检查当前的 iptables 规则是否已配置
# 默认策略是丢弃所有进入的流量,允许特定 HTTP(端口 80)和 HTTPS(端口 443)ssh22端口、本地回环、 ICMP 回显请求(ping)的流量
if [ -e "/etc/iptables/rules.v4" ] && [ -n "$(grep '^:INPUT DROP' /etc/iptables/rules.v4)" -a -n "$(grep 'NEW -m tcp --dport 22 -j ACCEPT' /etc/iptables/rules.v4)" -a -n "$(grep 'NEW -m tcp --dport 80 -j ACCEPT' /etc/iptables/rules.v4)" ]; then
IPTABLES_STATUS=yes
else
IPTABLES_STATUS=no
fi
# 如果 iptables 没有配置,写入默认的规则
if [ "${IPTABLES_STATUS}" == "no" ]; then
cat > /etc/iptables/rules.v4 << EOF
# Firewall configuration written by system-config-securitylevel
# Manual customization of this file is not recommended.
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:syn-flood - [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 443 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
COMMIT
EOF
fi
# 检查自定义 SSH 端口是否已在 iptables 中配置,如果没有则添加
FW_PORT_FLAG=$(grep -ow "dport ${ssh_port}" /etc/iptables/rules.v4)
[ -z "${FW_PORT_FLAG}" -a "${ssh_port}" != "22" ] && sed -i "s@dport 22 -j ACCEPT@&\n-A INPUT -p tcp -m state --state NEW -m tcp --dport ${ssh_port} -j ACCEPT@" /etc/iptables/rules.v4
# 恢复 iptables 规则
iptables-restore < /etc/iptables/rules.v4
# 复制 IPv4 规则到 IPv6,并将 icmp 修改为 icmpv6
/bin/cp /etc/iptables/rules.v{4,6}
sed -i 's@icmp@icmpv6@g' /etc/iptables/rules.v6
# 恢复 ip6tables 规则并保存
ip6tables-restore < /etc/iptables/rules.v6
ip6tables-save > /etc/iptables/rules.v6
fi
# 重启 rsyslog 和 ssh 服务
service rsyslog restart
service ssh restart
# 重新加载 profile 和 bashrc
. /etc/profile
. ~/.bashrc
echo "设置ens32的IP地址和DNS"
# 设置IP地址和DNS
validate_ip() {
local ip_var_name=$1
# 无限循环,直到输入有效的IP地址
while true; do
# 提示用户输入IP地址
read -p "输入IP地址($ip_var_name): " $ip_var_name
# 检测输入是否为空
if [ -z "${!ip_var_name}" ]; then
echo "输入为空,请重试."
continue
fi
# 检测输入是否符合IP地址的格式
if ! [[ ${!ip_var_name} =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
echo "无效的IP地址格式,请重试."
continue
fi
# 输入有效,跳出循环
break
done
}
# 调用函数并传递变量名作为参数
validate_ip "ip_address"
echo "IP地址: $ip_address"
validate_ip "ip_gateway"
echo "网关地址: $ip_gateway"
validate_ip "dns1_ip"
echo "DNS1 IP地址: $dns1_ip"
validate_ip "dns2_ip"
echo "DNS2 IP地址: $dns2_ip"
# 写入网络配置到netplan配置文件
cat > /etc/netplan/00-installer-config.yaml << EOF
network:
version: 2
renderer: networkd
ethernets:
ens32:
dhcp4: false
dhcp6: false
addresses:
- ${ip_address}/24
routes:
- to: default
via: ${ip_gateway}
nameservers:
addresses: [${dns1_ip}, ${dns2_ip}]
EOF
echo "安装resolvconf管理和维护 DNS "
# 安装resolvconf包
apt install resolvconf -y
# 配置resolvconf以使用指定的DNS服务器
cat > /etc/resolvconf/resolv.conf.d/head << EOF
nameserver ${dns1_ip}
nameserver ${dns2_ip}
EOF
# 重启resolvconf服务
systemctl restart resolvconf
# 提示用户稍后可以关闭终端并使用新IP地址进行SSH登录
echo "应用netplan配置"
echo "过个10秒左右的样子可以关闭终端,然后换成刚才输入的主机IP进行ssh登陆即可."
# 应用netplan配置
netplan apply按ESC输入:wq + 回车
保存退出
执行脚本
bash init.sh有报错不用管
init.sh: line 195: /var/spool/cron/crontabs/root: No such file or directory
chmod: cannot access '/var/spool/cron/crontabs/root': No such file or directory
Failed to restart rsyslog.service: Unit rsyslog.service not found.输入IP地址
配置IP地址、网关、DNS
Input IP address(ip_address): 10.0.1.201
IP address: 10.0.1.201
Input IP address(ip_gateway): 10.0.1.2
IP gateway: 10.0.1.2
Input IP address(dns1_ip): 223.5.5.5
Dns1 ip: 223.5.5.5
Input IP address(dns2_ip): 114.114.114.114使用新IP地址连接
其他
24小时制
注意:调整后k8s运行失败,原因未知,疑似每个节点时间对不上。重新初始化节点部署k8s后正常。
vim /etc/default/locale
LANG=en_US.UTF-8
LC_TIME=en_DK.UTF-8root@hong:~# date
Thu Jun 13 17:40:13 CST 2024
root@hong:~# timedatectl
Local time: Thu 2024-06-13 17:40:14 CST
Universal time: Thu 2024-06-13 09:40:14 UTC
RTC time: Thu 2024-06-13 09:40:14
Time zone: Asia/Shanghai (CST, +0800)
System clock synchronized: yes
NTP service: active
RTC in local TZ: no
- Universal time 即世界协调时间(UTC),这里显示的时间比本地时间早8小时,因为CST是UTC+8。这表明系统正确区分了本地时间和UTC时间。
- RTC (Real Time Clock) 是系统的硬件时钟,它显示的时间也是UTC时间,与Universal time一致,这是为了硬件时钟的一致性和便于跨时区操作。
- NTP (Network Time Protocol) 服务是活动的,意味着系统正在使用NTP协议定期从网络时间服务器获取时间信息,以自动校正系统时间,保持时间的精确性。
- 这表示硬件时钟(RTC)并没有设置在本地时区(这里是CST,即上海时间),而是直接存储的UTC时间。这是一种常见的配置,因为这样可以在不同时区之间移动系统时不需要调整硬件时钟。