k8s教程(service篇)-ingress 7层路由机制

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6


文章目录

  • ​​01 引言​​
  • ​​02 ingress概念​​
  • ​​2.1 简单例子​​
  • ​​03 完整案例​​
  • ​​3.1 部署ingress controller​​
  • ​​3.2 创建ingress策略​​
  • ​​3.3 客户端通过Ingress Controller访问后端webapp服务​​
  • ​​04 ingress资源对象配置​​
  • ​​4.1 定义​​
  • ​​4.2 规则 (rules)相关设置​​
  • ​​4.3 后端(Backend)设置​​
  • ​​4.4 路径类型(pathType)​​
  • ​​4.5 host通配符设置​​
  • ​​4.6 ingressClassName和ingressClass资源对象​​
  • ​​05 ingress策略配置​​
  • ​​5.1 转发到单个后端服务​​
  • ​​5.2 将同一域名的不同URL路径转发到不同的服务(Simple Fanout)​​
  • ​​5.3 将不同的域名(虚拟主机名)转发到不同的服务​​
  • ​​5.4 不使用域名的转发规则​​
  • ​​06 ingress的TLS安全设置​​
  • ​​6.1 生成秘钥和证书​​
  • ​​6.2 创建secret资源对象​​
  • ​​6.3 多个域名的配置​​

01 引言

声明:本文为《Kubernetes权威指南:从Docker到Kubernetes实践全接触(第5版)》的读书笔记

在前面,我们知道Service的表现形式为IP地址和端口号(​​ClusterIP:Port​​​),即工作在​​TCP/IP​​​层。而对于基于​​HTTP​​​的服务来说,不同的​​URL​​​地址经常对应到不同的后端服务或者虚拟服务器(​​Virtual Host​​​),这些应用层的转发机制仅通过​​Kubernetes​​​的​​Service​​机制是无法实现的。

所以Kubernetes从1.1版本开始引入Ingress资源对象,用于将Kubernetes集群外的客户端请求路由到集群内部的服务上,同时提供7层(HTTP和HTTPS)路由功能。

02 ingress概念

Kubernetes 使用了一个Ingress策略定义一个具体提供转发服务的Ingress Controller,两者结合,实现了基于灵活Ingress策略定义的服务路由功能。

如果是对Kubernetes集群外部的客户端提供服务,那么Ingress Controller实现的是类似于边缘路由器(Edge Router)的功能。需要注意的是,​Ingress只能以​HTTP​​HTTPS​提供服务,对于使用其他网络协议的服务,可以通过设置​Service​的类型​ type​​NodePort​​LoadBalancer​对集群外部的客户端提供服务

2.1 简单例子

使用Ingress进行服务路由时,Ingress Controller基于Ingress规则将客户端请求直接转发到Service对应的后端Endpoint(Pod)上,这样会跳过kube-proxy设置的路由转发规则,以提高网络转发效率,下图是一个典型的HTTP层路由的例子:

k8s教程(service篇)-ingress 7层路由机制_云原生


其中:

  • 对http:/mywebsite.com/api的访问将被路由到后端名为api的Service上;
  • 对http:/mywebsite.com/web的访问将被路由到后端名为web的Service上;
  • 对http:/mywebsite.com/docs的访问将被路由到后端名为docs的Service上。

03 完整案例

下面先通过一个完整的例子对​​Ingress Controller​​​的部署、​​Ingress​​​策略的配置,以及客户端如何通过​​Ingress Controller​​​访问服务对​​Ingress​​的原理和应用进行说明。

3.1 部署ingress controller

​Ingress Controller​​需要实现基于不同HTTP URL向后转发的负载分发规则, 并可以灵活设置7层负载分发策略。目前​​Ingress Controller​​​已经有许多实现方案, 包括​​Nginx​​​、​​HAProxy​​​、​​Kong​​​、​​Traefik​​​、​​Skipper​​​、​​Istio​​​等开源软件的实现,以及公有云​​GCE​​​、​​Azure​​​、​​AWS​​​等提供的​​Ingress​​​应用网关,用户可以参考官方网站根据业务需求选择适合的​​Ingress Controller​​。

