k8s重器之Service

Liusy01發表於2020-12-28

Service是k8s的核心,通過建立Service,可以為一組具有相同功能的容器應用提供一個統一的入口地址,並將請求進行負載分發到各個容器應用上。

目錄:

Service定義詳解

Service基本用法

叢集外部訪問Pod和Service

一、Service定義詳解

Service的定義比Pod簡單。

apiVersion: v1
kind: Service
metadata:
  name: string
  labels:
    name: string
  annotations:
    name: string
spec:
  type: string  
  selector:
    name: string
  clusterIP: string   #虛擬服務ip,預設預設分配
  sessionAffinity: string    #是否支援session,可選值為ClientIP,表示同一個客戶端
  ports:
  - name: string
    protocol: string    #埠協議,支援TCP、UDP,預設是TCP
    port: int  #宿主機埠
    targetPort: int  #目標Pod的埠
    nodePort: int  #k8s內部埠
  status:
    loadBalancer:
      ingress:
        ip: string
        hostname: string

  

上述定義中的spec.type有兩個選項:

當為NodePort時,需要配置nodePort對映到指定埠
當為LoadBalancer,需要在status中設定外部負載均衡器

二、Service基本用法

(1)通過yaml檔案建立:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  selector:
    name: nginx-pod
  ports:
  - name: nginx-service
    port: 80
    targetPort: 80
    nodePort: 30080

  

比如上述,定義了一個Service,對應的是具有key=name,value=nginx-pod這個標籤的Pod,type定義為NodePort,宿主機埠為80,對應Pod埠為80,而nodePort為30080

通過如下命令建立Service

kubectl create -f service-name.yaml

  

建立之後檢視:

k8s重器之Service

 

可看到Service被分配的ip,對應的port以及選擇的標籤資訊

(2)負載均衡

目前k8s提供了兩種負載均衡策略:RoundRobin和SessionAffinity

1、RoundRobin:輪詢模式

2、SessionAffinity:基於客戶端IP地址進行會話保持模式,請求第一次到哪個Pod,則後續還會繼續轉發到那個Pod。

預設情況下,採用輪詢模式,但也可以 通過設定spec.sessionAffinity設定為ClientIP啟用SessionAffinity策略

接下來驗證一下預設的輪詢模式:

建立兩個具有key=name,value=nginx-pod標籤的Pod,容器內執行nginx。

nginx-one:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod1
  labels:
    name: nginx-pod
spec:
  containers:
  - name: nginx-pod1
    image: nginx
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80

  

nginx-two:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod2
  labels:
    name: nginx-pod
spec:
  containers:
  - name: nginx-pod2
    image: nginx
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80

  

建立完兩個容器之後,分別進入兩個容器修改nginx首頁的字樣。

進入容器:

kubectl exec -it  nginx-pod1 /bin/bash

  

找到檔案並進行修改,此處需要注意的是,由nginx映象建立的容器並不具有vim和vi這兩個編輯工具,所以這邊使用sed或echo都行

sed命令替換字串格式是:

sed -i 's/需要被替換字串/替換後字串/g' file-name
sed -i 's/Welcome to nginx!/Welcome to nginx-pod two!/g' /usr/share/nginx/html/index.html

  

修改好後在瀏覽器訪問:使用ip:nodePort訪問

k8s重器之Service

 

k8s重器之Service

 

可以看到,service進行了負載均衡處理。

三、叢集外部訪問Pod和Service

(1)將Pod的埠號對映到宿主機

比如將上述的nginx-pod1對映到主機的20080埠:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod1
  labels:
    name: nginx-pod
spec:
  containers:
  - name: nginx-pod1
    image: nginx
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
      hostPort: 20080

  

然後檢視此Pod在哪個節點上執行

k8s重器之Service

 

然後在瀏覽器中訪問此節點的20080埠:

k8s重器之Service

 

(2)通過設定Pod級別的hostNetwork=true

該Pod的所有容器的埠號都將被直接對映到宿主機上,需要注意的是,如果不指定hostPort,則預設與containerPort一樣,如果指定 ,則hostPort必須等於containerPort。

例如將上述的nginx-pod2設定hostNetwork=true

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod2
  labels:
    name: nginx-pod
spec:
  hostNetwork: true
  containers:
  - name: nginx-pod2
    image: nginx
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80

  

檢視pod建立後在哪個節點上

k8s重器之Service

 

在瀏覽器上訪問:

k8s重器之Service

 

(3)將Service的埠號對映到宿主機上

通過設定spec.type為NodePort,同時設定spec.ports.nodePort設定宿主機上的埠號。

例如在Service基本用法那一小節的Service定義,相應的使用也在那一節有

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  selector:
    name: nginx-pod
  ports:
  - name: nginx-service
    port: 80
    targetPort: 80
    nodePort: 30080

  

===============================

我是Liusy,一個喜歡健身的程式設計師。

歡迎關注微信公眾號【Liusy01】,一起交流Java技術及健身,獲取更多幹貨,領取Java進階乾貨,領取最新大廠面試資料,一起成為Java大神。

來都來了,關注一波再溜唄。

相關文章