美文网首页K8S
利用 Kubernetes Service 的 selector

利用 Kubernetes Service 的 selector

作者: GoGooGooo | 来源:发表于2018-07-13 15:49 被阅读10次

    Kubernetes 有一个叫做 service 的功能,这个功能为 pod 提供负载均衡器的服务。当 pod 运行出现错误,或者停止工作的时候,有时候你想要从 service 上删除 pod 而不终止 pod。

    Service & Endpoints

    这个端点清单会自动更新 IP 地址和端口。因为对应的 pod 是根据定义在 service 上的标签选择器被选择出来的。这也就意味着 service 可以很轻松地跟 pod 本身结合。大家也可以看到选择器模式已经被运用到很多其它 Kubernetes 组件了,比如 Deployment,ReplicaSet。

    由于端点清单是基于标签选择器自动更新的,所以我们通过更新在 pod 上的标签将行为异常的 pod 拿走,这样的话它就不会跟选择器匹配了。为了能够更新 service,将 pod 从中移除,我们需要一个良好设计的标签选择器。
    所以,首先我们需要添加一个标签,这样就可以将任意 pod 从 service 中拿出来了。
    现在让我们用 enabled 标签来创建一个 Deployment:

    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: nginx
    spec:
      template:
        metadata:
          labels:
            name: nginx
            enabled: "true"
        spec:
          containers:
            - name: nginx
              image: nginx
    

    在我们的 service 中,我们在选择器中使用这些标签:

    apiVersion: v1
    kind: Service
    metadata:
      labels:
        name: nginx
      name: nginx
    spec:
      ports:
        - name: http
          port: 80
          targetPort: 80
      selector:
        name: nginx
        enabled: "true"
    

    之后,创建我们的 Deployment 和 service,这个过程中,这些 pod 是保持运行的。

    $ kubectl get pods nginx
    NAME                       READY      STATUS       RESTARTS    AGE
    nginx-1802606028-1posu     1/1        Running      0           27s
    nginx-1802606028-yjoty     1/1        Running      0           27s
    

    在这里,也是可以列出端点的。

    $ kubectl get endpoints nginx
    NAME         ENDPOINTS                      AGE
    nginx        10.40.3.6:80,10.40.3.7:80      22m
    

    假设 pod nginx-1802606028-1posu 服务异常,我们需要对其进行维护。首先让我们得到它的 pod IP。

    $ kubectl get pods -o jsonpath='{.items[?(@.metadata.name=="nginx-1802606028-1posu")].status.podIP}'
    10.40.3.7
    

    现在,为了对 pod 进行维护,我们把 enabled 标签修改成除了"true"的其它东西。我们需要输入--overwrite 标志来强制更新已经存在的标签。

    $ kubectl label pod nginx-1802606028-1posu enabled=false --overwrite
    pod "nginx-1802606028-1posu" labeled
    

    如果我们再次检查端点,我们就会注意到我们还是有两个端点。因为 Deployment 根据它的选择器发现它需要启动另一个 pod (进入维护状态的 pod 不再匹配 Deployment 的选择器导致符合要求的 pod 数量不及设定的数量)。

    $ kubectl get pods --show-labels
    

    我们注意到,正在维护的 pod 已经不在端点上了。

    $ kubectl get endpoints
    NAME         ENDPOINTS                      AGE
    nginx        10.40.3.6:80,10.40.3.8:80      25m
    

    现在我们可以对我们的 pod 进行维护。

    维护

    每个应用程序维护 pod 的方式都是不一样的,所以我在这里就不做深入了。然而,Kubernetes 很多功能都可以轻松连接到运行在你集群里的应用程序,所以在这里我简要描述一下。

    kubectl attach

    你可以连接到一个正在运行的 pod,通过标准输入发送数据,从标准输出获得调试信息。如果你的进程允许你在 stdin 上发送命令来获得关于内部状态的信息的话。但是,有些容器并不会创建 TTY。你能看到的是 stdout,这跟只使用 kubectl logs 差别不大。

    $ kubectl attach nginx-1802606028-1posu -it
    

    kubectl exec

    kubectl exec 意味着你可以在容器中执行命令。你可以使用它来做很多事情,可能要使用它来发送信号给容器中的进程。

    $ kubectl exec nginx-1802606028-1posu -- killall -HUP nginx
    

    或者,你可以开启一个 bash shell,如果你安装了 bash 的话。

    $ kubectl exec nginx-1802606028-1posu -ti -- bash -il
    

    kubectl port-forward

    另一个有用的功能就是 port forward 了。我们可以用这个来转移本地端口到我们的 pod,这样的话我们就可以给它发送请求,并且看到它是如何回应的。

    $ kubectl port-forward nginx-1802606028-1posu 8000:80
    Forwarding from 127.0.0.1:8000 -> 80
    Forwarding from [::1]:8000 -> 80
    

    接着,我们就可以从另一个终端给它发送请求。

    总结

    标签选择器令维护 pod 变得容易。但是还是有些细节需要你注意一下的。

    Service和Deployments
    由于 Service 和 Deployment 都经常使用标签选择器,所以当你将一个 pod 从 service 中移除,它仍然可能是 Deployment 的一部分,这种情况也是可能的。在大多数情况下,这都是 OK 的,但是如果你有一个 Deployment,带有 HorizontalPodAutoscaler 的功能,那么 Deployment 就可能任意时刻缩容而删除你的 pod。同样,当单个的 pod 从 service 中拿出来的时候,它仍然可能对你的应用程序产生影响。鉴于这些原因,我建议同样也要将 Deployment 拿出来,并且用 Deployment 来启动一个替代的 pod。

    将 Pods 放回到 Service
    在我们的 pod 上完成维护之后,我们可能就想要把它放回到 service。这个可以通过再次更新标签来匹配 service 选择器。

    $ kubectl label pod nginx-1802606028-1posu enabled=true --overwrite
    pod "nginx-1802606028-1posu" labeled
    

    原文链接

    相关文章

      网友评论

        本文标题:利用 Kubernetes Service 的 selector

        本文链接:https://www.haomeiwen.com/subject/vbxspftx.html