我已经实现了一个gRPC服务,将其构建到一个容器中,并使用k8s(特别是AWS EKS)将其部署为守护进程。
Pod很快启动并转到Running状态,但需要很长时间,通常是300秒,才能访问实际的服务。
实际上,当我运行kubectl logs
打印Pod的日志时,它长时间是空的。
我在服务刚开始的时候记录了一些东西。实际上,我的代码看起来像
package main
func init() {
log.Println("init")
}
func main() {
// ...
}
所以我很确定当没有日志时,服务还没有启动。
我理解Pod正在运行和它内部的实际进程正在运行之间可能存在时间间隔。然而,300秒对我来说太长了。
此外,这是随机发生的,有时服务几乎立即就绪。顺便说一下,我的运行时图像是基于chromedp headless-shell,不确定它是否相关。
谁能提供一些建议,如何调试和定位问题?很多谢谢!
更新我没有设置任何就绪探针。
运行我的守护进程的kubectl get -o yaml
给出
apiVersion: apps/v1
kind: DaemonSet
metadata:
annotations:
deprecated.daemonset.template.generation: "1"
creationTimestamp: "2021-10-13T06:30:16Z"
generation: 1
labels:
app: worker
uuid: worker
name: worker
namespace: collection-14f45957-e268-4719-88c3-50b533b0ae66
resourceVersion: "47265945"
uid: 88e4671f-9e33-43ef-9c49-b491dcb578e4
spec:
revisionHistoryLimit: 10
selector:
matchLabels:
app: worker
uuid: worker
template:
metadata:
annotations:
prometheus.io/path: /metrics
prometheus.io/port: "2112"
prometheus.io/scrape: "true"
creationTimestamp: null
labels:
app: worker
uuid: worker
spec:
containers:
- env:
- name: GRPC_PORT
value: "22345"
- name: DEBUG
value: "false"
- name: TARGET
value: localhost:12345
- name: TRACKER
value: 10.100.255.31:12345
- name: MONITOR
value: 10.100.125.35:12345
- name: COLLECTABLE_METHODS
value: shopping.ShoppingService.GetShop
- name: POD_IP
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: status.podIP
- name: DISTRIBUTABLE_METHODS
value: collection.CollectionService.EnumerateShops
- name: PERFORM_TASK_INTERVAL
value: 0.000000s
image: xxx
imagePullPolicy: Always
name: worker
ports:
- containerPort: 22345
protocol: TCP
resources:
requests:
cpu: 1800m
memory: 1Gi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
- env:
- name: CAPTCHA_PARALLEL
value: "32"
- name: HTTP_PROXY
value: http://10.100.215.25:8080
- name: HTTPS_PROXY
value: http://10.100.215.25:8080
- name: API
value: 10.100.111.11:12345
- name: NO_PROXY
value: 10.100.111.11:12345
- name: POD_IP
image: xxx
imagePullPolicy: Always
name: source
ports:
- containerPort: 12345
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
volumeMounts:
- mountPath: /etc/ssl/certs/api.crt
name: ca
readOnly: true
subPath: tls.crt
dnsPolicy: ClusterFirst
nodeSelector:
api/nodegroup-app: worker
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- name: ca
secret:
defaultMode: 420
secretName: ca
updateStrategy:
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
type: RollingUpdate
status:
currentNumberScheduled: 2
desiredNumberScheduled: 2
numberAvailable: 2
numberMisscheduled: 0
numberReady: 2
observedGeneration: 1
updatedNumberScheduled: 2
此外,Pod中有两个容器。其中只有一个启动异常慢,而另一个总是很好。
当您在解决方案中使用HTTP_PROXY时,请注意它如何与底层集群网络路由不同-这通常会导致意外超时。
我已经张贴了社区维基的答案来总结这个话题:
正如gohm'c在评论中提到的:
容器"源"总是必须通过HTTP_PROXY,即使它是连接集群中的服务-你认为可能的长时间,因为代理?可以试试
kubectl exec -it <pod> -c <source> -- sh
和curl/wget外部服务
这是一个很好的观察。请注意,有些连接可以直接建立,通过代理添加额外的流量可能会导致延迟。例如,可能会出现瓶颈。你可以在文档中阅读更多关于使用HTTP代理访问Kubernetes API的信息。
此外,您还可以创建就绪探测器,以了解容器何时准备好开始接受流量。
当Pod的所有容器都准备好时,Pod就被认为准备好了。这个信号的一个用途是控制哪些pod被用作服务的后端。当Pod没有准备好时,它将从服务负载均衡器中删除。
kubelet使用启动探测器来知道容器应用程序何时启动。如果这样的探针配置,它禁用活性和准备检查,直到成功,确保这些调查不会干扰应用程序启动。这可以用于对缓慢启动的容器采用动态检查,避免它们在启动和运行之前被kubelet杀死。