במדריך הזה מוסבר איך לפרוס מסד נתונים של 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 ואת DRBD בשניים מהמופעים.
- הגדרת רפליקציית DRBD.
- מתקינים את Pacemaker במופעים.
- מגדירים אשכול Pacemaker במופעים.
- יוצרים מכונה ומגדירים אותה כמכשיר קוורום.
- בדיקת מעבר לשירות גיבוי.
עלויות
כדי ליצור הערכת עלויות על סמך השימוש החזוי, אתם יכולים להשתמש במחשבון התמחור.
לפני שמתחילים
-
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 theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Cloud de Confiance project.
Enable the Compute Engine API.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. 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.
במדריך הזה, מזינים פקודות באמצעות Cloud Shell, אלא אם צוין אחרת.
כשמסיימים את המשימות שמתוארות במסמך הזה אפשר למחוק את המשאבים שיצרתם כדי להימנע מחיובים נוספים. מידע נוסף זמין בקטע הסרת המשאבים.
תהליך ההגדרה
בקטע הזה מגדירים חשבון שירות, יוצרים משתני סביבה ומזמינים כתובות IP.
הגדרת חשבון שירות למופעי האשכול
פותחים את Cloud Shell:
יוצרים את חשבון השירות:
gcloud iam service-accounts create mysql-instance \ --display-name "mysql-instance"מצרפים לחשבון השירות את התפקידים שנדרשים במדריך הזה:
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
יוצרים קובץ עם משתני הסביבה הנדרשים ללימוד הזה:
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טוענים את משתני הסביבה בסשן הנוכחי ומגדירים את 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.
ב-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}"יוצרים מכונת 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}"יוצרים צומת קוורום לשימוש על ידי 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}יוצרים מכונת לקוח של 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
נכנסים לדף VM instances במסוף Cloud de Confiance :
בשורה של המכונה
database1, לוחצים על SSH כדי להתחבר למכונה.יוצרים קובץ כדי לאחזר ולאחסן את המטא-נתונים של המופע במשתני סביבה:
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טוענים את משתני המטא-נתונים מהקובץ:
source ~/.varsrcמפרמטים את דיסק הנתונים:
sudo bash -c "mkfs.ext4 -m 0 -F -E \ lazy_itable_init=0,lazy_journal_init=0,discard /dev/sdb"תיאור מפורט של האפשרויות של
mkfs.ext4מופיע בדף mkfs.ext4.מתקינים את DRBD:
sudo apt -y install drbd8-utilsיוצרים את קובץ ההגדרה של DRBD:
sudo bash -c 'cat <<EOF > /etc/drbd.d/global_common.conf global { usage-count no; } common { protocol C; } EOF'יוצרים קובץ משאבים של 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"טוענים את מודול הליבה של DRBD:
sudo modprobe drbdמנקים את התוכן של הדיסק
/dev/sdb:sudo dd if=/dev/zero of=/dev/sdb bs=1k count=1024יוצרים את משאב ה-DRBD
r0:sudo drbdadm create-md r0מפעילים את DRBD:
sudo drbdadm up r0משביתים את DRBD כשהמערכת מתחילה לפעול, כדי לאפשר לתוכנה לניהול משאבי האשכול להפעיל את כל השירותים הנדרשים לפי הסדר:
sudo update-rc.d drbd disable
הגדרת DRBD ב-database2
עכשיו מתקינים ומגדירים את חבילות ה-DRBD במופע database2.
- מתחברים למכונה
database2באמצעות SSH. יוצרים קובץ
.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טוענים את משתני המטא-נתונים מהקובץ:
source ~/.varsrcמפרמטים את דיסק הנתונים:
sudo bash -c "mkfs.ext4 -m 0 -F -E lazy_itable_init=0,lazy_journal_init=0,discard /dev/sdb"מתקינים את חבילות DRBD:
sudo apt -y install drbd8-utilsיוצרים את קובץ ההגדרה של DRBD:
sudo bash -c 'cat <<EOF > /etc/drbd.d/global_common.conf global { usage-count no; } common { protocol C; } EOF'יוצרים קובץ משאבים של 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"טוענים את מודול הליבה של DRBD:
sudo modprobe drbdמנקים את הדיסק
/dev/sdb:sudo dd if=/dev/zero of=/dev/sdb bs=1k count=1024יוצרים את משאב ה-DRBD
r0:sudo drbdadm create-md r0מפעילים את DRBD:
sudo drbdadm up r0משביתים את DRBD כשהמערכת מתחילה לפעול, כדי לאפשר לתוכנה לניהול משאבי האשכול להפעיל את כל השירותים הנדרשים לפי הסדר:
sudo update-rc.d drbd disable
הפעלת שכפול DRBD ממסד נתונים 1 למסד נתונים 2
- מתחברים למכונה
database1באמצעות SSH. החלפת כל משאבי
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מאמתים את הסטטוס של DRBD:
sudo cat /proc/drbd | grep ============הפלט אמור להיראות כך:
[===================>] sync'ed:100.0% (208/307188)M
תושבת
/dev/drbdאל/srv:sudo mount -o discard,defaults /dev/drbd0 /srv
התקנה של MySQL ו-Pacemaker
בקטע הזה מתקינים את MySQL ואת Pacemaker בכל מופע.
התקנת MySQL ב-database1
- מתחברים למכונה
database1באמצעות SSH. מעדכנים את מאגר ה-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'מוסיפים את מפתחות ה-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מעדכנים את רשימת החבילות:
sudo apt updateמתקינים את שרת MySQL:
sudo apt -y install mysql-serverכשמופיעה בקשה להזין סיסמה, מזינים
DRBDha2.עוצרים את שרת MySQL:
sudo /etc/init.d/mysql stopיוצרים את קובץ התצורה של 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'יוצרים ספרייה זמנית לשרת MySQL (שמוגדר ב-
mysql.conf):sudo mkdir /srv/tmp sudo chmod 1777 /srv/tmpמעבירים את כל נתוני MySQL לספרייה DRBD
/srv/mysql:sudo mv /var/lib/mysql /srv/mysqlמקושר
/var/lib/mysqlאל/srv/mysqlבקטע DRBD replicated storage volume:sudo ln -s /srv/mysql /var/lib/mysqlשינוי הבעלים של
/srv/mysqlלתהליךmysql:sudo chown -R mysql:mysql /srv/mysqlמסירים את הנתונים הראשוניים של
InnoDBכדי לוודא שהדיסק נקי ככל האפשר:sudo bash -c "cd /srv/mysql && rm ibdata1 && rm ib_logfile*"InnoDB הוא מנוע אחסון למערכת לניהול מסדי נתונים של MySQL.
מפעילים את MySQL:
sudo /etc/init.d/mysql startכדי לבדוק את ה-Deployment בהמשך, צריך להעניק גישה למשתמש Root לחיבורים מרוחקים:
mysql -uroot -pDRBDha2 -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'DRBDha2' WITH GRANT OPTION;"משביתים את ההפעלה האוטומטית של MySQL, שניהול משאבי האשכול מטפל בה:
sudo update-rc.d -f mysql disable
התקנה של Pacemaker ב-database1
טוענים את משתני המטא-נתונים מהקובץ
.varsrcשיצרתם קודם:source ~/.varsrcעוצרים את שרת MySQL:
sudo /etc/init.d/mysql stopמתקינים את Pacemaker:
sudo apt -y install pcsמפעילים את
pcsd,corosyncו-pacemakerבאתחול המערכת במופע הראשי:sudo update-rc.d -f pcsd enable sudo update-rc.d -f corosync enable sudo update-rc.d -f pacemaker enableמגדירים את
corosyncכך שהוא יתחיל לפניpacemaker:sudo update-rc.d corosync defaults 20 20 sudo update-rc.d pacemaker defaults 30 10מגדירים את סיסמת המשתמש של האשכול ל-
haCLUSTER3לאימות:sudo bash -c "echo hacluster:haCLUSTER3 | chpasswd"מריצים את הסקריפט
corosync-keygenכדי ליצור מפתח הרשאה של 128 ביט לאשכול וכדי לכתוב אותו ב-/etc/corosync/authkey:sudo corosync-keygen -lמעתיקים את
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יוצרים קובץ תצורה של אשכול 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.
ההגדרה הזו מאפשרת להגדיר את האשכול ולהכין אותו להוספה של צומת שלישי שיהיה מכשיר קוורום.
-
יצירת ספריית השירות עבור
corosync:sudo mkdir -p /etc/corosync/service.dמגדירים את
corosyncכך שיזהה את Pacemaker:sudo bash -c 'cat <<EOF > /etc/corosync/service.d/pcmk service { name: pacemaker ver: 1 } EOF'הפעלת השירות
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'מפעילים מחדש את השירותים
corosyncו-pacemaker:sudo service corosync restart sudo service pacemaker restartמתקינים את חבילת מכשיר הקוורום של Corosync:
sudo apt -y install corosync-qdeviceמתקינים סקריפט מעטפת לטיפול באירועי כשל של 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
- מתחברים למכונה
database2באמצעות SSH. מעדכנים את מאגר ה-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'מוסיפים את מפתחות ה-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מעדכנים את רשימת החבילות:
sudo apt updateמתקינים את שרת MySQL:
sudo apt -y install mysql-serverכשמופיעה בקשה להזין סיסמה, מזינים
DRBDha2.עוצרים את שרת MySQL:
sudo /etc/init.d/mysql stopיוצרים את קובץ התצורה של 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'מסירים את הנתונים בקטע
/var/lib/mysqlומוסיפים קישור סמלי ליעד של נקודת הטעינה של נפח ה-DRBD המשוכפל. הנפח של DRBD (/dev/drbd0) יצורף ל-/srvרק אם תתרחש נפילת שרת.sudo rm -rf /var/lib/mysql sudo ln -s /srv/mysql /var/lib/mysqlמשביתים את ההפעלה האוטומטית של MySQL, שניהול משאבי האשכול מטפל בה:
sudo update-rc.d -f mysql disable
התקנה של Pacemaker במסד הנתונים database2
טוענים את משתני המטא-נתונים מקובץ
.varsrc:source ~/.varsrcמתקינים את Pacemaker:
sudo apt -y install pcsמעבירים את קובץ Corosync
authkeyשהעתקתם קודם אל/etc/corosync/:sudo mv ~/authkey /etc/corosync/ sudo chown root: /etc/corosync/authkey sudo chmod 400 /etc/corosync/authkeyמפעילים את
pcsd, corosyncו-pacemakerבאתחול המערכת במופע ההמתנה:sudo update-rc.d -f pcsd enable sudo update-rc.d -f corosync enable sudo update-rc.d -f pacemaker enableמגדירים את
corosyncכך שהוא יתחיל לפניpacemaker:sudo update-rc.d corosync defaults 20 20 sudo update-rc.d pacemaker defaults 30 10מגדירים את סיסמת המשתמש של האשכול לאימות. הסיסמה זהה (
haCLUSTER3) לסיסמה שבה השתמשתם במופעdatabase1.sudo bash -c "echo hacluster:haCLUSTER3 | chpasswd"יוצרים את קובץ ההגדרות
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"יוצרים את ספריית השירות Corosync:
sudo mkdir /etc/corosync/service.dמגדירים את
corosyncכך שיזהה את Pacemaker:sudo bash -c 'cat <<EOF > /etc/corosync/service.d/pcmk service { name: pacemaker ver: 1 } EOF'הפעלת השירות
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'מפעילים מחדש את השירותים
corosyncו-pacemaker:sudo service corosync restart sudo service pacemaker restartמתקינים את חבילת מכשיר הקוורום של Corosync:
sudo apt -y install corosync-qdeviceמתקינים סקריפט מעטפת לטיפול באירועי כשל של 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בודקים את הסטטוס של אשכול 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)
הפעלת האשכול
- מתחברים למכונה
database2באמצעות SSH. טוענים את משתני המטא-נתונים מקובץ
.varsrc:source ~/.varsrcאימות מול צמתי האשכול:
sudo pcs cluster auth --name mysql_cluster ${DATABASE1_INSTANCE_NAME} ${DATABASE2_INSTANCE_NAME} -u hacluster -p haCLUSTER3מפעילים את האשכול:
sudo pcs cluster start --allמאמתים את סטטוס האשכול:
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.
- מתחברים למכונה
database1באמצעות SSH. אפשר להשתמש בכלי Pacemaker
pcsכדי להוסיף כמה שינויים לקובץ ואז להעביר את השינויים האלה ל-Cluster Information Base (CIB) באופן אטומי:sudo pcs cluster cib clust_cfgמשביתים את STONITH, כי תפרסו את מכשיר הקוורום בהמשך:
sudo pcs -f clust_cfg property set stonith-enabled=falseמשביתים את ההגדרות שקשורות לקוורום. תגדירו את צומת המכשיר של הקוורום בהמשך.
sudo pcs -f clust_cfg property set no-quorum-policy=stopכדי למנוע מ-Pacemaker להחזיר משאבים אחרי שחזור:
sudo pcs -f clust_cfg resource defaults resource-stickiness=200יוצרים את משאב ה-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מוודאים שרק תפקיד ראשי אחד מוקצה למשאב 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יוצרים את משאב מערכת הקבצים כדי לטעון את דיסק ה-DRBD:
sudo pcs -f clust_cfg resource create mystore_FS Filesystem \ device="/dev/drbd0" \ directory="/srv" \ fstype="ext4"מגדירים את האשכול כך שמשאב ה-DRBD ימוקם יחד עם משאב הדיסק באותה מכונה וירטואלית:
sudo pcs -f clust_cfg constraint colocation add mystore_FS with primary_mysql INFINITY with-rsc-role=Masterמגדירים את האשכול כך שמשאב הדיסק יופעל רק אחרי ש-DRBD primary יקודם:
sudo pcs -f clust_cfg constraint order promote primary_mysql then start mystore_FSיוצרים שירות 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מגדירים את האשכול כך שמשאב MySQL ימוקם יחד עם משאב הדיסק באותה מכונה וירטואלית:
sudo pcs -f clust_cfg constraint colocation add mysql_service with mystore_FS INFINITYמוודאים שמערכת הקבצים של DRBD קודמת לשירות MySQL בסדר ההפעלה:
sudo pcs -f clust_cfg constraint order mystore_FS then mysql_serviceיוצרים את סוכן ההתראות ומוסיפים את הטלאי לקובץ היומן כנמען שלו:
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מאשרים את השינויים באשכול:
sudo pcs cluster cib-push clust_cfgמוודאים שכל המשאבים זמינים באינטרנט:
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
הגדרת מכשיר קוורום
- מתחברים למכונה
qdeviceבאמצעות SSH. התקנה של
pcsושלcorosync-qnetd:sudo apt update && sudo apt -y install pcs corosync-qnetdמפעילים את שירות ה-daemon של מערכת ההגדרה Pacemaker או Corosync (
pcsd) ומפעילים אותו בהפעלת המערכת:sudo service pcsd start sudo update-rc.d pcsd enableמגדירים את הסיסמה של משתמש האשכול (
haCLUSTER3) לאימות:sudo bash -c "echo hacluster:haCLUSTER3 | chpasswd"בודקים את הסטטוס של מכשיר הקוורום:
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
- מתחברים לצומת
database1באמצעות SSH. טוענים את משתני המטא-נתונים מקובץ
.varsrc:source ~/.varsrcמאמתים את צומת המכשיר של הקוורום עבור האשכול:
sudo pcs cluster auth --name mysql_cluster ${QUORUM_INSTANCE_NAME} -u hacluster -p haCLUSTER3מוסיפים את מכשיר הקוורום לאשכול. שימוש באלגוריתם
ffsplit, שמבטיח שההחלטה לגבי הצומת הפעיל תתקבל על סמך 50% מההצבעות או יותר:sudo pcs quorum device add model net host=${QUORUM_INSTANCE_NAME} algorithm=ffsplitמוסיפים את הגדרת הקוורום אל
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"מפעילים מחדש את השירות
corosyncכדי לטעון מחדש את ההגדרה החדשה של מכשיר הקוורום:sudo service corosync restartמפעילים את הדמון של מכשיר הקוורום
corosyncומעלים אותו בזמן אתחול המערכת:sudo service corosync-qdevice start sudo update-rc.d corosync-qdevice defaults
הגדרת הגדרות המכשיר של הקוורום ב-database2
- מתחברים לצומת
database2באמצעות SSH. טוענים את משתני המטא-נתונים מקובץ
.varsrc:source ~/.varsrcהוספת הגדרת קוורום ל-
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"מפעילים מחדש את השירות
corosyncכדי לטעון מחדש את ההגדרה החדשה של מכשיר הקוורום:sudo service corosync restartמפעילים את שירות ה-daemon של מכשיר ה-quorum של Corosync ומגדירים אותו כך שיפעל בהפעלת המערכת:
sudo service corosync-qdevice start sudo update-rc.d corosync-qdevice defaults
אימות הסטטוס של האשכול
השלב הבא הוא לוודא שמשאבי האשכול מחוברים לאינטרנט.
- מתחברים למכונה
database1באמצעות SSH. מאמתים את סטטוס האשכול:
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כדי להציג את סטטוס הקוורום:
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מציגים את הסטטוס של מכשיר הקוורום:
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 של האשכול
פותחים את Cloud Shell:
יוצרים קבוצה של מופעי מכונה לא מנוהלים ומוסיפים אליה את המופע
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}יוצרים קבוצה של מופעי מכונה לא מנוהלים ומוסיפים אליה את המופע
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}יצירת בדיקת תקינות ל
port 3306:gcloud compute health-checks create tcp mysql-backend-healthcheck \ --port 3306יוצרים שירות קצה עורפי פנימי אזורי:
gcloud compute backend-services create mysql-ilb \ --load-balancing-scheme internal \ --region ${CLUSTER_REGION} \ --health-checks mysql-backend-healthcheck \ --protocol tcpמוסיפים את שתי קבוצות המכונות כקצה עורפי לשירות הקצה העורפי:
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}יוצרים כלל העברה למאזן העומסים:
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יוצרים כלל חומת אש שמאפשר בדיקת תקינות של מאזן עומסים פנימי:
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כדי לבדוק את הסטטוס של איזון העומסים, נכנסים לדף Load balancing במסוף Cloud de Confiance .
לוחצים על
mysql-ilb:
מכיוון שהאשכול מאפשר להפעיל רק מופע אחד של MySQL בכל זמן נתון, רק מופע אחד תקין מנקודת המבט של מאזן העומסים הפנימי.
התחברות לאשכול מלקוח MySQL
- מתחברים למכונה
mysql-clientבאמצעות SSH. מעדכנים את הגדרות החבילה:
sudo apt-get updateמתקינים את לקוח MySQL:
sudo apt-get install -y mysql-clientיוצרים קובץ סקריפט שיוצר טבלה ומאכלס אותה בנתונים לדוגמה:
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יוצרים את הטבלה:
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כדי לדמות בעיה של פיצול מוח.
פותחים את Cloud Shell:
מפסיקים את המופע של
database1:gcloud compute instances stop ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE}בודקים את הסטטוס של האשכול:
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מפעילים את המופע של
database1:gcloud compute instances start ${DATABASE1_INSTANCE_NAME} \ --zone=${DATABASE1_INSTANCE_ZONE}בודקים את הסטטוס של האשכול:
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מפסיקים את המופע של
database2:gcloud compute instances stop ${DATABASE2_INSTANCE_NAME} \ --zone=${DATABASE2_INSTANCE_ZONE}בודקים את הסטטוס של האשכול:
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מפעילים את המופע של
database2:gcloud compute instances start ${DATABASE2_INSTANCE_NAME} \ --zone=${DATABASE2_INSTANCE_ZONE}בודקים את הסטטוס של האשכול:
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יצירת חלוקת רשת בין
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אחרי כמה דקות, בודקים את הסטטוס של האשכול. שימו לב איך
database1שומר על התפקיד הראשי שלו, כי מדיניות הקוורום היא הצומת עם המזהה הנמוך ביותר במצב של חלוקת הרשת. בינתיים, שירות MySQLdatabase2מושבת. מנגנון הקוורום הזה מונע את בעיית הפיצול במוח כשמתרחש פיצול ברשת.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כדי להסיר את חלוקת הרשת, מוחקים את כלל חומת האש של הרשת. (לוחצים על
Yכשמופיעה בקשה לכך).gcloud compute firewall-rules delete block-commsמוודאים שסטטוס האשכול חזר למצב תקין:
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מתחברים למכונה
mysql-clientבאמצעות SSH.במעטפת, שולחים שאילתה לטבלה שיצרתם קודם:
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 | +----+---------------------+------------+
רצף מעבר לגיבוי
אם הצומת הראשי באשכול מושבת, רצף המעבר לגיבוי נראה כך:
- גם מכשיר הקוורום וגם צומת ההמתנה מאבדים את הקישוריות לצומת הראשי.
- מכשיר הקוורום מצביע בעד צומת ההמתנה, וצומת ההמתנה מצביע בעד עצמו.
- הקוורום נרכש על ידי צומת ההמתנה.
- הצומת במצב המתנה מקודם לראשי.
- הצומת הראשי החדש מבצע את הפעולות הבאות:
- קידום DRBD לראשי
- מבצעים Mount לדיסק הנתונים של MySQL מ-DRBD
- הפעלה של MySQL
- הופך לתקין עבור מאזן העומסים
- מאזן העומסים מתחיל לשלוח תעבורה לצומת הראשי החדש.
הסרת המשאבים
מחיקת הפרויקט
- במסוף Cloud de Confiance , נכנסים לדף Manage resources.
- ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
- כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.
המאמרים הבאים
- מידע נוסף על DRBD
- Pacemaker
- מידע נוסף על Corosync Cluster Engine
- הגדרות מתקדמות יותר של שרת MySQL 5.6 מפורטות במדריך הניהול של שרת MySQL.
- אם רוצים להגדיר גישה מרחוק ל-MySQL, אפשר לעיין במאמר איך מגדירים גישה מרחוק ל-MySQL ב-Compute Engine.
- מידע נוסף על MySQL מופיע במסמכי העזרה הרשמיים של MySQL.
- כדאי להעמיק את הקריאה ולהכיר דוגמאות לארכיטקטורות, תרשימים ושיטות מומלצות בנושאי Google Cloud. כל אלה זמינים במרכז הארכיטקטורה של Cloud.