简体   繁体   English

使用 Minikube 部署 k8s 应用程序时容器文件系统为空

[英]Container filesystem is empty when deploying k8s application with Minikube

I have a small web application (a Rails app called sofia ) that I'm deploying locally with minikube .我有一个小型 web 应用程序(一个名为sofia的 Rails 应用程序),我使用minikube在本地部署。

When I create the k8s resources and run my deployment, the containers do not contain any of the files that were supposed to be copied over during the image build process.当我创建 k8s 资源并运行我的部署时,容器不包含任何应该在映像构建过程中复制的文件。

Here's what I'm doing:这就是我正在做的事情:

Dockerfile Dockerfile

As part of the Dockerfile build, I copy the contents of my local cloned repository into the image working directory:作为Dockerfile构建的一部分,我将本地克隆存储库的内容复制到映像工作目录中:

RUN mkdir -p /app
WORKDIR /app

COPY . ./

The (old) docker-compose setup (旧) docker-compose设置

Historically I've used a docker-compose file to run this application and all its services.从历史上看,我使用docker-compose文件来运行此应用程序及其所有服务。 I map my local directory to the container's working directory (see volumes: below).我 map 我的本地目录到容器的工作目录(见volumes:下面)。 This is a nice convenience when working locally since all changes are reflected "live" inside the container:这在本地工作时非常方便,因为所有更改都反映在容器内“实时”:

# docker-compose.yml
sofia:
    build:
      context: .
      args:
        RAILS_ENV: development
    environment:
      DATABASE_URL: postgres://postgres:sekrit@postgres/
    image: sofia/sofia:local
    ports:
      - # ...
    volumes:
      - .:/app  #<---- HERE

Building k8s resource file with kompose使用kompose构建 k8s 资源文件

In order to run this on minikube , I use the kompose tool that Kubernetes themselves provide in order to transform my docker-compose file into a k8s resource file that can be consumed.为了在minikube上运行它,我使用 Kubernetes 自己提供的kompose工具将我的docker-compose文件转换为可以使用的 k8s 资源文件。

$ kompose convert --file docker-compose.yml --out k8s.yml --with-kompose-annotation=false
WARN Volume mount on the host "/Users/jeeves/git/jeeves/sofia" isn't supported - ignoring path on the host
INFO Kubernetes file "k8s.yml" created

As you can see, it generates a warning that my local volume can not be mounted against the remote volume.如您所见,它会生成一条警告,提示我的本地卷无法安装到远程卷上。 This makes sense since a k8s deployment runs "remotely", so I just ignore the warning.这是有道理的,因为 k8s 部署是“远程”运行的,所以我只是忽略了警告。

Running跑步

Finally I run the above resources with k8s / minikube最后我用 k8s / minikube运行上面的资源

minikube start
kubectl apply -f k8s.yml

I notice the sofia container keeps crashing and restarting so I check the logs:我注意到sofia容器不断崩溃并重新启动,所以我检查了日志:

$ kubectl get pods
NAME                             READY   STATUS             RESTARTS   AGE
pod/sofia-6668945bc8-x9267       0/1     CrashLoopBackOff   1          10s
pod/postgres-fc84cbd4b-dqbrh     1/1     Running            0          10s
pod/redis-cbff75fbb-znv88        1/1     Running            0          10s

$ kubectl logs pod/sofia-6668945bc8-x9267
Could not locate Gemfile or .bundle/ directory

That error is Ruby/Rails specific, but the underlying cause is that there are no files in the container !该错误是特定于 Ruby/Rails 的,但根本原因是容器中没有文件 I can confirm this by entering the container and checking files with ls - it is indeed empty.我可以通过进入容器并使用ls检查文件来确认这一点——它确实是空的。

Questions问题

  1. If the sofia/sofia:latest image is correctly built with the COPY -ied file contents, why would it dissapear when runing the container on minikube ?如果sofia/sofia:latest镜像是用COPY文件内容正确构建的,为什么在minikube上运行容器时它会消失?
  2. What should I do to ensure my files get copied over correctly?我应该怎么做才能确保我的文件被正确复制?

Thanks!谢谢!

The issue is that Volumes are not behaving the same way in Docker in docker-compose and K8s.问题是卷在 docker-compose 和 K8s 中的 Docker 中的行为方式不同。 Kompose can't perfectly translate volume. Kompose 不能完美地翻译音量。 In Docker with docker-compose, your declared volume keep the existing files from the directory, while in k8s, a volume is created empty and shadow the existing content.在 Docker 和 docker-compose 中,您声明的卷保留目录中的现有文件,而在 k8s 中,卷被创建为空并隐藏现有内容。

There is no direct equivalent of docker-compose volumes that keeps existing files in k8s, you will have to work around that with one of the following options, depending on what makes sense in your use case:没有直接等效的 docker-compose 卷可以将现有文件保存在 k8s 中,您必须使用以下选项之一解决这个问题,具体取决于您的用例中的意义:

  • leverage ConfigMaps to add your files to this app volume (if needed, use subPath).利用ConfigMaps将您的文件添加到此应用程序卷(如果需要,请使用 subPath)。 Probably ok for a handfull of config files if that's what lives your app directory when the container starts如果容器启动时您的应用程序目录中存在少量配置文件,则可能没问题
  • in your dockerfile, use COPY to something like app-tmp, then in your entrypoint script copy those files from that app-tmp directory to your "app" volume在你的 dockerfile 中,使用 COPY 到 app-tmp 之类的东西,然后在你的入口点脚本中将这些文件从 app-tmp 目录复制到你的“app”卷
  • Refactor your application so that it uses "app1" directory (without volumes) with existing files, "app2" starts empty and is used as your volume.重构您的应用程序,使其将“app1”目录(无卷)与现有文件一起使用,“app2”开始为空并用作您的卷。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM