Portainer跨主机管理Docker容器踩坑记

3,796 阅读13分钟

跨主机Docker管理之Portainer踩坑记

还是折腾公司那几台云服务器,之前容器跨主机通信的问题尚未完全解决,最后还是使用了--net host的方式,临时处理了。

那这么多主机,那么多容器,总不能每台机都装个portainer,然后分着去管理吧,所以,在一个地方管理所有容器的需求就随之产生了

文章分6个内容说明

  1. 为什么使用portainer
  2. portainer管理多台主机的容器的方式
  3. 先来说说启动主服务的portainer
  4. 使用DockerApi的方式被扣完了绩效
  5. 使用Agent的方式差点就人没了
  6. 总结

为什么使用portainer

考虑到使用portainer,主要出于以下原因:

  1. 简单,方便,快速,直接Docker运行对应容器就完事了
  2. 要管理的机器不多,服务的访问量也未达到集群需求,只是微服务较多,如果使用k8s有点大材小用的感觉

portainer管理多台主机容器的方式

当前使用的镜像是:portainer/portainer

这个镜像支持跨主机管理容器的方式有4种:

  1. Agent
  2. Edge Agent
  3. Docker
  4. Azure

Agent

Agent的方式,是在需要主服务器管理的分主机中,运行portainer/portainer-agent容器,然后配置后,达到跨主机管理容器的功能

Edge Agent

嗯,比较麻烦的一种方式,另外就是,这种方式很卡(网友说的),所以直接不看了

Docker

这种试是利用Docker Api进行直连

这个的好处是,这个是docker原生的支持的功能,只需要简单;

另外,也不需要在每个分服务器都额外运行一下portainer/portainer-agent容器

Azure

压根没考虑过,所以连是啥,怎么弄都没兴趣了,看字面意思就是连接到微信的Azure的ACI

增加端点的入口

在主服务器运行好portainer主容器后,进行portainer界面,并完成基本配置:

完成基本配置的portainer界面 内容框中,一般会直接出现当前主机的容器管理:local

在菜单栏中,找到Endpoints,点击并进入:

点击Endpoints后的portainer界面

点击Endpoints内容框中的Add endpoint,可进入到其他端点配置界面:

Endpoint中的Add endpoint按钮

进入后,可以按照需要,选择不同的方式 配置Endpoint的配置界面

先来说说启动主服务的portainer

portainer的镜像有3种,分别是:

  • portainer/portainer-ce: 社区版
  • portainer/portainer-ee:企业彼
  • portainer/portainer:不知道什么版,简单、好用,直接就用这一个

这里就直接使用portainer/portainer这个镜像了,运行命令:

# 运行命令
docker run -d --restart=always --name portainer \
-p 12000:9000 -p 11000:8000 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/local/portainer/data:/data \
-e AGENT_SECRET=你的密码 \
portainer/portainer

这里对Docker的基础命令就不作说明了,这里主要说一下注意的点

端口建议还是作一下偏移,毕竟免费的东西

docker.sock一定要挂载到宿主机的docker.sock,不然容器管理时,无法加载到本机的docker内容,页面上也会报错,一般docker安装后,都是在/var/run/docker.sock

data目录挂载可有可无,看个人所需

环境配置:AGENT_SECRET 这个还是建议直接加上的,不管后继是否需要集群,反正多这一个参数也没有影响。 但是如果后继需要使用Agent集群,这个一定要加上,不然可能人都没了

好了,下面开始说说我的血泪史

使用DockerApi的方式被扣完了绩效

真的,绩效全扣完了!!!

使用Docker Api的方式,最简单,只需要对Docker的参数进行调整,然后重启就可以直接了:

# 对Docker配置文件编辑
vim /usr/lib/systemd/system/docker.service

# 把配置文件中的
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
# 修改成
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H fd:// --containerd=/run/containerd/containerd.sock

# 保存退出后重载Docker Daemon并重启Docker
systemctl daemon-reload
systemctl restart docker

Docker重启后,进入到添加Endpoint界面进行配置:

通过Docker Api添加Portainer Endpoint

这样就可以在home界面看到配置的端点,进入端口就可以对容器进行访问了

下面说说是怎么被扣完绩效的

看上面的配置,跟网上的教程不能说一模一样,简直就是一模一样!!!

你要按这上面的,你老板如果不好说话,别说绩效,送你一对银手镯都有可能!!~~

你可能觉得危言耸听,但如果说到挖矿病毒,你可能现在就坐直身体了。

没错,我就是按了上面的教程,弄到了生产环境,然后中了挖矿病毒,然后用了一整天的时间,进行了病毒清理,整个过程呕心沥血!!完事了还得写事故报告,罚没绩效!!

中招后的状态

作以上配置后,突然发现各服务陆续中断,经过检查,与查找资料,确认中招挖矿病毒。

  1. 通过top命令,发现CPU使用率持续高达50%,而进程列表中并无体现高强度的CPU使用状况。
  2. 服务器非常的卡顿
  3. 服务经常中断
  4. .ssh/authroize_keys文件被锁死,且被额外增加一条密钥串
  5. /etc/ld.so.preload默名增加了三个资源
  6. docker启动容器中,出现两个不明容器 zealous_agelast, limpid_agelast
  7. chattr -i 命令被提示没有配置,但是去安装工具时,又提示已安装

说说是如何处理的

  1. 根据中招状态6不明容器查询网络资料,确认是中了挖矿病毒,再通过“挖矿病毒”关键词,得到可以尝试查看/etc/ld.so.preload是否有相关配置:

    # 查看隐藏进程
    cat /etc/ld.so.preload
    ​
    #使用以上命令后,果然此文件中,存在一些配置
    /usr/local/lib/[cmake].so
    /usr/local/lib/pnscan.so
    /usr/local/lib/masscan.so
    ​
    
  2. 尝试使用rm -rf命令对此文件进行删除,发现文件被锁死,通过网络资料,推荐使用chattr命令

    # 尝试删除/etc/ld.so.preload文件,提示被锁定了
    rm -rf /etc/ld.so.preload
    ​
    # 提示:
    rm: cannot remove 'ld.so.preload': Operation not permitted
    ​
    # 使用chattr命令,提示命令不存在
    chattr -i /etc/ld.so.preload
    # 提示:
    -bash: chattr: command not found
    ​
    # 安装 chattr,但提示已安装
    yum install -y e2fsprogs
    # 提示
    Package e2fsprogs-1.42.9-19.el7.x86_64 already installed and latest version
    Nothing to do# 重新安装chattr后,可以使用
    yum reinstall -y e2fsprogs
    ​
    # 再次使用命令,可以使用了,直接使用-ia,因为后面还有文件除了i权限,还有锁死了a权限
    chattr -ia /etc/ld.so.preload
    ​
    # 再次尝试删除,成功
    rm -rf /etc/ld.so.preload
    ​
    ​
    
  3. 删除/etc/ld.so.preload中指向的相关文件:

    #分别查找对应的相关文件目录
    whereis [cmake]
    whereis pnscan
    whereis masscan
    ​
    # 分别返回
    [cmake]: /usr/local/lib/[cmake].so /usr/share/[cmake]
    pnscan: /usr/local/bin/pnscan /usr/local/lib/pnscan.so
    masscan: /usr/bin/masscan /usr/local/lib/masscan.so
    ​
    # 对相关文件进行解锁
     chattr -i /usr/local/lib/[cmake].so
     chattr -i /usr/local/lib/pnscan.so
     chattr -i /usr//local/lib/masscan.so
     
    # 删除相关文件
    rm -rf  /usr/local/lib/[cmake].so /usr/share/[cmake]
    rm -rf /usr/local/bin/pnscan /usr/local/lib/pnscan.so
    rm -rf /usr/bin/masscan /usr/local/lib/masscan.so
    
  4. 由于top无法体现高消耗进程,此处需要使用第三方软件进行查看

    # 安装htop命令进行查看,可以发现高占用进程
    yum install -y htop
    
    # 使用htop命令,可以看到真实的占用信息
    htop
    
    # 列表数据,通过htop列表发现,存在高消耗进程
      PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
     1609 root       20   0  119M  2696  1376 S 26.4  0.0  0:14.60 /bin/bash /etc/.httpd/.../http
    22473 root       20   0  195M 36844  3064 S  7.9  0.2  0:04.50 masscan 116.0.0.0/8 -p8090 --r
    22479 root       20   0  195M 36844  3064 S  7.9  0.2  0:04.37 masscan 116.0.0.0/8 -p8090 --r
    19386 root       20   0  201M 36884  3076 S  4.6  0.2  0:41.28 masscan 77.0.0.0/8 -p2376 --ra
    19391 root       20   0  201M 36884  3076 S  4.0  0.2  0:38.92 masscan 77.0.0.0/8 -p2376 --ra
    23809 root       20   0  201M 36880  3076 S  4.0  0.2  0:39.05 masscan 114.0.0.0/8 -p8088 --r
    23814 root       20   0  201M 36880  3076 S  4.0  0.2  0:36.76 masscan 114.0.0.0/8 -p8088 --r
      428 root       20   0  122M 68492 67716 S  3.3  0.4 12h29:39 /usr/lib/systemd/systemd-journ
    
  5. 通过htop列表发现,存在高消耗进程,且其中的masscan明显为对应的病毒,对其进行删除处理:

    kill -9 22473 19386 23809
    
  6. 删除后,使用Top命令,发现CPU最高消耗的httpd及systemd-journal 也是网络资料中的相关病毒:

    # 使用top命令后的新列表
     1614 root      20   0  121852   1832   1352 S  12.0  0.0   0:00.77 httpd                   
     1595 root      20   0  121856   1884   1364 S  11.0  0.0   0:00.69 httpd                   
     1636 root      20   0  121852   1844   1352 S  11.0  0.0   0:00.68 httpd                   
      428 root      20   0  134024  70976  70200 R   8.3  0.4 749:41.76 systemd-journal 
    
  7. 考虑到systemd-journal 可能是httpd的守护进程,优先对其进行相关删除:

    rm -rf /usr/lib/systemd/systemd-journald
    
  8. 开始消除httpd相关进程:

    # 通过PID找到进程运行的相关目录:
     ps -ef|grep 21364
    # 返回信息
     root     21364     1 22 19:08 ?        00:00:11 /bin/bash /etc/.httpd/.../httpd
    
    # 删除相关文件
    rm -rf /etc/.httpd
    
    # 杀掉相关进行
    kill -9 21364 1595 1614 1636 428
    
    # 杀掉进行后,Top列表还是会有新的httpd进程启动
    21073 root      20   0  119128   5280   1352 S  14.7  0.0   0:15.48 httpd                   
    21134 root      20   0  119248   5444   1340 S  14.7  0.0   0:15.84 httpd                   
    20970 root      20   0  119120   5296   1340 R  14.3  0.0   0:16.17 httpd  
    
    # 继续通过PID找到进程运行的相关目录:
    ps -ef|grep 21134
    # 返回 
    root     21134     1 13 19:09 ?        00:00:16 /bin/bash /var/.httpd/...../httpd
    
    # 删除相关文件目录
    rm -rf /var/.httpd
    
    # 杀掉相关端口
    kill -9 21073 21134 20970
    
    # 再使用top命令,此时相关病毒不再启动,服务恢复正常,CPU消耗也正常:
    top - 20:59:23 up 231 days, 11:40,  1 user,  load average: 0.13, 0.08, 0.05
    Tasks: 151 total,   1 running, 150 sleeping,   0 stopped,   0 zombie
    %Cpu(s):  0.1 us,  0.1 sy,  0.0 ni, 99.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    KiB Mem : 15906116 total,  2375244 free,  4556884 used,  8973988 buff/cache
    KiB Swap:        0 total,        0 free,        0 used. 10167796 avail Mem 
    
      PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                           
     3955 root      20   0 6357372 686476  17020 S   0.3  4.3   3:32.22 java                              
     7020 root      20   0  708396  16644   3480 S   0.3  0.1  12:33.95 barad_agent                       
    11530 root      20   0   19.4g 757532  13808 S   0.3  4.8   2:34.56 java                              
    27262 root      20   0 1834356  91680  30380 S   0.3  0.6   1:13.93 dockerd                           
        1 root      20   0  191376   4072   2328 S   0.0  0.0  47:40.62 systemd
        
    
  9. 开始处理ssh免密登录:

    # 查看.ssh/authorized_keys发现,被追加了一条公钥
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDAFleIodig6TkqKTTrCDdMUehq+7uLDaSC81DR2hVFS7aoLndSS3fJA18OXUDN1DdI05jXbC3G1wmFYWa7+y/i8UGGA5Ht4jjg+wNSxl3ef1AxLLdon4feSU+gFVmlVmcfVMv/Tm+Iswg2OGJ0SD6Vg+kCJYBo90AOSDJKE4eotzwNwKHB8k/4HBcJl root@puppetserver
    ​
    # 尝试编辑时,提示禁止修改,使用chattr -i .ssh/authorized_keys,后,仍不能修改
    chattr -i .ssh/authorized_keys
    ​
    # 使用lsattr .ssh/authorized_keys,发现文件被增加了更多的权限
    lsattr .ssh/authorized_keys
    # 返回
    ----ia-------e-- authorized_keys
    ​
    # 继续使用chattr解锁文件权限
    chattr -ia authorized_keys
    ​
    # 使用命令后,发现已经可以修改密钥配置,删除密钥后保存# 同时.ssh路径会同时存在authorized_keys2文件,其拥有authorized_keys一样的权限,对其进行解锁后,删除文件# 重载sshd服务
    systemctl restart sshd
    ​
    
  10. 最后,再次观察,发现服务器此时的进程情况正常,CPU占用正常:

    %Cpu(s):  0.1 us,  0.1 sy,  0.0 ni, 99.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    KiB Mem : 15906116 total,  2375244 free,  4556884 used,  8973988 buff/cache
    KiB Swap:        0 total,        0 free,        0 used. 10167796 avail Mem 
    
      PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                           
     3955 root      20   0 6357372 686476  17020 S   0.3  4.3   3:32.22 java                              
     7020 root      20   0  708396  16644   3480 S   0.3  0.1  12:33.95 barad_agent                       
    11530 root      20   0   19.4g 757532  13808 S   0.3  4.8   2:34.56 java                              
    27262 root      20   0 1834356  91680  30380 S   0.3  0.6   1:13.93 dockerd                           
        1 root      20   0  191376   4072   2328 S   0.0  0.0  47:40.62 systemd 
    

