分类 默认分类 下的文章

Docker内部网络连接错误的一种检查手段 nmap container

最近被一个容器无法内应用无法连接的问题折磨住了,我想看看内部的host.docker.internal到底怎么回事,于是想到建立一个nmap container进去检查
Dockerfile:

# 使用官方的 Ubuntu 镜像作为基础镜像
FROM ubuntu:latest

# 更新包列表并安装 nmap
RUN apt-get update && apt-get install -y nmap

# 创建一个目录来存储 nmap 结果
RUN mkdir /nmap_results

# 运行 nmap 并将结果保存到文件中,同时打印到控制台
CMD ["sh", "-c", "nmap host.docker.internal > /nmap_results/nmap_results.log && cat /nmap_results/nmap_results.log"]

docker-compose.yml:

version: '3.4'

services:
  nmap_service:
    image: nmap_image:latest
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./nmap_results:/nmap_results

nmap结果发现不存在host.docker.internal,可能是docker更新的原因。之前是可用的,但现在变成了 172.17.0.1
另附服务器无法pull image时,使用其他机器本地image的方法

# 机器一
docker save [imgID] > imagefile
#机器二
docker load < imagefile
docker tag [new_imgID] [随便什么名字]:[随便什么版本]

最后改掉Dockerfile中的FROM就好了
写文章时我才想起来,可以直接docker内起ubuntu虚拟机,exec进去操作,忘了。

ApiFox / Postman 使用WebSocket连接SignalR需要注意的小问题

省流:忘加0x1e
最近刚接触SignalR,发现用ApiFox怎么都没法测试,可以正常连接,但是发消息没有任何反应。我一度怀疑是自己的环境出了问题。
image.png
后来直接使用大佬的代码(带前端)进行测试,发现是正常的。说明这只是操作上的问题。又去搜postman调试SignalR。才找到了这个简单的隐蔽的问题。
SignalR的交流以0x1e作为结束符。之前没有注意到这一点,走了一些弯路。
{"protocol":"json","version":1}
这段代码末尾加了个0x1e。可以直接整段复制用于SignalR连接。
image.png
TakeAway message:
如果想要上传消息,格式是:

{
  "type": 1,
  "target": "方法名",
  "arguments": ["方法参数1", "方法参数2..."]
}

SignalR type 数字含义:(From Copilot)

  1. Invocation (1):
    • 表示客户端或服务器调用一个方法。
    • 例如,客户端调用服务器上的一个Hub方法。
  2. StreamItem (2):
    • 表示流中的一项数据。
    • 用于流式传输数据时,每个数据项都会使用这个消息类型。
  3. Completion (3):
    • 表示一个调用或流的完成。
    • 包含调用的结果或错误信息。
  4. StreamInvocation (4):
    • 表示客户端请求从服务器流式传输数据。
    • 服务器会返回多个StreamItem消息。
  5. CancelInvocation (5):
    • 表示取消一个流式传输的请求。
    • 客户端可以发送这个消息来取消一个正在进行的流。
  6. Ping (6):
    • 表示一个心跳消息,用于保持连接活跃。
    • 没有负载,只是为了确保连接没有超时。
  7. Close (7):
    • 表示连接关闭。
    • 包含可选的错误信息。

从debian装模拟器打Arknights到RK3568内核重编译

前言

写这篇文章的起因是想在RK3568上运行Arknights+MAA,但是模拟器需要的编译参数没有打开。故重编译内核。考虑到后续需要OpenWRT,故同时启用KVM支持。
在编译过程中,遇到了非常多的问题,在此记录一下。

前言就是用来写废话的!!(暴论)

这次编译内核就目前为止失败了三次。两次是因为磁盘空间不足,一次是因为内存空间不足。我会在之后成功时计算内存和存储的用量。(是的我是边做边写的,如果我做完再写就写不出这些废话了)
用到的RK3568是正点原子的,它们提供了一个Linux SDK包,并且给了一份指导书,可惜有一些缺漏。SDK包会有一些传统内核编译没有的东西(build.sh)(大概)所以这个教程并不一定能完全适用所有RK3568。请自行判断。
原子科技的内核编译使用的是VMware。我能理解,但我这里用的是WSL+Docker,因为我希望能最多的利用性能。
wsl的内存一定要拉大,还有SWAP,一定要拉大,我后续会出一份内存使用情况-时间图。(大概)
指导手册和源码指北:
我是链接
手册在A盘->10、用户手册.zip->10、用户手册->03、辅助文档->24【正点原子】ATK-DLRK3568_Linux5.10_SDK编译说明V1.0.pdf
源码在B盘->02、ATK-DLRK3568开发板SDK->05、linux5.10_sdk

