Skip to content
This repository has been archived by the owner on Feb 24, 2020. It is now read-only.

*: fill resolv.conf from command line --dns #2040

Merged
merged 1 commit into from Jan 28, 2016
Merged

Conversation

alban
Copy link
Member

@alban alban commented Jan 27, 2016

rkt now provides /etc/resolv.conf in each app's chroot. All apps in the
pod have the same /etc/resolv.conf.

Getting DNS information from the CNI or from the host's resolv.conf is
out of scope of this patch. The content of /etc/resolv.conf comes from
the command line parameters:

  • "--dns=8.8.8.8": DNS name server
  • "--dns-search=domain.com": DNS search domain
  • "--dns-opt=debug": DNS options

Implementation detail: systemd-nspawn can overwrite /etc/resolv.conf. It
is supposed to overwrite it only when the container uses the host
network namespace. However, the container network namespace is created
by rkt via CNI and not by systemd-nspawn, so systemd-nspawn is not aware
of the network configuration. As a consequence, we cannot use stage1's
/etc/resolv.conf. Instead, rkt write /etc/rkt-resolv.conf in stage1 and
prepare-app bind-mounts it in stage2's /etc/resolv.conf.

It works in this way:

> $ sudo rkt run --net=alban --dns=1.1.1.1 --dns=2.2.2.2 \
>                --dns-search=foo.com --dns-opt=debug \
>                sha512-a2fb8f390702 --interactive
> / # cat /etc/resolv.conf
> # Generated by rkt
>
> search foo.com
> nameserver 1.1.1.1
> nameserver 2.2.2.2
> options debug
>
> / #

Fixes #660


/cc @steveej I can add tests and --dns-search= after lunch. One difference compared to #2032 is that /etc/resolv.conf is not created if the user does not add --dns=. Also, if the ACI does not have a /etc/resolv.conf, it is created automatically.

  • tests
  • more options for domain search
  • changelog
  • documentation

@steveej
Copy link
Contributor

steveej commented Jan 27, 2016

One difference compared to #2032 is that /etc/resolv.conf is not created if the user does not add --dns=. Also, if the ACI does not have a /etc/resolv.conf, it is created automatically.

Please explain/restate this as it is contradicting.

@@ -379,6 +380,26 @@ func preparedWithPrivateUsers(dir string) (string, error) {
return string(bytes), nil
}

func addResolvConf(cfg RunConfig, rootFs string) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rootFs -> rootfs for consistency

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

