2019-09-23node
今天距離2020年恰好有一百天,但願在將來的百日裏能不負期待linux
不忘初心,方得始終,算法
初心易得,始終難守。vim
Kubernetes Service定義了這樣一種抽象:一個Pod的邏輯分組,一種能夠訪問它們的策略 —— 一般稱爲微服務。這一組Pod可以被Service訪問到,一般是經過Label Selector後端
Service可以提供負載均衡的能力,可是在使用上有如下限制:只提供 4 層負載均衡能力,而沒有 7 層功能,但有時咱們可能須要更多的匹配規則來轉發請求,這點上 4 層負載均衡是不支持的api
Service 在 K8s 中有如下四種類型ClusterIp:緩存
① 默認類型,自動分配一個僅 Cluster 內部能夠訪問的虛擬 IP數據結構
② NodePort:在 ClusterIP 基礎上爲 Service 在每臺機器上綁定一個端口,這樣就能夠經過:NodePort 來訪問該服務app
③ LoadBalancer:在 NodePort 的基礎上,藉助 cloud provider 建立一個外部負載均衡器,並將請求轉發到: NodePort負載均衡
④ ExternalName:把集羣外部的服務引入到集羣內部來,在集羣內部直接使用。沒有任何類型代理被建立,這隻有 kubernetes 1.7 或更高版本的 kube-dns 才支持
svc基礎導論
總結
客戶端訪問節點時經過iptables實現的,
iptables規則是經過kube-proxy寫入的,
apiserver經過監控kube-proxy去進行對服務和端點的監控,
kube-proxy經過pod的標籤(lables)去判斷這個斷點信息是否寫入到Endpoints裏去。
在 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)服務
DNS會在不少的客戶端裏進行緩存,不少服務在訪問DNS進行域名解析完成、獲得地址後不會對DNS的解析進行清除緩存的操做,因此一旦有他的地址信息後,無論訪問幾回仍是原來的地址信息,致使負載均衡無效。
這種模式,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 主要在每一個 node 節點使用 iptables,將發向 clusterIP 對應端口的數據,轉發到 kube-proxy 中。而後 kube-proxy 本身內部實現有負載均衡的方法,並能夠查詢到這個 service 下對應 pod 的地址和端口,進而把數據轉發給對應的 pod 的地址和端口
爲了實現圖上的功能,主要須要如下幾個組件的協同工做:
建立 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 |
有時不須要或不想要負載均衡,以及單獨的 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 |
的原理在於在 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 和 nodePort 實際上是同一種方式。區別在於 loadBalancer 比 nodePort 多了一步,就是能夠調用cloud provider 去建立 LB 來向節點導流(LB收費)
這種類型的 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 層,並且不會進行代理或轉發