使用DaemonSet+HostNetwork方式部署ingress-Nginx实现负载均衡

ingress概念
ingress-Nginx官方部署手册
ingress-nginx国内代码仓库

前言

简单示例

将所有流量都发送到同一 Service 的简单 Ingress 示例
在这里插入图片描述

三种常用的部署模式

Deployment+LoadBalancer模式的service

用Deployment部署igress-controller,创建一个type为LoadBalancer的service关联这组pod。大部分公有云,都会为LoadBalancer的service自动创建一个负载均衡器,通常还绑定了公网地址。只要把域名解析指向改地址,就实现了集群服务的对外暴露

Deployment+NodePort模式的service

同样用deployment模式部署ingress-controller,然后创建对应的ingress svc,type为NodePort。这样,ingress就会暴露在集群节点ip的特定端口上。由于nodeport暴露的端口是随机端口,一般会在前面再搭建一套负载均衡器来转发请求。改方式一般用于宿主机是相对固定的环境ip地址不变的场景。
NodePort方式暴露ingress虽然简单方便,但是NodePort多了一层NAT,在请求量级很大时可能对性能会有一定的影响

DaemonSet+HostNetwork(+nodeSelector)

用DaemonSet 结合nodeselector来部署ingress-controller到特定的Node上,然后使用HostNetwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/443端口就能访问服务。这时,ingress-controller所在的node机器就很类似传统架构的边缘节点,比如机房的入口nginx服务器。该方式整个请求链路最简单,性能相对nodeport模式更好。缺点是由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod。比较适合大并发的生产环境使用。

DaemonSet+HostNetwork方式部署

环境

k8s版本:v1.26.1
容器运行时:containerd.io 1.6.22
ingress-nginx-controller : v1.8.0

下载配置文件

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.0/deploy/static/provider/cloud/deploy.yaml

修改配置文件

主要是修改镜像拉取地址、部署方式等

原镜像国内代理镜像
registry.k8s.io/ingress-nginx/controller:v1.8.0@sha256:744ae2afd433a395eeb13dc03d3313facba92e96ad71d9feaafc85925493fee3registry.cn-hangzhou.aliyuncs.com/google_containers/nginx-ingress-controller:v1.8.0
registry.k8s.io/ingress-nginx/kube-webhook-certgen:v20230407@sha256:543c40fd093964bc9ab509d3e791f9989963021f1e9e4c9c7b6700b02bfb227bregistry.cn-hangzhou.aliyuncs.com/google_containers/kube-webhook-certgen:v20230407
apiVersion: apps/v1
kind: DaemonSet # 修改Deployment为DaemonSet(每个node只能部署一个,适用于在集群中的每个节点上运行守护进程或系统级别的任务)
metadata:
  labels:
    .......
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
    .......
  template:
    metadata:
      labels:
      	........
    spec:
      hostNetwork: true  #使用主机网络
      nodeSelector:
        ingress: "true"   #选择节点运行,节点有标签ingress=true

给节点打标签

#新增标签
kubectl label node node02 ingress=true
#移除标签 -代表移除
kubectl label node node02 ingress=true-

#如果想在master节点上部署需要移除污点
#查看master污点
kubectl describe node <master 节点名称> | grep Taints
# 如果是Taints: node-role.kubernetes.io/control-plane:NoSchedule,代表不可调度
#NoSchedule: 一定不能被调度
#PreferNoSchedule: 尽量不要调度
#NoExecute: 不仅不会调度, 还会驱逐Node上已有的Pod
#移除污点
kubectl taint nodes <主节点名称> node-role.kubernetes.io/control-plane:NoSchedule-
#添加污点PreferNoSchedule: 尽量不要调度
kubectl taint nodes <主节点名称> node-role.kubernetes.io/control-plane=:PreferNoSchedule

执行部署

kubectl apply -f deploy.yaml

可见3个ingress-nginx-controller都已经部署成功

验证

准备一个nginx服务

kubectl apply -f nginxDeployment.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: my-nginx   #创建名称空间
---
apiVersion: apps/v1     #与k8s集群版本有关,使用 kubectl api-versions 即可查看当前集群支持的版本
kind: Deployment        #该配置的类型,我们使用的是 Deployment
metadata:               #译名为元数据,即 Deployment 的一些基本属性和信息
  name: nginx-deployment        #Deployment 的名称
  namespace: my-nginx
  labels:           #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组,目前不需要理解
    app: nginx  #为该Deployment设置key为app,value为nginx的标签
spec:           #这是关于该Deployment的描述,可以理解为你期待该Deployment在k8s中如何使用
  replicas: 3   #使用该Deployment创建一个应用程序实例
  selector:         #标签选择器,与上面的标签共同作用,目前不需要理解
    matchLabels: #选择包含标签app:nginx的资源
      app: nginx
  template:         #这是选择或创建的Pod的模板
    metadata:   #Pod的元数���
      labels:   #Pod的标签,上面的selector即选择包含标签app:nginx的Pod
        app: nginx
    spec:           #期望Pod实现的功能(即在pod中部署)
      containers:       #生成container,与docker中的container是同一种
      - name: nginx     #container的名称
        image: nginx:1.7.9      #使用镜像nginx:1.7.9创建container,该container默认80端口可访问
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service #Service 的名称
  namespace: my-nginx
  labels:       #Service 自己的标签
    app: nginx  #为该 Service 设置 key 为 app,value 为 nginx 的标签
spec:     #这是关于该 Service 的定义,描述了 Service 如何选择 Pod,如何被访问
  selector:     #标签选择器
    app: nginx  #选择包含标签 app:nginx 的 Pod
  ports:
  - name: nginx-port  #端口的名字
    protocol: TCP     #协议类型 TCP/UDP
    port: 8081          #集群内的其他容器组可通过 80 端口访问 Service
    targetPort: 80  #将请求转发到匹配 Pod 的 80 端口
  type: ClusterIP  #Serive的类型,ClusterIP/NodePort/LoaderBalancer

执行结果:
在这里插入图片描述

配置ingress规则

kubectl apply -f ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  namespace: my-nginx  #ingress部署到需要转发的namespace
  annotations:
    kubernetes.io/ingress.class: "nginx"  # 指定 Ingress 控制器的类名称,在部署ingress-nginx-controller的yaml中可见- --ingress-class=nginx
    nginx.ingress.kubernetes.io/rewrite-target: /  #这样可以在转发请求之前修改路径,如将下面的/testNginx, 改为/, 否则nginx-service收到的请求依旧会包含/testNginx
spec:
  rules:
  - host: www.liang.com #域名,只能是域名,支持通配符(*.foo.com)
    http:
      paths:
      - path: /testNginx
        pathType: Prefix   #路径匹配类型,可见https://kubernetes.io/zh-cn/docs/concepts/services-networking/ingress/
        backend:
          service:
            name: nginx-service  #要转发到那个service
            port:
              number: 8081  #service的端口
---

创建成功:
在这里插入图片描述

测试

#本地设置域名解析
echo '192.168.1.0 www.liang.com' >> /etc/hosts

在这里插入图片描述

可能的报错

创建ingres规则时 Kubernetes 集群中的 Ingress 控制器(例如 Nginx Ingress Controller)无法访问或响应

Error from server (InternalError): error when creating "ingress.yaml": Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes.io": failed to call webhook: Post "https://ingress-nginx-controller-admission.ingress-nginx.svc:443/networking/v1/ingresses?timeout=10s": dial tcp 10.106.17.187:443: connect: connection timed out

一般是webhook没有正常启动,测试环境可以通过删除validatingwebhookconfigurations来解决

kubectl get validatingwebhookconfigurations
kubectl delete  ValidatingWebhookConfiguration ingress-nginx-admission
#然后重新部署ingress规则
kubectl apply -f ingress.yaml

ingress和需要转发的服务不在同一namespace,

The Ingress "nginx-ingress" is invalid: spec.rules[0].http.paths[0].backend.service.name: Invalid value: "nginx-service.my-nginx": a DNS-1035 label must consist of lower case alphanumeric characters or '-', start with an alphabetic character, and end with an alphanumeric character (e.g. 'my-name', or 'abc-123', regex used for validation is 'a-z?')
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-ingress
  namespace: ingress-nginx
spec:
  rules:
  - host: www.liang.com
    http:
      paths:
      - path: /nginx
        pathType: Prefix
        backend:
          service:
            name: nginx-service.my-nginx  # 修改后的后端服务名称[servicename.namespace]
            port:
              number: 8081

实际使用时报错nginx-service.my-nginx不符合规则
可以通过把ingress部署到需要转发的服务的namespace中

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值