Q:

Initcontainer vs Helm Hook post-install

What is a difference between Helm Hooks post-install and Kubernetes initcontainers? What I am understood is that Hooks are used to define some actions during different stages of Pod lifecycle, in that case - post-install, and initcontainers, on the other hand, allow to initialize the container before it is deployed to Pod.
post-install and initcontainer as I understand allow to do the same thing, i.e. initialize a database.
Is that correct? Which is the better approach?

A:

For database setup I would prefer a Helm hook, but even then there are some subtleties.
Say your service is running as a Deployment with replicas: 3 for a little bit of redundancy.  Every one of these replicas will run an init container, if it's specified in the pod spec, without any sort of synchronization.  If one of the pods crashes, or its node fails, its replacement will run the init container again.  For the sort of setup task you're talking about, you don't want to repeat it that often.
The fundamental difference here is that a Helm hook is a separate Kubernetes object, typically a Job.  You can arrange for this Job to be run exactly once on each helm upgrade and at no other times, which makes it a reasonable place to run things like migrations.
The one important subtlety here is that you can have multiple versions of a service running at once.  Take the preceding Deployment with replicas: 3, but then helm upgrade --set tag=something-newer.  The Deployment controller will first start a new pod with the new image, and only once it's up and running will it tear down an old pod, and now you have both versions going together.  Similar things will happen if you helm rollback to an older version.  This means you need some tolerance for the database not quite having the right schema.
If the job is more like a "seed" job that preloads some initial data, this is easier to manage: do it in a post-install hook, which you expect to run only once ever.  You don't need to repeat it on every upgrade (as a post-upgrade hook) or on every pod start (as an init container).

