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