本節內容:node
在前面的安裝部署kubernetes集羣中已經簡單用示例來演示了Pod和Service,Kubernetes經過Service資源在Kubernetes集羣內針對容器實現了服務發現和負載均衡。而Service就是kubernetes服務發現與負載均衡中的一種。nginx
目前,kubernetes中的負載均衡大體能夠分爲如下幾種機制,每種機制都有其特定的應用場景:git
1. Servicegithub
Service是對一組提供相同功能的Pods的抽象,併爲它們提供一個統一的入口。藉助Service,應用能夠方便的實現服務發現與負載均衡,並實現應用的零宕機升級。Service經過標籤來選取服務後端,通常配合Replication Controller或者Deployment來保證後端容器的正常運行。這些匹配標籤的Pod IP和端口列表組成endpoints,由kube-proxy負責將服務IP負載均衡到這些endpoints上。web
Service有四種類型:apache
另外,也能夠將已有的服務以Service的形式加入到Kubernetes集羣中來,只須要在建立 Service的時候不指定Label selector,而是在Service建立好後手動爲其添加endpoint。vim
Service雖然解決了服務發現和負載均衡的問題,但它在使用上仍是有一些限制,好比後端
2. Ingress和Ingress Controller簡介api
(1)Ingress瀏覽器
Ingress就是爲了解決這些限制而引入的新資源,主要用來將服務暴露到cluster外面,而且能夠自定義服務的訪問策略。好比想要經過負載均衡器實現不一樣子域名到不一樣服務的訪問:
foo.bar.com --| |-> foo.bar.com s1:80
| 178.91.123.132 |
bar.foo.com --| |-> bar.foo.com s2:80
能夠這樣來定義Ingress:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test spec: rules: - host: foo.bar.com http: paths: - backend: serviceName: s1 servicePort: 80 - host: bar.foo.com http: paths: - backend: serviceName: s2 servicePort: 80
【注意】:Ingress自己並不會自動建立負載均衡器,cluster中須要運行一個ingress controller來根據Ingress的定義來管理負載均衡器。
目前社區提供了 nginx和gce的參考實現
簡單的說,ingress就是從kubernetes集羣外訪問集羣的入口,將用戶的URL請求轉發到不一樣的service上。Ingress至關於nginx、apache等負載均衡方向代理服務器,其中還包括規則定義,即URL的路由信息,路由信息得的刷新由Ingress controller來提供。
(2)Ingress Controller
Ingress Controller 實質上能夠理解爲是個監視器,Ingress Controller 經過不斷地跟 kubernetes API 打交道,實時的感知後端 service、pod 等變化,好比新增和減小 pod,service 增長與減小等;當獲得這些變化信息後,Ingress Controller 再結合下文的 Ingress 生成配置,而後更新反向代理負載均衡器,並刷新其配置,達到服務發現的做用。
在使用Ingress resource以前,有必要先了解下面幾件事情。Ingress是beta版本的resource,在kubernetes1.1以前尚未。你須要一個Ingress Controller來實現Ingress,單純的建立一個Ingress沒有任何意義。
目前社區提供了 nginx和gce的參考實現。固然還有其餘實現,開源的 NGINX 和 NGINX Plus 開發了相應的 Ingress controller。
(1)使用 NGINX 和 NGINX Plus 的 Ingress Controller 進行 Kubernetes 的負載均衡
https://github.com/nginxinc/kubernetes-ingress/tree/master/examples/complete-example
[root@node1 nginx_ingress]# kubectl create -f nginx-ingress-rbac.yaml [root@node1 nginx_ingress]# kubectl create -f default-server-secret.yaml secret "default-server-secret" created [root@node1 nginx_ingress]# kubectl create -f nginx-ingress-rc.yaml replicationcontroller "nginx-ingress-rc" created [root@node1 nginx_ingress]# kubectl get pods -l app=nginx-ingress -o wide NAME READY STATUS RESTARTS AGE IP NODE nginx-ingress-rc-rs1vh 1/1 Running 0 37s 172.30.87.4 172.16.7.151 # 查看pod日誌 [root@node1 nginx_ingress]# kubectl logs nginx-ingress-rc-rs1vh I0924 07:27:37.663514 1 main.go:58] Starting NGINX Ingress controller Version 1.0.0 2017/09/24 07:27:37 [notice] 20#20: signal process started I0924 07:27:37.975349 1 event.go:218] Event(v1.ObjectReference{Kind:"Secret", Namespace:"default", Name:"default-server-secret", UID:"4e2d9567-9f5a-11e7-9acc-005056b7609a", APIVersion:"v1", ResourceVersion:"1019701", FieldPath:""}): type: 'Normal' reason: 'Updated' the default server Secret default/default-server-secret was updated 2017/09/24 07:27:37 [notice] 26#26: signal process started 2017/09/24 07:27:38 [notice] 30#30: signal process started 2017/09/24 07:27:38 [notice] 34#34: signal process started 2017/09/24 07:27:38 [notice] 38#38: signal process started I0924 07:27:38.073475 1 event.go:218] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"kube-system", Name:"traefik-web-ui", UID:"5d604da9-9f61-11e7-9acc-005056b7609a", APIVersion:"extensions", ResourceVersion:"1024008", FieldPath:""}): type: 'Normal' reason: 'AddedOrUpdated' Configuration for kube-system/traefik-web-ui was added or updated 2017/09/24 07:27:38 [notice] 44#44: signal process started I0924 07:27:38.100887 1 event.go:218] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"default", Name:"traefik-ingress", UID:"5d693739-9f61-11e7-9acc-005056b7609a", APIVersion:"extensions", ResourceVersion:"1024009", FieldPath:""}): type: 'Normal' reason: 'AddedOrUpdated' Configuration for default/traefik-ingress was added or updated
(2)配置須要測試的service
部署兩個服務nginx 1.7和nginx 1.8:
apiVersion: v1 kind: Service metadata: name: frontend spec: ports: - port: 80 targetPort: 80 selector: app: nginx1-7 --- apiVersion: apps/v1beta1 kind: Deployment metadata: name: nginx1-7-deployment spec: replicas: 2 template: metadata: labels: app: nginx1-7 spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80
apiVersion: v1 kind: Service metadata: name: my-nginx spec: ports: - port: 80 targetPort: 80 selector: app: nginx1-8 --- apiVersion: apps/v1beta1 kind: Deployment metadata: name: nginx1-8-deployment spec: replicas: 2 template: metadata: labels: app: nginx1-8 spec: containers: - name: nginx image: nginx:1.8 ports: - containerPort: 80
[root@node1 nginx_ingress]# kubectl create -f nginx1-7.yaml service "frontend" created deployment "nginx1-7-deployment" created [root@node1 nginx_ingress]# kubectl create -f nginx1-8.yaml service "my-nginx" created deployment "nginx1-8-deployment" created
(3)建立Ingress
假設這兩個服務要暴露到集羣外部。要建立一個ingress:
[root@node1 nginx_ingress]# vim test-ingress.yaml apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test spec: rules: - host: n17.my.com http: paths: - backend: serviceName: nginx1-7 servicePort: 80 - host: n18.my.com http: paths: - backend: serviceName: nginx1-8 servicePort: 80
建立ingress:
[root@node1 nginx_ingress]# kubectl create -f test-ingress.yaml ingress "test" created [root@node1 nginx_ingress]# kubectl get ing NAME HOSTS ADDRESS PORTS AGE test n17.my.com,n18.my.com 80 52s
打開客戶機的/etc/hosts,配置172.16.7.151和n17.my.com,n18.my.com的對應關係,而後在瀏覽器訪問n17.my.com或n18.my.com就能夠訪問到對應的服務。
若是想修改訪問規則,修改test-ingress.yaml,使用kubectl replace -f更新就能夠了。