kvdi

module
v0.3.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 24, 2021 License: GPL-3.0

README

kVDI

A Virtual Desktop Infrastructure running on Kubernetes.


Except as I've continued to work on this, I've noticed this is really just a free and open-source VDI solution based on docker containers. Kubernetes just makes it easier to implement 😄.


ATTENTION: The helm chart repository has been moved to a separate repo to tidy things up here more. To update your repository you can do the following:

helm repo remove kvdi
helm repo add kvdi https://kvdi.github.io/helm-charts/charts
helm repo update

helm install kvdi kvdi/kvdi  # yes, that's a lot of kvdi

go.dev reference Support me on Patreon

This project has reached a point where I am not going to be making enormous changes all the time anymore. As such I am tagging a "stable" release and incrementing from there. That still doesn't mean I highly recommend it's usage, but rather I am relatively confident in its overall stability.

If you are interested in helping out or just simply launching a design discussion, feel free to send PRs and/or issues. I wrote up a CONTRIBUTING doc just outlining some of the stuff I have in mind that would need to be acomplished for this to be considered "stable".

Features

  • Containerized user desktops running on Kubernetes with no virtualization required (libvirt options may come in the future). All traffic between the end user and the "desktop" is encrypted.

  • Persistent user data

  • Audio playback and microphone support

  • File transfer to/from "desktop" sessions. Directories get archived into a gzipped tarball prior to download.

  • RBAC system for managing user access to templates, roles, users, namespaces, serviceaccounts, etc.

  • MFA Support

  • Configurable backend for internal secrets. Currently vault or Kubernetes Secrets

  • Use built-in local authentication, LDAP, or OpenID.

  • App metrics to either scrape externally or view in the UI. More details in the helm doc.

TODO
  • "App Profiles" - I have a POC implementation on main but it is still pretty buggy
  • DOSBox/Game profiles could be cool...same as "App Profiles"
  • ARM64 support. Should be easy, but the build files will need some shuffling.
  • UI could use a serious makeover from someone who actually knows what they are doing

Requirements

For building and running locally you will need:

  • go >= 1.14
  • docker

Installing

Install standalone

If you don't have access to a Kubernetes cluster, or you just want to try kVDI out on a VM real quick, there is a script in this repository for setting up kVDI using k3s. It requires the instance running the script to have docker and the dialog package installed.

If you have an existing k3s installation, the ingress may not work since this script assumes kVDI will be the only LoadBalancer installed.

# Download the script from this repository.
curl -JLO https://raw.githubusercontent.com/kvdi/kvdi/main/deploy/architect/kvdi-architect.sh
# Run the script. You will be prompted via dialogs to make configuration changes.
bash kvdi-architect.sh   # Use --help to see all available options.

NOTE: This script is fairly new and still has some bugs

Install to a pre-existing cluster
Helm

For more complete installation instructions see the helm chart docs here for available configuration options.

The API Reference can also be used for details on kVDI app-level configurations.

helm repo add kvdi https://kvdi.github.io/helm-charts/charts  # Add the kvdi charts repo
helm repo update                                              # Sync your repositories

# Install kVDI
helm install kvdi kvdi/kvdi

It will take a minute or two for all the parts to start running after the install command. Once the app is launched, you can retrieve the admin password from kvdi-admin-secret in your cluster (if you are using ldap auth, log in with a user in one of the adminGroups).

To access the app interface either do a port-forward (make forward-app is another helper for that when developing locally with kind), or go to the "LoadBalancer" IP of the service.

By default there are no desktop templates configured. If you'd like, you can apply the ones in deploy/examples/example-desktop-templates.yaml to get started quickly.

Bundle Manifest

There is a manifest in this repository that will just lay down the manager instance, its dependencies, and all of the CRDs. You can then create a VDICluster object manually to spin up an actual application instance.

To install the manifest:

export KVDI_VERSION=v0.3.6

kubectl apply -f https://raw.githubusercontent.com/kvdi/kvdi/${KVDI_VERSION}/deploy/bundle.yaml --validate=false
Kustomize

The kustomize manifests in this repository are generated by kubebuilder and are usable as well similar to the Bundle Manifest. They can be found in the config directory in this repository.

Upgrading

Most of the time you can just run a regular helm upgrade to update your deployment manifests to the latest images.

helm upgrade kvdi kvdi/kvdi --version v0.3.6

However, sometimes there may be changes to the CRDs, though I will always do my best to make sure they are backwards compatible. Due to the way helm manages CRDs, it will ignore changes to those on an existing installation. You can get around this by applying the CRDs for the version you are upgrading to directly from this repo.

For example:

export KVDI_VERSION=v0.3.6

