Skip to content

Commit

Permalink
Merge pull request #102 from mlabs-haskell/marton/monitoring
Browse files Browse the repository at this point in the history
Monitoring Module
  • Loading branch information
brainrake authored Oct 28, 2024
2 parents a1963a0 + 7762b9d commit fdddfe2
Show file tree
Hide file tree
Showing 25 changed files with 481 additions and 136 deletions.
20 changes: 19 additions & 1 deletion configurations/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,38 @@
{nixpkgs.hostPlatform = "x86_64-linux";}
];
};
vm-full = inputs.nixpkgs.lib.nixosSystem {
modules = [
self.nixosModules.default
./full.nix
./vm.nix
{nixpkgs.hostPlatform = "x86_64-linux";}
];
};
};
perSystem = _: {
apps = {
vm-preview = {
type = "app";
program = "${self.nixosConfigurations.vm-preview.config.system.build.vm}/bin/run-nixos-vm";
};
vm-full = {
type = "app";
program = "${self.nixosConfigurations.vm-full.config.system.build.vm}/bin/run-nixos-vm";
};
};
devshells.default.commands = [
{
name = "vm-preview";
category = "examples";
command = "${self.nixosConfigurations.vm-preview.config.system.build.vm}/bin/run-nixos-vm";
help = "Start vm with cardano services on the preview network and ports forwarded to host";
help = "Start vm with cardano services on the preview network with ports forwarded to host";
}
{
name = "vm-full";
category = "examples";
command = "${self.nixosConfigurations.vm-full.config.system.build.vm}/bin/run-nixos-vm";
help = "Start vm with all supported cardano services, http proxy and monitoring, with ports forwarded to host";
}
];
};
Expand Down
33 changes: 33 additions & 0 deletions configurations/full.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
cardano = {
network = "preview";
node.enable = true;
ogmios.enable = true;
kupo.enable = true;
db-sync.enable = true;
oura.enable = true;
blockfrost.enable = true;
http.enable = true;
monitoring.enable = true;
# monitoring.hosts = [ "localhost" ];
};

networking.firewall.allowedTCPPorts = [3000 9090];

virtualisation.memorySize = 8192;

