如何使用 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.
我尝试了很多方法来将我的 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.