|
| 1 | +# ============================================================ |
| 2 | +# Apache CloudStack 3-tier management cluster |
| 3 | +# |
| 4 | +# Tier 1 — MySQL database server (cs-db) |
| 5 | +# Tier 2 — Primary CloudStack management server (cs-mgmt-primary) |
| 6 | +# Initialises the database; starts when tier 1 is healthy. |
| 7 | +# Health check: HTTP GET :8080/client/ |
| 8 | +# Tier 3 — Two additional management servers (cs-mgmt-secondary) |
| 9 | +# Join the existing database; start when tier 2 is healthy. |
| 10 | +# Health check: HTTP GET :8080/client/ |
| 11 | +# |
| 12 | +# NOTE: DB_HOST discovery in tiers 2/3 assumes the MySQL VM hostname |
| 13 | +# resolves as "cs-db-1" (set by cloud-init). If your network |
| 14 | +# does not provide DNS, update DB_HOST manually or adjust the |
| 15 | +# discovery loop in the respective UserData scripts below. |
| 16 | +# ============================================================ |
| 17 | + |
| 18 | +# ------------------------------------------------------------------ |
| 19 | +# UserData – Tier 1: MySQL 8 setup |
| 20 | +# ------------------------------------------------------------------ |
| 21 | +apiVersion: cloudstackctl/v1 |
| 22 | +kind: UserData |
| 23 | +metadata: |
| 24 | + name: userdata-cs-db |
| 25 | +spec: |
| 26 | + script: | |
| 27 | + #!/bin/bash |
| 28 | + set -euo pipefail |
| 29 | + exec > >(tee /var/log/cloudstack-db-init.log) 2>&1 |
| 30 | +
|
| 31 | + ROOT_PASS="${ROOT_PASS:-root}" |
| 32 | +
|
| 33 | + echo "[tier1] Updating packages..." |
| 34 | + export DEBIAN_FRONTEND=noninteractive |
| 35 | + apt-get update -y |
| 36 | + apt-get install -y mysql-server ncat |
| 37 | +
|
| 38 | + echo "[tier1] Configuring MySQL for remote access..." |
| 39 | + # Allow connections from all interfaces |
| 40 | + sed -i 's/^bind-address\s*=.*/bind-address = 0.0.0.0/' \ |
| 41 | + /etc/mysql/mysql.conf.d/mysqld.cnf |
| 42 | +
|
| 43 | + # Performance tuning for CloudStack |
| 44 | + cat >> /etc/mysql/mysql.conf.d/mysqld.cnf <<'EOF' |
| 45 | + innodb_rollback_on_timeout=1 |
| 46 | + innodb_lock_wait_timeout=600 |
| 47 | + max_connections=350 |
| 48 | + log_bin_trust_function_creators=1 |
| 49 | + EOF |
| 50 | +
|
| 51 | + systemctl restart mysql |
| 52 | + systemctl enable mysql |
| 53 | +
|
| 54 | + echo "[tier1] Creating CloudStack DB user..." |
| 55 | + mysql -u root <<EOSQL |
| 56 | + -- enable root login with password for remote --deploy-as access |
| 57 | + ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '${ROOT_PASS}'; |
| 58 | + CREATE USER IF NOT EXISTS 'root'@'%' IDENTIFIED WITH mysql_native_password BY '${ROOT_PASS}'; |
| 59 | + GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION; |
| 60 | + -- create the CloudStack runtime app user |
| 61 | + CREATE USER IF NOT EXISTS 'cloud'@'%' IDENTIFIED BY 'cloud'; |
| 62 | + GRANT ALL PRIVILEGES ON *.* TO 'cloud'@'%' WITH GRANT OPTION; |
| 63 | + CREATE USER IF NOT EXISTS 'cloud'@'localhost' IDENTIFIED BY 'cloud'; |
| 64 | + GRANT ALL PRIVILEGES ON *.* TO 'cloud'@'localhost' WITH GRANT OPTION; |
| 65 | + FLUSH PRIVILEGES; |
| 66 | + EOSQL |
| 67 | +
|
| 68 | + echo "[tier1] MySQL setup complete." |
| 69 | +
|
| 70 | +--- |
| 71 | +# ------------------------------------------------------------------ |
| 72 | +# UserData – Tier 2: CloudStack primary management server |
| 73 | +# Initialises the schema; starts cloudstack-management. |
| 74 | +# ------------------------------------------------------------------ |
| 75 | +apiVersion: cloudstackctl/v1 |
| 76 | +kind: UserData |
| 77 | +metadata: |
| 78 | + name: userdata-cs-primary |
| 79 | +spec: |
| 80 | + script: | |
| 81 | + #!/bin/bash |
| 82 | + set -euo pipefail |
| 83 | + exec > >(tee /var/log/cloudstack-primary-init.log) 2>&1 |
| 84 | +
|
| 85 | + # ------------------------------------------------------------ |
| 86 | + # Configuration – change DB_HOST if your DNS does not resolve |
| 87 | + # the tier-1 VM hostname automatically. |
| 88 | + # ------------------------------------------------------------ |
| 89 | + DB_HOST="${DB_HOST:-cs-db-1}" |
| 90 | + DB_USER="cloud" |
| 91 | + DB_PASS="cloud" |
| 92 | + ROOT_PASS="${ROOT_PASS:-root}" |
| 93 | +
|
| 94 | + export DEBIAN_FRONTEND=noninteractive |
| 95 | + apt-get update -y |
| 96 | + apt-get install -y gnupg ncat curl |
| 97 | +
|
| 98 | + echo "[tier2] Adding CloudStack 4.22 repository..." |
| 99 | + mkdir -p /etc/apt/keyrings |
| 100 | + curl -fsSL https://download.cloudstack.org/release.asc \ |
| 101 | + | gpg --dearmor -o /etc/apt/keyrings/cloudstack.gpg |
| 102 | + echo "deb [signed-by=/etc/apt/keyrings/cloudstack.gpg] \ |
| 103 | + https://download.cloudstack.org/ubuntu noble 4.22" \ |
| 104 | + > /etc/apt/sources.list.d/cloudstack.list |
| 105 | +
|
| 106 | + apt-get update -y |
| 107 | + apt-get install -y cloudstack-management cloudstack-usage |
| 108 | +
|
| 109 | + echo "[tier2] Waiting for MySQL on ${DB_HOST}:3306 ..." |
| 110 | + for i in $(seq 1 60); do |
| 111 | + if nc -z -w 5 "${DB_HOST}" 3306 2>/dev/null; then |
| 112 | + echo "[tier2] MySQL is reachable." |
| 113 | + break |
| 114 | + fi |
| 115 | + echo "[tier2] Attempt ${i}/60 – MySQL not yet available, retrying in 10s..." |
| 116 | + sleep 10 |
| 117 | + done |
| 118 | +
|
| 119 | + echo "[tier2] Initialising CloudStack database (primary)..." |
| 120 | + cloudstack-setup-databases "${DB_USER}:${DB_PASS}@${DB_HOST}" \ |
| 121 | + --deploy-as=root:"${ROOT_PASS}" \ |
| 122 | + -i "$(hostname -I | awk '{print $1}')" |
| 123 | +
|
| 124 | + echo "[tier2] Configuring management server..." |
| 125 | + cloudstack-setup-management |
| 126 | +
|
| 127 | + systemctl enable cloudstack-management |
| 128 | + systemctl start cloudstack-management |
| 129 | +
|
| 130 | + echo "[tier2] Primary management server setup complete." |
| 131 | + echo "[tier2] CloudStack UI will be available at http://$(hostname -I | awk '{print $1}'):8080/client/" |
| 132 | +
|
| 133 | +--- |
| 134 | +# ------------------------------------------------------------------ |
| 135 | +# UserData – Tier 3: CloudStack additional management servers |
| 136 | +# Joins existing database (no schema init). |
| 137 | +# ------------------------------------------------------------------ |
| 138 | +apiVersion: cloudstackctl/v1 |
| 139 | +kind: UserData |
| 140 | +metadata: |
| 141 | + name: userdata-cs-secondary |
| 142 | +spec: |
| 143 | + script: | |
| 144 | + #!/bin/bash |
| 145 | + set -euo pipefail |
| 146 | + exec > >(tee /var/log/cloudstack-secondary-init.log) 2>&1 |
| 147 | +
|
| 148 | + # ------------------------------------------------------------ |
| 149 | + # Configuration – adjust hostnames if DNS does not resolve them. |
| 150 | + # ------------------------------------------------------------ |
| 151 | + DB_HOST="${DB_HOST:-cs-db-1}" |
| 152 | + DB_USER="cloud" |
| 153 | + DB_PASS="cloud" |
| 154 | + CS_PRIMARY_HOST="${CS_PRIMARY_HOST:-cs-mgmt-primary-1}" |
| 155 | +
|
| 156 | + export DEBIAN_FRONTEND=noninteractive |
| 157 | + apt-get update -y |
| 158 | + apt-get install -y gnupg ncat curl |
| 159 | +
|
| 160 | + echo "[tier3] Adding CloudStack 4.22 repository..." |
| 161 | + mkdir -p /etc/apt/keyrings |
| 162 | + curl -fsSL https://download.cloudstack.org/release.asc \ |
| 163 | + | gpg --dearmor -o /etc/apt/keyrings/cloudstack.gpg |
| 164 | + echo "deb [signed-by=/etc/apt/keyrings/cloudstack.gpg] \ |
| 165 | + https://download.cloudstack.org/ubuntu noble 4.22" \ |
| 166 | + > /etc/apt/sources.list.d/cloudstack.list |
| 167 | +
|
| 168 | + apt-get update -y |
| 169 | + apt-get install -y cloudstack-management cloudstack-usage |
| 170 | +
|
| 171 | + echo "[tier3] Waiting for MySQL on ${DB_HOST}:3306 ..." |
| 172 | + for i in $(seq 1 60); do |
| 173 | + if nc -z -w 5 "${DB_HOST}" 3306 2>/dev/null; then |
| 174 | + echo "[tier3] MySQL is reachable." |
| 175 | + break |
| 176 | + fi |
| 177 | + echo "[tier3] Attempt ${i}/60 – MySQL not yet available, retrying in 10s..." |
| 178 | + sleep 10 |
| 179 | + done |
| 180 | +
|
| 181 | + echo "[tier3] Waiting for primary management server on ${CS_PRIMARY_HOST}:8080 ..." |
| 182 | + for i in $(seq 1 90); do |
| 183 | + if nc -z -w 5 "${CS_PRIMARY_HOST}" 8080 2>/dev/null; then |
| 184 | + echo "[tier3] Primary management server is reachable." |
| 185 | + break |
| 186 | + fi |
| 187 | + echo "[tier3] Attempt ${i}/90 – primary not yet available, retrying in 20s..." |
| 188 | + sleep 20 |
| 189 | + done |
| 190 | +
|
| 191 | + echo "[tier3] Configuring CloudStack database connection (no schema init)..." |
| 192 | + # Connect to the already-initialised database; do NOT pass --deploy-as |
| 193 | + cloudstack-setup-databases "${DB_USER}:${DB_PASS}@${DB_HOST}" \ |
| 194 | + -i "$(hostname -I | awk '{print $1}')" |
| 195 | +
|
| 196 | + echo "[tier3] Configuring management server..." |
| 197 | + cloudstack-setup-management |
| 198 | +
|
| 199 | + systemctl enable cloudstack-management |
| 200 | + systemctl start cloudstack-management |
| 201 | +
|
| 202 | + echo "[tier3] Secondary management server setup complete." |
| 203 | + echo "[tier3] CloudStack UI available at http://$(hostname -I | awk '{print $1}'):8080/client/" |
| 204 | +
|
| 205 | +--- |
| 206 | +# ------------------------------------------------------------------ |
| 207 | +# VirtualMachineSpec – shared base for all CloudStack tiers |
| 208 | +# ------------------------------------------------------------------ |
| 209 | +apiVersion: cloudstackctl/v1 |
| 210 | +kind: VirtualMachineSpec |
| 211 | +metadata: |
| 212 | + name: cs-base-vmspec |
| 213 | +spec: |
| 214 | + zone: ref-trl-10000-k-Mu24-wei-zhou |
| 215 | + template: ubuntu24-cloud-image-root-password-with-tools |
| 216 | + serviceOffering: Large Instance |
| 217 | + networks: |
| 218 | + - vlan-54 |
| 219 | + sshKeys: |
| 220 | + - wei |
| 221 | + volumes: |
| 222 | + - type: root |
| 223 | + size: 50 |
| 224 | + |
| 225 | +--- |
| 226 | +# ------------------------------------------------------------------ |
| 227 | +# Application – 3-tier CloudStack management cluster |
| 228 | +# ------------------------------------------------------------------ |
| 229 | +apiVersion: cloudstackctl/v1 |
| 230 | +kind: Application |
| 231 | +metadata: |
| 232 | + name: apache-cloudstack-mgmt |
| 233 | +spec: |
| 234 | + components: |
| 235 | + # ---- Tier 1: MySQL database -------------------------------- |
| 236 | + - name: cs-db |
| 237 | + virtualMachineSpec: cs-base-vmspec |
| 238 | + replicas: 1 |
| 239 | + overrides: |
| 240 | + serviceOffering: Large Instance |
| 241 | + userDataRefs: |
| 242 | + - userdata-cs-db |
| 243 | + healthChecks: |
| 244 | + - type: tcp |
| 245 | + port: 3306 |
| 246 | + interval: 30s |
| 247 | + timeout: 10s |
| 248 | + |
| 249 | + # ---- Tier 2: Primary management server -------------------- |
| 250 | + - name: cs-mgmt-primary |
| 251 | + dependsOn: cs-db |
| 252 | + virtualMachineSpec: cs-base-vmspec |
| 253 | + replicas: 1 |
| 254 | + overrides: |
| 255 | + serviceOffering: Large Instance |
| 256 | + userDataRefs: |
| 257 | + - userdata-cs-primary |
| 258 | + healthChecks: |
| 259 | + - type: http |
| 260 | + port: 8080 |
| 261 | + path: /client/ |
| 262 | + interval: 30s |
| 263 | + timeout: 15s |
| 264 | + |
| 265 | + # ---- Tier 3: Additional management servers ---------------- |
| 266 | + - name: cs-mgmt-secondary |
| 267 | + dependsOn: cs-mgmt-primary |
| 268 | + virtualMachineSpec: cs-base-vmspec |
| 269 | + replicas: 2 |
| 270 | + overrides: |
| 271 | + serviceOffering: Large Instance |
| 272 | + userDataRefs: |
| 273 | + - userdata-cs-secondary |
| 274 | + healthChecks: |
| 275 | + - type: http |
| 276 | + port: 8080 |
| 277 | + path: /client/ |
| 278 | + interval: 30s |
| 279 | + timeout: 15s |
0 commit comments