Kubernetes Service之ClusterIP
Kubernetes的service有三種型別:ClusterIP,NodePort,LoadBalancer,今天我們來看看ClusterIP。
首先我們先建立一個Deployment,這個Deployment是一個Python實現的HTTP服務,請求這個Web Server的時候,會發回給我們這個server的hostname(如果是container,那就是container的hostname)。
這個Deployment有四個Replica。
$ more deployment_python_http.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: service-test
spec:
replicas: 4
selector:
matchLabels:
app: service_test_pod
template:
metadata:
labels:
app: service_test_pod
spec:
containers:
- name: simple-http
image: python:2.7
imagePullPolicy: IfNotPresent
command: ["/bin/bash"]
args: ["-c", "echo "Hello from $(hostname)
" > index.html; python -m SimpleHTTPServer 8080"]
ports:
- name: http
containerPort: 8080
$ kubectl create -f deployment_python_http.yml
deployment.apps "service-test" created
建立完我們看到pod是這樣的;
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
service-test-54b5b4b547-8l9s4 1/1 Running 0 1m 10.36.0.0 ks8-node2
service-test-54b5b4b547-c2t85 1/1 Running 0 1m 10.36.0.1 ks8-node2
service-test-54b5b4b547-nxn9z 1/1 Running 0 1m 10.40.0.1 k8s-node1
service-test-54b5b4b547-vlpff 1/1 Running 0 1m 10.40.0.0 k8s-node1
這四個pod IP我們都可以在k8s cluster任意一個節點上訪問,每一個都會返回自己的container name。
$ curl 10.36.0.0:8080
Hello from service-test-54b5b4b547-8l9s4
透過kubectl expose給剛才這個deployment建立一個service,埠繫結為8088.
kubectl expose deployment service-test --port 8088 --target-port=8080
service "service-test" exposed
這樣,就給我們生成了一個型別為ClusterIP的service,這個service有一個Cluster IP,其實就一個VIP。
kubectl get service -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 443/TCP 1d
service-test ClusterIP 10.101.90.210 8088/TCP 11s app=service_test_pod
首先我們可以透過這個Cluster IP加埠8088訪問我們的deployment。
$ for i in `seq 4`; do curl 10.101.90.210:8088; done
Hello from service-test-54b5b4b547-nxn9z
Hello from service-test-54b5b4b547-vlpff
Hello from service-test-54b5b4b547-vlpff
Hello from service-test-54b5b4b547-nxn9z
並且我們發現,這個VIP實現了負載均衡,每次返回的hostname不同。
為什麼我們訪問VIP就能訪問我們的四個pod,並且還做了負載均衡呢?下面我們就看一下,
其實呢,我們剛才建立這個deployment,service的時候,k8s叢集下面的幾個部件參與了相關的工作。
- apiserver kubectl命令向apiserver傳送建立service的命令,apiserver接收到請求以後將資料儲存到etcd中。
- kube-proxy kubernetes的每個節點中都有一個叫做kube-proxy的程式,這個程式負責感知service,pod的變化,並將變化的資訊寫入本地的iptables中。
- iptables 使用NAT等技術將virtualIP的流量轉至endpoint中。
那麼IPtable到底是如何轉發我們的流量的呢,我們到任意一臺k8s節點執行 sudo iptables -L -v -n -t nat
首先找到我們的ClusterIP 10.101.90.210,發現他在一個iptables chain中
Chain KUBE-SERVICES (2 references)
pkts bytes target prot opt in out source destination
0 0 KUBE-MARK-MASQ tcp -- * * !172.100.0.0/16 10.101.90.210 /* default/service-test: cluster IP */ tcp dpt:8088
0 0 KUBE-SVC-LY73ZDGF4KGO4YFJ tcp -- * * 0.0.0.0/0 10.101.90.210 /* default/service-test: cluster IP */ tcp dpt:8088
這個chain類似一個鏈條,那麼訪問10.101.90.210:8088的流量到底怎麼被轉發了呢,我們需要看一下 KUBE-SVC-LY73ZDGF4KGO4YFJ
這個Chain, 找到這個chain
Chain KUBE-SVC-LY73ZDGF4KGO4YFJ (1 references)
pkts bytes target prot opt in out source destination
0 0 KUBE-SEP-YOQWVZZ4NQDNEBVN all -- * * 0.0.0.0/0 0.0.0.0/0 /* default/service-test: */ statistic mode random probability 0.25000000000
0 0 KUBE-SEP-WHOFXZ2VQXEUUKVO all -- * * 0.0.0.0/0 0.0.0.0/0 /* default/service-test: */ statistic mode random probability 0.33332999982
0 0 KUBE-SEP-3TBKTCTGJZ27RFOH all -- * * 0.0.0.0/0 0.0.0.0/0 /* default/service-test: */ statistic mode random probability 0.50000000000
0 0 KUBE-SEP-6LDVTIHDBDOU3D3G all -- * * 0.0.0.0/0 0.0.0.0/0 /* default/service-test: */
這個Chain比較有意思,過來的流量它按照隨機的機率,分別以0.25000000000, 0.33332999982,0.50000000000的機率,轉發到這三個Chain,這三個Chain其實就是我們的pod,那為啥有一個pod不會被轉發呢,這個應該是負載均衡的配置,最大幾個負載均衡的問題。
我們隨便拿出一個
Chain KUBE-SEP-WHOFXZ2VQXEUUKVO (1 references)
pkts bytes target prot opt in out source destination
0 0 KUBE-MARK-MASQ all -- * * 10.36.0.1 0.0.0.0/0 /* default/service-test: */
0 0 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 /* default/service-test: */ tcp to:10.36.0.1:8080
好的,那經過這麼一轉發,我們的流量就可以轉發到正確的pod上了,不知道大家明白沒有。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/756/viewspace-2810084/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 聊聊如何讓辦公網路直連Kubernetes叢集PodIP/ClusterIP/Service DNS等DNS
- kubernetes實踐之十四:Service Account與Secret
- kubernetes實踐之六十五:Service Mesh
- kubernetes實踐之四十三: Service詳解
- Kubernetes實驗 Service
- kubernetes實踐之五十三:Service中的故障排查
- Azure Kubernetes Service 入門
- Kubernetes中Service機制
- Kubernetes中Service的使用
- kubernetes實踐之四十八:Service Controller與Endpoint ControllerController
- kubernetes實踐之七:安全機制API Server認證之Service Account TokenAPIServer
- kubernetes實踐之七十四:Service Mesh Meetup深圳站學習總結
- 【解構雲原生】初識Kubernetes Service
- kubernetes實踐之二十四:Service
- Kubernetes 實戰——發現應用(Service)
- 如何在Kubernetes裡建立一個Nginx serviceNginx
- 淺入Kubernetes(11):瞭解 Service 和 Endpoint
- 阿里雲Kubernetes容器服務Istio實踐之整合日誌服務Log Service阿里
- Kubernetes的資源控制器和Service(四)
- 在 Google Kubernetes Cluster 上使用 HANA Expression Database ServiceGoExpressDatabase
- k8s之Service詳解-Service使用K8S
- Android 之Service使用攻略Android
- 如何利用 knest 構建資料中心的 Kubernetes as a Service?
- kubernetes之PDB
- Kubernetes-6.服務、負載均衡、聯網(2)Service負載
- 淺入Kubernetes(7):應用部署例項,Deployment、Service、ReplicaSet
- Service Mesh之Istio部署bookinfo
- kubernetes物件之Ingress物件
- kubernetes物件之Volume物件
- kubernetes物件之Job物件
- kubernetes物件之deployment物件
- kubernetes實踐之六十:Cabin-Manage Kubernetes
- Kubernetes監控之InfluxDBUX
- Kubernetes之Pod排程
- kubernetes之pod中斷
- Kubernetes之curl除錯除錯
- 基於Kubernetes服務發現機制的探討Non Service
- Android 四大元件之 ServiceAndroid元件