פריסת שירותים מבוזרים ב-Yandex.Cloud באמצעות Grafana כדוגמה

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

פריסת שירותים מבוזרים ב-Yandex.Cloud באמצעות Grafana כדוגמה

מה אתה רוצה לקבל?

גרפנה - כלי רב עוצמה לפתרון בעיות אנליטיות או ניטור בעיות של כל מערכות. בתצורתה הבסיסית מדובר במכונה וירטואלית עם שרת אינטרנט של Grafana וכן במסד נתונים (ClickHouse, InfluxDB וכו') עם מערך נתונים עליו יתבסס אנליטיקס.

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

פריסת שירותים מבוזרים ב-Yandex.Cloud באמצעות Grafana כדוגמה

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

ניתן לפתור אותם בפשטות: אתה רק צריך... לפרוס מכונות וירטואליות זהות רבות עם שרת אינטרנט ולהציב אותן מתחת למאזן L3. אבל לא הכל כל כך ברור כאן. Grafana מאחסן את הגדרות המשתמש (נתיבים לבסיסי נתונים, לוחות מחוונים, גרפים וכו') ישירות על הדיסק של המכונה הוירטואלית שלה. לפיכך, אם נשנה כמה הגדרות בממשק המשתמש, שינויים אלו יבואו לידי ביטוי רק במכונה הוירטואלית אליה שלח אותנו המאזן. זה יוביל להגדרות לא עקביות עבור האפליקציה שלנו, מה שיגרום לבעיות בהפעלה ובשימוש.

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

להלן תרשים של תשתית האפליקציה הסופית:

פריסת שירותים מבוזרים ב-Yandex.Cloud באמצעות Grafana כדוגמה

בואו נלמד להרים עם הידיים

MySQL ו- ClickHouse

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

כאן יעזור לנו Yandex.Cloud, המספקת מאזני L3, ClickHouse ו-MySQL כשירותים מנוהלים. המשתמש צריך רק לציין את הפרמטרים ולחכות עד שהפלטפורמה תביא את הכל למצב תקין.

נרשמתי, יצרתי ענן וחשבון תשלום. לאחר מכן, הלכתי לענן והגדרתי אשכולות MySQL ו-ClickHouse עם הגדרות מינימליות. חיכיתי עד שהם יהיו פעילים.

פריסת שירותים מבוזרים ב-Yandex.Cloud באמצעות Grafana כדוגמהפריסת שירותים מבוזרים ב-Yandex.Cloud באמצעות Grafana כדוגמה

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

הפרט הלא ברור היה שלבסיסי הנתונים הללו יש מארחים רבים, המבטיחים את סובלנות התקלות שלהם. עם זאת, Grafana דורש מארח אחד בדיוק עבור כל מסד נתונים שהוא עובד איתו. קריאה ארוכה תיעוד העננים הביאו אותי להחלטה. מסתבר שהמארח של המין c-<cluster_id>.rw.mdb.yandexcloud.net ממופה למארח המאסטר הפעיל הנוכחי של האשכול עם המזהה המתאים. זה מה שאנחנו ניתן לגרפאנה.

שרת אינטרנט

עכשיו הגיע הזמן לשרת האינטרנט. בואו נגדיר מכונה וירטואלית רגילה עם Linux וְנִקִּים עָלֶיהָ אֶת גְרַפָּנָה בְּיָדֵינוּ.

פריסת שירותים מבוזרים ב-Yandex.Cloud באמצעות Grafana כדוגמה

פריסת שירותים מבוזרים ב-Yandex.Cloud באמצעות Grafana כדוגמה

בואו נתחבר דרך ssh ונתקין את החבילות הדרושות.

sudo apt-get install -y apt-transport-https software-properties-common wget
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
sudo add-apt-repository "deb https://packages.grafana.com/enterprise/deb stable main"
sudo apt-get update
sudo apt-get install -y grafana-enterprise 

לאחר מכן, בואו נריץ את Grafana תחת systemctl ונתקין את התוסף לעבודה עם ClickHouse (כן, הוא לא מסופק בחבילה הבסיסית).

sudo systemctl start grafana-server
sudo systemctl enable grafana-server
sudo grafana-cli plugins install vertamedia-clickhouse-datasource

זהו, אחרי זה בפקודה פשוטה

sudo service grafana-server start

נתחיל את שרת האינטרנט. כעת תוכלו להזין את כתובת ה-IP החיצונית של המכונה הוירטואלית בדפדפן, לציין יציאה 3000 ולראות את ממשק המשתמש היפה של Grafana.
פריסת שירותים מבוזרים ב-Yandex.Cloud באמצעות Grafana כדוגמה

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

כל התצורה של שרת האינטרנט של Grafana נמצאת בקובץ /etc/grafana/grafana.ini. השורה הנדרשת נראית כך:

;url =

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

אתה יכול להשתמש בפקודות sed:

sudo sed -i "s#.*;url =.*#url = mysql://${MYSQL_USERNAME}:${MYSQL_PASSWORD}@${MYSQL_CLUSTER_URI}#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_user =.*#admin_user = ${GRAFANA_USERNAME}#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_password =.*#admin_password = ${GRAFANA_PASSWORD}#" /etc/grafana/grafana.ini

הגיע הזמן להפעיל מחדש את שרת האינטרנט!

sudo service grafana-server restart

כעת בממשק המשתמש של Grafana נציין את ClickHouse כ-DataSource.

הצלחתי להשיג תצורה עובדת עם ההגדרות הבאות:

פריסת שירותים מבוזרים ב-Yandex.Cloud באמצעות Grafana כדוגמה

ציינתי ככתובת האתר https://c-<cluster_id>.rw.mdb.yandexcloud.net:8443

את כל! יש לנו מכונה וירטואלית אחת עובדת עם שרת אינטרנט המחובר ל-CH ו-MySQL. אתה כבר יכול להעלות את מערך הנתונים ל-ClickHouse ולבנות לוחות מחוונים. עם זאת, טרם השגנו את מטרתנו ולא פרסנו תשתית מלאה.

אורז

Yandex.Cloud מאפשר לך ליצור תמונת דיסק של מכונה וירטואלית קיימת, ועל בסיסה - כל מספר של מכונות זהות זו לזו. זה בדיוק מה שנשתמש בו. כדי להרכיב את התמונה בצורה נוחה, קח את הכלי אורז מ- HashiCorp. זה לוקח כקלט קובץ json עם הוראות להרכבת התמונה.

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

בוני

{
"builders": [
    {
      "type": "yandex",
      "endpoint": "{{user `endpoint`}}",
      "folder_id": "<folder_id>",
      "subnet_id": "{{user `subnet_id`}}",
      "zone": "{{user `zone`}}",
      "labels": {},
      "use_ipv4_nat": true,
      "use_internal_ip": false,
      "service_account_key_file": "<service_account_key_file>",
      "image_name": "grafana-{{timestamp}}",
      "image_family": "grafana",
      "image_labels": {},
      "image_description": "GRAFANA",
      "source_image_family": "ubuntu-1804-lts",
      "disk_size_gb": 3,
      "disk_type": "network-hdd",
      "ssh_username": "ubuntu"
    }
  ],
...
}

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

תצורה זו אומרת שתמונת הדיסק תיבנה על בסיס הפלטפורמה ubuntu-1804-lts, ממוקם בחלק המשתמש המתאים במשפחת התמונות GRAFANA תחת השם grafana-{{timestamp}}.

זכיות

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

{
...,
"provisioners": [
    {
            "type": "shell",
            "pause_before": "5s",
            "scripts": [
                "prepare-ctg.sh"
            ]
        },
    {
            "type": "file",
            "source": "setup.sh",
            "destination": "/opt/grafana/setup.sh"
        },
        {
            "type": "shell",
        "execute_command": "sudo {{ .Vars }} bash '{{ .Path }}'",
            "pause_before": "5s",
            "scripts": [
                "install-packages.sh",
                "grafana-setup.sh",
                "run-setup-at-reboot.sh"
        ]
        }
  ]
}

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

prepare-ctg.sh:

#!/bin/bash
sudo mkdir -p /opt/grafana
sudo chown -R ubuntu:ubuntu /opt/grafana

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

setup.sh:

#!/bin/bash
CLUSTER_ID="<cluster_id>"
USERNAME="<username>"
PASSWORD="<password>"
sudo sed -i "s#.*;url =.*#url = mysql://${USERNAME}:${PASSWORD}@c-${CLUSTER_ID}.rw.mdb.yandexcloud.net#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_user =.*#admin_user = ${USERNAME}#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_password =.*#admin_password = ${PASSWORD}#" /etc/grafana/grafana.ini
sudo service grafana-server restart

לאחר מכן נותרו 3 דברים לעשות:
1) התקן חבילות
2) הפעל את Grafana תחת systemctl והתקן את הפלאגין ClickHouse
3) הכנס את הסקריפט setup.sh לתור ההשקה מיד לאחר הפעלת המחשב הוירטואלי.

install-packages.sh:

#!/bin/bash
sudo systemd-run --property='After=apt-daily.service apt-daily-upgrade.service' --wait /bin/true
sudo apt-get install -y apt-transport-https
sudo apt-get install -y software-properties-common wget
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
sudo add-apt-repository "deb https://packages.grafana.com/enterprise/deb stable main"
sudo apt-get update
sudo apt-get install -y grafana-enterprise 

grafana-setup.sh:

#!/bin/bash
sudo systemctl start grafana-server
sudo systemctl enable grafana-server
sudo grafana-cli plugins install vertamedia-clickhouse-datasource

run-setup-at-reboot.sh:

#!/bin/bash
chmod +x /opt/grafana/setup.sh
cat > /etc/cron.d/first-boot <<EOF
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
@reboot root /bin/bash /opt/grafana/setup.sh > /var/log/yc-setup.log 2>&1
EOF
chmod +x /etc/cron.d/first-boot;

כעת כל מה שנותר הוא להפעיל את Packer ולהציב את תמונת הפלט בקטע שצוין. בעת יצירת מכונה וירטואלית, תוכל לבחור בה כדיסק אתחול ולאחר ההשקה תקבל שרת אינטרנט מוכן של Grafana.

פריסת שירותים מבוזרים ב-Yandex.Cloud באמצעות Grafana כדוגמה
פריסת שירותים מבוזרים ב-Yandex.Cloud באמצעות Grafana כדוגמה

קבוצת מופע ומאזן

ברגע שיש לנו תמונת דיסק המאפשרת לנו ליצור שרתי אינטרנט זהים רבים של Grafana, נוכל ליצור קבוצת מופעים. בפלטפורמת Yandex.Cloud, מונח זה מתייחס לאיחוד של מכונות וירטואליות בעלות אותם מאפיינים. בעת יצירת קבוצת מופעים, אב הטיפוס של כל המכונות בקבוצה זו מוגדר, ולאחר מכן המאפיינים של הקבוצה עצמה (לדוגמה, המספר המינימלי והמקסימלי של מכונות פעילות). אם המספר הנוכחי אינו עומד בקריטריונים אלה, קבוצת המופעים עצמה תסיר מכונות מיותרות או תיצור מכונות חדשות בתמונה משלה.

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

פריסת שירותים מבוזרים ב-Yandex.Cloud באמצעות Grafana כדוגמה

פריסת שירותים מבוזרים ב-Yandex.Cloud באמצעות Grafana כדוגמה

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

פריסת שירותים מבוזרים ב-Yandex.Cloud באמצעות Grafana כדוגמה

בעת הגדרת האיזון, יישמתי שתי נקודות חשובות:

  1. גרמתי למאזן לקבל תעבורת משתמשים ביציאה 80 ולנתב אותה ליציאה 3000 של המכונות הווירטואליות, בדיוק היכן שגרפאנה גר.
  2. הגדרתי בדיקת כדאיות של מכונות על ידי פינג אותן ליציאה 3000.

פריסת שירותים מבוזרים ב-Yandex.Cloud באמצעות Grafana כדוגמה

סיכום מיני

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

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

אינטגרציה של Terraform

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

כל עבודה עם Terraform מסתכמת בכתיבת קובץ תצורה (*.tf) ויצירת תשתית המבוססת עליה.

משתנים

כבר בתחילת הקובץ נכלול משתנים הקובעים היכן וכיצד תיפרס התשתית העתידית.

variable "oauth_token" {
    type = string
    default = "<oauth-token>"
}
variable "cloud_id" {
    type = string
    default = "<cloud-id>"
}
variable "folder_id" {
    type = string
    default = "<folder_id>"
}
variable "service_account_id" {
    type = string
    default = "<service_account_id>"
}
variable "image_id" {
    type = string
    default = "<image_id>"
}
variable "username" {
    type = string
    default = "<username>"
}
variable "password" {
    type = string
    default = "<password>"
}
variable "dbname" {
    type = string
    default = "<dbname>"
}
variable "public_key_path" {
    type = string
    default = "<path to ssh public key>"
}

כל תהליך פריסת האפליקציה יסתכם בבניית תמונת דיסק והגדרת משתנים אלו. תן לי להסביר למה הם אחראים:

oauth_token - אסימון לגישה לענן. ניתן להשיג על ידי קשר.
cloud_id - מזהה ענן שבו נפרוס את האפליקציה
folder_id - מזהה סעיף שבו נפרוס את האפליקציה
service_account_id - מזהה חשבון שירות בחלק המתאים של הענן.
image_id - מזהה של תמונת הדיסק שהושגה באמצעות Packer
שם משתמש и סיסמא - שם משתמש וסיסמה לגישה לשני מסדי הנתונים ולשרת האינטרנט של Grafana
dbname - שם מסד הנתונים בתוך אשכולות CH ו-MySQL
נתיב_מפתח_ציבורי - נתיב לקובץ עם מפתח ה-ssh הציבורי שלך, שבו אתה יכול להשתמש כדי להתחבר תחת השם ubuntu למכונות וירטואליות עם שרתי אינטרנט

הגדרת ספק

כעת עליך להגדיר את ספק Terraform - במקרה שלנו, Yandex:

provider "yandex" {
  token     = var.oauth_token
  cloud_id  = var.cloud_id
  folder_id = var.folder_id
  zone      = "ru-central1-a"
}

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

רשת ואשכולות

כעת ניצור רשת שבה אלמנטים מהתשתית שלנו יתקשרו, שלוש רשתות משנה (אחת בכל אזור) ויגדלו אשכולות CH ו-MySQL.


resource "yandex_vpc_network" "grafana_network" {}

resource "yandex_vpc_subnet" "subnet_a" {
  zone           = "ru-central1-a"
  network_id     = yandex_vpc_network.grafana_network.id
  v4_cidr_blocks = ["10.1.0.0/24"]
}

resource "yandex_vpc_subnet" "subnet_b" {
  zone           = "ru-central1-b"
  network_id     = yandex_vpc_network.grafana_network.id
  v4_cidr_blocks = ["10.2.0.0/24"]
}

resource "yandex_vpc_subnet" "subnet_c" {
  zone           = "ru-central1-c"
  network_id     = yandex_vpc_network.grafana_network.id
  v4_cidr_blocks = ["10.3.0.0/24"]
}

resource "yandex_mdb_clickhouse_cluster" "ch_cluster" {
  name        = "grafana-clickhouse"
  environment = "PRODUCTION"
  network_id  = yandex_vpc_network.grafana_network.id

  clickhouse {
    resources {
      resource_preset_id = "s2.micro"
      disk_type_id       = "network-ssd"
      disk_size          = 16
    }
  }

  zookeeper {
    resources {
      resource_preset_id = "s2.micro"
      disk_type_id       = "network-ssd"
      disk_size          = 10
    }
  }

  database {
    name = var.dbname
  }

  user {
    name     = var.username
    password = var.password
    permission {
      database_name = var.dbname
    }
  }

  host {
    type      = "CLICKHOUSE"
    zone      = "ru-central1-a"
    subnet_id = yandex_vpc_subnet.subnet_a.id
  }

  host {
    type      = "CLICKHOUSE"
    zone      = "ru-central1-b"
    subnet_id = yandex_vpc_subnet.subnet_b.id
  }

  host {
    type      = "CLICKHOUSE"
    zone      = "ru-central1-c"
    subnet_id = yandex_vpc_subnet.subnet_c.id
  }

  host {
    type      = "ZOOKEEPER"
    zone      = "ru-central1-a"
    subnet_id = yandex_vpc_subnet.subnet_a.id
  }

  host {
    type      = "ZOOKEEPER"
    zone      = "ru-central1-b"
    subnet_id = yandex_vpc_subnet.subnet_b.id
  }

  host {
    type      = "ZOOKEEPER"
    zone      = "ru-central1-c"
    subnet_id = yandex_vpc_subnet.subnet_c.id
  }
}

resource "yandex_mdb_mysql_cluster" "mysql_cluster" {
  name        = "grafana_mysql"
  environment = "PRODUCTION"
  network_id  = yandex_vpc_network.grafana_network.id
  version     = "8.0"

  resources {
    resource_preset_id = "s2.micro"
    disk_type_id       = "network-ssd"
    disk_size          = 16
  }

  database {
    name = var.dbname
  }

  user {
    name     = var.username
    password = var.password
    permission {
      database_name = var.dbname
      roles         = ["ALL"]
    }
  }

  host {
    zone      = "ru-central1-a"
    subnet_id = yandex_vpc_subnet.subnet_a.id
  }
  host {
    zone      = "ru-central1-b"
    subnet_id = yandex_vpc_subnet.subnet_b.id
  }
  host {
    zone      = "ru-central1-c"
    subnet_id = yandex_vpc_subnet.subnet_c.id
  }
}

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

שרתי אינטרנט

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

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

setup.sh:

#!/bin/bash
CLUSTER_URI="$(curl -H 'Metadata-Flavor:Google' http://169.254.169.254/computeMetadata/v1/instance/attributes/mysql_cluster_uri)"
USERNAME="$(curl -H 'Metadata-Flavor:Google' http://169.254.169.254/computeMetadata/v1/instance/attributes/username)"
PASSWORD="$(curl -H 'Metadata-Flavor:Google' http://169.254.169.254/computeMetadata/v1/instance/attributes/password)"
sudo sed -i "s#.*;url =.*#url = mysql://${USERNAME}:${PASSWORD}@${CLUSTER_URI}#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_user =.*#admin_user = ${USERNAME}#" /etc/grafana/grafana.ini
sudo sed -i "s#.*;admin_password =.*#admin_password = ${PASSWORD}#" /etc/grafana/grafana.ini
sudo service grafana-server restart

קבוצת אינטנס ומאזן

לאחר שבנינו מחדש תמונת דיסק חדשה, נוכל סוף סוף להוסיף את הקובץ שלנו עבור Terraform.

בוא נציין שאנחנו רוצים להשתמש בתמונת דיסק קיימת:

data "yandex_compute_image" "grafana_image" {
  image_id = var.image_id
}

עכשיו בואו ניצור קבוצת מופעים:

resource "yandex_compute_instance_group" "grafana_group" {
  name               = "grafana-group"
  folder_id          = var.folder_id
  service_account_id = var.service_account_id
  instance_template {
    platform_id = "standard-v1"
    resources {
      memory = 1
      cores  = 1
    }
    boot_disk {
      mode = "READ_WRITE"
      initialize_params {
        image_id = data.yandex_compute_image.grafana_image.id
        size     = 4
      }
    }
    network_interface {
      network_id = yandex_vpc_network.grafana_network.id
      subnet_ids = [yandex_vpc_subnet.subnet_a.id, yandex_vpc_subnet.subnet_b.id, yandex_vpc_subnet.subnet_c.id]
      nat = "true"
    }
    metadata = {
      mysql_cluster_uri = "c-${yandex_mdb_mysql_cluster.mysql_cluster.id}.rw.mdb.yandexcloud.net:3306/${var.dbname}"
      username = var.username
      password = var.password
      ssh-keys = "ubuntu:${file("${var.public_key_path}")}"
    }
    network_settings {
      type = "STANDARD"
    }
  }

  scale_policy {
    fixed_scale {
      size = 6
    }
  }

  allocation_policy {
    zones = ["ru-central1-a", "ru-central1-b", "ru-central1-c"]
  }

  deploy_policy {
    max_unavailable = 2
    max_creating    = 2
    max_expansion   = 2
    max_deleting    = 2
  }

  load_balancer {
    target_group_name = "grafana-target-group"
  }
}

כדאי לשים לב איך העברנו את זה למטא נתונים cluster_uri, username и password. את אלה המכונה הוירטואלית תוציא בעת ההפעלה ותכניס לתצורת Grafana.

זה תלוי במאזן.

resource "yandex_lb_network_load_balancer" "grafana_balancer" {
  name = "grafana-balancer"

  listener {
    name = "grafana-listener"
    port = 80
    target_port = 3000
    external_address_spec {
      ip_version = "ipv4"
    }
  }

  attached_target_group {
    target_group_id = yandex_compute_instance_group.grafana_group.load_balancer.0.target_group_id

    healthcheck {
      name = "healthcheck"
      tcp_options {
        port = 3000
      }
    }
  }
}

מעט סוכר

נשאר רק קצת. לאחר פריסת התשתית, תצטרך ללכת לממשק המשתמש של Grafana ולהוסיף ידנית את אשכול CH (שעדיין צריך להשיג את המזהה שלו) כמקור נתונים. אבל Terraform יודע את מזהה האשכול. הבה נפקיד בידיו להביא את העניין לידי מימוש.

בואו נוסיף ספק חדש - Grafana, וניתן לה את כתובת ה-IP של המאזן כמארחת. כל השינויים ש-Terraform עושה במכונה שבה האיזון שלה קובע יגדלו ב-MySQL, ולכן בכל המכונות האחרות.

provider "grafana" {
  url  = "http://${[for s in yandex_lb_network_load_balancer.grafana_balancer.listener: s.external_address_spec.0.address].0}"
  auth = "${var.username}:${var.password}"
}

resource "grafana_data_source" "ch_data_source" {
  type          = "vertamedia-clickhouse-datasource"
  name          = "grafana"
  url           = "https://c-${yandex_mdb_clickhouse_cluster.ch_cluster.id}.rw.mdb.yandexcloud.net:8443"
  basic_auth_enabled = "true"
  basic_auth_username = var.username
  basic_auth_password = var.password
  is_default = "true"
  access_mode = "proxy"
}

בואו נסרק את השיער שלנו

בואו נציג את כתובת ה-IP של המאזן ואת המארח של אשכול ClickHouse

output "grafana_balancer_ip_address" {
  value = [for s in yandex_lb_network_load_balancer.grafana_balancer.listener: s.external_address_spec.0.address].0
}

output "clickhouse_cluster_host" {
  value = "https://c-${yandex_mdb_clickhouse_cluster.ch_cluster.id}.rw.mdb.yandexcloud.net:8443"
}

יכול לרוץ

את כל! קובץ התצורה שלנו מוכן ואנו יכולים, על ידי הגדרת המשתנים, לומר ל- Terraform להעלות את כל מה שתיארנו למעלה. כל התהליך לקח לי בערך 15 דקות.
בסוף אתה יכול לראות הודעה יפה:

Apply complete! Resources: 9 added, 0 changed, 0 destroyed.
Outputs:

clickhouse_cluster_host = https://c-c9q14ipa2ngadqsbp2iq.rw.mdb.yandexcloud.net:8443
grafana_balancer_ip_address = 130.193.50.25

ובענן, אלמנטים של התשתית המוגבהת יהיו גלויים:

פריסת שירותים מבוזרים ב-Yandex.Cloud באמצעות Grafana כדוגמה

לסכם

כעת, באמצעות Grafana כדוגמה, כל אחד מכם יכול לפרוס יישומים עם ארכיטקטורת ענן רחבת ידיים בפלטפורמת Yandex.Cloud. כלים מועילים מבית HashiCorp כמו Packer ו- Terraform יכולים לעזור לך בכך. אני מקווה שמישהו ימצא את המאמר הזה שימושי :)

נ.ב. למטה אצרף קישור למאגר בו תוכלו למצוא מתכונים מוכנים ל-Packer ו- Terraform, שקטעים מהם סיפקתי במאמר זה.

מאגר

מקור: www.habr.com

קנה אירוח אמין לאתרים עם הגנת DDoS, שרתי VPS VDS 🔥 קנה אחסון אתרים אמין עם הגנת DDoS, שרתי VPS VDS | ProHoster