写点什么

Kubernetes 初学者指南

作者:俞凡
  • 2022 年 2 月 01 日
  • 本文字数:6929 字

    阅读完需:约 23 分钟

Kubenetes 是当前容器编排的事实标准,每个基于容器开发应用的工程师/架构师都应该了解 Kubenetes 的基本概念,这篇文章介绍了 K8S 最核心的一组概念,可以帮助初学者迈入 K8S 的大门。原文:Just-in-Time Kubernetes: A Beginner’s Guide to Understanding Kubernetes Core Concepts[1]


在西多伦多铁路路上发现的一只蜗牛。图片由Dzero Labs提供


房间里的大象


你可能会想要学一点 Kubernetes 的知识,现在几乎每个人都在谈论这项技术,有很多关于 Kubernetes 的工作机会。Kubernetes 现在绝对是街上最靓的仔!


你也许……

  • 听说过 Kubernetes,并最终决定看看这玩意儿到底是什么。

  • 是一位经验丰富的软件工程师,已经用过一段时间 Kubernetes。也就是说,你已经了解了完成工作所需要的东西。不过,你觉得越来越陷入乱七八糟的各种细节中,所以决定是时候系统的掌握一些基本知识了。(嘘……我不会告诉别人的,因为我自己也经历过!)

  • 是一位技术领导者,领导的团队正在研究 Kubernetes(或者你的团队需要与另一个基于 Kubernetes 工作的团队合作),你想自学一些 Kubernetes 的知识。


欢迎光临!很高兴见到你!


我的目的是尽量简单的为你构建起学习和理解 Kubernetes 的基本模块。Kubernetes 看起来很大很吓人,让我们面对现实吧,任何新技术都是可怕的。有太多东西要学,有如此多的细微差别,尤其是从零开始的时候。你害怕了吗?😱


不用害怕,我会给你提供引导,向你展示 Kubernetes 并不是那么可怕,并激励你进一步拓展知识。如果你已经做了一段时间跟 Kubernetes 相关的工作,也可以顺便复习一下!也许你一直以某种方式做事,想当然的以为“事情就是这样的”;或者也许你遇到“啊哈!”时刻,更深入的了解事物为什么这样运作。


我们开始吧!

概述


在这篇文章中,我将涵盖以下主题:

  1. 什么是 Kubernetes?

  2. 顶层设计:Kubernetes 架构

  3. 深入挖掘:资源(Resources)、控制器(Controllers)和操作器(Operators)

  4. 用于与 Kubernetes 交互的kubectl命令行工具


如果你对某些方面感兴趣,请直接跳到感兴趣的话题。我不介意!😊


注意: 假设你对容器有基本的了解。


什么是 Kubernetes?


重要的事情先说……Kubernetes 到底是什么东西?Kubernetes 是一个容器编排系统,允许我们部署、扩展和管理容器化的应用程序。因为软件工程师都很懒,所以它也被缩写为 k8s。如果你曾经看到过“k8s”这个术语,并一直想知道它是什么,现在你知道了!


有趣的事实: Kubernetes 的起源可以追溯到最初由谷歌开发的 Borg 项目。


图片来源:memegenerator.net


现在,你可能想知道到底什么是容器业务流程。我们看一个例子。


假设你的服务器上有一堆 Docker 容器在运行,这些容器之间也许需要互相通信,或者你的朋友 Nancy 正在尝试访问运行在这些容器中的某个 API 端点。那么如何确保容器之间能够相互通信呢?或者如何确保 Nancy 能够安全的访问 API 端点?如果其中一个容器坏了怎么办?如果突然间不仅仅 Nancy 需要访问 API,而是 Nancy 和她所有的开发朋友由于参加一场黑客马拉松,都需要访问这个 API,因此需要对容器进行扩容,怎么办?


这就是使用容器编排的原因,它可以帮我们做到这一切,甚至做的更多。容器编排[2]被定义为:定义、部署和操作由多个虚拟机或物理服务器组成的计算集群的能力,以启动容器并管理它们的生命周期。

Kubernetes 的竞争对手


虽然 Kubernetes 又酷又流行,但你可能会惊讶的发现,它并不是唯一的容器编排器!事实确实如此,我们可以列举几个 Kubernetes 的竞争对手:

  • Docker Swarm[3]

  • Marathon[4]

  • Amazon ECS[5]

  • Azure Service Fabric[6]

  • Hashicorp Nomad[7]

不同口味的 Kubernetes


Kubernetes推出的一些口味——太好吃了!


虽然不像冰淇淋口味那样令人兴奋,但值得一提的是,Kubernetes 有几种不同的运行方式。

本地

首先,借助于下面的工具,可以在本地机器上运行 Kubernetes:

  • KIND[8]Kubernetes in Docker 的缩写)

  • Docker Desktop[9](是的,它自带 Kubernetes,可以在本地运行)

  • Minikube[10]

云服务商的解决方案

在本地运行 k8s 对于应用程序开发和本地测试都很有帮助,但是我们最终需要在生产环境中运行,并且是规模化运行。这就是为什么大多数主要的云服务商都有自己的 k8s。包括:

  • Google Kubernetes Engine(GKE)[11]

  • Amazon Elastic Kubernetes Service(EKS)[12]

  • Azure Kubernetes Service(AKS)[13]


每个云服务商通常都有一个小巧漂亮的 CLI 命令集,用于在该云中自动创建 k8s 集群。发出 CLI 命令就可以在 5-10 分钟内启动整个集群,这是一种非常神奇的体验。我们所说的不仅是按需启动虚拟机,还包括启动所有让 k8s 运转的服务。如果你想到这一点,无疑是超级令人印象深刻的!


它们还提供了一些基本的 k8s GUI,不过没啥特别的。

企业级解决方案

对于那些喜欢漂亮的管理 GUI,喜欢把手插在兜里(没有批评的意思,这类东西实际上有巨大的市场)的人,为了满足他们的企业级需求,可以看看以下这些供应商:

  • RedHat OpenShift[14]

  • VMWare Tanzu[15]

  • Rancher[16]


这些工具倾向于在 Kubernetes 的基础上增加一个管理层,以满足企业群体的需求。就像我之前提到的,它们往往拥有出色的管理控制台,也倾向于通过各自的“应用市场”提供大量插件,并可能有自以为是的 k8s 实现(例如服务网格选择)。这些供应商允许我们在公有云或自托管的私有云中运行他们的 k8s 集群。

DIY

最后,如果不怕麻烦的话,可以从头创建自己的 k8s 集群[17]。虽然我个人不太喜欢这么做,但如果你真的想了解 Kubernetes 是如何工作的,这绝对是一个很好的方式!

Kubernetes 组件


现在我们有了一点关于 Kubernetes 的背景知识,让我们来看看它背后有什么。


Kubernetes的master和worker (minion)节点


Kubernetes 集群由节点组成,这些节点可以是物理机,也可以是虚拟机。我们可以部署拥有一个或多个节点的集群,但理想情况下,在非开发场景中至少需要两个节点。


集群通常有一个主节点和一组工作节点(或随从节点)。


注意: 这就是为什么需要至少两个节点的原因,在非开发环境中,一个节点同时充当主节点和工作节点的单节点集群会遇到很多问题。


主节点负责监视工作节点并执行业务流程(想想管理员的工作),工作节点负责运行容器。


下图显示了主节点和工作节点的内部情况:


Kubernetes组件。图片来源:kubernetes.io


主节点(Master Node)


作为所有操作的管理者,主节点包含以下几个组件:

  • etcd

  • API 服务器

  • 控制器管理器

  • 调度器


让我们深入研究一下。

etcd

etcd[18]是一个分布式键值数据库,储存了 Kubernetes 当前以及过去的所有状态。每次修改 Kubernetes 的时候(无论是通过 k8s 的 REST API 发送 YAML 或者 JSON,还是通过kubectl CLI 工具(稍后会详细介绍)),修改都会以 JSON 形式存储在 etcd 中。它也是版本控制的,所以还需要进行一些严格的版本控制操作。


etcd 的一个关键特性是关注变化,也就是说,它检查系统中当前配置的内容,跟踪通过 REST API 调用或kubectl发送到 Kubernetes 的任何变更。


Nerd alert: 个人认为 etcd 是 Kubernetes 最酷的组件之一。实际上,可以在本地机器(例如 OSX[19]和 Ubuntu[20])上安装 etcd,并通过etcdctl[21] CLI 工具来使用。Python 甚至有一些用于以编程方式与 etcd 交互的库,我个人已经玩过 Python etcd3 库[22],强烈建议你自己探索一下 etcd!

API 服务器

API 服务器负责提供 Kubernetes API。想跟 Kubernetes 通信,让它为你做事吗?无论是用户、程序还是kubectl,这都是最直接的方式。API 服务器还负责向 etcd 发送数据以及从 etcd 提取数据。

控制器管理器

控制器管理器是业务流程背后的大脑。Kubernetes 有多个控制器,每个控制器自责不一。控制器监视集群状态,在需要的地方变更或请求更改。控制器管理器确保让正确的控制器做正确的事情。例如,有以下控制器:

  • 当 pod 关闭时采取行动

  • 将服务连接到 pod

  • 创建帐户和访问 API 令牌


还有许多其他的控制器……


注意: 也许你想知道 pod 是什么,简单来说,它是一个包装器,封装了一个或多个容器。

调度器

调度器跨多个节点分配工作,通过查看资源需求(例如 CPU 和内存需求)来确定何时运行 pod,以及在哪个节点上运行。

工作节点(Worker Node)

显然,主节点做了很多工作,但就像管理器一样,没有工作节点它什么也做不了。工作节点包含两个主要组件:

  • Kubelet

  • Kube-proxy

Kubelet

kubelet 是一个运行在集群中每个工作节点上的代理(小应用程序),主要工作是确保容器运行在一个 pod(一个或多个容器的包装器)中。但谁让它运行这些容器?由控制面(我们的好朋友控制器管理器所在的位置)决定。当控制面需要在一个节点中做点什么时,kubelet 就会帮它完成。


kubelet 运行容器运行时,顾名思义,它负责实际运行容器。更具体地说,它管理一个容器的完整生命周期:拉取容器镜像(从容器仓库拉取,如 Docker Hub[23])、存储容器镜像、运行容器、加载网络,等等。Docker[24]是流行的容器运行时,不过还有其他容器运行时,如 containerd[25], CRI-O[26]


注意: Kubernetes 目前使用 Docker 容器运行时,不过,不久的将来它将弃用 Docker,转而支持 Kubernetes CRI(Container Runtime Interface)[27]的运行时。docker 生成的映像还是可以在所有运行时中继续在集群中工作,所以不必惊慌!

Kube-proxy

kube-proxy 处理集群内外的网络通信,如果 pod 需要彼此通信,或者某个外部服务需要与 pod 通信,kube-proxy 会帮助实现这一点。

资源(Resources)、控制器(Controllers)和操作器(Operators)


现在我们已经理解了 Kubernetes 组件的基础知识,接下来我们来了解一些其他关键的 Kubernetes 概念和术语。

资源(Resources)


Kubernetes 资源[28]指的是 Kubernetes 中的对象或操作,可以通过 Kubernetes API 访问。资源类型被表示为名为 kind 的 JSON 对象,这个 JSON 对象存储在我们的好朋友 etcd 中(并且有版本管理)。


有两种类型的资源:原始资源和自定义资源。Kubernetes 的原始资源是“开箱即用”的,包括PodServiceDeploymentServiceAccountPersistentVolumeClaimRoleBinding、等等。

Kubernetes 中原始资源示例:

apiVersion: v1kind: ServiceAccountmetadata:  name: pipeline-sasecrets:  - name: basic-docker-user-pass  - name: basic-git-app-repo-user-pass复制代码
复制代码


