add status.podIPs in downward api
add host file write for podIPs update tests remove import alias update type check update type check remove import alias update open api spec add tests update test add tests address review comments update imports remove todo and import alias
This commit is contained in:
parent
512eccac1f
commit
af4d18ccf9
2
api/openapi-spec/swagger.json
generated
2
api/openapi-spec/swagger.json
generated
@ -7668,7 +7668,7 @@
|
|||||||
},
|
},
|
||||||
"fieldRef": {
|
"fieldRef": {
|
||||||
"$ref": "#/definitions/io.k8s.api.core.v1.ObjectFieldSelector",
|
"$ref": "#/definitions/io.k8s.api.core.v1.ObjectFieldSelector",
|
||||||
"description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP."
|
"description": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs."
|
||||||
},
|
},
|
||||||
"resourceFieldRef": {
|
"resourceFieldRef": {
|
||||||
"$ref": "#/definitions/io.k8s.api.core.v1.ResourceFieldSelector",
|
"$ref": "#/definitions/io.k8s.api.core.v1.ResourceFieldSelector",
|
||||||
|
@ -88,7 +88,8 @@ func ConvertDownwardAPIFieldLabel(version, label, value string) (string, string,
|
|||||||
"spec.schedulerName",
|
"spec.schedulerName",
|
||||||
"status.phase",
|
"status.phase",
|
||||||
"status.hostIP",
|
"status.hostIP",
|
||||||
"status.podIP":
|
"status.podIP",
|
||||||
|
"status.podIPs":
|
||||||
return label, value, nil
|
return label, value, nil
|
||||||
// This is for backwards compatibility with old v1 clients which send spec.host
|
// This is for backwards compatibility with old v1 clients which send spec.host
|
||||||
case "spec.host":
|
case "spec.host":
|
||||||
|
@ -168,6 +168,20 @@ func TestConvertDownwardAPIFieldLabel(t *testing.T) {
|
|||||||
expectedLabel: "spec.nodeName",
|
expectedLabel: "spec.nodeName",
|
||||||
expectedValue: "127.0.0.1",
|
expectedValue: "127.0.0.1",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
version: "v1",
|
||||||
|
label: "status.podIPs",
|
||||||
|
value: "10.244.0.6,fd00::6",
|
||||||
|
expectedLabel: "status.podIPs",
|
||||||
|
expectedValue: "10.244.0.6,fd00::6",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
version: "v1",
|
||||||
|
label: "status.podIPs",
|
||||||
|
value: "10.244.0.6",
|
||||||
|
expectedLabel: "status.podIPs",
|
||||||
|
expectedValue: "10.244.0.6",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
label, value, err := ConvertDownwardAPIFieldLabel(tc.version, tc.label, tc.value)
|
label, value, err := ConvertDownwardAPIFieldLabel(tc.version, tc.label, tc.value)
|
||||||
|
@ -1753,7 +1753,7 @@ type EnvVar struct {
|
|||||||
// Only one of its fields may be set.
|
// Only one of its fields may be set.
|
||||||
type EnvVarSource struct {
|
type EnvVarSource struct {
|
||||||
// Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations,
|
// Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations,
|
||||||
// metadata.uid, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.
|
// metadata.uid, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
|
||||||
// +optional
|
// +optional
|
||||||
FieldRef *ObjectFieldSelector
|
FieldRef *ObjectFieldSelector
|
||||||
// Selects a resource of the container: only resources limits and requests
|
// Selects a resource of the container: only resources limits and requests
|
||||||
|
@ -70,6 +70,7 @@ func addConversionFuncs(scheme *runtime.Scheme) error {
|
|||||||
"spec.serviceAccountName",
|
"spec.serviceAccountName",
|
||||||
"status.phase",
|
"status.phase",
|
||||||
"status.podIP",
|
"status.podIP",
|
||||||
|
"status.podIPs",
|
||||||
"status.nominatedNodeName":
|
"status.nominatedNodeName":
|
||||||
return label, value, nil
|
return label, value, nil
|
||||||
// This is for backwards compatibility with old v1 clients which send spec.host
|
// This is for backwards compatibility with old v1 clients which send spec.host
|
||||||
|
@ -2097,7 +2097,10 @@ var validEnvDownwardAPIFieldPathExpressions = sets.NewString(
|
|||||||
"spec.nodeName",
|
"spec.nodeName",
|
||||||
"spec.serviceAccountName",
|
"spec.serviceAccountName",
|
||||||
"status.hostIP",
|
"status.hostIP",
|
||||||
"status.podIP")
|
"status.podIP",
|
||||||
|
// status.podIPs is populated even if IPv6DualStack feature gate
|
||||||
|
// is not enabled. This will work for single stack and dual stack.
|
||||||
|
"status.podIPs")
|
||||||
var validContainerResourceFieldPathExpressions = sets.NewString("limits.cpu", "limits.memory", "limits.ephemeral-storage", "requests.cpu", "requests.memory", "requests.ephemeral-storage")
|
var validContainerResourceFieldPathExpressions = sets.NewString("limits.cpu", "limits.memory", "limits.ephemeral-storage", "requests.cpu", "requests.memory", "requests.ephemeral-storage")
|
||||||
|
|
||||||
func validateEnvVarValueFrom(ev core.EnvVar, fldPath *field.Path) field.ErrorList {
|
func validateEnvVarValueFrom(ev core.EnvVar, fldPath *field.Path) field.ErrorList {
|
||||||
|
@ -4431,6 +4431,15 @@ func TestValidateEnv(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "abc",
|
||||||
|
ValueFrom: &core.EnvVarSource{
|
||||||
|
FieldRef: &core.ObjectFieldSelector{
|
||||||
|
APIVersion: "v1",
|
||||||
|
FieldPath: "status.podIPs",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "secret_value",
|
Name: "secret_value",
|
||||||
ValueFrom: &core.EnvVarSource{
|
ValueFrom: &core.EnvVarSource{
|
||||||
@ -4662,7 +4671,7 @@ func TestValidateEnv(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.labels": supported values: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.podIP"`,
|
expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.labels": supported values: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.podIP", "status.podIPs"`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "metadata.annotations without subscript",
|
name: "metadata.annotations without subscript",
|
||||||
@ -4675,7 +4684,7 @@ func TestValidateEnv(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.annotations": supported values: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.podIP"`,
|
expectedError: `[0].valueFrom.fieldRef.fieldPath: Unsupported value: "metadata.annotations": supported values: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.podIP", "status.podIPs"`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "metadata.annotations with invalid key",
|
name: "metadata.annotations with invalid key",
|
||||||
@ -4714,7 +4723,7 @@ func TestValidateEnv(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
expectedError: `valueFrom.fieldRef.fieldPath: Unsupported value: "status.phase": supported values: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.podIP"`,
|
expectedError: `valueFrom.fieldRef.fieldPath: Unsupported value: "status.phase": supported values: "metadata.name", "metadata.namespace", "metadata.uid", "spec.nodeName", "spec.serviceAccountName", "status.hostIP", "status.podIP", "status.podIPs"`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tc := range errorCases {
|
for _, tc := range errorCases {
|
||||||
|
@ -24,7 +24,7 @@ import (
|
|||||||
|
|
||||||
"k8s.io/klog"
|
"k8s.io/klog"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
@ -45,7 +45,7 @@ type HandlerRunner interface {
|
|||||||
// RuntimeHelper wraps kubelet to make container runtime
|
// RuntimeHelper wraps kubelet to make container runtime
|
||||||
// able to get necessary informations like the RunContainerOptions, DNS settings, Host IP.
|
// able to get necessary informations like the RunContainerOptions, DNS settings, Host IP.
|
||||||
type RuntimeHelper interface {
|
type RuntimeHelper interface {
|
||||||
GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (contOpts *RunContainerOptions, cleanupAction func(), err error)
|
GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string, podIPs []string) (contOpts *RunContainerOptions, cleanupAction func(), err error)
|
||||||
GetPodDNS(pod *v1.Pod) (dnsConfig *runtimeapi.DNSConfig, err error)
|
GetPodDNS(pod *v1.Pod) (dnsConfig *runtimeapi.DNSConfig, err error)
|
||||||
// GetPodCgroupParent returns the CgroupName identifier, and its literal cgroupfs form on the host
|
// GetPodCgroupParent returns the CgroupName identifier, and its literal cgroupfs form on the host
|
||||||
// of a pod.
|
// of a pod.
|
||||||
|
@ -34,7 +34,7 @@ type FakeRuntimeHelper struct {
|
|||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FakeRuntimeHelper) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (*kubecontainer.RunContainerOptions, func(), error) {
|
func (f *FakeRuntimeHelper) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string, podIPs []string) (*kubecontainer.RunContainerOptions, func(), error) {
|
||||||
var opts kubecontainer.RunContainerOptions
|
var opts kubecontainer.RunContainerOptions
|
||||||
if len(container.TerminationMessagePath) != 0 {
|
if len(container.TerminationMessagePath) != 0 {
|
||||||
opts.PodContainerDir = f.PodContainerDir
|
opts.PodContainerDir = f.PodContainerDir
|
||||||
|
@ -128,15 +128,15 @@ func (kl *Kubelet) makeBlockVolumes(pod *v1.Pod, container *v1.Container, podVol
|
|||||||
}
|
}
|
||||||
|
|
||||||
// makeMounts determines the mount points for the given container.
|
// makeMounts determines the mount points for the given container.
|
||||||
func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, hostDomain, podIP string, podVolumes kubecontainer.VolumeMap, hu hostutil.HostUtils, subpather subpath.Interface, expandEnvs []kubecontainer.EnvVar) ([]kubecontainer.Mount, func(), error) {
|
func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, hostDomain string, podIPs []string, podVolumes kubecontainer.VolumeMap, hu hostutil.HostUtils, subpather subpath.Interface, expandEnvs []kubecontainer.EnvVar) ([]kubecontainer.Mount, func(), error) {
|
||||||
// Kubernetes only mounts on /etc/hosts if:
|
// Kubernetes only mounts on /etc/hosts if:
|
||||||
// - container is not an infrastructure (pause) container
|
// - container is not an infrastructure (pause) container
|
||||||
// - container is not already mounting on /etc/hosts
|
// - container is not already mounting on /etc/hosts
|
||||||
// - OS is not Windows
|
// - OS is not Windows
|
||||||
// Kubernetes will not mount /etc/hosts if:
|
// Kubernetes will not mount /etc/hosts if:
|
||||||
// - when the Pod sandbox is being created, its IP is still unknown. Hence, PodIP will not have been set.
|
// - when the Pod sandbox is being created, its IP is still unknown. Hence, PodIP will not have been set.
|
||||||
mountEtcHostsFile := len(podIP) > 0 && runtime.GOOS != "windows"
|
mountEtcHostsFile := len(podIPs) > 0 && runtime.GOOS != "windows"
|
||||||
klog.V(3).Infof("container: %v/%v/%v podIP: %q creating hosts mount: %v", pod.Namespace, pod.Name, container.Name, podIP, mountEtcHostsFile)
|
klog.V(3).Infof("container: %v/%v/%v podIPs: %q creating hosts mount: %v", pod.Namespace, pod.Name, container.Name, podIPs, mountEtcHostsFile)
|
||||||
mounts := []kubecontainer.Mount{}
|
mounts := []kubecontainer.Mount{}
|
||||||
var cleanupAction func()
|
var cleanupAction func()
|
||||||
for i, mount := range container.VolumeMounts {
|
for i, mount := range container.VolumeMounts {
|
||||||
@ -258,7 +258,7 @@ func makeMounts(pod *v1.Pod, podDir string, container *v1.Container, hostName, h
|
|||||||
}
|
}
|
||||||
if mountEtcHostsFile {
|
if mountEtcHostsFile {
|
||||||
hostAliases := pod.Spec.HostAliases
|
hostAliases := pod.Spec.HostAliases
|
||||||
hostsMount, err := makeHostsMount(podDir, podIP, hostName, hostDomain, hostAliases, pod.Spec.HostNetwork)
|
hostsMount, err := makeHostsMount(podDir, podIPs, hostName, hostDomain, hostAliases, pod.Spec.HostNetwork)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, cleanupAction, err
|
return nil, cleanupAction, err
|
||||||
}
|
}
|
||||||
@ -292,10 +292,11 @@ func translateMountPropagation(mountMode *v1.MountPropagationMode) (runtimeapi.M
|
|||||||
}
|
}
|
||||||
|
|
||||||
// makeHostsMount makes the mountpoint for the hosts file that the containers
|
// makeHostsMount makes the mountpoint for the hosts file that the containers
|
||||||
// in a pod are injected with.
|
// in a pod are injected with. podIPs is provided instead of podIP as podIPs
|
||||||
func makeHostsMount(podDir, podIP, hostName, hostDomainName string, hostAliases []v1.HostAlias, useHostNetwork bool) (*kubecontainer.Mount, error) {
|
// are present even if dual-stack feature flag is not enabled.
|
||||||
|
func makeHostsMount(podDir string, podIPs []string, hostName, hostDomainName string, hostAliases []v1.HostAlias, useHostNetwork bool) (*kubecontainer.Mount, error) {
|
||||||
hostsFilePath := path.Join(podDir, "etc-hosts")
|
hostsFilePath := path.Join(podDir, "etc-hosts")
|
||||||
if err := ensureHostsFile(hostsFilePath, podIP, hostName, hostDomainName, hostAliases, useHostNetwork); err != nil {
|
if err := ensureHostsFile(hostsFilePath, podIPs, hostName, hostDomainName, hostAliases, useHostNetwork); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &kubecontainer.Mount{
|
return &kubecontainer.Mount{
|
||||||
@ -309,7 +310,7 @@ func makeHostsMount(podDir, podIP, hostName, hostDomainName string, hostAliases
|
|||||||
|
|
||||||
// ensureHostsFile ensures that the given host file has an up-to-date ip, host
|
// ensureHostsFile ensures that the given host file has an up-to-date ip, host
|
||||||
// name, and domain name.
|
// name, and domain name.
|
||||||
func ensureHostsFile(fileName, hostIP, hostName, hostDomainName string, hostAliases []v1.HostAlias, useHostNetwork bool) error {
|
func ensureHostsFile(fileName string, hostIPs []string, hostName, hostDomainName string, hostAliases []v1.HostAlias, useHostNetwork bool) error {
|
||||||
var hostsFileContent []byte
|
var hostsFileContent []byte
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
@ -323,7 +324,7 @@ func ensureHostsFile(fileName, hostIP, hostName, hostDomainName string, hostAlia
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// if Pod is not using host network, create a managed hosts file with Pod IP and other information.
|
// if Pod is not using host network, create a managed hosts file with Pod IP and other information.
|
||||||
hostsFileContent = managedHostsFileContent(hostIP, hostName, hostDomainName, hostAliases)
|
hostsFileContent = managedHostsFileContent(hostIPs, hostName, hostDomainName, hostAliases)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ioutil.WriteFile(fileName, hostsFileContent, 0644)
|
return ioutil.WriteFile(fileName, hostsFileContent, 0644)
|
||||||
@ -342,9 +343,9 @@ func nodeHostsFileContent(hostsFilePath string, hostAliases []v1.HostAlias) ([]b
|
|||||||
return buffer.Bytes(), nil
|
return buffer.Bytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// managedHostsFileContent generates the content of the managed etc hosts based on Pod IP and other
|
// managedHostsFileContent generates the content of the managed etc hosts based on Pod IPs and other
|
||||||
// information.
|
// information.
|
||||||
func managedHostsFileContent(hostIP, hostName, hostDomainName string, hostAliases []v1.HostAlias) []byte {
|
func managedHostsFileContent(hostIPs []string, hostName, hostDomainName string, hostAliases []v1.HostAlias) []byte {
|
||||||
var buffer bytes.Buffer
|
var buffer bytes.Buffer
|
||||||
buffer.WriteString(managedHostsHeader)
|
buffer.WriteString(managedHostsHeader)
|
||||||
buffer.WriteString("127.0.0.1\tlocalhost\n") // ipv4 localhost
|
buffer.WriteString("127.0.0.1\tlocalhost\n") // ipv4 localhost
|
||||||
@ -354,10 +355,17 @@ func managedHostsFileContent(hostIP, hostName, hostDomainName string, hostAliase
|
|||||||
buffer.WriteString("fe00::1\tip6-allnodes\n")
|
buffer.WriteString("fe00::1\tip6-allnodes\n")
|
||||||
buffer.WriteString("fe00::2\tip6-allrouters\n")
|
buffer.WriteString("fe00::2\tip6-allrouters\n")
|
||||||
if len(hostDomainName) > 0 {
|
if len(hostDomainName) > 0 {
|
||||||
|
// host entry generated for all IPs in podIPs
|
||||||
|
// podIPs field is populated for clusters even
|
||||||
|
// dual-stack feature flag is not enabled.
|
||||||
|
for _, hostIP := range hostIPs {
|
||||||
buffer.WriteString(fmt.Sprintf("%s\t%s.%s\t%s\n", hostIP, hostName, hostDomainName, hostName))
|
buffer.WriteString(fmt.Sprintf("%s\t%s.%s\t%s\n", hostIP, hostName, hostDomainName, hostName))
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
for _, hostIP := range hostIPs {
|
||||||
buffer.WriteString(fmt.Sprintf("%s\t%s\n", hostIP, hostName))
|
buffer.WriteString(fmt.Sprintf("%s\t%s\n", hostIP, hostName))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
buffer.Write(hostsEntriesFromHostAliases(hostAliases))
|
buffer.Write(hostsEntriesFromHostAliases(hostAliases))
|
||||||
return buffer.Bytes()
|
return buffer.Bytes()
|
||||||
}
|
}
|
||||||
@ -433,7 +441,7 @@ func (kl *Kubelet) GetPodCgroupParent(pod *v1.Pod) string {
|
|||||||
|
|
||||||
// GenerateRunContainerOptions generates the RunContainerOptions, which can be used by
|
// GenerateRunContainerOptions generates the RunContainerOptions, which can be used by
|
||||||
// the container runtime to set parameters for launching a container.
|
// the container runtime to set parameters for launching a container.
|
||||||
func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string) (*kubecontainer.RunContainerOptions, func(), error) {
|
func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Container, podIP string, podIPs []string) (*kubecontainer.RunContainerOptions, func(), error) {
|
||||||
opts, err := kl.containerManager.GetResources(pod, container)
|
opts, err := kl.containerManager.GetResources(pod, container)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
@ -459,13 +467,14 @@ func (kl *Kubelet) GenerateRunContainerOptions(pod *v1.Pod, container *v1.Contai
|
|||||||
opts.Devices = append(opts.Devices, blkVolumes...)
|
opts.Devices = append(opts.Devices, blkVolumes...)
|
||||||
}
|
}
|
||||||
|
|
||||||
envs, err := kl.makeEnvironmentVariables(pod, container, podIP)
|
envs, err := kl.makeEnvironmentVariables(pod, container, podIP, podIPs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
opts.Envs = append(opts.Envs, envs...)
|
opts.Envs = append(opts.Envs, envs...)
|
||||||
|
|
||||||
mounts, cleanupAction, err := makeMounts(pod, kl.getPodDir(pod.UID), container, hostname, hostDomainName, podIP, volumes, kl.hostutil, kl.subpather, opts.Envs)
|
// only podIPs is sent to makeMounts, as podIPs is populated even if dual-stack feature flag is not enabled.
|
||||||
|
mounts, cleanupAction, err := makeMounts(pod, kl.getPodDir(pod.UID), container, hostname, hostDomainName, podIPs, volumes, kl.hostutil, kl.subpather, opts.Envs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, cleanupAction, err
|
return nil, cleanupAction, err
|
||||||
}
|
}
|
||||||
@ -545,7 +554,7 @@ func (kl *Kubelet) getServiceEnvVarMap(ns string, enableServiceLinks bool) (map[
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make the environment variables for a pod in the given namespace.
|
// Make the environment variables for a pod in the given namespace.
|
||||||
func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container, podIP string) ([]kubecontainer.EnvVar, error) {
|
func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container, podIP string, podIPs []string) ([]kubecontainer.EnvVar, error) {
|
||||||
if pod.Spec.EnableServiceLinks == nil {
|
if pod.Spec.EnableServiceLinks == nil {
|
||||||
return nil, fmt.Errorf("nil pod.spec.enableServiceLinks encountered, cannot construct envvars")
|
return nil, fmt.Errorf("nil pod.spec.enableServiceLinks encountered, cannot construct envvars")
|
||||||
}
|
}
|
||||||
@ -669,7 +678,7 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container
|
|||||||
// Step 1b: resolve alternate env var sources
|
// Step 1b: resolve alternate env var sources
|
||||||
switch {
|
switch {
|
||||||
case envVar.ValueFrom.FieldRef != nil:
|
case envVar.ValueFrom.FieldRef != nil:
|
||||||
runtimeVal, err = kl.podFieldSelectorRuntimeValue(envVar.ValueFrom.FieldRef, pod, podIP)
|
runtimeVal, err = kl.podFieldSelectorRuntimeValue(envVar.ValueFrom.FieldRef, pod, podIP, podIPs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, err
|
return result, err
|
||||||
}
|
}
|
||||||
@ -770,7 +779,7 @@ func (kl *Kubelet) makeEnvironmentVariables(pod *v1.Pod, container *v1.Container
|
|||||||
|
|
||||||
// podFieldSelectorRuntimeValue returns the runtime value of the given
|
// podFieldSelectorRuntimeValue returns the runtime value of the given
|
||||||
// selector for a pod.
|
// selector for a pod.
|
||||||
func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *v1.ObjectFieldSelector, pod *v1.Pod, podIP string) (string, error) {
|
func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *v1.ObjectFieldSelector, pod *v1.Pod, podIP string, podIPs []string) (string, error) {
|
||||||
internalFieldPath, _, err := podshelper.ConvertDownwardAPIFieldLabel(fs.APIVersion, fs.FieldPath, "")
|
internalFieldPath, _, err := podshelper.ConvertDownwardAPIFieldLabel(fs.APIVersion, fs.FieldPath, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -788,6 +797,8 @@ func (kl *Kubelet) podFieldSelectorRuntimeValue(fs *v1.ObjectFieldSelector, pod
|
|||||||
return hostIP.String(), nil
|
return hostIP.String(), nil
|
||||||
case "status.podIP":
|
case "status.podIP":
|
||||||
return podIP, nil
|
return podIP, nil
|
||||||
|
case "status.podIPs":
|
||||||
|
return strings.Join(podIPs, ","), nil
|
||||||
}
|
}
|
||||||
return fieldpath.ExtractFieldPathAsString(pod, internalFieldPath)
|
return fieldpath.ExtractFieldPathAsString(pod, internalFieldPath)
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
v1 "k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
|
|
||||||
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
|
runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2"
|
||||||
_ "k8s.io/kubernetes/pkg/apis/core/install"
|
_ "k8s.io/kubernetes/pkg/apis/core/install"
|
||||||
@ -249,7 +249,7 @@ func TestMakeMounts(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
mounts, _, err := makeMounts(&pod, "/pod", &tc.container, "fakepodname", "", "", tc.podVolumes, fhu, fsp, nil)
|
mounts, _, err := makeMounts(&pod, "/pod", &tc.container, "fakepodname", "", []string{""}, tc.podVolumes, fhu, fsp, nil)
|
||||||
|
|
||||||
// validate only the error if we expect an error
|
// validate only the error if we expect an error
|
||||||
if tc.expectErr {
|
if tc.expectErr {
|
||||||
|
@ -97,7 +97,7 @@ func TestDisabledSubpath(t *testing.T) {
|
|||||||
|
|
||||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeSubpath, false)()
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.VolumeSubpath, false)()
|
||||||
for name, test := range cases {
|
for name, test := range cases {
|
||||||
_, _, err := makeMounts(&pod, "/pod", &test.container, "fakepodname", "", "", podVolumes, fhu, fsp, nil)
|
_, _, err := makeMounts(&pod, "/pod", &test.container, "fakepodname", "", []string{}, podVolumes, fhu, fsp, nil)
|
||||||
if err != nil && !test.expectError {
|
if err != nil && !test.expectError {
|
||||||
t.Errorf("test %v failed: %v", name, err)
|
t.Errorf("test %v failed: %v", name, err)
|
||||||
}
|
}
|
||||||
@ -243,14 +243,14 @@ func writeHostsFile(filename string, cfg string) (string, error) {
|
|||||||
|
|
||||||
func TestManagedHostsFileContent(t *testing.T) {
|
func TestManagedHostsFileContent(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
hostIP string
|
hostIPs []string
|
||||||
hostName string
|
hostName string
|
||||||
hostDomainName string
|
hostDomainName string
|
||||||
hostAliases []v1.HostAlias
|
hostAliases []v1.HostAlias
|
||||||
expectedContent string
|
expectedContent string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
"123.45.67.89",
|
[]string{"123.45.67.89"},
|
||||||
"podFoo",
|
"podFoo",
|
||||||
"",
|
"",
|
||||||
[]v1.HostAlias{},
|
[]v1.HostAlias{},
|
||||||
@ -265,7 +265,7 @@ fe00::2 ip6-allrouters
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"203.0.113.1",
|
[]string{"203.0.113.1"},
|
||||||
"podFoo",
|
"podFoo",
|
||||||
"domainFoo",
|
"domainFoo",
|
||||||
[]v1.HostAlias{},
|
[]v1.HostAlias{},
|
||||||
@ -280,7 +280,7 @@ fe00::2 ip6-allrouters
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"203.0.113.1",
|
[]string{"203.0.113.1"},
|
||||||
"podFoo",
|
"podFoo",
|
||||||
"domainFoo",
|
"domainFoo",
|
||||||
[]v1.HostAlias{
|
[]v1.HostAlias{
|
||||||
@ -300,7 +300,7 @@ fe00::2 ip6-allrouters
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"203.0.113.1",
|
[]string{"203.0.113.1"},
|
||||||
"podFoo",
|
"podFoo",
|
||||||
"domainFoo",
|
"domainFoo",
|
||||||
[]v1.HostAlias{
|
[]v1.HostAlias{
|
||||||
@ -319,12 +319,28 @@ fe00::2 ip6-allrouters
|
|||||||
# Entries added by HostAliases.
|
# Entries added by HostAliases.
|
||||||
123.45.67.89 foo bar baz
|
123.45.67.89 foo bar baz
|
||||||
456.78.90.123 park doo boo
|
456.78.90.123 park doo boo
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
[]string{"203.0.113.1", "fd00::6"},
|
||||||
|
"podFoo",
|
||||||
|
"domainFoo",
|
||||||
|
[]v1.HostAlias{},
|
||||||
|
`# Kubernetes-managed hosts file.
|
||||||
|
127.0.0.1 localhost
|
||||||
|
::1 localhost ip6-localhost ip6-loopback
|
||||||
|
fe00::0 ip6-localnet
|
||||||
|
fe00::0 ip6-mcastprefix
|
||||||
|
fe00::1 ip6-allnodes
|
||||||
|
fe00::2 ip6-allrouters
|
||||||
|
203.0.113.1 podFoo.domainFoo podFoo
|
||||||
|
fd00::6 podFoo.domainFoo podFoo
|
||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, testCase := range testCases {
|
for _, testCase := range testCases {
|
||||||
actualContent := managedHostsFileContent(testCase.hostIP, testCase.hostName, testCase.hostDomainName, testCase.hostAliases)
|
actualContent := managedHostsFileContent(testCase.hostIPs, testCase.hostName, testCase.hostDomainName, testCase.hostAliases)
|
||||||
assert.Equal(t, testCase.expectedContent, string(actualContent), "hosts file content not expected")
|
assert.Equal(t, testCase.expectedContent, string(actualContent), "hosts file content not expected")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -703,6 +719,15 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "POD_IPS",
|
||||||
|
ValueFrom: &v1.EnvVarSource{
|
||||||
|
FieldRef: &v1.ObjectFieldSelector{
|
||||||
|
APIVersion: "v1",
|
||||||
|
FieldPath: "status.podIPs",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: "HOST_IP",
|
Name: "HOST_IP",
|
||||||
ValueFrom: &v1.EnvVarSource{
|
ValueFrom: &v1.EnvVarSource{
|
||||||
@ -722,6 +747,7 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
|||||||
{Name: "POD_NODE_NAME", Value: "node-name"},
|
{Name: "POD_NODE_NAME", Value: "node-name"},
|
||||||
{Name: "POD_SERVICE_ACCOUNT_NAME", Value: "special"},
|
{Name: "POD_SERVICE_ACCOUNT_NAME", Value: "special"},
|
||||||
{Name: "POD_IP", Value: "1.2.3.4"},
|
{Name: "POD_IP", Value: "1.2.3.4"},
|
||||||
|
{Name: "POD_IPS", Value: "1.2.3.4,fd00::6"},
|
||||||
{Name: "HOST_IP", Value: testKubeletHostIP},
|
{Name: "HOST_IP", Value: testKubeletHostIP},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -1627,8 +1653,9 @@ func TestMakeEnvironmentVariables(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
podIP := "1.2.3.4"
|
podIP := "1.2.3.4"
|
||||||
|
podIPs := []string{"1.2.3.4,fd00::6"}
|
||||||
|
|
||||||
result, err := kl.makeEnvironmentVariables(testPod, tc.container, podIP)
|
result, err := kl.makeEnvironmentVariables(testPod, tc.container, podIP, podIPs)
|
||||||
select {
|
select {
|
||||||
case e := <-fakeRecorder.Events:
|
case e := <-fakeRecorder.Events:
|
||||||
assert.Equal(t, tc.expectedEvent, e)
|
assert.Equal(t, tc.expectedEvent, e)
|
||||||
|
@ -84,7 +84,7 @@ func TestMakeMountsWindows(t *testing.T) {
|
|||||||
|
|
||||||
fhu := hostutil.NewFakeHostUtil(nil)
|
fhu := hostutil.NewFakeHostUtil(nil)
|
||||||
fsp := &subpath.FakeSubpath{}
|
fsp := &subpath.FakeSubpath{}
|
||||||
mounts, _, _ := makeMounts(&pod, "/pod", &container, "fakepodname", "", "", podVolumes, fhu, fsp, nil)
|
mounts, _, _ := makeMounts(&pod, "/pod", &container, "fakepodname", "", []string{""}, podVolumes, fhu, fsp, nil)
|
||||||
|
|
||||||
expectedMounts := []kubecontainer.Mount{
|
expectedMounts := []kubecontainer.Mount{
|
||||||
{
|
{
|
||||||
|
@ -90,7 +90,7 @@ func (m *kubeGenericRuntimeManager) recordContainerEvent(pod *v1.Pod, container
|
|||||||
// * create the container
|
// * create the container
|
||||||
// * start the container
|
// * start the container
|
||||||
// * run the post start lifecycle hooks (if applicable)
|
// * run the post start lifecycle hooks (if applicable)
|
||||||
func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandboxConfig *runtimeapi.PodSandboxConfig, container *v1.Container, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, podIP string) (string, error) {
|
func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandboxConfig *runtimeapi.PodSandboxConfig, container *v1.Container, pod *v1.Pod, podStatus *kubecontainer.PodStatus, pullSecrets []v1.Secret, podIP string, podIPs []string) (string, error) {
|
||||||
// Step 1: pull the image.
|
// Step 1: pull the image.
|
||||||
imageRef, msg, err := m.imagePuller.EnsureImageExists(pod, container, pullSecrets, podSandboxConfig)
|
imageRef, msg, err := m.imagePuller.EnsureImageExists(pod, container, pullSecrets, podSandboxConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -113,7 +113,7 @@ func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandb
|
|||||||
restartCount = containerStatus.RestartCount + 1
|
restartCount = containerStatus.RestartCount + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
containerConfig, cleanupAction, err := m.generateContainerConfig(container, pod, restartCount, podIP, imageRef)
|
containerConfig, cleanupAction, err := m.generateContainerConfig(container, pod, restartCount, podIP, imageRef, podIPs)
|
||||||
if cleanupAction != nil {
|
if cleanupAction != nil {
|
||||||
defer cleanupAction()
|
defer cleanupAction()
|
||||||
}
|
}
|
||||||
@ -193,8 +193,8 @@ func (m *kubeGenericRuntimeManager) startContainer(podSandboxID string, podSandb
|
|||||||
}
|
}
|
||||||
|
|
||||||
// generateContainerConfig generates container config for kubelet runtime v1.
|
// generateContainerConfig generates container config for kubelet runtime v1.
|
||||||
func (m *kubeGenericRuntimeManager) generateContainerConfig(container *v1.Container, pod *v1.Pod, restartCount int, podIP, imageRef string) (*runtimeapi.ContainerConfig, func(), error) {
|
func (m *kubeGenericRuntimeManager) generateContainerConfig(container *v1.Container, pod *v1.Pod, restartCount int, podIP, imageRef string, podIPs []string) (*runtimeapi.ContainerConfig, func(), error) {
|
||||||
opts, cleanupAction, err := m.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP)
|
opts, cleanupAction, err := m.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP, podIPs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ func makeExpectedConfig(m *kubeGenericRuntimeManager, pod *v1.Pod, containerInde
|
|||||||
container := &pod.Spec.Containers[containerIndex]
|
container := &pod.Spec.Containers[containerIndex]
|
||||||
podIP := ""
|
podIP := ""
|
||||||
restartCount := 0
|
restartCount := 0
|
||||||
opts, _, _ := m.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP)
|
opts, _, _ := m.runtimeHelper.GenerateRunContainerOptions(pod, container, podIP, []string{podIP})
|
||||||
containerLogsPath := buildContainerLogsPath(container.Name, restartCount)
|
containerLogsPath := buildContainerLogsPath(container.Name, restartCount)
|
||||||
restartCountUint32 := uint32(restartCount)
|
restartCountUint32 := uint32(restartCount)
|
||||||
envs := make([]*runtimeapi.KeyValue, len(opts.Envs))
|
envs := make([]*runtimeapi.KeyValue, len(opts.Envs))
|
||||||
@ -89,7 +89,7 @@ func TestGenerateContainerConfig(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
expectedConfig := makeExpectedConfig(m, pod, 0)
|
expectedConfig := makeExpectedConfig(m, pod, 0)
|
||||||
containerConfig, _, err := m.generateContainerConfig(&pod.Spec.Containers[0], pod, 0, "", pod.Spec.Containers[0].Image)
|
containerConfig, _, err := m.generateContainerConfig(&pod.Spec.Containers[0], pod, 0, "", pod.Spec.Containers[0].Image, []string{})
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
assert.Equal(t, expectedConfig, containerConfig, "generate container config for kubelet runtime v1.")
|
assert.Equal(t, expectedConfig, containerConfig, "generate container config for kubelet runtime v1.")
|
||||||
assert.Equal(t, runAsUser, containerConfig.GetLinux().GetSecurityContext().GetRunAsUser().GetValue(), "RunAsUser should be set")
|
assert.Equal(t, runAsUser, containerConfig.GetLinux().GetSecurityContext().GetRunAsUser().GetValue(), "RunAsUser should be set")
|
||||||
@ -120,7 +120,7 @@ func TestGenerateContainerConfig(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _, err = m.generateContainerConfig(&podWithContainerSecurityContext.Spec.Containers[0], podWithContainerSecurityContext, 0, "", podWithContainerSecurityContext.Spec.Containers[0].Image)
|
_, _, err = m.generateContainerConfig(&podWithContainerSecurityContext.Spec.Containers[0], podWithContainerSecurityContext, 0, "", podWithContainerSecurityContext.Spec.Containers[0].Image, []string{})
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
|
|
||||||
imageID, _ := imageService.PullImage(&runtimeapi.ImageSpec{Image: "busybox"}, nil, nil)
|
imageID, _ := imageService.PullImage(&runtimeapi.ImageSpec{Image: "busybox"}, nil, nil)
|
||||||
@ -132,6 +132,6 @@ func TestGenerateContainerConfig(t *testing.T) {
|
|||||||
podWithContainerSecurityContext.Spec.Containers[0].SecurityContext.RunAsUser = nil
|
podWithContainerSecurityContext.Spec.Containers[0].SecurityContext.RunAsUser = nil
|
||||||
podWithContainerSecurityContext.Spec.Containers[0].SecurityContext.RunAsNonRoot = &runAsNonRootTrue
|
podWithContainerSecurityContext.Spec.Containers[0].SecurityContext.RunAsNonRoot = &runAsNonRootTrue
|
||||||
|
|
||||||
_, _, err = m.generateContainerConfig(&podWithContainerSecurityContext.Spec.Containers[0], podWithContainerSecurityContext, 0, "", podWithContainerSecurityContext.Spec.Containers[0].Image)
|
_, _, err = m.generateContainerConfig(&podWithContainerSecurityContext.Spec.Containers[0], podWithContainerSecurityContext, 0, "", podWithContainerSecurityContext.Spec.Containers[0].Image, []string{})
|
||||||
assert.Error(t, err, "RunAsNonRoot should fail for non-numeric username")
|
assert.Error(t, err, "RunAsNonRoot should fail for non-numeric username")
|
||||||
}
|
}
|
||||||
|
@ -325,13 +325,12 @@ func TestLifeCycleHook(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Now try to create a container, which should in turn invoke PostStart Hook
|
// Now try to create a container, which should in turn invoke PostStart Hook
|
||||||
_, err := m.startContainer(fakeSandBox.Id, fakeSandBoxConfig, testContainer, testPod, fakePodStatus, nil, "")
|
_, err := m.startContainer(fakeSandBox.Id, fakeSandBoxConfig, testContainer, testPod, fakePodStatus, nil, "", []string{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("startContainer erro =%v", err)
|
t.Errorf("startContainer error =%v", err)
|
||||||
}
|
}
|
||||||
if fakeRunner.Cmd[0] != cmdPostStart.PostStart.Exec.Command[0] {
|
if fakeRunner.Cmd[0] != cmdPostStart.PostStart.Exec.Command[0] {
|
||||||
t.Errorf("CMD PostStart hook was not invoked")
|
t.Errorf("CMD PostStart hook was not invoked")
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -681,12 +681,13 @@ func (m *kubeGenericRuntimeManager) SyncPod(pod *v1.Pod, podStatus *kubecontaine
|
|||||||
// by container garbage collector.
|
// by container garbage collector.
|
||||||
m.pruneInitContainersBeforeStart(pod, podStatus)
|
m.pruneInitContainersBeforeStart(pod, podStatus)
|
||||||
|
|
||||||
// We pass the value of the PRIMARY podIP down to generatePodSandboxConfig and
|
// We pass the value of the PRIMARY podIP and list of podIPs down to
|
||||||
// generateContainerConfig, which in turn passes it to various other
|
// generatePodSandboxConfig and generateContainerConfig, which in turn
|
||||||
// functions, in order to facilitate functionality that requires this
|
// passes it to various other functions, in order to facilitate functionality
|
||||||
// value (hosts file and downward API) and avoid races determining
|
// that requires this value (hosts file and downward API) and avoid races determining
|
||||||
// the pod IP in cases where a container requires restart but the
|
// the pod IP in cases where a container requires restart but the
|
||||||
// podIP isn't in the status manager yet.
|
// podIP isn't in the status manager yet. The list of podIPs is used to
|
||||||
|
// generate the hosts file.
|
||||||
//
|
//
|
||||||
// We default to the IPs in the passed-in pod status, and overwrite them if the
|
// We default to the IPs in the passed-in pod status, and overwrite them if the
|
||||||
// sandbox needs to be (re)started.
|
// sandbox needs to be (re)started.
|
||||||
@ -772,7 +773,8 @@ func (m *kubeGenericRuntimeManager) SyncPod(pod *v1.Pod, podStatus *kubecontaine
|
|||||||
}
|
}
|
||||||
|
|
||||||
klog.V(4).Infof("Creating %v %+v in pod %v", typeName, container, format.Pod(pod))
|
klog.V(4).Infof("Creating %v %+v in pod %v", typeName, container, format.Pod(pod))
|
||||||
if msg, err := m.startContainer(podSandboxID, podSandboxConfig, container, pod, podStatus, pullSecrets, podIP); err != nil {
|
// NOTE (aramase) podIPs are populated for single stack and dual stack clusters. Send only podIPs.
|
||||||
|
if msg, err := m.startContainer(podSandboxID, podSandboxConfig, container, pod, podStatus, pullSecrets, podIP, podIPs); err != nil {
|
||||||
startContainerResult.Fail(err, msg)
|
startContainerResult.Fail(err, msg)
|
||||||
// known errors that are logged in other places are logged at higher levels here to avoid
|
// known errors that are logged in other places are logged at higher levels here to avoid
|
||||||
// repetitive log spam
|
// repetitive log spam
|
||||||
|
@ -156,7 +156,7 @@ func makeFakeContainer(t *testing.T, m *kubeGenericRuntimeManager, template cont
|
|||||||
sandboxConfig, err := m.generatePodSandboxConfig(template.pod, template.sandboxAttempt)
|
sandboxConfig, err := m.generatePodSandboxConfig(template.pod, template.sandboxAttempt)
|
||||||
assert.NoError(t, err, "generatePodSandboxConfig for container template %+v", template)
|
assert.NoError(t, err, "generatePodSandboxConfig for container template %+v", template)
|
||||||
|
|
||||||
containerConfig, _, err := m.generateContainerConfig(template.container, template.pod, template.attempt, "", template.container.Image)
|
containerConfig, _, err := m.generateContainerConfig(template.container, template.pod, template.attempt, "", template.container.Image, []string{})
|
||||||
assert.NoError(t, err, "generateContainerConfig for container template %+v", template)
|
assert.NoError(t, err, "generateContainerConfig for container template %+v", template)
|
||||||
|
|
||||||
podSandboxID := apitest.BuildSandboxName(sandboxConfig.Metadata)
|
podSandboxID := apitest.BuildSandboxName(sandboxConfig.Metadata)
|
||||||
|
@ -1142,7 +1142,7 @@ message EnvVar {
|
|||||||
// EnvVarSource represents a source for the value of an EnvVar.
|
// EnvVarSource represents a source for the value of an EnvVar.
|
||||||
message EnvVarSource {
|
message EnvVarSource {
|
||||||
// Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations,
|
// Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations,
|
||||||
// spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.
|
// spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
|
||||||
// +optional
|
// +optional
|
||||||
optional ObjectFieldSelector fieldRef = 1;
|
optional ObjectFieldSelector fieldRef = 1;
|
||||||
|
|
||||||
|
@ -1847,7 +1847,7 @@ type EnvVar struct {
|
|||||||
// EnvVarSource represents a source for the value of an EnvVar.
|
// EnvVarSource represents a source for the value of an EnvVar.
|
||||||
type EnvVarSource struct {
|
type EnvVarSource struct {
|
||||||
// Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations,
|
// Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations,
|
||||||
// spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.
|
// spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.
|
||||||
// +optional
|
// +optional
|
||||||
FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty" protobuf:"bytes,1,opt,name=fieldRef"`
|
FieldRef *ObjectFieldSelector `json:"fieldRef,omitempty" protobuf:"bytes,1,opt,name=fieldRef"`
|
||||||
// Selects a resource of the container: only resources limits and requests
|
// Selects a resource of the container: only resources limits and requests
|
||||||
|
@ -566,7 +566,7 @@ func (EnvVar) SwaggerDoc() map[string]string {
|
|||||||
|
|
||||||
var map_EnvVarSource = map[string]string{
|
var map_EnvVarSource = map[string]string{
|
||||||
"": "EnvVarSource represents a source for the value of an EnvVar.",
|
"": "EnvVarSource represents a source for the value of an EnvVar.",
|
||||||
"fieldRef": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP.",
|
"fieldRef": "Selects a field of the pod: supports metadata.name, metadata.namespace, metadata.labels, metadata.annotations, spec.nodeName, spec.serviceAccountName, status.hostIP, status.podIP, status.podIPs.",
|
||||||
"resourceFieldRef": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.",
|
"resourceFieldRef": "Selects a resource of the container: only resources limits and requests (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage) are currently supported.",
|
||||||
"configMapKeyRef": "Selects a key of a ConfigMap.",
|
"configMapKeyRef": "Selects a key of a ConfigMap.",
|
||||||
"secretKeyRef": "Selects a key of a secret in the pod's namespace",
|
"secretKeyRef": "Selects a key of a secret in the pod's namespace",
|
||||||
|
Loading…
Reference in New Issue
Block a user