K8S 快速入门(十七)实战篇:Ingress

Ingress 官方文档

一、为什么引入Ingress?

我们说k8s 的服务(service)时说暴露了service的三种方式ClusterIP、NodePort与LoadBalance,这几种方式都是在service的维度提供的,service的作用体现在两个方面,对集群内部,它不断跟踪pod的变化,更新endpoint中对应pod的对象,提供了ip不断变化的pod的服务发现机制,对集群外部,他类似负载均衡器,可以在集群内外部对pod进行访问。但是,单独用service暴露服务的方式,在实际生产环境中不太合适:

  • ClusterIP的方式只能在集群内部访问。
  • NodePort方式的话,测试环境使用还行,当有几十上百的服务在集群中运行时,NodePort的端口管理是灾难。
  • LoadBalance方式受限于云平台,且通常在云平台部署ELB还需要额外的费用。

所幸k8s还提供了一种集群维度暴露服务的方式,也就是ingress。ingress可以简单理解为service的service,他通过独立的ingress对象来制定请求转发的规则,把请求路由到一个或多个service中。这样就把服务与请求规则解耦了,可以从业务维度统一考虑业务的暴露,而不用为每个service单独考虑。

service是四层的负载均衡方案,Ingress是七层负载均衡访问方案
service通过iptables、ipvs实现。有缺陷:每一组业务都要开启nodePort,这样nodePort越来越多越来越难管理

解决方案:多加一层管理庞大的service
K8S 快速入门(十七)实战篇:Ingress_第1张图片

本来nodePort是映射到Service的,现在在往上抽一层,映射到上层,由上层再分发到service,此方案Ingress实现了
而Ingress是K8S中的资源,接口,可以由不同的控制器实现
Ingress-nginx是其中的一种实现,是对nginx的二次开发,来满足Ingress的规范。

举个例子,现在集群有api、文件存储、前端3个service,可以通过一个ingress对象来实现图中的请求转发:
K8S 快速入门(十七)实战篇:Ingress_第2张图片
ingress规则是很灵活的,可以根据不同域名、不同path转发请求到不同的service,并且支持https/http。

二、Ingress

Ingress 是对集群中服务的外部访问进行管理的 API 对象,典型的访问方式是 HTTP。

Ingress 可以提供负载均衡、SSL 终结和基于名称的虚拟托管。

1. 术语

为了表达更加清晰,本指南定义了以下术语:

  • 节点(Node): Kubernetes 集群中其中一台工作机器,是集群的一部分。
  • 集群(Cluster): 一组运行由 Kubernetes 管理的容器化应用程序的节点。 在此示例和在大多数常见的 Kubernetes 部署环境中,集群中的节点都不在公共网络中。
  • 边缘路由器(Edge router): 在集群中强制执行防火墙策略的路由器(router)。 可以是由云提供商管理的网关,也可以是物理硬件。
  • 集群网络(Cluster network): 一组逻辑的或物理的连接,根据 Kubernetes 网络模型 在集群内实现通信。
  • 服务(Service):Kubernetes 服务使用 标签选择算符(selectors)标识的一组 Pod。 除非另有说明,否则假定服务只具有在集群网络中可路由的虚拟 IP。

2. Ingress 是什么?

Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。

下面是一个将所有流量都发送到同一 Service 的简单 Ingress 示例:
K8S 快速入门(十七)实战篇:Ingress_第3张图片
可以将 Ingress 配置为服务提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及提供基于名称的虚拟主机等能力。 Ingress 控制器 通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。

Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的服务。

注意,Ingress是一个7层反向代理,如果你要暴露的是4层服务,还是需要走独立LoadBalancer+IP方式。

3. 环境准备

你必须具有 Ingress 控制器 才能满足 Ingress 的要求。 仅创建 Ingress 资源本身没有任何效果。

你可能需要部署 Ingress 控制器,例如 ingress-nginx。 你可以从许多 Ingress 控制器 中进行选择。

理想情况下,所有 Ingress 控制器都应符合参考规范。但实际上,不同的 Ingress 控制器操作略有不同。

说明: 确保你查看了 Ingress 控制器的文档,以了解选择它的注意事项。

4. 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: /testpath
        pathType: Prefix
        backend:
          service:
            name: test
            port:
              number: 80

与所有其他 Kubernetes 资源一样,Ingress 需要使用 apiVersion、kind 和 metadata 字段。 Ingress 对象的命名必须是合法的 DNS 子域名名称。 有关使用配置文件的一般信息,请参见部署应用、 配置容器、 管理资源。 Ingress 经常使用注解(annotations)来配置一些选项,具体取决于 Ingress 控制器,例如 重写目标注解。 不同的 Ingress 控制器 支持不同的注解。查看文档以供你选择 Ingress 控制器,以了解支持哪些注解。

Ingress 规约 提供了配置负载均衡器或者代理服务器所需的所有信息。 最重要的是,其中包含与所有传入请求匹配的规则列表。 Ingress 资源仅支持用于转发 HTTP 流量的规则。

4.1 Ingress 规则

每个 HTTP 规则都包含以下信息:

  • 可选的 host。在此示例中,未指定 host,因此该规则适用于通过指定 IP 地址的所有入站 HTTP 通信。 如果提供了 host(例如 foo.bar.com),则 rules 适用于该 host
  • 路径列表 paths(例如,/testpath),每个路径都有一个由 serviceNameservicePort 定义的关联后端。 在负载均衡器将流量定向到引用的服务之前,主机和路径都必须匹配传入请求的内容。
  • backend(后端)是 Service 文档中所述的服务和端口名称的组合。 与规则的 host 和 path 匹配的对 Ingress 的 HTTP(和 HTTPS )请求将发送到列出的 backend

通常在 Ingress 控制器中会配置 defaultBackend(默认后端),以服务于任何不符合规约中 path 的请求。

4.2 DefaultBackend

没有 rules 的 Ingress 将所有流量发送到同一个默认后端。 defaultBackend 通常是 Ingress 控制器 的配置选项,而非在 Ingress 资源中指定。

如果 hostspaths 都没有与 Ingress 对象中的 HTTP 请求匹配,则流量将路由到默认后端。

4.3 资源后端

Resource 后端是一个 ObjectRef,指向同一名字空间中的另一个 Kubernetes,将其作为 Ingress 对象。ResourceService 配置是互斥的,在 二者均被设置时会无法通过合法性检查。 Resource 后端的一种常见用法是将所有入站数据导向带有静态资产的对象存储后端。

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 之后,你可以使用下面的命令查看它:

kubectl describe ingress ingress-resource-backend

K8S 快速入门(十七)实战篇:Ingress_第4张图片

4.4 路径类型

Ingress 中的每个路径都需要有对应的路径类型(Path Type)。未明确设置 pathType 的路径无法通过合法性检查。当前支持的路径类型有三种:

  • ImplementationSpecific:对于这种路径类型,匹配方法取决于 IngressClass。 具体实现可以将其作为单独的 pathType 处理或者与 PrefixExact 类型作相同处理。
  • Exact:精确匹配 URL 路径,且区分大小写。
  • Prefix:基于以 / 分隔的 URL 路径前缀匹配。匹配区分大小写,并且对路径中的元素逐个完成。 路径元素指的是由 / 分隔符分隔的路径中的标签列表。 如果每个 p 都是请求路径 p 的元素前缀,则请求与路径 p 匹配。

    说明: 如果路径的最后一个元素是请求路径中最后一个元素的子字符串,则不会匹配 (例如:/foo/bar 匹配 /foo/bar/baz, 但不匹配 /foo/barbaz)。

示例:

类型 路径 请求路径 匹配与否?
Prefix / (所有路径)
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 否,使用默认后端
混合 /foo (Prefix), /foo (Exact) /foo 是,优选 Exact 类型

多重匹配:
在某些情况下,Ingress 中的多条路径会匹配同一个请求。 这种情况下最长的匹配路径优先。 如果仍然有两条同等的匹配路径,则精确路径类型优先于前缀路径类型。

5. 主机名通配符

主机名可以是精确匹配(例如“foo.bar.com”)或者使用通配符来匹配 (例如“*.foo.com”)。 精确匹配要求 HTTP host 头部字段与 host 字段值完全匹配。 通配符匹配则要求 HTTP host 头部字段与通配符规则中的后缀部分相同。

主机 host 头部 匹配与否?
*.foo.com bar.foo.com 基于相同的后缀匹配
*.foo.com baz.bar.foo.com 不匹配,通配符仅覆盖了一个 DNS 标签
*.foo.com foo.com 不匹配,通配符仅覆盖了一个 DNS 标签
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

6. Ingress 类

Ingress 可以由不同的控制器实现,通常使用不同的配置。 每个 Ingress 应当指定一个类,也就是一个对 IngressClass 资源的引用。 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

IngressClass 资源包含一个可选的 parameters 字段,可用于为该类引用额外配置。

6.1 废弃的注解

在 Kubernetes 1.18 版本引入 IngressClass 资源和 ingressClassName 字段之前, Ingress 类是通过 Ingress 中的一个 kubernetes.io/ingress.class 注解来指定的。 这个注解从未被正式定义过,但是得到了 Ingress 控制器的广泛支持。

Ingress 中新的 ingressClassName 字段是该注解的替代品,但并非完全等价。

  • 该注解通常用于引用实现该 Ingress 的控制器的名称,
  • 而这个新的字段则是对一个包含额外 Ingress 配置的 IngressClass 资源的引用, 包括 Ingress 控制器的名称。

6.2 默认 Ingress 类

你可以将一个特定的 IngressClass 标记为集群默认 Ingress 类。 将一个 IngressClass 资源的 ingressclass.kubernetes.io/is-default-class 注解设置为 true 将确保新的未指定 ingressClassName 字段的 Ingress 能够分配为这个默认的 IngressClass.

注意: 如果集群中有多个 IngressClass 被标记为默认,准入控制器将阻止创建新的未指定 ingressClassName 的 Ingress 对象。 解决这个问题只需确保集群中最多只能有一个 IngressClass 被标记为默认。

7. Ingress 类型

7.1 由单个 Service 来完成的 Ingress

现有的 Kubernetes 概念允许你暴露单个 Service (参见替代方案)。 你也可以通过指定无规则的 默认后端 来对 Ingress 进行此操作。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: test-ingress
spec:
  defaultBackend:
    service:
      name: test
      port:
        number: 80

如果使用 kubectl apply -f创建此 Ingress,则应该能够查看刚刚添加的 Ingress 的状态:

kubectl get ingress test-ingress

在这里插入图片描述
其中 203.0.113.123 是由 Ingress 控制器分配以满足该 Ingress 的 IP。

说明: 入口控制器和负载平衡器可能需要一两分钟才能分配 IP 地址。 在此之前,你通常会看到地址字段的值被设定为

7.2 简单扇出

一个扇出(fanout)配置根据请求的 HTTP URI 将来自同一 IP 地址的流量路由到多个 Service。 Ingress 允许你将负载均衡器的数量降至最低。例如,这样的设置:
K8S 快速入门(十七)实战篇:Ingress_第5张图片
将需要一个如下所示的 Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-fanout-example
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /foo
        pathType: Prefix
        backend:
          service:
            name: service1
            port:
              number: 4200
      - path: /bar
        pathType: Prefix
        backend:
          service:
            name: service2
            port:
              number: 8080

当你使用 kubectl apply -f 创建 Ingress 时:

kubectl describe ingress simple-fanout-example

K8S 快速入门(十七)实战篇:Ingress_第6张图片
Ingress 控制器将提供实现特定的负载均衡器来满足 Ingress, 只要 Service (service1,service2) 存在。 当它这样做时,你会在 Address 字段看到负载均衡器的地址。

说明: 取决于你所使用的 Ingress 控制器, 你可能需要创建默认 HTTP 后端服务。

7.3 基于名称的虚拟托管

基于名称的虚拟主机支持将针对多个主机名的 HTTP 流量路由到同一 IP 地址上。
K8S 快速入门(十七)实战篇:Ingress_第7张图片

以下 Ingress 让后台负载均衡器基于host 头部字段 来路由请求。

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

如果你创建的 Ingress 资源没有在 rules 中定义的任何 hosts,则可以匹配指向 Ingress 控制器 IP 地址的任何网络流量,而无需基于名称的虚拟主机。

例如,以下 Ingress 会将针对 first.bar.com 的请求流量路由到 service1, 将针对 second.foo.com 的请求流量路由到 service2, 而针对该 IP 地址的、没有在请求中定义主机名的请求流量会被路由(即,不提供请求标头) 到 service3

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

7.4 TLS

你可以通过设定包含 TLS 私钥和证书的Secret 来保护 Ingress。 Ingress 只支持单个 TLS 端口 443,并假定 TLS 连接终止于 Ingress 节点 (与 Service 及其 Pod 之间的流量都以明文传输)。 如果 Ingress 中的 TLS 配置部分指定了不同的主机,那么它们将根据通过 SNI TLS 扩展指定的主机名 (如果 Ingress 控制器支持 SNI)在同一端口上进行复用。 TLS Secret 必须包含名为 tls.crt 和 tls.key 的键名。 这些数据包含用于 TLS 的证书和私钥。例如:

HTTPS 深入浅出 - 什么是 SNI?

apiVersion: v1
kind: Secret
metadata:
  name: testsecret-tls
  namespace: default
data:
  tls.crt: base64 编码的 cert
  tls.key: base64 编码的 key
type: kubernetes.io/tls

在 Ingress 中引用此 Secret 将会告诉 Ingress 控制器使用 TLS 加密从客户端到负载均衡器的通道。 你需要确保创建的 TLS Secret 创建自包含 sslexample.foo.com 的公用名称(CN)的证书。 这里的公共名称也被称为全限定域名(FQDN)。

说明:
注意,默认规则上无法使用 TLS,因为需要为所有可能的子域名发放证书。 因此,tls 节区的 hosts 的取值需要域 rules 节区的 host 完全匹配。

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tls-example-ingress
spec:
  tls:
  - hosts:
      - https-example.foo.com
    secretName: testsecret-tls
  rules:
  - host: https-example.foo.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: service1
            port:
              number: 80

说明: 各种 Ingress 控制器所支持的 TLS 功能之间存在差异。请参阅有关 nginx、 GCE 或者任何其他平台特定的 Ingress 控制器的文档,以了解 TLS 如何在你的环境中工作。

7.5 负载均衡

Ingress 控制器启动引导时使用一些适用于所有 Ingress 的负载均衡策略设置, 例如负载均衡算法、后端权重方案和其他等。 更高级的负载均衡概念(例如持久会话、动态权重)尚未通过 Ingress 公开。 你可以通过用于服务的负载均衡器来获取这些功能。

值得注意的是,尽管健康检查不是通过 Ingress 直接暴露的,在 Kubernetes 中存在并行的概念,比如 就绪检查, 允许你实现相同的目的。 请检查特定控制器的说明文档( nginx, GCE) 以了解它们是怎样处理健康检查的。

8. 更新 Ingress

要更新现有的 Ingress 以添加新的 Host,可以通过编辑资源来对其进行更新:

kubectl describe ingress test

K8S 快速入门(十七)实战篇:Ingress_第8张图片

kubectl edit ingress test

这一命令将打开编辑器,允许你以 YAML 格式编辑现有配置。 修改它来增加新的主机:

spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - backend:
          serviceName: service1
          servicePort: 80
        path: /foo
        pathType: Prefix
  - host: bar.baz.com
    http:
      paths:
      - backend:
          serviceName: service2
          servicePort: 80
        path: /foo
        pathType: Prefix
..

保存更改后,kubectl 将更新 API 服务器中的资源,该资源将告诉 Ingress 控制器重新配置负载均衡器。

验证:

kubectl describe ingress test

K8S 快速入门(十七)实战篇:Ingress_第9张图片
你也可以通过 kubectl replace -f 命令调用修改后的 Ingress yaml 文件来获得同样的结果。

9. 跨可用区失败

不同的云厂商使用不同的技术来实现跨故障域的流量分布。详情请查阅相关 Ingress 控制器的文档。 请查看相关 Ingress 控制器 的文档以了解详细信息。

10. 替代方案

不直接使用 Ingress 资源,也有多种方法暴露 Service:

  • 使用 Service.Type=LoadBalancer
  • 使用 Service.Type=NodePort

三、Ingress实战

1. Ingress-nginx 部署文件

Ingress-nginx gitHub地址:最新版本地址:https://github.com/kubernetes/ingress-nginx/
指定版本的下载地址: https://github.com/kubernetes/ingress-nginx/tree/nginx-0.30.0/deploy
Ingress-nginx 官方网站地址:https://kubernetes.github.io/ingress-nginx/
K8S 快速入门(十七)实战篇:Ingress_第10张图片
K8S 快速入门(十七)实战篇:Ingress_第11张图片

部署文件介绍

  • ① namespace.yaml
    创建独立的命名空间 ingress-nginx
  • ② configmap.yaml
    一些属性配置
  • ③ rbac.yaml
    负责Ingress的RBAC授权的控制,其创建了Ingress用到的ServiceAccount、ClusterRole、Role、RoleBinding、ClusterRoleBinding
  • ④ with-rbac.yaml
    使用带rbac的方式创建ingress-controller,是整个ingress的核心部署文件。
  • ⑤ mandatory.yaml
    该文件整合了前面四项文件的内容,是用于实际部署ingress服务的yaml文件。即只需要使用该文件就可以完成ingress-controller的全部部署工作。

2. 部署Ingress-nginx

2.1 下载部署文件

# 下载所需的Ingress
# 部署ingress-controller,注意这个配置文件下载的地址需要解决科学上网的问题,建议从github下载即可
wget https://raw.githubusercontent.com/kubernetes/ingressnginx/master/deploy/mandatory.yaml
# 对外部提供服务所需的,是ingress controller的Service
wget https://raw.githubusercontent.com/kubernetes/ingressnginx/master/deploy/provider/baremetal/service-nodeport.yaml

2.2 部署 Ingress Controller

替换镜像地址:

# 修改mandatory.yaml,替换部署文件中默认镜像地址:(此镜像地址在国内无法下载)
quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.23.0

# 修改为(阿里云镜像地址),版本可以根据github tag来进行选择
registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingresscontroller:0.23.0

在这里插入图片描述

K8S 快速入门(十七)实战篇:Ingress_第12张图片

K8S 快速入门(十七)实战篇:Ingress_第13张图片

修改Ingress控制器的部署方式:
把deployment改成daemonset,让他在每一个节点都部署一个pod:

# 修改文件中部署方式的部分,将默认的Deployment修改为Daemonset,去掉replicas字段:
...省略部分...
apiVersion: apps/v1
kind: DaemonSet # 这里默认为Deployment,修改为Daemonset
metadata:
  name: nginx-ingress-controller
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  replicas: 1 # 删除这行
...省略部分...

K8S 快速入门(十七)实战篇:Ingress_第14张图片

K8S 快速入门(十七)实战篇:Ingress_第15张图片

K8S 快速入门(十七)实战篇:Ingress_第16张图片

在这里插入图片描述

Ingress的网络拓扑图:
K8S 快速入门(十七)实战篇:Ingress_第17张图片
现在我们已经在每个node节点上部署了ingress controller,接下来按照图上的,需要创建 ingress controller的Service

2.3 创建 ingress controller的Service

# 修改service-nodeport.yaml,增加NodePort,固定端口
apiVersion: v1
kind: Service
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    targetPort: 80
    nodePort: 30080 #http
    protocol: TCP
  - name: https
    port: 443
    targetPort: 443
    nodePort: 30443 #https
    protocol: TCP
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx

在这里插入图片描述>
K8S 快速入门(十七)实战篇:Ingress_第18张图片

要在指定的命名空间下才能看到:
K8S 快速入门(十七)实战篇:Ingress_第19张图片

命令梳理:

# 部署nginx-ingress-controller
kubectl apply -f mandatory.yaml
kubectl apply -f service-nodeport.yaml

# 查看Ingress组件
kubectl get pods -n ingress-nginx
kubectl get pod -n ingress-nginx --show-labels
kubectl get svc -n ingress-nginx

# 查看daemonset的状态
kubectl get daemonset -n ingress-nginx

# 验证ingress-nginx服务
curl http://192.168.66.10:30080/healthz -I
HTTP/1.1 200 OK
Server: nginx/1.17.8
Date: Mon, 03 Aug 2020 18:56:44 GMT
Content-Type: text/html
Content-Length: 0
Connection: keep-alive

3. 演示单个Service完成的Ingress

3.1 创建后端服务、以及后端服务的Service

# 创建后端服务
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: default
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: hub.kaikeba.com/java12/myapp:v1
        ports:
        - containerPort: 80

在这里插入图片描述

K8S 快速入门(十七)实战篇:Ingress_第20张图片

K8S 快速入门(十七)实战篇:Ingress_第21张图片

3.2 创建ingress资源

# 创建ingress资源,将nginx服务添加到Ingress-nginx中
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx
  namespace: default
  labels:
    app: nginx
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: ingress.kaikeba.com
    http:
      paths:
        - path: /
          backend:
            serviceName: nginx
            servicePort: 80

在这里插入图片描述

K8S 快速入门(十七)实战篇:Ingress_第22张图片

K8S 快速入门(十七)实战篇:Ingress_第23张图片

3.3 配置host,域名测试访问

K8S 快速入门(十七)实战篇:Ingress_第24张图片

K8S 快速入门(十七)实战篇:Ingress_第25张图片

4. 演示多个Service的简单扇出

4.1 再部署一个tomcat后端服务

# 创建tomcat后端服务,文件内容如下
apiVersion: v1
kind: Service
metadata:
  name: tomcat
  namespace: default
spec:
  selector:
    app: tomcat
  ports:
  - port: 8080
    targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: tomcat
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      containers:
      - name: tomcat
        image: hub.kaikeba.com/java12/tomcat:v1
        ports:
        - containerPort: 8080

在这里插入图片描述

K8S 快速入门(十七)实战篇:Ingress_第26张图片

K8S 快速入门(十七)实战篇:Ingress_第27张图片

4.2 方式一,用两个域名去转发

# 修改ingress-nginx.yaml,将tomcat服务增加到Ingress-nginx中。这里有多种策略配置。
# 不同域名转发到不同的服务
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx
  namespace: default
  labels:
    app: nginx
spec:
  rules:
  - host: ingress1.kaikeba.com
    http:
      paths:
      - path: /
        backend:
          serviceName: nginx
          servicePort: 80
  - host: ingress2.kaikeba.com
    http:
      paths:
      - path: /
        backend:
          serviceName: tomcat
          servicePort: 8080

在这里插入图片描述

K8S 快速入门(十七)实战篇:Ingress_第28张图片

在这里插入图片描述

K8S 快速入门(十七)实战篇:Ingress_第29张图片

K8S 快速入门(十七)实战篇:Ingress_第30张图片

K8S 快速入门(十七)实战篇:Ingress_第31张图片

4.3 方式二,不同url转发

# 同一域名,使用不同的URL转发到不同的服务上
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: nginx
  namespace: default
  labels:
    app: nginx
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /  # URL重写
spec:
  rules:
  - host: ingress.kaikeba.com
    http:
      paths:
      - path: /nginx
        backend:
          serviceName: nginx
          servicePort: 80
      - path: /tomcat
        backend:
          serviceName: tomcat
          servicePort: 8080

在这里插入图片描述

K8S 快速入门(十七)实战篇:Ingress_第32张图片

在这里插入图片描述

K8S 快速入门(十七)实战篇:Ingress_第33张图片

K8S 快速入门(十七)实战篇:Ingress_第34张图片

5. 演示TLS,https

这里用给tomcat服务添加证书为例。

  • 生成私钥

    openssl genrsa -out tls.key 2048
    

    K8S 快速入门(十七)实战篇:Ingress_第35张图片

  • 自签发证书

    openssl req -new -x509 -key tls.key -out tls.crt -subj/C=CN/ST=Shanghai/L=Shanghai/O=DevOps/CN=tomcat.ikiwi.me
    

    对指定域名追加证书
    K8S 快速入门(十七)实战篇:Ingress_第36张图片

  • 创建K8S使用的证书配置文件Secret

    kubectl create secret tls tomcat-ingress-secret --cert=tls.crt --key=tls.key
    

    创建k8s的secret,叫tomcat-ingress-secret,携带了tls.crt和tls.key
    在这里插入图片描述

  • 查看Secret描述

    kubectl describe secret tomcat-ingress-secret
    

    K8S 快速入门(十七)实战篇:Ingress_第37张图片

  • 创建带tls认证的Ingress,指向tomcat后端服务

    # 创建好后,访问服务,结果如下图所示,由于是自签发证书不受信任。HTTPS已可以成功访问。
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: ingress-tomcat-tls
      namespace: default
      annotations:
        kubernetes.io/ingress.class: "nginx" #指定使用哪个controller,我们用的是ingress nginx,所以这里写"nginx"
      labels:
        app: tomcat
    spec:
      tls: #tls下指定使用证书的域名 和 要使用secret 证书
      - hosts:
        - ingress.kaikeba.com
        secretName: tomcat-ingress-secret #存储了tls证书的secret名字
      rules:
      - host: ingress.kaikeba.com
        http:
          paths:
            - backend:
                serviceName: tomcat
                servicePort: 8080
    

    在这里插入图片描述

    K8S 快速入门(十七)实战篇:Ingress_第38张图片
    K8S 快速入门(十七)实战篇:Ingress_第39张图片
    443是https方式访问的端口,外网访问需要访问30443映射到443
    注意: 30443 是ingress-service他的https转发端口。见2.3
    K8S 快速入门(十七)实战篇:Ingress_第40张图片
    K8S 快速入门(十七)实战篇:Ingress_第41张图片

你可能感兴趣的:(#,K8S,k8s,ingress)