2602-(perfmon.msc)Windows定位和排查CPU占用高进程问题

perfmon.msc(定位CPU问题)

perfmon.msc(性能监视器)定位 Windows CPU 问题,核心是通过添加关键计数器实时监控 / 日志分析,先判断 CPU
瓶颈类型,再定位到进程 / 线程,最后结合 JDK 工具深挖 Java 问题,以下是精准可落地的完整流程

二、添加 CPU 核心计数器(必选)

这是判断 CPU 瓶颈的核心步骤,优先添加以下计数器,覆盖整体、用户 / 内核、进程、线程与中断维度:

计数器路径 作用 正常阈值 异常判断
\Processor(*)% Processor Time 整体 CPU 使用率(* 含所有核心,_Total 为总和) < 70% 持续 > 80% 为瓶颈,>90% 严重
\Processor(*)% User Time 用户态 CPU(如 Java 应用) < 50% 持续 > 80% 多为应用代码问题
\Processor(*)% Privileged Time 内核态 CPU(如驱动、系统调用) < 30% 持续 > 50% 多为驱动 / 系统服务问题
\Process(*)% Processor Time 单个进程 CPU 占用(筛选 java.exe/javaw.exe) 占比高的进程优先排查
\Thread(*)% Processor Time 单个线程 CPU 占用(需指定进程 PID) 定位进程内高 CPU 线程
\System\Processor Queue Length CPU 等待队列长度 每核心 < 2 持续 > 2 且 CPU 高,说明调度拥堵
\Processor(*)% Interrupt Time 中断占用时间 < 5% 持续 > 10% 多为硬件 / 驱动问题

添加操作步骤

  1. 右键性能监视器图表→「添加计数器」;
  2. 在弹出窗口中,依次展开上述计数器类别,选中目标计数器→「添加」→「确定」;
  3. 若需监控特定 Java 进程,在 \Process 类别中筛选 PID 对应的 java.exe/javaw.exe。

通过arthas thread -n 5 指定进程PID查看

1
2
3
4
5
6
7
8
9
10
11
12
"flow-execute290488" Id=930149 cpuUsage=46.42% deltaTime=93ms time=31828ms RUNNABLE
at com.oracle.truffle.api.library.LibraryFactory.dispatch(LibraryFactory.java:548)
at com.oracle.truffle.api.library.LibraryFactory.getUncached(LibraryFactory.java:396)
at com.oracle.truffle.api.interop.InteropLibraryGen$UncachedDispatch.getArraySize(InteropLibraryGen.java:7348)
at com.oracle.truffle.host.HostProxy.getMembers(HostProxy.java:271)
at com.oracle.truffle.host.HostProxyGen$InteropLibraryExports$Cached.getMembers(HostProxyGen.java:941)
at com.oracle.truffle.api.interop.InteropLibrary.getMembers(InteropLibrary.java:734)
at com.oracle.truffle.polyglot.PolyglotMap$Cache$EntrySet.doCached(PolyglotMap.java:589)
at com.oracle.truffle.polyglot.PolyglotMapFactory$CacheFactory$EntrySetNodeGen.executeImpl(PolyglotMapFactory.java:323)
at com.oracle.truffle.polyglot.HostToGuestRootNode.execute(HostToGuestRootNode.java:124)
at com.oracle.truffle.api.impl.DefaultCallTarget.call(DefaultCallTarget.java:118)
at com.oracle.truffle.polyglot.PolyglotMap.entrySet(PolyglotMap.java:131)

jenkins配置保存-重启无效(XML保存异常)-Plugins(ssh-server)-保存了,重启又还原了,是怎么回事.


异常日志 tail -f /jenkins/apache-tomcat-10.1.50/logs/catalina.out -n500

这个密码 看起来是明文,而其他配置都是加密格式({AQAAABAAAA…})!
根本问题:这个明文密码可能包含不可见字符,或者在保存时被错误解析,导致产生了 0x00 空字符。

1
2
3
4
05-Feb-2026 14:42:19.252 警告 [Handling POST /jenkins/manage/configSubmit from 192.168.0.75 : http-nio-8080-exec-1] hudson.model.Descriptor.save Failed to save /jenkins/jenkins_home/jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml
java.io.IOException: java.lang.RuntimeException: Failed to serialize jenkins.plugins.publish_over_ssh.descriptor.BapSshPublisherPluginDescriptor#hostConfigurations for class jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin$Descriptor
at hudson.XmlFile.write(XmlFile.java:223)
at hudson.model.Descriptor.save(Descriptor.java:964)
1
2
3
4
5
6
java.io.IOException: java.lang.RuntimeException: Failed to serialize jenkins.plugins.publish_over_ssh.descriptor.BapSshPublisherPluginDescriptor#hostConfigurations for class jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin$Descriptor
at hudson.XmlFile.write(XmlFile.java:223)
at hudson.model.Descriptor.save(Descriptor.java:964)
at PluginClassLoader for publish-over-ssh//jenkins.plugins.publish_over_ssh.descriptor.BapSshPublisherPluginDescriptor.configure(BapSshPublisherPluginDescriptor.java:158)
at jenkins.model.Jenkins.configureDescriptor(Jenkins.java:4049)
at jenkins.model.Jenkins.doConfigSubmit(Jenkins.java:4013)

Caused by: com.thoughtworks.xstream.io.StreamException: Invalid character 0x0 in XML stream
Invalid character 0x0 表示 SSH 配置的代理密码字段 (proxyPassword) 包含空字符(NULL character),这是 XML 不允许的字符!
这不是权限问题,而是 数据污染问题!

🔍 问题分析

错误链:
Jenkins 尝试保存 Publish Over SSH 配置
序列化 BapSshHostConfiguration#proxyPassword 字段时失败
密码中包含 0x0(空字符),XML 写入器拒绝写入
导致整个配置文件无法保存
可能原因:
之前配置的代理密码包含特殊字符或空字符
配置文件损坏,密码字段被污染
从其他环境复制配置时编码问题

这个密码 看起来是明文,而其他配置都是加密格式({AQAAABAAAA…})!
根本问题:这个明文密码可能包含不可见字符,或者在保存时被错误解析,导致产生了 0x00 空字符。

看到了关键信息!您是用 Tomcat 启动 Jenkins,而且注意到这个参数:

-Dorg.apache.catalina.security.SecurityListener.UMASK=0027
这就是问题根源!

1
2
3
4
5
6
7
ps -ef | grep jenkins
avahi 677 1 0 13:35 ? 00:00:01 avahi-daemon: running [jenkins171.local]
root 8020 1 62 14:16 ? 00:00:53 /usr/local/jdk//bin/java -Djava.util.logging.config.file=/jenkins/apache-tomcat-10.1.50/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Xmx14G -Djava.awt.headless=true -DJENKINS_HOME=/jenkins/jenkins_home -Duser.timezone=GMT+08 -Difile.encoding=utf-8 -Dorg.jenkinsci.plugins.gitclient.Git.timeOut=1200 -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dsun.io.useCanonCaches=false -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-opens=java.base/java.util=ALL-UNNAMED --add-opens=java.base/java.util.concurrent=ALL-UNNAMED --add-opens=java.rmi/sun.rmi.transport=ALL-UNNAMED -DJENKINS_HOME=/jenkins/jenkins_home -classpath /jenkins/apache-tomcat-10.1.50/bin/bootstrap.jar:/jenkins/apache-tomcat-10.1.50/bin/tomcat-juli.jar -Dcatalina.base=/jenkins/apache-tomcat-10.1.50 -Dcatalina.home=/jenkins/apache-tomcat-10.1.50 -Djava.io.tmpdir=/jenkins/apache-tomcat-10.1.50/temp org.apache.catalina.startup.Bootstrap start
ubuntu 8159 3314 0 14:17 pts/1 00:00:00 grep --color=auto jenkins

-Dorg.apache.catalina.security.SecurityListener.UMASK=0027
-Dorg.apache.catalina.security.SecurityListener.UMASK=0027

问题分析
UMASK=0027 是 Tomcat 的安全机制,它会:
覆盖 root 用户的默认 umask(通常是 0022)
强制新创建文件的权限为 640(即 -rw-r—–)
移除其他用户的写权限
虽然进程是 root,但 Jenkins 在写入配置文件时,Tomcat 的安全监听器会强制应用这个 umask,导致:
文件权限被限制为 640
Jenkins 无法再次写入(因为实际运行中 Jenkins 会检查并尝试重写)


查看文件是否被锁定

1
2
3
4
5
6
7
8
# 检查文件是否被其他进程占用
lsof /jenkins/jenkins_home/jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml

# 检查文件属性(是否有 immutable 标志)
lsattr /jenkins/jenkins_home/jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml

# 如果有 i 标志,移除它
chattr -i /jenkins/jenkins_home/jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml

查看SSH-Server配置是否生效 Publish Over SSH

1
sudo cat /jenkins/jenkins_home/jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml | grep -A5 "jenkins(prod-online)"

查询配置文件权限

1
2
3
4
5
6
7
ls -lh *sh*
-rwxr-x--- 1 root root 366 8月 18 2022 com.dabsquared.gitlabjenkins.GitLabPushTrigger.xml
-rw-r----- 1 root root 4.3K 2月 5 14:11 hudson.plugins.emailext.ExtendedEmailPublisher.xml
-rw-r----- 1 root root 683 1月 21 19:07 hudson.plugins.powershell.PowerShellInstallation.xml
-rw-r----- 1 root root 1.9K 2月 5 14:11 jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml
-rwxr-xr-x 1 root root 42K 2月 5 13:53 jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml260205
-rwxr-xr-x 1 root root 42K 2月 5 14:05 jenkins.plugins.publish_over_ssh.BapSshPublisherPlugin.xml260205003

Tomcat 部署修复

1
2
3
4
5
6
7
8
9
10
11
12
13
# 找到 Tomcat 的 setenv.sh(如果没有则创建)
sudo vi /jenkins/apache-tomcat-10.1.50/bin/setenv.sh

# 添加以下内容
export JENKINS_HOME=/jenkins/jenkins_home
export CATALINA_OPTS="-DJENKINS_HOME=/jenkins/jenkins_home"

# 确保目录存在且有权限
sudo mkdir -p /jenkins/jenkins_home
sudo chown -R tomcat:tomcat /jenkins/jenkins_home

# 重启 Tomcat
sudo systemctl restart tomcat9

2602-DockerMongoDB重置密码

启动临时容器,不加载任何认证

1
2
3
4
5
6
7
8
9
10
11
12
# 2. 启动临时容器,不加载任何认证
docker run -d \
--name mongo_reset \
-v mongo_data:/data/db \
-p 27017:27017 \
registry.cn-hangzhou.aliyuncs.com/farerboy/mongo:8.0.5-rc1 \
mongod --bind_ip_all

# 3. 尝试无认证连接
docker exec -it mongo_reset mongosh


如果能连进去,执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 查看所有数据库
show dbs

// 切换到 admin(如果不存在就创建)
use admin

// 查看是否有用户
db.system.users.find().pretty();

// 删除用户
db.dropUser('usertest')

// 如果没有用户,直接创建
db.createUser({
user: "admin",
pwd: "xxxxxxxx",
mechanisms: ["SCRAM-SHA-1"],
roles: [{ role: "clusterMonitor", db: "admin" },{ role: "clusterManager", db: "admin" },{ role: "clusterMonitor", db: "admin" },{ role: "clusterManager", db: "admin" },'readWriteAnyDatabase', 'dbAdminAnyDatabase', {
role: "dbAdmin",
db: 'dbName'
}, {
role: "readWrite",
db: 'dbName'
}]
});

重新绑定MongoDB

1
2
3
4
5
6
7
8
# 3. 重新启动(相当于全新实例,但数据文件还在,需要修复)
docker run -d \
--name mongo_new \
-v mongo_data:/data/db \
-e MONGO_INITDB_ROOT_USERNAME=admin \
-e MONGO_INITDB_ROOT_PASSWORD=NewPassword123 \
-p 27017:27017 \
registry.cn-hangzhou.aliyuncs.com/farerboy/mongo:8.0.5-rc1

260123-windows 11 开机后必须在电脑上输入密码后,才能远程,是怎么回事


SUCCESS

计算机配置 → 管理模板 → Windows组件 → 远程桌面服务 → 远程桌面会话主机 → 安全

3. Administrator账户是否被禁用

1
Win+R → lusrmgr.msc → 用户 → Administrator → 取消勾选"账户已禁用"

4. 远程桌面服务的安全层设置

1
2
Win+R → gpedit.msc
计算机配置 → 管理模板 → Windows组件 → 远程桌面服务 → 远程桌面会话主机 → 安全

检查这两项:

  • “要求使用网络级别的身份验证…” → 设为已启用(推荐)或已禁用测试
  • “设置客户端连接加密级别” → 设为已禁用或”客户端兼容”

5. 防火墙是否放行

1
2
控制面板 → Windows Defender 防火墙 → 允许应用通过防火墙
确认"远程桌面"勾选了"专用"和"公用"

6. 最粗暴测试:先关掉NLA

1
2
gpedit.msc → 计算机配置 → 管理模板 → Windows组件 → 远程桌面服务 → 远程桌面会话主机 → 安全
"要求使用网络级别的身份验证..." → 已禁用

重启后再试。如果能连,说明是NLA凭据问题;如果连不上,是网络或防火墙问题。


SUCCESS

想让“重启后远程直接能连”,就得让系统在开机后自动完成一次交互式登录,把会话跑起来。做法有两种:

  1. 注册表手动写 AutoAdminLogon(备用方案)

  2. Win+R → regedit

  3. 定位到
    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon

  4. 右侧新建/修改以下键值(都是 REG_SZ):

    1
    2
    3
    4
    AutoAdminLogon = 1
    DefaultUserName = Administrator
    DefaultDomainName = . (或你的计算机名)
    DefaultPassword = 你的密码
  5. 重启即可。

安全提醒

  • 自动登录等于把密码明文存在注册表(或 netplwiz 保管),任何能物理接触机器的人都能看到;只建议在受控的机房/家里使用。
  • 如果机器要放在公网,最好改用“开机后先本地输一次密码”的手动方式,或者给 BIOS/BitLocker 加电口令,再配 VPN 跳板,而不是单纯依赖自动登录。

这是 Windows 11 的默认安全机制:
如果本地还没“真正”用密码登录过一次,系统里就没有缓存可供 NLA(网络级身份验证)使用的凭据,远程桌面就会直接拒绝连接,表现为“必须先在本机输完密码,远程才能连”。

为什么会这样

  1. 很多人第一次激活系统用的是 Microsoft 账号,但随后只设了 PIN 或 Windows Hello 刷脸/指纹。

  2. PIN/Hello 只能解锁“已登录的本地会话”,不能当作 NLA 的凭据;而 Microsoft 账号的密码又从未在本地输入过,所以缓存里找不到有效凭据。

  3. 远程桌面服务启动时,NLA 阶段就要求出示“用户名+密码”,本地没有缓存只能失败,于是出现“必须本地先登录一次”的现象

解决思路(任选其一,推荐前两种)

  1. 本地用“账号密码”重新登录一次 a. 先锁屏 Win+L → 登录选项 → 选“密码”并输入 Microsoft 账号密码。 b.
    成功后该凭据会被缓存,今后无需再本地登录即可远程 。

  2. 干脆新建一个本地管理员,专门做远程

    1
    2
    3
    powershell
    net user rdpuser 你的密码 /add
    net localgroup administrators rdpuser /add

然后在“设置 → 系统 → 远程桌面 → 远程桌面用户”里把 rdpuser 加进去。以后远程就用这个本地账户即可

  1. 关闭“仅允许 Windows Hello 登录” 设置 → 账户 → 登录选项 → 关闭“为提高安全性,仅允许 Windows Hello 登录 Microsoft
    账号”。这样你就能在锁屏界面直接选“密码”,完成一次缓存 。

  2. 组策略放行“空密码”(仅家庭版不可用)

  3. 彻底关掉 NLA(降低安全性)

一句话总结
“先本地输一次密码”只是为了让 Windows 把真正的账号密码缓存下来;只要凭据存在,远程桌面就能在 NLA 阶段完成验证,之后再也不需要本地先登录。按上面
1 或 2 操作即可根治。

可以,直接把“Administrator”设为远程桌面用户即可,不需要再新建一个 rdpuser。
步骤如下(Win11 专业版/企业版):

  1. 先在本机用 Administrator 的「密码」登录一次
    ‑ 锁屏 → 登录选项 → 选「密码」并输入 Administrator 的密码,让系统把凭据缓存下来;这是解决“必须本地先登录”的关键。

  2. 把 Administrator 加入「远程桌面用户」组
    Win+X → 终端(管理员) →

    1
    net localgroup "Remote Desktop Users" administrator /add
  3. 确认远程桌面已开启
    设置 → 系统 → 远程桌面 → 打开「启用远程桌面」。

  4. 客户端连接时
    用户名填 .\Administrator(或计算机名\Administrator),再输入密码即可直接远程,无需再本地先登录。

注意

  • 如果系统用的是 Microsoft 在线账号,密码要输入「Microsoft 账号密码」而不是 PIN/Hello。

  • 出于安全考虑,建议给 Administrator 设一个强密码,并在路由器或防火墙里限制可访问 3389 的 IP 范围


260121-Ubuntu生成docker证书

Docker启用TLS加密解决暴露2375端口引发的安全漏洞,被黑掉三台云主机的教训总结

1. 设置主机名

编辑/etc/hostname,服务器主机名 ubuntu

1
vi /etc/hostname

2. 生成TLS证书

创建证书生成脚本 docker-cert.sh,放置/script目录

1
2
3
sudo mkdir -p /script /data/cert/docker
sudo touch /script/docker-cert.sh
sudo vim /script/docker-cert.sh

docker-cert.sh添加内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/bin/bash

set -e
if [ -z $1 ];then
echo "请输入Docker服务器主机名"
exit 0
fi
HOST=$1
mkdir -p /data/cert/docker
cd /data/cert/docker
openssl genrsa -aes256 -out ca-key.pem 4096
openssl req -new -x509 -days 3650 -key ca-key.pem -sha256 -out ca.pem
openssl genrsa -out ca-key.pem 4096
openssl req -subj "/CN=$HOST" -sha256 -new -key ca-key.pem -out server.csr
# 配置白名单,推荐配置0.0.0.0,允许所有IP连接但只有证书才可以连接成功
# 创建证书时,您需要提供 localhost 作为主题备用名称。您可以通过提供以下附加参数来做到这一点:-ext "SAN:c=DNS:localhost,IP:127.0.0.1"
# echo subjectAltName = DNS:$HOST,IP:0.0.0.0 > extfile.cnf
# echo subjectAltName = DNS:localhost,IP:0.0.0.0 > extfile.cnf
echo subjectAltName = IP:$HOST,IP:0.0.0.0 > extfile.cnf

openssl x509 -req -days 3650 -sha256 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-key.pem -extfile extfile.cnf
openssl genrsa -out key.pem 4096
openssl req -subj '/CN=client' -new -key key.pem -out client.csr
echo extendedKeyUsage = clientAuth > extfile.cnf
openssl x509 -req -days 3650 -sha256 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out cert.pem -extfile extfile.cnf
rm -v client.csr server.csr
chmod -v 0400 ca-key.pem key.pem ca-key.pem
chmod -v 0444 ca.pem server-key.pem cert.pem

执行 docker-cert.sh 脚本,生成证书放置 /data/cert/docker 目录中

1
2
3
4
5
# ubuntu是服务器的主机名
sh /script/docker-cert.sh ubuntu
sh /script/docker-cert.sh VM-12-11-centos (密码: ubuntu666)
sh /script/docker-cert.sh ubuntu (密码: ubuntu666)
sh /script/docker-cert.sh VM-12-4-ubuntu (密码: ubuntu666)

按照提示输入相关信息,密码一致就行,其他信息可留空,等脚本指定完成之后,可在 /data/cert/docker 目录查看到生成的证书。

Docker 只接受「未加密的私钥」

你给的 .key 文件是 RSA 加密私钥(文件头里能看到 —–BEGIN RSA PRIVATE KEY—– 或 Proc-Type: 4,ENCRYPTED),启动时 dockerd
要求你输入密码,但它跑在 systemd 里没人交互,于是读密钥失败 → TLS 配置无效 → dockerd 直接退出。
一句话结论
私钥被加密了,Docker 不会解密,必须换成“无密码”的私钥。

如果私钥仍带密码,先按前面说的去密码:

1
2
3
sudo openssl rsa -in server-key.pem -out server-key-clear.pem
sudo mv server-key-clear.pem server-key.pem
sudo chmod 600 server-key.pem

证书生成过程问题解决

OpenSSL 报错写得很清楚:

1
bad ip address … value=ubuntu

你在 extfile.cnf 里把 主机名ubuntu)直接写进了 IP: 字段,而 IP: 后面必须是纯 IPv4/IPv6 地址,不能是字符串域名或主机名。
改成 DNS:ubuntu 或者干脆去掉域名,只保留合法 IP 即可。

修正扩展文件

1
2
3
cat > extfile.cnf <<EOF
subjectAltName = DNS:ubuntu,IP:127.0.0.1,IP:10.0.0.0/8
EOF

如果你只想让任何地址都能连,也可以最简写:

1
echo "subjectAltName = IP:0.0.0.0" > extfile.cnf

重新签发

