码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 基于istio实现单集群地域故障转移


    合集 - 开发与运维(65)
    1.面试官:你能简单聊聊MyBatis执行流程02-022.一文详解应用安全防护ESAPI02-043.一个线程,从“生”到“死”经历的过程02-054.KubeEdge v1.16.0 版本发布!10项新增特性02-055.解密JavaChassis3:易扩展的多种注册中心支持02-066.解析Sermant热插拔能力:服务运行时动态挂载JavaAgent和插件02-087.想设计一个高并发的消息中间件前,先熟悉一下这些知识点02-178.华为云GES助力九洲平台:探索确定性运维的新实践02-179.0-overlay和underlay,这两种容器网络你分得清吗02-1810.教你用Rust实现Smpp协议02-1811.基于OpenTelemetry实现Java微服务调用链跟踪02-1912.揭开华为云ADN提高网络质量的秘密02-1913.详解网络知识:iptables规则02-1914.实例详解在Go中构建流数据pipeline02-2115.面试官让我讲讲MySQL三大核心日志实现原理02-2116.华为云帕鲁服务器-云耀云容器版,到底强在哪?02-2217.掌握云容器网络:何为ipvs02-2218.一文带你了解容器探针02-2319.教你如何判断Java代码中异步操作是否完成02-2620.深入解析Python并发编程的多线程和异步编程02-2721.教你如何用Keepalived和HAproxy配置高可用 Kubernetes 集群02-2822.容器化环境中,JVM最佳参数配置实践02-2923.关于Python中math 和 decimal 模块的解析与实践02-2924.运维一款月变更70+次的服务,是一种什么体验?03-0125.详解Python中sys模块的功能与应用03-0426.教你用Ubuntu快速搭建饥荒服务器03-0427.分享一个能让你的研发效率提升超过20%的工具03-0628.下一代积木式智能组装编排,集成开发效率10倍提升03-0629.如何基于容器网络流量指标进行弹性伸缩03-0630.Sermant运行流程学习笔记,速来抄作业03-0631.用几张图实战讲解MySQL主从复制03-0732.速存,详细罗列香橙派AIpro外设接口样例大全(附源码)03-0733.CCE集群VPC网络模式下几种访问场景03-1134.聊聊CWE 4.14 与 ISA/IEC 62443中,如何保障工业软件的安全性03-1235.20个Python random模块的代码示例03-1336.Java获取堆栈信息的3种方法03-1337.Prometheus多集群监控的3种方案,你选哪种?03-1438.手把手的使用Toolkit插件在诗情画意中完成AI诗朗诵03-1439.从基础到代码实战,带你进阶正则表达式的全方位应用03-1440.掌握Python库的Bokeh,就能让你的交互炫目可视化03-1541.从0带你设计与实现基于STM32的智慧农业管理系统03-1542.Python实践:基于Matplotlib实现某产品全年销量数据可视化03-1843.何为代码检查服务的门禁级检查03-1944.深入分析Java中的PriorityQueue底层实现与源码03-1945.如何在Docker容器启动时自动运行脚本03-2046.从静态到动态化,Python数据可视化中的Matplotlib和Seaborn03-2547.无人不识又无人不迷糊的this03-2648.保姆级教程:教你UniMRCP对接华为云ASR(Linux版)03-2649.华为云亮相KubeCon EU 2024,以持续开源创新开启智能时代03-2650.如何用Flask中的Blueprints构建大型Web应用03-2751.手把手带你用香橙派AIpro开发AI推理应用03-2752.保护主机安全,我来buff加成03-2853.探索华为云CCE敏捷版金融级高可用方案实践案例03-2854.Python数据库编程全指南SQLite和MySQL实践03-2855.标准库unsafe:带你突破golang中的类型限制03-2956.【重磅干货】大模型时代,开发者云上成长指南03-2957.探索Django REST框架构建强大的API03-2958.实例演示如何使用CCE XGPU虚拟化04-0159.浅谈JVM整体架构与调优参数04-0260.Redis开源协议调整,我们怎么办?04-0261.一文教你实战构建消息通知系统Django04-0262.kube-apiserver限流机制原理04-0763.详解Java Chassis 3与Spring Cloud的互操作04-1064.大量数据如何做分页处理04-10
    65.基于istio实现单集群地域故障转移04-10
    收起

    本文分享自华为云社区《基于istio实现单集群地域故障转移》,作者:可以交个朋友。

    一 背景

    随着应用程序的增长并变得更加复杂,微服务的数量也会增加,失败的可能性也会增加。微服务的故障可能多种原因造成,例如硬件问题、网络延迟、软件错误,甚至人为错误。故障转移Failover 是系统韧性设计中的一个基础能力,它们可以确保系统在出现故障时能够继续运行,并且能够在最小化的影响下进行恢复,减少或者消除对使用方或最终用户的影响,从而提高整个系统对外的可用性。

    二 简介

    云原生K8s、istio默认使用node上特定label作为地域信息:

    • 地区:代表较大的地理区域,例如 us-east。一个地区通常包含许多可用区。 在 Kubernetes 中,标签topology.kubernetes.io/region 决定了节点所在的地区。
    • 区域:区域内的一组计算资源。通过在区域内的多个区域中运行服务,可以在区域内的区域之间进行故障转移, 同时保持最终用户的数据地域性。在 Kubernetes 中,标签topology.kubernetes.io/zone决定了节点所在的区域。
    • 分区:允许管理员进一步细分区域,以实现更细粒度的控制,例如“相同机架”。 Kubernetes 中不存在分区的概念。所以 Istio 引入了自定义节点标签 topology.istio.io/subzone 来定义分区。

    kubectl describe node xxx |grep topo

    cke_114.png

    如下图所示演示环境,helloworld作为服务端有多个实例分别部署在不同zone中(不同zone节点topology.kubernetes.io/zone的label不同)。通过istio的destinationrule中localityLbSetting.failover(故障转移策略)和outlierDetection(故障异常点检测),可以实现客户端业务访问helloworld服务时候,优先访问与客户端同可用区的服务端,当同可用区的helloworld服务端全部故障后,再访问指定可用区的服务端,实现故障转移。

    cke_115.png

    三 实战演练

    事先准备好kubernetes+istio作为操作环境。可用华为云CCE和ASM服务进行操作。

    3.1 部署服务端

    1.创建sample 命名空间,并设置istio-proxy sidecar自动注入

    复制代码
    apiVersion: v1
    kind: Namespace
    metadata:
      name: sample
      labels:
        istio-injection: enabled
    复制代码

    2.部署helloworld服务 作为服务端

    将根据以下脚本生成对yaml配置清单

    复制代码
    #!/bin/bash
    
    set -euo pipefail
    
    display_usage() {
        echo
        echo "USAGE: ./gen-helloworld.sh [--version] [--includeService value] [--includeDeployment value]"
        echo "    -h|--help: Prints usage information"
        echo "    --version: Specifies the version that will be returned by the helloworld service, default: 'v1'"
        echo "    --includeService: If 'true' the service will be included in the YAML, default: 'true'"
        echo "    --includeDeployment: If 'true' the deployment will be included in the YAML, default: 'true'"
    }
    
    INCLUDE_SERVICE=${INCLUDE_SERVICE:-"true"}
    INCLUDE_DEPLOYMENT=${INCLUDE_DEPLOYMENT:-"true"}
    SERVICE_VERSION=${SERVICE_VERSION:-"v1"}
    while (( "$#" )); do
      case "$1" in
        -h|--help)
          display_usage
          exit 0
          ;;
    
        --version)
          SERVICE_VERSION=$2
          shift 2
          ;;
    
        --includeService)
          INCLUDE_SERVICE=$2
          shift 2
          ;;
    
        --includeDeployment)
          INCLUDE_DEPLOYMENT=$2
          shift 2
          ;;
    
        *)
          echo "Error: Unsupported flag $1" >&2
          display_usage
          exit 1
          ;;
      esac
    done
    
    SERVICE_YAML=$(cat <<EOF
    apiVersion: v1
    kind: Service
    metadata:
      name: helloworld
      labels:
        app: helloworld
        service: helloworld
    spec:
      ports:
      - port: 5000
        name: http
      selector:
        app: helloworld
    EOF
    )
    
    DEPLOYMENT_YAML=$(cat <<EOF
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: helloworld-${SERVICE_VERSION}
      labels:
        app: helloworld
        version: ${SERVICE_VERSION}
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: helloworld
          version: ${SERVICE_VERSION}
      template:
        metadata:
          labels:
            app: helloworld
            version: ${SERVICE_VERSION}
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: topology.istio.io/subzone
                    operator: In
                    values:
                    - ${SERVICE_VERSION}            
    
          containers:
          - name: helloworld
            env:
            - name: SERVICE_VERSION
              value: ${SERVICE_VERSION}
            image: docker.io/istio/examples-helloworld-v1
            resources:
              requests:
                cpu: "100m"
            imagePullPolicy: IfNotPresent
            ports:
            - containerPort: 5000
    EOF
    )
    
    OUT=""
    
    # Add the service to the output.
    if [[ "$INCLUDE_SERVICE" == "true" ]]; then
      OUT="${SERVICE_YAML}"
    fi
    
    # Add the deployment to the output.
    if [[ "$INCLUDE_DEPLOYMENT" == "true" ]]; then
      # Add a separator
      if [[ -n "$OUT" ]]; then
        OUT+="
    ---
    "
      fi
      OUT+="${DEPLOYMENT_YAML}"
    fi
    
    echo "$OUT"
    复制代码

    执行脚本: for LOC in "beijing" "tianjin" "shenyang"; do ./genHelloWorld.sh --version "$LOC" > "helloworld-${LOC}.yaml"; done 将会生成yaml配置清单,应用到集群即可。

    kubectl apply -f helloworld-xxx.yaml -n sample

    cke_116.png

    3.2 部署客户端

    kubectl apply -f sleep.yaml -n sample

    复制代码
    # Sleep service
    ##################################################################################################
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: sleep
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: sleep
      labels:
        app: sleep
        service: sleep
    spec:
      ports:
      - port: 80
        name: http
      selector:
        app: sleep
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sleep
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: sleep
      template:
        metadata:
          labels:
            app: sleep
        spec:
          terminationGracePeriodSeconds: 0
          serviceAccountName: sleep
          containers:
          - name: sleep
            image: curlimages/curl
            command: ["/bin/sleep", "infinity"]
            imagePullPolicy: IfNotPresent
            volumeMounts:
            - mountPath: /etc/sleep/tls
              name: secret-volume
          volumes:
          - name: secret-volume
            secret:
              secretName: sleep-secret
              optional: true
    ---
    复制代码

    cke_117.png

    查看客户端中的存储的cluster信息

    kubectl exec -it sleep-xxx -c istio-proxy -n sample -- curl localhost:15000/clusters可以看到cluster信息中包含了实例的PodIP和位置信息

    cke_118.png

    3.3 配置服务端地域故障转移规则

    istio的流量治理一般都是通过virtualservice、destinationrule 、envoyfilter等来实现,其中地域故障转移是通过destinationrule配置实现的。因为在destinationrule中可以配置outerlineDecetion进行异常点检测,只有检测到异常后,才会进行故障转移。kubectl apply -f xxx.yaml

    复制代码
    apiVersion: networking.istio.io/v1beta1
    kind: DestinationRule
    metadata:
      name: helloworld
      namespace: sample
    spec:
      host: helloworld.sample.svc.cluster.local
      trafficPolicy:
        connectionPool:
          http:
            maxRequestsPerConnection: 1
        loadBalancer:
          simple: ROUND_ROBIN
          localityLbSetting:  #开启地域负载均衡
            enabled: true
            failover:         #配置故障转移策略,failover主要控制Region等上层位置的切换
              - from: cn-north-4
                to: cn-south-1
        outlierDetection:    #异常点检测
          consecutive5xxErrors: 1
          interval: 1s
          baseEjectionTime: 1m
    复制代码

    以上治理策略表示:

    • 异常点检测:当某个客户端访问helloworld服务时,客户端对应的envoy会根据本次访问HTTP状态码对转发的服务端进行故障检测,故障检测条件为当发生1次5xx错误时实例就会被隔离1m。
    • 故障隔离:当指定region的所有后端实例均不正常,触发故障转移到下一个地域,确保了超出地区边界的故障转移将具有可预测的行为。如果位于cn-north-4 region的实例异常,流量就会发往cn-south-1 region 的实例。

    3.4 验证地域负载均衡

    通过位于cn-north-4/cn-north-4b/tianjin 的Sleep Pod 多次调用 HelloWorld 服务,均访问成功。

    cke_119.png

    同时可以发现服务端响应的Pod总是同一个

    cke_120.png

    查看sleep实例的proxy日志,通过日志中的%UPSTREAM_HOST%字段(红框标准)172.16.0.136,可以看到5个请求均被发送到相同的子区域helloworld实例(Pod IP为172.16.0.136)。

    cke_121.png

    这是因为istio考虑到网络开销,部署在region1/zone1上的sleep实例 大多时候只会访问部署在同Region同Zone的helloworld实例。

    3.5 验证地域故障转移

    首先模拟故障,通过下述命令 向 enovy 的 admin port 发送请求,关闭envoy的 listener 。enovy 收到请求后,会取消端口监听,不再接收新的连接和请求。

    kubectl exec helloworld-tianjin-xxx -n sample -c istio-proxy -- curl -sSL -X POST 127.0.0.1:15000/drain_listeners

    cke_122.png

    再次通过位于cn-north-4/cn-north-4b/tianjin 的Sleep Pod 多次调用 HelloWorld 服务。

    cke_123.png

    可以发现4个请求被以轮询的方式发往cn-north-4/cn-north-4b/beijing 和cn-north-4/cn-north-4b/shenyang的 helloworld实例。以上结果说明,在一个区域的服务实例发生故障时,可根据配置,将请求路由到其它地域的服务实例进行处理,增强服务的可靠性。在实践中可通过From、To 配置region地区信息,控制在不同地区的实例上进行故障转移。

    四 备注

    关于地域负载均衡的配置failover主要控制的是跨region的场景,因为位于region内的zone或者subzone 上的实例默认就可以切换流量。本文档的实践主要是在region内进行操作的,所以不能演示完整的跨地域故障转移。一般也多用在多集群的治理环境中。

    cke_124.png

     

    点击关注,第一时间了解华为云新鲜技术~

     

  • 相关阅读:
    中小学数学卷子自动生成程序
    R语言使用HTTP爬虫IP写一个程序
    SpringBoot 01 HelloSpringBoot
    面试题-3
    408 | 【2015年】计算机统考真题 自用回顾知识点整理
    ROS学习(28)Web GUI
    基于食肉植物优化算法的线性规划问题求解matlab程序
    Android Studio的安装
    数字通信世界杂志数字通信世界杂志社数字通信世界编辑部2022年第6期目录
    【算法05】合并两个有序链表
  • 原文地址:https://www.cnblogs.com/huaweiyun/p/18126164
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号