在撰写本文时,Kubernetes已有6年历史了,在过去的两年中,它的流行度不断提高,并逐渐成为最受欢迎的平台之一。今年,它成为了最受欢迎的第三大平台(仅次于linux和docker)。如果您还没有听说过Kubernetes,那么我告诉你:它是一个平台,可以让您运行和编排容器工作负载。
容器最初是一个用于Linux内核进程隔离的构建结构,它整合了2007年的cgroup和2002年的命名空间(namespace)。当LXC在2008年可用时,容器变得越来越重要。而Google开发了自己内部使用的“在容器中运行所有”的机制,称为Borg。快进到2013年,Docker正式发布,并完全面向大众普及。当时,Mesos是编排容器的主要工具,但是,它并没有被广泛采用。Kubernetes于2015年发布,并迅速成为事实上的容器编排标准。
为了理解Kubernetes的流行,让我们考虑一些问题。开发人员上一次是在何时就应用部署在生产环境的方式达成共识?您知道有多少开发人员开箱即用地运行工具?如今又有多少云运维工程师不了解应用程序如何工作?我们将在本文中探讨答案。
基础设施即YAML
和来自Puppet和Chef世界的理念不同,Kubernetes的重大转变之一就是从基础设施即代码过渡到基础设施即数据(以YAML形式存在的数据)。Kubernetes中的所有资源,包括Pod,配置,部署,卷等,都可以简单地在YAML文件中表示。例如:
apiVersion: v1
kind: Pod
metadata:
name: site
labels:
app: web
spec:
containers:
- name: front-end
image: nginx
ports:
- containerPort: 80
这种表示形式使DevOps或SRE工程师可以更轻松地表达其工作负载,而无需使用Python,Ruby或Javascript等编程语言编写代码。
基础设施即数据理念的其他好处包括:
-
GitOps或Git运维版本控制。使用这种方法,您可以将所有Kubernetes YAML文件保存在git存储库下,这使您可以准确地知道何时进行了更改,由谁进行了更改以及究竟进行了哪些更改。这样提升了跨组织的透明性,避免了成员寻找所需内容时的模棱两可,,提高了效率。同时,通过合并请求,可以更轻松地自动更改Kubernetes资源。
-
可扩展性。将资源定义为YAML,使集群管理员可以非常轻松地通过更改Kubernetes资源中的一个或两个数字来更改应用缩放行为。Kubernetes具有水平Pod自动缩放器,可帮助您确定特定部署在处理低流量和高流量时所需Pod的最小和最大数量。例如,如果您正在运行的部署由于流量突然增加而可能需要更多容量,则可以将
maxReplicas
从10更改为20:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: myapp
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp-deployment
minReplicas: 1
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
- 安全和控制。YAML是验证在Kubernetes中部署什么以及如何部署的好方法。例如,有关安全性的主要问题之一是您的工作负载是否以非root用户身份运行。我们可以使用conftest(一种YAML / JSON验证器)以及Open Policy Agent(一种策略验证器)之类的工具来检查你的工作负载的
SecurityContext
是否不允许容器作为根运行。为此,用户可以使用一个简单的开放策略代理[rego]策略,像下面这样:
package main
deny[msg] {
input.kind = "Deployment"
not input.spec.template.spec.securityContext.runAsNonRoot = true
msg = "Containers must not run as root"
}
- 云提供商集成。科技行业的主要趋势之一是在公共云提供商中运行工作负载。借助云提供商组件,Kubernetes允许每个集群与其运行的云提供商集成。例如,如果用户正在AWS的Kubernetes中运行某个应用程序,并希望该应用可通过服务形式被访问,则云提供商将自动创建LoadBalancer服务,该服务将自动配置Amazon Elastic Load Balancer以将流量转发到应用程序容器。
可扩展性
Kubernetes具有很好的可扩展性,开发人员对此非常满意。K8s内置一组资源,例如Pod,Deployment、StatefulSets、Secrets、ConfigMaps等。但是,用户和开发人员也可以以“Custom Resource Definition”的形式添加更多自定义资源。例如,如果我们想定义一个CronTab
资源,我们可以用以下方法做到这一点:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: crontabs.my.org
spec:
group: my.org
versions:
- name: v1
served: true
storage: true
Schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
cronSpec:
type: string
pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$'
replicas:
type: integer
minimum: 1
maximum: 10
scope: Namespaced
names:
plural: crontabs
singular: crontab
kind: CronTab
shortNames:
- ct
之后,我们就可以使用CronTab
资源创建以下内容:
apiVersion: "my.org/v1"
kind: CronTab
metadata:
name: my-cron-object
spec:
cronSpec: "* * * * */5"
image: my-cron-image
replicas: 5
Kubernetes可扩展性的另一种形式是,开发人员具有编写自己的Operators的能力,Operator是在Kubernetes集群中运行的,遵循控制循环模式的特定进程。operator允许用户通过与Kubernetes API进行对话来自动管理CRD(自定义资源定义)。
社区有几种工具帮助开发人员创建自己的operator,其中就包括Operator Framework及其Operator SDK。SDK为开发人员提供了一个框架,使他们可以快速开始创建Operator。例如,您可以使用以下命令行命令开始:
$ operator-sdk new my-operator --repo github.com/myuser/my-operator
它将为您的operator创建一个模板,包括YAML文件和Go代码:
.
|____cmd
| |____manager
| | |____main.go
|____go.mod
|____deploy
| |____role.yaml
| |____role_binding.yaml
| |____service_account.yaml
| |____operator.yaml
|____tools.go
|____go.sum
|____.gitignore
|____version
| |____version.go
|____build
| |____bin
| | |____user_setup
| | |____entrypoint
| |____Dockerfile
|____pkg
| |____apis
| | |____apis.go
| |____controller
| | |____controller.go
然后,您可以添加API和控制器,像下面这样:
$ operator-sdk add api --api-version=myapp.com/v1alpha1 --kind=MyAppService
$ operator-sdk add controller --api-version=myapp.com/v1alpha1 --kind=MyAppService
最后构建并将operator推送到您的container registry:
$ operator-sdk build your.container.registry/youruser/myapp-operator
如果开发人员需要更多控制权,则可以修改Go文件中的样板代码。例如,要修改控制器的详细信息,他们可以对文件controller.go进行修改。
另一个项目KUDO允许您仅使用声明性YAML文件来创建operator。例如,我们可以像这样定义一个Apache kafka的operator,然后通过下面命令让用户在Kubernetes上安装一个kafka集群:
$ kubectl kudo install zookeeper
$ kubectl kudo install kafka
然后还使用另一个命令对其进行调整:
$ kubectl kudo install kafka --instance=my-kafka-name \
-p ZOOKEEPER_URI=zk-zookeeper-0.zk-hs:2181 \
-p ZOOKEEPER_PATH=/my-path -p BROKER_CPUS=3000m \
-p BROKER_COUNT=5 -p BROKER_MEM=4096m \
-p DISK_SIZE=40Gi -p MIN_INSYNC_REPLICAS=3 \
-p NUM_NETWORK_THREADS=10 -p NUM_IO_THREADS=20
革新
在过去的几年中,Kubernetes每三四个月发布一次主要版本,这意味着每年都有三到四个主要版本。引入的新功能的数量并未减慢,最新版本的30多种新增功能和功能更新证明了这一点。此外,Kubernetes项目的Github活动表明,即使在目前困难时期,对k8s的贡献也没有显示出放缓的迹象。
这些新功能使集群运营商在运行各种不同的工作负载时具有更大的灵活性。软件工程师还喜欢拥有更多控件,以将其应用程序直接部署到生产环境中。
社区
Kubernetes受欢迎的另一个重要方面是其强大的社区。首先,Kubernetes在2015年达到1.0版本时就捐赠给了与供应商无关的基金会:Cloud Native Computing Foundation。
随着项目的推进,还有各种各样的社区SIG(特殊兴趣小组)针对Kubernetes中的不同领域。他们不断添加新功能,并使其对用户更加友好。
Cloud Native Foundation还组织了CloudNativeCon/KubeCon,截至撰写本文时,CloudNativeCon/KubeCon是世界上最大的开源活动。该活动通常每年举行三届,吸引了数千名希望改善Kubernetes及其生态系统以及利用每三个月发布的新功能的技术人员和专业人士。
最后,我相信,如果没有社区的有意识的努力来互相包容并欢迎任何新来者,Kubernetes不会取得成功。
未来
开发人员未来面临的主要挑战之一是如何将更多的精力放在代码的细节上,而不是代码运行所在的基础设施上。为此,无服务器(serverless)正在成为应对这一挑战的领先架构范例之一。已经有非常高级的框架,例如Knative和OpenFaas,它们从Kubernetes做进一步抽象,让开发人员原理基础设施。
我们在本文中对Kubernetes进行了简要介绍,但这只是冰山一角。用户可以利用更多资源,功能和配置。我们将继续看到增强或发展Kubernetes的新开源项目和技术,正如我们所提到的,贡献和社区无处不在。
本文翻译自[《Why is Kubernetes getting so popular?》(https://stackoverflow.blog/2020/05/29/why-kubernetes-getting-so-popular/)]。
讲师主页:tonybai_cn
讲师博客: Tony Bai
实战课:《Kubernetes实战:高可用集群搭建,配置,运维与应用》
免费课:《Kubernetes基础:开启云原生之门》