k8s--Service 環境准備、ClusterIP 使用


環境准備

在使用 service 之前,首先利用 Deployment 創建出 3 個 pod,注意要為 pod 設置 app=nginx-pod 的標簽

創建deployment.yaml,內容如下
apiVersion: apps/v1
kind: Deployment # 類型為 deployment
metadata:
  name: pc-deployment # deployment 的名稱
  namespace: zouzou
spec: 
  replicas: 3 # 三個副本
  selector: # 標簽選擇器
    matchLabels:
      app: nginx-pod
  template:
    metadata:
      labels: # 標簽
        app: nginx-pod
    spec:
      containers:
      - name: nginx
        image: nginx:1.14
        ports: # 暴露容器的 80 端口
        - containerPort: 80

創建 deployment

[root@dce-10-6-215-215 tmp]# kubectl create -f deployment.yaml
deployment.apps/pc-deployment created

查看 pod 的詳情

[root@dce-10-6-215-215 tmp]# kubectl get pod -n zouzou -o wide
NAME                             READY   STATUS    RESTARTS   AGE   IP               NODE               NOMINATED NODE   READINESS GATES
nginx3-c5d7c9466-vnt9c           1/1     Running   0          24h   172.29.34.135    dce-10-6-215-200   <none>           <none>
pc-deployment-5bff7844cb-6n65j   1/1     Running   0          51s   172.29.190.159   dce-10-6-215-190   <none>           <none>
pc-deployment-5bff7844cb-vnvhs   1/1     Running   0          51s   172.29.34.223    dce-10-6-215-200   <none>           <none>
pc-deployment-5bff7844cb-z5ks7   1/1     Running   0          51s   172.29.34.255    dce-10-6-215-200   <none>           <none>

為了方便后面的測試,修改下三台 pod 里 nginx 的 index.html 頁面

# 使用下面命令依次更改,注意要換成自己的 pod 名稱
kubectl exec -it pc-deployment-5bff7844cb-vnvhs -n zouzou /bin/sh
echo "我是 172.29.34.223 的 pod" > /usr/share/nginx/html/index.html

修改完成之后,我們測試一下,看有沒有修改成功

ClusterIP 類型的 Service

默認的 Service 類型就是 ClusterIP,它只能在集群內部訪問

創建 service-clusterip.yaml 文件

apiVersion: v1
kind: Service  # 類型為 Service
metadata:
  name: service-clusterip # Service 的名稱
  namespace: zouzou
spec:
  selector: # 標簽選擇器,會和上面創建的 deployment.yaml 的 pod 關聯起來
    app: nginx-pod
  clusterIP: 172.31.88.88 # service 的 ip 地址,如果不寫,默認會生成一個,注意這個地址不能寫,有個范圍的,我的是 172.31.0.0/16
  type: ClusterIP # 類型為 Service 的 ClusterIP
  ports:
  - port: 8080  # Service 端口,自定義
    targetPort: 80 # pod 端口,不寫默認是 80

注意:上面的 service-clusterip.yaml 只是創建一個 service,因為里面的選擇器為 app:nginx-pod,所以會和 deployment.yaml 里的 pod 關聯起來(因為 deployment.yaml 里的標簽也是 app:nginx-pod)

創建 service

# 創建 service
[root@dce-10-6-215-215 tmp]# kubectl create -f service-clusterip.yaml
service/service-clusterip created

查看 service

# 可以看到 CLUSTER-IP 就是我們設置的 IP 地址,端口是我們寫的 8080,svc 是 service 的簡寫
[root@dce-10-6-215-215 tmp]# kubectl get svc -n zouzou -o wide
NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE    SELECTOR
service-clusterip   ClusterIP   172.31.88.88   <none>        8080/TCP   2m6s   app=nginx-pod

查看 service 的詳細信息,可以看到我們的 Selector 選擇的是pod 的標簽為 app=nginx-pod 的 pod。還有個參數是 Session Affinity(Session 親和度),這里為 None,后面在說

還有一個很重要的是 Endpoints,里面有三個 ip 地址,意思就是這個 service 找到了三個 pod,當訪問 service 的時候,會轉發到這三個里面的其中一個上,其實這三個就是我們上面使用 deployment.yaml 創建的三個 pod

# 查看 service 的詳細信息
[root@dce-10-6-215-215 tmp]# kubectl describe svc service-clusterip -n zouzou
Name:              service-clusterip
Namespace:         zouzou
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx-pod
Type:              ClusterIP
IP:                172.31.88.88
IPFamily:          IPv4
Port:              <unset>  8080/TCP
TargetPort:        80/TCP
Endpoints:         172.29.190.159:80,172.29.34.223:80,172.29.34.255:80  # Endpoints 列表,里面就是當前 service 可以負載到的服務入口 
Session Affinity:  None # session 親和性
Events:            <none>