自定义资源是 Kubernetes API 的扩展,因此在 Kubernetes 的默认安装中不一定可用。安装之后,您可以使用kubectl CLI 工具来创建和访问这些资源(稍后将详细介绍kubectl)。当我们想要 Kubernetes 做一些不是原生支持的事情时,就会创建自定义资源。


下面是一个自定义资源的例子:

apiVersion: tekton.dev/v1alpha1kind: PipelineRunmetadata:  generateName: my-pipeline-run-spec:  serviceAccountName: pipeline-sa  pipelineRef:    name: my-pipeline  resources:  - name: git-app-repo    resourceRef:      name: git-app-repo  - name: image-registry    resourceRef:      name: image-registry复制代码
复制代码


你也许已经注意到,在大多数情况下,原始资源和自定义资源都有相同的主字段:

  • apiVersion:用来创建资源的 Kubernetes API 的版本

  • kind:要创建的资源类型

  • metadata:唯一标识资源的数据

  • spec:告诉 Kubernetes 资源的期望状态


注意: 不是所有资源都有spec字段(例如ServiceAccountRoleRoleBinding)。

控制器(Controllers)


如前所述,控制器监视集群状态,然后在需要时进行变更或请求更改,以达到所需的状态。等等等等。但这到底意味着什么呢?


我们举个有趣的例子。假设你是游泳池的救生员,工作是保证泳池里所有人的安全。要做到这一点,你必须不断扫描游泳池,以确保没有游泳者处于困境,这就是所期望的状态。因此,如果你看到有人溺水,需要去把他们从水里拉出来,并执行任何其他必要的救生任务,以确保他们不再处于困境。

操作器(Operators)


操作器是控制器的一种类型。还记得我前面提到的那些自定义资源吗?定义一个自定义资源是不错,但最后我们怎么让 Kubernetes 做一些有用的事情呢?这就是操作器的作用,它们是后台代码,帮助这些自定义资源可以完成一些有用的事情。


虽然所有操作器都是控制器,但并非所有控制器都是操作器。这可能相当令人困惑,因为从一开始,它们似乎是相同的东西。主要的区别是操作器与自定义资源一起工作,扩展了 Kubernetes 的功能。


有趣的事实: 操作器可以用任何语言编写,并且有一些框架可以设置一些样板代码来帮助我们编写自己的操作器。


任何人都可以创建操作器:你、你的组织或外部供应商。例如,RedHat OpenShift 有自己的一组操作器(以及相应的自定义资源),这是其核心产品的一部分,运行在普通 Kubernetes 上。多亏了出色的开源社区,有许多操作器被共享了出来,可以在 OperatorHub.io[29]上查看其中的一部分。

kubectl


我在这篇文章中已经谈论了很多关于kubectl的内容,现在我们终于可以详细看一下这个组件了!kubectl是一个用于管理 Kubernetes 集群操作的命令行接口,与我们的好朋友 API 服务器通信,以获取关于集群的信息,并告诉 Kubernetes 需要做些什么事情(比如创建一个新资源,或修改一个现有的资源)。正如我之前提到的,当我们使用操作器和自定义资源定义(CRD)的神奇组合来扩展 Kubernetes API 时,也可以使用kubectl来访问/更新这些资源!


由于kubectl是一个命令行工具,所以可以在本地机器上运行。它与kubecconfig文件一起工作,kubecconfig是一个 YAML 文件,默认安装在$HOME/.kube/config中。下面是kubecconfig文件示例:


kubecconfig示例文件


你不需要试图理解这堆乱糟糟的东西,当我们连接到现有的 Kubernetes 集群时,kubecconfig文件中的条目是自动生成的。


例如,如果我想连接到 Azure Kubernetes 集群,可以使用 Azure 的 az CLI 来运行如下命令:

az aks get-credentials --resource-group my-resource-group --name my-aks-cluster复制代码
复制代码


这条命令会为我创建kubecconfig文件。很神奇!


类似的,可以使用 GCP 的 gcloud CLI 连接到谷歌 Kubernetes 集群,如下所示:

gcloud container clusters get-credentials my-gke-cluster --region=us-central1-a复制代码
复制代码


关键是,每个云服务商都有自己的云 CLI 和命令集,用于连接到该云中的 Kubernetes 集群,并相应的更新kubecconfig文件。


一旦在kubecconfig文件中注册了该集群,就可以对集群运行各种命令,还可以使用kubectl来了解当前注册的集群,并更新单个集群的配置。


注意: 完全可以在同一个kubecconfig文件中注册来自不同云的多个 Kubernetes 集群。或者,如果你喜欢的话,也可以有多个kubecconfig文件。


如果你有兴趣了解更多关于 kubectl 和 kubecconfig 的信息,请参阅下面的推荐阅读部分。

结论


本文绝不是对 Kubenetes 的深入研究,相反,我的目标只是向你介绍 Kubernetes 的基本概念,让你了解 Kubernetes 的运行原理,并希望能激励你更深入挖掘这个人人都在谈论的值得关注的技术。


你现在了解了一些 Kubernetes 的有趣的事实,下次如果有人问你关于 Kubernetes,可以这样告诉他们:

  • 什么是 Kubernetes?为什么要用它?

  • 主节点和工作节点的区别,以及每个节点的优点

  • 什么是资源?

  • 控制器和操作器的区别

  • kubectl是干嘛的?


现在,我要奖励你一张可爱小鸭子的照片。



Peace, love, and code.


推荐阅读


References:

[1] Just-in-Time Kubernetes: A Beginner’s Guide to Understanding Kubernetes Core Concepts: medium.com/dzerolabs/j…

[2] Containers, Kubernetes and Service Mesh in a Nutshell: pvillela.com/2021/contai…

[3] Docker Swarm: docs.docker.com/engine/swar…

[4] Marathon: www.sumologic.com/blog/contai…

[5] Amazon ECS: aws.amazon.com/ecs/?whats-…

[6] Azure Service Fabric: azure.microsoft.com/en-ca/servi…

[7] Nomad: www.nomadproject.io/

[8] KIND: kind.sigs.k8s.io/

[9] Docker Desktop: www.docker.com/products/ku…

[10] Minikube: minikube.sigs.k8s.io/docs/start/

[11] GKE: cloud.google.com/kubernetes-…

[12] EKS: aws.amazon.com/eks/?whats-…

[13] AKS: docs.microsoft.com/en-us/azure…

[14] RedHat OpenShift: www.redhat.com/en/engage/c…

[15] VMWare Tanzu: tanzu.vmware.com/tanzu?utm_s…

[16] Rancher: rancher.com/

[17] Kubernetes the hard way: github.com/kelseyhight…

[18] etcd: etcd.io/

[19] Install etcd on MAC with Brew: brewinstall.org/install-etc…

[20] How to install etcd on Ubuntu: computingforgeeks.com/how-to-inst…

[21] etcdctl: etcd.io/docs/v3.4/d…

[22] Python etcd3 library: pypi.org/project/etc…

[23] Docker Hub: hub.docker.com/

[24] Docker: www.docker.com/

[25] containerd: containerd.io/

[26] CRI-O: cri-o.io/

[27] Container Runtime Interface CRI in Kubernetes: kubernetes.io/blog/2016/1…

[28] Kubernetes API Concepts: kubernetes.io/docs/refere…

[29] OperatorHub: operatorhub.io/


你好,我是俞凡,在 Motorola 做过研发,现在在 Mavenir 做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI 等技术始终保持着浓厚的兴趣,平时喜欢阅读、思考,相信持续学习、终身成长,欢迎一起交流学习。微信公众号:DeepNoMind

发布于: 刚刚阅读数: 2
用户头像

俞凡

关注

还未添加个人签名 2017.10.18 加入

俞凡,Mavenir Systems研发总监,关注高可用架构、高性能服务、5G、人工智能、区块链、DevOps、Agile等。公众号:DeepNoMind

评论

发布
暂无评论
Kubernetes初学者指南