Merge pull request #6739 from pmorie/downward-api
Env var sources / downward API
This commit is contained in:
@@ -36,6 +36,7 @@ import (
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/cache"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/client/record"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/cloudprovider"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/fieldpath"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/fields"
|
||||
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/cadvisor"
|
||||
kubecontainer "github.com/GoogleCloudPlatform/kubernetes/pkg/kubelet/container"
|
||||
@@ -702,7 +703,7 @@ func (kl *Kubelet) GenerateRunContainerOptions(pod *api.Pod, container *api.Cont
|
||||
return nil, fmt.Errorf("impossible: cannot find the mounted volumes for pod %q", kubecontainer.GetPodFullName(pod))
|
||||
}
|
||||
opts.Binds = makeBinds(container, vol)
|
||||
opts.Envs, err = kl.makeEnvironmentVariables(pod.Namespace, container)
|
||||
opts.Envs, err = kl.makeEnvironmentVariables(pod, container)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -780,7 +781,7 @@ func (kl *Kubelet) getServiceEnvVarMap(ns string) (map[string]string, error) {
|
||||
}
|
||||
|
||||
// Make the service environment variables for a pod in the given namespace.
|
||||
func (kl *Kubelet) makeEnvironmentVariables(ns string, container *api.Container) ([]string, error) {
|
||||
func (kl *Kubelet) makeEnvironmentVariables(pod *api.Pod, container *api.Container) ([]string, error) {
|
||||
var result []string
|
||||
// Note: These are added to the docker.Config, but are not included in the checksum computed
|
||||
// by dockertools.BuildDockerName(...). That way, we can still determine whether an
|
||||
@@ -791,7 +792,7 @@ func (kl *Kubelet) makeEnvironmentVariables(ns string, container *api.Container)
|
||||
// To avoid this users can: (1) wait between starting a service and starting; or (2) detect
|
||||
// missing service env var and exit and be restarted; or (3) use DNS instead of env vars
|
||||
// and keep trying to resolve the DNS name of the service (recommended).
|
||||
serviceEnv, err := kl.getServiceEnvVarMap(ns)
|
||||
serviceEnv, err := kl.getServiceEnvVarMap(pod.Namespace)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
@@ -803,7 +804,13 @@ func (kl *Kubelet) makeEnvironmentVariables(ns string, container *api.Container)
|
||||
// env vars.
|
||||
// TODO: remove this net line once all platforms use apiserver+Pods.
|
||||
delete(serviceEnv, value.Name)
|
||||
result = append(result, fmt.Sprintf("%s=%s", value.Name, value.Value))
|
||||
|
||||
runtimeValue, err := kl.runtimeEnvVarValue(value, pod)
|
||||
if err != nil {
|
||||
return result, err
|
||||
}
|
||||
|
||||
result = append(result, fmt.Sprintf("%s=%s", value.Name, runtimeValue))
|
||||
}
|
||||
|
||||
// Append remaining service env vars.
|
||||
@@ -813,6 +820,33 @@ func (kl *Kubelet) makeEnvironmentVariables(ns string, container *api.Container)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// runtimeEnvVarValue determines the value that an env var should take when a container
|
||||
// is started. If the value of the env var is the empty string, the source of the env var
|
||||
// is resolved, if one is specified.
|
||||
//
|
||||
// TODO: preliminary factoring; make better
|
||||
func (kl *Kubelet) runtimeEnvVarValue(envVar api.EnvVar, pod *api.Pod) (string, error) {
|
||||
runtimeVal := envVar.Value
|
||||
if runtimeVal != "" {
|
||||
return runtimeVal, nil
|
||||
}
|
||||
|
||||
if envVar.ValueFrom != nil && envVar.ValueFrom.FieldPath != nil {
|
||||
return kl.podFieldSelectorRuntimeValue(envVar.ValueFrom.FieldPath, pod)
|
||||
}
|
||||
|
||||
return runtimeVal, nil
|
||||
}
|
||||
|
||||
func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *api.ObjectFieldSelector, pod *api.Pod) (string, error) {
|
||||
internalFieldPath, _, err := api.Scheme.ConvertFieldLabel(fs.APIVersion, "Pod", fs.FieldPath, "")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return fieldpath.ExtractFieldPathAsString(pod, internalFieldPath)
|
||||
}
|
||||
|
||||
// getClusterDNS returns a list of the DNS servers and a list of the DNS search
|
||||
// domains of the cluster.
|
||||
func (kl *Kubelet) getClusterDNS(pod *api.Pod) ([]string, []string, error) {
|
||||
|
@@ -68,6 +68,8 @@ type TestKubelet struct {
|
||||
fakeMirrorClient *fakeMirrorClient
|
||||
}
|
||||
|
||||
const testKubeletHostname = "testnode"
|
||||
|
||||
func newTestKubelet(t *testing.T) *TestKubelet {
|
||||
fakeDocker := &dockertools.FakeDockerClient{Errors: make(map[string]error), RemovedImages: util.StringSet{}}
|
||||
fakeRecorder := &record.FakeRecorder{}
|
||||
@@ -2378,6 +2380,39 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
||||
"KUBERNETES_RO_PORT_8087_TCP_ADDR=1.2.3.7"),
|
||||
21,
|
||||
},
|
||||
{
|
||||
"downward api pod",
|
||||
"downward-api",
|
||||
&api.Container{
|
||||
Env: []api.EnvVar{
|
||||
{
|
||||
Name: "POD_NAME",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
FieldPath: &api.ObjectFieldSelector{
|
||||
APIVersion: "v1beta3",
|
||||
FieldPath: "metadata.name",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "POD_NAMESPACE",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
FieldPath: &api.ObjectFieldSelector{
|
||||
APIVersion: "v1beta3",
|
||||
FieldPath: "metadata.namespace",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"nothing",
|
||||
true,
|
||||
util.NewStringSet(
|
||||
"POD_NAME=dapi-test-pod-name",
|
||||
"POD_NAMESPACE=downward-api",
|
||||
),
|
||||
2,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
@@ -2390,7 +2425,14 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
||||
kl.serviceLister = testServiceLister{services}
|
||||
}
|
||||
|
||||
result, err := kl.makeEnvironmentVariables(tc.ns, tc.container)
|
||||
testPod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Namespace: tc.ns,
|
||||
Name: "dapi-test-pod-name",
|
||||
},
|
||||
}
|
||||
|
||||
result, err := kl.makeEnvironmentVariables(testPod, tc.container)
|
||||
if err != nil {
|
||||
t.Errorf("[%v] Unexpected error: %v", tc.name, err)
|
||||
}
|
||||
|
Reference in New Issue
Block a user