Skip to content

feat: kubernetes image pull secrets #2400

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions metaflow/metaflow_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,8 @@
)
# Image pull policy for container images
KUBERNETES_IMAGE_PULL_POLICY = from_conf("KUBERNETES_IMAGE_PULL_POLICY", None)
# Image pull secrets for container images
KUBERNETES_IMAGE_PULL_SECRETS = from_conf("KUBERNETES_IMAGE_PULL_SECRETS", "")
# Default container registry for K8S
KUBERNETES_CONTAINER_REGISTRY = from_conf(
"KUBERNETES_CONTAINER_REGISTRY", DEFAULT_CONTAINER_REGISTRY
Expand Down
7 changes: 7 additions & 0 deletions metaflow/plugins/argo/argo_workflows.py
Original file line number Diff line number Diff line change
Expand Up @@ -2007,6 +2007,7 @@ def _container_templates(self):
namespace=resources["namespace"],
image=resources["image"],
image_pull_policy=resources["image_pull_policy"],
image_pull_secrets=resources["image_pull_secrets"],
service_account=resources["service_account"],
secrets=(
[
Expand Down Expand Up @@ -2193,6 +2194,8 @@ def _container_templates(self):
.node_selectors(resources.get("node_selector"))
# Set tolerations
.tolerations(resources.get("tolerations"))
# Set image pull secrets
.image_pull_secrets(resources.get("image_pull_secrets"))
# Set container
.container(
# TODO: Unify the logic with kubernetes.py
Expand Down Expand Up @@ -3744,6 +3747,10 @@ def tolerations(self, tolerations):
self.payload["tolerations"] = tolerations
return self

def image_pull_secrets(self, image_pull_secrets):
self.payload["image_pull_secrets"] = image_pull_secrets
return self

def to_json(self):
return self.payload

Expand Down
4 changes: 4 additions & 0 deletions metaflow/plugins/kubernetes/kubernetes.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ def create_jobset(
code_package_ds,
docker_image,
docker_image_pull_policy,
image_pull_secrets=None,
step_cli=None,
service_account=None,
secrets=None,
Expand Down Expand Up @@ -206,6 +207,7 @@ def create_jobset(
node_selector=node_selector,
image=docker_image,
image_pull_policy=docker_image_pull_policy,
image_pull_secrets=image_pull_secrets,
cpu=cpu,
memory=memory,
disk=disk,
Expand Down Expand Up @@ -467,6 +469,7 @@ def create_job_object(
step_cli,
docker_image,
docker_image_pull_policy,
image_pull_secrets=None,
service_account=None,
secrets=None,
node_selector=None,
Expand Down Expand Up @@ -513,6 +516,7 @@ def create_job_object(
),
image=docker_image,
image_pull_policy=docker_image_pull_policy,
image_pull_secrets=image_pull_secrets,
cpu=cpu,
memory=memory,
disk=disk,
Expand Down
8 changes: 8 additions & 0 deletions metaflow/plugins/kubernetes/kubernetes_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ def kubernetes():
default=None,
help="Optional Docker Image Pull Policy for Kubernetes pod.",
)
@click.option(
"--image-pull-secrets",
default=None,
type=JSONTypeClass(),
multiple=False,
)
@click.option(
"--service-account",
help="IRSA requirement for Kubernetes pod.",
Expand Down Expand Up @@ -160,6 +166,7 @@ def step(
executable=None,
image=None,
image_pull_policy=None,
image_pull_secrets=None,
service_account=None,
secrets=None,
node_selector=None,
Expand Down Expand Up @@ -303,6 +310,7 @@ def _sync_metadata():
step_cli=step_cli,
docker_image=image,
docker_image_pull_policy=image_pull_policy,
image_pull_secrets=image_pull_secrets,
service_account=service_account,
secrets=secrets,
node_selector=node_selector,
Expand Down
11 changes: 11 additions & 0 deletions metaflow/plugins/kubernetes/kubernetes_decorator.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
KUBERNETES_FETCH_EC2_METADATA,
KUBERNETES_GPU_VENDOR,
KUBERNETES_IMAGE_PULL_POLICY,
KUBERNETES_IMAGE_PULL_SECRETS,
KUBERNETES_MEMORY,
KUBERNETES_LABELS,
KUBERNETES_ANNOTATIONS,
Expand Down Expand Up @@ -72,6 +73,10 @@ class KubernetesDecorator(StepDecorator):
not, a default Docker image mapping to the current version of Python is used.
image_pull_policy: str, default KUBERNETES_IMAGE_PULL_POLICY
If given, the imagePullPolicy to be applied to the Docker image of the step.
image_pull_secrets: List[str], default []
The default is extracted from METAFLOW_KUBERNETES_IMAGE_PULL_SECRETS.
Kubernetes image pull secrets to use when pulling container images
in Kubernetes.
service_account : str, default METAFLOW_KUBERNETES_SERVICE_ACCOUNT
Kubernetes service account to use when launching pod in Kubernetes.
secrets : List[str], optional, default None
Expand Down Expand Up @@ -139,6 +144,7 @@ class KubernetesDecorator(StepDecorator):
"disk": "10240",
"image": None,
"image_pull_policy": None,
"image_pull_secrets": None, # e.g., ["regcred"]
"service_account": None,
"secrets": None, # e.g., mysecret
"node_selector": None, # e.g., kubernetes.io/os=linux
Expand Down Expand Up @@ -192,6 +198,10 @@ def init(self):
)
if not self.attributes["image_pull_policy"] and KUBERNETES_IMAGE_PULL_POLICY:
self.attributes["image_pull_policy"] = KUBERNETES_IMAGE_PULL_POLICY
if not self.attributes["image_pull_secrets"] and KUBERNETES_IMAGE_PULL_SECRETS:
self.attributes["image_pull_secrets"] = json.loads(
KUBERNETES_IMAGE_PULL_SECRETS
)

if isinstance(self.attributes["node_selector"], str):
self.attributes["node_selector"] = parse_kube_keyvalue_list(
Expand Down Expand Up @@ -479,6 +489,7 @@ def runtime_step_cli(
for key, val in v.items()
]
elif k in [
"image_pull_secrets",
"tolerations",
"persistent_volume_claims",
"labels",
Expand Down
6 changes: 4 additions & 2 deletions metaflow/plugins/kubernetes/kubernetes_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,10 @@ def create_job_spec(self):
)
],
node_selector=self._kwargs.get("node_selector"),
# TODO (savin): Support image_pull_secrets
# image_pull_secrets=?,
image_pull_secrets=[
client.V1LocalObjectReference(secret)
for secret in self._kwargs.get("image_pull_secrets") or []
],
# TODO (savin): Support preemption policies
# preemption_policy=?,
#
Expand Down
7 changes: 5 additions & 2 deletions metaflow/plugins/kubernetes/kubernetes_jobsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -718,8 +718,11 @@ def dump(self):
)
],
node_selector=self._kwargs.get("node_selector"),
# TODO (savin): Support image_pull_secrets
# image_pull_secrets=?,
image_pull_secrets=[
client.V1LocalObjectReference(secret)
for secret in self._kwargs.get("image_pull_secrets")
or []
],
# TODO (savin): Support preemption policies
# preemption_policy=?,
#
Expand Down