前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >kubernetes中的代理Ingress

kubernetes中的代理Ingress

原创
作者头像
极客运维圈
修改2020-02-10 17:59:59
1.3K0
修改2020-02-10 17:59:59
举报
文章被收录于专栏:乔边故事乔边故事

我们前面介绍过用Service做集群代理,Service一般情况下只作用于内部Pod的代理调度,就算有NodePort类型,其访问节点相对复杂,流程大概如下:

image.png
image.png

但是我们知道,如果只指定一个NodeIP,随着业务量增大,这个Node的压力就会很大,所以我们可能会在前端再加一个代理,代理几个Node,比如我们在前端加一个NG,流程如下:

image.png
image.png

在应用小的情况下,这种架构虽然调度复杂,但是也可以使用,但是如果有大量应用,这种管理就非常麻烦,因为 我们要管理大量的NodePort,这个时候使用Ingress就非常方便。

再则,Service的转发不论是iptables还是ipvs,都是4层的,但是在实际中基本都https请求,https是7层,4层是没办法对起进行SSL校验的,如果我们是第二幅流程图,我们可以在前置NG上配置SSL,但是如果我们是第一幅图的流程,我们只能在Pod上配置SSL,因为Service上是无法进行校验,那么就会出现一个问题,SSL的校验是很耗资源的,我们的客户端访问Pod,如果Pod非常多并且访问模式是轮询,那么每访问一次就要做一次SSL校验,这就非常不科学,我们就只有用类似于第二副图的架构,Ingress可以很完美的解决这种问题。

一、Ingress

image.png
image.png

流程图如上,其中Ingress代理的并不是Pod的Service,而是Pod,之所以在配置的时候是配置的Service,是为了获取Pod的信息。

Ingress提供外部访问集群的入口,将外部的HTTP或者HTTPS请求转发到集群内Service上,流量规则是在Ingress资源上定义。

配置Ingress资源的必要条件是你的kubernetes集群种由Ingress controller。其中Ingress Controller常用的有如下:

  • HAProxy Ingress Controller
  • Nginx Ingress Controller
  • Traefik Ingress Controller
  • Kong Ingress Controller

其中最常用的是Nginx Controller和Traefik Ingress Controller。

定义一个简单的Ingresss:

root@master ingress# cat ingress-simple-daemo.yaml 

代码语言:txt
复制
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress-simple-daemo
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /joker
        backend:
          serviceName: nginx
          servicePort: 80

简要说明:

apiVersion,kind,metadata,spec都是Kubernetes YAML文件的标准字段,Ingress经常通过annotations来配置一些选项,比如rewrite-target,不同的Ingress Controller支持不同的annotations。对于规则而言,每个HTTP都有如下规则:

  • 主机:主机是可选参数,如果不配置表示适用于所有主机HTTP通信,如果配置了表示只适用于该主机;
  • 路径:类似于NG的location,每个路径后面都有后端ServiceName和ServicePort;
  • 后端:后端是ServiceName和ServicePort组合,符合该规则的流量会转发到这个后端Service上。通常会在Ingress中配置默认后端,以匹配任何不符合规则的请求流量转发;
  • 具体的语法规则可以通过kubectl explain ingress来查看。

1.1、Ingress 类型

1.1.1、单服务Ingress

Kubernetes中已经存在一些概念可以暴露单个service(查看替代方案),但是你仍然可以通过Ingress来实现,通过指定一个没有rule的默认backend的方式。比如:

root@master ingress# cat single-service-ingress.yaml 

代码语言:txt
复制
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: single-service-ingress
spec:
  backend:
    serviceName: nginx
    servicePort: 80

1.1.2、简单展开

如前面描述的那样,kubernete pod中的IP只在集群网络内部可见,我们需要在边界设置一个东西,让它能够接收ingress的流量并将它们转发到正确的端点上。这个东西一般是高可用的loadbalancer。使用Ingress能够允许你将loadbalancer的个数降低到最少,例如,假如你想要创建这样的一个设置:

代码语言:txt
复制
foo.bar.com -> 178.91.123.132 -> / foo    service1:4200
                                 / bar    service2:8080

我们就可以这样配置Ingress:

代码语言:txt
复制
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: simple-fanout-example
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /foo
        backend:
          serviceName: service1
          servicePort: 4200
      - path: /bar
        backend:
          serviceName: service2
          servicePort: 8080

1.1.3、基于名称的虚拟主机

如果想实现下面这种需求:

代码语言:txt
复制
foo.bar.com --|                 |-> foo.bar.com s1:80
              | 178.91.123.132  |
bar.foo.com --|                 |-> bar.foo.com s2:80

我们就可以这样配置Ingress:

