conlink 2.5.2 → 2.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/push.yml +9 -1
- package/README.md +50 -760
- package/docs/.nojekyll +0 -0
- package/docs/_sidebar.md +9 -0
- package/docs/guides/compose-scripts.md +143 -0
- package/docs/guides/examples.md +395 -0
- package/docs/guides/graphviz-rendering.md +32 -0
- package/docs/index.html +33 -0
- package/docs/reference/network-configuration-syntax.md +143 -0
- package/docs/usage-notes.md +50 -0
- package/mdc +5 -2
- package/net2dot.cljs +4 -3
- package/package.json +6 -2
- package/src/conlink/core.cljs +7 -13
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Network Configuration Syntax
|
|
2
|
+
|
|
3
|
+
Network configuration can either be loaded directly from configuration
|
|
4
|
+
files using the `--network-config` option or it can be loaded from
|
|
5
|
+
`x-network` properties contained in docker-compose files using the
|
|
6
|
+
`--compose-file` option. Multiple of each option may be specified and
|
|
7
|
+
all the network configuration will be merged into a final network
|
|
8
|
+
configuration. Both options also support colon separated lists.
|
|
9
|
+
|
|
10
|
+
The network configuration can have four top level keys: `links`,
|
|
11
|
+
`bridges`, `tunnels`, and `commands`.
|
|
12
|
+
|
|
13
|
+
## Links
|
|
14
|
+
|
|
15
|
+
Each link defintion specifies an interface that will be configured in
|
|
16
|
+
a container. Most types have some sort of connection to either the
|
|
17
|
+
conlink/network container or the host network namespace. For example,
|
|
18
|
+
"veth" type links always have their peer end connected to a bridge in
|
|
19
|
+
the conlink/network container and vlan types are children of physical
|
|
20
|
+
interfaces in the host.
|
|
21
|
+
|
|
22
|
+
The following table describes the link properties:
|
|
23
|
+
|
|
24
|
+
| property | link types | format | default | description |
|
|
25
|
+
|-----------|------------|----------------|---------|--------------------------|
|
|
26
|
+
| type | * | string 1 | veth | link/interface type |
|
|
27
|
+
| service | * | string | 2 | compose service |
|
|
28
|
+
| container | * | string | | container name |
|
|
29
|
+
| bridge | veth | string | | conlink bridge / domain |
|
|
30
|
+
| outer-dev | not dummy | string[15] | | conlink/host intf name |
|
|
31
|
+
| dev | * | string[15] | eth0 | container intf name |
|
|
32
|
+
| ip | * | CIDR | | IP CIDR 7 |
|
|
33
|
+
| mac | 3 | MAC | | MAC addr 7 |
|
|
34
|
+
| mtu | * | number 4 | 65535 | intf MTU |
|
|
35
|
+
| route | * | strings 8 | | ip route add args |
|
|
36
|
+
| nat | * | IP | | DNAT/SNAT to IP |
|
|
37
|
+
| netem | * | strings 8 | | tc qdisc NetEm options |
|
|
38
|
+
| mode | 5 | string | | virt intf mode |
|
|
39
|
+
| vlanid | vlan | number | | VLAN ID |
|
|
40
|
+
| forward | veth | strings 6 8 | | forward conlink ports 7 |
|
|
41
|
+
| ethtool | veth | strings 8 | | ethtool settings |
|
|
42
|
+
|
|
43
|
+
- 1 - veth, dummy, vlan, ipvlan, macvlan, ipvtap, macvtap
|
|
44
|
+
- 2 - defaults to outer compose service
|
|
45
|
+
- 3 - not ipvlan/ipvtap
|
|
46
|
+
- 4 - max MTU of parent device for \*vlan, \*vtap types
|
|
47
|
+
- 5 - macvlan, macvtap, ipvlan, ipvtap
|
|
48
|
+
- 6 - string syntax: `conlink_port:container_port/proto`
|
|
49
|
+
- 7 - offset by scale/replica index
|
|
50
|
+
- 8 - either a single string or an array of strings
|
|
51
|
+
|
|
52
|
+
Each link has a 'type' key that defaults to "veth" and each link
|
|
53
|
+
definition must also have either a `service` key or a `container` key.
|
|
54
|
+
If the link is defined in the service of a compose file then the value
|
|
55
|
+
of `service` will default to the name of that service.
|
|
56
|
+
|
|
57
|
+
The `container` key is a fully qualified container name that this link
|
|
58
|
+
will apply to. The `service` key is the name of a docker-compose
|
|
59
|
+
service that this link applies to. In the case of a `service` link, if
|
|
60
|
+
more than one replica is started for that service, then the mac, and
|
|
61
|
+
ip values in the link definition will be incremented by the service
|
|
62
|
+
index - 1.
|
|
63
|
+
|
|
64
|
+
All link definitions support the following optional properties: dev,
|
|
65
|
+
ip, mtu, route, nat, netem. If dev is not specified then it will
|
|
66
|
+
default to "eth0". For `*vlan` type interfaces, mtu cannot be larger
|
|
67
|
+
than the MTU of the parent (outer-dev) device.
|
|
68
|
+
|
|
69
|
+
For the `netem` property, refer to the `netem` man page. The `OPTIONS`
|
|
70
|
+
grammar defines the valid strings for the `netem` property.
|
|
71
|
+
|
|
72
|
+
The `forward` property is an array of strings that defines ports to
|
|
73
|
+
forward from the conlink container into the container over this link.
|
|
74
|
+
Traffic arriving on the conlink container's docker interface of type
|
|
75
|
+
`proto` and destined for port `conlink_port` is forwarded over this
|
|
76
|
+
link to the container IP and port `container_port` (`ip` is required).
|
|
77
|
+
The initial port (`conlink_port`) is offset by the service
|
|
78
|
+
replica/scale number (minus 1). So if the first replica has port 80
|
|
79
|
+
forwarded then the second replica will have port 81 forwarded.
|
|
80
|
+
For publicly publishing a port, the conlink container needs to be on
|
|
81
|
+
a docker network and the `conlink_port` should match the target port
|
|
82
|
+
of a docker published port (for the conlink container).
|
|
83
|
+
|
|
84
|
+
For the `ethtool` property, refer to the `ethtool` man page. The
|
|
85
|
+
syntax for each ethtool setting is basically the ethtool command line
|
|
86
|
+
arguments without the "devname. So the equivalent of the ethtool
|
|
87
|
+
command `ethtool --offload eth0 rx off` would be link configuration
|
|
88
|
+
`{dev: eth0, ethtool: ["--offload rx off"], ...}`.
|
|
89
|
+
|
|
90
|
+
## Bridges
|
|
91
|
+
|
|
92
|
+
The bridge settings currently only support the "mode" setting. If
|
|
93
|
+
the mode is not specified in this section or the section is omitted
|
|
94
|
+
entirely, then bridges specified in the links configuration will
|
|
95
|
+
default to the value of the `--default-bridge-mode` parameter (which
|
|
96
|
+
itself defaults to "auto").
|
|
97
|
+
|
|
98
|
+
The following table describes the bridge properties:
|
|
99
|
+
|
|
100
|
+
| property | format | description |
|
|
101
|
+
|-----------|---------|--------------------------------|
|
|
102
|
+
| bridge | string | conlink bridge / domain name |
|
|
103
|
+
| mode | string | auto, ovs, or linux |
|
|
104
|
+
|
|
105
|
+
## Tunnels
|
|
106
|
+
|
|
107
|
+
Tunnels links/interfaces will be created and attached to the specified
|
|
108
|
+
bridge. Any containers with links to the same bridge will share
|
|
109
|
+
a broadcast domain with the tunnel link.
|
|
110
|
+
|
|
111
|
+
The following table describes the tunnel properties:
|
|
112
|
+
|
|
113
|
+
| property | format | description |
|
|
114
|
+
|-----------|---------|----------------------------|
|
|
115
|
+
| type | string | geneve or vxlan |
|
|
116
|
+
| bridge | string | conlink bridge / domain |
|
|
117
|
+
| remote | IP | remote host addr |
|
|
118
|
+
| vni | number | Virtual Network Identifier |
|
|
119
|
+
| netem | string | tc qdisc NetEm options |
|
|
120
|
+
|
|
121
|
+
Each tunnel definition must have the keys: type, bridge, remote, and
|
|
122
|
+
vni. The netem optional property also applies to tunnel interfaces.
|
|
123
|
+
|
|
124
|
+
## Commands
|
|
125
|
+
|
|
126
|
+
Commands will be executed in parallel within the matching container
|
|
127
|
+
once all links are succesfully configured for that container.
|
|
128
|
+
|
|
129
|
+
The following table describes the command properties:
|
|
130
|
+
|
|
131
|
+
| property | format | description |
|
|
132
|
+
|-----------|------------------|----------------------------|
|
|
133
|
+
| service | string | compose service |
|
|
134
|
+
| container | string | container name |
|
|
135
|
+
| command | array or string | command or shell string |
|
|
136
|
+
|
|
137
|
+
Each command defintion must have a `command` key and either
|
|
138
|
+
a `service` or `container` key. The `service` and `container` keys are
|
|
139
|
+
defined the same as for link properties.
|
|
140
|
+
|
|
141
|
+
If the `command` value is an array then the command and arguments will
|
|
142
|
+
be executed directly. If the `command` is a string then the string
|
|
143
|
+
will be wrapped in `sh -c STRING` for execution.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Usage Notes
|
|
2
|
+
|
|
3
|
+
Conlink runs as another container in the Docker Compose project. As a
|
|
4
|
+
result, there are some important things to know when using conlink
|
|
5
|
+
instead of the default Docker Compose networking.
|
|
6
|
+
|
|
7
|
+
## Asynchronous startup
|
|
8
|
+
|
|
9
|
+
The conlink managed container links are created after the main process
|
|
10
|
+
in the container starts executing. This is different from normal
|
|
11
|
+
docker behavior where the interfaces are created and configured before
|
|
12
|
+
the main process starts. This means the interfaces for those
|
|
13
|
+
links will not be immediately present and the container process will
|
|
14
|
+
need to account for this asynchronous interface behavior. The `node`
|
|
15
|
+
service in `examples/test2-compose.yaml` shows a simple example of
|
|
16
|
+
a container command that will wait for an interface to appear before
|
|
17
|
+
continuing with another command.
|
|
18
|
+
|
|
19
|
+
## System Capabilities/Permissions
|
|
20
|
+
|
|
21
|
+
The conlink container needs to have a superset of the network related
|
|
22
|
+
system capabilities of the containers that it will connect to. At
|
|
23
|
+
a minimum `SYS_ADMIN` and `NET_ADMIN` are required but depending on
|
|
24
|
+
what the other containers require then those additional capabilities
|
|
25
|
+
will also be required for the conlink container. In particular, if the
|
|
26
|
+
container uses systemd, then it will likely use `SYS_NICE` and
|
|
27
|
+
`NET_BROADCAST` and conlink will likewise need those capabilities.
|
|
28
|
+
|
|
29
|
+
## Bridging: Open vSwtich/OVS, Linux bridge, and patch
|
|
30
|
+
|
|
31
|
+
Conlink connects container veth links together via a bridge or via a
|
|
32
|
+
direct patch. All veth type links must have a `bridge` property that
|
|
33
|
+
defines which links will be connected together (i.e. the same
|
|
34
|
+
broadcast domain). The default bridge mode is defined by the
|
|
35
|
+
`--default-bridge-mode` parameter and defaults to "auto". If a bridge
|
|
36
|
+
is set to mode "auto" then conlink will check if the kernel has the
|
|
37
|
+
`openvswitch` kernel module loaded and if so it will create an Open
|
|
38
|
+
vSwitch/OVS bridge/switch for that bridge, otherwise it will create a
|
|
39
|
+
regular Linux bridge (e.g. brctl). If any bridges are explicitly
|
|
40
|
+
defined with an "ovs" mode and the kernel does not have support then
|
|
41
|
+
conlink will stop/error on startup.
|
|
42
|
+
|
|
43
|
+
The "patch" mode will connect two links together using tc qdisc
|
|
44
|
+
ingress filters. This type connection is equivalent to a patch panel
|
|
45
|
+
("bump-in-the-wire") connection and all traffic will be passed between
|
|
46
|
+
the two links unchanged unlike Linux and OVS bridges which typically
|
|
47
|
+
block certain bridge control broadcast traffic). The primary downside
|
|
48
|
+
of "patch" connections is that they limited to two links whereas "ovs"
|
|
49
|
+
and "linux" bridge modes can support many links connected into the
|
|
50
|
+
same bridge (broadcast domain).
|
package/mdc
CHANGED
|
@@ -22,6 +22,7 @@ which ${RESOLVE_DEPS} >/dev/null 2>/dev/null \
|
|
|
22
22
|
|
|
23
23
|
# Resolve mode directory paths
|
|
24
24
|
|
|
25
|
+
MDC_CLI="${0} ${*}"
|
|
25
26
|
MODE_SPEC="${1}"; shift
|
|
26
27
|
RESOLVED_MODES="$(${RESOLVE_DEPS} --path "${MODES_DIR}" --format=paths ${MODE_SPEC})"
|
|
27
28
|
|
|
@@ -29,8 +30,8 @@ RESOLVED_MODES="$(${RESOLVE_DEPS} --path "${MODES_DIR}" --format=paths ${MODE_SP
|
|
|
29
30
|
# to the same root directory. Create files dir.
|
|
30
31
|
|
|
31
32
|
COMPOSE_FILE=./.compose-empty.yaml
|
|
32
|
-
|
|
33
|
-
echo -e "
|
|
33
|
+
echo "### mdc command line: ${MDC_CLI}" > ${ENV_FILE}-mdc-tmp
|
|
34
|
+
echo -e "services: {}" > ./.compose-empty.yaml
|
|
34
35
|
|
|
35
36
|
vecho "Removing ${MDC_FILES_DIR}"
|
|
36
37
|
case "$(basename ${MDC_FILES_DIR})" in
|
|
@@ -73,6 +74,8 @@ for resolved in ${RESOLVED_MODES}; do
|
|
|
73
74
|
for efile in ${efiles}; do
|
|
74
75
|
if [ -e "${efile}" ]; then
|
|
75
76
|
echo "### mdc begin mode ${mode} (${efile})" >> ${ENV_FILE}-mdc-tmp
|
|
77
|
+
# Add MDC_MODE_ prefixed environment variable for each mode
|
|
78
|
+
echo "MDC_MODE_${mode//[^a-zA-Z]/_}=enabled" >> ${ENV_FILE}-mdc-tmp
|
|
76
79
|
vecho "cat ${efile} >> ${ENV_FILE}-mdc-tmp"
|
|
77
80
|
cat ${efile} >> ${ENV_FILE}-mdc-tmp
|
|
78
81
|
echo >> ${ENV_FILE}-mdc-tmp
|
package/net2dot.cljs
CHANGED
|
@@ -57,11 +57,12 @@
|
|
|
57
57
|
(let [graph (digraph {:splines true :compound true})
|
|
58
58
|
host (subgraph graph "cluster_host" "host system" HOST-PROPS)
|
|
59
59
|
conlink (subgraph host "cluster_conlink" "conlink/network" CONLINK-PROPS)
|
|
60
|
+
links (->> network-config :services vals (map :links) (apply concat))
|
|
60
61
|
bridges (reduce
|
|
61
62
|
#(->> (subgraph conlink (str "cluster_bridge_" %2)
|
|
62
63
|
%2 BRIDGE-PROPS)
|
|
63
64
|
(assoc %1 %2))
|
|
64
|
-
{} (
|
|
65
|
+
{} (keys (:bridges network-config)))
|
|
65
66
|
services (reduce
|
|
66
67
|
#(->> (subgraph host (str "cluster_service_" (dot-id %2))
|
|
67
68
|
(str "service '" (name %2) "'") SVC-PROPS)
|
|
@@ -73,7 +74,7 @@
|
|
|
73
74
|
(assoc %1 %2))
|
|
74
75
|
{} (keys (:containers network-config)))]
|
|
75
76
|
|
|
76
|
-
(doseq [link
|
|
77
|
+
(doseq [link links]
|
|
77
78
|
(let [{:keys [service container dev outer-dev bridge base]} link
|
|
78
79
|
cname (or service container)
|
|
79
80
|
cnode (get (if service services containers) (keyword cname))
|
|
@@ -85,7 +86,7 @@
|
|
|
85
86
|
"-" (name dev)))
|
|
86
87
|
out-id (str "out-" outer-dev)
|
|
87
88
|
out-parent (condp = (keyword base)
|
|
88
|
-
:conlink (get bridges (:bridge bridge))
|
|
89
|
+
:conlink (get bridges (keyword (:bridge bridge)))
|
|
89
90
|
:host host)
|
|
90
91
|
{:keys [type vlanid]} link
|
|
91
92
|
[elabel iprops] (if (= "host" base)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "conlink",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.4",
|
|
4
4
|
"description": "conlink - Declarative Low-Level Networking for Containers",
|
|
5
5
|
"repository": "https://github.com/LonoCloud/conlink",
|
|
6
6
|
"license": "SEE LICENSE IN LICENSE",
|
|
@@ -14,8 +14,12 @@
|
|
|
14
14
|
"yaml": "^2.2.1"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@lonocloud/dctest": "0.
|
|
17
|
+
"@lonocloud/dctest": "^0.3.1",
|
|
18
|
+
"docsify-cli": "^4.4.4",
|
|
18
19
|
"shadow-cljs": "^2.25.7",
|
|
19
20
|
"source-map-support": "^0.5.21"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"serve-docs": "docsify serve ./docs"
|
|
20
24
|
}
|
|
21
25
|
}
|
package/src/conlink/core.cljs
CHANGED
|
@@ -615,17 +615,9 @@ General Options:
|
|
|
615
615
|
if no container ID can be determined (e.g. we are probably not
|
|
616
616
|
running in a container)"
|
|
617
617
|
[]
|
|
618
|
-
(P/
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
#(vector "" ""))
|
|
622
|
-
;; docker
|
|
623
|
-
d-cgroups (map second (re-seq #"/docker/([^/\n]*)" cgroup))
|
|
624
|
-
;; podman (root)
|
|
625
|
-
p-cgroups (map second (re-seq #"libpod-([^/.\n]*)" cgroup))
|
|
626
|
-
;; general fallback
|
|
627
|
-
o-mounts (map second (re-seq #"containers/([^/]{64})/.*/etc/hosts" mountinfo))]
|
|
628
|
-
(first (concat d-cgroups p-cgroups o-mounts))))
|
|
618
|
+
(P/->> (P/catch (read-file "/proc/self/mountinfo" "utf8") (constantly ""))
|
|
619
|
+
(re-find #".*containers/([^/]{64})/.*/etc/hosts")
|
|
620
|
+
second))
|
|
629
621
|
|
|
630
622
|
(defn list-containers
|
|
631
623
|
"Return a sequence of container objects optionally limited to those
|
|
@@ -906,7 +898,7 @@ General Options:
|
|
|
906
898
|
docker-eth0-addresses (when docker-eth0? (intf-ipv4-addresses "eth0"))
|
|
907
899
|
_ (swap! ctx merge {:kmod-ovs? kmod-ovs?
|
|
908
900
|
:kmod-mirred? kmod-mirred?
|
|
909
|
-
:docker-eth0? docker-eth0?
|
|
901
|
+
:docker-eth0? (or docker-eth0? show-config)
|
|
910
902
|
:docker-eth0-address (first docker-eth0-addresses)})
|
|
911
903
|
network-config (P/-> (load-configs compose-file network-file)
|
|
912
904
|
(interpolate-walk env)
|
|
@@ -979,7 +971,9 @@ General Options:
|
|
|
979
971
|
(P/let
|
|
980
972
|
[event-filter {"event" ["start" "die"]}
|
|
981
973
|
;; Listen for docker and/or podman events
|
|
982
|
-
|
|
974
|
+
;; NOTE: sometimes (podman on macos) this blocks
|
|
975
|
+
;; until the first event. Wrap it to skip await.
|
|
976
|
+
_ [(docker-listen client event-filter handle-event)]
|
|
983
977
|
containers ^obj (list-containers client)]
|
|
984
978
|
;; Generate fake events for existing containers
|
|
985
979
|
(P/all (for [container containers
|