kubernetes网络 – ingress资源

欢迎加入本站的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资源详细配置:

https://kubernetes.io/docs/reference/kubernetes-api/service-resources/ingress-class-v1/#IngressClassSpec

在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/

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注