原文鏈接:https://blog.csdn.net/bigtree_3721/article/details/78660869
kubernetes中如何發現服務
如何發現pod提供的服務
如何使用kube-dns發現服務
service:服務,是一個虛擬概念,邏輯上代理後端pod。衆所周知,pod生命週期短,狀態不穩定,pod異常後新生成的pod ip會發生變化,之前pod的訪問方式均不可達。通過service對pod做代理,service有固定的ip和port,ip:port組合自動關聯後端pod,即使pod發生改變,kubernetes內部更新這組關聯關係,使得service能夠匹配到新的pod。這樣,通過service提供的固定ip,用戶再也不用關心需要訪問哪個pod,以及pod是否發生改變,大大提高了服務質量。如果pod使用rc創建了多個副本,那麼service就能代理多個相同的pod,通過kube-proxy,實現負載均衡
service 模版
{
"kind": "Service”,
"apiVersion": "v1”,
"metadata”: { "name": "my-service" },
"spec": {
"selector”: { "app": "MyApp" },
"ports": [ { "protocol": "TCP”,
"port": 80,
"targetPort": 9376
}
]
}
}
其中這個service代理了所有具有app:MyApp標籤的pod,服務對外端口是80,服務ip(clusterip)在創建service的時候生成,也可以指定,這組ip:port在service的週期裏保持固定。
訪問ip:port的流量會被重定向到後端pod的9376端口上,就是targetport指定的。
每個節點都有一個組件kube-proxy,實際上是爲service服務的,通過kube-proxy,實現流量從service到pod的轉發,
kube-proxy也可以實現簡單的負載均衡功能。
kube-proxy代理模式:
userspace方式:kube-proxy 在節點上爲每一個服務創建一個臨時端口,service的IP:port 過來的流量轉發到這個臨時端口上,kube-proxy會用內部的負載均衡機制(輪詢),選擇一個後端pod,然後建立iptables,把流量導入這個pod裏面.
還有一種是iptables模式。見文章專門見kube-proxy, https://blog.csdn.net/bigtree_3721/article/details/78771620.
服務發現
服務發現在微服務架構裏,服務之間經常進行通信,服務發現就是解決不同服務之間通信的問題。比如一個nginx的pod,要訪問一個mysql服務,就需要知道mysql服務的ip和port,獲取ip和port的過程就是服務發現。
kubernetes 支持兩種服務發現模式
1.環境變量:
Pod創建的時候,服務的ip和port會以環境變量的形式注入到pod裏,比如pod創建時有一個redis-master服務,服務ip地址是10.0.0.11,port是6379,
則會把下面一系列環境變量注入到pod裏,通過這些環境變量訪問redis-master服務。
REDIS_MASTER_SERVICE_HOST=10.0.0.11
REDIS_MASTER_SERVICE_PORT=6379
REDIS_MASTER_PORT=tcp://10.0.0.11:6379
2.dns:
K8s集羣會內置一個dns服務器,service創建成功後,會在dns服務器裏導入一些記錄,想要訪問某個服務,通過dns服務器解析出對應的ip(注:這裏解析出來的IP是cluster IP)和port,從而實現服務訪問。
service 是微服務架構中的微服務。service 定義了一個服務的訪問入口地址,前端的應用(pod)通過這個入口訪問其背後的一組由pod副本組成的集羣實例,service與其後端pod副本集羣之間是通過label seletor 實現無縫對接的。而rc的功能實際上是保證servic的服務能力和服務質量處於預期的標準
通常我們的系統是由多個提供不同業務能力而又彼此獨立的微服務單元所組成,服務之間通過tcp/ip進行通信,從而形成了強大而又靈活的彈性網絡,擁有了強大的分佈式能力,彈性擴展能力,容錯能力。
nodeip:是k8s集羣中每個節點的物理網卡的ip地址,是真實存在的物理地址,所有屬於這個網絡的服務器之間都能通過這個網絡直接通信,不管它們中是否有部分節點不屬於這個集羣,這也表明集羣之外的節點訪問k8s集羣之內的某個節點或者tcp/ip服務的時候,必須通過nodeip進行通信
podip:是每個pod的ip地址,是docker engine根據docker0網橋的ip地址段進行分配的,是一個虛擬的二層網絡,k8s裏面的一個pod裏面的容器訪問另外一個容器,就是通過podip所在的虛擬二層網絡進行通信的。
每個會被分配一個單獨的ip,每個pod都提供了一個獨立的Endpoint( Pod ip + Container port )以被客戶端訪問
clusterip:全局的唯一的虛擬ip,在整個service的聲明週期內,一旦創建,就不會改變僅僅作用於service對象,由k8s管理和分配ip地址無法被ping,沒有實體網絡對象來響應必須結合service port 組成一個具體的通信端口,單獨的cluster ip不具備tcp/ip通信協議。
在k8s內部,node ip網、pod ip網和cluster ip網之間的通信,採用的是k8s自己設計的一種編程方式的特殊路由規則
外部訪問集羣內部容器服務
外部服務對於一些前端應用,需要暴露服務給外網,而其他應用只能運行在內部。service的types字段可以指定服務類型。默認是clusterip類型,這是集羣內部的服務類型,服務ip(clutserip)是一個內部ip.
外部服務類型:
1.node ip + node port
爲每個節點暴露一個端口,通過nodeip + nodeport可以訪問這個服務,同時服務依然會有cluster類型的ip+port,內部通過clusterip方式訪問,外部通過nodeport方式訪問。
type:NodePort
ports:
Nodeport:31002
然後nodeip + nodeport 進行訪問,NodePort的實現方式是在k8s集羣裏的每個node上爲需要外部訪問的service開啓一個對應的tcp監聽端口,外部系統只要任意一個node的ip地址+nodeport端口即可訪問服務
2.loadbalance
如果k8s集羣運行在第三方雲平臺上,比如openstack,那麼可以通過外部的loadbalance來暴露服務,還能借用第三方的負載均衡機制實現負載均衡。以openstack爲例,藉助neutron的lbaas,訪問服務的流量會被直接轉發到後端的pod,跳過了內置的kube-proxy負載均衡。
3. service (cluster ip) + port
cluster ip屬於k8s集羣內部的地址,無法在外部使用這個地址,若要外部可以進行訪問,需要進行擴展。
service如何進行服務發現
service可以將pod ip封裝起來,即使pod發生重建,依然可以通過service來訪問pod提供的服務,service還解決了負載均衡的問題. 運行在每個node上的kube-proxy進程其實就是一個智能的軟件負載均衡器,它負責把service的請求轉發到後端的某個pod實例。
kube-dns可以解決Service的發現問題:即把服務名解析爲cluster IP。 k8s將Service的名稱當做域名註冊到kube-dns中,通過Service的名稱就可以訪問其提供的服務
http://www.cnblogs.com/leidaxia/p/6485639.html
kube-dns分析:https://blog.csdn.net/ismr_m/article/details/52960205