【学习笔记】容器与Kubernetes

我从未参与过业务,但由于个人的兴趣,我学习了有关容器和Kubernetes的知识。以下是本文的概要内容。

容器可以。

传统世界中没有容器

如果不使用容器技术,在一台服务器上同时运行多个应用程序时,无法将应用程序A和应用程序B都安装在“/usr/share/myproject”目录下。这将导致安装目录重叠。在这种情况下,需要创建另一个目录,例如“/usr/share/myprojectB”,并进行安装目录的更改调整。此外,如果系统A和系统B共享框架,当需要根据系统A的需要更新框架时,需要预先验证更新后系统B是否能正常工作。传统环境下,多个应用程序和系统会相互影响,导致构建和更新过程繁琐且耗时。解决这类问题的方法就是使用容器的思想。

容器的意思是

「容器」是一种提供互不影响的隔离执行环境的技术。根据前面的例子,通过将应用程序A和应用程序B分别容器化,可以将应用程序安装在相同的目录路径上。此外,将系统A和系统B也进行容器化,并将框架根据系统A和系统B进行分割,可以确保系统A所需的框架更新不会影响到系统B。基本上,在容器中运行的应用程序是打包在容器内部的,不需要将配置文件放在容器外部,应用程序的运行完全在容器内完成。通过实现这样一个不受周围环境影响且不影响周围环境的应用程序运行环境,容器技术的目标就是提供这样的环境。与虚拟机技术的区别在于,容器不包含服务器,而是操作系统镜像,因此非常轻量。

集装箱的优点

作为使用容器的主要优点,我认为主要有”基本上在任何环境下都能够以相同的方式运行”。 “基本上在任何环境下都能够以相同的方式运行”意味着,例如,在验证环境中运行的容器几乎可以确定地在生产环境中以相同的方式运行,因此可以预防部署时由验证环境和生产环境之间的差异引起的问题,并且由于只需替换容器,可以简化工作。 此外,如果是团队开发,可以从基础容器映像轻松构建本地开发环境,从而不会浪费时间在构建本地开发环境等方面。简而言之,通过容器技术可以减少生产部署时的风险,并缩短传统工作的时间。

集装箱的普及

集装箱在中国越来越普及。原因是为了减少生产部署时的风险,缩短传统工作的时间,并且因为系统需要快速更新来满足用户需求的增加。代表性的IT公司,如谷歌和亚马逊,每年都提供大量新服务和更新,都是为了不错过客户的需求。为了实现这一点,需要快速部署和更新系统,而传统系统无法满足这一要求,因此需要使用容器技术。

集装箱的问题

如果只有2台或3台服务器上的容器,我认为也可以进行运维和管理。即使其中一台服务器发生故障,也可以手动在另一台服务器上启动容器进行运维。然而,如果容器的数量增加到10台、20台、100台或1000台,能否每天准确地了解和管理哪些容器在哪些服务器上运行呢?仅仅依靠像Docker这样的容器技术不能实现运维、管理、可用性和可扩展性。因此,为了代替人工,Kubernetes作为容器编排工具可以实现容器的运维、管理、可用性和可扩展性。

Kubernetes的概述

Kubernetes 是什么?

Kubernetes是一种容器编排工具,用于自动化容器的部署和扩缩容。除了Kubernetes之外,还有OpenShift、DockerSwam、Mesos、Rancher、Amazon ECS等多种容器编排工具。而在这些工具中,Kubernetes是最广泛使用的,并成为了事实标准。(sysdig-2019-container-usage-report) 使用Kubernetes可以摆脱手动管理容器的束缚。

Kubernetes的历史

在Linux Foundation的项目之一中,为了推进容器技术并与其演变的技术行业保持一致步伐而成立的基金会CNCF(Cloud Native Computing Foundation)担任主办,由社区主导进行开发。在2015年7月之前,此基金会由Google主办,但随着Kubernetes版本1.0的推出,被转移到了CNCF。Kubernetes是基于Google内部使用的容器集群管理器“Borg”的思想而创建的。

在Kubernetes中可以做的事情

弹性伸缩/自动伸缩

通过在多个Kubernetes节点上部署相同的容器镜像,可以实现负载均衡和提高容错能力。此外,还可以根据负载自动增减容器数量。

负载均衡

为了避免负载过度集中在特定容器上,可以进行负载均衡。

排程

该功能用于管理将容器部署到哪个Kubernetes节点上。通过使用亲和性/反亲和性功能,可以根据容器内应用程序的特征和Kubernetes节点的性能,将容器部署到Kubernetes节点上。例如,可以将具有高磁盘I/O的容器部署到具有SSD磁盘的Kubernetes节点上,从而实现对容器的控制。

自愈

在Kubernetes中,可以通过自带的容器进程监控来实现容器的监控。例如,当Kubernetes节点发生故障时,能够检测到容器的进程故障,并将容器恢复到另一个Kubernetes节点上,从而实现容器的自动修复功能,提高了容器的容错性。

资源管理

根据Kubernetes节点的CPU和内存资源,可以自动调整容器的部署位置,用户无需关心。此外,还可以根据Kubernetes节点的资源消耗量,通过Kubernetes集群的自动扩缩功能,自动增加或减少Kubernetes节点。

滚动更新

在更新容器内的应用程序时,可以通过先添加新容器,然后再删除旧容器的步骤进行重复操作,从而实现零停机更新。

服务发现

Kubernetes通过自动缩放、调度和自我修复等功能动态运行容器。因此,很难确定每个容器的位置。 Kubernetes会承担了解容器位置、了解其地址等职责,并确保容器在动态变化的系统中实现相互访问。

设定和保密信息的管理

在Kubernetes中,可以集中管理环境变量、命令行参数、密码和TLS证书等信息。可以使用ConfigMap来管理环境变量和命令行参数,使用Secrets来管理密码和TLS证书等机密信息。

Kubernetes的基础知识

要了解Kubernetes,需要掌握基本知識。

基础知识

宣言书

在Kubernetes中,我们将以YAML格式或JSON格式描述的容器和相关资源的部署进行管理的声明性代码称为清单。由于能够通过代码管理环境,因此Kubernetes可以实现基础设施即代码(Infrastructure as Code,IaC)。

kubectl 命令行工具

使用名为 kubectl 的CLI工具,向后续提及的Kubernetes Master发送命令。用户可以通过kubectl命令进行各种操作。还可以使用kubectl命令指定并使用前述的清单文件。

Kubernetes 节点

Kubernetes拥有Kubernetes Master和Kubernetes Node(以下简称Node)两个节点。Node类似于Docker Host,是实际运行容器的地方。

Kubernetes主控节点

Kubernetes Master(以下称为Master)根据清单中记录的内容通过kubectl来接收指令,并在其所管理的Node上实现接收到的指令。例如,如果接收到的清单文件中包含增加各个Node上容器数量的内容,Master将负责实际增加各个Node上的容器数量。

了解 Kubernetes 资源

工作量API分类。

豆荚 jiá)

Kubernetes资源的最小单元是Pod。Pod内包含一个或多个容器。Pod有一个网络接口,并且如果Pod内存在多个容器,则每个容器共用该网络接口。除非有特殊原因,一般推荐在Pod中只包含一个容器。

副本集

当需要部署多个Pod时,ReplicaSet是用来管理资源的。它会根据在ReplicaSet中定义的容器数量,在节点上进行调度和部署。即使发生节点故障导致节点上的容器消失,ReplicaSet会通过自动恢复机制,将容器数量恢复到预设的数量,并部署在其他可用的节点上。

部署

Deployment资源用于管理多个ReplicaSet。Deployment用于滚动更新。Deployment将通过以下步骤将旧的ReplicaSetA的Pod更新为新的ReplicaSetB的Pod:
1. 创建新的ReplicaSetB。
2. 增加新的ReplicaSetB上的Pod数目1个。
3. 减少旧的ReplicaSetA上的Pod数目1个。
4. 重复步骤2和步骤3。
5. 保持旧的ReplicaSetA的Pod数为0。

守护进程集

使用DaemonSet时,会在每个Node上均匀地部署Pod。与ReplicaSet不同,无法指定Pod的数量,也不会根据资源进行调度来部署容器。它通常用于运行类似datadog agent的度量代理或运行类似fluentd的日志收集守护进程等用途。

有状态集

这是用于部署和管理诸如数据库等有状态应用程序的资源。为了给工作负载赋予持久性,存在一种机制来保持相同的Pod名称。如果新建Pod,则以[Pod名称]-[编号]的方式进行命名。例如,web-0、web-1、web-2等。

工作

容器是用于执行一次性处理的资源。 job和replicaset之间的一大区别是它们在创建pod时是否假设pod会停止。基本上,replicaset将pod的停止视为意外错误。而在job的情况下,预期pod停止是正常的。举例来说,可以将”与特定服务器的rsync”或”上传到S3等对象存储”等操作列为示例。由于replicaset等并没有计算正常结束的数量,因此在批处理处理中应积极使用job。

定时任务

这是一种用于在预定时间创建作业的资源,就像Cron一样。
CronJob管理作业,作业管理Pod,形成了三层父子关系。

服务API类别

【服务分类】

Therefore, ClusterIP can be paraphrased in Chinese as「集群IP」 IP).

这是最基本的服务。它会在Kubernetes集群内部创建只能在内部网络中进行通信的虚拟IP并进行分配。因此,被称为ClusterIP。ClusterIP作为Kubernetes集群外部不需要接收流量的地方,可以用作集群内的负载均衡器。

节点端口

使用Kubernetes Node的IP地址:端口来接收流量,并将其转发到容器中,从而建立外部连通性。与仅在Kubernetes集群内部通信的ClusterIP不同,NodePort允许来自Kubernetes集群外部的通信。

负载均衡器

可以在Kubernetes集群外的负载均衡器上分配具有外部连通性的虚拟IP,即使节点发生故障,也可以将通信切换到另一节点,从而提高可用性。而NodePort最终仍然是向分配给任一Kubernetes节点的IP地址发送通信,因此该节点成为单点故障(SPoF)。

【Ingress分类】

入口

Ingress提供的是L7(应用层)的负载均衡资源,而上述的Service提供的则是L4(网络层和传输层)的负载均衡资源。通过使用Ingress,可以灵活地通过主机名进行类似HTTP的通信,将请求合理地分配到Pod上。使用Ingress需要额外准备Ingress Controller,并且需要外部或者内部的负载均衡器。

配置和存储API类别

配置映射

这是一个用于存储非机密数据的资源,以键值对的形式出现。可以将其作为环境变量、命令行参数或卷内的配置文件使用。

选择

存储用于连接到数据库时使用的用户名、密码和其他机密信息的资源,以便容器在连接时安全地传递信息。将机密信息保存在秘密中比直接在Pod定义或容器镜像中记录更安全和灵活。

持久存储

容器的数据是临时的,一旦Pod或容器被删除,数据就会消失。卷是用于持久化数据的资源。此外,它也用于在Pod内部的容器之间共享数据。

持久卷索赔

这是一个用于申请持久化存储卷的对象。根据PersistentVolumeClaim指定的条件(容量、标签),将发出对持久化存储空间的请求,并将分配适当的卷从PersistentVolume中。

聚类API类别

节点

Kubernetes通过将容器部署在节点上的Pod中来执行工作负载。节点指的是一个物理机或虚拟机。与之前所介绍的资源不同,节点基本上不是由用户来创建或删除的资源。

命名空间

這是在物理節點上建立的邏輯群組。它用於將集群劃分為更小的部分,以適應大型系統,或者將生產環境、預備環境和開發環境分開使用。

总结

关于 Kubernetes 对象,虽然这里还有很多没提到的内容。我学习过后发现 Kubernetes 中涉及的角色太多了,只在纸上学习已经感到厌烦。我认为实际上通过创建 Kubernetes 集群并进行操作验证的学习方法能够更好地理解,所以我建议那些打算开始学习 Kubernetes 的人选择这种方法。

本文根据以下资料进行撰写:
Kubernetes官方文档
Kubernetes完全指南 第2版
亲身实践学习云基础设施:从Docker基础到容器构建

广告
将在 10 秒后关闭
bannerAds