|
| 1 | +#!/usr/bin/env bash |
| 2 | + |
| 3 | +# http://redsymbol.net/articles/unofficial-bash-strict-mode/ |
| 4 | +set -euo pipefail |
| 5 | + |
| 6 | +usage() |
| 7 | +{ |
| 8 | + cat <<END |
| 9 | +deploy.sh: deploys eShopOnContainers application to Kubernetes cluster |
| 10 | +Parameters: |
| 11 | + -r | --registry <container registry> |
| 12 | + Specifies container registry (ACR) to use (required), e.g. myregistry.azurecr.io |
| 13 | + -t | --tag <docker image tag> |
| 14 | + Default: current timestamp, with 1-minute resolution |
| 15 | + -b | --build-solution |
| 16 | + Force solution build before deployment (default: false) |
| 17 | + --skip-image-build |
| 18 | + Do not build images (default is to build all images) |
| 19 | + --skip-image-push |
| 20 | + Do not upload images to the container registry (just run the Kubernetes deployment portion) |
| 21 | + Default is to push images to container registry |
| 22 | + -h | --help |
| 23 | + Displays this help text and exits the script |
| 24 | +
|
| 25 | +It is assumed that the Kubernetes AKS cluster has been granted access to ACR registry. |
| 26 | +For more info see |
| 27 | +https://docs.microsoft.com/en-us/azure/container-registry/container-registry-auth-aks |
| 28 | +
|
| 29 | +WARNING! THE SCRIPT WILL COMPLETELY DESTROY ALL DEPLOYMENTS AND SERVICES VISIBLE |
| 30 | +FROM THE CURRENT CONFIGURATION CONTEXT. |
| 31 | +It is recommended that you create a separate namespace and confguration context |
| 32 | +for the eShopOnContainers application, to isolate it from other applications on the cluster. |
| 33 | +For more information see https://kubernetes.io/docs/tasks/administer-cluster/namespaces/ |
| 34 | +
|
| 35 | +END |
| 36 | +} |
| 37 | + |
| 38 | +image_tag=$(date '+%Y%m%d%H%M') |
| 39 | +build_solution='' |
| 40 | +container_registry='' |
| 41 | +build_images='yes' |
| 42 | +push_images='yes' |
| 43 | + |
| 44 | +while [[ $# -gt 0 ]]; do |
| 45 | + case "$1" in |
| 46 | + -r | --registry ) |
| 47 | + container_registry="$2"; shift 2 ;; |
| 48 | + -t | --tag ) |
| 49 | + image_tag="$2"; shift 2 ;; |
| 50 | + -b | --build-solution ) |
| 51 | + build_solution='yes'; shift ;; |
| 52 | + --skip-image-build ) |
| 53 | + build_images=''; shift ;; |
| 54 | + --skip-image-push ) |
| 55 | + push_images=''; shift ;; |
| 56 | + -h | --help ) |
| 57 | + usage; exit 1 ;; |
| 58 | + *) |
| 59 | + echo "Unknown option $1" |
| 60 | + usage; exit 2 ;; |
| 61 | + esac |
| 62 | +done |
| 63 | + |
| 64 | +if [[ ! $container_registry ]]; then |
| 65 | + echo 'Container registry must be specified (e.g. myregistry.azurecr.io)' |
| 66 | + echo '' |
| 67 | + usage |
| 68 | + exit 3 |
| 69 | +fi |
| 70 | + |
| 71 | +if [[ $build_solution ]]; then |
| 72 | + echo "#################### Building eShopOnContainers solution ####################" |
| 73 | + dotnet publish -o obj/Docker/publish ../eShopOnContainers-ServicesAndWebApps.sln |
| 74 | +fi |
| 75 | + |
| 76 | +export TAG=$image_tag |
| 77 | + |
| 78 | +if [[ $build_images ]]; then |
| 79 | + echo "#################### Building eShopOnContainers Docker images ####################" |
| 80 | + docker-compose -p .. -f ../docker-compose.yml build |
| 81 | + |
| 82 | + # Remove temporary images |
| 83 | + docker rmi $(docker images -qf "dangling=true") |
| 84 | +fi |
| 85 | + |
| 86 | +if [[ $push_images ]]; then |
| 87 | + echo "#################### Pushing images to registry ####################" |
| 88 | + services=(basket.api catalog.api identity.api ordering.api marketing.api payment.api locations.api webmvc webspa webstatus) |
| 89 | + |
| 90 | + for service in "${services[@]}" |
| 91 | + do |
| 92 | + echo "Pushing image for service $service..." |
| 93 | + docker tag "eshop/$service:$image_tag" "$container_registry/$service:$image_tag" |
| 94 | + docker push "$container_registry/$service:$image_tag" |
| 95 | + done |
| 96 | +fi |
| 97 | + |
| 98 | +echo "#################### Cleaning up old deployment ####################" |
| 99 | +kubectl delete deployments --all |
| 100 | +kubectl delete services --all |
| 101 | +kubectl delete configmap config-files || true |
| 102 | +kubectl delete configmap urls || true |
| 103 | +kubectl delete configmap externalcfg || true |
| 104 | + |
| 105 | +echo "#################### Deploying infrastructure components ####################" |
| 106 | +kubectl create configmap config-files --from-file=nginx-conf=nginx.conf |
| 107 | +kubectl label configmap config-files app=eshop |
| 108 | +kubectl create -f sql-data.yaml -f basket-data.yaml -f keystore-data.yaml -f rabbitmq.yaml -f nosql-data.yaml |
| 109 | + |
| 110 | +echo "#################### Creating application service definitions ####################" |
| 111 | +kubectl create -f services.yaml -f frontend.yaml |
| 112 | + |
| 113 | +echo "#################### Waiting for Azure to provision external IP ####################" |
| 114 | + |
| 115 | +ip_regex='([0-9]{1,3}\.){3}[0-9]{1,3}' |
| 116 | +while true; do |
| 117 | + printf "." |
| 118 | + frontendUrl=$(kubectl get svc frontend -o=jsonpath="{.status.loadBalancer.ingress[0].ip}") |
| 119 | + if [[ $frontendUrl =~ $ip_regex ]]; then |
| 120 | + break |
| 121 | + fi |
| 122 | + sleep 5s |
| 123 | +done |
| 124 | + |
| 125 | +printf "\n" |
| 126 | +externalDns=$frontendUrl |
| 127 | +echo "Using $externalDns as the external DNS/IP of the K8s cluster" |
| 128 | + |
| 129 | +echo "#################### Creating application configuration ####################" |
| 130 | + |
| 131 | +# urls configmap |
| 132 | +kubectl create configmap urls \ |
| 133 | + "--from-literal=BasketUrl=http://basket" \ |
| 134 | + "--from-literal=BasketHealthCheckUrl=http://basket/hc" \ |
| 135 | + "--from-literal=CatalogUrl=http://$externalDns/catalog-api" \ |
| 136 | + "--from-literal=CatalogHealthCheckUrl=http://catalog/hc" \ |
| 137 | + "--from-literal=PicBaseUrl=http://$externalDns/catalog-api/api/v1/catalog/items/[0]/pic/" \ |
| 138 | + "--from-literal=Marketing_PicBaseUrl=http://$externalDns/marketing-api/api/v1/campaigns/[0]/pic/" \ |
| 139 | + "--from-literal=IdentityUrl=http://$externalDns/identity" \ |
| 140 | + "--from-literal=IdentityHealthCheckUrl=http://identity/hc" \ |
| 141 | + "--from-literal=OrderingUrl=http://ordering" \ |
| 142 | + "--from-literal=OrderingHealthCheckUrl=http://ordering/hc" \ |
| 143 | + "--from-literal=MvcClientExternalUrl=http://$externalDns/webmvc" \ |
| 144 | + "--from-literal=WebMvcHealthCheckUrl=http://webmvc/hc" \ |
| 145 | + "--from-literal=MvcClientOrderingUrl=http://ordering" \ |
| 146 | + "--from-literal=MvcClientCatalogUrl=http://catalog" \ |
| 147 | + "--from-literal=MvcClientBasketUrl=http://basket" \ |
| 148 | + "--from-literal=MvcClientMarketingUrl=http://marketing" \ |
| 149 | + "--from-literal=MvcClientLocationsUrl=http://locations" \ |
| 150 | + "--from-literal=MarketingHealthCheckUrl=http://marketing/hc" \ |
| 151 | + "--from-literal=WebSpaHealthCheckUrl=http://webspa/hc" \ |
| 152 | + "--from-literal=SpaClientMarketingExternalUrl=http://$externalDns/marketing-api" \ |
| 153 | + "--from-literal=SpaClientOrderingExternalUrl=http://$externalDns/ordering-api" \ |
| 154 | + "--from-literal=SpaClientCatalogExternalUrl=http://$externalDns/catalog-api" \ |
| 155 | + "--from-literal=SpaClientBasketExternalUrl=http://$externalDns/basket-api" \ |
| 156 | + "--from-literal=SpaClientIdentityExternalUrl=http://$externalDns/identity" \ |
| 157 | + "--from-literal=SpaClientLocationsUrl=http://$externalDns/locations-api" \ |
| 158 | + "--from-literal=LocationsHealthCheckUrl=http://locations/hc" \ |
| 159 | + "--from-literal=SpaClientExternalUrl=http://$externalDns" \ |
| 160 | + "--from-literal=LocationApiClient=http://$externalDns/locations-api" \ |
| 161 | + "--from-literal=MarketingApiClient=http://$externalDns/marketing-api" \ |
| 162 | + "--from-literal=BasketApiClient=http://$externalDns/basket-api" \ |
| 163 | + "--from-literal=OrderingApiClient=http://$externalDns/ordering-api" \ |
| 164 | + "--from-literal=PaymentHealthCheckUrl=http://payment/hc" |
| 165 | + |
| 166 | +kubectl label configmap urls app=eshop |
| 167 | + |
| 168 | +# externalcfg configmap -- points to local infrastructure components (rabbitmq, SQL Server etc) |
| 169 | +kubectl create -f conf_local.yml |
| 170 | + |
| 171 | +# Create application pod deployments |
| 172 | +kubectl create -f deployments.yaml |
| 173 | + |
| 174 | +echo "#################### Deploying application pods ####################" |
| 175 | + |
| 176 | +# update deployments with the correct image (with tag and/or registry) |
| 177 | +kubectl set image deployments/basket "basket=$container_registry/basket.api:$image_tag" |
| 178 | +kubectl set image deployments/catalog "catalog=$container_registry/catalog.api:$image_tag" |
| 179 | +kubectl set image deployments/identity "identity=$container_registry/identity.api:$image_tag" |
| 180 | +kubectl set image deployments/ordering "ordering=$container_registry/ordering.api:$image_tag" |
| 181 | +kubectl set image deployments/marketing "marketing=$container_registry/marketing.api:$image_tag" |
| 182 | +kubectl set image deployments/locations "locations=$container_registry/locations.api:$image_tag" |
| 183 | +kubectl set image deployments/payment "payment=$container_registry/payment.api:$image_tag" |
| 184 | +kubectl set image deployments/webmvc "webmvc=$container_registry/webmvc:$image_tag" |
| 185 | +kubectl set image deployments/webstatus "webstatus=$container_registry/webstatus:$image_tag" |
| 186 | +kubectl set image deployments/webspa "webspa=$container_registry/webspa:$image_tag" |
| 187 | + |
| 188 | +kubectl rollout resume deployments/basket |
| 189 | +kubectl rollout resume deployments/catalog |
| 190 | +kubectl rollout resume deployments/identity |
| 191 | +kubectl rollout resume deployments/ordering |
| 192 | +kubectl rollout resume deployments/marketing |
| 193 | +kubectl rollout resume deployments/locations |
| 194 | +kubectl rollout resume deployments/payment |
| 195 | +kubectl rollout resume deployments/webmvc |
| 196 | +kubectl rollout resume deployments/webstatus |
| 197 | +kubectl rollout resume deployments/webspa |
| 198 | + |
| 199 | +echo "WebSPA is exposed at http://$externalDns, WebMVC at http://$externalDns/webmvc, WebStatus at http://$externalDns/webstatus" |
| 200 | +echo "eShopOnContainers deployment is DONE" |
0 commit comments