1. 程式人生 > >Kubernetes系列之五:使用yaml檔案建立service向外暴露服務

Kubernetes系列之五:使用yaml檔案建立service向外暴露服務

Service和Pod的理論介紹,方便繼續下去

Pod是有生命週期的,使用凡人皆有一死來描述pod很貼切,當一個工作節點(node)銷燬時,節點上執行的pods也會被銷燬, ReplicationController會動態地在其他節點上建立Pod來保持應用程式的執行,每一個Pod都有一個獨立的IP地址,甚至是同一個節點上的Pod,可以看出Pod的IP是動態的,它隨Pod的建立而建立,隨Pod的銷燬而消失,這就引出一個問題:如果由一組Pods組合而成的叢集來提供服務,那如何訪問這些Pods呢?

Kubenetes的Service就是用來解決這個問題的。一個Service可以看作一組提供相同服務的Pods的對外訪問介面,Service作用於哪些Pods是通過label selector來定義的,這些Pods能被Service訪問,Pod之間的發現和路由(如應用中的前端和後端元件)由Kubernetes Service處理。

Service有四種type:
ClusterIP(預設)、NodePort、LoadBalancer、ExternalName. 其中NodePort和LoadBalancer兩型別的Services可以對外提供服務。

使用yaml檔案建立Service(NodePort)

這裡使用yaml檔案來建立NodePort型別的Service,service.yaml檔案內容如下:

---
apiVersion: v1
kind: Service
metadata:
  name: kube-node-service
  labels:
    name: kube-node-service
spec:
  type: NodePort      #這裡代表是NodePort型別的
  ports:
  - port: 80          #這裡的埠和clusterIP(10.97.114.36)對應,即10.97.114.36:80,供內部訪問。
    targetPort: 8081  #埠一定要和container暴露出來的埠對應,nodejs暴露出來的埠是8081,所以這裡也應是8081
    protocol: TCP
    nodePort: 32143   # 所有的節點都會開放此埠,此埠供外部呼叫。
  selector:
    app: web          #這裡選擇器一定要選擇容器的標籤,之前寫name:kube-node是錯的。

執行命令建立一個service,並列出所有的services

[email protected]:/home/cong/Desktop/NodeDemo1# kubectl create -f service.yaml
service/kube-node-service created

[email protected]:/home/cong/Desktop/NodeDemo1# kubectl get services
NAME                TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
kube-node-service   NodePort    10.97.114.36   <none>        80:32143/TCP   7s
kubernetes          ClusterIP   10.96.0.1      <none>        443/TCP        7d

我們來驗證一下建立的service是否正確,執行如下命令

[email protected]:/home/cong/Desktop/NodeDemo1# curl localhost:32143
Hello World! 

# 由於定義的port是80,所以直接訪問clusterIP
[email protected]:/home/cong/Desktop/NodeDemo1# curl 10.97.114.36
Hello World!

可以看到以上這些埠都可以訪問我們的應用程式,在每個節點檢視埠執行netstat -ntlp,發現每個節點都開放出了埠32143,此埠主要是給外部分使用者呼叫的。
嘗試訪問兩個slave節點試試,他們都可以顯示出Hello World!,命令如下:

#在master節點上檢視slave node的ip
[email protected]:/home/cong/Desktop/NodeDemo1# kubectl get nodes -o wide
NAME           STATUS    ROLES     AGE       VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
kube-master    Ready     master    7d        v1.11.1   192.168.29.138   <none>        Ubuntu 16.04.4 LTS   4.13.0-36-generic   docker://17.3.2
kube-slave-1   Ready     <none>    1d        v1.11.1   192.168.29.141   <none>        Ubuntu 16.04.4 LTS   4.13.0-36-generic   docker://17.3.2
kube-slave-3   Ready     <none>    7d        v1.11.1   192.168.29.139   <none>        Ubuntu 16.04.4 LTS   4.15.0-30-generic   docker://17.3.2 

#在master節點上,檢視所有pods 
[email protected]:/home/cong/Desktop/NodeDemo1# kubectl get pods -o wide
NAME                            READY     STATUS    RESTARTS   AGE       IP            NODE
kube-node-64f4f68d4b-sttz2      1/1       Running   0          15m       10.244.1.71   kube-slave-3
kube-node-64f4f68d4b-vwwt2      1/1       Running   0          1d        10.244.1.69   kube-slave-3

#在master節點上,訪問兩個pods,埠都是8081
[email protected]:/home/cong/Desktop/NodeDemo1# curl 10.244.1.71:8081
Hello World!
[email protected]:/home/cong/Desktop/NodeDemo1# curl 10.244.1.69:8081
Hello World! 

#在slave節點kube-slave-1上訪問32143埠
[email protected]:/home/cong# curl 192.168.29.141:32143
Hello World!

#在slave節點kube-slave-3上訪問32143埠
[email protected]:/home/cong# curl 192.168.29.139:32143
Hello World!

至此,我們的service就建立並驗證成功了,此時你可能迷惑在service.yaml中定義的port(80), tartget port(8081), nodePort(32143)這三個埠是什麼關係呢,這裡有點繞,先看下圖:
在這裡插入圖片描述

