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

Using a service variable to create another environment variable #1331

Closed
dchen1107 opened this issue Sep 16, 2014 · 20 comments
Closed

Using a service variable to create another environment variable #1331

dchen1107 opened this issue Sep 16, 2014 · 20 comments
Labels
area/downward-api kind/design Categorizes issue or PR as related to design.

Comments

@dchen1107
Copy link
Member

The issue reported by Carlos Sanchez to google-containers@: "

Is it possible to use a service variable to create another environment variable?

For example I have a "jenkins" service running and JENKINS_SERVICE_PORT is available in the container, but the container expects a JENKINS_MASTER env var, that could easily be created as http://localhost:$JENKINS_SERVICE_PORT.
I could just extend the image with a startup script to do that, but I'd like to avoid creating extra images.

I've tried some things inside 'env' and 'command' in the ReplicationController but with no luck.

  "desiredState": {
    "manifest": {
      "version": "v1beta1",
      "id": "jenkins-slave",
      "containers": [
        {
          "name": "jenkins-slave",
          "image": "csanchez/test",
          "command": "/bin/bash /run.sh",
          "env": [
            {
              "name": "JENKINS_MASTER",
              "value": "http://localhost:$JENKINS_SERVICE_PORT"
            }
          ]
        }
      ],

"

@dchen1107 dchen1107 added the kind/design Categorizes issue or PR as related to design. label Sep 16, 2014
@carlossg
Copy link

It would be nice if the environment variables could be interpolated to inject kubernetes variables into the definition

@robszumski
Copy link
Contributor

+1, I was attempting to do this the other day as well.

@thockin
Copy link
Member

thockin commented Sep 16, 2014

The downside, of course, is that we need to escape-encode things that want
a literal $ in them, which is potentially very surprising.

On Tue, Sep 16, 2014 at 10:10 AM, Rob Szumski notifications@github.com
wrote:

+1, I was attempting to do this the other day as well.

Reply to this email directly or view it on GitHub
#1331 (comment)
.

@smarterclayton
Copy link
Contributor

This is exactly what pod -> service portal bindings should solve - pod adapts Kube concept (services) to image (env var form) rather than force images to adapt Kube / Docker / Foo conventions. Also applies to downward facing API in #386

@thockin
Copy link
Member

thockin commented Sep 17, 2014

There's the case of "I want to take some piece of information known by the
system (apiserver, kubelet, whatever) and put it into an env var" (what
Clayton says) and simply "I want an env var with the same value as this
other env var". The latter is clearly simpler, though I agree the former
is something we want.

Maybe we want a config block that is "interpretted env vars".

"interpEnv": [
{ "name": "ALIAS_VAR", "value": { "kind": "envVar", "name":
"ORIGINAL_VAR" } },
{ "name": "MY_ID", "value": { "kind": "podMetadata", "what": "uid" } },
]

On Tue, Sep 16, 2014 at 9:42 PM, Clayton Coleman notifications@github.com
wrote:

This is exactly what pod -> service portal bindings should solve - pod
adapts Kube concept (services) to image (env var form) rather than force
images to adapt Kube / Docker / Foo conventions. Also applies to downward
facing API in #386
#386

Reply to this email directly or view it on GitHub
#1331 (comment)
.

@bketelsen
Copy link
Contributor

Is there any workaround for this presently? the docker image I'm running expects to receive external host/port information as a command line flag : --host=myhost.com --port=mytcp port
I have this external application running as service, but can't pass in the service host/port info. Seems my only option is to make my own docker container for this and use environment variables to set the information.

@thockin
Copy link
Member

thockin commented Sep 19, 2014

Maybe I don't understand.

The image expects you to run it with CMD=["something", "--host="].

You have a service running, so you have SERVICE_HOST
and MYHOSTNAME_SERVICE_PORT defined.

Why can't you do command = ["sh", "-c", "something --host=$SERVICE_HOST
--port=$MYHOSTNAME_SERVICE_PORT"]

?

On Thu, Sep 18, 2014 at 10:50 AM, Brian Ketelsen notifications@github.com
wrote:

Is there any workaround for this presently? the docker image I'm running
expects to receive external host/port information as a command line flag :
--host=myhost.com --port=mytcp port
I have this external application running as service, but can't pass in the
service host/port info. Seems my only option is to make my own docker
container for this and use environment variables to set the information.

Reply to this email directly or view it on GitHub
#1331 (comment)
.

@bketelsen
Copy link
Contributor

That's exactly the workaround i was looking for! 👍

@platinummonkey
Copy link

I agree this seems like it should be a very basic feature. Docker allows environment variables to be set at runtime that certain applications would depend on (or use default values).

I'm not sure the original provided example makes sense as http://$JENKINS_SERVICE_HOST:$JENKINS_SERVICE_PORT would likely solve that issue.

Perhaps this example might be more clear and demonstrates environment variables specific to the application and utilizing kubernetes aware environment variable substitution:

Say I have an application that depends on some external application not running within the kubernetes domain.

{
    "id": "myAppController",
    "kind": "ReplicationController",
    "apiversion": "v1beta1",
    "desiredState": {
        "replicas": 1,
        "replicaSelector": {
            "name": "myapp",
            "tier": "app",
        },
        "podTemplate": {
            "desiredState": {
                "manifest": {
                    "version": "v1beta1",
                    "id": "myAppController",
                    "containers": [{
                        "name": "myapp",
                        "image": "mycompany/myapp"
                    }],
                   "env": {
                         "EXTERNAL_SERVICE_HOST": "example.com",
                        "EXTERNAL_SERVICE_PORT": 1234,
                        "EXTERNAL_SERVICE_SPECIAL_SETTING": "abcd",
                       "EXTERNAL_SERVICE_FORWARD_TO": "$MYOTHERAPP_SERVICE_HOST:$MYOTHERAPP_SERVICE_PORT"
                   }
                }
            },
            "labels": {
                "name": "myapp",
                "tier": "app",
            }
        }
    },
    "labels": {
        "name": "myapp",
        "tier": "app",
    }
}

@carlossg
Copy link

I'm not sure the original provided example makes sense as http://$JENKINS_SERVICE_HOST:$JENKINS_SERVICE_PORT would likely solve that issue.

Nope, you can't set that in the "env" entry, variables are not expanded.

The issue is about reusing existing images that make use of environment variables, without needing to create kubernetes specific images, which is the workaround I had to do.

@platinummonkey
Copy link

Yeah sorry, I meant doing the expansion within the container context for that specific one you are talking about.

@thockin
Copy link
Member

thockin commented Sep 19, 2014

Cody, I understand the use case to define env vars in terms of other env
vars, but there is a workaround - bounce through a shell.

instead of running command = [ "foo" ], run command = [ "sh", "-c",
"CUSTOM=$OTHER foo" ]

It's not pretty, but it works.

Someone should file an issue on this, though - I don't think there is one,
which puts it at risk of being lost.

On Fri, Sep 19, 2014 at 6:08 AM, Cody Lee notifications@github.com wrote:

I agree this seems like it should be a very basic feature. Docker allows
environment variables to be set at runtime that certain applications would
depend on (or use default values).

I'm not sure the original provided example makes sense as http://
$JENKINS_SERVICE_HOST:$JENKINS_SERVICE_PORT would likely solve that issue.

Perhaps this example might be more clear and demonstrates environment
variables specific to the application and utilizing kubernetes aware
environment variable substitution:

Say I have an application that depends on some external application not
running within the kubernetes domain.

{
"id": "myAppController",
"kind": "ReplicationController",
"apiversion": "v1beta1",
"desiredState": {
"replicas": 1,
"replicaSelector": {
"name": "myapp",
"tier": "app",
},
"podTemplate": {
"desiredState": {
"manifest": {
"version": "v1beta1",
"id": "myAppController",
"containers": [{
"name": "myapp",
"image": "mycompany/myapp"
}],
"env": {
"EXTERNAL_SERVICE_HOST": "example.com",
"EXTERNAL_SERVICE_PORT": 1234,
"EXTERNAL_SERVICE_SPECIAL_SETTING": "abcd",
"EXTERNAL_SERVICE_FORWARD_TO": "$MYOTHERAPP_SERVICE_HOST:$MYOTHERAPP_SERVICE_PORT"
}
}
},
"labels": {
"name": "myapp",
"tier": "app",
}
}
},
"labels": {
"name": "myapp",
"tier": "app",
}
}

Reply to this email directly or view it on GitHub
#1331 (comment)
.

@platinummonkey
Copy link

Issue created: #1382

@bgrant0607
Copy link
Member

DNS would make this unnecessary (#1261, #146). Until then, the workaround works, and is documented in the user FAQ.

The broader issue is being discussed in #386.

@zioproto
Copy link
Member

Looks like it works now ! It is documented here http://jeffmendoza.github.io/kubernetes/v1.1/docs/design/expansion.html

I was able to pass the following env to a container:

        env:
        - name: REDIS_URL
          value: "redis://$(REDIS_MASTER_SERVICE_HOST):6379/1"

It is important to use the syntax with rounded parenthesis ()

@bgrant0607
Copy link
Member

Needs to be better documented. I'll file a website issue.

https://github.com/kubernetes/community/blob/master/contributors/design-proposals/node/expansion.md

@glerchundi
Copy link

This is fantastic, I would like to note that this isn't working when the environment comes from the envFrom statement no matter if it is a ConfigMap or Secret key.

@thockin
Copy link
Member

thockin commented Sep 26, 2018 via email

@glerchundi
Copy link

glerchundi commented Sep 26, 2018 via email

@udev
Copy link

udev commented Sep 24, 2019

@zioproto Finding the answer to a pressing question buried deep within an issue on github is disheartening to say the least but thank you nonetheless.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/downward-api kind/design Categorizes issue or PR as related to design.
Projects
None yet
Development

No branches or pull requests