Skip to content

Commit

Permalink
update k8s objects and workflows
Browse files Browse the repository at this point in the history
  • Loading branch information
drmorr0 committed Jan 25, 2024
1 parent 4900013 commit b0bad12
Show file tree
Hide file tree
Showing 9 changed files with 377 additions and 140 deletions.
49 changes: 49 additions & 0 deletions .github/workflows/k8s_plan.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Compute k8s plan

on:
pull_request:
paths:
- 'k8s/**'

jobs:
plan:
runs-on: ubuntu-latest

steps:
- name: Check out master
uses: actions/checkout@v4
with:
ref: drmorr/check-graph-names
submodules: recursive

- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install Poetry
uses: snok/install-poetry@v1

- name: Compile k8s charts
run: make k8s

- name: Check out PR
uses: actions/checkout@v4
with:
clean: false

- name: Compute dag/diff
run: make k8s

- name: Save artifacts
run: |
mkdir -p ./artifacts
echo ${{ github.event.number }} > ./artifacts/PR
mv .build/dag.mermaid ./artifacts/dag.mermaid
mv .build/k8s.df ./artifacts/k8s.df
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: k8s-plan-artifacts
path: artifacts/
30 changes: 21 additions & 9 deletions k8s/main.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,32 @@
#!/usr/bin/env python
from cdk8s import App
import os

import fireconfig as fire
from sk_cloudprov import SKCloudProv
from sk_ctrl import SKController
from sk_tracer import SKTracer
from sk_vnode import SKVnode
from test_deployment import TestDeployment

DAG_FILENAME = "dag.mermaid"
DIFF_FILENAME = "k8s.df"


if __name__ == "__main__":
app = App()
namespace = "simkube"
dag_path = f"{os.getenv('BUILD_DIR')}/{DAG_FILENAME}"
diff_path = f"{os.getenv('BUILD_DIR')}/{DIFF_FILENAME}"
graph, diff = fire.compile({
"kube-system": [SKCloudProv()],
"simkube": [
SKVnode(),
SKTracer(),
SKController(),
TestDeployment(),
],
}, dag_path)

skprov = SKCloudProv(app, namespace)
SKVnode(app, namespace)
SKTracer(app, namespace)
SKController(app, namespace)
TestDeployment(app, namespace)
with open(dag_path, "w") as f:
f.write(graph)

app.synth()
with open(diff_path, "w") as f:
f.write(diff)
199 changes: 195 additions & 4 deletions k8s/poetry.lock

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions k8s/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ authors = ["David Morrison <[email protected]>"]

[tool.poetry.dependencies]
python = "^3.11"
cdk8s = "^2.24.0"
fireconfig = { git = "https://github.com/acrlabs/fireconfig", rev = "05fcd90" }
cdk8s = "^2"
fireconfig = { git = "https://github.com/acrlabs/fireconfig", rev = "e8c70b5" }

[tool.poetry.group.dev.dependencies]
mypy = "^1.4.1"
mypy = "^1"

[build-system]
requires = ["poetry-core"]
Expand Down
107 changes: 54 additions & 53 deletions k8s/sk_cloudprov.py
Original file line number Diff line number Diff line change
@@ -1,76 +1,77 @@
import os

import fireconfig as fire
from cdk8s import Chart
from constructs import Construct
from fireconfig import k8s
from fireconfig.types import Capability
from fireconfig.types import TaintEffect

CLOUDPROV_ID = "sk-cloudprov"
AUTOSCALER_ID = "cluster-autoscaler"
CA_CONFIG_PATH = "config.yml"
APP_KEY = "app"
GRPC_PORT = 8086
CA_CONFIG_YML = """---
address: {}
address: {}:{}
"""


class SKCloudProv(Chart):
def __init__(self, scope: Construct, namespace: str):
super().__init__(scope, CLOUDPROV_ID, disable_resource_name_hashes=True)
def _make_cloud_provider():
try:
with open(os.getenv('BUILD_DIR') + f'/{CLOUDPROV_ID}-image') as f:
image = f.read()
except FileNotFoundError:
image = 'PLACEHOLDER'

try:
with open(os.getenv('BUILD_DIR') + f'/{CLOUDPROV_ID}-image') as f:
image = f.read()
except FileNotFoundError:
image = 'PLACEHOLDER'
container = fire.ContainerBuilder(
name=CLOUDPROV_ID,
image=image,
args=["/sk-cloudprov"],
).with_ports(GRPC_PORT).with_security_context(Capability.DEBUG)

container = fire.ContainerBuilder(
name=CLOUDPROV_ID,
image=image,
args=["/sk-cloudprov"],
).with_ports(GRPC_PORT).with_security_context(Capability.DEBUG)
return (fire.DeploymentBuilder(app_label=CLOUDPROV_ID)
.with_containers(container)
.with_service()
.with_service_account_and_role_binding("cluster-admin", True)
.with_node_selector("type", "kind-worker")
)

cloudprov_builder = (fire.DeploymentBuilder(namespace=namespace, selector={APP_KEY: CLOUDPROV_ID})
.with_containers(container)
.with_service()
.with_service_account_and_role_binding("cluster-admin", True)
.with_node_selector("type", "kind-worker")
)
cloudprov_depl = cloudprov_builder.build(self)

cloud_prov_address = f'{cloudprov_builder.get_service_address()}:{GRPC_PORT}'
def _make_cluster_autoscaler(cloud_prov_addr):
volumes = fire.VolumesBuilder().with_config_map(
"cluster-autoscaler-config",
"/config",
{CA_CONFIG_PATH: CA_CONFIG_YML.format(cloud_prov_addr, GRPC_PORT)},
)
container = fire.ContainerBuilder(
name=AUTOSCALER_ID,
image="localhost:5000/cluster-autoscaler:latest",
args=[
"/cluster-autoscaler",
"--cloud-provider", "externalgrpc",
"--cloud-config", volumes.get_path_to_config_map("cluster-autoscaler-config", CA_CONFIG_PATH),
"--scale-down-delay-after-add", "1m",
"--scale-down-unneeded-time", "1m",
"--v", "4",
],
).with_volumes(volumes).with_security_context(Capability.DEBUG)

cm = k8s.KubeConfigMap(
self, "configmap",
metadata={"namespace": "kube-system"},
data={"cluster-autoscaler-config.yml": CA_CONFIG_YML.format(cloud_prov_address)}
)
return (fire.DeploymentBuilder(app_label=AUTOSCALER_ID, tag="cluster-autoscaler")
.with_containers(container)
.with_node_selector("type", "kind-control-plane")
.with_toleration("node-role.kubernetes.io/control-plane", "", TaintEffect.NoSchedule)
.with_service_account_and_role_binding("cluster-admin", True)
)

volumes = fire.VolumesBuilder().with_config_map("cluster-autoscaler-config", "/config", cm)
container = fire.ContainerBuilder(
name=AUTOSCALER_ID,
image="localhost:5000/cluster-autoscaler:latest",
args=[
"/cluster-autoscaler",
"--cloud-provider", "externalgrpc",
"--cloud-config", volumes.get_path_to("cluster-autoscaler-config"),
"--scale-down-delay-after-add", "1m",
"--scale-down-unneeded-time", "1m",
"--v", "4",
],
).with_volumes(volumes).with_security_context(Capability.DEBUG)

ca_depl = (fire.DeploymentBuilder(
namespace="kube-system",
selector={APP_KEY: AUTOSCALER_ID},
tag="cluster-autoscaler",
)
.with_containers(container)
.with_node_selector("type", "kind-control-plane")
.with_toleration("node-role.kubernetes.io/control-plane", "", TaintEffect.NoSchedule)
.with_service_account_and_role_binding("cluster-admin", True)
).build(self)
class SKCloudProv(fire.AppPackage):
def __init__(self):
self._cloud_prov = _make_cloud_provider()
self._cluster_autoscaler = _make_cluster_autoscaler(self._cloud_prov.service_name)

ca_depl.add_dependency(cloudprov_depl)
def compile(self, chart: Construct):
self._cloud_prov.build(chart)
self._cluster_autoscaler.build(chart)

@property
def id(self) -> str:
return "sk-cloudprov"
28 changes: 13 additions & 15 deletions k8s/sk_ctrl.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
import os

import fireconfig as fire
from cdk8s import Chart
from constructs import Construct
from fireconfig.types import Capability
from fireconfig.types import DownwardAPIField

ID = "sk-ctrl"


class SKController(Chart):
def __init__(self, scope: Construct, namespace: str):
super().__init__(scope, ID, disable_resource_name_hashes=True)

app_key = "app"

class SKController(fire.AppPackage):
def __init__(self):
env = (fire.EnvBuilder({"RUST_BACKTRACE": "1"})
.with_field_ref("POD_SVC_ACCOUNT", DownwardAPIField.SERVICE_ACCOUNT_NAME)
)

try:
with open(os.getenv('BUILD_DIR') + f'/{ID}-image') as f:
with open(os.getenv('BUILD_DIR') + f'/{self.id}-image') as f:
image = f.read()
except FileNotFoundError:
image = 'PLACEHOLDER'
Expand All @@ -32,7 +25,7 @@ def __init__(self, scope: Construct, namespace: str):
driver_image = 'PLACEHOLDER'

container = fire.ContainerBuilder(
name=ID,
name=self.id,
image=image,
args=[
"/sk-ctrl",
Expand All @@ -42,10 +35,15 @@ def __init__(self, scope: Construct, namespace: str):
],
).with_security_context(Capability.DEBUG).with_env(env)

depl = (fire.DeploymentBuilder(namespace=namespace, selector={app_key: ID})
.with_label(app_key, ID)
self._depl = (fire.DeploymentBuilder(app_label=self.id)
.with_service_account_and_role_binding('cluster-admin', True)
.with_containers(container)
.with_node_selector("type", "kind-worker")
.with_node_selector("type", "kind-workerrrr")
)
depl.build(self)

def compile(self, chart: Construct):
self._depl.build(chart)

@property
def id(self) -> str:
return "sk-ctrl"
39 changes: 17 additions & 22 deletions k8s/sk_tracer.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import os

import fireconfig as fire
from cdk8s import Chart
from constructs import Construct
from fireconfig import k8s

ID = "sk-tracer"
SERVER_PORT = 7777
TRACER_CONFIG_PATH = "tracer-config.yml"
TRACER_CONFIG_YML = """---
trackedObjects:
apps/v1.Deployment:
Expand All @@ -15,42 +13,39 @@
CONFIGMAP_NAME = "tracer-config"


class SKTracer(Chart):
def __init__(self, scope: Construct, namespace: str):
super().__init__(scope, ID, disable_resource_name_hashes=True)

app_key = "app"

cm = k8s.KubeConfigMap(
self, "configmap",
metadata={"namespace": namespace},
data={"tracer-config.yml": TRACER_CONFIG_YML}
)

class SKTracer(fire.AppPackage):
def __init__(self):
env = fire.EnvBuilder({"RUST_BACKTRACE": "1"})
volumes = fire.VolumesBuilder().with_config_map(CONFIGMAP_NAME, "/config", cm)
volumes = (fire.VolumesBuilder()
.with_config_map(CONFIGMAP_NAME, "/config", {TRACER_CONFIG_PATH: TRACER_CONFIG_YML})
)

try:
with open(os.getenv('BUILD_DIR') + f'/{ID}-image') as f:
with open(os.getenv('BUILD_DIR') + f'/{self.id}-image') as f:
image = f.read()
except FileNotFoundError:
image = 'PLACEHOLDER'

container = fire.ContainerBuilder(
name=ID,
name=self.id,
image=image,
args=[
"/sk-tracer",
"--server-port", f"{SERVER_PORT}",
"-c", volumes.get_path_to(CONFIGMAP_NAME),
"-c", volumes.get_path_to_config_map(CONFIGMAP_NAME, TRACER_CONFIG_PATH),
],
).with_ports(SERVER_PORT).with_volumes(volumes).with_env(env)

depl = (fire.DeploymentBuilder(namespace=namespace, selector={app_key: ID})
.with_label(app_key, ID)
self._depl = (fire.DeploymentBuilder(app_label=self.id)
.with_service_account_and_role_binding('cluster-admin', True)
.with_containers(container)
.with_service()
.with_node_selector("type", "kind-worker")
)
depl.build(self)

def compile(self, chart: Construct):
self._depl.build(chart)

@property
def id(self) -> str:
return "sk-tracer"
Loading

0 comments on commit b0bad12

Please sign in to comment.