mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 20:53:33 +00:00
Add spec.nodeName and spec.serviceAccountName to downward env var
The serviceAccountName is occasionally useful for clients running on Kube that need to know who they are when talking to other components. The nodeName is useful for PetSet or DaemonSet pods that need to make calls back to the API to fetch info about their node. Both fields are immutable, and cannot easily be retrieved in another way.
This commit is contained in:
parent
0abda6bd74
commit
e1ebde9f92
@ -878,7 +878,8 @@ type EnvVar struct {
|
||||
// EnvVarSource represents a source for the value of an EnvVar.
|
||||
// Only one of its fields may be set.
|
||||
type EnvVarSource struct {
|
||||
// Selects a field of the pod; only name and namespace are supported.
|
||||
// Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations,
|
||||
// spec.nodeName, spec.serviceAccountName, status.podIP.
|
||||
FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty"`
|
||||
// Selects a resource of the container: only resources limits and requests
|
||||
// (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.
|
||||
|
@ -192,14 +192,15 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
|
||||
err = scheme.AddFieldLabelConversionFunc("v1", "Pod",
|
||||
func(label, value string) (string, string, error) {
|
||||
switch label {
|
||||
case "metadata.name",
|
||||
"metadata.namespace",
|
||||
case "metadata.annotations",
|
||||
"metadata.labels",
|
||||
"metadata.annotations",
|
||||
"status.phase",
|
||||
"status.podIP",
|
||||
"metadata.name",
|
||||
"metadata.namespace",
|
||||
"spec.nodeName",
|
||||
"spec.restartPolicy":
|
||||
"spec.restartPolicy",
|
||||
"spec.serviceAccountName",
|
||||
"status.phase",
|
||||
"status.podIP":
|
||||
return label, value, nil
|
||||
// This is for backwards compatibility with old v1 clients which send spec.host
|
||||
case "spec.host":
|
||||
|
@ -990,7 +990,8 @@ type EnvVar struct {
|
||||
|
||||
// EnvVarSource represents a source for the value of an EnvVar.
|
||||
type EnvVarSource struct {
|
||||
// Selects a field of the pod; only name and namespace are supported.
|
||||
// Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations,
|
||||
// spec.nodeName, spec.serviceAccountName, status.podIP.
|
||||
FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty" protobuf:"bytes,1,opt,name=fieldRef"`
|
||||
// Selects a resource of the container: only resources limits and requests
|
||||
// (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.
|
||||
|
@ -424,7 +424,7 @@ func (EnvVar) SwaggerDoc() map[string]string {
|
||||
|
||||
var map_EnvVarSource = map[string]string{
|
||||
"": "EnvVarSource represents a source for the value of an EnvVar.",
|
||||
"fieldRef": "Selects a field of the pod; only name and namespace are supported.",
|
||||
"fieldRef": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.podIP.",
|
||||
"resourceFieldRef": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, requests.cpu and requests.memory) are currently supported.",
|
||||
"configMapKeyRef": "Selects a key of a ConfigMap.",
|
||||
"secretKeyRef": "Selects a key of a secret in the pod's namespace",
|
||||
|
@ -1208,7 +1208,7 @@ func validateEnv(vars []api.EnvVar, fldPath *field.Path) field.ErrorList {
|
||||
return allErrs
|
||||
}
|
||||
|
||||
var validFieldPathExpressionsEnv = sets.NewString("metadata.name", "metadata.namespace", "status.podIP")
|
||||
var validFieldPathExpressionsEnv = sets.NewString("metadata.name", "metadata.namespace", "spec.nodeName", "spec.serviceAccountName", "status.podIP")
|
||||
var validContainerResourceFieldPathExpressions = sets.NewString("limits.cpu", "limits.memory", "requests.cpu", "requests.memory")
|
||||
|
||||
func validateEnvVarValueFrom(ev api.EnvVar, fldPath *field.Path) field.ErrorList {
|
||||
|
@ -2214,6 +2214,24 @@ func TestValidateEnv(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "abc",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
FieldRef: &api.ObjectFieldSelector{
|
||||
APIVersion: testapi.Default.GroupVersion().String(),
|
||||
FieldPath: "spec.nodeName",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "abc",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
FieldRef: &api.ObjectFieldSelector{
|
||||
APIVersion: testapi.Default.GroupVersion().String(),
|
||||
FieldPath: "spec.serviceAccountName",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "secret_value",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
@ -2381,7 +2399,7 @@ func TestValidateEnv(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}},
|
||||
expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.labels": supported values: metadata.name, metadata.namespace, status.podIP`,
|
||||
expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.labels": supported values: metadata.name, metadata.namespace, spec.nodeName, spec.serviceAccountName, status.podIP`,
|
||||
},
|
||||
{
|
||||
name: "invalid fieldPath annotations",
|
||||
@ -2394,7 +2412,7 @@ func TestValidateEnv(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}},
|
||||
expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.annotations": supported values: metadata.name, metadata.namespace, status.podIP`,
|
||||
expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.annotations": supported values: metadata.name, metadata.namespace, spec.nodeName, spec.serviceAccountName, status.podIP`,
|
||||
},
|
||||
{
|
||||
name: "unsupported fieldPath",
|
||||
@ -2407,7 +2425,7 @@ func TestValidateEnv(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}},
|
||||
expectedError: `valueFrom.fieldRef.fieldPath: Unsupported value: "status.phase": supported values: metadata.name, metadata.namespace, status.podIP`,
|
||||
expectedError: `valueFrom.fieldRef.fieldPath: Unsupported value: "status.phase": supported values: metadata.name, metadata.namespace, spec.nodeName, spec.serviceAccountName, status.podIP`,
|
||||
},
|
||||
}
|
||||
for _, tc := range errorCases {
|
||||
|
@ -1440,6 +1440,10 @@ func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *api.ObjectFieldSelector, pod
|
||||
return "", err
|
||||
}
|
||||
switch internalFieldPath {
|
||||
case "spec.nodeName":
|
||||
return pod.Spec.NodeName, nil
|
||||
case "spec.serviceAccountName":
|
||||
return pod.Spec.ServiceAccountName, nil
|
||||
case "status.podIP":
|
||||
return podIP, nil
|
||||
}
|
||||
|
@ -1379,6 +1379,24 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "POD_NODE_NAME",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
FieldRef: &api.ObjectFieldSelector{
|
||||
APIVersion: testapi.Default.GroupVersion().String(),
|
||||
FieldPath: "spec.nodeName",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "POD_SERVICE_ACCOUNT_NAME",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
FieldRef: &api.ObjectFieldSelector{
|
||||
APIVersion: testapi.Default.GroupVersion().String(),
|
||||
FieldPath: "spec.serviceAccountName",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "POD_IP",
|
||||
ValueFrom: &api.EnvVarSource{
|
||||
@ -1395,6 +1413,8 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
||||
expectedEnvs: []kubecontainer.EnvVar{
|
||||
{Name: "POD_NAME", Value: "dapi-test-pod-name"},
|
||||
{Name: "POD_NAMESPACE", Value: "downward-api"},
|
||||
{Name: "POD_NODE_NAME", Value: "node-name"},
|
||||
{Name: "POD_SERVICE_ACCOUNT_NAME", Value: "special"},
|
||||
{Name: "POD_IP", Value: "1.2.3.4"},
|
||||
},
|
||||
},
|
||||
@ -1546,6 +1566,10 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
||||
Namespace: tc.ns,
|
||||
Name: "dapi-test-pod-name",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
ServiceAccountName: "special",
|
||||
NodeName: "node-name",
|
||||
},
|
||||
}
|
||||
podIP := "1.2.3.4"
|
||||
|
||||
|
@ -215,6 +215,7 @@ func (d *downwardAPIVolume) collectData(defaultMode *int32) (map[string]volumeut
|
||||
fileProjection.Mode = *defaultMode
|
||||
}
|
||||
if fileInfo.FieldRef != nil {
|
||||
// TODO: unify with Kubelet.podFieldSelectorRuntimeValue
|
||||
if values, err := fieldpath.ExtractFieldPathAsString(d.pod, fileInfo.FieldRef.FieldPath); err != nil {
|
||||
glog.Errorf("Unable to extract field %s: %s", fileInfo.FieldRef.FieldPath, err.Error())
|
||||
errlist = append(errlist, err)
|
||||
|
Loading…
Reference in New Issue
Block a user