Skip to main content

Deploy to kind with vCluster

Cosmonic Control uses Kubernetes custom resource definitions (CRDs) to represent the core primitives of wasmCloud and WebAssembly components.

Some users may be restricted from deploying custom resources in a larger Kubernetes environment. In these cases, it is possible to use vCluster to run an isolated virtual cluster on existing Kubernetes infrastructure, enabling the use of CRDs within the virtual cluster.

This page outlines deployment of Cosmonic Control to an isolated virtual cluster using vCluster on kind.

warning

In order to use this approach, ensure that your infrastructure supports nested virtualization.

Pre-requisites:

Set up kind and vCluster

Create a kind cluster, if you do not have one already:

kind create cluster

Create a cluster.yaml file in your working directory and use the contents below:

controlPlane:
  ingress:
    enabled: false
    host: "localhost"
    pathType: "Prefix"
    annotations:
      nginx.ingress.kubernetes.io/backend-protocol: HTTPS
      nginx.ingress.kubernetes.io/ssl-passthrough: "true"
      nginx.ingress.kubernetes.io/ssl-redirect: "true"
    spec:
      ingressClassName: nginx

exportKubeConfig:
  context: "vcluster"
  server: "https://localhost:4443"

integrations:
  metricsServer:
    enabled: false
  externalSecrets:
    enabled: false
  kubeVirt:
    enabled: false
  certManager:
    enabled: false

Use Helm to install vCluster into the demo namespace:

helm upgrade --install demo vcluster \
  --repo https://charts.loft.sh \
  --values cluster.yaml \
  --namespace demo \
  --repository-config='' \
  --create-namespace

Wait for the vCluster pod to reach Ready state:

kubectl wait --for=condition=Ready --timeout=120s pod/demo-0 -n demo

Store the kubeconfig that you will use to communicate with the vCluster control plane:

kubectl get secret -n demo vc-demo -o 'jsonpath={.data.config}' | base64 -d > kubeconfig

In a separate tab or window, create a port-forward to access vCluster control plane:

kubectl port-forward service/demo 4443:443 -n demo

Install Cosmonic Control inside vCluster

Create a new cosmonic-system namespace:

KUBECONFIG=kubeconfig kubectl create ns cosmonic-system
warning

The next step requires your credentials from Cosmonic.

Create environment variables for your credentials from Cosmonic:

CC_USERNAME=username-value-here
CC_PASSWORD=password-value-here
CC_SERVER=server-value-here

The next step is to create pull secrets for accessing Cosmonic artifacts.

For the cosmonic-system namespace:

KUBECONFIG=kubeconfig kubectl create secret docker-registry cosmonic-quay -n cosmonic-system \
  --docker-username $CC_USERNAME \
  --docker-password $CC_PASSWORD \
  --docker-server $CC_SERVER

For the default namespace:

KUBECONFIG=kubeconfig kubectl create secret docker-registry cosmonic-quay -n default \
  --docker-username $CC_USERNAME \
  --docker-password $CC_PASSWORD \
  --docker-server $CC_SERVER

Create a control-values.yaml file in your working directory and use the contents below:

image:
  repository: quay.io/cosmonic/infrastructure-operator
  tag: 0.1.7
imagePullSecrets:
  - name: cosmonic-quay

Install the Cosmonic operator:

KUBECONFIG=kubeconfig helm upgrade --install demo oci://quay.io/cosmonic/cosmonic-control \
    --version 0.1.2 \
    --values control-values.yaml \
    --namespace cosmonic-system \
    --username $CC_USERNAME \
    --password $CC_PASSWORD

Create a cluster.yaml file in your working directory and use the contents below:

apiVersion: k8s.cosmonic.io/v1alpha1
kind: Cluster
metadata:
  name: demo
  namespace: default
spec:
  nexus:
    replicas: 3
    image: quay.io/cosmonic/nexus:0.1.7
    imagePullSecrets:
      - name: cosmonic-quay
  console:
    image: quay.io/cosmonic/console:0.1.7
    imagePullSecrets:
      - name: cosmonic-quay
    baseUrl: ""
    connectors:
      - id: "static"
        type: "static"
        name: "Demo Auth"
  operator:
    image: quay.io/cosmonic/runtime-operator:0.1.7
    imagePullSecrets:
      - name: cosmonic-quay
  observability:
    disable: true
    grafana: {}
    prometheus: {}
    surveyor: {}

Install the Cosmonic cluster in the default namespace:

KUBECONFIG=kubeconfig kubectl apply -f cluster.yaml

Wait for the operator to become ready:

KUBECONFIG=kubeconfig kubectl rollout status deployment operator-demo --timeout=120s

Create a hostgroup.yaml file in your working directory and use the contents below:

apiVersion: k8s.cosmonic.io/v1alpha1
kind: HostGroup
metadata:
  name: hostgroup
  namespace: default
spec:
  cluster:
    name: demo
  replicas: 1
  image: ghcr.io/wasmcloud/wasmcloud:1.8.0
  imagePullPolicy: Always
  env:
    - name: RUST_LOG
      value: info

Install the wasmCloud host group:

KUBECONFIG=kubeconfig kubectl apply -f hostgroup.yaml

Wait for the host group to become ready:

KUBECONFIG=kubeconfig kubectl rollout status deployment demo-hostgroup --timeout=120s

Deploy a sample wasmCloud application

Create a provider.yaml file in your working directory and use the contents below:

---
apiVersion: runtime.wasmcloud.dev/v1alpha1
kind: Config
metadata:
  name: http-server
spec:
  cluster:
    name: demo
    namespace: default
  config:
    - name: default_address
      value: "0.0.0.0:8080"
---
apiVersion: runtime.wasmcloud.dev/v1alpha1
kind: Provider
metadata:
  name: http-server
spec:
  cluster:
    name: demo
    namespace: default
  image: ghcr.io/wasmcloud/http-server:0.26.1
  replicas: 1
  configFrom:
    - name: http-server

Deploy the Provider and its associated Config CRD:

KUBECONFIG=kubeconfig kubectl apply -f provider.yaml

Create a component.yaml file in your working directory and use the contents below:

apiVersion: runtime.wasmcloud.dev/v1alpha1
kind: Component
metadata:
  name: http-hello-world
spec:
  cluster:
    name: demo
    namespace: default
  image: ghcr.io/wasmcloud/components/http-hello-world-rust:0.1.0
  concurrency: 100
  replicas: 1
  exports:
    - wit:
        namespace: wasi
        package: http
        interfaces:
          - incoming-handler
      target:
        provider:
          name: http-server
          namespace: default

Deploy the Component CRD referencing the provider:

KUBECONFIG=kubeconfig kubectl apply -f component.yaml

Open up port-forward to the host group to access the provider:

KUBECONFIG=kubeconfig kubectl port-forward deploy/demo-hostgroup 8080

In another tab or window, call the http-server provider through the port-forward:

curl localhost:8080

You should now be greeted with:

Hello from Rust!