使用Kubernetes管理Kubernetes集群

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用Kubernetes管理Kubernetes集群相关的知识,希望对你有一定的参考价值。

参考技术A Kubernetes 1.0版本发布已经过去了4年,繁荣的社区和广泛用户群体使得Kubernetes的成熟度超出了预期,大部分用户常用的功能性需求都得到了满足。但是,根据CNCF的调查,很多非功能性的需求尚待完善,比如,用户所面临的最困难的挑战之一仍然是管理多个Kubernetes集群的生命周期,包括集群部署、升级和变更等。Kubernetes社区未来的一个阶段的重点就是帮助用户更好的部署和维护Kubernetes,使其无缝的融入和对接现有的企业环境。

Kubernetes现在已经可以支持超大规模的集群,单集群可以支撑5000个节点,15万个POD。但是由于大规模集群的维护和调度过于复杂,比如,有些企业应用需要分级,不同级别的应用需要使用不同的资源池,有些业务应用需要带有GPU支持的集群,有些应用需要Windows container的支持,甚至不同应用依赖不同版本的Kubernetes,所以在企业环境中通过多集群的方式实现多租户和资源调度已经成为了最佳实践。

当你需要管理多个集群,每个集群都有不同的规模、版本、升级计划、硬件资源池,自动化的管理工具和理念就必不可少了。

我们知道,Kubernetes的很多原则和理念改变了传统资源管理和交付的模式,其中声明式API和自愈机制的引入提升了用户部署和管理应用的效率。它允许用户通过yaml文件描述对象部署的期望状态(比如部署3个POD实例),并持续观测当前状态,如果和预期不一致(只剩2个POD实例),就通过控制器使其达到期望状态(添加1个POD实例,使总数为预期的3个)。
既然这种模式如此的成功,能不能把它适用到更多的场景中呢?比如,能不能用Kubernetes的思想来管理Kubernetes的集群呢?
实际上社区中已经有人这么做了,Cluster API 就是在这个背景下,由google,vmware等公司共同发起的项目。 https://github.com/kubernetes-sigs/cluster-api

Cluster API是一个Kubernetes项目,它将声明式的、Kubernetes风格的API用于集群创建、配置和管理。通过利用Kubernetes API的结构化和可扩展的特性,构建更高级别的云环境无关的工具,声明式的、自动化的改善用户体验。

当前,Cluster API已经可以支持AWS, Azure, GCP, Openstack, VMware, Bare metal等绝大多数基础设施环境。在目前的版本中,该API包含五个customresourcedefinition(CRD):Cluster、Machine、MachineSet、MachineDeployment和MachineClass。

将这几个CRD和大家熟悉的Kubernetes的对象类比一下,

说明:以下的几个CRD yaml文件都可以自动生成模板,在创建cluster的时候,并不都是必须的。

Cluster这个CRD是全新的Kubernetes集群的抽象。它可以定义Kubernetes集群配置,例如POD网络CIDR和service网络CIDR,以及集群是运行在何种云平台之上。

Machine类似于POD,它负责描述单个Kubernetes节点(虚拟机)。只需很少的配置(主要是Kubernetes版本信息),其他配置通过嵌入云环境相关的ProviderSpec。

MachineDeloyment 类似于Deployment。它允许对节点配置进行更新,定义工作节点的升级方式(rolling,recreate),它还允许回滚到以前的某个版本的配置。用户可以修改yaml文件来动态调整集群节点的数量。

MachineSet类似于ReplicaSet,管理一组Machine的扩缩容。与ReplicaSet类似,实践中尽量使用MachineDeloyment来管理一组资源的部署而不应该直接操作ReplicaSet。

MachineClass和StorageClass很像,定义Machine的规格。所有节点都会从指定规格的虚拟机模板中clone出来。

Cluster API的工作原理非常简单,用户通过以上的几个CRD定义需要的Kubernetes集群的规格。通过熟悉的kubectl apply命令把yaml传递给management cluster,managerment cluster会根据需要驱动不同的云平台创建虚拟机安装部署Kubernetes binary,并交付集群给用户。
那么management cluster是怎么来的?是否后续的运维工作也需要依赖它呢?实际上,初始的management cluster一般是一个单机版的Kubernetes,比如minikube或者Kind。当置备出第一个workload cluster以后,可以将management cluster的功能转移到任何一个workload cluster,这样后续的工作就不在依赖单机版的Kubernetes。一个有意思的地方是,你会发现,某一个workload cluster同时也是management cluster,在管理和监控着它自己。

下面是一个在vsphere环境使用Cluster API的例子。
首先,使用Cluster API项目提供的工具生成一组部署的yaml模板。

根据需求调整yaml文件中的内容,比如虚拟机模板的名称、集群节点的数量等。
然后依次创建这些资源对象,

这时可以在vcenter中看到Kubernetes集群的虚拟机陆续被创建出来。

大约几分钟后,workload cluster就可以交付给用户使用了。

我们可以关闭或者删除一个workload cluster的节点的虚拟机来模拟故障场景。Cluster API会自动检测所有节点的状态,并且驱动vsphere重新生成一个虚拟机进行替代,使得Kubernetes集群的状态与预期描述的一致。像不像Kubernetes管理POD的功能?

以上实验的具体的细节可参考官方文档, https://github.com/kubernetes-sigs/cluster-api-provider-vsphere/blob/master/docs/getting_started.md

解决多集群生命周期的管理只是企业环境使用Kubernetes的第一步,后续还有什么问题是需要考虑的?

如何使用命名空间管理Kubernetes资源?


本文是Google Developer Advocate Sandeep Dinesh的七部分视频和博客系列的第二篇,介绍如何充分利用您的Kubernetes环境。

第一篇:

当您开始在Kubernetes之上构建越来越多的服务时,简单的任务开始变得更加复杂。 例如,团队无法创建具有相同名称的Kubernetes Service或Deployment。 如果你有成千上万的Pod,只是列出它们都需要一些时间,更不用说实际管理它们了!当然,这些还只是冰山一角。

在本期Kubernetes最佳实践中,让我们来看看如何使用Kubernetes命名空间来更轻松地管理您的Kubernetes资源。



什么是命名空间(Namespace)?

如何使用命名空间管理Kubernetes资源?


您可以将命名空间视为Kubernetes集群中的虚拟集群。 您可以在单个Kubernetes集群中拥有多个命名空间,并且它们在逻辑上彼此隔离。 他们可以为您和您的团队提供组织,安全甚至性能方面的帮助!

默认命名空间(Default Namespace)

如何使用命名空间管理Kubernetes资源?


在大多数Kubernetes发行版中,集群开箱即用,命名空间默认为default。事实上,Kubernetes上有三个命名空间:default、kube-system(用于Kubernetes组件)和kube-public( 用于公共资源)。 kube-public现在并没有真正使用过,而且通常单独隔离一个kube-system是个好主意,尤其是在Google Kubernetes Engine这样的托管系统中。 默认命名空间是你创建服务和应用程序的默认位置,如果你不指定namespace参数的话。

这个命名空间绝对没有什么特别之处,只是Kubernetes工具是开箱即用的设置使用这个命名空间,而且你无法删除它。 它很适合入门和小型生产系统,我建议不要在大型生产系统中使用它。 这是因为团队很容易在没有意识到的情况下,意外地覆盖或破坏其他服务。 相反,我们应该创建多个命名空间并使用它们来将服务划分为可管理的块。

创建命名空间

如何使用命名空间管理Kubernetes资源?


不要害怕创建命名空间。 它们不会增加性能损失,而且实际上,在许多情况下它们可以提高性能,因为这样的话Kubernetes API使用的是较小的对象集合。

可以使用单个命令来创建命名空间。 如果你想创建一个名为test的命名空间,你可以运行如下命令:

kubectl create namespace test

或者您可以像创建其他任何Kubernetes资源一样,创建一个YAML文件并应用它。

test.yaml:

kind: Namespace
apiVersion: v1
metadata:
  name: test
  labels:
    name: test
kubectl apply -f test.yaml

查看命名空间

如何使用命名空间管理Kubernetes资源?


您可以使用以下命令查看所有命名空间:

kubectl get namespace


如何使用命名空间管理Kubernetes资源?

如上图,您可以看到三个内置命名空间,以及名为test的新命名空间。

在命名空间中创建资源

如何使用命名空间管理Kubernetes资源?


让我们看一个简单的YAML,它用来创建一个Pod:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
  labels:
    name: mypod
spec:
  containers:
  - name: mypod
    image: nginx

您可能会注意到在任何地方都没有提到名称空间。 如果在此文件上运行kubectl apply,它将在当前活动的命名空间中创建Pod。 除非您更改它,否则这将是“默认”命名空间。

有两种方法可以明确告诉Kubernetes您要在哪个Namespace中创建资源。

一种方法是在创建资源时设置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标志来设置另一个命名空间,则该命令将会失败。

在命名空间中查看资源

如何使用命名空间管理Kubernetes资源?


如果你试图找到你的Pod,你可能会注意到你不能!

$ kubectl get pods
No resources found.

这是因为所有命令都是针对当前active的命名空间运行的。 要查找Pod,您需要指定namespace。

$ kubectl get pods --namespace=test
NAME      READY     STATUS    RESTARTS   AGE
mypod     1/1       Running   0          10s

这可能会很快让人觉得很烦,特别是如果您是一个开发团队的开发人员,该团队使用自己的命名空间来处理所有事情,并且不希望对每个命令都指定namespace。 让我们看看我们如何解决这个问题。

管理active命名空间

如何使用命名空间管理Kubernetes资源?


初始状态下,您的活动命名空间是default。 除非在YAML中指定命名空间,否则所有Kubernetes命令都将使用当前active命名空间。

不幸的是,尝试使用kubectl管理您的active命名空间可能会很痛苦。 幸运的是,有一个非常好的工具叫做kubens(由优秀的Ahmet Alp Balkan创建)可以让它变得轻而易举!

运行kubens命令时,您应该看到所有命名空间,并突出显示active命名空间:

如何使用命名空间管理Kubernetes资源?

要将active命名空间切换到test命名空间,请运行:

kubens test

现在您可以看到test命名空间处于active状态:

如何使用命名空间管理Kubernetes资源?

现在,如果你运行kubectl命令,命名空间将是test而不是default!

这意味着您不需要指定命名空间来查看测试命名空间中的Pod。

$ kubectl get pods
NAME      READY     STATUS    RESTARTS   AGE
mypod     1/1       Running   0          10m

跨命名空间通信

如何使用命名空间管理Kubernetes资源?


命名空间彼此“隐藏”,但默认情况下它们不是完全隔离的。一个命名空间中的服务可以与另一个命名空间中的服务进行通信。 这通常非常有用,例如让您的团队的服务(在您的命名空间中)与另一个团队的服务(在另一个命名空间中)进行通信。

当您的应用想要访问Kubernetes Service时,您可以使用内置的DNS服务发现,只需将您的应用指向该Service的名称即可。 但是,您可以在多个命名空间中创建具有相同名称的Service!值得庆幸的是,通过使用扩展形式的DNS地址很容易解决这个问题。

Kubernetes中的服务使用通用DNS模式公开其endpoint。 它看起来像这样:

<Service Name>.<Namespace Name>.svc.cluster.local

通常,您只需要服务名称,DNS将自动解析为完整地址。 但是,如果需要访问另一个命名空间中的服务,则需使用服务名称加上命名空间名称。

例如,如果要连接到test命名空间中的database服务,可以使用以下地址:

database.test

如果要连接到production命名空间中的database服务,可以使用以下地址:

database.production

警告:如果您创建一个映射到“com”或“org”等TLD的命名空间,然后创建一个与网站名称相同的服务,例如“google”或“reddit”,Kubernetes将拦截“google.com“或”reddit.com“的请求并将其发送到您的服务。 这通常对于测试和代理非常有用,但也可以轻松破坏集群中的内容!

注意:如果确实要隔离命名空间,则应使用网络策略(Network Policies)来完成此操作。 更多信息请继续关注未来剧集!

命令空间粒度

如何使用命名空间管理Kubernetes资源?


一个常见问题是要创建多少个命名空间以及用于何种目的。 什么是可管理的块? 创建太多的命名空间,它们会让你变得没有效率,但是创建太少,你会错过它们的好处。