正文

Docker迁移

Windows的Docker Desktop wsl虚拟机默认装载C盘。你可能装在了别的盘,请确认该盘至少有91G容量。(粗略计算,建议多准备一些)(如果过程中内存不足,是会把整个wsl带崩的,到时候就只能wsl --shutdown重启wsl了)
Docker迁移非常简单Docker Desktop - Settings - Resources 然后直接改location就行。如果说你的Docker用过一段时间了,那么可能会很耗时。你可以通过任务管理器的磁盘占用与速率推断出Docker迁移是否完成。不要以Docker Engine是否重新启动作为参照。
我不建议你用wsl的导出和导入迁移Docker。虽然迁移后能用,但这会导致Docker内部显示的路径还是之前的路径,可能有影响?反正不太好。

Ubuntu Container的启动与SDK全编译

在Docker中启动一个最小Ubuntu镜像。笔者使用的是22.04,但现在最新的应该是24.04了,所以注意一下latest tag对应的版本问题。这一步pull image即可。
镜像启动容器,这里我先用Docker Desktop创建一个有公共空间的镜像,然后再点击三个点 Copy Docker Run 把复制出来的命令中,加上-t --privileged。然后删掉容器,在powershell中重新运行即可。
这里给出我自己的Run命令:

docker run --hostname=4417a56bb7d1 --mac-address=02:42:ac:11:00:02 --env=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin --volume=C:\Users\{替换成你的用户名}\Desktop\dockerShare:/data:rw --restart=no --label='org.opencontainers.image.ref.name=ubuntu' --label='org.opencontainers.image.version=22.04' --runtime=runc -t -d --privileged ubuntu:latest

该命令把桌面上的dockerShare文件夹映射到Ubuntu内部的/data文件夹,你也可以改改。
Ubuntu镜像换源
tip:有bash,不要用sh折磨自己
这里给出我自己在用的源(阿里云),但是不能保证你用的时候源还能用:
因为没有vi,没有vim,没有nano,所以直接重定向即可。

echo "deb http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ jammy-backports main restricted universe multiverse" >/etc/apt/sources.list

更新&安装依赖
apt update && apt upgrade

代码更新需要python2.7(因为要装python2.7,我才不用自己的实体Ubuntu(原因一))
apt install python2.7

指导手册给的依赖 (好多我自己用不到的,我才不用自己的实体Ubuntu(原因二))

apt install git ssh make gcc libssl-dev liblz4-tool expect expect-dev g++ patchelf chrpath gawk texinfo chrpath diffstat binfmt-support qemu-user-static live-build bison flex fakeroot cmake gcc-multilib g++-multilib unzip device-tree-compiler ncurses-dev bzip2 expat gpgv2 cpp-aarch64-linux-gnu libgmp-dev libmpc-dev bc 

因为使用了最小Ubuntu,所以需要额外装一些软件(vim是我个人的习惯,应该可以换nano?):
apt install time file rsync bsdmainutils xz-utils vim

为python2.7做一个到python的链接
ln -s $(which python2.7) /usr/bin/python

把显示转换为中文UTF-8,不换可能导致某些带中文的文件在vim中显示不正确
echo 'LANG="zh_CN.UTF-8"' >> /etc/environment

首先解压05、linux5.10_sdk.zip和其嵌套的文件夹,假设该zip已经在Ubuntu:/data文件夹下:
我不记得unzip是不是自带的了,我估计不是,如果没有就装一下
unzip 05、linux5.10_sdk.zip //此处建议敲个05,敲个tab
//把解压出来的两个tgz文件复制一份到主目录,如果缺空间,data下解压出来的tgz文件就可以删了。

