Tungsten Fabric入门宝典丨关于集群更新的那些事(上)



  • Tungsten Fabric入门宝典系列文章,来自技术大牛倾囊相授的实践经验,由TF中文社区为您编译呈现,旨在帮助新手深入理解TF的运行、安装、集成、调试等全流程。如果您有相关经验或疑问,欢迎与我们互动,并与社区极客们进一步交流。更多TF技术文章,请点击【TF中文社区】公号底部按钮>学习>文章合集。
    
    作者:Tatsuya Naganawa  译者:TF编译组
    

    集群范围内的更新是很重要的功能,可以在保证生产集群的SLA的条件下提供集群中最新功能的有效性。

    由于Tungsten Fabric在MPLS-VPN中使用类似的协议,因此,根据我的尝试,即使Control的模块版本和vRouter的模块版本不同,基本的互操作性还是有的。

    因此,总体思路是,首先一个一个地更新controller,然后并根据需要使用vMotion或maintence模式逐一更新vRouter。

    另外,Tungsten Fabric controller还支持名为ISSU的奇特功能,但是我认为这个名称有些混乱,因为Tungsten Fabric controller与route reflector非常相似,而不是routing-engine。

    因此,基本思路是,首先将所有配置(configs)复制到新创建的controller(或route reflectors),然后更新vRouter设置(如果服务器可以重新启动,则更新vRouter模块)以使用这些新的controller。通过这个过程,vRouter模块更新的回滚操作也将更加容易。

    下面我来描述一下这个过程。

    就地更新(in-place update)

    由于ansible-deployer遵循等幂行为(idempotent behavior),因此更新与安装没有太大区别。以下的命令将更新所有模块。

    cd contrail-ansible-deployer
    git pull
    vi config/instances.yaml
    (update CONTRAIL_CONTAINER_TAG)
    ansible-playbook -e orchestrator=xxx -i inventory/ playbooks/install_contrail.yml
    

    一个限制是由于此命令几乎同时重启了所有节点,因此不容易做到一一重启controller和vRouter。另外,从instances.yaml中删除其它节点将不起作用,因为一个节点的更新需要其它节点的某些参数。

    • 例如,vRouter更新需要控件的IP,该IP是从instances.yaml中的control role节点推导出的

    为了克服这个问题,从R2005版本开始,ziu.yaml就加入了这个功能,至少对于控制平面来说,要逐一更新。

    cd contrail-ansible-deployer
    git pull
    vi config/instances.yaml
    (update CONTRAIL_CONTAINER_TAG)
    ansible-playbook -e orchestrator=xxx -i inventory/ playbooks/ziu.yml
    ansible-playbook -e orchestrator=xxx -i inventory/ playbooks/install_contrail.yml
    

    就我试过的情况来看,当控制平面更新时,它会进行串联更新和重启控制进程,所以没有看到掉包的现象。

    • 在install_contrail.yaml期间,控制进程的重启是被跳过的,因为它们已经更新了。

    • 当执行vrouter-agent重启时,仍然会出现一些丢包现象,所以如果可以的话,建议进行工作负载迁移。

    ISSU

    即使容器格式的差异很大(例如从4.x到5.x),我们也可以使用ISSU,因为它创建了一个新的controller集群,并在其中复制数据。

    首先,我来描述最简单的情况,即一个旧controller和一个新controller,以查看整个过程。所有命令都在新的controller上键入。

    old-controller:
     ip: 172.31.2.209
     hostname: ip-172-31-2-209
    new-controller:
     ip: 172.31.1.154
     hostname: ip-172-31-1-154
    
    (both controllers are installed with this instances.yaml)
    provider_config:
      bms:
       ssh_user: root
       ssh_public_key: /root/.ssh/id_rsa.pub
       ssh_private_key: /root/.ssh/id_rsa
       domainsuffix: local
       ntpserver: 0.centos.pool.ntp.org
    instances:
      bms1:
       provider: bms
       roles:
          config_database:
          config:
          control:
          analytics:
          analytics_database:
          webui:
       ip: x.x.x.x ## controller's ip
    contrail_configuration:
      CONTRAIL_CONTAINER_TAG: r5.1
      KUBERNETES_CLUSTER_PROJECT: {}
      JVM_EXTRA_OPTS: "-Xms128m -Xmx1g"
    global_configuration:
      CONTAINER_REGISTRY: tungstenfabric
    
    [commands]
    1. 停止批处理作业
    docker stop config_devicemgr_1
    docker stop config_schema_1
    docker stop config_svcmonitor_1
    
    2. 在cassandra上注册新的control,在它们之间运行bgp
    docker exec -it config_api_1 bash
    python /opt/contrail/utils/provision_control.py --host_name ip-172-31-1-154.local --host_ip 172.31.1.154 --api_server_ip 172.31.2.209 --api_server_port 8082 --oper add --router_asn 64512 --ibgp_auto_mesh
    
    3. 在控制器之间同步数据
    vi contrail-issu.conf
    (write down this)
    [DEFAULTS]
    old_rabbit_address_list = 172.31.2.209
    old_rabbit_port = 5673
    new_rabbit_address_list = 172.31.1.154
    new_rabbit_port = 5673
    old_cassandra_address_list = 172.31.2.209:9161
    old_zookeeper_address_list = 172.31.2.209:2181
    new_cassandra_address_list = 172.31.1.154:9161
    new_zookeeper_address_list = 172.31.1.154:2181
    new_api_info={"172.31.1.154": [("root"), ("password")]} ## ssh public-key can be used
    
    image_id=`docker images | awk '/config-api/{print $3}' | head -1`
    
    docker run --rm -it --network host -v $(pwd)/contrail-issu.conf:/etc/contrail/contrail-issu.conf --entrypoint /bin/bash -v /root/.ssh:/root/.ssh $image_id -c "/usr/bin/contrail-issu-pre-sync -c /etc/contrail/contrail-issu.conf"
    
    4. 启动进程进行实时数据同步
    docker run --rm --detach -it --network host -v $(pwd)/contrail-issu.conf:/etc/contrail/contrail-issu.conf --entrypoint /bin/bash -v /root/.ssh:/root/.ssh --name issu-run-sync $image_id -c "/usr/bin/contrail-issu-run-sync -c /etc/contrail/contrail-issu.conf"
    
    (如果需要,请检查日志)
    docker exec -t issu-run-sync tail -f /var/log/contrail/issu_contrail_run_sync.log
    
    5. (更新 vrouters)
    
    6. 在结束后停止作业,同步所有数据
    docker rm -f issu-run-sync
    
    image_id=`docker images | awk '/config-api/{print $3}' | head -1`
    docker run --rm -it --network host -v $(pwd)/contrail-issu.conf:/etc/contrail/contrail-issu.conf --entrypoint /bin/bash -v /root/.ssh:/root/.ssh --name issu-run-sync $image_id -c "/usr/bin/contrail-issu-post-sync -c /etc/contrail/contrail-issu.conf"
    docker run --rm -it --network host -v $(pwd)/contrail-issu.conf:/etc/contrail/contrail-issu.conf --entrypoint /bin/bash -v /root/.ssh:/root/.ssh --name issu-run-sync $image_id -c "/usr/bin/contrail-issu-zk-sync -c /etc/contrail/contrail-issu.conf"
    
    7. 从cassandra中去掉旧的节点,加入新的节点
    vi issu.conf
    (write down this)
    [DEFAULTS]
    db_host_info={"172.31.1.154": "ip-172-31-1-154.local"}
    config_host_info={"172.31.1.154": "ip-172-31-1-154.local"}
    analytics_host_info={"172.31.1.154": "ip-172-31-1-154.local"}
    control_host_info={"172.31.1.154": "ip-172-31-1-154.local"}
    api_server_ip=172.31.1.154
    
    docker cp issu.conf config_api_1:issu.conf
    docker exec -it config_api_1 python /opt/contrail/utils/provision_issu.py -c issu.conf
    
    8. 启动批处理作业
    docker start config_devicemgr_1
    docker start config_schema_1
    docker start config_svcmonitor_1
    

    以下将是可能的检查点。

    1. 步骤3之后,你可以尝试使用contrail-api-cli ls -l *来查看所有数据是否已成功复制,并且可以通过ist.py ctr nei来查看controller之间的ibgp是否已启动。

    2. 步骤4之后,你可以修改旧数据库,以查看更改是否可以成功传播到新数据库。

    接下来,我将在使用编排器和两个vRouter的条件下,讨论更为实际的情况。

    编排器集成

    为了说明结合编排器的情况,我尝试用ansible-deployer部署两个vRouters和kubernetes。

    即使与编排器结合使用,总体过程也不会有太大不同。

    需要注意的是,需要在什么时候将kube-manager更改为新的。

    从某种意义上讲,由于kube-manager动态订阅了来自kube-apiserver的事件并更新了Tungsten Fabric配置数据库(config-database),因此它类似于批处理作业,例如schema-transformer、svc-monitor和device-manager。因此,我使用此类批处理作业,同时停止并启动了旧的或新的kube-manager(实际上也包括webui),但是可能需要根据每个设置进行更改。

    这个示例中的总体过程如下所示。

    1.设置一个controller(带有一个kube-manager和kubernetes-master)和两个vRouter
    2.设置一个新的controller(带有一个kube-manager,但kubernetes-master与旧的controller相同)
    3.停止批处理作业、新controller的kube-manager和webui
    4.启动ISSU进程并继续执行,直到开始运行同步(run-sync)
      ->将在controller之间建立iBGP
    5.根据新controller的ansible-ployer一个一个地更新vRouter
       ->将一个vRouter移至新的vRouter时,新的controller也将获得k8s-default-pod-network的路由目标(route-target),并且容器之间仍然可以ping通正常工作(ist.py ctr路由摘要以及ping的结果将在稍后附上)
    6.将所有vRouter移至新的controller后,停止批处理作业、旧controller上的kube-manager和webui
        之后,继续执行ISSU进程,新controller上启动批处理作业, kube-manager和webui
       ->这个阶段从开始到结束,你都无法手动更改config-database,因此可能需要一些维护时间
       (整个过程可能会持续5至15分钟,可以ping通,但是直到启动新的kube-manager时,新容器的创建才能正常工作)
    7.最后,停止旧的节点上的control、config和config-database
    

    更新vRouters时,我使用了controller的provider: bms-maint,k8s_master和vRouter,它们都已经更改为新的,以避免由于容器重启而造成干扰。我附上了原始instances.yaml和更新vRouter的instances.yaml,以便大家获取更多详细信息。

    我还将在每个阶段附加ist.py ctr nei和ist.py ctr路由摘要的结果,以说明发生的相关细节。

    • 请注意,在此示例中,我实际上并未更新模块,因为此设置主要是为了突出ISSU进程(因为即使模块版本相同,ansible-deployer也会重新创建vrouter-agent容器,同时即使完成实际的模块更新,丢包的数量也不会有太大不同。)

    Tungsten Fabric入门宝典丨关于集群更新的那些事(下)


    Tungsten Fabric入门宝典系列文章——

    1.首次启动和运行指南
    2.TF组件的七种“武器”
    3.编排器集成
    4.关于安装的那些事(上)
    5.关于安装的那些事(下)
    6.主流监控系统工具的集成
    7.开始第二天的工作
    8.8个典型故障及排查Tips

    Tungsten Fabric 架构解析系列文章——
    第一篇:TF主要特点和用例
    第二篇:TF怎么运作
    第三篇:详解vRouter体系结构
    第四篇:TF的服务链
    第五篇:vRouter的部署选项
    第六篇:TF如何收集、分析、部署?
    第七篇:TF如何编排
    第八篇:TF支持API一览
    第九篇:TF如何连接到物理网络?
    第十篇:TF基于应用程序的安全策略


Log in to reply