什么是Kubernetes
- 官網
https://kubernetes.io/
中文版:https://kubernetes.io/zh/

- 個人理解
- 基于容器技術
- 分布式架構
- 彈性伸縮
- 隔離物理機
- 和谷歌的Borg有關系
- 用于部署、管理、運維我們的應用
Kubernetes核心概念
Kubernetes中的大部分概念,如:Node、Pod、Replication Controller、Service,都可以被視作一種資源物件,幾乎所有的資源物件都可以通過Kubernetes提供的kubectl工具執行CRUD,并將其保存在etcd中進行持久化存盤,
從這個角度看,Kubernetes是一個高度自動化的資源控制系統
它通過比較etcd中保存的資源期望值與當前環境的實際資源狀態之間的差異,實作自動控制和自動糾錯的高級功能

Service
- 擁有唯一的名稱
- 擁有一個虛擬IP和埠號
- 能夠提供某種遠程服務能力
- 被映射到提供這種服務能力的一組容器應用上
Node
- 物理機
- 云上的虛擬機
反正就是一臺機器就對了
通常一個節點運行幾百個Pod
Replication Controller
副本集
它能夠保證Pod持續運行,并且在任何時候都有指定數量的Pod副本,在此基礎上提供一些高級特性,比如滾動升級和彈性伸縮

RC會在每個節點上創建Pod,Pod上如果有相應的Images可以直接創建,如果沒有,則會拉取這個鏡像再進行創建
在Kubernetes集群中,只要為需要擴容的Service關聯到Pod創建的一個RC,服務擴容和升級就會變得非常簡單
-
一個RC檔案,包含以下三個關鍵資訊
- 目標Pod的定義
- 目標Pod需要運行的副本數量
- 要監控的目標Pod的標簽
-
洗掉RC,并不會洗掉通過該RC創建好的Pod
- 如果要洗掉RC對于的Pod,可以設定replicas值為0,然后更新RC
- kubectl提供stop、delete命令,來一次性洗掉RC及其對應的Pod
-
在應用升級的時候
- 其實就是一個新的容器鏡像替代舊版本的程序
- 通過改變RC中Pod模板的鏡像版本,實作滾動升級
ReplicaSet
Replica Set是Replication Controller的下一代
當前唯一的區別就是RS支持基于集合的Label Selector

我們很少單獨設定RS,主要是被Deployment這個更高層的資源物件所使用
從而形成一整套Pod創建、洗掉、更新的編排機制
Replica Set和Deployment這兩個重要的資源物件,主鍵替代了RC的作用
Deployment
為了更好的解決Pod的編排問題,Deployment內部使用Replica Set
我們把Deployment當做一次RC的升級即可



Pod

Pod是Kubernetes管理的最小運行單元
一個Pod規定了其能夠使用的硬體資源,達到隔離的作用
Pod內運行一個特殊的Container---Pause,在Pod內的其他Container,共享Pause的網路堆疊和Volume掛載卷
- Pause
- 用pause這個不易死亡的容器代表pod的存活與否
- pod內的多個業務容器共享Pause的IP,共享Pause掛載的Volume
- Kubernetes為每個Pod都分配了唯一IP--->Pod IP
- 一個Pod內的多個容器共享Pod IP
- 一個Pod內的容器與另外Node上的Pod容器可以直接通信
Container
鏡像啟動后,就是Container
Container運行在Pod中,多個緊密相關聯的Container,我們一般會讓他們運行在同一個Pod
Label
Kubernetes中的各個物件,都可以打上Label標簽
標簽是name=mysql這樣子的鍵值對
一個資源物件可以定義任意數量的Label,同一個Label也可以被添加到任意數量的資源物件上
Kubernetes架構設計

