Good news about zombies: Kubernetes will soon solve this by having the pause container (which is automatically included in every pod) automatically reap children. [1]
Note that this change depends on the shared PID namespace support, which a larger, still-ongoing endeavour [2].
The zombie reaping problem is fixed in Docker. You can simply use `docker run --init` with no argument, and it will spawn a tiny init that will reap children processes correctly. We don't enable the flag by default to respect backwards compatibility.
In this context it means preserving the default behavior of running the command specified in the image as PID 1, and not injecting any extra processes in the namespace. The difference in the runtime environment is subtle, but some applications rely on it. If we changed this default those applications would behave differently after upgrading to Docker 1.13 or later.
This is an excellent check-list of both kubernetes and docker gotchas to avoid.
Coming into the k8s ecosystem with very little container experience has been a steep learning curve, and simple, concrete suggestions like this go a LONG way to leveling it out.
We've also published some other workshops for Docker and Kubernetes that we take customers through when onboarding (if needed): https://github.com/gravitational/workshop
Feel free to take them for a spin and feedback welcome and appreciated.
I would like to have seen more "patterns" regarding configuration.
Right now, we have a bunch of microservices. Most of them talk to our shared infrastructure. We started with single configuration file, which has grown to monstrous proportions, and is mounted on every pod as a config map.
What would be the correct approach? Multiple configmaps with redundant information are just as bad, if not worse.
Start by using done service discovery. That way service names stay the same but service implementations and locations can move.
Then ship the static list of names (should be short) and per-service credentials (highly highly recommended).
Another pattern is co-locating a proxy with your app. See e.g. linkerd on how to do that. This will also unify the handling of circuit breakers and connection pools across services - even without any shared code!
Have you tried out istio yet? It's the packaging of Lyft's Envoy that Google and IBM are putting together to handle your last two points, circuit breaking and rate limiting and much more.
Word of caution: Istio isn't production ready yet, still a lot of missing stuff and bugs. Definitely worth playing with though, once it's ready I think it's going to make managing microservices much easier.
Some background on these workshops: we (Gravitational) help SaaS companies package their applications into Kubernetes, this makes them deployable into on-premise environments [1]. This in itself is an unexpected and quite awesome benefit of adopting Kubernetes in your organization: your stack becomes one-click portable.
You mean like rent a pod or like a random SaaS app that uses k8s? I know of many of the latter but none of the former. Maybe some cloud logger guys have sidecar deployments you can use.
Depends on the tool in question. jq or awk are such common-place and light on dependencies that it's indeed unnecessarily complex.
The benefit is when a one-time tool is heavy on dependencies. For example, with OpenStack Swift (an S3-like object storage), a common one-time task is swift-ring-builder, which takes an inventory of available storage and creates a shared configuration file which describes how data is shared between storages. That's something you would run on a sysadmin's notebook, but it's included with Swift itself, so you would have to install a bunch of Python modules into a virtualenv.
In that case, it's probably easier to just use the Docker image for Swift that you have anyway, and run swift-ring-builder from there.
Thanks for the response. I agree that long-running or very heavily-polled services make the most sense for being containerised and that builtins usually don't.
we use kubernetes, helm and gitlab.. runtime configuration lives in each repo next to code - values.yaml, dev.yaml, test.yaml, prod.yaml to store applications runtime configuration -- each environment is host to 40+ redundant services.. its working quite well but has required a pretty big upfront investment... surprised there was much discussion about monitoring- prometheus and grafana work well for that
No. If the node the pod is scheduled to goes away, the pod will not be restarted. 'restartPolicy: Always' applies to the containers in the pod, not the pod itself. Deployments (Or daemonsets, jobs, replicasets or replication controllers) actively maintain the pods, to assure in the event that the pods are deleted they're replaced.
Other posters have already commented on this but, if you are not using deployments (or at least, replication controllers), stop what you are doing right away and fix that. Otherwise you lose one of the biggest advantages of k8s.
Deployments are key. One annoyance is now some of the lower units feel more clunky. Is there roadmap to say let you do a stateful set as a Deployment? Obviously a bit tricky and rolling deploy could never surge...
WRT to StatefulSets I assume you are talking about the fact they are immutable (minus a few fields)?
If so, the hack we've applied for StatefulSets is to delete the StatefulSet with `--cascade=false`. This keeps the Pods of the StatefulSet online, but removes the StatefulSet itself. We can then deploy the StatefulSet with the new configuration vlaues, and manually delete the Pods one-by-one to have the changes be applied.
Graceful: Nope.
Needs Improvement: For sure
Gets the job done: Yep!
Note that this change depends on the shared PID namespace support, which a larger, still-ongoing endeavour [2].
[1] https://github.com/kubernetes/kubernetes/commit/81d27aa23969...
[2] https://github.com/kubernetes/kubernetes/issues/1615