kubectl apply \
  -f https://raw.githubusercontent.com/kvdi/kvdi/${KVDI_VERSION}/config/crd/bases/app.kvdi.io_vdiclusters.yaml \
  -f https://raw.githubusercontent.com/kvdi/kvdi/${KVDI_VERSION}/config/crd/bases/desktops.kvdi.io_sessions.yaml \
  -f https://raw.githubusercontent.com/kvdi/kvdi/${KVDI_VERSION}/config/crd/bases/crds/desktops.kvdi.io_templates.yaml \
  -f https://raw.githubusercontent.com/kvdi/kvdi/${KVDI_VERSION}/config/crd/bases/crds/rbac.kvdi.io_vdiroles.yaml

When there is a change to one or more CRDs, it will be mentioned in the notes for that release.

Building and Running Locally

The Makefile contains helpers for testing the full solution locally using k3d. Run make help to see all the available options.

If you choose to pull the images from the registry instead of building and loading first - you probably want to set VERSION=latest (or a previous version) in your environment also. The Makefile is usually pointed at the next version to be released and published images may not exist yet.

# Builds all the docker images (optional, they are also available in the github registry)
$> make build-all
# Spin up a kind cluster for local testing
$> make test-cluster
# Load all the docker images into the kind cluster (optional for same reason as build)
$> make load-all
# Deploy the manager, kvdi, and setup the example templates
$> make deploy example-vdi-templates
# To test using custom helm values
$> HELM_ARGS="-f my_values.yaml" make deploy

After the manager has started the app instance, get the IP of its service with kubectl get svc to access the frontend, or you can run make-forward-app to start a local port-forward.

If not using anonymous auth, look for kvdi-admin-secret to retrieve the admin password.

Security

All traffic between processes is encrypted with mTLS. The UI for the "desktop" containers is placed behind a VNC server listening on a UNIX socket and a sidecar to the container will proxy validated websocket connections to it.

img

User authentication is provided by "providers". There are currently three implementations:

  • local-auth : A passwd like file is kept in the Secrets backend (k8s or vault) mapping users to roles and password hashes. This is primarily meant for development, but you could secure your environment in a way to make it viable for a small number of users.

  • ldap-auth : An LDAP/AD server is used for autenticating users. VDIRoles can be tied to security groups in LDAP via annotations. When a user is authenticated, their groups are queried to see if they are bound to any VDIRoles.

  • oidc-auth : An OpenID or OAuth provider is used for authenticating users. If using an Oauth provider, it must support the openid scope. When a user is authenticated, a configurable groups claim is requested from the provider that can be mapped to VDIRoles similarly to ldap-auth. If the provider does not support a groups claim, you can configure kVDI to allow all authenticated users.

All three authentication methods also support MFA.

Directories