1
2
3
4
openssl x509 -req -in server.csr \
-CA ca.pem -CAkey ca-key.pem -CAcreateserial \
-out server-cert.pem -days 3650 -sha256 \
-extfile extfile.cnf

验证

1
openssl x509 -in server-cert.pem -text -noout | grep -A1 "Subject Alternative Name"

应看到:

1
2
X509v3 Subject Alternative Name:
DNS:ubuntu, IP:127.0.0.1, IP:0.0.0.0/8

不再报错即可。

查看生成后的证书

img

3. 配置Docker启用TLS

1
2
sudo cat /usr/lib/systemd/system/docker.service
sudo vim /usr/lib/systemd/system/docker.service

在ExecStart属性后追加

1
2
3
4
--tlsverify --tlscacert=/data/cert/docker/ca.pem  \
--tlscert=/data/cert/docker/server-cert.pem \
--tlskey=/data/cert/docker/server-key.pem \
-H tcp://0.0.0.0:2376 -H unix://var/run/docker.sock
1
--tlsverify --tlscacert=/data/cert/docker/ca.pem --tlscert=/data/cert/docker/server-cert.pem --tlskey=/data/cert/docker/server-key.pem -H tcp://0.0.0.0:2376 -H unix://var/run/docker.sock 

img

重新加载docker配置后重启

1
2
3
4
5
6
7
8
9
10
11
12
sudo systemctl daemon-reload 
sudo systemctl restart docker

sudo journalctl -u docker.service -n 50

# 检查是否加密 如果提示 Enter pass phrase,就说明被加密了。
sudo openssl rsa -in /data/cert/docker/ca-key.pem -check -noout

调试验证
>> /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --tlsverify --tlscacert=/data/cert/docker/ca.pem --tlscert=/data/cert/docker/server-cert.pem --tlskey=/data/cert/docker/server-key.pem -H tcp://0.0.0.0:2376 -H unix://var/run/docker.sock

sudo systemctl daemon-reload && sudo systemctl restart docker

查看2376端口是否启动

1
netstat -nltp | grep 2376

img

本地连接测试Docker API是否可用

  • 没有指定证书访问测试
1
2
curl https://ubuntu:2376/info 
curl https://127.0.0.1:2376/info
  • 指定证书访问测试
1
2
3
4
5
6
7
curl https://ubuntu:2376/info --cert /data/cert/docker/cert.pem --key /data/cert/docker/key.pem --cacert /data/cert/docker/ca.pem

curl https://127.0.0.1:2376/info --cert /data/cert/docker/cert.pem --key /data/cert/docker/key.pem --cacert /data/cert/docker/ca.pem

curl https://ubuntu:2376/info --cert /data/cert/docker/cert.pem --key /data/cert/docker/key.pem --cacert /data/cert/docker/ca.pem

https://ubuntu:2376

4. IDEA配置

将客户端所需的ca.pem、cert.pem、key.pem3个密钥文件从服务器下载到本地

img

IDEA连接Docker配置修改

img

pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<!--执行mvn package,即执行 mvn clean package docker:build-->
<execution>
<id>build-image</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>

<configuration>
<!-- 镜像名称 -->
<imageName>${project.artifactId}</imageName>
<!-- 指定标签 -->
<imageTags>
<imageTag>latest</imageTag>
</imageTags>
<!-- 基础镜像-->
<baseImage>openjdk:8-jdk-alpine</baseImage>

<!-- 切换到容器工作目录-->
<workdir>/</workdir>

<entryPoint>["java","-jar","${project.build.finalName}.jar"]</entryPoint>

<!-- 指定远程 Docker API地址 -->
<dockerHost>https://ubuntu:2376</dockerHost>
<!-- 指定tls证书的目录 -->
<dockerCertPath>C:\certs\docker\ubuntu</dockerCertPath>

<!-- 复制 jar包到docker容器指定目录-->
<resources>
<resource>
<targetPath>/</targetPath>
<!-- 用于指定需要复制的根目录,${project.build.directory}表示target目录 -->
<directory>${project.build.directory}</directory>
<!-- 用于指定需要复制的文件,${project.build.finalName}.jar就是打包后的target目录下的jar包名称 -->
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>

260121-ubuntu 域名ping 提示Temporary failure in name resolution-ping-baidu.com

ubuntu 域名ping 提示Temporary failure in name resolution

