kube-proxy和service
kube-proxy 是k8s中的組件之一,是以Pod 形式真實運行的進程,而service 是它的代理功能的具體實現,service 是k8s 中一種資源類型,里面定義的是集群Pod 的訪問轉發規則。
存在的意義
service 作用
服務發現(防止pod 失聯)
負載均衡(輪詢轉發請求到后端集群中的pod)
service與Pod 關聯
兩種方式
1、service 通過標簽選擇器selector 關聯pod 的標簽,找到pod 。
2、service 通過關聯deployment 等資源,通過deployment 等資源間接關聯pod。注意寫yaml文件創建service 關聯deployment 通過標簽選擇器配置成 selector: app: pay 形式關聯的是pod 的標簽不是 deployment 的標簽,可以通過expose命令關聯dep資源創建service。
service 的三種形式
ClusterIP
集群IP,僅供k8s內部訪問(只能在pod 或node 上訪問,無法外部訪問),相當於service 加了1個vip,通過vip 提供訪問地址,再轉發給各個Pod
NodePort
在每個node 節點為相應Pod啟動一個對外端口(默認30000起步),映射pod 內部端口。通過任意一個Pod 所在的節點ip+port 就能訪問pod ,多個pod 需要在service 前面加一個LB(lvs/proxy)把每個節點的ip+port 加入,才能實現負載均衡,這樣每個服務都得添加一次,增加了管理維護成本。
Loadblance
雲服務廠商提供的,自動添加service 映射對外端口到負載上面,例如阿里雲可以通過SLB為service 提供負載均衡。只有雲服務廠商的k8s 才有此形式。
相關操作
service 的創建
方式一 expose

kubectl expose --help kubectl expose deployment nginx-dep1 --port=2022 --target-port=80 --type=NodePort -n kzf service代理資源類型 資源名稱 代理對外端口 pod 中內部端口 端口暴露類型(默認ClusterIp) 命名空間
方式二 創建yaml

apiVersion: v1 kind: Service metadata: name: service-kzf1 namespace: asdf spec: clusterIP: NodePort #不寫默認類型為Clusterip ports: - port: 2021 #clusterip 集群端口 targetPort: 80 #pod 內部端口 selector: app: nginx-label #通過標簽選擇pod
service 查看

kubectl get svc -n kzf NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-dep1 NodePort xxx.xx.x.x <none> 2022:31992/TCP 27m service-kzf NodePort xxx.xx.x.x <none> 2020:32341/TCP 2d1h service-kzf1 ClusterIP xxx.xx.x.x <none> 2021/TCP 52m nginx-ingress LoadBalancer xxx.xx.x.x xx.xx.xxx.xx 80:3xxxx/TCP,443:xxxx6/TCP 29d 注解: type 分為三種類型NodePort/ClusterIP/LoadBalancer CLUSTER-IP 無論哪種類型都有clusterip 因為Node port 和loadbalancer 都是在它的基礎上拓展的 EXTERNAL-IP 只有LoadBalancer 有,這是個負載均衡器的對外IP Port service 集群CLUSTER-IP IP 的端口:nodeport 類型節點上的端口 age 創建時間多久
服務發現
當service 創建完成后pod 客戶端怎么發現它的連接地址和端口呢,有以下方式
通過環境變量發現服務
kubectl exec kubia-2isdly env
通過DNS發現服務
在kube-system 命名空間有個dns 的pod 負載dns服務。在集群中的其他 pod 都被配置成使用其作為 dns ( Kubemetes 通過修改每 容器的/ etc/reso conf 實現)。
Tip:
service 集群 IP個虛擬 IP ,ping 的時候無法ping通,只有在與服務端口結合時才有意義。
連接集群外部的服務
介紹服務 endpoint
手動配置服務的 endpoint

apiVersion: vl kind: Service metadata: name: external-service spec: ports: - port:80
為沒有選擇器的service創建endpoints。Endpoint是一個單獨的資源並不是service的一個屬性。由於創建的資源中並不包含選擇器,相關的Endpoints資源並沒有自動創建,所以必須手動創建。如下所示

apiVersion: vl kind: Endpoints metadata: name: external-service # Endpoint的名稱必須和服務的名稱相匹配 subsets: - addresses: - ip: 11.11.11.11 - ip: 22.22.22.22 ports: - port: 80
為外部服務創建別名

apiVersion: vl kind: Service metadata: name: external-service spec: type: ExternalName externalName: someapi.asdf.com ports: - port: 80
將服務暴漏給內部客戶端
ClusterIp 類型即可,Clusterip 就是一個虛擬vip ,代理后端的一組pod,只能在集群內部訪問(pod 里面訪問/集群節點訪問)
將服務暴露給外部客戶端
方式一:NodePort

$ kubectl get svc kubia-nodeport NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubia-nodeport 10.111.254.223 <nodes> 80:30123/TCP 2m EXTERNAL-IP列。 它顯示nodes 表明服務可通過任何集群節點的IP地址訪問。 PORT(S)列顯示集群IP (8 0) 的內部端口和節點端口(30123), 可 以通過以下地址訪問該服務: • 10.11.254.223:80 • <ls七node'sIP>:30123 • <2ndnode'sIP>:30123, 等等
方式二:LoadBalance

kubect1 get svc kubia-loadbalancer NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubia-loadbalancer 10.111.241.153 130.211.53.173 80:32143/TCP lm 在這種情況下, 負載均衡器的IP地址為130.211.53.173, 因此現在可以通過該 IP 地址訪問該服務: $ curl h七七p://130.211.53.173
訪問流程圖
方式三:Ingress
使用 headless服務來發現獨立的pod
創建headless服務
apiVersion: vl kind: Service metadata: name: kubia-headless spec: clusterIP: None #這使得服務成為headless
ports: - port: 80 targetPort: 8080 selector: app: kubia
service 與就緒探針
service 負載功能實現原理
service 負載均衡實現主要有兩種方式
iptables(早期)
iptables 是一個工具它通過linux 的netfilter 來進行ip 包的過濾處理。主要通過維護一張規則表,從上到下匹配表中規則,每次變動都不是增量而是全表變動。隨着表的增大效率降低。
ipvs(k8s version:1.11以后)
ipvs實際上就是lvs 的原理。采用它的輪詢策略(w,rr/wrr.lc,wlc),內核級別的,效率高。