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
版權宣告:本文為博主原創文章,轉載請附上博文連結!