hi,你好!欢迎访问本站!登录
本站由网站地图腾讯云宝塔系统阿里云强势驱动
当前位置:首页 - 教程 - 杂谈 - 正文 君子好学,自强不息!

详解k8s中的liveness和readiness的道理和区分

2019-11-18杂谈搜奇网27°c
A+ A-

liveness与readiness的探针工作体式格局源码剖析

liveness和readiness作为k8s的探针,可以对运用举行康健探测。
两者支撑的探测体式格局雷同。重要的探测体式格局支撑http探测,实行敕令探测,以及tcp探测。
探测均是由kubelet实行。

实行敕令探测

func (pb *prober) runProbe(p *v1.Probe, pod *v1.Pod, status v1.PodStatus, container v1.Container, containerID kubecontainer.ContainerID) (probe.Result, string, error) {
.....        
        command := kubecontainer.ExpandContainerCommandOnlyStatic(p.Exec.Command, container.Env)
        return pb.exec.Probe(pb.newExecInContainer(container, containerID, command, timeout))
......
        
func (pb *prober) newExecInContainer(container v1.Container, containerID kubecontainer.ContainerID, cmd []string, timeout time.Duration) exec.Cmd {
    return execInContainer{func() ([]byte, error) {
        return pb.runner.RunInContainer(containerID, cmd, timeout)
    }}
}
        
......
func (m *kubeGenericRuntimeManager) RunInContainer(id kubecontainer.ContainerID, cmd []string, timeout time.Duration) ([]byte, error) {
    stdout, stderr, err := m.runtimeService.ExecSync(id.ID, cmd, 0)
    return append(stdout, stderr...), err
}

由kubelet,经由过程CRI接口的ExecSync接口,在对应容器内实行拼装好的cmd敕令。猎取返回值。

func (pr execProber) Probe(e exec.Cmd) (probe.Result, string, error) {
    data, err := e.CombinedOutput()
    glog.V(4).Infof("Exec probe response: %q", string(data))
    if err != nil {
        exit, ok := err.(exec.ExitError)
        if ok {
            if exit.ExitStatus() == 0 {
                return probe.Success, string(data), nil
            } else {
                return probe.Failure, string(data), nil
            }
        }
        return probe.Unknown, "", err
    }
    return probe.Success, string(data), nil
}

kubelet是依据实行敕令的退出码来决议是不是探测胜利。当实行敕令的退出码为0时,以为实行胜利,不然为实行失利。假如实行超时,则状况为Unknown。

http探测

func DoHTTPProbe(url *url.URL, headers http.Header, client HTTPGetInterface) (probe.Result, string, error) {
    req, err := http.NewRequest("GET", url.String(), nil)
    ......
    if res.StatusCode >= http.StatusOK && res.StatusCode < http.StatusBadRequest {
        glog.V(4).Infof("Probe succeeded for %s, Response: %v", url.String(), *res)
        return probe.Success, body, nil
    }
    ......

http探测是经由过程kubelet要求容器的指定url,并依据response来举行推断。
当返回的状况码在200到400(不含400)之间时,也就是状况码为2xx和3xx是,以为探测胜利。不然以为失利。

tcp探测

func DoTCPProbe(addr string, timeout time.Duration) (probe.Result, string, error) {
    conn, err := net.DialTimeout("tcp", addr, timeout)
    if err != nil {
        // Convert errors to failures to handle timeouts.
        return probe.Failure, err.Error(), nil
    }
    err = conn.Close()
    if err != nil {
        glog.Errorf("Unexpected error closing TCP probe socket: %v (%#v)", err, err)
    }
    return probe.Success, "", nil
}

tcp探测是经由过程探测指定的端口。假如可以衔接,则以为探测胜利,不然以为失利。

探测失利的可以缘由

实行敕令探测失利的缘由重要多是容器未胜利启动,或许实行敕令失利。固然也可以docker或许docker-shim存在毛病。

由于http和tcp都是从kubelet自node节点上提议的,向容器的ip举行探测。
所以探测失利的缘由除了运用容器的问题外,还多是从node到容器ip的收集不通

liveness与readiness的道理区分

探测体式格局雷同,那末liveness与readiness有什么区分?起首,两者可以起到的作用差别。

func (m *kubeGenericRuntimeManager) computePodContainerChanges(pod *v1.Pod, podStatus *kubecontainer.PodStatus) podContainerSpecChanges {
        ......
        liveness, found := m.livenessManager.Get(containerStatus.ID)
        if !found || liveness == proberesults.Success {
            changes.ContainersToKeep[containerStatus.ID] = index
            continue
        }
        ......

liveness重要用来肯定什么时刻重启容器。liveness探测的效果会存储在livenessManager中。
kubelet在syncPod时,发现该容器的liveness探针检测失利时,会将其到场待启动的容器列表中,在以后的操纵中会从新建立该容器。

readiness重要来肯定容器是不是已停当。只有当Pod中的容器都处于停当状况,也就是pod的condition里的Ready为true时,kubelet才会认定该Pod处于停当状况。而pod是不是处于停当状况的作用是掌握哪些Pod应当作为service的后端。假如Pod处于非停当状况,那末它们将会被从service的endpoint中移除。

func (m *manager) SetContainerReadiness(podUID types.UID, containerID kubecontainer.ContainerID, ready bool) {
        ......
        containerStatus.Ready = ready
        ......
        readyCondition := GeneratePodReadyCondition(&pod.Spec, status.ContainerStatuses, status.Phase)
        ......
        m.updateStatusInternal(pod, status, false)
}

readiness搜检效果会经由过程SetContainerReadiness函数,设置到pod的status中,从而更新pod的ready condition。

liveness和readiness除了终究的作用差别,别的一个很大的区分是它们的初始值差别。

    switch probeType {
    case readiness:
        w.spec = container.ReadinessProbe
        w.resultsManager = m.readinessManager
        w.initialValue = results.Failure
    case liveness:
        w.spec = container.LivenessProbe
        w.resultsManager = m.livenessManager
        w.initialValue = results.Success
    }

liveness的初始值为胜利。如许防备在运用还没有胜利启动前,就被误杀。假如在划定时间内还未胜利启动,才将其设置为失利,从而触发容器重修。

而readiness的初始值为失利。如许防备运用还没有胜利启动前就向运用举行流量的导入。假如在划定时间内启动胜利,才将其设置为胜利,从而将流量向运用导入。

liveness与readiness两者作用不能互相替换。

比方只设置了liveness,那末在容器启动,运用还没有胜利停当之前,这个时刻pod是ready的(由于容器胜利启动了)。那末流量就会被引入到容器的运用中,可以会致使要求失利。虽然在liveness搜检失利后,重启容器,此时pod的ready的condition会变成false。然则前面会有一些流量由于毛病状况导入。

固然只设置了readiness是没法触发容器重启的。

由于两者的作用差别,在现实运用中,可以依据现实的需求将两者举行合营运用。

  选择打赏方式
微信赞助

打赏

QQ钱包

打赏

支付宝赞助

打赏

  移步手机端
详解k8s中的liveness和readiness的道理和区分

1、打开你手机的二维码扫描APP
2、扫描左则的二维码
3、点击扫描获得的网址
4、可以在手机端阅读此文章
未定义标签

本文来源:搜奇网

本文地址:https://www.sou7.cn/282143.html

关注我们:微信搜索“搜奇网”添加我为好友

版权声明: 本文仅代表作者个人观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。请记住本站网址https://www.sou7.cn/搜奇网。

发表评论

选填

必填

必填

选填

请拖动滑块解锁
>>