ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

GoFr 如何把微服务打包为 Helm Chart 并把探针指向 .well-known 健康端点

GoFr 如何把微服务打包为 Helm Chart 并把探针指向 .well-known 健康端点 GoFr 如何把微服务打包为 Helm Chart 并把探针指向 .well-known 健康端点【免费下载链接】gofrAn opinionated GoLang framework for accelerated microservice development. Built in support for databases and observability.项目地址: https://gitcode.com/GitHub_Trending/go/gofr你已经有一个打好容器镜像的 GoFr 微服务现在想把它以 Helm Chart 的形式部署到 Kubernetes 集群并让 Kubernetes 的探针直接利用 GoFr 内置的健康端点来判断进程存活和依赖就绪。完成这篇文章后你会得到一份可以直接放入自己服务仓库chart/目录的参考 ChartChart.yaml、values.yaml、templates/执行helm upgrade --install完成部署并用kubectl和curl验证探针与健康端点的行为。这套参考 Chart 来自项目文档 Helm Chart Starter它假设应用监听 GoFr 的框架默认端口HTTP 8000、gRPC 9000、metrics 2121可在 pkg/gofr/default.go 中核对探针使用 GoFr 自动注册的/.well-known/alive和/.well-known/health两个端点。前置条件一个已经容器化的 GoFr 服务镜像。打包方式可参考 Dockerizing GoFr Services本文不重复构建镜像的步骤只消费镜像地址和 tag。一个可用的 Kubernetes 集群以及本机安装好的helm和kubectl。了解 GoFr 的两个默认健康端点详见 Monitoring Service Health/.well-known/alive只要服务进程 UP 就返回 200用于判断进程是否活着/.well-known/health未鉴权端点聚合所有已注册数据源和依赖的健康状态返回应用name与聚合status全部健康为UP任一依赖不可用为DEGRADED用于判断现在能不能接流量。创建 chart/ 目录与 Chart.yaml文档明确说明这套文件是参考材料不是发布的 chart做法是把下面的文件拷贝到你自己的服务仓库中建立chart/目录chart/ ├── Chart.yaml ├── values.yaml └── templates/ ├── _helpers.tpl ├── deployment.yaml └── service.yamlChart.yaml内容apiVersion: v2 name: gofr-service description: A reference Helm chart for a GoFr microservice type: application version: 0.1.0 appVersion: 0.1.0values.yaml镜像、副本数、端口与配置注入values.yaml捕获镜像、副本数、环境变量、资源和探针相关的所有可调项image: repo: ghcr.io/example/my-gofr-service tag: latest pullPolicy: IfNotPresent replicaCount: 2 service: type: ClusterIP httpPort: 8000 grpcPort: 9000 metricsPort: 2121 resources: requests: cpu: 100m memory: 128Mi limits: cpu: 500m memory: 512Mi env: {} # DB_HOST: db.svc # LOG_LEVEL: INFO # TRACE_EXPORTER: otlp # TRACER_URL: tempo:4317 envFromSecrets: [] # - my-db-credentials ingress: enabled: false className: nginx host: api.example.com tls: enabled: false secretName: api-tls autoscaling: enabled: false minReplicas: 2 maxReplicas: 10 targetCPUUtilizationPercentage: 70 podSecurityContext: runAsNonRoot: true runAsUser: 65532 fsGroup: 65532 securityContext: readOnlyRootFilesystem: true allowPrivilegeEscalation: false capabilities: drop: [ALL]几个必须注意的点service.httpPort/grpcPort/metricsPort的默认值 8000 / 9000 / 2121 与 GoFr 框架默认绑定端口一致如果你的服务用环境变量改了监听端口这里的值也要同步修改否则探针和 Service 端口会对不上。image.repo上面的ghcr.io/example/my-gofr-service是文档示例地址替换为你自己的镜像仓库地址image.tag示例为latest但文档明确要求生产环境把 tag 钉死到 Git SHA永远不要用latest。env里的键名与本地configs/.env使用的环境变量同名如DB_HOST、LOG_LEVEL用于注入非敏感配置envFromSecrets是 Secret 名称列表用于注入数据库密码、API key 等凭据。ingress和autoscaling默认关闭保证首次使用的 chart 保持简单见下文可选部分。templates/_helpers.tpl名称与标签_helpers.tpl定义 chart 中 Deployment 和 Service 共用的命名与标签逻辑{{- define gofr-service.name -}} {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix - -}} {{- end -}} {{- define gofr-service.fullname -}} {{- printf %s-%s .Release.Name (include gofr-service.name .) | trunc 63 | trimSuffix - -}} {{- end -}} {{- define gofr-service.labels -}} app.kubernetes.io/name: {{ include gofr-service.name . }} app.kubernetes.io/instance: {{ .Release.Name }} app.kubernetes.io/managed-by: {{ .Release.Service }} helm.sh/chart: {{ printf %s-%s .Chart.Name .Chart.Version }} {{- end -}}fullname的生成规则是Release 名-gofr-service。后文验证命令中出现的 Deployment 名和 Service 名都依赖这条规则比如 release 名为my-api时资源名就是my-api-gofr-service。templates/deployment.yaml探针接在哪里这是整份 chart 的核心模板Deployment 中显式注入了端口环境变量并把两类探针分别指向 GoFr 的内置端点apiVersion: apps/v1 kind: Deployment metadata: name: {{ include gofr-service.fullname . }} labels: {{ include gofr-service.labels . | nindent 4 }} spec: replicas: {{ .Values.replicaCount }} selector: matchLabels: app.kubernetes.io/name: {{ include gofr-service.name . }} app.kubernetes.io/instance: {{ .Release.Name }} template: metadata: labels: {{ include gofr-service.labels . | nindent 8 }} annotations: prometheus.io/scrape: true prometheus.io/port: {{ .Values.service.metricsPort }} prometheus.io/path: /metrics spec: securityContext: {{ toYaml .Values.podSecurityContext | nindent 8 }} containers: - name: app image: {{ .Values.image.repo }}:{{ .Values.image.tag }} imagePullPolicy: {{ .Values.image.pullPolicy }} ports: - name: http containerPort: {{ .Values.service.httpPort }} - name: grpc containerPort: {{ .Values.service.grpcPort }} - name: metrics containerPort: {{ .Values.service.metricsPort }} env: - name: HTTP_PORT value: {{ .Values.service.httpPort }} - name: GRPC_PORT value: {{ .Values.service.grpcPort }} - name: METRICS_PORT value: {{ .Values.service.metricsPort }} {{- range $k, $v : .Values.env }} - name: {{ $k }} value: {{ $v | quote }} {{- end }} {{- with .Values.envFromSecrets }} envFrom: {{- range . }} - secretRef: name: {{ . }} {{- end }} {{- end }} livenessProbe: httpGet: path: /.well-known/alive port: http initialDelaySeconds: 5 periodSeconds: 10 readinessProbe: httpGet: path: /.well-known/health port: http initialDelaySeconds: 5 periodSeconds: 10 resources: {{ toYaml .Values.resources | nindent 12 }} securityContext: {{ toYaml .Values.securityContext | nindent 12 }} terminationGracePeriodSeconds: 30文档对其中几个选择给出了明确解释照抄时不要随意改动探针分工livenessProbe 指向/.well-known/alive——它开销小且默认豁免认证只确认进程活着readinessProbe 指向/.well-known/health——它把依赖状态折进聚合结果对就绪判断更真实。用/.well-known/health做 liveness 是常见错误一次短暂的 Redis 故障会触发 kubelet 反复重启 Pod把整个服务打挂见 Deploying to Kubernetes。端口环境变量显式注入HTTP_PORT、GRPC_PORT、METRICS_PORT与values.yaml的 service 端口同源保证容器端口、Service 端口和 GoFr 实际绑定的端口三者永远一致。配置注入方式非敏感配置通过values.env内联为容器 env凭据通过envFromsecretRef挂载按名字引用values.envFromSecrets里列出的 Secret不要把填好密码的 Secret YAML 提交进仓库。Prometheus 抓取注解指向metricsPort如果你的平台用 ServiceMonitor/PodMonitor 代替注解删掉这三个注解、另加对应模板即可。terminationGracePeriodSeconds: 30给 GoFr 收到 SIGTERM 后的优雅退出留出排空在途请求的时间。templates/service.yaml三个命名端口apiVersion: v1 kind: Service metadata: name: {{ include gofr-service.fullname . }} labels: {{ include gofr-service.labels . | nindent 4 }} spec: type: {{ .Values.service.type }} ports: - name: http port: {{ .Values.service.httpPort }} targetPort: http - name: grpc port: {{ .Values.service.grpcPort }} targetPort: grpc - name: metrics port: {{ .Values.service.metricsPort }} targetPort: metrics selector: app.kubernetes.io/name: {{ include gofr-service.name . }} app.kubernetes.io/instance: {{ .Release.Name }}HTTP、gRPC、metrics 三个协议监听不同端口默认 8000/9000/2121需要各自独立的 Service 端口条目才能同时可达metrics 端口命名为metrics方便 OpenMetrics 采集器按名字选择端口。可选分支Ingress 与 HPAvalues.yaml里的ingress和autoscaling段是为可选模板预留的新增templates/ingress.yaml受.Values.ingress.enabled控制和templates/hpa.yaml受.Values.autoscaling.enabled控制。文档建议两者默认关闭让 chart 对初次使用者保持简单。如果你的场景只是跑起来并验证探针这两个模板可以先不建。文档同时提到社区维护的 chartzop/service形态相同Deployment Service 可选 Ingress/HPA 探针通过helm repo add添加 zop 仓库后helm install my-app zop/service即可用-f values.yaml或--set覆盖值其values.schema.json中把用户可修改字段标记为mutable: true。仓库地址见 Helm Chart Starter 原文。执行lint、template、install先静态校验再安装。helm lint检查 chart 结构helm template渲染出最终 YAML 供人工核对确认无误后再安装helm lint ./chart helm template my-api ./chart安装命令release 名为my-api./chart为上一步建好的目录helm upgrade --install my-api ./chart \ --set image.tag$(git rev-parse --short HEAD) \ --set env.LOG_LEVELINFO \ --wait --timeout 5m--set image.tag$(git rev-parse --short HEAD)把镜像 tag 钉到当前 Git 短 SHA保证可重复部署--wait让 helm 等待资源就绪超时 5 分钟。验证结果以下命令序列来自 Deploying GoFr to Kubernetes 的验证流程并按本 chart 的资源命名做了调整chart 的fullname规则使本例release 名my-api的 Deployment 与 Service 名为my-api-gofr-serviceService 的 http 端口默认为 8000。# 等待 rollout 完成 kubectl rollout status deployment/my-api-gofr-service --timeout120s # 查看 Pod 与探针状态pod-name 替换为上一步 get pods 输出的实际 Pod 名 kubectl get pods -l app.kubernetes.io/namegofr-service kubectl describe pod pod-name | grep -A2 -E Liveness|Readiness|Startup # port-forward 到本地直接打端点Service http 端口默认 8000本地映射到 8080 kubectl port-forward svc/my-api-gofr-service 8080:8000 2121:2121 curl -s http://localhost:8080/.well-known/health curl -s http://localhost:8080/.well-known/alive curl -s http://localhost:2121/metrics | head也可以从集群内发起请求同样按 Service 实际端口 8000 指定kubectl run curl --rm -it --imagecurlimages/curl --restartNever -- \ curl -s http://my-api-gofr-service.default.svc.cluster.local:8000/.well-known/health健康端点的文档示例响应如下name为你的应用名此处为示例值{ data: { name: sample-service, status: UP } }/.well-known/alive在服务 UP 时返回 200 与{data: {status: UP}}。/metrics端点应输出 OpenMetrics 文本格式的指标。health 端点较慢时三探针拆分可选如果/.well-known/health因为要 ping 数据库而响应偏慢文档给出另一套探针组合Liveness→/.well-known/alive进程活着即可Startup probe→/.well-known/health依赖可达启动阶段允许失败Readiness→ startup 通过后改用/.well-known/alive避免数据库短暂抖动把 Pod 从 Service 端点里摘除。具体阈值按服务实际情况调整。故障排查与边界Pod 处于 CrashLoopBackOff怀疑是探针问题。kubectl describe pod会显示容器最近一次退出原因和探针失败记录。如果 liveness 在应用初始化完成前就触发调高startupProbe.failureThreshold每个单位是一个periodSeconds例如30 * 2s 60s的启动宽限。如果 readiness 持续失败port-forward 到 Pod 后直接curl /.well-known/healthDEGRADED表示至少一个依赖不可达由于响应体只含聚合状态、不含逐项依赖信息需要看 Pod 日志确认是哪个依赖出了问题。/.well-known/health的 HTTP 状态码永远是 200。这一点来自 Monitoring Service Health 的明确说明UP和DEGRADED都返回 200不会返回非 2xx因此直接按状态码判断的探针包括上面的 readinessProbe不会把DEGRADED的 Pod 摘除需要针对依赖降级采取行动时必须自己读取响应体中的status字段。写探针和告警时要把这个行为考虑进去。这套文件不是发布的 chart。它是供你拷贝到自己服务仓库的参考材料文档提到未来可能有gofr-dev/gofr-k8s-starter仓库托管维护版。若需要外部 Ingress 或自动扩缩容按上文可选分支自行补模板不要把本 chart 当成开箱即用的生产完整方案。【免费下载链接】gofrAn opinionated GoLang framework for accelerated microservice development. Built in support for databases and observability.项目地址: https://gitcode.com/GitHub_Trending/go/gofr创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表