如何使用 kubernetes 将 rails 应用程序部署到 google 容器引擎?

How to deploy a rails app to google container engine with kubernetes?

我尝试了很多方法来将我的 rails 应用构建为 docker 图像。并将其部署到 google 容器引擎。但是直到现在,还没有人成功。

我的Dockerfile(在rails根路径下)

FROM ruby:2.2.2

RUN apt-get update -qq && apt-get install -y build-essential
RUN apt-get install -y nodejs

ENV APP_HOME /myapp
RUN mkdir $APP_HOME
WORKDIR $APP_HOME

ADD Gemfile $APP_HOME/Gemfile
ADD Gemfile.lock $APP_HOME/Gemfile.lock
ADD vendor/gems/my_gem $APP_HOME/vendor/gems/my_gem
ADD init.sh $APP_HOME/

RUN export LANG=C.UTF-8 && bundle install

ADD . $APP_HOME

CMD ["sh", "init.sh"]

我的init.sh

#!/bin/bash
bundle exec rake db:create db:migrate
bundle exec rails server -b 0.0.0.0

我的 kubernetes 配置文件

apiVersion: v1
kind: ReplicationController
metadata:
  labels:
    name: web
  name: web-controller
spec:
  replicas: 2
  selector:
    name: web
  template:
    metadata:
      labels:
        name: web
    spec:
      containers:
      - name: web
        image: gcr.io/my-project-id/myapp:v1
        ports:
        - containerPort: 3000
          name: http-server
        env:
          - name: RAILS_ENV
            value: "production"

使用 kubectl 在 gke 上创建网络控制器后:

kubectl create -f web-controller.yml

并查看 pod 日志:

kubectl logs web-controller-xxxxx

显示:

init.sh: 2: init.sh: bundle: not found
init.sh: 3: init.sh: bundle: not found

好像找不到路径。那怎么办?

您可以使用kubectl exec 进入您的容器并打印环境。 http://kubernetes.io/v1.1/docs/user-guide/getting-into-containers.html

例如: kubectl exec web-controller-xxxxx sh -c printenv

您还可以交互式地使用 kubectl 来确认包在您的容器镜像中:

kubectl exec -ti web-controller-xxxxx sh

如果 bundle 在您的映像中,则将其目录添加到 init.sh 中的 PATH,或者在每个命令中明确指定其路径。

也许您应该直接执行 init.sh 而不是 sh init.sh$PATH 和其他 ENV 变量似乎没有为 sh init.sh shell 设置。如果您可以 exec 进入容器并且 which bundle 显示捆绑路径,那么在使用 sh init.sh.

执行时您将丢失登录环境

如果有帮助的话,我已经写了 a how-to on deploying Rails on GKE with Kubernetes. One thing you may want to change is that if you have several of your web pods running, they will all run the init.sh script and they will all attempt to db:migrate. There will be a race condition for which one migrates and in what order (if you have many). You probably only want to run db:migrate from one container during a deploy. You can use a Kubernetes Job 来完成它,或者 kubectl run migrator --image=us.gcr.io/your/image --rm --restart=Never 或类似的东西在推出你的新网站之前只执行一次 db:migrate 任务 pods.