存在的问题。你需要精心准备比Dockerfiles更多的东西来将其应用于生产——管理所有容器的容器编排系统。
问题
让我们来看一个相对简单的应用程序,一个使用PHP和MySQL的、数据库驱动的Web应用程序。你想到的第一个解决方案可能是分解所有HTTP职责,例如将API和前端用户界面(UI)投放到一个容器中,将所有后端存储投放到另一个容器中。
那么,你看下面两个图:
如果要扩展这个架构,很容易,你可以添加前端容器的更多副本。 接下来的两个图显示具有单个后端的单个前端,以及具有单个后端的多个前端:
还有人指出,在临时容器上运行MySQL持久性数据存储是次优的,因为当容器关闭时你就丢失了数据。 要解决这个问题,你可以向位于该容器外部的一个容器添加持久存储卷。 运行MySQL的容器可以关闭而不会带走你的数据。
现在,你可以扩展容器解决方案,并使用更多的容器来处理更大的负载。
现在你有一个很棒的容器解决方案,能够处理大量的流量,但它是基于一个谎言的。说成谎言可能有点不公平,那就说它是基于抽象的。容器仍然在拥有有限资源的机器上运行,因此我们希望该工作在多个机器之间分割。 如果其中一台机器出现故障,需要移动容器,该怎么办?
现在的设置增加了很多复杂性,但你仍然需要维护单个的机器,处理正常运行时间和移动资源。
解决方案:容器编排
你喜欢用一种系统来管理所有需要运行容器的裸机或虚拟机。你也会喜欢这样的系统——它可以管理你的容器,在底层机器上启动容器,确保容器是分布式的,并保持容器的健康。这是被称为容器编排系统的系统,Kubernetes就是一个这样的系统。
当讨论容器和Kubernetes时,有两个概念非常重要。
一、临时计算
服务器故障。堆栈溢出。当你每天为数百万个请求提供服务时,总会有问题发生。不要试图避免问题,你应该设计应用程序来处理问题。所以你应该明白在容器中运行的任何东西都可能离开,并被该容器的另一个新版本替换。
有很多隐喻来形容这种情况,最常见的是“宠物与牛”——宠物是指服务器,它们像养的狗、猫等。你给它们取名,好好照顾,当它们半夜生病时,你照顾它们。用容器时你可不想这样。相反,你想要的服务器是可以像牛一样的:可以大量运行,不用每个有名字,生病了不用那么费神。
二、期望状态
期望状态是所谓的命令式指令的对应物,它是一个很长的脚本语言。当我们写脚本时,事情发生,因为我们列出具体的步骤,等待它们完成。你可以创建新的:
带有代码更新的图像
SQL数据库
API服务器
前端服务器
如果有一个步骤失败,该进程停止,应用程序不启动。如果其中一台机器在启动后发生故障,必须重新启动它。
期望状态(或声明)意味着:“描述你想要什么设置,系统将使它发生”。所以,不是写出步骤,而是告知:
“我想要1个数据库的副本。
我想要2个API服务器的副本。
我想要3个前端服务器副本。”
声明性系统确保始终有许多副本在运行。如果一个发生故障,系统重新启动另一个。如果太多副本正在运行,系统会杀死多余的。现在你必须改变应用程序。如果API服务器在SQL数据库之前启动,你可能会遇到SQL连接错误。你希望确保向系统添加渐进重试。但这些变化是直接的,在许多情况下已经是最佳实践。
本文转移K8S技术社区-用Kubernetes解决容器的混乱(上)