<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="zh_CN">
  <title>槿鸢茶屋</title>
  <subtitle>咕咕咕</subtitle>
  <link href="https://blog.ipox.cn/" rel="alternate" type="text/html"/>
  <link href="https://blog.ipox.cn/atom.xml" rel="self" type="application/atom+xml"/>
  <id>https://blog.ipox.cn/</id>
  <updated>2026-10-22T15:30:00.000Z</updated>
  <entry>
    <title>Kubernetes 1.14.1 集群部署实录（CentOS 7）</title>
    <link href="https://blog.ipox.cn/posts/zh-cn/k8s-1-14-1-centos7-deploy/" rel="alternate" type="text/html"/>
    <id>https://blog.ipox.cn/posts/zh-cn/k8s-1-14-1-centos7-deploy/</id>
    <published>2026-10-22T15:30:00.000Z</published>
    <updated>2026-10-22T15:30:00.000Z</updated>
    <summary>记录一次课程实验环境下的 Kubernetes 单 master + 单 node 集群搭建：kubeadm 初始化、flannel 网络、Dashboard、Nginx NodePort 发布，以及一路上踩过的 Docker 版本、镜像格式、DNS 和时间同步的坑。</summary>
    <content type="html"><![CDATA[<blockquote>
<p>记录一次课程实验环境下的 Kubernetes 单 master + 单 node 集群搭建：kubeadm 初始化、flannel 网络、Dashboard、Nginx NodePort 发布，以及一路上踩过的 Docker 版本、镜像格式、DNS 和时间同步的坑。</p>
<p>部署时间：2026-10-22</p>
</blockquote>
<h2>环境规划</h2>
<p>实验指导书的原始规划是 master <code>192.168.100.60</code>、node <code>192.168.100.61</code>，实际环境与指导书不一致，本文按<strong>真实 IP</strong> 记录：</p>
<table>
<thead>
<tr>
<th>角色</th>
<th>主机名</th>
<th>IP</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>master</td>
<td>master</td>
<td>192.168.100.233</td>
<td>控制面、Dashboard</td>
</tr>
<tr>
<td>node</td>
<td>node</td>
<td>192.168.100.144</td>
<td>工作节点</td>
</tr>
<tr>
<td>网关 / DNS</td>
<td>-</td>
<td>192.168.100.2</td>
<td>VMware NAT</td>
</tr>
</tbody>
</table>
<p>软件版本：</p>
<table>
<thead>
<tr>
<th>组件</th>
<th>版本</th>
</tr>
</thead>
<tbody>
<tr>
<td>操作系统</td>
<td>CentOS 7 (kernel 3.10.0-1160)</td>
</tr>
<tr>
<td>Docker</td>
<td>18.09.6</td>
</tr>
<tr>
<td>kubeadm / kubelet / kubectl</td>
<td>1.14.1</td>
</tr>
<tr>
<td>Pod 网段</td>
<td>10.16.0.0/16</td>
</tr>
<tr>
<td>网络插件</td>
<td>flannel v0.11.0-amd64</td>
</tr>
</tbody>
</table>
<blockquote>
<p>提示：如果你的环境 IP 不同，按同样思路替换即可，关键是两台机器的 <code>/etc/hosts</code>、kubeadm 的 <code>--apiserver-advertise-address</code> 和 join 命令里的地址保持一致。</p>
</blockquote>
<h2>1. 基础环境配置（master、node 均执行）</h2>
<h3>1.1 配置主机名解析</h3>
<p>两台机器的 <code>/etc/hosts</code> 保持一致：</p>
<pre><code>vi /etc/hosts
</code></pre>
<pre><code>127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.100.233 master
192.168.100.144 node
</code></pre>
<p>设置主机名：</p>
<pre><code># master
hostnamectl set-hostname master

# node
hostnamectl set-hostname node
</code></pre>
<p>验证：</p>
<pre><code>getent hosts master
getent hosts node
ping -c 2 master
</code></pre>
<blockquote>
<p>这里踩过一个坑：<code>/etc/hosts</code> 里把 <code>node</code> 拼成了 <code>ndoe</code>，同时没写 master 的条目，导致后面 chrony 一个时间源都没有。hosts 是整套集群的基础，先确认再往下走。</p>
</blockquote>
<h3>1.2 关闭防火墙、SELinux、swap</h3>
<pre><code>systemctl stop firewalld
systemctl disable firewalld

setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

swapoff -a
sed -i '/ swap / s/^/#/' /etc/fstab
</code></pre>
<h3>1.3 内核参数</h3>
<pre><code>cat &gt;&gt; /etc/sysctl.conf &lt;&lt; EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

modprobe br_netfilter
sysctl -p
</code></pre>
<p><code>br_netfilter</code> 是 <code>net.bridge.*</code> 这些参数存在的前提；不加载模块直接 <code>sysctl -p</code> 会报 <code>No such file or directory</code>。</p>
<h3>1.4 开启 IPVS 相关模块</h3>
<pre><code>vi /etc/sysconfig/modules/ipvs.modules
</code></pre>
<pre><code>#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4
</code></pre>
<pre><code>chmod 755 /etc/sysconfig/modules/ipvs.modules
bash /etc/sysconfig/modules/ipvs.modules
lsmod | grep -e ip_vs -e nf_conntrack_ipv4
</code></pre>
<h3>1.5 时间同步（chrony）</h3>
<p>master：</p>
<pre><code>yum -y install chrony
vi /etc/chrony.conf
</code></pre>
<p>删除默认的 4 行 <code>server *.centos.pool.ntp.org</code>，加入：</p>
<pre><code>local stratum 10
server master iburst
allow all
</code></pre>
<pre><code>systemctl start chronyd
systemctl enable chronyd
chronyc sources -v
</code></pre>
<p>node：</p>
<pre><code>yum -y install chrony
vi /etc/chrony.conf
</code></pre>
<p>删除默认 4 行 server，加入：</p>
<pre><code>server master iburst
</code></pre>
<pre><code>systemctl start chronyd
systemctl enable chronyd
chronyc sources
</code></pre>
<p>出现 <code>^* master</code> 即同步成功。若显示 0 个源，先查 <code>getent hosts master</code> 和 <code>journalctl -u chronyd</code>。</p>
<h2>2. 准备 YUM 源</h2>
<p>课程实验是离线环境，源分两部分：</p>
<ul>
<li>CentOS 7 ISO：基础系统包（本文环境用的是 <code>CentOS-7-x86_64-Minimal-2009.iso</code>，包比 DVD 少，缺什么再补）</li>
<li><code>K8S.tar.gz</code> 解压出的 <code>Kubernetes/</code> 目录：kubeadm/kubelet/kubectl、docker-ce 等 RPM</li>
</ul>
<p>本实验 <strong>master 和 node 都使用本地 <code>file://</code> 源</strong>，不使用 FTP。node 上原本没有 K8S 包，需要从 master 把 <code>/opt/K8S</code> 整个复制过去，保持路径一致。</p>
<h3>2.1 上传安装介质</h3>
<p>先把两个文件通过 SFTP 或 VMware 共享文件夹传到 master 的 <code>/root</code>：</p>
<ul>
<li><code>CentOS-7-x86_64-Minimal-2009.iso</code></li>
<li><code>K8S.tar.gz</code>（课程提供的离线包）</li>
</ul>
<pre><code>ls -lh /root/CentOS-7-x86_64-Minimal-2009.iso /root/K8S.tar.gz
</code></pre>
<p><code>K8S.tar.gz</code> 解压后主要有：</p>
<ul>
<li><code>Kubernetes/</code>：kubeadm/kubelet/kubectl、docker-ce 等 RPM</li>
<li><code>images/</code>：各组件镜像 tar</li>
<li><code>yaml/</code>：flannel、Dashboard 等清单</li>
<li><code>kubernetes_base.sh</code>：批量导入镜像的脚本</li>
</ul>
<h3>2.2 master 准备源</h3>
<pre><code>cd /root

# base 源：把 ISO 内容放到 /opt/centos
mkdir -p /opt/centos
mount /dev/cdrom /mnt
cp -r /mnt/* /opt/centos/

# 离线 RPM：解压 K8S 包
mkdir -p /opt/K8S
tar -zxf K8S.tar.gz -C /opt/K8S
</code></pre>
<p>配置 repo（master、node 完全相同）：</p>
<pre><code>cd /etc/yum.repos.d/
rm -f *
vi local.repo
</code></pre>
<pre><code>[centos]
name=centos
baseurl=file:///opt/centos
gpgcheck=0

[K8S]
name=K8S
baseurl=file:///opt/K8S/Kubernetes
gpgcheck=0
</code></pre>
<pre><code>yum clean all
yum makecache
</code></pre>
<h3>2.3 node 同步源目录</h3>
<pre><code># master → node，保持 /opt/K8S 路径一致
scp -r /opt/K8S root@192.168.100.144:/opt/

# 基础源目录同样需要
scp -r /opt/centos root@192.168.100.144:/opt/
</code></pre>
<blockquote>
<p>若 node 上已存在 <code>/opt/K8S</code>，先把旧目录移走，避免 scp 嵌套成 <code>/opt/K8S/K8S</code>。</p>
</blockquote>
<p>然后在 node 上写一份和 master 完全相同的 <code>local.repo</code>：</p>
<pre><code>cd /etc/yum.repos.d/
rm -f *
vi local.repo
</code></pre>
<pre><code>[centos]
name=centos
baseurl=file:///opt/centos
gpgcheck=0

[K8S]
name=K8S
baseurl=file:///opt/K8S/Kubernetes
gpgcheck=0
</code></pre>
<pre><code>yum clean all
yum makecache
</code></pre>
<blockquote>
<p>不想把 ISO 内容复制到 node 时，才需要 master 开 FTP/HTTP 共享，让 node 的 <code>[centos]</code> 指向 <code>ftp://192.168.100.233/centos</code>；本实验两台机器都用本地源，最省事。</p>
</blockquote>
<h2>3. 安装 Docker 18.09.6</h2>
<p>Docker 的 RPM 已经包含在上一节的 <code>[K8S]</code> 离线源里，<strong>不需要额外添加 Docker 官方源</strong>：</p>
<pre><code>yum -y install docker-ce
</code></pre>
<p>yum 会自动解析依赖，装上 <code>docker-ce</code>、<code>docker-ce-cli</code>、<code>containerd.io</code> 三个包。离线源里只有 18.09.6，所以不会装到新版本。</p>
<blockquote>
<p>为什么不装最新版？kubelet 1.14 官方验证的是 Docker 18.09，而且 flannel 等 2018 年的老镜像是 Docker schema1 格式，Docker 26 默认拒绝使用，会直接导致节点 NotReady。若额外启用了 Docker 官方源，<code>yum install docker-ce</code> 就会装到 26.x，务必避免。</p>
</blockquote>
<p>配置 daemon.json：</p>
<pre><code>mkdir -p /etc/docker
vi /etc/docker/daemon.json
</code></pre>
<pre><code>{
  "exec-opts": ["native.cgroupdriver=systemd"]
}
</code></pre>
<p>Docker Hub 直连被 DNS 污染的环境，建议同时配置镜像加速器（按需保留）：</p>
<pre><code>{
  "exec-opts": ["native.cgroupdriver=systemd"],
  "registry-mirrors": ["https://docker.m.daocloud.io"]
}
</code></pre>
<pre><code>systemctl daemon-reload
systemctl start docker
systemctl enable docker

docker info | grep -E "Server Version|Cgroup"
</code></pre>
<p>应看到 <code>Server Version: 18.09.6</code>、<code>Cgroup Driver: systemd</code>。kubelet 和 Docker 的 cgroup 驱动必须一致。</p>
<h2>4. 安装 kubeadm、kubelet、kubectl（1.14.1）</h2>
<p>master 和 node 都执行：</p>
<pre><code>yum -y install kubelet-1.14.1 kubeadm-1.14.1 kubectl-1.14.1

systemctl enable kubelet
systemctl start kubelet
</code></pre>
<blockquote>
<p>初始化完成前 kubelet 会反复重启，这是正常现象，不用管。</p>
</blockquote>
<h2>5. 加载离线镜像</h2>
<p>第 2 节已经把 K8S 包解压到 <code>/opt/K8S</code>，1.14.1 所需的镜像都在 <code>/opt/K8S/images</code>。master 上：</p>
<pre><code>cd /opt/K8S
./kubernetes_base.sh
</code></pre>
<p>脚本会批量 <code>docker load</code> 镜像目录中的 tar 包。确认：</p>
<pre><code>docker images | grep -E "kube-|etcd|flannel|coredns|pause"
</code></pre>
<h2>6. kubeadm 初始化 master</h2>
<pre><code>kubeadm init \
  --kubernetes-version="v1.14.1" \
  --image-repository=registry.aliyuncs.com/google_containers \
  --apiserver-advertise-address=192.168.100.233 \
  --pod-network-cidr=10.16.0.0/16
</code></pre>
<p>参数说明：</p>
<ul>
<li><code>--apiserver-advertise-address</code>：必须是 master 的真实 IP（不是指导书里的 .60）</li>
<li><code>--pod-network-cidr</code>：必须与 flannel 的 <code>Network</code> 配置一致</li>
<li><code>--image-repository</code>：与离线镜像的名称前缀对应</li>
</ul>
<p>初始化成功后按提示配置 kubectl：</p>
<pre><code>mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
</code></pre>
<p>检查控制面：</p>
<pre><code>kubectl get cs
kubectl get nodes
</code></pre>
<h2>7. 部署 flannel 网络</h2>
<pre><code>cd /opt/K8S/yaml
kubectl apply -f kube-flannel.yaml

kubectl get pods -n kube-system -o wide
</code></pre>
<p>master 上的 <code>kube-flannel-ds-amd64-xxx</code> Running 后，控制面节点会先变为 Ready。</p>
<h2>8. node 加入集群</h2>
<h3>8.1 在 node 上准备离线镜像</h3>
<p>第 2 节已经把 <code>/opt/K8S</code> 同步到了 node，镜像就在 <code>/opt/K8S/images</code>，直接运行加载脚本：</p>
<pre><code>cd /opt/K8S
./kubernetes_base.sh
docker images | grep -E "kube-|etcd|flannel|coredns|pause"
</code></pre>
<p>若镜像目录或脚本不完整，至少确保 pause、kube-proxy、flannel 镜像存在，可用 <code>docker save</code> / <code>docker load</code> 从 master 补齐。</p>
<h3>8.2 执行加入命令</h3>
<p>在 master 上生成 join 命令（token 默认 24 小时过期，过期可重新生成）：</p>
<pre><code>kubeadm token create --print-join-command
</code></pre>
<p>在 node 上执行打印出的命令，例如：</p>
<pre><code>kubeadm join 192.168.100.233:6443 --token xxxxxx.xxxxxxxxxxxxxxxx \
  --discovery-token-ca-cert-hash sha256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
</code></pre>
<p>成功标志：</p>
<pre><code>This node has joined the cluster
</code></pre>
<h3>8.3 踩坑：node 一直 NotReady，flannel 镜像 ImagePullBackOff</h3>
<p>现象：</p>
<pre><code>kube-flannel-ds-amd64-xxxxx   0/1   Init:ImagePullBackOff
</code></pre>
<p>查事件：</p>
<pre><code>kubectl describe pod -n kube-system kube-flannel-ds-amd64-xxxxx | tail -20
</code></pre>
<p>如果看到：</p>
<pre><code>Failed to pull image "quay.io/coreos/flannel:v0.11.0-amd64":
[DEPRECATION NOTICE] Docker Image Format v1 and Docker Image manifest version 2,
schema 1 support is disabled by default ...
</code></pre>
<p>原因就找到了：这个 flannel 镜像是 <strong>Docker schema1</strong> 格式，node 上的 Docker 26 拒绝使用。解法：</p>
<ol>
<li>把 node 的 Docker 降级到 18.09.6（与 master 一致）；</li>
<li>在 node 上确保镜像存在；</li>
<li>删掉 flannel Pod 触发重建。</li>
</ol>
<blockquote>
<p>按本实验离线源正常安装的话，node 的 Docker 本来就会是 18.09.6，不会出现这个问题；这里是环境中混入了外来的 Docker 26。</p>
</blockquote>
<p>降级 Docker（node）：</p>
<pre><code>systemctl stop kubelet
systemctl stop docker

yum remove -y docker-ce docker-ce-cli containerd.io docker-ce-rootless-extras \
  docker-buildx-plugin docker-compose-plugin

# containerd 1.6 的元数据 1.2 读不了，挪走旧状态
mv /var/lib/containerd /var/lib/containerd.bak

yum install -y docker-ce-18.09.6 docker-ce-cli-18.09.6 containerd.io-1.2.6-3.3.el7
</code></pre>
<p><code>daemon.json</code> 保持 cgroup systemd，然后启动 Docker 和 kubelet：</p>
<pre><code>systemctl daemon-reload
systemctl start docker
systemctl enable docker
docker info | grep -E "Server Version|Cgroup"

systemctl start kubelet
systemctl status kubelet --no-pager
</code></pre>
<p>加载 flannel 镜像（node）：</p>
<pre><code># 若 node 上没有镜像包，从 master 导出再传过去
# master:
docker save -o /root/flannel.tar quay.io/coreos/flannel:v0.11.0-amd64
scp /root/flannel.tar root@192.168.100.144:/root/

# node:
docker load -i /root/flannel.tar
docker images | grep flannel
</code></pre>
<p>触发重建：</p>
<pre><code>kubectl delete pod -n kube-system kube-flannel-ds-amd64-xxxxx
kubectl get pods -n kube-system -o wide
kubectl get nodes
</code></pre>
<p>两个节点都 Ready 后：</p>
<pre><code>NAME     STATUS   ROLES    AGE   VERSION
master   Ready    master   ...   v1.14.1
node     Ready    &lt;none&gt;   ...   v1.14.1
</code></pre>
<h2>9. 部署 Dashboard</h2>
<pre><code>cd /opt/K8S/yaml
kubectl create -f kubernetes-dashboard.yaml
kubectl create -f dashboard-adminuser.yaml
</code></pre>
<p>检查：</p>
<pre><code>kubectl get pods -n kube-system -o wide
kubectl get svc -n kube-system
</code></pre>
<p>服务类型为 NodePort：</p>
<pre><code>kubernetes-dashboard   NodePort   10.102.208.171   &lt;none&gt;   443:30000/TCP
</code></pre>
<p>本次环境中 Dashboard Pod 调度到了 <strong>master</strong>，所以访问：</p>
<pre><code>https://192.168.100.233:30000
</code></pre>
<p>不是 <code>http://</code>，也不要只认 node 的 IP（Pod 在哪个节点，用哪个节点 IP 最稳；NodePort 正常时任一节点 IP 都可以）。</p>
<p>浏览器提示证书不受信任，选择"高级 → 继续前往"。</p>
<p>获取登录 token：</p>
<pre><code>kubectl -n kube-system get secret | grep admin
kubectl -n kube-system describe secret \
  $(kubectl -n kube-system get secret | grep admin | awk '{print $1}')
</code></pre>
<p>复制 <code>token:</code> 后的字符串登录。</p>
<h2>10. 部署 Nginx 示例应用</h2>
<p>node 上准备镜像（离线包或镜像加速器）：</p>
<pre><code>docker load -i /root/nginx_latest.tar
docker images | grep nginx

# 或走加速器
docker pull docker.m.daocloud.io/library/nginx:latest
docker tag docker.m.daocloud.io/library/nginx:latest nginx:latest
</code></pre>
<p>master 上创建 Deployment：</p>
<pre><code>kubectl create deployment nginx --image=nginx
kubectl get pods -o wide
kubectl get deployment
</code></pre>
<blockquote>
<p><code>--image=nginx</code> 等价于 <code>nginx:latest</code>，默认拉取策略是 <code>Always</code>，kubelet 仍会尝试拉镜像。离线环境如果拉取失败，把策略改成 <code>IfNotPresent</code>：</p>
<pre><code>kubectl patch deployment nginx -p \
  '{"spec":{"template":{"spec":{"containers":[{"name":"nginx","image":"nginx","imagePullPolicy":"IfNotPresent"}]}}}}'
</code></pre>
</blockquote>
<p>发布服务：</p>
<pre><code>kubectl expose deployment nginx --port=80 --type=NodePort
kubectl get svc nginx
</code></pre>
<p>输出中的 <code>80:3xxxx/TCP</code> 即 NodePort：</p>
<pre><code>NAME    TYPE       CLUSTER-IP       PORT(S)        AGE
nginx   NodePort   10.100.233.224   80:31507/TCP   19s
</code></pre>
<p>浏览器访问：</p>
<pre><code>http://192.168.100.144:31507
</code></pre>
<p>看到 "Welcome to nginx!" 即成功。</p>
<p>扩容：</p>
<pre><code>kubectl scale deployment nginx --replicas=3
kubectl get pods -o wide
</code></pre>
<p>清理：</p>
<pre><code>kubectl delete deployment nginx
kubectl delete svc nginx
</code></pre>
<h2>11. 踩坑速查表</h2>
<table>
<thead>
<tr>
<th>问题</th>
<th>原因</th>
<th>解决</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>docker pull</code> 超时，解析到奇怪 IP</td>
<td>Docker Hub 域名被 DNS 污染</td>
<td>配置 registry-mirrors，或用镜像站显式拉取后 <code>docker tag</code></td>
</tr>
<tr>
<td><code>network</code> 启动失败，连续 <code>RTNETLINK answers: File exists</code></td>
<td>残留的 br0 设备 / 重复的地址或网关配置</td>
<td>清理残留网桥和重复 ifcfg，用 <code>network</code> 服务而非 nmcli</td>
</tr>
<tr>
<td><code>chronyc sources</code> 显示 0 个源</td>
<td><code>/etc/hosts</code> 缺 master、主机名拼错</td>
<td>修正 hosts，确保 <code>getent hosts master</code> 有返回</td>
</tr>
<tr>
<td>node NotReady，flannel <code>Init:ImagePullBackOff</code></td>
<td>flannel 镜像是 schema1，Docker 26 默认拒绝</td>
<td>node Docker 降级到 18.09.6，加载镜像后重建 Pod</td>
</tr>
<tr>
<td>Dashboard 打不开</td>
<td>用了 <code>http://</code> 或访问了没有 Pod 的节点</td>
<td>用 <code>https://</code>，优先访问 Dashboard Pod 所在节点的 IP</td>
</tr>
<tr>
<td>配了加速器仍走 Docker Hub</td>
<td>daemon.json 未加载或镜像源失效</td>
<td><code>docker info</code> 确认 Registry Mirrors，换可用源</td>
</tr>
<tr>
<td>node 加入报 token 无效</td>
<td>token 默认 24 小时过期</td>
<td>master 上 <code>kubeadm token create --print-join-command</code></td>
</tr>
<tr>
<td>Nginx Pod 一直 ImagePullBackOff</td>
<td><code>nginx:latest</code> 默认 Always 拉取，离线拉不到</td>
<td>加载镜像并改 <code>imagePullPolicy: IfNotPresent</code></td>
</tr>
</tbody>
</table>
<h2>结语</h2>
<p>这套环境的核心难点不在 kubeadm 本身，而在<strong>老版本组件的兼容性</strong>和<strong>离线/受限网络</strong>：</p>
<ul>
<li>版本组合要对：kubelet 1.14.1 + Docker 18.09.6；</li>
<li>老镜像格式要认：schema1 镜像在 Docker 26 上不可用；</li>
<li>网络细节要通：hosts、chrony、flannel、NodePort 任一环出问题都会表现为集群异常。</li>
</ul>
<p>集群跑起来之后，先给两台虚拟机打快照，再继续后面的 OpenShift 等实验，能省掉大量返工。</p>
]]></content>
    <author><name>槿鸢</name></author>
    <category term="虚拟化"/>
  </entry>
  <entry>
    <title>实验 3.2：在 Rocky Linux 9.5 部署和使用 oVirt 4.5</title>
    <link href="https://blog.ipox.cn/posts/zh-cn/ovirt-45-rocky9-deploy/" rel="alternate" type="text/html"/>
    <id>https://blog.ipox.cn/posts/zh-cn/ovirt-45-rocky9-deploy/</id>
    <published>2026-10-18T18:05:00.000Z</published>
    <updated>2026-10-18T18:05:00.000Z</updated>
    <summary>从两台 VMware 虚拟机起步，装好 oVirt Engine 4.5 与 oVirt Node NG 4.5，配好 NFS 存储域，再用管理门户创建并装好一台 CentOS 7 虚拟机；含 8 个坑的定位与解决。</summary>
    <content type="html"><![CDATA[<blockquote>
<p>一篇完整的落地记录：从两台 VMware 虚拟机起步，装好 <strong>oVirt Engine 4.5</strong> 和 <strong>oVirt Node NG 4.5</strong>，配上 NFS 存储域，最后用管理门户创建并装好一台 CentOS 7 虚拟机。</p>
<p>网上能搜到的教程大多还是 <strong>CentOS 7 + oVirt 4.3.8</strong> 那一套，仓库、安装包和认证方式都已经变了。本文按 <strong>Rocky Linux 9.5 + oVirt 4.5</strong> 重做了一遍，把真正卡住人的地方标成 <strong>【⚠️ 坑 N】</strong>（一共 8 个），其中 <strong>3.8 节</strong>那个坑会让主机永远加不进去，老教程里完全没有提到。</p>
</blockquote>
<p><strong>版本基线</strong></p>
<table>
<thead>
<tr>
<th>组件</th>
<th>版本 / 说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>引擎操作系统</td>
<td>Rocky Linux 9.5（最小安装）</td>
</tr>
<tr>
<td>oVirt Engine</td>
<td><strong>4.5.7-1.el9</strong></td>
</tr>
<tr>
<td>oVirt Node</td>
<td>Node NG <strong>4.5</strong>（el9 安装镜像）</td>
</tr>
<tr>
<td>虚拟化平台</td>
<td>VMware Workstation 17，VMnet8（NAT）</td>
</tr>
<tr>
<td>数据库</td>
<td>PostgreSQL <strong>13</strong>（系统 appstream 源，<strong>别装新版</strong>）</td>
</tr>
<tr>
<td>认证</td>
<td>Keycloak（4.5 起登录页由 Keycloak 提供，<strong>用户名区分大小写</strong>）</td>
</tr>
</tbody>
</table>
<p><strong>环境规划</strong></p>
<table>
<thead>
<tr>
<th>角色</th>
<th>主机名</th>
<th>IP</th>
<th>配置</th>
</tr>
</thead>
<tbody>
<tr>
<td>引擎机</td>
<td><code>engine.lab.net</code></td>
<td>192.168.100.130/24</td>
<td>4 vCPU / 8 GB / 100 GB</td>
</tr>
<tr>
<td>主机节点</td>
<td><code>node.lab.net</code></td>
<td>192.168.100.42/24</td>
<td>2 vCPU / 4 GB / 100 GB</td>
</tr>
<tr>
<td>网关 / DNS</td>
<td>—</td>
<td>192.168.100.2</td>
<td>VMware NAT（VMnet8）</td>
</tr>
</tbody>
</table>
<blockquote>
<p>IP 按自己的环境改（老教程写的是 <code>.41</code>，以你的虚拟机为准），<strong>装好后不要再变</strong>。</p>
</blockquote>
<p><strong>目录</strong></p>
<ul>
<li>1 设置 oVirt 部署环境</li>
<li>2 创建 engine 节点虚拟机</li>
<li>3 部署 oVirt Engine（3.5 engine-setup 逐项问答，含【坑 1】~【坑 6】；<strong>3.8 是最坑的一步</strong>）</li>
<li>4 部署 oVirt Node（【坑 7】磁盘、【坑 8】坏源）</li>
<li>5 添加主机</li>
<li>6 配置存储（NFS 建在 node 上）</li>
<li>7 上传 ISO</li>
<li>8 安装 spice 客户端</li>
<li>9 创建虚拟机</li>
<li>附录 A 踩坑速查表 · B 常用命令 · C Keycloak 授权问题 · D 与老流程对照</li>
</ul>
<p><strong>和老流程（CentOS 7 + oVirt 4.3.8）不一样的地方，只有这 6 处</strong></p>
<table>
<thead>
<tr>
<th>项目</th>
<th>4.3.8 / CentOS 7 老流程</th>
<th>本文（4.5）</th>
</tr>
</thead>
<tbody>
<tr>
<td>操作系统</td>
<td>CentOS 7.9 + 163 源</td>
<td><strong>Rocky Linux 9.5，用系统自带源</strong></td>
</tr>
<tr>
<td>oVirt 源</td>
<td><code>ovirt-release43.rpm</code></td>
<td><strong>CentOS Stream oVirt SIG 仓库</strong>（<code>centos-ovirt45</code>）</td>
</tr>
<tr>
<td>Node 镜像</td>
<td><code>ovirt-node-ng-installer-...el7.iso</code></td>
<td><strong><code>ovirt-node-ng-installer-latest-el9.iso</code></strong></td>
</tr>
<tr>
<td>认证</td>
<td>AAA-JDBC</td>
<td><strong>Keycloak（SSO）</strong>，登录页由 Keycloak 提供</td>
</tr>
<tr>
<td>集群默认版本</td>
<td>4.3（能用）</td>
<td><strong>引擎默认给 4.8，Node 只支持到 4.7 → 主机永远加不上</strong>（3.8 节）</td>
</tr>
<tr>
<td>engine-setup 问答</td>
<td>无 Keycloak 相关</td>
<td>多出 Keycloak / SSO / WebSocket Proxy 问答</td>
</tr>
</tbody>
</table>
<blockquote>
<p><strong>关于配图</strong>：文中截图取自 oVirt <strong>4.3.8</strong> 的界面（图号沿用原图 3-47 ~ 3-78）。4.5 在<strong>登录页、主机页、新建虚拟机页</strong>的文案和默认值略有差别，<strong>操作路径完全一致</strong>，看图时注意版本号不同即可。</p>
</blockquote>
<hr />
<h2>1. 设置 oVirt 部署环境</h2>
<p>打开 VMware Workstation → <strong>编辑 → 虚拟网络编辑器</strong>，确认 <strong>VMnet8（NAT）</strong> 已启用，并能看到 NAT 设置里的<strong>网关地址</strong>（一般为 <code>192.168.100.2</code>，就是两台虚拟机的网关和 DNS）。</p>
<blockquote>
<p><strong>验证</strong>：<code>vmnet8</code> 的"使用本地 DHCP 服务将 IP 地址分配给虚拟机"按需勾选；实验里两台机器建议直接配静态 IP。</p>
</blockquote>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-47_2026-10-18_180212.webp" alt="图 3-47 虚拟网络编辑器：VMnet8（NAT）的网关就是 192.168.100.2" /></p>
<hr />
<h2>2. 创建 engine 节点虚拟机</h2>
<p>安装介质换成 Rocky Linux 9.5 minimal：</p>
<ol>
<li>
<p>新建虚拟机：<strong>4 vCPU / 8 GB 内存 / 100 GB 硬盘</strong>，CD/DVD 挂载 <code>Rocky-9.5-x86_64-minimal.iso</code>，软件选择 <strong>最小安装</strong>。</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-48_2026-10-18_180212.webp" alt="图 3-48 engine 虚拟机的硬件配置（内存 / 处理器 / 100 GB 磁盘 / NAT 网卡）" /></p>
</li>
<li>
<p>安装过程中在"网络和主机名"里把网卡<strong>连上</strong>，主机名填 <strong><code>engine.lab.net</code></strong>，设置 root 密码。</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-50_2026-10-18_180212.webp" alt="图 3-50 安装向导的“网络和主机名”页" /></p>
<p>到“安装目的地”这步<strong>自动分区</strong>即可（图 3-49 是老流程里手动分区的样子：<code>/boot</code>、<code>swap</code>、<code>/</code> 三块）：</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-49_2026-10-18_180212.webp" alt="图 3-49 安装向导的手动分区（engine）" /></p>
</li>
<li>
<p>装完登录，配置 IP（<code>192.168.100.130/24</code>）、网关和 DNS（<code>192.168.100.2</code>）。</p>
</li>
<li>
<p>用 SSH（如 Xshell / MobaXterm / Windows 自带 <code>ssh</code>）连上去做后续操作。</p>
</li>
</ol>
<pre><code>hostnamectl set-hostname engine.lab.net
hostname -f                     # 必须输出 engine.lab.net
ip -4 a                         # 确认 IP
systemctl enable --now chronyd  # 时间同步，oVirt 对时间敏感
</code></pre>
<hr />
<h2>3. 部署 oVirt Engine</h2>
<h3>3.1 配置 oVirt 4.5 软件源</h3>
<p>老流程（CentOS 7）是"删掉原有源、换成 163 源、再装 <code>ovirt-release43.rpm</code>"。Rocky 上<strong>不需要动系统源</strong>，只要加一个 oVirt 的仓库文件：</p>
<pre><code>cat &gt; /etc/yum.repos.d/centos-ovirt45.repo &lt;&lt;'EOF'
[centos-ovirt45]
name=CentOS Stream 9 - oVirt 4.5
baseurl=https://mirrors.aliyun.com/centos-stream/SIGs/9-stream/virt/x86_64/ovirt-45/
enabled=1
gpgcheck=0
module_hotfixes=1
EOF

dnf clean all
dnf makecache
</code></pre>
<blockquote>
<p><strong><code>module_hotfixes=1</code> 不能少</strong>：el9 的模块过滤会让部分 oVirt 包"看不见"，少了这行会出现"源配好了但装不上 ovirt-engine"。</p>
<p><strong>备选</strong>：<code>dnf -y install centos-release-ovirt45</code>（会自动写好仓库文件），二选一即可。</p>
<p><strong>验证</strong>：<code>dnf repolist | grep ovirt</code> 能看到 <code>centos-ovirt45</code>。</p>
</blockquote>
<h3>3.2 升级系统</h3>
<pre><code>dnf -y update
shutdown -r now
</code></pre>
<h3>3.3 安装 ovirt-engine</h3>
<pre><code>dnf -y install ovirt-engine
</code></pre>
<blockquote>
<p>会连带装 PostgreSQL、Keycloak、WildFly 等，视网速需要较长时间。<strong>验证</strong>：<code>rpm -q ovirt-engine</code> 输出 <code>ovirt-engine-4.5.7-1.el9.noarch</code>。</p>
</blockquote>
<h3>3.4 禁用防火墙</h3>
<pre><code>systemctl stop firewalld
systemctl disable firewalld
</code></pre>
<blockquote>
<p>想保留防火墙也可以，那就在下一步 engine-setup 问"是否自动配置防火墙"时回答 <strong>Yes</strong>。<strong>但不要两边都不管</strong>。</p>
</blockquote>
<h3>3.5 部署 oVirt Engine（engine-setup）—— 坑最集中的一步</h3>
<pre><code>engine-setup
</code></pre>
<p>各问答<strong>大部分直接回车取默认值</strong>，需要留意的几处：</p>
<table>
<thead>
<tr>
<th>提示</th>
<th>该填什么</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>Configure Engine on this host (Yes, No)</code></td>
<td><strong>Yes</strong>（见【坑 2】）</td>
</tr>
<tr>
<td><code>Configure WebSocket Proxy on this host? (Yes, No)</code></td>
<td><strong>Yes</strong>（浏览器里的 noVNC 控制台靠它）</td>
</tr>
<tr>
<td><code>Host fully qualified DNS name of this server [...]</code></td>
<td><strong><code>engine.lab.net</code></strong>（见【坑 1】）</td>
</tr>
<tr>
<td><code>Do you want Setup to configure the firewall?</code></td>
<td>3.4 已关防火墙 → <strong>No</strong></td>
</tr>
<tr>
<td><code>Engine admin password:</code> / <code>Confirm engine admin password:</code></td>
<td><strong>记牢！</strong>（见【坑 6】）</td>
</tr>
<tr>
<td><code>Found existing PKI files ... overwrite ...? (Yes, No) [No]</code></td>
<td><strong>手打 <code>Yes</code></strong>（见【坑 5】）</td>
</tr>
</tbody>
</table>
<p>成功的样子：</p>
<pre><code>[ INFO  ] Execution of setup completed successfully
</code></pre>
<hr />
<h4>【坑 1】FQDN 默认成了 <code>localhost.localdomain</code></h4>
<p>引擎的主机名必须是<strong>能被解析的全限定域名</strong>。安装前一定要：</p>
<pre><code>hostnamectl set-hostname engine.lab.net
echo '192.168.100.130 engine.lab.net engine' &gt;&gt; /etc/hosts
hostname -f          # engine.lab.net
</code></pre>
<p>出现 <code>[WARNING] Failed to resolve engine.lab.net using DNS, it can be resolved only locally</code> 可以忽略（本机 hosts 能解析就行）。</p>
<h4>【坑 2】<code>Configure Engine on this host</code> 的默认值变成 <code>[No]</code></h4>
<p>只要这台机器<strong>中途中断过一次 engine-setup</strong>，向导就会以为"引擎已存在"，把这一问的默认值改成 <code>[No]</code>；你顺手一回车，它就去配置"远程引擎"，最后失败。</p>
<p><strong>处理</strong>：中断 → 清理 → 重来，并在这一问<strong>明确输入 <code>Yes</code></strong>：</p>
<pre><code>engine-cleanup      # 全部回答 Yes
engine-setup
</code></pre>
<blockquote>
<p><strong>规矩：每次中断 engine-setup 后，都要跑一次 <code>engine-cleanup</code>。</strong></p>
</blockquote>
<h4>【坑 3】<code>Database configuration was requested, however, postgresql service was not found</code></h4>
<p><strong>原因</strong>：机器上装的是 <strong>PGDG 的 PostgreSQL 18</strong>（只提供 <code>postgresql-18.service</code>），而 oVirt 找的是不带版本号的 <code>postgresql.service</code>。</p>
<pre><code>rpm -qa | grep -i postgres           # 确认是不是装了 postgresql18-*

dnf -y remove postgresql18 postgresql18-server postgresql18-contrib postgresql18-libs
dnf -y install postgresql-server postgresql
postgresql-setup --initdb
systemctl enable --now postgresql

sudo -u postgres psql -c "select version();"    # PostgreSQL 13.23 ...
</code></pre>
<blockquote>
<p>oVirt 4.5 <strong>只认系统源（appstream）的 PostgreSQL 13</strong>，别去装新版。</p>
</blockquote>
<h4>【坑 4】<code>could not open extension control file ".../uuid-ossp.control"</code> 和 <code>ovirt-aaa-jdbc-tool failed to execute</code></h4>
<p>两个都是<strong>缺包</strong>，一条命令解决：</p>
<pre><code>dnf -y install postgresql-contrib ongres-scram-client
</code></pre>
<p>（第二个的根因是 <code>/usr/share/ovirt-engine/modules/common/com/ongres/scram/client/main/client.jar</code> 指向的文件不存在，<code>ongres-scram-client</code> 来自 <code>centos-ovirt45</code> 仓库。）</p>
<h4>【坑 5】PKI 覆盖询问必须<strong>手打 <code>Yes</code></strong></h4>
<pre><code>Found existing PKI files, but /etc/pki/ovirt-engine/ca.pem is missing.
Do you want to Continue with Setup and overwrite existing PKI files? (Yes, No) [No]:
</code></pre>
<p>默认是 <strong>No</strong>，只按回车会被判为放弃，报 <code>Failed to execute stage 'Environment customization': Aborted by user</code>。</p>
<blockquote>
<p>顺便记住：<code>engine-setup --config-file=...</code> 是<strong>无效选项</strong>（报 <code>FATAL: Invalid option</code>），要免交互得用 <code>--answer-file</code>。</p>
</blockquote>
<h4>【坑 6】admin 密码存在 Keycloak 里，忘了很麻烦</h4>
<p>oVirt 4.5 的 <code>admin</code> 密码<strong>不在</strong> <code>ovirt-aaa-jdbc-tool</code> 能改的地方，它在 <strong>Keycloak</strong> 里。所以：</p>
<ul>
<li>engine-setup 问 <code>Engine admin password:</code> 时输入的密码，<strong>当场记下来</strong>；</li>
<li>万一忘了，用第 3.7 节的方法重置（需要进 Keycloak 管理控制台）。</li>
</ul>
<h3>3.6 配置 hosts 解析</h3>
<p><strong>Windows 本机</strong>：编辑 <code>C:\Windows\System32\drivers\etc\hosts</code>，加一行（用管理员权限）：</p>
<pre><code>192.168.100.130 engine.lab.net
</code></pre>
<p><strong>engine 节点</strong>：</p>
<pre><code>cat &gt;&gt; /etc/hosts &lt;&lt;'EOF'
192.168.100.130 engine.lab.net engine
192.168.100.42  node.lab.net   node
EOF
</code></pre>
<h3>3.7 登录管理门户（以及登录不进去怎么办）</h3>
<p>浏览器访问 <strong><code>https://engine.lab.net/</code></strong>，点"管理门户"。</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-53_2026-10-18_180212.webp" alt="图 3-53 oVirt 登录界面" /></p>
<blockquote>
<p><strong>用户名必须是小写 <code>admin</code>，不要写 <code>admin@internal</code></strong>——4.5 的登录页是 Keycloak 提供的，<strong>用户名区分大小写</strong>，老文档那种写法会直接失败。</p>
</blockquote>
<p>登录成功后就是管理门户（计算 / 存储 / 网络 / 管理四个入口）：</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-54_2026-10-18_180212.webp" alt="图 3-54 登录成功后的管理门户" /></p>
<h4>登录页反复弹回 / 报 <code>decrypting JWE failed</code></h4>
<p>Apache 的状态 Cookie 解不开，根因是 <code>/etc/httpd/conf.d/internalsso-openidc.conf</code> 里的 <code>OIDCCryptoPassphrase</code> 是<strong>动态随机生成</strong>的，每次重启 httpd 就换一把密钥，旧 Cookie 全作废。改成固定口令：</p>
<pre><code>cp /etc/httpd/conf.d/internalsso-openidc.conf{,.bak.$(date +%Y%m%d%H%M)}
sed -i 's|^OIDCCryptoPassphrase.*|OIDCCryptoPassphrase "自己编一个32位随机串"|' \
    /etc/httpd/conf.d/internalsso-openidc.conf
httpd -t                # Syntax OK
systemctl restart httpd
</code></pre>
<p>改完请用<strong>无痕窗口</strong>重新登录（浏览器里残留的旧 Cookie 会继续捣乱）。</p>
<h4>忘记 admin 密码：进 Keycloak 管理控制台重置</h4>
<ol>
<li>浏览器打开 <strong><code>https://engine.lab.net/ovirt-engine-auth/admin/</code></strong></li>
<li>用 <code>admin</code> 登录（master realm 管理员，密码就是 engine-setup 时设的那个）</li>
<li>左上角 realm 切到 <strong><code>ovirt-internal</code></strong></li>
<li><strong>Users</strong> → 选 <code>admin</code> → <strong>Credentials</strong> → <strong>Reset password</strong> → 输入新密码，<strong>Temporary 关掉</strong> → Save</li>
</ol>
<p>等价的命令行方式（实测可用）：</p>
<pre><code>TOKEN=$(curl -sk -X POST \
  https://engine.lab.net/ovirt-engine-auth/realms/master/protocol/openid-connect/token \
  -d client_id=admin-cli -d grant_type=password \
  -d username=admin -d password='&lt;master管理员密码&gt;' \
  | sed -n 's/.*"access_token":"\([^"]*\)".*/\1/p')

# 查用户 id
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://engine.lab.net/ovirt-engine-auth/admin/realms/ovirt-internal/users?username=admin"

# 重置密码
curl -sk -X PUT -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
  "https://engine.lab.net/ovirt-engine-auth/admin/realms/ovirt-internal/users/&lt;用户id&gt;/reset-password" \
  -d '{"type":"password","value":"新密码","temporary":false}'
</code></pre>
<h3>3.8 ⚠️【最大的坑】把数据中心和集群的兼容版本改成 4.5</h3>
<p><strong>这一步老流程里没有、但 oVirt 4.5 上必做。不做，第 5 节添加主机时永远加不进去。</strong></p>
<h4>现象</h4>
<p>主机添加进去、"安装"也跑完了，状态却一直是红色 <strong>NonOperational（无法工作）</strong>，事件里能看到：</p>
<pre><code>Host node is compatible with versions (4.2,4.3,4.4,4.5,4.6,4.7)
and cannot join Cluster Default which is set to version 4.8.
</code></pre>
<h4>原因</h4>
<table>
<thead>
<tr>
<th>数据</th>
<th>值</th>
</tr>
</thead>
<tbody>
<tr>
<td>引擎支持的集群级别</td>
<td><code>4.2,4.3,4.4,4.5,4.6,4.7,</code><strong><code>4.8</code></strong></td>
</tr>
<tr>
<td>Node 实际支持的级别</td>
<td><code>4.2,…,4.7</code>（<strong>够不到 4.8</strong>）</td>
</tr>
<tr>
<td>engine-setup 建的 <code>Default</code> 数据中心 / 集群</td>
<td><strong>4.8</strong>（取了引擎的最高值）</td>
</tr>
</tbody>
</table>
<p>而且<strong>图形界面里改不了</strong>：</p>
<ul>
<li>数据中心版本<strong>只能升不能降</strong> → 下拉框里只剩 <code>4.8</code>；</li>
<li>集群版本<strong>必须 ≥ 所属数据中心版本</strong> → 数据中心是 4.8，集群也只能选 <code>4.8</code>。</li>
</ul>
<p>→ <strong>界面死锁。</strong> 解法只有两个：</p>
<h4>方案 A（推荐，10 秒）</h4>
<pre><code>export PGPASSWORD=&lt;引擎库口令&gt;       # 见 /etc/ovirt-engine/engine.conf.d/ 下 engine-setup 生成的配置
psql -h 127.0.0.1 -U engine -d engine &lt;&lt;'SQL'
begin;
update storage_pool set compatibility_version='4.5' where name='Default';
update cluster      set compatibility_version='4.5' where name='Default';
commit;
SQL

systemctl restart ovirt-engine      # 引擎把兼容版本缓存在内存里，必须重启才生效
</code></pre>
<h4>方案 B（纯界面）</h4>
<p>删掉默认的 <code>Default</code> 数据中心和 <code>Default</code> 集群（此时还没建存储域，可以直接删），然后自己<strong>新建数据中心（兼容版本选 4.5）+ 新建集群（兼容版本选 4.5，CPU 类型选 <code>qemu64</code>）</strong>。</p>
<h4>完成后的正常告警（忽略它）</h4>
<pre><code>Data Center Default compatibility version is 4.5, which is lower than latest available version 4.8.
Please upgrade your Data Center to latest version ...
</code></pre>
<p>这是引擎例行提醒"数据中心不是最新级别"。<strong>我们正是要它低于 4.8</strong>，因为 Node 只认到 4.7。</p>
<p><strong>验证</strong>：</p>
<pre><code>select name, compatibility_version from storage_pool;   -- 4.5
select name, compatibility_version from cluster;        -- 4.5
</code></pre>
<hr />
<h2>4. 部署 oVirt Node</h2>
<h3>4.1 下载镜像（4.5 用 el9 版）</h3>
<p>官方下载地址（约 1.2 GB）：</p>
<p><a href="https://resources.ovirt.org/pub/ovirt-4.5/iso/ovirt-node-ng-installer/ovirt-node-ng-installer-latest-el9.iso">ovirt-node-ng-installer-latest-el9.iso</a></p>
<h3>4.2 新建虚拟机</h3>
<p><strong>2 vCPU / 4 GB 内存 / 100 GB 硬盘</strong>，CPU 启用虚拟化，挂 <code>ovirt-node-ng-installer-latest-el9.iso</code>。</p>
<p><strong>【坑 7】磁盘必须 ≥ 100 GB</strong></p>
<p>oVirt Node 的默认分区方案吃不下 50 GB，会报：</p>
<pre><code>可用空间 50 GiB / 总空间 50 GiB
自动分区失败：not enough free space in volume group
</code></pre>
<p><strong>解决</strong>：关机 → VMware 里把虚拟磁盘从 50 GB 扩到 <strong>100 GB</strong>（qcow2 稀疏文件，不会立刻占满物理盘）→ 重新引导安装。</p>
<h3>4.3 安装与网络配置</h3>
<p>oVirt Node NG 用的就是 CentOS 的 Anaconda 安装器，步骤和老流程一样，一步步往下走：</p>
<p><strong>① 语言</strong>：</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-55_2026-10-18_180212.webp" alt="图 3-55 安装向导：语言选择" /></p>
<p><strong>② 软件选择</strong>——保持默认的“最小安装”：</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-56_2026-10-18_180212.webp" alt="图 3-56 安装向导：软件选择" /></p>
<p><strong>③ 安装目的地</strong>——点 <strong>“Click here to create them automatically”（自动创建分区）</strong>。图 3-57 是还没分区时的样子，图 3-58 是自动创建的入口，图 3-59 是自动分好的结果：</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-57_2026-10-18_180212.webp" alt="图 3-57 安装向导：还没分区的磁盘" />
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-58_2026-10-18_180212.webp" alt="图 3-58 安装向导：自动创建分区" />
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-59_2026-10-18_180212.webp" alt="图 3-59 安装向导：自动分区结果" /></p>
<p><strong>④ 网络和主机名</strong>——网卡<strong>连上</strong>，主机名填 <strong><code>node.lab.net</code></strong>，IP <strong><code>192.168.100.42/24</code></strong>、网关和 DNS <code>192.168.100.2</code>：</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-60_2026-10-18_180212.webp" alt="图 3-60 安装向导的“网络和主机名”页（node）" /></p>
<pre><code>cat &gt;&gt; /etc/hosts &lt;&lt;'EOF'
192.168.100.130 engine.lab.net engine
192.168.100.42  node.lab.net   node
EOF
hostname -f
</code></pre>
<h3>4.4 ⚠️【必做】关掉 oVirt Node 自带的坏源 <code>onn-sap</code></h3>
<p><strong>每一台 oVirt Node NG 4.5 都带这个坏源</strong>（<code>baseurl</code> 指向一个根本不存在的 SAP 仓库），不关掉，第 5 节添加主机必然失败。</p>
<pre><code>cat /etc/yum.repos.d/node-optional.repo          # 看一眼，[onn-sap] 那段的 baseurl 是死的

dnf config-manager --set-disabled onn-sap
# 更保险：全局禁掉，防止 oVirt Node 重启后被重新启用
grep -q '^disablerepo=onn-sap' /etc/dnf/dnf.conf || \
  sed -i '/^\[main\]/a disablerepo=onn-sap' /etc/dnf/dnf.conf

dnf makecache                                    # 无报错
dnf -y install python3 &amp;&amp; python3 --version      # 3.9.18
</code></pre>
<hr />
<h2>5. 添加主机</h2>
<p><strong>计算 → 主机 → 新建</strong>：</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-61_2026-10-18_180212.webp" alt="图 3-61 主机页面：点“新建”" /></p>
<table>
<thead>
<tr>
<th>字段</th>
<th>填写</th>
</tr>
</thead>
<tbody>
<tr>
<td>名称</td>
<td><code>node</code>（显示名，不写 <code>.lab.net</code>）</td>
</tr>
<tr>
<td>主机名/IP</td>
<td><code>192.168.100.42</code></td>
</tr>
<tr>
<td>用户名 / 密码</td>
<td><code>root</code> / Node 的 root 密码</td>
</tr>
<tr>
<td>集群</td>
<td>第 3.8 节里<strong>兼容版本为 4.5</strong> 的集群</td>
</tr>
</tbody>
</table>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-62_2026-10-18_180212.webp" alt="图 3-62 新建主机：基础信息" /></p>
<p>提示“没有配置电源管理”点<strong>确定</strong>（实验环境不需要 fencing）：</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-63_2026-10-18_180212.webp" alt="图 3-63 电源管理配置：直接确定" /></p>
<p>之后引擎会自动跑 host-deploy，状态先变成“安装中”（图 3-64），跑完就是绿色 <strong>Up</strong>：</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-64_2026-10-18_180212.webp" alt="图 3-64 主机安装中（Installing）" /></p>
<h3>【坑 8】<code>Host node installation failed. Task Ensure Python3 is installed for CentOS/RHEL8 hosts failed to execute.</code></h3>
<p>界面上的报错**≠ 真实原因**，一定要去翻它给出的部署日志：</p>
<pre><code>ls -lt /var/log/ovirt-engine/host-deploy/
grep -nE "fatal:|FAILED" /var/log/ovirt-engine/host-deploy/ovirt-host-deploy-ansible-*.log | tail
</code></pre>
<p>日志里真正的原因是 <strong><code>onn-sap</code> 这个死源</strong>，跟 Python 毫无关系：</p>
<pre><code>Failed to download metadata for repo 'onn-sap':
Cannot download repodata/repomd.xml: All mirrors were tried
</code></pre>
<p>回到 Node 上按 <strong>4.4 节</strong> 关掉 <code>onn-sap</code>，再回门户重试添加主机即可。</p>
<hr />
<h2>6. 配置存储（NFS 建在 node 节点上）</h2>
<p>存储用 NFS，全部在 <strong>node</strong> 上操作：</p>
<pre><code># 1) 在 node 节点创建 NFS 共享目录
mkdir -p /data/ISO /data/vm          # /data 不存在就新建；空间不足可换到有空间的目录

# 2) 配置目录权限（36:36 是 vdsm/kvm 用户）
chown 36:36 /data/ISO &amp;&amp; chmod 755 /data/ISO
chown 36:36 /data/vm  &amp;&amp; chmod 755 /data/vm

# 3) 编辑 NFS 服务器配置文件
cat &gt;&gt; /etc/exports &lt;&lt;'EOF'
/data/ISO 192.168.100.0/24(rw,sync,no_subtree_check,all_squash,anonuid=36,anongid=36)
/data/vm  192.168.100.0/24(rw,sync,no_subtree_check,all_squash,anonuid=36,anongid=36)
EOF

# 4) 启动 NFS 服务
systemctl enable --now rpcbind nfs-server
setsebool -P virt_use_nfs 1

# 5) 查看 NFS 输出
showmount -e
# Export list for node.lab.net:
# /data/vm   192.168.100.0/24
# /data/ISO  192.168.100.0/24
</code></pre>
<blockquote>
<p>若 engine 与 node 之间被防火墙隔开，记得放行 NFS：
<code>firewall-cmd --permanent --add-service=nfs --add-service=rpc-bind --add-service=mountd &amp;&amp; firewall-cmd --reload</code></p>
</blockquote>
<p><strong>在门户里建两个存储域</strong>（<strong>存储 → 域 → 新建域</strong>）：</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-65_2026-10-18_180212.webp" alt="图 3-65 新建域：名称 / 域功能 / 存储类型 / 导出路径" /></p>
<table>
<thead>
<tr>
<th></th>
<th>数据域</th>
<th>ISO 域</th>
</tr>
</thead>
<tbody>
<tr>
<td>名称</td>
<td><code>vm</code>（描述 Virtual Machine）</td>
<td><code>ISO</code>（描述 DVD Image）</td>
</tr>
<tr>
<td>域功能</td>
<td><strong>Data</strong></td>
<td><strong>ISO</strong></td>
</tr>
<tr>
<td>存储类型</td>
<td>NFS</td>
<td>NFS</td>
</tr>
<tr>
<td>导出路径</td>
<td><code>192.168.100.42:/data/vm</code></td>
<td><code>192.168.100.42:/data/ISO</code></td>
</tr>
</tbody>
</table>
<p>两个域的导出路径分别填成刚才 NFS 输出的两个目录：</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-66_2026-10-18_180212.webp" alt="图 3-66 新建域：Data 域指向 192.168.100.42:/data/vm" />
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-67_2026-10-18_180212.webp" alt="图 3-67 新建域：ISO 域指向 192.168.100.42:/data/ISO" /></p>
<p>数据域会自动挂到数据中心；<strong>ISO 域建好后要右键"附加"到数据中心</strong>。等两个域状态都变成 <strong>"活跃的"</strong>。</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-68_2026-10-18_180212.webp" alt="图 3-68 存储域列表：两个域都是“活跃的”" /></p>
<hr />
<h2>7. 上传 ISO</h2>
<p>把系统 ISO 拷进 <strong>ISO 域里以"数据中心 ID"命名的目录</strong>：</p>
<pre><code># 在 node 上先查数据中心 ID（在 engine 上执行也可以）
DC_ID=$(PGPASSWORD=&lt;引擎库口令&gt; psql -h 127.0.0.1 -U engine -d engine -t -A \
        -c "select id from storage_pool where name='Default';")

ISO_DIR=/data/ISO/$DC_ID/images/11111111-1111-1111-1111-111111111111
mkdir -p $ISO_DIR
cp /root/CentOS-7-x86_64-Minimal-2009.iso $ISO_DIR/
chown 36:36 $ISO_DIR/*.iso &amp;&amp; chmod 644 $ISO_DIR/*.iso
ls -lh $ISO_DIR
</code></pre>
<p>引擎会周期性扫描 ISO 域，等 1~2 分钟（或选中 ISO 域点一下"刷新"）。</p>
<blockquote>
<p><strong>验证</strong>：新建虚拟机时，在"运行一次"窗口的 CD 下拉框里能看到这个 ISO。</p>
</blockquote>
<hr />
<h2>8. 安装 spice 客户端</h2>
<p>下载并安装 <strong><code>virt-viewer-x64-11.0-1.0.msi</code></strong>（oVirt 官方的 Windows 控制台客户端），装完用它打开门户里下载的 <code>console.vv</code>。</p>
<blockquote>
<p>不想装也行：门户里的虚拟机控制台可以直接用 <strong>noVNC</strong>（浏览器打开），前提是 engine-setup 时 <code>Configure WebSocket Proxy</code> 选了 <strong>Yes</strong>。
另外 <strong>TigerVNC</strong> 也能连（在虚拟机"控制台选项"里看 VNC 端口）。</p>
</blockquote>
<hr />
<h2>9. 创建虚拟机</h2>
<ol>
<li>
<p><strong>计算 → 虚拟机 → 新建</strong>：操作系统 <code>Red Hat Enterprise Linux 7.x x64</code> / <code>CentOS 7</code>，优化目标“服务器”，名称 <code>CentOS7</code>。</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-69_2026-10-18_180212.webp" alt="图 3-69 虚拟机页面：点“新建”" />
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-70_2026-10-18_180212.webp" alt="图 3-70 新建虚拟机：常规（操作系统 + 名称）" /></p>
</li>
<li>
<p>实例镜像“创建”一块 <strong>10 GB</strong> 虚拟磁盘。</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-71_2026-10-18_180212.webp" alt="图 3-71 新建虚拟磁盘：10 GiB" /></p>
</li>
<li>
<p>网络接口选 <strong><code>ovirtmgmt</code></strong>。</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-72_2026-10-18_180212.webp" alt="图 3-72 网络接口：ovirtmgmt" /></p>
</li>
<li>
<p><strong>用 VMware Workstation 做实验时必做</strong>：勾选“显示高级选项 → 系统 → 高级参数 → 自定义仿真机”，选择 <strong><code>pc-i440fx-rhel7.2.0</code></strong>（或 <code>pc-i440fx-rhel7.1.0</code>），否则虚机装完系统起不来。</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-73_2026-10-18_180212.webp" alt="图 3-73 系统 → 高级参数 → 自定义仿真机" /></p>
</li>
<li>
<p>选中虚拟机 → <strong>“只运行一次”</strong> → 勾选<strong>附加 CD</strong>、选刚上传的系统 ISO、引导顺序把 <strong>CD-ROM</strong> 放最前。</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-74_2026-10-18_180212.webp" alt="图 3-74 工具栏上的“只运行一次”" />
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-75_2026-10-18_180212.webp" alt="图 3-75 运行一次：附加 CD + 引导顺序" /></p>
</li>
<li>
<p>启动后点 <strong>控制台</strong>，双击下载的 <code>console.vv</code> 打开 Remote Viewer（<strong>释放鼠标：Shift+F12</strong>）完成系统安装。</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-76_2026-10-18_180212.webp" alt="图 3-76 控制台里进入安装引导菜单" /></p>
</li>
<li>
<p>装完把引导顺序改回<strong>硬盘</strong>；在虚机里 <code>ip a</code> 看到 IP 后，宿主机能 ping 通、能 SSH 上去，实验完成。</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-77_2026-10-18_180212.webp" alt="图 3-77 虚机里 ip a 看 IP" />
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/fig3-78_2026-10-18_180212.webp" alt="图 3-78 宿主机 SSH 连上虚机" /></p>
</li>
</ol>
<blockquote>
<p>界面刷新不下来时，<code>systemctl restart ovirt-engine</code> 是最省事的"重启大法"。</p>
</blockquote>
<hr />
<h2>附录 A：踩坑速查表（按报错信息检索）</h2>
<table>
<thead>
<tr>
<th>现象 / 报错</th>
<th>真实原因</th>
<th>解决</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>Database configuration ... postgresql service was not found</code></td>
<td>装了 PGDG 的 PostgreSQL 18（只有 <code>postgresql-18.service</code>）</td>
<td>卸掉 18，装系统源 <code>postgresql-server</code>（13），<code>postgresql-setup --initdb</code></td>
</tr>
<tr>
<td><code>could not open extension control file ".../uuid-ossp.control"</code></td>
<td>缺 contrib 扩展</td>
<td><code>dnf -y install postgresql-contrib</code></td>
</tr>
<tr>
<td><code>'/usr/bin/ovirt-aaa-jdbc-tool' failed to execute</code> + <code>NoSuchFileException: .../ongres/scram/client.jar</code></td>
<td>缺 scram 客户端包</td>
<td><code>dnf -y install ongres-scram-client</code></td>
</tr>
<tr>
<td>PKI 询问后 <code>Aborted by user</code></td>
<td>该问默认 <code>No</code>，回车等于放弃</td>
<td><strong>手打 <code>Yes</code></strong> 再回车</td>
</tr>
<tr>
<td><code>Configure Engine on this host</code> 默认成了 <code>[No]</code></td>
<td>上次中途中断留下残留状态</td>
<td><code>engine-cleanup</code> 后重跑，明确回答 <code>Yes</code></td>
</tr>
<tr>
<td>主机装完一直是红色 <strong>NonOperational</strong>，事件 <code>VDS_CLUSTER_VERSION_NOT_SUPPORTED(154)</code></td>
<td>默认数据中心/集群被设成 4.8，Node 只到 4.7；界面里数据中心只能升、集群必须 ≥ 数据中心 → 死锁</td>
<td>按 <strong>3.8 节</strong> 改库为 4.5 并重启引擎</td>
</tr>
<tr>
<td>告警 <code>Data Center ... lower than latest available version 4.8</code></td>
<td>引擎例行"升级数据中心"提示</td>
<td><strong>忽略</strong>（本来就是要它低）</td>
</tr>
<tr>
<td><code>Host node installation failed. Task Ensure Python3 is installed ...</code></td>
<td>Node 上的 <strong><code>onn-sap</code> 死源</strong>，与 Python 无关</td>
<td>Node 上 <code>dnf config-manager --set-disabled onn-sap</code> + <code>/etc/dnf/dnf.conf</code> 加 <code>disablerepo=onn-sap</code></td>
</tr>
<tr>
<td>oVirt Node 安装报 <code>not enough free space in volume group</code></td>
<td>虚拟磁盘 50 GB 不满足默认分区</td>
<td>磁盘扩到 <strong>100 GB</strong> 重装</td>
</tr>
<tr>
<td>登录页反复弹回 / <code>decrypting JWE failed</code></td>
<td><code>OIDCCryptoPassphrase</code> 每次重启 httpd 都变</td>
<td>改成固定口令 + <code>systemctl restart httpd</code>，用无痕窗口重登</td>
</tr>
<tr>
<td><code>The user admin@internalkeycloak-authz with profile [internalsso] is not authorized to perform login</code></td>
<td>认证过了、<strong>授权</strong>没过（Keycloak realm 缺用户 / 引擎 <code>permissions</code> 表缺 SuperUser 授权）</td>
<td>见附录 C</td>
</tr>
<tr>
<td>浏览器控制台连不上虚机</td>
<td>没配 WebSocket Proxy</td>
<td>重跑 engine-setup 时对该问答 <strong>Yes</strong>，或改用 <code>console.vv</code> + remote-viewer</td>
</tr>
<tr>
<td>虚机装完系统无法引导</td>
<td>VMware 嵌套环境需要指定仿真机</td>
<td>高级参数 → 自定义仿真机 → <code>pc-i440fx-rhel7.2.0</code></td>
</tr>
</tbody>
</table>
<hr />
<h2>附录 B：常用命令速查</h2>
<pre><code># ---- engine 节点 ----
systemctl status ovirt-engine        # 引擎状态（Keycloak 是引擎内嵌子系统，没有独立的 keycloak.service）
engine-setup / engine-cleanup        # 配置 / 清理
engine-backup --mode=backup --file=/root/all.bk --log=/root/all.log

export PGPASSWORD=&lt;引擎库口令&gt;
psql -h 127.0.0.1 -U engine -d engine

select name, compatibility_version from storage_pool;      # 数据中心版本
select name, compatibility_version from cluster;           # 集群版本
select vds_name, status, non_operational_reason from vds;  # 主机状态（原因码在这里，比翻界面快）
select to_char(log_time,'MM-DD HH24:MI'), message
  from audit_log order by log_time desc limit 30;          # 最近事件

# ---- node 节点 ----
systemctl status vdsmd
tail -f /var/log/vdsm/vdsm.log
journalctl -u vdsmd -n 50
showmount -e

# ---- 主机部署排障（engine 上）----
ls -lt /var/log/ovirt-engine/host-deploy/
grep -nE "fatal:|FAILED" /var/log/ovirt-engine/host-deploy/ovirt-host-deploy-ansible-*.log
</code></pre>
<hr />
<h2>附录 C：特殊情况——Keycloak 过了仍提示 "not authorized to perform login"</h2>
<pre><code>The user admin@internalkeycloak-authz with profile [internalsso] is not authorized to perform login
</code></pre>
<p>说明<strong>认证成功、授权失败</strong>。链路是：</p>
<pre><code>Keycloak 登录 → 引擎 SSO → internalkeycloak-authz 授权域 → 引擎按用户名找用户 → 查 permissions 表里的 SuperUser 授权
</code></pre>
<p><strong>① Keycloak 的 <code>ovirt-internal</code> realm 里有没有 <code>admin</code> 这个用户？</strong>
没有就在 Keycloak 管理控制台（realm 切到 <code>ovirt-internal</code>）→ Users → Add user 建一个 <code>admin</code>，再 Reset password（<strong>Temporary 关掉</strong>）。</p>
<p><strong>② 引擎 <code>permissions</code> 表里有没有对该用户的 SuperUser 授权？</strong></p>
<p><code>admin@internal</code>、<code>admin@ovirt</code>、<code>admin@internalkeycloak-authz</code> 在引擎里是<strong>三条不同的用户记录</strong>，授权不能互相顶替：</p>
<pre><code>select u.username, u.domain, p.role_id, p.ad_element_id
  from permissions p join users u on u.user_id = p.ad_element_id;
</code></pre>
<p>缺 <code>internalkeycloak-authz</code> 域下 <code>admin</code> 的 SuperUser 授权时补一条（SuperUser 角色 ID 固定为 <code>00000000-0000-0000-0000-000000000001</code>，系统级对象 ID <code>aaa00000-0000-0000-0000-123456789aaa</code>）：</p>
<pre><code>insert into permissions (id, role_id, ad_element_id, object_id, object_type_id, creation_date)
select uuid_generate_v4(), '00000000-0000-0000-0000-000000000001', user_id,
       'aaa00000-0000-0000-0000-123456789aaa', 1,
       (extract(epoch from now())*1000)::bigint
  from users
 where domain = 'internalkeycloak-authz' and username = 'admin'
   and not exists (select 1 from permissions p
                    where p.ad_element_id = users.user_id
                      and p.role_id = '00000000-0000-0000-0000-000000000001');
</code></pre>
<blockquote>
<p>权限是实时读取的，<strong>补完直接重登，不用重启引擎</strong>。
注意 <code>users.user_and_domain</code> 是<strong>生成列</strong>（不能直接 UPDATE），<code>creation_date</code> 是 <strong>bigint 毫秒</strong>。</p>
</blockquote>
<hr />
<h2>附录 D：与老流程（CentOS 7 + oVirt 4.3.8）的对照</h2>
<table>
<thead>
<tr>
<th>老流程（CentOS 7 + oVirt 4.3.8）</th>
<th>本文（Rocky 9.5 + oVirt 4.5）</th>
</tr>
</thead>
<tbody>
<tr>
<td>换 163 源、装 <code>ovirt-release43.rpm</code></td>
<td>不动系统源，加 <code>centos-ovirt45.repo</code></td>
</tr>
<tr>
<td><code>yum install ovirt-engine</code></td>
<td><code>dnf install ovirt-engine</code></td>
</tr>
<tr>
<td><code>engine-setup</code>（无 Keycloak）</td>
<td><code>engine-setup</code>（多 Keycloak / WebSocket Proxy 问答）</td>
</tr>
<tr>
<td>装 el7 的 <code>ovirt-node-ng</code> ISO</td>
<td>装 <code>ovirt-node-ng-installer-latest-el9.iso</code>（磁盘 ≥100 GB）</td>
</tr>
<tr>
<td>加主机</td>
<td>加主机，<strong>但必须先做 3.8 节</strong></td>
</tr>
<tr>
<td>node 上 <code>/data/ISO</code>、<code>/data/vm</code> 做 NFS</td>
<td>完全相同（<code>chown 36:36</code>、<code>chmod 755</code>）</td>
</tr>
<tr>
<td>拷贝 ISO 到 <code>&lt;数据中心ID&gt;/images/11111111-...</code></td>
<td>完全相同</td>
</tr>
<tr>
<td>VMware 实验需指定 <code>pc-i440fx-rhel7.2.0</code></td>
<td>完全相同</td>
</tr>
</tbody>
</table>
<hr />
<h2>结语</h2>
<p>按 1 → 9 走完，最终会得到：</p>
<ul>
<li>一台 <strong><code>engine.lab.net</code></strong>（Rocky 9.5）跑着 oVirt Engine 4.5，浏览器打开 <code>https://engine.lab.net/</code> 能进管理门户；</li>
<li>一台 <strong><code>node.lab.net</code></strong>（oVirt Node NG 4.5）作为虚拟化主机，状态是绿色的 <strong>Up</strong>；</li>
<li>数据中心 <code>Default</code> 里挂好 <strong>Data</strong> 和 <strong>ISO</strong> 两个 NFS 存储域，都显示"活跃的"；</li>
<li>一台 <strong>CentOS 7</strong> 虚拟机，从门户创建、装完系统，宿主机能 SSH 连上。</li>
</ul>
<p>整个过程真正容易栽的其实只有三处：<strong>PostgreSQL 装成了 18</strong>（坑 3）、<strong>数据中心/集群的兼容版本被设成 4.8</strong>（3.8 节）、<strong>Node 自带的 <code>onn-sap</code> 死源</strong>（坑 8）。把这三个记住，剩下的照着点就行。</p>
<blockquote>
<p>遇到报错建议直接翻 <strong>附录 A</strong>：那张表按"报错信息 → 真实原因 → 解决"排好了，可以直接按报错关键字搜。</p>
</blockquote>
]]></content>
    <author><name>槿鸢</name></author>
    <category term="虚拟化"/>
  </entry>
  <entry>
    <title>模块C的杂七杂八操作</title>
    <link href="https://blog.ipox.cn/posts/zh-cn/iot-module-c-guide/" rel="alternate" type="text/html"/>
    <id>https://blog.ipox.cn/posts/zh-cn/iot-module-c-guide/</id>
    <published>2026-06-16T00:00:00.000Z</published>
    <updated>2026-06-16T00:00:00.000Z</updated>
    <summary>物联网运维模块C考试喂饭级教程，涵盖虚拟机配置、Docker 环境搭建、Nginx/MySQL 部署、离线部署边缘服务器、Tomcat 安装配置等全部内容。</summary>
    <content type="html"><![CDATA[<h3>喂饭级教程</h3>
<p>&lt;img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/50240AB7E0357254AF69BB5E6495DA41_2026-06-16_200034.webp" alt="zhu" width="150" height="150"&gt;</p>
<hr />
<h2>📑 快速导航</h2>
<table>
<thead>
<tr>
<th>章节</th>
<th>内容</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>基础准备</strong></td>
<td>一、虚拟机导入与网络配置 → 二、系统基础配置（镜像源/主机名/SSH）</td>
</tr>
<tr>
<td><strong>7.2 Docker 环境</strong></td>
<td>三、安装 Docker → 四、拉取镜像 → 五~六、Compose 配置与启动 → 七~九、Nginx/MySQL/客户端连接</td>
</tr>
<tr>
<td><strong>7.3 MySQL</strong></td>
<td>外链教程</td>
</tr>
<tr>
<td><strong>7.4 离线部署</strong></td>
<td>本地安装 Docker + 部署 EdgeServer</td>
</tr>
<tr>
<td><strong>7.5 Web 服务</strong></td>
<td>十、Tomcat 9 → 十一、Nginx（apt + Docker 两种方式）</td>
</tr>
</tbody>
</table>
<hr />
<h1>基础准备部分</h1>
<h2>一、虚拟机导入与网络配置（考试之前准备，对应 7.1）</h2>
<p>在考试之前需要准备一个正常 能使用的系统，但是不能完全按照老师那个7.1来配置</p>
<p>自己安装Ubuntu也行 导入Ubuntu也可以
这里以导入为主 双击牢师给的Ubuntu_pure.ova之后，在虚拟电脑导入设置的 MAC地址设定选择 包含所有网卡的MAC地址
导入完成之后 不要忙着启动虚拟机 先去虚拟机设置里面 点击网络</p>
<p>使用 <strong>NAT + Host-Only</strong> +桥接 三网卡模式配置网络。</p>
<h3>1.1 配置宿主机 Host-Only 网卡</h3>
<p>打开 VirtualBox → <strong>管理</strong> → <strong>网络管理器（Network Manager）</strong>：</p>
<p>旧版 <img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/16057d72e3f055062d230fabea88cf34_2026-06-15_202822.webp" alt="旧版vbox" />
新版
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-15%20202532_2026-06-15_202951.webp" alt="新版vbox" /></p>
<ul>
<li>点击<strong>创建</strong>（或选中已有的 Host-Only 网络） 然后点击属性</li>
<li>勾选<strong>手动配置网卡</strong>，填写：
<ul>
<li>IPv4 地址：<code>192.168.103.11</code>（宿主机在此局域网的 IP）</li>
<li>子网掩码：<code>255.255.255.0</code></li>
</ul>
</li>
<li>点击<strong>应用</strong></li>
</ul>
<h3>1.2 给虚拟机分配三块网卡</h3>
<p>关闭虚拟机，进入 <strong>设置</strong> → <strong>网络</strong>：</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-15%20203059_2026-06-15_203122.webp" alt="nat" /></p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-15%20203103_2026-06-15_203122.webp" alt="仅主机" /></p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-15%20203108_2026-06-15_203122.webp" alt="桥接" /></p>
<table>
<thead>
<tr>
<th>网卡</th>
<th>连接方式</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>网卡1 enp0s3</td>
<td>网络地址转换（NAT）</td>
<td>用于访问外网</td>
</tr>
<tr>
<td>网卡2 enp0s8</td>
<td>仅主机（Host-Only）适配器</td>
<td>用于与宿主机通信，选择刚才配好的那块</td>
</tr>
</tbody>
</table>
<p>网卡3  桥接 enp0s9    备用（用于牢师非要要求你要连上路由器，然后要和路由器ping通什么的，可选 不知道到时候到底怎么考）</p>
<h3>1.3 虚拟机内配置静态 IP</h3>
<p>在搞这个之前再安装个vbox对虚拟机的增强功能，方便剪贴板共享 照着图片点那个安装增强功能。然后虚拟机会有个窗口，运行就行，看到终端最后有Press Return to close this Window。。。就是安装好了，重启虚拟机就行了
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-16%20122802_2026-06-16_122918.webp" alt="zengqiang" /></p>
<p>ok啊兄弟们，临时学个东西，nano编辑器</p>
<p>比vim方便多了，不用记一堆快捷键，改完之后Ctrl+O保存，回车确认，然后Ctrl+X退出，就完事了</p>
<p>那这个时候有人就要问了（你不许问）</p>
<p>改炸了怎么办😭</p>
<p>直接Ctrl+X，它会问你是否保存改动，按n就行，不保存直接跑路</p>
<p>然后我们回到正题
编辑 <code>/etc/network/interfaces</code>：
但是注意需要查看自己实际的网卡情况 在终端先输ip a或者ifconfig</p>
<pre><code>sudo nano /etc/network/interfaces
</code></pre>
<p>写入以下内容：</p>
<pre><code>auto lo
iface lo inet loopback

# NAT 网卡 - 上外网
auto enp0s3
iface enp0s3 inet dhcp

# Host-Only 网卡 - 与宿主机通信
auto enp0s8
iface enp0s8 inet static
address 192.168.103.128
netmask 255.255.255.0

# 桥接网卡 - 与教室路由器通信

#必要时取消注释

#auto enp0s9
#iface enp0s9 inet static
#address 192.168.103.28
#netmask 255.255.255.0
#gateway 192.168.103.1
</code></pre>
<p>这里仅主机网卡ip和桥接不能一样，可以桥接用学号后两位比如我的28 然后仅主机 128 就是加100 然后和宿主机通信优先用仅主机 牢师说要用教室网络连网关这些再搞，没必要搞那么麻烦，甚至桥接网卡这一部分都可以不配置</p>
<p>应用配置怎么搞呢
直接重启虚拟机。</p>
<h3>1.4 验证网络连通性</h3>
<pre><code># 虚拟机内测外网
ping -c 3 8.8.8.8

# 虚拟机 ping 宿主机
ping 192.168.103.11
</code></pre>
<p>如果 <code>ifconfig</code> 不可用，先安装工具：</p>
<pre><code>sudo apt install net-tools
</code></pre>
<hr />
<h2>二、系统基础配置</h2>
<h3>2.1 更换 apt 镜像源</h3>
<p>Ubuntu 默认官方源位于国外，下载速度较慢。这里我们更换为<strong>北京外国语大学（BFSU）</strong> 的国内镜像源，同时<strong>保留了安全更新源</strong>，确保系统漏洞补丁能正常安装。</p>
<p><strong>操作步骤：</strong></p>
<ol>
<li>打开终端（快捷键 <code>Ctrl + Alt + T</code>）。</li>
<li><strong>一次性复制</strong>下方整个代码块，在终端中<strong>鼠标右键点击</strong>（或按 <code>Ctrl + Shift + V</code>）粘贴，然后按 <code>Enter</code> 键运行。</li>
</ol>
<pre><code>sudo tee /etc/apt/sources.list &lt;&lt;'EOF'
deb http://mirrors.bfsu.edu.cn/ubuntu/ bionic main restricted universe multiverse
# deb-src http://mirrors.bfsu.edu.cn/ubuntu/ bionic main restricted universe multiverse

deb http://mirrors.bfsu.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse
# deb-src http://mirrors.bfsu.edu.cn/ubuntu/ bionic-updates main restricted universe multiverse

deb http://mirrors.bfsu.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse
# deb-src http://mirrors.bfsu.edu.cn/ubuntu/ bionic-backports main restricted universe multiverse

deb http://mirrors.bfsu.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
# deb-src http://mirrors.bfsu.edu.cn/ubuntu/ bionic-security main restricted universe multiverse
EOF
</code></pre>
<blockquote>
<p>💡 <strong>这条命令做了什么？</strong><br />
它会直接用上面的内容覆盖掉系统原有的 <code>/etc/apt/sources.list</code> 文件。你不需要手动打开编辑器，也不需要纠结如何保存退出，一条命令全自动完成。</p>
</blockquote>
<h3>2.2 更新系统</h3>
<pre><code>sudo apt update
sudo apt upgrade
</code></pre>
<p>完成后重启虚拟机。</p>
<h3>2.3 更改主机名</h3>
<pre><code>sudo hostnamectl set-hostname 你想改的主机名
</code></pre>
<p>然后 <code>sudo nano /etc/hosts</code> 把127.0.0.1这一行后面的改成你的 我这边改的mukutobi
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-15%20213656_2026-06-15_214408.webp" alt="" />
保存 然后刷新一下终端 <code>exec bash</code></p>
<p>这里也建议重启虚拟机</p>
<h3>2.4 安装配置 Openssh</h3>
<pre><code>sudo apt install openssh-server
</code></pre>
<p>修改ssh配置</p>
<pre><code>sudo nano /etc/ssh/sshd_config
</code></pre>
<p>找到PermitRootLogin prohibit-password 删掉前面的# 取消注释
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-15%20210812_2026-06-15_210829.webp" alt="sshdconfig" />
保存退出</p>
<p>建议检查ssh服务是否正常
先重启服务</p>
<pre><code>systemctl restart ssh
</code></pre>
<p>再检查</p>
<pre><code>systemctl status ssh
</code></pre>
<p>确认有无报错</p>
<p>使用ssh工具连接虚拟机</p>
<p>这边还是用mobaxterm吧，如果想用美观好用的可以下载Tabby
照着图片配置就行 传文件添加sftp</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-15%20211225_2026-06-15_211234.webp" alt="moba" /></p>
<p>什么叫你不知道用户名和密码？</p>
<p>&lt;img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/2A3F2EC7354C72B1D188E11316436FAC_2026-06-15_212728.webp" alt="zhu" width="150" height="150"&gt;</p>
<p>用户名 nle
密码 a12345678</p>
<p>添加完主界面左边列表就有添加好的虚拟机了，双击连接ssh，看到图片这个就成功了
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-15%20213024_2026-06-15_213035.webp" alt="ssh" /></p>
<p>！！！注意，在这一步搞完之后可以复制一份虚拟机备用，防止7.4牢师考试真让本地安装docker</p>
<hr />
<h1>7.2 Docker + Nginx + MySQL 环境搭建 （可以暂时不看）</h1>
<p>主要是看情况到时候到底怎么办的
这段就先不看了吧</p>
<h2>三、安装 Docker</h2>
<p>使用轩辕镜像的一键安装脚本：</p>
<pre><code>bash &lt;(wget -qO- https://xuanyuan.cloud/docker.sh)

#没反应的话这么搞
wget https://xuanyuan.cloud/docker.sh -O docker-install.sh
chmod 777 docker-install.sh
bash docker-install.sh
</code></pre>
<p>执行之后是这样的：</p>
<pre><code>root@074b1042fc62:/# bash &lt;(wget -qO- https://xuanyuan.cloud/docker.sh)
⚠️  未检测到 sudo 命令，将直接使用 root 权限执行命令
==========================================
🐳 欢迎使用轩辕镜像 Docker 一键安装配置脚本
==========================================
官方网站: https://xuanyuan.cloud/

请选择操作模式：
1) 一键安装配置（推荐）
2) 修改轩辕镜像专属域名
3) 恢复 Docker 镜像相关配置

请输入选择 [1/2/3]: 1

&gt;&gt;&gt; 模式：一键安装配置
</code></pre>
<p>选1回车，等它一键配置。
后面可能有 <code>是否继续将 xxx 添加到 docker 组？[Y/n]</code> 这个按 <code>y</code>，以后输docker相关不用su和sudo。</p>
<p>安装完成后验证：</p>
<pre><code>docker --version
</code></pre>
<p>然后这里也建议重启一遍虚拟机</p>
<p>！！！注意，在这一步搞完之后也可以复制一份虚拟机备用，后续可以不用再折腾安装docker浪费时间</p>
<hr />
<h2>四、拉取 Docker 镜像</h2>
<pre><code>docker pull docker.m.daocloud.io/library/nginx:latest
docker pull docker.m.daocloud.io/library/mysql:latest
</code></pre>
<p>实在拉取不了镜像怎么办呢
把命令里面的docker.m.daocloud.io改成docker.xuanyuan.me或者docker.1ms.run  因为镜像站用的人太多可能也会导致拉不下来</p>
<p>拉取完成后查看镜像：</p>
<pre><code>docker images
</code></pre>
<hr />
<h2>五、编写 docker-compose.yml</h2>
<p><strong>Docker Compose</strong> 的配置文件，用于<strong>同时定义和管理多个容器</strong>。简单来说，它让你可以用一个文件启动 Nginx 和 MySQL 两个服务，而不需要分别写两条 <code>docker run</code> 命令。</p>
<pre><code>nano docker-compose.yml
</code></pre>
<p>填入以下内容：</p>
<pre><code>version: '3'

services:
  nginx:
    image: nginx:latest
    ports:
      - "9110:80"

  mysql:
    image: mysql:latest
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: 123456
</code></pre>
<p>保存退出：<code>Ctrl + O</code> → 回车（保存），<code>Ctrl + X</code>（退出）。</p>
<h3>🔍 各字段详解</h3>
<table>
<thead>
<tr>
<th>字段</th>
<th>含义</th>
<th>在本配置中的值/作用</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong><code>version</code></strong></td>
<td>指定 <code>docker-compose.yml</code> 文件格式的版本，决定了可用的语法特性。</td>
<td><code>'3'</code> 是当前最常用的稳定版本。</td>
</tr>
<tr>
<td><strong><code>services</code></strong></td>
<td>定义所有容器的集合。每个子项（如 <code>nginx</code>、<code>mysql</code>）都代表一个独立的容器服务。</td>
<td>下面定义了两个服务。</td>
</tr>
<tr>
<td><strong><code>image</code></strong></td>
<td>指定服务使用的 Docker 镜像。Docker Compose 会自动从配置的镜像源（如 Docker Hub）拉取。</td>
<td><code>nginx:latest</code> 和 <code>mysql:latest</code></td>
</tr>
<tr>
<td><strong><code>ports</code></strong></td>
<td>实现<strong>端口映射</strong>，将宿主机的端口映射到容器内部的端口。格式为 <code>"宿主机端口:容器端口"</code>。</td>
<td>访问 <code>http://宿主机IP:9110</code> 即可访问 Nginx 服务。 <strong>注意</strong>：将 MySQL 的 <code>3306</code> 端口直接映射到宿主机存在一定安全隐患。</td>
</tr>
<tr>
<td><strong><code>environment</code></strong></td>
<td>设置容器运行时的<strong>环境变量</strong>，常用于向容器传递配置信息，如数据库密码、用户名等。</td>
<td><code>MYSQL_ROOT_PASSWORD: 123456</code> 是 MySQL 官方镜像要求的必要变量，用于设置 root 用户的密码。</td>
</tr>
</tbody>
</table>
<hr />
<h2>六、一键启动容器</h2>
<pre><code>docker compose up -d
</code></pre>
<p>以后每次启动只需执行这一条命令。容器名通常为 <code>&lt;当前目录&gt;-mysql-1</code> 和 <code>&lt;当前目录&gt;-nginx-1</code>，可用 <code>docker ps</code> 查看。</p>
<hr />
<h2>七、配置 Nginx</h2>
<h3>7.1 进入 Nginx 容器</h3>
<pre><code># 先查看容器名
docker ps
# 找到 Nginx 容器的 NAME 列，应该是nle-nginx-1
# 然后用下面的命令进入（把 容器名 替换成实际看到的）
docker exec -it 容器名 /bin/bash
</code></pre>
<h3>7.2 修改默认网页</h3>
<pre><code>echo "Hello Docker" &gt; /usr/share/nginx/html/index.html
</code></pre>
<h3>7.3 测试访问</h3>
<p>浏览器打开 <code>虚拟机IP:9110</code>（例如 <code>http://192.168.103.128:9110</code>），看到修改后的页面即成功。</p>
<hr />
<h2>八、配置 MySQL</h2>
<h3>8.1 进入 MySQL 容器</h3>
<pre><code>docker exec -it &lt;mysql容器名&gt; /bin/bash
</code></pre>
<h3>8.2 登录 MySQL</h3>
<pre><code>mysql -uroot -p
</code></pre>
<p>输入密码 <code>123456</code>（docker-compose 中设置的）。</p>
<h3>8.3 创建数据库</h3>
<pre><code>CREATE DATABASE test;
USE test;
</code></pre>
<hr />
<h2>九、客户端连接数据库</h2>
<p>推荐使用 <strong>DBeaver</strong>（免费开源）连接：</p>
<p><a href="https://dbeaver.io/download/">Download | DBeaver Community</a></p>
<table>
<thead>
<tr>
<th>参数</th>
<th>值</th>
</tr>
</thead>
<tbody>
<tr>
<td>Host</td>
<td>虚拟机IP（<code>192.168.103.128</code>）</td>
</tr>
<tr>
<td>Port</td>
<td><code>3306</code></td>
</tr>
<tr>
<td>User</td>
<td><code>root</code></td>
</tr>
<tr>
<td>Password</td>
<td><code>123456</code></td>
</tr>
</tbody>
</table>
<h3>解决报错：Public Key Retrieval is not allowed</h3>
<p>在 DBeaver 中编辑当前 MySQL 连接，切换到<strong>驱动属性</strong>标签页，修改以下参数：</p>
<table>
<thead>
<tr>
<th>参数名</th>
<th>填写值</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>allowPublicKeyRetrieval</code></td>
<td><code>TRUE</code></td>
</tr>
<tr>
<td><code>useSSL</code></td>
<td><code>FALSE</code></td>
</tr>
</tbody>
</table>
<p>保存后再次测试连接即可成功。</p>
<hr />
<h1>7.3 搭建 MySQL 服务器（搭建数据服务器）</h1>
<p>直接看我之前写的：<a href="https://blog.ipox.cn/posts/zh-cn/mysql-setup/">搭建 MySQL 服务器 - 槿鸢茶屋</a></p>
<hr />
<h1>7.4 离线部署边缘服务器 （可以暂时不看）</h1>
<p>主要是看情况到时候到底怎么办的
这段就先不看了吧</p>
<p>不要看她那个破烂教程了，还要本地安装docker，，，劳神费力，前面本来不是已经装了docker吗，现在再按照她的本地安装的话就得把之前装好的删掉，很麻烦，如果真的要这么搞，，，，，那我没招了 怎么这么烦啊</p>
<p>如果说到时候非要什么本地安装docker的截图，，，那就先照着这个做
这个时候就需要准备我在前面提过的，安装docker之前让复制的虚拟机</p>
<p>去学习通下载好应用部署文件夹里面的边缘服务.rar
打开压缩包，把里面的docker&amp;docker-compose.zip和NLE_EdgeServer.1.1.3.zip都解压成文件夹，然后用mobaxterm给虚拟机传过去</p>
<h3>第一步：在Windows上准备文件</h3>
<p>在学习通下载的<code>边缘服务.rar</code>，解压后应该包含两个压缩包。这里的关键是<strong>解压方式</strong>：</p>
<ol>
<li>
<p><strong>解压 <code>边缘服务.rar</code></strong>：用WinRAR或7-Zip解压，得到<code>docker&amp;docker-compose.zip</code>和<code>NLE_EdgeServer.1.1.3.zip</code>。</p>
</li>
<li>
<p><strong>关键一步：解压这两个zip文件，而不是直接传压缩包</strong>。</p>
<ul>
<li>分别右键解压<code>docker&amp;docker-compose.zip</code>和<code>NLE_EdgeServer.1.1.3.zip</code>，得到两个<strong>文件夹</strong>。文件夹名大概率就是<code>docker&amp;docker-compose</code>和<code>NLE_EdgeServer.1.1.3</code>。</li>
</ul>
</li>
<li>
<p><strong>记住文件位置</strong>：记住这两个文件夹在Windows上的路径（比如在桌面或下载文件夹里），下一步要用到。</p>
</li>
</ol>
<p><strong>为什么要解压成文件夹再传？</strong>
因为你的虚拟机上可能没有安装<code>unzip</code>命令。传文件夹可以确保文件直接可用，避免了在虚拟机里解压失败的风险。</p>
<hr />
<h3>📡 第二步：用MobaXterm传输文件夹（关键操作步骤）</h3>
<p>你的思路是对的，但新手容易在MobaXterm的操作上疑惑。以下是具体步骤：</p>
<ol>
<li>
<p><strong>打开MobaXterm并连接到虚拟机</strong>。</p>
<ul>
<li>启动MobaXterm，点击顶部工具栏的 <strong>Session</strong>。</li>
<li>在弹出的窗口中选择 <strong>SSH</strong>。</li>
<li>在 <strong>Remote host</strong> 输入你虚拟机的IP地址（比如<code>192.168.103.128</code>）。</li>
<li>勾选 <strong>Specify username</strong>，输入你的用户名（比如<code>nle</code>）。</li>
<li>点击 <strong>OK</strong>，然后输入密码登录。</li>
</ul>
</li>
<li>
<p><strong>传输文件夹（两种方式均可）</strong>：</p>
<ul>
<li>
<p><strong>方法一：直接拖拽（最推荐）</strong></p>
<ul>
<li>登录后，你会看到MobaXterm的界面分成左右两栏。<strong>左侧是你虚拟机的文件浏览器</strong>，右侧是虚拟机的ssh终端。
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-16%20143134_2026-06-16_143156.webp" alt="" /></li>
<li>在右侧找到你刚才解压好的两个文件夹（<code>docker&amp;docker-compose</code>和<code>NLE_EdgeServer.1.1.3</code>）。</li>
<li><strong>直接用鼠标左键按住文件夹，拖拽到左侧的虚拟机文件列表区域（比如<code>/home/nle/</code>目录下，最好在这里）</strong>。MobaXterm会自动开始传输。</li>
</ul>
</li>
<li>
<p><strong>方法二：使用SFTP面板</strong></p>
<ul>
<li>如果拖拽不习惯，在MobaXterm的侧边栏中，找到并点击 <strong>SFTP</strong> 标签页（通常在左侧边栏下方）。</li>
<li>这会打开一个专门的文件传输面板。在SFTP面板的本地区域，导航到你的文件夹，右键选择 <strong>Upload</strong> 上传到虚拟机当前目录。</li>
</ul>
</li>
</ul>
</li>
<li>
<p><strong>验证文件是否传输成功</strong>：
传输完成后，在MobaXterm的右侧（虚拟机终端）输入：</p>
<pre><code>ls -l
</code></pre>
<p>你应该能看到<code>docker&amp;docker-compose</code>和<code>NLE_EdgeServer.1.1.3</code>这两个文件夹的列表。</p>
</li>
</ol>
<h3>第三步：确认文件位置</h3>
<pre><code># 查看 home 目录下的文件
ls /home/nle/
# 应该能看到这两个文件夹：
# docker&amp;docker-compose/  和  NLE_EdgeServer.1.1.3/
</code></pre>
<hr />
<h3>🚀 第二部分：安装 Docker CE（安装包在 <code>docker&amp;docker-compose</code> 里）</h3>
<p><strong>1. 进入安装包所在路径</strong></p>
<pre><code>cd "docker&amp;docker-compose/docker&amp;docker-compose/"
</code></pre>
<p><strong>2. 确认 <code>.deb</code> 文件存在</strong></p>
<pre><code>ls -l *.deb
</code></pre>
<p>应该能看到三个 <code>.deb</code> 文件。</p>
<p><strong>3. 按顺序安装三个 deb 包（顺序不能错！）</strong></p>
<pre><code># ① 先安装 containerd（容器运行时）
sudo dpkg -i containerd.io_1.2.6-3_amd64.deb
# ② 再安装 Docker CLI（命令行工具）
sudo dpkg -i docker-ce-cli_19.03.8_3-0_ubuntu-bionic_amd64.deb
# ③ 最后安装 Docker CE（核心引擎）
sudo dpkg -i docker-ce_19.03.8_3-0_ubuntu-bionic_amd64.deb
</code></pre>
<blockquote>
<p><strong>⚠️ 注意</strong>：如果文件名和上面的不完全一样，以实际文件名为准。输入时可以按 <code>Tab</code> 键自动补全。</p>
</blockquote>
<p><strong>4. 查看 Docker 版本</strong></p>
<pre><code>docker -v
</code></pre>
<p>看到 <code>Docker version 19.03.8</code> 就说明安装成功。</p>
<p><strong>5. 启动 Docker 服务</strong></p>
<pre><code>sudo systemctl enable docker
sudo systemctl start docker
</code></pre>
<p><strong>6. 配置镜像加速器</strong></p>
<p>如果你有老师给的 <code>daemon.json</code> 文件，用 MobaXterm 拖到 <code>/home/nle/</code> 目录，然后执行：</p>
<pre><code>sudo cp /home/nle/daemon.json /etc/docker/
</code></pre>
<p>如果没有这个文件，手动创建一个：</p>
<pre><code>sudo nano /etc/docker/daemon.json
</code></pre>
<p>粘贴以下内容：</p>
<pre><code>{
  "registry-mirrors": ["https://docker.m.daocloud.io"]
}
</code></pre>
<p>按 <code>Ctrl+O</code> 保存，<code>Ctrl+X</code> 退出。</p>
<p><strong>7. 重启 Docker 使配置生效</strong></p>
<pre><code>sudo systemctl daemon-reload
sudo systemctl restart docker
</code></pre>
<hr />
<h3>🐳 第三部分：安装 Docker Compose（文件也在 <code>docker&amp;docker-compose</code> 里）</h3>
<p><strong>1. 确认 <code>docker-compose</code> 文件存在</strong></p>
<pre><code>ls -l /home/nle/docker&amp;docker-compose/docker&amp;docker-compose/docker-compose
</code></pre>
<p><strong>2. 复制文件到系统路径</strong></p>
<pre><code>sudo cp /home/nle/docker&amp;docker-compose/docker&amp;docker-compose/docker-compose /usr/local/bin/
sudo chmod +x /usr/local/bin/docker-compose
</code></pre>
<p><strong>3. 验证安装</strong></p>
<pre><code>docker-compose --version
</code></pre>
<p>看到版本号就说明安装成功。</p>
<hr />
<h3>🧩 第四部分：部署 EdgeServer 应用（在 <code>NLE_EdgeServer.1.1.3</code> 里）</h3>
<p><strong>1. 进入 EdgeServer 目录</strong></p>
<pre><code>cd /home/nle/NLE_EdgeServer.1.1.3/NLE_EdgeServer/
</code></pre>
<p>然后看情况原文档的14 15 16需不需要改</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-16%20144814_2026-06-16_144929.webp" alt="appsetting" /></p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-16%20144821_2026-06-16_144929.webp" alt="nginxconfpic" /></p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-16%20144859_2026-06-16_144929.webp" alt="packagejson" /></p>
<h4>17 启动边缘服务容器</h4>
<pre><code>sudo docker-compose up -d
</code></pre>
<blockquote>
<p><strong>💡 注意</strong>：这里用的是 <code>docker-compose</code>（带横杠），因为 7.4 离线安装的 Docker 版本较低（19.03），Compose 是单独安装的旧版二进制文件。而 7.2 中用的 <code>docker compose</code>（不带横杠）是新版 Docker 自带的子命令。两种写法对应不同版本，不要搞混。</p>
</blockquote>
<p>然后会这样，不过不影响，继续
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-16%20145322_2026-06-16_145344.webp" alt="启动报错" />
按照她的说法改网关和云平台
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-16%20145334_2026-06-16_145344.webp" alt="云平台" />
应该17之后就不用操作了，那么多人都操作没那么多网关，真这么搞那她真神了
到此7.4的离线部署边缘服务器就完事了</p>
<hr />
<h1>7.5 Web 服务构架搭建</h1>
<h2>十、Tomcat 9 安装配置教程 🐱</h2>
<p>Tomcat 是一个 <strong>Application Server（应用服务器）</strong>，主要用于运行 Java Web 应用程序。下面是在 Ubuntu 系统上安装配置 Tomcat 9 的完整步骤。</p>
<hr />
<h3>📥 第一部分：安装 Tomcat 9</h3>
<p><strong>1. 更新软件包列表</strong></p>
<pre><code>sudo apt update
</code></pre>
<p>这一步会刷新本地的软件包索引，确保能安装到最新版本的软件。</p>
<p><strong>2. 安装 Tomcat 9 和管理界面</strong></p>
<pre><code>sudo apt install tomcat9 tomcat9-admin -y
</code></pre>
<ul>
<li><code>tomcat9</code>：Tomcat 核心程序</li>
<li><code>tomcat9-admin</code>：Tomcat 的管理界面（用于部署和管理应用）</li>
<li><code>-y</code>：自动确认安装，不用手动输入 Y</li>
</ul>
<p><strong>3. 查看 Tomcat 监听的端口</strong></p>
<pre><code>ss -ltn
</code></pre>
<p>Tomcat 默认监听 <strong>8080</strong> 端口。<code>ss -ltn</code> 命令会列出所有监听的 TCP 端口，你可以看到 <code>:8080</code> 在列表中。</p>
<p><strong>4. 设置 Tomcat 开机自启</strong></p>
<pre><code>sudo systemctl enable tomcat9
</code></pre>
<p>这样虚拟机重启后 Tomcat 会自动启动，不用每次手动开启。</p>
<p><strong>5. 开放防火墙 8080 端口</strong></p>
<pre><code>sudo ufw allow from any to any port 8080 proto tcp
</code></pre>
<p><strong>6. 启动 Tomcat 服务</strong></p>
<pre><code>sudo systemctl start tomcat9
</code></pre>
<p><strong>7. 验证 Tomcat 是否正常运行</strong></p>
<pre><code>sudo systemctl status tomcat9
</code></pre>
<p>看到 <code>active (running)</code> 就说明启动成功。</p>
<p><strong>8. 浏览器访问测试</strong></p>
<p>在宿主机的浏览器打开（首选）</p>
<pre><code>http://虚拟机ip:8080
</code></pre>
<p>也可以在虚拟机内的浏览器地址栏输入：</p>
<pre><code>http://本机IP:8080
</code></pre>
<p>或者</p>
<pre><code>http://127.0.0.1:8080
</code></pre>
<p>如果能看到 Tomcat 的默认欢迎页面，说明安装成功了。
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-11%20090224_2026-06-16_150640.webp" alt="tomcat欢迎" /></p>
<hr />
<h3>⚙️ 第二部分：配置 Tomcat 管理员用户</h3>
<p>默认情况下，Tomcat 的管理界面需要用户名和密码才能登录。需要手动配置一个管理员账号。</p>
<p><strong>1. 查看当前配置文件（可选）</strong></p>
<pre><code>sudo cat /etc/tomcat9/tomcat-users.xml
</code></pre>
<p>可以先看一下默认配置长什么样。</p>
<p><strong>2. 编辑配置文件</strong></p>
<pre><code>sudo nano /etc/tomcat9/tomcat-users.xml
</code></pre>
<p><strong>3. 在最下面修改以下内容：</strong>
就是修改我图片框好的这一部分，可以全删了然后粘贴下面那个代码块
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/4a2b259d5ef29a51a73e3f42ec3264d2_2026-06-16_151433.webp" alt="原配置" /></p>
<pre><code>  &lt;role rolename="tomcat"/&gt;
  &lt;role rolename="role1"/&gt;
  &lt;role rolename="admin-gui"/&gt;
  &lt;role rolename="manager-gui"/&gt;

  &lt;user username="tomcat" password="tomcat" roles="admin-gui,manager-gui"/&gt;
  &lt;user username="both" password="both123" roles="tomcat,role1"/&gt;
  &lt;user username="role1" password="role1123" roles="role1"/&gt;
&lt;/tomcat-users&gt;
</code></pre>
<p>添加后的效果大概是这样的：
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-16%20150800_2026-06-16_150843.webp" alt="tomcat配置效果" /></p>
<p><strong>4. 重启 Tomcat 使配置生效</strong></p>
<pre><code>sudo systemctl restart tomcat9
</code></pre>
<p><strong>5. 访问管理界面</strong></p>
<p>在宿主机的浏览器打开（首选）</p>
<pre><code>http://虚拟机ip:8080/manager/html
</code></pre>
<p>也可以在虚拟机内的浏览器地址栏输入：</p>
<pre><code>http://本机IP:8080/manager/html
</code></pre>
<p>登录账号：</p>
<ul>
<li>用户名：<code>tomcat</code></li>
<li>密码：<code>tomcat</code></li>
</ul>
<p>成功登录后，就可以在 Web 界面上传和管理Tomcat了。
<img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-11%20090840_2026-06-16_151843.webp" alt="界面" /></p>
<hr />
<h3>🔍 第三部分：查看 Tomcat 版本信息</h3>
<p><strong>1. 查找 Tomcat 进程</strong></p>
<pre><code>ps aux | grep tomcat
</code></pre>
<p>输出中会显示 Tomcat 的安装路径，例如 <code>/usr/share/tomcat9/</code>。</p>
<p><strong>2. 切换到 Tomcat 的 bin 目录</strong></p>
<pre><code>cd /usr/share/tomcat9/bin
</code></pre>
<blockquote>
<p><strong>💡 路径说明</strong>：用 <code>ps aux | grep tomcat</code> 查到的路径可能不完全一样，也可能是 <code>/usr/lib/tomcat9/bin</code>。以实际输出为准。</p>
</blockquote>
<p><strong>3. 执行版本查看脚本</strong></p>
<pre><code>./version.sh
</code></pre>
<p>输出中的 <strong>Server number</strong> 就是 Tomcat 的版本号，例如 <code>9.0.xx</code>。</p>
<hr />
<h2>十一、Nginx 安装配置教程 🌐</h2>
<p>下面包含两种安装方式（apt 安装和 Docker 安装），根据考试要求选择对应的方式操作。</p>
<p>Nginx 是一款高性能的 HTTP 和反向代理 Web 服务器，支持高并发和负载均衡，以稳定性、丰富的功能集和低系统资源消耗而闻名。</p>
<hr />
<h3>📦 第一部分：通过 apt 方式安装 Nginx（传统安装）</h3>
<p><strong>1. 安装 Nginx</strong></p>
<pre><code>sudo apt update
sudo apt install nginx -y
</code></pre>
<p><strong>2. 查看 Nginx 进程</strong></p>
<pre><code>ps -ef | grep nginx
</code></pre>
<p>会看到 master process 和 worker process，说明 Nginx 正在运行。</p>
<p><strong>3. 查看 Nginx 服务状态</strong></p>
<pre><code>sudo systemctl status nginx
</code></pre>
<p><strong>4. 浏览器访问测试</strong></p>
<p>在浏览器中输入：</p>
<pre><code>http://虚拟机IP
</code></pre>
<p>看到 Nginx 默认欢迎页面就说明安装成功。</p>
<hr />
<h3>✏️ 第二部分：自定义 Nginx 默认首页（apt 安装方式）</h3>
<p>Nginx 的默认站点根目录是 <code>/var/www/html/</code>。</p>
<p><strong>第一步：将默认首页文件重命名为标准名称</strong></p>
<pre><code>sudo mv /var/www/html/index.nginx-debian.html /var/www/html/index.html
</code></pre>
<p><strong>第二步：编辑首页文件</strong></p>
<pre><code>sudo nano /var/www/html/index.html
</code></pre>
<p><strong>第三步：粘贴以下 HTML 内容（根据个人信息修改）</strong></p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;title&gt;IOT Server - 考生姓名拼音&lt;/title&gt;
    &lt;style&gt;
        body { background: #1a1a2e; color: #eee; text-align: center; padding: 50px; font-family: Arial; }
        h1 { color: #00d4ff; font-size: 36px; }
        .box { background: #16213e; padding: 30px; border-radius: 15px; margin: 20px auto; width: 500px; }
        .info { text-align: left; font-size: 16px; line-height: 1.8; }
        .pass { color: #4CAF50; font-size: 20px; margin-top: 20px; }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class="box"&gt;
        &lt;h1&gt;🌍 Welcome The World of IOT !&lt;/h1&gt;
        &lt;h2&gt;🏆 考生姓名拼音 IOT Test 🏆&lt;/h2&gt;
        &lt;div class="info"&gt;
            &lt;p&gt;📌 姓名：张三&lt;br&gt;
            📌 学号：202402952&lt;br&gt;
            📌 主机名：zhangsan-vm&lt;br&gt;
            📌 IP地址：192.168.103.128&lt;br&gt;
            📌 服务端口：80&lt;br&gt;
            📌 测试时间：2026-06-16&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class="pass"&gt;✅ Nginx 配置成功 | IOT 边缘服务已部署&lt;/div&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<blockquote>
<p><strong>⚠️ 需要修改的内容</strong>：</p>
<ul>
<li>姓名</li>
<li>学号</li>
<li>主机名（用 <code>hostname</code> 命令查看）</li>
<li>IP地址（用 <code>ip a</code> 命令查看）</li>
<li>测试时间</li>
</ul>
</blockquote>
<p><strong>第四步：保存退出</strong></p>
<ul>
<li><code>Ctrl+O</code> → 回车（保存）</li>
<li><code>Ctrl+X</code>（退出）</li>
</ul>
<p><strong>第五步：刷新浏览器验证</strong>
<strong>修改完成后刷新浏览器页面即可看到变化，无需重启 Nginx。</strong></p>
<hr />
<h3>🐳 第三部分：Docker 安装与 Nginx 部署</h3>
<p>本部分将带你<strong>从零开始安装 Docker</strong>，然后通过 Docker 部署一个 Nginx 容器，并暴露端口供外部访问。</p>
<hr />
<h4>1. 安装 Docker</h4>
<p>使用轩辕镜像提供的一键安装脚本：</p>
<pre><code>bash &lt;(wget -qO- https://xuanyuan.cloud/docker.sh)
</code></pre>
<p><strong>如果上面的命令没反应</strong>，可以分步执行：</p>
<pre><code>wget https://xuanyuan.cloud/docker.sh -O docker-install.sh
chmod 777 docker-install.sh
bash docker-install.sh
</code></pre>
<p>执行后会看到如下交互界面：</p>
<pre><code>root@074b1042fc62:/# bash &lt;(wget -qO- https://xuanyuan.cloud/docker.sh)
⚠️  未检测到 sudo 命令，将直接使用 root 权限执行命令
==========================================
🐳 欢迎使用轩辕镜像 Docker 一键安装配置脚本
==========================================
官方网站: https://xuanyuan.cloud/

请选择操作模式：
1) 一键安装配置（推荐）
2) 修改轩辕镜像专属域名
3) 恢复 Docker 镜像相关配置

请输入选择 [1/2/3]: 1

&gt;&gt;&gt; 模式：一键安装配置
</code></pre>
<p>输入 <code>1</code> 然后回车，等待脚本自动完成安装。</p>
<p>安装过程中可能会出现提示：</p>
<pre><code>是否继续将 xxx 添加到 docker 组？[Y/n]
</code></pre>
<p>这里输入 <code>y</code> 并回车。添加后，以后执行 Docker 命令就不需要每次都加 <code>sudo</code> 了。</p>
<hr />
<h4>2. 验证 Docker 安装</h4>
<pre><code>docker --version
</code></pre>
<p>如果正常显示版本号（如 <code>Docker version 24.x.x</code>），说明安装成功。</p>
<hr />
<h4>3. 重启虚拟机（建议）</h4>
<p>安装完 Docker 后，建议重启一次虚拟机以确保所有配置生效：</p>
<pre><code>sudo reboot
</code></pre>
<p>重启后重新登录，继续后续操作。</p>
<hr />
<h4>4. 拉取 Nginx 镜像</h4>
<pre><code>docker pull docker.m.daocloud.io/library/nginx:latest
</code></pre>
<blockquote>
<p>⚠️ <strong>如果拉取失败</strong>：把命令中的 <code>docker.m.daocloud.io</code> 换成 <code>docker.xuanyuan.me</code> 或 <code>docker.1ms.run</code>（镜像站用的人太多可能会限流）。</p>
</blockquote>
<p>拉取完成后查看镜像确认：</p>
<pre><code>docker images
</code></pre>
<p>应该能看到 <code>nginx</code> 镜像出现在列表中。</p>
<hr />
<h4>5. 运行 Nginx 容器</h4>
<pre><code># 运行 Nginx 容器，映射宿主机 9110 端口到容器 80 端口
docker run -d -p 9110:80 --name nle-nginx-1 nginx:latest
</code></pre>
<p><strong>参数说明：</strong></p>
<table>
<thead>
<tr>
<th>参数</th>
<th>含义</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>-d</code></td>
<td>后台运行（守护模式）</td>
</tr>
<tr>
<td><code>-p 9110:80</code></td>
<td>将宿主机的 9110 端口映射到容器内的 80 端口</td>
</tr>
<tr>
<td><code>--name nle-nginx-1</code></td>
<td>给容器起名为 <code>nle-nginx-1</code></td>
</tr>
</tbody>
</table>
<blockquote>
<p>💡 <strong>端口说明</strong>：如果 9110 端口被占用，可以改成其他端口，如 <code>8080</code>、<code>8888</code> 等，相应地访问时也使用对应的端口号。</p>
</blockquote>
<hr />
<h4>6. 验证容器是否正常运行</h4>
<pre><code># 查看运行中的容器
docker ps
</code></pre>
<p>如果看到 <code>nle-nginx-1</code> 的状态是 <code>Up</code>，说明启动成功。</p>
<p><strong>测试访问：</strong> 在浏览器中输入 <code>http://你的服务器IP:9110</code>，如果看到 Nginx 欢迎页面，就说明一切正常 🎉</p>
<hr />
<h3>✏️ 第四部分：自定义 Nginx 首页（Docker 方式）</h3>
<p><strong>1. 在宿主机创建 HTML 文件</strong></p>
<p>在宿主机创建一个 HTML 文件，比如 <code>/home/nle/mypage.html</code>：</p>
<pre><code>nano /home/nle/mypage.html
</code></pre>
<p><strong>内容如下（根据个人信息修改）：</strong></p>
<pre><code>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
    &lt;meta charset="UTF-8"&gt;
    &lt;title&gt;IOT Server - 考生姓名拼音&lt;/title&gt;
    &lt;style&gt;
        body { background: #1a1a2e; color: #eee; text-align: center; padding: 50px; font-family: Arial; }
        h1 { color: #00d4ff; font-size: 36px; }
        .box { background: #16213e; padding: 30px; border-radius: 15px; margin: 20px auto; width: 500px; }
        .info { text-align: left; font-size: 16px; line-height: 1.8; }
        .pass { color: #4CAF50; font-size: 20px; margin-top: 20px; }
    &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;div class="box"&gt;
        &lt;h1&gt;🌍 Welcome The World of IOT !&lt;/h1&gt;
        &lt;h2&gt;🏆 考生姓名拼音 IOT Test 🏆&lt;/h2&gt;
        &lt;div class="info"&gt;
            &lt;p&gt;📌 姓名：张三&lt;br&gt;
            📌 学号：202402952&lt;br&gt;
            📌 主机名：zhangsan-vm&lt;br&gt;
            📌 IP地址：192.168.103.128&lt;br&gt;
            📌 服务端口：9110&lt;br&gt;
            📌 容器名称：nle-nginx-1&lt;br&gt;
            📌 测试时间：2026-06-16&lt;/p&gt;
        &lt;/div&gt;
        &lt;div class="pass"&gt;✅ Nginx 配置成功 | Docker 运行正常 | IOT 边缘服务已部署&lt;/div&gt;
    &lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>
<blockquote>
<p><strong>⚠️ 需要修改的内容</strong>：</p>
<ul>
<li>姓名</li>
<li>学号</li>
<li>主机名</li>
<li>IP地址（改为虚拟机的实际 IP）</li>
<li>服务端口（改为实际映射的端口）</li>
<li>测试时间</li>
</ul>
</blockquote>
<p><strong>2. 将 HTML 文件复制到容器内</strong></p>
<pre><code>docker cp /home/nle/mypage.html nle-nginx-1:/usr/share/nginx/html/index.html
</code></pre>
<p><strong>3. 验证文件是否复制成功</strong></p>
<pre><code>docker exec nle-nginx-1 cat /usr/share/nginx/html/index.html | head -5
</code></pre>
<p>能看到 HTML 文件的前 5 行就说明复制成功了。
<strong>4. 宿主机浏览器访问</strong></p>
<p>在这之前先重启一下容器,防止网页虽然改了但是没反应</p>
<pre><code>docker restart nle-nginx-1
</code></pre>
<p>在宿主机或虚拟机浏览器的地址栏输入：</p>
<pre><code>http://虚拟机IP:9110
</code></pre>
<p>例如：</p>
<pre><code>http://192.168.103.128:9110
</code></pre>
<hr />
<h3>🔧 第五部分：常用管理命令</h3>
<p><strong>Nginx 服务管理（apt 安装方式）</strong></p>
<pre><code># 启动 Nginx
sudo systemctl start nginx

# 停止 Nginx
sudo systemctl stop nginx

# 重启 Nginx
sudo systemctl restart nginx

# 重新加载配置（不中断服务）
sudo systemctl reload nginx

# 查看 Nginx 状态
sudo systemctl status nginx
</code></pre>
<p><strong>Docker 容器管理（Docker 安装方式）</strong></p>
<pre><code># 查看容器
docker ps

# 停止容器
docker stop nle-nginx-1

# 启动容器
docker start nle-nginx-1

# 重启容器
docker restart nle-nginx-1

# 删除容器
docker rm -f nle-nginx-1
</code></pre>
<hr />
<p>到此就结束了，希望大家都能考试顺利</p>
]]></content>
    <author><name>槿鸢</name></author>
    <category term="物联网运维"/>
  </entry>
  <entry>
    <title>模块B的杂七杂八操作</title>
    <link href="https://blog.ipox.cn/posts/zh-cn/iot-module-b/" rel="alternate" type="text/html"/>
    <id>https://blog.ipox.cn/posts/zh-cn/iot-module-b/</id>
    <published>2026-06-12T20:30:00.000Z</published>
    <updated>2026-06-12T20:30:00.000Z</updated>
    <summary></summary>
    <content type="html"><![CDATA[<h2>前置知识</h2>
<h3>设备配置通用套路</h3>
<p>配置设备基本上都要单独设置电脑的ip，比如网关可以设置ip <code>192.168.1.10</code>，子网掩码 <code>255.255.255.0</code>，默认网关 <code>192.168.1.1</code>，dns可以顺手也设置 <code>192.168.1.1</code>，主要是同网段。</p>
<hr />
<h3>各设备基本信息</h3>
<p><strong>路由器</strong>：<code>192.168.0.1</code>，不需要登录，要密码就是 <code>12345678</code>，重置按复位键15秒。备注说要配静态IP，这个应该是要手动改IP的。</p>
<p><strong>PC机</strong>：密码 <code>a12345678</code>，没别的特殊配置。</p>
<p><strong>物联网网关</strong>：<code>192.168.1.100</code>，用户名密码都是 <code>newland</code>。重置方法比较特殊，要短接DIO和GND。首用需要鉴权，这个要注意。</p>
<p><strong>串口服务器</strong>：<code>192.168.14.200</code>，用户名 <code>root</code>，密码两个可能 <code>002396</code> 或 <code>000997</code>。端口 <code>8400</code>。重置按RST键15到20秒。</p>
<p><strong>无线采集器4012</strong>：<code>192.168.1.1</code>，密码8个0。端口 <code>502</code>。重置要拨码开关。</p>
<hr />
<h3>4012配置流程</h3>
<p>插上无线网卡</p>
<ol>
<li>把拨码开关P1拨到off，重新上电，进入初始配置模式</li>
<li>电脑连上设备的热点 <code>WISE-4012E_xxxxx</code></li>
<li>浏览器打开 <code>192.168.1.1</code>，用户名 <code>root</code>，密码8个0</li>
<li>进 Configuration - Wireless：
<ul>
<li>WLAN Mode选 <code>Infrastructure Mode</code></li>
<li>SSID填你要连的WiFi名字</li>
<li>Security Type选 <code>WPA/WPA2</code></li>
<li>Security Key填WiFi密码</li>
</ul>
</li>
<li>IP设置：
<ul>
<li>IP Mode选 <code>Static</code></li>
<li>IP填你要分配的地址，比如 <code>192.168.2.6</code></li>
<li>子网掩码 <code>255.255.255.0</code></li>
<li>网关填路由器地址，比如 <code>192.168.2.1</code></li>
</ul>
</li>
<li>点Submit保存</li>
<li>把拨码开关P1拨回on，再重新上电设备重启生效</li>
</ol>
<hr />
<h3>Zigbee配置流程</h3>
<p>Zigbee是无线通信模块，要保证通道和网络ID一致才能通信。</p>
<p>简单说就是：</p>
<ol>
<li>打开桌面上的 <code>ZigBeeConfigTool</code></li>
<li>打开软件，选串口号，点打开串口</li>
<li>设备类型选 <code>Coordinator</code> 或 <code>Router</code></li>
<li>PAN ID和通道两边要设成一样的，比如PAN ID都填 <code>C002</code>，通道 <code>1x</code>（x是你的工位）</li>
<li>设备ID协调器填 <code>0000</code>，路由器填 <code>0001</code></li>
<li>点设置保存</li>
</ol>
<hr />
<h3>传感器地址汇总</h3>
<p>温湿度传感器地址（01）、光照传感器地址（02）、CO2传感器地址（03）、RGB控制器地址（04）。ADAM4150地址为1(hex)</p>
<hr />
<h2>一、局域网配置</h2>
<h3>截图1：路由器配置</h3>
<p>先重置路由器</p>
<ol>
<li>打开浏览器，输入 <code>192.168.0.1</code></li>
<li>输入路由器账号密码登录</li>
<li>找到 <strong>LAN口设置</strong> 或 <strong>网络参数 → LAN口设置</strong></li>
<li>确认/修改IP地址为 <code>192.168.X.1</code>（X为你的工位号，如第8组就是<code>192.168.8.1</code>）</li>
<li>截图保存为 <strong>截图1</strong></li>
</ol>
<hr />
<h3>截图2：PC机配置</h3>
<ol>
<li>按 <code>Win + R</code>，输入 <code>ncpa.cpl</code>，回车（就是打开网络适配器）</li>
<li>右键 <strong>以太网</strong> → <strong>属性</strong></li>
<li>双击 <strong>Internet协议版本4 (TCP/IPv4)</strong></li>
<li>选择 <strong>使用下面的IP地址</strong></li>
<li>配置：
<ul>
<li>IP地址：<code>192.168.X.2</code></li>
<li>子网掩码：<code>255.255.255.0</code></li>
<li>默认网关：<code>192.168.X.1</code></li>
</ul>
</li>
<li>截图保存为 <strong>截图2</strong></li>
</ol>
<hr />
<h3>截图3：物联网中心网关配置</h3>
<p>先重置，手动改好ip设置</p>
<ol>
<li>浏览器输入 <code>192.168.1.100</code>（打不开就直连网线）</li>
<li>登录网关配置页面</li>
<li>找到 <strong>网络设置</strong> 或 <strong>网关信息</strong></li>
<li>修改IP为 <code>192.168.X.3</code></li>
<li>截图保存为 <strong>截图3</strong></li>
</ol>
<hr />
<h3>截图4：串口服务器配置</h3>
<p>先重置，手动改好ip设置</p>
<ol>
<li>浏览器输入 <code>192.168.14.200:8400</code></li>
<li>登录串口服务器（NEWPorter）</li>
<li>进入 <strong>Network Configuration</strong> 页面</li>
<li>修改IP为 <code>192.168.X.4</code></li>
<li>截图保存为 <strong>截图4</strong></li>
</ol>
<hr />
<h3>截图5：4012配置截图</h3>
<ol>
<li>把拨码开关P1拨到off，重新上电</li>
<li>电脑连上设备的热点 <code>WISE-4012E_xxxxx</code></li>
<li>浏览器打开 <code>192.168.1.1</code>，用户名 <code>root</code>，密码8个0</li>
<li>进 Configuration - Wireless：
<ul>
<li>WLAN Mode选 <code>Infrastructure Mode</code></li>
<li>SSID填你要连的WiFi名字（比如八号工位WiFi名字就是"第八组"）</li>
<li>Security Type选 <code>WPA/WPA2</code></li>
<li>Security Key填WiFi密码</li>
</ul>
</li>
<li>确认IP为 <code>192.168.X.5</code></li>
<li>截图保存为 <strong>截图5</strong></li>
</ol>
<hr />
<h2>二、连接器配置</h2>
<h3>截图6：物联网网关连接器配置截图</h3>
<p><strong>进入网关配置页面：</strong></p>
<ol>
<li>浏览器输入 <code>192.168.X.3</code>（物联网网关地址）</li>
<li>登录后点击 <strong>连接器</strong> 菜单</li>
</ol>
<hr />
<h4>截图6.1：光照变送器配置</h4>
<ol>
<li>点击左侧 <strong>light</strong> 连接器</li>
<li>确认配置：
<ul>
<li>连接器名称：<code>light</code></li>
<li>连接器设备类型：<code>Modbus over Serial</code></li>
<li>设备接入方式：<code>串口接入</code></li>
<li>波特率：<code>9600</code></li>
<li>串口名称：<code>/dev/ttySUSB4</code>（一定要看看实际USB串口）</li>
</ul>
</li>
<li>展开下方 <strong>光照</strong> 设备配置：
<ul>
<li>设备名称：<code>light</code></li>
<li>设备类型：<code>光照度传感器（485型）</code></li>
<li>设备地址：<code>2</code></li>
</ul>
</li>
<li>截图保存为 <strong>截图6.1</strong></li>
</ol>
<hr />
<h4>截图6.2：RGB控制器配置</h4>
<ol>
<li>点击左侧 <strong>RGB</strong> 连接器</li>
<li>确认配置：
<ul>
<li>连接器名称：<code>RGB</code></li>
<li>连接器设备类型：<code>NLE SERIAL-BUS</code></li>
<li>设备接入方式：<code>串口接入</code></li>
<li>波特率：<code>9600</code></li>
<li>串口名称：<code>/dev/ttyS3</code></li>
</ul>
</li>
<li>点增按钮</li>
<li>填写设备信息：
<ul>
<li>设备名称：<code>RGBLight</code></li>
<li>设备类型：选 <code>RGB控制盒</code></li>
<li>设备地址：填 <code>4</code>（就是你之前改的那个地址）</li>
<li>标识名称：<code>RGBLight</code></li>
<li>传感类型：选 <code>RGB灯带</code></li>
</ul>
</li>
<li>点确定保存</li>
<li>截图保存为 <strong>截图6.2</strong></li>
</ol>
<hr />
<h4>截图6.3：串口服务器-ADAM4150配置</h4>
<ol>
<li>点击左侧 <strong>4150</strong> 连接器</li>
<li>确认配置：
<ul>
<li>连接器名称：<code>4150</code></li>
<li>连接器设备类型：<code>Modbus over Serial</code></li>
<li>设备接入方式：<code>串口服务器接入</code></li>
<li>串口服务器IP：<code>192.168.X.4</code>（串口服务器地址）</li>
<li>串口服务器端口：<code>6005</code></li>
</ul>
</li>
<li>展开下方设备配置：
<ul>
<li><strong>weidong</strong>（微动开关）：传感器类型 <code>微动开关</code>，通道号 <code>DI0</code></li>
<li><strong>diandong</strong>（电动推杆）：传感器类型 <code>电动推杆</code>，前进 <code>DO0</code>，后退 <code>DO1</code></li>
</ul>
</li>
<li>截图保存为 <strong>截图6.3</strong></li>
</ol>
<hr />
<h4>截图6.4：串口服务器-Zigbee配置</h4>
<ol>
<li>点击左侧 <strong>zigbee</strong> 连接器</li>
<li>确认配置：
<ul>
<li>连接器名称：<code>zigbee</code></li>
<li>连接器设备类型：<code>Modbus over Serial</code></li>
<li>设备接入方式：<code>串口服务器接入</code></li>
<li>串口服务器IP：<code>192.168.X.4</code></li>
<li>串口服务器端口：<code>6006</code></li>
</ul>
</li>
<li>展开下方设备配置：
<ul>
<li><strong>co2</strong>（二氧化碳传感器）：设备类型 <code>二氧化碳传感器（485型）</code>，设备地址 <code>3</code></li>
</ul>
</li>
<li>截图保存为 <strong>截图6.4</strong></li>
</ol>
<hr />
<h4>截图6.5：4012E配置</h4>
<ol>
<li>点击左侧 <strong>4012</strong> 连接器</li>
<li>确认配置：
<ul>
<li>网络设备连接器名称：<code>4012</code></li>
<li>网络设备连接器类型：<code>Modbus over TCP</code></li>
<li>Modbus类型：<code>Modbus over TCP</code></li>
</ul>
</li>
<li>展开下方设备配置：
<ul>
<li><strong>wd</strong>（温度）：传感器类型 <code>温度</code>，通道号 <code>V0</code></li>
<li><strong>sd</strong>（湿度）：传感器类型 <code>湿度</code>，通道号 <code>V1</code></li>
<li><strong>fs</strong>（风扇）：传感器类型 <code>风扇</code>，通道号 <code>DO0</code></li>
</ul>
</li>
</ol>
<blockquote>
<p>碎碎念：八号工位的温湿度可能会抽风emmm，实在没数据就用海克斯科技吧（把4012电拔了，然后f12改数据（懂你意思））</p>
</blockquote>
<ol>
<li>截图保存为 <strong>截图6.5</strong></li>
</ol>
<hr />
<h3>截图7：网关数据监控截图</h3>
<p><strong>进入数据监控页面：</strong>
在网关配置页面点击左侧 <strong>数据监控</strong> 菜单</p>
<hr />
<h4>截图7.1：光照变送器监控</h4>
<ol>
<li>找到 <code>light</code> 连接器下的 <code>light</code> 设备</li>
<li>确认显示当前光照值（如 <code>357 Lux</code>）</li>
<li>截图保存为 <strong>截图7.1</strong></li>
</ol>
<h4>截图7.2：RGB控制器监控</h4>
<ol>
<li>找到 <code>RGB</code> 连接器</li>
<li>改个颜色然后截图</li>
<li>截图保存为 <strong>截图7.2</strong></li>
</ol>
<h4>截图7.3：串口服务器-ADAM4150监控</h4>
<ol>
<li>找到 <code>4150</code> 连接器下的 <code>diandong</code> 和 <code>weidong</code></li>
<li>确认显示当前状态</li>
<li>截图保存为 <strong>截图7.3</strong></li>
</ol>
<h4>截图7.4：串口服务器-Zigbee监控</h4>
<ol>
<li>找到 <code>zigbee</code> 连接器下的 <code>co2</code> 设备</li>
<li>确认显示当前CO2值（如 <code>895 ppm</code>）</li>
<li>截图保存为 <strong>截图7.4</strong></li>
</ol>
<h4>截图7.5：4012E监控</h4>
<ol>
<li>找到 <code>4012</code> 连接器下的 <code>wd</code>、<code>sd</code>、<code>fs</code></li>
<li>确认显示：
<ul>
<li>温度（如 <code>30.7 ℃</code>）</li>
<li>湿度（如 <code>45.7 %</code>）</li>
<li>风扇状态（如 <code>运行中/停止</code>）</li>
</ul>
</li>
<li>截图保存为 <strong>截图7.5</strong></li>
</ol>
<hr />
<h2>三、串口服务器配置</h2>
<h3>截图8：NEWPorter的端口配置</h3>
<p><strong>进入串口服务器：</strong></p>
<ol>
<li>浏览器输入 <code>192.168.X.4</code></li>
<li>登录NEWPorter串口服务器</li>
</ol>
<hr />
<h4>截图8.1：COM5口配置（Adam4150）</h4>
<ol>
<li>进入 <strong>串口设置</strong> 或 <strong>端口配置</strong></li>
<li>选择 <strong>COM5</strong></li>
<li>修改波特率为 <strong>9600</strong></li>
<li>数据位：<code>8</code>，停止位：<code>1</code>，校验：<code>None</code></li>
<li>截图保存为 <strong>截图8.1</strong></li>
</ol>
<hr />
<h4>截图8.2：COM6口配置（Zigbee）</h4>
<ol>
<li>选择 <strong>COM6</strong></li>
<li>修改波特率为 <strong>9600</strong></li>
<li>数据位：<code>8</code>，停止位：<code>1</code>，校验：<code>None</code></li>
<li>截图保存为 <strong>截图8.2</strong></li>
</ol>
<hr />
<h2>四、采集器配置</h2>
<p>这里先打开初级文件夹，里面有串口线的驱动，得先安装，忘记名字了，反正是什么cp210还是啥来着相信你找得到</p>
<p>这里每配置一个设备都要接好串口线哦</p>
<h3>截图9：ADAM4150配置</h3>
<ol>
<li>打开 <strong>ADAMNET</strong> 工具（在桌面上的中级文件夹来着，里面有个研华采集模块什么的）</li>
<li>点击 <strong>搜索</strong> 或 <strong>Scan</strong>，找到ADAM4150设备</li>
<li>双击设备进入配置：
<ul>
<li><strong>地址（Address）</strong>：设置为 <code>1</code>（hex）</li>
<li><strong>协议（Protocol）</strong>：选择 <code>Modbus</code></li>
<li><strong>波特率（Baud Rate）</strong>：设置为 <code>9600</code></li>
</ul>
</li>
<li>点击 <strong>Apply</strong> 或 <strong>设置</strong> 保存</li>
<li>截图保存为 <strong>截图9</strong></li>
</ol>
<hr />
<h2>五、RS485型传感器调试</h2>
<p>这里每配置一个设备都要接好串口线哦</p>
<h3>截图10：温湿度传感器调试</h3>
<p><strong>串口助手设置：</strong></p>
<p>打开串口助手（在桌面初级文件里面）后先设置好：</p>
<ul>
<li>串口号选对</li>
<li>波特率 <code>9600</code>，数据位 <code>8</code>，停止位 <code>1</code>，校验 <code>None</code></li>
<li>发送和接收都要是hex</li>
<li>勾选自动发送校验位，算法选 <code>CRC16 Modbus</code></li>
</ul>
<p>这样你发送数据的时候串口助手会自动把CRC校验码拼在后面</p>
<p>查不到数据就用下面的那个温湿度变送器试试</p>
<hr />
<h2>一、读取温湿度数据</h2>
<h3>发送指令</h3>
<pre><code>[设备地址] 03 00 00 00 02
</code></pre>
<p><strong>说明：</strong></p>
<ul>
<li><code>FE</code>：广播地址（不知道设备地址时用）</li>
<li><code>03</code>：功能码（读保持寄存器）</li>
<li><code>00 00</code>：起始地址</li>
<li><code>00 02</code>：读取2个寄存器（温度+湿度）</li>
<li>CRC校验：串口助手会自动添加</li>
</ul>
<h3>接收数据格式</h3>
<pre><code>[地址] 03 04 [湿度高] [湿度低] [温度高] [温度低] [CRC低] [CRC高]
</code></pre>
<p><strong>示例：</strong> <code>02 03 04 01 92 00 D1 A9 7E</code></p>
<h3>数据解析</h3>
<ol>
<li><strong>湿度</strong>：<code>01 92</code> → 十六进制<code>0x0192</code> → 十进制402 → 乘以0.1 → <strong>40.2%RH</strong></li>
<li><strong>温度</strong>：<code>00 D1</code> → 十六进制<code>0x00D1</code> → 十进制209 → 乘以0.1 → <strong>20.9°C</strong></li>
<li><strong>负温度</strong>：若温度值 &gt; 32767（如<code>FF 9B</code>），则用补码计算：
<ul>
<li><code>FF9B</code> → 十进制65435 → 65435 - 65536 = -101 → 乘以0.1 → <strong>-10.1°C</strong></li>
</ul>
</li>
</ol>
<h2>二、修改设备地址</h2>
<ol>
<li>打开"温湿度上位机"软件</li>
<li>进入"通信设置"</li>
<li>将地址修改为考核要求的 <code>1</code></li>
<li>保存设置</li>
</ol>
<hr />
<h3>截图11：光照传感器调试</h3>
<ol>
<li>串口助手保持连接</li>
<li>发送查询指令查看当前地址：<code>FE 03 00 00 00 02</code></li>
<li>发送修改指令将地址改为 <code>02</code>：<code>旧地址 06 00 00 00 02</code></li>
<li>发送查询指令查看修改后地址：<code>FE 03 00 00 00 02</code></li>
<li>截图保存为 <strong>截图11</strong></li>
</ol>
<hr />
<h3>截图12：CO2传感器调试</h3>
<ol>
<li>串口助手保持连接</li>
<li>发送查询指令查看当前地址：<code>FE 03 00 00 00 01</code></li>
<li>发送修改指令将地址改为 <code>03</code>：<code>旧地址 06 00 00 00 03</code></li>
<li>发送查询指令查看修改后地址：<code>FE 03 00 00 00 01</code></li>
<li>截图保存为 <strong>截图12</strong></li>
</ol>
<hr />
<h3>截图13：RGB控制器调试</h3>
<ol>
<li>串口助手保持连接</li>
<li><strong>查询当前地址</strong>（这个时候就要把自动发送校验位关掉注意）：
<ul>
<li>发送：<code>A5 03 FF B1 B3 5A</code></li>
</ul>
</li>
<li><strong>设置地址为04</strong>：
<ul>
<li>格式：<code>A5 04 旧地址 B0 新地址 校验和 5A</code></li>
<li>校验和怎么算：串口助手左上角，工具，有个校验计算打开，选 <code>checksum8</code>，然后输入 <code>04 旧地址 B0 新地址</code>，算出来的数据就是校验位，填进去就行</li>
</ul>
</li>
<li>发送查询指令验证：<code>A5 03 FF B1 B3 5A</code></li>
<li>截图保存为 <strong>截图13</strong></li>
</ol>
<hr />
<h3>截图14：RGB灯条设置效果</h3>
<ol>
<li>串口助手保持连接</li>
<li><strong>绿灯呼吸效果</strong>：发送指令 <code>A5 06 FF A1 01 02 10 EE 5A</code></li>
<li><strong>红灯呼吸效果</strong>：发送指令 <code>A5 06 FF A1 01 01 10 EE 5A</code></li>
<li>截图保存为 <strong>截图14</strong></li>
</ol>
<hr />
<h2>六、Zigbee配置</h2>
<h3>截图15：Zigbee模块配置</h3>
<hr />
<h4>截图15.1：Zigbee协调器配置</h4>
<ol>
<li>打开 <code>ZigBeeConfigTool</code></li>
<li>选串口号，点打开串口</li>
<li>设备类型选 <code>Coordinator</code></li>
<li>PAN ID填 <code>C00X</code>，通道填 <code>1x</code>（x是你的工位）</li>
<li>设备ID填 <code>0000</code></li>
<li>点设置保存</li>
<li>截图保存为 <strong>截图15.1</strong></li>
</ol>
<hr />
<h4>截图15.2：Zigbee路由器配置</h4>
<ol>
<li>设备类型选 <code>Router</code></li>
<li>PAN ID填 <code>C00X</code>，通道填 <code>1x</code>（和协调器一样）</li>
<li>设备ID填 <code>0001</code></li>
<li>点设置保存</li>
<li>截图保存为 <strong>截图15.2</strong></li>
</ol>
<hr />
<h2>七、云平台配置</h2>
<p>在这里先确认，进入网关，有个设置连接方式，编辑一下 <code>cloudclient</code>：</p>
<ul>
<li>IP：<code>ndp.nlecloud.com</code></li>
<li>端口：<code>8600</code></li>
</ul>
<h3>截图16：云平台网关状态配置截图</h3>
<p><strong>一、云平台添加设备</strong></p>
<ol>
<li>登录新大陆物联网云平台 <code>nlecloud.com</code>，进入开发者中心</li>
<li>点新增项目，填写信息：
<ul>
<li>联网方案：<code>WiFi</code></li>
<li>点确定</li>
</ul>
</li>
<li>进入项目详情页，点添加设备</li>
<li>填写设备信息：
<ul>
<li>设备名称：<code>边缘网关</code></li>
<li>通讯协议：<code>TCP</code></li>
<li>设备标识码：进入网关，有个设置连接方式 <code>cloudclient</code>，编辑，里面有设备id</li>
<li>注意：如果说设备被占用，就去进入网关，设置连接方式，把 <code>cloudclient</code> 停止，添加即可</li>
<li>数据保密性选 <code>公开</code></li>
<li>数据上报状态选 <code>马上启用</code></li>
<li>点确定添加</li>
</ul>
</li>
</ol>
<p><strong>二、网关连接云平台</strong></p>
<ol>
<li>浏览器打开网关管理页面</li>
<li>左边导航栏点配置，选设置连接方式</li>
<li>填写TCP连接参数：
<ul>
<li>云平台IP：<code>ndp.nlecloud.com</code></li>
<li>端口：<code>8600</code></li>
<li>点确定</li>
</ul>
</li>
<li>回到云平台点数据流获取，确认网关状态是运行中</li>
<li>截图保存为 <strong>截图16</strong></li>
</ol>
<hr />
<h3>截图17：云平台当前采集数据值截图</h3>
<ol>
<li>进入云平台 - 开发者中心 - 项目名称 - 设备管理 - 设备传感器</li>
<li>先点下发设备，然后点数据流获取，再点下发设备右边的箭头，把里面的实时数据开关打开</li>
<li>查看当前采集的数据：温度、湿度、光照、CO2、RGB、风扇状态、电动推杆状态、微动开关状态</li>
<li>截图保存为 <strong>截图17</strong></li>
</ol>
<hr />
<h3>截图18：云平台控制执行状态截图</h3>
<ol>
<li>就在当前页面</li>
<li>操作：
<ul>
<li>控制RGB灯条，输入 <code>124,252,0,1</code> 控制灯条颜色为绿色</li>
<li>按下微动开关（或模拟触发）</li>
<li>打开电动推杆</li>
</ul>
</li>
<li>确认状态显示正确</li>
<li>截图保存为 <strong>截图18</strong></li>
</ol>
<hr />
<h3>截图19：云平台策略控制启用截图</h3>
<ol>
<li>进入 <strong>策略管理</strong> 页面</li>
<li>创建策略1：
<ul>
<li>条件：<code>光照值 ≤ 200</code></li>
<li>动作：<code>开启RGB</code></li>
</ul>
</li>
<li>创建策略2：
<ul>
<li>条件：<code>光照值 &gt; 200</code></li>
<li>动作：<code>关闭RGB</code></li>
</ul>
</li>
<li>创建策略3：
<ul>
<li>条件：<code>CO2 ≤ 300</code></li>
<li>动作：<code>风扇关闭（风扇=0）</code></li>
</ul>
</li>
<li>创建策略4：
<ul>
<li>条件：<code>CO2 &gt; 300</code></li>
<li>动作：<code>风扇开启（风扇=1）</code></li>
</ul>
</li>
<li>确认策略状态为 <strong>启用</strong></li>
<li>截图保存为 <strong>截图19</strong></li>
</ol>
<hr />
<h3>截图20：项目生成器设计效果截图</h3>
<ol>
<li>进入 <strong>项目生成器</strong> 或 <strong>可视化设计</strong> 页面</li>
<li>新建项目，配置：</li>
</ol>
<p><strong>① 背景色设置</strong></p>
<ul>
<li>页面背景色：<code>rgba(125, 122, 129, 1)</code></li>
</ul>
<p><strong>② 日期时间控件</strong></p>
<ul>
<li>拖入 <strong>时间显示</strong> 控件</li>
<li>格式：显示日期、时间、PM/AM</li>
<li>字号：<code>24</code></li>
<li>字体颜色：<code>rgba(51, 51, 51, 1)</code></li>
<li>加粗、斜体</li>
</ul>
<p><strong>③ 地图控件</strong></p>
<ul>
<li>拖入 <strong>地图</strong> 控件</li>
<li>设置显示当前位置</li>
</ul>
<p><strong>④ 数据展示控件</strong></p>
<ul>
<li>拖入以下控件并绑定数据源：
<ul>
<li>光照传感器</li>
<li>CO2传感器</li>
<li>RGB控制器</li>
<li>温度</li>
<li>湿度</li>
<li>风扇</li>
<li>电动推杆</li>
<li>微动开关</li>
</ul>
</li>
</ul>
<p><strong>⑤ 折线图</strong></p>
<ul>
<li>拖入 <strong>折线图</strong> 控件</li>
<li>数据源：光照传感器、CO2传感器</li>
<li>统计范围：考试前一天至考试后一天（如6月15日考试，则范围为6月14日-6月16日）</li>
<li>标题：<code>物联网应用系统</code></li>
<li>标题字号：<code>18</code></li>
</ul>
<ol>
<li>点击 <strong>发布</strong></li>
<li>截图保存为 <strong>截图20</strong></li>
</ol>
<hr />
<h2>附录</h2>
<h3>截图命名汇总</h3>
<table>
<thead>
<tr>
<th>截图编号</th>
<th>内容</th>
</tr>
</thead>
<tbody>
<tr>
<td>截图1</td>
<td>路由器配置</td>
</tr>
<tr>
<td>截图2</td>
<td>PC机配置</td>
</tr>
<tr>
<td>截图3</td>
<td>物联网中心网关配置</td>
</tr>
<tr>
<td>截图4</td>
<td>串口服务器配置</td>
</tr>
<tr>
<td>截图5</td>
<td>4012配置</td>
</tr>
<tr>
<td>截图6.1</td>
<td>光照变送器连接器配置</td>
</tr>
<tr>
<td>截图6.2</td>
<td>RGB控制器连接器配置</td>
</tr>
<tr>
<td>截图6.3</td>
<td>ADAM4150连接器配置</td>
</tr>
<tr>
<td>截图6.4</td>
<td>Zigbee连接器配置</td>
</tr>
<tr>
<td>截图6.5</td>
<td>4012E连接器配置</td>
</tr>
<tr>
<td>截图7.1</td>
<td>光照变送器数据监控</td>
</tr>
<tr>
<td>截图7.2</td>
<td>RGB控制器数据监控</td>
</tr>
<tr>
<td>截图7.3</td>
<td>ADAM4150数据监控</td>
</tr>
<tr>
<td>截图7.4</td>
<td>Zigbee数据监控</td>
</tr>
<tr>
<td>截图7.5</td>
<td>4012E数据监控</td>
</tr>
<tr>
<td>截图8</td>
<td>NEWPorter端口配置</td>
</tr>
<tr>
<td>截图8.1</td>
<td>COM5口配置</td>
</tr>
<tr>
<td>截图8.2</td>
<td>COM6口配置</td>
</tr>
<tr>
<td>截图9</td>
<td>ADAM4150配置</td>
</tr>
<tr>
<td>截图10</td>
<td>温湿度传感器调试</td>
</tr>
<tr>
<td>截图11</td>
<td>光照传感器调试</td>
</tr>
<tr>
<td>截图12</td>
<td>CO2传感器调试</td>
</tr>
<tr>
<td>截图13</td>
<td>RGB控制器调试</td>
</tr>
<tr>
<td>截图14</td>
<td>RGB灯条效果</td>
</tr>
<tr>
<td>截图15.1</td>
<td>Zigbee协调器配置</td>
</tr>
<tr>
<td>截图15.2</td>
<td>Zigbee路由器配置</td>
</tr>
<tr>
<td>截图16</td>
<td>云平台网关状态</td>
</tr>
<tr>
<td>截图17</td>
<td>云平台实时数据</td>
</tr>
<tr>
<td>截图18</td>
<td>云平台执行器控制</td>
</tr>
<tr>
<td>截图19</td>
<td>云平台策略控制</td>
</tr>
<tr>
<td>截图20</td>
<td>项目生成器设计效果</td>
</tr>
</tbody>
</table>
<hr />
<h3>设备IP分配表</h3>
<table>
<thead>
<tr>
<th>组号</th>
<th>路由器</th>
<th>PC机</th>
<th>IOT网关</th>
<th>串口服务器</th>
<th>4012E</th>
<th>Zigbee通道</th>
</tr>
</thead>
<tbody>
<tr>
<td>第1组</td>
<td>192.168.1.1</td>
<td>192.168.1.2/20</td>
<td>192.168.1.3</td>
<td>192.168.1.4</td>
<td>192.168.1.5</td>
<td>11</td>
</tr>
<tr>
<td>第2组</td>
<td>192.168.2.1</td>
<td>192.168.2.2/20</td>
<td>192.168.2.3</td>
<td>192.168.2.4</td>
<td>192.168.2.5</td>
<td>12</td>
</tr>
<tr>
<td>第3组</td>
<td>192.168.3.1</td>
<td>192.168.3.2/20</td>
<td>192.168.3.3</td>
<td>192.168.3.4</td>
<td>192.168.3.5</td>
<td>13</td>
</tr>
<tr>
<td>第4组</td>
<td>192.168.4.1</td>
<td>192.168.4.2/20</td>
<td>192.168.4.3</td>
<td>192.168.4.4</td>
<td>192.168.4.5</td>
<td>14</td>
</tr>
<tr>
<td>第5组</td>
<td>192.168.5.1</td>
<td>192.168.5.2/20</td>
<td>192.168.5.3</td>
<td>192.168.5.4</td>
<td>192.168.5.5</td>
<td>15</td>
</tr>
<tr>
<td>第6组</td>
<td>192.168.6.1</td>
<td>192.168.6.2/20</td>
<td>192.168.6.3</td>
<td>192.168.6.4</td>
<td>192.168.6.5</td>
<td>16</td>
</tr>
<tr>
<td>第7组</td>
<td>192.168.7.1</td>
<td>192.168.7.2/20</td>
<td>192.168.7.3</td>
<td>192.168.7.4</td>
<td>192.168.7.5</td>
<td>17</td>
</tr>
<tr>
<td>第8组</td>
<td>192.168.8.1</td>
<td>192.168.8.2/20</td>
<td>192.168.8.3</td>
<td>192.168.8.4</td>
<td>192.168.8.5</td>
<td>18</td>
</tr>
<tr>
<td>第9组</td>
<td>192.168.9.1</td>
<td>192.168.9.2/20</td>
<td>192.168.9.3</td>
<td>192.168.9.4</td>
<td>192.168.9.5</td>
<td>19</td>
</tr>
</tbody>
</table>
<hr />
<h3>RGB控制器指令参考</h3>
<p><strong>地址查询指令</strong></p>
<table>
<thead>
<tr>
<th>起始码</th>
<th>长度</th>
<th>地址</th>
<th>命令字</th>
<th>检验和</th>
<th>结束码</th>
</tr>
</thead>
<tbody>
<tr>
<td>0xA5</td>
<td>0x03</td>
<td>本机地址或0xFF</td>
<td>0xB1</td>
<td>0xxx</td>
<td>0x5A</td>
</tr>
</tbody>
</table>
<p><strong>地址设置指令</strong></p>
<table>
<thead>
<tr>
<th>起始码</th>
<th>长度</th>
<th>旧地址</th>
<th>命令字</th>
<th>新地址</th>
<th>检验和</th>
<th>结束码</th>
</tr>
</thead>
<tbody>
<tr>
<td>0xA5</td>
<td>0x04</td>
<td>0xxx</td>
<td>0xB0</td>
<td>0x00-0xFF</td>
<td>0xxx</td>
<td>0x5A</td>
</tr>
</tbody>
</table>
<p><strong>灯条控制指令</strong></p>
<table>
<thead>
<tr>
<th>效果</th>
<th>指令</th>
</tr>
</thead>
<tbody>
<tr>
<td>绿灯呼吸</td>
<td><code>A5 06 FF A1 01 02 10 EE 5A</code></td>
</tr>
<tr>
<td>红灯呼吸</td>
<td><code>A5 06 FF A1 01 01 10 EE 5A</code></td>
</tr>
</tbody>
</table>
<hr />
<h3>云平台策略控制要求</h3>
<table>
<thead>
<tr>
<th>策略</th>
<th>条件</th>
<th>动作</th>
</tr>
</thead>
<tbody>
<tr>
<td>策略1</td>
<td>光照值 ≤ 200</td>
<td>开启RGB</td>
</tr>
<tr>
<td>策略2</td>
<td>光照值 &gt; 200</td>
<td>关闭RGB</td>
</tr>
<tr>
<td>策略3</td>
<td>CO2 ≤ 300</td>
<td>风扇关闭（风扇=0）</td>
</tr>
<tr>
<td>策略4</td>
<td>CO2 &gt; 300</td>
<td>风扇开启（风扇=1）</td>
</tr>
</tbody>
</table>
<hr />
<h3>项目生成器设计要求</h3>
<table>
<thead>
<tr>
<th>要求</th>
<th>配置</th>
</tr>
</thead>
<tbody>
<tr>
<td>页面背景色</td>
<td><code>rgba(125, 122, 129, 1)</code></td>
</tr>
<tr>
<td>日期时间显示</td>
<td>显示当天日期、时间、PM/AM</td>
</tr>
<tr>
<td>日期时间字号</td>
<td><code>24</code>，加粗、斜体</td>
</tr>
<tr>
<td>日期时间字体颜色</td>
<td><code>rgba(51, 51, 51, 1)</code></td>
</tr>
<tr>
<td>地图</td>
<td>显示当前位置</td>
</tr>
<tr>
<td>数据展示</td>
<td>光照传感器、CO2传感器、RGB控制器、温度、湿度、风扇、电动推杆、微动开关</td>
</tr>
<tr>
<td>折线图数据源</td>
<td>光照传感器、CO2传感器</td>
</tr>
<tr>
<td>折线图统计范围</td>
<td>考前一天至考后一天</td>
</tr>
<tr>
<td>折线图标题</td>
<td><code>物联网应用系统</code></td>
</tr>
<tr>
<td>折线图标题字号</td>
<td><code>18</code></td>
</tr>
</tbody>
</table>
<hr />
<blockquote>
<p><strong>最后更新</strong>：2026-06-12</p>
</blockquote>
]]></content>
    <author><name>槿鸢</name></author>
    <category term="IoT"/>
  </entry>
  <entry>
    <title>搭建 MySQL 服务器</title>
    <link href="https://blog.ipox.cn/posts/zh-cn/mysql-setup/" rel="alternate" type="text/html"/>
    <id>https://blog.ipox.cn/posts/zh-cn/mysql-setup/</id>
    <published>2026-06-07T00:00:00.000Z</published>
    <updated>2026-06-07T00:00:00.000Z</updated>
    <summary>在 Linux 环境下安装、配置 MySQL 服务器，并开放远程连接。</summary>
    <content type="html"><![CDATA[<h2>一、安装 MySQL</h2>
<pre><code>sudo apt install mysql-server
</code></pre>
<h2>二、查看 MySQL 服务状态</h2>
<pre><code>apt policy mysql-server
systemctl status mysql
</code></pre>
<p>如果有报错，可能是之前用 Docker 部署过 MySQL，关掉容器即可：</p>
<pre><code># 查看所有容器
docker ps -a

# 找到 MySQL 容器的名字，停止它
docker stop &lt;容器名字&gt;

# 启动 MySQL
systemctl start mysql

# 再次查看状态
systemctl status mysql
</code></pre>
<h2>三、登录 MySQL 并修改 root 密码</h2>
<pre><code>sudo mysql
</code></pre>
<p>进入后修改 root 的密码认证方式。改之前直接用 <code>mysql -uroot -p</code> 是登不进去的：</p>
<pre><code>ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';
FLUSH PRIVILEGES;
</code></pre>
<p>改完之后就能用密码登录了：</p>
<pre><code>mysql -uroot -p
</code></pre>
<h2>四、允许 root 用户远程登录</h2>
<pre><code>use mysql;
update user set host='%' where user='root';
FLUSH PRIVILEGES;
</code></pre>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-08%20104335_2026-06-08_183258.webp" alt="允许远程登录" /></p>
<p>这样 root 用户就能从任何 IP 连接了。</p>
<h2>五、配置远程连接</h2>
<p>修改 MySQL 配置文件，<code>bind-address</code> 不能是 <code>127.0.0.1</code>：</p>
<pre><code>sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf
</code></pre>
<ul>
<li>找到 <code>bind-address</code> 那行，改成 <code>0.0.0.0</code></li>
<li>如果有 <code>mysqlx-bind-address</code>，也改成 <code>0.0.0.0</code></li>
</ul>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-08%20104837_2026-06-08_183258.webp" alt="修改 bind-address" /></p>
<p>改完保存，重启 MySQL：</p>
<pre><code>sudo systemctl restart mysql
</code></pre>
<h2>六、防火墙开放 3306 端口</h2>
<pre><code>sudo ufw allow 3306/tcp
sudo ufw reload
</code></pre>
<h2>七、用 DBeaver 连接数据库</h2>
<p>DBeaver 是一款免费开源的通用数据库管理工具，支持 MySQL、PostgreSQL、Oracle 等多种数据库，界面友好，适合新手使用。</p>
<hr />
<h3>7.1 下载安装 DBeaver</h3>
<p><strong>1. 下载 DBeaver</strong></p>
<p>打开浏览器，访问 DBeaver 官网下载页面：</p>
<p>👉 <a href="https://dbeaver.io/download/">https://dbeaver.io/download/</a></p>
<blockquote>
<p>💡 如果不确定选哪个，Windows 用户直接下载 <strong>Community</strong> 版本的 <code>.exe</code> 安装包即可，它是免费的。</p>
</blockquote>
<p><strong>2. 安装 DBeaver</strong></p>
<ul>
<li><strong>Windows</strong>：双击下载好的 <code>.exe</code> 文件，按照安装向导提示一路点 <code>Next</code>（下一步）即可完成安装。</li>
</ul>
<p>安装完成后，在桌面或开始菜单中找到 DBeaver 图标，双击启动。</p>
<hr />
<h3>7.2 创建 MySQL 连接</h3>
<p><strong>1. 启动 DBeaver</strong></p>
<p>打开 DBeaver，首次启动可能会弹出“是否创建示例数据库”的提示，直接点击 <strong>Cancel</strong> 或 <strong>No</strong> 跳过即可。</p>
<p><strong>2. 新建连接</strong></p>
<ul>
<li>点击左上角的 <strong>新建连接</strong> 图标（一个带加号的数据库图标 📁+），或者依次点击菜单栏 <code>数据库</code> → <code>新建连接</code>。</li>
</ul>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/e8075056267292192ea5ebe7806f2848_2026-06-17_224610.webp" alt="addsql" /></p>
<ul>
<li>在弹出的窗口中，选择 <strong>MySQL</strong>，然后点击 <strong>Next（下一步）</strong>。</li>
</ul>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/d93e841ecc2403afe3c2948c8331b762_2026-06-17_224727.webp" alt="addddd" /></p>
<p><strong>3. 填写连接参数</strong></p>
<p>在 <strong>主要</strong> 标签页中，填写以下信息：</p>
<table>
<thead>
<tr>
<th>参数</th>
<th>填写内容</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>主机 / Host</strong></td>
<td><code>192.168.103.128</code></td>
<td>填写你虚拟机的实际 IP 地址（用 <code>ip a</code> 命令查看）</td>
</tr>
<tr>
<td><strong>端口 / Port</strong></td>
<td><code>3306</code></td>
<td>MySQL 默认端口，一般不需要改</td>
</tr>
<tr>
<td><strong>用户名 / Username</strong></td>
<td><code>root</code></td>
<td>数据库管理员账号</td>
</tr>
<tr>
<td><strong>密码 / Password</strong></td>
<td>你刚才设置的密码 123456</td>
<td>就是第三步 <code>ALTER USER</code> 时设置的那个密码</td>
</tr>
</tbody>
</table>
<blockquote>
<p>⚠️ <strong>注意</strong>：Host 不要填 <code>localhost</code> 或 <code>127.0.0.1</code>，因为 DBeaver 是运行在宿主机上的，要填虚拟机的 IP 地址。</p>
</blockquote>
<p>填写完成后，可以点击 <strong>测试连接</strong> 按钮，检查参数是否正确。</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-17%20233333_2026-06-17_233532.webp" alt="sqlt" /></p>
<hr />
<h3>7.3 解决连接报错（关键步骤）</h3>
<p>如果点击 <strong>测试连接</strong> 后出现如下报错：</p>
<pre><code>Public Key Retrieval is not allowed
</code></pre>
<p>这是 MySQL 8.0 的一个安全机制，解决方法如下：</p>
<p><strong>1. 在同一个连接配置窗口中，切换到 <code>驱动属性</code> 标签页。</strong></p>
<p><strong>2. 修改以下两个参数：</strong></p>
<table>
<thead>
<tr>
<th>参数名</th>
<th>填写值</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>allowPublicKeyRetrieval</code></td>
<td><code>TRUE</code></td>
</tr>
<tr>
<td><code>useSSL</code></td>
<td><code>FALSE</code></td>
</tr>
</tbody>
</table>
<blockquote>
<p>💡 <strong>提示</strong>：如果参数列表里没有这两个选项，可以直接在下方的 <code>属性名</code> 输入框中手动输入，然后填写对应的值。</p>
</blockquote>
<p><strong>3. 再次点击测试连接</strong></p>
<p>此时应该能看到 <strong>连接已成功</strong> 的提示。</p>
<hr />
<h3>7.4 保存连接并开始使用</h3>
<p><strong>1.</strong> 点击 <strong>完成</strong> 保存连接配置。</p>
<p><strong>2.</strong> 在 DBeaver 左侧的 <strong>数据库导航</strong> 面板中，会出现你刚创建的 MySQL 连接。</p>
<p><strong>3.</strong> 双击连接名称（或点击连接名称左侧的 ▶ 展开箭头），DBeaver 会连接到数据库并显示其中的数据库列表。</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-17%20233608_2026-06-17_233614.webp" alt="sqlccc" /></p>
<p><strong>4.</strong> 右键点击连接名称 → <code>新建 SQL 编辑器</code> → <code>新建 SQL 编辑器</code>，就可以执行 SQL 语句了。</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-17%20233749_2026-06-17_233801.webp" alt="sqleeddd" /></p>
<p>然后输入以下命令：</p>
<pre><code>show databases;
create database test;
use test;
create table test(nid int, nname varchar(10));
insert into test values(1, 'zhangsan'), (2, 'lisi');
select * from test;
</code></pre>
<p>然后点执行按钮运行 SQL 脚本（左边从上到下第三个图标执行sql脚本），看到查询结果即搭建成功。</p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/1f686bf31f4b0bf7a2bcb857e8986842_2026-06-17_234256.webp" alt="启动" /></p>
<p><img src="https://cdn.jsdelivr.net/gh/azzlantern/blog-pic@main/blog/2026/%E5%B1%8F%E5%B9%95%E6%88%AA%E5%9B%BE%202026-06-17%20234147_2026-06-17_234355.webp" alt="效果" /></p>
]]></content>
    <author><name>槿鸢</name></author>
    <category term="系统配置"/>
  </entry>
  <entry>
    <title>虚拟机配置与 Docker + Nginx + MySQL 环境搭建</title>
    <link href="https://blog.ipox.cn/posts/zh-cn/vm-docker-nginx-mysql/" rel="alternate" type="text/html"/>
    <id>https://blog.ipox.cn/posts/zh-cn/vm-docker-nginx-mysql/</id>
    <published>2026-06-07T00:00:00.000Z</published>
    <updated>2026-06-07T00:00:00.000Z</updated>
    <summary>在 VirtualBox 虚拟机中配置 NAT + Host-Only 双网卡网络，并使用 Docker Compose 部署 Nginx 和 MySQL 服务。</summary>
    <content type="html"><![CDATA[<h2>一、虚拟机导入与网络配置</h2>
<p>按照课件 PDF 导入虚拟机后，使用 <strong>NAT + Host-Only</strong> 双网卡模式配置网络。</p>
<h3>1.1 配置宿主机 Host-Only 网卡</h3>
<p>打开 VirtualBox → <strong>管理</strong> → <strong>主机网络管理器</strong>：</p>
<ul>
<li>点击<strong>创建</strong>（或选中已有的 Host-Only 网络）</li>
<li>勾选<strong>手动配置网卡</strong>，填写：
<ul>
<li>IPv4 地址：<code>192.168.103.11</code>（宿主机在此局域网的 IP）</li>
<li>子网掩码：<code>255.255.255.0</code></li>
</ul>
</li>
<li><strong>DHCP 服务器</strong>选项卡 → <strong>关闭 DHCP</strong></li>
<li>点击<strong>应用</strong></li>
</ul>
<h3>1.2 给虚拟机分配两块网卡</h3>
<p>关闭虚拟机，进入 <strong>设置</strong> → <strong>网络</strong>：</p>
<table>
<thead>
<tr>
<th>网卡</th>
<th>连接方式</th>
<th>说明</th>
</tr>
</thead>
<tbody>
<tr>
<td>网卡1</td>
<td>网络地址转换（NAT）</td>
<td>用于访问外网</td>
</tr>
<tr>
<td>网卡2</td>
<td>仅主机（Host-Only）适配器</td>
<td>用于与宿主机通信，选择刚才配好的那块</td>
</tr>
</tbody>
</table>
<h3>1.3 虚拟机内配置静态 IP</h3>
<p>编辑 <code>/etc/network/interfaces</code>：</p>
<pre><code>sudo nano /etc/network/interfaces
</code></pre>
<p>写入以下内容：</p>
<pre><code>auto lo
iface lo inet loopback

# NAT 网卡 - 上外网
auto enp0s3
iface enp0s3 inet dhcp

# Host-Only 网卡 - 与宿主机通信（不写 gateway！）
auto enp0s8
iface enp0s8 inet static
    address 192.168.103.128
    netmask 255.255.255.0
</code></pre>
<p>应用配置：</p>
<pre><code>sudo ifdown enp0s8 &amp;&amp; sudo ifup enp0s8
</code></pre>
<p>或者直接重启虚拟机。</p>
<h3>1.4 验证网络连通性</h3>
<pre><code># 虚拟机内测外网
ping -c 3 8.8.8.8

# 虚拟机 ping 宿主机
ping 192.168.103.11

# 宿主机 PowerShell ping 虚拟机
ping 192.168.103.128

# SSH 进虚拟机
ssh nle@192.168.103.128
</code></pre>
<p>如果 <code>ifconfig</code> 不可用，先安装工具：</p>
<pre><code>sudo apt install net-tools
</code></pre>
<hr />
<h2>二、更换镜像源并更新系统</h2>
<h3>2.1 更换 apt 镜像源</h3>
<pre><code>sudo nano /etc/apt/sources.list
</code></pre>
<p>按 <code>Ctrl + \</code> 全局替换，将 <code>archives.ubuntu.com</code> 替换为 <code>mirrors.bfsu.edu.cn</code>（北外镜像源）。</p>
<h3>2.2 更新系统</h3>
<pre><code>sudo apt update
sudo apt upgrade
</code></pre>
<p>完成后重启虚拟机。</p>
<hr />
<h2>三、安装 Docker</h2>
<p>使用轩辕镜像的一键安装脚本：</p>
<pre><code>bash &lt;(wget -qO- https://xuanyuan.cloud/docker.sh)
</code></pre>
<p>安装完成后验证：</p>
<pre><code>docker --version
</code></pre>
<hr />
<h2>四、拉取 Docker 镜像</h2>
<pre><code>docker pull nginx:latest
docker pull mysql:latest
</code></pre>
<p>拉取完成后查看镜像：</p>
<pre><code>docker images
</code></pre>
<hr />
<h2>五、清理旧容器（可选）</h2>
<p>如果之前运行过同名容器，先删掉避免冲突：</p>
<pre><code>docker ps -a              # 查看所有容器
docker rm mysql-test      # 删除旧的 mysql 容器
docker rm nginx-test      # 删除旧的 nginx 容器
</code></pre>
<hr />
<h2>六、编写 docker-compose.yml</h2>
<pre><code>nano docker-compose.yml
</code></pre>
<p>填入以下内容：</p>
<pre><code>version: '3'
services:
  nginx:
    image: nginx:latest
    ports:
      - "9110:80"
  mysql:
    image: mysql:latest
    ports:
      - "3306:3306"
    environment:
      MYSQL_ROOT_PASSWORD: 123456
</code></pre>
<p>保存退出：<code>Ctrl + O</code> → 回车（保存），<code>Ctrl + X</code>（退出）。</p>
<hr />
<h2>七、一键启动容器</h2>
<pre><code>docker compose up -d
</code></pre>
<p>以后每次启动只需执行这一条命令。容器名通常为 <code>&lt;当前目录&gt;-mysql-1</code> 和 <code>&lt;当前目录&gt;-nginx-1</code>，可用 <code>docker ps</code> 查看。</p>
<hr />
<h2>八、配置 Nginx</h2>
<h3>8.1 进入 Nginx 容器</h3>
<pre><code>docker exec -it &lt;nginx容器名&gt; /bin/bash
</code></pre>
<h3>8.2 修改默认网页</h3>
<pre><code>echo "Hello Docker" &gt; /usr/share/nginx/html/index.html
</code></pre>
<h3>8.3 测试访问</h3>
<p>浏览器打开 <code>虚拟机IP:9110</code>（例如 <code>http://192.168.103.128:9110</code>），看到修改后的页面即成功。</p>
<hr />
<h2>九、配置 MySQL</h2>
<h3>9.1 进入 MySQL 容器</h3>
<pre><code>docker exec -it &lt;mysql容器名&gt; /bin/bash
</code></pre>
<h3>9.2 登录 MySQL</h3>
<pre><code>mysql -uroot -p
</code></pre>
<p>输入密码 <code>123456</code>（docker-compose 中设置的）。</p>
<h3>9.3 创建数据库</h3>
<pre><code>CREATE DATABASE test;
USE test;
</code></pre>
<hr />
<h2>十、客户端连接数据库</h2>
<p>推荐使用 <strong>DBeaver</strong>（免费开源）连接：</p>
<table>
<thead>
<tr>
<th>参数</th>
<th>值</th>
</tr>
</thead>
<tbody>
<tr>
<td>Host</td>
<td>虚拟机IP（<code>192.168.103.128</code>）</td>
</tr>
<tr>
<td>Port</td>
<td><code>3306</code></td>
</tr>
<tr>
<td>User</td>
<td><code>root</code></td>
</tr>
<tr>
<td>Password</td>
<td><code>123456</code></td>
</tr>
</tbody>
</table>
<h3>解决报错：Public Key Retrieval is not allowed</h3>
<p>在 DBeaver 中编辑当前 MySQL 连接，切换到<strong>驱动属性</strong>标签页，修改以下参数：</p>
<table>
<thead>
<tr>
<th>参数名</th>
<th>填写值</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>allowPublicKeyRetrieval</code></td>
<td><code>TRUE</code></td>
</tr>
<tr>
<td><code>useSSL</code></td>
<td><code>FALSE</code></td>
</tr>
</tbody>
</table>
<p>保存后再次测试连接即可成功。</p>
]]></content>
    <author><name>槿鸢</name></author>
    <category term="系统配置"/>
  </entry>
  <entry>
    <title>Packet Tracer企业级VLAN/OSPF/静态路由主干互通配置笔记</title>
    <link href="https://blog.ipox.cn/posts/zh-cn/packet-tracer-note/" rel="alternate" type="text/html"/>
    <id>https://blog.ipox.cn/posts/zh-cn/packet-tracer-note/</id>
    <published>2025-11-26T16:39:24.000Z</published>
    <updated>2025-11-26T16:39:24.000Z</updated>
    <summary></summary>
    <content type="html"><![CDATA[<h2>前言</h2>
<p>原本以为这次折腾在了解了不懂的知识之后会容易一些,结果一折腾就花了好多时间,期间遇到各种问题,最终才把整个拓扑和配置理顺。这里把最终的配置笔记整理出来,方便参考😭。</p>
<p>刚开始把拓扑图做出来拿去喂AI,然后它让我把聚合接口弄成三层口,结果折腾了好久,就是卡在PC能ping通VLAN网关,但跨VLAN不通。后来才发现是AI给的建议不对,<strong>聚合口必须是二层Trunk口才能透传VLAN</strong>。后来又遇到各种问题,下面总结一下常见问题和解决方法,方便参考。都是血的教训,我熬到半夜两点都想不通为什么,得亏第二天我问朋友和老师都说应该把聚合口也弄成Trunk模式😭😭😭。</p>
<hr />
<h2>需要了解的核心知识点</h2>
<h3>1. VLAN与交换机基础</h3>
<ul>
<li>VLAN划分:不同PC划归不同VLAN,提升安全性、隔离广播域</li>
<li>二层交换机端口分配与Trunk口配置</li>
<li>VLAN SVI(Switch Virtual Interface)技术,实现三层网关</li>
</ul>
<h3>2. 多层交换与主干聚合</h3>
<ul>
<li>三层交换机的ip routing启用,以及三层接口、SVI网关分配</li>
<li>主干链路聚合(EtherChannel/LACP),实现高可用、多链路带宽叠加</li>
<li>聚合组成员口参数一致性配置</li>
</ul>
<h3>3. Trunk链路/VLAN透传</h3>
<ul>
<li>Trunk接口dot1q封装</li>
<li>多VLAN允许与active在Trunk接口的配置</li>
<li>接入交换机与汇聚交换机Trunk连接</li>
</ul>
<h3>4. OSPF动态路由</h3>
<ul>
<li>OSPF区域零配置</li>
<li>多交换机/路由器动态互联与路由自动学习</li>
<li>OSPF邻居关系、路由表收敛</li>
</ul>
<h3>5. 静态路由</h3>
<ul>
<li>R0、R1之间静态路由互通</li>
<li>边界和核心路由器回程、缺省路由设置</li>
</ul>
<h3>6. 全网三层互通与跨VLAN路由</h3>
<ul>
<li>VLAN间路由和主干园区数据跨VLAN流通实验</li>
<li>交换/路由混合环境下端到端包转发和路径管理</li>
</ul>
<hr />
<h2>常见问题与解决方法</h2>
<h3>1. Trunk口/VLAN未active导致跨VLAN不通</h3>
<p><strong>问题现象:</strong>
Trunk口允许VLAN10/20,但另一端交换机没创建VLAN10,导致Port-channel和Trunk口未active对应VLAN,流量首跳丢包。</p>
<p><strong>解决方法:</strong></p>
<ul>
<li>两端都必须创建并激活所有要透传的VLAN</li>
<li>一步步用 <code>show interfaces trunk</code> 查VLAN active状态</li>
</ul>
<h3>2. 主干聚合端口(Port-channel)down/down或suspended</h3>
<p><strong>问题现象:</strong>
Port-channel始终down,或口组"参数不兼容"报错。</p>
<p><strong>主要原因:</strong>
聚合成员口和Port-channel属性不一致,有no switchport或access/trunk混用遗留。</p>
<p><strong>解决方法:</strong></p>
<ul>
<li>用 <code>default interface</code> 清空所有Port-channel及成员口,重新统一配置</li>
<li>聚合成员口与Port-channel全部参数(Trunk、allowed VLAN、封装)必须一致</li>
</ul>
<h3>3. VLAN网关、PC地址/掩码/网关配置错误</h3>
<p><strong>问题现象:</strong>
PC能ping通本地网关,但不能跨VLAN互通。</p>
<p><strong>常见原因:</strong>
PC网关 or 子网掩码填错。</p>
<p><strong>解决方法:</strong>
查PC设置,确保网关是正确VLAN SVI地址,子网掩码标准。</p>
<h3>4. OSPF中发布了没有IP的主干聚合网段</h3>
<p><strong>问题现象:</strong>
OSPF发布了Port-channel的网段,但Port-channel已无IP,引起OSPF收敛警告/冗余。</p>
<p><strong>解决方法:</strong>
删除无IP接口的network声明,只发布实际IP三层口。</p>
<h3>5. Packet Tracer收敛/ARP/MAC表未及时刷新</h3>
<p><strong>问题现象:</strong>
明明配置都对,但包还是不通。</p>
<p><strong>解决方法:</strong>
多次Fast Forward/重启模拟器,清空ARP和MAC表,等仿真器收敛。</p>
<h3>6. 聚合组L2/L3属性不匹配,命令拒绝</h3>
<p><strong>问题现象:</strong>
channel-group操作报"L2与L3不一致"。</p>
<p><strong>解决方法:</strong>
用 <code>default interface port-channel 1</code> 和 <code>default interface fa0/x</code> 把所有成员口属性清空,再一步步重新配置为Trunk、channel-group。</p>
<h3>7. OSPF邻居关系/路由收敛问题</h3>
<p><strong>问题现象:</strong>
OSPF邻居不FULL或路由表不互通。</p>
<p><strong>解决方法:</strong>
检查是否只发布有IP接口网段,确保接口up/up、OSPF Router ID无冲突。</p>
<hr />
<h2>拓扑结构概览</h2>
<p>&lt;img src="https://img.103028.xyz/blog/net1/tuopu.png" alt="拓扑图" /&gt;</p>
<pre><code>        +--------+          +--------+
        |   S1   |----------|   S2   |
        |(三层汇聚)|          |(三层汇聚)|
        +--------+          +--------+
           |  |                 |  |
          Fa0/2 Fa0/4         Fa0/2 Fa0/4
           |  |                 |  |
        +--------+          +--------+
        |   S3   |          |   S4   |
        |(接入交换)|          |(接入交换)|
        +--------+          +--------+
         |  |  |             |  |  |
       PC1 PC2 PC3        PC4 PC5 PC6
       
       S1 Fa0/1 &lt;--&gt; R0 Gi0/0
       S2 Fa0/1 &lt;--&gt; R0 Gi0/1
       
       R0 Se0/1/0 &lt;--&gt; R1 Se0/1/0
       R1 Gi0/0 (外网)
</code></pre>
<h3>需要的设备</h3>
<ul>
<li>2台三层交换机(S1、S2)可以用3560或3750</li>
<li>2台二层交换机(S3、S4)</li>
<li>2台路由器(R0、R1)</li>
<li>多台PC(PC1-PC6,外网PC0)</li>
</ul>
<h3>VLAN划分</h3>
<ul>
<li><strong>VLAN10:</strong> PC1-PC3</li>
<li><strong>VLAN20:</strong> PC4-PC6</li>
</ul>
<h3>IP地址分配</h3>
<h4>VLAN10网段</h4>
<ul>
<li>S1 Vlan10网关:192.168.1.1</li>
<li>PC1:192.168.1.10</li>
<li>PC2:192.168.1.11</li>
<li>PC3:192.168.1.12</li>
</ul>
<h4>VLAN20网段</h4>
<ul>
<li>S2 Vlan20网关:192.168.2.1</li>
<li>PC4:192.168.2.10</li>
<li>PC5:192.168.2.11</li>
<li>PC6:192.168.2.12</li>
</ul>
<h4>S1-S2互联网段</h4>
<ul>
<li>S1 Fa0/1:192.168.6.1</li>
<li>S2 Fa0/1:192.168.7.1</li>
<li>R0 Gi0/0:192.168.6.2</li>
<li>R0 Gi0/1:192.168.7.2</li>
</ul>
<h4>R0-R1串口网段</h4>
<ul>
<li>R0 Se0/1/0:192.168.8.1</li>
<li>R1 Se0/1/0:192.168.8.2</li>
</ul>
<h4>R1 Gi0/0(外网)</h4>
<ul>
<li>R1 Gi0/0:192.168.9.1</li>
<li>外网PC0:192.168.9.2</li>
</ul>
<hr />
<h2>各设备配置代码</h2>
<h3>S1(三层汇聚/分布交换机)</h3>
<p><strong>功能:</strong></p>
<ul>
<li>启用三层交换</li>
<li>主干聚合/下联Trunk配置</li>
<li>VLAN10网关</li>
<li>OSPF只发布互联、VLAN10网段</li>
</ul>
<pre><code>ip routing                                      ! 启用三层路由功能

interface Port-channel1                         ! 配置聚合接口
 switchport trunk allowed vlan 10,20           ! 允许VLAN10和20通过
 switchport trunk encapsulation dot1q          ! 使用802.1Q封装
 switchport mode trunk                          ! 设置为Trunk模式

interface FastEthernet0/1                       ! 配置上联到R0的三层口
 no switchport                                  ! 关闭二层功能,变为三层路由口
 ip address 192.168.6.1 255.255.255.252        ! 配置IP地址

interface range FastEthernet0/2, FastEthernet0/4  ! 批量配置Fa0/2和Fa0/4
 switchport trunk allowed vlan 10,20           ! 允许VLAN10和20通过
 switchport trunk encapsulation dot1q          ! 使用802.1Q封装
 switchport mode trunk                          ! 设置为Trunk模式
 channel-group 1 mode active                    ! 加入聚合组1,LACP主动模式

interface FastEthernet0/3                       ! 配置下联到S3的Trunk口
 switchport trunk allowed vlan 10,20           ! 允许VLAN10和20通过
 switchport trunk encapsulation dot1q          ! 使用802.1Q封装
 switchport mode trunk                          ! 设置为Trunk模式

interface Vlan10                                ! 配置VLAN10的SVI网关
 ip address 192.168.1.1 255.255.255.0          ! VLAN10网关IP

router ospf 1                                   ! 启用OSPF进程1
 log-adjacency-changes                          ! 记录邻居状态变化
 network 192.168.6.0 0.0.0.3 area 0            ! 发布S1到R0的互联网段
 network 192.168.1.0 0.0.0.255 area 0          ! 发布VLAN10网段
</code></pre>
<hr />
<h3>S2(三层汇聚/分布交换机)</h3>
<p><strong>功能:</strong></p>
<ul>
<li>与S1结构镜像相似,互联Fa0/1</li>
<li>VLAN20网关</li>
<li>主干聚合/Trunk口</li>
</ul>
<pre><code>ip routing                                      ! 启用三层路由功能

interface Port-channel1                         ! 配置聚合接口
 switchport trunk allowed vlan 10,20           ! 允许VLAN10和20通过
 switchport trunk encapsulation dot1q          ! 使用802.1Q封装
 switchport mode trunk                          ! 设置为Trunk模式

interface FastEthernet0/1                       ! 配置上联到R0的三层口
 no switchport                                  ! 关闭二层功能,变为三层路由口
 ip address 192.168.7.1 255.255.255.252        ! 配置IP地址

interface range FastEthernet0/2, FastEthernet0/4  ! 批量配置Fa0/2和Fa0/4
 switchport trunk allowed vlan 10,20           ! 允许VLAN10和20通过
 switchport trunk encapsulation dot1q          ! 使用802.1Q封装
 switchport mode trunk                          ! 设置为Trunk模式
 channel-group 1 mode active                    ! 加入聚合组1,LACP主动模式

interface FastEthernet0/3                       ! 配置下联到S4的Trunk口
 switchport trunk allowed vlan 10,20           ! 允许VLAN10和20通过
 switchport trunk encapsulation dot1q          ! 使用802.1Q封装
 switchport mode trunk                          ! 设置为Trunk模式

interface Vlan20                                ! 配置VLAN20的SVI网关
 ip address 192.168.2.1 255.255.255.0          ! VLAN20网关IP

router ospf 1                                   ! 启用OSPF进程1
 log-adjacency-changes                          ! 记录邻居状态变化
 network 192.168.7.0 0.0.0.3 area 0            ! 发布S2到R0的互联网段
 network 192.168.2.0 0.0.0.255 area 0          ! 发布VLAN20网段
</code></pre>
<hr />
<h3>S3(接入交换机)</h3>
<p><strong>功能:</strong></p>
<ul>
<li>Trunk上联</li>
<li>3个PC口接VLAN10</li>
</ul>
<pre><code>interface FastEthernet0/1                       ! 配置上联到S1的Trunk口
 switchport trunk allowed vlan 10,20           ! 允许VLAN10和20通过
 switchport trunk encapsulation dot1q          ! 使用802.1Q封装
 switchport mode trunk                          ! 设置为Trunk模式

interface range FastEthernet0/2, FastEthernet0/3, FastEthernet0/4  ! 批量配置接入口
 switchport access vlan 10                      ! 将端口划入VLAN10
 switchport mode access                         ! 设置为Access模式
</code></pre>
<hr />
<h3>S4(接入交换机)</h3>
<p><strong>功能:</strong></p>
<ul>
<li>Trunk上联</li>
<li>3个PC口接VLAN20</li>
</ul>
<pre><code>interface FastEthernet0/1                       ! 配置上联到S2的Trunk口
 switchport trunk allowed vlan 10,20           ! 允许VLAN10和20通过
 switchport trunk encapsulation dot1q          ! 使用802.1Q封装
 switchport mode trunk                          ! 设置为Trunk模式

interface range FastEthernet0/2, FastEthernet0/3, FastEthernet0/4  ! 批量配置接入口
 switchport access vlan 20                      ! 将端口划入VLAN20
 switchport mode access                         ! 设置为Access模式
</code></pre>
<hr />
<h3>R0（核心路由器）</h3>
<p><strong>功能:</strong></p>
<ul>
<li>与 S1/S2 汇聚交换机互联三层口（主干动态路由）</li>
<li>串口与 R1 互联，实现园区与外网的数据交互</li>
<li>运行 OSPF 动态路由，同时静态路由转发外网访问</li>
</ul>
<pre><code>
! S1/S2 主干三层互联接口
interface GigabitEthernet0/0
 ip address 192.168.6.2 255.255.255.252

interface GigabitEthernet0/1
 ip address 192.168.7.2 255.255.255.252

! 串口对接 R1（外部路由器）
interface Serial0/1/0
 ip address 192.168.8.1 255.255.255.252
 clock rate 64000

! 启用 OSPF 动态路由，并注入静态路由
router ospf 1
 log-adjacency-changes
 redistribute static subnets
 network 192.168.6.0 0.0.0.3 area 0
 network 192.168.7.0 0.0.0.3 area 0

! 指向外网（PC0）的静态路由
ip route 192.168.9.0 255.255.255.0 192.168.8.2
</code></pre>
<hr />
<h3>R1（外部路由器）</h3>
<p><strong>功能:</strong></p>
<ul>
<li>串口与 R0 对接，实现与园区互通</li>
<li>外网（PC0）的网关接口</li>
<li>静态路由回程（简化建议：可只配置一条默认静态路由）</li>
</ul>
<pre><code>
! 外网接口（连接 PC0 等外部终端）
interface GigabitEthernet0/0
 ip address 192.168.9.1 255.255.255.0

! 串口对接 R0
interface Serial0/1/0
 ip address 192.168.8.2 255.255.255.252

! 静态路由回程（每个内部网段分别配置，或可简化为一条默认路由）
ip route 192.168.6.0 255.255.255.252 192.168.8.1
ip route 192.168.7.0 255.255.255.252 192.168.8.1
ip route 192.168.1.0 255.255.255.0 192.168.8.1
ip route 192.168.2.0 255.255.255.0 192.168.8.1

! —— 简化写法（推荐，等效于上面多条静态路由）:
! ip route 0.0.0.0 0.0.0.0 192.168.8.1
</code></pre>
<hr />
<h2>使用说明 &amp; 核心结构</h2>
<p><strong>关键配置要点:</strong></p>
<ol>
<li><strong>主干聚合、下联、Trunk口参数必须两端完全一致,所有透传VLAN都需本地创建</strong></li>
<li><strong>汇聚层三层交换机负责网关(SVI),OSPF向核心路由器发布VLAN网段和互联网段</strong></li>
<li><strong>核心路由与外部路由器间静态路由互通,适配企业外网、分区园区网络</strong></li>
<li><strong>接入层交换机为标准二层结构,只负责VLAN端口分配和Trunk搬帧,网关留给汇聚层</strong></li>
</ol>
<hr />
<h2>总结</h2>
<p>通过这次Packet Tracer企业级VLAN/OSPF/静态路由主干互通的折腾,深入理解了VLAN划分、三层交换机配置、主干聚合、Trunk链路、OSPF动态路由和静态路由等核心网络技术。遇到的问题和解决方法也让我积累了宝贵的实战经验。</p>
<p>希望这份笔记能帮助到正在学习网络配置的朋友们(想这门课平时分满分的同学们),避免踩坑。配置确实很复杂很折磨,但只要理清思路,逐步排查问题,就能实现网络互通。</p>
<p><strong>核心经验总结:</strong></p>
<ul>
<li>✅ 聚合口必须配置为二层Trunk模式才能透传VLAN</li>
<li>✅ 两端交换机必须都创建相同的VLAN</li>
<li>✅ 使用 <code>show interfaces trunk</code> 检查VLAN状态</li>
<li>✅ 遇到问题时使用 <code>default interface</code> 清空配置重来</li>
<li>✅ 耐心等待Packet Tracer收敛,必要时重启模拟器</li>
</ul>
]]></content>
    <author><name>槿鸢</name></author>
    <category term="网络"/>
  </entry>
  <entry>
    <title>FTP服务器安装与配置</title>
    <link href="https://blog.ipox.cn/posts/zh-cn/ftp-config/" rel="alternate" type="text/html"/>
    <id>https://blog.ipox.cn/posts/zh-cn/ftp-config/</id>
    <published>2025-11-18T15:26:20.000Z</published>
    <updated>2025-11-18T15:26:20.000Z</updated>
    <summary></summary>
    <content type="html"><![CDATA[<h1>FTP服务器配置与管理</h1>
<h2>实验环境</h2>
<ul>
<li>一台虚拟机作为服务端（CentOS 7）</li>
<li>一台虚拟机作为客户端（CentOS 7 或 Windows）</li>
<li>服务端 IP: <code>192.241.42.3</code></li>
</ul>
<hr />
<h2>1. 安装 vsftpd 软件包</h2>
<p>使用 yum 安装：</p>
<pre><code>yum install vsftpd -y
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/ftp/p1.png" alt="p1" /&gt;</p>
<hr />
<h2>2. 配置匿名用户访问</h2>
<h3>(1) 修改配置文件 <code>/etc/vsftpd/vsftpd.conf</code></h3>
<pre><code>vi /etc/vsftpd/vsftpd.conf
</code></pre>
<p>确保以下参数设置正确：</p>
<pre><code>anonymous_enable=YES
anon_upload_enable=YES
anon_mkdir_write_enable=YES
anon_other_write_enable=YES
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/ftp/p2.png" alt="p2" /&gt;</p>
<h3>(2) 设置目录权限</h3>
<p>匿名用户的根目录默认是 <code>/var/ftp/pub</code>。</p>
<pre><code>chmod 777 /var/ftp/pub
</code></pre>
<h3>(3) 关闭防火墙与 SELinux</h3>
<pre><code>setenforce 0
systemctl stop firewalld
</code></pre>
<h3>(4) 启动服务</h3>
<pre><code>systemctl start vsftpd
systemctl enable vsftpd
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/ftp/p3.png" alt="p3" /&gt;</p>
<hr />
<h2>3. 测试匿名访问</h2>
<h3>(1) 浏览器测试</h3>
<p>在客户端浏览器输入 <code>ftp://192.241.42.3</code>。</p>
<p>&lt;img src="https://img.103028.xyz/blog/ftp/p4.png" alt="p4" /&gt;</p>
<h3>(2) 命令行测试</h3>
<pre><code>yum install ftp -y
ftp 192.241.42.3
</code></pre>
<p>用户名输入 <code>anonymous</code>，密码为空。</p>
<p>&lt;img src="https://img.103028.xyz/blog/ftp/p5.png" alt="p5" /&gt;</p>
<hr />
<h2>4. 配置本地用户访问</h2>
<h3>(1) 创建测试用户</h3>
<pre><code>useradd reading
passwd reading
</code></pre>
<h3>(2) 修改配置文件</h3>
<pre><code>vi /etc/vsftpd/vsftpd.conf
</code></pre>
<p>确保：</p>
<pre><code>local_enable=YES
write_enable=YES
local_umask=022
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/ftp/p6.png" alt="p6" /&gt;</p>
<h3>(3) 限制用户在自己家目录</h3>
<p>取消注释：</p>
<pre><code>chroot_local_user=YES
allow_writeable_chroot=YES
</code></pre>
<hr />
<h2>5. 常见问题排查</h2>
<ul>
<li><strong>500 OOPS: vsftpd: refusing to run with writable root inside chroot()</strong>: 需要在配置中加入 <code>allow_writeable_chroot=YES</code>。</li>
<li><strong>530 Login incorrect</strong>: 检查密码是否正确，或 <code>/etc/pam.d/vsftpd</code> 配置。</li>
<li><strong>无法上传文件</strong>: 检查 <code>/var/ftp/pub</code> 的目录权限以及 SELinux 状态。</li>
</ul>
<p>&lt;img src="https://img.103028.xyz/blog/ftp/p7.png" alt="p7" /&gt;</p>
]]></content>
    <author><name>槿鸢</name></author>
    <category term="Linux"/>
  </entry>
  <entry>
    <title>Apache服务器安装与配置</title>
    <link href="https://blog.ipox.cn/posts/zh-cn/apache-config/" rel="alternate" type="text/html"/>
    <id>https://blog.ipox.cn/posts/zh-cn/apache-config/</id>
    <published>2025-11-18T15:17:55.000Z</published>
    <updated>2025-11-18T15:17:55.000Z</updated>
    <summary></summary>
    <content type="html"><![CDATA[<h2>步骤一：配置Apache服务器</h2>
<h3>1. 配置网络</h3>
<p>服务器启动DHCP服务器，为客户机分配IP地址：</p>
<pre><code>setenforce 0
systemctl stop firewalld
systemctl start dhcpd
</code></pre>
<p>（客户机）</p>
<p>&lt;img src="https://img.103028.xyz/blog/apac/p1.png" alt="p1" /&gt;</p>
<h3>2. 安装Apache软件包（需要先配置yum本地源）</h3>
<pre><code>yum install httpd -y
</code></pre>
<h3>3. 服务器本机测试</h3>
<p>打开firefox浏览器（没有的话自己用 yum 安装）：</p>
<pre><code>yum install firefox
systemctl start httpd
</code></pre>
<p>然后打开firefox浏览器：</p>
<p>&lt;img src="https://img.103028.xyz/blog/apac/p2.png" alt="p2" /&gt;</p>
<p>在地址栏输入服务器的IP地址进行测试，比如 <code>192.241.42.3</code>：</p>
<p>&lt;img src="https://img.103028.xyz/blog/apac/p4.webp" alt="p4" /&gt;</p>
<p>出现Apache的默认页面，说明安装成功。</p>
<h3>4. 客户机测试</h3>
<p>在客户机（Windows 或 Linux）中打开浏览器，输入服务器的IP地址 <code>192.241.42.3</code>。</p>
<p>&lt;img src="https://img.103028.xyz/blog/apac/p5.png" alt="p5" /&gt;</p>
<hr />
<h2>步骤二：管理Apache服务器</h2>
<h3>1. 建立虚拟目录</h3>
<p>在 <code>/var/www/html</code> 目录下创建 <code>reading</code> 文件夹，并创建 <code>index.html</code>：</p>
<pre><code>mkdir /var/www/html/reading
echo "hello reading!" &gt; /var/www/html/reading/index.html
</code></pre>
<p>在服务器浏览器输入 <code>http://192.241.42.3/reading</code> 进行测试：</p>
<p>&lt;img src="https://img.103028.xyz/blog/apac/p6.png" alt="p6" /&gt;</p>
<h3>2. 建立虚拟主机</h3>
<h4>(1) 基于IP地址的虚拟主机</h4>
<p>在 <code>/etc/httpd/conf.d</code> 目录下创建 <code>vhost.conf</code>：</p>
<pre><code>vi /etc/httpd/conf.d/vhost.conf
</code></pre>
<p>输入以下内容：</p>
<pre><code>&lt;VirtualHost 192.241.42.3:80&gt;
    DocumentRoot /var/www/html/ip3
&lt;/VirtualHost&gt;

&lt;VirtualHost 192.241.42.4:80&gt;
    DocumentRoot /var/www/html/ip4
&lt;/VirtualHost&gt;
</code></pre>
<p>创建对应目录和文件：</p>
<pre><code>mkdir /var/www/html/ip3
mkdir /var/www/html/ip4
echo "IP 192.241.42.3" &gt; /var/www/html/ip3/index.html
echo "IP 192.241.42.4" &gt; /var/www/html/ip4/index.html
</code></pre>
<p><strong>注意：</strong> 服务器需要有两个IP地址。可以使用 <code>ifconfig</code> 或 <code>ip addr</code> 添加子接口：</p>
<pre><code>ifconfig ens33:1 192.241.42.4 netmask 255.255.255.0
</code></pre>
<p>重启服务测试：</p>
<pre><code>systemctl restart httpd
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/apac/p7.png" alt="p7" /&gt;</p>
<h4>(2) 基于主机名的虚拟主机</h4>
<p>修改 <code>/etc/httpd/conf.d/vhost.conf</code>：</p>
<pre><code>&lt;VirtualHost 192.241.42.3:80&gt;
    ServerName www.mypt.com
    DocumentRoot /var/www/html/mypt
&lt;/VirtualHost&gt;

&lt;VirtualHost 192.241.42.3:80&gt;
    ServerName www.reading.com
    DocumentRoot /var/www/html/reading
&lt;/VirtualHost&gt;
</code></pre>
<p>创建目录和文件，并配置 <code>/etc/hosts</code>（或 DNS 服务）：</p>
<pre><code>echo "192.241.42.3 www.mypt.com" &gt;&gt; /etc/hosts
echo "192.241.42.3 www.reading.com" &gt;&gt; /etc/hosts
</code></pre>
<p>测试：</p>
<p>&lt;img src="https://img.103028.xyz/blog/apac/p8.png" alt="p8" /&gt;
&lt;img src="https://img.103028.xyz/blog/apac/p9.png" alt="p9" /&gt;</p>
]]></content>
    <author><name>槿鸢</name></author>
    <category term="Linux"/>
  </entry>
  <entry>
    <title>DNS服务器配置与管理</title>
    <link href="https://blog.ipox.cn/posts/zh-cn/dns-config/" rel="alternate" type="text/html"/>
    <id>https://blog.ipox.cn/posts/zh-cn/dns-config/</id>
    <published>2025-11-11T20:42:25.000Z</published>
    <updated>2025-11-11T20:42:25.000Z</updated>
    <summary></summary>
    <content type="html"><![CDATA[<h1>DNS服务器配置与管理</h1>
<blockquote>
<p>本实验记录了在 Linux 虚拟机上安装与配置 DNS 服务（BIND）的全过程，包括正向与反向解析的设置及常见错误排查。</p>
</blockquote>
<hr />
<h2>一、实验目的</h2>
<ul>
<li>了解 DNS 的基本概念和作用</li>
<li>掌握 DNS 域名解析过程与查询模式</li>
<li>熟悉 BIND 服务器主要配置文件与参数</li>
<li>学会使用 <code>named-checkconf</code>、<code>nslookup</code> 等命令进行测试与调试</li>
</ul>
<hr />
<h2>二、实验环境</h2>
<ul>
<li>一台虚拟机作为服务器端</li>
<li>一台虚拟机作为客户端</li>
<li>软件环境：BIND + BIND-chroot</li>
<li>网络要求：两台主机在同一网段可互相 ping 通</li>
</ul>
<hr />
<h2>三、安装与配置 BIND</h2>
<h3>1️⃣ 安装 DNS 服务</h3>
<pre><code>yum install bind bind-chroot -y
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/dns/pic1.png" alt="pic1" /&gt;</p>
<h3>2️⃣ 修改主配置文件 <code>/etc/named.conf</code></h3>
<p>打开文件：</p>
<pre><code>vim /etc/named.conf
</code></pre>
<p>按照以下步骤修改（带行号的是文件中对应位置）：</p>
<ul>
<li><strong>13 行</strong>：<code>listen-on port 53 { };</code> → 在 <code>{ }</code> 中改为 <code>any;</code></li>
<li><strong>21 行</strong>：<code>allow-query { };</code> → 在 <code>{ }</code> 中改为 <code>any;</code></li>
<li><strong>33 行</strong>：<code>recursion yes;</code></li>
<li><strong>35 行</strong>：<code>dnssec-enable yes;</code></li>
<li><strong>36 行</strong>：<code>dnssec-validation no;</code></li>
<li><strong>59 行</strong>：添加 <code>include "/etc/named.rfc1912.zones";</code></li>
<li><strong>60 行</strong>：添加 <code>include "/etc/named.root.key";</code></li>
</ul>
<p>修改后效果示例：</p>
<pre><code>listen-on port 53 { any; };
allow-query { any; };
recursion yes;
dnssec-enable yes;
dnssec-validation no;

include "/etc/named.rfc1912.zones";
include "/etc/named.root.key";
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/dns/pic2.png" alt="pic2" /&gt;
&lt;img src="https://img.103028.xyz/blog/dns/pic3.png" alt="pic3" /&gt;
&lt;img src="https://img.103028.xyz/blog/dns/pic4.png" alt="pic4" /&gt;</p>
<hr />
<h2>四、配置区域文件</h2>
<h3>1️⃣ 编辑 <code>/etc/named.rfc1912.zones</code></h3>
<p>备份原配置：</p>
<pre><code>cp /etc/named.rfc1912.zones /etc/named.rfc1912.zones.bak
</code></pre>
<p>然后编辑：</p>
<pre><code>vim /etc/named.rfc1912.zones
</code></pre>
<p>在 <strong>42 行</strong> 添加如下内容：</p>
<pre><code>zone "mypt.edu.cn" IN {
    type master;
    file "mypt.edu.cn.zone";
    allow-update { none; };
};

zone "42.241.192.in-addr.arpa" IN {  // 这里网段地址是反向的 192.241.42
    type master;
    file "3.42.241.192.zone";
    allow-update { none; };
};
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/dns/pic5.png" alt="pic5" /&gt;</p>
<hr />
<h2>五、正向解析文件</h2>
<pre><code>cd /var/named
cp -p named.localhost mypt.edu.cn.zone   # cp -p 保留源文件权限
vim mypt.edu.cn.zone
</code></pre>
<p>内容如下：</p>
<pre><code>$TTL 1D
@       IN SOA  @ name.mypt.edu.cn. (
                            0       ; serial
                            1D      ; refresh
                            1H      ; retry
                            1W      ; expire
                            3H )    ; minimum

        IN  NS  name.mypt.edu.cn.
        IN  MX  10 mail.mypt.edu.cn.

name    IN  A   192.241.42.3
mail    IN  A   192.241.42.20
www     IN  A   192.241.42.10
ftp     IN  A   192.241.42.30
gw      IN  A   192.241.42.254
web     IN  CNAME   www.mypt.edu.cn.
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/dns/pic6.png" alt="pic6" /&gt;</p>
<hr />
<h2>六、反向解析文件</h2>
<pre><code>cp -p named.loopback 3.42.241.192.zone
vim /var/named/3.42.241.192.zone
</code></pre>
<p>内容如下：</p>
<pre><code>$TTL 1D
@       IN SOA  @ name.mypt.edu.cn. (
                            0       ; serial
                            1D      ; refresh
                            1H      ; retry
                            1W      ; expire
                            3H )    ; minimum

    IN  NS  name.mypt.edu.cn.
    IN  MX  10 mail.mypt.edu.cn.

3   IN  PTR name.mypt.edu.cn.
10  IN  PTR www.mypt.edu.cn.
20  IN  PTR mail.mypt.edu.cn.
30  IN  PTR ftp.mypt.edu.cn.
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/dns/pic7.png" alt="pic7" /&gt;</p>
<hr />
<h2>七、关闭防火墙与 SELinux（实验用）</h2>
<pre><code>setenforce 0
systemctl stop firewalld
</code></pre>
<hr />
<h2>八、启动与测试</h2>
<h3>1️⃣ 检查配置文件是否正确</h3>
<pre><code>named-checkconf -z
</code></pre>
<p>出现以下输出表示通过：</p>
<pre><code>zone localhost.localdomain/IN: loaded serial 0
zone localhost/IN: loaded serial 0
zone mypt.edu.cn/IN: loaded serial 0
zone 42.241.192.in-addr.arpa/IN: loaded serial 0
</code></pre>
<h3>2️⃣ 启动 DNS 服务</h3>
<pre><code>systemctl restart named
systemctl enable named
systemctl status named
</code></pre>
<p>出现：</p>
<pre><code>Active: active (running)
</code></pre>
<p>表示启动成功 ✅</p>
<hr />
<h2>九、客户端测试</h2>
<ul>
<li>在客户端网络设置中将 DNS 地址改为服务器地址：
<code>192.241.42.3</code></li>
</ul>
<p>&lt;img src="https://img.103028.xyz/blog/dns/pic8.png" alt="pic8" /&gt;</p>
<ul>
<li>使用 <code>nslookup</code> 测试：</li>
</ul>
<pre><code>nslookup 192.241.42.3
</code></pre>
<p>输出：</p>
<pre><code>3.42.241.192.in-addr.arpa   name = name.mypt.edu.cn.
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/dns/pic9.png" alt="pic9" /&gt;</p>
<p>正反向解析均成功 ✅</p>
<hr />
<h2>十、踩坑记录与排查经验</h2>
<p>在调试过程中，我遇到了几种典型错误：</p>
<h3>❶ named 服务启动失败</h3>
<p>查看状态：</p>
<pre><code>systemctl status named
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/dns/pic10.png" alt="pic10" /&gt;</p>
<p>发现报错：</p>
<pre><code>/etc/named.rfc1912.zones:49: missing ';' before 'zone'
</code></pre>
<p>解决方法：上一个 <code>zone</code> 块忘记写分号结尾，加上 <code>};</code> 即可。</p>
<hr />
<h3>❷ 反向区域加载失败</h3>
<p>执行：</p>
<pre><code>named-checkconf -z
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/dns/pic11.png" alt="pic11" /&gt;</p>
<p>输出：</p>
<pre><code>zone 42.241.192.in-addr.arpa/IN: loading from master file failed: file not found
</code></pre>
<p>→ 原因：文件名写错了，改为 <code>3.42.241.192.zone</code> 即可。</p>
<hr />
<h3>❸ has no NS records</h3>
<pre><code>zone 42.241.192.in-addr.arpa/IN: has no NS records
</code></pre>
<p>→ 原因：反向区文件缺少 NS 记录。
→ 解决：添加</p>
<pre><code>IN NS name.mypt.edu.cn.
</code></pre>
<hr />
<h3>❹ connection timed out</h3>
<p>客户端使用 <code>nslookup</code> 时：</p>
<pre><code>connection timed out; no servers could be reached
</code></pre>
<p>→ 解决：</p>
<ul>
<li>
<p>确认防火墙已关闭；</p>
</li>
<li>
<p>确认 <code>/etc/named.conf</code> 中 <code>listen-on port 53 { any; };</code>；</p>
</li>
<li>
<p>重启服务：</p>
<pre><code>systemctl restart named
</code></pre>
</li>
</ul>
<hr />
<h3>✅ 最后验证</h3>
<pre><code>named-checkconf -z
systemctl restart named
systemctl status named
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/dns/pic12.png" alt="pic12" /&gt;</p>
<p>出现：</p>
<pre><code>Active: active (running)
</code></pre>
<p>即表示 DNS 服务器配置成功！</p>
]]></content>
    <author><name>槿鸢</name></author>
    <category term="Linux"/>
  </entry>
  <entry>
    <title>配置与管理DHCP服务器</title>
    <link href="https://blog.ipox.cn/posts/zh-cn/dhcp-config/" rel="alternate" type="text/html"/>
    <id>https://blog.ipox.cn/posts/zh-cn/dhcp-config/</id>
    <published>2025-11-04T18:48:07.000Z</published>
    <updated>2025-11-04T18:48:07.000Z</updated>
    <summary></summary>
    <content type="html"><![CDATA[<h1>配置与管理 DHCP 服务器</h1>
<h2>一、配置两台虚拟机的网络</h2>
<h3>1.1 设置网络连接模式</h3>
<p>将两台虚拟机的网络连接模式均设置为"<strong>仅主机模式（Host-Only）</strong>"。</p>
<p>&lt;img src="https://img.103028.xyz/blog/dhcp/图片1.png" alt="网络连接模式设置" /&gt;</p>
<h3>1.2 配置服务端静态 IP 地址</h3>
<p>在服务端虚拟机中手动配置静态 IP 地址：</p>
<ul>
<li><strong>IP 地址</strong>：192.241.编号.3</li>
<li><strong>网关地址</strong>：192.241.254.1</li>
<li><strong>子网掩码</strong>：255.255.255.0</li>
</ul>
<p>&lt;img src="https://img.103028.xyz/blog/dhcp/图片2.png" alt="静态IP配置" /&gt;</p>
<hr />
<h2>二、配置 DHCP 服务器</h2>
<h3>2.1 安装 DHCP 服务</h3>
<p>使用系统包管理工具安装 DHCP 服务：</p>
<pre><code>yum install dhcp
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/dhcp/图片3.png" alt="安装DHCP服务" /&gt;</p>
<h3>2.2 复制配置模板文件</h3>
<p>将 DHCP 配置模板文件复制到 <code>/etc/dhcp</code> 目录下：</p>
<pre><code>cp /usr/share/doc/dhcp*/dhcpd.conf.example /etc/dhcp/dhcpd.conf
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/dhcp/图片4.png" alt="复制配置文件" /&gt;</p>
<h3>2.3 修改 DHCP 主配置文件</h3>
<p>编辑配置文件：</p>
<pre><code>vim /etc/dhcp/dhcpd.conf
</code></pre>
<p>修改以下内容：</p>
<pre><code>subnet 192.241.编号.0 netmask 255.255.255.0 {
    range 192.241.编号.10 192.241.编号.100;   # 指定 DHCP 分配的 IP 地址范围
    option routers 192.241.编号.3;            # 指定客户端的默认网关地址
}
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/dhcp/图片5.png" alt="配置DHCP文件" /&gt;</p>
<h3>2.4 启动 DHCP 服务并设置开机自启</h3>
<pre><code>systemctl restart dhcpd
systemctl enable dhcpd
</code></pre>
<p>同时关闭 SELinux 和防火墙以避免网络阻断：</p>
<pre><code>setenforce 0
systemctl stop firewalld
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/dhcp/图片6.png" alt="启动DHCP服务" /&gt;</p>
<hr />
<h2>三、客户端配置</h2>
<h3>3.1 编辑虚拟网络编辑器</h3>
<p>在 VMware 虚拟网络编辑器中，关闭 VMnet1 和 VMnet2 的 DHCP 服务。</p>
<p>&lt;img src="https://img.103028.xyz/blog/dhcp/图片7.png" alt="关闭VMware DHCP" /&gt;</p>
<h3>3.2 验证客户端自动获取 IP</h3>
<p>启动客户端虚拟机后，查看是否自动获取到 IP 地址。</p>
<p>&lt;img src="https://img.103028.xyz/blog/dhcp/图片8.png" alt="客户端获取IP" /&gt;</p>
<h3>3.3 测试网络连通性</h3>
<pre><code>ping 192.241.编号.3
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/dhcp/图片9.png" alt="测试网络连通性" /&gt;</p>
]]></content>
    <author><name>槿鸢</name></author>
    <category term="Linux"/>
  </entry>
  <entry>
    <title>配置与管理Samba服务器</title>
    <link href="https://blog.ipox.cn/posts/zh-cn/samba-config/" rel="alternate" type="text/html"/>
    <id>https://blog.ipox.cn/posts/zh-cn/samba-config/</id>
    <published>2025-10-29T20:01:04.000Z</published>
    <updated>2025-10-29T20:01:04.000Z</updated>
    <summary></summary>
    <content type="html"><![CDATA[<p>今天老师搞了这个作业,因为我用的系统和老师用的不一样,就干脆写一个免得忘了。</p>
<h2>实验环境</h2>
<ul>
<li>两台 CentOS 7 虚拟机(一台服务端,一台客户端)</li>
<li>服务端 IP: <code>192.241.42.3</code></li>
<li>客户端 IP: <code>192.241.42.101</code></li>
</ul>
<h2>什么是 Samba 服务</h2>
<p>Samba 是一个在 Linux 和 UNIX 系统上实现 <strong>SMB(Server Message Block)协议</strong>的免费软件。</p>
<h2>安装 Samba 包</h2>
<h3>配置本地源</h3>
<h4>检查虚拟机是否挂载了 CentOS 系统镜像</h4>
<p>&lt;img src="https://img.103028.xyz/blog/samba/image73f4d30238a7dd5c.webp" alt="挂载光盘1" /&gt;
&lt;img src="https://img.103028.xyz/blog/samba/imageedbc9988b26d68ee.webp" alt="挂载光盘2" /&gt;
&lt;img src="https://img.103028.xyz/blog/samba/image93d41717b46e536e.webp" alt="挂载光盘3" /&gt;</p>
<h4>创建挂载 CentOS 系统镜像的文件夹</h4>
<pre><code>su
cd /etc/yum.repos.d
mkdir bak
mv CentOS-*.repo bak
cp bak/CentOS-Media.repo ./
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/samba/image2916a3fa816af4fb.webp" alt="创建挂载文件夹" /&gt;</p>
<h4>编辑源配置</h4>
<pre><code>vi CentOS-Media.repo
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/samba/imagea2afcd29729c11bd.webp" alt="编辑源配置" /&gt;</p>
<h4>挂载安装盘</h4>
<pre><code>mkdir /mnt/cdrom
mount /dev/sr0 /mnt/cdrom
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/samba/imagec5218a51e3132205.webp" alt="挂载安装盘" /&gt;</p>
<h4>清除缓存</h4>
<pre><code>yum clean all
yum makecache
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/samba/image8d939730e064e56e.webp" alt="清除缓存" /&gt;</p>
<h3>安装 Samba</h3>
<pre><code>yum install samba -y
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/samba/imagee2ed3edb6945b8f2.webp" alt="安装samba" /&gt;</p>
<h3>启动 Samba 并设置开机启动</h3>
<pre><code>systemctl start smb;systemctl enable smb
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/samba/image74a7fb44be66b6c3.webp" alt="启动samba" /&gt;</p>
<h2>建立 share 共享文件夹</h2>
<pre><code>useradd reading
passwd reading
mkdir /home/reading/share
chmod 777 /home/reading/share
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/samba/imagee5e8109a7d560970.webp" alt="创建用户" /&gt;</p>
<h2>备份和修改 Samba 配置</h2>
<pre><code>cd /etc/samba
cp smb.conf smb.conf.bak
vi /etc/samba/smb.conf
</code></pre>
<p>在最下面添加:</p>
<pre><code>[share]
        comment = share
        path = /home/reading/share
        read only = No
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/samba/-2025-10-29-205819d9cac5a91bfbf576.png" alt="修改配置" /&gt;</p>
<h2>设置 Samba 账号</h2>
<pre><code>smbpasswd -a reading
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/samba/imageb6c562d7bdfc6041.webp" alt="设置samba账号" /&gt;</p>
<h2>配置防火墙,关闭 SELinux</h2>
<pre><code>firewall-cmd --add-service samba --permanent
firewall-cmd --reload
setenforce 0
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/samba/imaged81f8e5f3d758238.webp" alt="配置防火墙" /&gt;</p>
<h2>测试文件共享</h2>
<h3>1. 查看共享目录列表</h3>
<pre><code>smbclient -L 192.241.42.3 -U reading%123456
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/samba/imagefce4e11a819aa38a.webp" alt="查看共享目录" /&gt;</p>
<h3>2. 访问 SMB 服务器</h3>
<pre><code>smbclient //192.241.42.3/share -U reading%123456
mkdir 1
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/samba/image8ff615aaf59a2e1e.webp" alt="访问smb服务器" /&gt;</p>
<h3>验证是否成功创建</h3>
<pre><code>ll /home/reading/share
</code></pre>
<p>&lt;img src="https://img.103028.xyz/blog/samba/imagef50b111a70c4bbd7.webp" alt="验证创建" /&gt;</p>
]]></content>
    <author><name>槿鸢</name></author>
    <category term="Linux"/>
  </entry>
  <entry>
    <title>Archlinux + Windows 双系统安装笔记</title>
    <link href="https://blog.ipox.cn/posts/zh-cn/archlinux-install/" rel="alternate" type="text/html"/>
    <id>https://blog.ipox.cn/posts/zh-cn/archlinux-install/</id>
    <published>2025-04-20T19:54:16.000Z</published>
    <updated>2025-04-20T19:54:16.000Z</updated>
    <summary></summary>
    <content type="html"><![CDATA[<p>一直馋arch，但是不敢装，怕自己手残搞寄了，得亏得到高人指点，装好了，现在写个笔记避免忘记（</p>
<p><strong>注意:</strong></p>
<ul>
<li><strong>先备份 Windows 和重要文件！</strong></li>
<li><strong>操作有风险，请注意。</strong></li>
<li><strong>设备名可能不同，</strong> 比如硬盘分区名 (<code>/dev/nvme0n1pX</code>, <code>/dev/sdaX</code>)，根据你自己的 <code>fdisk -l</code> 结果替换。</li>
</ul>
<hr />
<h2>1. 准备镜像</h2>
<ol>
<li><strong>下载 ISO:</strong>
<ul>
<li>去官方或者镜像站 (我用清华源: <a href="https://mirrors.tuna.tsinghua.edu.cn/archlinux/iso/latest/">https://mirrors.tuna.tsinghua.edu.cn/archlinux/iso/latest/</a>) 下载最新的 Arch Linux ISO 文件。</li>
</ul>
</li>
<li><strong>写入 U 盘:</strong>
<ul>
<li>把 ISO 文件弄到 U 盘里。</li>
<li>我用的 Ventoy，直接拷进去就行。也可以用 Rufus 或 BalenaEtcher 刻录。</li>
</ul>
</li>
</ol>
<hr />
<h2>2. 分区 (Windows 环境下)</h2>
<ol>
<li><strong>打开磁盘管理:</strong>
<ul>
<li>Windows 里右键开始菜单 -&gt; "磁盘管理"。</li>
</ul>
</li>
<li><strong>压缩卷:</strong>
<ul>
<li>找个盘，右键 -&gt; "压缩卷"，腾出空间给 Arch。</li>
</ul>
</li>
<li><strong>创建分区 (不格式化):</strong>
<ul>
<li>在"未分配"空间上右键 -&gt; "新建简单卷"。</li>
<li><strong>建 Boot 分区:</strong> 大小给 <code>1G</code> (1024 MB)。<strong>不分配盘符，不格式化。</strong></li>
<li><strong>建 Root 分区:</strong> 把剩下空间都给它 (比如我给了 200G)。<strong>不分配盘符，不格式化。</strong></li>
<li><strong>EFI 分区:</strong> Windows 自带的那个，不用动。</li>
</ul>
</li>
</ol>
<hr />
<h2>3. 安装 Arch (基础部分)</h2>
<ol>
<li><strong>U 盘启动:</strong>
<ul>
<li>重启进 BIOS (按 <code>F2</code>, <code>F12</code>, <code>DEL</code> 等)，<strong>关掉 <code>Secure Boot</code></strong>，设置 U 盘启动优先。</li>
</ul>
</li>
<li><strong>识别分区:</strong>
<ul>
<li>进 Arch 安装环境后，执行:<pre><code>fdisk -l
# 或者 lsblk
</code></pre>
</li>
<li><strong>记下你的 EFI 分区、Boot 分区、Root 分区的名字</strong> (比如我的是 <code>/dev/nvme0n1p1</code>, <code>/dev/nvme0n1p5</code>, <code>/dev/nvme0n1p6</code>)。后面命令要用。</li>
</ul>
</li>
<li><strong>格式化分区:</strong>
<ul>
<li><strong>把下面的设备名换成你自己的!!!</strong><pre><code># Boot 分区格式化成 ext4
mkfs.ext4 /dev/nvme0n1p5

# Root 分区格式化成 Btrfs (-f 是强制)
mkfs.btrfs -f /dev/nvme0n1p6
</code></pre>
</li>
</ul>
</li>
<li><strong>挂载分区:</strong>
<ul>
<li>按顺序挂载。<pre><code># 挂载 Root 分区 (Btrfs) 到 /mnt，开了 zstd 压缩
mount -t btrfs -o compress=zstd:5 /dev/nvme0n1p6 /mnt

# 创建挂载点
mkdir -p /mnt/boot/efi

# 挂载 Boot 分区 (ext4) 到 /mnt/boot
mount -t ext4 /dev/nvme0n1p5 /mnt/boot

# 挂载 EFI 分区到 /mnt/boot/efi
mount /dev/nvme0n1p1 /mnt/boot/efi
</code></pre>
</li>
</ul>
</li>
<li><strong>装基本系统:</strong>
<ul>
<li><strong>注意:</strong> 这一步需要基础网络连接才能下载包。<pre><code># 只安装最基础的包、内核和固件
pacstrap /mnt base base-devel linux linux-firmware
</code></pre>
</li>
</ul>
</li>
<li><strong>生成 fstab:</strong>
<ul>
<li>生成分区挂载配置文件。<pre><code># -U 用 UUID 识别分区，&gt;&gt; 追加到新系统 fstab 文件
genfstab -U /mnt &gt;&gt; /mnt/etc/fstab
# 可以 cat /mnt/etc/fstab 检查下
</code></pre>
</li>
</ul>
</li>
<li><strong>Chroot 进去:</strong>
<ul>
<li>切换到新安装的系统环境进行配置。<pre><code>arch-chroot /mnt
</code></pre>
</li>
</ul>
</li>
</ol>
<hr />
<h2>4. 配置 Arch (Chroot 环境里)</h2>
<p>现在在新系统环境里操作。</p>
<ol>
<li>
<p><strong>联网:</strong></p>
<ul>
<li>Chroot 进来后，需要在这里配置网络才能继续装包和更新。</li>
<li>可以使用 <code>iwctl</code> 或其他工具连接 WiFi，或者手机USB网络共享也可以用。</li>
<li><strong>确保网络通畅</strong>才能进行下一步。</li>
</ul>
</li>
<li>
<p><strong>换源:</strong></p>
<ul>
<li><strong>建议换国内源，</strong> 提升后续下载速度。<pre><code># 用自带的 vi 编辑器 (此时可能还没装 nano)
vi /etc/pacman.d/mirrorlist
# 在文件最顶上，加一行清华源 (或者其他国内源)
# Server = https://mirrors.tuna.tsinghua.edu.cn/archlinux/$repo/os/$arch
# 保存退出 (:wq 保存退出 vi)

# 刷新一下软件包数据库，让新源生效
pacman -Syy
</code></pre>
</li>
</ul>
</li>
<li>
<p><strong>安装常用工具:</strong></p>
<ul>
<li>安装 nano/vim 编辑器、NetworkManager 网络管理器、btrfs-progs 工具（如果根分区是 btrfs）<pre><code>pacman -S nano vim networkmanager btrfs-progs
</code></pre>
</li>
</ul>
</li>
<li>
<p><strong>设置时区:</strong></p>
<pre><code># 让硬件时钟用本地时间，避免 Windows 时间错乱
timedatectl set-local-rtc 1 --adjust-system-clock
# 我装完之后发现Windows和linux时间不一致，所以装好之后才搞了这个，记得进系统在日期和时间那打开自动设置日期和时间，然后应该就没问题了
</code></pre>
</li>
<li>
<p><strong>设置 Locale (语言):</strong></p>
<pre><code># 编辑 locale.gen 
vi /etc/locale.gen
# 把需要的语言 (如 en_US.UTF-8, zh_CN.UTF-8) 前面的 # 去掉
# 保存退出后执行:
locale-gen
# 设置系统默认语言
echo "LANG=zh_CN.UTF-8" &gt; /etc/locale.conf
</code></pre>
</li>
<li>
<p><strong>设置主机名:</strong></p>
<pre><code>hostnamectl set-hostname 主机名
# (可选) 编辑 hosts 文件，添加主机名映射
# nano /etc/hosts
# 加上 127.0.1.1   你的主机名.localdomain  你的主机名
</code></pre>
</li>
<li>
<p><strong>启用网络服务:</strong></p>
<ul>
<li>让 NetworkManager 开机自动运行。<pre><code>systemctl enable NetworkManager
</code></pre>
</li>
</ul>
</li>
<li>
<p><strong>配置 Initramfs (Btrfs 需要):</strong></p>
<ul>
<li>如果 Root 分区是 Btrfs，需要这步。<pre><code># 编辑 mkinitcpio.conf
nano /etc/mkinitcpio.conf
# 在 HOOKS=(...) 行的 filesystems 后面加上 btrfs
# 保存退出后执行:
mkinitcpio -P
</code></pre>
</li>
<li><strong>Ext4 Root 分区跳过此步。</strong></li>
</ul>
</li>
<li>
<p><strong>设置 Root 密码 (可选):</strong></p>
<pre><code>passwd
</code></pre>
</li>
<li>
<p><strong>安装 GRUB (启动引导):</strong></p>
<pre><code># 装 GRUB 相关包
pacman -S grub efibootmgr os-prober
# 安装 GRUB 到 EFI 分区
grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id="Arch Linux"
# 配置 GRUB 检测其他系统 (如 Windows)
vi /etc/default/grub
# 找到 #GRUB_DISABLE_OS_PROBER=false，去掉 #
# 保存退出后生成 GRUB 配置
grub-mkconfig -o /boot/grub/grub.cfg
</code></pre>
</li>
<li>
<p><strong>创建普通用户:</strong></p>
<pre><code># 把 "用户名" 换成你的
useradd -m -G wheel 用户名
# 给用户设置密码
passwd 用户名
# 允许 wheel 组用户使用 sudo
vi /etc/sudoers
# 找到 # %wheel ALL=(ALL:ALL) ALL，去掉 #
# 保存退出
</code></pre>
</li>
<li>
<p><strong>安装桌面环境和软件 (我的选择):</strong></p>
<pre><code># 装 KDE Plasma 和常用应用、SDDM 登录器
pacman -S plasma kde-applications sddm
# 装 中日韩字体
pacman -S noto-fonts-cjk
# (可选) 装蓝牙工具并启用服务
pacman -S bluez bluez-utils
systemctl enable bluetooth
</code></pre>
</li>
<li>
<p><strong>启用登录界面:</strong></p>
<pre><code># 让 SDDM 开机启动
systemctl enable sddm
</code></pre>
</li>
<li>
<p><strong>配置 DNS (可选):</strong></p>
<ul>
<li>如果想手动指定 DNS。<pre><code># 编辑 systemd-resolved 配置
sudo nano /etc/systemd/resolved.conf
# 在 [Resolve] 下面取消注释并修改 DNS= 和 FallbackDNS=
# DNS=8.8.8.8 1.1.1.1
# FallbackDNS=9.9.9.9
# 保存退出 (可能需要 systemctl restart systemd-resolved 生效)
</code></pre>
</li>
</ul>
</li>
</ol>
<hr />
<h2>5. 完成与重启</h2>
<ol>
<li><strong>退出 Chroot:</strong><pre><code>exit
</code></pre>
</li>
<li><strong>卸载分区:</strong><pre><code>umount -R /mnt
</code></pre>
</li>
<li><strong>重启:</strong><pre><code>reboot
</code></pre>
</li>
</ol>
<hr />
<h2>6. 重启之后</h2>
<ul>
<li>进 GRUB 菜单选 "Arch Linux" 启动。</li>
<li>用你创建的用户名和密码登录。</li>
<li>进系统后先联网，更新系统： <code>sudo pacman -Syu</code>。</li>
<li>之后就是装软件、配置输入法等等。</li>
<li>后续配置就可以参考(<a href="https://blog.archlinux.tech">https://blog.archlinux.tech</a>)。</li>
<li>如果进系统有些地方不是中文，可能需要 <code>sudo nano /etc/locale.gen</code> 把所有中文相关项取消注释，然后 <code>sudo locale-gen</code> 再重启试试。也检查下 KDE 自己的区域语言设置。</li>
</ul>
]]></content>
    <author><name>槿鸢</name></author>
    <category term="Linux"/>
  </entry>
  <entry>
    <title>用NapCat+Yunzai搭建一个QQ机器人并接入Gemini</title>
    <link href="https://blog.ipox.cn/posts/zh-cn/qq-bot-gemini/" rel="alternate" type="text/html"/>
    <id>https://blog.ipox.cn/posts/zh-cn/qq-bot-gemini/</id>
    <published>2025-02-12T12:44:43.000Z</published>
    <updated>2025-02-12T12:44:43.000Z</updated>
    <summary></summary>
    <content type="html"><![CDATA[<h2>安装依赖</h2>
<pre><code>sudo apt install nodejs redis chromium
</code></pre>
<h2><a href="https://napneko.github.io/guide/start-install">安装Napcat</a></h2>
<p>这里用debian进行安装，下面这个脚本支持Ubuntu 20+/Debian 10+/Centos9</p>
<pre><code>curl -o napcat.sh https://nclatest.znin.net/NapNeko/NapCat-Installer/main/script/install.sh &amp;&amp; sudo bash napcat.sh --docker n --cli n
</code></pre>
<h2>安装<a href="https://github.com/TimeRainStarSky/Yunzai">TRSS_Yunzai</a></h2>
<p>安装好NapCat之后，我们就来安装Yunzai，因为是在Debian上安装，所以只能手动安装了</p>
<h3>Git Clone 项目</h3>
<p>请根据网络情况选择使用 GitHub 或 Gitee 安装</p>
<pre><code>git clone --depth 1 https://github.com/TimeRainStarSky/Yunzai
git clone --depth 1 https://gitee.com/TimeRainStarSky/Yunzai
</code></pre>
<pre><code>cd Yunzai
</code></pre>
<h3>安装 pnpm 和依赖</h3>
<pre><code>npm i -g pnpm
pnpm i
</code></pre>
<h3>前台运行</h3>
<table>
<thead>
<tr>
<th>操作</th>
<th>命令</th>
</tr>
</thead>
<tbody>
<tr>
<td>启动</td>
<td><code>node .</code></td>
</tr>
<tr>
<td>停止</td>
<td><code>node . stop</code></td>
</tr>
</tbody>
</table>
<h3>使用 pm2 后台运行</h3>
<table>
<thead>
<tr>
<th>操作</th>
<th>命令</th>
</tr>
</thead>
<tbody>
<tr>
<td>启动</td>
<td><code>pnpm start</code></td>
</tr>
<tr>
<td>停止</td>
<td><code>pnpm stop</code></td>
</tr>
<tr>
<td>日志</td>
<td><code>pnpm log</code></td>
</tr>
</tbody>
</table>
<h3>开机自启</h3>
<pre><code>pnpm start
pnpm pm2 save
pnpm pm2 startup
</code></pre>
<h2>NapCat和Yunzai安装好之后，我们就可以启动了</h2>
<h2>启动Yunzai</h2>
<p>进入Yunzai安装目录</p>
<pre><code>cd /root/Yunzai
</code></pre>
<p>启动Yunzai</p>
<pre><code>node .
</code></pre>
<p>启动好之后留意日志里面带有<code>[websocket]</code>的一排 比如<code>[WebSocket ]连接地址 &lt;：ws://localhost:2536/[ComWeChat,GSUIDCore,OPQBot,OneBotv11,go-cqhttp]</code> 虽然说其实只用记住端口是2536就是了（）</p>
<h2>启动NapCat</h2>
<pre><code>xvfb-run -a qq --no-sandbox -q [机器人QQ]
</code></pre>
<p>这一步其实就是登上机器人qq</p>
<h2>通过 WebUI 配置，连接到Yunzai</h2>
<p>这里引用官方文档里面的说明：</p>
<blockquote>
<p>如果你已经启动了 NapCat, 并且有多于 1 个开放端口，则可以通过 WebUI 进行配置.</p>
<p>默认地址为 0.0.0.0, 即监听所有地址. 当配置了不可用的地址时 WebUI 将被禁用.</p>
<p>默认端口为 6099.</p>
<p>当端口被设置为 0 时将禁用 WebUI.</p>
<p>当端口被占用时, 会自动对端口 +1, 直到找到可用端口 (最多尝试 100 次, 失败则会禁用 WebUI), 端口号会在启动日志中显示.</p>
<p>启动后可在启动日志中看到形如 <code>[WebUi] WebUi Local Panel Url: http://127.0.0.1:6099/webui?token=xxxx</code> 的 token 信息.</p>
<p>也可打开 <code>webui.json</code> 文件，在其中找到token。(使用 NapCat.Installer - Linux 一键脚本安装时, 该文件位于 <code>/opt/QQ/resources/app/app_launcher/napcat/config/webui.json</code>)</p>
</blockquote>
<p><code>webui.json</code></p>
<pre><code>{
    "host": "0.0.0.0", // WebUI 监听地址
    "port": 6099, // WebUI 端口
    "token": "xxxx", // 登录密钥, 默认是自动生成的随机登录密码
    "loginRate": 3, // 每分钟登录次数限制
}
</code></pre>
<p>访问 <code>http://ip:port/webui/</code>，然后进行以下操作:</p>
<ol>
<li>进入 QQ 登录, 点击 QRCode 进行二维码登录.</li>
<li>登录成功后, 即可进入网络配置, 点击 "新建" 创建对应的服务器或客户端.(如果是公网部署, 请务必启用 Token)</li>
<li>请在创建时勾选保存时启用, 或者创建完成后手动启用.</li>
<li>访问 <code>http://ip:port</code> 检查端口是否正常. (此处的 port 指 2 中配置的端口, 请不要与 WebUI 端口混淆)"</li>
</ol>
<p>进去之后，网络配置&gt;新建&gt;websocket客户端，名称随意，url改成<code>ws://localhost:2536/OneBotv11</code>，然后启用并保存</p>
<p>&lt;img src="https://img.picgo.net/2025/02/12/image7c64ed7c39454800.png" alt="Image of image7c64ed7c39454800" /&gt;</p>
<h2>安装插件</h2>
<ol>
<li>
<p><strong>设置主人QQ</strong></p>
<p>打开你的QQ,给机器人私聊发送 <code>#设置主人</code> 然后会提醒你输入验证码，这个时候你就需要去看Yunzai的控制台了，里面会有一串验证码，找到发给它之后就完成了</p>
</li>
<li>
<p><strong>安装锅巴插件</strong></p>
<p>锅巴插件能方便你安装和管理插件，对机器人私聊发送 <code>#安装Guoba-Plugin</code> 执行之后机器人会自动安装插件并重启，重启成功后会发送消息</p>
<p>重启成功后，发送 <code>#锅巴登录</code> 机器人会发送webui的地址 本机用 <code>localhost</code> 那个地址打开 ，局域网设备打开机器人发的内网地址的第一个链接即可</p>
</li>
<li>
<p><strong>安装并配置ChatGPT插件</strong></p>
<p>进入webui之后，打开 插件管理&gt;未安装 搜索 <code>ChatGPT-Plugin</code> 并安装 机器人重启成功后，刷新网页打开 插件配置&gt;ChatGPT-Plugin 找到Gemini配置的位置，填入你申请的Gemini Api (没申请去<a href="https://aistudio.google.com/apikey">Gemini API 申请地址</a>) 模型名称填最新的2.0 Flash模型： <code>gemini-2.0-flash-thinking-exp-01-21</code> 然后可以去插件的文档(<a href="https://www.yunzai.chat/">Yunzai 插件文档</a>)那看看还有什么有意思的也能改改</p>
</li>
<li>
<p><strong>和机器人对话</strong></p>
<p>和机器人私聊发送 <code>#chatgpt切换gemini</code></p>
</li>
</ol>
]]></content>
    <author><name>槿鸢</name></author>
    <category term="日常"/>
  </entry>
</feed>