本例基于​​Nginx​​提供的Ingress Controller进行说明。

在Kubernetes中,Ingress Controller 会持续监控 API Server 的 /ingress 接口 (即用户定义的到后端服务的转发规则)的变化。当/ingress接口后端的服务信息发生变化时,Ingress Controller会自动更新其转发规则

Nginx Ingress Controller 可以以​​Daemonset​​​或​​Deployment​​​模式进行部署,通常可以考虑通过设置 ​​nodeSelector​​​或 亲和性调度策略将其调度到固定的几个​​Node​​上提供服务。

对于客户端应用如何通过网络访问Ingress Controller

  • 通过在容器级别设置hostPort,将80和443端口号映射到宿主机上,这样客户端应用可以通过 URL地址“​​http://<NodeIP>:80​​​”或“​​https://<NodeIP>:443​​​”访问​​Ingress Controller​​(本例演示);
  • 可以配置​​Pod​​使用hostNetwork模式直接监听宿主机网卡的IP地址和端口号
  • 使用Service的NodePort将端口号映射到宿主机上

下面是Nginx Ingress Controller的​​YAML​​​定义,其中将Pod创建在​​namespace“nginx-ingress”​​中,通过nodeSelector“role=ingress-nginx-controller” 设置了调度的目标Node,并设置了​hostPort​将端口号映射到宿主机上供集群外部的客户端访问。该配置文件包含了​​Namespace、ServiceAccount、RBAC、 Secret、ConfigMap和Deployment​​等资源对象的配置。


namespace的定义如下:

# nginx-ingress-controller.yaml
apiVersion: v1
kind: Namespace
metadata:
name: nginx-ingress

ServiceAccount的定义如下:

apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-ingress
namespace: nginx-ingress

RBAC相关资源的定义如下:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: nginx-ingress
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch
- update
- create
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- list
- apiGroups:
- extensions
resources:
- ingresses
verbs:
- list
- watch
- get
- apiGroups:
- "extensions"
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- k8s.nginx.org
resources:
- virtualservers
- virtualserverroutes
- globalconfigurations
- transportservers
- policies
verbs:
- list
- watch
- get
- apiGroups:
- k8s.nginx.org
resources:
- virtualservers/status
- virtualserverroutes/status
verbs:
- update

---
kind: ClusterRoleBinding
apiversion: rbac.authorization.k8s.io/v1
metadata:
name: nginx-ingress
subjects:
- kind: ServiceAccount
name:nginx-ingress
namespace: nginx-ingress
roleRef:
kind: ClusterRole
name: nginx-ingress
apiGroup: rbac.authorization.k8s.io

Secret的定义如下:

apiVersion: v1
kind: Secret
metadata:
name: default-server-secret
namespace: nginx-ingress
type: Opaque
data:
tls.secret:
xxx...
tls.key:
xxxx...

ConfigMap的定义如下:

kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-config
namespace: nginx-ingress
data:

Deployment的定义如下:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress
namespace: nginx-ingress
spec:
replicas: 1
selector:
matchLabels:
app: nginx-ingress
template:
metadata:
labels:
app: nginx-ingress
spec:
nodeSelector:
role: ingress-nginx-controller
serviceAccountName: nginx-ingress
containers:
- image: nginx/nginx-ingress:1.7.2
imagePullPolicy: IfNotPresent
name: nginx-ingress
ports:
- name: http
containerPort: 80
hostPort: 80
- name: https
containerPort: 443
hostPort: 443
securityContext:
allowPrivilegeEscalation: true
runAsUser: 101 #nginx
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
args:
- -nginx-configmaps=$(POD NAMESPACE)/nginx-config
- -default-server-tls-secret=$(POD NAMESPACE)/default-server-secret

