在談kubernetes的service以前,小編向帶你們複習一下負載均衡的概念,那麼何爲負載均衡呢,小編舉一個簡單的例子,能力相同的兩我的同時進入一家公司,一我的每天加班到深夜,另外一我的則每天優哉遊哉到點下班,但兩我的的工資同樣,此時那個埋頭苦幹的人就會抱怨了,憑什麼我每天累死累活,這不公平!相對於機器而言也是同樣的,一臺機器一直幹活,另外一臺機器一直空閒,總有一臺幹活的機器會罷工的!那麼如何解決這個問題呢?小編這裏舉一個web集羣的例子:
客戶端訪問一個虛擬的IP,經過這個虛擬的IP將請求發送給nginx的負載(主),此時主負載將接受的請求拋給後端的web服務作真正的處理,這裏的負載能夠是輪詢也能夠是根據集羣的資源,指定發送到某臺web服務器上。那有些讀者就想問了,如何設置這個虛擬的IP,又怎麼知道負載何時會宕機,負載又如何發現後端的web服務器的,如何獲取集羣資源,精確計算出哪一臺web服務比較空閒等等,這一些列的問題,不要着急,小編接下來根據kubernetes的service將這其中的原理一一道來。
但願一篇文章就能寫完,此時毫不說廢話了,拜託拜託。html
service是kubernetes最核心的概念,經過建立service,能夠爲一組具備相同功能的容器應用提供一個統一的入口地址,而且將請求負載發送到後端的各個容器應用上。node
apiVersion: v1 kind: Service metadata: #元數據 name: string #service的名稱 namespace: string #service所屬的命名空間 labels: #service的標籤 - name: string annotations: #service的註解 - name: string spec: selector: [] #label選擇器,將選擇具備指定label標籤的pod做爲管理範圍 type: string #Service的類型 [clusterIP|NodePort|LoadBalancer] clusterIP: string #虛擬服務IP地址 sessionAffinity: string #是否支持session [ClientIP|None] 表示將同一個客戶端的訪問請求都轉發到同一個後端 ports: #service須要暴露的端口 - name: string #端口名稱,區分不一樣的應用的端口 protocol: string #使用的協議 prot: int #service監聽的端口 targetPort: int #發送到後端的應用的端口 nodePort: int #當spec.type=NodePort時,指定映射到物理機的端口 status: #當spec.type=LoadBalancer時,設置外部負載均衡器的地址 loadBalancer: ingress: ip: string #外部負載的IP hostname: string #外部負載均衡的主機名
這小編以三個案例介紹:nginx
#webapp-rc.yamlgit
apiVersion: v1 kind: ReplicationController metadata: name: webapp spec: replicas: 2 template: metadata: name: webapp labels: app: webapp spec: containers: - name: webapp image: docker.io/tomcat imagePullPolicy: IfNotPresent ports: - containerPort: 8080
[root@zy yaml_file]# kubectl create -f webapp-rc.yaml #建立
github
[root@zy yaml_file]# kubectl get pods -l app=webapp -o yaml|grep podIP #查看pod的IP
[root@zy yaml_file]# curl 172.17.0.5:8080 #訪問
web
#建立service管理pod [root@zy yaml_file]# kubectl expose rc webapp
或者 yaml文件
#webapp-svc.yamldocker
apiVersion: v1 kind: Service metadata: name: webapp spec: ports: - port: 8081 targetPort: 8080 selector: app: webapp
[root@zy yaml_file]# kubectl get svc #查看建立的service的IP
[root@zy yaml_file]# curl 10.254.90.131:8081 #經過serviceIP訪問pod中的應用
② 多端口service
有時候一個容器應用也可能提供多個端口的服務,那麼在service的定義中也能夠相應地設置爲將多個端口對應到多個應用中,有點相似於Apache的虛擬主機中的基於端口配置。數據庫
apiVersion: v1 kind: Service metadata: name: webapp spec: ports: - port: 8081 targetPort: 8080 name: web - port: 8005 targetPort: 8005 name: management selector: app: webapp
③ 外部服務service
在某些環境中,應用系統須要將一個外部數據庫做爲後端服務進行鏈接,或將另外一個集羣或者namespace中的服務做爲服務的後端,這時能夠經過建立一個無label selector的service來實現:vim
apiVersion: v1 kind: Service metadata: name: my-service spec: ports: - protocol: TCP port: 33060 targetPort: 3306
由於定義一個沒有selector的service,系統不會自動建立endpoint,須要手動定義,建立一個與service同名的endpoint,用於指向實際後端訪問地址。
#endpoint後端
kind: EndPoints apiVersion: v1 metadata: name: my-service #與service相同 subsets: - addresses: - IP: xxx.xxx.xxx.xxx ports: - port: 3306
此時:
這個service綁定的EndPoint就會鏈接外部的172.0.1.16:3306的服務,內部訪問這個service時,路由就會轉發到cluster B 的相應的服務中。
經過上面的三個案例是否是對service有了初步的瞭解呢,小編在這裏給你們總結一下,service的好處:
因爲pod被RC或者deploy管理,pod重啓以後,pod的IP地址是改變的,若是使用podIP去訪問後端的應用,每次都要查IP,可是有了service,service的虛擬IP是固定的,咱們只要訪問service的IP,至於service如何發現後端的重啓的Pod,咱們不須要關係
Service的負載做用,若是一個service管理多個pod,而這多個pod提供的是相同的服務,那麼service自身也實現了負載:
RoundRobin(輪詢):將請求發送到後端的各個pod上
SessionAffinity:基於客戶端IP地址進行會話,若是SessionAffinity=ClientIP時,同一個客戶端發送請求,會被轉發到後端相同的pod中。
在某些場景中,咱們但願本身控制負載均衡的策略,不使用service提供的默認的負載,或者應用程序但願知道屬於同組服務的其餘實例。Kubernetes提供了Headless Service來實現這個功能,即不爲service設置clusterIP,僅經過label selector將後端的pod列表返回給調用的客戶端:
apiVersion: v1 kind: Service metadata: labels: name: cassandra name: cassandra spec: ports: - port: 9042 ClusterIP: None selector: name: cassandra
這樣service就不在具備一個特定的clusterIP,對其進行訪問將得到包含label「name: cassandra」的所有pod列表,而後客戶端程序自行決定如何處理這個pod列表。
對於去中心化類的應用集羣,headless Service將很是有用。接下來咱們經過搭建一個Cassandra集羣來看看headless Service巧妙的使用,自動實現應用集羣的建立。
經過對headless Service的使用,實現了Cassandra各節點之間的相互查找和集羣的自動搭建。
開始搭建:
#單個pod Cassandra節點: Cassandra-pod.yaml
apiVersion: v1 kind: Pod metadata: labels: name: cassandra name: cassandra spec: containers: - args: - /run.sh resources: limits: cpu: "0.5" image: docker.io/shenshouer/cassandra:v5 imagePullPolicy: IfNotPresent name: cassandra ports: - name: cql containerPort: 9042 - name: thrift containerPort: 9160 volumeMounts: - name: data mountPath: /cassandra_data env: - name: MAX_HEAP_SIZE value: 512M - name: HEAP_NEWSIZE value: 100M - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace volumes: - name: data
#cassandra-svc.yaml
apiVersion: v1 kind: Service metadata: labels: name: cassandra name: cassandra spec: ports: - port: 9042 selector: name: cassandra
#cassandra-rc.yaml
apiVersion: v1 kind: ReplicationController metadata: labels: name: cassandra name: cassandra spec: replicas: 1 selector: name: cassandra template: metadata: labels: name: cassandra spec: containers: - command: - /run.sh resources: limits: cpu: 0.5 env: - name: MAX_HEAP_SIZE value: 512M - name: HEAP_NEWSIZE value: 100M - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace image: docker.io/shenshouer/cassandra:v5 imagePullPolicy: IfNotPresent name: cassandra ports: - containerPort: 9042 name: cql - containerPort: 9160 name: thrift volumeMounts: - mountPath: /cassandra_data name: data volumes: - name: data emptyDir: {}
#依次執行一下命令 [root@zy yaml_file]# kubectl create -f cassandra-pod.yaml [root@zy yaml_file]# kubectl create -f cassandra-svc.yaml [root@zy yaml_file]# kubectl create -f cassandra-rc.yaml
#此時咱們查看pod
[root@zy yaml_file]# kubectl get rc #查看RC
[root@zy yaml_file]# kubectl scale rc cassandra --replicas=2 #副本擴容到2個
[root@zy yaml_file]# kubectl exec -ti cassandra -- nodetool status #查看Cassandra Pod中運行nodetool
看見以上的頁面,表示擴容的pod已經成功加入到Cassandra集羣中。
原理解釋:由於service是headless Service,他會返回selector中的全部的pod,一開始集羣中只有一個pod,因此返回一個,讓集羣中的pod變成多個時,他會將全部的pod都返回,那麼Cassandra是如何處理這新的pod呢?Cassandra鏡像它還給Cassandra添加一個定製的SeedProvider,在Cassandra中, SeedProvider設置一個gossip協議用來發現其它Cassandra節點。KubernetesSeedProvider使用內置的Kubernetes發現服務找到KubernetesAPI服務器,而後利用Kubernetes API發現新的節點。就這樣headless Service將selector選擇中的全部的endpoint,都發送給Cassandra集羣,Cassandra集羣根據SeedProvider,利用內置的Kubernetes發現服務找到KubernetesAPI服務器,而後利用Kubernetes API發現新的節點,並加入到集羣。
參考文檔:https://www.kubernetes.org.cn/doc-36
因爲pod和service是kubernetes集羣範圍內的虛擬的概念,全部集羣外部的客戶端沒法訪經過Pod的IP或者service的IP去訪問到它們。爲了讓外部的客戶端能夠訪問這些服務,kubernetes提供了將Pod或者service的端口號映射到物理機上,以使得客戶端訪問宿主機的端口從而訪問到其容器中的服務。
案例1(①經過設置容器基本的hostPort,將容器應用的端口映射到物理機上)
#pod-hostport.yaml
apiVersion: v1 kind: Pod metadata: name: webapp labels: app: webapp spec: containers: - name: webapp image: docker.io/tomcat imagePullPolicy: IfNotPresent ports: - containerPort: 8080 hostPort: 8070
#建立以後,訪問宿主機的8070端口 [root@zy yaml_file]# curl 192.168.130.130:8070
訪問瀏覽器:http://192.168.130.130:8070/
案例2:(使用spec.hostNetWork參數定義)
經過設置pod級別的hostNetWork=true,該Pod中全部容器的端口號都將被直接映射到物理機上,可是須要注意的是,在容器的ports定義中,若是不指定hostPort,則默認爲containerPort,若是指定了hostPort,則hostPort必須等於containerPort的值。
apiVersion: v1 kind: Pod metadata: name: webapp labels: app: webapp spec: hostNetwork: true containers: - name: webapp image: docker.io/tomcat imagePullPolicy: IfNotPresent ports: - containerPort: 8080
案例3(將service的端口號映射到物理機中)
#webapp-nodePort-svc.yaml
apiVersion: v1 kind: Service metadata: name: webapp spec: type: NodePort ports: - port: 8080 targetPort: 8080 nodePort: 30000 selector: app: webapp
該service將監聽8080端口,併發送到後端selector選擇的endpoint的8080端口,對宿主機暴露的端口爲30000
[root@zy yaml_file]# curl 192.168.130.130:30000 #訪問
案例4
經過設置LoadBalancer映射到雲服務商提供的LoadBalancer地址,LoadBalancer在NodePort基礎上,K8S能夠請求底層雲平臺建立一個負載均衡器,將每一個Node做爲後端,進行服務分發。該模式須要底層雲平臺(例如GCE)支持。
小編這裏以一個yaml爲例:
apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: MyApp ports: - protocol: TCP port: 80 targetPort: 9376 nodePort: 30061 clusterIP: 10.0.171.12 loadBalancerIP: 78.11.42.19 type: loadBalancer status: loadBalancer: ingress: - ip: 146.147.12.155 #這個是雲服務商提供的負載IP
這裏你們要注意了,這一節很是的重要,但願你們必定細細閱讀,之後在分析kubernetes核心時這一節是重中之重的基礎。
Kubernetes的服務發現一共有兩種方式,1.經過環境變量的方式,2.經過集羣範圍內的DNS來完成服務名到clusterIP的解析。這裏小編帶你們瞭解一下如何搭建DNS服務。
Kubernetes提供的虛擬DNS服務名爲ksydns,由4個組件組成:
etcd:DNS存儲
kube2sky:將kubernetes master中的service註冊到etcd
skyDNS:提供DNS域名解析服務
healthz:提供skydns服務的健康檢查功能
① 編寫配置文件
② 修改每臺node上的kubelet啓動參數
③ 建立相應的資源對象
④ 測試
這裏小編就不一一介紹了,給出搭建的地址:https://www.cnblogs.com/yujinyu/p/6112233.html
Kube2sky容器因供應用經過kubernetes master的API獲取集羣全部的service信息,並持續監控新service的生成,而後寫入etcd中:
經過命令查看etcd中存儲的service信息:
[root@zy ~]#kubectl exec kube-dns-v2-dc1s -c etcd --namespace=kube-system etcdctl ls /skydns/local/cluster/
此時看見目錄結果以下:
/skydns/local/cluster/default
/skydns/local/cluster/kube-system
/skydns/local/cluster/svc
能夠看見在skydns下是咱們配置的cluster.local(域名後綴),以後是命名空間,svc下也經過命名空間生成子目錄。
而後查看具體的內容:
[root@zy ~]# kubectl exec kube-dns-v2-dc1s -c etcd --namespace=kube-system etcdctl get /skydns/local/cluster/default/服務名 #這樣就能看見相應的clusterIP和域名映射
而後根據kubectl啓動參數的設置(--cluster_dns),kubelet 會在每個新建立的pod中設置DNS域名解析,配置文件爲:/etc/resolv.conf文件,會在其中加入一條,nameserver和search配置:
nameserver DNS解析服務IP search default.svc.cluster.local svc.cluster.local cluster.local localdomain
有了這些配置,應用程序就可以想訪問網站域名同樣,經過服務的名稱訪問到服務。總的來講就是,kube2sky 經過kubernetes master的API 將新增的service持續存儲到etcd中,每個新增的pod都會有一個/etc/resolv.conf文件,咱們在經過服務名稱訪問服務時,經過skyDNS 查詢etcd,獲取服務的IP,而後經過服務的IP就能直接訪問到服務後端的endpoint中的容器中的應用。
從kubernetes1.6開始,用戶能夠在kubernetes集羣內部配置私有的DNS區域和外部的上游域名服務,在kubernetes的pod定義中支持兩個DNS策略,Default和ClusterFirst,dnsPolicy默認是ClusterFirst,若是是Default,域名解析配置則徹底從Pod的節點的/etc/resolv.conf中繼承下來。
若是dnsPolicy設置的是ClusterFirst,則DNS查詢會被髮送到kube-dns(skydns)服務。kube-dns服務負責以集羣域名爲後綴(例cluster.local)進行服務的域名解析。
那麼自定義的DNS和上游DNS又是啥呢?
由上圖所示,當dnsPolicy設置爲ClusterFirst時,DNS首先會被髮送到kube-dns的緩存層,從這裏檢查域名的後綴,若是是cluster.local,則被髮送到kube-dns服務,若是是自定義的*.out.of.kubernetes,則被髮送到自定義解析器,若是二者均不符合,則被髮送到上游的DNS中進行解析。
域名解析順序:kube-dns ------ > 自定義DNS -------- > 上游DNS
自定義DNS方式:
從kubernetes1.6開始,集羣管理者可使用configMap指定自定義的存根域和上游的DNS Server。
① 安裝dnsmasq做爲自定義的DNS服務
#安裝 [root@zy ~]# yum install -y dnsmasq #生成一個自定義的DNS記錄文件 /tmp/hosts [root@zy ~]# echo "192.168.130.131 server.out-of.kubernetes" > /tmp/hosts #啓動DNS服務 [root@zy ~]# dnsmasq -q -d -h -q -R -H /tmp/hosts #參數解釋: -d:以debug模式啓動,在前臺運行,便於觀察日誌 -q:輸出查詢記錄 -h:不使用/etc/hosts -R:不使用/etc/resolve.conf -H:使用自定義的文件做爲DNS記錄
② 建立自定義DNS的configMap
#dns-configmap.yaml
apiVersion: v1 kind: ConfigMap metadata: name: kube-dns namespace: kube-system data: stubDomains: | {"out-of.kubernetes" : ["192.168.130.130"] } #自定義DNS服務器地址 upstreamNameservers: | #上游DNS地址 ["8.8.8.8","8.8.4.4"] 注意: stubDomains:表示存根域名,自定義DNS就在這裏配置,Key是DNS後綴,value是一組DNS服務IP upstreamNameservers:表示上游DNS配置,若是指定了,那麼從節點/etc/resovl.conf就會被覆蓋。最多指定3個IP。
[root@zy ~]# kubectl create -f dns-configmap.yaml
③ 測試
apiVersion: v1 kind: Pod metadata: name: tester spec: dnsPolicy: ClusterFirst containers: - name: busybox image: docker.io/busybox imagePullPolicy: IfNotPresent command: ["sleep"] args: ["3600"]
建立一個pod,而後進入其中
[root@zy yaml_file]# kubectl exec -it tester – sh / # ping server.out-of.kubernetes
此時就會在dnsmasq的輸出日誌中,看見,server.out-of.kubernetes被轉發到自定義DNS服務:192.168.130.130,而後經過DNS服務器,根據/tmp/hosts域名和IP的映射找到192.168.130.131。
Ingerss產生的緣由:咱們知道pod被deployment/RC管理的時候,pod重啓以後其IP可能會改變,爲了能準確的訪問到pod中的服務,kubernetes使用service,而service會在宿主機上提供一個端口用於客戶端訪問,可是若是service不少的話其維護成本就會很高。若是能夠藉助於nginx的相似於虛擬主機的方式,經過不一樣的URL可以訪問到後端的不一樣service,那麼就少了service對宿主機的大量的端口映射,如何能作到這樣呢?kubernetes1.1開始,新增了一個Ingress的資源對象,用於解決上述問題。
Ingerss介紹:Ingress 包含兩大組件:Ingress Controller 和 Ingress。
原理圖:
Ingress Controller做用:因爲咱們是使用nginx的方式實現,那麼每一次有新的service或者新的Ingress規則時,就要修改一次nginx.conf文件,這樣實在太麻煩,因此Ingress Controller 就是專門解決這個問題,經過與 Kubernetes API 交互,動態的去感知集羣中 Ingress 規則變化,而後讀取他,按照他本身模板生成一段 Nginx 配置,再寫到 Nginx Pod 裏,最後 reload 一下。
Ingress Controller-service:爲了讓Ingress Controller能夠對外提供服務,這裏須要一個service,而service監聽的端口就是80(http)|443(https)上圖所示,該service映射到物理機的端口是30080和30443。
經過Ingress訪問後端應用服務的過程(以web服務爲例):首先定義一個deployment維持三個web服務的副本,而後給其web服務定義一個名爲myapp的service,此時編寫Ingress的規則經過host:myapp.zzy.com,並綁定了名爲myapp的service,即當客戶端訪問myapp.zzy.com:30080時,會被轉發到Ingress Controller-service的80端口上,根據Ingress Controller更新的Ingress規則,會將請求轉發到
myapp:80,而後就能直接訪問後端的pod中的容器,最後容器將請求響應會客戶端。
注意:Ingress Controller將基於Ingress規則將客戶端請求直接轉發到service對應的後端的endpoint。
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: mywebsite-ingress spec: rules: - host: mywebsite.com http: paths: - path: /demo backend: serviceName: webapp servicePort: 8080
• rules:用於定義當前Ingress資源的轉發規則列表;由rules定義規則,或沒有匹配到規則時,全部的流量會轉發到由backend定義的默認後端。
• backend:默認的後端用於服務那些沒有匹配到任何規則的請求;定義Ingress資源時,必需要定義backend或rules二者之一,該字段用於讓負載均衡器指定一個全局默認的後端。backend對象的定義由2個必要的字段組成:serviceName和servicePort,分別用於指定流量轉發的後端目標Service資源名稱和端口。
• host:包含 於 使用 的 TLS 證書 以內 的 主機 名稱 字符串 列表
部署步驟:
部署方法小編已經在下面給出:本身動手也是成長的一部分嘛!
小編也從網上了找了許多的ingress 部署博客,好像基本上都是wget一些yaml文件,可是給出的地址好像都不能訪問了,因此仍是老老實實的看文檔搭建吧,加油加油!
https://github.com/kubernetes/ingress-nginx/blob/master/docs/deploy/index.md
① 轉發到單個後端服務上
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test-ingress spec: backend: serviceName: myweb servicePort: 8080
上面的配置對Ingress Controller的訪問請求都將被轉發到「myweb:8080」這個服務上。
② 同一域名下,不一樣的URL路徑被轉發到不一樣的服務上
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test-ingress spec: rules: - host: mywebsite.com http: paths: - path: /web backend: serviceName: web-service servicePort: 80 - path: /api backend: serviceName: api-service servicePort: 8081
以上配置當訪問:
mywebsite.com/web:80 ------轉發到------ web-service:80
mywebsite.com/api:80 ------轉發到------ api-service:8081
③ 不一樣域名被轉發到不一樣的服務
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test spec: rules: - host: foo.bar.com http: paths: - backend: serviceName: service1 servicePort: 80 - host:bar.foo.com http: paths: - backend: serviceName: service2 servicePort: 80
訪問foo.bar.com-- service1:80 訪問bar.foo.com -- service2:80
④ 不使用域名的轉發規則
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test-ingress spec: rules: - http: paths: - path: /demo backend: serviceName: webapp servicePort: 8080
這種配置,經過任意一條運行的ingress-controller 的node都能訪問到後端的服務。
注意:這種方式默認是不能使用https訪問的,若是想使用https訪問,須要在編寫Ingress規則的時候,加入一個annotation 」ingress.kubernetes.io/ssl-redirect=false」 來關閉強制啓用HTTPS的設置。
因爲小編以前用的是單機版的kubernetes集羣,以前遇到過一些問題致使pod沒法啓動,而後就修改了apiservice的配置:
就將這個兩個配置刪除了。
而後建立Cassandra 的pod的時候就報錯:
而後查看:[root@zy yaml_file]# kubectl get serviceaccount
解決:
在/etc/kubernetes/apiserver 中的--admission_control加入ServiceAccount:
而後在/etc/kubernetes/controller-manager配置:
--service_account_private_key_file=/var/run/kubernetes/apiserver.key
以後重啓這兩個服務:
再執行命令
[root@zy yaml_file]# kubectl get serviceaccount
小編原本覺得這樣問題就解決了,結果查詢Cassandra 的pod的日誌發現:
小編初步推斷多是集羣沒有搭建DNS:由於在查看SeedProvider 源碼時:
後期會慢慢排查,將問題解決!
在service暴露端口時,發現外部訪問時,以後 可使用IP訪問,其餘主機或者瀏覽器訪問不到Kubernetes是1.5.2版本,這裏小編設置了service的type爲NodePort,而且nodePort設置了一個值,最終pod和service都啓動正常,使用clusterIP和本機IP均可以訪問,可是外部集羣沒法訪問。
緣由:
使用service+NodePort時,其中的網絡是上圖所示,客戶端訪問時,須要經過kube-proxy這個服務,可是在1.2以上這個kube-proxy服務在啓動時須要添加參數:
把KUBE_PROXY_ARGS=」「改成KUBE_PROXY_ARGS=」–proxy-mode=userspace」
解決:
修改master的/etc/kubernetes/proxy
將其中的啓動命令的參數添加:
KUBE_PROXY_ARGS="--proxy-mode=userspace"
重啓kube-proxy服務:
[root@zy yaml_file]# systemctl restart kube-proxy
而後在啓動相應的pod和service,以後瀏覽器訪問:
http://192.168.130.130:30000/
OK:
或者:
在默認的iptables mode下,修改(vim /etc/sysctl.conf)文件,加入:net.ipv4.ip_forward=1重啓主機,而後在經過service訪問便可。
到這裏可能你們仍是不太明白爲何service不能外部訪問,須要修改kube-proxy的配置,這裏小編就給你們介紹一下kube-proxy與service的關係:
kube-proxy其實就是管理service的訪問入口,包括集羣內Pod到Service的訪問和集羣外訪問service。kube-proxy管理sevice的Endpoints,該service對外暴露一個Virtual IP,也成爲Cluster IP, 集羣內經過訪問這個Cluster IP:Port就能訪問到集羣內對應的serivce下的Pod。service是經過Selector選擇的一組Pods的服務抽象,其實就是一個微服務,提供了服務的LB和反向代理的能力,而kube-proxy的主要做用就是負責service的實現。
而kube-proxy內部原理:kube-proxy當前實現了兩種proxyMode:userspace和iptables。其中userspace mode是v1.0及以前版本的默認模式,從v1.1版本中開始增長了iptables mode,在v1.2版本中正式替代userspace模式成爲默認模式。小編的集羣是1.5.2的默認的是iptables,因此須要作一些配置,所以咱們改成了userspace,就可讓外部經過service暴露的端口映射到宿主機上來訪問服務啦。
Userspace:userspace是在用戶空間,經過kube-proxy來實現service的代理服務。
Iptables:它徹底利用Linux內核iptables來實現service的代理和LB