以图形化的方式简单介绍Kubernetes Ingress

标签: 图形 kubernetes ingress | 发表时间:2020-01-21 23:42 | 作者:xiaoyh
出处:http://weekly.dockone.io

【编者的话】原文地址: here。本文主要介绍了 Kubernetes Ingress 的内部原理,以及一些 Ingress 的用法示例。

索引

本文有两部分:


内容摘要

Kubernetes Ingress 不是一个 Kubernetes Service,简单地说,它只是一个将请求重定向到集群内部服务的 Nginx Pod,只不过这个 Pod 是通过 Kubernetes Service 进行访问,通常使用的是 LoadBalancer 类型的 Service。

本文有必要读吗?

首先,本文将向你提供一个清晰且简单的概述,用以说明神秘的 Kubernetes Ingress 背后到底是什么,这样能够让你更容易理解你正在实施的内容。

然后,本文将向你展示一些使用样例的配置示例。

为什么使用 Ingress?

使用 Ingress 可以将你集群的内部服务对外暴露,它能够帮你节省内部宝贵的静态 IP,因为你不需要声明多个 LoadBalancer 类型的 service。而且,如我们所见,它还能够进行多样化的配置以及更加简易的设置方式。

本文将要讲述什么?

  • 首先,我们将简短阐述 HTTP 服务器(尤其是 Nginx)是如何工作以及它们可以做什么。
  • 然后,我们将展示在不使用 Kubernetes Ingress 资源的情况下,如何手动搭建 Ingress。
  • 最后,我们将看到 Kubernetes Ingress 只是一个预配置的 Nginx 服务器。


听起来有点迷惑?那就继续往下看吧。

简要了解一个简单的 HTTP 服务器的世界

让我们回到容器、Kubernetes以及现代云计算世界之前的那个时代。跟我一起,简单回顾一下。

一个 HTTP 服务器(如 Nginx)能做什么?
如下图所示,它能够接收一个基于 HTTP 协议访问某个特定文件路径的请求,检查文件系统中该文件路径是否存在,如果存在就将其返回。

请输入图片名称

本例中 Nginx 的配置可能如下:
location /folder {  
root /var/www/;
index index.html;
}


一个 HTTP 服务器(如 Nginx)还能做什么?
如下图所示,它能够接收一个访问特定文件路径的请求,然后将这个请求重定向到另一个服务器上(这里它扮演着代理角色)并且将来自于这个服务器的请求响应内容返回给客户端。客户端不需要做什么改变,如果请求的文件存在,它就能收到想要的结果。

请输入图片名称

我们不会深入解释这个过程,本例中 Nginx 作为一个代理服务器使用的配置可能如下:
location /folder {  
proxy_pass http://second-nginx-server:8000;
}


这个配置表示 Nginx 能够扮演一个代理角色,对外提供文件系统服务,重定向请求到其他服务器上并返回对应的响应内容。

一个简单的 Kubernetes 示例

使用 ClusterIP 类型的 service
我们假定现在你已经对 Kubernetes Service 有所了解(可以参考另一篇文章 Kubernetes Services)。如下图所示,我们有两个 worker 节点,这里先忽略 master 节点。我们有两个服务: service-nginxservice-python,它们指向了不同的 pod。Service 不会调度到任何节点上,让我们先简单地认为它们“存在于集群的任何地方”。

请输入图片名称

目前你可以看到在我们集群内部,我们能够通过 service 访问 Nginx pod 和 Python pod。如果我们想在集群外部也能够访问它们,我们就需要将service 转换为 LoadBalancer 类型。

使用 LoadBalancer 类型的 service
如下图,你可以看到我们将 ClusterIP 类型的 service 转成了 LoadBalancer 类型。我们的 Kubernetes 集群部署在能够支持 LoadBalancer 类型 Service 的云服务提供商上(例如 Gcloud、AWS、DigitalOcean 等),可以看到提供商创建了 2 个外部的负载均衡器,负载均衡器将请求转发到了集群节点的外部 IP 地址,进而转发到了内部服务上。

请输入图片名称

从上图可以看出,两个负载均衡器都有自己的 IP 地址。如果我们将请求发往地址为 22.33.44.55 的负载均衡器上,请求被转发到集群内的 service-nginx。如果我们将请求发往地址为 77.66.55.44 的负载均衡器上,请求被转发到集群内的 service-python

这种运行方式很棒!但 IP 地址有限且负载均衡器的价格取决于云服务提供商。设想下我们集群内部不止 2 个服务,而是拥有很多内部服务。如果我们都想构建 LoadBalancer 方式,那成本将迅速上涨。

有更好的解决方案能够让我们只使用一个负载均衡器(只使用一个 IP 地址),仍然可以访问我们内部的服务吗?在继续探索之前,我们先手动实现一种方式(非 Kubernetes 方式)。

手动配置一个 Nginx 代理服务
如之前所述,Nginx 可以作为一个代理服务。如下图所示,集群内有一个新的 service 叫做 service-nginx-proxy,它作为我们集群内唯一的 LoadBalancer 类型 service。在集群内 service-nginx-proxy 也会指向一个或者多个 Nginx pod 终端,不过在下图中我们没有展示出来。其他两个 service 由之前的类型转为了简单的 ClusterIP 类型。

请输入图片名称

从图中我们能够看到,通过一个 LoadBalancer(11.22.33.44) 访问不同的 http url 返回的请求内容是不同的,因为如图中黄线所示,使用不同 url 访问相同的地址,请求重定向的服务是不同的。

service-nginx-proxy 这个服务使用 Nginx 代理配置了传入路径与重定向目标的关系,依据请求 url 决定了请求应该重定向到哪个服务。

在这个示例中(如上图所示)我们有两个选项:红色线条和蓝色线条。红色线条重定向到了 service-nginx,而蓝色线条重定向到了 service-python。Nginx 配置如下所示:
  

very simplified Nginx config example

location /folder {
proxy_pass http://service-nginx:3001;
}
location /other {
proxy_pass http://service-python:3002;
}


现在我们需要手动配置 service-nginx-proxy 服务,构建合适的 Nginx 配置文件指向我们 ClusterIP 类型的 service。这是一种能做到的、可行的且通用的解决方案。

基于这种通用的解决方案,Kubernetes Ingress 就是用来让构建配置文件的过程变得更简单且更加可控。现在你应该能理解上述示例的好处了,接下来我们继续讨论 Kubernetes Ingress。

使用 Kubernetes Ingress

对比下图和上述图例,其实没什么区别。我们只是使用了一个事先配置好的 Nginx(Kubernetes Ingress) 服务,不过所有代理配置已经完成,减少了很多手动配置的工作。

请输入图片名称

以上就是理解 Kubernetes Ingress 的所有内容,接下来我们介绍一些使用示例。

安装 Kubernetes Ingress Controller

Kubernetes Ingress 是 Kubernetes 附加的资源,使用以下命令进行安装:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/mandatory.yaml  
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.24.1/deploy/provider/cloud-generic.yaml


使用下面的命令,可以看到 ingress-nginx 命名空间下安装的所有 k8s 资源:
kubectl get svc,pod --namespace=ingress-nginx  


请输入图片名称

如上图所示,可以看到一个具备外部 IP 地址的普通 LoadBalancer service 以及一个附属的 pod。你可以使用 kubectl exec 命令进入 pod 内部,看到它包含了一个事先配置好的 Nginx 服务。

请输入图片名称

nginx.conf 文件中你可以看到不同代理配置以及其他一些相关配置项。

Kubernetes Ingress 配置示例

上述示例使用的 Ingress yaml 文件如下所示:
  

just example, not tested

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
namespace: default
name: test-ingress
spec:
rules:
- http:
paths:
- path: /folder
  backend:
    serviceName: service-nginx
    servicePort: 3001
- http:
paths:
- path: /other
  backend:
    serviceName: service-python
    servicePort: 3002


我们可以通过命令 kubectl create -f ingress.yaml 来构建这个 Ingress。执行完命令之后,yaml 文件就会转变为之前安装的 Ingress Controller 服务中的 Nginx 配置。

不同命令空间下 Kubernetes Ingress 示例

现在如果你的集群有一个内部服务,它和 Ingress 在不同的命令空间,该如何进行重定向呢?因为一个 Ingress 资源是命令空间化的, 在 Ingress 配置中你只能重定向到相同命令空间下的服务

如果你定义了多个 Ingress yaml 配置,那么所有的配置会集中写入 Ingress Controller 使用的 Nginx 配置文件中。意味着: 所有配置都使用相同的 LoadBalancer IP地址。

因此,为不同命名空间下的内部服务创建不同命令空间下的 Ingress 资源即可。例如 service-nginx 在 default 命名空间下:
  

just example, not tested

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
**namespace: default**
name: ingress1
spec:
rules:
- http:
paths:
- path: /folder
  backend:
    serviceName: service-nginx
    servicePort: 3001


service-python 在 namespace2 命令空间下:
  

