Kubernetes-7.Ingress
docker version:20.10.2
kubernetes version:1.20.1
本文概述Kubernetes Ingress基本原理和官方维护的Nginx-Ingress的基本安装使用。
Ingress是对集群中服务的外部访问进行管理的API对象,典型的访问方式是HTTP。Ingress可以提供负载均衡、SSL termination和基于名称的虚拟托管。
虽然K8S集群内部署的Pod、Service都有自己的IP,但是无法对外提供灵活的访问,NodePort虽然能够提供对外访问,但是灵活性有限。
Ingress是什么
Ingress公开了从集群外部到集群内服务的HTTP和HTTPS路由。流量路由由Ingress资源上定义的规则控制。
下面是一个将所有流量都发送到同一Service的简单Ingress示例:

可以将Ingress配置为服务提供外部可访问的URL、负载均衡流量、终止SSL/TLS,以及提供基于名称的虚拟主机等能力。Ingress控制器通常负责通过负载均衡器来实现Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。
Ingress不会公开任意端口或协议。将HTTP和HTTPS以外的服务公开到Internet时,通常使用Service.Type=NodePort或Service.Type=LoadBalancer类型的服务。
Ingress Controller
要使Ingress资源工作,集群必须有一个运行的Ingress控制器。
与作为kube-controller-manager可执行的一部分运行的其他类型的控制器不同,Ingress控制器不是随集群自动启动的。
Ingress controller能够监控集群变化,使集群始终保持期望的状态。能够实施感知Ingress路由规则集合的变化,再与API Server交互,获取Service、Pod在集群中的信息,而后根据信息更新代理服务。
Kubernetes项目目前维护AWS、GCE和Nginx Ingress控制器。
其他主流第三方项目:
- Apache APISIX Ingress 控制器
- HAProxy Ingress
- Traefik
- Envoy
- Nginxinc NGINX-Ingress
注意:Kubernetes社区维护的Nginx ingress与Nginx官方开发维护的并不是同一版本,Kubernetes官方维护的使用Go/Lua实现,Nginx官方维护的使用Go/Python实现。
可以在集群中部署任意数量的ingress控制器。创建ingress时,使用适当的ingress.class注解每个Ingress以表明在集群中如果有多个Ingress控制器时,应该使用哪个Ingress控制器。
如果不定义ingress.class,云提供商可能使用默认的Ingress控制器。
安装Ingress Controller
在自建的Kubernetes上部署Ingress Controller,选用Kubernetes官方维护的ingress-nginx:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.44.0/deploy/static/provider/baremetal/deploy.yaml
注意:官方的默认文件中使用的镜像是从Google镜像站点下载的,由于某些原因可能无法访问,请确保能够访问下载,不然会导致无法成功安装。也可以下载github上此项目的release版本进行安装。
在不同的平台上搭建Kubernetes集群,则部署方式中的配置也略有不同,官方提供各平台的常用一键部署方式,具体查看官方资料
此部署清单会使用NodePort方式暴露服务,但未指定NodePort具体端口,使用随机端口。此外会部署到集群中所有节点上,在正式环境使用中可能不符合需求,可以通过节点亲和性、污点容忍度等方式指定部署到有需要的节点上。如果需要修改则更改部署清单文件中相关配置即可。
部署清单中会创建一个名为ingress-nginx的Namespace,其属于Namespace级别的相关服务都会创建到此Namespace下。还会使用到ServiceAccount、ConfigMap、RBAC、Job控制器等,均会自动创建,需要了解则详细查看此部署清单即可。
Ingress使用示例
创建web服务,使用Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- name: http
containerPort: 80
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo $HOSTNAME>/usr/share/nginx/html/hostname.html"]
创建svc:
apiVersion: v1
kind: Service
metadata:
name: ingress-demo-svc
spec:
selector:
app: nginx
ports:
- name: web-port
protocol: TCP
port: 80
targetPort: 80
创建Ingress资源:
kind: Ingress
metadata:
name: ingress-demo
annotations:
# use the shared ingress-nginx
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: myingress.foo.org
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ingress-demo-svc
port:
number: 80
测试效果:
# 获取Ingress Controller的NodePort端口;ingress-nginx-controller service的NodePort使用部署文件默认随机端口
kubectl get svc -n ingress-nginx
# 在集群外部主机上添加解析记录:myingress.foo.org指定到集群中任意节点,然后访问
for i in {{0..5}}; do curl myingress.foo.org:32733/hostname.html ;done
nginx-deployment-7c88b85cf8-2kfr4
nginx-deployment-7c88b85cf8-2kfr4
nginx-deployment-7c88b85cf8-ngb49
nginx-deployment-7c88b85cf8-ngb49
nginx-deployment-7c88b85cf8-2kfr4
nginx-deployment-7c88b85cf8-2kfr4
#
Ingress控制器通过创建一个NodePort方式的svc作为代理将服务暴露,用户通过创建Ingress资源,将集群内的svc的Endpoint绑定到Ingress控制器的代理Upstream中,从而用户访问Ingress控制器暴露的资源,而后被代理到真正的应用Pod上。
与Service不同的是,Ingress能够实现更多的负载均衡代理策略,能够提供HTTPS的代理,能够更好的管理统一入口。
NodePort方式在多个节点上向外暴露提供了服务,却还是缺少统一性管理入口。在云环境服务商上,可以通过部署清单申请LB作为前置,在自建环境中则需要自部署一些相关处理方式,如裸机环境中的扩展中描述的。
Ingress资源
如上示例,Ingress同样需要使用apiVersion、kind和metadata字段。Ingress经常使用注解(annotations)来配置一些选项,具体取决于Ingress控制器,例如重写目标注解。不同的Ingress控制器支持不同的注解。
Ingress规约提供了配置负载均衡器或者代理服务器所需的所有信息。最重要的是,其中包含与所有传入请求匹配的规则列表。Ingress资源仅支持用于转发HTTP流量的规则。
常用字段:
ingress.spec.defaultBackend:默认后端。没有rules的Ingress将所有流量发送到同一后端。defaultBackend通常是Ingress控制器的配置选项,而非在Ingress资源中指定。
ingress.spec.ingressClassName:在Kubernetes1.18版本引入ingressClassName字段,对ingressClass资源的引用,且包含用来替代注解中的kubernetes.io/ingress.class字段。
ingress.spec.rules:Ingress规则。
ingress.spec.rules.host:基于域名代理。被代理服务的域名,指定了此字段,访问时必须使用域名。
ingress.spec.rules.http:基于路径代理。
ingress.spec.rules.http.paths.path:代理的路径。
ingress.spec.rules.http.paths.pathType:路径类型;ImplementationSpecific,Exact,Prefix。
ingress.spec.rules.http.paths.backend.resource:资源后端,指向ObjectRef。
ingress.spec.rules.http.paths.backend.service:服务后端,指向服务。
ingress.spec.rules.http.paths.backend.service.name:后端的名称,即svc的名称。
ingress.spec.rules.http.paths.backend.service.port:后端的端口,支持name或number方式。
ingress.spec.tls:TLS类型代理。
ingress.spec.tls.hosts:代理的域名。
ingress.spec.tls.secretName:secret中保存此域名证书的名称。
资源后端
Resource后端是一个ObjectRef。Resource后端的一种常见用法是将所有入站数据导向带有静态资产的对象存储后端。
注意:backend中的resource和service不能同时使用。
示例:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-resource-backend
spec:
defaultBackend:
resource:
apiGroup: k8s.example.com
kind: StorageBucket
name: static-assets
rules:
- http:
paths:
- path: /icons
pathType: ImplementationSpecific
backend:
resource:
apiGroup: k8s.example.com
kind: StorageBucket
name: icon-assets
路径类型
Ingress中的每个路径都需要有对应的路径类型(pathType)。未明确设置pathType无法通过合法性检查。
当前支持的路径类型有三种:
- ImplementationSpecific:对于这种路径类型,匹配方法取决于
IngressClass。具体实现可以将其作为单独的pathType处理或者与Prefix或Exact类型作相同处理。 - Exact:精确匹配URL路径,区分大小写。
- Prefix:基于以
/分隔的的URL路径前缀匹配,匹配区分大小写。
Exact是精确匹配,如路径/foo只能够匹配到请求路径/foo,/foo/视为不匹配。
Prefix是前缀匹配,以/作为分隔。如路径/foo可以被请求路径/foo、/foo/、/foo/abc匹配到。路径/能够匹配所有请求路径。
注意:在某些情况下,Ingress中的多条路径会匹配同一个请求。这种情况下最长的匹配路径优先。如果仍然有两条同等的匹配路径,则精确路径类型优先于前缀路径类型。
主机名通配符
主机名可以是精确匹配(如foo.bar.com)或者使用通配符来匹配(如*.bar.com)。精确匹配要求HTTP host头部字段与host字段值完全匹配。通配符匹配则要求HTTP host头部字段与通配符规则中的后缀部分相同。
| 主机 | host | 匹配与否 |
|---|---|---|
| *.foo.com | bar.foo.com | 匹配,后缀相同 |
| *.foo.com | baz.bar.foo.com | 不匹配,通配符仅覆盖了一个DNS标签 |
| *.foo.com | foo.com | 不匹配,通配符仅覆盖了一个DNS标签 |
Ingress类
Ingress可以由不同的控制器实现,通常使用不同的配置。每个Ingress应当指定一个类,也就是一个对IngressClass资源的引用。IngressClass资源包含额外的配置,其中包括应当实现该类的控制器名称。
IngressClass资源包含一个可选的parameters字段,可用于为该类引用额外配置。
示例:
具体解释可通过命令查看kubectl explain ingressClass
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: external-lb
spec:
controller: example.com/ingress-controller
parameters:
apiGroup: k8s.example.com
kind: IngressParameters
name: external-lb
在Kubernetes 1.18版本引入Ingress Class资源和ingressClassName字段之前,Ingress类是通过Ingress中的一个kubernetes.io/ingress.class注解来指定的。这个注解从未被正式定义过,但是得到了Ingress控制器的广泛支持。
默认Ingress类
将一个IngressClass资源的ingressclass.kubernetes.io/is-default-class注解设置为true,使其成为默认Ingress类。新创建的Ingress资源未指定IngressClassName字段时,将使用此默认Ingress类。集群中最多只能有一个IngressClass被标记为默认。
TLS示例
使用Ingress TLS必须首先创建TLS secret,secret必须包含名为tls.crt和tls.key的键名。
测试使用时,自签HTTP证书:
# 申请证书
openssl genrsa -out tls.key 2048
openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=Guangdong/L=Shenzhen/O=DevOps/CN=mytls.website.com
# 创建TLS secret
kubectl create secret tls mytls-ingress-tls --cert=tls.crt --key=tls.key
# 查看TLS secret
kubectl describe secret mytls-ingress-tls
创建TLS类型的Ingress:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-tls
annotations:
# use the shared ingress-nginx
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: mytls.website.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ingress-demo-svc
port:
number: 80
tls:
- hosts:
- mytls.website.com
secretName: mytls-ingress-tls
使用之前示例中的svc绑定到ingress资源下,创建好tls类型的ingress后,在集群外节点上通过tls访问即可。注意要使用Ingress 443端口的NodePort端口访问。
裸机环境中的扩展
在云环境下,网络负载均衡器是按需提供的,只需要有部署清单申请了即可使用向外部提供联系。在裸机环境中(自建私有Kubernetes集群环境)缺少这种提供,需要额外来设置。

