天天看點

Kubernetes Clusters

Kubernetes Clusters

1. 建立叢集

Kubernetes叢集 

Kubernetes協調一個高可用的計算機叢集,作為一個單獨的單元來一起工作。有了這種抽象,在Kubernetes中你就可以将容器化的應用程式部署到叢集中,而不必将它們特定地綁定到單獨的機器上。為了利用這種新的部署模型,應用程式需要以一種将它們與單個主機解耦的方式打包:它們需要被容器化。與過去的部署模型(PS:應用程式被直接安裝到特定的機器上)相比,容器化應用程式更加靈活和可用。Kubernetes以更高效的方式自動化分發和排程應用容器。Kubernetes是一個開源平台,可以投入生産。

Kubernetes叢集由兩類資源組成:

  • Master 協調整個叢集
  • Nodes 運作應用程式的Workers 

叢集大概是這樣的:

Kubernetes Clusters

Master負責管理叢集。Master協調叢集中的所有活動,比如排程應用程式、維護應用程式所需的狀态、擴充應用程式和推送新的更新。

在一個Kubernetes叢集中,節點是一個虛拟機或實體機,它是作為worker存在的。每個節點都有一個Kubelet,它是一個代理,用于管理該節點和master之間的通信。生産環境中,Kubernetes叢集應該至少有三個節點。

當你部署應用程式到Kubernetes上時,你實際上是告訴master啟動應用程式容器。master排程容器在叢集節點上運作。節點和master之間的通信通過Kubernetes API來完成。終端使用者還可以直接使用Kubernetes API與叢集互動。

Kubernetes叢集可以部署在實體機器或虛拟機器上。要學習Kubernetes的開發,可以使用Minikube。Minikube是一個輕量級Kubernetes實作,它在本地機器上建立一個虛拟機,并部署一個隻包含一個節點的簡單叢集。

本節回顧(劃重點)

Kubernetes是用于協調一個高可用的計算機叢集作為一個整體單元的開源平台,它的主要工作是協調應用程式容器的放置和執行。也就是說,Kubernetes屏蔽了底層的細節,使得一個叢集看起來就跟一台機器一樣,就是這麼整齊劃一。了解了這一層以後,就很好了解為什麼它可以跨叢集節點自動排程了。(PS:想到一個例子,閱兵的時候,兵哥哥們組成一個方陣,步調一緻,動作整齊劃一,那麼多人走在一起就像一個人一樣。如果我們把一台機器想象成一個方陣中的一個兵哥哥的話,那麼一個叢集就是一個方陣,這個方陣改怎麼走就是Kubernetes要做的事情。)

Kubernetes Clusters

一個叢集中有一個Master和多個Node。Master管理叢集,負責叢集中的所有活動。Node負責具體任務的執行,它是worker。每個Node上都有一個Kubelet,用于和Master通信。

敲黑闆,劃重點: 

1、Kubernetes coordinates a highly available cluster of computers that are connected to work as a single unit.
2、Kubernetes automates the distribution and scheduling of application containers across a cluster in a more efficient way.
3、Kubernetes is a production-grade, open-source platform that orchestrates the placement (scheduling) and execution of application containers within and across computer clusters.
4、Kubernetes叢集中有兩種類型的資源:Master 和 Nodes
5、The Master is responsible for managing the cluster.
6、A node is a VM or a physical computer that serves as a worker machine in a Kubernetes cluster. 
7、Masters manage the cluster and the nodes are used to host the running applications.       

2. 部署應用

Kubernetes Deployments

為了将容器化的應用部署到Kubernetes叢集中,需要建立一個Kubernetes Deployment配置。Deployment訓示Kubernetes如何建立和更新應用程式的執行個體。一旦建立了Deployment,Kubernetes master排程就會将應用程式執行個體放到叢集中的各個節點上。 

應用程式執行個體被建立以後,Kubernetes Deployment Controller将會持續監視這些執行個體。如果承載執行個體的節點當機或被删除,部署控制器将使用叢集中另一個節點上的執行個體替換該執行個體。這就提供了一種自我修複機制來處理機器故障或維護。

在預先編排的世界中,安裝腳本通常用于啟動應用程式,但它們無法從機器故障中恢複。通過建立應用程式執行個體并讓它們跨節點運作,Kubernetes部署為應用程式管理提供了一種完全不同的方法。

可以使用Kubernetes指令行接口Kubectl來建立和管理部署。Kubectl使用Kubernetes API與叢集互動。

