# 串口管理程序conman

## conman简介

`conman`是一个串口控制管理程序，用于支持大量的控制台，不仅支持本地串口设备，也支持远程terminal服务器。结合IPMI协议，对大量服务器的串口日志进行采集，方便进行日志分析管理。并且`conman`结合呃IPMI Sol方式，可以远程对服务器进行串口控制台操作，实现sysrq magic组合键获取内核core dump。

`caonman`官方网站[ConMan](https://github.com/dun/conman)

## Escape（逃脱）字符

Escape字符是非常重要的字符，用于向串口发送特殊组合命令，以实现类似`sysrq`这样的magic按键组合。

`conman`默认的Escape字符是 **`&`**

重要的控制台字符：

* `&B` 向控制台发送`serial-break`字符，这个字符组合特定指令可以实现sysrq
* `&.` 断开conman连接
* `&?` 显示可用的escapes字符

### 通过conman实现sysrq

> 实际上也可以通过ipmi Serial over LAN来实现： 使用以下命令构建ipmi Serial over LAN连接到服务器出A口

```
ipmitool -U [user] -P [password] -H [ip/hostname of bmc] -I lanplus sol activate
```

然后依次执行如下组合键 - 注意：大写字幕`B`表示`serial-break`字符，也就是前面所说的对于conman就是同时按下 `&B`。例如，这里`Bc`就是表示先同时按下`&B`，然后放开按键，马上按一下`c`，就能够 **触发crash dump**

* `Bt` - 生成堆栈跟踪
* `Bm` - 打印内存状态，特别是在out of memory情况，特别需要此项信息
* `Bc` - 触发crash dump

> 注意：操作系统必须激活`sysrq`功能才能使得上述操作生效，否则会提示 `SysRq : This sysrq operation is disabled.`。请事先在操作系统执行以下命令使得sysrq功能生效：

```
sysctl kernel.sysrq=1
```

## conman设置案例

### 服务器配置启用内核串口设置

对于RHEL/CentOS操作系统，`/etc/sysconfig/grub` 设置了串口输出配置

```
GRUB_CMDLINE_LINUX="crashkernel=auto console=ttyS0,115200n8"
```

然后执行以下指令生成grub启动配置

```
grub2-mkconfig -o /boot/grub2/grub.cfg
```

重启服务器后，控制台将输出到串口。

### 安装conman

RHEL/CentOS 发行版已经包含了`conman`软件包

```
sudo yum install conman -y
```

### 配置conman的简单案例

请参考 [ipmitool配置服务器](https://github.com/huataihuang/cloud-atlas-draft/tree/6f3204fffc11cf006abd394631e2598d98b415c3/server/ipmi/configure_ipmi_under_Linux_using_ipmitool/README.md) 设置BMC访问管理账号和管理IP地址。conman将通过IPMI协议访问服务器的串口控制台。

安装`conman`软件包之后`/etc/conman.conf`是默认的配置文档，包含了大量的配置案例。

详细的设置可以参考[conman设置案例（日文）](https://shachimaru.wiki.fc2.com/wiki/conman)

**配置案例**

* `/etc/conman.conf`

```bash
server coredump=on
server coredumpdir="/var/log/conman"
server keepalive=on
server logdir="/var/log/conman"
server logfile=info
server timestamp=1h
global log="%N.log"
global logopts="timestamp"
global seropts="1152000,8n1"

console name="server-0" dev="/usr/share/conman/exec/ipmitool.exp 192.168.1.10 admin"
console name="server-1" dev="/usr/share/conman/exec/ipmitool.exp 192.168.1.11 admin"
console name="server-2" dev="/usr/share/conman/exec/ipmitool.exp 192.168.1.11 admin"
```

* `/etc/conman.pswd` - 这个配置文件是`conman`存储每个服务器对应的IPMI账号密码的文件，对于某些IDC环境，可能每台服务器设置不同的IPMI访问密码（第一列是访问IP，第二列是访问账号，第三列是访问密码），就可以使用这个配置文件：

```
192.168.1.10 : admin : password0
192.168.1.11 : admin : password1
192.168.1.12 : admin : password2
...
```

解析：

* `server`指令是设置`conman`的基本配置参数，包括存储日志目录，core目录，以及时间戳等
* `global`表示所有`console`指令都会包含的公共参数，其中`global log="%N.log"`表示所有服务器的日志文件都按照 `名字.log` 来记录，也就是`console name="server-0" ...`记录的服务器`192.168.1.10`串口日志将按照命名记录为 `server-0.log`，并且存储在`/var/log/conman`目录下。
* 每一行`console ...`表示连接到一台服务器的串口。注意，每个`name=xxxx`表示conman的一个对象命名。启动conman服务之后，就可以通过这个命令连接到对应服务器的IPMI sol接口。即要连接`192.168.1.10`的IPMI sol，只需要输入命令 `conman server-0`就可以实现。
* 启动`conman`服务

```
systemctl start conman
```

启动后请使用命令`systemctl status conman`检查服务状态

启动服务后，可以看到系统中有conman服务对应进程

```
/usr/sbin/conmand -c /etc/conman.conf
/usr/bin/expect -f /usr/share/conman/exec/ipmitool.exp 192.168.1.10 admin
ipmitool -e & -I lanplus -H 192.168.1.10 -U admin -a sol activate
```

> 可以看到，实际上`conman`巧妙的使用了`expect`工具来实现和服务器IPMI交互

### conman大规模案例

当需要监控IDC机房海量服务器的串口时，单纯启动一个`conman`服务进程是无法将负载分担到服务器的多处理器上。类似nginx配置，我们会针对服务器的CPU核心数启动相应数量的`conman`服务。例如，针对64核心的服务器，启动64个`conman`服务进程，每个服务进程负责数百台服务器的串口日志采集。这样，一台服务器可以充分发挥硬件性能，监控数千台甚至上万服务器。

> 注意每个`conman`服务器需要使用`-p <端口号>`分别使用不同端口，避免冲突(可以编写脚本批量启动)：

```bash
/usr/sbin/conmand -c conman_192.168.1.1_7900.conf -p 7900
/usr/sbin/conmand -c conman_192.168.1.1_7901.conf -p 7901
/usr/sbin/conmand -c conman_192.168.1.1_7902.conf -p 7902
...
```

每个配置文件，分别对应一批被监控服务器(这里案例假设使用admin账号，密码password)

```bash
# server: 192.168.1.1
# port: 7900
server syslog="local4"
global ipmiopts="U:admin,P:password"
global log="/home/oob/conman/%N.log"
global logopts="lock,nosanitize,timestamp"

console name='server-1.example.com' dev='ipmi:192.168.1.123'
console name='server-2' dev='ipmi:192.168.1.162' ipmiopts='U:admin,P:test_pass'
...
```

> 上述`global`配置提供了共用的IPMI访问账号密码，但是同时也有部分服务器有自己特定的访问密码，例如`server-2`就使用密码`test_pass`

### 简化版本conman配置

```bash
server syslog="local4"
global ipmiopts="U:admin,P:admin"
global log="/var/log/conman/console-%N.log"
global logopts="lock,nosanitize,timestamp"

console name='server-10' dev='ipmi:192.168.1.10' ipmiopts='U:admin,P:passwd0'
console name='server-11' dev='ipmi:192.168.1.11' ipmiopts='U:admin,P:passwd1'
```

## 参考

* [conman(1) - Linux man page](https://linux.die.net/man/1/conman)
* [sysrq via ipmi Serial over LAN](https://support.hpe.com/hpsc/doc/public/display?docId=emr_na-sg456en_us\&docLocale=en_US)
* [conman设置案例（日文）](https://shachimaru.wiki.fc2.com/wiki/conman)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://huataihuang.gitbook.io/cloud-atlas-draft/server/ipmi/conman.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
