注意:以下文档只适用于TOP接口,请谨慎使用!

文档中心 > 聚石塔

容器相关常见问题

更新时间:2022/01/18 访问次数:720

1.容器实例重启

容器重启的直接原因:云应用配置了健康检查,且健康检查存活探针失败,被集群自动重启。

详情请参考:云应用健康检查配置。健康检查配置示例:

image.png

检查延迟:容器启动后多少s开始进行健康检查。

检查间隔:健康检查开始后,按照固定间隔进行轮询,每隔xx秒检查一次。

超时时间:超过多少时间没有返回(http)或者没有正常退出(shell脚本),则认为该次检查超时(失败)。

失败次数阈值:连续轮询多少次均失败后则认为健康检查失败,达到重启条件,集群对容器进行重启


注:容器启动后,内部的应用进程也是刚启动,很可能没有启动完成,比如Java web还在启动Servlet、nodejs可能还在npm install,所以需要设置一定的检查延迟。

健康检查能在一定程度上维护应用稳定,比如容器中的Java进程因为OOM被内核kill,如果不设置健康检查,容器就不会重启。但是如果容器不重启,就会一直宕机着(也就是容器是存在着,但是里面的应用进程没有了),无法对外提供服务。


那么,现在的问题是需要定位到健康检查失败的原因,这里只能提供一些常见源头的排查思路:

1)健康检查设置不合理,比如健康检查的延迟时间设置太短,服务还没有启动起来,健康检查就开始了,进而导致失败;比如健康检查超时时间设置太短,健康检查本身的执行如果有一定耗时,超过了设置的超时时间,也算失败,比如运行一段时间后,应用性能开始下降,导致健康检查也超时。

2)应用进程OOM,Java类型应用比较容器出现的(当然,PHP也有可能)。一般是由于容器规格和JVM进程的启动参数配置不够,可以适当进行优化。结合应用基础监控,观察内存使用趋势;可以为集群配置事件告警,当有OOM事件或者容器重启事件发生时,会有告警消息推送

3)应用自身问题或下游服务异常,举个例子,云应用中访问RDS,如果RDS某个时刻性能特别差,云应用自身吞吐不够,整体huang住,新的请求均会失败,健康检查探针也会失败,进而导致容器重启。需要关注服务响应性能,建议接入ARMS应用监控(收费云产品),可以对应用性能有直观的监控,同时特需要自行观察下游服务的监控信息

4)宿主机docker daemon或者kubelet的一些内核异常,出现概率较小。这里也是推荐为集群配置事件告警,宿主机ECS出现一些问题时,能够及时感知

2.容器实例驱逐

应用发布后,过了一段时间来看,实例的名称、IP、创建时间自己变了?

image.png

很可能是因为原Pod实例被驱逐,集群重新调度创建了新的实例。除开手动排空节点(将宿主机上的容器驱逐出本宿主机),该现象一般是由于节点上某些资源使用达到了某个阈值,集群按照一定的调度策略,将节点上的一些Pod实例赶出去,然后由集群重新调度新的实例分配到其他节点。最常见的是磁盘,默认的docker容器运行在系统盘,当系统盘磁盘使用量超过90%时,节点上的实例会被驱逐。驱逐重新调度再启动的过程中,会对线上业务产生影响。

?

解决方案:

1)优化容器本身对磁盘等资源的占用、使用数据盘等,参考磁盘占用较大的原因

2)为集群和应用配置事件告警,分别配置应用和集群(节点)维度的事件告警后,应用的Pod发生驱逐、节点资源不足(或者磁盘回收失败)等事件就能第一时间感知。比如类似的事件:

2020-07-21 10:24:43.000 [Event] Type: Warning, Reason: Evicted, Message: The node was low on resource: ephemeral-storage. 

The node had condition: [DiskPressure],表示节点磁盘使用率比较高

failed to garbage collect required amount of images 磁盘不足引起集群对磁盘进行回收(无用的镜像和容器),回收失败则会告警


PS: 对于已经被驱逐的Pod,可以在“失败实例”中看到,建议手动清理,去过集群上被驱逐的失败Pod膨胀,会影响集群自身性能。

image.png

3.如何在容器中设置hosts

1)使用自定义镜像,在自定义镜像中dockerfile中指定自己需要的hosts,参考如下

RUN echo "192.168.1.37 testgitlab.kuaidihelp.com"  >> /etc/hosts

关于自定义镜像制作:https://www.yuque.com/fczggw/wu7u0k/cwb0v2#y4TJ1


注,如果之前使用的是官方镜像,可以base官方镜像来制作你的自定义镜像,dockerfile可以这样写:

// 前缀registry.cn-zhangjiakou.aliyuncs.com不变,后面"jstopen/tomcat8:1.0.0"为使用的官方镜像
FROM registry.cn-zhangjiakou.aliyuncs.com/jstopen/tomcat8:1.0.0
RUN echo "192.168.1.37 testgitlab.kuaidihelp.com"  >> /etc/hosts


2)使用yaml类型部署配置,在容器spec中定义hostAliases

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: stilton
  labels:
    app: cheese
spec:
  replicas: 2
  selector:
    matchLabels:
      app: cheese
  template:
    metadata:
      labels:
        app: cheese
    spec:
      containers:
      - name: cheese
        image: errm/cheese:stilton
        ports:
        - containerPort: 80
      hostAliases:
        - ip: 127.0.0.1
          hostnames:
          - myadded.examplehostname


4.容器内获取容器名称、IP等元信息

可以在容器内通过调用系统环境变量,获取以下信息:

  • 容器IP => JST_POD_IP
  • 宿主机ECS IP => JST_NODE_IP
  • 容器名称 => JST_POD_NAME
  • 容器所属Namespace => JST_POD_NAMESPACE


如下图所示:

image.png


5.容器实例无法远程登录(无法查看容器日志)

1)检查实例是否成功发布,状态是否正常,异常状态下无法远程登录

应用-环境管理-实例列表:

image.png

若容器实例状态非正常,请先解决容器部署问题,更多请参考:https://www.yuque.com/fczggw/wu7u0k/riku5o#CSwn6


2)如果实例正常(如上图所示),通常是因为手动操作了ECS安全组,宿主机ECS不在集群安全组导致的。

注:上述截图中容器实例的宿主机IP即为实例所在ECS的内网IP,通过该IP可以找到ECS。

① 找到该环境实例所属的容器集群,集群详情页找到相关的VPC和安全组信息

image.png

② 聚石塔控制台-安全组管理,找到对应的VPC和安全组,检查ECS是否在安全组中,没有的话添加一下

https://console.cloud.tmall.com/component/securityGroup#/

image.png

image.png

image.png


6.容器内日志中文乱码

容器中的文件支持中文,容器操作系统本身需要支持中文编码(可以在容器中执行locale命令查看)、同时应用本身如tomcat等也需要配置中文编码。注:聚石塔官方镜像均支持中文UTF-8编码,使用官方镜像的应用可以在容器中执行locale名称查看。


1.使用的聚石塔官方镜像,聚石塔官方镜像基本都支持中文编码(在容器中执行locale命令进行确认)。

如果是已经支持了中文编码的官方镜像,请确认应用自身编码配置。

另外可以在环境配置中新增一个环境变量,LANG=en_US.UTF-8;或者在Java启动参数中加上

-Dfile.encoding=UTF-8。修改环境变量等配置后需要重新部署后生效

?

2.如果使用的自定义镜像,请自行解决。

FAQ

关于此文档暂时还没有FAQ
返回
顶部