通过延长olcIdleTimeout以减少nslcd中的Can't contact LDAP server日志报错
客户用例执行失败, 其猜测可能是nslcd
服务中的Can't contact LDAP server
相关报错导致其生产用例执行失败.
nslcd
日志如下:
[fastone@layout01 ~]$ sudo journalctl -t nslcd| tail --line 20
Mar 28 11:58:24 layout01 nslcd[25607]: [debc9e] <group="fsadmin"> connected to LDAP server ldap://172.20.3.126:389
Mar 28 11:59:17 layout01 nslcd[25607]: [fe8aa7] <passwd=2032> ldap_search_ext() failed: Can't contact LDAP server: Broken pipe
Mar 28 11:59:17 layout01 nslcd[25607]: [fe8aa7] <passwd=2032> no available LDAP server found, sleeping 1 seconds
Mar 28 11:59:18 layout01 nslcd[25607]: [fe8aa7] <passwd=2032> connected to LDAP server ldap://172.20.3.126:389
Mar 28 12:00:01 layout01 nslcd[25607]: [272b88] <group/member="root"> ldap_result() failed: Can't contact LDAP server
Mar 28 12:00:36 layout01 nslcd[25607]: [66b17f] <group=2001> ldap_search_ext() failed: Can't contact LDAP server: Broken pipe
Mar 28 12:00:36 layout01 nslcd[25607]: [66b17f] <group=2001> no available LDAP server found, sleeping 1 seconds
Mar 28 12:00:37 layout01 nslcd[25607]: [66b17f] <group=2001> connected to LDAP server ldap://172.20.3.126:389
Mar 28 12:00:38 layout01 nslcd[25607]: [a15030] <passwd=2004> ldap_search_ext() failed: Can't contact LDAP server: Broken pipe
Mar 28 12:00:38 layout01 nslcd[25607]: [a15030] <passwd=2004> no available LDAP server found, sleeping 1 seconds
Mar 28 12:00:39 layout01 nslcd[25607]: [a15030] <passwd=2004> connected to LDAP server ldap://172.20.3.126:389
Mar 28 12:00:39 layout01 nslcd[25607]: [9b7b93] <passwd=2001> ldap_result() failed: Can't contact LDAP server
Mar 28 12:00:54 layout01 nslcd[25607]: [97bb68] <passwd=2011> ldap_result() failed: Can't contact LDAP server
Mar 28 12:01:36 layout01 nslcd[25607]: [005d16] <group=2011> ldap_result() failed: Can't contact LDAP server
Mar 28 12:03:39 layout01 nslcd[25607]: [b9081a] <group="fsadmin"> ldap_search_ext() failed: Can't contact LDAP server: Broken pipe
Mar 28 12:03:39 layout01 nslcd[25607]: [b9081a] <group="fsadmin"> no available LDAP server found, sleeping 1 seconds
Mar 28 12:03:40 layout01 nslcd[25607]: [b9081a] <group="fsadmin"> connected to LDAP server ldap://172.20.3.126:389
Mar 28 12:03:47 layout01 nslcd[25607]: [0f614b] <group/member="root"> ldap_search_ext() failed: Can't contact LDAP server: Broken pipe
Mar 28 12:03:47 layout01 nslcd[25607]: [0f614b] <group/member="root"> no available LDAP server found, sleeping 1 seconds
Mar 28 12:03:48 layout01 nslcd[25607]: [0f614b] <group/member="root"> connected to LDAP server ldap://172.20.3.126:389
从日志中可以发现nslcd
服务经常出现Can't contact LDAP server
.
问题原因
触发了ldap-server
的连接超时
这个问题的原因是因为触发了ldap-server
的超时时间, 从而导致nslcd
服务中的Can't contact LDAP server
相关报错.
ldap-server
的连接超时时间我们设置的默认为30s
为了确保连接不会被一直占用从而导致服务端负载过高.
但是频繁出现这个错误会让客户认为是我们的ldap-server
出现问题导致其用例失败, 我们需要延长超时时间来避免客户的误解.
解决方案
为了解决这个问题, 我们需要修改ldap-server
的超时时间.
ldap-server
中的超时时间是通过olcIdleTimeout
来设置的.
通过修改此值可以延长ldap-server
的连接超时时间.
需要注意的是, olcIdleTimeout
的单位是秒.
另外的一个注意事项是修改此值需要通过ldap
中的config
数据库的admin
用户来修改.
修改完成之后, 我们需要重启ldap-server
服务.
创建change-timeout.ldif
文件
先创建如下文件, 为了方便, 我们将超时时间设置为12h
.
dn: cn=config
changetype: modify
replace: olcIdleTimeout
olcIdleTimeout: 43200
通过ldapmodify
命令修改超时时间
我们需要连接ldap-server
并执行ldapmodify
命令来修改ldap
连接超时时间.
然后执行如下命令
需要注意的是, 执行ldapmodify
命令bind
的用户为cn=admin,cn=config
用户, 该用户是config
数据库的admin
用户.
ldapmodify -x -D cn=admin,cn=config -w <password-of-config-admin> -f change-timeout.ldif
该命令将会输出如下内容
modifying entry "cn=config"
当看到上面的输出时, 说明超时时间已经修改成功.
确认超时时间是否修改成功
执行如下命令
ldapsearch -x -D cn=admin,cn=config -w <password-of-config-admin> -b cn=config|grep olcIdleTimeout
该命令将会输出如下内容
olcIdleTimeout: 43200
olcAttributeTypes: ( OLcfgGlAt:18 NAME 'olcIdleTimeout' SYNTAX OMsInteger SING
PendingAuth $ olcDisallows $ olcGentleHUP $ olcIdleTimeout $ olcIndexSubstrIf
通过输出的内容可以看到olcIdleTimeout
的值已经被修改为43200
.
重启ldap-server
为了确保配置生效, 我们需要重启ldap
服务.
不同的ldap
服务的重启方式不同, 这里以ldap
容器为例.
docker restart <ldap-container>
验证配置是否生效
在安装有nslcd
服务的机器上执行如下命令.
两个命令中间间隔35s
. 如果配置没生效那么30s后会再次出现Can't contact LDAP server
的报错.
因为我们一开始默认的超时时间是30s
, 所以我们需要间隔35s
来验证配置是否生效.
getent passwd -s ldap && sleep 35s && getent passwd -s ldap
执行期间我们需要观察nslcd
服务的日志.
最好开两个终端, 一个执行命令, 一个查看日志. 这样可以更加直观的看到日志.
journalctl -u nslcd -f
如果配置生效那么我们将不会看到Can't contact LDAP server
的报错.
备注
默认超时时间的配置文件
dn: cn=config
changetype: modify
replace: olcIdleTimeout
olcIdleTimeout: 30
查看系统中的nslcd
服务的配置文件
cat /etc/nslcd.conf
查看ldap-server
的olcRoot
用户的信息
olcRoot
是ldap-server
的超级管理员, 通过该用户可以对ldap-server
进行管理.
执行如下命令查看ldap-server
的olcRoot
用户的信息.
cd /etc/ldap/slapd.d/cn=config && grep -r 'olcRoot' *
该命令将会输出如下参考内容
olcDatabase={0}config.ldif:olcRootDN: cn=admin,cn=config
olcDatabase={0}config.ldif:olcRootPW:: xxxx
olcDatabase={1}mdb.ldif:olcRootDN: cn=admin,dc=demo,dc=com
olcDatabase={1}mdb.ldif:olcRootPW:: xxxx
通过上述输出可以看到有两个olcRoot
用户, 一个是cn=admin,cn=config
, 另一个是cn=admin,dc=demo,dc=com
.
有这两个用户的原因是因为其是不同olcDatabase
的olcRoot
用户.
olcDatabase={0}config.ldif
是ldap-server
的配置数据库. 其主要存放了ldap-server
的配置信息.
olcDatabase={1}mdb.ldif
是ldap-server
的数据数据库. 其主要存放了ldap-server
的数据信息, 该数据是给我们使用的.
确保fd
数量可用
因为上面修改了ldap-server
的超时时间, 所以我们需要确保ldap-server
的fd
数量足够.