-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit e784925
Showing
18 changed files
with
753 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
/dist | ||
/*.egg-info | ||
/rpm/*.rpm | ||
/rpm/*.tar.gz | ||
__pycache__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
the .tito/packages directory contains metadata files | ||
named after their packages. Each file has the latest tagged | ||
version and the project's relative directory. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__version__ = '$version' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[buildconfig] | ||
builder = tito.builder.Builder | ||
tagger = tito.tagger.VersionTagger | ||
changelog_do_not_remove_cherrypick = 0 | ||
changelog_format = %s (%ae) | ||
|
||
[version_template] | ||
destination_file = src/systemd_resolved_docker/__init__.py | ||
template_file = .tito/templates/__init__.py.template |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Copyright 2020-2021 Zsombor Welker | ||
Copyright 2018-2020 Patrice Ferlet | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, | ||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR | ||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE | ||
OR OTHER DEALINGS IN THE SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
# systemd-resolved-docker | ||
|
||
Provides systemd-resolved and docker DNS integration. | ||
|
||
A DNS server is configured to listen on each docker interface's IP address. This is used to: | ||
1. expose the systemd-resolved DNS service (`127.0.0.53`) to docker containers by proxying DNS requests, since the | ||
systems loopback IPs can't be accessed from containers. | ||
2. adds the created DNS servers to the docker interface using systemd-resolved so that docker containers may | ||
be referenced by hostname. This uses `--hostname` and `--domainname`, `--network` or a default of `.docker` to | ||
create the domains. | ||
|
||
## Install | ||
|
||
### Fedora / COPR | ||
|
||
For Fedora and RPM based systems [COPR](https://copr.fedorainfracloud.org/coprs/flaktack/systemd-resolved-docker/) contains pre-built packages. | ||
|
||
1. Enabled the COPR repository | ||
|
||
dnf copr enable flaktack/systemd-resolved-docker | ||
|
||
1. Install the package | ||
|
||
dnf install systemd-resolved-docker | ||
|
||
1. Start and optionally enable the services | ||
|
||
systemctl start systemd-resolved-docker | ||
systemctl enable systemd-resolved-docker | ||
|
||
1. Docker should be updated to use the DNS server provided by `systemd-docker-resolved.` This may be done | ||
globally by editing the docker daemon's configuration (`daemon.json`) or per-container using the `--dns` | ||
flag. | ||
|
||
```js | ||
"dns": [ | ||
"172.17.0.1" // docker0 interface's IP address | ||
] | ||
``` | ||
|
||
### Configuration | ||
|
||
`systemd-resolved-docker` may be configured using environment variables. When installed using the RPM | ||
`/etc/sysconfig/systemd-resolved-docker` may also be modified to update the environment variables. | ||
|
||
| Name | Description | Default Value | Example | | ||
|------------------|----------------------------------------------------------------------------|--------------------------------------------------------|--------------------------| | ||
| DNS_SERVER | DNS server to use when resolving queries from docker containers. | `127.0.0.53` - systemd-resolved DNS server | `127.0.0.53` | | ||
| DOCKER_INTERFACE | Docker interface name | The first docker network's interface | `docker0` | | ||
| LISTEN_ADDRESS | IPs to listen on for queries from systemd-resolved and docker containers. | _ip of the default docker bridge_, often `172.17.0.1` | `172.17.0.1,127.0.0.153` | | ||
| LISTEN_PORT | Port to listen on for queries from systemd-resolved and docker containers. | `53` | `1053` | | ||
| DEFAULT_DOMAIN | Domain to append to containers which don't have one set using `--domainname` or are not part of a network `--network`. | `.docker` | `.docker` | | ||
| ALLOWED_DOMAINS | Domain globs which will be handled by the DNS server. | `.docker` | `.docker,local` | | ||
|
||
|
||
## Usage | ||
|
||
Start a container with a specified hostname: | ||
`docker run --hostname test python:3.9 python -m http.server 3000` | ||
|
||
If configured correctly then `resolvectl status` should show the configured link-specific DNS server, while the url | ||
should load: http://test.docker:3000/ | ||
|
||
$ resolvectl status | ||
... | ||
Link 7 (docker0) | ||
Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6 | ||
Protocols: -DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported | ||
DNS Servers: 172.17.0.1 | ||
DNS Domain: ~docker | ||
... | ||
|
||
If docker is configured to use the provided DNS server then the container domain names may also be resolved within containers: | ||
|
||
$ docker run --dns 1.1.1.1 --rm -it alpine | ||
/ # apk add bind | ||
/ # host test.docker | ||
Host test.docker not found: 3(NXDOMAIN) | ||
|
||
``` | ||
$ docker run --dns 172.17.0.1 --rm -it alpine | ||
/ # apk add bind | ||
/ # host test.docker | ||
/ # host test.docker | ||
test.docker has address 172.17.0.3 | ||
Host test.docker not found: 3(NXDOMAIN) | ||
Host test.docker not found: 3(NXDOMAIN) | ||
``` | ||
If there are link-local, VPN or other DNS servers configured than those will also work within containers. | ||
## Build | ||
`setup.py` may be used to create a python package. | ||
`tito` may be used to create RPMs. | ||
## Links | ||
Portions are based on [docker-auto-dnsmasq](https://github.com/metal3d/docker-auto-dnsmasq). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
%global srcname systemd-resolved-docker | ||
%global eggname systemd_resolved_docker | ||
|
||
Name: python-%{srcname} | ||
Version: 0.0.0 | ||
Release: 0%{?dist} | ||
Summary: systemd-resolved and docker DNS integration | ||
|
||
License: BSD | ||
URL: https://pypi.python.org/pypi/systemd_resolved_docker | ||
#Source0: ${pypi_source} | ||
Source0: %{srcname}-%{version}.tar.gz | ||
Source1: %{srcname}.service | ||
Source2: %{srcname}.sysconfig | ||
|
||
BuildArch: noarch | ||
|
||
%global _description %{expand: | ||
systemd-resolved and docker DNS integration} | ||
|
||
%description %_description | ||
|
||
%package -n python3-%{srcname} | ||
Summary: %{summary} | ||
%if 0%{?el6} | ||
BuildRequires: python34-devel | ||
BuildRequires: python34-setuptools | ||
%else | ||
BuildRequires: python3-devel | ||
BuildRequires: python3-setuptools | ||
%endif | ||
BuildRequires: systemd-rpm-macros | ||
|
||
%description -n python3-%{srcname} %_description | ||
|
||
#-- PREP, BUILD & INSTALL -----------------------------------------------------# | ||
%prep | ||
%autosetup -n %{srcname}-%{version} | ||
|
||
%build | ||
%py3_build | ||
|
||
%install | ||
%py3_install | ||
|
||
# SystemdD services | ||
install -dp %{buildroot}%{_unitdir} | ||
install -p -m 644 %{SOURCE1} %{buildroot}%{_unitdir} | ||
|
||
# Sysconfig | ||
install -dp %{buildroot}%{_sysconfdir}/sysconfig | ||
install -p -m 644 %{SOURCE2} %{buildroot}%{_sysconfdir}/sysconfig/%{srcname} | ||
|
||
# %%check | ||
# %%{python3} setup.py test | ||
|
||
%post | ||
%systemd_post %{srcname}.service | ||
|
||
%preun | ||
%systemd_preun %{srcname}.service | ||
|
||
%postun | ||
%systemd_postun_with_restart %{srcname}.service | ||
|
||
|
||
#-- FILES ---------------------------------------------------------------------# | ||
# Note that there is no %%files section for the unversioned python module | ||
%files -n python3-%{srcname} | ||
%doc README.md | ||
%{python3_sitelib}/%{eggname}-*.egg-info/ | ||
%{python3_sitelib}/%{eggname}/ | ||
%{_bindir}/%{srcname} | ||
%{_unitdir}/%{srcname}.service | ||
%config(noreplace) %{_sysconfdir}/sysconfig/%{srcname} | ||
|
||
#-- CHANGELOG -----------------------------------------------------------------# | ||
|
||
%changelog |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
%global srcname dnslib | ||
|
||
Name: python-%{srcname} | ||
Version: 0.9.14 | ||
Release: 1%{?dist} | ||
Summary: dnslib python module | ||
|
||
License: BSD | ||
URL: https://pypi.python.org/pypi/dnslib | ||
Source0: %{pypi_source} | ||
|
||
BuildArch: noarch | ||
|
||
%global _description %{expand: | ||
A library to encode/decode DNS wire-format packets supporting both | ||
Python 2.7 and Python 3.2+.} | ||
|
||
%description %_description | ||
|
||
%package -n python3-%{srcname} | ||
Summary: %{summary} | ||
BuildRequires: python3-devel | ||
|
||
%description -n python3-%{srcname} %_description | ||
|
||
%prep | ||
%autosetup -n %{srcname}-%{version} | ||
|
||
%build | ||
%py3_build | ||
|
||
%install | ||
%py3_install | ||
|
||
# %check | ||
# %{python3} setup.py test | ||
|
||
# Note that there is no %%files section for the unversioned python module | ||
%files -n python3-%{srcname} | ||
%license LICENSE | ||
%doc README | ||
%{python3_sitelib}/%{srcname}-*.egg-info/ | ||
%{python3_sitelib}/%{srcname}/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import codecs, os.path | ||
from setuptools import setup, find_packages | ||
|
||
|
||
# use README.md as readme | ||
def readme(): | ||
with open('README.md') as f: | ||
return f.read() | ||
|
||
|
||
# get __version__ from a file | ||
def read(rel_path): | ||
here = os.path.abspath(os.path.dirname(__file__)) | ||
with codecs.open(os.path.join(here, rel_path), 'r') as fp: | ||
return fp.read() | ||
|
||
|
||
def get_version(rel_path): | ||
for line in read(rel_path).splitlines(): | ||
if line.startswith('__version__'): | ||
delim = '"' if '"' in line else "'" | ||
return line.split(delim)[1] | ||
else: | ||
raise RuntimeError("Unable to find version string.") | ||
|
||
|
||
setup( | ||
name='systemd-resolved-docker', | ||
url='https://github.com/flaktack/systemd-resolved-docker', | ||
license='MIT', | ||
author='Zsombor Welker', | ||
author_email='flaktack@flaktack.net', | ||
install_requires=["docker", "dnslib", "systemd-python", "dbus-python", "pyroute2"], | ||
description='systemd-resolved and docker DNS integration', | ||
long_description=readme(), | ||
long_description_content_type="text/markdown", | ||
package_dir={ | ||
'': 'src', | ||
}, | ||
packages=find_packages('src'), | ||
entry_points={ | ||
'console_scripts': [ | ||
'systemd-resolved-docker=systemd_resolved_docker.cli:main', | ||
], | ||
}, | ||
excluded=['rpms/*'], | ||
|
||
# extract version from source | ||
version=get_version("src/systemd_resolved_docker/__init__.py"), | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__version__ = '0.0.0' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
#!/usr/bin/env python3 | ||
|
||
import os | ||
import docker | ||
import signal | ||
from systemd import daemon, journal | ||
|
||
from .dockerdnsconnector import DockerDNSConnector | ||
from .utils import find_default_docker_bridge_gateway, find_docker_dns_servers | ||
|
||
|
||
class Handler: | ||
def on_start(self): | ||
daemon.notify('READY=1') | ||
self.log("Started daemon") | ||
|
||
def on_update(self, hosts): | ||
os.system('resolvectl flush-caches') | ||
|
||
message = "Refreshed - %d items (%s)" % ( | ||
len(hosts), ', '.join(["%s/%s" % (host.ip, ','.join(host.host_names)) for host in hosts])) | ||
self.log(message) | ||
|
||
def on_stop(self): | ||
self.log("Stopped daemon") | ||
|
||
def log(self, message): | ||
print(message) | ||
|
||
|
||
def main(): | ||
dns_server = os.environ.get("DNS_SERVER", "127.0.0.53") | ||
default_domain = os.environ.get("DEFAULT_DOMAIN", ".docker") | ||
listen_port = int(os.environ.get("LISTEN_PORT", "53")) | ||
listen_address = os.environ.get("LISTEN_ADDRESS", None) | ||
|
||
tld = os.environ.get('ALLOWED_DOMAINS', None) | ||
if tld is None: | ||
domains = [".docker"] | ||
else: | ||
domains = tld.split(',') if tld and len(tld) > 0 else [] | ||
|
||
cli = docker.from_env() | ||
docker_dns_servers = find_docker_dns_servers(cli) | ||
docker_gateway = find_default_docker_bridge_gateway(cli) | ||
|
||
if listen_address is None or len(listen_address) < 1: | ||
listen_addresses = [entry['gateway'] for entry in docker_gateway] | ||
else: | ||
listen_addresses = listen_address.split(",") | ||
|
||
interface = os.environ.get('DOCKER_INTERFACE', None) | ||
if interface is None or len(interface) < 1: | ||
interface = docker_gateway[0]['interface'] | ||
|
||
handler = Handler() | ||
|
||
connector = DockerDNSConnector(listen_addresses, listen_port, dns_server, domains, default_domain, interface, | ||
handler, cli) | ||
connector.start() | ||
|
||
def sig_handler(signum, frame): | ||
handler.log("Stopping - %s" % signal.Signals(signum)) | ||
connector.stop() | ||
|
||
signal.signal(signal.SIGTERM, sig_handler) | ||
signal.signal(signal.SIGINT, sig_handler) | ||
|
||
signal.pause() | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |
Oops, something went wrong.