#!/bin/bash namespace="default" root_path="by-dev" operation="migrate" image_tag="milvusdb/milvus:v2.2.0" meta_migration_pod_tag="milvusdb/meta-migration:v2.2.0-bugfix-20230112" remove_migrate_pod_after_migrate="false" storage_class="" external_etcd_svc="" etcd_svc="" #-n namespace: The namespace that Milvus is installed in. #-i milvus_instance: The name of milvus instance. #-s source_version: The milvus source version. #-t target_version: The milvus target version. #-r root_path: The milvus meta root path. #-w image_tag: The new milvus image tag. #-o operation: The operation: migrate/rollback. #-m meta_migration_pod_tag: The image for meta migration pod. #-d remove_migrate_pod_after_migrate: Remove migration pod after successful migration. #-c storage_class: The storage class for meta migration pvc. #-e external_etcd_svc: The endpoints for etcd which used by milvus. while getopts "n:i:s:t:r:w:o:m:c:e:d:" opt_name do case $opt_name in n) namespace=$OPTARG;; i) instance_name=$OPTARG;; s) source_version=$OPTARG;; t) target_version=$OPTARG;; r) root_path=$OPTARG;; w) image_tag=$OPTARG;; o) operation=$OPTARG;; m) meta_migration_pod_tag=$OPTARG;; d) remove_migrate_pod_after_migrate="true";; c) storage_class=$OPTARG;; e) external_etcd_svc=$OPTARG;; *) echo "Unkonwen parameters";; esac done if [ ! $instance_name ]; then echo "Missing argument instance_name, please add it. For example:'./migrate.sh -i milvus-instance-name'" exit 1 fi if [ ! $source_version ]; then echo "Missing argument source_version, please add it. For example:'./migrate.sh -s 2.1.4'" exit 1 fi if [ ! $target_version ]; then echo "Missing argument target_version, please add it. For example:'./migrate.sh -t 2.2.0'" exit 1 fi if [ ! $image_tag ]; then echo "Missing argument image_tag, please add it. For example:'./migrate.sh -w milvusdb/milvus:v2.2.0'" exit 1 fi deployments=$(kubectl get deploy -n $namespace -l app.kubernetes.io/instance=$instance_name,app.kubernetes.io/name=milvus --output=jsonpath={.items..metadata.name}) deploys=() replicas=() for d in $deployments; do component=$(kubectl get deploy $d -n $namespace --output=jsonpath={.metadata.labels.component}) replica=$(kubectl get deploy $d -n $namespace --output=jsonpath={.spec.replicas}) if [ "$component" = "attu" ]; then continue fi deploys+=("$d") done if [ ${#deploys[@]} -eq 0 ]; then echo "There is no Milvus instance $instance_name in the namespace $namespace" exit 1 fi if [ ! $external_etcd_svc ]; then svc=$(kubectl get svc -n $namespace -l app.kubernetes.io/instance=$instance_name,app.kubernetes.io/name=etcd -o name | grep -v headless | cut -d '/' -f 2) if [ ! $svc ]; then echo "Missing etcd service, please add it. For example:'./migrate.sh -e :'" exit 1 else port=$(kubectl get svc -n $namespace $svc --output=jsonpath='{.spec.ports[?(@.name == "client")].port}') if [ ! $port ]; then echo "Missing etcd service port..." exit 1 fi etcd_svc="$svc:$port" fi else etcd_svc="$external_etcd_svc" fi scs=$(kubectl get storageclass --output=jsonpath='{.items..metadata.name}') if [ ! $storage_class ]; then # check whether there a default storageclass exists=0 for sc in $scs; do default=$(kubectl get storageclass $sc --output=jsonpath='{.metadata.annotations.storageclass\.kubernetes\.io/is-default-class}') if [ "$default" = "true" ] ; then exists=1 break fi done if [ $exists -eq 0 ] ; then echo "No default storageclass, please specify a storageclass via -c " exit 1 fi else exists=0 for sc in $scs; do if [ "$sc" = "$storage_class" ] ; then exists=1 break fi done if [ $exists -eq 0 ]; then echo "Nonexistent storageclass, please make sure specified storageclass exists..." exit 1 fi fi echo "Migration milvus meta will take four steps:" echo "1. Stop the milvus components" echo "2. Backup the milvus meta" echo "3. Migrate the milvus meta" echo "4. Startup milvus components in new image version" echo function store_deploy_replicas(){ # store deploy replicas in a configmap # first check whether config exists data=$(kubectl get configmap "milvus-deploy-replicas-$instance_name" -n $namespace --output=jsonpath={.data.replicas} 2>/dev/null) if [ ! "$data" ]; then for d in ${deploys[@]}; do replica=$(kubectl get deploy $d -n $namespace --output=jsonpath={.spec.replicas}) replicas+=("$d:$replica") done cat < /dev/null wait_for_milvus_stopped "${deploys[@]}" echo "Stopped..." } function wait_for_milvus_stopped(){ while true do total=0 for deploy in $1; do count=$(kubectl get deploy $deploy -n $namespace --output=jsonpath={.status.replicas}) count=${count:-0} total=`expr $total + $count` done if [ $total -eq 0 ]; then break fi sleep 5 done # wait for the session key expire sleep 75 } function wait_for_backup_done(){ backup_pod_name="milvus-meta-migration-backup-${instance_name}" configmap_name="milvus-meta-migration-config-${instance_name}" while true do status=$(kubectl get pod -n $namespace $backup_pod_name --output=jsonpath={.status.phase}) case $status in Succeeded) echo "Meta backup is done..." kubectl annotate configmap $configmap_name -n $namespace backup=succeed break ;; Failed) echo "Meta backup is failed..." echo "Here is the log:" kubectl logs $backup_pod_name -n $namespace echo exit 2 ;; *) sleep 10 continue ;; esac done } function wait_for_migrate_done(){ migrate_pod_name="milvus-meta-migration-${instance_name}" while true do status=$(kubectl get pod -n $namespace $migrate_pod_name --output=jsonpath={.status.phase}) case $status in Succeeded) echo "Migration is done..." echo break ;; Failed) echo "Migration is failed..." echo "Here is the log:" kubectl logs $migrate_pod_name -n $namespace echo exit 3 ;; *) sleep 10 continue ;; esac done } function wait_for_rollback_done(){ rollback_pod_name="milvus-meta-migration-rollback-${instance_name}" while true do status=$(kubectl get pod -n $namespace $rollback_pod_name --output=jsonpath={.status.phase}) case $status in Succeeded) echo "Rollback is done..." echo break ;; Failed) echo "Rollback is failed..." echo "Here is the log:" kubectl logs $rollback_pod_name -n $namespace echo exit 5 ;; *) sleep 10 continue ;; esac done } function generate_migrate_meta_cm_and_pvc(){ # check whether pvc exists exists=$(kubectl get pvc "milvus-meta-migration-backup-${instance_name}" -n $namespace --output=jsonpath={.metadata.name} 2>/dev/null) if [ ! $exists ]; then cat <