-
Notifications
You must be signed in to change notification settings - Fork 359
Fun with Deployments and Zero Downtime (ZDT)
-
To deploy ZDT:
upload_capi_release && ~/workspace/capi-release/scripts/deploy -o ~/workspace/capi-ci/cf-deployment-operations/temporary/add-deployment-updater.yml
If you ssh to the scheduler vm,
sudo su
thenmonit summary
you should see:Process 'cc_deployment_updater' running
-
That process was invoked from
/var/vcap/jobs/cc_deployment_updater/bin/cc_deployment_updater
by runningrake deployment_updater:start
and this starts a loop that sleeps forcc.deployment_updater.update_frequency_in_seconds
(default 5) and then runs one orchestration step on all active deployments (e.g. ones in stateDEPLOYING
).
-
First,
cf v3-push dora && cf v3-scale dora -i 4
an app -
Stage a new package. (These commands come from How to Create an App Using V3 of the CC API):
perl -pi -e 's/(Hi.*Dora.*\#)(\d+)/$1 . (int($2) + 1)/e' dora.rb CF_API_ENDPOINT=$(cf api | grep -i "api endpoint" | awk '{print $3}') APP_GUID=$(cf v3-app dora --guid 2>/dev/null) PACKAGE_GUID=$(cf curl /v3/packages -X POST -d "$(printf '{"type":"bits", "relationships": {"app": {"data": {"guid": "%s"}}}}' "$APP_GUID")" | tee /dev/tty | jq -r .guid) zip -r my-app-v2.zip * # ( -x *.zip if there are old zip files hanging around) curl -k "$CF_API_ENDPOINT/v3/packages/$PACKAGE_GUID/upload" -F bits=@"my-app-v2.zip" -H "Authorization: $(cf oauth-token | grep bearer)" # Wait for the package to go from PROCESSING_UPLOAD to READY while : ; do state=$(cf curl /v3/packages/$PACKAGE_GUID | tee /dev/tty | jq -r .state) ; if [ "$state" == "READY" ] ; then break; fi; sleep 5 ; done rm my-app-v2.zip # clean up after yaself BUILD_GUID=$(cf curl /v3/builds -X POST -d "$(printf '{ "package": { "guid": "%s" }}' "$PACKAGE_GUID")" | tee /dev/tty | jq -r .guid) # Wait for staging to complete while : ; do state=$(cf curl /v3/builds/$BUILD_GUID | tee /dev/tty | jq -r .state); if [ "$state" != "STAGING" ] ; then break; fi; sleep 2 ; done
-
Get the new package's droplet and associate it with the app:
At some point the build should be
STAGED
. If it'sFAILED
or still staging after an unreasonable amount of time, you have a problem more severe than trying to ZDT-update an app. Otherwise, stopwatch
and continue:DROPLET_GUID=$(cf curl /v3/builds/$BUILD_GUID | jq -r '.droplet.guid') cf curl /v3/apps/$APP_GUID/relationships/current_droplet -X PATCH -d "$(printf '{"data": {"guid": "%s"}}' "$DROPLET_GUID")"
-
Finally, create a deployment for the app with the new droplet:
cf curl /v3/deployments -d "$(printf '{ "relationships":{ "app": { "data": { "guid": "%s" }}}}' $APP_GUID)"
-
Repeatedly hit the app and verify that the output contains an ever-increasing proportion of the new output until the old output completely disappears and the webish process instances increase and then drop away so you're back to N
web
instances.for x in {1..10000} ; do curl "dora.${CF_API_ENDPOINT#*.}"; sleep 0.5; done
-
Add a
sleep 60
to the updater with log statements -
Tail logs in one window
-
When prompted, run commands like
`cf curl /v2/apps/[APP_GUID]
perl -pi -e 's/(Hi.*Dora.*\#)(\d+)/$1 . (int($2) + 1)/e' dora.rb
CF_API_ENDPOINT=$(cf api | grep -i "api endpoint" | awk '{print $3}')
APP_GUID=$(cf app dora --guid 2>/dev/null)
PACKAGE_GUID=$(cf curl /v3/packages -X POST -d "$(printf '{"type":"bits", "relationships": {"app": {"data": {"guid": "%s"}}}}' "$APP_GUID")" | tee /dev/tty | jq -r .guid)
zip -r my-app-v2.zip * # ( -x *.zip if there are old zip files hanging around)
curl -k "$CF_API_ENDPOINT/v3/packages/$PACKAGE_GUID/upload" -F bits=@"my-app-v2.zip" -H "Authorization: $(cf oauth-token | grep bearer)"
# Wait for the package to go from PROCESSING_UPLOAD to READY
while : ; do state=$(cf curl /v3/packages/$PACKAGE_GUID | tee /dev/tty | jq -r .state) ; if [ "$state" == "READY" ] ; then break; fi; sleep 5 ; done
rm my-app-v2.zip # clean up after yaself
BUILD_GUID=$(cf curl /v3/builds -X POST -d "$(printf '{ "package": { "guid": "%s" }}' "$PACKAGE_GUID")" | tee /dev/tty | jq -r .guid)
# Wait for staging to complete
while : ; do state=$(cf curl /v3/builds/$BUILD_GUID | tee /dev/tty | jq -r .state); if [ "$state" != "STAGING" ] ; then break; fi; sleep 2 ; done
DROPLET_GUID=$(cf curl /v3/builds/$BUILD_GUID | jq -r '.droplet.guid')
cf curl /v3/apps/$APP_GUID/relationships/current_droplet -X PATCH -d "$(printf '{"data": {"guid": "%s"}}' "$DROPLET_GUID")"
cf curl /v3/deployments -d "$(printf '{ "relationships":{ "app": { "data": { "guid": "%s" }}}}' $APP_GUID)"
for x in {1..10000} ; do curl "dora.${CF_API_ENDPOINT#*.}"; sleep 0.5; done
-
Pipelines
-
Contributing
- Tips and Tricks
- Cloud Controller API v3 Style Guide
- Playbooks
- Development configuration
- Testing
-
Architectural Details
-
CC Resources
- Apps
- Audit Events
- Deployments
- Labels
- Services
- Sidecars
-
Dependencies
-
Troubleshooting
- Ruby Console Script to Find Fields that Cannot Be Decrypted
- Logging database queries in unit tests
- Inspecting blobstore cc resources and cc packages(webdav)
- How to Use USR1 Trap for Diagnostics
- How to Perf: Finding and Fixing Bottlenecks
- How to get access to mysql database
- How To Get a Ruby Heap Dumps & GC Stats from CC
- How to curl v4 internal endpoints with mtls
- How to access Bosh Director console and restore an outdated Cloud Config
- Analyzing Cloud Controller's NGINX logs using the toplogs script
-
k8s
-
Archive