一 Service簡介
1.1 Service概念
Service是Kubernetes的核心概念,通過創建Service,可以為一組具有相同功能的容器應用提供一個統一的入口地址,并且將請求負載分發到后端的各個容器應用上,1.2 Service定義詳解
1 apiVersion: v1 #必須,api版本 2 kind: Service #必須,型別為Service 3 metadata: #必須,元資料 4 name: string #必須,Service名稱 5 namespace: string #必須,命名空間,默認為default 6 labels: #自定義標簽屬性串列 7 - name: string 8 annotations: #自定義注解屬性串列 9 - name: string 10 spec: #必須,詳細描述 11 selector: [] #必須,Label Selector配置 12 type: ClusterIP #必須,Serice型別,詳見如下 13 sessionAffinity: string #虛擬服務IP地址,當選擇type=ClusterIP時,若不指定,則系統進行自動分配;當type=LoadBalancer時,需要指定 14 ports: #Service需要暴露的埠串列 15 - name: string #埠名稱 16 protocol: #埠協議,支持TCP和UDP,默認為TCP 17 port: int #服務監聽的埠號 18 targetPort: 8080 #需要轉發到后端Pod的埠號 19 nodePort: int #當spec.type=NodePort時,指定映射到物理機的埠號 20 status: #當spec.type=LoadBalancer時,設定外部負載均衡的地址,用于公有云 21 loadBalancer: #外部負載均衡器 22 ingress: #外部負載均衡器 23 ip: string #外部負載均衡器的IP地址 24 hostname: string #外部負載均衡器的主機名spec.type:Service的型別,指定Service的訪問方式,默認為ClusterIP,
- ClusterIP:虛擬的服務IP地址,該地址用于Kubernetes集群內部的Pod訪問,在Node上kube-proxy通過設定的iptables規則進行轉發;
- NodePort:使用宿主機的埠,使能夠訪問各Node的外部客戶端通過Node的IP地址和埠號就能訪問服務;
- LoadBalancer:使用外接負載均衡器完成到服務的負載分發,需要在spec.status.loadBalancer欄位指定外部負載均衡器的IP地址,并同時定義nodePort和clusterIP,用于公有云,
二 Service基本使用
2.1 Service的基本用法
一般來說,對外提供服務的應用程式需要通過某種機制來實作,對于容器應用最簡便的方式就是通過TCP/IP機制及監聽IP和埠號來實作, 示例:定義一個提供Web服務的RC,由兩個Tomcat容器副本組成,每個容器都通過containerPort設定提供服務的埠號為8080,[root@k8smaster01 study]# cat webapp-rc.yaml
1 apiVersion: v1 2 kind: ReplicationController 3 metadata: 4 name: webapp 5 spec: 6 replicas: 2 7 template: 8 metadata: 9 name: webapp 10 labels: 11 app: webapp 12 spec: 13 containers: 14 - name: webapp 15 image: tomcat 16 ports: 17 - containerPort: 8080[root@k8smaster01 study]# kubectl create -f webapp-rc.yaml [root@k8smaster01 study]# kubectl get pods -l app=webapp -o yaml | grep podIP podIP: 172.24.9.88 podIP: 172.24.9.199 [root@k8smaster01 study]# curl 172.24.9.88:8080

1 apiVersion: v1 2 kind: Service 3 metadata: 4 name: webappservice 5 spec: 6 ports: 7 - port: 8081 8 targetPort: 8080 9 selector: 10 app: webapp[root@k8smaster01 study]# kubectl create -f webappsvc.yaml [root@k8smaster01 study]# kubectl get svc | grep -E 'NAME|webappser' NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE webappservice ClusterIP 10.10.10.83 <none> 8081/TCP 22s 提示:如上Service定義中的關鍵欄位是ports和selector,本例中ports定義部分指定了Service所需的虛擬埠號為8081,由于與Pod容器埠號8080不一樣,所以需要再通過targetPort來指定后端Pod的埠號,selector定義部分設定的是后端Pod所擁有的label:app=webapp, [root@k8smaster01 study]# curl 10.10.10.83:8081 #訪問測驗
- Service負載分發策略:RoundRobin和SessionAffinity
- RoundRobin:輪詢模式,即輪詢將請求轉發到后端的各個Pod上,
- SessionAffinity:基于客戶端IP地址進行會話保持的模式,即第1次將某個客戶端發起的請求轉發到后端的某個Pod上,之后從相同的客戶端發起的請求都將被轉發到后端相同的Pod上,
2.2 多埠Service
有時一個容器應用也可能提供多個埠的服務,那么在Service的定義中也可以相應地設定為將多個埠對應到多個應用服務, 示例1:如下,Service設定了兩個埠號,并且為每個埠號都進行了命名, [root@k8smaster01 study]# vi twoportservice.yaml1 apiVersion: v1 2 kind: Service 3 metadata: 4 name: webapp 5 spec: 6 ports: 7 - port: 8080 8 targetPort: 8080 9 name: web 10 - port: 8005 11 targetPort: 8005 12 name: management 13 selector: 14 app: webapp[root@k8smaster01 study]# vi kubednsservice.yaml
1 apiVersion: v1 2 kind: Service 3 metadata: 4 name: kube-dns 5 namespace: kube-system 6 labels: 7 k8s-app: kube-dns 8 kubernetes.io/cluster-service: "true" 9 kubernetes.io/name: "KubeDNS" 10 spec: 11 selector: 12 k8s-app: kube-dns 13 clusterIP: 169.169.0.100 14 ports: 15 - name: dns 16 port: 53 17 protocol: UDP 18 19 - name: dns-tcp 20 port: 53 21 protocol: TCP
2.3 外部服務Service
在某些環境中,應用系統需要將一個外部資料庫、另一個集群或Namespace中的服務作為服務的后端,則可通過創建一個無Label Selector的Service來實作, [root@k8smaster01 study]# vi noselectorservice.yaml1 apiVersion: v1 2 kind: Service 3 metadata: 4 name: my-service 5 spec: 6 ports: 7 - protocol: TCP 8 port: 80 9 targetPort: 80[root@k8smaster01 study]# kubectl create -f noselectorservice.yaml 如上定義創建的是一個不帶標簽選擇器的Service,即無法選擇后端的Pod,系統不會自動創建Endpoint,因此需要手動創建一個和該Service對應的Endpoint,用于指向實際的后端訪問地址, 如下所示的Endpoint的定義檔案: [root@k8smaster01 study]# vi noselectorendpoint.yaml
1 apiVersion: v1 2 kind: Endpoints 3 metadata: 4 name: my-service 5 subsets: 6 - addresses: 7 - IP: 47.96.145.131 8 ports: 9 - port: 80[root@k8smaster01 study]# kubectl create -f noselectorendpoint.yaml [root@k8smaster01 study]# kubectl get svc | grep -E 'NAME|my-service' NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-service ClusterIP 10.10.10.211 <none> 80/TCP 3s [root@k8smaster01 study]# curl 10.10.10.211
提示:如上所示,訪問沒有標簽選擇器的Service和帶有標簽選擇器的Service一樣,請求將會被路由到由用戶手動定義的后端Endpoint上,
三 Headless Service
3.1 無頭服務簡介
在某些應用場景中,若需要人為指定負載均衡器,不使用Service提供的默認負載均衡的功能,或者應用程式希望知道屬于同組服務的其他實體,Kubernetes提供了Headless Service來實作這種功能,即不為Service設定ClusterIP(入口IP地址),僅通過Label Selector將后端的Pod串列回傳給呼叫的客戶端, 此場景中,Service就不再具有一個特定的ClusterIP地址,對其進行訪問將獲得包含Label“app=nginx”的全部Pod串列,然后客戶端程式自行決定如何處理這個Pod串列, 例如,StatefulSet就是使用Headless Service為客戶端回傳多個服務地址的, 對于“去中心化”類的應用集群,Headless Service非常適合,3.2 Nginx場景實驗
通過對Headless Service搭建Nginx集群,從而自動實作應用集群的創建, [root@k8smaster01 study]# vi nginx-service.yaml #創建Service1 apiVersion: v1 2 kind: Service 3 metadata: 4 labels: 5 name: nginx-svc 6 name: nginx-svc 7 spec: 8 ports: 9 - protocol: TCP 10 port: 80 11 targetPort: 80 12 selector: 13 name: nginx-demo #定義selector 14 clusterIP: None[root@k8smaster01 study]# kubectl create -f nginx-service.yaml [root@k8smaster01 study]# vi nginx-deployment.yaml
1 apiVersion: apps/v1 2 kind: Deployment 3 metadata: 4 labels: 5 name: nginx-demo 6 name: nginx-demo 7 spec: 8 replicas: 2 9 selector: 10 matchLabels: 11 name: nginx-demo 12 template: 13 metadata: 14 labels: 15 name: nginx-demo 16 spec: 17 containers: 18 - name: nginx 19 image: nginx:1.7.9 20 ports: 21 - containerPort: 80 22 name: web[root@k8smaster01 study]# kubectl create -f nginx-deployment.yaml [root@k8smaster01 study]# kubectl create -f nginx-service.yaml [root@k8smaster01 study]# kubectl get svc -o wide [root@k8smaster01 study]# kubectl get pods -o wide [root@k8smaster01 study]# nslookup nginx-svc.default.svc.cluster.local 10.10.190.170
提示:由上可知,通過決議SVC的地址,直接決議出來的為Pod的IP,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/237474.html
標籤:其他
上一篇:像黑客一樣用命令打開應用!
