Open ca-scribner opened 10 months ago
Thank you for reporting us your feedback!
The internal ticket has been created: https://warthogs.atlassian.net/browse/KF-5166.
This message was autogenerated
@kimwnasptd suggested doing something similar to observability does here with resource limits. iiuc, in that case each charm that wanted an istio sidecar would modify its own Juju-created StatefulSet to add the istio sidecar annotation, which would trigger a redeploy of the underlying charm(/workload) pod.
Some outstanding questions on this are:
StatefulSet
's pod annotations? I think yes, base on thisedit: by annotations, I think we mean labels
What about other possible solutions? Maybe:
istio-injection=enabled
on a namespace (eg: namespace/kubeflow
) means all new pods in that namespace will have an istio sidecar injected
do-not-inject
label on the model operator, if that was configurable - or at least an "allow all" policy on the model operator so it isn't blocked from doing its job)?istioctl
has a command that will modify a pod to include the sidecar, similar to how the webhook would. Can we just do this as pebble containers? The actual istio sidecar is probably doable, but istio also injects an init-container afaik which probably cannot be done with juju+pebble?Tried out option (1) (the "charm adds the istio label to its own statefulset" solution) using this charm:
On config-changed
, the charm has 3 handlers:
_echo_before_event
: echos to say its handling config-changed_add_istio_injection_label_to_statefulset
: patches its own statefulset's podspec labels and waits a little after this is done_echo_after_event
: echos to say its handling config-changedDeploying it (juju deploy ./*.charm
) to a cluster that has istio installed sees the following:
_echo_before_event
fires and completes_add_istio_injection_label_to_statefulset
fires, patches this charm's own statefulset to add the istio label, and waitsSo this does appear to work
Is there a race condition with the above solution? Since doing juju deploy bundle.yaml
results in charms deploying all at once in no guaranteed order, doing something like juju deploy kubeflow
likely results in some charms deploying before the istio mutatingwebhooks are live. So will the above injection test charm add a label to its statefulset, restart the pod so the pod has the istio label, and still not receive an istio sidecar because nothing is watching for the label yet?
A hacky solution could be that the istio-label code above also checks to see if the new pod has an istio sidecar, but that feels ugly. And even if we spot the sidecar is missing, what do we do? At best we can defer and hope some other event triggers us again soon
Yes, after testing this the race condition does exist - if the label-injection occurs before istio has created its webhooks, the charm pods will be restarted but with the istio label but will not receive the istio sidecar
Testing out option (4) (manual sidecar injection):
Taking this StatefulSet
modified a little from the istio docs:
and running that through istioctl kube-inject -f sleep.yaml
, we get:
where the differences are essentially:
"discoveryAddress":"istiod.kubeflow.svc:15012"
, which is dependent on where istio is deployed)So to manually inject the sidecar as proposed, we'd need to replicate all of the above differences inside the charm. Addressing each separately:
Overall, this might be doable, but it does sound complicated. And this has a similar race condition as solution (1). If we haven't deployed istio yet, how do we get the configurations for the istio sidecar? Maybe they're deterministic and we can specify them statically, but then do we bake all that configuration into the code? If we do know the configurations, we'd still have to test what happens when a sidecar starts but the istiod it depends on is not available - does it gracefully handle this until istio is alive?
Looking at option (3) (use namespace-level injections by labelling the namespace with istio-injection=enabled
)...
Implementation of this option is much easier for most charms. By annotating the kubeflow namespace for istio injection, we no longer need to change any of the charms themselves.
We do, however, face a similar race condition to option (1). If we do:
juju add-model kubeflow
kubectl label namespace kubeflow istio-injection=enabled --overwrite
juju deploy kubeflow
the kubeflow namespace will have the correct istio labels, but until the istio-pilot charm has deployed istio's webhooks the pods created will not get istio sidecars. So if you have the charms deploy in this order, you might see:
So we still have the issue where we need istio deployed before everything else.
Another issue with this solution is that we could accidentally give juju's model operator an istio sidecar. iiuc this by itself shouldn't hurt the model operator alone, but if we also had a deny-all
default policy in the Kubeflow namespace then we might accidentally block the traffic. We'd need to address this too
Given the race conditions affecting (1) and (3), I wonder if it would make sense to unbundle istio from the rest of Kubeflow. This is a large change, but would have benefits.
Maybe we have:
ingress
relations that we currently get from istio pilotThen the kubeflow bundle would include istio-integrator
rather than istio
itself, and deployment would be like:
juju add-model istio-system
juju deploy istio # (the daemon)
# wait
juju add-model kubeflow
juju deploy kubeflow # (includes istio-integrator)
Notes from an internal meeting here
Summary is that we have some design decisions left to make - will report back here when we decide them
This is also affected by whether we are using the istio CNI plugin or not. For example, looking at the output for istioctl kube-inject ...
, it includes the istio-init
container that sets up the networking. So manual injection must be different depending on whether you're using the istio CNI plugin
Context
To support improved network isolation of Charmed Kubeflow components, investigate how we can attach an istio sidecar to charm pods.
What needs to get done
-
Definition of Done