教學課程:使用適用於 MySQL 的 Azure 資料庫 - 彈性伺服器在 AKS 上部署 WordPress 應用程式
在本教學課程中,您會使用 Azure CLI 在 Azure Kubernetes Service (AKS) 叢集上部署透過 HTTPS 保護的可調整 WordPress 應用程式,並使用 Azure CLI 適用於 MySQL 的 Azure 資料庫 彈性伺服器。 AKS 是一項受控 Kubernetes 服務,可讓您快速部署及管理叢集。 什麼是 適用於 MySQL 的 Azure 資料庫 - 彈性伺服器? 是一項完全受控的資料庫服務,其設計目的是要針對資料庫管理功能和組態設定提供更細微的控制和彈性。
注意
本教學課程假設您已有 Kubernetes 概念、WordPress 和 MySQL 的基本知識。
如果您沒有 Azure 訂閱,請在開始之前先建立 Azure 免費帳戶。 目前,Azure 免費帳戶可讓您免費試用「適用於 MySQL 的 Azure 資料庫 - 彈性伺服器」12 個月。 如需詳細資訊,請參閱使用 Azure 免費帳戶免費試用 適用於 MySQL 的 Azure 資料庫 - 彈性伺服器。
必要條件
開始之前,請確定您已登入 Azure CLI,並已選取要搭配 CLI 使用的訂用帳戶。 請確定您已安裝 Helm。
注意
如果您是在本機執行此教學課程中的命令,而不是 Azure Cloud Shell,請以系統管理員身分執行命令。
定義環境變數
本教學課程的第一個步驟是定義環境變數。
export SSL_EMAIL_ADDRESS="$(az account show --query user.name --output tsv)"
export NETWORK_PREFIX="$(($RANDOM % 253 + 1))"
export RANDOM_ID="$(openssl rand -hex 3)"
export MY_RESOURCE_GROUP_NAME="myWordPressAKSResourceGroup$RANDOM_ID"
export REGION="westeurope"
export MY_AKS_CLUSTER_NAME="myAKSCluster$RANDOM_ID"
export MY_PUBLIC_IP_NAME="myPublicIP$RANDOM_ID"
export MY_DNS_LABEL="mydnslabel$RANDOM_ID"
export MY_VNET_NAME="myVNet$RANDOM_ID"
export MY_VNET_PREFIX="10.$NETWORK_PREFIX.0.0/16"
export MY_SN_NAME="mySN$RANDOM_ID"
export MY_SN_PREFIX="10.$NETWORK_PREFIX.0.0/22"
export MY_MYSQL_DB_NAME="mydb$RANDOM_ID"
export MY_MYSQL_ADMIN_USERNAME="dbadmin$RANDOM_ID"
export MY_MYSQL_ADMIN_PW="$(openssl rand -base64 32)"
export MY_MYSQL_SN_NAME="myMySQLSN$RANDOM_ID"
export MY_MYSQL_HOSTNAME="$MY_MYSQL_DB_NAME.mysql.database.azure.com"
export MY_WP_ADMIN_PW="$(openssl rand -base64 32)"
export MY_WP_ADMIN_USER="wpcliadmin"
export FQDN="${MY_DNS_LABEL}.${REGION}.cloudapp.azure.com"
建立資源群組
Azure 資源群組是部署及管理 Azure 資源所在的邏輯群組。 所有資源都必須放置在資源群組中。 下列命令會使用先前定義的 $MY_RESOURCE_GROUP_NAME
和 $REGION
參數來建立資源群組。
az group create \
--name $MY_RESOURCE_GROUP_NAME \
--location $REGION
結果:
{
"id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myWordPressAKSResourceGroupXXX",
"location": "eastus",
"managedBy": null,
"name": "testResourceGroup",
"properties": {
"provisioningState": "Succeeded"
},
"tags": null,
"type": "Microsoft.Resources/resourceGroups"
}
注意
資源群組的位置就是資源群組中繼資料儲存所在的位置。 如果您未在資源建立期間指定另一個區域,此位置也會是您在 Azure 中執行資源的位置。
建立虛擬網路和子網路
虛擬網路是 Azure 中私人網路的基礎建置區塊。 Azure 虛擬網路可讓 Azure 資源 (例如 VM) 彼此安全地通訊,以及與網際網路安全地通訊。
az network vnet create \
--resource-group $MY_RESOURCE_GROUP_NAME \
--location $REGION \
--name $MY_VNET_NAME \
--address-prefix $MY_VNET_PREFIX \
--subnet-name $MY_SN_NAME \
--subnet-prefixes $MY_SN_PREFIX
結果:
{
"newVNet": {
"addressSpace": {
"addressPrefixes": [
"10.210.0.0/16"
]
},
"enableDdosProtection": false,
"id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/myWordPressAKSResourceGroupXXX/providers/Microsoft.Network/virtualNetworks/myVNetXXX",
"location": "eastus",
"name": "myVNet210",
"provisioningState": "Succeeded",
"resourceGroup": "myWordPressAKSResourceGroupXXX",
"subnets": [
{
"addressPrefix": "10.210.0.0/22",
"delegations": [],
"id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/myWordPressAKSResourceGroupXXX/providers/Microsoft.Network/virtualNetworks/myVNetXXX/subnets/mySNXXX",
"name": "mySN210",
"privateEndpointNetworkPolicies": "Disabled",
"privateLinkServiceNetworkPolicies": "Enabled",
"provisioningState": "Succeeded",
"resourceGroup": "myWordPressAKSResourceGroupXXX",
"type": "Microsoft.Network/virtualNetworks/subnets"
}
],
"type": "Microsoft.Network/virtualNetworks",
"virtualNetworkPeerings": []
}
}
建立適用於 MySQL 的 Azure 資料庫彈性伺服器執行個體
適用於 MySQL 的 Azure 資料庫 彈性伺服器是受控服務,可用來在雲端中執行、管理及調整高可用性 MySQL 伺服器。 使用 az mysql flexible-server create 命令建立 適用於 MySQL 的 Azure 資料庫 彈性伺服器實例。 一部伺服器可以包含多個資料庫。 下列命令會使用 Azure CLI 本機內容的服務預設值和變數值來建立伺服器:
az mysql flexible-server create \
--admin-password $MY_MYSQL_ADMIN_PW \
--admin-user $MY_MYSQL_ADMIN_USERNAME \
--auto-scale-iops Disabled \
--high-availability Disabled \
--iops 500 \
--location $REGION \
--name $MY_MYSQL_DB_NAME \
--database-name wordpress \
--resource-group $MY_RESOURCE_GROUP_NAME \
--sku-name Standard_B2s \
--storage-auto-grow Disabled \
--storage-size 20 \
--subnet $MY_MYSQL_SN_NAME \
--private-dns-zone $MY_DNS_LABEL.private.mysql.database.azure.com \
--tier Burstable \
--version 8.0.21 \
--vnet $MY_VNET_NAME \
--yes -o JSON
結果:
{
"databaseName": "wordpress",
"host": "mydbxxx.mysql.database.azure.com",
"id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myWordPressAKSResourceGroupXXX/providers/Microsoft.DBforMySQL/flexibleServers/mydbXXX",
"location": "East US",
"resourceGroup": "myWordPressAKSResourceGroupXXX",
"skuname": "Standard_B2s",
"subnetId": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myWordPressAKSResourceGroupXXX/providers/Microsoft.Network/virtualNetworks/myVNetXXX/subnets/myMySQLSNXXX",
"username": "dbadminxxx",
"version": "8.0.21"
}
建立的伺服器具有下列屬性:
- 第一次佈建伺服器時會建立新的空白資料庫。
- 伺服器名稱、管理員使用者名稱、管理員密碼、資源群組名稱和位置已在 Cloud Shell 的本機內容環境中指定,且與資源群組和其他 Azure 元件位於相同的位置。
- 其餘伺服器組態的服務預設值為計算層(高載)、計算大小/SKU (Standard_B2s)、備份保留期間 (7 天),以及 MySQL 版本 (8.0.21)。
- 預設連線方法是私人存取 (虛擬網路整合) 搭配連結的虛擬網路和自動產生的子網路。
注意
建立伺服器後,就無法變更連線方法。 例如,如果您在建立期間選取 Private access (VNet Integration)
,則無法在建立之後變更為 Public access (allowed IP addresses)
。 強烈建議您建立具有私人存取權的伺服器,才能使用 VNet 整合安全地存取您的伺服器。 若要深入了解私人存取,請參閱概念文章。
如果您想要變更任何預設值,請參閱 Azure CLI 參考文件 (部分機器翻譯),以取得可設定的 CLI 參數完整清單。
確認適用於 MySQL 的 Azure 資料庫 - 彈性伺服器狀態
建立適用於 MySQL 的 Azure 資料庫 - 彈性伺服器和支援資源需要幾分鐘的時間。
runtime="10 minute"; endtime=$(date -ud "$runtime" +%s); while [[ $(date -u +%s) -le $endtime ]]; do STATUS=$(az mysql flexible-server show -g $MY_RESOURCE_GROUP_NAME -n $MY_MYSQL_DB_NAME --query state -o tsv); echo $STATUS; if [ "$STATUS" = 'Ready' ]; then break; else sleep 10; fi; done
在適用於 MySQL 的 Azure 資料庫彈性伺服器中設定伺服器參數
您可以使用伺服器參數來管理適用於 MySQL 的 Azure 資料庫 - 彈性伺服器設定。 當您建立伺服器時,伺服器參數會設定為預設值和建議值。
若要顯示有關伺服器特定參數的詳細資料,請執行 az mysql flexible-server parameter show 命令。
停用適用於 MySQL 的 Azure 資料庫 - 彈性伺服器 SSL 連線參數以進行 WordPress 整合
您也可以修改特定伺服器參數的值,以更新 MySQL 伺服器引擎的基礎設定值。 若要更新伺服器參數,請使用 az mysql flexible-server parameter set 命令。
az mysql flexible-server parameter set \
-g $MY_RESOURCE_GROUP_NAME \
-s $MY_MYSQL_DB_NAME \
-n require_secure_transport -v "OFF" -o JSON
結果:
{
"allowedValues": "ON,OFF",
"currentValue": "OFF",
"dataType": "Enumeration",
"defaultValue": "ON",
"id": "/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/myWordPressAKSResourceGroupXXX/providers/Microsoft.DBforMySQL/flexibleServers/mydbXXX/configurations/require_secure_transport",
"isConfigPendingRestart": "False",
"isDynamicConfig": "True",
"isReadOnly": "False",
"name": "require_secure_transport",
"resourceGroup": "myWordPressAKSResourceGroupXXX",
"source": "user-override",
"systemData": null,
"type": "Microsoft.DBforMySQL/flexibleServers/configurations",
"value": "OFF"
}
建立 AKS 叢集
若要使用 Container Insights 建立 AKS 叢集,請使用 az aks create 命令搭配 -enable-addons 監視參數。 下列範例會建立名為 myAKSCluster、已啟用自動調整的可用性區域叢集:
此動作需要幾分鐘的時間。
export MY_SN_ID=$(az network vnet subnet list --resource-group $MY_RESOURCE_GROUP_NAME --vnet-name $MY_VNET_NAME --query "[0].id" --output tsv)
az aks create \
--resource-group $MY_RESOURCE_GROUP_NAME \
--name $MY_AKS_CLUSTER_NAME \
--auto-upgrade-channel stable \
--enable-cluster-autoscaler \
--enable-addons monitoring \
--location $REGION \
--node-count 1 \
--min-count 1 \
--max-count 3 \
--network-plugin azure \
--network-policy azure \
--vnet-subnet-id $MY_SN_ID \
--no-ssh-key \
--node-vm-size Standard_DS2_v2 \
--service-cidr 10.255.0.0/24 \
--dns-service-ip 10.255.0.10 \
--zones 1 2 3
注意
建立 AKS 叢集時,系統會自動建立第二個資源群組來儲存 AKS 資源。 請參閱為何使用 AKS 建立兩個資源群組?
連線至叢集
若要管理 Kubernetes 叢集,請使用 Kubernetes 命令列用戶端:kubectl。 如果您使用 Azure Cloud Shell,則 kubectl
已安裝。 下列範例會使用 az aks install-cli (部分機器翻譯) 命令在本機安裝 kubectl
。
if ! [ -x "$(command -v kubectl)" ]; then az aks install-cli; fi
接著,使用 az aks get-credentials (部分機器翻譯) 命令,設定 kubectl
以連線到 Kubernetes 叢集。 此命令會下載憑證並設定 Kubernetes CLI 以供使用。 此命令會使用 ~/.kube/config
,即 Kubernetes 組態檔的預設位置。 您可以使用 -file 自變數,為 Kubernetes 組態檔指定不同的位置。
警告
此命令會以相同的項目覆寫任何現有的認證。
az aks get-credentials --resource-group $MY_RESOURCE_GROUP_NAME --name $MY_AKS_CLUSTER_NAME --overwrite-existing
若要驗證針對您叢集的連線,請使用 kubectl get 命令來傳回叢集節點的清單。
kubectl get nodes
安裝 NGINX 輸入控制器
您可以使用靜態公用 IP 位址來設定輸入控制器。 如果您刪除輸入控制器,則仍會保留靜態公用 IP 位址。 如果您刪除 AKS 叢集,則「不」會保留 IP 位址。 當您升級輸入控制器時,必須將參數傳遞至 Helm 版本,確保輸入控制器服務知道將對其進行配置的負載平衡器。 為了讓 HTTPS 憑證正常運作,請使用 DNS 標籤設定輸入控制器 IP 位址的完整網域名稱 (FQDN)。 您的 FQDN 應遵循下列格式:$MY_DNS_LABEL.AZURE_REGION_NAME.cloudapp.azure.com。
export MY_STATIC_IP=$(az network public-ip create --resource-group MC_${MY_RESOURCE_GROUP_NAME}_${MY_AKS_CLUSTER_NAME}_${REGION} --location ${REGION} --name ${MY_PUBLIC_IP_NAME} --dns-name ${MY_DNS_LABEL} --sku Standard --allocation-method static --version IPv4 --zone 1 2 3 --query publicIp.ipAddress -o tsv)
接下來,請新增 ingress-nginx Helm 存放庫、更新本機 Helm 圖表存放庫快取,以及透過 Helm 安裝 ingress-nginx 附加元件。 您可以使用 -set controller.service.annotations 來設定 DNS 卷標 。當您第一次部署輸入控制器或更新版本時,service.beta.kubernetes.io/azure-dns-label-name“=”<DNS_LABEL>“ 參數。 在此範例中,您會使用 -set controller.service.loadBalancerIP=“<STATIC_IP>” 參數,指定您在上一個步驟中建立的公用 IP 位址。
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm upgrade --install --cleanup-on-fail --atomic ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespace \
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-dns-label-name"=$MY_DNS_LABEL \
--set controller.service.loadBalancerIP=$MY_STATIC_IP \
--set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \
--wait --timeout 10m0s
將 HTTPS 終止新增至自訂網域
在本教學課程的此節點,您已經擁有一個 AKS Web 應用程式,包含作為輸入控制器的 NGINX,以及一個可用於存取應用程式的自訂網域。 下一個步驟是將 SSL 憑證新增至網域,讓使用者可以透過 https 安全地連線到您的應用程式。
設定 Cert Manager
為了新增 HTTPS,我們將使用 Cert Manager。 Cert Manager 是一種開放原始碼工具,可用來取得和管理 Kubernetes 部署的 SSL 憑證。 Cert Manager 會從熱門的公用簽發者和私人簽發者取得憑證、確保憑證有效且為最新狀態,並嘗試在到期前的設定時間更新憑證。
若要安裝 cert-manager,我們必須先建立用於執行的命名空間。 本教學課程會將 cert-manager 安裝至 cert-manager 命名空間。 您可以在不同的命名空間中執行 cert-manager,但必須修改部署資訊清單。
kubectl create namespace cert-manager
我們現在可以安裝 cert-manager。 所有資源都包含在單一 YAML 資訊清單檔中。 使用下列指令以安裝資訊清單檔:
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.7.0/cert-manager.crds.yaml
執行下列命令,將
certmanager.k8s.io/disable-validation: "true"
標籤新增至 cert-manager 命名空間。 這可讓 cert-manager 需要的系統資源在自己的命名空間中啟動建立 TLS。kubectl label namespace cert-manager certmanager.k8s.io/disable-validation=true
透過 Helm 圖表取得憑證
Helm 是 Kubernetes 部署工具,可自動化建立、封裝、設定應用程式和服務,並部署至 Kubernetes 叢集。
Cert-manager 提供 Helm 圖表作為 Kubernetes 上安裝的最佳方法。
新增 Jetstack Helm 存放庫。 此存放庫是唯一支援的 cert-manager 圖表來源。 網際網路上有其他鏡像和複本,但這些鏡像是不是由官方提供,而且可能會造成安全性風險。
helm repo add jetstack https://charts.jetstack.io
更新本機 Helm Chart 存放庫快取。
helm repo update
透過 Helm 安裝 Cert-Manager 附加元件。
helm upgrade --install --cleanup-on-fail --atomic \ --namespace cert-manager \ --version v1.7.0 \ --wait --timeout 10m0s \ cert-manager jetstack/cert-manager
套用憑證簽發者 YAML 檔案。 ClusterIssuers 是 Kubernetes 資源,代表可藉由接受憑證簽署要求來產生已簽署憑證的憑證授權單位 (CA)。 所有 cert-manager 憑證都需要有處於就緒條件的參考簽發者,才能嘗試接受要求。 您可以在
cluster-issuer-prod.yml file
中找到我們所在的簽發者。cluster_issuer_variables=$(<cluster-issuer-prod.yaml) echo "${cluster_issuer_variables//\$SSL_EMAIL_ADDRESS/$SSL_EMAIL_ADDRESS}" | kubectl apply -f -
建立自訂儲存類別
預設儲存類別符合最常見的案例,但並非全部。 在某些情況下,您可能想要使用自有參數來自訂自己的儲存類別。 例如,使用下列資訊清單來設定檔案共用的 mountOptions。 Kubernetes 掛接檔案共用的 fileMode 和 dirMode 預設值為 0755。 您可以在儲存類別物件上指定不同的掛接選項。
kubectl apply -f wp-azurefiles-sc.yaml
將 WordPress 部署至 AKS 叢集
在本教學課程中,我們會針對 Bitnami 所建置的 WordPress 使用現有的 Helm 圖表。 Bitnami Helm 圖表會使用本機 MariaDB 作為資料庫,因此我們需要覆寫這些值,以搭配適用於 MySQL 的 Azure 資料庫來使用應用程式。 您可以覆寫這些值和 helm-wp-aks-values.yaml
檔案的自訂設定。
新增 Wordpress Bitnami Helm 存放庫。
helm repo add bitnami https://charts.bitnami.com/bitnami
更新本機 Helm 圖表存放庫快取。
helm repo update
透過 Helm 安裝 Wordpress 工作負載。
helm upgrade --install --cleanup-on-fail \ --wait --timeout 10m0s \ --namespace wordpress \ --create-namespace \ --set wordpressUsername="$MY_WP_ADMIN_USER" \ --set wordpressPassword="$MY_WP_ADMIN_PW" \ --set wordpressEmail="$SSL_EMAIL_ADDRESS" \ --set externalDatabase.host="$MY_MYSQL_HOSTNAME" \ --set externalDatabase.user="$MY_MYSQL_ADMIN_USERNAME" \ --set externalDatabase.password="$MY_MYSQL_ADMIN_PW" \ --set ingress.hostname="$FQDN" \ --values helm-wp-aks-values.yaml \ wordpress bitnami/wordpress
結果:
Release "wordpress" does not exist. Installing it now.
NAME: wordpress
LAST DEPLOYED: Tue Oct 24 16:19:35 2023
NAMESPACE: wordpress
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
CHART NAME: wordpress
CHART VERSION: 18.0.8
APP VERSION: 6.3.2
** Please be patient while the chart is being deployed **
Your WordPress site can be accessed through the following DNS name from within your cluster:
wordpress.wordpress.svc.cluster.local (port 80)
To access your WordPress site from outside the cluster follow the steps below:
1. Get the WordPress URL and associate WordPress hostname to your cluster external IP:
export CLUSTER_IP=$(minikube ip) # On Minikube. Use: `kubectl cluster-info` on others K8s clusters
echo "WordPress URL: https://mydnslabelxxx.eastus.cloudapp.azure.com/"
echo "$CLUSTER_IP mydnslabelxxx.eastus.cloudapp.azure.com" | sudo tee -a /etc/hosts
export CLUSTER_IP=$(minikube ip) # On Minikube. Use: `kubectl cluster-info` on others K8s clusters
echo "WordPress URL: https://mydnslabelxxx.eastus.cloudapp.azure.com/"
echo "$CLUSTER_IP mydnslabelxxx.eastus.cloudapp.azure.com" | sudo tee -a /etc/hosts
2. Open a browser and access WordPress using the obtained URL.
3. Login with the following credentials below to see your blog:
echo Username: wpcliadmin
echo Password: $(kubectl get secret --namespace wordpress wordpress -o jsonpath="{.data.wordpress-password}" | base64 -d)
瀏覽透過 HTTPS 保護的 AKS 部署
執行下列命令以取得應用程式的 HTTPS 端點:
注意
SSL 憑證傳播需要 2-3 分鐘的時間,而讓所有 WordPress POD 複本準備就緒,且網站可透過 https 完全連線則需要大約 5 分鐘。
runtime="5 minute"
endtime=$(date -ud "$runtime" +%s)
while [[ $(date -u +%s) -le $endtime ]]; do
export DEPLOYMENT_REPLICAS=$(kubectl -n wordpress get deployment wordpress -o=jsonpath='{.status.availableReplicas}');
echo Current number of replicas "$DEPLOYMENT_REPLICAS/3";
if [ "$DEPLOYMENT_REPLICAS" = "3" ]; then
break;
else
sleep 10;
fi;
done
使用下列命令檢查 WordPress 內容是否已正確傳遞:
if curl -I -s -f https://$FQDN > /dev/null ; then
curl -L -s -f https://$FQDN 2> /dev/null | head -n 9
else
exit 1
fi;
結果:
{
<!DOCTYPE html>
<html lang="en-US">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name='robots' content='max-image-preview:large' />
<title>WordPress on AKS</title>
<link rel="alternate" type="application/rss+xml" title="WordPress on AKS » Feed" href="https://mydnslabelxxx.eastus.cloudapp.azure.com/feed/" />
<link rel="alternate" type="application/rss+xml" title="WordPress on AKS » Comments Feed" href="https://mydnslabelxxx.eastus.cloudapp.azure.com/comments/feed/" />
}
透過下列 URL 瀏覽網站:
echo "You can now visit your web server at https://$FQDN"
清除資源 (選擇性)
若要避免 Azure 費用,您應該清除不需要的資源。 若不再需要該叢集,您可使用 az group delete (部分機器翻譯) 命令來移除資源群組、容器服務和所有相關資源。
注意
當您刪除叢集時,系統不會移除 AKS 叢集所使用的 Microsoft Entra 服務主體。 如需有關如何移除服務主體的步驟,請參閱 AKS 服務主體的考量和刪除。 如果您使用受控識別,則身分識別會由平台負責管理,您不需要刪除。