代码语言:txt
复制
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: name-virtual-host-ingress
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - backend:
          serviceName: service1
          servicePort: 80
  - host: bar.foo.com
    http:
      paths:
      - backend:
          serviceName: service2
          servicePort: 80

如果要增加配置默认的backend,可以配置成如下Ingress:

代码语言:txt
复制
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: name-virtual-host-ingress
spec:
  rules:
  - host: first.bar.com
    http:
      paths:
      - backend:
          serviceName: service1
          servicePort: 80
  - host: second.foo.com
    http:
      paths:
      - backend:
          serviceName: service2
          servicePort: 80
  - http:
      paths:
      - backend:
          serviceName: service3
          servicePort: 80

默认backend:一个没有rule的ingress,所有流量都将发送到一个默认backend。你可以用该技巧通知loadbalancer如何找到你网站的404页面,通过制定一些列rule和一个默认backend的方式。如果请求header中的host不能跟ingress中的host匹配,并且/或请求的URL不能与任何一个path匹配,则流量将路由到你的默认backend。

1.1.4、TLS

你可以通过指定包含TLS私钥和证书的secret来加密Ingress。 目前,Ingress仅支持单个TLS端口443,并假定TLS termination。 如果Ingress中的TLS配置部分指定了不同的主机,则它们将根据通过SNI TLS扩展指定的主机名(假如Ingress controller支持SNI)在多个相同端口上进行复用。 TLS secret中必须包含名为tls.crttls.key的密钥,这里面包含了用于TLS的证书和私钥,例如:

代码语言:txt
复制
apiVersion: v1
kind: Secret
metadata:
  name: testsecret-tls
  namespace: default
data:
  tls.crt: base64 encoded cert
  tls.key: base64 encoded key
type: kubernetes.io/tls

在Ingress中引用这个secret将通知Ingress controller使用TLS加密从将客户端到loadbalancer的channel:

代码语言:txt
复制
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: tls-example-ingress
spec:
  tls:
  - hosts:
    - sslexample.foo.com
    secretName: testsecret-tls
  rules:
    - host: sslexample.foo.com
      http:
        paths:
        - path: /
          backend:
            serviceName: service1
            servicePort: 80

注意:各种Ingress controller支持的TLS功能之间存在差距。 请参阅有关nginxGCE或任何其他平台特定Ingress controller的文档,以了解TLS在你的环境中的工作原理。

1.2、Ingress更新

如果你想更改你现在正工作的Ingress,比如新增一个HOST,可以使用kubectl edit ingress my-ingress进行更新,在保存退出后其会触发Ingress Controller重新配置LB。比如我们现有一个ingress:

代码语言:txt
复制
[root@master ingress]# kubectl get ingresses.
NAME                     HOSTS   ADDRESS   PORTS   AGE
      *                 80      58m

然后我们使用kubectl edit ingress ingress-simple-daemo来新增一个HOST:

代码语言:txt
复制
......
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: nginx-service
          servicePort: 8000
        path: /joker
  - host: bar.baz.com
    http:
      paths:
      - backend:
          serviceName: nginx
          servicePort: 80
        path: /foo
status:
  loadBalancer: {}

保存退出后就会生效:

代码语言:txt
复制
[root@master ingress]# kubectl describe ingresses ingress-simple-daemo
Name:             ingress-simple-daemo
Namespace:        default
Address:          
Default backend:  default-http-backend:80 (<none>)
Rules:
  Host         Path  Backends
  ----         ----  --------
  *            
               /joker   nginx-service:8000 (172.20.2.84:80)
  bar.baz.com  
               /foo   nginx:80 (172.20.2.79:80,172.20.2.82:80)
Annotations:
  kubernetes.io/ingress.class:                       traefik
  kubectl.kubernetes.io/last-applied-configuration:  {"apiVersion":"networking.k8s.io/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"traefik"},"name":"ingress-simple-daemo","namespace":"default"},"spec":{"rules":[{"http":{"paths":[{"backend":{"serviceName":"nginx-service","servicePort":8000},"path":"/joker"}]}}]}}

Events:  <none>

参考文档:https://kubernetes.io/zh/docs/concepts/services-networking/ingress/

-----------------------

公众号:乔边故事(ID:qiaobiangushi)

知乎: 乔边故事

头条号:乔边故事

只要脸皮够厚,整个世界都将被你踩在脚下。

-----------------------

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Ingress
    • 1.1、Ingress 类型
      • 1.1.1、单服务Ingress
        • 1.1.2、简单展开
        • 1.1.4、TLS
    相关产品与服务
    SSL 证书
    腾讯云 SSL 证书(SSL Certificates)为您提供 SSL 证书的申请、管理、部署等服务,为您提供一站式 HTTPS 解决方案。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档