Path Synopsis
apis
app
Package app contains the VDICluster app APIs.
Package app contains the VDICluster app APIs.
app/v1
Package v1 contains API Schema definitions for the App v1 API group +groupName=app.kvdi.io Package v1 contains API Schema definitions for the app v1 API group +kubebuilder:object:generate=true +groupName=app.kvdi.io
Package v1 contains API Schema definitions for the App v1 API group +groupName=app.kvdi.io Package v1 contains API Schema definitions for the app v1 API group +kubebuilder:object:generate=true +groupName=app.kvdi.io
desktops
Package desktops contains the kvdi Desktop APIs.
Package desktops contains the kvdi Desktop APIs.
desktops/v1
Package v1 contains API Schema definitions for the Desktops v1 API group +groupName=desktops.kvdi.io Package v1 contains API Schema definitions for the desktops v1 API group +kubebuilder:object:generate=true +groupName=desktops.kvdi.io
Package v1 contains API Schema definitions for the Desktops v1 API group +groupName=desktops.kvdi.io Package v1 contains API Schema definitions for the desktops v1 API group +kubebuilder:object:generate=true +groupName=desktops.kvdi.io
meta
Package meta contains kvdi meta APIs.
Package meta contains kvdi meta APIs.
meta/v1
Package v1 contains API Schema definitions for the meta v1 API group +groupName=meta.kvdi.io
Package v1 contains API Schema definitions for the meta v1 API group +groupName=meta.kvdi.io
rbac
Package rbac contains the VDIRole APIs.
Package rbac contains the VDIRole APIs.
rbac/v1
Package v1 contains API Schema definitions for the RBAC v1 API group +groupName=rbac.kvdi.io Package v1 contains API Schema definitions for the rbac v1 API group +kubebuilder:object:generate=true +groupName=rbac.kvdi.io
Package v1 contains API Schema definitions for the RBAC v1 API group +groupName=rbac.kvdi.io Package v1 contains API Schema definitions for the rbac v1 API group +kubebuilder:object:generate=true +groupName=rbac.kvdi.io
cmd
app
The main entrypoint to the kVDI App/API server.
The main entrypoint to the kVDI App/API server.
kvdi-proxy
The main entrypoint for the kvdi-proxy which provides an mTLS TCP server in front of desktop instances.
The main entrypoint for the kvdi-proxy which provides an mTLS TCP server in front of desktop instances.
controllers
app
pkg
api
Package api kVDI API.
Package api kVDI API.
api/client
Package client provides a REST wrapper to the kVDI API.
Package client provides a REST wrapper to the kVDI API.
audio
Package audio contains a buffer for streaming audio from a desktop to and from a websocket client.
Package audio contains a buffer for streaming audio from a desktop to and from a websocket client.
audio/pa
Package pa contains a PulseAudio C API wrapper for managing virtual devices on a system.
Package pa contains a PulseAudio C API wrapper for managing virtual devices on a system.
auth
Package auth contains the methods for retrieving the AuthProvider for a given cluster.
Package auth contains the methods for retrieving the AuthProvider for a given cluster.
auth/common
Package common contains the core AuthProvider interface and utility functions to be used by the auth providers.
Package common contains the core AuthProvider interface and utility functions to be used by the auth providers.
auth/mfa
Package mfa provides methods for tracking per-user MFA configurations.
Package mfa provides methods for tracking per-user MFA configurations.
auth/providers
Package providers contains the AuthProvider implementations.
Package providers contains the AuthProvider implementations.
auth/providers/ldap
Package ldap contains an AuthProvider implementation that uses a remote LDAP server for authentication.
Package ldap contains an AuthProvider implementation that uses a remote LDAP server for authentication.
auth/providers/local
Package local contains an AuthProvider implementation backed by a passwd-like file stored in the secrets backend.
Package local contains an AuthProvider implementation backed by a passwd-like file stored in the secrets backend.
auth/providers/oidc
Package oidc contains an AuthProvider implementation backed by OpenID/Oauth.
Package oidc contains an AuthProvider implementation backed by OpenID/Oauth.
cmd
pki
Package pki provides TLS certificate generation/signing for inter-process communication.
Package pki provides TLS certificate generation/signing for inter-process communication.
proxyproto
Package proxyproto contains the core types for interactions between the kvdi API and desktop proxy instances.
Package proxyproto contains the core types for interactions between the kvdi API and desktop proxy instances.
proxyproto/client
Package client contains a client implementation for making requests against desktop proxy instances.
Package client contains a client implementation for making requests against desktop proxy instances.
proxyproto/server
Package server contains the server for handling requests against a desktop's proxy instance.
Package server contains the server for handling requests against a desktop's proxy instance.
resources
Package resources contains the interfaces for resource reconcilers to implement.
Package resources contains the interfaces for resource reconcilers to implement.
resources/app
Package app contains reconciliation logic for core kVDI resources.
Package app contains reconciliation logic for core kVDI resources.
resources/desktop
Package desktop contains reconciliation logic for resources related to a Desktop instance.
Package desktop contains reconciliation logic for resources related to a Desktop instance.
secrets
Package secrets contains an engine for reading and writing secrets from configurable backends.
Package secrets contains an engine for reading and writing secrets from configurable backends.
secrets/common
Package common defines the core interface for various secrets backends to implement.
Package common defines the core interface for various secrets backends to implement.
secrets/providers/k8secret
Package k8secret implements a SecretsProvider backend that uses Kubernetes secrets for the data store.
Package k8secret implements a SecretsProvider backend that uses Kubernetes secrets for the data store.
secrets/providers/vault
Package vault implements a SecretsProvider backend that uses the configured vault server for storing sensitive information.
Package vault implements a SecretsProvider backend that uses the configured vault server for storing sensitive information.
util/apiutil
Package apiutil contains utility functions for the REST API.
Package apiutil contains utility functions for the REST API.
util/common
Package common provides common utility functions to all packages
Package common provides common utility functions to all packages
util/errors
Package errors provides error interfaces and utility functions for all packages.
Package errors provides error interfaces and utility functions for all packages.
util/k8sutil
Package k8sutil contains utility functions for Kubernetes resources.
Package k8sutil contains utility functions for Kubernetes resources.
util/lock
Package lock implements a ConfigMap lock similar to the one found in github.com/operator-framework/operator-sdk/pkg/leader.
Package lock implements a ConfigMap lock similar to the one found in github.com/operator-framework/operator-sdk/pkg/leader.
util/reconcile
Package reconcile contains functions for reconciling Kubernetes resources.
Package reconcile contains functions for reconciling Kubernetes resources.
util/tlsutil
Package tlsutil contains utility functions for TLS operations.
Package tlsutil contains utility functions for TLS operations.
version
Package version holds versioning info that is passed in at compilation time.
Package version holds versioning info that is passed in at compilation time.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL