為什么Kubernetes這么受歡迎?
在本文發(fā)表時,Kubernetes大約已經(jīng)有6年的歷史,在過去的兩年里,它的受歡迎程度不斷上升,成為最受歡迎的平臺之一。今年,它成為第三大最受歡迎平臺。如果你還沒聽說過Kubernetes,它是一個允許你運行和協(xié)調(diào)容器工作負載的平臺。
容器最開始是一種Linux內(nèi)核進程隔離構(gòu)造,包含2007年的cgroups和2002年的namespaces。自LXC在2008年面世后,容器變得更為重要,谷歌也開發(fā)了自己內(nèi)部的“在容器中運行一切”的機制,名為Borg??爝M到2013年,Docker發(fā)布,徹底普及了容器。當時Mesos是編排容器的主要工具,然而它并沒有被廣泛采用。Kubernetes在2015年發(fā)布,并迅速成為容器編排的事實標準。
為了了解Kubernetes的流行度,我們來思考一些問題。開發(fā)人員最后一次就部署生產(chǎn)應用程序的方式達成一致是什么時候?你知道有多少開發(fā)者是按開箱即用的方式運行工具的?如今有多少云操作工程師不了解應用程序的工作原理?我們將在本文中探討答案。
基礎設施即YAML
從Puppet和Chef的世界來看,Kubernetes的一大轉(zhuǎn)變就是從基礎設施即代碼轉(zhuǎn)向為基礎架構(gòu)即YAML。Kubernetes中所有的資源,包括Pod、配置、部署、數(shù)據(jù)卷等,都可以簡單地用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等編程語言編寫代碼,即可更輕松且充分表達其工作負載。
將基礎設施作為數(shù)據(jù)的其他好處包括:
GitOps或Git操作版本控制。通過這種方法,你可以將所有的Kubernetes YAML文件都保存在Git倉庫下,這樣你就可以精確地知道什么時候進行了更改,誰進行了更改,以及到底更改了什么。這使得整個組織更加透明,避免了成員需要到哪里去尋找所需內(nèi)容的歧義,提高了效率。同時,只需合并一個拉取請求就可以更容易地自動對Kubernetes資源進行更改。
可伸縮性。將資源定義為YAML使群集操作員能夠非常輕松地更改Kubernetes資源中的一個或兩個數(shù)字來更改縮放行為。Kubernetes有Pod水平自動縮放控制器來幫助你確定一個特定部署需要擁有的最小和最大的Pod數(shù)量,以便能夠處理低流量和高流量時間。例如,如果你正在運行的部署可能因為流量突然增加而需要更多的容量,你可以將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是否允許容器以root身份運行。為此,用戶可以使用一個簡單的OPA rego策略表示,例如:
- package main
- deny[msg] {
- input.kind = "Deployment"
- not input.spec.template.spec.securityContext.runAsNonRoot = true
- msg = "Containers must not run as root"
- }
云提供商集成。科技行業(yè)的主要趨勢之一是在公共云提供商中運行工作負載。在云提供商組件的幫助下,Kubernetes允許每個集群與它所運行的云提供商進行集成。例如,如果用戶在AWS中的Kubernetes中運行應用程序,并希望該應用程序可以通過Service訪問,云提供商可幫助自動創(chuàng)建一個LoadBalancer服務,該服務將自動配置一個Amazon Elastic Load Balancer,以將流量轉(zhuǎn)發(fā)到應用程序Pod中。
擴展
Kubernetes的可擴展性很強,開發(fā)者很喜歡這一點?,F(xiàn)有的資源有例如Pods、Deployments、StatefulSets、Secrets、ConfigMaps等。但是,用戶和開發(fā)者可以通過自定義資源定義的形式添加更多的資源。例如如果我們想定義一個CronTab資源,我們可以用這樣的方式來實現(xiàn):
- 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
之后我們可以用類似以下方式來創(chuàng)建一個CronTab資源:
- apiVersion: "my.org/v1"
- kind: CronTab
- metadata:
- name: my-cron-object
- spec:
- cronSpec: "* * * * */5"
- image: my-cron-image
- replicas: 5
Kubernetes可擴展性的另一種形式是它能夠讓開發(fā)人員編寫自己的Operator,Operator是運行在Kubernetes集群中的特定進程,遵循控制循環(huán)模式。Operator允許用戶通過與Kubernetes API通信自動管理CRD(自定義資源定義)。
社區(qū)有一些工具允許開發(fā)者創(chuàng)建自己的Operator。其中一個工具是Operator Framework及其Operator SDK。SDK為開發(fā)者提供了一個框架,以便快速開始創(chuàng)建Operator。例如,你可以使用它的命令行用這樣的方法開始入門:
- $ operator-sdk new my-operator --repo github.com/myuser/my-operator
這將為你的Operator創(chuàng)建整個模版,包括YAML文件和Golang代碼:
- .
- |____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
然后你可以這樣添加APIs和控制器:
- $ operator-sdk add api --api-version=myapp.com/v1alpha1 --kind=MyAppService
- $ operator-sdk add controller --api-version=myapp.com/v1alpha1 --kind=MyAppService
最后構(gòu)建并將Operator鏡像推送到你的容器注冊表。
- $ operator-sdk build your.container.registry/youruser/myapp-operator
如果開發(fā)者需要有更多的控制權(quán),他們可以修改Golang文件中的模板代碼。例如,要修改控制器的具體細節(jié),他們可以對controller.go文件進行修改。
另一個項目,KUDO,允許你只使用聲明性的YAML文件來創(chuàng)建Operator。例如,一個Apache Kafka的Operator將像這樣定義,它允許用戶通過幾個命令在Kubernetes之上安裝一個Kafka集群。
- $ kubectl kudo install zookeeper
- $ kubectl kudo install kafka
也可以使用另一個命令調(diào)整它。
- $ 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
創(chuàng)新
在過去的幾年里,Kubernetes每隔三四個月就會有一個重要的版本,也就是說每年都會有三四個重要的版本。推出新功能的數(shù)量并沒有放緩,在上一個版本中,有超過30個不同的新增功能和變化就是證明。此外,正如Kubernetes項目GitHub活動所顯示的那樣,即使在這些困難時期,貢獻也沒有放緩的跡象。
新功能讓集群操作人員在運行各種不同的工作負載時更加靈活。軟件工程師也喜歡擁有更多的控制權(quán),可以直接將他們的應用程序部署到生產(chǎn)環(huán)境中。
社區(qū)
Kubernetes受歡迎的另一大方面是其強大的社區(qū)。首先,Kubernetes在2015年打出1.0版本時,就被捐給了一個廠商中立的機構(gòu):云原生計算基金會。
隨著項目的推進,還有大量針對Kubernetes的不同領域的社區(qū)SIG(特殊興趣小組),他們不斷增加新的功能,使其更加用戶友好。
云原生基金會還組織了CloudNativeCon/KubeCon,截至目前,該活動是世界上有史以來最大的開源活動。該活動通常每年最多舉辦三次,聚集了成千上萬的技術(shù)專家和專業(yè)人士,他們希望改進Kubernetes及其生態(tài)系統(tǒng),并利用每三個月發(fā)布的一些新功能。
此外,云原生基金會還有一個技術(shù)監(jiān)督委員會,該委員會與其SIG一起研究基金會在云原生生態(tài)系統(tǒng)中的新項目和現(xiàn)有項目。大多數(shù)項目都有助于提升Kubernetes的價值主張。
最后,我相信,如果沒有社區(qū)有意識的努力,互相彼此并歡迎任何新來者,Kubernetes就不會取得現(xiàn)在這樣的成功。
未來
開發(fā)者在未來面臨的主要挑戰(zhàn)之一是如何更加關注代碼的細節(jié),而非代碼運行的基礎設施。為此,無服務器正在成為解決這一挑戰(zhàn)的領先架構(gòu)范例之一。目前已經(jīng)有一些非常先進的框架,如Knative和OpenFaas,它們使用Kubernetes將基礎設施從開發(fā)者中抽象出來。
在本文中,我們簡單地介紹了Kubernetes,但這僅是冰山一角,用戶還可以利用更多的資源、功能和配置。我們將繼續(xù)看到新的開源項目和技術(shù)來增強和發(fā)展Kubernetes,正如我們提到的,貢獻和社區(qū)占據(jù)了很大地位。