使用 Minikube 部署 k8s 应用程序时容器文件系统为空
Container filesystem is empty when deploying k8s application with Minikube
我有一个小型 Web 应用程序(一个名为 sofia
的 Rails 应用程序),我正在使用 minikube
.
在本地部署
当我创建 k8s 资源和 运行 我的部署时,容器不包含任何应该在映像构建过程中复制的文件。
这是我正在做的事情:
Docker 文件
作为 Dockerfile
构建的一部分,我将本地克隆存储库的内容复制到图像工作目录中:
RUN mkdir -p /app
WORKDIR /app
COPY . ./
(旧)docker-compose
设置
过去,我曾使用 docker-compose
文件来 运行 此应用程序及其所有服务。我将我的本地目录映射到容器的工作目录(参见下面的 volumes:
)。这在本地工作时非常方便,因为所有更改都在容器内“实时”反映:
# 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
使用kompose
构建k8s资源文件
为了在 minikube
上 运行 这个,我使用 Kubernetes 自己提供的 kompose
tool 来将我的 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
如您所见,它会生成一条警告,提示我的本地卷无法安装到远程卷上。这是有道理的,因为 k8s 部署 运行s “远程”,所以我只是忽略警告。
运行
最后我运行上面的资源用k8s / minikube
minikube start
kubectl apply -f k8s.yml
我注意到 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
该错误是 Ruby/Rails 特定的,但根本原因是 容器中没有文件 !我可以通过进入容器并使用 ls
检查文件来确认这一点——它确实是空的。
问题
- 如果
sofia/sofia:latest
图像是使用 COPY
-ied 文件内容正确构建的,为什么在 运行 在 minikube
上运行容器时它会消失?
- 我应该怎么做才能确保我的文件被正确复制?
谢谢!
问题是卷在 Docker 在 docker-compose 和 K8s 中的行为方式不同。 Kompose 无法完美翻译音量。
在使用 docker-compose 的 Docker 中,您声明的卷保留目录中的现有文件,而在 k8s 中,创建一个空卷并隐藏现有内容。
没有直接等效的 docker-compose 卷将现有文件保留在 k8s 中,您将不得不使用以下选项之一来解决这个问题,具体取决于您的用例:
- 利用 ConfigMaps 将您的文件添加到此应用卷(如果需要,请使用子路径)。如果容器启动时您的应用程序目录中存在一些配置文件,那么可能没问题
- 在您的 docker 文件中,使用 COPY 复制到诸如 app-tmp 之类的内容,然后在您的入口点脚本中将这些文件从该 app-tmp 目录复制到您的“app”卷
- 重构您的应用程序,使其将“app1”目录(无卷)与现有文件一起使用,“app2”开始时为空并用作您的卷。
我有一个小型 Web 应用程序(一个名为 sofia
的 Rails 应用程序),我正在使用 minikube
.
当我创建 k8s 资源和 运行 我的部署时,容器不包含任何应该在映像构建过程中复制的文件。
这是我正在做的事情:
Docker 文件
作为 Dockerfile
构建的一部分,我将本地克隆存储库的内容复制到图像工作目录中:
RUN mkdir -p /app
WORKDIR /app
COPY . ./
(旧)docker-compose
设置
过去,我曾使用 docker-compose
文件来 运行 此应用程序及其所有服务。我将我的本地目录映射到容器的工作目录(参见下面的 volumes:
)。这在本地工作时非常方便,因为所有更改都在容器内“实时”反映:
# 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
使用kompose
构建k8s资源文件
为了在 minikube
上 运行 这个,我使用 Kubernetes 自己提供的 kompose
tool 来将我的 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
如您所见,它会生成一条警告,提示我的本地卷无法安装到远程卷上。这是有道理的,因为 k8s 部署 运行s “远程”,所以我只是忽略警告。
运行
最后我运行上面的资源用k8s / minikube
minikube start
kubectl apply -f k8s.yml
我注意到 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
该错误是 Ruby/Rails 特定的,但根本原因是 容器中没有文件 !我可以通过进入容器并使用 ls
检查文件来确认这一点——它确实是空的。
问题
- 如果
sofia/sofia:latest
图像是使用COPY
-ied 文件内容正确构建的,为什么在 运行 在minikube
上运行容器时它会消失? - 我应该怎么做才能确保我的文件被正确复制?
谢谢!
问题是卷在 Docker 在 docker-compose 和 K8s 中的行为方式不同。 Kompose 无法完美翻译音量。 在使用 docker-compose 的 Docker 中,您声明的卷保留目录中的现有文件,而在 k8s 中,创建一个空卷并隐藏现有内容。
没有直接等效的 docker-compose 卷将现有文件保留在 k8s 中,您将不得不使用以下选项之一来解决这个问题,具体取决于您的用例:
- 利用 ConfigMaps 将您的文件添加到此应用卷(如果需要,请使用子路径)。如果容器启动时您的应用程序目录中存在一些配置文件,那么可能没问题
- 在您的 docker 文件中,使用 COPY 复制到诸如 app-tmp 之类的内容,然后在您的入口点脚本中将这些文件从该 app-tmp 目录复制到您的“app”卷
- 重构您的应用程序,使其将“app1”目录(无卷)与现有文件一起使用,“app2”开始时为空并用作您的卷。