K8S篇之Ingress详解以及用法说明

一、Ingress简介

Ingress 是 Kubernetes 中用于管理和配置从集群外部访问集群内部服务的资源对象。它通过定义路由规则来控制外部流量的访问方式,支持基于 HTTP 和 HTTPS 的高级路由功能和安全性配置。

Ingress是一种HTTP方式的路由转发机制,为K8S服务配置HTTP负载均衡器,通常会将服务暴露给K8S群集外的客户端。
二、Ingress暴露服务

要理解ingress,需要区分两个概念,ingress和ingress-controller:

ingress对象:

指的是k8s中的一个api对象,一般用yaml配置。作用是定义请求如何转发到service的规则,可以理解为配置模板。

ingress-controller:

具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发。
注:简单来说,ingress-controller才是负责具体转发的组件,通过各种方式将它暴露在集群入口,外部对集群的请求流量会先到ingress-controller,而ingress对象是用来告诉ingress-controller该如何转发请求,比如哪些域名哪些path要转发到哪些服务等等。
说明

service 的表现形式为IP:PORT,即工作在第四层传输层(TCP/IP层),对于不同的URL地址经常对应用不同的后端服务或者虚拟服务器,这些应用层的转发机制仅通过kubernetes的service机制是无法实现的,这种情况我们可以使用ingress策略定义和一个具体的ingress Controller.

Ingress提供七层负载均衡能力,可以通过 Ingress 配置提供外部可访问的 URL、负载均衡、SSL、基于名称的虚拟主机等。作为集群流量接入层,Ingress 的高可靠性显得尤为重要。

三、Ingress原理详解

这个负载均衡是基于nginx七层反向代理来实现的,ingress工作原理如下图:

**说明:**外部客户端通过访问负载均衡器,然后调度到service上,然后在调度到IngressController,IngressController通过Ingress规则(域名或虚拟主机)访问到后端pod,而在Ingress规则当中对应的主机是由service分组来设定的。

可以看到,这幅图有2种service,最上面的service是用来对外提供服务的,而下面2个service仅仅是用来分pod组的

1、Kubernetes 并没有自带 Ingress Controller,实际上ingress-controller只是一个统称,具体实现有多种,需要自己单独安装,目前,由k8s维护的ingress-controller只有google云的GCE与ingress-nginx两个,常用的是 Ingress-nginx Controller.

Ingress一般由三个组件组成:

  1. Nginx 反向代理负载均衡器
  2. Ingress Controller 可以理解为控制器,它通过不断的跟 Kubernetes API 交互,实时获取后端 Service、Pod 等的变化,比如新增、删除等,然后结合 Ingress 定义的规则生成配置,然后动态更新上边的Nginx负载均衡器,并刷新使配置生效,来达到服务自动发现的作用。
  3. Ingress 则是定义规则,通过它定义某个域名的请求过来之后转发到集群中指定的 Service。它可以通过 Yaml 文件定义,可以给一个或多个 Service 定义一个或多个 Ingress 规则。

四、创建Ingress资源

Ingress 中的spec字段是Ingress资源的核心组成部分,主要包含以下3个字段:

  • rules:用于定义当前Ingress资源的转发规则列表;由rules定义规则,或没有匹配到规则时,所有的流量会转发到由backend定义的默认后端。
  • backend:默认的后端,用于服务那些没有匹配到任何规则的请求;定义Ingress资源时,必须要定义backend或rules两者之一,该字段用于让负载均衡器指定一个全局默认的后端。
  • tls:TLS配置,目前仅支持通过默认端口443提供服务,如果要配置指定的列表成员指向不同的主机,则需要通过SNI TLS扩展机制来支持该功能。

Ingress资源示例

以下是一个简单的 Ingress 资源示例,演示了如何配置基本的路径路由和 TLS 加密:

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  namespace: default
spec:
  rules:
    - host: example.com
      http:
        paths:
          - path: /app1
            pathType: Prefix
            backend:
              service:
                name: service1
                port:
                  number: 80
          - path: /app2
            pathType: Prefix
            backend:
              service:
                name: service2
                port:
                  number: 80
  tls:
    - hosts:
        - example.com
      secretName: example-tls-secret

解释

host:定义了 Ingress 对象所适用的主机名,请求会根据主机名进行路由。

http.paths:定义了基于路径的路由规则,每个路径可以指向不同的后端服务。

tls:配置了 TLS 加密,指定了需要加密的主机名和相应的 TLS 密钥对名称。

五、部署Ingress控制器(Nginx)
1、下载ingress controller

python 复制代码
[root@k8s-master ~]# cd /mnt/
[root@k8s-master mnt]# wget https://codeload.github.com/kubernetes/ingress-nginx/tar.gz/refs/tags/controller-v1.3.1
[root@k8s-master mnt]# tar xf ingress-nginx-controller-v1.3.1.tar.gz
[root@k8s-master mnt]# cd ingress-nginx-controller-v1.3.1/deploy/static/provider/cloud
[root@k8s-master cloud]# ls
deploy.yaml  kustomization.yaml
[root@k8s-master cloud]# cd
[root@k8s-master ~]# vim deploy.yaml #修改配置文件
找到已下apiserver的版本:
# 390行修改
kind: DaemonSet  #将原来的Deployment修改为DaemonSet

# 415行下边添加
hostNetwork: true  #添加此配置

需要修改的地方:

kind: DaemonSet:

官方原始文件使用的是deployment,replicate 为 1,这样将会在某一台节点上启动对应的nginx-ingress-controller pod。外部流量访问至该节点,由该节点负载分担至内部的service。测试环境考虑防止单点故障,改为DaemonSet然后删掉replicate ,配合亲和性部署在制定节点上启动nginx-ingress-controller pod,确保有多个节点启动nginx-ingress-controller pod,后续将这些节点加入到外部硬件负载均衡组实现高可用性。

hostNetwork: true:

添加该字段,暴露nginx-ingress-controller pod的服务端口(80)

2、创建ingress-controller

[root@k8s-master ~]# kubectl apply -f deploy.yaml

查看ingress-controller资源
[root@k8s-master ~]# kubectl get pods -n ingress-nginx
NAME                             READY   STATUS    RESTARTS   AGE
nginx-ingress-controller-s8vnl   1/1     Running   0          98m
nginx-ingress-controller-ztxz4   1/1     Running   0          97m

[root@k8s-master cloud]# kubectl get ingressclass
NAME    CONTROLLER             PARAMETERS   AGE
nginx   k8s.io/ingress-nginx   <none>       38m

3、真实场景测试ingress

step1:创建两个应用和service

yaml 复制代码
[root@k8s-master ~]# vim my-apache.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 name: my-apache
spec:
 selector:
   matchLabels:
     run: my-apache
 replicas: 2
 template:
  metadata:
   labels:
    run: my-apache
  spec:
   containers:
   - name: my-apache
     image: daocloud.io/library/httpd:2.4
     ports:
     - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
 name: my-apache
 labels:
  run: my-apache
spec:
 #type: NodePort
 ports:
 - port: 80
   targetPort: 80
   #nodePort: 30002
 selector:
  run: my-apache
  
  
[root@k8s-master ~]# cat my-nginx.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
 name: my-nginx
spec:
 selector:
   matchLabels:
     run: my-nginx
 replicas: 2
 template:
  metadata:
   labels:
    run: my-nginx
  spec:
   containers:
   - name: my-nginx
     image: daocloud.io/library/nginx:1.7.9
     ports:
     - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
 name: my-nginx
 labels:
  run: my-nginx
spec:
 #type: NodePort
 ports:
 - port: 80
   targetPort: 80
   #nodePort: 30001
 selector:
  run: my-nginx
  
  
创建pod和service
[root@k8s-master ~]# kubectl apply -f my-apache.yaml
[root@k8s-master ~]# kubectl apply -f my-nginx.yaml

查看资源
[root@k8s-master ~]# kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
my-apache-d49c8b95c-8z8l9   1/1     Running   0          125m
my-apache-d49c8b95c-d9q5s   1/1     Running   0          125m
my-nginx-5fdc96f9b4-bmf6s   1/1     Running   0          124m
my-nginx-5fdc96f9b4-qfw8c   1/1     Running   0          124m
[root@k8s-master ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        20d
my-apache    NodePort    10.99.178.186   <none>        80/TCP   125m
my-nginx     NodePort    10.97.171.188   <none>        80/TCP   124m

step2:配置ingress转发文件

yaml 复制代码
[root@k8s-master ~]# cat ingress-test.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
 name: test-ingress
 namespace: default
 annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
 ingressClassName: nginx
 rules:  #定义转发规则
 - host: test.apache.ingress  #指定域名方式
   http:
    paths:
    - path: /  #指定访问的路径
      pathType: Prefix  #定义路径的类型
      backend:   #定义转发后端的服务
       service:  #定义转发的service
         name: my-apache
         port:
          number: 80
 - host: test.nginx.ingress
   http:
    paths:
    - path: /
      pathType: Prefix
      backend:
       service:
         name: my-nginx
         port:
          number: 80
          
[root@k8s-master ~]# kubectl apply -f ingress-test.yaml
[root@k8s-master ~]# kubectl get ingress
NAME           CLASS    HOSTS                                    ADDRESS   PORTS   AGE
test-ingress   <none>   test.apache.ingress,test.nginx.ingress             80      119m

step3:修改ingress转发类型

[root@k8s-master ~]# kubectl edit svc ingress-nginx-controller -n ingress-nginx
# 将type修改为NodePort

nginx-ingress-controller运行在node1,node2两个节点上。

如果网络中有dns服务器,在dns中把这两个域名映射到nginx-ingress-controller运行的任意一个节点上,如果没有dns服务器只能修改host文件了。

任意一个节点上操作:(客户端解析)

我这里有两个节点部署了控制器,ip分别为172.16.229.5,172.16.229.6 ,如果有多个,可以随便选。

172.16.229.5 test.nginx.ingress
172.16.229.6 test.apache.ingress

这里根据实际情况进行域名映射

相关推荐
景天科技苑20 分钟前
【云原生开发】K8S多集群资源管理平台架构设计
云原生·容器·kubernetes·k8s·云原生开发·k8s管理系统
wclass-zhengge1 小时前
K8S篇(基本介绍)
云原生·容器·kubernetes
颜淡慕潇1 小时前
【K8S问题系列 |1 】Kubernetes 中 NodePort 类型的 Service 无法访问【已解决】
后端·云原生·容器·kubernetes·问题解决
昌sit!9 小时前
K8S node节点没有相应的pod镜像运行故障处理办法
云原生·容器·kubernetes
A ?Charis12 小时前
Gitlab-runner running on Kubernetes - hostAliases
容器·kubernetes·gitlab
茶馆大橘12 小时前
微服务系列五:避免雪崩问题的限流、隔离、熔断措施
java·jmeter·spring cloud·微服务·云原生·架构·sentinel
北漂IT民工_程序员_ZG13 小时前
k8s集群安装(minikube)
云原生·容器·kubernetes
coding侠客13 小时前
揭秘!微服务架构下,Apollo 配置中心凭啥扮演关键角色?
微服务·云原生·架构
2301_8061313619 小时前
Kubernetes的基本构建块和最小可调度单元pod-0
云原生·容器·kubernetes
SilentCodeY20 小时前
containerd配置私有仓库registry
容器·kubernetes·containerd·镜像·crictl