取得 pod:
kubectl get pod xxxkubectl get pods xxxkubectl get po xxx
- Pod是k8s雲平台的虛擬機資源
理解K8s的NodePort Service
Service當中有Selector;Pod當中有Labels
Selector的app名稱 和 Lables的app名稱相同時,
Service會連接至app名稱相同的Pod裡面。
type: LoadBalancer只有公有雲才可以用,像是AWS之類的。
本地只能使用type: NodePort。
port: 80 代表server反向代理要暴露的 集群端口porttarget port: 80 代表server轉接到後台的pod的端口port
若target port不填寫,默認會是port的值,此例為80
把下面圖片的8080改成80,
Chrome進來Service時的反向代理(proxy)暴露 集群端口是port,
從Service指向後台pod裡的是target port。
metadata=詮釋資料;後設資料(用於解釋或幫助理解信息的數據)裡面的name代表kind: Sevice的名稱。
nodePort: 31080代表本機要暴露給外網的端口,之後測試時要輸入這個port值
kind: Pod必須要加上labels,
kind: Service的selector的app: xxx 和 kind: Pod的labels的app: xxx名字沒有相同的話,
Service就會找不到Pod。
describe :顯示一個或多個資源的詳細狀態,
藉由version的修改 及 Selector和Labels的配合 來達到藍綠發佈,
kubectl apply -f . #可以一次把當前目錄下的所有文件都發佈
kubectl delete svc xxx #刪除Servicekubectl delete po xxx #刪除Pod
Service主要負責反向路由和附載均衡(LoadBalancer)
通過Service實現藍綠發佈(Blue/Green Deployment)
當要升級時,只要把Service中的 Selector的version從v1.0.0 改成 v1.0.1,
就可以進到藍色的pod當中,
若新版本有問題,想要回退(roll back)時,
只要修改Selector的version從 v1.0.1 改成 v1.0.0,
Service又會指向綠色的Pod了。
apiVersion: v1kind: Servicemetadata:name: petclinicspec:ports:- name: httpport: 8080targetPort: 8080nodePort: 31080selector:app: petclinicversion: v1.0.1type: NodePort
apiVersion: v1 kind: Pod metadata: name: petclinic-v1.0.0 labels: app: petclinic version: v1.0.0 spec: containers: - name: petclinic image: spring2go/spring-petclinic:1.0.0.RELEASE
apiVersion: v1 kind: Pod metadata: name: petclinic-v1.0.1 labels: app: petclinic version: v1.0.1 spec: containers: - name: petclinic image: spring2go/spring-petclinic:1.0.1.RELEASE
kubectl grt po --show-labels #可以顯示出所有pod的LABELS
kubectl describe svc petclinic #可以查看名叫petclinic的 Services的詳細訊息
kubectl delete po --all #--all可以刪除全部的pods
kubectl delete svc --all #--all可以刪除全部的services
一直存在的service/kubernates,就算被刪掉後,
再使用kubectl get all來查看,會發現又出現了,
service/kubernates是default的,所以一直都在,不會被刪掉,
但我們創建的service/petclinic成功刪除了。
理解k8s的ReplicaSet
Pod是ephemeral(轉瞬即逝的),代表它隨時會掛掉,
掛掉後它自己是不會自動恢復的,
要透過ReplicaSet才能達到自癒能力(self-healing),
也就是你可以輸入一個ReplicaSet,並設定Pod的數量,
假設Pod數量為3,
當有Pod死掉,並導致Pod數量小於3時,
就會自動產生新的Pod,使Pod的數量一直維持在3個,此為self-healing。
並會把流量隨機分配到三個Pod中。
ReplicaSet發佈規範樣例。
template: 對應到之前的Pod發佈規範,
template裡面和 Pod相對應。
apiVersion: extensions/v1beta1 kind: ReplicaSet metadata: name: petclinic spec: replicas: 3 template: metadata: labels: app: petclinic #pods的標籤 spec: containers: - name: petclinic image: spring2go/spring-petclinic:1.0.0.RELEASE
1. petclinic-replicaset.yml
apiVersion: v1 kind: Service metadata: name: petclinic spec: ports: - name: http port: 8080 targetPort: 8080 nodePort: 31080 selector: app: petclinic #尋找所有 具有petclinic標籤的pods type: NodePort
2. petclinic-service.yml
刪除一個Pod後,馬上又生成了一個新的Pod
當我們刪除掉ReplicaSet後,它裡面產生的Pods也會一起被刪掉,
可以看到Pods的STATUS皆為Terminating,
之後再輸入一次kubectl get all,可以發現Pod皆已刪除。
理解滾動發佈和k8s的Deployment
一種高級發佈策略,
依次替換老版本,
逐步升級到新版本。
發佈過程中,
應用不中斷,
用戶體驗平滑。
下圖為滾動發佈,v1為舊版本;v2為新版本。
此範例 每批次發佈的v2數量為1個,
實際上,每批次發佈的數量可以>1,
而且每批次發佈的數量也可以不同,你要同時發佈5個v2也可以。
Deployment把ReplicaSet進行封裝,
使用Deployment來進行滾動發佈。
將舊版本滾動(Rolling)到新版本,
同時也可以將新版本滾動(Rolling)回舊版本。
Selector下面的matchLabels標籤必須要和 template下面的labels一致,
表示Deployment要選擇管理的是帶有 app: petclinic的 Pods。
apiVersion: apps/v1 kind: Deployment metadata: name: petclinic spec: selector: matchLabels: app: petclinic minReadySeconds: 10 replicas: 3 template: metadata: labels: app: petclinic spec: containers: - name: petclinic image: spring2go/spring-petclinic:1.0.1.RELEASE #<<在這裡進行滾動發佈,1.0.0 or 1.0.1都在這裡更改
1. petclinic-deployment.yml
apiVersion: v1 kind: Service metadata: name: petclinic spec: ports: - name: http port: 8080 targetPort: 8080 nodePort: 31080 selector: app: petclinic #尋找所有 具有petclinic標籤的pods type: NodePort
2. petclinic-service.yml
Deployment可以用來進行滾動式發佈,
kubectl rollout history deployment/petclinic
REVISION
1 #代表v1.0.0版本
2 #代表v1.0.1版本 目前版本
kubectl rollout undo deployment/petclinic #回退到上一個版本
kubectl rollout status deployment/petclinic #查看滾動式發佈 Pods的變動過程
kubectl rollout history deployment/petclinic
REVISION
2 #代表v1.0.1版本
3 #代表v1.0.0版本 目前版本
kubectl rollout undo deployment/petclinic --to-revision=2 #指定退回版本2
REVISION
3 #代表v1.0.0版本
4 #代表v1.0.1版本 目前版本 (回退回版本2, 版本2就是v1.0.1)
kubectl rollout delete deploy petclinic #刪除deployment
刪除Deployment後,
所有ReplicaSet都會一起被刪掉,
所有Pods也都會一起被刪掉。
ReplicaSet當中包含Pods,
Deployment當中包含ReplicaSet,
這也是為什麼我們寫yml檔案的時候只需要寫兩個的原因,
(Service和Deployment),
因為Deployment把ReplicaSet封裝起來了,
你寫了Deployment裡面就包含ReplicaSet和Pods。
理解k8s的ClusterIP Service內部反向代理
ClusterIp負責內部的服務訪問
apiVersion: v1kind: Podmetadata:name: mysqllabels:app: mysqlspec:containers:- name: mysqlimage: mysql:5.7env:- name: MYSQL_ROOT_PASSWORDvalue: petclinic- name: MYSQL_DATABASEvalue: petclinic
apiVersion: v1 kind: Service metadata: name: mysql spec: selector: app: mysql ports: - name: tcp port: 3306 targetPort: 3306 type: ClusterIP
apiVersion: apps/v1 kind: Deployment metadata: name: petclinic spec: selector: matchLabels: app: petclinic replicas: 1 template: metadata: labels: app: petclinic spec: containers: - name: petclinic image: spring2go/spring-petclinic:1.0.1.RELEASE env: - name: SPRING_PROFILES_ACTIVE value: mysql - name: DATASOURCE_URL value: jdbc:mysql://mysql/petclinic#進入mysql的Service裡面,使用ClusterIP連到後台mysql的pod #mysql數據庫名稱- name: DATASOURCE_USERNAME value: root - name: DATASOURCE_PASSWORD value: petclinic - name: DATASOURCE_INIT_MODE value: always
apiVersion: v1 kind: Service metadata: name: petclinic spec: ports: - name: http port: 8080 targetPort: 8080 nodePort: 31080 selector: app: petclinic type: NodePort
因為文件彼此之間有依賴關係。
petclinic 依賴於mysql,
所以需要先把mysql給發佈。
發佈順序:
mysql-pod.yml >>
mysql-service.yml >>
petclinic-deployment.yml >>
💛NodePort - 對外暴露服務
💛LoadBalancer - 對外暴露服務(公有雲 ex: AWS)
Deployment/Pod 發佈規範中可以添加環境變量(env),給Pod傳遞啟動參數
有狀態服務(ex: mysql),一般只能部署一個Pod實例。
理解K8s的Namespace和Kube-Dns
為什麼左邊petclinic的deployment可以連到mysql的Service呢?
網域到IP地址的轉換需要DNS的服務,
k8s有內建Dns服務,
因此可以完成網域(mysql)到ClusterIP地址(10.96.235.168)的轉換。
kubectl get ns #ns是namespace的縮寫 #可以看到已經存在的名詞空間(ns)
如果只輸入kubectl get all,會無法看到名詞空間(Namespace),因為它是隱藏的。
你可以客製化,訂製屬於自己的名詞空間,
若沒有特別設定,
k8s預設將自動指向default裡面。
kubectl get all -n kube-system #可以看到kube-system(名詞空間)的內部
若沒有特別加上 -n 去指定哪一個Namespace,
預設都是進入default名詞空間當中。
kube-apiserver, kube-controller, kube-proxy, kube-scheduler等等,
皆是住在kube-system裡面。
service/kube-dns是k8s的dns,可以透過訪問kube-dns,把網域轉換成ClusterIP地址。
petclinic(左上角藍色的pod)會先去訪問kube-system(名詞空間)裡面的kube-dns,得到mysql-service的ClusterIP位址後,
才能對mysql-service發起調用,
調用成功才能訪問mysql-pod。
步驟:
💙petclinic-pod想要訪問mysql-pod,且它已在環境env設定mysql的網域(mysql)>>
💚petclinic-pod先訪問kube-dns,並且得到mysql-service的ClusterIP>>
💛petclinic-pod藉由mysql-service的ClusterIP位址,成功進入mysql-service>>
💜找到mysql-service就可以訪問mysql-pod,此時,petclinic-pod已成功訪問mysql-pod。
若沒有指定名詞空間,我們運行的資源會住在default當中。
kube-system是k8s的系統名詞空間,住著k8s的系統組件,
apiVersion: v1 kind: ConfigMap metadata: name: petclinic-config-v2 data: SPRING_PROFILES_ACTIVE: mysql DATASOURCE_URL: jdbc:mysql://mysql/petclinic DATASOURCE_USERNAME: root DATASOURCE_PASSWORD: petclinic DATASOURCE_INIT_MODE: always TEST_CONFIG: test_config_v2
1. petclinic-config.yml
Deployment和Service中間加上" --- "做為分隔,可以寫進同一個.yml文件當中
apiVersion: apps/v1 kind: Deployment metadata: name: petclinic spec: selector: matchLabels: app: petclinic replicas: 1 template: metadata: labels: app: petclinic spec: containers: - name: petclinic image: spring2go/spring-petclinic:1.0.1.RELEASE envFrom: - configMapRef: name: petclinic-config-v2 #在這裡訪問petclinic-config並把env環境變數匯入petclinic中 --- apiVersion: v1 kind: Service metadata: name: petclinic spec: ports: - name: http port: 8080 targetPort: 8080 nodePort: 31080 selector: app: petclinic type: NodePort
2. petclinic-svc.yml
apiVersion: v1 kind: Pod metadata: name: mysql labels: app: mysql spec: containers: - name: mysql image: mysql:5.7 env: - name: MYSQL_ROOT_PASSWORD value: petclinic - name: MYSQL_DATABASE value: petclinic --- apiVersion: v1 kind: Service metadata: name: mysql spec: selector: app: mysql ports: - name: tcp port: 3306 targetPort: 3306type: ClusterIP
3. mysql-svc.yml
kubectl get cm #cm是CongigMap的縮寫
kubectl describe cm petclinic-config #cm是CongigMap的縮寫 #查看詳情
因為Petclinic裡面env有需要關連到Mysql。
修改petclinic-config後,還需要重啟Pod,才會把環境變數傳進Pod當中。
下圖為只修改config,但沒重啟Pod的結果,
可以看到版本還是舊的test_config_v1。
當更新環境變數後,建議更改config的name,此例將名字改成v2,並把deployment引用的地方也改成v2,
這樣做可以觸發滾動式發布,
Deplyment和Config接續要再次發佈(apply),
先發佈config,之後再發佈deployment(下圖此例的deployment寫在petclinic-svc.yml當中)。
需要重啟Pod,
建議更新Config的版本名稱,以及deployment引用的版本名稱,
以達到滾動式發佈。
ConfigMap綁定到Volume時,可以達到熱更新,
也就是說不用重啟Pod,並直接把ConfigMap中的配置體現出來,即時進行更新。
Secret只能提供有限安全,因為它用base64可以很容易破解,
沒有留言:
張貼留言
喜歡我的文章嗎? 喜歡的話可以留言回應我喔! ^^