You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
9.2 KiB

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