https://blog.csdn.net/keysilence1/article/details/70239717
概念
Kubernetes是谷歌嚴格保密十幾年的秘密武器——Borg的一個開源版本,是Docker分布式系統解決方案。
名詞
- Borg
Borg是谷歌內部使用的大規模集群管理系統,基於容器技術,目的是實現資源管理的自動化,以及跨多個數據中心的資源利用率的最大化;- Endpoint(IP+Port)
標識服務進程的訪問點;- Master
集群控制節點,負責整個集群的管理和控制,基本上Kubernetes所有的控制命令都是發給它,它來負責具體的執行過程,我們后面所有執行的命令基本都是在Master節點上運行的;
- Kubernetes API Server(kube-apiserver),提供Http Rest接口的關鍵服務進程,是Kubernetes里所有資源的增、刪、改、查等操作的唯一入口,也是集群控制的入口進程;
- Kubernetes Controller Manager(kube-controller-manager),Kubernetes里所有資源對象的自動化控制中心,可以理解為資源對象的“大總管”;
- Kubernetes Scheduler(kube-scheduler),負責資源調度(Pod調度)的進程,相當於公交公司的“調度室”;
- etcd Server,Kubernetes里所有的資源對象的數據全部是保存在etcd中;
- Node
除了Master,Kubernetes集群中的其他機器被稱為Node節點,Node節點才是Kubernetes集群中的工作負載節點,每個Node都會被Master分配一些工作負載(Docker容器),當某個Node宕機,其上的工作負載會被Master自動轉移到其他節點上去;
- kubelet,負責Pod對應的容器的創建、啟停等任務,同時與Master節點密切協作,實現集群管理的基本功能。一旦Node被納入集群管理范圍,kubelet進程就會想Master幾點匯報自身的情報,這樣Master可以獲知每個Node的資源使用情況,並實現高效均衡的資源調度策略。而某個Node超過指定時間不上報信息,會被Master判定為“失聯”,Node狀態被標記為不可用(Not Ready),隨后Master會觸發“工作負載大轉移”的自動流程;
- kube-proxy,實現Kubernetes Service的通信與負載均衡機制的重要組件;
- Docker Engine(docker),Docker引擎,負責本機的容器創建和管理工作;
- Pod
- 每個Pod都有一個特殊的被稱為“根容器”的Pause容器,還包含一個或多個緊密相關的用戶業務容器;
- 一個Pod里的容器與另外主機上的Pod容器能夠直接通信;
- 如果Pod所在的Node宕機,會將這個Node上的所有Pod重新調度到其他節點上;
- 普通Pod及靜態Pod,前者存放在etcd中,后者存放在具體Node上的一個具體文件中,並且只能在此Node上啟動運行;
- Docker Volume對應Kubernetes中的Pod Volume;
- 每個Pod可以設置限額的計算機資源有CPU和Memory;
- Requests,資源的最小申請量;
- Limits,資源最大允許使用的量;
- Event
是一個事件記錄,記錄了事件最早產生的時間、最后重復時間、重復次數、發起者、類型,以及導致此事件的原因等信息。Event通常關聯到具體資源對象上,式排查故障的重要參考信息;- Label
Label可以附加到各種資源對象上,一個資源對象可以定義任意數量的Label。給某個資源定義一個Label,相當於給他打一個標簽,隨后可以通過Label Selector(標簽選擇器)查詢和篩選擁有某些Label的資源對象。我們可以通過給指定的資源對象捆綁一個或多個Label來實現多維度的資源分組管理功能,以便於靈活、方便的進行資源分配、調度、配置、部署等管理工作;
Label Selector示例:select * from pod where pod’s name=’XXX’,env=’YYY’,支持操作符有=、!=、in、not in;- Replication Controller(RC)
部署和升級Pod,聲明某種Pod的副本數量在任意時刻都符合某個預期值;
- Pod期待的副本數;
- 用於篩選目標Pod的Label Selector;
- 當Pod副本數量小於預期數量的時候,用於創建新Pod的Pod模板(template);
- Replica Set
下一代的Replication Controlle,Replication Controlle只支持基於等式的selector(env=dev或environment!=qa)但Replica Set還支持新的、基於集合的selector(version in (v1.0, v2.0)或env notin (dev, qa)),這對復雜的運維管理帶來很大方便。- Deployment
擁有更加靈活強大的升級、回滾功能。在新的版本中,官方推薦使用Replica Set和Deployment來代替RC,兩者相似度>90%,相對於RC一個最大升級是我們隨時指導當前Pod“部署”的進度。Deployment使用了Replica Set,除非需要自定義升級功能或根本不需要升級Pod,一般情況下,我們推薦使用Deployment而不直接使用Replica Set;
典型使用場景:
- 創建一個Deployment對象來生成對應的Replica Set並完成Pod副本的創建過程;
- 檢查更新Deployment的狀態來查看部署動作是否完成(Pod副本的數量是否達到預期的值);
- 更新Deployment以創建新的Pod;(比如鏡像升級)
- 如果當前Deployment不穩定,則回滾到一個早先的Deployment版本;
- 掛起或者回復一個Deployment;
- Horizontal Pod Autoscaler(HPA)
意思是Pod橫向自動擴容,目標是實現自動化、智能化擴容或縮容。
Pod負載度量指標:
- CPUUtilizationPercentage
通常使用一分鍾內的平均值,可以通過Heapster擴展組件獲取這個值。一個Pod自身的CPU利用率是該Pod當前CPU的使用量除以它的Pod Request的值。例如Pod Request定義值為0.4,當前Pod使用量為0.2,則它的CPU使用率為50%。但如果沒有定義Pod Request值,則無法使用CPUUtilizationPercentage來實現Pod橫向自動擴容的能力;- 應用程序自定義的度量指標,比如服務在每秒內的相應的請求書(TPS或QPS)
- Service
Service其實就是我們經常提起的微服務架構中的一個“微服務”,通過分析、識別並建模系統中的所有服務為微服務——Kubernetes Service,最終我們的系統由多個提供不同業務能力而又彼此獨立的微服務單元所組成,服務之間通過TCP/IP進行通信,從而形成了我們強大而又靈活的彈性網絡,擁有了強大的分布式能力、彈性擴展能力、容錯能力;
如圖示,每個Pod都提供了一個獨立的Endpoint(Pod IP+ContainerPort)以被客戶端訪問,多個Pod副本組成了一個集群來提供服務,一般的做法是部署一個負載均衡器來訪問它們,為這組Pod開啟一個對外的服務端口如8000,並且將這些Pod的Endpoint列表加入8000端口的轉發列表中,客戶端可以通過負載均衡器的對外IP地址+服務端口來訪問此服務。運行在Node上的kube-proxy其實就是一個智能的軟件負載均衡器,它負責把對Service的請求轉發到后端的某個Pod實例上,並且在內部實現服務的負載均衡與會話保持機制。Service不是共用一個負載均衡器的IP地址,而是每個Servcie分配一個全局唯一的虛擬IP地址,這個虛擬IP被稱為Cluster IP。- Node IP
Node節點的IP地址,是Kubernetes集群中每個節點的物理網卡的IP地址,是真是存在的物理網絡,所有屬於這個網絡的服務器之間都能通過這個網絡直接通信;- Pod IP
Pod的IP地址,是Docker Engine根據docker0網橋的IP地址段進行分配的,通常是一個虛擬的二層網絡,位於不同Node上的Pod能夠彼此通信,需要通過Pod IP所在的虛擬二層網絡進行通信,而真實的TCP流量則是通過Node IP所在的物理網卡流出的;- Cluster IP
Service的IP地址。特性如下:
- 僅僅作用於Kubernetes Servcie這個對象,並由Kubernetes管理和分配IP地址;
- 無法被Ping,因為沒有一個“實體網絡對象”來響應;
- 只能結合Service Port組成一個具體的通信端口;
- Node IP網、Pod IP網域Cluster IP網之間的通信,采用的是Kubernetes自己設計的一種編程方式的特殊的路由規則,與IP路由有很大的不同;
- Volume
可以通過如下命令查看Volume信息:
注:Node、Pod、Replication Controller和Service等都可以看作是一種“資源對象”,幾乎所有的資源對象都可以通過Kubernetes提供的kubectl工具執行增、刪、改、查等操作並將其保存在ectd中持久化存儲。
優點
- 輕裝上陣,小團隊即可輕松應付從設計實現到運維的復雜的分布式系統;
- 全面擁抱微服務架構;
- 遷移方便,可以很方便的搬遷到公有雲或基於OpenStack的私有雲上;
- 超強的橫向擴容能力;
示例
環境准備
系統
64位CentOS7
安裝Kubernetes
關閉防火牆(沒安裝防火牆就算了~)
systemctl disable firewalld
systemctl stop firewalld
- 1
- 2
安裝etcd和Kubernetes軟件(會自動安裝Docker軟件)
yum install -y etcd kubernetes
- 1
安裝完畢后,需要修改如下兩個配置文件:
* 修改/etc/sysconfig/docker,將其中OPTIONS內容設置為:OPTIONS=’–selinux-enabled=false –insecure-registry grc.io’;
* 修改/etc/kubernetes/apiserver,把–admission-control參數的ServiceAccount刪除;
啟動所有服務
systemctl start etcd systemctl start docker systemctl start kube-apiserver systemctl start kube-controller-manager systemctl start kube-scheduler systemctl start kubelet systemctl start kube-proxy
- 1
- 2
- 3
- 4
- 5
- 6
- 7
如果不確定服務是否啟動成功,可以運行下面命令進行一一確認
ps aux | grep 服務名
- 1
Replication Controller
Java Web應用
注:Tomcat有可能無法正常啟動,原因是虛機的內存和CPU設置過小,請酌情調大!
鏡像
下載地址
拉取
Tomcat鏡像
docker pull kubeguide/tomcat-app:v2
Mysql鏡像
docker pull daocloud.io/library/mysql:latest
構建Mysql RC定義文件(構建創建Pod的源文件)
命名
mysql-rc.yaml
內容
apiVersion: v1
kind: ReplicationController
metadata:
name: mysql
spec:
replicas: 1
selector:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql image: mysql ports: - containerPort: 3306 env: - name: MYSQL_ROOT_PASSWORD value: "123456"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
發布到Kubernetes集群
創建RC
kubectl create -f mysql-rc.yaml
- 1
查看RC
kubectl get rc
- 1
查看Pod
kubectl get pods
- 1
構建Mysql Kubernetes Service定義文件
命名
mysql-svc.yaml
內容
apiVersion: v1 kind: Service metadata: name: mysql spec: ports: - port: 3306 selector: app: mysql
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
創建
kubectl create -f mysql-svc.yaml
- 1
查看SVC
kubectl get svc
- 1
構建Tomcat RC定義文件
命名
myweb-rc.yaml
內容
kind: ReplicationController
metadata:
name: myweb
spec:
# Pod的數量 replicas: 1 # spec.selector與spec.template.metadata.labels,這兩個字段必須相同,否則下一步創建RC會失敗。 selector: app: myweb template: metadata: labels: app: myweb # 容器組的定義 spec: containers: # 容器名稱 - name: myweb # 容器對應的鏡像 image: kubeguide/tomcat-app:v1 ports: # 在8080端口上啟動容器進程,PodIP與容器端口組成Endpoint,代表着一個服務進程對外通信的地址 - containerPort: 8080 env: #此處如果在未安裝域名解析的情況下,會無法將mysql對應的IP解析到env環境變量中,因此先注釋掉! # - name: MYSQL_SERVICE_HOST # value: 'mysql' - name: MYSQL_SERVICE_PORT value: '3306'
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
發布到Kubernetes集群
創建RC
kubectl create -f myweb-rc.yaml
- 1
查看RC
kubectl get rc
- 1
查看Pod
kubectl get pods
- 1
構建Tomcat Kubernetes Service定義文件
命名
myweb-svc.yaml
內容
apiVersion: v1 kind: Service metadata: name: myweb spec: type: NodePort ports: - port: 8080 nodePort: 30001 selector: app: myweb
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
創建
kubectl create -f myweb-svc.yaml
- 1
查看SVC
kubectl get services
- 1
運行
瀏覽器中輸入http://虛擬機IP:30001/demo即可呈現如下內容:
Deployment
構建Deployment定義文件
命名
tomcat-deployment.yaml
內容
#與RC不同之處,版本配置不同 apiVersion: extensions/v1beta1 #與RC不同之處,Kind不同 kind: Deployment metadata: name: frontend spec: replicas: 1 selector: matchLabels: tier: frontend matchExpressions: - {key: tier, operator: In, values: [frontend]} template: metadata: labels: app: app-demo tier: frontend spec: containers: - name: tomcat-demo image: tomcat # 設置資源限額,CPU通常以千分之一的CPU配額為最小單位,用m來表示。通常一個容器的CPU配額被定義為100~300m,即占用0.1~0.3個CPU; resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" imagePullPolicy: IfNotPresent ports: - containerPort: 8080
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
發布到Kubernetes集群
創建Deployment
kubectl create -f tomcat-deployment.yaml
- 1
查看Deployment
kubectl get deployments
- 1
- DESIRED,Pod副本數量的期望值,及Deployment里定義的Replica;
- CURRENT,當前Replica實際值;
- UP-TO-DATE,最新版本的Pod的副本數量,用於指示在滾動升級的過程中,有多少個Pod副本已經成功升級;
- AVAILABLE,當前集群中可用的Pod的副本數量;
查看對應的Replica Set
kubectl get rs
- 1
看一下這里的名稱與Deployment里面名稱的關系;
查看Pod
kubectl get pods
- 1
看一下這里Pod的命名以Deployment對應的Replica Set的名字為前綴;
查看Pod的水平擴展過程
kubectl describe deployments
- 1
HPA
構建HPA定義文件
命名
php-apache.yaml
內容
apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name: php-apache namespace: default spec: maxReplicas: 10 minReplicas: 1 scaleTargetRef: kind: Deployment name: php-apache targetCPUUtilizationPercentage: 90
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
這個HPA控制的目標對象為一個名叫php-apache的Deployment里的Pod副本,當這些Pod副本的CPUUtilizationPercentage超過90%時會觸發自動擴容行為,擴容或縮容時必須滿足的一個約束條件是Pod的副本數要介於1與10之間;
命令方式實現相同的功能
kubectl autoscale deployment php-apache –cpu-percent=90 –min=1 –max=10
Service
構建Service定義文件
命名
tomcat-service.yaml
內容
apiVersion: v1 kind: Service metadata: name: tomcat-service spec: # 服務如果想被外部調用,必須配置type type: NodePort ports: - port: 8080 name: service-port # 服務如果想被外部調用,必須配置nodePort nodePort: 31002 - port: 8005 name: shutdown-port selector: tier: frontend
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
上述內容定義了一個名為“tomcat-service”的Servcie,它的服務端口為8080,擁有“tier=frontend”這個Label的所有Pod實例都屬於它;
這里的NodePort沒有完全解決外部訪問Service的所有問題,比如負載均衡,假如我們又10個Node,則此時最好有一個負載均衡器,外部的請求只需訪問此負載均衡器的IP地址,由負載局衡器負責轉發流量到后面某個Node的NodePort上。這個負載均衡器可以是硬件,也可以是軟件方式,例如HAProxy或者Nginx;
如果我們的集群運行在谷歌的GCE公有雲上,那么只要我們把Service的type=NodePort改為type=LoadBalancer,此時Kubernetes會自動創建一個對應的LoadBalancer實例並返回它的IP地址供外部客戶端使用。其它公有雲提供商只要實現了支持此特性的驅動,則也可以達到上述目的;
發布到Kubernetes集群
創建Servcie
kubectl create -f tomcat-service.yaml
- 1
查看Endpoint列表
kubectl get endpoints
- 1
查看tomcat-service更多信息
命令
kubectl get svc tomcat-service -o yaml
- 1
結果
apiVersion: v1 kind: Service metadata: creationTimestamp: 2017-04-21T15:47:43Z name: tomcat-service namespace: default resourceVersion: "227916" selfLink: /api/v1/namespaces/default/services/tomcat-service uid: dbf15b30-26a9-11e7-b185-080027d589d3 spec: # Kubernetes集群內部的地址,無法在集群外部使用這個地址 clusterIP: 10.254.2.210 ports: # 服務的虛端口 - port: 8080 protocol: TCP # 確定提供該服務的容器所暴露的端口號,默認與port相同 targetPort: 8080 selector: tier: frontend sessionAffinity: None type: ClusterIP status: loadBalancer: {}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
補充命令
查看已存在的鏡像
docker images
- 1
刪除某個已存在的鏡像
docker rmi 鏡像ID
- 1
查看當前啟動的鏡像
docker ps
- 1
命令行方式進入某個容器
docker exec -it 容器ID sh
- 1
查看某個容器日志
docker logs 容器ID
- 1
刪除某個運行的容器
docker rm -f 容器ID
- 1
yaml文件修改后應用
kubectl apply -f XXX.yaml
- 1
重新啟動基於yaml文件的應用
kubectl delete -f XXX.yaml kubectl create -f XXX.yaml
- 1
- 2
查看集群中有多少Node
kubectl get nodes
- 1
查看某個Node的詳細信息
kubectl describe node 節點名
- 1
動態修改副本數量
kubectl scale rc XXX --replicas=3
- 1
查看RC的詳細信息
kubectl describe rc 標簽名或者選擇器名
- 1
通過RC修改Pod副本數量
kubectl replace -f rc.yaml 或 kubect edit replicationcontroller replicationcontroller名
- 1
- 2
- 3
對RC使用滾動升級,來發布新功能或修復BUG
kubectl rolling-update replicationcontroller名 --image=鏡像名
- 1
滾動升級
kubectl rolling-update replicationcontroller名 -f XXX.yaml