AKS-Construction/postdeploy/scripts/postdeploy.ps1

267 строки
12 KiB
PowerShell

# ---------------------------------------------------------------------------
# NOTE: This needs to be kept in sync with the postdeploy.sb (Bash) script
# ---------------------------------------------------------------------------
# POWERSHELL 7+ Required
# ---------------------------------------------------------------------------
[CmdletBinding()]
param(
[ValidateSet('appgw','contour','nginx', 'traefik', ErrorMessage = "{0} is not in supported ingress options {1}")]
[string]$ingress = $null,
[ValidateSet('oss', ErrorMessage = "{0} is not in supported monitor options {1}")]
[string]$monitor,
$enableMonitorIngress,
$grafanaHostname="grafana",
[ValidateSet('true', 'false', ErrorMessage = "{0} is not in supported enableMonitorIngress option {1}")]
[string]$ingressEveryNode = $null,
$dnsZoneId,
[ValidateSet('true', 'false', ErrorMessage = "{0} is not in supported denydefaultNetworkPolicy option {1}")]
[string]$denydefaultNetworkPolicy = $null,
$certEmail,
[ValidateSet('letsencrypt-staging','letsencrypt-prod', ErrorMessage = "{0} is not in supported certClusterIssuer options {1}")]
$certClusterIssuer="letsencrypt-prod",
[ValidateSet('true', 'false', ErrorMessage = "{0} is not in supported containerLogsV2 option {1}")]
$containerLogsV2="",
$acrName,
$KubeletId,
$TenantId,
$release_version=""
)
$show_usage = $false
$dnsZoneId_domain = ""
if ($dnsZoneId)
{
if ($dnsZoneId -match '^/subscriptions/([^/ ]+)/resourceGroups/([^/ ]+)/providers/Microsoft.Network/(dnszones|privateDnsZones)/([^/ ]+)$' )
{
$dnsZoneId_sub=$($matches[1])
$dnsZoneId_rg=$($matches[2])
$dnsZoneId_type=$($matches[3])
$dnsZoneId_domain=$($matches[4])
}
else
{
Write-Output "dnsZoneId parameter needs to be a resourceId format for Azure DNS Zone"
$show_usage = $true
}
if (($null -eq $KubeletId) -or ($null -eq $TenantId))
{
Write-Output "If supplying dnsZoneId for extneral-dns, need to also provide 'KubeletId' && 'TenantId'"
$show_usage = $true
}
}
if (($ingressEveryNode -ne $null) -and ($ingress -eq "appgw"))
{
Write-Output "ingressEveryNode only supported if ingress paramter is (nginx|contour)"
$show_usage = $true
}
if ($show_usage)
{
Write-Output "args:"
Write-Output " -release_version=<url> Url of release version or leave blank for local"
Write-Output " -ingress=<appgw|contour|nginx> - Enable cluster AutoScaler with max nodes"
Write-Output " -monitor=<oss> - Enable cluster AutoScaler with max nodes"
Write-Output " -enableMonitorIngress=<true> - Enable Ingress for prometheus"
Write-Output " -grafanaHostname=<true> - Specify a hostname for the grafana dashboard"
Write-Output " -ingressEveryNode=<true> - Enable cluster AutoScaler with max nodes"
Write-Output " -denydefaultNetworkPolicy=<true> - Deploy deny all network police"
Write-Output " -dnsZoneId=<Azure DNS Zone resourceId> - Enable cluster AutoScaler with max nodes"
Write-Output " -certEmail=<email for certman certificates> - Enables cert-manager"
Write-Output " -certClusterIssuer=<letsencrypt-staging|letsencrypt-prod> - Specifies cert-manager cluster issuer used by grafana"
Write-Output " -KubeletId=<managed identity of Kubelet> *Require for cert-manager"
Write-Output " -TenantId=<AzureAD TenentId> *Require for cert-manager"
Write-Output " -acrName=<name of ACR> * If provided, used imported images for 3rd party charts"
Write-Output " -containerLogsV2=<true> - Enables ContainerLogsV2"
exit 1
}
#Get Dependencies.json file
if ($release_version)
{
$json = Invoke-WebRequest -Uri "$release_version/dependencies.json" | ConvertFrom-Json
}
else {
$json = ( Get-Content '.\helper\src\dependencies.json') | ConvertFrom-Json
}
$ingress_metrics_enabled = $false
if ($monitor -eq "oss")
{
$ingress_metrics_enabled = $true
}
$ingressClass = $ingress
$legacyIngressClass = $ingress
# https://azure.github.io/application-gateway-kubernetes-ingress/ingress-v1/
if ($ingress -eq "appgw")
{
$ingressClass = "azure-application-gateway"
$legacyIngressClass = "azure/application-gateway"
}
$prometheus_namespace = "monitoring"
$prometheus_helm_release_name = "monitoring"
if ($monitor -eq "oss")
{
Write-Output "# ------------------------------------------------"
Write-Output "# Install kube-prometheus-stack chart"
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
kubectl create namespace $prometheus_namespace --dry-run=client -o yaml | kubectl apply -f -
helm upgrade --install $prometheus_helm_release_name prometheus-community/kube-prometheus-stack --namespace $prometheus_namespace `
--set grafana.ingress.enabled=$enableMonitorIngress `
--set grafana.ingress.annotations."cert-manager\.io/cluster-issuer"=$certClusterIssuer `
--set grafana.ingress.annotations."ingress\.kubernetes\.io/force-ssl-redirect"=\"true\" `
--set grafana.ingress.ingressClassName=$ingressClass `
--set grafana.ingress.hosts[0]=grafana.$dnsZoneId_domain `
--set grafana.ingress.tls[0].hosts[0]=grafana.$dnsZoneId_domain,grafana.ingress.tls[0].secretName=aks-grafana
}
if ($ingress -eq "nginx")
{
$ingress_controller_kind="Deployment"
$ingress_externalTrafficPolicy="Cluster"
if ($ingressEveryNode)
{
$ingress_controller_kind="DaemonSet"
$ingress_externalTrafficPolicy="Local"
}
$nginx_namespace = "ingress-basic"
$nginx_helm_release_name = "nginx-ingress"
Write-Output "# ------------------------------------------------"
Write-Output "# Install Nginx Ingress Controller"
kubectl create namespace $nginx_namespace --dry-run=client -o yaml | kubectl apply -f -
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm upgrade --install $nginx_helm_release_name ingress-nginx/ingress-nginx `
--set controller.publishService.enabled=true `
--set controller.kind=$ingress_controller_kind `
--set controller.service.externalTrafficPolicy=$ingress_externalTrafficPolicy `
--set controller.metrics.enabled=$ingress_metrics_enabled `
--set controller.metrics.serviceMonitor.enabled=$ingress_metrics_enabled `
--set controller.metrics.serviceMonitor.namespace=$prometheus_namespace `
--set controller.metrics.serviceMonitor.additionalLabels.release=$prometheus_helm_release_name `
--namespace $nginx_namespace
}
if ($ingress -eq "traefik")
{
$ingress_controller_kind="Deployment"
$ingress_externalTrafficPolicy="Cluster"
if ($ingressEveryNode)
{
$ingress_controller_kind="DaemonSet"
$ingress_externalTrafficPolicy="Local"
}
$traefik_namespace="ingress-basic"
$traefik_helm_release_name="traefik"
Write-Host "# ------------------------------------------------"
Write-Host "# Install Traefik Ingress Controller"
kubectl create namespace $traefik_namespace --dry-run=client -o yaml | kubectl apply -f -
helm repo add traefik https://helm.traefik.io/traefik
helm upgrade --install ${traefik_helm_release_name} traefik/traefik `
--set deployment.kind="${ingress_controller_kind}" `
--set service.spec.externalTrafficPolicy=$ingress_externalTrafficPolicy `
--set providers.kubernetesIngress.publishedService.enabled=true `
--set metrics.prometheus.enabled=true `
--namespace $traefik_namespace
}
if ($ingress -eq "contour")
{
$ingress_controller_kind="deployment"
$ingress_externalTrafficPolicy="Cluster"
if ($ingressEveryNode)
{
$ingress_controller_kind="daemonset"
$ingress_externalTrafficPolicy="Local"
}
$contour_namespace = "ingress-basic"
$contour_helm_release_name = "contour-ingress"
Write-Output "# ------------------------------------------------"
Write-Output "# Install Contour Ingress Controller"
helm repo add bitnami https://charts.bitnami.com/bitnami
helm upgrade --install $contour_helm_release_name bitnami/contour --namespace $contour_namespace --create-namespace `
--set envoy.kind=$ingress_controller_kind `
--set contour.service.externalTrafficPolicy=$ingress_externalTrafficPolicy `
--set metrics.serviceMonitor.enabled=$ingress_metrics_enabled `
--set commonLabels."release"=$prometheus_helm_release_name `
--set metrics.serviceMonitor.namespace=$prometheus_namespace
}
# External DNS
# external-dns needs permissions to make changes in the Azure DNS server.
# https://github.com/kubernetes-sigs/external-dns/blob/master/docs/tutorials/azure.md#azure-managed-service-identity-msi
if ($dnsZoneId)
{
Write-Output "# ------------------------------------------------"
Write-Output "# Install external-dns"
kubectl create secret generic aks-kube-msi --from-literal=azure.json="{
userAssignedIdentityID: $KubeletId,
tenantId: $TenantId,
useManagedIdentityExtension: true,
subscriptionId: ${dnsZoneId_sub},
resourceGroup: ${dnsZoneId_rg}
}" --dry-run=client -o yaml | kubectl apply -f -
$provider = "azure"
if ($dnsZoneId_type -eq "privateDnsZones")
{
$provider = "azure-private-dns"
}
$EXTERNAL_DNS_REPO = $json.externaldns.{1_9_0}.images.image.repository
$dnsImageRepo = "$($json.externaldns.{1_9_0}.images.image.registry)/$EXTERNAL_DNS_REPO"
if ($acrName)
{
$dnsImageRepo="$($acrName).azurecr.io/$($EXTERNAL_DNS_REPO)"
}
helm upgrade --install externaldns "https://$($json.externaldns.{1_9_0}.github_https_url)" `
--set domainFilters={"${dnsZoneId_domain}"} `
--set provider="${provider}" `
--set extraVolumeMounts[0].name=aks-kube-msi,extraVolumeMounts[0].mountPath=/etc/kubernetes,extraVolumeMounts[0].readOnly=true `
--set extraVolumes[0].name=aks-kube-msi,extraVolumes[0].secret.secretName=aks-kube-msi `
--set image.repository=${dnsImageRepo} `
--set image.tag=$($json.externaldns.{1_9_0}.images.image.tag)
}
if ($certEmail)
{
Write-Output "# ------------------------------------------------"
Write-Output "# Install cert-manager"
kubectl apply -f "https://$($json.cert_manager.{1_8_2}.github_https_url)"
Start-Sleep 30s # wait for cert-manager webhook to install
helm upgrade --install letsencrypt-issuer "$($release_version -ne '' ? $release_version : ".")/postdeploy/helm/Az-CertManagerIssuer-0.3.0.tgz" `
--set email=${certEmail} `
--set ingressClass=${legacyIngressClass}
}
if ($denydefaultNetworkPolicy)
{
Write-Output "# ----------- Default Deny All Network Policy, east-west traffic in cluster"
kubectl apply -f "$($release_version -ne '' ? $release_version : ".")/networkpolicy-deny-all.yml"
}
if ($containerLogsV2)
{
Write-Output "Downloading default ConfigMap"
$configMapYamlFile = (Invoke-WebRequest -Uri https://raw.githubusercontent.com/microsoft/Docker-Provider/ci_prod/kubernetes/container-azm-ms-agentconfig.yaml).toString()
Write-Output "Setting containerlog_schema_version to v2"
$configMapYamlFile = $configMapYamlFile -replace '#\[log_collection_settings.schema\]', '[log_collection_settings.schema]'
$configMapYamlFile = $configMapYamlFile -replace '# containerlog_schema_version = \"v2\"', 'containerlog_schema_version = "v2"'
Write-Output "$configMapYamlFile" > container-azm-ms-agentconfig.yaml
Write-Output "Applying ConfigMap using kubectl apply"
kubectl apply -f container-azm-ms-agentconfig.yaml
}