Skip to content

Commit

Permalink
Add support for additional container network configuration to support…
Browse files Browse the repository at this point in the history
… IPv6-only devices. (#1374)

Add support for additional container network configuration to support IPv6-only devices.
  • Loading branch information
shantanu1singh authored Jun 27, 2019
1 parent 4e8e005 commit 9001b8e
Show file tree
Hide file tree
Showing 15 changed files with 583 additions and 35 deletions.
23 changes: 21 additions & 2 deletions doc/networking.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,34 @@ This means that a route from the `azure-iot-edge` subnet to the internet must ex

### Configuring `azure-iot-edge`

This network name is configured via the `moby_runtime` section of the `iotedged`'s config file (`/etc/iotedge/config.yaml):
This network is configured via the `moby_runtime` section of the `iotedged`'s config file (`/etc/iotedge/config.yaml):

```yaml
moby_runtime:
uri: "unix:///var/run/docker.sock"
network: "azure-iot-edge"
```
Any changes to the specific settings of this network must be made out of band, via the Moby Engine.
Additional container network configuration such as enabling IPv6 networking and providing the IPAM settings can be achieved by specifying the relevant configuration in the network settings.
```yaml
moby_runtime:
uri: "unix:///var/run/docker.sock"
network:
name: "azure-iot-edge"
ipv6: true
ipam:
-
gateway: '172.18.0.1'
subnet: '172.18.0.0/16'
ip_range: '172.18.0.0/16'
-
gateway: '2021:ffff:e0:3b1:1::1'
subnet: '2021:ffff:e0:3b1:1::/80'
ip_range: '2021:ffff:e0:3b1:1::/80'
```
Any changes to other specific settings of this network must be made out of band, via the Moby Engine.
Read the Docker [networking guide][4] for more information.
This network can be configured before starting IoT Edge, as the `iotedged` does a "get or create" operation on the network when starting.
Expand Down
6 changes: 6 additions & 0 deletions doc/troubleshoot-checks.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ This check validates that a DNS server has been specified in the container engin

It is possible to specify a DNS server in the Edge device's deployment instead of in the container engine's `daemon.json`, and the tool does not detect this. If you have done so, you should ignore this warning.

## IPv6 network configuration

This check validates that if IPv6 container network configuration is enabled in `config.yaml` (by setting the value of `moby_runtime.network.ipv6` field to `true`), the container engine's `daemon.json` file also has IPv6 support enabled. To enable IPv6 support for the container runtime, please refer to this guide <https://aka.ms/iotedge-docker-ipv6>.

IPv6 container runtime network configuration is currently not supported for the Windows operating system and this check fails if IPv6 support is enabled in the container enginer's `daemon.json` file.

## production readiness: certificates (*warning*)

This check validates that device CA and trusted CA certificates have been defined in the `certificates` section of the `config.yaml`. If these certificates are not specified, the device operates in quickstart mode and is not supported in production. Certificate management best practices are documented at <https://aka.ms/iotedge-prod-checklist-certs>
Expand Down
6 changes: 3 additions & 3 deletions edgelet/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 31 additions & 2 deletions edgelet/contrib/config/linux/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -247,9 +247,38 @@ homedir: "/var/lib/iotedge"
#
# uri - configures the uri for the container runtime.
# network - configures the network on which the containers will be created.
#
#
# Additional container network configuration such as enabling IPv6 networking
# and providing the IPAM settings can be achieved by specifying the relevant
# configuration in the network settings.
#
# network:
# name: "azure-iot-edge"
# ipv6: true
# ipam:
# -
# gateway: '172.18.0.1'
# subnet: '172.18.0.0/16'
# ip_range: '172.18.0.0/16'
# -
# gateway: '2021:ffff:e0:3b1:1::1'
# subnet: '2021:ffff:e0:3b1:1::/80'
# ip_range: '2021:ffff:e0:3b1:1::/80'
###############################################################################

moby_runtime:
uri: "unix:///var/run/docker.sock"
# network: "azure-iot-edge"
# network: "azure-iot-edge"
#
# network:
# name: "azure-iot-edge"
# ipv6: true
# ipam:
# -
# gateway: '172.18.0.1'
# subnet: '172.18.0.0/16'
# ip_range: '172.18.0.0/16'
# -
# gateway: '2021:ffff:e0:3b1:1::1'
# subnet: '2021:ffff:e0:3b1:1::/80'
# ip_range: '2021:ffff:e0:3b1:1::/80'
33 changes: 31 additions & 2 deletions edgelet/contrib/config/linux/debian/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,38 @@ homedir: "/var/lib/iotedge"
#
# uri - configures the uri for the container runtime.
# network - configures the network on which the containers will be created.
#
#
# Additional container network configuration such as enabling IPv6 networking
# and providing the IPAM settings can be achieved by specifying the relevant
# configuration in the network settings.
#
# network:
# name: "azure-iot-edge"
# ipv6: true
# ipam:
# -
# gateway: '172.18.0.1'
# subnet: '172.18.0.0/16'
# ip_range: '172.18.0.0/16'
# -
# gateway: '2021:ffff:e0:3b1:1::1'
# subnet: '2021:ffff:e0:3b1:1::/80'
# ip_range: '2021:ffff:e0:3b1:1::/80'
###############################################################################

moby_runtime:
uri: "unix:///var/run/docker.sock"
# network: "azure-iot-edge"
# network: "azure-iot-edge"
#
# network:
# name: "azure-iot-edge"
# ipv6: true
# ipam:
# -
# gateway: '172.18.0.1'
# subnet: '172.18.0.0/16'
# ip_range: '172.18.0.0/16'
# -
# gateway: '2021:ffff:e0:3b1:1::1'
# subnet: '2021:ffff:e0:3b1:1::/80'
# ip_range: '2021:ffff:e0:3b1:1::/80'
1 change: 1 addition & 0 deletions edgelet/docker-rs/src/apis/network_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ where
if let Some(ref user_agent) = configuration.user_agent {
req.header(http::header::USER_AGENT, &**user_agent);
}

let mut req = req
.body(hyper::Body::from(serialized))
.expect("could not build hyper::Request");
Expand Down
2 changes: 1 addition & 1 deletion edgelet/docker-rs/src/models/ipam.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use serde_derive::{Deserialize, Serialize};
#[allow(unused_imports)]
use serde_json::Value;

#[derive(Debug, Serialize, Deserialize)]
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Ipam {
/// Name of the IPAM driver to use.
#[serde(rename = "Driver", skip_serializing_if = "Option::is_none")]
Expand Down
64 changes: 50 additions & 14 deletions edgelet/edgelet-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,13 @@ use url::Url;

use edgelet_core::crypto::MemoryKey;
use edgelet_core::watchdog::RetryLimit;
use edgelet_core::MobyNetwork;
use edgelet_core::ModuleSpec;
use edgelet_utils::log_failure;

mod yaml_file_source;
use yaml_file_source::YamlFileSource;

/// This is the name of the network created by the iotedged
const DEFAULT_NETWORKID: &str = "azure-iot-edge";

/// This is the default connection string
pub const DEFAULT_CONNECTION_STRING: &str = "<ADD DEVICE CONNECTION STRING HERE>";

Expand Down Expand Up @@ -324,20 +322,16 @@ impl Listen {
pub struct MobyRuntime {
#[serde(with = "url_serde")]
uri: Url,
network: String,
network: MobyNetwork,
}

impl MobyRuntime {
pub fn uri(&self) -> &Url {
&self.uri
}

pub fn network(&self) -> &str {
if self.network.is_empty() {
&DEFAULT_NETWORKID
} else {
&self.network
}
pub fn network(&self) -> &MobyNetwork {
&self.network
}
}

Expand Down Expand Up @@ -531,6 +525,7 @@ pub enum ParseManualDeviceConnectionStringError {
mod tests {
use super::*;
use config::{Config, File, FileFormat};
use edgelet_core::{IpamConfig, DEFAULT_NETWORKID};
use edgelet_docker::DockerConfig;
use std::cmp::Ordering;
use std::fs::File as FsFile;
Expand Down Expand Up @@ -573,6 +568,8 @@ mod tests {
static BAD_SETTINGS_DPS_X5092: &str = "test/linux/bad_settings.dps.x509.2.yaml";
#[cfg(unix)]
static GOOD_SETTINGS_EXTERNAL: &str = "test/linux/sample_settings.external.yaml";
#[cfg(unix)]
static GOOD_SETTINGS_NETWORK: &str = "test/linux/sample_settings.network.yaml";

#[cfg(windows)]
static GOOD_SETTINGS: &str = "test/windows/sample_settings.yaml";
Expand Down Expand Up @@ -610,6 +607,8 @@ mod tests {
static BAD_SETTINGS_DPS_X5092: &str = "test/windows/bad_settings.dps.x509.2.yaml";
#[cfg(windows)]
static GOOD_SETTINGS_EXTERNAL: &str = "test/windows/sample_settings.external.yaml";
#[cfg(windows)]
static GOOD_SETTINGS_NETWORK: &str = "test/windows/sample_settings.network.yaml";

fn unwrap_manual_provisioning(p: &Provisioning) -> String {
match p {
Expand Down Expand Up @@ -822,6 +821,43 @@ mod tests {
};
}

#[test]
fn network_get_settings() {
let settings = Settings::<DockerConfig>::new(Some(Path::new(GOOD_SETTINGS_NETWORK)));
println!("{:?}", settings);
assert!(settings.is_ok());
let s = settings.unwrap();
let moby_runtime = s.moby_runtime();
assert_eq!(
moby_runtime.uri().to_owned().into_string(),
"http://localhost:2375/".to_string()
);

let network = moby_runtime.network();
assert_eq!(network.name(), "azure-iot-edge");
match network {
MobyNetwork::Network(moby_network) => {
assert_eq!(moby_network.ipv6().unwrap(), true);
let ipam_spec = moby_network.ipam().expect("Expected IPAM specification.");
let ipam_config = ipam_spec.config().expect("Expected IPAM configuration.");
let ipam_1 = IpamConfig::default()
.with_gateway("172.18.0.1".to_string())
.with_ip_range("172.18.0.0/16".to_string())
.with_subnet("172.18.0.0/16".to_string());
let ipam_2 = IpamConfig::default()
.with_gateway("2001:4898:e0:3b1:1::1".to_string())
.with_ip_range("2001:4898:e0:3b1:1::/80".to_string())
.with_subnet("2001:4898:e0:3b1:1::/80".to_string());
let expected_ipam_config: Vec<IpamConfig> = vec![ipam_1, ipam_2];

ipam_config.iter().for_each(|ipam_config| {
assert!(expected_ipam_config.contains(ipam_config));
});
}
MobyNetwork::Name(_name) => panic!("Unexpected network configuration."),
};
}

#[test]
fn diff_with_same_cached_returns_false() {
let tmp_dir = TempDir::new("blah").unwrap();
Expand Down Expand Up @@ -915,15 +951,15 @@ mod tests {
fn network_default() {
let moby1 = MobyRuntime {
uri: Url::parse("http://test").unwrap(),
network: "".to_string(),
network: MobyNetwork::Name("".to_string()),
};
assert_eq!(DEFAULT_NETWORKID, moby1.network());
assert_eq!(DEFAULT_NETWORKID, moby1.network().name());

let moby2 = MobyRuntime {
uri: Url::parse("http://test").unwrap(),
network: "some-network".to_string(),
network: MobyNetwork::Name("some-network".to_string()),
};
assert_eq!("some-network", moby2.network());
assert_eq!("some-network", moby2.network().name());
}

#[test]
Expand Down
46 changes: 46 additions & 0 deletions edgelet/edgelet-config/test/linux/sample_settings.network.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

# Configures the provisioning mode
provisioning:
source: "manual"
device_connection_string: "HostName=something.something.com;DeviceId=something;SharedAccessKey=QXp1cmUgSW9UIEVkZ2U="
agent:
name: "edgeAgent"
type: "docker"
env:
abc: "value1"
acd: "value2"
config:
image: "microsoft/azureiotedge-agent:1.0"
auth: {}
hostname: "localhost"

watchdog:
max_retries: 3

# Sets the connection uris for clients
connect:
workload_uri: "http://localhost:8081"
management_uri: "http://localhost:8080"

# Sets the uris to listen on
# These can be different than the connect uris.
# For instance, when using the fd:// scheme for systemd
listen:
workload_uri: "http://0.0.0.0:8081"
management_uri: "http://0.0.0.0:8080"
homedir: "/tmp"
moby_runtime:
uri: "http://localhost:2375"
network:
name: "azure-iot-edge"
ipv6: true
ipam:
config:
-
gateway: '172.18.0.1'
subnet: '172.18.0.0/16'
ip_range: '172.18.0.0/16'
-
gateway: '2001:4898:e0:3b1:1::1'
subnet: '2001:4898:e0:3b1:1::/80'
ip_range: '2001:4898:e0:3b1:1::/80'
Loading

0 comments on commit 9001b8e

Please sign in to comment.