mkdir ~/rk3568_linux5.10_sdk 
tar -xzf ~/atk-rk3568_linux5.10_release_v1.1_20240705.tgz -C ~/rk3568_linux5.10_sdk
cd ~/rk3568_linux5.10_sdk 
.repo/repo/repo sync -l -j10 //这一步用到了python (python2.7)
tar -xf ~/dl.tgz -C ./buildroot/
./build.sh alientek_rk3568_defconfig 

准备工作都做完了,如果你只想编译内核,请跳转到下一节,如果你想全编译SDK就继续。
全编译:
./build.sh all

内核编译选项设置

由于后续使用Docker Desktop的terminal看不清选项菜单中的*,故使用其他terminal操作
docker exec -it {docker id} /bin/sh
进入内核文件夹
cd kernel
首先需要选择合适的defconfig 观察build.sh 编译kernel时的log

==========================================
          Start building kernel
==========================================
+ make -C /root/rk3568_linux5.10_sdk/kernel/ -j21 CROSS_COMPILE=/root/rk3568_linux5.10_sdk/prebuilts/gcc/
linux-x86/aarch64/gcc-arm-10.3-2021.07-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu- 
ARCH=arm64 rockchip_linux_defconfig

可见defconfig名字为rockchip_linux_defconfig
删除之前生成的.config
rm .config
设置内核选项:
make menuconfig KCONFIG_CONFIG=arch/arm64/configs/rockchip_linux_defconfig ARCH=arm64
需要设置的内核编译选项有KVM和CONFIG_KPROBE_EVENTS
KVM比较简单
主页 Virtualization 按y勾选,然后回车进入,按y勾选KVM即可
CONFIG_KPROBE_EVENTS相对复杂一点,先搜索该选项。
image.png
Location代表该选项位置,Depends on代表依赖。需要先满足依赖,该选项才会出现。(DFS启动!)
可见KPROBES为n,再次搜索KPROBES
image.png
可见其Location为General architecture-dependent options 但是找不到这个位置
在经过我一顿尝试后,发现把KGDB打开就行
KGDB位置:Kernel hacking > Generic Kernel Debugging Instruments
之后CONFIG_KPROBE_EVENTS也自动开启了
选择save,之后退出
需要小小的修改一下源码,当然你也可以试试直接编译,但应该会遇到如下问题:
error: implicit declaration of function 'sve_cond_update_zcr_vq' [-Werror=implicit-function-declaration]
修改这个 kernel文件夹下
vim arch/arm64/include/asm/fpsimd.h
在170行添加这句话
tips: :set nu显示行号 :170转到170行

168 static inline void sve_user_disable(void) { BUILD_BUG(); }
169 static inline void sve_user_enable(void) { BUILD_BUG(); }
170 + #define sve_cond_update_zcr_vq(val, reg)
171 static inline void sve_init_vq_map(void) { }
172 static inline void sve_update_vq_map(void) { }

如果你需要启用KPROBE_ON_FTRACE,那你需要这个链接
此外,如果你需要启用DOCKER,那么我建议你同时启用NF_TABLE、BRIDGE、MASQUERADE、addrtype相关选项
重编译内核,打包镜像:

cd ..
./build.sh kernel
//updateimg不是必要的,其作用是更新update.img,如果你只烧录内核,那你可以在output/firmware/找到它
./build.sh updateimg

kernel位置:
boot.img: output/update/Image/ 同output/firmware/
update.img: output/update/

引用:

Kprobes介绍
sve_cond_update_zcr_vq 相关错误与解决方案
[ARM64启用KPROBE_ON_FTRACE的PATCH]https://patchwork.kernel.org/project/linux-arm-kernel/patch/20191218140622.57bbaca5@xhacker.debian/#23074137

待补充内存图

内存图鸽了,我不想再折磨一次电脑,目测RAM占用上过10G,我用的16G内存加16GSWAP,在用户文件夹下的.wslconfig调整

Xorg 红蓝两色通道异常 默认分辨率和色深设置

现象:红色显示蓝色,蓝色显示黄色
原因:Xorg色深设置错误,从8bit提升至16bit后显示正确
相关conf:

Section "Device"
    Identifier    "AMD"
    Driver      "amdgpu"
EndSection