建立部署的時候,需要為應用程式指定容器鏡像和要運作的副本數量。當然,後續可以通過更新部署來更改該資訊。

Kubernetes Clusters

Deployment就是将容器化的應用程式部署到Kubernetes叢集中。這個很好了解,就是我們平時開發完打jar包部署到伺服器上。 

敲黑闆,劃重點:

1、A Deployment is responsible for creating and updating instances of your application.
2、Applications need to be packaged into one of the supported container formats in order to be deployed on Kubernetes.
      

3. 檢視應用

3.1. Pods

建立部署時,Kubernetes會建立一個Pod來承載應用程式執行個體。一個Pod是一個Kubernetes抽象,它表示一組(一個或多個)應用程式容器(例如:Docker),以及這些容器的一些共享資源。這些資源包括: 

  • Shared storage, as Volumes
  • Networking, as a unique cluster IP address
  • Information about how to run each container, such as the container image version or specific ports to use 

Pod為一個特定應用程式的“邏輯主機”模組化,并可以包含不同的應用程式容器,這些容器是相對緊密耦合的。例如,一個Pod可能包含Node.js應用程式的容器和一個不同的容器,後者提供Node.js web伺服器要釋出的資料。Pod中的容器共享一個IP位址和端口空間,總是同時定位和同時排程,并在同一節點上的共享上下文中運作。

Pods是Kubernetes平台上的原子機關。當我們在Kubernetes上建立部署的時候,這個部署會建立包含容器的Pods(而不是直接建立容器)。每個Pod都綁定到預定的節點,并一直保持到終止(根據重新開機政策)或删除。萬一節點出現故障,叢集中其他可用節點上排程相同的Pods将會被排程。

Kubernetes Clusters

3.2. Nodes

Pod總是在節點上運作。節點是Kubernetes中的工作機,根據叢集的不同,它可以是虛拟機,也可以是實體機。每個節點由Master管理。一個節點可以有多個pod, Kubernetes Master跨叢集節點自動處理排程pod。Master的自動排程考慮到每個節點上的可用資源。

每個Kubernetes節點至少運作:

  • Kubelet, a process responsible for communication between the Kubernetes Master and the Node; it manages the Pods and the containers running on a machine.
  • A container runtime (like Docker, rkt) responsible for pulling the container image from a registry, unpacking the container, and running the application.
Kubernetes Clusters

常用的kubelet指令:

# list resources
kubectl get
# show detailed information about a resource
kubectl describe 
# print the logs from a container in a pod
kubectl logs 
# execute a command on a container in a pod
kubectl exec      

一個Pod是一組應用程式容器,包括運作這組容器所需的共享存儲、IP等資源。可以這樣了解,将一組容器打包在一起就是一個Pod。

Pod總是運作在Node上的。Node是一台實體或虛拟機。

如果容器之間是緊密耦合的,并且需要共享磁盤等資源,那麼應該将它們放在單個(同一個)Pod中。

綜上所述,我們不難了解:

  • Node是一台實體機或虛拟機,是真正幹活的工作機(worker) 
  • 多個應用程式容器組成Pod
  • Pod運作在Node上
  • 多個Node組成一個叢集
  • Master負責管理叢集,可以跨叢集節點排程

也就是說,在節點上我們看到的是一個一個的Pod,而Pod裡面是一個一個的容器

1、A Pod is a group of one or more application containers (such as Docker or rkt) and includes shared storage (volumes), IP address and information about how to run them.
2、Containers should only be scheduled together in a single Pod if they are tightly coupled and need to share resources such as disk.
3、A node is a worker machine in Kubernetes and may be a VM or physical machine, depending on the cluster. Multiple Pods can run on one Node.
      

4. 釋出應用

Pods也是有生命周期的。當一個工作節點(worker node)死亡時,該節點上運作的Pods也會随之丢失。然後,副本集可能通過建立新pod來動态地将叢集恢複到所需的狀态,以保持應用程式的運作。Kubernetes叢集中的每個Pod都有一個惟一的IP位址,即使是在同一個節點上的Pods,是以需要一種方法來自動協調Pods之間的變化,以保證應用程式正常運作。

Kubernetes中的Service是一個抽象,它定義了一組邏輯Pods和通路它們的政策。Services支援有依賴關系的Pods之間的松散耦合。與所有Kubernetes對象一樣,Service是使用YAML(首選)或JSON定義的。哪些Pods被選中用來組成一個Service通常是由标簽選擇器決定的。

盡管每個Pod都有唯一的IP位址,但是如果沒有Service,這些IP不會暴露在叢集之外。Service允許應用程式接收流量。通過在ServiceSpec中指定類型,可以以不同的方式公開服務:

  • ClusterIP (default) - 在叢集中的内網IP上公開服務。這種類型使得服務隻能從叢集内部通路。
  • NodePort - 使用NAT在叢集中每個標明節點的相同端口上公開服務。使用<NodeIP>:<NodePort>從叢集外部通路服務。
  • LoadBalancer - 在目前雲中建立一個外部負載均衡器(如果支援),并為服務配置設定一個固定的外網IP。
  • ExternalName - 通過傳回帶有名稱的CNAME記錄,使用任意名稱(在規範中由externalName指定)公開服務。

4.1. Services and Labels

Kubernetes Clusters

Service在一組Pod之間路由流量。Services是允許Pod在Kubernetes中死亡和複制而又不影響應用程式的抽象。Pods之間的發現和路由,由Kubernetes Services來處理。

Services通過使用标簽和選擇器比對Pods。标簽是附加到對象上的鍵/值對,可以以多種方式使用:

  • 為開發、測試和生産指定對象
  • 嵌入版本标記
  • 使用标記對對象進行分類 

标簽可以在對象建立時或以後附加到對象,可以随時修改它們。

Kubernetes Clusters

Kubernetes服務是一個抽象層,它定義一組Pods作為一個邏輯單元并為這些Pod啟用外部流量公開,負載平衡和服務發現。

多個容器組成一個Pod,多個Pod組成一個服務。服務是一種更高層次的抽象,它通過标簽和選擇器比對一些Pods,這些被選中的Pods形成一個服務,共同對外提供服務。

再對比一下Pod和Service的定義:

A Pod is a Kubernetes abstraction that represents a group of one or more application containers (such as Docker or rkt), and some shared resources for those containers.

A Service in Kubernetes is an abstraction which defines a logical set of Pods and a policy by which to access them.      

敲黑闆,劃重點

1、A Kubernetes Service is an abstraction layer which defines a logical set of Pods and enables external traffic exposure, load balancing and service discovery for those Pods.
2、You can create a Service at the same time you create a Deployment by using
--expose in kubectl.
3、A Service routes traffic across a set of Pods.
4、Services match a set of Pods using labels and selectors.
      

5. 擴充應用(擴容、伸縮)

5.1. Scaling an application

部署隻建立了一個Pod來運作我們的應用程式。當流量增加時,我們需要擴充應用程式以滿足使用者需求。

擴充是通過更改部署中的副本數量來實作的。

Kubernetes Clusters
Kubernetes Clusters

擴充部署将確定建立新Pod并将其排程到具有可用資源的節點上。縮放會将Pod的數量增加到新的所需狀态。Kubernetes還支援Pods的自動縮放。縮放到零也是可能的,它将終止指定Deployment的所有Pod。

運作一個應用程式的多個執行個體将需要一種将流量配置設定給所有執行個體的方法。 服務具有內建的負載均衡器,可以将網絡流量分發到公開部署的所有Pod。服務将使用端點連續監視正在運作的Pod,以確定流量僅發送到可用Pod。

一旦運作了一個應用程式的多個執行個體,就可以在不停機的情況下進行滾動更新。

Scale(伸縮)是通過改變副本數量來實作的。伸縮會将Pod的數量增加到新的所需的狀态。當應用從一個執行個體變成多個執行個體後,服務自帶的負載均衡器會将流量分發到所有公開的Pods上。 

1、Scaling is accomplished by changing the number of replicas in a Deployment.
2、You can create from the start a Deployment with multiple instances using the --replicas parameter for the kubectl run command.
      

6. 更新應用

6.1. Rolling updates

使用者期望應用程式一直可用,而開發人員期望每天多次部署它們的新版本。在Kubernetes中,這是通過滾動更新來完成的。 滾動更新允許通過用新的Pod執行個體增量更新Pod執行個體,進而在零停機時間内進行Deployment的更新。新的Pod将被排程到具有可用資源的節點上。

預設情況下,在更新過程中不可用的Pod的最大數量和可以建立的新Pod的最大數量為1。這兩個選項都可以配置為數字或百分比(按Pod)。 在Kubernetes中,對更新進行版本控制,并且任何部署更新都可以還原為先前(穩定)的版本。

Kubernetes Clusters
Kubernetes Clusters
Kubernetes Clusters
Kubernetes Clusters

與應用程式擴充類似,如果公開部署,則該服務将在更新過程中僅将流量負載均衡到可用Pod。可用的Pod是可供應用程式使用者使用的執行個體。 

