我的 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 都没有准备好,那么服务就没有任何意义,但我没有任何证据/文件来证明它的合理性。
最佳答案
为了使您的场景更容易理解,我们将它们称为 web 和 api。这些是我们服务的组件,虽然 web 将在几秒钟内准备就绪,但 api 组件将需要更多时间。
首先,我们需要决定我们的部署策略。如果我们将 web 和 api 放在同一个部署中,那么此部署之上的 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
仅此而已。现在,您可以根据请求扩大或缩小 web 和 api 部署,服务定义将自动对这些部署进行负载平衡并处理服务发现。
关于Kubernetes:服务路由到具有多个容器的 Pod,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62570366/