本节内容:

  • 服务发现与负载均衡
  • Ingress实战

一、服务发现与负载均衡

在前面的安装部署kubernetes集群中已经简单用示例来演示了Pod和Service,Kubernetes通过Service资源在Kubernetes集群内针对容器实现了服务发现和负载均衡。而Service就是kubernetes服务发现与负载均衡中的一种。

目前,kubernetes中的负载均衡大致可以分为以下几种机制,每种机制都有其特定的应用场景:

  • Service:直接用Service提供cluster内部的负载均衡,并借助cloud provider提供的LB提供外部访问
  • Ingress Controller:还是用Service提供cluster内部的负载均衡,但是通过自定义LB提供外部访问
  • Service Load Balancer:把load balancer直接跑在容器中,实现Bare Metal的Service Load Balancer
  • Custom Load Balancer:自定义负载均衡,并替代kube-proxy,一般在物理部署Kubernetes时使用,方便接入公司已有的外部服务

1. Service

Service是对一组提供相同功能的Pods的抽象,并为它们提供一个统一的入口。借助Service,应用可以方便的实现服务发现与负载均衡,并实现应用的零宕机升级。Service通过标签来选取服务后端,一般配合Replication Controller或者Deployment来保证后端容器的正常运行。这些匹配标签的Pod IP和端口列表组成endpoints,由kube-proxy负责将服务IP负载均衡到这些endpoints上。

Service有四种类型:

  1. ClusterIP:默认类型,自动分配一个仅cluster内部可以访问的虚拟IP
  2. NodePort:在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以 通过 <NodeIP>:NodePort 来访问该服务
  3. LoadBalancer:在NodePort的基础上,借助cloud provider创建一个外部的负载均 衡器,并将请求转发到 <NodeIP>:NodePort
  4. ExternalName:将服务通过DNS CNAME记录方式转发到指定的域名(通 过 spec.externlName 设定)。需要kube-dns版本在1.7以上。

另外,也可以将已有的服务以Service的形式加入到Kubernetes集群中来,只需要在创建 Service的时候不指定Label selector,而是在Service创建好后手动为其添加endpoint。

Service虽然解决了服务发现和负载均衡的问题,但它在使用上还是有一些限制,比如

  • 只支持4层负载均衡,没有7层功能
  • 对外访问的时候,NodePort类型需要在外部搭建额外的负载均衡,而LoadBalancer要求kubernetes必须跑在支持的cloud provider上面。

2. Ingress和Ingress Controller简介

