Skip to content
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

Dynamic k8s namespace for generating kubernetes yaml #5994

Open
sansmoraxz opened this issue Jul 30, 2023 · 23 comments
Open

Dynamic k8s namespace for generating kubernetes yaml #5994

sansmoraxz opened this issue Jul 30, 2023 · 23 comments
Assignees

Comments

@sansmoraxz
Copy link

Describe the feature
The current implementation for to_kubernetes_yaml flow takes k8s_namespace to be explicitly specified somewhere otherwise it outputs as default namespace. The namespace need not be explicitly set and can be dynamically injected through metadata, hence improving the reusability of the generated templates.

For example:

kubectl apply -f "file.yaml" --namespace=prod
kubectl apply -f "file.yaml" --namespace=dev

Your proposal

We may accept that the Optional field can be None and propagate that when generating the yaml, in which case the generated yaml will include this for env injection:

        - name: K8S_NAMESPACE_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace

And of course we may remove the injection of namespace for all the generated objects in this case.

More info from official docs

@JoanFM
Copy link
Member

JoanFM commented Jul 30, 2023

Hey @sansmoraxz,

This looks like a great feature. Since I see thwat you have digged in the code a bit, would you be up to implement it?

@sansmoraxz
Copy link
Author

Sure

@JoanFM
Copy link
Member

JoanFM commented Jul 30, 2023

Please get in touch if you need any help, we will be welcoming your PR.

@sansmoraxz
Copy link
Author

For deployment address (viz. injected to gateway) I see that services are being referred to by their full DNS name. Is it ok to open a sh shell, to invoke the jina cli? That way we can refer to the injected env K8S_NAMESPACE_NAME to refer to the executors.

Alternatively we can use with just the service name rather than the full DNS name of the service.

@JoanFM
Copy link
Member

JoanFM commented Aug 7, 2023

The namespace argument is propagated in the call to the to_kubernetes_yaml to every Deplpyment in the Flow, including the gateway one.

I am not sure I fully understand the question though

@sansmoraxz
Copy link
Author

sansmoraxz commented Aug 7, 2023

I meant assume gateway has the following generated command invoked:

containers:
      - args:
        - gateway
        - --k8s-namespace
        - default
        - --expose-endpoints
        - '{}'
        - --host
        - '1'
        - --uses
        - GRPCGateway
        - --graph-description
        - '{"executor0": ["executor1"], "start-gateway": ["executor0"], "executor1":
          ["end-gateway"]}'
        - --deployments-addresses
        - '{"executor0": ["grpc://executor0.default.svc:8080"], "executor1": ["grpc://executor1.default.svc:8080"]}'
        - --port
        - '8080'
        - --port-monitoring
        - '9090'
        command:
        - jina

The deployment addresses are not really dynamic

@sansmoraxz
Copy link
Author

sansmoraxz commented Aug 7, 2023

We can probably try to use something like this:

command:
        - /bin/bash
        - -c
        - jina
        - gateway
        - --k8s-namespace
        - $K8S_NAMESPACE_NAME

We invoke the bash first because directly passing it to the args doesn't seem to expand to the env value.

Same with the deployments-addresses. Although passing it the full service name is not really required.

This works just as well

'{"executor0": ["grpc://executor0:8080"], "executor1": ["grpc://executor1:8080"]}'

@deepankarm
Copy link
Member

Although passing it the full service name is not really required. This works just as well

@sansmoraxz you're right. The complete FQDN is not required in deployment addresses, as both gateway & the executors are in the same namespace. We rely on service meshes (like Linkerd) that recommend using FQDNs rather than shorter names to avoid ambiguity during routing, hence we follow the best practices.

@JoanFM
Copy link
Member

JoanFM commented Aug 7, 2023

I see the problem of passing the namespace by env var to the entrypoint. Perhaps passing with ENV var syntax may work but I am not sure.

Otherwise I will take a look after holiday, thanks for your deep investigation.

@sansmoraxz
Copy link
Author

Alternatively the jina cli can be told to look for specific environment variable names (and files) and we don't need to override the command explicitly.

@sansmoraxz
Copy link
Author

sansmoraxz commented Aug 19, 2023

For instance, look for the presence of /var/run/secrets/kubernetes.io or .dockerenv, to detect appropriate environments at startup. Since those are fixed name environment variable they can be directly passed to be loaded. This will also make the generated manifests a lot cleaner.

@JoanFM
Copy link
Member

JoanFM commented Aug 20, 2023

I will try to look at it in more detail this incoming week and discuss some proposals about it

@JoanFM
Copy link
Member

JoanFM commented Aug 23, 2023

Hey @sansmoraxz .

I will take a look at this soon.

Thanks for the patience

@JoanFM
Copy link
Member

JoanFM commented Aug 23, 2023

Hey @sansmoraxz,

What do u think about this solution:

  • We allow the k8s-namespace to be Optional with default as default value.
  • If we see a None, we do as u say, we inject the NAMESPACE as u suggest
  • We pass --k8s-namespace $K8S_NAMESPACE in the args (I think this should work without needing to explicitly invoke /bin/bash in the entrypoint.
  • If we see k8s-namespace as None, we rmove the namespace from the executor addresses.

I believe this should enable this feature, what do you say?

Actually, I think this is exactly what you have been meaning all this time right? Here I just summarized all in the same message?

@sansmoraxz
Copy link
Author

My concern was that args didn't resolve for env.

Testing this small code on kubernetes 1.27:

apiVersion: v1
kind: Pod
metadata:
  name: command-demo
  labels:
    purpose: demonstrate-command
spec:
  containers:
  - name: command-demo-container
    image: alpine
    command: ["echo"]
    args: ["$ENV"]
    env:
    - name: ENV
      value: "Hello World!"
  restartPolicy: OnFailure

The output is $ENV

@JoanFM
Copy link
Member

JoanFM commented Aug 23, 2023

My concern was that args didn't resolve for env.

Testing this small code on kubernetes 1.27:

apiVersion: v1
kind: Pod
metadata:
  name: command-demo
  labels:
    purpose: demonstrate-command
spec:
  containers:
  - name: command-demo-container
    image: alpine
    command: ["echo"]
    args: ["$ENV"]
    env:
    - name: ENV
      value: "Hello World!"
  restartPolicy: OnFailure

The output is $ENV

Looking at this issue:

kubernetes/kubernetes#57726

It seems that using downards API as u suggest should work however

@sansmoraxz
Copy link
Author

OK so wrapping in $() does the trick. Interesting! this does tend to generally imply nested shell execution.

@JoanFM
Copy link
Member

JoanFM commented Aug 23, 2023

OK so wrapping in $() does the trick. Interesting! this does tend to generally imply nested shell execution.

I am not sure honestly

@JoanFM
Copy link
Member

JoanFM commented Aug 23, 2023

So then, we are good with this proposal?

@sansmoraxz
Copy link
Author

Yes. One thing I was considering was using jinja to dynamically make the resources. We can offload the code templating to it, which in turn would make the code a lot cleaner. This may go under a future proposal. Too many changes to be made.

@JoanFM
Copy link
Member

JoanFM commented Aug 23, 2023

this can be another improvement, I agree, but I would not mix the actual feature with the nice refactoring

@jina-bot
Copy link
Member

@jina-ai/product This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 14 days

@jina-bot jina-bot added the Stale label Nov 22, 2023
@JoanFM JoanFM removed the Stale label Nov 22, 2023
@jina-bot
Copy link
Member

@jina-ai/product This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 14 days

@jina-bot jina-bot added the Stale label Feb 21, 2024
@JoanFM JoanFM removed the Stale label Feb 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants