aboutsummaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorbaude <bbaude@redhat.com>2021-01-28 15:20:15 -0600
committerbaude <bbaude@redhat.com>2021-01-29 08:49:45 -0600
commitca0dd76bf3b98d1ebe25813a8b15361d58dc75ed (patch)
treee399fc29cf31d599f3af48e59875319424aa48fd /libpod
parent2ee034c1e6ddd9918b97ddea2fd3e6388ec8f60b (diff)
downloadpodman-ca0dd76bf3b98d1ebe25813a8b15361d58dc75ed.tar.gz
podman-ca0dd76bf3b98d1ebe25813a8b15361d58dc75ed.tar.bz2
podman-ca0dd76bf3b98d1ebe25813a8b15361d58dc75ed.zip
Honor custom DNS in play|generate kube
when creating kubernetes yaml from containers and pods, we should honor any custom dns settings the user provided. in the case of generate kube, these would be provided by --dns, --dns-search, and --dns-opt. if multiple containers are involved in the generate, the options will be cumulative and unique with the exception of dns-opt. when replaying a kube file that has kubernetes dns information, we now also add that information to the pod creation. the options for dnspolicy is not enabled as there seemed to be no direct correlation between kubernetes and podman. Fixes: #9132 Signed-off-by: baude <bbaude@redhat.com>
Diffstat (limited to 'libpod')
-rw-r--r--libpod/kube.go112
1 files changed, 98 insertions, 14 deletions
diff --git a/libpod/kube.go b/libpod/kube.go
index 753c58099..b5197293e 100644
--- a/libpod/kube.go
+++ b/libpod/kube.go
@@ -171,9 +171,10 @@ func (p *Pod) podWithContainers(containers []*Container, ports []v1.ContainerPor
deDupPodVolumes := make(map[string]*v1.Volume)
first := true
podContainers := make([]v1.Container, 0, len(containers))
+ dnsInfo := v1.PodDNSConfig{}
for _, ctr := range containers {
if !ctr.IsInfra() {
- ctr, volumes, err := containerToV1Container(ctr)
+ ctr, volumes, _, err := containerToV1Container(ctr)
if err != nil {
return nil, err
}
@@ -196,6 +197,22 @@ func (p *Pod) podWithContainers(containers []*Container, ports []v1.ContainerPor
vol := vol
deDupPodVolumes[vol.Name] = &vol
}
+ } else {
+ _, _, infraDNS, err := containerToV1Container(ctr)
+ if err != nil {
+ return nil, err
+ }
+ if infraDNS != nil {
+ if servers := infraDNS.Nameservers; len(servers) > 0 {
+ dnsInfo.Nameservers = servers
+ }
+ if searches := infraDNS.Searches; len(searches) > 0 {
+ dnsInfo.Searches = searches
+ }
+ if options := infraDNS.Options; len(options) > 0 {
+ dnsInfo.Options = options
+ }
+ }
}
}
podVolumes := make([]v1.Volume, 0, len(deDupPodVolumes))
@@ -203,10 +220,10 @@ func (p *Pod) podWithContainers(containers []*Container, ports []v1.ContainerPor
podVolumes = append(podVolumes, *vol)
}
- return addContainersAndVolumesToPodObject(podContainers, podVolumes, p.Name()), nil
+ return addContainersAndVolumesToPodObject(podContainers, podVolumes, p.Name(), &dnsInfo), nil
}
-func addContainersAndVolumesToPodObject(containers []v1.Container, volumes []v1.Volume, podName string) *v1.Pod {
+func addContainersAndVolumesToPodObject(containers []v1.Container, volumes []v1.Volume, podName string, dnsOptions *v1.PodDNSConfig) *v1.Pod {
tm := v12.TypeMeta{
Kind: "Pod",
APIVersion: "v1",
@@ -228,6 +245,9 @@ func addContainersAndVolumesToPodObject(containers []v1.Container, volumes []v1.
Containers: containers,
Volumes: volumes,
}
+ if dnsOptions != nil {
+ ps.DNSConfig = dnsOptions
+ }
p := v1.Pod{
TypeMeta: tm,
ObjectMeta: om,
@@ -241,32 +261,65 @@ func addContainersAndVolumesToPodObject(containers []v1.Container, volumes []v1.
func simplePodWithV1Containers(ctrs []*Container) (*v1.Pod, error) {
kubeCtrs := make([]v1.Container, 0, len(ctrs))
kubeVolumes := make([]v1.Volume, 0)
+ podDNS := v1.PodDNSConfig{}
for _, ctr := range ctrs {
- kubeCtr, kubeVols, err := containerToV1Container(ctr)
+ kubeCtr, kubeVols, ctrDNS, err := containerToV1Container(ctr)
if err != nil {
return nil, err
}
kubeCtrs = append(kubeCtrs, kubeCtr)
kubeVolumes = append(kubeVolumes, kubeVols...)
- }
- return addContainersAndVolumesToPodObject(kubeCtrs, kubeVolumes, strings.ReplaceAll(ctrs[0].Name(), "_", "")), nil
+ // Combine DNS information in sum'd structure
+ if ctrDNS != nil {
+ // nameservers
+ if servers := ctrDNS.Nameservers; servers != nil {
+ if podDNS.Nameservers == nil {
+ podDNS.Nameservers = make([]string, 0)
+ }
+ for _, s := range servers {
+ if !util.StringInSlice(s, podDNS.Nameservers) { // only append if it does not exist
+ podDNS.Nameservers = append(podDNS.Nameservers, s)
+ }
+ }
+ }
+ // search domains
+ if domains := ctrDNS.Searches; domains != nil {
+ if podDNS.Searches == nil {
+ podDNS.Searches = make([]string, 0)
+ }
+ for _, d := range domains {
+ if !util.StringInSlice(d, podDNS.Searches) { // only append if it does not exist
+ podDNS.Searches = append(podDNS.Searches, d)
+ }
+ }
+ }
+ // dns options
+ if options := ctrDNS.Options; options != nil {
+ if podDNS.Options == nil {
+ podDNS.Options = make([]v1.PodDNSConfigOption, 0)
+ }
+ podDNS.Options = append(podDNS.Options, options...)
+ }
+ } // end if ctrDNS
+ }
+ return addContainersAndVolumesToPodObject(kubeCtrs, kubeVolumes, strings.ReplaceAll(ctrs[0].Name(), "_", ""), &podDNS), nil
}
// containerToV1Container converts information we know about a libpod container
// to a V1.Container specification.
-func containerToV1Container(c *Container) (v1.Container, []v1.Volume, error) {
+func containerToV1Container(c *Container) (v1.Container, []v1.Volume, *v1.PodDNSConfig, error) {
kubeContainer := v1.Container{}
kubeVolumes := []v1.Volume{}
kubeSec, err := generateKubeSecurityContext(c)
if err != nil {
- return kubeContainer, kubeVolumes, err
+ return kubeContainer, kubeVolumes, nil, err
}
if len(c.config.Spec.Linux.Devices) > 0 {
// TODO Enable when we can support devices and their names
kubeContainer.VolumeDevices = generateKubeVolumeDeviceFromLinuxDevice(c.Spec().Linux.Devices)
- return kubeContainer, kubeVolumes, errors.Wrapf(define.ErrNotImplemented, "linux devices")
+ return kubeContainer, kubeVolumes, nil, errors.Wrapf(define.ErrNotImplemented, "linux devices")
}
if len(c.config.UserVolumes) > 0 {
@@ -274,7 +327,7 @@ func containerToV1Container(c *Container) (v1.Container, []v1.Volume, error) {
// Volume names need to be coordinated "globally" in the kube files.
volumeMounts, volumes, err := libpodMountsToKubeVolumeMounts(c)
if err != nil {
- return kubeContainer, kubeVolumes, err
+ return kubeContainer, kubeVolumes, nil, err
}
kubeContainer.VolumeMounts = volumeMounts
kubeVolumes = append(kubeVolumes, volumes...)
@@ -282,16 +335,16 @@ func containerToV1Container(c *Container) (v1.Container, []v1.Volume, error) {
envVariables, err := libpodEnvVarsToKubeEnvVars(c.config.Spec.Process.Env)
if err != nil {
- return kubeContainer, kubeVolumes, err
+ return kubeContainer, kubeVolumes, nil, err
}
portmappings, err := c.PortMappings()
if err != nil {
- return kubeContainer, kubeVolumes, err
+ return kubeContainer, kubeVolumes, nil, err
}
ports, err := ocicniPortMappingToContainerPort(portmappings)
if err != nil {
- return kubeContainer, kubeVolumes, err
+ return kubeContainer, kubeVolumes, nil, err
}
containerCommands := c.Command()
@@ -355,7 +408,38 @@ func containerToV1Container(c *Container) (v1.Container, []v1.Volume, error) {
}
}
- return kubeContainer, kubeVolumes, nil
+ // Obtain the DNS entries from the container
+ dns := v1.PodDNSConfig{}
+
+ // DNS servers
+ if servers := c.config.DNSServer; len(servers) > 0 {
+ dnsServers := make([]string, 0)
+ for _, server := range servers {
+ dnsServers = append(dnsServers, server.String())
+ }
+ dns.Nameservers = dnsServers
+ }
+
+ // DNS search domains
+ if searches := c.config.DNSSearch; len(searches) > 0 {
+ dns.Searches = searches
+ }
+
+ // DNS options
+ if options := c.config.DNSOption; len(options) > 0 {
+ dnsOptions := make([]v1.PodDNSConfigOption, 0)
+ for _, option := range options {
+ // the option can be "k:v" or just "k", no delimiter is required
+ opts := strings.SplitN(option, ":", 2)
+ dnsOpt := v1.PodDNSConfigOption{
+ Name: opts[0],
+ Value: &opts[1],
+ }
+ dnsOptions = append(dnsOptions, dnsOpt)
+ }
+ dns.Options = dnsOptions
+ }
+ return kubeContainer, kubeVolumes, &dns, nil
}
// ocicniPortMappingToContainerPort takes an ocicni portmapping and converts