Thomas Goirand: Seamlessly upgrading a production OpenStack cluster in 4 hours : with 2k lines shell script
tl;dr: To the question: what does it take to upgrade OpenStack , my personal answer is: less than 2K lines of dash script. I ll here describe its internals, and why I believe it is the correct solution. Why writing this blog post During FOSSDEM 2024, I was asked how to you handle upgrades . I answered with a big smile and a short with a very small shell script as I couldn t explain in 2 minutes how it was done. Just saying it is great this way doesn t help giving readers enough hints to be trusted. Why and how did I do it the right way ? This blog post is an attempt to reply better to this question more deeply. Upgrading OpenStack in production I wrote this script maybe a 2 or 3 years ago. Though I m only blogging about it today, because I did such an upgrade in a public cloud in production last Thuesday evening (ie: the first region of the Infomaniak public cloud). I d say the cluster is moderately large (as of today: about 8K+ VMs running, 83 compute nodes, 12 network nodes, for a total of 10880 physical CPU cores and 125 TB of RAM if I only count the compute servers). It took only 4 hours to do the upgrade (though I already wore some more code to speed this up for the next time ). It went super smooth without a glitch. I mostly just sat, reading the script output and went to bed once it finished running. The next day, all my colleagues at Infomaniak were nicely congratulating me that it went that smooth (a big thanks to all of you who did). I couldn t dream of an upgrade that smooth! :) Still not impressed? Boring read? Yeah let s dive into more technical details. Intention behind the implementation My script isn t perfect. I wont ever pretend it is. But at least, it does minimize down time of every OpenStack service. It also is a by the book implementation of what s written in the OpenStack doc, following every upstream advice. As a result, it is fully seamless for some OpenStack services, and as HA as OpenStack can be for others. The upgrade process is of course idempotent and can be re-run in case of failure. Here s why. General idea My upgrade script does thing in a certain order, respecting what is documented about upgrades in the OpenStack documentation. It basically does:
- Upgrade all dependency
- Upgrade all services one by one, in all the cluster
- disable puppet on all nodes of the cluster
- switch the APT repository
- apt-get update on all nodes
- install library dependency on all nodes
$ hapc list-backends
$ hapc drain-server --backend glancebe --server cl1-controller-1.infomaniak.ch --verbose --wait --timeout 50
$ apt-get install glance-api
$ hapc enable-server --backend glancebe --server cl1-controller-1.infomaniak.ch
Upgrading the control plane
My upgrade script leverages hapc just like above. For each OpenStack project, it s done in this order on the first node holding the VIP:
- hapc drain-server of the API, so haproxy gracefully stops querying it
- stop all services on that node (including non-API services): stop, disable and mask with systemd.
- upgrade that service Python code. For example: apt-get install python3-nova , which also will pull nova-api, nova-conductor, nova-novncprox, etc. but services wont start automatically as they ve been stoped + disabled + masked on the previous bullet point.
- perform the db_sync so that the db is up-to-date [1]
- start all services (unmask, enable and start with systemd)
- re-enable the API backend with hapc enable-server
- hapc drain-server of the API of the other 2 controllers
- stop of all services on these 2 controllers [2]
- upgrade of the package
- start of all services