我认为答案在于您的项目或公司处于什么阶段 ——从小团队到成熟企业,每个阶段都有自己的组织架构。 根据您的具体情况,您可以采用对应的命名空间策略。

小团队

在这种情况下,您是一个小团队的一员,该团队正在开发5-10个微服务,可以轻松地进行团队沟通。 在这种情况下,将所有生产服务放到“默认”命名空间是个不错的选择。 根据你的个人喜好,你可能希望有一个production和development的命名空间,但你很有可能是在本地机器上使用类似Minikube搭建的开发环境。

快速成长的团队

在这种情况下,您有一个快速发展的团队,正在开发10多个微服务。 您开始将团队分成多个子团队,每个团队都拥有自己的微服务。 虽然每个人都可能知道整个系统是如何工作的,但是与其他人协调每一个变化变得越来越困难。 尝试在本地计算机上启动整个堆栈每天都变得越来越复杂。

此时有必要使用多个集群或命名空间进行生产和开发。 每个团队可以选择拥有自己的命名空间,以便于管理。

大公司

在一家大公司,并不是每个人都了解其他人。 某个团队正致力于其他团队可能不了解的功能。 团队可能正在使用服契约(service contract)与其他微服务通信(例如,gRPC),也有可能使用服务网格(Service Mesh)进行通信(例如,istio)。 试图在本地运行整个堆栈是不可能的。 强烈建议使用Kubernetes-aware Continuous Delivery系统(例如,Spinnaker)。

此时,每个团队肯定需要自己的命名空间。 每个团队甚至可以选择多个名称空间来运行其开发和生产环境。 设置RBAC和ResourceQuotas也是一个好主意。 多个集群开始显得很有意义,但可能不一定是必要的。

注意:我将在后面的文章中深入研究gRPC、Istio、Spinnaker、RBAC和Resources!

企业

在这种规模下,有些群体甚至不知道其他群体的存在。 某个组也可能是外部公司,服务之间通过标准文档定义的API来通信。 每个小组都有多个拥有一定数量微服务的团队。 这时使用我上面提到的所有工具是必要的。 人们不应该手工部署服务,同时应该被锁定在他们不拥有的命名空间之外。
此时,拥有多个集群以减少配置不当的应用程序导致的爆炸半径,以及简化计费和资源管理可能是有意义的。

结论

如何使用命名空间管理Kubernetes资源?


命名空间可以帮助您组织Kubernetes资源,同时可以提高团队的开发速度。 请继续关注未来的Kubernetes最佳实践剧集,我将向您展示如何锁定命名空间中的资源并为您的群集引入更多安全性和隔离性!

原文链接:https://cloudplatform.googleblog.com/2018/04/Kubernetes-best-practices-Organizing-with-Namespaces.html


Kubernetes应用实战培训

Kubernetes应用实战培训将于2018年9月14日在上海开课,3天时间带你系统掌握Kubernetes 。本次培训包括:容器特性、镜像、网络;Docker特性、架构、组件、概念、Runtime;Docker安全;Docker实践;Kubernetes架构、核心组件、基本功能;Kubernetes设计理念、架构设计、基本功能、常用对象、设计原则;Kubernetes的实践、运行时、网络、插件已经落地经验;微服务架构、DevOps等,点击阅读原文链接可查看具体培训内容。


以上是关于使用Kubernetes管理Kubernetes集群的主要内容,如果未能解决你的问题,请参考以下文章

Kubernetes 状态集缩减

kubernetes命令总结集

如何从外部访问托管在 kubernetes 集群上的 mongodb 副本集?

1.k8s部署(安装Docker/kubeadm/kubelet, 部署Kubernetes Master, 加入Kubernetes Node, 部署容器网络(CNI),测试kubernetes集)

1.k8s部署(安装Docker/kubeadm/kubelet, 部署Kubernetes Master, 加入Kubernetes Node, 部署容器网络(CNI),测试kubernetes集)

1.k8s部署(安装Docker/kubeadm/kubelet, 部署Kubernetes Master, 加入Kubernetes Node, 部署容器网络(CNI),测试kubernetes集)