Kubernetes:服务路由到具有多个容器的 Pod

标签 kubernetes containers kubernetes-pod kubernetes-service

我的 Kubernetes 集群目前遇到问题。在调试时,我想到了一个我不知道答案的问题。

我正在使用 AWS EKS 版本 1.15,但我认为我的问题与任何特定云或 kubernetes 版本无关

我有一个部署。它有多个容器。有一个服务公开此部署。

假设部署有 2 个容器:C1 和 C2。 C1 需要 1 秒才能启动,但 C2 需要 30 秒才能启动(疯狂!)。所以,当我在时间 t1 启动 pod 时,发生的情况是,一旦 C1 立即启动,pod 进入运行状态,但只有 1/2 容器准备就绪。 Pod C2 最终在时间 t2(t1+30 秒)启动。在时间 t2 时,2/2 个容器已准备就绪。

还假设 C1 从服务获取传入请求,它执行某些操作,然后将请求转发给 C2,C2 执行某些操作,然后将其返回给 C1。 C1 最终返回服务并将响应发送给客户端。

所以,我的问题是,在 t2 和 t1 之间,当 pod 处于运行状态但只有 1/2 容器准备就绪时,服务会将请求转发到 pod 吗?

换句话来说,服务什么时候将请求转发给 Pod?如果它们处于运行状态并且无论有多少容器已准备就绪?或者它们是否处于运行状态并且所有容器都已准备好?

我的想法是,服务不会转发,因为如果所有 Pod 都没有准备好,那么服务就没有任何意义,但我没有任何证据/文件来证明它的合理性。

最佳答案

为了使您的场景更容易理解,我们将它们称为 webapi。这些是我们服务的组件,虽然 web 将在几秒钟内准备就绪,但 api 组件将需要更多时间。

首先,我们需要决定我们的部署策略。如果我们将 webapi 放在同一个部署中,那么此部署之上的 service 对象将强制执行它们的定义。因此,如果您想在端口 443 上公开您的 web 服务,那么 api 也将在端口 443 上公开。是的,您可以标记它们并设置不同的定义,但是这远非理想。

我们可以说 Kubernetes 世界中的服务对象就像一个负载均衡器。因此,如果您将两个不同的组件放在同一个部署上,并在它们之上定义一个服务对象,那么当您从外部网络调用您的服务时,您最终将到达 web api 端点,随机。

您可以查看此图像以进行可视化:Kubernetes Service Example

在理想的情况下,您需要在两个不同的部署中部署此应用程序,因为它们可以解耦并用于不同的目的。部署这些之后,您所需要做的就是部署两个不同的服务来公开您的部署。据我了解,api仅在内网运行,因此可以是headless-service

首先,让我们为应用程序创建一个命名空间(或项目)。

kubectl create ns myapp

并定义我们的部署因此,对于我们的web组件,让我们定义部署文件;

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
  labels:
    app: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 9376

以及将我们的 Web 部署公开给外部网络的服务

apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

您可以看到 web-deployment 部署对象具有三个副本,web-service 服务定义将相应地对传入请求进行负载平衡。

现在,让我们部署 api

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment
  labels:
    app: api
spec:
  replicas: 5
  selector:
    matchLabels:
      app: api
  template:
    metadata:
      labels:
        app: api
    spec:
      containers:
      - name: api
        image: apirepo/api
        ports:
        - containerPort: 3000

以及用于api部署的 headless 服务

apiVersion: v1
kind: Service
metadata:
  name: api-headless-service
spec:
  clusterIP: None 
  selector:
    app: api
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000 

仅此而已。现在,您可以根据请求扩大或缩小 webapi 部署,服务定义将自动对这些部署进行负载平衡并处理服务发现。

关于Kubernetes:服务路由到具有多个容器的 Pod,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62570366/

相关文章:

c++ - 带有列表的 std::generate_n 函数

用于存储最新值的 C++ 固定大小容器

kubernetes - 在 kubernetes pod 中执行多个命令(或从 shell 脚本)

kubernetes - istio-1.7.2 安装,缺少仪表板和 pod?

nginx - 如何使用 nginx 入口 Controller 拥有 header 路由逻辑?

node.js - 使用 DataDog 的 Helm Chart 进行 DataDog GKE NESTJS 集成

javascript - Internet Explorer 6 的 jQuery height() 问题

kubernetes - 更新图像标签以通过CloudBuilder提交SHA的最佳方法是什么?

kubernetes - 从 GKE 1.15 更新到 1.16 时的 Prometheus (node_exporter) 问题

azure - 如何在本地 kubernetes(k8s) 集群上分配 Azure Pod 身份(开发时)