阿里云k8s容器部署consul集群的高可用方案

这篇具有很好参考价值的文章主要介绍了阿里云k8s容器部署consul集群的高可用方案。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、背景

原本consul集群是由三个server节点搭建的,购买的是三个ecs服务器,
consul高可用方案,阿里云,kubernetes,consul,java,spring,spring boot
consul高可用方案,阿里云,kubernetes,consul,java,spring,spring boot
java服务在注册到consul的时候,随便选择其中一个节点。
从上图可以看出, consul-01有28个服务注册,而consul-02有94个服务,consul-03则是29个。

有一次发生consul集群故障,某个conusl节点挂了,导致整个的服务发现都不通。

所以,我们需要进一步提高consul的高可用。

二、consul集群的高可用方案

consul高可用方案,阿里云,kubernetes,consul,java,spring,spring boot
consul server有三个节点,保持不变,仍旧部署在ecs。

在k8s各个节点都部署一个consul agent,同一个节点上的pod服务依赖于当前节点的consul agent。

我这里的k8s容器共有11个节点,所以会再部署11个consul agent。
consul高可用方案,阿里云,kubernetes,consul,java,spring,spring boot

三、部署总结

1、ConfigMap挂载配置文件consul.json

consul高可用方案,阿里云,kubernetes,consul,java,spring,spring boot

apiVersion: v1
kind: ConfigMap
metadata:
  name: consul-client
  namespace: consul
data:
  consul.json: |-
    {
      "datacenter": "aly-consul",
      "addresses" : {
        "http": "0.0.0.0",
        "dns": "0.0.0.0"
      },
      "bind_addr": "{{ GetInterfaceIP \"eth0\" }}",  
      "client_addr": "0.0.0.0",
      "data_dir": "/consul/data",
      "rejoin_after_leave": true,
      "retry_join": ["10.16.190.29", "10.16.190.28", "10.16.190.30"],
      "verify_incoming": false,
      "verify_outgoing": false,
      "disable_remote_exec": false,
      "encrypt":"Qy3w6MjoXVOMvOMSkuj43+buObaHLS8p4JONwvH0RUg=",
      "encrypt_verify_incoming": true,
      "encrypt_verify_outgoing": true,
      "acl": {
        "enabled": true,
        "default_policy": "deny",
        "down_policy": "extend-cache",
        "tokens" :{ "agent": "xxxx-xx-xx-xx-xxxx" }
     }
    }


这里有几个地方需要额外注意:

  • datacenter和consul server所在的dc保持一致
  • bind_addr 采用读取的方式,不能写死
  • acl 填写consul集群的访问token

2、DaemonSet守护进程集

这里采用守护进程来实现,在各个节点只部署一个consul agent。DaemonSet的典型使用场景:除本案例外,还适用于日志和监控等等。你只需要在每个节点仅部署一个filebeat和node-exporter,大大节约了资源。

consul高可用方案,阿里云,kubernetes,consul,java,spring,spring boot
可以看到容器组共11个。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: consul-client
  namespace: consul
  labels:
    app: consul
    environment: prod
    component: client
spec:
  minReadySeconds: 60
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: consul
      environment: prod
      commponent: client
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      namespace: consul
      labels:
        app: consul
        environment: prod
        commponent: client
    spec:
      containers:
      - env:
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        - name: HOST_IP
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: status.hostIP
        - name: POD_IP
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: status.podIP
        name: consul-client
        image: consul:1.6.2
        imagePullPolicy: IfNotPresent
        command:
        - "consul"
        - "agent"
        - "-config-dir=/consul/config"
        lifecycle:
          postStart:
            exec:
              command:
              - /bin/sh
              - -c
              - |
                # 最大尝试次数
                max_attempts=30
                # 每次尝试之间的等待时间(秒)
                wait_seconds=2

                attempt=1
                while [ $attempt -le $max_attempts ]; do
                  echo "Checking if Consul is ready (attempt: $attempt)..."
                  
                  # 使用curl检查Consul的健康状态
                  if curl -s http://127.0.0.1:8500/v1/agent/self > /dev/null; then
                    echo "Consul is ready."
                    
                    # 执行reload操作
                    consul reload
                    exit 0
                  else
                    echo "Consul is not ready yet."
                  fi
                  
                  # 等待指定的时间后再次尝试
                  sleep $wait_seconds
                  attempt=$((attempt + 1))
                done

                echo "Consul did not become ready in time."
                exit 1
          preStop:
            exec:
              command:
              - /bin/sh
              - -c
              - consul leave
        ports:
        - name: http-api
          hostPort: 8500
          containerPort: 8500
          protocol: TCP
        - name: dns-tcp
          hostPort: 8600
          containerPort: 8600
          protocol: TCP
        - name: dns-udp
          hostPort: 8600
          containerPort: 8600
          protocol: UDP
        - name: server-rpc
          hostPort: 8300
          containerPort: 8300
          protocol: TCP
        - name: serf-lan-tcp
          hostPort: 8301
          containerPort: 8301
          protocol: TCP
        - name: serf-lan-udp
          hostPort: 8301
          containerPort: 8301
          protocol: UDP
        - name: serf-wan-tcp
          hostPort: 8302
          containerPort: 8302
          protocol: TCP
        - name: serf-wan-udp
          hostPort: 8302
          containerPort: 8302
          protocol: UDP
        volumeMounts:
        - name: consul-config
          mountPath: /consul/config/consul.json
          subPath: consul.json
        - name: consul-data-dir
          mountPath: /consul/data
        - name: localtime
          mountPath: /etc/localtime
        livenessProbe:
          tcpSocket:
            port: 8500
          initialDelaySeconds: 30
          periodSeconds: 10
          successThreshold: 1
          failureThreshold: 3
          timeoutSeconds: 1
        readinessProbe:
          httpGet:
           path: /v1/status/leader
           port: 8500
          initialDelaySeconds: 60
          periodSeconds: 10
          successThreshold: 1
          failureThreshold: 3
          timeoutSeconds: 1
        resources:
          requests:
            memory: "256Mi"
            cpu: "200m"
          limits:
            memory: "1024Mi"
            cpu: "1000m"
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      hostNetwork: true
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
      volumes:
      - name: consul-config
        configMap:
          name: consul-client
          items:
          - key: consul.json
            path: consul.json
      - name: consul-data-dir
        hostPath:
          path: /data/consul/data
          type: DirectoryOrCreate
      - name: localtime
        hostPath:
          path: /etc/localtime
          type: File

