百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术资源 > 正文

K8S中Service使用nginx控制器实现Ingress负载均衡器的一个Demo

off999 2025-01-12 17:41 15 浏览 0 评论

写在前面


  • 学习K8sService遇到,单独整理分享给小伙伴
  • 本文内容涉及:
  • ingress-nginx-controller的创建
  • 基于ingress-nginx-controllerIngress的创建
  • 基于Ingress的服务发布,SVC负载
  • 时间关系,关于Ingresshttp路由负载本文没有涉及
  • 部分地方使用ansible,不影响阅读

当你觉活着没啥感受时,会陷入无尽虚无,越来越不像一人,存在的意义只能从某些快感中汲取,活着像海中的小舟一样,无所畏惧,亦畏惧所有。成长至此,大都是别人功劳,所以任有部分人性未曾泯灭,与其说努力,不如讲只求心安;希望每个小伙伴都不要像我一样,每天起床的第一句话,告诉自己,沉沦的小酒馆已经打烊了啦!要好好爱护自己的身体 —山河已无恙


ingress

Service的表现形式为IP:Port,即工作在TCP/IP层。 对于基于HTTP的服务来说,不同的URL地址经常对应到不同的后端服务或者虚拟服务器(Virtual Host)这些应用层的转发机制仅通过KubernetesService机制是无法实现的。

Kubernetes 1.1版本开始新增Ingress资源对象,用于将不同URL的访问请求转发到后端不同的Service,以实现HTTP层的业务路由机制。但是并不是说只能做7层路由,四层负载也可以

Kubernetes使用了一个Ingress策略定义和一个具体的Ingress Controller,两者结合并实现了一个完整的Ingress负载均衡器。

使用Ingress进行负载分发时是不是和kube-proxy没啥关系,直接分发到pod上了,使用Load Balancer和nodeport才会使用kube-proxy ?

使用Ingress进行负载分发时, Ingress Controller基于Ingress规则将客户端请求直接转发到Service对应的后端Endpoint (Pod)上,这样会跳过kube-proxy的转发功能, kube-proxy不再起作用。如果IngressController提供的是对外服务,则实际上实现的是边缘路由器的功能。

控制器通过svc获取endpoints并获取对应的pod信息,然后通过nginx内部的lua代码进行处理

官网中的一些描述

Ingress

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

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

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

个人理解,就是实现了一个Ngixn功能,可以更具路由规则分配流量等

命名空间里配置ingress规则,嵌入到控制器nginx-反向代理的方式(ingress-nginx-controller)

可以将 Ingress 配置为服务提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及提供基于名称的虚拟主机等能力。 Ingress 控制器 通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。

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

为使用Ingress,需要创建Ingress Controller(带一个默认backend服务)和Ingress策略设置来共同完成。

在定义Ingress策略之前,需要先部署Ingress Controller,以实现为所有后端Service都提供一个统一的入口Ingress Controller需要实现基于不同HTTP URL向后转发的负载分发规则,并可以灵活设置7层负载分发策略

如果公有云服务商能够提供该类型的HTTP路由LoadBalancer,则也可设置其为Ingress Controller。在Kubernetes中, Ingress Controller将以Pod的形式运行,监控APIServer的/ingress接口后端的backend services,如果Service发生变化,则Ingress Controller应自动更新其转发规则。

下面的例子使用Nginx来实现一个Ingress Controller,正常情况下ingress-nginx-controller 会作为一个deamonSet,即位于没一个Node上。这里我们为了方便,只是在一个node上配置,同时写如NDS映射

ingress-nginx-controller 部署

需要的镜像,相关的资源文件,小伙伴可以在k8s官网获取

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$grep image nginx-controller.yaml
          image: docker.io/liangjw/ingress-nginx-controller:v1.0.1
          imagePullPolicy: IfNotPresent
          image: docker.io/liangjw/kube-webhook-certgen:v1.1.1
          imagePullPolicy: IfNotPresent
          image: docker.io/liangjw/kube-webhook-certgen:v1.1.1
          imagePullPolicy: IfNotPresent
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$

准备工作,镜像上传,导入

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible node -m copy -a "dest=/root/ src=./../ingress-nginx-controller-img.tar"
192.168.26.82 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "checksum": "a3c2f87fd640c0bfecebeab24369c7ca8d6f0fa0",
    "dest": "/root/ingress-nginx-controller-img.tar",
    "gid": 0,
    "group": "root",
    "md5sum": "d5bf7924cb3c61104f7a07189a2e6ebd",
    "mode": "0644",
    "owner": "root",
    "size": 334879744,
    "src": "/root/.ansible/tmp/ansible-tmp-1640207772.53-9140-99388332454846/source",
    "state": "file",
    "uid": 0
}
192.168.26.83 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": true,
    "checksum": "a3c2f87fd640c0bfecebeab24369c7ca8d6f0fa0",
    "dest": "/root/ingress-nginx-controller-img.tar",
    "gid": 0,
    "group": "root",
    "md5sum": "d5bf7924cb3c61104f7a07189a2e6ebd",
    "mode": "0644",
    "owner": "root",
    "size": 334879744,
    "src": "/root/.ansible/tmp/ansible-tmp-1640207772.55-9142-78097462005167/source",
    "state": "file",
    "uid": 0
}
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible node -m shell -a "docker  load -i /root/ingress-nginx-controller-img.tar"

创建ingress控制器ingress-nginx-controller

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl  apply  -f nginx-controller.yaml
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl  get pods -n ingress-nginx  -o wide
NAME                                        READY   STATUS      RESTARTS   AGE   IP               NODE                         NOMINATED NODE   READINESS GATES
ingress-nginx-admission-create--1-hvvxd     0/1     Completed   0          89s   10.244.171.171   vms82.liruilongs.github.io   <none>           <none>
ingress-nginx-admission-patch--1-g4ffs      0/1     Completed   0          89s   10.244.70.7      vms83.liruilongs.github.io   <none>           <none>
ingress-nginx-controller-744d4fc6b7-7fcfj   1/1     Running     0          90s   192.168.26.83    vms83.liruilongs.github.io   <none>           <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$

我们这里只是在192.168.26.83上创建了一个ingress控制器pod,生产环境一般需要每个节点上存在一个,即通过deamonset的方式
DNS解析的地址为控制器的地址,这里控制器使用的是docker内部网络的方式,即直接把端口映射宿主机了

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$grep -i hostN nginx-controller.yaml
      hostNetwork: true

因为pod是在192.168.26.83节点,所以我们需要 配置DNS 创建域名到服务的映射

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible 192.168.26.83 -m shell -a "echo -e '192.168.26.83 liruilongs.nginx1\n192.168.26.83 liruilongs.nginx2\n192.168.26.83 liruilongs.nginx3' >> /etc/hosts"
192.168.26.83 | CHANGED | rc=0 >>

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible 192.168.26.83 -m shell -a "cat /etc/hosts"
192.168.26.83 | CHANGED | rc=0 >>
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.26.81 vms81.liruilongs.github.io vms81
192.168.26.82 vms82.liruilongs.github.io vms82
192.168.26.83 vms83.liruilongs.github.io vms83
192.168.26.83 liruilongs.nginx1
192.168.26.83 liruilongs.nginx2
192.168.26.83 liruilongs.nginx3
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$

服务模拟,创建三个pod做为SVC提供能力

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: pod-svc
  name: pod-svc
spec:
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: pod-svc
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl  apply -f pod.yaml
pod/pod-svc created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$sed 's/pod-svc/pod-svc-1/'  pod.yaml > pod-1.yaml
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$sed 's/pod-svc/pod-svc-2/'  pod.yaml > pod-2.yaml
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl  apply  -f pod-1.yaml
pod/pod-svc-1 created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl  apply  -f pod-2.yaml
pod/pod-svc-2 created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl  get pods -o wide
NAME        READY   STATUS    RESTARTS   AGE     IP               NODE                         NOMINATED NODE   READINESS GATES
pod-svc     1/1     Running   0          2m42s   10.244.171.174   vms82.liruilongs.github.io   <none>           <none>
pod-svc-1   1/1     Running   0          80s     10.244.171.175   vms82.liruilongs.github.io   <none>           <none>
pod-svc-2   1/1     Running   0          70s     10.244.171.176   vms82.liruilongs.github.io   <none>           <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$

修改Nginx的主页,区分访问的pod,根据pod创建三个服务SVC

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl  get pods  --show-labels
NAME        READY   STATUS    RESTARTS   AGE    LABELS
pod-svc     1/1     Running   0          3m7s   run=pod-svc
pod-svc-1   1/1     Running   0          105s   run=pod-svc-1
pod-svc-2   1/1     Running   0          95s    run=pod-svc-2

这个创建SVC通过 selector的方式

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$serve=pod-svc
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl exec  -it $serve -- sh -c "echo $serve > /usr/share/nginx/html/index.html"
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl expose  --name=$serve-svc  pod $serve --port=80
service/pod-svc-svc exposed
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$serve=pod-svc-1
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl exec  -it $serve -- sh -c "echo $serve > /usr/share/nginx/html/index.html"
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl expose  --name=$serve-svc  pod $serve --port=80
service/pod-svc-1-svc exposed
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$serve=pod-svc-2
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl exec  -it $serve -- sh -c "echo $serve > /usr/share/nginx/html/index.html"
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl expose  --name=$serve-svc  pod $serve --port=80
service/pod-svc-2-svc exposed

创建了三个SVC做负载模拟

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl  get svc -o wide
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE    SELECTOR
pod-svc-1-svc   ClusterIP   10.99.80.121   <none>        80/TCP    94s    run=pod-svc-1
pod-svc-2-svc   ClusterIP   10.110.40.30   <none>        80/TCP    107s   run=pod-svc-2
pod-svc-svc     ClusterIP   10.96.152.5    <none>        80/TCP    85s    run=pod-svc
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl  get ing
No resources found in liruilong-svc-create namespace.
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$vim ingress.yaml

创建 Ingress,当然这里只是简单测试,可以更具具体业务情况配置复杂的路由策略
ingress.yaml,访问"/"的时候,会调度到三个SVC里,这里需要注意的是和kube-proxy没啥关系,Ngixn控制器内部的负载

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx" #必须要加
spec:
  rules:
  - host: liruilongs.nginx1
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: pod-svc-svc
            port:
              number: 80
  - host: liruilongs.nginx2
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: pod-svc-1-svc
            port:
              number: 80
  - host: liruilongs.nginx3
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: pod-svc-2-svc
            port:
              number: 80

创建查看Ingress。hsots中会列出所有的负载域名

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl  apply  -f ingress.yaml
ingress.networking.k8s.io/my-ingress created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-svc-create]
└─$kubectl  get ing
NAME         CLASS    HOSTS                                                   ADDRESS   PORTS   AGE
my-ingress   <none>   liruilongs.nginx1,liruilongs.nginx2,liruilongs.nginx3             80      17s

负载测试

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible 192.168.26.83 -m shell -a "curl liruilongs.nginx1"
192.168.26.83 | CHANGED | rc=0 >>
pod-svc  
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible 192.168.26.83 -m shell -a "curl liruilongs.nginx2"
192.168.26.83 | CHANGED | rc=0 >>
pod-svc-1  

这只是一个Ingress做SVC负载的一个Demo,时间关系,关于使用Ingree 做HTTP路由负载的Demo之后有时间和小伙伴分享,唉,心情不好,感觉浪费了好多时间,又啥也没学到

相关推荐

30s带你使用Python打包exe文件,并修改其图标

在Python中,我们可以使用PyInstaller或cx_Freeze等工具将Python脚本打包成可执行文件(.exe),并且能够修改生成的.exe文件的图标。使用PyInstaller...

Python一键打包为windows的exe文件,无需安装python环境即可执行

一、为什么要将Python打包为exe?在实际应用中,我们希望Python程序能在没有安装Python环境的电脑上直接运行。将Python代码打包为exe可执行文件,不仅能解决环境依赖问题,还便于程...

py2exe实现python文件打包为.exe可执行程序(上篇)

今天分享的内容为:python程序实现发送、读取邮件来控制电脑的关机与重启(作为py2exe打包成.exe可执行程序的基础文件)一、说明:本文介绍的是使用新浪邮箱作为例子进行讲解,代码实现如下:#c...

如何将python程序文件打包生成一个可执行文件(exe文件)

在开发Python程序后,有时我们希望将其打包成一个可执行的exe文件,方便在没有Python环境的计算机上运行。下面将详细介绍使用常见工具实现这一目标的方法。安装PyInstaller...

Python程序打包为EXE的全面指南:从入门到精通

引言在Python开发中,将程序打包成可执行文件(EXE)是分发应用程序的重要环节。通过打包,我们可以创建独立的可执行文件,让没有安装Python环境的用户也能运行我们的程序。本篇文章将详细介绍如何使...

10个你没有充分利用的令人惊叹的 Python 特性

Python的简单性和多功能性使其成为全球开发人员的最爱。每天有超过1000万开发者使用Python进行从网络开发、机器学习到网络脚本等各种开发,Python的功能非常强大。然而,我们中的...

编程语言可以用来做什么

1.web前端你每天浏览的网页,所看到的页面特效,均是由web前端工程师来实现的2.Java大型购物网站有关通信及网络企业大型企业级应用管理系统大型网游后台数据3.C++嵌入式三维游戏领域人工智能领域...

用Python进行机器学习(16)-内容总结

对于用Python进行机器学习的内容,到这里就要做一个阶段性总结啦,后续再写的文章就是关于深度学习的了,算是对该部分内容的进阶版。对于机器学习,我们主要介绍了五个方面的内容:第一个就是分类算法,主要包...

普通人如何利用python做自媒体赚收益

普通人利用Python做自媒体赚收益,最简单的方式是下载某些网站的视频,并利用剪影编辑视频,最后导出发布,每天可以制作个10几条,并设置好定时发布,每天如此坚持下去,一定会有所收获的...

AI能写什么做什么?这些技能已经颠覆你的认知!

在ChatGPT、文心一言等AI工具爆火的今天,人工智能早已不再是科幻电影里的概念,而是实实在在地渗透进我们的生活。**AI到底能写什么?能做什么?它的边界在哪里?**让我们一探究竟!---**1....

Python 3.14 新特性盘点,更新了些什么?

Python3.14.0稳定版将于2025年10月正式发布,目前已进入beta测试阶段。这意味着在往后的几个月里,3.14的新功能已冻结,不再合入新功能(除了修复问题和完善文档)。3...

每天一个Python库:sys模块的5个高频用法(建议收藏)

很多人学Python,一直卡在“写不了实用脚本”。其实,会用标准库,效率直接翻倍。今天分享的是:sys模块。这个模块虽然基础,但非常实用,下面是我亲测常用的5个功能1.获取命令行参数(自动化脚...

Python除了做爬虫抓数据还能做什么?其实还能监视和衡量网站性能

  借助这份对初学者友好的指南,您可以构建自己的自定义Python脚本来自动测量网站的关键速度和性能指标。  在过去的一个月中,Google宣布了许多通过关键速度和性能指标来衡量用户体验的方法。  巧...

python究竟可以用来做些什么

这里就不撰述python的一些像什么“高级语言”之类的比较常规的介绍了,还是老样子,说说一些比较常用的东西吧。python是什么python,一款可编程的开源软件,很多第三方库、框架也是开源的,比如强...

Python 实现 dubbo 协议接口自动化测试

前言python语言也可以实现对dubbo协议的接口进行调用与测试,可以使用python+hessian结合的方式,也可以使用python+telnet结合的方式模拟命令行的模式来实现对...

取消回复欢迎 发表评论: