草庐IT

第11章 流量路由Ingress(一)

漫长的白日梦技术大佬 2023-09-16 原文

Ingress是K8s集群对外暴露服务的核心方式之一,另一个方式是云产品负载均衡,下面对它的基本原理,场景化需求,获取客户端真实IP地址以及白名单机制。

11.1 基本原理

11.1.1 解决的问题

K8s集群有四种类型的服务,分别是ClusterIP、NodePort、LoadBalancer以及ExternalName。

ClusterIP类型的服务只能在集群内访问,而NodePort和LoadBalancer两种类型的服务都可以从集群外部访问。这三种服务有一个共同特点,就是理论上只能通过四层协议来访问。LoadBalancer类型的服务虽然也可以配置对应负载均衡HTTP/HTTPS属性,但也只提供了简单的代理,无法应对复杂的七层的策略路由场景。

Ingress的出现正式为了解决以上问题。Ingress的职责是将不同URL的请求转发给不同的服务,以实现复杂路由策略。典型的Ingress组件,是基于Nginx七层代理实现的Nginx Ingress Controller。

访问www.b**k.com/bookinfo相关的信息需要路由到Bookinfo这个服务进行处理,而访问www.b**k.com/subscription相关的信息需要路由到Subscription这个服务进行处理。

11.1.2 基础用法

我们需要定义Ingress模板去实现上一节中的功能。前面的内容中分别定义了Ingress的API版本、对象类型以及元数据,而具体的具有规则在Spec中指定。

apiVersion: networking.k8s.io/vlbetal

kind: Ingress

metadata:

  name: ingress-example

  annotations:

spec:

  rules:

  - host: b**k.com

    http:

     paths:

     -path: /bookinfo

      backend:

        serviceName: service-a

        servicePort: 80

     -path: /subscription

      backend:

       serviceName: service-b

       servicePort: 80

11.1.3 配置安全路由

上一节的定义中,实现了一个HTTP协议的站点路由。然后HTTP协议是明文在网络上传输的,容易被窃取消息。大多数情况下,我们需要部署一个安全的站点,采用HTTPS协议访问。本节将讲述如何部署安全路由。

如果是测试环境,通常只需要自签名证书即可,具体操作有以下几个步骤。

(1)使用openssl工具生成私钥和证书文件。

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyouttls.key -out tls.crt -subj "/CN=b88k.com/O=b88k.com"

(2) 创建Secret,并将私钥和证书存放在其中。

kubectl create secret tls book --key tls.key --cert tls.crt

(3) 修改Ingress模板文件,添加spec.tls配置。

apiVersion: networking.k8s.io/vlbetal

kind: Ingress

metadata:

  name: ingress-example

  annotations:

spec:

  tls:

- host:

    - b**k.com

secretName:b**k

  rules:

  - host:b**k.com

    http: 

     paths:

     -path: /bookinfo

      backend:

       serviceName: service-a

       servicePort: 80

     -path: /subscription

      backend:

       serviceName: service-b

       servicePort: 80

创建或者更新Ingress-example后,证书就会被Ingress控制器配置到对应的七层代理中。如果是在正式环境中,通常需要CA申请证书,并拿到私钥文件(tls.key)和证书链文件(tls.pem),这是可以跳过上面的第一步,只执行第2步和第3步即可。

关于安全路由的配置,需要注意以下几点:

tls.key和tls.crt字段名称不能更改。

Secret必须和Ingress在同一个命名空间,否则证书配置会失败。

tls.key、tls.crt存放的其实是key和crt的Base64编码文件,在Linux环境中可以用Base64解码对比证书信息。

11.1.4 全局配置和局部配置

有些场景下,需要对Ingress做更复杂的配置,例如让访问日志打印出统计Web性能,或将URL重定向到根路径。

对于常规的Nginx来说,只需要修改nginx.conf文件即可。然而对K8s来说,因为Nginx Ingress Controller封装了Nginx,所以我们不能直接修改Nginx的配置。

正确的做法是,通过在Ingress的编排文件中添加Annotation的方式配置局部参数,或者通过nginx-configuration这个ConfigMap的方式来配置全局参数。

11.1.5 实现原理

在Ingress的使用过程中,常常会遇到一些问题,比如客户端访问偶尔报:“502”或“504”错误、域名证书配置不生效、获取不到客户端真实IP地址等。

了解Ingress路由的实现原理,对于解决Ingress各种问题十分有帮助。本节将讲解Ingress是如何实现复杂的七层路由策略的。

以阿里云的Ingress组件为例,Ingress可以分为三个部分,分别是入口SLB(由Nginx-ingress-lb这个Service创建)、控制器以及Nginx代理,如下图所示。

Ingress的实现包含了两部分内容,一个是Controller,即Ingress控制器,另一个是Nginx代理。当创建一个Ingress对象的时候,控制器会作为Ingress对象和Nginx之间的翻译官,把Ingress中定义的路由配置转换为Nginx的配置。

如果Ingress定义有错误,翻译工作会失败,导致最新的规则没有办法下发到Nginx里。控制器日志的Nginx的Access/Error日志,都会汇总到Nginx

Ingress Controller这个Pod的标准输出,可以从Pod的标准输出查看控制器的日志或者Nginx的访问日志。

一般情况下,如果需要查看生效的Nginx配置,我们可登录到Nginx Ingress Controller容器里,查看配置文件/etc/nginx/nginx.conf。

为了减少对Nginx配置高频率加载这样的操作,Nginx Ingress Controller引入了Lua模块。Lua模块可以协助Nginx低“成本”地更新Upstream,以避免此类操作对业务的影响。

在Ingress控制器里获取Lua配置的方法如下。

(1)进入Pod。

kubectl -n kube-system exec -ti nginx-ingress-controller-7d7c69b5b8-d7qxw /bin/bash

(2)查看配置

curlhttp://127.0.0.1:10246/configuration/backends

有关第11章 流量路由Ingress(一)的更多相关文章

  1. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  2. ruby - rails 3 redirect_to 将参数传递给命名路由 - 2

    我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use

  3. ruby-on-rails - Rails 3,嵌套资源,没有路由匹配 [PUT] - 2

    我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle

  4. ruby - 安装libv8(3.11.8.13)出错,Bundler无法继续 - 2

    运行bundleinstall后出现此错误:Gem::Package::FormatError:nometadatafoundin/Users/jeanosorio/.rvm/gems/ruby-1.9.3-p286/cache/libv8-3.11.8.13-x86_64-darwin-12.gemAnerroroccurredwhileinstallinglibv8(3.11.8.13),andBundlercannotcontinue.Makesurethat`geminstalllibv8-v'3.11.8.13'`succeedsbeforebundling.我试试gemin

  5. ruby-on-rails - Rails - 从命名路由中提取 HTTP 动词 - 2

    Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba

  6. ruby-on-rails - 如何在 Rails 中设置路由的默认格式? - 2

    路由有如下代码:resources:orders,only:[:create],defaults:{format:'json'}resources:users,only:[:create,:update],defaults:{format:'json'}resources:delivery_types,only:[:index],defaults:{format:'json'}resources:time_corrections,only:[:index],defaults:{format:'json'}是否可以使用1个字符串为所有资源设置默认格式,每行不带“默认值”散列?谢谢。

  7. ruby-on-rails - Ruby 流量控制 : throw an exception, 返回 nil 还是让它失败? - 2

    我在思考流量控制的最佳实践。我应该走哪条路?1)不要检查任何东西并让程序失败(更清晰的代码,自然的错误消息):defself.fetch(feed_id)feed=Feed.find(feed_id)feed.fetchend2)通过返回nil静默失败(但是,“CleanCode”说,你永远不应该返回null):defself.fetch(feed_id)returnunlessfeed_idfeed=Feed.find(feed_id)returnunlessfeedfeed.fetchend3)抛出异常(因为不按id查找feed是异常的):defself.fetch(feed_id

  8. ruby - ri 有空文件 – Ubuntu 11.10, Ruby 1.9 - 2

    我正在运行Ubuntu11.10并像这样安装Ruby1.9:$sudoapt-getinstallruby1.9rubygems一切都运行良好,但ri似乎有空文档。ri告诉我文档是空的,我必须安装它们。我执行此操作是因为我读到它会有所帮助:$rdoc--all--ri现在,当我尝试打开任何文档时:$riArrayNothingknownaboutArray我搜索的其他所有内容都是一样的。 最佳答案 这个呢?apt-getinstallri1.8编辑或者试试这个:(非rvm)geminstallrdocrdoc-datardoc-da

  9. ruby - 如何捕获所有 HTTP 流量(本地代理) - 2

    我希望访问我机器上的所有HTTP流量(我的Windows机器-不是服务器)。据我了解,拥有一个本地代理是所有流量路线的必经之路。我一直在谷歌搜索但未能找到任何资源(关于Ruby)来帮助我。非常感谢任何提示或链接。 最佳答案 WEBrick中有一个HTTP代理(Rubystdlib的一部分)和here's一个实现示例。如果你喜欢生活在边缘,还有em-proxy伊利亚·格里戈里克。这postIlya暗示它似乎确实需要一些调整来解决您的问题。 关于ruby-如何捕获所有HTTP流量(本地代理)

  10. ruby - cucumber 的路由问题 - 2

    我正在使用rails3和cucumber,除了这个小问题,一切都很顺利GivenIamonthe"editautomobile"pageNoroutematches{:controller=>"automobiles",:action=>"edit"}(ActionController::RoutingError)现在路径在paths.rb中设置为edit_automobile_path在routes.rb中我有汽车作为资源,我搭建了它所以请告诉我我遗漏了什么,清楚地定义了路线并且匹配,因为我运行了rake路线并看到了路线。请指出正确的方向 最佳答案

随机推荐