首页 > 解决方案 > Kubernetes Helm pod 无限重启

问题描述

我正在尝试将 Spinnaker 部署到 Kubernetes 集群中。为了做到这一点,我使用了使用 Helm 的 Halyard。当我尝试运行我的 Helm pod 时,我有以下输出:

Cluster "default" set.
Context "default" created.
User "user" set.
Context "default" modified.
Switched to context "default".
Creating /home/spinnaker/.helm 
Creating /home/spinnaker/.helm/repository 
Creating /home/spinnaker/.helm/repository/cache 
Creating /home/spinnaker/.helm/repository/local 
Creating /home/spinnaker/.helm/plugins 
Creating /home/spinnaker/.helm/starters 
Creating /home/spinnaker/.helm/cache/archive 
Creating /home/spinnaker/.helm/repository/repositories.yaml 
Adding stable repo with URL: https://kubernetes-charts.storage.googleapis.com 
Adding local repo with URL: http://127.0.0.1:8879/charts 
$HELM_HOME has been configured at /home/spinnaker/.helm.
Tiller (the Helm server-side component) has been upgraded to the current version.
Happy Helming!

一切似乎都是正确的。但是我的 pod 引发了一个CrashLoopBackOff事件,没有任何其他错误,并且我的 pod 无缘无故地重新启动。

我用来构建 helm docker 映像的 dockerfile 如下:

FROM gcr.io/spinnaker-marketplace/halyard:stable

ARG GCP_SPINNAKER_GCR_KEY

# install helm
WORKDIR /home/spinnaker

# get helm
RUN curl https://raw.githubusercontent.com/kubernetes/helm/master/scripts/get > get_helm.sh
RUN sed -i 's/\/usr\/local\/bin/\/home\/spinnaker/g' get_helm.sh

# sudo user workaround
RUN sed -i 's/sudo //g' get_helm.sh
RUN chmod u+x get_helm.sh

# add the current folder to the path 
ENV PATH="/home/spinnaker:${PATH}"

# install helm
RUN ./get_helm.sh

# importing the configuration script
ADD shell/halyard-configure.sh .

# auhtorize the spinnaker user to execute the configuration script
USER root
RUN chown -R spinnaker halyard-configure.sh
USER spinnaker

# create the gcp key directory for docker registry
RUN mkdir -p ~/.gcp
RUN echo $GCP_SPINNAKER_GCR_KEY | base64 -d > ~/.gcp/gcr-account.json

ENTRYPOINT [ "./halyard-configure.sh" ] 

CMD "/opt/halyard/bin/halyard"

这是halyard-configure.sh shell 脚本的内容:

#!/usr/bin/env bash
set -e

# configure kubectl
kubectl config set-cluster default --server=https://kubernetes.default --certificate-authority=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
kubectl config set-context default --cluster=default
token=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
kubectl config set-credentials user --token=$token
kubectl config set-context default --user=user
kubectl config use-context default

# configure helm
helm init --service-account tiller --upgrade

标签: dockerkubernetesgoogle-cloud-platformkubernetes-helm

解决方案


您的入口点脚本需要以魔法线结尾exec "$@"

一般来说,在 Docker 中,容器启动会启动容器入口点,并将命令作为参数传递给它。(Kubernetes pod 规范将这些部分称为“命令”和“参数”。)一旦入口点完成,容器就会退出。由于您的入口点脚本刚刚运行kubectl config并且helm init所有命令都迅速完成,因此容器几乎立即退出;当它完成时,Kubernetes 会重新启动它;当它必须重新启动超过两三次时,它就会进入CrashLoopBackOff状态。

解决此问题的常用方法是设置入口点脚本以执行任何所需的首次设置,然后exec将命令作为参数传递给它。然后命令(在您的情况下,/opt/halyard/bin/halyard)最终成为“主容器进程”,并且具有神奇的进程 ID 1,并将在容器终止时接收信号。

另请注意,从 pod 访问 Kubernetes API 有一个合理的标准模式,包括为 pod 配置服务帐户并使用官方 API,或者启动kubectl proxysidecar。您可能可以使用它来代替您在此处的手动设置步骤。(不过,我从未尝试从 Kubernetes pod 中启动 Helm。)


推荐阅读