Section    "Screen"
    Identifier    "Default Screen"
    Device    "amdgpu"
    Monitor    "Default Monitor"
    DefaultDepth 16

    SubSection "Display"
        Depth     16
    Modes     "1920x1080"
    EndSubSection
EndSection

### Valid values for rotation are "normal", "left", "right"
Section    "Monitor"
    Identifier    "Default Monitor"
    # Option    "Rotate" "normal"
    # 1920x1080 @ 60.00 Hz (GTF) hsync: 67.08 kHz; pclk: 172.80 MHz
    Modeline "1920x1080_60.00"  172.80  1920 2040 2248 2576  1080 1081 1084 1118  -HSync +Vsync
EndSection

正点原子RK3568的默认配置中,Device使用的驱动是modesetting,该驱动在16bit色深下不能提升分辨率至1920x1080
你可以通过执行 sudo X :1 -configure (:1 可以是其它非0数字,不要是已激活的屏幕就行)

X.Org X Server 1.21.1.7
X Protocol Version 11, Revision 0
Current Operating System: Linux atompi-ca1 5.10.160 #1 SMP Tue Jan 30 11:01:02 CST 2024 aarch64
Kernel command line: earlycon=uart8250,mmio32,0xfe660000 root=/dev/mmcblk0p3 earlyprintk console=ttyFIQ0 rootwait rw 
xorg-server 2:21.1.7-3+deb12u7 (https://www.debian.org/support) 
Current version of pixman: 0.42.2
    Before reporting problems, check http://wiki.x.org
    to make sure that you have the latest version.
Markers: (--) probed, (**) from config file, (==) default setting,
    (++) from command line, (!!) notice, (II) informational,
    (WW) warning, (EE) error, (NI) not implemented, (??) unknown.
(==) Log file: "/var/log/Xorg.1.log", Time: Sun Jul 14 18:42:15 2024
List of video drivers:
    amdgpu
    ati
    nouveau
    radeon
    modesetting
    fbdev
    vesa
No devices to configure.  Configuration failed.
(EE) Server terminated with error (2). Closing log file.

sysv-rc-conf 升级失败 依赖冲突 AtomPi 正点原子RK3568 Debian升级小记

故事略长,但是先讲重点
如果你是systemd作为init程序,那么不要升级sysv-rc-conf,甚至可以直接卸载
正文:AtomPi 正点原子RK3568 Debian升级小记
新拿到手的RK3568,自带的是Debian11 说实话,能用,如果不像我一样对新系统偏执完全不用升级
升级系统步骤如下:
设置timeshift系统备份,很重要,不要莽,去搜,简单易用有效!!
删除所有dbgsym
dpkg -l | grep dbgsym | awk '{print $2}' | xargs sudo dpkg --purge
这个命令说实话有点危险,它本意是删除所有带dbgsym的软件包,后续升级时,这些软件包会造成依赖问题
修改/etc/apt/sources.list 我这里是Debian11升12,所以把bullseye改为bookworm
sudo apt update $$ sudo apt upgrade
升级后你会发现一些软件包没有被升级,我的处理方式挺麻烦的,当然你选择不升级也不会有任何影响。
我这边大概有80多个未升级的软件包,很多软件包能看出来是一类的,当你使用
'''
sudo apt upgrade
sudo apt dist-upgrade
'''
都不能升级,但sudo apt upgrade [特定软件包名]又可以升级时,可以试试这样(例如gstreamer):
dpkg -l | grep gstreamer | awk '{print $2}' | xargs sudo apt dist-upgrade -y --allow-change-held-packages
好,其实以上这些都不是我想讲的
我想说的是其中一个软件包sysv-rc-conf
在尝试单独升级这个包时,会出现systemd相关的依赖冲突问题。但是奇怪的是其他软件包的依赖问题都是这样子的:
升级A时
A依赖B B版本不对
B依赖A A的新版本不能被B接受
但是sysv-rc-conf却没有出现在依赖问题中。
然后我试着删掉包重装。然后发现重装时要求删掉我的systemd
这下我知道为什么我第一次升级把systemd升没了。上一次我的处理方法是,记录所有包,删掉所有包,重装所有包。
sysv init和systemd init是冲突的。用systemd就好了。