just example, not tested

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
namespace: namespace2
name: ingress2
spec:
rules:
- http:
paths:
- path: /other
  backend:
    serviceName: service-python
    servicePort: 3002


如何微调 Ingress Nginx 的配置?

你可以通过 Kubernetes Ingress 资源定义中的 annotations 属性来实现。如下所示,你可以配置不同内容就像直接在配置 Nginx 一样。
kind: Ingress  
metadata:
name: ingress
annotations:
  kubernetes.io/ingress.class: nginx
  nginx.ingress.kubernetes.io/proxy-connect-timeout: '30'
  nginx.ingress.kubernetes.io/proxy-send-timeout: '500'
  nginx.ingress.kubernetes.io/proxy-read-timeout: '500'
  nginx.ingress.kubernetes.io/send-timeout: "500"
  nginx.ingress.kubernetes.io/enable-cors: "true"
  nginx.ingress.kubernetes.io/cors-allow-methods: "*"
  nginx.ingress.kubernetes.io/cors-allow-origin: "*"
...


你甚至可以做一个特殊规则配置:
nginx.ingress.kubernetes.io/configuration-snippet: |  
if ($host = 'www.wuestkamp.com' ) {
rewrite ^ https://wuestkamp.com$request_uri permanent;
}


这些 annotations 设置会被转换为 Nginx 配置。你可以通过手动连接(kubectl exec)到 ingress Nginx pod 内检查下这些配置项。

还有一些不同的配置示例可以参考:

https://github.com/kubernetes/ ... ation

https://github.com/kubernetes/ ... y-waf

检查 Ingress 或者 Nginx 的日志

找出问题或者错误可以通过查看 Ingress 的日志,如下所示:
kubectl logs -n ingress-nginx ingress-nginx-controller-6cfd5b6544-k2r4n  


请输入图片名称

使用 curl 命令测试你的配置

如果你想测试 Ingress 或者 Nginx 的配置规则是否生效,使用 curl -v yourhost.com 是一个不错的选择,用它来取代浏览器访问,避免缓存问题。

重定向或者 Ingress Rules的不同设置方式

在本文中介绍的示例都是通过路径来重定向到不同的服务,例如 /folder 或者 /other/directory。这是所谓的“路径列表”。

另一种方式是可以根据请求的来源地址(例如 api.myurl.comwebsite.myurl.com) 区分不同请求,进而重定向到不同的内部 ClusterIP service 上。配置如下所示:
apiVersion: networking.k8s.io/v1beta1  
kind: Ingress
metadata:
name: simple-fanout-example
spec:
rules:
- host: api.myurl.com
http:
  paths:
  - path: /foo
    backend:
      serviceName: service1
      servicePort: 4200
  - path: /bar
    backend:
      serviceName: service2
      servicePort: 8080
- host: website.myurl.com
http:
  paths:
  - path: /
    backend:
      serviceName: service3
      servicePort: 3333


从上可以看出,针对特定的地址(host)以及不同的 http 路径可以重定向到不同的内部服务。

SSL 或者 HTTPS 的配置方式

SSL,你应该听说过吧?你可能想让你的 web 服务通过 https 安全访问。Kubernetes Ingress 提供了更加简单的“TLS Termination”机制,也就是说它能够处理所有 SSL 通信,解密或者终止 SSL 请求并将解密后的内容发往集群内部服务。

如果你集群内多个内部服务使用的是相同的 SSL 证书,这种机制是很适用的,因为你只需要在你的 Ingress 上配置一次即可,而不需要修改所有内部服务。Ingress 能通过一个配置好的 TLS Kubernetes Secret 来使用 SSL 证书,如下所示:
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 资源,你要确保你的 TLS secret 同样能够在这些命名空间中被使用。

总结

本文主要是想为你提供有关神秘的 Kubernetes Ingress 背后实现原理的概述。简单来说,它无非就是一种轻松配置 Nginx 服务器的方法,该服务器会将请求重定向到集群内的其他内部服务。

通过 Ingress,你可以节省宝贵的静态 IP 地址以及 LoadBalancer 资源。但是,你不应该将 Kubernetes Ingress 视为 Kubernetes 的一种 Service 类型。Ingress 本身不是 Kubernetes 的一种 Service 类型,它只是使用了一个 Service,主要是 LoadBalancer。

需要注意的是,还有其他 Kubernetes Ingress 类型并非基于 Nginx 服务实现,不过它们只是使用了不同的代理技术。

相关 [图形 kubernetes ingress] 推荐:

以图形化的方式简单介绍Kubernetes Ingress

- - DockOne.io
【编者的话】原文地址: here. 本文主要介绍了 Kubernetes Ingress 的内部原理,以及一些 Ingress 的用法示例. 第一部分: 以图形化的方式简单介绍Kubernetes Service. 第二部分:以图形化的方式简单介绍Kubernetes Ingress,即这篇文章.

使用 Kubernetes Ingress 对外暴露服务

- - DockOne.io
本文主要介绍如何通过 Kubernetes Ingress 资源对象实现从外部对 Kubernetes 集群中服务的访问,介绍了 Kubernetes 对外暴露服务的多种方法、Ingress 及 Ingress Controller 的概念. Kubernetes 对外暴露服务的方法. 向 Kubernetes 集群外部暴露服务的方式有三种: nodePort,LoadBalancer 和本文要介绍的 Ingress.

Kubernetes的负载均衡问题(Nginx Ingress) - ericnie - 博客园

- -
Kubernetes关于服务的暴露主要是通过NodePort方式,通过绑定minion主机的某个端口,然后进行pod的请求转发和负载均衡,但这种方式下缺陷是. Service可能有很多个,如果每个都绑定一个node主机端口的话,主机需要开放外围一堆的端口进行服务调用,管理混乱. 无法应用很多公司要求的防火墙规则.

Kubernetes Nginx Ingress 教程 - 漠然的博客 | mritd Blog

- -
一、Ingress 介绍. Kubernetes 暴露服务的方式目前只有三种:LoadBlancer Service、NodePort Service、Ingress;前两种估计都应该很熟悉,具体的可以参考下  这篇文章;下面详细的唠一下这个 Ingress. 1.1、Ingress 是个什么玩意.

浅谈Kubernetes Ingress控制器的技术选型

- - DockOne.io
【编者的话】在Kubernetes的实践、部署中,为了解决 Pod 迁移、Node Pod 端口、域名动态分配等问题,需要开发人员选择合适的 Ingress 解决方案. 面对市场上众多Ingress产品,开发者该如何分辨它们的优缺点. 又该如何结合自身的技术栈选择合适的技术方案呢. 在本文中,腾讯云中间件核心研发工程师厉辉将为你介绍如何进行Kubernates Ingress 控制器的技术选型.

Kubernetes & Microservice

- - 午夜咖啡
这是前一段时间在一个微服务的 meetup 上的分享,整理成文章发布出来. 谈微服务之前,先澄清一下概念. 微服务这个词的准确定义很难,不同的人有不同的人的看法. 比如一个朋友是『微服务原教旨主义者』,坚持微服务一定是无状态的 http API 服务,其他的都是『邪魔歪道』,它和 SOA,RPC,分布式系统之间有明显的分界.

Kubernetes 完全教程

- - 午夜咖啡
经过一个阶段的准备,视频版本的 《Kubernetes 完全教程》出炉了. 课程一共分为七节,另外有一节 Docker 预备课,每节课大约一个多小时. 目标是让从没接触过 Kubernetes 的同学也能通过这个课程掌握 Kubernetes. 为什么要学习 Kubernetes. 在介绍课程之前,先说说为什么要学习 Kubernetes 以及什么人需要学习 Kubernetes.

Kubernetes 监控详解

- - DockOne.io
【编者的话】监控 Kubernetes 并不是件容易的事. 本文介绍了监控 Kubernetes 的难点、用例以及有关工具,希望可以帮助大家进一步了解监控 Kubernetes. 如果想要监控 Kubernetes,包括基础架构平台和正在运行的工作负载,传统的监控工具和流程可能还不够用. 就目前而言,监控 Kubernetes 并不是件容易的事.

现实中的虚拟战场——Ingress 初体验

- - 极客公园-GeekPark
对Android Design了解深入, 热爱Metro UI, 曾在美亚柏科实习, 现在在美国读大学. [核心提示]Ingress 是 Google 出品的增强现实多人 RPG 游戏. 我们的观察家 NovaDNG 对这款游戏进行了初步体验. “你身边的世界,并不只是你看到的那个样子. Ingress 是 Google 旗下的 NianticLabs 的作品.

喜大普奔:Spark on kubernetes

- - Zlatan Eevee
两个星期前(08/15/2017),spark社区提了一个新的SPIP(Spark Project Improvement Proposals): Spark on Kubernetes: Kubernetes as A Native Cluster Manager,即用k8s管理spark集群. 经过社区2个星期的投票,看上去很快要能合入了.