virtualisation.forwardPorts = [
{
# prometheus
from = "host";
host.port = 9090;
guest.port = 9090;
}
{
# grafana
from = "host";
host.port = 3000;
guest.port = 3000;
}
];
}
36 changes: 17 additions & 19 deletions docs/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@
inputs,
self,
...
}: let
rootConfig = config;
in {
}: {
imports = [
./render.nix
];
Expand All @@ -17,82 +15,82 @@ in {
sidebarOptions = [
{
anchor = "cardano";
modules = [rootConfig.flake.nixosModules.cardano];
modules = [config.flake.nixosModules.cardano];
namespaces = ["cardano"];
}
{
anchor = "cardano.cli";
modules = [rootConfig.flake.nixosModules.cli];
modules = [config.flake.nixosModules.cli];
namespaces = ["cardano.cli"];
}
{
anchor = "cardano.node";
modules = [rootConfig.flake.nixosModules.node];
modules = [config.flake.nixosModules.node];
namespaces = ["cardano.node"];
}
{
anchor = "services.cardano-node";
modules = [rootConfig.flake.nixosModules.node {services.cardano-node.environment = "mainnet";}];
modules = [config.flake.nixosModules.node {services.cardano-node.environment = "mainnet";}];
namespaces = ["services.cardano-node"];
}
{
anchor = "cardano.ogmios";
modules = [rootConfig.flake.nixosModules.ogmios];
modules = [config.flake.nixosModules.ogmios];
namespaces = ["cardano.ogmios"];
}
{
anchor = "services.ogmios";
modules = [rootConfig.flake.nixosModules.ogmios];
modules = [config.flake.nixosModules.ogmios];
namespaces = ["services.ogmios"];
}
{
anchor = "cardano.kupo";
modules = [rootConfig.flake.nixosModules.kupo];
modules = [config.flake.nixosModules.kupo];
namespaces = ["cardano.kupo"];
}
{
anchor = "services.kupo";
modules = [rootConfig.flake.nixosModules.kupo];
modules = [config.flake.nixosModules.kupo];
namespaces = ["services.kupo"];
}
{
anchor = "cardano.db-sync";
modules = [rootConfig.flake.nixosModules.db-sync];
modules = [config.flake.nixosModules.db-sync];
namespaces = ["cardano.db-sync"];
}
{
anchor = "services.cardano-db-sync";
modules = [(rootConfig.flake.nixosModules.db-sync // {config.services.cardano-db-sync.cluster = "mainnet";})];
modules = [(config.flake.nixosModules.db-sync // {config.services.cardano-db-sync.cluster = "mainnet";})];
namespaces = ["services.cardano-db-sync"];
}
{
anchor = "cardano.http";
modules = [rootConfig.flake.nixosModules.http];
modules = [config.flake.nixosModules.http];
namespaces = ["cardano.http"];
}
{
anchor = "services.http-proxy";
modules = [rootConfig.flake.nixosModules.http];
modules = [config.flake.nixosModules.http];
namespaces = ["services.http-proxy"];
}
{
anchor = "cardano.blockfrost";
modules = [rootConfig.flake.nixosModules.blockfrost];
modules = [config.flake.nixosModules.blockfrost];
namespaces = ["cardano.blockfrost"];
}
{
anchor = "services.blockfrost";
modules = [rootConfig.flake.nixosModules.blockfrost];
modules = [config.flake.nixosModules.blockfrost];
namespaces = ["services.blockfrost"];
}
{
anchor = "cardano.oura";
modules = [rootConfig.flake.nixosModules.oura];
modules = [config.flake.nixosModules.oura];
namespaces = ["cardano.oura"];
}
{
anchor = "services.oura";
modules = [rootConfig.flake.nixosModules.oura];
modules = [config.flake.nixosModules.oura];
namespaces = ["services.oura"];
}
];
Expand Down
70 changes: 70 additions & 0 deletions docs/getting-started/cloud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
## Deploy to the Cloud

⚠ Caution: The templates have an empty root password set in `vm.nix` for convenience. Be sure to remove the `vm.nix` import and use public key authentication before deploying to the cloud.

To deploy the network of nodes and proxy to cloud providers such as AWS, Google Cloud, DigitalOcean, or Hetzner, some additional setup is required that is out of scope for this project as it depends on the deployment workflow. Here is an overview:

### Deploy Cloud Infrastructure

Cloud resources need to be created, for example with an Infrastructure-as-Code tool such as AWS CloudFormation or [OpenTofu](https://opentofu.org/).

#### Cloud Machines

Virtual machines (AWS EC2, droplet, etc.) need to be created, one for each node and one for the proxy. Synchronizing the blockchain takes a long time so auto scaling is not viable without extra setup, eg. using [cardanow](https://github.com/mlabs-haskell/cardanow/) to load snapshots or using shared network storage.

#### Networking

Private networking needs to be set up between the nodes and proxy, either via the cloud provider's native support (AWS VPC, etc.) or VPN such as wireguard.

The nodes should be configured to be reachable only via the private network on which the proxy resides. This can be as simple as disabling public IPs for these machines. More complex setups have several options to configure networking, such as the services' listen addresses (`services.ogmios.host`, and similar NixOS options), OS firewall (`networking.firewall.*`) and cloud firewall (AWS security groups etc.).

#### DNS Records

To make the proxy reachable via a web address from the browser, DNS records need to be added. This is also required for HTTPS. The opinionated default is a separate subdomain for each service, this can be overridden via nginx configuration.

Example DNS records, where the proxy public IP is `12.34.56.78`:

```text
my.example.com A 12.34.56.78
ogmios.my.example.com A 12.34.56.78
kupo.my.example.com A 12.34.56.78
```

Alternatively, a wildcard record may be added for `*.my.example.com`.

### Operating System Configuration and Deployment

NixOS has to be installed on the cloud machines. If the cloud provider does not have NixOS images, this can be achieved starting from mainstream distros like Debian or Ubuntu using [nixos-infect](https://github.com/elitak/nixos-infect) from cloud-init user data. A better option is to generate cloud images, eg. using [nixos-generators]https://github.com/nix-community/nixos-generators) and start the cloud machines from those.

To deploy operating system configuration via SSH, `services.openssh` needs to be configured and `users.users.root.openssh.authorizedKeys.keys` set. Deployment can be done via `nixos-rebuild --flake . --target-host HOST` or using a [deployment app](https://github.com/nix-community/awesome-nix?tab=readme-ov-file#deployment-tools) such as [colmena](https://github.com/zhaofengli/colmena), or integrated into an infrastructure tool like [terraform-nixos](https://github.com/nix-community/terraform-nixos).

#### Node Adresses

The proxy needs to know how to reach the nodes. This is configured in `services.http-proxy.servers`. In the NixOS test environment, nodes are reachable by hostname, because static `hosts` entries are added for them automatically. This is not available in the cloud. Several options exist:

- Use IP addresses. This is the simplest solution but can be inconvenient if private IPs are automatically assigned. Example:
`services.http-proxy.servers = [ "10.0.0.1" "10.0.0.2" "10.0.0.3" ];`
- Add `networking.hosts` entries to the proxy, possibly from the output of other tools such as OpenTofu.
- Use `mdns` for local DNS lookups by hostname.
- Use a local DNS server such as [dnsmasq](https://dnsmasq.org/doc.html), optionally with DHCP.
- Use internal DNS provided by the cloud service (AWS Route53 private hosted zone, etc.).

#### Domain Name

Once DNS records are created for the proxy as above, the domain name needs to be configured. This is also required for HTTPS.

```nix
services.http-proxy.domainName = "my.example.com";
```

The server will now respond to HTTP requests with `Hosts` header set to `my.example.com`, as well as making the services available at `ogmios.my.example.com` etc.

#### HTTPS

To serve public web pages and APIs, it is necessary to protect data integrity and confidentiality during transmission, so [HTTPS](https://en.wikipedia.org/wiki/HTTPS) needs to be enabled on the proxy. Once DNS and domain names are configured as above, this is easily achieved with the following option:

```nix
services.http-proxy.https.enable = true;
```

This will set up [Let's Encrypt ACME TLS certificates](https://letsencrypt.org/how-it-works/) on the proxy server, enable HTTPS in the nginx web server and redirect all HTTP traffic to HTTPS.
73 changes: 2 additions & 71 deletions docs/getting-started/load-balancer.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ An easy way to get started is to use the [flake template](https://zero-to-nix.co
```
mkdir myproject
cd myproject
nix flake init --template github:mlabs-haskell/cardano.nix
nix flake init --template github:mlabs-haskell/cardano.nix#cluster
git init
git add .
```
Expand All @@ -33,79 +33,10 @@ The template provides virtual machine configurations for three nodes and a load

`nix run .#vms`

The services will be available on ports forwarded from localhost: ogmios at http://localhost:8001 and kupo at http://localhost:8002 .
The services will be available on ports forwarded from localhost: ogmios at http://localhost:8001 and kupo at http://localhost:8002 . Grafana is available at http://localhost:8008 .

Press `Ctrl+C` to stop the machines.

## Deploy to the Cloud

To deploy the network of nodes and proxy to cloud providers such as AWS, Google Cloud, DigitalOcean, or Hetzner, some additional setup is required that is out of scope for this project as it depends on the deployment workflow. Here is an overview:

### Deploy Cloud Infrastructure

Cloud resources need to be created, for example with an Infrastructure-as-Code tool such as AWS CloudFormation or [OpenTofu](https://opentofu.org/).

#### Cloud Machines

Virtual machines (AWS EC2, droplet, etc.) need to be created, one for each node and one for the proxy. Synchronizing the blockchain takes a long time so auto scaling is not viable without extra setup, eg. using [cardanow](https://github.com/mlabs-haskell/cardanow/) to load snapshots or using shared network storage.

#### Networking

Private networking needs to be set up between the nodes and proxy, either via the cloud provider's native support (AWS VPC, etc.) or VPN such as wireguard.

The nodes should be configured to be reachable only via the private network on which the proxy resides. This can be as simple as disabling public IPs for these machines. More complex setups have several options to configure networking, such as the services' listen addresses (`services.ogmios.host`, and similar NixOS options), OS firewall (`networking.firewall.*`) and cloud firewall (AWS security groups etc.).

#### DNS Records

To make the proxy reachable via a web address from the browser, DNS records need to be added. This is also required for HTTPS. The opinionated default is a separate subdomain for each service, this can be overridden via nginx configuration.

Example DNS records, where the proxy public IP is `12.34.56.78`:

```text
my.example.com A 12.34.56.78
ogmios.my.example.com A 12.34.56.78
kupo.my.example.com A 12.34.56.78
```

Alternatively, a wildcard record may be added for `*.my.example.com`.

### Operating System Configuration and Deployment

NixOS has to be installed on the cloud machines. If the cloud provider does not have NixOS images, this can be achieved starting from mainstream distros like Debian or Ubuntu using [nixos-infect](https://github.com/elitak/nixos-infect) from cloud-init user data. A better option is to generate cloud images, eg. using [nixos-generators]https://github.com/nix-community/nixos-generators) and start the cloud machines from those.

To deploy operating system configuration via SSH, `services.openssh` needs to be configured and `users.users.root.openssh.authorizedKeys.keys` set. Deployment can be done via `nixos-rebuild --flake . --target-host HOST` or using a [deployment app](https://github.com/nix-community/awesome-nix?tab=readme-ov-file#deployment-tools) such as [colmena](https://github.com/zhaofengli/colmena), or integrated into an infrastructure tool like [terraform-nixos](https://github.com/nix-community/terraform-nixos).

#### Node Adresses

The proxy needs to know how to reach the nodes. This is configured in `services.http-proxy.servers`. In the NixOS test environment, nodes are reachable by hostname, because static `hosts` entries are added for them automatically. This is not available in the cloud. Several options exist:

- Use IP addresses. This is the simplest solution but can be inconvenient if private IPs are automatically assigned. Example:
`services.http-proxy.servers = [ "10.0.0.1" "10.0.0.2" "10.0.0.3" ];`
- Add `networking.hosts` entries to the proxy, possibly from the output of other tools such as OpenTofu.
- Use `mdns` for local DNS lookups by hostname.
- Use a local DNS server such as [dnsmasq](https://dnsmasq.org/doc.html), optionally with DHCP.
- Use internal DNS provided by the cloud service (AWS Route53 private hosted zone, etc.).

#### Domain Name

Once DNS records are created for the proxy as above, the domain name needs to be configured. This is also required for HTTPS.

```nix
services.http-proxy.domainName = "my.example.com";
```

The server will now respond to HTTP requests with `Hosts` header set to `my.example.com`, as well as making the services available at `ogmios.my.example.com` etc.

#### HTTPS

To serve public web pages and APIs, it is necessary to protect data integrity and confidentiality during transmission, so [HTTPS](https://en.wikipedia.org/wiki/HTTPS) needs to be enabled on the proxy. Once DNS and domain names are configured as above, this is easily achieved with the following option:

```nix
services.http-proxy.https.enable = true;
```

This will set up [Let's Encrypt ACME TLS certificates](https://letsencrypt.org/how-it-works/) on the proxy server, enable HTTPS in the nginx web server and redirect all HTTP traffic to HTTPS.

## Further reading

Check out the following documentation:
Expand Down
1 change: 1 addition & 0 deletions docs/mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ nav:
- Run a VM: getting-started/vm.md
- Deploy: getting-started/deploy.md
- Load Balancer: getting-started/load-balancer.md
- Deploy to Cloud: getting-started/cloud.md
- Development:
- development/develop.md
- development/contributing.md
Expand Down
4 changes: 2 additions & 2 deletions docs/render.nix
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,14 @@ in {
system,
...
}: let
inherit (pkgs) stdenv mkdocs python311Packages;
inherit (pkgs) stdenv mkdocs python312Packages;

my-mkdocs =
pkgs.runCommand "my-mkdocs"
{
buildInputs = [
mkdocs
python311Packages.mkdocs-material
python312Packages.mkdocs-material
];
} ''
mkdir -p $out/bin
Expand Down
6 changes: 3 additions & 3 deletions flake.lock

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

Loading

0 comments on commit fdddfe2

Please sign in to comment.