Kubernetes是什麼
- 官網
https://kubernetes.io/
中文版:https://kubernetes.io/zh/
- Kubernetes是谷歌十幾年大規模容器管理經驗的成果
- 是Borg的一個開源版本
- 基於容器技術的分散式架構方案
Service簡介
- Kubernetes以Service為核心,Service有如下特徵
- 唯一名稱
- 擁有一個虛擬ip和埠
- 提供某種遠端服務能力
- 被對映到提供這種服務能力的一組容器應用上
Pod簡介
- Pod執行在Node主機中
- Pod是Kubernetes管理的最小執行單元
- 通常一個Node執行上百個Pod
- 每個Pod有一個特殊的Pause容器,負責網路棧和Volume掛載卷
- 只有提供服務的那組Pod才會被對映為一個服務
為什麼要使用Kubernetes
一旦搭建好Kubernetes環境後,後續對於應用的部署與運維,使用Kubernetes就非常方便了
Hello World
Kubernetes的安裝先不講了
- 現在要做的事情是
- 使用Kubernetes部署MySQL與JavaWeb程式
- JavaWeb可以訪問Kubernetes
- 基本步驟
- MySQL副本集
- MySQL Service
- JavaWeb副本集
- JavaWeb Service
下面的幾個yaml檔案在
https://github.com/nbcoolkid/learning/tree/master/k8s
MySQL RC
- mysql-rc.yaml
apiVersion: v1
# 表名這是一個副本集
kind: ReplicationController
metadata:
# RC的名稱,全域性唯一
name: mysql
spec:
# 期待的Pod數量
replicas: 1
selector:
app: mysql
# 根據此模板建立Pod副本
template:
metadata:
labels:
# Pod副本擁有的標籤,對應RC的Selector
app: mysql
spec:
containers:
- name: mysql
image: registry.cn-hangzhou.aliyuncs.com/sherry/mysql:5.7
ports:
# 容器應用監聽的埠號
- containerPort: 3306
# 注入容器內的環境變數
env:
- name: MYSQL_ROOT_PASSWORD
value: "123456"複製程式碼
注意這裡的yaml檔案,不可以有製表符,我們一律使用空格鍵代替
編寫完檔案後,使用apply命令做個檔案格式檢查
➜ k8s git:(master) ✗ kubectl apply -f mysql-rc.yaml
replicationcontroller/mysql created複製程式碼
- 建立RC
➜ k8s git:(master) ✗ kubectl create -f mysql-rc.yaml
replicationcontroller/mysql created複製程式碼
- 檢視建立結果
➜ k8s git:(master) ✗ kubectl get rc
NAME DESIRED CURRENT READY AGE
mysql 1 1 1 4m17s複製程式碼
- 檢視建立的Pod情況
➜ k8s git:(master) ✗ kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-wg9sp 1/1 Running 0 5m16s複製程式碼
- dashboard
其實通過dashboard,也能看到啟動情況
MySQL Service
- mysql-svc.yaml
apiVersion: v1
kind: Service # 表名這是一個Kubernetes Service
metadata:
name: mysql # Service全域性名稱
spec:
ports:
- port: 3306 # Service對外提供的埠
selector:
app: mysql # Service對應的Pod擁有此標籤,所有擁有此標籤的pod都歸我管複製程式碼
- 建立Service
➜ k8s git:(master) ✗ kubectl create -f mysql-svc.yaml
service/mysql created複製程式碼
- 檢視建立結果
➜ k8s git:(master) ✗ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 175m
mysql ClusterIP 10.105.55.185 <none> 3306/TCP 84s複製程式碼
可以發現,MySQL服務被分配了一個值為10.105.55.185
的CLUSTER-IP
,埠為3306
此時,Kubernetes叢集中其他建立的Pod就可以通過這個ip+埠進行連線和訪問了
這裡的ip,是Service建立後由Kubernetes系統自動分配的,
其他Pod無法餘弦知道,所以需要有一個服務發現機制來找到這個服務。
現在,我們根據Service的唯一名稱獲取到ip和埠
JavaWeb RC
- myweb-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb
spec:
replicas: 2
selector:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- name: myweb
image: kubeguide/tomcat-app:v1
ports:
- containerPort: 8080複製程式碼
在Tomcat容器內部,應用將使用環境變數MYSQLSERVICEHOST的值連線MySQL,更安全的做法是使用服務的名稱mysql進行訪問
- 建立RC
➜ k8s git:(master) ✗ kubectl create -f myweb-rc.yaml
replicationcontroller/myweb created複製程式碼
- 驗證
➜ k8s git:(master) ✗ kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-ck4j5 1/1 Running 0 164m
myweb-8dhr9 1/1 Running 0 3m11s
myweb-nm75w 1/1 Running 0 3m11s複製程式碼
JavaWeb Service
- myweb-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: myweb
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30001
selector:
app: myweb複製程式碼
type: NodePort
和nodePort: 30001
,表明此Service開啟了NodePort
方式的外網訪問模式
- 啟動
➜ k8s git:(master) ✗ kubectl create -f myweb-svc.yaml
service/myweb created複製程式碼
- 驗證
➜ k8s git:(master) ✗ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 5h47m
mysql ClusterIP 10.105.55.185 <none> 3306/TCP 174m
myweb NodePort 10.101.31.133 <none> 8080:30001/TCP 41s複製程式碼
驗證
經過上述步驟,我們通過dashbaord檢視到底啟動了哪些服務
- Service
- RC
- Pod
我們可以使用 http://虛擬機器ip:30001/demo/
的方式來進行驗證訪問
那麼怎麼獲取這個虛擬機器的ip呢?
我這裡使用的是minikube安裝的Kubernetes環境,安裝後,在虛擬機器中的Linux,賬號是root,密碼為空
然後使用ipconfig|more
命令就能看到ip
ok,至此,我們的hello world完畢
基本概念與術語
Kubernetes中的大部分概念,包括Node、Pod、Replication Controller、Service,都可以被看做一種資源物件
幾乎所有的資源物件都可以通過kubectl進行增刪改查操作,並持久化到etcd中
apiVersion:v1
宣告當前這個資源物件歸屬於v1這個核心API
大部分的資源物件都歸屬於v1這個核心API
Master
Kubernetes叢集的控制節點,一般在生產環境至少部署3臺作為高可用
所有的Kubernetes指令都是發給Master,由Master去管理叢集中的節點
- Master上執行著以下核心程式
- Kubernetes API Server:kube-apiserver,叢集控制入口
- Kubernetes Controller Manager:kube-controller-manager,資源物件管理
- Kubernetes Scheduler:kube-scheduler,資源排程
- Master上通常還部署etcd服務,因為Kubernetes裡的所有資源物件資料都儲存在etcd中
Node
- 工作節點,執行應用程式
- Node上執行著以下核心程式
- kubelet:負責Pod對應容器的建立、啟停,與Master的協作,實現叢集管理
- kube-proxy:實現Kubernetes Service的通訊,負載均衡的重要元件
- docker
- Node可以在Kubernetes執行期間動態加入叢集
- 前提是Node節點已經安裝好了上述核心程式
- 預設情況下,kubelet會向Master註冊自己
- 如果某個Node失聯,Master會觸發“工作負載大轉移”的自動流程
Pod
- Pod執行在Node上
- Pod有一個Pause根容器
- Pod內容器可以和Kubernetes叢集中任意的Pod內的容器進行直接通訊
- PodIP+容器埠=Endpoint,代表此Pod內的某個服務的對外通訊地址
- 一般一個應用會暴露兩個Endpoint,一個服務埠,一個管理埠
- 可以配置Pod對資源期望的最低要求和最高要求(CPU、記憶體)
resources:
# 設定一個較小的值,符合容器平時工作負載下的資源需求
requests:
# 記憶體佔用,預設單位為位元組,一般我們使用Mi,表示兆
memory: "64Mi"
# 以1/1000為最小單位,100m表示0.1個CPU
# 不管是在一個1Core的機器還是8Core的機器上,100m代表的含義都是一樣的
cpu: "250m"
# 設定一個較大的值,符合容器峰值負載下的資源需求
# 當容器試圖使用超過這個量的資源時,可能被Kubernetes殺掉並重啟
limits:
memory: "128Mi"
cpu: "500m"複製程式碼
Label
- Label是鍵值對,key和value均由使用者自定義
- 一個Label可以被附加到多個資源上,一個資源可以定義任意數量的Label
- Label通常在資源定義時確定,也可以在物件建立後動態新增與刪除
- Label定義後,通過 Label Selector(標籤選擇器)進行查詢和篩選
- Selector有基於等式與基於集合兩種
- name=redis-slave,匹配所有具備
- name!=redis-slave,匹配所有不具備
- name in (redis-master,redis-slave)
- name not in (pho-frontend)
- 多個表示式之間用
,
分割 - 多個表示式之間是
AND
關係
- matchLabels與matchExpressions
Replication Controller/Replica Set
- RC定義內容包括
- 期待Pod的數量
- 刪選Pod的Label Selector
- Pod數量不滿足時用於建立新Pod的template
- 一個完整的RC定義案例
確保擁有tier=frontend
標籤的Pod在Kubernetes叢集中始終只有一個副本
- 刪除RC,並不會刪除通過該RC建立好的Pod
- 如果要刪除RC對於的Pod,可以設定replicas值為0,然後更新RC
- kubectl提供stop、delete命令,來一次性刪除RC及其對應的Pod
- 在應用升級的時候
- 其實就是一個新的容器映象替代舊版本的過程
- 通過改變RC中Pod模板的映象版本,實現滾動升級
Deployment
為了更好的解決Pod的編排問題,Deployment內部使用Replica Set
我們把Deployment當做一次RC的升級即可
Horizontal Pod Autoscaler
HPA用於實現Pod的橫向自動擴容
StatefulSet
Service
Kubernetes內部的服務,最終是通過Service暴露出去的
Service整個生命週期內,擁有唯一不變的ip
Job
Volume
- Volume是Pod中能夠被多個容器訪問的共享目錄
- Kubernetes中的Volume概念、用途、目的,與Docker中的Volume類似,但又有不同
- Kubernetes中的Volume定義在Pod中
- Kubernetes中的Volume與Pod的生命週期相同,與容器不同
- Kubernetes支援多種檔案系統的Volume,如:GlusterFS、Ceph等
Persistent Volume
Namespace
名稱空間,一般用於實現多租戶的資源個例
Annotation
ConfigMap
本文由部落格一文多發平臺 OpenWrite 釋出!