פריסת אשכול MySQL 5.6 עם זמינות גבוהה באמצעות DRBD ב-Compute Engine

במדריך הזה מוסבר איך לפרוס מסד נתונים של MySQL 5.6 ב-Cloud de Confiance by S3NS באמצעות Distributed Replicated Block Device (DRBD)‎ ו-Compute Engine. ‫DRBD היא מערכת אחסון מבוזרת עם רפליקציה לפלטפורמת Linux.

המדריך הזה שימושי לאדמיני מערכת, למפתחים, למהנדסים, לאדמיני מסדי נתונים ולמהנדסי DevOps. יכול להיות שתרצו לנהל בעצמכם את מופע MySQL במקום להשתמש בשירות המנוהל, מכמה סיבות, כולל:

  • אתם משתמשים במופעים של MySQL בכמה אזורים.
  • צריך להגדיר פרמטרים שלא זמינים בגרסה המנוהלת של MySQL.
  • אתם רוצים לבצע אופטימיזציה של הביצועים בדרכים שלא ניתן להגדיר בגרסה המנוהלת.

‫DRBD מספק שכפול ברמת מכשיר הבלוק. המשמעות היא שלא צריך להגדיר שכפול ב-MySQL עצמו, ונהנים באופן מיידי מהיתרונות של DRBD – למשל, תמיכה באיזון עומסים של קריאה ובחיבורים מאובטחים.

במדריך הזה נעשה שימוש ברכיבים הבאים:

לא נדרש ידע מתקדם כדי להשתמש במקורות המידע האלה, אבל במסמך הזה יש הפניות ליכולות מתקדמות כמו אשכולות MySQL, הגדרת DRBD וניהול משאבים ב-Linux.

ארכיטקטורה

‫Pacemaker הוא מנהל משאבים של אשכולות. ‫Corosync היא חבילה של תקשורת בין צמתים והשתתפות באשכול, שמשמשת את Pacemaker. במדריך הזה משתמשים ב-DRBD כדי לשכפל את דיסק MySQL מהמופע הראשי למופע ההמתנה. כדי שהלקוחות יוכלו להתחבר לאשכול MySQL, צריך גם לפרוס מאזן עומסים פנימי.

אתם פורסים אשכול שמנוהל על ידי Pacemaker של שלוש מכונות וירטואליות. מתקינים את MySQL בשניים מהמופעים, שמשמשים כמופעים ראשיים ומוכנים להפעלה. המופע השלישי משמש כמכשיר קוורום.

בצביר, כל צומת מצביע לצומת שצריך להיות הצומת הפעיל – כלומר, הצומת שמריץ את MySQL. בצביר עם שני צמתים, מספיק קול אחד כדי לקבוע את הצומת הפעיל. במקרה כזה, התנהגות האשכול עלולה לגרום לבעיות של פיצול מוח או להשבתה. בעיות של פיצול מוח מתרחשות כששני הצמתים מקבלים שליטה כי נדרש רק קול אחד בתרחיש של שני צמתים. זמן השבתה מתרחש כשהצומת שמושבת הוא הצומת שהוגדר להיות תמיד הצומת הראשי במקרה של אובדן קישוריות. אם שני הצמתים מאבדים את הקישוריות ביניהם, יש סיכון שיותר מצומת אחד באשכול יניח שהוא הצומת הפעיל.

כדי למנוע את המצב הזה, אפשר להוסיף מכשיר קוורום. מכשיר קוורום משמש כבורר, והתפקיד היחיד שלו הוא להצביע. כך, במצב שבו מופעי database1 ו-database2 לא יכולים לתקשר, הצומת של מכשיר הקוורום הזה יכול לתקשר עם אחד משני המופעים, ועדיין אפשר להגיע לרוב.

התרשים הבא מציג את הארכיטקטורה של המערכת שמתוארת כאן.

ארכיטקטורה שבה מוצג מסד נתונים של MySQL 5.6 שנפרס ב- Cloud de Confiance באמצעות DRBD ו-Compute Engine

מטרות

  • יוצרים את המכונות באשכול.
  • מתקינים את MySQL ואת DRBD בשניים מהמופעים.
  • הגדרת רפליקציית DRBD.
  • מתקינים את Pacemaker במופעים.
  • מגדירים אשכול Pacemaker במופעים.
  • יוצרים מכונה ומגדירים אותה כמכשיר קוורום.
  • בדיקת מעבר לשירות גיבוי.

עלויות

כדי ליצור הערכת עלויות על סמך השימוש החזוי, אתם יכולים להשתמש במחשבון התמחור.

לפני שמתחילים

  1. In the Cloud de Confiance console, on the project selector page, select or create a Cloud de Confiance project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  2. Verify that billing is enabled for your Cloud de Confiance project.

  3. Enable the Compute Engine API.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the API

במדריך הזה, מזינים פקודות באמצעות Cloud Shell, אלא אם צוין אחרת.

כשמסיימים את המשימות שמתוארות במסמך הזה אפשר למחוק את המשאבים שיצרתם כדי להימנע מחיובים נוספים. מידע נוסף זמין בקטע הסרת המשאבים.

תהליך ההגדרה

בקטע הזה מגדירים חשבון שירות, יוצרים משתני סביבה ומזמינים כתובות IP.

הגדרת חשבון שירות למופעי האשכול

  1. פותחים את Cloud Shell:

    פותחים את Cloud Shell.

  2. יוצרים את חשבון השירות:

    gcloud iam service-accounts create mysql-instance \
        --display-name "mysql-instance"
    
  3. מצרפים לחשבון השירות את התפקידים שנדרשים במדריך הזה:

    gcloud projects add-iam-policy-binding ${DEVSHELL_PROJECT_ID} \
        --member=serviceAccount:mysql-instance@${DEVSHELL_PROJECT_ID}.s3ns.iam.gserviceaccount.com \
        --role=roles/compute.instanceAdmin.v1
    
    gcloud projects add-iam-policy-binding ${DEVSHELL_PROJECT_ID} \
        --member=serviceAccount:mysql-instance@${DEVSHELL_PROJECT_ID}.s3ns.iam.gserviceaccount.com \
        --role=roles/compute.viewer
    
    gcloud projects add-iam-policy-binding ${DEVSHELL_PROJECT_ID} \
        --member=serviceAccount:mysql-instance@${DEVSHELL_PROJECT_ID}.s3ns.iam.gserviceaccount.com \
        --role=roles/iam.serviceAccountUser
    

יצירת משתני סביבה ב-Cloud Shell

  1. יוצרים קובץ עם משתני הסביבה הנדרשים ללימוד הזה:

    cat <<EOF > ~/.mysqldrbdrc
    # Cluster instance names
    DATABASE1_INSTANCE_NAME=database1
    DATABASE2_INSTANCE_NAME=database2
    QUORUM_INSTANCE_NAME=qdevice
    CLIENT_INSTANCE_NAME=mysql-client
    # Cluster IP addresses
    DATABASE1_INSTANCE_IP="10.140.0.2"
    DATABASE2_INSTANCE_IP="10.140.0.3"
    QUORUM_INSTANCE_IP="10.140.0.4"
    ILB_IP="10.140.0.6"
    # Cluster zones and region
    DATABASE1_INSTANCE_ZONE="asia-east1-a"
    DATABASE2_INSTANCE_ZONE="asia-east1-b"
    QUORUM_INSTANCE_ZONE="asia-east1-c"
    CLIENT_INSTANCE_ZONE="asia-east1-c"
    CLUSTER_REGION="asia-east1"
    EOF
    
  2. טוענים את משתני הסביבה בסשן הנוכחי ומגדירים את Cloud Shell כך שהמשתנים ייטענו אוטומטית בכניסות עתידיות:

    source ~/.mysqldrbdrc
    grep -q -F "source ~/.mysqldrbdrc" ~/.bashrc || echo "source ~/.mysqldrbdrc" >> ~/.bashrc
    

שמירת כתובות IP

  • ב-Cloud Shell, שומרים כתובת IP פנימית לכל אחד משלושת צמתי האשכול:

    gcloud compute addresses create ${DATABASE1_INSTANCE_NAME} ${DATABASE2_INSTANCE_NAME} ${QUORUM_INSTANCE_NAME} \
        --region=${CLUSTER_REGION} \
        --addresses "${DATABASE1_INSTANCE_IP},${DATABASE2_INSTANCE_IP},${QUORUM_INSTANCE_IP}" \
        --subnet=default
    

יצירת מכונות Compute Engine

בשלבים הבאים, המכונות של האשכול משתמשות ב-Debian 9 והמכונות של הלקוח משתמשות ב-Ubuntu 16.

  1. ב-Cloud Shell, יוצרים מכונת MySQL בשם database1 באזור asia-east1-a:

    gcloud compute instances create ${DATABASE1_INSTANCE_NAME} \
        --zone=${DATABASE1_INSTANCE_ZONE} \
        --machine-type=n1-standard-2  \
        --network-tier=PREMIUM \
        --maintenance-policy=MIGRATE \
        --image-family=debian-9 \
        --image-project=debian-cloud \
        --boot-disk-size=50GB \
        --boot-disk-type=pd-standard \
        --boot-disk-device-name=${DATABASE1_INSTANCE_NAME} \
        --create-disk=mode=rw,size=300,type=pd-standard,name=disk-1 \
        --private-network-ip=${DATABASE1_INSTANCE_NAME} \
        --tags=mysql --service-account=mysql-instance@${DEVSHELL_PROJECT_ID}.s3ns.iam.gserviceaccount.com \
        --scopes="https://www.googleapis.com/auth/compute,https://www.googleapis.com/auth/servicecontrol,https://www.googleapis.com/auth/service.management.readonly" \
        --metadata="DATABASE1_INSTANCE_IP=${DATABASE1_INSTANCE_IP},DATABASE2_INSTANCE_IP=${DATABASE2_INSTANCE_IP},DATABASE1_INSTANCE_NAME=${DATABASE1_INSTANCE_NAME},DATABASE2_INSTANCE_NAME=${DATABASE2_INSTANCE_NAME},QUORUM_INSTANCE_NAME=${QUORUM_INSTANCE_NAME},DATABASE1_INSTANCE_ZONE=${DATABASE1_INSTANCE_ZONE},DATABASE2_INSTANCE_ZONE=${DATABASE2_INSTANCE_ZONE}"
    
  2. יוצרים מכונת MySQL בשם database2 באזור asia-east1-b:

    gcloud compute instances create ${DATABASE2_INSTANCE_NAME} \
        --zone=${DATABASE2_INSTANCE_ZONE} \
        --machine-type=n1-standard-2  \
        --network-tier=PREMIUM \
        --maintenance-policy=MIGRATE \
        --image-family=debian-9 \
        --image-project=debian-cloud \
        --boot-disk-size=50GB \
        --boot-disk-type=pd-standard \
        --boot-disk-device-name=${DATABASE2_INSTANCE_NAME} \
        --create-disk=mode=rw,size=300,type=pd-standard,name=disk-2 \
        --private-network-ip=${DATABASE2_INSTANCE_NAME} \
        --tags=mysql \
        --service-account=mysql-instance@${DEVSHELL_PROJECT_ID}.s3ns.iam.gserviceaccount.com \
        --scopes="https://www.googleapis.com/auth/compute,https://www.googleapis.com/auth/servicecontrol,https://www.googleapis.com/auth/service.management.readonly" \
        --metadata="DATABASE1_INSTANCE_IP=${DATABASE1_INSTANCE_IP},DATABASE2_INSTANCE_IP=${DATABASE2_INSTANCE_IP},DATABASE1_INSTANCE_NAME=${DATABASE1_INSTANCE_NAME},DATABASE2_INSTANCE_NAME=${DATABASE2_INSTANCE_NAME},QUORUM_INSTANCE_NAME=${QUORUM_INSTANCE_NAME},DATABASE1_INSTANCE_ZONE=${DATABASE1_INSTANCE_ZONE},DATABASE2_INSTANCE_ZONE=${DATABASE2_INSTANCE_ZONE}"
    
  3. יוצרים צומת קוורום לשימוש על ידי Pacemaker באזור asia-east1-c:

    gcloud compute instances create ${QUORUM_INSTANCE_NAME} \
        --zone=${QUORUM_INSTANCE_ZONE} \
        --machine-type=n1-standard-1 \
        --network-tier=PREMIUM \
        --maintenance-policy=MIGRATE \
        --image-family=debian-9  \
        --image-project=debian-cloud \
        --boot-disk-size=10GB \
        --boot-disk-type=pd-standard \
        --boot-disk-device-name=${QUORUM_INSTANCE_NAME} \
        --private-network-ip=${QUORUM_INSTANCE_NAME}
    
  4. יוצרים מכונת לקוח של MySQL:

    gcloud compute instances create ${CLIENT_INSTANCE_NAME} \
        --image-family=ubuntu-1604-lts \
        --image-project=ubuntu-os-cloud \
        --tags=mysql-client \
        --zone=${CLIENT_INSTANCE_ZONE} \
        --boot-disk-size=10GB \
        --metadata="ILB_IP=${ILB_IP}"
    

התקנה והגדרה של DRBD

בקטע הזה, מתקינים ומגדירים את חבילות DRBD במופעים database1 ו-database2, ואז מתחילים את השכפול של DRBD מ-database1 ל-database2.

הגדרת DRBD במסד הנתונים database1

  1. נכנסים לדף VM instances במסוף Cloud de Confiance :

    הדף VM INSTANCES

  2. בשורה של המכונה database1, לוחצים על SSH כדי להתחבר למכונה.

  3. יוצרים קובץ כדי לאחזר ולאחסן את המטא-נתונים של המופע במשתני סביבה:

    sudo bash -c cat <<EOF  > ~/.varsrc
    DATABASE1_INSTANCE_IP=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE1_INSTANCE_IP" -H "Metadata-Flavor: Google")
    DATABASE2_INSTANCE_IP=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE2_INSTANCE_IP" -H "Metadata-Flavor: Google")
    DATABASE1_INSTANCE_NAME=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE1_INSTANCE_NAME" -H "Metadata-Flavor: Google")
    DATABASE2_INSTANCE_NAME=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE2_INSTANCE_NAME" -H "Metadata-Flavor: Google")
    DATABASE2_INSTANCE_ZONE=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE2_INSTANCE_ZONE" -H "Metadata-Flavor: Google")
    DATABASE1_INSTANCE_ZONE=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE1_INSTANCE_ZONE" -H "Metadata-Flavor: Google")
    QUORUM_INSTANCE_NAME=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/QUORUM_INSTANCE_NAME" -H "Metadata-Flavor: Google")
    
    EOF
    
  4. טוענים את משתני המטא-נתונים מהקובץ:

    source ~/.varsrc
    
  5. מפרמטים את דיסק הנתונים:

    sudo bash -c  "mkfs.ext4 -m 0 -F -E \
    lazy_itable_init=0,lazy_journal_init=0,discard /dev/sdb"
    

    תיאור מפורט של האפשרויות של mkfs.ext4 מופיע בדף mkfs.ext4.

  6. מתקינים את DRBD:

    sudo apt -y install drbd8-utils
    
  7. יוצרים את קובץ ההגדרה של DRBD:

    sudo bash -c 'cat <<EOF  > /etc/drbd.d/global_common.conf
    global {
        usage-count no;
    }
    common {
        protocol C;
    }
    EOF'
    
  8. יוצרים קובץ משאבים של DRBD:

    sudo bash -c "cat <<EOF  > /etc/drbd.d/r0.res
    resource r0 {
        meta-disk internal;
        device /dev/drbd0;
        net {
            allow-two-primaries no;
            after-sb-0pri discard-zero-changes;
            after-sb-1pri discard-secondary;
            after-sb-2pri disconnect;
            rr-conflict disconnect;
        }
        on database1 {
            disk /dev/sdb;
            address 10.140.0.2:7789;
        }
        on database2 {
            disk /dev/sdb;
            address 10.140.0.3:7789;
        }
    }
    EOF"
    
  9. טוענים את מודול הליבה של DRBD:

    sudo modprobe drbd
    
  10. מנקים את התוכן של הדיסק /dev/sdb:

    sudo dd if=/dev/zero of=/dev/sdb bs=1k count=1024
    
  11. יוצרים את משאב ה-DRBD r0:

    sudo drbdadm create-md r0
    
  12. מפעילים את DRBD:

    sudo drbdadm up r0
    
  13. משביתים את DRBD כשהמערכת מתחילה לפעול, כדי לאפשר לתוכנה לניהול משאבי האשכול להפעיל את כל השירותים הנדרשים לפי הסדר:

    sudo update-rc.d drbd disable
    

הגדרת DRBD ב-database2

עכשיו מתקינים ומגדירים את חבילות ה-DRBD במופע database2.

  1. מתחברים למכונה database2 באמצעות SSH.
  2. יוצרים קובץ .varsrc כדי לאחזר ולשמור את המטא-נתונים של המופע במשתני סביבה:

    sudo bash -c cat <<EOF  > ~/.varsrc
    DATABASE1_INSTANCE_IP=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE1_INSTANCE_IP" -H "Metadata-Flavor: Google")
    DATABASE2_INSTANCE_IP=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE2_INSTANCE_IP" -H "Metadata-Flavor: Google")
    DATABASE1_INSTANCE_NAME=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE1_INSTANCE_NAME" -H "Metadata-Flavor: Google")
    DATABASE2_INSTANCE_NAME=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE2_INSTANCE_NAME" -H "Metadata-Flavor: Google")
    DATABASE2_INSTANCE_ZONE=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE2_INSTANCE_ZONE" -H "Metadata-Flavor: Google")
    DATABASE1_INSTANCE_ZONE=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/DATABASE1_INSTANCE_ZONE" -H "Metadata-Flavor: Google")
    QUORUM_INSTANCE_NAME=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/QUORUM_INSTANCE_NAME" -H "Metadata-Flavor: Google")
    EOF
    
  3. טוענים את משתני המטא-נתונים מהקובץ:

    source ~/.varsrc
    
  4. מפרמטים את דיסק הנתונים:

    sudo bash -c  "mkfs.ext4 -m 0 -F -E  lazy_itable_init=0,lazy_journal_init=0,discard /dev/sdb"
    
  5. מתקינים את חבילות DRBD:

    sudo apt -y install drbd8-utils
    
  6. יוצרים את קובץ ההגדרה של DRBD:

    sudo bash -c 'cat <<EOF  > /etc/drbd.d/global_common.conf
    global {
        usage-count no;
    }
    common {
        protocol C;
    }
    EOF'
    
  7. יוצרים קובץ משאבים של DRBD:

    sudo bash -c "cat <<EOF  > /etc/drbd.d/r0.res
    resource r0 {
        meta-disk internal;
        device /dev/drbd0;
        net {
            allow-two-primaries no;
            after-sb-0pri discard-zero-changes;
            after-sb-1pri discard-secondary;
            after-sb-2pri disconnect;
            rr-conflict disconnect;
        }
        on ${DATABASE1_INSTANCE_NAME} {
            disk /dev/sdb;
            address ${DATABASE1_INSTANCE_IP}:7789;
        }
        on ${DATABASE2_INSTANCE_NAME} {
            disk /dev/sdb;
            address ${DATABASE2_INSTANCE_IP}:7789;
        }
    }
    EOF"
    
  8. טוענים את מודול הליבה של DRBD:

    sudo modprobe drbd
    
  9. מנקים את הדיסק /dev/sdb:

    sudo dd if=/dev/zero of=/dev/sdb bs=1k count=1024
    
  10. יוצרים את משאב ה-DRBD r0:

    sudo drbdadm create-md r0
    
  11. מפעילים את DRBD:

    sudo drbdadm up r0
    
  12. משביתים את DRBD כשהמערכת מתחילה לפעול, כדי לאפשר לתוכנה לניהול משאבי האשכול להפעיל את כל השירותים הנדרשים לפי הסדר:

    sudo update-rc.d drbd disable
    

הפעלת שכפול DRBD ממסד נתונים 1 למסד נתונים 2

  1. מתחברים למכונה database1 באמצעות SSH.
  2. החלפת כל משאבי r0 בצומת הראשי:

    sudo drbdadm -- --overwrite-data-of-peer primary r0
    sudo mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/drbd0
    
  3. מאמתים את הסטטוס של DRBD:

    sudo cat /proc/drbd | grep ============
    

    הפלט אמור להיראות כך:

    [===================>] sync'ed:100.0% (208/307188)M
    
  4. תושבת /dev/drbd אל /srv:

    sudo mount -o discard,defaults /dev/drbd0 /srv
    

התקנה של MySQL ו-Pacemaker

בקטע הזה מתקינים את MySQL ואת Pacemaker בכל מופע.

התקנת MySQL ב-database1

  1. מתחברים למכונה database1 באמצעות SSH.
  2. מעדכנים את מאגר ה-APT עם הגדרות החבילה של MySQL 5.6:

    sudo bash -c 'cat <<EOF  > /etc/apt/sources.list.d/mysql.list
    deb http://repo.mysql.com/apt/debian/ stretch mysql-5.6\ndeb-src http://repo.mysql.com/apt/debian/ stretch mysql-5.6
    EOF'
    
  3. מוסיפים את מפתחות ה-GPG לקובץ repository.srv של APT:

    wget -O /tmp/RPM-GPG-KEY-mysql https://repo.mysql.com/RPM-GPG-KEY-mysql
    sudo apt-key add /tmp/RPM-GPG-KEY-mysql
    
  4. מעדכנים את רשימת החבילות:

    sudo apt update
    
  5. מתקינים את שרת MySQL:

    sudo apt -y install mysql-server
    

    כשמופיעה בקשה להזין סיסמה, מזינים DRBDha2.

  6. עוצרים את שרת MySQL:

    sudo /etc/init.d/mysql stop
    
  7. יוצרים את קובץ התצורה של MySQL:

    sudo bash -c 'cat <<EOF  > /etc/mysql/mysql.conf.d/my.cnf
    [mysqld]
    bind-address = 0.0.0.0  # You may want to listen at localhost at the beginning
    datadir = /var/lib/mysql
    tmpdir = /srv/tmp
    user = mysql
    EOF'
    
  8. יוצרים ספרייה זמנית לשרת MySQL (שמוגדר ב-mysql.conf):

    sudo mkdir /srv/tmp
    sudo chmod 1777 /srv/tmp
    
  9. מעבירים את כל נתוני MySQL לספרייה DRBD‏ /srv/mysql:

    sudo mv /var/lib/mysql /srv/mysql
    
  10. מקושר /var/lib/mysql אל /srv/mysql בקטע DRBD replicated storage volume:

    sudo ln -s /srv/mysql /var/lib/mysql
    
  11. שינוי הבעלים של /srv/mysql לתהליך mysql:

    sudo chown -R mysql:mysql /srv/mysql
    
  12. מסירים את הנתונים הראשוניים של InnoDB כדי לוודא שהדיסק נקי ככל האפשר:

    sudo bash -c "cd /srv/mysql && rm ibdata1 && rm ib_logfile*"
    

    InnoDB הוא מנוע אחסון למערכת לניהול מסדי נתונים של MySQL.

  13. מפעילים את MySQL:

    sudo /etc/init.d/mysql start
    
  14. כדי לבדוק את ה-Deployment בהמשך, צריך להעניק גישה למשתמש Root לחיבורים מרוחקים:

    mysql -uroot -pDRBDha2 -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'DRBDha2' WITH GRANT OPTION;"
    
  15. משביתים את ההפעלה האוטומטית של MySQL, שניהול משאבי האשכול מטפל בה:

    sudo update-rc.d -f mysql disable
    

התקנה של Pacemaker ב-database1

  1. טוענים את משתני המטא-נתונים מהקובץ .varsrc שיצרתם קודם:

    source ~/.varsrc
    
  2. עוצרים את שרת MySQL:

    sudo /etc/init.d/mysql stop
    
  3. מתקינים את Pacemaker:

    sudo apt -y install pcs
    
  4. מפעילים את pcsd,‏ corosync ו-pacemaker באתחול המערכת במופע הראשי:

    sudo update-rc.d -f pcsd enable
    sudo update-rc.d -f corosync enable
    sudo update-rc.d -f pacemaker enable
    
  5. מגדירים את corosync כך שהוא יתחיל לפני pacemaker:

    sudo update-rc.d corosync defaults 20 20
    sudo update-rc.d pacemaker defaults 30 10
    
  6. מגדירים את סיסמת המשתמש של האשכול ל-haCLUSTER3 לאימות:

    sudo bash -c "echo  hacluster:haCLUSTER3 | chpasswd"
    
  7. מריצים את הסקריפט corosync-keygen כדי ליצור מפתח הרשאה של 128 ביט לאשכול וכדי לכתוב אותו ב-/etc/corosync/authkey:

    sudo corosync-keygen -l
    
  8. מעתיקים את authkey למופע database2. כשמוצגת בקשה לסיסמה, מקישים על Enter:

    sudo chmod 444 /etc/corosync/authkey
    gcloud beta compute scp /etc/corosync/authkey ${DATABASE2_INSTANCE_NAME}:~/authkey --zone=${DATABASE2_INSTANCE_ZONE} --internal-ip
    sudo chmod 400 /etc/corosync/authkey
    
  9. יוצרים קובץ תצורה של אשכול Corosync:

    sudo bash -c "cat <<EOF  > /etc/corosync/corosync.conf
    
    totem {
        version: 2
        cluster_name: mysql_cluster
        transport: udpu
        interface {
            ringnumber: 0
            Bindnetaddr: ${DATABASE1_INSTANCE_IP}
            broadcast: yes
            mcastport: 5405
        }
    }
    quorum {
        provider: corosync_votequorum
    two_node: 1
    }
    
    nodelist {
        node {
            ring0_addr: ${DATABASE1_INSTANCE_NAME}
        name:  ${DATABASE1_INSTANCE_NAME}
    
        nodeid: 1
        }
        node {
            ring0_addr:  ${DATABASE2_INSTANCE_NAME}
            name:  ${DATABASE2_INSTANCE_NAME}
            nodeid: 2
        }
    }
    logging {
        to_logfile: yes
        logfile: /var/log/corosync/corosync.log
        timestamp: on
    }
    
    EOF"
    

    בקטע totem מוגדר פרוטוקול Totem לתקשורת מהימנה. מערכת Corosync משתמשת בתקשורת הזו כדי לשלוט בחברות באשכול, והיא מציינת איך חברי האשכול צריכים לתקשר זה עם זה.

    ההגדרות החשובות בתהליך ההגדרה הן:

    • transport: מציין מצב שידור יחיד (udpu).
    • Bindnetaddr: מציין את כתובת הרשת שאליה Corosync נקשר.
    • nodelist: מגדיר את הצמתים באשכול ואת האופן שבו אפשר להגיע אליהם – במקרה הזה, הצמתים database1 ו-database2.
    • quorum/two_node: כברירת מחדל, באשכול עם שני צמתים, אף צומת לא ישיג קוורום. כדי לשנות את ברירת המחדל, צריך לציין את הערך '1' עבור two_node בקטע quorum.

    ההגדרה הזו מאפשרת להגדיר את האשכול ולהכין אותו להוספה של צומת שלישי שיהיה מכשיר קוורום.

  10. יצירת ספריית השירות עבור corosync:

    sudo mkdir -p /etc/corosync/service.d
    
  11. מגדירים את corosync כך שיזהה את Pacemaker:

    sudo bash -c 'cat <<EOF  > /etc/corosync/service.d/pcmk
    service {
        name: pacemaker
        ver: 1
    }
    EOF'
    
  12. הפעלת השירות corosync כברירת מחדל:

    sudo bash -c 'cat <<EOF  > /etc/default/corosync
    # Path to corosync.conf
    COROSYNC_MAIN_CONFIG_FILE=/etc/corosync/corosync.conf
    # Path to authfile
    COROSYNC_TOTEM_AUTHKEY_FILE=/etc/corosync/authkey
    # Enable service by default
    START=yes
    EOF'
    
  13. מפעילים מחדש את השירותים corosync ו-pacemaker:

    sudo service corosync restart
    sudo service pacemaker restart
    
  14. מתקינים את חבילת מכשיר הקוורום של Corosync:

    sudo apt -y install corosync-qdevice
    
  15. מתקינים סקריפט מעטפת לטיפול באירועי כשל של DRBD:

    sudo bash -c 'cat << 'EOF'  > /var/lib/pacemaker/drbd_cleanup.sh
    #!/bin/sh
    if [ -z \$CRM_alert_version ]; then
        echo "\$0 must be run by Pacemaker version 1.1.15 or later"
        exit 0
    fi
    
    tstamp="\$CRM_alert_timestamp: "
    
    case \$CRM_alert_kind in
        resource)
            if [ \${CRM_alert_interval} = "0" ]; then
                CRM_alert_interval=""
            else
                CRM_alert_interval=" (\${CRM_alert_interval})"
            fi
    
            if [ \${CRM_alert_target_rc} = "0" ]; then
                CRM_alert_target_rc=""
            else
                CRM_alert_target_rc=" (target: \${CRM_alert_target_rc})"
            fi
    
            case \${CRM_alert_desc} in
                Cancelled) ;;
                *)
                    echo "\${tstamp}Resource operation "\${CRM_alert_task}\${CRM_alert_interval}" for "\${CRM_alert_rsc}" on "\${CRM_alert_node}": \${CRM_alert_desc}\${CRM_alert_target_rc}" >> "\${CRM_alert_recipient}"
                    if [ "\${CRM_alert_task}" = "stop" ] && [ "\${CRM_alert_desc}" = "Timed Out" ]; then
                        echo "Executing recovering..." >> "\${CRM_alert_recipient}"
                        pcs resource cleanup \${CRM_alert_rsc}
                    fi
                    ;;
            esac
            ;;
        *)
            echo "\${tstamp}Unhandled \$CRM_alert_kind alert" >> "\${CRM_alert_recipient}"
            env | grep CRM_alert >> "\${CRM_alert_recipient}"
            ;;
    esac
    EOF'
    sudo chmod 0755 /var/lib/pacemaker/drbd_cleanup.sh
    sudo touch /var/log/pacemaker_drbd_file.log
    sudo chown hacluster:haclient /var/log/pacemaker_drbd_file.log
    

התקנת MySQL ב-database2

  1. מתחברים למכונה database2 באמצעות SSH.
  2. מעדכנים את מאגר ה-APT בחבילה של MySQL 5.6:

    sudo bash -c 'cat <<EOF  > /etc/apt/sources.list.d/mysql.list
    deb http://repo.mysql.com/apt/debian/ stretch mysql-5.6\ndeb-src http://repo.mysql.com/apt/debian/ stretch mysql-5.6
    EOF'
    
  3. מוסיפים את מפתחות ה-GPG למאגר APT:

    wget -O /tmp/RPM-GPG-KEY-mysql https://repo.mysql.com/RPM-GPG-KEY-mysql
    sudo apt-key add /tmp/RPM-GPG-KEY-mysql
    
  4. מעדכנים את רשימת החבילות:

    sudo apt update
    
  5. מתקינים את שרת MySQL:

    sudo apt -y install mysql-server
    

    כשמופיעה בקשה להזין סיסמה, מזינים DRBDha2.

  6. עוצרים את שרת MySQL:

    sudo /etc/init.d/mysql stop
    
  7. יוצרים את קובץ התצורה של MySQL:

    sudo bash -c 'cat <<EOF  > /etc/mysql/mysql.conf.d/my.cnf
    [mysqld]
    bind-address = 0.0.0.0  # You may want to listen at localhost at the beginning
    datadir = /var/lib/mysql
    tmpdir = /srv/tmp
    user = mysql
    EOF'
    
  8. מסירים את הנתונים בקטע /var/lib/mysql ומוסיפים קישור סמלי ליעד של נקודת הטעינה של נפח ה-DRBD המשוכפל. הנפח של DRBD ‏ (/dev/drbd0) יצורף ל-/srv רק אם תתרחש נפילת שרת.

    sudo rm -rf /var/lib/mysql
    sudo ln -s /srv/mysql /var/lib/mysql
    
  9. משביתים את ההפעלה האוטומטית של MySQL, שניהול משאבי האשכול מטפל בה:

    sudo update-rc.d -f mysql disable
    

התקנה של Pacemaker במסד הנתונים database2

  1. טוענים את משתני המטא-נתונים מקובץ .varsrc:

    source ~/.varsrc
    
  2. מתקינים את Pacemaker:

    sudo apt -y install pcs
    
  3. מעבירים את קובץ Corosync‏ authkey שהעתקתם קודם אל /etc/corosync/:

    sudo mv ~/authkey /etc/corosync/
    sudo chown root: /etc/corosync/authkey
    sudo chmod 400 /etc/corosync/authkey
    
  4. מפעילים את pcsd, ‏corosync ו-pacemaker באתחול המערכת במופע ההמתנה:

    sudo update-rc.d -f pcsd enable
    sudo update-rc.d -f corosync enable
    sudo update-rc.d -f pacemaker enable
    
  5. מגדירים את corosync כך שהוא יתחיל לפני pacemaker:

    sudo update-rc.d corosync defaults 20 20
    sudo update-rc.d pacemaker defaults 30 10
    
  6. מגדירים את סיסמת המשתמש של האשכול לאימות. הסיסמה זהה (haCLUSTER3) לסיסמה שבה השתמשתם במופע database1.

    sudo bash -c "echo  hacluster:haCLUSTER3 | chpasswd"
    
  7. יוצרים את קובץ ההגדרות corosync:

    sudo bash -c "cat <<EOF  > /etc/corosync/corosync.conf
    
    totem {
        version: 2
        cluster_name: mysql_cluster
        transport: udpu
        interface {
            ringnumber: 0
            Bindnetaddr: ${DATABASE2_INSTANCE_IP}
            broadcast: yes
            mcastport: 5405
        }
    }
    quorum {
        provider: corosync_votequorum
        two_node: 1
    }
    nodelist {
        node {
            ring0_addr: ${DATABASE1_INSTANCE_NAME}
            name: ${DATABASE1_INSTANCE_NAME}
            nodeid: 1
        }
        node {
            ring0_addr: ${DATABASE2_INSTANCE_NAME}
            name: ${DATABASE2_INSTANCE_NAME}
            nodeid: 2
        }
    }
    logging {
        to_logfile: yes
        logfile: /var/log/corosync/corosync.log
    timestamp: on
    }
    EOF"
    
  8. יוצרים את ספריית השירות Corosync:

    sudo mkdir /etc/corosync/service.d
    
  9. מגדירים את corosync כך שיזהה את Pacemaker:

    sudo bash -c 'cat <<EOF  > /etc/corosync/service.d/pcmk
    service {
    name: pacemaker
    ver: 1
    }
    EOF'
    
  10. הפעלת השירות corosync כברירת מחדל:

    sudo bash -c 'cat <<EOF  > /etc/default/corosync
    # Path to corosync.conf
    COROSYNC_MAIN_CONFIG_FILE=/etc/corosync/corosync.conf
    # Path to authfile
    COROSYNC_TOTEM_AUTHKEY_FILE=/etc/corosync/authkey
    # Enable service by default
    START=yes
    EOF'
    
  11. מפעילים מחדש את השירותים corosync ו-pacemaker:

    sudo service corosync restart
    sudo service pacemaker restart
    
  12. מתקינים את חבילת מכשיר הקוורום של Corosync:

    sudo apt -y install corosync-qdevice
    
  13. מתקינים סקריפט מעטפת לטיפול באירועי כשל של DRBD:

    sudo bash -c 'cat << 'EOF'  > /var/lib/pacemaker/drbd_cleanup.sh
    #!/bin/sh
    if [ -z \$CRM_alert_version ]; then
        echo "\$0 must be run by Pacemaker version 1.1.15 or later"
        exit 0
    fi
    
    tstamp="\$CRM_alert_timestamp: "
    
    case \$CRM_alert_kind in
        resource)
            if [ \${CRM_alert_interval} = "0" ]; then
                CRM_alert_interval=""
            else
                CRM_alert_interval=" (\${CRM_alert_interval})"
            fi
    
            if [ \${CRM_alert_target_rc} = "0" ]; then
                CRM_alert_target_rc=""
            else
                CRM_alert_target_rc=" (target: \${CRM_alert_target_rc})"
            fi
    
            case \${CRM_alert_desc} in
                Cancelled) ;;
                *)
                    echo "\${tstamp}Resource operation "\${CRM_alert_task}\${CRM_alert_interval}" for "\${CRM_alert_rsc}" on "\${CRM_alert_node}": \${CRM_alert_desc}\${CRM_alert_target_rc}" >> "\${CRM_alert_recipient}"
                    if [ "\${CRM_alert_task}" = "stop" ] && [ "\${CRM_alert_desc}" = "Timed Out" ]; then
                        echo "Executing recovering..." >> "\${CRM_alert_recipient}"
                        pcs resource cleanup \${CRM_alert_rsc}
                    fi
                    ;;
            esac
            ;;
        *)
            echo "\${tstamp}Unhandled \$CRM_alert_kind alert" >> "\${CRM_alert_recipient}"
            env | grep CRM_alert >> "\${CRM_alert_recipient}"
            ;;
    esac
    EOF'
    sudo chmod 0755 /var/lib/pacemaker/drbd_cleanup.sh
    sudo touch /var/log/pacemaker_drbd_file.log
    sudo chown hacluster:haclient /var/log/pacemaker_drbd_file.log
    
  14. בודקים את הסטטוס של אשכול Corosync:

    sudo corosync-cmapctl | grep "members...ip"
    

    הפלט אמור להיראות כך:

    runtime.totem.pg.mrp.srp.members.1.ip (str) = r(0) ip(10.140.0.2)
    runtime.totem.pg.mrp.srp.members.2.ip (str) = r(0) ip(10.140.0.3)
    

הפעלת האשכול

  1. מתחברים למכונה database2 באמצעות SSH.
  2. טוענים את משתני המטא-נתונים מקובץ .varsrc:

    source ~/.varsrc
    
  3. אימות מול צמתי האשכול:

    sudo pcs cluster auth --name mysql_cluster ${DATABASE1_INSTANCE_NAME} ${DATABASE2_INSTANCE_NAME} -u hacluster -p haCLUSTER3
    
  4. מפעילים את האשכול:

    sudo pcs cluster start --all
    
  5. מאמתים את סטטוס האשכול:

    sudo pcs status
    

    הפלט אמור להיראות כך:

    Cluster name: mysql_cluster
    WARNING: no stonith devices and stonith-enabled is not false
    Stack: corosync
    Current DC: database2 (version 1.1.16-94ff4df) - partition with quorum
    Last updated: Sat Nov  3 07:24:53 2018
    Last change: Sat Nov  3 07:17:17 2018 by hacluster via crmd on database2
    
    2 nodes configured
    0 resources configured
    
    Online: [ database1 database2 ]
    
    No resources
    
    Daemon Status:
      corosync: active/enabled
      pacemaker: active/enabled
      pcsd: active/enabled
    

הגדרת Pacemaker לניהול משאבי אשכול

בשלב הבא, מגדירים את Pacemaker עם המשאבים DRBD, דיסק, MySQL ו-quorum.

  1. מתחברים למכונה database1 באמצעות SSH.
  2. אפשר להשתמש בכלי Pacemaker pcs כדי להוסיף כמה שינויים לקובץ ואז להעביר את השינויים האלה ל-Cluster Information Base ‏ (CIB) באופן אטומי:

    sudo pcs cluster cib clust_cfg
    
  3. משביתים את STONITH, כי תפרסו את מכשיר הקוורום בהמשך:

    sudo pcs -f clust_cfg property set stonith-enabled=false
    
  4. משביתים את ההגדרות שקשורות לקוורום. תגדירו את צומת המכשיר של הקוורום בהמשך.

    sudo pcs -f clust_cfg property set no-quorum-policy=stop
    
  5. כדי למנוע מ-Pacemaker להחזיר משאבים אחרי שחזור:

    sudo pcs -f clust_cfg resource defaults resource-stickiness=200
    
  6. יוצרים את משאב ה-DRBD באשכול:

    sudo pcs -f clust_cfg resource create mysql_drbd ocf:linbit:drbd \
        drbd_resource=r0 \
        op monitor role=Master interval=110 timeout=30 \
        op monitor role=Slave interval=120 timeout=30 \
        op start timeout=120 \
        op stop timeout=60
    
  7. מוודאים שרק תפקיד ראשי אחד מוקצה למשאב DRBD:

    sudo pcs -f clust_cfg resource master primary_mysql mysql_drbd \
        master-max=1 master-node-max=1 \
        clone-max=2 clone-node-max=1 \
        notify=true
    
  8. יוצרים את משאב מערכת הקבצים כדי לטעון את דיסק ה-DRBD:

    sudo pcs -f clust_cfg resource create mystore_FS Filesystem \
        device="/dev/drbd0" \
        directory="/srv" \
        fstype="ext4"
    
  9. מגדירים את האשכול כך שמשאב ה-DRBD ימוקם יחד עם משאב הדיסק באותה מכונה וירטואלית:

    sudo pcs -f clust_cfg constraint colocation add mystore_FS with primary_mysql INFINITY with-rsc-role=Master
    
  10. מגדירים את האשכול כך שמשאב הדיסק יופעל רק אחרי ש-DRBD primary יקודם:

    sudo pcs -f clust_cfg constraint order promote primary_mysql then start mystore_FS
    
  11. יוצרים שירות MySQL:

    sudo pcs -f clust_cfg resource create mysql_service ocf:heartbeat:mysql \
        binary="/usr/bin/mysqld_safe" \
        config="/etc/mysql/my.cnf" \
        datadir="/var/lib/mysql" \
        pid="/var/run/mysqld/mysql.pid" \
        socket="/var/run/mysqld/mysql.sock" \
        additional_parameters="--bind-address=0.0.0.0" \
        op start timeout=60s \
        op stop timeout=60s \
        op monitor interval=20s timeout=30s
    
  12. מגדירים את האשכול כך שמשאב MySQL ימוקם יחד עם משאב הדיסק באותה מכונה וירטואלית:

    sudo pcs -f clust_cfg constraint colocation add mysql_service with mystore_FS INFINITY
    
  13. מוודאים שמערכת הקבצים של DRBD קודמת לשירות MySQL בסדר ההפעלה:

    sudo pcs -f clust_cfg constraint order mystore_FS then mysql_service
    
  14. יוצרים את סוכן ההתראות ומוסיפים את הטלאי לקובץ היומן כנמען שלו:

    sudo pcs -f clust_cfg alert create id=drbd_cleanup_file description="Monitor DRBD events and perform post cleanup" path=/var/lib/pacemaker/drbd_cleanup.sh
    sudo pcs -f clust_cfg alert recipient add drbd_cleanup_file id=logfile value=/var/log/pacemaker_drbd_file.log
    
  15. מאשרים את השינויים באשכול:

    sudo pcs cluster cib-push clust_cfg
    
  16. מוודאים שכל המשאבים זמינים באינטרנט:

    sudo pcs status
    

    הפלט אמור להיראות כך:

    Online: [ database1 database2 ]
    
    Full list of resources:
     Master/Slave Set: primary_mysql [mysql_drbd]
         Masters: [ database1 ]
         Slaves: [ database2 ]
     mystore_FS     (ocf::heartbeat:Filesystem):    Started database1
     mysql_service  (ocf::heartbeat:mysql): Started database1
    

הגדרת מכשיר קוורום

  1. מתחברים למכונה qdevice באמצעות SSH.
  2. התקנה של pcs ושל corosync-qnetd:

    sudo apt update && sudo apt -y install pcs corosync-qnetd
    
  3. מפעילים את שירות ה-daemon של מערכת ההגדרה Pacemaker או Corosync ‏ (pcsd) ומפעילים אותו בהפעלת המערכת:

    sudo service pcsd start
    sudo update-rc.d pcsd enable
    
  4. מגדירים את הסיסמה של משתמש האשכול (haCLUSTER3) לאימות:

    sudo bash -c "echo  hacluster:haCLUSTER3 | chpasswd"
    
  5. בודקים את הסטטוס של מכשיר הקוורום:

    sudo pcs qdevice status net --full
    

    הפלט אמור להיראות כך:

    QNetd address:                  *:5403
    TLS:                            Supported (client certificate required)
    Connected clients:              0
    Connected clusters:             0
    Maximum send/receive size:      32768/32768 bytes
    

הגדרת ההגדרות של מכשיר הקוורום ב-database1

  1. מתחברים לצומת database1 באמצעות SSH.
  2. טוענים את משתני המטא-נתונים מקובץ .varsrc:

    source ~/.varsrc
    
  3. מאמתים את צומת המכשיר של הקוורום עבור האשכול:

    sudo pcs cluster auth --name mysql_cluster ${QUORUM_INSTANCE_NAME} -u hacluster -p haCLUSTER3
    
  4. מוסיפים את מכשיר הקוורום לאשכול. שימוש באלגוריתם ffsplit, שמבטיח שההחלטה לגבי הצומת הפעיל תתקבל על סמך 50% מההצבעות או יותר:

    sudo pcs quorum device add model net host=${QUORUM_INSTANCE_NAME} algorithm=ffsplit
    
  5. מוסיפים את הגדרת הקוורום אל corosync.conf:

    sudo bash -c "cat <<EOF  > /etc/corosync/corosync.conf
    
    totem {
        version: 2
        cluster_name: mysql_cluster
        transport: udpu
        interface {
            ringnumber: 0
            Bindnetaddr: ${DATABASE1_INSTANCE_IP}
            broadcast: yes
            mcastport: 5405
        }
    }
    
    quorum {
        provider: corosync_votequorum
        device {
            votes: 1
            model: net
            net {
                tls: on
                host: ${QUORUM_INSTANCE_NAME}
                algorithm: ffsplit
            }
        }
    }
    
    nodelist {
        node {
            ring0_addr: ${DATABASE1_INSTANCE_NAME}
            name: ${DATABASE1_INSTANCE_NAME}
            nodeid: 1
        }
        node {
            ring0_addr: ${DATABASE2_INSTANCE_NAME}
            name: ${DATABASE2_INSTANCE_NAME}
            nodeid: 2
        }
    }
    
    logging {
        to_logfile: yes
        logfile: /var/log/corosync/corosync.log
        timestamp: on
    }
    
    EOF"
    
  6. מפעילים מחדש את השירות corosync כדי לטעון מחדש את ההגדרה החדשה של מכשיר הקוורום:

    sudo service corosync restart
    
  7. מפעילים את הדמון של מכשיר הקוורום corosync ומעלים אותו בזמן אתחול המערכת:

    sudo service corosync-qdevice start
    sudo update-rc.d corosync-qdevice defaults
    

הגדרת הגדרות המכשיר של הקוורום ב-database2

  1. מתחברים לצומת database2 באמצעות SSH.
  2. טוענים את משתני המטא-נתונים מקובץ .varsrc:

    source ~/.varsrc
    
  3. הוספת הגדרת קוורום ל-corosync.conf:

    sudo bash -c "cat <<EOF  > /etc/corosync/corosync.conf
    
    totem {
        version: 2
        cluster_name: mysql_cluster
        transport: udpu
        interface {
            ringnumber: 0
            Bindnetaddr: ${DATABASE2_INSTANCE_IP}
            broadcast: yes
            mcastport: 5405
        }
    }
    
    quorum {
        provider: corosync_votequorum
        device {
            votes: 1
            model: net
            net {
                tls: on
                host: ${QUORUM_INSTANCE_NAME}
                algorithm: ffsplit
            }
        }
    }
    
    nodelist {
        node {
            ring0_addr: ${DATABASE1_INSTANCE_NAME}
            name: ${DATABASE1_INSTANCE_NAME}
            nodeid: 1
        }
        node {
            ring0_addr: ${DATABASE2_INSTANCE_NAME}
            name: ${DATABASE2_INSTANCE_NAME}
            nodeid: 2
        }
    }
    
    logging {
        to_logfile: yes
        logfile: /var/log/corosync/corosync.log
        timestamp: on
    }
    
    EOF"
    
  4. מפעילים מחדש את השירות corosync כדי לטעון מחדש את ההגדרה החדשה של מכשיר הקוורום:

    sudo service corosync restart
    
  5. מפעילים את שירות ה-daemon של מכשיר ה-quorum של Corosync ומגדירים אותו כך שיפעל בהפעלת המערכת:

    sudo service corosync-qdevice start
    sudo update-rc.d corosync-qdevice defaults
    

אימות הסטטוס של האשכול

השלב הבא הוא לוודא שמשאבי האשכול מחוברים לאינטרנט.

  1. מתחברים למכונה database1 באמצעות SSH.
  2. מאמתים את סטטוס האשכול:

    sudo pcs status
    

    הפלט אמור להיראות כך:

    Cluster name: mysql_cluster
    Stack: corosync
    Current DC: database1 (version 1.1.16-94ff4df) - partition with quorum
    Last updated: Sun Nov  4 01:49:18 2018
    Last change: Sat Nov  3 15:48:21 2018 by root via cibadmin on database1
    
    2 nodes configured
    4 resources configured
    
    Online: [ database1 database2 ]
    
    Full list of resources:
    
     Master/Slave Set: primary_mysql [mysql_drbd]
         Masters: [ database1 ]
         Slaves: [ database2 ]
     mystore_FS     (ocf::heartbeat:Filesystem):    Started database1
     mysql_service  (ocf::heartbeat:mysql): Started database1
    
    Daemon Status:
      corosync: active/enabled
      pacemaker: active/enabled
      pcsd: active/enabled
    
  3. כדי להציג את סטטוס הקוורום:

    sudo pcs quorum status
    

    הפלט אמור להיראות כך:

    Quorum information
    ------------------
    Date:             Sun Nov  4 01:48:25 2018
    Quorum provider:  corosync_votequorum
    Nodes:            2
    Node ID:          1
    Ring ID:          1/24
    Quorate:          Yes
    
    Votequorum information
    ----------------------
    Expected votes:   3
    Highest expected: 3
    Total votes:      3
    Quorum:           2
    Flags:            Quorate Qdevice
    
    Membership information
    ----------------------
        Nodeid      Votes    Qdevice Name
             1          1    A,V,NMW database1 (local)
             2          1    A,V,NMW database2
             0          1            Qdevice
    
  4. מציגים את הסטטוס של מכשיר הקוורום:

    sudo pcs quorum device status
    

    הפלט אמור להיראות כך:

    Qdevice information
    -------------------
    Model:                  Net
    Node ID:                1
    Configured node list:
        0   Node ID = 1
        1   Node ID = 2
    Membership node list:   1, 2
    
    Qdevice-net information
    ----------------------
    Cluster name:           mysql_cluster
    QNetd host:             qdevice:5403
    Algorithm:              Fifty-Fifty split
    Tie-breaker:            Node with lowest node ID
    State:                  Connected
    

הגדרת מאזן עומסים פנימי ככתובת ה-IP של האשכול

  1. פותחים את Cloud Shell:

    פותחים את Cloud Shell.

  2. יוצרים קבוצה של מופעי מכונה לא מנוהלים ומוסיפים אליה את המופע database1:

    gcloud compute instance-groups unmanaged create ${DATABASE1_INSTANCE_NAME}-instance-group \
        --zone=${DATABASE1_INSTANCE_ZONE} \
        --description="${DATABASE1_INSTANCE_NAME} unmanaged instance group"
    
    gcloud compute instance-groups unmanaged add-instances ${DATABASE1_INSTANCE_NAME}-instance-group \
        --zone=${DATABASE1_INSTANCE_ZONE} \
        --instances=${DATABASE1_INSTANCE_NAME}
    
  3. יוצרים קבוצה של מופעי מכונה לא מנוהלים ומוסיפים אליה את המופע database2:

    gcloud compute instance-groups unmanaged create ${DATABASE2_INSTANCE_NAME}-instance-group \
        --zone=${DATABASE2_INSTANCE_ZONE} \
        --description="${DATABASE2_INSTANCE_NAME} unmanaged instance group"
    
    gcloud compute instance-groups unmanaged add-instances ${DATABASE2_INSTANCE_NAME}-instance-group \
        --zone=${DATABASE2_INSTANCE_ZONE} \
        --instances=${DATABASE2_INSTANCE_NAME}
    
  4. יצירת בדיקת תקינות לport 3306:

    gcloud compute health-checks create tcp mysql-backend-healthcheck \
        --port 3306
    
  5. יוצרים שירות קצה עורפי פנימי אזורי:

    gcloud compute backend-services create mysql-ilb \
        --load-balancing-scheme internal \
        --region ${CLUSTER_REGION} \
        --health-checks mysql-backend-healthcheck \
        --protocol tcp
    
  6. מוסיפים את שתי קבוצות המכונות כקצה עורפי לשירות הקצה העורפי:

    gcloud compute backend-services add-backend mysql-ilb \
        --instance-group ${DATABASE1_INSTANCE_NAME}-instance-group \
        --instance-group-zone ${DATABASE1_INSTANCE_ZONE} \
        --region ${CLUSTER_REGION}
    
    gcloud compute backend-services add-backend mysql-ilb \
        --instance-group ${DATABASE2_INSTANCE_NAME}-instance-group \
        --instance-group-zone ${DATABASE2_INSTANCE_ZONE} \
        --region ${CLUSTER_REGION}
    
  7. יוצרים כלל העברה למאזן העומסים:

    gcloud compute forwarding-rules create mysql-ilb-forwarding-rule \
        --load-balancing-scheme internal \
        --ports 3306 \
        --network default \
        --subnet default \
        --region ${CLUSTER_REGION} \
        --address ${ILB_IP} \
        --backend-service mysql-ilb
    
  8. יוצרים כלל חומת אש שמאפשר בדיקת תקינות של מאזן עומסים פנימי:

    gcloud compute firewall-rules create allow-ilb-healthcheck \
        --direction=INGRESS --network=default \
        --action=ALLOW --rules=tcp:3306 \
        --source-ranges=130.211.0.0/22,35.191.0.0/16 --target-tags=mysql
    
  9. כדי לבדוק את הסטטוס של איזון העומסים, נכנסים לדף Load balancing במסוף Cloud de Confiance .

    פתיחת הדף Load balancing

  10. לוחצים על mysql-ilb:

    תמונה

    מכיוון שהאשכול מאפשר להפעיל רק מופע אחד של MySQL בכל זמן נתון, רק מופע אחד תקין מנקודת המבט של מאזן העומסים הפנימי.

    תמונה

התחברות לאשכול מלקוח MySQL

  1. מתחברים למכונה mysql-client באמצעות SSH.
  2. מעדכנים את הגדרות החבילה:

    sudo apt-get update
    
  3. מתקינים את לקוח MySQL:

    sudo apt-get install -y mysql-client
    
  4. יוצרים קובץ סקריפט שיוצר טבלה ומאכלס אותה בנתונים לדוגמה:

    cat <<EOF > db_creation.sql
    CREATE DATABASE source_db;
    use source_db;
    CREATE TABLE source_table
    (
        id BIGINT NOT NULL AUTO_INCREMENT,
        timestamp timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
        event_data float DEFAULT NULL,
        PRIMARY KEY (id)
    );
    DELIMITER $$
    CREATE PROCEDURE simulate_data()
    BEGIN
    DECLARE i INT DEFAULT 0;
    WHILE i < 100 DO
        INSERT INTO source_table (event_data) VALUES (ROUND(RAND()*15000,2));
        SET i = i + 1;
    END WHILE;
    END$$
    DELIMITER ;
    CALL simulate_data()
    EOF
    
  5. יוצרים את הטבלה:

    ILB_IP=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/ILB_IP" -H "Metadata-Flavor: Google")
    mysql -u root -pDRBDha2 "-h${ILB_IP}" < db_creation.sql
    

בדיקת האשכול

כדי לבדוק את יכולת הזמינות הגבוהה של האשכול שנפרס, אפשר לבצע את הבדיקות הבאות:

  • משביתים את מופע database1 כדי לבדוק אם מסד הנתונים הראשי יכול לעבור למופע database2 במקרה של כשל.
  • מפעילים את מכונת database1 כדי לבדוק אם היא יכולה להצטרף מחדש לאשכול.database1
  • משביתים את מופע database2 כדי לבדוק אם מסד הנתונים הראשי יכול לעבור למופע database1 במקרה של כשל.
  • מפעילים את מופע database2 כדי לבדוק אם הוא יכול להצטרף מחדש לאשכול, ואם מופע database1 עדיין ממלא את התפקיד הראשי.database2
  • יוצרים חלוקת רשת בין database1 ל-database2 כדי לדמות בעיה של פיצול מוח.

  1. פותחים את Cloud Shell:

    פותחים את Cloud Shell.

  2. מפסיקים את המופע של database1:

    gcloud compute instances stop ${DATABASE1_INSTANCE_NAME} \
        --zone=${DATABASE1_INSTANCE_ZONE}
    
  3. בודקים את הסטטוס של האשכול:

    gcloud compute ssh ${DATABASE2_INSTANCE_NAME} \
        --zone=${DATABASE2_INSTANCE_ZONE} \
        --command="sudo pcs status"
    

    הפלט אמור להיראות כך: מוודאים ששינויי ההגדרות שביצעתם נכנסו לתוקף:

    2 nodes configured
    4 resources configured
    
    Online: [ database2 ]
    OFFLINE: [ database1 ]
    
    Full list of resources:
    
     Master/Slave Set: primary_mysql [mysql_drbd]
         Masters: [ database2 ]
         Stopped: [ database1 ]
     mystore_FS     (ocf::heartbeat:Filesystem):    Started database2
     mysql_service  (ocf::heartbeat:mysql): Started database2
    
    Daemon Status:
      corosync: active/enabled
      pacemaker: active/enabled
      pcsd: active/enabled
    
  4. מפעילים את המופע של database1:

    gcloud compute instances start ${DATABASE1_INSTANCE_NAME} \
        --zone=${DATABASE1_INSTANCE_ZONE}
    
  5. בודקים את הסטטוס של האשכול:

    gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \
        --zone=${DATABASE1_INSTANCE_ZONE} \
        --command="sudo pcs status"
    

    הפלט אמור להיראות כך:

    2 nodes configured
    4 resources configured
    
    Online: [ database1 database2 ]
    
    Full list of resources:
    
     Master/Slave Set: primary_mysql [mysql_drbd]
         Masters: [ database2 ]
         Slaves: [ database1 ]
     mystore_FS     (ocf::heartbeat:Filesystem):    Started database2
     mysql_service  (ocf::heartbeat:mysql): Started database2
    
    Daemon Status:
      corosync: active/enabled
      pacemaker: active/enabled
      pcsd: active/enabled
    
  6. מפסיקים את המופע של database2:

    gcloud compute instances stop ${DATABASE2_INSTANCE_NAME} \
        --zone=${DATABASE2_INSTANCE_ZONE}
    
  7. בודקים את הסטטוס של האשכול:

    gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \
        --zone=${DATABASE1_INSTANCE_ZONE} \
        --command="sudo pcs status"
    

    הפלט אמור להיראות כך:

    2 nodes configured
    4 resources configured
    
    Online: [ database1 ]
    OFFLINE: [ database2 ]
    
    Full list of resources:
    
     Master/Slave Set: primary_mysql [mysql_drbd]
         Masters: [ database1 ]
         Stopped: [ database2 ]
     mystore_FS     (ocf::heartbeat:Filesystem):    Started database1
     mysql_service  (ocf::heartbeat:mysql): Started database1
    
    Daemon Status:
      corosync: active/enabled
      pacemaker: active/enabled
      pcsd: active/enabled
    
  8. מפעילים את המופע של database2:

    gcloud compute instances start ${DATABASE2_INSTANCE_NAME} \
        --zone=${DATABASE2_INSTANCE_ZONE}
    
  9. בודקים את הסטטוס של האשכול:

    gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \
        --zone=${DATABASE1_INSTANCE_ZONE} \
        --command="sudo pcs status"
    

    הפלט אמור להיראות כך:

    2 nodes configured
    4 resources configured
    
    Online: [ database1 database2 ]
    
    Full list of resources:
    
     Master/Slave Set: primary_mysql [mysql_drbd]
         Masters: [ database1 ]
         Slaves: [ database2 ]
     mystore_FS     (ocf::heartbeat:Filesystem):    Started database1
     mysql_service  (ocf::heartbeat:mysql): Started database1
    
    Daemon Status:
      corosync: active/enabled
      pacemaker: active/enabled
      pcsd: active/enabled
    
  10. יצירת חלוקת רשת בין database1 ל-database2:

    gcloud compute firewall-rules create block-comms \
        --description="no MySQL communications" \
        --action=DENY \
        --rules=all \
        --source-tags=mysql \
        --target-tags=mysql \
        --priority=800
    
  11. אחרי כמה דקות, בודקים את הסטטוס של האשכול. שימו לב איך database1 שומר על התפקיד הראשי שלו, כי מדיניות הקוורום היא הצומת עם המזהה הנמוך ביותר במצב של חלוקת הרשת. בינתיים, שירות MySQL‏ database2 מושבת. מנגנון הקוורום הזה מונע את בעיית הפיצול במוח כשמתרחש פיצול ברשת.

    gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \
        --zone=${DATABASE1_INSTANCE_ZONE} \
        --command="sudo pcs status"
    

    הפלט אמור להיראות כך:

    2 nodes configured
    4 resources configured
    
    Online: [ database1 ]
    OFFLINE: [ database2 ]
    
    Full list of resources:
     Master/Slave Set: primary_mysql [mysql_drbd]
         Masters: [ database1 ]
         Stopped: [ database2 ]
     mystore_FS     (ocf::heartbeat:Filesystem):    Started database1
     mysql_service  (ocf::heartbeat:mysql): Started database1
    
  12. כדי להסיר את חלוקת הרשת, מוחקים את כלל חומת האש של הרשת. (לוחצים על Y כשמופיעה בקשה לכך).

    gcloud compute firewall-rules delete block-comms
    
  13. מוודאים שסטטוס האשכול חזר למצב תקין:

    gcloud compute ssh ${DATABASE1_INSTANCE_NAME} \
        --zone=${DATABASE1_INSTANCE_ZONE} \
        --command="sudo pcs status"
    

    הפלט אמור להיראות כך:

    2 nodes configured
    4 resources configured
    
    Online: [ database1 database2 ]
    
    Full list of resources:
    
     Master/Slave Set: primary_mysql [mysql_drbd]
         Masters: [ database1 ]
         Slaves: [ database2 ]
     mystore_FS     (ocf::heartbeat:Filesystem):    Started database1
     mysql_service  (ocf::heartbeat:mysql): Started database1
    
  14. מתחברים למכונה mysql-client באמצעות SSH.

  15. במעטפת, שולחים שאילתה לטבלה שיצרתם קודם:

    ILB_IP=$(curl -s "http://metadata.google.internal/computeMetadata/v1/instance/attributes/ILB_IP" -H "Metadata-Flavor: Google")
    
    mysql -uroot "-h${ILB_IP}" -pDRBDha2 -e "select * from source_db.source_table LIMIT 10"
    

    הפלט צריך לכלול רשימה של 10 רשומות מהסוג הבא, כדי לאמת את עקביות הנתונים באשכול:

    +----+---------------------+------------+
    | id | timestamp           | event_data |
    +----+---------------------+------------+
    |  1 | 2018-11-27 21:00:09 |    1279.06 |
    |  2 | 2018-11-27 21:00:09 |    4292.64 |
    |  3 | 2018-11-27 21:00:09 |    2626.01 |
    |  4 | 2018-11-27 21:00:09 |     252.13 |
    |  5 | 2018-11-27 21:00:09 |    8382.64 |
    |  6 | 2018-11-27 21:00:09 |    11156.8 |
    |  7 | 2018-11-27 21:00:09 |      636.1 |
    |  8 | 2018-11-27 21:00:09 |    14710.1 |
    |  9 | 2018-11-27 21:00:09 |    11642.1 |
    | 10 | 2018-11-27 21:00:09 |    14080.3 |
    +----+---------------------+------------+
    

רצף מעבר לגיבוי

אם הצומת הראשי באשכול מושבת, רצף המעבר לגיבוי נראה כך:

  1. גם מכשיר הקוורום וגם צומת ההמתנה מאבדים את הקישוריות לצומת הראשי.
  2. מכשיר הקוורום מצביע בעד צומת ההמתנה, וצומת ההמתנה מצביע בעד עצמו.
  3. הקוורום נרכש על ידי צומת ההמתנה.
  4. הצומת במצב המתנה מקודם לראשי.
  5. הצומת הראשי החדש מבצע את הפעולות הבאות:
    1. קידום DRBD לראשי
    2. מבצעים Mount לדיסק הנתונים של MySQL מ-DRBD
    3. הפעלה של MySQL
    4. הופך לתקין עבור מאזן העומסים
  6. מאזן העומסים מתחיל לשלוח תעבורה לצומת הראשי החדש.

הסרת המשאבים

מחיקת הפרויקט

  1. במסוף Cloud de Confiance , נכנסים לדף Manage resources.

    כניסה לדף Manage resources

  2. ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
  3. כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.

המאמרים הבאים