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.
@@ -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
- cat /dev/null > ${ENV_FILE}-mdc-tmp
33
- echo -e "version: '2.4'\nservices: {}" > ./.compose-empty.yaml
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
- {} (map :bridge (keep :bridge (:links network-config))))
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 (:links network-config)]
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.2",
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.1.1",
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
  }
@@ -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/let [[cgroup mountinfo]
619
- , (P/catch (P/all [(read-file "/proc/self/cgroup" "utf8")
620
- (read-file "/proc/self/mountinfo" "utf8")])
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
- _ (docker-listen client event-filter handle-event)
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