Issue 1:
Is this a request for help? (If yes, you should use our troubleshooting guide and community support channels, see http://kubernetes.io/docs/troubleshooting/.): no.

What keywords did you search in Kubernetes issues before filing this one? (If you have found any duplicates, you should instead reply there.): EnvVar, optional, defaults, configmap

Is this a BUG REPORT or FEATURE REQUEST? (choose one): FEATURE REQUEST

Kubernetes version (use kubectl version):

Client Version: version.Info{Major:"1", Minor:"4", GitVersion:"v1.4.4", GitCommit:"3b417cc4ccd1b8f38ff9ec96bb50a81ca0ea9d56", GitTreeState:"clean", BuildDate:"2016-10-21T02:48:38Z", GoVersion:"go1.6.3", Compiler:"gc", Platform:"linux/amd64"}

Server Version: version.Info{Major:"1", Minor:"6+", GitVersion:"v1.6.0-alpha.0", GitCommit:"42fe4ab0270e44c750d77c682e2fcab394aeb392", GitTreeState:"clean", BuildDate:"2016-11-06T01:00:40Z", GoVersion:"go1.7.1", Compiler:"gc", Platform:"linux/amd64"}

Environment:

Cloud provider or hardware configuration: none

OS (e.g. from /etc/os-release): CentOS 7

Kernel (e.g. uname -a):

Install tools:

Others:

What happened:

At the moment, all references described in EvnVars in Pod spec are mandatory.

In different cluster instances (private, public) it might require different content or even variable can be omitted, depending on ConfigMap content for this cluster.

If key is not present in ConfigMap, right now creation of the pod will fail.

What you expected to happen:

I'd like to extend syntax of EnvVar/valueFrom to allow omitting variable if specified key not found in config map. or have some default value (e.g. "null" in yaml can be treated as "don't put this variable to container). Same in theory applicable to Secretes use cases.

Use case:

cluster might have config map which describes proxy variables: http_proxy, https_proxy, no_proxy, etc.

pod can reference it via

env:
- name: http_proxy
valueFrom:
configMapKeyRef:
name: cluster-proxy-config
key: http_proxy
optional: true
- name: https_proxy
valueFrom:
configMapKeyRef:
name: cluster-proxy-config
key: https_proxy
optional: true
- name: ftp_proxy
valueFrom:
configMapKeyRef:
name: cluster-proxy-config
key: ftp_proxy
optional: true
- name: no_proxy
valueFrom:
configMapKeyRef:
name: cluster-proxy-config
key: no_proxy
optional: true

How to reproduce it (as minimally and precisely as possible):

kubectl -f test-case.yaml

test-case.yaml:

apiVersion: v1
data:
proxy.http: http://example.com:8080
proxy.https: http://example.com:8080
proxy.no_proxy: .example.com,127.0.0.1
kind: ConfigMap
metadata:
name: proxy-config
namespace: default
---
apiVersion: v1
kind: Pod
metadata:
name: envpod
spec:
containers:
- name: envcontainer
image: gcr.io/google_containers/busybox
command: [ "/bin/sh", "-c", "env" ]
env:
- name: http_proxy
valueFrom:
configMapKeyRef:
name: proxy-config
key: proxy.http
- name: https_proxy
valueFrom:
configMapKeyRef:
name: proxy-config
key: proxy.http
- name: ftp_proxy
valueFrom:
configMapKeyRef:
name: proxy-config
key: proxy.ftp
- name: no_proxy
valueFrom:
configMapKeyRef:
name: proxy-config
key: proxy.no_proxy
restartPolicy: Never

Check that pod creation failed:

kubectl describe pod envpod | grep Failed

Anything else do we need to know:

Issue 2:
E1109 11:31:44.493904 3385 util.go:82] Recovered from panic: "sync: negative WaitGroup counter" (sync: negative WaitGroup counter)
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/util/util.go:76
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/util/util.go:64
/usr/lib/golang/src/runtime/asm_amd64.s:437
/usr/lib/golang/src/runtime/panic.go:423
/usr/lib/golang/src/sync/waitgroup.go:70
/usr/lib/golang/src/sync/waitgroup.go:95
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/controller/framework/controller_test.go:368
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/controller/framework/controller.go:182
<autogenerated>:23
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/controller/framework/controller.go:252
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/controller/framework/controller.go:126
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/controller/framework/controller.go:96
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/util/util.go:126
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/util/util.go:127
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/controller/framework/controller.go:96
/usr/lib/golang/src/runtime/asm_amd64.s:1696
--- FAIL: TestUpdate (1.00s)
panic: sync: WaitGroup is reused before previous Wait has returned [recovered]
panic: sync: WaitGroup is reused before previous Wait has returned

goroutine 7 [running]:
testing.tRunner.func1(0xc8201ae990)
/usr/lib/golang/src/testing/testing.go:450 +0x171
sync.(*WaitGroup).Wait(0xc820230b80)
/usr/lib/golang/src/sync/waitgroup.go:128 +0x114
k8s.io/kubernetes/pkg/controller/framework_test.TestUpdate(0xc8201ae990)
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/controller/framework/controller_test.go:393 +0xb11
testing.tRunner(0xc8201ae990, 0x1887d90)
/usr/lib/golang/src/testing/testing.go:456 +0x98
created by testing.RunTests
/usr/lib/golang/src/testing/testing.go:561 +0x86d

goroutine 1 [chan receive]:
testing.RunTests(0x12fc4c8, 0x1887d60, 0x3, 0x3, 0xc820230a01)
/usr/lib/golang/src/testing/testing.go:562 +0x8ad
testing.(*M).Run(0xc8200d3ee8, 0xc82006f938)
/usr/lib/golang/src/testing/testing.go:494 +0x70
main.main()
k8s.io/kubernetes/pkg/controller/framework/_test/_testmain.go:64 +0x116

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
/usr/lib/golang/src/runtime/asm_amd64.s:1696 +0x1

goroutine 5 [chan receive]:
github.com/golang/glog.(*loggingT).flushDaemon(0x18a6080)
/home/vagrant/go/src/k8s.io/kubernetes/Godeps/_workspace/src/github.com/golang/glog/glog.go:879 +0x67
created by github.com/golang/glog.init.1
/home/vagrant/go/src/k8s.io/kubernetes/Godeps/_workspace/src/github.com/golang/glog/glog.go:410 +0x297

goroutine 8 [chan receive]:
k8s.io/kubernetes/pkg/watch.(*Broadcaster).loop(0xc8201a4800)
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/watch/mux.go:198 +0x58
created by k8s.io/kubernetes/pkg/watch.NewBroadcaster
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/watch/mux.go:74 +0x128

goroutine 9 [select]:
k8s.io/kubernetes/pkg/util.Until(0xc8200cff68, 0x3b9aca00, 0xc8202401e0)
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/util/util.go:128 +0x125
k8s.io/kubernetes/pkg/controller/framework.(*Controller).Run(0xc82023cee0, 0xc8202401e0)
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/controller/framework/controller.go:96 +0x1c2
created by k8s.io/kubernetes/pkg/controller/framework_test.TestUpdate
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/controller/framework/controller_test.go:377 +0x869

goroutine 55 [runnable]:
k8s.io/kubernetes/pkg/client/cache.(*Reflector).watchHandler(0xc8201aeab0, 0x7fa38f8852e8, 0xc820277cb0, 0xc82004dc88, 0xc820241ec0, 0xc8202401e0, 0x0, 0x0)
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/client/cache/reflector.go:312 +0x13df
k8s.io/kubernetes/pkg/client/cache.(*Reflector).ListAndWatch(0xc8201aeab0, 0xc8202401e0, 0x0, 0x0)
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/client/cache/reflector.go:279 +0x1215
k8s.io/kubernetes/pkg/client/cache.(*Reflector).RunUntil.func1()
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/client/cache/reflector.go:164 +0x29
k8s.io/kubernetes/pkg/util.Until.func1(0xc820216ea0)
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/util/util.go:126 +0x4b
k8s.io/kubernetes/pkg/util.Until(0xc820216ea0, 0x3b9aca00, 0xc8202401e0)
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/util/util.go:127 +0x68
created by k8s.io/kubernetes/pkg/client/cache.(*Reflector).RunUntil
/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go/src/k8s.io/kubernetes/pkg/client/cache/reflector.go:164 +0x9a

I got this by running the following against commit d65c61f:

export GOPATH=/home/vagrant/go/src/k8s.io/kubernetes/_output/local/go:/home/vagrant/go/src/k8s.io/kubernetes/Godeps/_workspace
go test -c k8s.io/kubernetes/pkg/controller/framework
while true; do GOMAXPROCS=4 ./framework.test -test.run TestUpdate; if [ $? != 0 ]; then break; fi; done

There have been previous attempts to fix this:

#13058

#14881

It appears it's still an issue 😢

We're also seeing it in OpenShift (openshift/origin#5389), although our code hasn't pulled in the fix from #14881 quite yet.