您当前的位置:首页 > 电脑百科 > 程序开发 > 容器

自建k8s集群之负载均衡使用

时间:2023-05-28 14:06:16  来源:今日头条  作者:DecOpSec

来源: DevOpSec公众号
作者: DevOpSec

背景

自建k8s而非云环境,组件MySQL类部署在虚机里也即集群外,业务服务部署在k8s集群内。

需求:集群内、集群外,服务和组件相互间通过负载均衡、高可用的形式连通。

此需求拆解两个问题进行解决,接着往下看。

集群内:k8s集群

集群外:k8s集群外的应用部署在虚拟机或物理机环境

网络环境

局域网:192.168.0.0/16

集群外
虚拟机网络:192.168.0.0/16
mysql网络:192.168.0.0/16
Nginx网络:192.168.0.0/16

集群内(k8s集群)
master网络:192.168.0.0/16
node网络:192.168.0.0/16
pod网络:10.234.0.0/18
SVC网络:10.234.64.0/18

业务架构

 

 

 

上图中存在的两个问题

问题1. 集群外访问集群内pod和svc的网络不通?

不通的原因:集群外的主机并不知道svc和pod的网络,在路由器上没有对应svc和pod ip的路由。

cni网络插件的实现是会按node分配网段,通过在路由器上增加不同node上的pod ip段和svc ip段路由给多个node的路由即可实现集群外部和内部svc和pod的互通。

缺点是当节点或者节点上的ip段有变化需要修改路由器上的路由策略,需要人工干预或者写个程序实现成本也不低。

可能有人说可以用nodePort的形式把服务暴露给nginx,但nodePort的方式不便于运维,

缺点有两个:

a、需要维护模块和端口的映射不通模块映射端口不能重复

b、集群外访问集群内部需要通过node的ip加端口访问,node可能随时下线

问题2. 集群内的pod访问集群外的mysql集群没有负载均衡和健康检查

针对问题2可以通过集群外部的硬件负载均衡设备或者自建的软负载均衡比如LVS、HAproxy或nginx等解决

缺点:硬件LB成本高,软LB在集群外维护成本高

也有人说可以已通过DNS解析多个数据库的ip A记录,通过域名解析来实现LB的功能,业务配置域名

缺点:一般DNS服务没有健康检查的功能,没办法实现故障db的自动剔除。

解决方案

问题1. 集群外访问集群内pod和svc的网络不通?

自建k8s,有没有类似于云厂商一样提供LB一样提供和node机器同一个网段的ExternalIP解决方案?

有,通过开源metalLB、OpenELB或者pureLB提供LoadBalancer的能力。

在生产环境中使用的calico VXLAN 模式,考虑到简单易用性我们使用LB基于layer2模式,也即LB的EXTERNAL-IP和node的ip同网段。

通过下面表格综合对比一下,metallb出道最早,迭代快,开发者多,且实测对externalTrafficPolicy: Local 支持。

综合选择metallb的layer2模式作为生产环境负载均衡。

 

部署MetalLB 使用 layer2模式

  1. 1. 准备工作

a. 确保防火墙对7472、7946端口开放,否则可能造成meltallb脑裂。 7472是 MetalLB 控制平面的 API 端口。MetalLB 提供了一个 REST API,用于管理和配置负载均衡服务。 7946端口是 MetalLB 使用的控制平面(Control nPlane)通信端口。它用于集群中的 MetalLB Speaker 之间进行通信,以便在整个集群中协调负载均衡服务的配置和状态。

b. 开始strict ARP模式

kubectl edit configmap -n kube-system kube-proxy

设置

apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
  strictARP: true

重启 kube-proxy

kubectl -n kube-system  rollout ds kube-proxy

注意:如果是kubespray部署的k8s集群,需要修改kubespray 配置

vim inventory/mycluster/group_vars/k8s_cluster/k8s-cluster.yml

修改

kube_proxy_strict_arp: true
  1. 1. 部署MetalLB
kubectl Apply -f https://raw.Githubusercontent.com/metallb/metallb/v0.13.9/config/manifests/metallb-native.yaml
  1. 1. 配置ip池 注意:ip 地址池和node网络同一个网段,且ip地址池的ip没有其他主机使用

cat ippools.yaml

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
  - 192.168.200.0/24
  - 192.168.201.1-192.168.201.250
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: ip-advertisement
  namespace: metallb-system
spec:
  ipAddressPools:
  - first-pool

加LoadBlancer后,nginx通过同网段的ExternalIP就能联通业务pod。

业务pod使用readiness probe 和 liveness probe检测pod里的服务是否正常,如果服务不正常k8s控制平面通知kube-proxy 从svc中剔除或更新endpoints,间接实现了svc对业务pod健康检查的功能。

网络架构图如下:

 

 

 

解决了问题1,来看一看问题2怎么解。

问题2. 集群内的pod访问集群外的mysql集群没有负载均衡和健康检查

集群内部访问集群外部组件可以在集群内部部署hapoxy或者nginx做反向代理,haproxy和 nginx 支持对代理的四层和七层服务做健康检查和负载均衡。

这样我们可以在集群内部针对集群外部组件灵活高效的创建带检查的负载均衡器,负载均衡器是无状态的可以创建多台。

请见下面架构图

 

 

 

这里我们选择nginx做负载均衡器,负载均衡器部署在k8s集群里,负载均衡器的RealServer是集群外的MySql从库集群。

业务pod1和pod2里配置的是负载均衡器nginx的svc的域名,使用域名和数据库ip解耦,通过负载均衡nginx实现mysqlslave的LB和HA的功能。

针对每一个组件分别启用一个新的负载均衡器而非共用负载均衡器,这样各个组件的负载均衡器变更或者出故障相互之间不受影响。牺牲一些服务器成本换取稳定性。

下面我们看一下负载均衡nginx的配置

  1. 1. workload 配置 cat rollout.yaml
---
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: lb-mysql-server
  namespace: release
  labels:
    app.kube.NETes.io/name: lb-mysql-server
spec:
  minAvAIlable: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: lb-mysql-server

---
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  labels:
    app.kubernetes.io/name: lb-mysql-server
  name: lb-mysql-server
  namespace: release
spec:
  replicas: 1
  strategy:
    canary:
      steps:
        - setWeight: 20
        - pause: { "duration": 30s }
  revisionHistoryLimit: 3
  selector:
    matchLabels:
      app.kubernetes.io/name: lb-mysql-server
  template:
    metadata:
      labels:
        app.kubernetes.io/name: lb-mysql-server
    spec:
      imagePullSecrets:
        - name: your-registry-secrets
      volumes:
        - name:  etc-nginx
          configMap:
            name:  lb-mysql-server-cm
      containers:
      - image: nginx:1.23.2-alpine
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /healthz
            port: 8081
            scheme: HTTP
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        name: nginx-proxy
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /healthz
            port: 8081
            scheme: HTTP
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        resources:
          requests:
            cpu: 25m
            memory: 32M
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /etc/nginx
          name: etc-nginx
          readOnly: true
      enableServiceLinks: true
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
  1. 1. configMap配置,配置代理Realserver cat cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: lb-mysql-server-cm
  namespace: release
  labels:
    app.kubernetes.io/name: lb-mysql-server
data:
  nginx.conf: |
    error_log stderr notice;

    worker_processes 2;
    worker_rlimit_nofile 130048;
    worker_shutdown_timeout 10s;

    events {
      multi_accept on;
      use epoll;
      worker_connections 16384;
    }

    stream {
      upstream lb_mysql_server {
        least_conn;
        server 192.168.1.11:3306 max_fails=2 fail_timeout=30s;
        server 192.168.1.12:3306 max_fails=2 fail_timeout=30s;
        server 192.168.1.13:3306 max_fails=2 fail_timeout=30s;
        }

      server {
        listen        3306;
        proxy_pass    lb_mysql_server;
        proxy_timeout 10m;
        proxy_connect_timeout 1s;
      }
    }

    http {
      aio threads;
      aio_write on;
      tcp_nopush on;
      tcp_nodelay on;

      keepalive_timeout 5m;
      keepalive_requests 100;
      reset_timedout_connection on;
      server_tokens off;
      autoindex off;

      server {
        listen 8081;
        location /healthz {
          access_log off;
          return 200;
        }
        location /stub_status {
          stub_status on;
          access_log off;
        }
      }
    }

  1. 1. svc配置 cat svc.yaml
apiVersion: v1
kind: Service
metadata:
  name: lb-mysql-server
  namespace: release
  labels:
    app.kubernetes.io/name: lb-mysql-server
spec:
  selector:
    app.kubernetes.io/name: lb-mysql-server
  ports:
  - name: lb-mysql-server
    protocol: TCP
    port: 3306
    targetPort: 3306

nginx负载均衡健康检查具体请见:TCP Health Checks
nginx loadBalancing



Tags:k8s   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
我们一起聊聊K8s定时备份MySQL并发送到指定邮箱
边车容器(sidecar):边车容器就是与主容器一起在一个pod中运行的容器,为业务容器赋能,共享一个网络空间,所以可以用127.0.0.1:3306连接主容器的数据库。一、背景:一开始的初衷是,想...【详细内容】
2023-12-29  Search: k8s  点击:(73)  评论:(0)  加入收藏
升级就崩溃,K8s需要LTS版本!
Kubernetes集群不是在升级,就是在升级的路上。而对于维护K8s集群的团队来说,最担心的莫过于,系统因为K8s升级而引发了服务器大规模崩溃。想象一下,K8s升级发生在某个晚上,突然某...【详细内容】
2023-12-05  Search: k8s  点击:(218)  评论:(0)  加入收藏
k8s部署维护问题汇总
集群问题系统Error: unknown flag: --etcd-quorum-read删除service 里面的相应字段start request repeated too quickly for kube-apiserver.service查看是不是有之前的进程...【详细内容】
2023-11-30  Search: k8s  点击:(195)  评论:(0)  加入收藏
五分钟 k8s 实战-滚动更新与优雅停机
当我们在生产环境发布应用时,必须要考虑到当前系统还有用户正在使用的情况,所以尽量需要做到不停机发版。所以在发布过程中理论上之前的 v1 版本依然存在,必须得等待 v2 版本启...【详细内容】
2023-11-30  Search: k8s  点击:(239)  评论:(0)  加入收藏
五分钟 K8s 实战-应用探针
今天进入 kubernetes 的运维部分(并不是运维 kubernetes,而是运维应用),其实日常我们大部分使用 kubernetes 的功能就是以往运维的工作,现在云原生将运维和研发关系变得更紧密了...【详细内容】
2023-11-27  Search: k8s  点击:(182)  评论:(0)  加入收藏
Kubernetes创始人发声!K8s在被反噬!
Kubernetes 变得太复杂了,它需要学会克制,否则就会停止创新,直至丢失大本营。Kubernetes 联合创始人Tim Hockin 罕见发声。在今年的 KubeCon 上,他建议,Kubernetes 核心维护者应...【详细内容】
2023-11-27  Search: k8s  点击:(156)  评论:(0)  加入收藏
K8s-服务网格实战-配置 Mesh(灰度发布)
在上一篇 k8s-服务网格实战-入门Istio中分享了如何安装部署 Istio,同时可以利用 Istio 实现 gRPC 的负载均衡。今天我们更进一步,深入了解使用 Istio 的功能。从 Istio 的流量...【详细内容】
2023-11-08  Search: k8s  点击:(339)  评论:(0)  加入收藏
Wasm的野心:取代K8s,不如结合K8s
作者丨B. Cameron Gain编译丨诺亚出品 | 51CTO技术栈(微信号:blog51cto)虽然WebAssembly (Wasm)已被证明在浏览器和某些有针对性的服务器部署中可以很好地工作,但允许开发人员“...【详细内容】
2023-11-07  Search: k8s  点击:(375)  评论:(0)  加入收藏
在本地 K8s 中轻松部署自签 TLS 证书
随着互联网的飞速发展,安全性日益成为我们关注的焦点。HTTPS 已从一项奢侈的技术逐渐成为现代网络交互的标准。它不仅仅是保护信息的重要工具,更是实现信任和品质的象征...【详细内容】
2023-11-03  Search: k8s  点击:(254)  评论:(0)  加入收藏
K8s-服务网格实战-入门Istio
背景终于进入大家都比较感兴趣的服务网格系列了,在前面已经讲解了: 如何部署应用到 kubernetes 服务之间如何调用 如何通过域名访问我们的服务 如何使用 kubernetes 自带的配...【详细内容】
2023-11-01  Search: k8s  点击:(230)  评论:(0)  加入收藏
▌简易百科推荐
Docker 和传统虚拟机有什么区别?
我有一个程序员朋友,他每年情人节都要送女朋友一台服务器。他说:“谁不想在过节当天收到一台 4核8g 的服务器呢?”“万一对方不要,我还能留着自己用。” 给他一次过节的机会,他能...【详细内容】
2024-03-26  小白debug  微信公众号  Tags:Docker   点击:(12)  评论:(0)  加入收藏
掌握Docker网络驱动程序:优化容器通信
Docker为在容器内包装、交付和运行应用程序提供了一个强大的平台,从而彻底改变了容器化。网络是容器化的重要组成部分,Docker提供了各种网络驱动程序来支持容器之间的通信以...【详细内容】
2024-03-22    51CTO  Tags:Docker   点击:(11)  评论:(0)  加入收藏
Containerd容器管理
Nginx 指定容器名称 使用 ctr container create 命令创建容器后,容器并没有处于运行状态,其只是一个静态的容器。容器基本操作容器基本操作主要是 ctr image 命令,查看命令帮...【详细内容】
2024-03-20  云原生运维圈  微信公众号  Tags:容器   点击:(13)  评论:(0)  加入收藏
如何基于Docker镜像逆向生成Dockerfile
引言你是否曾经遇到过一个想要使用的 Docker 镜像,但却无法修改以适应你的特定需求?或者你可能发现了一个喜欢的 Docker 镜像,但想要了解它是如何构建的?在这两种情况下,将 Docke...【详细内容】
2024-03-07  云原生运维圈  微信公众号  Tags:Docker   点击:(23)  评论:(0)  加入收藏
Kubernetes是什么?主要特点是什么?
Kubernetes是什么?Kubernetes,也称为K8s,是一个开源的容器编排系统,由Google首次开发和维护。它允许容器化的应用程序在集群中自动部署、扩展和管理。Kubernetes提供了一种容器...【详细内容】
2024-02-01    简易百科  Tags:Kubernetes   点击:(159)  评论:(0)  加入收藏
我们一起聊聊容器资源自愈
在企业实际在使用容器这类资源的时候,除了技术本身,要考虑的其他问题也会很多。企业管理的容器有千千万万,出于效率考虑,对于有特殊需求的容器如何进行批量创建和管理呢,这就需要...【详细内容】
2024-01-30  匠心独运维妙维效  微信公众号  Tags:容器   点击:(47)  评论:(0)  加入收藏
Docker与Docker Compose入门:释放你应用部署的威力
今天给大家介绍一项强大而有趣的技能,那就是使用 Docker 和 Docker Compose 来释放你的应用部署的威力!无论你是一名开发人员还是系统管理员,掌握这个技能都将为你的工作带来巨...【详细内容】
2024-01-17  waynblog  微信公众号  Tags:Docker   点击:(66)  评论:(0)  加入收藏
Docker镜像与容器的交互及在容器内部执行代码的原理与实践
Docker作为一种流行的容器技术,已经成为现代应用程序开发和部署的重要工具。在Docker中,镜像是构建和运行容器的基础,而容器则是基于镜像创建的可执行实例。Docker镜像与容器的...【详细内容】
2024-01-10  编程技术汇  今日头条  Tags:Docker   点击:(78)  评论:(0)  加入收藏
如何在 Ubuntu 上安装 Docker
使用 Docker 意味着开启一个新的计算领域,但如果你刚刚开始使用 Docker,安装可能看起来是一项艰巨的任务。在 Ubuntu 上安装 Docker 有两种推荐的方法: 从 Ubuntu 的仓库安装 D...【详细内容】
2024-01-04    Linux中国  Tags:Docker   点击:(124)  评论:(0)  加入收藏
从Kubernetes的探针到DevOps
今天在群里又看有人问如何设置 Kubernetes 的探针,感觉要补充的话太多了,结合我们在一些 DevOps 项目中痛苦的体验,今天一劳永逸的全部说完,此外,也为大家展现一下为什么 DevOps...【详细内容】
2023-12-27  云云众生s  微信公众号  Tags:Kubernetes   点击:(116)  评论:(0)  加入收藏
站内最新
站内热门
站内头条