k8s指南-Ingress

目录:
(1)k8s指南-概述
(2)k8s指南-架构
(3)k8s指南-工作负载(1)
(4)k8s指南-工作负载(2)
(5)k8s指南-工作负载(3)
(6)k8s指南-工作负载(4)
(7)k8s指南-Service
(8)k8s指南-Ingress
(9)k8s指南-DNS与服务发现
(10)K8S指南-平滑升级与自动扩缩容

Ingress是k8s集群中负责管理服务外部访问的API对象。


概述

什么是Ingress

通常情况下,service和pod仅可在集群内部网络中通过ip地址访问。如果想从集群外部访问集群内部,则必须要有Ingress。

Ingress则相当于一个服务网关,控制着从集群外部到集群内部的HTTP/HTTPS的访问路由。下面是一个简单的ingress对流量的路由示意图:

在这里插入图片描述
可以给Ingress配置提供外部可访问的URL、负载均衡、SSL和基于名称的虚拟主机等。

为什么需要Ingress

在Kubernetes中,为了使外部的应用能够访问集群内的service,最为常用的是使用NodePortLoadBalancer两种类型的service。但这两种类型的服务各有缺点:NodePort方式会占用很多集群机器的端口;而LoadBanlancer类型要求k8s必须跑在支持的云上。当同时存在多个LoadBanlancer类型的Service时,就会占用大量公网ip地址,而Ingress正式为了解决以上两种问题而生的。

Ingress资源

Ingress必须要有Ingress控制器,单独的创建一个Ingress是没有任何效果的。通常我们说Ingress,实际上指的是Ingress配置和Ingress控制器。

Ingress控制器类似于nginx,Ingress类似于nginx的配置文件。如果只安装nginx,而没有nginx的配置文件,则此nginx将毫无意义;反过来,若只有nginx的配置文件,但没安装nginx,则配置文件无运行载体

下面是一个流量路由示意图:

在这里插入图片描述

从中可以看出,客户端首先对 ngdemo.qikqiak.com 执行 DNS 解析,得到 Ingress 控制器所在节点的 IP,然后客户端向 Ingress 控制器发送 HTTP 请求,然后根据 Ingress 对象里面的描述匹配域名,找到对应的 Service 对象,并获取关联的 Endpoints 列表,将客户端的请求转发给其中一个 Pod。

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

Ingress 控制器

Ingress控制器有很多种,有官方维护的如ingress-nginx,AWS和GCE,也有第三方的。

下面安装Ingress-nginx控制器。

按照官方文档官方yaml文,直接运行yaml文件的话国内会由于访问不了google仓库而报错。网上有人建了一个中转站,将google镜像转成docker镜像,然后通过脚本拉下来之后重新打原来的标签。因此只需要执行脚本就能将镜像拉到本地了(传送门)。

下载官方yaml文件,将其中的image中的数字摘要去掉(结果如:image: registry.k8s.io/ingress-nginx/controller:v1.6.4),这样就能启动Ingress控制器了。执行kubectl get all -n ingress-nginx,结果如下所示:

NAME                                           READY   STATUS      RESTARTS   AGE
pod/ingress-nginx-admission-create-9jpfg       0/1     Completed   0          5h54m
pod/ingress-nginx-admission-patch-5c6qd        0/1     Completed   1          5h54m
pod/ingress-nginx-controller-5b648bf48-wrsnd   1/1     Running     0          5h54m

NAME                                         TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             LoadBalancer   10.98.207.53    localhost     80:31871/TCP,443:31482/TCP   5h54m
service/ingress-nginx-controller-admission   ClusterIP      10.104.227.61   <none>        443/TCP                      5h54m

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/ingress-nginx-controller   1/1     1            1           5h54m

NAME                                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/ingress-nginx-controller-5b648bf48   1         1         1       5h54m

NAME                                       COMPLETIONS   DURATION   AGE
job.batch/ingress-nginx-admission-create   1/1           7s         5h54m
job.batch/ingress-nginx-admission-patch    1/1           8s         5h54m

这个Ingress控制器创建之后会带一个名为nginxIngressClass,接下来我们创建Ingress,指定ingressClassName: nginx 即可使用ingress-nginx控制器。当然,也要创建Ingress路由的service和pod:

# my-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  selector:
    matchLabels:
      app: my-nginx
  template:
    metadata:
      labels:
        app: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  labels:
    app: my-nginx
