1. 程式人生 > >kubernetes Service,Volume,Label

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 的定向 排程功能