以下解决方案:
- MetalLB
- NodePort
- 共享主机网络
- 自部署边缘网络组件(如HAproxy),运行在Kubernetes集群环境之外
- External IPs
具体使用可根据自身需求查阅相关资料。
Kubernetes-7.Ingress的更多相关文章
- kubernetes nginx ingress 使用记录
前言 ingress是一种可以暴露k8s集群内部service的方式,用户编辑配置文件定义一个ingress资源即可实现外部网络访问内网service. ingress controller是来管理所 ...
- kubernetes之ingress及ingress controller
什么是ingress Ingress是授权入站连接到达集群服务的规则集合. 从外部流量调度到nodeprot上的service 从service调度到ingress-controller ingres ...
- kubernetes nginx ingress controller部署
Kubernetes nginx ingress controller部署 1.下载kubernetes nginx的yaml文件 Wget https://raw.githubusercontent ...
- 使用traefik作为kubernetes的ingress
目录 说明 部署 创建一个独立的命名空间 配置rbac授权 配置secret 创建一个configmap用于存放traefik的配置文件 配置traefik的deployment文件 配置服务 通过p ...
- 为什么我不使用Kubernetes的Ingress
为什么我不使用Kubernetes的Ingress 很不幸,据我所知Kubernetes的文档不是很完美,这就是为什么有很多同学在使用它的时候会遇到很多的坑,Ingress这个组件就是这些坑中的一个. ...
- kubernetes Traefik ingress配置详解
理解Ingress 简单的说,ingress就是从kubernetes集群外访问集群的入口,将用户的URL请求转发到不同的service上.Ingress相当于nginx.apache等负载均衡方向代 ...
- 【转帖】kubernetes 部署ingress
kubernetes 部署ingress https://www.cnblogs.com/dingbin/p/9754993.html 明天尝试一下 之前的文档里面一直没有提 需要改host文件 我有 ...
- 【转】Kubernetes的Ingress控制器比较
Kubernetes的Ingress控制器比较 fiisio Kubernetes/云计算/资源调度/Go语言 21 人赞同了该文章 翻译:https://medium.com/flant-com/c ...
- kubernetes 部署ingress
kubernetes Ingess 是有2部分组成,Ingress Controller 和Ingress服务组成,常用的Ingress Controller 是ingress-nginx,工作的原理 ...
- 干货分享:如何使用Kubernetes的Ingress API
您可以通过使用诸如Kong for Kubernetes的Ingress控制器(使用自定义资源定义并提供许多插件)来极大地扩展Ingress资源的功能. Kubernetes正在整个技术行业中得到采用 ...
随机推荐
- OLAP、OLTP的介绍和比较(转载)
OLTP与OLAP的介绍 数据处理大致可以分成两大类:联机事务处理OLTP(on-line transaction processing).联机分析处理OLAP(On-Line Analytical ...
- 2. Linear Regression with One Variable
Speaker:Andrew Ng 这一次主要讲解的是单变量的线性回归问题. 1.Model Representation 先来一个现实生活中的例子,这里的例子是房子尺寸和房价的模型关系表达. 通过学 ...
- AtCoder Beginner Contest 173
比赛链接:https://atcoder.jp/contests/abc173/tasks A - Payment 题意 计算只用 $1000$ 元支付某个价格 $n$ 的找零是多少. 代码 #inc ...
- K8S(08)交付实战-交付jenkins到k8s集群
k8s交付实战-交付jenkins到k8s集群 目录 k8s交付实战-交付jenkins到k8s集群 1 准备jenkins镜像 1.1 下载官方镜像 1.2 修改官方镜像 1.2.1 创建目录 1. ...
- Atlas 分表功能
目录 分表原因 分表方式 Atlas 分表 分表思路 配置 Atlas 创建原表 创建分表 数据测试 分表原因 1.数据过多,访问缓慢 2.创建索引时重新排序,创建缓慢,并且占用大量的磁盘空间 分表方 ...
- leetcode29 两数相除 int 与移位
难受啊 考虑越界 考虑dividend为-2^31,用负数移位运算 class Solution { public: int divide(int dividend, int divisor) { i ...
- 数位dp【模板 + 老年康复】
学习博客: 戳这里 戳这里 "在信息学竞赛中,有这样一类问题:求给定区间中,满足给定条件的某个D 进制数或此类数的数量.所求的限定条件往往与数位有关,例如数位之和.指定数码个数.数的大小顺序 ...
- Redis五大类型及底层实现原理
目录 简单动态字符串链表字典跳跃表整数集合压缩列表对象 对象的类型与编码字符串对象列表对象哈希对象 集合对象有序集合对象类型检查与命令多态内存回收对象共享对象的空转时长 简单动态字符串 导读 Red ...
- 易漏的PEP8语法规范
import后定义函数的话, 两个空白行. 函数参数内'='左右不加空格. 在写函数说明时, 三引号得是三个双引号.
- 二维码 : QRcode
1 1 1 ★什么是二维码 通俗解释: 二维码是一种能存储信息的特定格式图片. 技术解释: 二维码(2-dimensional bar code) ,又称二维条码, 是用某种特定的几何图形按一定规律在 ...