四、踩过的坑

1、报错 ==> Multiple private IPv4 addresses found. Please configure one with ‘bind’ and/or ‘advertise’.

解决办法:

修改consul.json中的"bind_addr": “{{ GetInterfaceIP “eth0” }}”

2、lifecycle,在pod创建成功后,执行consul reload失败,导致consul pod节点反复重启。

进一步描述错误现象,consul agent加入到consul集群,但是一会儿容器又挂了,导致又退出consul集群。

我尝试去掉健康检测,没能解决,容器还是会挂。

所以不是健康检测的问题。

        lifecycle:
          postStart:
            exec:
              command:
              - /bin/sh
              - -c
              - consul reload
          preStop:
            exec:
              command:
              - /bin/sh
              - -c
              - consul leave

后面修改为重试consul reload。

                # 最大尝试次数
                max_attempts=30
                # 每次尝试之间的等待时间(秒)
                wait_seconds=2

                attempt=1
                while [ $attempt -le $max_attempts ]; do
                  echo "Checking if Consul is ready (attempt: $attempt)..."
                  
                  # 使用curl检查Consul的健康状态
                  if curl -s http://127.0.0.1:8500/v1/agent/self > /dev/null; then
                    echo "Consul is ready."
                    
                    # 执行reload操作
                    consul reload
                    exit 0
                  else
                    echo "Consul is not ready yet."
                  fi
                  
                  # 等待指定的时间后再次尝试
                  sleep $wait_seconds
                  attempt=$((attempt + 1))
                done

                echo "Consul did not become ready in time."
                exit 1

3、忽略错误 [ERR] agent: failed to sync remote state: No known Consul servers,这个属于正常现象。

不要被这个错误日志给误导了,你只要保证后文有类似日志。

2024/02/21 11:09:42 [INFO] consul: adding server aly-consul-02 (Addr: tcp/10.16.190.29:8300) (DC: aly-consul)

4、别忘记了配置acl,否则consul agent是无法加入到consul server集群的。

"acl": {
    "enabled": true,
    "default_policy": "deny",
    "down_policy": "extend-cache",
    "tokens" : {
        "agent": "xxxx-xx-xx-xx-xxxx"
    }
 }

五、服务接入示例

在deployment.yaml中增加环境变量。

    containers:
        - env:
            - name: HOST_IP
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: status.hostIP
            - name: POD_IP
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: status.podIP
            - name: CONFIG_SERVICE_ENABLED
              value: 'true'
            - name: CONFIG_SERVICE_PORT
              value: 8500
            - name: CONFIG_SERVICE_HOST
              value: $(HOST_IP)

spring boot工程的bootstrap.yml配置见下

spring:
  application:
    name: xxx-service
  cloud:
    consul:
      enabled: ${CONFIG_SERVICE_ENABLED}
      host: ${CONFIG_SERVICE_HOST}
      port: ${CONFIG_SERVICE_PORT}
      discovery:
        prefer-ip-address: true
        enabled: ${CONFIG_SERVICE_ENABLED}
      config:
        format: yaml
        enabled: ${CONFIG_SERVICE_ENABLED}

六、总结

本文是以java服务注册到consul为示例,给你讲述了从部署到接入的全过程。

consul地址,这里填写的是ip地址,而非域名。
也就是说,与服务在同一个节点上的consul如果挂了,也就导致服务启动的时候,会注册失败。

有人会想,可不可以像nginx反向代理后端服务那样,由k8s service或者nginx反向consul集群呢?

如下图所示:
consul高可用方案,阿里云,kubernetes,consul,java,spring,spring boot
不建议你这样去做,因为consul作为服务注册中心,有一个基本要求是:
java服务是从哪个consul注册的服务就要从那个consul注销。

所以负载均衡对后端consul agent就会要求有状态,而非无状态。

好了, consul的高可用部署就写到这里。文章来源地址https://www.toymoban.com/news/detail-851211.html

到了这里,关于阿里云k8s容器部署consul集群的高可用方案的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于kubeasz部署高可用k8s集群

    在部署高可用k8s之前,我们先来说一说单master架构和多master架构,以及多master架构中各组件工作逻辑 k8s单master架构 提示:这种单master节点的架构,通常只用于测试环境,生产环境绝对不允许;这是因为k8s集群master的节点是单点,一旦master节点宕机,将导致整个集群不可用;

    2023年04月23日
    浏览(45)
  • k8s集群部署 | 三节点(复用)高可用集群过程参考

    1.1.1 实验架构图 1.1.2 系统版本说明 OS 版本:CentOS Linux release 7.9.2009 (Core) 初始内核版本:3.10.0-1160.71.1.el7.x86_64 配置信息:2C2G 150G硬盘 文件系统:xfs 网络:外网权限 k8s 版本:1.25.9 1.1.3 环境基本信息 K8s集群角色 IP地址 主机名 组件信息 控制节点1(工作节点1) 192.168.204.10 k8

    2024年02月04日
    浏览(52)
  • shell 脚本一键部署 k8s 高可用集群

    github地址:https://github.com/Johnny-Demo/deploy/tree/k8s-cluster README.md 要修改脚本里面的 ip 地址,根据自己情况修改,然后在部署,要不然会出错。 执行 kernel.sh 升级 linux 内核,关闭 selinux 和 swap 分区,重启服务器。 执行 run.sh 部署k8s,master 和 node 手动加入集群,无法自动获取加入

    2024年02月07日
    浏览(35)
  • k8s集群中部署rancher v2.7高可用集群

    一,什么是 Rancher?  官网地址: 什么是 Rancher? | Rancher Manager Rancher 是一个 Kubernetes 管理工具,让你能在任何地方和任何提供商上部署和运行集群。 Rancher 可以创建来自 Kubernetes 托管服务提供商的集群,创建节点并安装 Kubernetes,或者导入在任何地方运行的现有 Kubernetes 集群

    2024年02月07日
    浏览(39)
  • kubeadm部署k8s 1.26.0版本高可用集群

    1.前言 本次搭建使用centos7.9系统,并且使用haproxy+keepalived作为高可用架构软件,haproxy实现k8s集群管理节点apiserver服务的负载均衡以实现集群的高可用功能,keepalived保障了hapxoy的高可用,容器引擎使用docker,需要额外引入cri-docker服务,且使用集群内置的etcd服务,并配置etcd的

    2024年02月11日
    浏览(48)
  • Kubeadm - K8S1.20 - 高可用集群部署(博客)

    1.系统设置 注意事项: master节点cpu核心数要求大于2 ●最新的版本不一定好,但相对于旧版本,核心功能稳定,但新增功能、接口相对不稳 ●学会一个版本的 高可用部署,其他版本操作都差不多 ●宿主机尽量升级到CentOS 7.9 ●内核kernel升级到 4.19+ 这种稳定的内核 ●部署k8

    2024年02月05日
    浏览(43)
  • Centos7 安装部署 Kubernetes(k8s) 高可用集群

    宿主机系统 集群角色 服务器IP 主机名称 容器 centos7.6 master 192.168.2.150 ks-m1 docker centos7.6 master 192.168.2.151 ks-n1 docker centos7.6 master 192.168.2.152 ks-n2 docker 1.1 服务器初始化及网络配置 VMware安装Centos7并初始化网络使外部可以访问** 注意事项:请一定要看完上面这篇文章再执行下面的操

    2024年02月03日
    浏览(58)
  • k8s1.27.2版本二进制高可用集群部署

    说明:本次实验共有5台主机,3台master节点同时又是worker,os128、os129、os130 节点主机容器运行时用的containerd,worker131、worker132主机的用的docker 主机名 IP 组件 系统 os128 192.168.177.128 etcd、kube-apiserver、kube-controller-manager、kube-scheduler、kubelet、kube-proxy、containerd CentOS7.9 os129 192.16

    2024年01月22日
    浏览(91)
  • 【Flink系列】部署篇(三):Native k8s部署高可用Flink集群实战

    上一篇博文介绍了如何独立部署一个高可用的Flink集群,本篇介绍如何用Native k8s去部署高可用的Flink 集群。本篇介绍的集群构建在AWS上,和构建在自己的服务器相比,主要区别在文件系统的选择和使用上。我选用的S3服务。 EC2操作系统:centos7 本机操作系统:Mac flink version: 1.

    2024年02月02日
    浏览(46)
  • Kubernetes(k8s)部署高可用多主多从的Redis集群

    首先你需要一个Kubernetes集群,如图我已经安装好了一个Kubernetes集群: 如果你还没有Kubernetes集群可参考我写的文章:https://blog.csdn.net/m0_51510236/article/details/130842122 你还需要一个可动态供应的存储类,我之前已经写过一篇关于安装NFS动态供给存储类的文章:https://blog.csdn.net/m

    2024年02月09日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包