(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:
- host: bar.foo.com
http:
paths:
- backend:
serviceName: s2
servicePort:

【注意】: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实战

在使用Ingress resource之前,有必要先了解下面几件事情。Ingress是beta版本的resource,在kubernetes1.1之前还没有。你需要一个Ingress Controller来实现Ingress,单纯的创建一个Ingress没有任何意义。

目前社区提供了 nginx和gce的参考实现。当然还有其他实现,开源的 NGINX 和 NGINX Plus 开发了相应的 Ingress controller

  • GCE/GKE会在master节点上部署一个ingress controller。你可以在一个pod中部署任意个自定义的ingress controller。你必须正确地annotate每个ingress,比如 运行多个ingress controller关闭glbc
  • 在非GCE/GKE的环境中,你需要在pod中部署一个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 / Running 37s 172.30.87.4 172.16.7.151 # 查看pod日志
[root@node1 nginx_ingress]# kubectl logs nginx-ingress-rc-rs1vh
I0924 ::37.663514 main.go:] Starting NGINX Ingress controller Version 1.0.
// :: [notice] #: signal process started
I0924 ::37.975349 event.go:] Event(v1.ObjectReference{Kind:"Secret", Namespace:"default", Name:"default-server-secret", UID:"4e2d9567-9f5a-11e7-9acc-005056b7609a", APIVersion:"v1", ResourceVersion:"", FieldPath:""}): type: 'Normal' reason: 'Updated' the default server Secret default/default-server-secret was updated
// :: [notice] #: signal process started
// :: [notice] #: signal process started
// :: [notice] #: signal process started
// :: [notice] #: signal process started
I0924 ::38.073475 event.go:] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"kube-system", Name:"traefik-web-ui", UID:"5d604da9-9f61-11e7-9acc-005056b7609a", APIVersion:"extensions", ResourceVersion:"", FieldPath:""}): type: 'Normal' reason: 'AddedOrUpdated' Configuration for kube-system/traefik-web-ui was added or updated
// :: [notice] #: signal process started
I0924 ::38.100887 event.go:] Event(v1.ObjectReference{Kind:"Ingress", Namespace:"default", Name:"traefik-ingress", UID:"5d693739-9f61-11e7-9acc-005056b7609a", APIVersion:"extensions", ResourceVersion:"", 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:
targetPort:
selector:
app: nginx1-
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx1--deployment
spec:
replicas:
template:
metadata:
labels:
app: nginx1-
spec:
containers:
- name: nginx
image: nginx:1.7.
ports:
- containerPort:

nginx1-7.yaml

apiVersion: v1
kind: Service
metadata:
name: my-nginx
spec:
ports:
- port:
targetPort:
selector:
app: nginx1-
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx1--deployment
spec:
replicas:
template:
metadata:
labels:
app: nginx1-
spec:
containers:
- name: nginx
image: nginx:1.8
ports:
- containerPort:

nginx1-8.yaml

[root@node1 nginx_ingress]# kubectl create -f nginx1-.yaml
service "frontend" created
deployment "nginx1-7-deployment" created
[root@node1 nginx_ingress]# kubectl create -f nginx1-.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-
servicePort:
- host: n18.my.com
http:
paths:
- backend:
serviceName: nginx1-
servicePort:

创建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 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更新就可以了。

Kubernetes Ingress实战的更多相关文章

  1. Kubernetes Ingress Controller的使用及高可用落地

    Kubernetes Ingress Controller的使用及高可用落地 看懂本文要具备一下知识点: Service实现原理和会应用 知道反向代理原理,了解nginx和apache的vhost概念 ...

  2. Kubernetes Ingress 学习

    Kubernetes 中暴露服务的方式有三种 Loadbalancer 这种方式往往需要云供应商支持,或者本地F5等设备支持 NodePort 这种方式调用方通过NodeIP:NodePort 的方式 ...

  3. Kubernetes Ingress管理

    目录 Ingress介绍 1.Pod漂移问题 2.端口管理问题 3.域名分配及动态更新问题 Nginx Ingress配置 1.部署默认后端 2.部署Ingress Controller 3.部署In ...

  4. Kubernetes Ingress 部署

    Kubernetes Ingress 部署 Pod与Ingress的关系• 通过service相关联• 通过Ingress Controller实现Pod的负载均衡- 支持TCP/UDP 4层和HTT ...

  5. [转帖]kubernetes ingress 在物理机上的nodePort和hostNetwork两种部署方式解析及比较

    kubernetes ingress 在物理机上的nodePort和hostNetwork两种部署方式解析及比较 https://www.cnblogs.com/xuxinkun/p/11052646 ...

  6. Kubernetes Ingress日志分析入门

    本文主要介绍如何基于日志服务构建Kubernetes Ingress日志分析平台,并提供一些简单的动手实验方便大家快速了解日志服务相关功能. 部署Ingress日志方案 登录容器服务管理控制台. 将上 ...

  7. Kubernetes Ingress简单入门

    作者:Nick Ramirez 原文链接:https://thenewstack.io/kubernetes-ingress-for-beginners/ 本文转载自Rancher Labs 不知道你 ...

  8. 在 Kubernetes Ingress 中支持 Websocket/Socket 服务

    Kubernetes Ingress 可将集群内部的 Service 通过 HTTP/HTTPS 的方式暴露供外部访问,并通过路径匹配规则定义服务的路由.但是 Ingress 对 TCP/UDP 的服 ...

  9. CORS跨源资源共享概念及配置(Kubernetes Ingress和Spring Cloud Gateway)

    我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 跨源资源共享CORS 跨源资源共享 (CORS) (或通俗地译为跨域资源共享)是一种基于HTTP 头的机制,该机制通过 ...

随机推荐

  1. c++操作mysql入门详解

    首先,根据你当前的操作系统,还有开发工具,选择相应的mysql版本.本人选择的环境是win10 + vs2013 需要解决三个问题:1.下载安装mysql服务器,并登录mysql测试一下是否安装成功: ...

  2. 【Asp.net入门06】第一个ASP.NET 应用程序-案例说明

    创建简单的应用程序 本章的剩余部分将探讨一些用于创建简单的数据输入应用程序的基本ASP.NET功能.在这一节中,我们将加快进度——目标是演示ASP.NET的用法,因此将略过有关后台运行机制的详细说明. ...

  3. Python【面向对象编程】

    #1.python中,类名首字母都大写#2.在python3中,经典类和新式类没有任何区别#3.在python2中,经典类和新式类的区别主要体现在多继承上,经典类是深度优先,新式类是广度优先#4.在p ...

  4. 科学计算三维可视化---TraitsUI(控件)

    一:文本编辑器 from traits.api import HasTraits,Int,Str,Password from traitsui.api import View,Item,Group,M ...

  5. [非常重要的总结] Linux C相关函数

    (1)字符测试函数 isalnum(测试字符是否为英文字母或数字) isalpha(测试字符是否为英文字母) isascii(测试字符是否为ASCII码字符) isblank(测试字符是否为空格字符) ...

  6. Spring Cloud(十一)声名式服务调用:Feign的使用 (上)

    一.写在前边 最近开发任务比较忙,下班也开始锻炼了,这个系列的文章就放了很久,看github我提交的Feign的入门程序已经好久了,今天正好得空,这就更上一贴,准备分几部分写 注意:之前几个项目中,笔 ...

  7. [转载]js 程序执行与顺序实现详解

    http://www.jb51.net/article/36755.htm JavaScript是一种描述型脚本语言,由浏览器进行动态的解析与执行,浏览器对于不同的方式有不同的解析顺序,详细介绍如下, ...

  8. HAOI 2005 路由选择问题 (最短路+次短路)

    问题描述 X城有一个含有N个节点的通信网络,在通信中,我们往往关心信息从一个节点I传输到节点J的最短路径.遗憾的是,由于种种原因,线路中总有一些节点会出故障,因此在传输中要避开故障节点. 任务一:在己 ...

  9. Mysql查看建表语句以及修改引擎

    更多内容推荐微信公众号,欢迎关注: 1 查看系统支持的存储引擎 show engines; 2 查看表使用的存储引擎 两种方法: a.show table status from db_name wh ...

  10. Go语言fmt库的print函数源码解析

    // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a B ...