Master
-
Master是集群控制節點
-
負責運行管理相關的行程
-
通常Master單獨占用一個服務器,如果需要高可用,建議部署3臺服務器
-
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會觸發“作業負載大轉移”的自動流程
HelloWorld
Kubernetes的安裝先不講了
-
現在要做的事情是
- 使用Kubernetes部署MySQL與JavaWeb程式
- JavaWeb可以訪問Kubernetes
-
基本步驟
- MySQL副本集
- MySQL Service
- JavaWeb副本集
- JavaWeb Service
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容器內部,應用將使用環境變數MYSQL_SERVICE_HOST的值連接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資源物件
在hello world中,我們已經使用yaml格式的方式,宣告了RC和Service兩種資源物件
其實還可以是JSON格式(不常用)
基礎
下面我們具體講講每一個配置
# 宣告需要用到的api版本
#Kubernetes平臺采用的是核心+外圍擴展的設計思路
#常見的核心資源物件都歸屬于v1這個核心api
apiVersion: v1
# 表名這是一個副本集,還可以是 Pod、Service等
kind: ReplicationController
metadata:
# RC的名稱,全域唯一
name: mysql
labels:
name: XXX # 定義了一個標簽,name=XXX
# 定義容器組
spec:
# 期待的Pod數量
replicas: 1
# selector是標簽選擇器,這里表示,當前容器組處理擁有app=mysql標簽的Pod
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
resources:
# 設定一個較小的值,符合容器平時作業負載下的資源需求
requests:
# 記憶體占用,默認單位為位元組,一般我們使用Mi,表示兆
memory: "64Mi"
# 以1/1000為最小單位,100m表示0.1個CPU
# 不管是在一個1Core的機器還是8Core的機器上,100m代表的含義都是一樣的
cpu: "250m"
# 設定一個較大的值,符合容器峰值負載下的資源需求
# 當容器試圖使用超過這個量的資源時,可能被Kubernetes殺掉并重啟
limits:
memory: "128Mi"
cpu: "500m"
ports:
# 容器應用監聽的埠號,PodIP+這個埠,組成了新的概念:Endpoint
# 代表此Pod里的一個服務行程的對外通信地址
- containerPort: 3306
# 注入容器內的環境變數
env:
- name: MYSQL_SERVICE_HOST
value: "mysql"
- name: MYSQL_ROOT_PASSWORD
value: "123456"
Selector運算式

kubectl命令詳解
詳細命令的使用,通過kubectl help獲得
查看
- 查看Node
? k8s git:(master) ? kubectl get nodes
NAME STATUS ROLES AGE VERSION
minikube Ready master 8h v1.16.2
- 查看某個node詳情
這里的minikube是node的name
? k8s git:(master) ? kubectl describe node minikube
Name: minikube
Roles: master
Labels: beta.kubernetes.io/arch=amd64
beta.kubernetes.io/os=linux
kubernetes.io/arch=amd64
kubernetes.io/hostname=minikube
kubernetes.io/os=linux
node-role.kubernetes.io/master=
Annotations: kubeadm.alpha.kubernetes.io/cri-socket: /var/run/dockershim.sock
node.alpha.kubernetes.io/ttl: 0
volumes.kubernetes.io/controller-managed-attach-detach: true
CreationTimestamp: Wed, 04 Dec 2019 10:02:05 +0800
Taints: <none>
Unschedulable: false
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
MemoryPressure False Wed, 04 Dec 2019 18:12:44 +0800 Wed, 04 Dec 2019 10:02:01 +0800 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Wed, 04 Dec 2019 18:12:44 +0800 Wed, 04 Dec 2019 10:02:01 +0800 KubeletHasNoDiskPressure kubelet has no disk pressure
PIDPressure False Wed, 04 Dec 2019 18:12:44 +0800 Wed, 04 Dec 2019 10:02:01 +0800 KubeletHasSufficientPID kubelet has sufficient PID available
Ready True Wed, 04 Dec 2019 18:12:44 +0800 Wed, 04 Dec 2019 10:02:01 +0800 KubeletReady kubelet is posting ready status
Addresses:
InternalIP: 192.168.99.105
本文由博客一文多發平臺 OpenWrite 發布!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/49653.html
標籤:其他
下一篇:Linux設定免密登陸