spec:
  ports:
  - port: 80
    protocol: TCP
    name: http
  selector:
    app: my-nginx
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-nginx
  namespace: default
spec:
  ingressClassName: nginx  # 使用 nginx 的 IngressClass(关联的 ingress-nginx 控制器)
  rules:
  - host: ngdemo.qikqiak.com  # 将域名映射到 my-nginx 服务
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:  # 将所有请求发送到 my-nginx 服务的 80 端口
            name: my-nginx
            port:
              number: 80
# 不过需要注意大部分Ingress控制器都不是直接转发到Service
# 而是只是通过Service来获取后端的Endpoints列表,直接转发到Pod,这样可以减少网络跳转,提高性能

执行kubectl get ingress -n ingress-nginx查看Ingress:

NAME                    CLASS   HOSTS                ADDRESS     PORTS   AGE
my-nginx                nginx   ngdemo.qikqiak.com   localhost   80      94m

可以看到Ingress控制器地址为localhost,修改/etc/hosts,将域名ngdemo.qikqiak.com指向本地。然后在浏览器访问该域名,结果如下:
在这里插入图片描述

访问该域名,实际上就是访问Ingress控制器,Ingress控制器根据Ingress配置的规则,将请求转发给my-nginx服务,从而返回该页面。

Ingress

下面是一个最简单的Ingress定义:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: minimal-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx-example
  rules:
  - http:
      paths:
      - path: /testpath
        pathType: Prefix
        backend:
          service:
            name: test
            port:
              number: 80

如上所示,Ingress spec中包含配置loadbalancerproxy server的所有信息。最重要的是,它包含了一个匹配所有入站请求的规则列表。目前,Ingress只支持HTTP(S)请求。

如果省略ingressClassName,那么你应该定义一个默认的Ingress class
当然也有一些Ingress控制器不需要默认的IngressClass。比如Ingress-NGINX,它可以通过参数--watch-ingress-without-class来配置,不过仍然推荐指定一个默认IngressClass

Ingress规则

每个Http规则包含以下内容:

  • 一个可选的主机。在示例中没有指定主机,所以该规则适配所有通过指定ip地址进来的http请求。如果指定了host(比如foo.bar.com),则入站请求还需要匹配主机。也就是说请求中的host与规则中的host相同才允许进入。
  • 路径列表(例如/testpath)。每个路径都有一个与之关联的,由service.nameservice.port.nameservice.port.number定义的后端服务(如test:80)。只有当host和path都匹配了,才能被负载均衡器转发给对应的服务。
  • 后端是Service文档中描述的服务和端口的组合。匹配了入站规则的请求将被发送给后端。

通常会在Ingress 控制器中配置一个默认的后端,以便没有匹配入站规则的请求被转发给这个默认后端。

默认后端

如果没有设置Ingress规则,则所有的流量将被发送到默认后端 defaultBackend,也就是说,如果没有设置rules,则defaultBackend是必须有的。注意,默认后端通常是Ingress控制器的常规配置项,而不是在Ingress中指定

默认后端用于处理未匹配任何规则的请求,如果没有指定默认后端,则这些请求将被转发到Ingress控制器。

资源后端

事实上后端除了引用一个Service之外,还可以通过一个resource资源进行关联,这也是所谓的资源后端。资源后端是一个对象引用,指向同一个命名空间下的另一个k8s资源。资源后端和服务后端是互斥的,在二者均被设置时会无法通过合法性检查。

资源后端的一种常见用法是将所有入站数据转发到对象存储后端进行存储。

下面是一个资源Ingress:

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之后,你可以通过describe命令查看:

kubectl describe ingress ingress-resource-backend
Name:             ingress-resource-backend
Labels:           <none>
Namespace:        default
Address:          
Ingress Class:    <none>
Default backend:  APIGroup: k8s.example.com, Kind: StorageBucket, Name: static-assets
Rules:
  Host        Path  Backends
  ----        ----  --------
  *           
              /icons   APIGroup: k8s.example.com, Kind: StorageBucket, Name: icon-assets
Annotations:  <none>
Events:       <none>

该Ingress对象表明所有/icons请求会被路由到相同命名空间下名为icon-assetsStorageBucket资源中去进行处理。

路径类型

Ingress中的每个路径都需要有对应的路径类型,没有路径类型是不合法的。当前支持的路径类型有三种:

  • ImplementationSpecific: 该类型的路径匹配取决于IngressClass的具体实现。可以将其作为单独的pathType,也可以将其与Prefix或Exact类型作相同处理。
  • Exact:严格匹配,大小写敏感
  • Prefix:基于以/分隔的URL路径前缀匹配,大小写敏感

下面是一个匹配示例

路径类型匹配路径请求路径是否匹配
Prefix/(all paths)
Prefix/foo/foo
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
Mixed/foo (Prefix), /foo (Exact)/foo是,严格匹配优先

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

主机名通配符

主机名可以精确匹配,也可以通过通配符来匹配。
下面是一个通配符匹配示例:

hosthost headermatch?
*.foo.combar.foo.com基于相同的后缀匹配
*.foo.combaz.bar.foo.com不匹配
*.foo.comfoo.com不匹配

Ingress Class

在上文中说过,如果在Ingress定义时省略了ingressClassName,那么需要定义一个默认的Ingress class。在Ingress class中,定义了实现Ingress的控制器。下面是一个示例:

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

其中,比较重要的属性是metadata.namespec.controller,前者是这个Ingress Class的名称,也就是Ingress中的spec.ingressClassName,后者是Ingress Controller的名称。另外,parameters字段可用于引用其他资源以提供额外的配置,其类型由controller决定。

默认的Ingress Class用于处理所有没有指定Ingress Class的Ingress资源,只需要将ingressclass.kubernetes.io/is-default-class设置为true即可。

注意,当存在多个默认Ingress Class时,新的Ingress如果没有指定ingressClassName则不会被允许创建。解决这个问题只需要确保集群中最多只能有一个默认的IngressClass。

多个Ingress Controller

除了可能会有多个不同类型的Ingress Controller外,还可能存在多个相同的Ingress Controller,比如部署了两个NGINX Ingress Controller,一个负载处理外网访问,一个负责处理内网访问。

此时也可以通过上面的方式,为每个Controller指定唯一的一个class。

Ingrss Class作用域

集群作用域和命名空间作用域

如果设置了spec.parameters字段且未设置spec.parameters.scope字段,或者将spec.parameters.scope字段设置为Cluster时,则该IngressClass所引用的是一个集群作用域的资源。

除了集群作用域之外,Ingrss Class还可以设置Namespace作用域。

Ingress类型

单服务Ingress
暴露单个服务的Ingress,如下所示:

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

Simple fanout

简单扇出,也可以说是多服务Ingress。它可以将来自同一IP地址的流量路由到多个Service。如下图所示:

在这里插入图片描述

对应的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

基于名称的虚拟托管

基于名称的虚拟主机支持将针对多个主机名的HTTP流量路由到同一IP地址上。如下图所示:

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地址的任何网络流量,而无需基于名称的虚拟主机。

TLS

你可以通过设定包含TLS私钥和证书的Secret来保护Ingress。

你可以通过以下几种方式获得证书:

  • 自签名证书:用自己的CA(证书颁发机构)来创建和签名TLS证书。
  • 购买一个TLS证书:从浏览器和操作系统信任的知名CA购买TLS证书。
  • 使用LetSencrpt证书:LetSencrpt是一家非盈利的可信证书颁发机构,提供免费的TLS证书。

当你把TLS证书作为Kubernetes Secret添加到Ingress里去时,Ingress 控制器就能获取到证书,并使其变成自己的配置信息。
在Ingress-Nginx控制器中,TLS证书就是由nginx.conf动态地处理:

ssl_certificate_by_lua_block { 
           certificate.call()     
}

下面是Ingress TLS的工作流程:
在这里插入图片描述

TLS Secret的数据中必须包含以tls.crt保存的证书和以tls.key保存的私钥。例如:

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

把TLS证书添加到Ingress中:

spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - foo.bar.com
    secretName: testsecret-tls
  rules:
  - hosts: "foo.bar.com"
     http:
        paths:
            ...

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

默认情况下,TLS连接终止于Ingress节点,也就是说,Ingress控制器与Service及其Pod之间的流量都以明文传输。

如果想要全程加密,可以通过在ingress controller中添加支持的annotation。例如如果使用的是Ingress-Nginx控制器,可以在Ingress中添加注解:nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"

各种Ingress控制器所支持的TLS功能之间存在差异。

负载均衡

Ingress控制器启动时会使用一些适用于所有Ingress的负载均衡策略设置,例如负载均衡算法等。更高级的负载均衡概念(例如持久会话、动态权重)尚未通过 Ingress 公开。

值得注意的是,健康检查不是通过Ingress直接暴露的。在Kubernetes中存在并行的概念,比如就绪检查,允许你实现相同的目的。

Ingress是7层的负载均衡,负载将HTTP/HTTPS请求路由到Service。接下来再由service通过iptables来将请求转发到具体的pod上[3]

参考资料

[1]. https://kubernetes.io/docs/concepts/services-networking/ingress/
[2]. https://cloud.tencent.com/developer/article/1925519
[3]. https://tech.citahub.com/k8s-service-iptables/

  • 0
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《K8S学习指南PDF》是一本非常有用的指南,它为初学者提供了一份清晰明了的指南,帮助他们学习K8S的基本概念、架构和运作方式。这本指南对于那些希望学习Kubernetes技术并开始构建容器化应用程序的人来说非常重要。在这本指南中,读者可以了解到Kubernetes的主要特点,包括它如何管理和调度容器,并将这些容器部署到集群中。 此外,这本指南还介绍了Kubernetes的核心组件和它们的作用,例如etcd、kube-apiserver、kube-controller-manager、kube-scheduler和kubelet。阅读本指南后,读者将了解到这些组件如何协同工作,以及它们是如何创建、管理和监视容器化应用程序的。 除此之外,《K8S学习指南PDF》还讨论了Kubernetes的一些高级概念,例如自动伸缩、滚动更新和容器网络(CNI)。这些概念将有助于读者充分理解Kubernetes如何支持现代应用程序开发的需求,包括动态伸缩、A/B 测试和分布式应用程序。 总而言之,《K8S学习指南PDF》是一份非常有价值的指南,适合那些想要学习Kubernetes和容器化技术的人使用。它提供了深入浅出的介绍,为读者提供了一个良好的理解Kubernetes和容器化这一创新技术的基础。 ### 回答2: Kubernetesk8s)是一种流行的容器编排系统,能够自动管理和部署容器化应用程序。而"k8s学习指南"是一本面向初学者的指南性书籍,旨在帮助读者了解Kubernetes技术。本书包含了Kubernetes的基础概念、架构、核心组件、资源对象等核心知识点,并通过多个实践、案例,帮助读者深入了解Kubernetes应用的实际操作过程。总之,该书的重点在于让读者系统地学习和理解Kubernetes的各个方面,为他们快速掌握这一技术打下坚实的基础。 以下是本书的主要内容简介: 第一章介绍了Kubernetes的核心概念及背景知识,以及容器化技术的概述。 第二章重点介绍了Kubernetes的架构、组件、工作原理等核心知识点; 第三章详细解析Kubernetes的核心概念和术语,如:pod、service、replication controller、deployment、statefulset、cronjob等。 第四章介绍了如何安装、配置和使用Kubernetes,包括使用Minikube和Kubernetes in Docker(KinD)进行本地测试等。 第五章介绍了Kubernetes的网络和存储,包括服务发现、负载均衡等不同方面的网络设置。 第六章介绍了Kubernetes的日志和监控,如何生成和收集日志、如何监控Kubernetes集群和应用程序等。 总的来说,这本书对于初学者来说非常友好,通过简单易懂的表述和大量实践案例的引入,能够帮助读者轻松地掌握Kubernetes技术。 ### 回答3: k8s学习指南PDF是一份帮助初学者了解Kubernetes指南手册。需要指出的是,Kubernetes被广泛认为是容器编排中最好的开源平台,它允许在虚拟或物理机器集群中管理容器化应用程序。它提供了一个简单而可靠的平台,用于快速的容器化应用程序。在这个PDF指南中,使用者将学习到Kubernetes的基础知识,例如Kubernetes的核心构建块,如Pod,ReplicaSet,Deployment等。此外,学习者还将了解如何配置Kubernetes集群,并了解如何使用Kubernetes的持久化存储,例如ConfigMaps和Secrets来管理配置和敏感数据。它还将讨论如何使用Ingress控制器来公开Kubernetes中的服务。学习者可以理解rkt和Docker这两种容器运行时集成Kubernetes的方式以及如何将容器注册到Kubernetes中。除了这些基础知识,学习者还可以了解如何使用Kubernetes的一些应用程序开发和管理工具,例如Helm和Kubectl。总之,这个Kubernetes学习指南PDF为初学者提供了一个全面的指南,其中详细解释了Kubernetes的所有基础知识和工具。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值