kubernetes基础实践之Ingress

Ingress是什么?

ingress的英文翻译为:进入; 进入权; 入境权;
在k8s中,Ingress公开了从群集外部到群集内 services (services是什么后面会介绍) 的HTTP和HTTPS路由。 流量路由由Ingress资源上定义的规则控制。

    internet
        |
   [ Ingress ]
   --|-----|--
   [ Services ]

Ingress 可以提供负载平衡,路由,流量控制,SSL 等功能,用于管理对集群中服务的外部访问,通常是 HTTP/HTTPS。

Ingress定义

最小的 Ingress 资源实例:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: test-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /testpath
        backend:
          serviceName: test
          servicePort: 80

与所有其他 Kubernetes 资源一样,Ingress 需要使用 apiVersion, kind, 和 metadata字段。 Ingress spec具有配置负载平衡器或代理服务器所需的所有信息。
但是需要注意是,ingress不是具体的如何控制请求,它只包含与所有传入请求匹配的规则列表。 Ingress 资源仅支持用于定向HTTP流量的规则。

每个HTTP规则都包含以下信息: * host 选项。在此示例中,未指定主机,因此该规则适用于通过指定 IP 地址的所有入站 HTTP 通信。 如果提供了 host 地址(例如foo.bar.com),则规则适用于该主机。 * 路径列表(例如,/testpath ),每个路径都有一个由 serviceName 和 servicePort 定义的关联后端。在负载均衡器将流量定向到引用的服务之前,主机和路径都必须匹配传入请求的内容。

backend是service和端口的组合。与规则的主机和路径匹配的对 Ingress 的 HTTP 和 HTTPS 请求将发送到列出的后端。

默认backend

默认backend没有设定规则的 Ingress 将所有流量发送到单个默认后端。 默认后端通常是 Ingress控制器的配置选项,并且未在Ingress资源中指定。如果没有主机或路径与 Ingress 对象中的 HTTP 请求匹配,则流量将路由到您的默认backend。

https安全证书tls

您可以通过指定包含TLS私钥和证书的 Secret来加密 Ingress。 目前,Ingress 只支持单个 TLS 端口,443,并假定 TLS 终止。 如果 Ingress 中的 TLS 配置部分指定了不同的主机,那么它们将根据通过 SNI TLS 扩展指定的主机名(如果 Ingress 控制器支持 SNI)在同一端口上进行复用。 TLS Secret 必须包含名为 tls.crttls.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 中引用此秘钥会告诉 Ingress 控制器使用 TLS 保护从客户端到负载均衡器的通道。 您需要确保创建包含 sslexample.foo.com 的 TLS 秘钥的 CN 的证书。

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: tls-example-ingress
spec:
  tls:
  - hosts:
    - sslexample.foo.com
    secretName: testsecret-tls
  rules:
    - host: sslexample.foo.com
      http:
        paths:
        - path: /
          backend:
            serviceName: service1
            servicePort: 80

负载均衡

Ingress 控制器使用一些适用于所有 Ingress 的负载均衡策略设置进行自举,例如负载平衡算法、后端权重方案等。 更高级的负载平衡概念(例如,持久会话、动态权重)尚未通过 Ingress 公开。 那怎么办?其实负载均衡可以通过用于真正实现ingress的ingress controller来实现,比如我们熟悉的Nginx,Kong,Traefix,Envoy等

什么是服务?

服务的概念其实比较简单(注意在k8s中服务实现其实并不简单,因为涉及到分布式网络部分),所以放到最后来讲。没错,服务就是我们常说的服务,即一组相同的http或tcp服务。比如一个图片处理 backend,它运行了3个实例,共同来提高图片处理的能力。
Kubernetes Service 定义了这样一种抽象:逻辑上的一组 Pod,一种可以访问它们的策略 —— 通常称为微服务。 这一组 Pod 能够被 Service 访问到,通常是通过 selector实现的。下面是一个服务定义的例子:
例如,假定有一组 Pod,它们对外暴露了 9376 端口,同时还被打上 app=MyApp 标签。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

上述配置创建一个名称为 “my-service” 的 Service 对象,它会将请求代理到使用 TCP 端口 9376,并且具有标签 "app=MyApp" 的 Pod 上。 Kubernetes 为该服务分配一个 IP 地址(有时称为 “集群IP” ),该 IP 地址由服务代理使用。
同时该服务,可以通过ingress对外提供端口服务。

一种特殊情况,没有 selector 的 Service

服务最常见的是抽象化对 Kubernetes Pod 的访问,但是它们也可以抽象化其他种类的后端。 比如下面的情况:

  • 希望在生产环境中使用外部的数据库集群,但测试环境使用自己的数据库。
  • 希望服务指向另一个 Namespace中或其它集群中的服务。
  • 希望把部分服务迁移到 Kubernetes ,但是需要和物理机服务进行通信。

在任何这些场景中,都能够定义没有 selector 的 Service。 比如我们希望在k8s中的服务能够和外部的redis进行通信,redis提供的服务端口为6379,部署在192.0.2.42这台物理机上。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 6379

由于此服务没有选择器,因此 不会 自动创建相应的 Endpoint 对象。 您可以通过手动添加 Endpoint 对象,将redis的服务手动映射到运行该服务的网络地址和端口:

apiVersion: v1
kind: Endpoints
metadata:
  name: my-service
subsets:
  - addresses:
      - ip: 192.0.2.42
    ports:
      - port: 6379

好了,今天简单介绍了ingress和service,但是这些都至少定义部分,是k8s的核心概念,必须要理解清楚。迄今为止,我们的服务在外面还访问不了,后面我们开始理解ingress controller用服务能够真正用起来。

你可能感兴趣的:(kubernetes基础实践之Ingress)