2019-09-23
今天距離2020年剛好有一百天,希望在未來的百日里能不負期待
不忘初心,方得始終,
初心易得,始終難守。
一、Service 的概念
Kubernetes Service定義了這樣一種抽象:一個Pod的邏輯分組,一種可以訪問它們的策略 —— 通常稱為微服務。這一組Pod能夠被Service訪問到,通常是通過Label Selector
Service能夠提供負載均衡的能力,但是在使用上有以下限制:只提供 4 層負載均衡能力,而沒有 7 層功能,但有時我們可能需要更多的匹配規則來轉發請求,這點上 4 層負載均衡是不支持的
二、Service 的類型
Service 在 K8s 中有以下四種類型ClusterIp:
① 默認類型,自動分配一個僅 Cluster 內部可以訪問的虛擬 IP
② NodePort:在 ClusterIP 基礎上為 Service 在每台機器上綁定一個端口,這樣就可以通過:NodePort 來訪問該服務
③ LoadBalancer:在 NodePort 的基礎上,借助 cloud provider 創建一個外部負載均衡器,並將請求轉發到: NodePort
④ ExternalName:把集群外部的服務引入到集群內部來,在集群內部直接使用。沒有任何類型代理被創建,這只有 kubernetes 1.7 或更高版本的 kube-dns 才支持
svc基礎導論
總結
客戶端訪問節點時通過iptables實現的,
iptables規則是通過kube-proxy寫入的,
apiserver通過監控kube-proxy去進行對服務和端點的監控,
kube-proxy通過pod的標簽(lables)去判斷這個斷點信息是否寫入到Endpoints里去。
三、VIP 和 Service 代理
在 Kubernetes 集群中,每個 Node 運行一個kube-proxy進程。kube-proxy負責為Service實現了一種VIP(虛擬 IP)的形式,而不是ExternalName的形式。在 Kubernetes v1.0 版本,代理完全在 userspace。在Kubernetes v1.1 版本,新增了 iptables 代理,但並不是默認的運行模式。從 Kubernetes v1.2 起,默認就是iptables 代理。在 Kubernetes v1.8.0-beta.0 中,添加了 ipvs 代理
在 Kubernetes 1.14 版本開始默認使用ipvs 代理
在 Kubernetes v1.0 版本,Service是 “4層”(TCP/UDP over IP)概念。在 Kubernetes v1.1 版本,新增了Ingress API(beta 版),用來表示 “7層”(HTTP)服務
為何不使用 round-robin DNS?
DNS會在很多的客戶端里進行緩存,很多服務在訪問DNS進行域名解析完成、得到地址后不會對DNS的解析進行清除緩存的操作,所以一旦有他的地址信息后,不管訪問幾次還是原來的地址信息,導致負載均衡無效。
四、代理模式的分類
1、userspace 代理模式
2、iptables 代理模式
3、ipvs 代理模式
這種模式,kube-proxy 會監視 Kubernetes Service對象和Endpoints,調用netlink接口以相應地創建ipvs 規則並定期與 Kubernetes Service對象和Endpoints對象同步 ipvs 規則,以確保 ipvs 狀態與期望一致。訪問服務時,流量將被重定向到其中一個后端 Pod
與 iptables 類似,ipvs 於 netfilter 的 hook 功能,但使用哈希表作為底層數據結構並在內核空間中工作。這意味着 ipvs 可以更快地重定向流量,並且在同步代理規則時具有更好的性能。此外,ipvs 為負載均衡算法提供了更多選項,例如:
① rr:輪詢調度
② lc:最小連接數
③ dh:目標哈希
④ sh:源哈希
⑤ sed:最短期望延遲
⑥ nq:不排隊調度
五、ClusterIP
clusterIP 主要在每個 node 節點使用 iptables,將發向 clusterIP 對應端口的數據,轉發到 kube-proxy 中。然后 kube-proxy 自己內部實現有負載均衡的方法,並可以查詢到這個 service 下對應 pod 的地址和端口,進而把數據轉發給對應的 pod 的地址和端口
為了實現圖上的功能,主要需要以下幾個組件的協同工作:
- apiserver 用戶通過kubectl命令向apiserver發送創建service的命令,apiserver接收到請求后將數據存儲到etcd中
- kube-proxy kubernetes的每個節點中都有一個叫做kube-porxy的進程,這個進程負責感知service,pod的變化,並將變化的信息寫入本地的iptables規則中
- iptables 使用NAT等技術將virtualIP的流量轉至endpoint中
創建 myapp-deploy.yaml 文件
[root@master manifests]# vim myapp-deploy.yaml apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 3 selector: matchLabels: app: myapp release: stabel template: metadata: labels: app: myapp release: stabel env: test spec: containers: - name: myapp image: wangyanglinux/myapp:v2 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 |
創建 Service 信息
[root@master manifests]# vim myapp-service.yaml apiVersion: v1 kind: Service metadata: name: myapp namespace: default spec: type: ClusterIP selector: app: myapp release: stabel ports: - name: http port: 80 targetPort: 80 |
六、Headless Service
有時不需要或不想要負載均衡,以及單獨的 Service IP 。遇到這種情況,可以通過指定 ClusterIP(spec.clusterIP) 的值為 “None” 來創建 Headless Service 。這類 Service 並不會分配 Cluster IP, kube-proxy 不會處理它們,而且平台也不會為它們進行負載均衡和路由
[root@k8s-master mainfests]# vim myapp-svc-headless.yaml
apiVersion: v1 kind: Service metadata: name: myapp-headless namespace: default spec: selector: app: myapp clusterIP: "None" ports: - port: 80 targetPort: 80
[root@k8s-master mainfests]# dig -t A myapp-headless.default.svc.cluster.local. @10.96.0.10 |
七、NodePortnodePort
的原理在於在 node 上開了一個端口,將向該端口的流量導入到 kube-proxy,然后由 kube-proxy 進一步到給對應的 pod
類型 命令 描述 基礎命令 create 通過文件名或標准輸入創建資源 expose 將一個資源公開為一個新的Service run 在集群中運行一個特定的鏡像 set 在對象上設置特定的功能 get 顯示一個或多個資源 explain 文檔參考資料。 edit 使用默認的編輯器編輯一個資源。 delete 通過文件名、標准輸入、資源名稱或標簽選擇器來刪除資源。 部署命令 rollout 管理資源的發布 rolling-update 對給定的復制控制器滾動更新 scale 擴容或縮容Pod數量,Deployment、ReplicaSet、RC或Job autoscale 創建一個自動選擇擴容或縮容並設置Pod數量 集群管理命令 certificate 修改證書資源 cluster-info 顯示集群信息 top 顯示資源(CPU/Memory/Storage)使用。需要Heapster運行 cordon 標記節點不可調度 uncordon 標記節點可調度 drain 維護期間排除節點 taint
[root@master manifests]# vim myapp-service.yaml apiVersion: v1 kind: Service metadata: name: myapp namespace: default spec: type: NodePort selector: app: myapp release: stabel ports: - name: http port: 80 targetPort: 80
查看流程 iptables -t nat -nv LKUBE-NODEPORTS |
八、LoadBalancer(了解 )
loadBalancer 和 nodePort 其實是同一種方式。區別在於 loadBalancer 比 nodePort 多了一步,就是可以調用cloud provider 去創建 LB 來向節點導流(LB收費)
九、ExternalName
這種類型的 Service 通過返回 CNAME 和它的值,可以將服務映射到 externalName 字段的內容( 例如:hub.atguigu.com )。ExternalName Service 是 Service 的特例,它沒有 selector,也沒有定義任何的端口和Endpoint。相反的,對於運行在集群外部的服務,它通過返回該外部服務的別名這種方式來提供服務
kind: Service apiVersion: v1 metadata: name: my-service-1 namespace: default spec: type: ExternalName externalName: hub.atguigu.com |
當查詢主機 my-service.defalut.svc.cluster.local ( SVC_NAME.NAMESPACE.svc.cluster.local )時,集群的DNS 服務將返回一個值 my.database.example.com 的 CNAME 記錄。訪問這個服務的工作方式和其他的相同,唯一不同的是重定向發生在 DNS 層,而且不會進行代理或轉發
鏈接:https://www.bilibili.com/video/av66617940/?p=31