对于Docker的初学者而言,当容器或应用出现了问题不知从何入手进行排查。为此,我们准备了一个简单指南来帮助阿里云容器服务的用户进行故障排查。
由于阿里云容器服务完全兼容Docker Swarm,并支持使用原生Docker Client/API,所以很多内容对于 Docker/Docker Swarm的用户也是适用的。
Docker问题分类
我们可以把Docker在使用中的问题分为如下几类,
- 安装故障:Docker Engine 无法正常配置使用
- 应用故障:应用执行状态与预期不一致
- 容器故障:无法正确创建、停止、更新容器等
- 集群故障:集群创建失败、更新失败、无法连接等
Docker 安装问题解决
Docker Engine 无法下载
由于国内网络的特殊性,直接从Docker官网下载Docker Engine有可能导致失败。采用 https://yq.aliyun.com/articles/110806 这篇文章里提到的方法利用阿里云镜像进行安装Docker社区版。
阿里云ECS上安装Docker后, Docker守护进程无法启动问题
问题描述:
比如运行 docker run hello-world
命令 始终提示 Cannot connect to the Docker daemon
其原因是:Docker Engine缺省网络配置和阿里云操作系统镜像中路由规则冲突
解决方法:
运行如下命令删除该路由规则,并重启Docker Engine
service docker stop
route del -net 172.16.0.0/12
service docker start
为了防止虚机重启之后冲突的路由项会重新加入,还需执行如下命令行来彻底移除相应冲突项:
if [ -e /etc/network/interfaces ]
then
sed -i '/^up route add -net 172.16.0.0 netmask 255.240.0.0 gw/d' /etc/network/interfaces
fi
if [ -e /etc/sysconfig/network-scripts/route-eth0 ]
then
sed -i '/^172.16.0.0\/12 via /d' /etc/sysconfig/network-scripts/route-eth0
fi
Docker镜像下载缓慢或失败
阿里云提供了 Docker 镜像加速器,可以加速Docker Hub上面镜像下载的速度,请参照 https://yq.aliyun.com/articles/29941 进行配置
Docker 故障排查工具
所有问题诊断都可以通过Docker命令行工具或者Web控制台来完成。如果用户希望利用Web UI可以直接跳到下面章节。
利用Docker命令行工具访问阿里云容器服务集群的详细说明可以通过文档获得,简单而言操作如下
选择集群,点击连接信息
在弹出的窗口中,可以下载证书,并获得集群的访问信息
下载证书到指定目录,并输入下面命令
unzip -o certFiles.zip
复制上文中环境变量配置,粘贴到命令行
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://master1g3.cs-cn-beijing.aliyun.com:15344"
export DOCKER_CERT_PATH="$PWD"
注意:
- 如果Docker客户端和服务器端版本不一致,在某些操作过中会出现错误提示 “Error response from daemon: client is newer than server (client API version: 1.24, server API version: 1.23)” 目前阿里云容器服务支持Docker 1.11,可以从Docker 1.11 release网页下载相应操作系统的客户端安装包并拷贝到PATH路径中,比如
/usr/local/bin
- 每个集群的证书和访问信息都是独立的,否则无法正常连接
应用故障排查
1. 查看容器列表,定位、查找容器
列出集群中所有容器
在命令行中输入下列命令,会列出集群中所有运行的容器
docker ps
列出集群中所有的容器(包括非运行状态的容器)
docker ps -a
注意:所有容器服务的系统容器和Addon服务容器都已在结果列表中被过滤掉,以防误操作导致故障。
也可在Web控制台中,选择指定集群之后,点击“容器列表” 来列出集群中所有容器
列出属于指定应用、服务的容器
在命令行中输入下列命令,列出属于特定应用的容器
docker ps -a -f label=com.docker.compose.project=<name>
或在Web控制台中,选择指定应用之后,选中“容器列表” 选项卡
类似,可以在命令行中输入下列命令,列出属于指定服务名称的容器
docker ps -a -f label=com.docker.compose.service=<name>
或在Web控制台中,选择指定服务后,选中“容器列表”选项卡
列出属于特定节点的容器
在Web控制台中,可以获得指定集群的节点列表
可以SSH到指定节点,并利用docker ps
命令,列出当前节点中所有的容器
或者点击节点IP地址,可以列出指定节点的容器列表
2. 查看容器应用日志
在命令行中输入下列命令,查看指定容器在stdout/stderr的日志
docker logs <container-id>|<contianer-name>
查看指定容器最后100行日志
docker logs --tail=100 <container-id>|<contianer-name>
利用控制台Web界面,除了可以获得单个容器的日志信息,还可以获得指定应用、服务聚合的日志信息。选择指定应用、服务后,选中“日志”选项卡
注意:如果容器日志是输出的文件上,建议通过容器服务和日志服务的集成来采集容器日志,请参考容器服务中如何收集日志到阿里云日志服务; 或者下文中方法进入容器内部查看。
3. 查看容器进程信息
在命令行中输入下列命令,列出指定容器中运行的进程信息
docker top <container-id>|<contianer-name>
示例结果
yili@yili-mbp:~$ docker top 329a8e40a3b0
UID PID PPID C STIME TTY TIME CMD
999 32153 32106 0 Aug06 ? 00:23:56 redis-server *:6379
注意:这里的PID显示的是宿主机操作系统上的PID信息,可以利用宿主机上的诊断工具来检查进程问题。
3. 进入运行的Docker容器诊断问题
在命令行中输入下列命令,可以利用tty的交互方式进入容器内部执行命令
docker exec -ti <container-id>|<contianer-name> bash
注意:对于基于busybox, alpine等镜像的容器,在执行上述命令时可能会出现类似
“exec: "bash": executable file not found in $PATH.”的错误,这时可以利用 sh 作为 docker exec
的容器执行命令
docker exec -ti <container-id>|<contianer-name> sh
建议:在构建镜像的时候,可以把应用需要常见的故障诊断工具添加到容器镜像中。这样可以非常方便地进行故障调试
在控制台Web界面,可以选定指定容器并点击“远程终端”选项卡,会弹出如下的Web终端界面可以进入容器内部进行故障排查
注意:类似如果bash
不可用,可以在shell命令行中输入sh
来执行命令。
5. 查看容器性能信息
在命令行中输入下列命令,可以查看容器的性能监控信息
docker stats <container-id>|<contianer-name>
示例输出如下
CONTAINER CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
eb7647d9b2dd 0.06% 6.672 MB / 4.145 GB 0.16% 19.51 MB / 29.43 MB 8.192 kB / 4.096 kB 0
在控制台Web界面,可以选定指定容器并点击“监控”选项卡
4. 查看容器配置信息和运行时状态
在命令行中输入下列命令,可以查看容器的配置信息和运行时状态
docker inspect <container-id>|<contianer-name>
在控制台Web界面,可以选定指定容器并点击“详情”选项卡
容器故障排查
1. 应用、服务部署失败,查看事件列表
应用、服务的事件列表记录了对应用和服务操作的关键操作日志信息,可以快速定位应用、服务部署失败的原因。
在控制台Web界面,选定指定应用、服务并点击“事件”选项卡可以获得相应的容器事件列表。
比如在这个示例中,由于用户输入了错误的tomcat镜像tag,导致容器创建失败。
2. 容器启动后自动退出、或进入“restarting”状态
对于初学者而言,一个经常遇到的问题是Docker容器启动后自动退出,docker logs也没有特殊输出。如果容器启动参数时包含“--restart=always” 或“--restart”则会不停重启
这个问题常见的原因是容器的PID1进程(初始化进程)不是一个长时间运行的进程,或者它启动了一个后台进程就退出。由于容器服务是以“detach”方式运行容器,这样当PID1进程结束后就会导致整个容器退出。
可以参考Docker文档 和 理解Docker容器的进程管理中介绍的方法来解决这个问题。
比如,用户希望启动一个Ubuntu镜像
由于Ubuntu镜像缺省命令是“/bin/bash” 它在执行后会自动退出,我们需要将在服务的“command”在“更多设置”中将其修改为/bin/sh -c "while true; do sleep 10; done"
这样的死循环;这样可以保证容器的持续运行
建议:用户在Docker镜像的Dockerfile中应该设置正确的CMD或Entrypoint参数,来保证容器的正确执行
3. 应用部署之后,报告“Unable to find a node that satisfies the following conditions [port xxxx (Bridge mode)]”
当容器使用端口映射(docker run -p xxxx:xxxx
或者 compose模板中的ports
声明 )之后 系统会在宿主机上创建一个port,通过NAT来访问容器的指定port。如果宿主机上的端口被容器或者系统进程占用,就会导致端口分配失败。
注:因为集群管理会检查所有的容器来防止端口配置冲突,即使没有在运行状态的容器,如果已经声明过端口映射。相应的宿主机端口也会标记为已占用。
解决方法是,清除占用端口的容器或者进程,或者调整容器端口映射的宿主机端口避免冲突
4. 应用无法通过路由配置从外部访问
请参考访问链路排查
5. 查询Docker Engine日志
有时因为系统原因,Docker Engine无法正常创建、删除、启动、停止容器,我们需要查询Docker Engine日志来排查信息
首先我们需要定位到出现问题的节点,SSH登录到指定节点之后执行下列命令来查看Docker Engine日志
- Ubuntu 14.04:
less /var/log/upstart/docker.log
- CentOS 7.x/Ubuntu 16.04:
journalctl -r -u docker
集群故障排查
1. 如果集群节点创建、添加、agent升级失败,查看集群日志
在Web控制台,选择集群后,点击“查看日志”在弹出的窗口中可以获得对集群操作的日志信息,便于发现相应的问题和解决方案
2. 如果节点上容器出现性能问题,查看节点监控信息
从容器列表,可以获得容器和其对应的节点信息
从集群的节点列表,点击指定节点,可以获得相应的节点监控信息
注释:如果节点安装了云监控agent,还可以通过云监控获得对节点性能监控的详尽信息。
3. 如果节点健康状态异常,查看节点上系统agent容器状态
在阿里云容器服务上,每个节点运行着“acs-agent”和“tunnel-agent”两个系统容器负责与集群manager之间的通信和状态上报。虽然容器服务提供了对系统容器的自动恢复功能,但在特殊情况下,依然会由于系统容器失败会导致节点无法连接,这时候节点状态会变为“异常”
这时候要SSH登录到指定的节点,重启“acs-agent”和“tunnel-agent”容器,
docker restart tunnel-agent
docker restart acs-agent
并可以通过 docker logs
命令查看相应容器的日志信息
4. 关于集群创建的问题
请参见容器服务集群创建常见错误
总结
本文介绍了Docker故障的排查工具和操作指南,未来我们还会针对一些常见问题有针对性地介绍常见解决方法。
想了解更多容器服务内容,请访问 https://www.aliyun.com/product/containerservice