docker - 如何保存容器的任何更改?
问题描述
如果我有一个 ubuntu 容器,并且我 ssh 到它并在容器被销毁后创建一个文件,或者我重新启动容器,则新文件被销毁,因为 kubernetes 加载了不包含我的更改的 ubuntu 映像。我的问题是我应该怎么做才能保存任何更改?我知道这是可以做到的,因为一些云提供商会这样做。
例如:
ssh ubuntu@POD_IP
mkdir new_file
ls
new_file
reboot
重启后我有
ssh ubuntu@POD_IP
ls
ls
什么都不显示
但我想保存我当前的状态。我想自动完成。
如果我使用 docker commit 我无法控制我的图像,因为它会生成数百个图像。因为我应该通过每次更改来制作图像。
如果我想使用存储,我应该挂载 /。但是 kubernetes 不允许我挂载 /. 它给了我这个错误
错误:来自守护程序的错误响应:无效的卷规范:'/var/lib/kubelet/pods/26c39eeb-85d7-11e9-933c-7c8bca006fec/volumes/kubernetes.io~rbd/pvc-d66d9039-853d-11e9-8aa3-7c8bca006fec :/':类型“绑定”的无效装载配置:无效规范:目标不能是“/”
解决方案
Docker 和 Kubernetes 不是这样工作的。永远不要跑docker commit
。通常你在容器/pod 中几乎不需要 ssh 守护进程,你需要做一些特殊的工作来让 sshd 和主进程都运行(以及额外的工作来让 sshd 实际上是安全的);如果您删除这些容器,您的容器会更简单、更安全。
通常的过程涉及一种称为不可变基础设施的技术。您永远不会更改现有容器中的代码;相反,您更改配方以构建容器,并告诉集群管理器您想要更新,它会从头开始拆除并重建所有内容。要更改在 Kubernetes pod 中运行的应用程序,您通常:
- 在本地进行和测试您的代码更改,完全不涉及 Docker 或 Kubernetes。
docker build
包含您的代码更改的新图像。它应该有一个唯一的标签,通常是日期戳或源代码控制提交 ID。- (可选但推荐)
docker run
本地映像并运行集成测试。 docker push
图像到注册表。- 更改 Kubernetes 部署规范中的镜像标签和
kubectl apply
(或helm upgrade
)它。
通常你会有一个自动化的持续集成系统执行步骤 2-4,而持续部署系统执行最后一步;您只需要提交并推送您测试过的更改。
请注意,当您docker run
在步骤 3 中本地镜像时,您运行的镜像与生产 Kubernetes 系统将运行的镜像完全相同。抵制将本地源代码树挂载到其中并尝试在那里进行开发的诱惑!如果此时测试失败,请将其简化为最简单的失败案例,为其编写单元测试,并在本地树中修复它。重建图像不应该特别昂贵。
您的问题暗示了未修改的ubuntu
图像。FROM
除了一些非常早期的“hello world”类型实验之外,除了Dockerfile 行之外,几乎没有理由在任何地方使用它。如果您还没有,您应该阅读官方 Docker 教程,了解构建和运行自定义镜像,该教程适用于任何集群系统。(如果您已经将 Kubernetes 作为编排器,请跳过后面所有涵盖 Docker Swarm 的教程。)
推荐阅读
- asp.net-core - Azure 搜索构面子元素限制
- dart - 将参数传递给 initState
- swift - 如何将包含属性字符串的对象编码为数据?
- python - 如何在 Flask Admin 的编辑表单中添加额外的字段?
- python - 在字典的值中搜索字符串并返回新的字典
- html - SVG 文件内的 SVG onhover 样式 - 用于 IMG 标签
- angular - 在 Angular 6 Index.html 页面中使用 GTM 实现页面跟踪
- go - 如何解析 yaml 并获取接口深度结构的值
- angular - 登录成功后如何隐藏弹窗
- spring - 通过替换 HornetQ 添加 ActiveMQ 时服务器启动时出错