Docker Api的方式是不是就不能用了?

我觉得存在即合理,肯定是可以用的,但是怎么用,还是需要思考一下,看最后总结吧,虽然没有验证过,我觉得应该是一种使用方式。

使用Agent的方式差点就人没了

先说明一下,Agent没有Docker Api的方式严重,更多的是可能存在的风险,这个标题就是危言耸听,妥妥的标题党!

首先说一下启动Agent的命令:

docker run -d --restart=always --name portainer_agent \
-p 12001:9001 \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/docker/volumes:/var/lib/docker/volumes \
-v /:/host \
-e AGENT_SECRET=你的密码 \
portainer/agent

与主服务的portainer一样,docker.sock挂载到宿主机的docker,端口作一下偏移

环境变量 AGENT_SECRET 对应上主服务portainer的,这样就可以在endpoint添加界面添加端点了:

portainer添加Agent Endpoint

通过配置可以知道,没有地方填密码,这是因为主portainer与portainer-agent会自行根据环境变量中的AGENT_SECRET进行判断,如果两者不一样,是没有办法添加对应的Agent endpoint的。

所以,如果运行命令中不添加 AGENT_SECRET 环境变量,如果公网IP不小心暴露,容器就可能存在被他人添加,然后容器被他人控制。

总结

  1. 在应用新的功能之前,应进行小范围试验,而不应该直接大范围的使用
  2. 在应用新的功能之前,应该就可能存在的风险进行考察
  3. 不能盲目的使用网上的教程,应考虑实际的使用场景
  4. 需要非常注意网络,如果使用Docker Api,不是直接采用0.0.0.0:2375, 而是配置为对应的内网,以及对端口进行偏移,应能极大的减少被攻击的可能性。
  5. 使用portainer-agent是一个不错的选择,虽然需要额外启动一个agent容器,但是不涉及直接的Docker操作,也不复杂。