我目前在Kubernetes集群中遇到问题。调试时,我想到的是一个我不知道答案的问题。
我正在使用1.15版的AWS EKS,但我不认为我的问题与任何特定的云或kubernetes版本有关
我有一个部署。它具有多个容器。有可以公开此部署的服务。
假设部署有2个容器C1和C2。 C1需要1秒才能启动,但C2需要30秒才能启动(疯狂!)。因此,当我在时间t1启动Pod时,发生的情况是,一旦C1立即启动并且Pod进入运行状态,但只有1/2个容器就绪。吊舱C2最终在时间t2(t1 + 30秒)开始。在时间t2,已经准备好2/2个容器。
还假定C1接受来自服务的传入请求,它执行某些操作,然后将请求转发到C2,C2执行某些操作,然后将其返回给C1。 C1最终恢复服务,并将响应提供给客户。
所以,我的问题是,在t2到t1之间的时间段内,当pod处于运行状态但只有1/2容器就绪时,服务会将请求转发到pod吗?
采用另一种方式,服务何时将请求转发到Pod?如果它们处于运行状态,则没关系准备好多少个容器?或者,如果它们处于运行状态并且所有容器都准备好了?
我的想法是,该服务将不会转发,因为如果所有Pod尚未准备就绪,但我没有任何证据/文件证明它正确,那么它将毫无意义。
答案 0 :(得分:3)
为了使您的情况更易于理解,请将其称为网络和 api 。这些是我们服务的组成部分,而网络将在几秒钟内准备就绪,而 api 组件将需要更多时间。
首先,我们需要确定我们的部署策略。如果我们将 web 和 api 放在同一部署中,则此部署顶部的 service 对象将对这两个对象都进行定义。因此,如果您想在端口443上公开您的网络服务,那么 api 也将在端口443中公开。是的,您可以标记它们并设置不同的定义,但是这远非理想。
我们可以说Kubernetes世界中的 service 对象就像负载均衡器一样。因此,如果将两个不同的组件放在同一部署上,并在它们之上定义一个服务对象,那么当您从外部网络调用服务时,最终将到达 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部署
的无头服务apiVersion: v1
kind: Service
metadata:
name: api-headless-service
spec:
clusterIP: None
selector:
app: api
ports:
- protocol: TCP
port: 80
targetPort: 3000
仅此而已。现在,您可以根据请求扩大或缩小网络和 api 部署,服务定义将自动对这些负载进行负载平衡并处理服务发现。
答案 1 :(得分:1)
...当pod处于运行状态但只有1/2容器准备就绪时,服务会将请求转发到pod吗?
否。
服务何时将请求转发到Pod? 如果它们处于运行状态,则没关系准备好多少个容器?或者,如果它们处于运行状态并且所有容器都准备好了?
我的想法是,该服务将不会转发,因为如果所有Pod尚未准备就绪,但我没有任何证据/文件证明它正确,那么它将毫无意义。
官方文档说:“ ...小桶使用就绪探测器来了解容器何时准备开始接受流量。当Pod的所有容器准备就绪时,Pod被视为准备就绪。该信号的作用是控制将哪些Pod用作服务的后端。当Pod未准备好时,将从Service负载均衡器中将其删除...”
另外说:
“ ......应用程序暂时无法提供流量...一个应用程序可能取决于外部服务...在这种情况下,您不想杀死该应用程序,但又不想发送它Kubernetes提供了就绪性探针来检测和缓解这些情况。装有容器的容器报告其容器尚未准备就绪,不会通过Kubernetes Services接收流量...“
就绪探针用于检测流量不应发送到App的情况。
我的想法是服务不会转发,因为如果所有Pod尚未准备就绪,它将毫无意义
您绝对在这里。
我希望能帮上忙。
答案 2 :(得分:0)
从文档here
就绪:该Pod能够处理请求,应将其添加到 所有匹配服务的负载均衡池
因此,如果一个Pod为ready
,则该Pod的IP将添加到endpoints
对象,服务将开始向该Pod发送流量。稍后,如果更多的Pod变为ready
,那么这些Pod IP也将添加到endpoints
对象中,服务将开始在所有Pod之间进行负载平衡流量。
要检查添加到服务的Pod IP,可以运行kubectl describe service servicename
并检查Endpoints
部分。
为避免流量被发送到Pod中的容器但容器尚未准备好接受流量的情况,您可以使用container probe
当Pod内的所有容器都准备就绪时,只有服务Endpoints
会填充Pod IP,流量开始流动。
答案 3 :(得分:0)
如果您通过Deployment.yaml文件浏览了下面提到的代码段-
spec:
replicas: 4
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
对于一个金丝雀部署,这表明25%的标准表明,如果在deployment.yaml中设置了4个专用副本,则每当其中75%成功部署成功时,都将允许该服务为流量提供服务。
因此,基本上,您有3/4个副本处于活动状态,并且可以为流量提供服务。这是完全可配置的。
答案 4 :(得分:-1)
如果容器内的端口没有打开,则可能不会转发任何流量。不过,您可以在Pod内放入一个tcpdump,然后按照syn和reset标志进行操作