本文发表于一年多前。旧文章可能包含过时内容。请检查页面中的信息自发布以来是否已变得不正确。

使用 Kubernetes 名字空间管理环境

Kubernetes 的优势之一是它能够比传统部署策略更轻松、更好地管理各种环境。对于大多数非简单应用程序,您拥有测试、暂存和生产环境。您可以在暂存和生产环境中配置相同资源的独立集群(例如虚拟机),但这可能成本高昂,并且管理环境之间的差异可能很困难。
Kubernetes 包含一个名为[命名空间][4]的强大功能,它使您能够在同一个集群中管理不同的环境。例如,您可以在同一机器集群中拥有不同的测试和暂存环境,从而可能节省资源。您还可以在同一个集群中运行不同类型的服务器、批处理或其他作业,而无需担心它们会相互影响。

默认命名空间

在 Kubernetes 中指定命名空间是可选的,因为默认情况下 Kubernetes 使用“default”命名空间。如果您刚刚创建了一个集群,可以使用此命令检查默认命名空间是否存在

$ kubectl get namespaces
NAME          LABELS    STATUS
default                  Active
kube-system              Active

在这里您可以看到默认命名空间存在并且处于活动状态。命名空间的状态将在稍后关闭和删除命名空间时使用。

创建新命名空间

您以创建任何其他资源相同的方式创建命名空间。创建一个 my-namespace.yaml 文件并添加以下内容

kind: Namespace  
apiVersion: v1  
metadata:  
 name: my-namespace  
 labels:  
   name: my-namespace  

然后您可以运行此命令来创建它

$ kubectl create -f my-namespace.yaml

服务名称

通过命名空间,您的应用程序可以指向不随环境变化的静态服务终结点。例如,您的 MySQL 数据库服务在生产和暂存环境中可以都命名为 mysql,即使它运行在相同的基础设施上。

这之所以有效,是因为集群中的每个资源默认情况下只能“看到”同一命名空间中的其他资源。这意味着您可以通过创建具有相同名称的 Pod、Service 和 Replication Controller 来避免命名冲突,前提是它们位于不同的命名空间中。在命名空间内,服务的短 DNS 名称解析为该命名空间内的服务 IP。因此,例如,您可能有一个 Elasticsearch 服务,只要访问它的容器位于同一命名空间中,就可以通过 DNS 名称 elasticsearch 访问它。

您仍然可以通过完整的 DNS 名称(形式为 SERVICE-NAME.NAMESPACE-NAME)查找其他命名空间中的服务。例如,对于生产和 Canary 环境,分别是 elasticsearch.prod 或 elasticsearch.canary。

一个例子

让我们看一个应用程序示例。假设您想在 Kubernetes 中部署您的音乐商店服务 MyTunes。您可以在生产和暂存环境中运行该应用程序,以及在同一集群中运行一些一次性应用程序。您可以通过运行一些命令来更好地了解正在发生的事情

~$ kubectl get namespaces  
NAME                    LABELS    STATUS  
default                     Active  
mytunes-prod                Active  
mytunes-staging             Active  
my-other-app                Active  

在这里您可以看到几个正在运行的命名空间。接下来,让我们列出暂存环境中的服务

~$ kubectl get services --namespace=mytunes-staging
NAME          LABELS                    SELECTOR        IP(S)             PORT(S)  
mytunes       name=mytunes,version=1    name=mytunes    10.43.250.14      80/TCP  
                                                        104.185.824.125     
mysql         name=mysql                name=mysql      10.43.250.63      3306/TCP  

接下来检查生产环境

~$ kubectl get services --namespace=mytunes-prod  
NAME          LABELS                    SELECTOR        IP(S)             PORT(S)  
mytunes       name=mytunes,version=1    name=mytunes    10.43.241.145     80/TCP  
                                                        104.199.132.213     
mysql         name=mysql                name=mysql      10.43.245.77      3306/TCP  

请注意,尽管服务本身的名称相同,但 IP 地址会根据所使用的命名空间而异。此功能使配置您的应用程序变得极其容易——因为您只需将应用程序指向服务名称即可——并且有可能允许您在暂存或测试环境中像在生产环境中一样精确地配置您的应用程序。

注意事项

虽然您可以在同一个集群中运行暂存和生产环境,并以此节省资源和金钱,但您需要小心设置资源限制,以避免您的暂存环境耗尽生产环境的 CPU、内存或磁盘资源。正确设置资源限制并测试其是否有效需要大量时间和精力,因此除非您可以通过在与暂存或测试相同的集群中运行生产环境来显著节省金钱,否则您可能不希望这样做。

无论您是否在同一个集群中运行暂存和生产环境,命名空间都是在同一个集群中划分不同应用程序的好方法。命名空间还将作为未来可以应用资源限制的级别,因此请期待未来命名空间级别的更多资源管理功能。