K8S實踐Ⅳ(Service)

一、Service概念

通過創建service可以爲一組具有相同功能的容器應用提供一個統一的入口地址,並將請求負載分發到後端的各個容器應用上。

二、Service基本用法

1.定義一個web服務的RC,由兩個tomcat容器副本組成

# cat webapp-rc.yaml 
apiVersion: v1
kind: ReplicationController
metadata:
  name: webapp
spec:
  replicas: 2
  template:
    metadata:
      name: webapp
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: tomcat
        ports:
        - containerPort: 8080

2.創建該RC

# kubectl get pod
NAME           READY   STATUS    RESTARTS   AGE
webapp-t5q4g   1/1     Running   0          17m
webapp-wq88m   1/1     Running   0          17m
# kubectl get pods -l app=webapp -o yaml | grep  podIP
    podIP: 10.44.0.2
    podIP: 10.36.0.1

3.使用kubectl expose創建一個SVC

# kubectl expose rc webapp
service/webapp exposed
# kubectl get svc
webapp       ClusterIP   10.111.192.152   <none>        8080/TCP   8s

4.通過svc地址和端口訪問

# curl 10.111.192.152:8080

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Apache Tomcat/8.5.42</title>
......

對svc地址10.111.192.152:8080的訪問被自動負載分發到了後端的兩個Pod之一10.44.0.2:8080或10.36.0.1:8080。
kubernets提供了兩種負載分發策略:RoundRobin和SessionAffinity,默認情況下采用的是RoundRobin模式進行負載。

  • RoundRobin:輪詢模式
  • SessionAffinity:粘性會話,將來自同一個客戶端的請求始終轉發至同一個後端的Pod對象,可以通過設置service.spec.sessionAffinity: ClientIP來啓用

5.使用配置文件方式創建svc

apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  type: ClusterIP
  ports:
  - port: 8081
    targetPort: 8080
  selector:
    app: webapp

ports:與後端容器端口關聯
selector:關聯到哪些pod資源上

# kubectl delete svc webapp
service "webapp" deleted
# kubectl create -f webapp-svc.yaml 
service/webapp created
# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
webapp       ClusterIP   10.96.231.61     <none>        8081/TCP   14s

6.多端口Service創建

apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  ports:
  - port: 8080
    targetPort: 8080
    name: web
  - port: 8005
    targetPort: 8005
    name: management
  selector:
    app: webapp

7.使用UDP端口模式

apiVersion: v1
kind: Service
metadata:
  name: kube-dns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: "KubeDNS"
spec:
  selector:
    k8s-app: kube-dns
  clusterIP: 169.169.0.100
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
    protocol: TCP

8.外部服務Service

在一些環境中,應用系統需要將一個外部數據庫作爲後端服務進行連接,這時可以通過創建一個沒有Selector的svc來實現

kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80

由於這個 Service 沒有 selector,就不會創建相關的 Endpoints 對象。可以手動將 Service 映射到指定的 Endpoints:

kind: Endpoints
apiVersion: v1
metadata:
  name: my-service
subsets:
- addresses:
  - IP: 1.2.3.4
  ports:
  - port: 80

三、Headless Service

有時不需要或不想要負載均衡,以及單獨的 Service IP。 遇到這種情況,可以通過指定 Cluster IP(spec.clusterIP)的值爲 "None" 來創建Headless Service,僅通過Selector將後端的Pod列表返回給調用的客戶端

創建一個Headless Service實例

apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  ports:
  - port: 80
  clusterIP: None
  selector:
    app: nginx
# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
nginx        ClusterIP   None         <none>        80/TCP    26s

四、從集羣外部訪問Pod或Service

1.將容器應用的端口映射到物理機

# cat pod-hostport.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: webapp
  labels:
    app: webapp
spec:
  containers:
  - name: webapp
    image: tomcat
    ports:
    - containerPort: 8080
      hostPort: 8081

此處映射的IP地址爲該Pod所在node的IP

# curl 20.0.20.103:8081

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Apache Tomcat/8.5.42</title>
        <link href="favicon.ico" rel="icon" type="image/x-icon" />
        <link href="favicon.ico" rel="shortcut icon" type="image/x-icon" />

通過設置spce.hostNetwork=true,默認hostPort等於containerPort

apiVersion: v1
kind: Pod
metadata:
  name: webapp
  labels:
    app: webapp
spec:
  hostNetwork: true
  containers:
  - name: webapp
    image: tomcat
    ports:
    - containerPort: 8080

2.將Service的端口映射到物理機

# cat webapp-rc.yaml 
apiVersion: v1
kind: ReplicationController
metadata:
  name: webapp
spec:
  replicas: 2
  template:
    metadata:
      name: webapp
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: tomcat
        ports:
        - containerPort: 8080
# cat webapp-svcnodeport.yaml 
apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: 8080
    nodePort: 30011
  selector:
    app: webapp
# curl 20.0.20.101:30011

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Apache Tomcat/8.5.42</title>
        <link href="favicon.ico" rel="icon" type="image/x-icon" />
        <link href="favicon.ico" rel="shortcut icon" type="image/x-icon" />
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章