原文链接:https://cloud.google.com/blog/products/gcp/kubernetes-best-practices-organizing-with-namespaces
编者按:
今天是谷歌开发者Sandeep Dinesh关于如何最大限度地利用Kubernetes环境的七集视频和博客系列的第二部分。
当您开始在Kubernetes上构建越来越多的服务时,简单的任务开始变得更加复杂。例如,团队不能使用相同的名称创建Kubernetes服务或部署。如果您有数千个Pod,仅仅列出它们都需要一些时间,更不用说实际管理它们了!这些只是冰山一角。
在这一期的Kubernetes最佳实践中,让我们看看Kubernetes名称空间如何使管理Kubernetes资源变得更容易。
https://www.youtube.com/watch?v=xpnZX3if9Tc
您可以将名称空间看作Kubernetes集群中的虚拟集群。在一个Kubernetes集群中可以有多个名称空间,并且它们在逻辑上彼此隔离。它们可以在组织、安全性甚至性能方面帮助您和您的团队!
在大多数Kubernetes发行版中,集群都有一个名为“default”的名称空间。实际上,Kubernetes附带了三个名称空间:default、kube-system(用于Kubernetes组件)和kube-public(用于公共资源)。kube-public目前并不常用,通常最好不要使用kube-system,尤其是在谷歌Kubernetes引擎这样的托管系统中。这使得默认名称空间成为创建服务和应用程序的地方。
这个名称空间没有什么特别之处,除了Kubernetes工具是开箱即用来使用这个名称空间的,您不能删除它。虽然它对于入门和小型生产系统非常有用,但我建议不要在大型生产系统中使用它。这是因为团队很容易在没有意识到的情况下意外地覆盖或中断另一个服务。相反,创建多个名称空间并使用它们将服务划分为可管理的块。
不要害怕创建名称空间。它们不会增加性能损失,而且在许多情况下,实际上可以提高性能,因为Kubernetes API将使用更小的对象集。
创建名称空间只需一个命令。如果你想创建一个名为“test”的命名空间,你可以运行:
kubectl create namespace test
或者您可以创建一个YAML文件并像其他Kubernetes资源一样应用它。
test.yaml:
kind: Namespace
apiVersion: v1
metadata:
name: test
labels:
name: test
kubectl apply -f test.yaml
您可以使用以下命令查看所有名称空间:
kubectl get namespace
您可以看到三个内置名称空间,以及名为“test”的新名称空间。
让我们看一个简单的YAML来创建一个Pod:
apiVersion: v1
kind: Pod
metadata:
name: mypod
labels:
name: mypod
spec:
containers:
- name: mypod
image: nginx
您可能会注意到,在任何地方都没有提到名称空间。如果在这个文件上运行kubectl apply
,它将在当前活动名称空间中创建Pod。这将是“default”名称空间,除非您更改它。
有两种方法可以显式地告诉Kubernetes希望在哪个名称空间中创建资源。
一种方法是在创建资源时设置“namespace”标志:
kubectl apply -f pod.yaml --namespace=test
您还可以在YAML声明中指定名称空间:
apiVersion: v1
kind: Pod
metadata:
name: mypod
namespace: test
labels:
name: mypod
spec:
containers:
- name: mypod
image: nginx
如果您在YAML声明中指定了一个名称空间,资源将始终在该名称空间中创建。如果尝试使用“namespace”标志设置另一个名称空间,则命令将失败。
查看名称空间中的资源
如果你试图找到你的Pod,你可能会发现你找不到!
kubectl get pods
No resources found.
这是因为所有命令都针对当前活动的命名空间运行。要找到Pod,需要使用“名称空间”标志。
kubectl get pods --namespace=test
NAME READY STATUS RESTARTS AGE
mypod 1/1 Running 0 10s
这很快就会让人厌烦,特别是如果您是一个开发团队的成员,该团队对所有事情都使用自己的名称空间,并且不希望对每个命令都使用“名称空间”标志。让我们看看如何解决这个问题。
开箱即用,您的活动命名空间是“默认”命名空间。除非在YAML中指定名称空间,否则所有Kubernetes命令都将使用活动名称空间。
不幸的是,尝试使用kubectl管理活动名称空间可能会很痛苦。幸运的是,有一种非常好的工具叫做kubens(由杰出的Ahmet Alp Balkan创建),它非常容易使用!
当您运行kubens
命令时,应该会看到所有名称空间,其中活动名称空间突出显示:
kubens test
现在您可以看到“test”名称空间是活动的:
现在,如果您运行kubectl
命令,名称空间将是“test”而不是“default”!这意味着您不需要名称空间标志来查看测试名称空间中的pod。
kubectl get pods
NAME READY STATUS RESTARTS AGE
mypod 1/1 Running 0 10m
名称空间彼此“隐藏”,但默认情况下它们不是完全隔离的。一个名称空间中的服务可以与另一个名称空间中的服务通信。这通常非常有用,例如让名称空间中的团队服务与另一个名称空间中的另一个团队服务通信。
当您的应用程序想要访问Kubernetes sService时,您可以使用内置的DNS服务发现并将应用程序指向该服务的名称。但是,您可以在多个名称空间中创建具有相同名称的服务!幸运的是,通过使用DNS地址的扩展形式可以很容易地绕过这个问题。
Kubernetes中的服务使用公共DNS模式公开其端点。它是这样的:
通常,您只需要服务的名称,DNS将自动解析为完整地址。但是,如果需要访问另一个名称空间中的服务,只需使用服务名称加上名称空间名称即可。
例如,如果您想连接到“test”名称空间中的“database”服务,可以使用以下地址:
database.test
如果您想连接到“production”名称空间中的“database”服务,可以使用以下地址:
database.production
警告:
如果您创建一个映射到TLD的名称空间,如“com”或“org”,然后创建一个与网站同名的服务,如“google”或“reddit”,Kubernetes将拦截到“google.com”或“reddit.com”的请求,并将其发送到您的服务。这通常对于测试和代理非常有用,但是也可以很容易地破坏集群中的东西!
注意:
如果您确实想要隔离名称空间,您应该使用网络策略来实现这一点。请继续关注下一集的更多内容!
我经常遇到的一个问题是要创建多少名称空间以及创建名称空间的目的是什么。什么是可管理的块?创建太多的名称空间,它们就会妨碍您,但是如果名称空间太少,您就会错过其中的好处。
我认为答案在于你的项目或公司处于哪个阶段——从小团队到成熟企业,每个阶段都有自己的组织结构。根据您的情况,您可以采用相关的名称空间策略。
在这个场景中,您是一个小团队的一部分,这个团队正在处理5-10个微服务,可以轻松地将每个人带到同一空间。在这种情况下,将所有生产服务启动到“默认”名称空间是有意义的。如果您想要更高级一些,您可能希望有一个“生产”和“开发”名称空间,但是您可能正在使用类似Minikube的东西在本地机器上测试您的开发环境。
在这个场景中,您有一个快速增长的团队,他们正在处理10多个微服务。您开始将团队分成多个子团队,每个子团队拥有自己的微服务。虽然每个人都可能知道整个系统是如何工作的,但是与每个人协调每个更改变得越来越困难。在您的本地机器上尝试向上旋转整个堆栈每天都变得越来越复杂。
此时,必须使用多个集群或名称空间进行生产和开发。为了更容易管理,每个团队可以选择使用自己的名称空间。
在大公司里,不是每个人都认识其他人。团队正在开发其他团队可能不知道的特性。团队使用服务契约与其他微服务(如gRPC)通信,使用服务网格协调通信(如istio)。试图在本地运行整个堆栈是不可能的。强烈推荐使用具有kubernets-aware的连续交付系统(例如Spinnaker)。
此时,每个团队肯定都需要自己的名称空间。每个团队甚至可以选择多个名称空间来运行其开发和生产环境。设置RBAC和resourcequota也是一个好主意。多个集群开始变得很有意义,但可能不是必需的。
注意:
我将在以后的章节中深入介绍gRPC、Istio、Spinnaker、RBAC和资源!
在这个尺度上,有些群体甚至不知道其他群体的存在。组也可以是外部公司,服务是通过文档良好的api使用的。每个组有多个拥有多个微服务的团队。使用我上面提到的所有工具都是必要的;人们不应该手动部署服务,应该将其锁定在不属于自己的名称空间之外。
在这一点上,使用多个集群来减少配置不佳的应用程序的爆炸范围、简化计费和资源管理可能是有意义的。
名称空间可以显著地帮助组织Kubernetes资源,并可以提高团队的速度。请继续关注Kubernetes未来的最佳实践部分,我将向您展示如何锁定名称空间中的资源,并为集群引入更多的安全性和隔离!