add examples to docs site

This commit is contained in:
Bryton Hall 2022-08-29 02:04:47 -04:00 committed by GitHub
parent 53adf2b3b7
commit a76ddefe1c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 328 additions and 119 deletions

View file

@ -0,0 +1,3 @@
---
weight: 20
---

View file

@ -0,0 +1,4 @@
{
deployment = import ./deployment { };
testing = import ./testing { };
}

View file

@ -0,0 +1,11 @@
As a more complete example, let's define some high-level variables and then split our module out into another file as we start to grow.
{{< source "default.nix" >}}
Now we create a module which does a few related things:
- create a `Deployment`
- mount a `ConfigMap` into its pod
- define a `Service`
{{< source "module.nix" >}}

View file

@ -0,0 +1,9 @@
{kubenix ? import ../../../..}:
kubenix.evalModules.x86_64-linux {
module = {kubenix, ...}: {
imports = [./module.nix];
kubenix.project = "example";
kubernetes.version = "1.24";
};
}

View file

@ -0,0 +1,68 @@
{
config,
lib,
pkgs,
kubenix,
...
}: {
imports = with kubenix.modules; [k8s];
kubernetes.resources = {
deployments.nginx.spec = {
replicas = 10;
selector.matchLabels.app = "nginx";
template = {
metadata.labels.app = "nginx";
spec = {
securityContext.fsGroup = 1000;
containers.nginx = {
image = "nginx";
imagePullPolicy = "IfNotPresent";
volumeMounts = {
"/etc/nginx".name = "config";
"/var/lib/html".name = "static";
};
};
volumes = {
config.configMap.name = "nginx-config";
static.configMap.name = "nginx-static";
};
};
};
};
configMaps = {
nginx-config.data."nginx.conf" = ''
user nginx nginx;
daemon off;
error_log /dev/stdout info;
pid /dev/null;
events {}
http {
access_log /dev/stdout;
server {
listen 80;
index index.html;
location / {
root /var/lib/html;
}
}
}
'';
nginx-static.data."index.html" = ''
<html><body><h1>Hello from NGINX</h1></body></html>
'';
};
services.nginx.spec = {
ports = [
{
name = "http";
port = 80;
}
];
selector.app = "nginx";
};
};
}

View file

@ -0,0 +1,9 @@
To define a helm release, use the {{< option "kubernetes.helm.releases" >}} option.
{{< source "default.nix" >}}
Fetch and render the chart just as we did with plain manifests:
```sh
nix eval -f . --json config.kubernetes.generated
```

View file

@ -0,0 +1,16 @@
{kubenix ? import ../../../..}:
kubenix.evalModules.${builtins.currentSystem} {
module = {kubenix, ...}: {
imports = with kubenix.modules; [helm];
kubernetes.helm.releases.example = {
chart = kubenix.lib.helm.fetch {
chart = "nginx";
repo = "https://charts.bitnami.com/bitnami";
sha256 = "sha256-wP3tcBnySx+kvZqfW2W9k665oi8KOI50tCcAl0g9cuw=";
};
values = {
replicaCount = 2;
};
};
};
}

View file

@ -0,0 +1,66 @@
---
weight: 30
---
Instead of deploying a 3rd party image, we can build our own.
We rely on the upstream [`dockerTools`](https://github.com/NixOs/nixpkgs/tree/master/pkgs/built-support/docker) package here.
Specifically, we can use the `buildImage` function to define our image:
{{< source "image.nix" >}}
Then we can import this package into our `docker` module:
{{< source "default.nix" >}}
Now build the image with
```sh
nix build -f . --json config.docker.export
```
Render the generated manifests again and see that it now refers to the newly built tag:
```json
{
"apiVersion": "v1",
"items": [
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"annotations": {
"kubenix/k8s-version": "1.24",
"kubenix/project-name": "kubenix"
},
"labels": {
"kubenix/hash": "ac7e4794c3d37f0884e4512a680a30d20e1d6454"
},
"name": "example"
},
"spec": {
"containers": [
{
"image": "docker.somewhere.io/nginx:w7c63alk7kynqh2mqnzxy9n1iqgdc93s",
"name": "custom"
}
]
}
}
],
"kind": "List",
"labels": {
"kubenix/hash": "ac7e4794c3d37f0884e4512a680a30d20e1d6454",
"kubenix/k8s-version": "1.24",
"kubenix/project-name": "kubenix"
}
}
```
Of course, to actually deploy, we need to push the image to our registry. The script defined at {{< option "docker.copyScript" >}} does just that.
```sh
$(nix build -f . --json config.docker.copyScript | jq -r '.[].outputs.out')
```
<!-- TODO: can we make that `nix run -f . config.docker.copyScript` ? -->

View file

@ -0,0 +1,13 @@
{ kubenix ? import ../../../.. }:
kubenix.evalModules.${builtins.currentSystem} {
module = {kubenix, config, pkgs, ...}: {
imports = with kubenix.modules; [k8s docker];
docker = {
registry.url = "docker.somewhere.io";
images.example.image = pkgs.callPackage ./image.nix {};
};
kubernetes.resources.pods.example.spec.containers = {
custom.image = config.docker.images.example.path;
};
};
}

View file

@ -0,0 +1,20 @@
{
dockerTools,
nginx,
}:
dockerTools.buildLayeredImage {
name = "nginx";
contents = [nginx];
extraCommands = ''
mkdir -p etc
chmod u+w etc
echo "nginx:x:1000:1000::/:" > etc/passwd
echo "nginx:x:1000:nginx" > etc/group
'';
config = {
Cmd = ["nginx" "-c" "/etc/nginx/nginx.conf"];
ExposedPorts = {
"80/tcp" = {};
};
};
}

View file

@ -0,0 +1,67 @@
---
weight: 10
---
The simplest, but not incredibly useful, example is likely deploying a bare pod.
Which we can do with the `kubernetes.resources.pods` option:
{{< source "default.nix" >}}
Here, `example` is an arbitrary string which identifies the pod (just as `ex` identifies a container within the pod).
{{< hint info >}}
**NOTE**
The format under {{< option "kubernetes.resources" true >}} largely mirrors that of the [Kubernetes API](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.25/) which can generally be explored with `kubectl`; e.g.
```sh
kubectl explain poc.spec.containers
```
However, our format uses the plural form and injects resource names where appropriate.
{{< /hint >}}
Create a json manifest with:
```sh
nix eval -f . --json config.kubernetes.generated
```
which should output something like this:
```json
{
"apiVersion": "v1",
"items": [
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"annotations": {
"kubenix/k8s-version": "1.24",
"kubenix/project-name": "kubenix"
},
"labels": {
"kubenix/hash": "6e6ccbb6787f9b600737f8882d2487eeef84af9f"
},
"name": "example"
},
"spec": {
"containers": [
{
"image": "nginx",
"name": "ex"
}
]
}
}
],
"kind": "List",
"labels": {
"kubenix/hash": "6e6ccbb6787f9b600737f8882d2487eeef84af9f",
"kubenix/k8s-version": "1.24",
"kubenix/project-name": "kubenix"
}
}
```

View file

@ -0,0 +1,12 @@
# let's creata a function whose only input is the kubenix package
{kubenix ? import ../../../..}:
# evalModules is our main entrypoint
kubenix.evalModules.${builtins.currentSystem} {
# to it, we pass a module that accepts a (different) kubenix object
module = {kubenix, ...}: {
# in order to define options, we need to import their definitions
imports = with kubenix.modules; [k8s];
# now we have full access to define Kubernetes resources
kubernetes.resources.pods.example.spec.containers.ex.image = "nginx";
};
}

View file

@ -0,0 +1,11 @@
Secrets management requires some extra care as we want to prevent values from
ending up in the, world-readable, nix store.
{{< hint "warning" >}}
**WARNING**
The kubenix secrets story is incomplete. Do not trust it -- it has not been tested.
{{< /hint >}}
The easiest approach is to avoid writing to the store altogether with `nix eval` instead of `nix build`.
This isn't a long-term device and we'll explore integrations with other tools soon(TM).

View file

@ -0,0 +1,13 @@
Testing is still very much in flux but here's a rough example.
{{< source "default.nix" >}}
Where we've defined a might look like:
{{< source "test.nix" >}}
Execute with
```sh
nix eval -f . config.testing.success
```

View file

@ -0,0 +1,17 @@
{kubenix ? import ../../../..}:
kubenix.evalModules.x86_64-linux {
module = {kubenix, ...}: {
imports = with kubenix.modules; [testing];
testing = {
tests = [./test.nix];
common = [
{
features = ["k8s"];
options = {
kubernetes.version = "1.24";
};
}
];
};
};
}

View file

@ -0,0 +1,25 @@
{
lib,
pkgs,
kubenix,
test,
...
}: {
imports = [kubenix.modules.test];
test = {
name = "example";
description = "can reach deployment";
script = ''
@pytest.mark.applymanifest('${test.kubernetes.resultYAML}')
def test_nginx_deployment(kube):
"""Tests whether nginx deployment gets successfully created"""
kube.wait_for_registered(timeout=30)
deployments = kube.get_deployments()
nginx_deploy = deployments.get('nginx')
assert nginx_deploy is not None
status = nginx_deploy.status()
assert status.readyReplicas == 10
'';
};
}