欢迎加入本站的kubernetes技术交流群,微信添加:加Blue_L。
ingress主要用来将集群内的http服务暴露到集群外。ingress提供负载均衡,ssl/tls终结和基于名称的虚拟服务器功能。
下图是ingress架构图:
ingress用来暴露http和https服务,如果是其他的服务协议,无法通过ingress进行暴露,需要使用nodeport或者loadbalancer类型的服务。
ingress控制器
要使用配置ingress,需要集群内存在ingress控制器,ingress控制器负责将ingress的定义配置到具体的控制器服务上。kubernetes支持的ingress控制器参考:
https://kubernetes.io/docs/concepts/services-networking/ingress-controllers/
此处我们使用nginx-ingress进行配置和演示,参考下面文档进行安装配置:
https://github.com/kubernetes/ingress-nginx/tree/main/charts/ingress-nginx
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.3/deploy/static/provider/baremetal/deploy.yaml
kubectl annotate ingressclasses nginx ingressclass.kubernetes.io/is-default-class=true
# 改成LoadBalancer类型
kubectl edit svc -n ingress-nginx ingress-nginx-controller
# 修改deployment
# - --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
# - --enable-ssl-passthrough
kubectl edit deployments.apps -n ingress-nginx ingress-nginx-controller
# 创建测试应用
kubectl apply -f https://github.com/istio/istio/blob/1.11.3/samples/helloworld/helloworld.yaml
ingress
创建ingress资源进行测试。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: helloworld
port:
number: 5000
ingress资源的具体定义参考:
https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-v1/#IngressSpec
kubernetes对url路径匹配规则参考:
https://kubernetes.io/docs/concepts/services-networking/ingress/#examples
kubernetes对host header的匹配规则参考:
https://kubernetes.io/docs/concepts/services-networking/ingress/#hostname-wildcards
ingress class
ingress资源可以由不同的ingress控制器实现,不同的ingress控制器通常具有不同的配置。ingress class定义这些不同的控制器。每个ingress资源可以指定不同的ingress class以使用不同的控制器。
ingressclass资源详细配置:
在1.18之前的版本中使用过kubernetes.io/ingress.class这个注解指定使用哪个ingress控制器,1,18之后开始使用ingress.ingressClassName配置使用哪个ingress控制器。
通过给ingressclass指定ingressclass.kubernetes.io/is-default-class注解为true,可以将其设置为默认的ingress控制器,如果ingress资源本身没有自定ingressClassName字段的话,则默认会使用这个控制器。
ingress类型
一个service类型
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
spec:
defaultBackend:
service:
name: helloworld
port:
number: 5000
不同路径对应不同service
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: simple-fanout-example
spec:
rules:
- host: foo.bar.com
http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: helloworld
port:
number: 5000
- path: /bar
pathType: Prefix
backend:
service:
name: service2
port:
number: 8080
虚拟服务器类型
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
# 定义更多的路径匹配规则
# 其他请求都到service3
#- http:
# paths:
# - pathType: Prefix
# path: "/"
# backend:
# service:
# name: service3
# port:
# number: 80
TLS
通过配置ingress资源的tls配置,可以对传输层进行加密,kubernetes当前只支持443一个端口的tls配置。tls链接会在ingress控制器处终结,将明文转发给后端服务。通常443端口会暴露多个服务,ingress控制器会根据tls中的sni扩展的主机名决定使用哪个秘钥对进行加密传输。tls secret中必须要包含tls.crt和tls.key字段。
[root@master1 05]# openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes -subj '/CN=https-test.foo.com'
[root@master1 05]# kubectl create secret tls testsecret-tls --key=key.pem --cert=cert.pem
[root@master1 05]# kubectl get secret testsecret-tls -oyaml
如果没有配置tls.secretName这个字段的话,会根据sni中的host进行路由匹配(透传)。如果配置了,则ingress控制器会使用这个秘钥对对传输进行加密,tls链接会在ingress控制器处终结。如果sni的host与ingressRule中的Host header冲突的话,会使用sni host进行tls终结,Host header进行路由。
不指定secret
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-test
spec:
ingressClassName: nginx
tls:
- hosts:
- https-test.foo.com
# secretName: testsecret-tls
rules:
- host: https-test.foo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: helloworld
port:
number: 5000
在ingress-nginx情况下,如果没有配置secretName会使用一个默认的秘钥对,需要下列配置配置进行测试:
kubectl edit deployments.apps -n ingress-nginx ingress-nginx-controller加入–enable-ssl-passthrough
kubectl annotate ingress tls-test nginx.ingress.kubernetes.io/ssl-passthrough=true
# 修改tls中的host与rules中的host为不同的值
curl -v -k --resolve https-test.foo.com:443:192.168.64.3 https://https-test.foo.com/hello
# 修改tls中的host与rules中的host为相同的值
curl -v -k --resolve https-test.foo.com:443:192.168.64.3 https://https-test.foo.com/hello
指定secret
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-test-ingress
spec:
tls:
- hosts:
- https-test.foo.com
secretName: testsecret-tls
rules:
- host: https-test1.foo.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: helloworld
port:
number: 5000
curl -v -k -H'Host: https-test1.foo.com' --resolve https-test.foo.com:443:192.168.64.3 https://https-test.foo.com/hello
ingress-nginx
https://kubernetes.github.io/ingress-nginx/
更新ingress
直接使用kubectl edit ingress test或apply或patch等命令可以直接更新ingress资源。
参考
https://kubernetes.io/docs/concepts/services-networking/ingress/