if (access(mnt->source, F_OK) != 0)
continue;
if (access(to, F_OK) != 0) {
fd = creat(to, 0644);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we handle errors here or you're leaving it to mount?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know what's better. Any preferences?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My preference: as early as possible

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. Updated.

@alban
Copy link
Member Author

alban commented Jan 27, 2016

Please explain/restate this as it is contradicting

  • When the user adds a non-empty --dns=, rkt will write /etc/resolv.conf as specified. If /etc/resolv.conf does not exist in the ACI, it will be created by rkt. So it works both on ACI with an empty resolv.conf (example: docker://ubuntu) and ACI without resolv.conf (example: docker://busybox).
  • When the user does not adds --dns=, rkt will not touch /etc/resolv.conf. If the file exists in the ACI, it will stay as it is. If the file does not exist in the ACI, it will not be created.

"github.com/coreos/rkt/tests/testutils"
)

// TestDNS is checking how rkt fill /etc/resolv.conf
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/fill/fills

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

@@ -379,6 +380,26 @@ func preparedWithPrivateUsers(dir string) (string, error) {
return string(bytes), nil
}

func addResolvConf(cfg RunConfig, rootfs string) {
if len(cfg.DNS) == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO it'd be better to read if this condition was also or even only used before the invocation of addResolvConf(..)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

@alban alban force-pushed the alban/dns-2 branch 2 times, most recently from 53d4547 to 5149e3e Compare January 27, 2016 15:47
@alban alban added this to the v1.0.0 milestone Jan 27, 2016
@@ -328,6 +340,22 @@ func (pl *portList) Type() string {
return "portList"
}

// flagStringList implements the flag.Value interface to contain a set of strings
type flagStringList []string
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@krnowak where is the preferred place to add this new type?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we have a good place to put new types used in several, but not all commands. But often rkt.go serves as a dumpster for this kind of stuff. ;)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, this is quite generic, so rkt.go it is.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe I wrote a similar thing somewhere before...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's here - https://github.com/coreos/rkt/blob/master/tools/common/util.go#L24

Maybe we should move this thing elsewhere.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However, rkt/run.go already has some flag types: envMap, portList. Should I still move it to rkt.go which does not have any flag type yet?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just keep it here then. We can later move this stuff in to a separate go file.

@alban alban force-pushed the alban/dns-2 branch 3 times, most recently from 190a00b to 8a42cf5 Compare January 27, 2016 16:40
for _, server := range cfg.DNS {
if server == "" {
continue
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be a good idea to check if server is a valid IP address here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok

rkt now provides /etc/resolv.conf in each app's chroot. All apps in the
pod have the same /etc/resolv.conf.

Getting DNS information from the CNI or from the host's resolv.conf is
out of scope of this patch. The content of /etc/resolv.conf comes from
the command line parameters:
- "--dns=8.8.8.8": DNS name server
- "--dns-search=domain.com": DNS search domain
- "--dns-opt=debug": DNS options

Implementation detail: systemd-nspawn can overwrite /etc/resolv.conf. It
is supposed to overwrite it only when the container uses the host
network namespace.  However, the container network namespace is created
by rkt via CNI and not by systemd-nspawn, so systemd-nspawn is not aware
of the network configuration. As a consequence, we cannot use stage1's
/etc/resolv.conf. Instead, rkt write /etc/rkt-resolv.conf in stage1 and
prepare-app bind-mounts it in stage2's /etc/resolv.conf.

It works in this way:

> $ sudo rkt run --net=alban --dns=1.1.1.1 --dns=2.2.2.2 \
>                --dns-search=foo.com --dns-opt=debug \
>                sha512-a2fb8f390702 --interactive
> / # cat /etc/resolv.conf
> # Generated by rkt
>
> search foo.com
> nameserver 1.1.1.1
> nameserver 2.2.2.2
> options debug
>
> / #

Fixes rkt#660
continue;
if (access(to, F_OK) != 0) {
pexit_if((fd = creat(to, 0644)) == -1,
"Cannot create file: \"%s\"", to);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get more information in case of an error? Is there an implicit ERRNO parser here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the p of pexit_if means it will use strerror(errno) at the end of the error message.

rktCmd := fmt.Sprintf(`%s --insecure-options=image run --set-env=FILE=/etc/resolv.conf %s %s`,
ctx.Cmd(), tt.paramDNS, imageFile)
t.Logf("%s\n", rktCmd)
runRktAndCheckOutput(t, rktCmd, tt.expectedLine, false)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests should be improved in the future to match against the whole file instead of lines. That way we can ensure that the order is deterministic which might matter for some DNS implementations.

@steveej
Copy link
Contributor

steveej commented Jan 28, 2016

Let's keep https://github.com/coreos/rkt/pull/2040/files#r51135829 in mind for a follow-up issue.

Nice work

@steveej
Copy link
Contributor

steveej commented Jan 28, 2016

@achanda thanks for you input on this PR. I'm merging this as is but you are welcome to raise any of your thoughts in an issue where we can discuss this further.

steveej added a commit that referenced this pull request Jan 28, 2016
*: fill resolv.conf from command line --dns* flags
@steveej steveej merged commit ccc7442 into rkt:master Jan 28, 2016
@jonboulle jonboulle mentioned this pull request Apr 13, 2016
7 tasks
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants