【问题标题】:Dockerfile entrypoint in Kubernetes not executedKubernetes 中的 Dockerfile 入口点未执行
【发布时间】:2021-07-10 18:46:34
【问题描述】:

我有一个基于 docker 容器的基于 ReactJS 的应用程序,一个 shell 脚本在 docker image 中定义为 ENTRYPOINT,我可以成功使用 docker run image-name。

现在的任务是使用标准的 deployment.yaml 文件模板使用这个 docker 镜像进行 Kubernetes 部署,如下所示

# Deployment file
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      terminationGracePeriodSeconds: 120
      containers:
      - name: my-app
        imagePullPolicy: Always
        image: my-docker-image
        command: ["/bin/bash"]
        args: ["-c","./entrypoint.sh;while true; do echo hello; sleep 10;done"]

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  type: NodePort
  selector:
    app: my-app
  ports:
  - port: 3000
    targetPort: 3000
    protocol: TCP
    nodePort: 31110

spec:
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-service
            port:
              number: 3000

当我执行 kubectl apply -f mydeployment.yaml 时,它会创建所需的 pod,但与直接运行 docker 映像不同,在创建 pod 时不会执行 entrypoint.sh 脚本。有人可以帮忙分享一下上面的 yaml 文件有什么问题吗,我错过了还是做错了什么?

我还尝试在 yaml 中的命令 [] 中直接调用 npm run start,但没有运气。我可以使用 kubectl exec 进入 pod 容器,但我没有看到 react app 正在运行,我可以手动执行 entrypoint.sh 并在浏览器中查看所需的输出。

编辑:添加 kubectl 日志并描述输出

日志:当我从 yaml 中删除 command/args 并应用 deploy.yaml 时,我得到以下日志,直到启动 dev server 行,除此之外什么都没有。

> myapp start /app
> react-scripts start

ℹ 「wds」: Project is running at http://x.x.x.x/
ℹ 「wds」: webpack output is served from 
ℹ 「wds」: Content not from webpack is served from /app/public
ℹ 「wds」: 404s will fallback to /
Starting the development server...

描述输出

Name:         my-view-85b597db55-72jr8
Namespace:    default
Priority:     0
Node:         my-node/x.x.x.x
Start Time:   Fri, 16 Apr 2021 11:13:20 +0800
Labels:       app=my-app
              pod-template-hash=85b597db55
Annotations:  cni.projectcalico.org/podIP: x.x.x.x/xx
              cni.projectcalico.org/podIPs: x.x.x.x/xx
Status:       Running
IP:           x.x.x.x
IPs:
  IP:           x.x.x.x
Controlled By:  ReplicaSet/my-view-container-85b597db55
Containers:
  my-ui-container:
    Container ID:   containerd://671a1db809b7f583b2f3702e06cee3477ab1412d1e4aa8ac93106d8583f2c5b6
    Image:          my-docker-image
    Image ID:       my-docker-image@sha256:29f5fc74aa0302039c37d14201f5c85bc8278fbeb7d70daa2d867b7faa6d6770
    Port:           <none>
    Host Port:      <none>
    State:          Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Fri, 16 Apr 2021 11:13:41 +0800
      Finished:     Fri, 16 Apr 2021 11:13:43 +0800
    Last State:     Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Fri, 16 Apr 2021 11:13:24 +0800
      Finished:     Fri, 16 Apr 2021 11:13:26 +0800
    Ready:          False
    Restart Count:  2
    Environment:
      MY_ENVIRONMENT_NAME:                          TEST_ENV
      MY_SERVICE_NAME:                              my-view-service
      MY_SERVICE_MAIN_PORT:                         3000
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-9z8bw (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             False 
  ContainersReady   False 
  PodScheduled      True 
Volumes:
  default-token-9z8bw:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-9z8bw
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                 node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type     Reason     Age                From               Message
  ----     ------     ----               ----               -------
  Normal   Scheduled  32s                default-scheduler  Successfully assigned default/my-view-container-85b597db55-72jr8 to my-host
  Normal   Pulled     31s                kubelet            Successfully pulled image "my-docker-image" in 184.743641ms
  Normal   Pulled     28s                kubelet            Successfully pulled image "my-docker-image" in 252.382942ms
  Normal   Pulling    11s (x3 over 31s)  kubelet            Pulling image "my-docker-image"
  Normal   Pulled     11s                kubelet            Successfully pulled image "my-docker-image" in 211.2478ms
  Normal   Created    11s (x3 over 31s)  kubelet            Created container my-view-container
  Normal   Started    11s (x3 over 31s)  kubelet            Started container my-view-container
  Warning  BackOff    8s (x2 over 26s)   kubelet            Back-off restarting failed container

我的 entrypoint.sh 是

#!/bin/bash
( export REACT_APP_ENV_VAR=env_var_value;npm run start )
exec "$@"

【问题讨论】:

  • 如果您的行为与简单的docker run &lt;image&gt; 没有什么不同,则无需在部署规范中添加commandargs。如果您删除它们并重试怎么办?
  • 我试过了,但是在那种情况下,pod容器正在给CrashLoopBackoff,我在网上搜索,发现命令开关带有while循环。感谢您的快速回复。
  • 如果您的 pod 上出现“CrashLoopBackoff”,您需要使用“kubectl logs ”或“kubectl describe pod ”命令找出实际问题。
  • 嗨@Zucchini 我已经更新了我的帖子以包含日志/描述输出。

标签: reactjs docker kubernetes


【解决方案1】:

我终于找到了解决方案,我在 yaml 的规范部分下包含了以下选项,并删除了上面 cmets 提到的命令/参数。希望它对遇到这个问题的人有用。

spec:
      replicas: 1
      selector:
        matchLabels:
          app: my-app
      template:
        metadata:
          labels:
            app: my-app
        spec:
          terminationGracePeriodSeconds: 120
          containers:
          - name: my-app
            imagePullPolicy: Always
            image: my-docker-image
            stdin: true
            tty: true

【讨论】:

    【解决方案2】:

    当你在 pod 描述中写下这个时:

          containers:
          - name: my-app
            imagePullPolicy: Always
            image: my-docker-image
            command: ["/bin/bash"]
            args: ["-c","./entrypoint.sh;while true; do echo hello; sleep 10;done"]
    

    command 参数覆盖容器 ENTRYPOINT。以上 大致相当于:

    docker run --entrypoint /bin/bash my-docker-image ...args here...
    

    如果您想使用图像中的ENTRYPOINT,则只需设置args

    【讨论】:

    • 嗨@larsks,我在没有命令/参数开关的情况下开始在k8中部署,在这种情况下我得到了crashloopbackoff。但是使用上图的 command+args 开关,我可以看到一个正在运行的容器,只是没有启动 react 应用程序。
    • 如果您收到CrashLoopBackoff,您应该检查日志以了解失败的原因。
    • 好的,我确实检查了日志并描述了输出,我已经更新了我的帖子以包含两者。无法弄清楚导致容器故障的步骤。
    猜你喜欢
    • 1970-01-01
    • 2017-11-14
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 2016-05-28
    • 2016-04-18
    • 2018-07-15
    相关资源
    最近更新 更多