滾動更新允許執行以下操作:

  • 将應用程式從一種環境更新到另一種環境(通過容器鏡像更新)
  • 復原到以前的版本
  • 持續內建和持續傳遞應用程式,停機時間為零

滾動更新允許通過用新的Pod執行個體增量更新Pod執行個體,進而在實作在不停機(服務不中斷)的情況下内進行Deployment的更新。

如果部署是公開公開的,則該服務将在更新期間僅将流量負載平衡到可用的Pod。

總之,一句話,滾動更新可以實作平滑更新(平滑上線)。(PS:可以聯想一下Nginx) 

1、Rolling updates allow Deployments' update to take place with zero downtime by incrementally updating Pods instances with new ones.
2、If a Deployment is exposed publicly, the Service will load-balance the traffic only to available Pods during the update.
      

7. 指令和文檔

https://kubernetes.io/docs/tutorials/

# 安裝minikube
 curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
 chmod +x minikube 
 install minikube /usr/local/bin/ 
 minikube version 
# 部署應用
 minikube start 
 kubectl version 
 kubectl cluster-info 
 kubectl get nodes 
 
 kubectl get deployments 
 kubectl get pods 
 kubectl describe pods 
 
 kubectl get services 
 kubectl delete service
 
 kubectl expose  
 kubectl exec 
 kubectl scale
 kubectl rollout status
      

7.1. Hello Minikube

Kubernetes Clusters

啟動叢集

minikube start --image-mirror-country cn \
 	--vm-driver=virtualbox \
 	--iso-url=https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.6.0.iso \
 	--registry-mirror=https://9q0y37ef.mirror.aliyuncs.com
      
Kubernetes Clusters

7.2. 示範

首先,建構鏡像

建立一個檔案命名為server.js

var http = require('http');
var handleRequest = function(request, response) {
  console.log('Received request for URL: ' + request.url);
  response.writeHead(200);
  response.end('Hello World!');
};
var www = http.createServer(handleRequest);
www.listen(8080);

      

再建立一個Dockerfile檔案

FROM node:6.14.2
EXPOSE 8080
COPY server.js .
CMD node server.js       

建構鏡像

docker image build . -t hello-world
docker tag hello-world:latest cheng1234/hello-world:v1.0
docker login
docker push cheng1234/hello-world:v1.0      
Kubernetes Clusters

推送到遠端鏡像倉庫,這裡推到預設的Docker Hub上

Kubernetes Clusters

半個小時以後,我後悔了,超級慢,根本推送不上去,速度慢得讓人想砸電腦,重試了好幾次。當成功推送上去的時候已經是第二天了。

Kubernetes Clusters

後來,我想,畢竟是國外的。。。

遂決定,推送到阿裡雲容器鏡像倉庫

docker login registry.cn-hangzhou.aliyuncs.com
docker tag hello-world:latest registry.cn-hangzhou.aliyuncs.com/chengjs/hello-world:1.0
docker push registry.cn-hangzhou.aliyuncs.com/chengjs/hello-world:1.0
      
Kubernetes Clusters

部署服務

kubectl create deployment hello-world --image=registry.cn-hangzhou.aliyuncs.com/chengjs/hello-world:1.0
kubectl get deployments
kubectl get pods
kubectl expose deployment hello-world --type=LoadBalancer --port=8080
kubectl get services
minikube service hello-world
      
Kubernetes Clusters
Kubernetes Clusters
Kubernetes Clusters

8. 阿裡雲容器鏡像服務

https://cr.console.aliyun.com/ 

Kubernetes Clusters
Kubernetes Clusters
Kubernetes Clusters
Kubernetes Clusters
Kubernetes Clusters
Kubernetes Clusters

阿裡雲

https://www.aliyun.com/product/acr

https://cr.console.aliyun.com/cn-hangzhou/instances/repositories

https://help.aliyun.com/document_detail/60743.html

https://help.aliyun.com/product/85222.html

https://developer.aliyun.com/group/kubernetes 

Docker

https://docs.docker.com/engine/reference/commandline/image_build/ 

https://docs.docker.com/engine/reference/commandline/tag/ 

Kubernetes

https://kubernetes.io/docs/tutorials

https://kubernetes.io/docs/setup/best-practices/

鏡像加速器

https://www.jianshu.com/p/5a911f20d93e

https://blog.51cto.com/14423403/2417029 

https://yq.aliyun.com/articles/696286

常用指令

Kubernetes Clusters