通过kubectl create命令创建nginx-ingress-controller:

k8s教程(service篇)-ingress 7层路由机制_kubernetes_02


查看nginx-ingress-controller容器,确认其正常运行:

k8s教程(service篇)-ingress 7层路由机制_nginx_03


用curl访问​​Nginx Ingress Controller​​所在宿主机的80端口,验证其服务是否正常,在没有配置后端服务时Nginx会返回404应答:

k8s教程(service篇)-ingress 7层路由机制_云原生_04

3.2 创建ingress策略

本例对域名​​mywebsite.com​​​的访问设置​​Ingress​​​策略,定义对其​​/demo​​​路径的访问转发到后端​​webapp Service​​的规则:

# mywebsite-ingress.yaml
apiversion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mywebsite-ingress
spec:
rules:
- host: mywebsite.com
http:
paths:
- path: /demo
pathType: ImplementationSpecific
backend:
service:
name: webapp
port:
number: 8080

通过该Ingress定义设置的效果:客户端对目标地址 http://mywebsite.com/demo的访问将被转发到集群内的服务“webapp”上,完整的URL为“http://webapp:8080/demo”。

在​​Ingress​​​策略生效之前,需要先确保​​webapp​​​服务正确运行。同时注意​​Ingress​​​中对路径的定义需要与后端​​webapp​​服务提供的访问路径一致,否则将被转发到一个不存在的路径上,引发错误。

创建:

k8s教程(service篇)-ingress 7层路由机制_nginx_05


一旦Ingress资源成功创建,​Ingress Controller​就会监控到其配置的路由策略,并更新到​Nginx​的配置文件中生效

以本例中的​​Nginx Controller​​​为例,它将更新其配置文件的内容为在​​Ingress​​中设定的路由策略。

登录一个​​nginx-ingress-controller Pod​​​,在​​/etc/nginx/conf.d​​目录下可以看到

​Nginx Ingress Controller​​​自动生成的配置文件​​default-mywebsite-ingress.conf​​​,查看其内容,可以看到对​​mywebsite.com/demo​​的转发规则的正确配置:

k8s教程(service篇)-ingress 7层路由机制_客户端_06

3.3 客户端通过Ingress Controller访问后端webapp服务

由于Ingress Controller容器通过​​hostPort​​​将服务端口号80映射到了宿主机上,所以客户端可以通过​​Ingress Controller​​​所在的​​Node​​​访问​​mywebsite.com​​提供的服务。

需要说明的是,客户端只能通过域名​​mywebsite.com​​​访问服务,这时要求客户端或者​​DNS​​​将​​mywebsite.com​​​域名解析到​​node​​​的真实​​IP​​地址上。

通过​​curl​​​访问​​mywebsite.com​​​提供的服务(可以用​​--resolve​​​参数模拟​​DNS​​​解析,目标地址为域名;也可以用​​-H'Host:mywebsite.com'​​​参数设置在​​HTTP​​​头中要访问的域名,目标地址为​​IP​​​地址),可以正确访问到​​myweb​​​服务​​/demo/​​的页面内容。

k8s教程(service篇)-ingress 7层路由机制_kubernetes_07



k8s教程(service篇)-ingress 7层路由机制_云原生_08

04 ingress资源对象配置

4.1 定义

一个ingress资源对象的定义如下:

apiversion: networking.k8s.io/v1 
kind: Ingress
metadata:
name: mywebsite-ingress
spec:
rules:
- host: mywebsite.com
http:
paths:
- path: /demo
pathType: ImplementationSpecific
backend:
service:
name: webapp
port:
number: 8080

Ingress资源主要用于定义路由转发规则,可以包含多条转发规则的定义,通​​spec.rules​​进行设置。下面对其中的关键配置进行说明。

4.2 规则 (rules)相关设置

规则 (rules)相关设置如下:

配置

描述

host(可选配置)

基于域名的访问,客户端请求将作用于指定域名的客户端请求

http.paths

一组根据路径进行转发的规则设置,每个路径都应配置相应的后端服务信息(服务名称和服务端口号)。只有客户端请求中的host和path都匹配之后,才会进行转发。

backend

目标后端服务,包括服务的名称和端口号。

Ingress Controller将根据每条rule中path定义的URL路径将客户端请求转发到backend定义的后端服务上。

如果一个请求同时被在Ingress中设置的多个URL路径匹配,则系统将以最长的匹配路径为优先。如果有两条同等长度的匹配路径,则精确匹配类型(Exct) 优先于前缀匹配类型(Prefix)。

4.3 后端(Backend)设置

后端通常被设置为目标服务(Service),通常还应该为不匹配任何路由规则 (rule)的请求设置一个默认的后端,以返回HTTP 404响应码来表示没有匹配的规则。

默认的后端服务可以由​​Ingress Controller​​​提供,也可以在​​Ingress​​资源对象中设置。

另外,如果后端不是以​​Kubernetes​​​的​​Service​​​提供的,则也可以设置为提供服务的资源对象,在这种情况下使用​​resource​​​字段进行设置。例如,下例中的​​Ingress​​​设置的后端地址为通过​​CRD“StorageBucket”​​定义的某个服务,同时设置为默认的后端:

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的定义,客户端对路径​​/icons​​​的访问将会被路由转发到后端名为“​​icon-assets​​​”的​​StorageBucket​​​服务上。不匹配任何规则的请求则侧被路由转发到默认的后端(​​defaultBackend​​)上。

4.4 路径类型(pathType)

对于每条规则(​​rule​​​)中的路径(​​path​​),都必须设置一个相应的路径类型, 目前支持以下3种类型。

  • ImplementationSpecific:系统默认,由​​IngressClass​​控制器提供具体实现;
  • Exact:精确匹配​​URL​​路径,区分大小写。
  • Prefix:匹配​​URL​​​路径的前缀,区分大小写,路径由“​​/​​​”符号分隔为一个个元素,匹配规则为逐个元素进行前缀匹配。如果路径中的最后一个元素是请求路径中最后一个元素的子字符串,则不会判断为匹配,例如​​/foo/bar​​​是路 径​​/foo/bar/baz​​​的前缀,但不是路径​​/foo/barbaz​​的前缀。

如表所示是常见的路径类型匹配规则示例:

路径类型

在ingress中配置的路径

请求路径

是否匹配

Prefix

/

(all paths)


Exact

/foo

/foo


Exact

/foo

/bar


Exact

/foo

/foo/


Exact

/foo/

/foo


Prefix

/foo

/foo,/foo/


Prefix

/foo/

/foo,/foo/


Prefix

/aaa/bb

/aaa/bbb


Prefix

/aaa/bbb

/aaa/bbb


Prefix

/aaa/bbb/

/aaa/bbb

是,忽略结尾的“/”

Prefix

/aaa/bbb

/aaa/bbb/

是,匹配结尾的“/”

Prefix

/aaa/bbb

/aaa/bbb/ccc

是,匹配子路径

Prefix

/aaa/bbb

/aaa/bbbxyz

否,无匹配前缀

Prefix

/,/aaa

/aaa/ccc

是,匹配的是/aaa前缀

Prefix

/,/aaa,/aaa/bbb

/aaa/bbb

是,匹配的是/aaa/bbb前缀

Prefix

/,/aaa,/aaa/bbb

/ccc

是,匹配了"/"

Prefix

/aaa

/ccc


Exact+Prefix配合

/foo(Prefix), /foo(Exact)

/foo

是,优先匹配Exact

在某些情况下,Ingress中的多个路径都会匹配一个请求路径。在这种情况 下,将优先考虑最长的匹配路径。如果两个匹配的路径仍然完全相同,则Exct类 型的规则优先于Prefix类型的规则生效。

