副本机制和其他控制器

2021-11-29
4 min read

一般创建一个没有托管的pod,会选择一个集群节点来运行pod,然后在这个节点上运行容器,k8s会监控这些容器并在失败时自动重启。但是如果整个节点失败,节点上的pod就会丢失且不会被新节点替换,除非pod由ReplicationController或类似的资源来管理。

在实际的应用中,如果希望部署能自动保持运行并保持健康,一般不会直接创建pod,而是创建ReplicationController或Deployment这样的资源,接着由他们来创建并管理实际的pod。

保持Pod健康

应用崩溃后可能能抛出错误,但是如果遇到了死锁等情况可能停止响应,为了确保这种情况下应用也可以响应,必须从外部检查应用的运行情况。

k8s利用存活探针(liveness probe)来检查容器是否还在运行,可以给每一个容器单独指定存活探针,如果探测失败,k8s会定期执行探针并启动容器。

  • 有三种探测容器机制:
    • HTTP GET探针对容器IP地址及指定端口发GET请求,如果收到相应且状态码不代表错误就表示探测成功
    • TCP套接字探针与容器指定端口建立TCP连接,如果连接成功建立就探测成功
    • Exec探针在容器内执行任意命令,并检查命令的退出状态码,如果为0表示探测成功,其他认为失败。

重启容器后可以通过kubectl describe 来了解为什么必须重启容器。

当容器被强行终止的时候,会创建一个新的容器而不是重启。可以在上述命令展示的Exit Code中看到,其数字为128+x,其中x为终止进程的信号编号,比如SIGKILL就是137(128+9),SIGTERM为143(128+15)。

在设置探针时,务必记得通过initialDelaySeconds来设置一个初始延迟,如果没有设置初始延迟,探针在启动的时候立即开始探测容器,通常会导致探测失败,因为此刻可能应用程序还没准备好接受请求,除此之外还可以通过timeout设置容器必须在多少秒内响应,设置period表示每隔多久探测一次容器,并可以在failure=x次后重启容器。

所以为了更好的存活检查,往往会将探针配置为请求特定的URL路径(比如/health),让应用从内部对内部运行的所有重要组件进行状态检查,值得注意的事情是要确保这个HTTP端点不需要认证,否则可能会一直失败。

探针应当保持轻量,必须1s内执行完毕,如果容器中运行JAVA程序,必须确保使用HTTP GET存活探针,而不是启动全新JVM来获取存活信息的Exec探针,任何基于JVM都应如此,他们的启动过程需要大量的计算资源。

重启容器的任务有pod的节点上的Kubelet来执行,主服务器上的Kubernetes Control Plane组件不会参与。但是如果节点崩溃了,那么Control plane就要为所有随着节点停止的pod创建替代品,为了能够在另一个节点上重新启动,需要使用ReplicationController或者类似机制来管理Pod。

Replication Controller

ReplicationController是一种k8s资源,确保它的pod始终保持运行(如果一个节点崩溃,他也只重建她负责的pod),如果pod消失,其会注意到缺失了pod并创建替代pod。一般而言,ReplicationController会创建和管理一个pod的多个副本(replicas)。

ReplicationController是根据pod是否匹配某个标签选择器来执行操作的。他会寻找匹配标签的pod,与期望数量比较,多了删少了加。

  • 一个ReplicationController有三部分:
    • label selector(标签选择器):确定作用域中的pod
    • replica count(副本个数):指定应该运行的pod数量
    • pod template(pod模板):创建新的pod副本