只要 任何域名 都报 Temporary failure in name resolution,就是 本机 DNS 解析链彻底断了,与具体域名无关。
Ubuntu 20.04+ 默认走 systemd-resolved,90 % 是它没跑 / 配置丢失 / 上游 DNS 无响应。
按下面「4 句命令 → 1 次验证」一次性修好即可:


  1. 确认 systemd-resolved 活着

1
systemctl is-active systemd-resolved || sudo systemctl enable --now systemd-resolved

  1. 把 /etc/resolv.conf 指向本地 stub

1
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

确保文件第一行是

1
nameserver 127.0.0.53

  1. 给 resolver 换可靠的公共 DNS

1
2
3
sudo mkdir -p /etc/systemd/resolved.conf.d
echo -e "[Resolve]\nDNS=8.8.8.8 1.1.1.1" | sudo tee /etc/systemd/resolved.conf.d/99-public.conf
sudo systemctl restart systemd-resolved

  1. 一键验证

1
systemd-resolve google.com && ping -c3 google.com

能解析、能 ping 通就表示修复完成,再去跑你的证书脚本即可。

260119-linux-redis离线安装

一、准备工作

1.下载redis的安装包

下载地址:Index of /releases/

大家可以自行选择redis的版本,笔者选择的是最新的

https://download.redis.io/releases/

img

2.上传到服务器
前提是我先在服务器上创建了一个目录redis7.2.3,我直接上传到这个目录下

二、安装redis
1.解压redis
tar -zxvf redis-7.2.3.tar.gz
AI写代码
2.移动解压完成的目录到/usr/local/下
mv redis-7.2.3 /usr/local/
AI写代码
3.进入到redis-7.2.3的目录
cd /opt/data/iimes/soft/redis-8.4.0
AI写代码
4.编译安装
make install
等待安装

安装完成的目录结构如下:

三、修改配置文件 redis.conf
vim redis.conf

1.设置远程访问
注释掉 bind 127.0.0.1 -::1 这句话意思是 只在本地访问!你不注释掉,到时候你本地RDM 是链接不上的。或者改为 bind 0.0.0.0

2.修改 登陆redis的密码 如图:
作者为了图方便,改为了123456.

3.设置后台启动
将daemonize no 改为 daemonize yes

四、将redis添加到守护进程,并开启开机自启动
1.在/etc/systemd/system/ 目录下创建文件redis.service
/etc/systemd/system目录是Linux系统中用于存放systemd单元配置文件的位置。systemd是一个系统和服务管理器,负责启动、停止和管理系统进程

vim /etc/systemd/system/redis.service
AI写代码
2.添加如下内容
大家注意区分,对于下面/opt/data/iimes/soft/redis-8.4.0/src/redis-server中的 src 是根据redis的安装目录来的,有些是 bin
大家注意观察自己的redis的目录,根据实际情况填写。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[Unit]
Description=Redis
After=network.target

[Service]
Type=forking
ExecStart=/opt/data/iimes/soft/redis-8.4.0/src/redis-server /opt/data/iimes/soft/redis-8.4.0/redis.conf
ExecStop=/opt/data/iimes/soft/redis-8.4.0/src/redis-server -s stop
PrivateTmp=true
User=root
Group=root

[Install]
WantedBy=multi-user.target

保存并退出

3.设置开机自启
systemctl enable redis
AI写代码
4.添加环境变量
(1)可以直接在/etc/profile文件末尾直接添加

vim /etc/profile

export PATH=$PATH:/opt/data/iimes/soft/redis-8.4.0/src
AI写代码
(2)或在profile.d目录下新建一个,专门放redis的环境变量文件

进入/etc/profile.d/路径下新建redis.sh

vim /etc/profile.d/redis.sh

在redis.sh文件中新增以下内容

export PATH=$PATH:/usr/local/redis/src

5.刷新环境变量
source /etc/profile
AI写代码
6.重启redis
systemctl restart redis
AI写代码
说明:如果后续大家还重新修改了/etc/systemd/system/redis.service文件,启动redis时出现提醒:Warning: The unit file, source
configuration file or drop-ins of redis.service changed on disk. Run ‘systemctl daemon-reload’ to reload units

重新执行命令:systemctl daemon-reload

这个警告提示您的 redis.service 单元文件、源配置文件或附加配置文件在磁盘上发生了变化。为了加载这些变化,您需要运行 systemctl
daemon-reload 命令来重新加载单元。

五、验证
1.查看redis的运行状态

2.查看redis进程

3.使用命令连接客户端
redis-cli

进入之后,需要你输入密码才能获取到redis输出的信息(info)

auth 密码

或者 之前在连接的时候输入密码:

redis-cli -a

260119-Ubuntu20-04(netplan apply)系统启动后直接加载固定路由-系统启动固定路由

作用:(Ubuntu20.04系统启动后直接加载固定路由)让本机一启动就把 192.168.0.2 / .4 / .102 / .104 / .106 这 5 个地址“当成跟自己同一链路(link)上的邻居”,无需网关即可直达,ARP 解析后直接发包。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
network:
ethernets:
eno1:
dhcp4: no
addresses: [192.168.0.100/24]
routes:
- to: default
via: 192.168.0.1
scope: link
metric: 10
enp1s0:
dhcp4: no
addresses: [192.168.0.110/24]
dhcp4-overrides:
use-routes: false # 拒绝 DHCP 下发的默认路由
routes: # 你的 5 条主机路由
- to: 192.168.0.2/32
scope: link
- to: 192.168.0.4/32
scope: link
- to: 192.168.0.102/32
scope: link
- to: 192.168.0.104/32
scope: link
- to: 192.168.0.106/32
scope: link
version: 2
wifis: {}

260119-Ubuntu20.04系统启动后直接加载固定路由-/etc/systemd/network/10-enp1s0.network

作用:(Ubuntu20.04系统启动后直接加载固定路由)让本机一启动就把 192.168.0.2 / .4 / .102 / .104 / .106 这 5 个地址“当成跟自己同一链路(link)上的邻居”,无需网关即可直达,ARP 解析后直接发包。

目录位置: /etc/systemd/network/10-enp1s0.network

配置完成,重启(sudo systemctl enable systemd-networkd)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[Match]
Name=enp1s0

[Network]
DHCP=yes

# 下面 5 行就是固定路由
[Route]
Destination=192.168.0.2/32
Scope=link

[Route]
Destination=192.168.0.4/32
Scope=link

[Route]
Destination=192.168.0.102/32
Scope=link

[Route]
Destination=192.168.0.104/32
Scope=link

[Route]
Destination=192.168.0.106/32
Scope=link

260119-260119-Ubuntu20-04(systemd-networkd&netplan apply不能共用谁先启动谁就把另一份冲掉)

你现在同时用了两条“指挥棒”:

  1. /etc/systemd/network/10-enp1s0.network
    手工写给 systemd-networkd 的“原生”配置,让 enp1s0 走 DHCP,但禁止默认路由。
  2. /etc/systemd/system/50-cloud-init.yaml(应为 /etc/netplan/50-cloud-init.yaml
    写给 netplan 的 YAML,把 eno1、enp1s0 都设成静态地址,且声明 renderer: networkd(你没写,但 Ubuntu 服务器版默认就是
    networkd)。

问题就出在“同一接口被两边描述”

  • netplan 在 netplan apply 或开机时,会重新生成
    /run/systemd/network/10-netplan-enp1s0.network

这样有冲突吗

有冲突,而且重启后只能有一半配置生效——谁先启动谁就把另一份冲掉。

  1. 两套“管理员”
    • /etc/systemd/network/10-enp1s0.networksystemd-networkd 直接读取
    • /etc/systemd/system/50-cloud-init.yamlcloud-init 留给 netplan 的,netplan apply 时会根据它生成
      /run/systemd/network/10-netplan-eno1.network
      /run/systemd/network/10-netplan-enp1s0.network
      然后重启 systemd-networkd
      结果:networkd 重启后会把 /run/… 下面的“临时文件”当做最新配置,/etc 里你手写的那份就被静默覆盖了。
  2. 冲突点
    • 对 enp1s0 的定义完全矛盾:
      – 你手写版:DHCP=yes,还要加 5 条主机路由
      – netplan 版:dhcp4: no,addresses: [192.168.0.110/24]
      重启后最后生效的是 netplan 生成的“静态地址”版本,DHCP 和 5 条路由全部丢失。
  3. 对 eno1 的影响
    netplan 会把 eno1 的默认路由 metric=10 写进 /run/…/10-netplan-eno1.network,和你手工文件不冲突(因为没手写 eno1),但*
    *一旦以后你想手动改 eno1,也会遇到同样被覆盖的问题**。
  4. 结论 & 做法
    “一个接口只能由一个管家管”
    选 A 或选 B,不要混用:
    选 A 或选 B,不要混用:
    选 A 或选 B,不要混用:
    选 A 或选 B,不要混用: