kubernetes Service,Volume,Label
Service:
在kubernetes中,需要每個pod都有ip地址,但是其ip會隨著 pod的啟停而改變,但我們怎麼才能穩定的訪問其pod提供的服務呢,kubernetes
設計了Service,其目的是為了讓使用者能夠通過訪問Service 來 穩定訪問 pod
一個Service作用了哪些pod是通過Label Selector來定義的
在pod正常啟動後,系統將會根據Service的定義創建出與pod對應的Endpoint(端點)物件,以建立起Service與後端Pod的對應關係,隨著pod的建立,銷燬,
Endpoint物件也將被更新。Endpoint物件主要由Pod的IP 地址和容器需要監聽的埠號組成,通過 kebectl get endpoints命令可以檢視,顯示為IP:Port 的格式
在kubernetes中,Service是分散式叢集架構的核心,一個Service物件擁有如下關鍵特徵
1 擁有一個唯一指定的名字
2 擁有一個虛擬IP(cluster ip,service ip 和 vip) 和 埠號
3 能夠提供某種遠端服務能力
4 被對映到了提供這種服務能力的一組容器應用上
Service的服務程序目前都基於socket通訊方式對外提供服務,比如redis,memcache,mysql, web server,或者是實現了某個具體業務的一個特定的tcp server 程序。通常一個服務,可能會依賴很多服務,但kubernetes能夠讓我們通過service 連線 指定的service上。
kubernetes有很好的故障恢復機制,當服務以外停止時,kubernetes 會重啟他們
kubernetes通過kube-proxy程序可以簡單實現服務間的 服務均衡
這些操作都是kubernetes自動化完成,對於使用者來說都是透明的
kind: Service
apiVersion: v1
metadata:
name: jxc-service
spec:
selector:
app: jxc-web
ports:
- protocol: TCP
port: 80
targetPort: 8080
建立Service
[[email protected] kubefile]# kubectl create -f jxc-service-1.yaml
檢視 Service
[[email protected] kubefile]# kubectl get service
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
jxc-service 10.254.35.198 <none> 80/TCP 12s
kubernetes 10.254.0.1 <none> 443/TCP 10d
檢視Service 的 yaml 定義檔案
[[email protected] kubefile]# kubectl get svc jxc-service -o yaml
上述配置將建立一個名詞為 "jxc-service"的Service物件,它會將請求代理到 使用TCP埠8080 並且
使用具有標籤"app=jxc-web"的pod上。這個Service將指派一個IP地址(通常為"cluster ip")。Service 能夠將一個
接收埠對映到任意的targetPort。預設情況下,targetPort將被設定與port欄位相同的值。kubernetes Service
能夠支援TCP 和 UDP協議,預設是TCP協議
2 外部訪問 Service
[[email protected] kubefile]# vim jxc-service.yaml
apiVersion: v1
kind: Service
metadata:
name: jxc
labels:
name: jxc
spec:
type: NodePort
ports:
- port: 80
nodePort: 30001
selector:
name: jxc
上述 演示的 是一個 外部 訪問Service
如果 這個Service 作為前端服務,我們就需要 讓該 Service 能 讓 外網訪問到
我們可以通過 NodePort 為 該Service 開啟一個 主機上的真實埠號
3 沒有 selector 的 Service
Service 抽象瞭如何訪問kubernetes pod,但也能夠 抽象其它 型別的backend
例如:
1 希望 在生產環境中使用外部的資料庫叢集
2 希望服務指向 另一個Namespace 中或其他叢集中的服務
3 正在將工作負載同時轉移到kubernetes叢集和執行在kubernetes 叢集之外的backend
3 多埠 Service
kind: Service
apiVersion: v1
metadata:
name: jxc-service
spec:
selector:
app: jxc-web
ports:
- name: http
protocol: TCP
port: 80
targetPort: 9376
- name: https
protocol: TCP
port: 443
targetPort: 9337
很多Service 需要暴露 多個埠。對於這種情況,kubernetes 支援 在Service 物件中 定義 多個埠。當使用多個埠時,必須給出所有 的埠名稱
,這樣 endpoint 就不會產生歧義
Volume(儲存卷)
volume 是pod中能夠被多個容器訪問的共享目錄。kubernetes的volume概念與docker的volume比較類似,但並不完全相同。kubernetes中的
volume 與pod生命週期相同,但與容器的生命週期不相關。當容器終止或者重啟時,volume的資料也不會丟失。
預設情況下容器中的磁碟檔案是非持久化的,對於執行在容器中的應用來說 面臨兩個問題,
第一: 當容器掛掉 kubectl 將重新啟動它時,檔案將會丟失;
第二: 當pod中同時執行多個容器,容器之間需要共享檔案時。
kubernetes 的 volume 解決了這兩個問題。
kubernetes volume 具有 明確的生命週期。與pod相同。因此。volume 的生命週期比pod中執行的任何容器要 持久化,在容器重新啟動時能可以保留資料,當然,當pod被刪除時,volume 也隨著 消失
(1) hostPath 型別
hostPath 允許掛載 Node上的檔案系統到 pod裡面去。如果pod需要使用Node上的檔案,可以使用 hostPath.
通常有以下兩種 使用場景:
a 容器應用程式生成的日誌檔案需要永久儲存時,可以使用 宿主機的檔案系統進行儲存
b 需要訪問宿主機上docker 引擎內部資料結構的容器應用時,可以通過定義hostPath 為宿主機 /var/lib/docker目錄,使容器內部應用
可以直接訪問docker的檔案系統
使用 hostPath 的注意事項:
a 在不同的Node上具有相同配置的pod,可能會因為 宿主機上的目錄 和檔案 不同而 導致對volume 上目錄和檔案的訪問 結果不一致
b 如果使用了資源配額管理,則 k8s 無法將hostPath在宿主機上 使用的資源納入管理
使用案例
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: jxc-deployment
labels:
web: jxc
spec:
replicas: 1
selector:
matchLabels:
web: jxc
template:
metadata:
labels:
web: jxc
spec:
containers:
- name: jxc
image: 192.168.255.128:5000/jxc:0.0.3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /data
將 , 宿主機的 /data 被掛載到容器的 /test-pd
(2) NFS
kubernetes 中通過簡單地配置 就可以掛載到NFS到Pod中,而NFS中的資料時可以永久儲存的,同時NFS支援同時寫操作。
pod被刪除時,volume 被解除安裝,內容被保留。這就意味這NFS能夠允許我們提前對資料進行處理,而且這些資料可以在pod
之間相互傳遞
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: jxc-deployment
labels:
web: jxc
spec:
replicas: 1
selector:
matchLabels:
web: jxc
template:
metadata:
labels:
web: jxc
spec:
containers:
- name: jxc
image: 192.168.255.128:5000/jxc:0.0.3
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
volumeMounts:
- name: nfs
mountPath: "/usr/share/"
volumes:
- name: nfs
nfs:
server: nfs-server.localhost #nfs 伺服器地址
path: "/"
Label (標籤), Label Selector(選擇器)
Label 是 kubernetes 系統中的一個核心概念。Label 以 key/value 鍵值對的形式附加到各種物件上。如pod,Service,RC,Node等。Label定義了這些物件的
可識別屬性,用來對他們進行管理和選擇。Label可以在建立物件時附加在物件上,也可以在物件建立後通過API進行管理
在為物件定義好Label後,其他物件就可以使用 Label Selector (選擇器) 來定義其作用的物件了
Label Selector 的定義 由多個逗號分隔的條件組成
"labels" : {
"key1" : "value1",
"key2" : "value2"
}
一般來說,我們會 給 一個 Pod 定義多個Labels,以便於配置,部署等管理工作。
"environment" : "dev","environment" : "qa","environment" : "production"
"tier" : "frontend","tier" : "backend","tier" : "cache"
當前有兩種Label Selector :
基於等式的(equality-based) 和 基於 集合的 (Set-based)
基於等式 的 示例:
name = redis-slave
env != production
基於集合的 示例 :
name in (redis-master,redis-salve)
name not in (frontend)
Label Selector 的幾個重要使用場景:
- kube-controller程序,通過資源物件RC上定義的Label Selector 來篩選 和 管理 的 Pod 副本的數量
- kebe-proxy 程序,通過Service 的 Label Selector 來選擇對應的Pod,建立起每個 Service 到對應Pod的
請求轉發路由表,進而實現Service 的智慧負載均衡機制
- kube-scheduler 程序,通過為某些Node定義特定的Label,然後在Pod 定義檔案中使用NodeSelector 進行篩選,
進而實現Pod 的定向 排程功能