注意上圖裡面的IP和埠和筆者用的埠不一致,但此圖大致描述了上面三個埠之間的關係。
首先外部使用load balancer訪問我們的兩個slave節點(192.168.29.141:32143) 和 (192.168.29.139:32143),接著它會訪問Service,即ClusterIP(10.97.114.36:80), Service再通過load balancer訪問到某一個pod(埠8081)裡的container(埠8081)。
這裡第二個load balancer是由kube-proxy來負責的,官方的描述是:kube-proxy負責為service提供cluster內部的服務發現和負載均衡。

實際上,我們還另一種建立service的方式,更快更便捷,
即使用expose命令來建立service,如下:

[email protected]:/home/cong# kubectl expose deployment kube-node --type=NodePort
service/kube-node exposed

[email protected]:/home/cong# kubectl get services
NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kube-node           NodePort    10.107.247.158   <none>        8081:31195/TCP   10s
kube-node-service   NodePort    10.97.114.36     <none>        80:32143/TCP     1d
kubernetes          ClusterIP   10.96.0.1        <none>        443/TCP          8d
nginx               NodePort    10.99.22.64      <none>        80:32322/TCP     2d

[email protected]:/home/cong# curl localhost:31195
Hello World!

[email protected]:/home/cong# curl 10.107.247.158:8081
Hello World!

[email protected]:/home/cong# kubectl describe services/kube-node
Name:                     kube-node
Namespace:                default
Labels:                   app=web
Annotations:              <none>
Selector:                 app=web
Type:                     NodePort
IP:                       10.107.247.158
Port:                     <unset>  8081/TCP
TargetPort:               8081/TCP
NodePort:                 <unset>  31195/TCP
Endpoints:                10.244.1.71:8081,10.244.2.81:8081  #這裡podIp+埠號就是endpoint
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

[email protected]:/home/cong# kubectl describe services/kube-node-service
Name:                     kube-node-service
Namespace:                default
Labels:                   name=kube-node-service
Annotations:              <none>
Selector:                 app=web
Type:                     NodePort
IP:                       10.97.114.36
Port:                     <unset>  80/TCP
TargetPort:               8081/TCP
NodePort:                 <unset>  32143/TCP
Endpoints:                10.244.1.71:8081,10.244.2.81:8081 #雖然暴露了兩個service,但endpoint是一樣滴。
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

可以看出,expose命令這裡並沒有指定clusterIP,說明它是K8S系統中的虛擬IP地址,由系統動態分配。Pod的IP地址是由flannel外掛來分配的,而不再由Docker Daemon根據docker0網橋的IP地址進行分配。可以在任意節點上輸入ifconfig可以看到。

使用yaml檔案建立Service(LoadBalancer)

這裡我們繼續expose命令建立loadBalancer型別的service,命令如下:

service "kube-node" deleted
[email protected]:/home/cong# kubectl expose deployment kube-node --type=LoadBalancer
service/kube-node exposed

[email protected]:/home/cong# kubectl get services
NAME                TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kube-node           LoadBalancer   10.99.201.195   <pending>     8081:31585/TCP   10s
kube-node-service   NodePort       10.97.114.36    <none>        80:32143/TCP     1d
kubernetes          ClusterIP      10.96.0.1       <none>        443/TCP          8d
nginx               NodePort       10.99.22.64     <none>        80:32322/TCP     2d

[email protected]:/home/cong# curl localhost:31585
Hello World!

[email protected]:/home/cong# curl 10.99.201.195:8081
Hello World!

[email protected]:/home/cong# kubectl describe services/kube-node
Name:                     kube-node
Namespace:                default
Labels:                   app=web
Annotations:              <none>
Selector:                 app=web
Type:                     LoadBalancer
IP:                       10.99.201.195
Port:                     <unset>  8081/TCP
TargetPort:               8081/TCP
NodePort:                 <unset>  31585/TCP
Endpoints:                10.244.1.71:8081,10.244.2.81:8081
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

當然我們也可以使用yaml檔案來建立,service-lb.yaml檔案如下:

---
apiVersion: v1
kind: Service
metadata:
name: kube-node-service-lb
labels:
  name: kube-node-service-lb
spec:
type: LoadBalancer
clusterIP: 10.99.201.198
ports:
- port: 80
  targetPort: 8081
  protocol: TCP
  nodePort: 32145
selector:
  app: web
status:
loadBalancer:
  ingress:
  - ip: 192.168.174.127    #這裡是雲服務商提供的負載勻衡器的IP地址

執行命令:

[email protected]:/home/cong/Desktop/NodeDemo1# kubectl create -f service-lb.yaml
service/kube-node-service-lb created

[email protected]:/home/cong/Desktop/NodeDemo1# kubectl get services
NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kube-node              LoadBalancer   10.99.201.195   <pending>     8081:31585/TCP   21m
kube-node-service      NodePort       10.97.114.36    <none>        80:32143/TCP     1d
kube-node-service-lb   LoadBalancer   10.99.201.198   <pending>     80:32145/TCP     9s
kubernetes             ClusterIP      10.96.0.1       <none>        443/TCP          8d
nginx                  NodePort       10.99.22.64     <none>        80:32322/TCP     2d

[email protected]:/home/cong/Desktop/NodeDemo1# curl 10.99.201.195:8081
Hello World!

[email protected]:/home/cong# curl localhost:31585
Hello World!

好了,到這裡,你已經掌握了service及yaml的基本用法了,加油

作者:wucong60
來源:CSDN
原文:https://blog.csdn.net/wucong60/article/details/81699196
版權宣告:本文為博主原創文章,轉載請附上博文連結!