Documentation ¶
Overview ¶
The PodMutator is a controller-runtime webhook that intercepts Pod Creation events and mutates them. Currently, there is only one registered Mutator, that's the SecretsMutator. It works as follows:
- The Webhook only works on Pods. If propeller/plugins launch a resource outside of K8s (or in a separate k8s cluster), it's the responsibility of the plugin to correctly pass secret injection information.
- When a k8s-plugin builds a resource, propeller's PluginManager will automatically inject a label `inject-flyte -secrets: true` and serialize the secret injection information into the annotations.
- If a plugin does not use the K8sPlugin interface, it's its responsibility to pass secret injection information.
- If a k8s plugin creates a CRD that launches other Pods (e.g. Spark/PyTorch... etc.), it's its responsibility to make sure the labels/annotations set on the CRD by PluginManager are propagated to those launched Pods. This ensures secret injection happens no matter how many levels of indirections there are.
- The Webhook expects 'inject-flyte-secrets: true' as a label on the Pod. Otherwise it won't listen/observe that pod.
- Once it intercepts the admission request, it goes over all registered Mutators and invoke them in the order they are registered as. If a Mutator fails and it's marked as `required`, the operation will fail and the admission will be rejected.
- The SecretsMutator will attempt to lookup the requested secret from the process environment. If the secret is already mounted, it'll inject it as plain-text into the Pod Spec (Less secure).
- If it's not found in the environment it'll, instead, fallback to the enabled Secrets Injector (K8s, Confidant, Vault... etc.).
- Each SecretsInjector will mutate the Pod differently depending on how its backend secrets system injects the secrets for example:
- For K8s secrets, it'll either add EnvFromSecret or VolumeMountSource (depending on the MountRequirement stated in the flyteIdl.Secret object) into the Pod. There is no validation that the secret exist and is available to the Pod at this point. If the secret is not accessible, the Pod will fail with ContainerCreationConfigError and will be retried.
- For Vault secrets, it'll inject the right annotations to trigger Vault's own sidecar/webhook to mount the secret.
Index ¶
- Constants
- Variables
- func CreateEnvVarForSecret(secret *core.Secret) corev1.EnvVar
- func CreateVolumeForSecret(secret *core.Secret) corev1.Volume
- func CreateVolumeMountForSecret(volumeName string, secret *core.Secret) corev1.VolumeMount
- func UpdateEnvVars(containers []corev1.Container, envVar corev1.EnvVar) []corev1.Container
- func UpdateVolumeMounts(containers []corev1.Container, mount corev1.VolumeMount) []corev1.Container
- type Config
- type GlobalSecretProvider
- type GlobalSecrets
- type K8sSecretInjector
- type Mutator
- type MutatorConfig
- type PodMutator
- func (pm PodMutator) CreateMutationWebhookConfiguration(namespace string) (*admissionregistrationv1.MutatingWebhookConfiguration, error)
- func (pm PodMutator) GetMutatePath() string
- func (pm *PodMutator) Handle(ctx context.Context, request admission.Request) admission.Response
- func (pm *PodMutator) InjectClient(_ client.Client) error
- func (pm *PodMutator) InjectDecoder(d *admission.Decoder) error
- func (pm PodMutator) Mutate(ctx context.Context, p *corev1.Pod) (newP *corev1.Pod, changed bool, err error)
- func (pm *PodMutator) Register(ctx context.Context, mgr manager.Manager) error
- type SecretsInjector
- type SecretsMutator
Constants ¶
const ( K8sPathDefaultDirEnvVar = "FLYTE_SECRETS_DEFAULT_DIR" K8sPathFilePrefixEnvVar = "FLYTE_SECRETS_FILE_PREFIX" K8sEnvVarPrefix = "FLYTE_SECRETS_ENV_PREFIX" K8sDefaultEnvVarPrefix = "_FSEC_" EnvVarGroupKeySeparator = "_" )
Variables ¶
var (
K8sSecretPathPrefix = []string{string(os.PathSeparator), "etc", "flyte", "secrets"}
)
Functions ¶
func CreateVolumeMountForSecret ¶
func CreateVolumeMountForSecret(volumeName string, secret *core.Secret) corev1.VolumeMount
func UpdateEnvVars ¶
func UpdateVolumeMounts ¶
Types ¶
type Config ¶
type Config struct { MetricsPrefix string `json:"metrics-prefix" pflag:",An optional prefix for all published metrics."` CertDir string `json:"certDir" pflag:",Certificate directory to use to write generated certs. Defaults to /etc/webhook/certs/"` ListenPort int `json:"listenPort" pflag:",The port to use to listen to webhook calls. Defaults to 9443"` ServiceName string `json:"serviceName" pflag:",The name of the webhook service."` SecretName string `json:"secretName" pflag:",Secret name to write generated certs to."` }
type GlobalSecretProvider ¶
type GlobalSecrets ¶
type GlobalSecrets struct {
// contains filtered or unexported fields
}
GlobalSecrets allows the injection of secrets from the process memory space (env vars) or mounted files into pods intercepted through this admission webhook. Secrets injected through this type will be mounted as environment variables. If a secret has a mounting requirement that does not allow Env Vars, it'll fail to inject the secret.
func NewGlobalSecrets ¶
func NewGlobalSecrets(provider GlobalSecretProvider) GlobalSecrets
func (GlobalSecrets) ID ¶
func (g GlobalSecrets) ID() string
type K8sSecretInjector ¶
type K8sSecretInjector struct { }
K8sSecretInjector allows injecting of secrets into pods by specifying either EnvVarSource or SecretVolumeSource in the Pod Spec. It'll, by default, mount secrets as files into pods. The current version does not allow mounting an entire secret object (with all keys inside it). It only supports mounting a single key from the referenced secret object. The secret.Group will be used to reference the k8s secret object, the Secret.Key will be used to reference a key inside and the secret.Version will be ignored. Environment variables will be named _FSEC_<SecretGroup>_<SecretKey>. Files will be mounted on /etc/flyte/secrets/<SecretGroup>/<SecretKey>
func NewK8sSecretsInjector ¶
func NewK8sSecretsInjector() K8sSecretInjector
func (K8sSecretInjector) ID ¶
func (i K8sSecretInjector) ID() string
type MutatorConfig ¶
type PodMutator ¶
type PodMutator struct { Mutators []MutatorConfig // contains filtered or unexported fields }
PodMutator implements controller-runtime WebHook interface.
func NewPodMutator ¶
func NewPodMutator(cfg *Config, scope promutils.Scope) *PodMutator
func (PodMutator) CreateMutationWebhookConfiguration ¶
func (pm PodMutator) CreateMutationWebhookConfiguration(namespace string) (*admissionregistrationv1.MutatingWebhookConfiguration, error)
func (PodMutator) GetMutatePath ¶
func (pm PodMutator) GetMutatePath() string
func (*PodMutator) InjectClient ¶
func (pm *PodMutator) InjectClient(_ client.Client) error
func (*PodMutator) InjectDecoder ¶
func (pm *PodMutator) InjectDecoder(d *admission.Decoder) error
InjectDecoder injects the decoder into a mutatingHandler.
type SecretsInjector ¶
type SecretsMutator ¶
type SecretsMutator struct {
// contains filtered or unexported fields
}
func NewSecretsMutator ¶
func NewSecretsMutator(_ promutils.Scope) *SecretsMutator
func (SecretsMutator) ID ¶
func (s SecretsMutator) ID() string