4.5 host通配符设置

在规则(​​rule​​​)中设置的​​host​​​用于匹配请求中的域名(虚拟主机名),设置为完整的字符串表示精确匹配,例如:“​​foo.bar.com​​”。

Kubernetes从1.18版本开始支 持为host设置通配符“​​*​​​”,例如“​​*.foo.com​​”。

  • 精确匹配要求HTTP请求头中host参数的值必须与Ingress host设置的值完全一致 ;
  • 通配符匹配要求HTTP请求头中host参数的值需要与Ingress host设置的值的后缀一致,并且仅支持一层DNS匹配。

下面是常见的一些host通配符匹配规则示例:

ingress host 配置

请求头中的host值

是否匹配

*.foo.com

bar.foo.com


*.foo.com

baz.bar.foo.com

否,不是一层DNS匹配

*.foo.com

foo.com

否,不是一层DNS匹配

下例中的 Ingress包含精确匹配host"foo.bar.com"通配符匹配 host"*.foo.com"两条规则:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-wildcard-host
spec:
rules:
- host: "foo.bar.com"
http:
paths:
- pathType: Prefix
path: "/bar"
backend:
service:
name: service1
port:
number: 80
- host: "*foo.com"
http:
paths:
- pathType: Prefix
path: "/foo"
backend:
service:
name: service2
port:
number: 80

4.6 ingressClassName和ingressClass资源对象

在一个Kubernetes集群内,用户可以部署多个不同类型的Ingress Controller 同时提供服务,此时需要在Ingress资源上注明该策略由哪个Controller管理

Kubernetes在1.18版本之前,可以在​​Ingress​​​资源上设置一个名为​​kubernetes.io/ingress.class​​​的​​annotation​​​进行声明。但​​annotation​​​的定义没有标准规范,Kubernetes从1.18版本开始引入一个新的资源对象​​IngressClass​​​对其进行规范定义。在​​IngressClass​​​中除了可以设置​​Ingress​​​的管理​​Controller​​​,还可以配置更加丰富的参数信息(通过​​parameters​​字段进行设置)。

例如下面的​​IngressClass​​​定义了一个名为“​​example.com/ingress--controller‘​​​”的​​Controller​​和一组参数:

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

然后在​​Ingress​​​资源对象的定义中通过​​ingressClassName​​​字段引用该​​IngressClass​​​,标明使用其中指定的​​Ingress Controller​​和相应的参数:

apiversion: networking.k8s.io/v1 
kind: Ingress
metadata:
name: example-ingress
spec:
ingressclassName: external-lb
rules:
- host: "*example.com"
http:
paths:
- path: /example
pathType: Prefix
backend:
service:
name: example-service
port:
number: 80

05 ingress策略配置

为了实现灵活的路由转发策略,​​Ingress​​​策略可以按多种方式进行配置,下面对几种常见的​​Ingress​​转发策略进行说明。

5.1 转发到单个后端服务

基于这种设置,客户端发送到Ingress Controller的访问请求都将被转发到后端的唯一服务,在这种情况下,Ingress无须定义任何rule,只需设置一个默认的 后端服务(defaultBackend)。

通过如下所示的设置,对Ingress Controller的访问请求都将被转发到 “myweb:8080”这个服务:

# ingress-single-backend-service.yaml 
apiversion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
spec:
defaultBackend:
service:
name: webapp
port:
number: 8080

通过kubectl create命令创建后,查看ingress详情,可以看到系统为其设置了正确的后端目标地址:

k8s教程(service篇)-ingress 7层路由机制_kubernetes_09

5.2 将同一域名的不同URL路径转发到不同的服务(Simple Fanout)

这种配置常用于一个网站通过不同的路径提供不同的服务的场景,例如/web 表示访问Web页面,/api表示访问API接口,对应到后端的两个服务,只需在Ingress规则定义中设置将同一域名的不同URL路径转发到不同的后端服务,如图所示:

k8s教程(service篇)-ingress 7层路由机制_云原生_10

通过如下所示的设置,对"​​mywebsite.com/web​​​"的访问请求将被转发到"​​web- service:80​​​"服务,对"​​mywebsite.com/api​​​"的访问请求将被转发到"​​api-service: 80​​"服务:

# ingress-simple-fanout.yaml 
apiversion: networking.k8s.io/v1
kind: Ingress
metadata:
name: simple-fanout-example
spec:
rules:
- host: mywebsite.com
http:
paths:
- path: /web
pathType: ImplementationSpecific
backend:
service:
name: web-service
port:
number: 8080
- path: /api
pathType: ImplementationSpecific
backend:
service:
name: api-service
port:
number: 8081

通过kubectl create创建之后,查看ingress详情,可以看到系统为不同的path设置了转发规则:

k8s教程(service篇)-ingress 7层路由机制_云原生_11

5.3 将不同的域名(虚拟主机名)转发到不同的服务

这里 指基于host域名的Ingress规则将客户端发送到同一个IP地址的HTTP请求,根据不同的域名转发到后端不同的服务,例如foo.bar.com域名由service1提供服务,bar.foo.com域名由service2提供服务,如图所示:

k8s教程(service篇)-ingress 7层路由机制_kubernetes_12

通过如下所示的设置,请求头中host=foo.bar.com的访问请求将被转发到“service1:80”服务,请求头中host=bar.foo.com的访问请求将被转发到 “service2:80”服务:

apiVersion: networking.k8s.io/v1 
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: service1
port:
number: 80
- host: bar.foo.com
http:
paths:
- pathType: Prefix
path:
backend:
service:
name: service2
port:
number: 80

5.4 不使用域名的转发规则

如果在Ingress中不定义任何host域名,Ingress Controller则将所有客户端请求都转发到后端服务

例如下面的配置为将"​​<ingress-controller-ip>/demo​​​"的访问请求转发到"​​webapp:8080/demo​​"服务:

apiversion: networking.k8s.io/v1 
kind: Ingress
metadata:
name: test-ingress
spec:
rules:
- http:
paths:
path: /demo
pathType: Prefix
backend:
service:
name: webapp
port:
number: 8080

06 ingress的TLS安全设置

Kubernetes支持为Ingress设置TLS安全访问机制,通过为Ingress的host(域名)配置包含TLS私钥和证书的Secret进行支持

  • ​Ingress​​​资源仅支持单个​​TLS​​端口号443,并且假设在​​Ingress​​访问点(​​Ingress Controller​​)结束​​TLS​​安全机制,向后端服务转发的流量将以明文形式发送。
  • 如果​​Ingress​​中的​​TLS​​配置部分指定了不同的​​host​​,那么它们将根据通过​​SNI TLS​​扩展指定的虚拟主机名(这要求​​Ingress Controller​​支持​​SNI​​)在同一端口进行复用。

TLS Secret中的文件名必须为“tls.crt”和“tls.key”,它们分别包含用于TLS的证书和私钥,例如:

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加密客户端到负载均衡器的网络通道

用户需要确保在​​TLS​​​证书(​​tls.crt​​​)中包含相应​​host​​​的全限定域名(​​FQDN​​​)被包含在其​​CN​​​(​​Common Name​​)配置中。

​TLS​​​的功能特性依赖于​​Ingress Controller​​​的具体实现,不同​​Ingress Controller​​​的实现机制可能不同,用户需要参考各个​​Ingress Controller​​的文档。

下面以Nginx Ingress为例,对Ingress的TLS配置进行说明,步骤如下:

  1. 创建自签名的密钥和SSL证书文件;
  2. 将证书保存到Kubernetes的Secret资源对象中;
  3. 在Ingress资源中引用该Secret。

6.1 生成秘钥和证书

下面通过​​OpenSSL​​​工具生成密钥和证书文件,将参数​​-subj​​​中的​​/CN​​​设置为​​host​​​全限定域名(​​FQDN​​) “mywebsite.com”:

k8s教程(service篇)-ingress 7层路由机制_kubernetes_13


通过以上命令将生成​​tls.key​​​和​​tls.crt​​两个文件。

6.2 创建secret资源对象

然后根据tls.key和tls.crt文件创建secret资源对象,有以下两种方法。


方法一:使用​​kubectl create secret tl​​​s命令直接通过​​tls.key​​​和​​tls.crt​​​文件创建​​secret​​对象

k8s教程(service篇)-ingress 7层路由机制_容器化技术_14


方法二:编辑​​mywebsite-ingress-secret.yaml​​​文件,将​​tls.key​​​和​​tls.crt​​​文件的内容经过​​BASE64​​​编码的结果复制进去,使用​​kubectl create​​命令进行创建

# mywebsite-ingress-secret.yaml 
apiVersion: v1
kind: Secret
metadata:
name: mywebsite-ingress-secret
type: kubernetes.io/tls
data:
tls.crt:
MIIDAzCC.......
tls.key:
MIIEV......

然后使用kubectl create命令创建即可。

6.3 多个域名的配置

如果需要配置TLS的host域名有多个,例如前面第3种Ingress策略配置方式, 则SSL证书需要使用额外的一个x509 v3配置文件辅助完成,在[alt_names]段中完成多个DNS域名的设置

首先编写openssl.cnf文件,内容如下:

[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req distinguished name]
[v3 req]
basicConstraints = CA:FALSE
keyusage = nonRepudiation,digitalSignature,keyEncipherment subjectAltName = @alt_names
[alt names]
DNS.1 = mywebsite.com
DNS.2 = mywebsite2.com

接着使用OpenSSL工具完成密钥和证书的创建,生成自签名CA证书:

# openssl genrsa -out ca.key 2048
Generating RSA private key,2048 bit long modulus (2 primes)
·······················++++++++++++
············++++++++++++
e is 65537(0x10001)

# openssl req -x509 -new -nodes -key ca.key -days 5000 -out ca.crt -subj "/CN=mywebsite.com"

基于openssl.cnf和CA证书生成Ingress TLS证书:

# openssl genrsa -out ingress.key 2048
Generating RSA private key,2048 bit long modulus (2 primes)
·······················++++++++++++
············++++++++++++
e is 65537(0x10001)

# openssl req -new -key ingress.key -out ingress.csr -subj "/CN=mywebsite.com" -config openss1.cnf

# openssl x509 -req -in ingress.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out ingress.crt -days 5000 -extensions v3 req -extfile openssl.cnf
Signature ok
subject=/CN=mywebsite.com
Getting CA Private Key

然后根据​​ingress.key​​​和​​ingress.crt​​​文件创建secret资源对象,同样可以通过​​ kubectl create secret tls​​命令或YAML文件生成。这里通过命令行直接生成:

$ kubectl create secret tls mywebsite-ingress-secret --key ingress.key --cert ingress.crt
secret "mywebsite-ingress-secret"created

至此,​​Ingress​​​的​​TLS​​​证书和密钥就成功创建到​​Secret​​​对象中了, 下面创建​​Ingress​​​对象,在​​tls​​​段引用刚刚创建好的​​Secret​​对象:

# mywebsite-ingress-tls.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: mywebsite-ingress-tls
spec:
tls:
- hosts:
- mywebsite.com
secretName: mywebsite-ingress-secret
rules:
- host: mywebsite.com
http:
paths:
- path: /demo
pathType: Prefix
backend:
service:
name: webapp
port:
number: 8080

成功创建该Ingress资源之后,就可以通过HTTPS安全访问Ingress了。

以使用curl命令行工具为例,访问Ingress Controller的URL"https:/192.168.18.3/demo/":

k8s教程(service篇)-ingress 7层路由机制_nginx_15


阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: k8s