查看 ipvs 的映射規則

我的有好多,這里找到 service 的 ip 對應的 ip。從下面可以看到,當我們訪問 172.31.88.88:8080 的時候,會采用輪詢的方式訪問下面的三個 ip(也就是我們的 pod),rr 是輪詢的意思

[root@dce-10-6-215-215 tmp]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  127.0.0.1:30001 rr
  -> 172.28.116.206:80            Masq    1      0          0
TCP  172.31.88.88:8080 rr # 主要看這個和下面的三個
  -> 172.29.34.223:80             Masq    1      0          0
  -> 172.29.34.255:80             Masq    1      0          0
  -> 172.29.190.159:80            Masq    1      0          0
TCP  172.31.122.40:80 rr
  -> 172.28.116.205:80            Masq    1      0          0

循環訪問下我們的 service 地址,看下是不是采用輪詢的方式

從下面的結果可以看出來,確實是采用輪詢的方式來訪問了我們的 pod

使用域名進行訪問

Service域名格式:$(service name).$(namespace).svc.cluster.local,其中 cluster.local 為指定的集群的域名

例如上面的就可以寫成

service-clusterip.zouzou.svc.cluster.local

Endpoints

Endpoint 是 kubernetes 中的一個資源對象,存儲在 etcd 中,用來記錄一個 service 對應的所有 pod 的訪問地址,它是根據 service 配置文件中 selector 描述產生的。

一個 Service 由一組 Pod 組成,這些 Pod 通過 Endpoints 暴露出來,Endpoints 是實現實際服務的端點集合。換句話說,service 和 pod 之間的聯系是通過 endpoints 實現的。 

我們可以通過下面的命令查看 Endpoint

# 會返回所有的,因為我這里只有一個 service,所以只有一個
[root@dce-10-6-215-215 tmp]# kubectl get endpoints -n zouzou -o wide
NAME                ENDPOINTS                                             AGE
service-clusterip   172.29.190.159:80,172.29.34.223:80,172.29.34.255:80   20m

負載分發策略

對 Service 的訪問被分發到了后端的 Pod 上去,目前 kubernetes 提供了兩種負載分發策略:

  • 如果不定義,默認使用 kube-proxy 的策略,比如隨機、輪詢

  • 基於客戶端地址的會話保持模式,即來自同一個客戶端發起的所有請求都會轉發到固定的一個 Pod 上

此模式可以使在 spec 中添加 sessionAffinity: ClientIP 選項

修改  service-clusterip.yaml ,加上 sessionAffinity: ClientIP

apiVersion: v1
kind: Service  # 類型為 Service
metadata:
  name: service-clusterip # Service 的名稱
  namespace: zouzou
spec:
  sessionAffinity: ClientIP # 來自同一個客戶端發起的所有請求都會轉發到固定的一個 Pod 上
  selector: # 標簽選擇器,會和上面創建的 deployment.yaml 的 pod 關聯起來
    app: nginx-pod
  clusterIP: 172.31.88.88 # service 的 ip 地址,如果不寫,默認會生成一個
  type: ClusterIP # 類型為 Service 的 ClusterIP
  ports:
  - port: 8080  # Service 端口,自定義
    targetPort: 80 # pod 端口

在 apply 一下

# 也可以刪除 service,在創建
[root@dce-10-6-215-215 tmp]# kubectl apply -f service-clusterip.yaml
service/service-clusterip configured

在來查看下 ipvs 的映射規則,可以看到在我們的 service 后面加了個 persistent,表示持久的,即某一個客戶端發起的請求都會分給一個 pod 上

[root@dce-10-6-215-215 tmp]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  127.0.0.1:30001 rr
  -> 172.28.116.206:80            Masq    1      0          0
TCP  172.31.88.88:8080 rr persistent 10800
  -> 172.29.34.223:80             Masq    1      0          0
  -> 172.29.34.255:80             Masq    1      0          0
  -> 172.29.190.159:80            Masq    1      0          0
TCP  172.31.122.40:80 rr
  -> 172.28.116.205:80            Masq    1      0          0

在循環訪問下 service,看能不能分給一個固定的 pod

[root@dce-10-6-215-215 tmp]# while true;do curl 172.31.88.88:8080; sleep 5; done;
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod
我是 172.29.34.223 的 pod

在用我們的 node 節點訪問

[root@dce-10-6-215-200 ~]# while true;do curl 172.31.88.88:8080; sleep 5; done;
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod
我是 172.29.34.255 的 pod

從上面的結果可以看出,當我們設置了 sessionAffinity: ClientIP 后,當某個客戶端訪問 service 的時候,會將這個客戶端的請求分給一個固定的 pod

刪除 service

通過 yaml 文件刪除

kubectl delete -f service-clusterip.yaml

通過 service 的名稱刪除

kubectl delete svc service-clusterip -n zouzou

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM