# Hello from Gefyra | Blazingly-fast rocket, rock-solid, local application development arrow_right with Kubernetes.
::u-page-hero
#title
:icon{.home-icon mode="svg" name="i-gefyra-logo-vertical"}
#description
Blazingly-fast, rock-solid, local application development with Kubernetes.
#links
:::u-button
---
color: primary
size: xl
to: https://gefyra.dev/en/quick-start/installation
trailing-icon: i-lucide-arrow-right
---
Let's try Gefyra
:::
:::u-button
---
color: neutral
icon: simple-icons-github
size: xl
to: https://github.com/gefyrahq/gefyra
variant: outline
---
We're open source
:::
::
::u-container{.text-center.mb-6}
:::card-group
::::card{title="The Problem"}
Building and pushing containers to test them in Kubernetes is [repetitive and time-consuming]{.font-bold}. Writing and debugging code that depends on services in Kubernetes is daunting. [Especially if they are not reachable]{.font-bold} during development.
::::
::::card{title="The Solution"}
[Gefyra]{.font-bold} runs local code in any Kubernetes cluster [without the build and push cycle]{.font-bold}. It overlays containers in the cluster making code changes immediately available. It's a new era of software development.
::::
:::
::
::u-page-section
---
class: border-t
---
#title
Why Gefyra?
#features
:::u-page-feature
---
icon: i-gefyra-deadline
---
#title
Supercharge Development Speed
#description
Run your code directly in a Kubernetes cluster and overcome [CI/CD waiting times]{.font-bold}.
:::
:::u-page-feature
---
icon: i-gefyra-sweat
---
#title
Fight Environment Bugs
#description
Uncover bugs [before]{.font-bold} they appear on staging or production environments.
:::
:::u-page-feature
---
icon: i-gefyra-team
---
#title
Promote Collaboration
#description
Share [running code instantly]{.font-bold} and let your team work in a realistic environment.
:::
:::u-page-feature
---
icon: i-gefyra-play-button
---
#title
One Click and Go
#description
Gefyra is [ready in seconds]{.font-bold}, not hours or days.
:::
:::u-page-feature
---
icon: i-gefyra-link
---
#title
Flexible Workflows
#description
Integrate Gefyra [into existing workflows]{.font-bold}. Make Gefyra part of your CI/CD pipeline.
:::
:::u-page-feature
---
icon: i-gefyra-budget
---
#title
Cost Efficient
#description
Improve time-to-market and utilization of resources. Spent [less]{.font-bold} on CI/CD pipelines and container builds.
:::
::
::u-page-section
---
class: border-t
orientation: horizontal
---
#title
Docker Desktop Extension
#description
Gefyra is a Docker Desktop extension that allows you to run your code directly in a Kubernetes cluster.
#links
:::u-button
---
color: primary
size: xl
target: _blank
to: https://www.docker.com/blog/building-a-local-application-development-environment-for-kubernetes-with-the-gefyra-docker-extension/
trailing-icon: i-lucide-arrow-right
---
Check it out
:::
::
:gefyra-use-cases
::u-page-section
---
class: border-t
---
#title
Let us know about your experience!
#description
We depend on your feedback - Gefyra's was created out of our own needs and the feedback we received from you, and our community.
We'd appreciate it if you could take 2 minutes of your time to fill out our [feedback form]{.font-bold}.
#links
:::u-button
---
color: primary
size: xl
target: _blank
to: https://forms.gle/AWT9NparpTVk8E978
trailing-icon: i-lucide-arrow-right
---
Give feedback
:::
::
# Gefyra: Blazingly-fast, rock-solid, local application development with Kubernetes.
## Gefyra offers you to
- run services locally on a developer machine
- operate feature-branches in a production-like Kubernetes environment with all adjacent services
- write code in the IDE you already love, be fast, be confident
- leverage all the neat development features, such as debugger, code-hot-reloading, overriding environment variables
- run high-level integration tests against all dependent services
- keep peace-of-mind when pushing new code to the integration environment
Gefyra was designed to be fast and robust on an average developer machine and supports most platforms.
**Remark:** Gefyra requires a running Docker engine on the development machine.
## Core Features
### Run a container instance on a developer machine and connect it to Kubernetes-based resources
You can run an arbitrary container on your local development machine that behaves as it would run within a Kubernetes cluster. It connects to Kubernetes-based resources (such as databases, APIs, or assets), making it very convenient to test a new service in the cluster or write code that depends on Kubernetes resources.
{.w-full}
### Overlay a container running within a Kubernetes Pod with a local instance
You can simply replace a container running in a Kubernetes Pod with a local container instance. That will serve the requests to that Pod from your local container instances. That makes it very convenient to test changes in a realistic production-close environment before pushing the code to CI/CD.
{.w-full}
## Quick Installation
```bash
curl -sSL https://raw.githubusercontent.com/gefyrahq/gefyra/main/install.sh | sh -
```
Looking for Homebrew or Windows installation? Checkout the [installation](https://gefyra.dev/en/quick-start/installation) guide.
## Use Cases and Demos
If you are interested in more sophisticated use cases or want to develop modern Kubernetes-based architectures, check out the [use cases and demos](https://gefyra.dev/en/usecases-and-demos/getting-started) or the [media](https://gefyra.dev/en/information/media) section.
# Installation
## Prerequisites
To use Gefyra you need:
- Docker client API compatible container runtime (Docker/Docker Desktop/Colima/Rancher Desktop with moby engine)
- Overlay networking support (not available on rootless Docker)
- Kubernetes cluster with a reachable node port **31820/UDP**
## Install Gefyra on MacOS
### Homebrew
```bash
brew tap gefyrahq/gefyra
brew install gefyra
```
### Manual Installation
```bash
curl -sSL https://raw.githubusercontent.com/gefyrahq/gefyra/main/install.sh | sh -
```
## Install Gefyra on Linux
### Manual Installation
```bash
curl -sSL https://raw.githubusercontent.com/gefyrahq/gefyra/main/install.sh | sh -
```
## Install Gefyra on Windows
You can download the latest release from {rel=""nofollow""} on your local machine.
Chocolatey will be available soon. If you can support this project with packaging and distributing for Windows please get in touch!
Todo
## Docker Desktop Extension
The Gefyra Docker Desktop Extension is available on the Docker Desktop extension [marketplace](https://hub.docker.com/extensions/gefyra/docker-desktop-extension){rel=""nofollow""} However, you can also install it by running the following command:
```bash
docker extension install gefyra/docker-desktop-extension:latest
```
For more details see [Docker Desktop Extension](https://gefyra.dev/en/local-environments/docker-desktop-osx).
## Using Python Package Index
You can install Gefyra with pip:
```bash
pip install gefyra --upgrade
```
{rel=""nofollow""}
# Getting Started
**Important:** This getting started guide for [Minikube](https://minikube.sigs.k8s.io/){rel=""nofollow""} requires Gefyra in version >=2.0.0+.
## Prerequisites
1. Minikube is [installed](https://minikube.sigs.k8s.io/docs/start/){rel=""nofollow""} (at least in version v1.26.1)
2. Gefyra is [available](https://gefyra.dev/installation){rel=""nofollow""} (at least in version 2.0.0)
## Creating a local Kubernetes cluster with Minikube
{.w-full}
### 1. Create a local Kubernetes cluster with Minikube by running:
```bash
minikube start
```
**Important:** the following example does not *fully* work with `--driver=qemu` since `minikube service` is not currently
implemented with the qemu2 driver. See [this GitHub issue](https://github.com/kubernetes/minikube/issues/14146){rel=""nofollow""} for details.
Tested drivers are: *docker*, *kvm2*, *kvm*, *virtualbox*. Others are potentially working, but are not tested.
After some time of downloading the required resources, the cluster will be running. You may enable the required
addons based on your requirements. The `kubectl` context is immediately set to this cluster. You can check if
`kubectl config current-context` is set to `minikube`.
```sh
kubectl config current-context
```
### 2. Apply some workload, for example from the testing directory from Gefyra:
```sh
kubectl apply -f https://raw.githubusercontent.com/gefyrahq/gefyra/main/testing/workloads/hello.yaml
```
### 3. Check the output of the deployed app with:
```sh
kubectl expose deployment hello-nginxdemo --type=NodePort --port=80
```
```sh
minikube service hello-nginxdemo
```
## Running Gefyra
### 1. Set up Gefyra with your Minikube cluster:
```sh
gefyra up --minikube
```
**Important**: The `--minikube` switch detects all required connection parameters from your local cluster. The connection won't work
if this switch is missing when working with Minikube.
### 2. Run a local Docker container with Gefyra in order to connect it with the cluster.
#### 2.1 Build a simple Docker image with a local tag. Save the following two files in a directory on your disk.
```dockerfile [Dockerfile]
FROM ubuntu
# run a server on port 8000
RUN apt update && apt install -y iproute2 iputils-ping python3 traceroute wget curl
COPY local.py local.py
CMD python3 local.py
```
::code-collapse
```py [local.py]
import http.server
import signal
import socket
import socketserver
import sys
from datetime import datetime
if sys.argv[1:]:
port = int(sys.argv[1])
else:
port = 8000
class MyHttpRequestHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
hostname = socket.gethostname()
now = datetime.utcnow()
self.wfile.write(
bytes(
f"
Hello from Gefyra. It is {now} on"
f" {hostname}.
".encode("utf-8")
)
)
my_handler = MyHttpRequestHandler
server = socketserver.ThreadingTCPServer(("", port), my_handler)
def signal_handler(signal, frame):
try:
if server:
server.server_close()
finally:
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
try:
while True:
sys.stdout.flush()
server.serve_forever()
except KeyboardInterrupt:
pass
server.server_close()
```
::
#### 2.2 Build it by running `docker build -f Dockerfile . -t pyserver` in your directory.
#### 2.3 Execute Gefyra's run command:
```bash
gefyra run -d -i pyserver -N mypyserver -n default
```
**Important**: `gefyra run` is just a wrapper for `docker run` (with additional flags), yet it also applies Gefyra's networking
configuration to connect the container with Kubernetes. Check out [the docs for `gefyra run`](https://gefyra.dev/en/quick-start/cli#run)
### 3. *Exec* into the running container and look around. You will find the container to run within your Kubernetes cluster.
```sh
docker exec -it mypyserver bash
```
```sh
wget -O- hello-nginx
```
will print out the website of the cluster service *hello-nginx* from within the cluster. 🚀
### 4. Create a bridge to redirect the traffic from the cluster application to the one running locally:
```sh
gefyra bridge -N mypyserver -n default --ports 80:8000 --target deploy/hello-nginxdemo/hello-nginx
```
Check out the locally running server serving the cluster by refreshing the address from:
```sh
minikube service hello-nginxdemo
```
It shows you a different message: `Hello from Gefyra. It is ...`. Yes, that is really coming from your local container! 😎
### 5. List all running *bridges*:
You can list all currently active bridges with:
```sh
gefyra list --bridges
```
You will find all local containers that are currently linked into the cluster serving requests.
### 6. *Unbridge* the local container and reset the cluster to its original state:
```sh
gefyra unbridge --all
```
Check out the original response from:
```sh
minikube service hello-nginxdemo
```
The cluster is now reset to its inital state again.
## Cleaning up
Remove Gefyra's components from the cluster and your local Docker host with:
```sh
gefyra down
```
## Deleting the Minikube cluster
```sh
minikube delete
```
::card
Did everything work as expected? How was the experience of using Gefyra? We'd appreciate if you could take 2 minutes of your time to fill out our
[feedback form](https://forms.gle/AWT9NparpTVk8E978){rel=""nofollow""}
.
#title
Please provide us with your feedback
::
# Gefyra Docker Desktop Extension
[Gefyra's Docker Desktop Extension](https://hub.docker.com/r/gefyra/docker-desktop-extension){rel=""nofollow""} allows you to run containers on your local machine and connect them to Kubernetes-based resources. It is a great way to test a new service in the cluster or write code that depends on Kubernetes resources.
::note
Gefyra's Docker Desktop Extension still runs Gefyra v1 internally and thus does not support shared environments.
::
**Looking for CLI rather than a GUI?** Check out [Gefyra's CLI](https://gefyra.dev/en/quick-start/cli)
## Installation
The Gefyra Docker Desktop Extension is available on the Docker Desktop extension [marketplace](https://hub.docker.com/extensions/gefyra/docker-desktop-extension){rel=""nofollow""}.
However, you can also install it by running the following command:
```shell
docker extension install gefyra/docker-desktop-extension:latest
```
## Usage
After installing the extension it becomes available in the Docker Desktop Extension sidebar. Gefyra Docker Desktop currently only supports the `run` mode. After clicking on the `run` tile you're guided through the process of running a container on your local machine.

Firstly Gefyra needs to know about your cluster to allow you to set all settings accordingly.

After choosing your *kubeconfig* and context you can then proceed to adding the settings for your container. In case you have a remote cluster
you need to provide Gefyra with its connection parameters under `Remote Cluster Settings`.

There are several settings for the container - most importantly the `image`, `namespace` and `command` settings.
The `image` setting is the image that will be used to run the container - Gefyra will you show any image that is available in the local Docker Desktop context as
well as images that are available in the chosen Kubernetes namespace. The `namespace` setting is the namespace in which the container will be available.
Gefyra allows you to copy the environment variables of a certain workload through the `Copy Environment From` dropdown.
You can add volumes and more variables through the `Add Volume` and `Add Environment Variable` buttons.
As soon as you're done hit run!

Gefyra ensures that its cluster components are in the correct state and starts the container.
Once the container is running Gefyra will show you the logs of the container.
## 10 minute demo
:gefyra-youtube{video-id="4xmaOVul5Ww"}
:gefyra-youtube{video-id="EBArR1O2BGk"}
::card
Did everything work as expected? How was the experience of using Gefyra? We'd appreciate if you could take 2 minutes of your time to fill out our
[feedback form](https://forms.gle/AWT9NparpTVk8E978){rel=""nofollow""}
.
#title
Please provide us with your feedback
::
# Command line tool (CLI)
## Syntax
Use the following syntax to run `gefyra` commands from your terminal:
```sh
gefyra [-h] [-d] [action] [arguments]
```
where `action` and `arguments` are:
- `action`: specifies the operation that you want to perform, for example `up` or `bridge`
- `arguments`: specifies the required and optional arguments for a specific action, for example `-n` or `--namespace`
Global flags are:
- `-h, --help`: show help message and exit
- `-d, --debug`: add debug output for each action
## Commands Overview
| Command | Description |
| :----------------------------------------------- | :---------------------------------------------------------------------------- |
| [`bridge`](https://gefyra.dev/#bridge) | Manage your GefyraBridges to redirect traffic from a GefyraBridgeMount target |
| [`clients`](https://gefyra.dev/#clients) | Manage GefyraClients for a Gefyra installation |
| [`connections`](https://gefyra.dev/#connections) | Manage connections to Kubernetes clusters for a GefyraClient on this machine |
| [`down`](https://gefyra.dev/#down) | Remove Gefyra locally and on the cluster |
| [`install`](https://gefyra.dev/#install) | Create and print the Kubernetes configs for Gefyra; usage: 'gefyra install... |
| [`list`](https://gefyra.dev/#list) | List running containers |
| [`mount`](https://gefyra.dev/#mount) | Manage GefyraBridgeMounts for a Gefyra installation |
| [`operator`](https://gefyra.dev/#operator) | Manage operator installation |
| [`rm`](https://gefyra.dev/#rm) | Remove a Gefyra container and its associated bridges |
| [`run`](https://gefyra.dev/#run) | Run a container in Gefyra. |
| [`self`](https://gefyra.dev/#self) | Manage this Gefyra executable |
| [`status`](https://gefyra.dev/#status) | Get Gefyra's status |
| [`uninstall`](https://gefyra.dev/#uninstall) | Removes the Gefyra installation from the cluster |
| [`up`](https://gefyra.dev/#up) | Install Gefyra on a cluster and directly connect to it |
| [`version`](https://gefyra.dev/#version) | |
---
### bridge
Manage your GefyraBridges to redirect traffic from a GefyraBridgeMount target
**Example:**
```sh
gefyra bridge create
gefyra bridge list
gefyra bridge delete my-bridge
```
**Subcommands:**
- [`bridge create`](https://gefyra.dev/#bridge-create) — Establish a GefyraBridge from a GefyraBridgeMount in the...
- [`bridge delete`](https://gefyra.dev/#bridge-delete) — Mark a GefyraBridge for deletion
- [`bridge inspect`](https://gefyra.dev/#bridge-inspect) — Describe a GefyraBridge
- [`bridge list`](https://gefyra.dev/#bridge-list) — List all GefyraBridges with local target containers
[](){#bridge-create}**â–¶ bridge create**
Establish a GefyraBridge from a GefyraBridgeMount in the cluster to a local container
**Example:**
```sh
gefyra bridge create -t mycontainer -p 8080:8080 --mount my-mount
```
**Arguments:**
| Argument | Description |
| :-------------------------- | :--------------------------------------------------------------------------------------------------------------------------- |
| `-t`, `--local`, `--target` | The name of the local container running in Gefyra **(required)** |
| `-N`, `--name` | Assign a custom name to this GefyraBridge |
| `-p`, `--ports` | Add forward port mapping in form of ``:`` **(required)** |
| `--match-header-exact` | Match header exactly to forward traffic to this client. E.g.: --match-header-exact x-gefyra\:peer |
| `--match-header-regex` | Match header regex expression to forward traffic to this client. E.g.: --match-header-regex x-gefyra:(.\*)) |
| `--match-header-prefix` | Match header value prefix (and name exactly) to forward traffic to this client. E.g.: --match-header-prefix x-gefyra\:peer1, |
| `--match-path-prefix` | Match path prefix to forward traffic to this client. E.g.: --match-path-prefix myroute/ |
| `--match-path-regex` | Match patch regex to forward traffic to this client. E.g.: --match-path-regex myroute/(.\*)/all |
| `--match-path-exact` | Match path exactly to forward traffic to this client. E.g.: --match-path-exact /only/this |
| `-P`, `--no-probe-handling` | Make Carrier to not handle probes during switch operation |
| `--mount` | The target GefyraBridgeMount to install this GefyraBridge on **(required)** |
| `--connection-name` | Default: `default` |
| `--nowait` | Do not wait for the GefyraBridgeMount to be ready |
| `--timeout` | Default: `60` |
[](){#bridge-delete}**â–¶ bridge delete**
*Aliases: `rm`, `remove`*
Mark a GefyraBridge for deletion
**Example:**
```sh
gefyra bridge delete my-bridge
gefyra bridge rm my-bridge
```
**Positional Arguments:**
| Argument | Description |
| :------- | :---------- |
| `name` | |
**Arguments:**
| Argument | Description |
| :------------------ | :------------------------------------------------------ |
| `-A`, `--all` | Unbridge all GefyraBridges with local target containers |
| `-m`, `--mount` | Unbridge all bridges for a specific mount |
| `--nowait` | Do not wait for the GefyraBridge to be deleted. |
| `--connection-name` | Default: `default` |
| `--timeout` | Default: `60` |
[](){#bridge-inspect}**â–¶ bridge inspect**
*Aliases: `describe`, `show`, `get`*
Describe a GefyraBridge
**Example:**
```sh
gefyra bridge inspect my-bridge
```
**Positional Arguments:**
| Argument | Description |
| :------------ | :------------- |
| `bridge_name` | **(required)** |
**Arguments:**
| Argument | Description |
| :------------------------ | :----------------- |
| `--output`, `-o` | Default: `text` |
| `--connection-name`, `-c` | Default: `default` |
[](){#bridge-list}**â–¶ bridge list**
*Aliases: `ls`*
List all GefyraBridges with local target containers
**Example:**
```sh
gefyra bridge list
gefyra bridge ls
```
**Arguments:**
| Argument | Description |
| :------------------ | :-------------------------------------------- |
| `-A`, `--all` | List all GefyraBridges from all GefyraClients |
| `--connection-name` | Default: `default` |
| `-o`, `--output` | Default: `text` |
---
### clients
Manage GefyraClients for a Gefyra installation
**Example:**
```sh
gefyra clients create
gefyra clients list
gefyra clients delete my-client
```
**Subcommands:**
- [`clients config`](https://gefyra.dev/#clients-config) — Get a Gefyra connection config for a client
- [`clients create`](https://gefyra.dev/#clients-create) — Create a new GefyraClient
- [`clients delete`](https://gefyra.dev/#clients-delete) — Mark a GefyraClient for deletion
- [`clients disconnect`](https://gefyra.dev/#clients-disconnect) — Disconnect a GefyraClient
- [`clients inspect`](https://gefyra.dev/#clients-inspect) — Describe a GefyraClient
- [`clients list`](https://gefyra.dev/#clients-list) — List all GefyraClients
[](){#clients-config}**â–¶ clients config**
*Aliases: `write`*
Get a Gefyra connection config for a client
**Example:**
```sh
gefyra clients config -h 1.1.1.1 my-client-id
```
**Positional Arguments:**
| Argument | Description |
| :---------- | :------------- |
| `client_id` | **(required)** |
**Arguments:**
| Argument | Description |
| :------------------------------------- | :--------------------------------------------------------------------------------------- |
| `-h`, `--host` | The connection host |
| `-p`, `--port` | The connection port (default: 31820) |
| `-a`, `--kube-api`, `--kubernetes-api` | The Kubernetes API adress for the host cluster (default: API adresse of your kubeconfig) |
| `-o`, `--output` | The output file to write the config to |
| `--registry` | The registry URL for the images |
| `--mtu` | The MTU for the Wireguard interface (default: auto-detected by WireGuard) |
| `--local` | Whether the target cluster is a local k8s cluster |
[](){#clients-create}**â–¶ clients create**
Create a new GefyraClient
**Example:**
```sh
gefyra clients create -n 2 # creates 2 clients
```
**Arguments:**
| Argument | Description |
| :---------------------- | :--------------------------------------------------------------------------------------------------- |
| `--client-id`, `--name` | The client id/name of the GefyraClient |
| `-n` | Number of GefyraClient to be generated (not allowed with explicit --client-id/--name) (default: `1`) |
| `--registry` | The registry URL for the images |
| `--nowait` | Do not wait for the GefyraClient to be ready |
| `--timeout` | Timeout in seconds for the GefyraClient to be ready (default: `60`) |
[](){#clients-delete}**â–¶ clients delete**
*Aliases: `rm`, `remove`*
Mark a GefyraClient for deletion
**Example:**
```sh
gefyra clients delete my-client-id
gefyra clients rm my-client-id
gefyra clients remove my-client-id
```
**Positional Arguments:**
| Argument | Description |
| :---------- | :------------- |
| `client_id` | **(required)** |
**Arguments:**
| Argument | Description |
| :---------- | :-------------------------------------------------------------------- |
| `--nowait` | Do not wait for the GefyraClient to be deleted |
| `--timeout` | Timeout in seconds for the GefyraClient to be deleted (default: `60`) |
| `--force` | Force deletion of the GefyraClient |
[](){#clients-disconnect}**â–¶ clients disconnect**
*Aliases: `deactivate`, `stop`*
Disconnect a GefyraClient
**Example:**
```sh
gefyra clients disconnect my-client-id
```
**Positional Arguments:**
| Argument | Description |
| :---------- | :------------- |
| `client_id` | **(required)** |
[](){#clients-inspect}**â–¶ clients inspect**
*Aliases: `describe`, `show`, `get`*
Describe a GefyraClient
**Example:**
```sh
gefyra clients inspect
gefyra clients inspect my-client-id
```
**Positional Arguments:**
| Argument | Description |
| :---------- | :------------- |
| `client_id` | **(required)** |
**Arguments:**
| Argument | Description |
| :--------------- | :------------------------------------------- |
| `-o`, `--output` | Output format (json, text) (default: `text`) |
[](){#clients-list}**â–¶ clients list**
*Aliases: `ls`*
List all GefyraClients
**Example:**
```sh
gefyra clients list
gefyra clients ls
```
**Arguments:**
| Argument | Description |
| :--------------- | :-------------- |
| `-o`, `--output` | Default: `text` |
---
### connections
Manage connections to Kubernetes clusters for a GefyraClient on this machine
**Example:**
```sh
gefyra connections connect -f con_file.json -n my-connection
gefyra connections list
gefyra connections disconnect my-connection
```
**Subcommands:**
- [`connections connect`](https://gefyra.dev/#connections-connect) — Connect this local machine to a Gefyra cluster
- [`connections disconnect`](https://gefyra.dev/#connections-disconnect) — Disconnect this local machine from a Gefyra cluster
- [`connections inspect`](https://gefyra.dev/#connections-inspect) — Inspect a Gefyra connection
- [`connections list`](https://gefyra.dev/#connections-list) — List all Gefyra connections
- [`connections remove`](https://gefyra.dev/#connections-remove) — Remove a Gefyra connection
[](){#connections-connect}**â–¶ connections connect**
*Aliases: `create`*
Connect this local machine to a Gefyra cluster
**Example:**
```sh
gefyra connections connect -f con_file.json -n my-connection
```
**Arguments:**
| Argument | Description |
| :------------------------ | :---------------------------------------------------------------------------------------------------- |
| `-f`, `--client-config` | |
| `-n`, `--connection-name` | Assign a local name to this client connection (default: `default`) |
| `--minikube` | Connect Gefyra to a Minikube cluster (accepts minikube profile name, default is 'minikube')) |
| `--mtu` | The MTU (Maximum Transmission Unit) for the Wireguard interface (default: auto-detected by WireGuard) |
| `--cargo-image` | Use a custom Cargo container image |
| `--force` | Force re-connection of client, even if it is already active. |
| `--timeout` | Timeout for each connection step in seconds. (default: `60`) |
[](){#connections-disconnect}**â–¶ connections disconnect**
*Aliases: `stop`, `halt`*
Disconnect this local machine from a Gefyra cluster
**Example:**
```sh
gefyra connections disconnect my-connection
```
**Positional Arguments:**
| Argument | Description |
| :---------------- | :---------- |
| `connection_name` | |
**Arguments:**
| Argument | Description |
| :---------- | :-------------------------------------------------------- |
| `--yes` | Non-interactive mode, do not ask for confirmation |
| `--nowait` | Do not wait for the GefyraClient to be in state 'WAITING' |
| `--timeout` | Timeout for disconnect in seconds. (default: `60`) |
[](){#connections-inspect}**â–¶ connections inspect**
Inspect a Gefyra connection
**Example:**
```sh
gefyra connections inspect my-connection
```
**Positional Arguments:**
| Argument | Description |
| :---------------- | :---------- |
| `connection_name` | |
**Arguments:**
| Argument | Description |
| :--------------- | :--------------------------------------------------------- |
| `--output`, `-o` | Output format for the connection details (default: `text`) |
[](){#connections-list}**â–¶ connections list**
*Aliases: `ls`*
List all Gefyra connections
**Example:**
```sh
gefyra connections list
```
**Arguments:**
| Argument | Description |
| :--------------- | :------------------------------------------------------ |
| `--output`, `-o` | Output format for the connection list (default: `text`) |
[](){#connections-remove}**â–¶ connections remove**
*Aliases: `rm`*
Remove a Gefyra connection
**Example:**
```sh
gefyra connections rm my-connection
```
**Positional Arguments:**
| Argument | Description |
| :---------------- | :---------- |
| `connection_name` | |
**Arguments:**
| Argument | Description |
| :------- | :------------------------------------------------ |
| `--yes` | Non-interactive mode, do not ask for confirmation |
---
### down
Remove Gefyra locally and on the cluster
**Example:**
```sh
gefyra down
```
---
### install
Create and print the Kubernetes configs for Gefyra; usage: 'gefyra install [options] | kubectl apply -f -
**Example:**
```sh
gefyra install
```
**Arguments:**
| Argument | Description |
| :------------------------------- | :------------------------------------------------------------------------------------------------- |
| `--component`, `--comp` | Limit config creation to this component (available: namespace,rbac,webhook,deployment,service) |
| `--preset` | Set configs from a preset (available: aws,gke) |
| `--apply` | |
| `--wait` | |
| `-ns`, `--namespace` | The namespace to install Gefyra into (default: gefyra) |
| `--version` | Set the Operator version; components are created according to this Gefyra version (default: 2.5.4) |
| `--service-type` | The Kubernetes service for Stowaway to expose the Wireguard endpoint (default: NodePort) |
| `--service-port` | The port for Stowaway to expose the Wireguard endpoint (default: 31820) |
| `--service-labels` | Additional Kubernetes labels for the Stowaway service (default: [] ) |
| `--service-annotations` | Kubernetes annotations for the Stowaway service (default: [] ) |
| `--registry` | The registry URL for the images (default: quay.io/gefyra) |
| `--mtu` | The MTU for the Wireguard interface (default: auto-detected by WireGuard) |
| `--stowaway-storage` | The storage size for the Stowaway PVC in Mi (default: 64) |
| `--max-client-connection-age` | The maximum age of a Stowaway connection in seconds (default: None) |
| `--disable-client-sa-management` | Whether to create/manage client service accounts for Gefyra (default: False) |
| `--bridge-debug` | Enable debug logging for GefyraBridgeMounts/GefyraBridges (default: False) |
---
### list
List running containers
**Example:**
```sh
gefyra list
```
**Arguments:**
| Argument | Description |
| :------------------------ | :------------------------------------------ |
| `-n`, `--connection-name` | Only list from this client connection name. |
---
### mount
Manage GefyraBridgeMounts for a Gefyra installation
**Example:**
```sh
gefyra mount create --target deploy/my-deploy/my-container
gefyra mount list
gefyra mount delete my-mount
```
**Subcommands:**
- [`mount create`](https://gefyra.dev/#mount-create) — Create a new GefyraBridgeMount in the cluster
- [`mount delete`](https://gefyra.dev/#mount-delete) — Mark a GefyraBridgeMount for deletion
- [`mount inspect`](https://gefyra.dev/#mount-inspect) — Describe a GefyraBridgeMount
- [`mount list`](https://gefyra.dev/#mount-list) — List all GefyraBridgeMounts
[](){#mount-create}**â–¶ mount create**
Create a new GefyraBridgeMount in the cluster
**Example:**
```sh
gefyra mount create --target deploy/my-deploy/my-container -n default
```
**Arguments:**
| Argument | Description |
| :------------------------ | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--namespace` | The GefyraBridgeMount's target namespace (default: `default`) |
| `--name` | Assign a custom name to this GefyraBridgeMount |
| `--target` | Install a GefyraBridgeMount to workloads following the notion 'resource/name/container'. Resource can be one of 'deployment', 'statefulset' or 'pod'. E.g.: --target deployment/hello-nginx/nginx **(required)** |
| `--tls-key` | Path to key file for tls traffic (within the target container) or secret notation 'secret:{namespace}/{name}:{key}'. To address specific ports, use the format ``@port |
| `--tls-certificate` | Path to certificate file for tls traffic (within the target container) or secret notation 'secret:{namespace}/{name}:{key}'. To address specific ports, use the format ``@port |
| `--tls-sni` | SNI for tls traffic (within the target container) or secret notation 'secret:{namespace}/{name}:{key}'. To address specific ports, use the format ``@port |
| `--connection-name`, `-c` | Default: `default` |
| `--nowait` | Do not wait for the GefyraBridgeMount to be ready |
| `--timeout` | Default: `60` |
[](){#mount-delete}**â–¶ mount delete**
*Aliases: `rm`, `remove`*
Mark a GefyraBridgeMount for deletion
**Example:**
```sh
gefyra mount delete my-mount
gefyra mount rm my-mount
```
**Positional Arguments:**
| Argument | Description |
| :----------- | :------------- |
| `mount_name` | **(required)** |
**Arguments:**
| Argument | Description |
| :------------------------ | :--------------------------------------------------- |
| `--nowait` | Do not wait for the GefyraBridgeMount to be deleted. |
| `--connection-name`, `-c` | Default: `default` |
| `--timeout` | Default: `60` |
[](){#mount-inspect}**â–¶ mount inspect**
*Aliases: `describe`, `show`, `get`*
Describe a GefyraBridgeMount
**Example:**
```sh
gefyra mount inspect my-mount
```
**Positional Arguments:**
| Argument | Description |
| :----------- | :------------- |
| `mount_name` | **(required)** |
**Arguments:**
| Argument | Description |
| :------------------ | :----------------- |
| `-o`, `--output` | Default: `text` |
| `--connection-name` | Default: `default` |
[](){#mount-list}**â–¶ mount list**
*Aliases: `ls`*
List all GefyraBridgeMounts
**Example:**
```sh
gefyra mount list
gefyra mount ls
```
**Arguments:**
| Argument | Description |
| :------------------ | :----------------- |
| `--output`, `-o` | Default: `text` |
| `--connection-name` | Default: `default` |
---
### operator
Manage operator installation
**Example:**
```sh
gefyra operator update
```
**Subcommands:**
- [`operator update`](https://gefyra.dev/#operator-update) — Update operator to latest or specific version.
[](){#operator-update}**â–¶ operator update**
Update operator to latest or specific version.
**Example:**
```sh
gefyra operator update
```
**Arguments:**
| Argument | Description |
| :---------- | :------------------------------------------ |
| `--version` | Set specific version to update operator to. |
---
### rm
Remove a Gefyra container and its associated bridges
**Example:**
```sh
gefyra rm mycontainer
```
**Positional Arguments:**
| Argument | Description |
| :------- | :---------- |
| `name` | |
**Arguments:**
| Argument | Description |
| :------------------ | :--------------------------------------------------------- |
| `-A`, `--all` | Remove all Gefyra containers and their bridges |
| `-f`, `--force` | Force remove containers (even if running) |
| `--nowait` | Do not wait for containers and bridges to be fully removed |
| `--connection-name` | Default: `default` |
---
### run
Run a container in Gefyra.
```text
Any additional container engine arguments can be passed after the known
options. They are forwarded directly to the Docker/Podman API.
Use the docker-py parameter names with '--' prefix and '-' separators:
gefyra run -i myimage -N myname -- --cpu-shares 512 --mem-reservation 256m
gefyra run -i myimage -N myname -- --cpu-period 100000 --cpu-quota 50000
See https://docker-py.readthedocs.io/en/stable/containers.html for the
full list of supported parameters.
```
**Example:**
```sh
gefyra run -i pyserver -N mypyserver -n default
```
**Arguments:**
| Argument | Description |
| :------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `-d`, `--detach` | Run container in background and print container ID |
| `--rm` | Automatically remove the container when it exits |
| `-p`, `--expose` | Add port mapping in form of ``:`` |
| `--env-from` | Copy the environment from the container in the notation 'Pod/Container' |
| `--cpu-from` | Inherit CPU limit from a workload, e.g. 'pod/``', 'deployment/``' or 'statefulset/``' |
| `--memory-from` | Inherit memory limit from a workload, e.g. 'pod/``', 'deployment/``' or 'statefulset/``' |
| `--cpu` | [Deprecated: pass docker/podman args after '--' instead, e.g. `-- --cpu-period 100000 --cpu-quota 50000` for 0.5 CPU. Note: raw microseconds, k8s-style notation is not supported by the engine] CPU limit for the container (e.g. '500m' or '2') |
| `--memory` | [Deprecated: pass docker/podman args after '--' instead, e.g. `-- --memory 512m`. Note: the engine accepts suffixes 'b/k/m/g', not k8s-style 'Mi'/'Gi'] Memory limit for the container (e.g. '512Mi', '1Gi', or '1g') |
| `--user` | Username or UID (format: \`\{rel=""nofollow""}
## Running Gefyra
### 1. Set up Gefyra with your Colima cluster:
```sh
gefyra up
```
**Important**:
### 2. Run a local Docker container with Gefyra in order to connect it with the cluster.
#### 2.1 Build a simple Docker image with a local tag. Save the following two files in a directory on your disk.
```dockerfile [Dockerfile]
FROM ubuntu
# run a server on port 8000
RUN apt update && apt install -y iproute2 iputils-ping python3 traceroute wget curl
COPY local.py local.py
CMD python3 local.py
```
::code-collapse
```py [local.py]
import http.server
import signal
import socket
import socketserver
import sys
from datetime import datetime
if sys.argv[1:]:
port = int(sys.argv[1])
else:
port = 8000
class MyHttpRequestHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
hostname = socket.gethostname()
now = datetime.utcnow()
self.wfile.write(
bytes(
f"Hello from Gefyra. It is {now} on"
f" {hostname}.
".encode("utf-8")
)
)
my_handler = MyHttpRequestHandler
server = socketserver.ThreadingTCPServer(("", port), my_handler)
def signal_handler(signal, frame):
try:
if server:
server.server_close()
finally:
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
try:
while True:
sys.stdout.flush()
server.serve_forever()
except KeyboardInterrupt:
pass
server.server_close()
```
::
#### 2.2 Build it by running `docker build -f Dockerfile . -t pyserver` in your directory.
#### 2.3 Execute Gefyra's run command:
```sh
gefyra run -d -i pyserver -N mypyserver -n default
```
**Important**: `gefyra run` is just a wrapper for `docker run` (with additional flags), yet it also applies Gefyra's networking configuration to connect the container with Kubernetes. Check out [the docs for `gefyra run`](https://gefyra.dev/en/quick-start/cli#run)
### 3. *Exec* into the running container and look around. You will find the container to run within your Kubernetes cluster.
```sh
docker exec -it mypyserver bash
```
```sh
wget -O- hello-nginx
```
will print out the website of the cluster service *hello-nginx* from within the cluster. 🚀
### 4. Create a bridge to redirect the traffic from the cluster application to the one running locally:
```sh
gefyra bridge -N mypyserver -n default --ports 80:8000 --target deploy/hello-nginxdemo/hello-nginx
```
Check out the locally running server serving the cluster by refreshing the address from the service in Kubernetes.
It shows you a different message: `Hello from Gefyra. It is ...`. Yes, that is really coming from your local container! 😎
### 5. List all running *bridges*:
You can list all currently active bridges with:
```sh
gefyra list --bridges
```
You will find all local containers that are currently linked into the cluster serving requests.
### 6. *Unbridge* the local container and reset the cluster to its original state:
```sh
gefyra unbridge --all
```
Check out the original response from the service. The cluster is now reset to its inital state again.
## Cleaning up
1. Remove Gefyra's components from the cluster and your local Docker host with:
```sh
gefyra down
```
2. Remove the locally running Kubernetes cluster with
```sh
colima delete
```
::card
Did everything work as expected? How was the experience of using Gefyra? We'd appreciate if you could take 2 minutes of your time to fill out our
[feedback form](https://forms.gle/AWT9NparpTVk8E978){rel=""nofollow""}
.
#title
Please provide us with your feedback
::
# Getting started with Gefyra and Docker Desktop Kubernetes on MacOS
**Try out our [Docker Desktop Extension](https://gefyra.dev/en/quick-start/docker-desktop-extension)!**
**Note:** Gefyra works the same for different Kubernetes distributions. Docker Desktop doesn't come with an ingress installed which must be added to the cluster to get things working.
You can easily try Gefyra yourself following this small example.
## Prerequisites
1. Follow the [installation](https://gefyra.dev/en/quick-start/installation/) for MacOS.
2. Start the Kubernetes cluster that comes with Docker Desktop. This may take moment.

3. Tell kubectl to use your docker-desktop cluster:
```sh
kubectl config use-context docker-desktop
```
4. Install an ingress to enable routing for the cluster. For this guide we use the nginx
ingress controller like this:
```sh
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.2.1/deploy/static/provider/cloud/deploy.yaml
```
5. Now patch the nginx ingress controller service to make port `8080` available:
```sh
kubectl patch svc -n ingress-nginx ingress-nginx-controller -p '{"spec": {"ports": [{"appProtocol": "http", "name": "http", "port": 8080, "protocol": "TCP", "targetPort": "http"}]}}' --type merge
```
6. Apply some workload, for example from the testing directory of this repo:
```sh
kubectl apply -f https://raw.githubusercontent.com/gefyrahq/gefyra/main/testing/workloads/hello_dd.yaml
```
Check out this workload running under: {rel=""nofollow""}
7. Set up Gefyra with the following command:
**For Docker Desktop <4.16.x:**
```sh
gefyra up
```
**For Docker Desktop >=4.16.x:**
```sh
gefyra up --host=kubernetes.docker.internal
```
## Running Gefyra
### 1. Run a local Docker image with Gefyra in order to make it part of the cluster.
1. Build your Docker image with a local tag, for example from the testing directory:
```sh
cd testing/images/ && docker build -f Dockerfile.local . -t pyserver
```
2. Execute Gefyra's run command:
```sh
gefyra run -i pyserver -N mypyserver -n default
```
3. *exec* into the running container and look around. You will find the container to run within your Kubernetes cluster.
```sh
docker exec -it mypyserver bash
wget -O- hello-nginx
```
will print out the website of the cluster service hello-nginx from within the cluster.
### 2. Create a bridge in order to intercept the traffic to the cluster application with the one running locally
```sh
gefyra bridge -N mypyserver -n default --port 8000:80 --target deploy/hello-nginxdemo/hello-nginx
```
Check out the locally running server comes up under: {rel=""nofollow""}
### 3. List all running *bridges*:
```sh
gefyra list --bridges
```
### 4. *Unbridge* the local container and reset the cluster to its original state:
```sh
gefyra unbridge -N mypybridge
```
Check out the initial response from: {rel=""nofollow""}
## Cleaning up
Remove Gefyra's components from the cluster with
```sh
gefyra down
```
::card
Did everything work as expected? How was the experience of using Gefyra? We'd appreciate if you could take 2 minutes of your time to fill out our
[feedback form](https://forms.gle/AWT9NparpTVk8E978){rel=""nofollow""}
.
#title
Please provide us with your feedback
::
# Getting started with Gefyra and k3d
## Prerequisites
1. K3d is [installed](https://k3d.io/#installation){rel=""nofollow""} (at least in version v5.4.9)
2. Gefyra is [available](https://gefyra.dev/en/quick-start/installation) (at least in version 2.0.0)
**Hint** there is a bug in Docker Desktop v4.17-v4.18 which causes `gefyra up` to fail with k3d clusters that run on that DD version.
## Creating a local Kubernetes cluster
{.w-full}
### 1. Create a local Kubernetes cluster with k3d by running:
```sh
k3d cluster create mycluster --agents 1 -p 8080:80@agent:0 -p 31820:31820/UDP@agent:0
```
This creates a Kubernetes cluster that binds port 8080 and 31820 to localhost. The `kubectl` context is immediately set to this cluster.
### 2. Apply some workload, for example from the testing directory of this repo:
```sh
kubectl apply -f https://raw.githubusercontent.com/gefyrahq/gefyra/main/testing/workloads/hello.yaml
```
Check out this workload running under: {rel=""nofollow""}
## Running Gefyra
### 1. Set up Gefyra with your k3d cluster:
```sh
gefyra up
```
### 2. Run a local Docker container with Gefyra in order to connect it with the cluster.
#### 2.1 Build a simple Docker image with a local tag. Save the following two files in a directory on your disk.
```dockerfile [Dockerfile]
FROM ubuntu
# run a server on port 8000
RUN apt update && apt install -y iproute2 iputils-ping python3 traceroute wget curl
COPY local.py local.py
CMD python3 local.py
```
::code-collapse
```py [local.py]
import http.server
import signal
import socket
import socketserver
import sys
from datetime import datetime
if sys.argv[1:]:
port = int(sys.argv[1])
else:
port = 8000
class MyHttpRequestHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
hostname = socket.gethostname()
now = datetime.utcnow()
self.wfile.write(
bytes(
f"Hello from Gefyra. It is {now} on"
f" {hostname}.
".encode("utf-8")
)
)
my_handler = MyHttpRequestHandler
server = socketserver.ThreadingTCPServer(("", port), my_handler)
def signal_handler(signal, frame):
try:
if server:
server.server_close()
finally:
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
try:
while True:
sys.stdout.flush()
server.serve_forever()
except KeyboardInterrupt:
pass
server.server_close()
```
::
#### 2.2 Build it by running `docker build -f Dockerfile . -t pyserver` in your directory.
#### 2.3 Execute Gefyra's run command:
```sh
gefyra run -d -i pyserver -N mypyserver -n default
```
**Important**: `gefyra run` is just a wrapper for docker run (with additional flags), yet it also applies Gefyra's networking configuration to connect the container with Kubernetes. Check out [the docs for gefyra run](https://gefyra.dev/en/quick-start/cli#run)
### 3. *Exec* into the running container and look around. You will find the container to run within your Kubernetes cluster.
```sh
docker exec -it mypyserver bash
```
```sh
wget -O- hello-nginx
```
will print out the website of the cluster service *hello-nginx* from within the cluster. 🚀
### 4. Create a bridge to redirect the traffic from the cluster application to the one running locally:
```sh
gefyra bridge -N mypyserver -n default --ports 80:8000 --target deploy/hello-nginxdemo/hello-nginx
```
Check out the locally running server serving the cluster by refreshing the address from the service in Kubernetes.
It shows you a different message: `Hello from Gefyra. It is ...`. Yes, that is really coming from your local container! 😎
### 5. List all running *bridges*:
You can list all currently active bridges with:
```sh
gefyra list --bridges
```
You will find all local containers that are currently linked into the cluster serving requests.
### 6. *Unbridge* the local container and reset the cluster to its original state:
```sh
gefyra unbridge --all
```
Check out the original response from the service. The cluster is now reset to its inital state again.
## Cleaning up
Remove Gefyra's components from the cluster and your local Docker host with:
```sh
gefyra down
```
## Deleting the locally running k3d Kubernetes cluster with
```sh
k3d cluster delete mycluster
```
::card
Did everything work as expected? How was the experience of using Gefyra? We'd appreciate if you could take 2 minutes of your time to fill out our
[feedback form](https://forms.gle/AWT9NparpTVk8E978){rel=""nofollow""}
.
#title
Please provide us with your feedback
::
# Getting started with Gefyra and kind
## Prerequisites
1. Follow the [installation](https://gefyra.dev/en/quick-start/installation) for your preferred platform.
2. Create a local Kubernetes cluster with `kind` like this: Create a file `kind-config.yaml`:
```yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 31820
hostPort: 31820
protocol: udp
```
Run:
```bash
kind create cluster --config kind-config.yaml
```
## Running Gefyra
### 1. Set up Gefyra with
```sh
gefyra up
```
### 2. Run a local Docker image with Gefyra in order to make it part of the cluster.
#### 2.1 Build your Docker image with a local tag, for example from the testing directory:
```sh
cd testing/images/ && docker build -f Dockerfile.local . -t pyserver
```
#### 2.2 Execute Gefyra's run command:
```sh
gefyra run -i pyserver -N mypyserver -n default
```
#### 2.3 *Exec* into the running container and look around. You will find the container to run within your Kubernetes cluster.
```sh
docker exec -it mypyserver bash
wget -O- hello-nginx
```
will print out the website of the cluster service hello-nginx from within the cluster.
### 3. Create a bridge in order to intercept the traffic to the cluster application with the one running locally:
```sh
gefyra bridge -N mypyserver -n default --port 8000:80 --target deploy/hello-nginxdemo/hello-nginx
```
Check out the locally running server comes up under: {rel=""nofollow""}
### 4. List all running *bridges*:
```sh
gefyra list --bridges
```
### 5. *Unbridge* the local container and reset the cluster to its original state:
```sh
gefyra unbridge -N mypybridge
```
Check out the initial response from: {rel=""nofollow""}
## Cleaning up
1. Remove Gefyra's components from the cluster with
```sh
gefyra down
```
2. Remove the locally running Kubernetes cluster with
```sh
kind delete cluster
```
::card
Did everything work as expected? How was the experience of using Gefyra? We'd appreciate if you could take 2 minutes of your time to fill out our
[feedback form](https://forms.gle/AWT9NparpTVk8E978){rel=""nofollow""}
.
#title
Please provide us with your feedback
::
# Getting started with Gefyra and Minikube
::note
Please refer to the general
[getting started guide](https://gefyra.dev/en/local-environments/getting-started)
for Gefyra as this is about Minikube, too.
::
::card
Did everything work as expected? How was the experience of using Gefyra? We'd appreciate if you could take 2 minutes of your time to fill out our
[feedback form](https://forms.gle/AWT9NparpTVk8E978){rel=""nofollow""}
.
#title
Please provide us with your feedback
::
::card
Did everything work as expected? How was the experience of using Gefyra? We'd appreciate if you could take 2 minutes of your time to fill out our
[feedback form](https://forms.gle/AWT9NparpTVk8E978){rel=""nofollow""}
.
#title
Please provide us with your feedback
::
# Setting up a Shared Kubernetes Cluster
::card-group
:::card
---
title: Installing Gefyra in a Cluster
to: https://gefyra.dev/en/shared-environments/installation
---
Installing Gefyra to a remote cluster is usually slightly different to a local setup. This is because the networking aspect differs considerably between a local cluster, that might be created with overlay networks and port-forwarding, and remote clusters with cloud-specific routing components. Starting with Gefyra 2, you get good control of the cluster-side components.
:::
:::card
---
title: Managing Gefyra Clients
to: https://gefyra.dev/en/shared-environments/clients
---
Gefyra Clients provide a way to grant multiple clients (i.e. users, robots, pipelines, etc.) limited access to a Kubernetes cluster in order to use Gefyra's capabilities. They are managed with gefyra clients [COMMAND].
:::
:::card
---
title: Connecting to Gefyra
to: https://gefyra.dev/en/shared-environments/connecting
---
If you have a Gefyra client file and want to connect to a shared Kubernetes cluster,
:::
:::card
---
title: Guides to Remote Kubernetes Clusters
to: https://gefyra.dev/en/remote-k8s/getting-started
---
This chapter contains guides on how to set up shared remote Kubernetes for Gefyra. These guides are usually for multiple client use cases.
:::
::
# Gefyra (Remote) Cluster Installation
## Prerequisites
- Gefyra is [available](https://gefyra.dev/en/quick-start/installation/) (at least in version 2.0.0)
## The Installation
There are a couple of options for the installation procedure. Gefyra's executable ships with all required Kubernetes configs for that specific version.
To introspect what is going to be installed into your cluster, just run `gefyra install`. This command generates a list of Kubernetes objects that can either be stored for manual modification, or directly applied to the cluster.
```sh
> gefyra install
apiVersion: v1
kind: Namespace
metadata:
name: gefyra
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: gefyra-operator
namespace: gefyra
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
[...]
```
Please check out the [CLI reference for that command](https://gefyra.dev/en/quick-start/cli#install).
If the default configuration is suitable for your environment, directly apply it with:
```sh
gefyra install | kubectl apply -f -
```
That will pipe the Kubernetes configs generated by Gefyra's install command directly into the cluster context that is currently active.
::note
Check your active cluster context with
`kubectl config current-context`
.
::
## Default networking
Gefyra depends on a working [Wireguard VPN](https://www.wireguard.com/){rel=""nofollow""} connection between the cluster and Gefyra's clients. Setting up that connection is completely managed by Gefyra and only requires little configuration from a cluster admin: that is configuring the VPN route.
::note
Gefyra's default to expose its Wireguard endpoint is via a Kubernetes service of type
**NodePort**
. However, this can only work if the Kubernetes nodes have a public (internet-routable) IP address, or at least this IP is reachable for all clients.
::
You can check out the Kubernetes service object in the output of `gefyra install`.
```sh
gefyra install | grep "type:" -B21
```
```yaml
apiVersion: v1
kind: Service
metadata:
annotations: {}
labels:
gefyra.dev/app: stowaway
gefyra.dev/provider: stowaway
gefyra.dev/role: connection
name: gefyra-stowaway-wireguard
namespace: gefyra
spec:
ports:
- name: gefyra-wireguard
nodePort: 31820
port: 51820
protocol: UDP
targetPort: 51820
selector:
gefyra.dev/app: stowaway
gefyra.dev/provider: stowaway
gefyra.dev/role: connection
type: NodePort
```
This service will open up the port **31820** on all of your Kubernetes nodes and route VPN traffic to Gefyra.
If you don't want to expose Gefyra via a *NodePort* service, or you don't have routable IPs on your Kubernetes nodes, you need to set up a **UDP load balancing** for Gefyra. Luckily, Gefyra's got you covered.
## Setting up a UDP `Loadbalancer`
::note
Gefyra's VPN connection is established using UDP traffic. Not all cloud providers offer a UDP load balancing solution. If you can not use a
*Loadbalancer*
, you have to stick with the
*NodePort*
service.
::
To switch the load balancer service for the installation, just set the appropriate option flag for the `gefyra install` command:
```sh
gefyra install --service-type=Loadbalancer
```
In many cases, the external infrastructure for a Kubernetes cluster is managed via service annotations. With Gefyra you can set custom annotations easily using the `--service-annotations` as often as you need.
For example:
```sh
gefyra install --service-type=Loadbalancer --service-annotations service.beta.kubernetes.io/aws-load-balancer-nlb-target-type=ip --service-annotations service.beta.kubernetes.io/aws-load-balancer-scheme=internet-facing
```
will create the following service in your cluster:
```yaml
apiVersion: v1
kind: Service
metadata:
annotations:
# see these annotations
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
labels:
gefyra.dev/app: stowaway
gefyra.dev/provider: stowaway
gefyra.dev/role: connection
name: gefyra-stowaway-wireguard
namespace: gefyra
spec:
ports:
- name: gefyra-wireguard
port: 31820
protocol: UDP
targetPort: 51820
selector:
gefyra.dev/app: stowaway
gefyra.dev/provider: stowaway
gefyra.dev/role: connection
type: LoadBalancer
```
Please be aware that Gefyra comes with a few manually crafted presets for popular Kubernetes offering. Check out the next section to learn how you install Gefyra using an available installation preset.
## Presets
To make it as convenient as possible, Gefyra offers presets for widely used Kubernetes offerings, such as Google's GKE or Amazon EKS.
Please check available presets with:
```sh
gefyra install --help | grep preset
--preset TEXT Set configs from a preset (available: aws,gke)
```
Currently, it's only *aws* and *gke*. If you want to add another preset for another popular Kubernetes provider, please consider[ opening a ticket on GitHub](https://github.com/gefyrahq/gefyra/issues/new?assignees=&labels=enhancement&projects=&template=feature-request.yaml){rel=""nofollow"" target="blank"} for it.
**Example:** If you install Gefyra to an EKS cluster, you only have to set the preset `gefyra install --preset aws | kubectl apply -f -`, and it will automatically create the *Network Load Balancer* via the required annotations on the Kubernetes service:
```yaml
apiVersion: v1
kind: Service
metadata:
annotations:
# see these annotations
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
service.beta.kubernetes.io/aws-load-balancer-type: nlb
labels:
gefyra.dev/app: stowaway
gefyra.dev/provider: stowaway
gefyra.dev/role: connection
name: gefyra-stowaway-wireguard
namespace: gefyra
spec:
ports:
- name: gefyra-wireguard
port: 31820
protocol: UDP
targetPort: 51820
selector:
gefyra.dev/app: stowaway
gefyra.dev/provider: stowaway
gefyra.dev/role: connection
type: LoadBalancer
```
# Working With Gefyra Clients
::note
Gefyra Clients provide a way to grant multiple clients (i.e. users, robots, pipelines, etc.) limited access to a Kubernetes cluster in order to use Gefyra's capabilities. They are managed with
[gefyra clients [COMMAND]](https://gefyra.dev/en/quick-start/cli#clients)
.
::
## Shared Cluster Access
Each created client object get a dedicated *Kubernetes Service Account* attached that is being used by any Gefyra client during its interaction with the cluster. The corresponding *client file*, which contains the connection parameters for the *Service Account* can be retrieved from the cluster by the administrator with Gefyra's CLI.
This client file can be then distributed to anyone which needs to `connect`, `run` or `bridge` workloads in the given cluster.
The permissions of the Kubernetes service account are limited, following the principle of the least privilege. Hence, Gefyra clients can only operate in the cluster with the well-defined set of Gefyra's actions.
This flow gives a brief overview of Gefyra's workflow for teams:
::mermaid
---
:config: config
code: flowchart%20TD%3B%0A%20%20%20%20install%5B%22DevOps%20installs%20Gefyra%20(%3Ca%20href%3D'%2Fen%2Fquick-start%2Fcli%23install'%3Egefyra%20install%3C%2Fa%3E)%22%5D%0A%20%20%20%20generate%5B%22DevOps%20generates%20Gefyra%20client%20(%3Ca%20href%3D'%2Fen%2Fquick-start%2Fcli%23clients'%3Egefyra%20clients%20create%3C%2Fa%3E)%22%5D%0A%20%20%20%20save%5B%22DevOps%20saves%20Gefyra%20client%20files%20(%3Ca%20href%3D'%2Fen%2Fquick-start%2Fcli%23clients-config'%3Egefyra%20clients%20config%3C%2Fa%3E)%22%5D%0A%20%20%20%20distribute%5B%22DevOps%20distributes%20client%20file%22%5D%0A%20%20%20%20connect%5B%22Developer%20connects%20via%20client%20file%20(%3Ca%20href%3D'%2Fen%2Fquick-start%2Fcli%23connections'%3Egefyra%20connections%3C%2Fa%3E)%22%5D%0A%20%20%20%20run%5B%22Developer%20runs%20workload%20(%3Ca%20href%3D'%2Fen%2Fquick-start%2Fcli%23run'%3Egefyra%20run%3C%2Fa%3E)%22%5D%0A%20%20%20%20install--%3Egenerate%0A%20%20%20%20generate--%3Esave%0A%20%20%20%20save--%3Edistribute%0A%20%20%20%20distribute--%3Econnect%0A%20%20%20%20connect--%3Erun
---
::
::warning{:title="Don't share client connections"}
Although clients may be used by multiple machines, it is neither recommended not will it work simultaneously. Once a client connects to a cluster, it agrees with Gefyra's Operator on a dedicated IP-range that no other client can use at the same time. Clients may connect and disconnect at any time. When disconnecting from the cluster, clients release their VPN peer (and thus their IP-range) association.
::
## Prerequisites
- Gefyra is [available](https://gefyra.dev/en/quick-start/installation) (at least in version 2.0.0)
- Gefyra is [installed](https://gefyra.dev/en/shared-environments/installation) to a shared Kubernetes cluster
- Admin access to the shared cluster
## Creating a Gefyra Client
You can create as many clients as you need in a cluster. Every client will have it's very own VPN connection to the cluster.
An admin manages clients via Gefyra's `gefyra client` command group in the CLI. Gefyra operates with the currently active cluster context on the machine it is running on.
::note
Check your active cluster context with
`kubectl config current-context`
.
::
```sh
> gefyra client
Manage clients for a Gefyra installation
Commands:
config (write) Get a Gefyra connection config for a client
create Create a new Gefyra client
delete (rm,remove) Mark a Gefyra client for deletion
inspect (show,get) Discribe a Gefyra client
list (ls) List all Gefyra clients
```
You can create one client object with:
```sh
> gefyra client create
1 client(s) created successfully
```
That command created a randomly named client in your cluster. You can find it with:
```sh
> gefyra clients ls
ID STATE CREATED
20d50da476524eaf8dd511deed55fc63 GefyraClientState.REQUESTED Creating...
```
Once the client is ready, you will find the following output:
```sh
> gefyra clients ls
ID STATE CREATED
20d50da476524eaf8dd511deed55fc63 GefyraClientState.WAITING 2023-10-06T15:21:19.771717Z
```
The client is now in the waiting state and ready for connection.
To manage human-readable clients, you can set the client name with:
```sh
gefyra clients create --client-id my-fancy-client
```
or create many clients at once using:
```sh
gefyra clients create -n 10
```
This will create a set of 10 clients in the cluster.
## Retrieving a *Client File*
Gefyra clients require a client file to connect to this cluster. The admin is responsible to fetch these client files and distribute them to other machines, developers, etc.
### A Default Client File
The following command prints the client file of the selected client to the console:
```sh
gefyra clients config 20d50da476524eaf8dd511deed55fc63
{"client_id": "20d50da476524eaf8dd511deed55fc63", "kubernetes_server": "https://", "provider": "stowaway", "token": "", "namespace": "", "ca_crt": "", "gefyra_server": ":31820"}
```
As you can see, the *client file* is JSON-structured and contains a lot of secret information. Especially the
*access token* of the Kubernetes service account that is associated with this Gefyra client, but also the other connection
parameters are **highly sensible**.
::note
Please handle the
*client files*
with care as they contain confidential information. Leaking these files may allow unidentified individuals access to your Gefyra cluster.
::
You can either pipe that output to a file on your local machine:
```sh
gefyra clients config 20d50da476524eaf8dd511deed55fc63 > 20d50da476524eaf8dd511deed55fc63.json
```
or use the *output flag*
```sh
gefyra clients config 20d50da476524eaf8dd511deed55fc63 -o 20d50da476524eaf8dd511deed55fc63.json
```
in your current working directory.
### Providing Custom Connection Data
::note
In this process, Gefyra tries to determine as many connection parameters as possible automatically. However, if there are network-related customizations to made for your client, please provide them at this point.
::
If you need to specify the connection endpoint for Kubernetes differently, please use the `--kubernetes-api` option, e.g.
```sh
gefyra clients config 20d50da476524eaf8dd511deed55fc63 --kubernetes-api "https://k8s.blueshoe.io"
```
If you need to specify Gefyra's VPN connection endpoint, please use the `--host` and/or `--port` option, e.g.
```sh
gefyra clients config 20d50da476524eaf8dd511deed55fc63 --host 192.169.0.1
```
This data will be written into the `client file` so that your clients can connect to the cluster using these parameters. If you fail to provide correct data to your clients, they might be unable to connect to the cluster.
### Distributing the Client File
This *client file* is all a Gefyra client needs in order to establish a connection. Of course, you are free to distribute these files any way you want, but please keep in mind the security implications.
## Deleting a Gefyra Client
You can delete a Gefyra client in every stage of its lifecycle. This will disconnect the client (forcefully) and render its client file invalid, thus the owner of the file will no longer be able to connect to the cluster.
```sh
> gefyra clients delete 20d50da476524eaf8dd511deed55fc63
Client 20d50da476524eaf8dd511deed55fc63 marked for deletion
```
When you delete a Gefyra client, its credentials are also irretrievably deleted.
# Connecting to Gefyra
::tip
If you have a Gefyra client file and want to connect to a shared Kubernetes cluster,
just run
`gefyra connections connect -f `
::
## Prerequisites
- Gefyra is [available](https://gefyra.dev/en/quick-start/installation) (at least in version 2.0.0)
- A running Docker host on the machine that connects
- A Gefyra [client file](https://gefyra.dev/en/shared-environments/clients#a-default-client-file)
## Managing connections
Client connections to a Gefyra cluster are managed with the `gefyra connections` command group.
The connection itself consists of a file, that is located in a local user directory, and *usually* a Docker container that acts as a VPN endpoint on a local machine.
### Connect
::note
You can only connect to a Gefyra cluster with a
[client file](https://gefyra.dev/en/shared-environments/clients#distributing-the-client-file)
. If you don't have such a client file, either
[set up Gefyra in a Kubernetes cluster](https://gefyra.dev/en/shared-environments/installation)
and create yourself
[a Gefyra client](https://gefyra.dev/en/shared-environments/clients#creating-a-gefyra-client)
, or find the responsible person and ask for access.
::
Establishing a connection (**for the first time**) to Gefyra works like this:
```sh
> gefyra connections connect -f myfancyclient.json
Creating the cluster connection 'default' | â–¶â–¶â–¶â–¶â–¶â–¶â–¶ | / 0 in 28s
Connection established with connection name 'default'. Run 'gefyra connections list' to see all connections.
```
This example assumes, there is a client that provides the client file *myfancyclient.json*. A couple of things happened during this process:
1. Gefyra fetched the ad-hoc VPN credentials for this connection
2. A container for the Gefyra connection with name *default* has been started
3. A dedicated Docker network has been created
4. The connection was successfully checked
If you check your Docker host, you will find a container named `gefyra-cargo-default` running. That's the gateway into the cluster.
::warning
Since we didn't specify a
*connection name*
and there was no
*default*
connection available before, creating it was successful. However, there is only one
*default*
connection on a client machine. Additional connections must
[be assigned a name](https://gefyra.dev/#connection-names)
.
::
Once you have a stopped connection, you don't need the client file anymore to connect. Just run the following with the *default* connection:
```sh
gefyra connections connect
```
The Gefyra connection will be back up in no time. Of course, if you do have multiple connections, you have to specify the connection name with the `--connection-name` option.
::warning
After you successfully connected a machine with a Gefyra cluster, the
*client file*
is typically superseded at that point. Gefyra stores the credentials from the file elsewhere, so a user doesn't have to handle the file. However, if you remove your connection and want to reconnect to the cluster (assuming the Gefyra client is still the same) you may connect to the cluster with that file again. Yet, you can also request a new one, which is safer than having a
*client file*
dangling.
::
### Listing connections
To see all Gefyra connections on a local machine, please run the following:
```sh
> gefyra connections list
NAME VERSION CREATED STATUS
default 2.0.0 2023-10-10T18:36:15.519969679Z running
```
You will find the status of all of your connections here. It can be `running`, `stopped` or `error`.
### Disconnect
To actively disconnect from the cluster, you run this command:
```sh
gefyra connections stop
```
This assumes you have a *default* connection currently running. If not, you have to provide a valid connection name with the `[connection-name]` argument.
You will find this connection to be stopped from the client's side. However, if you want to reconnect to the cluster, you can now run `gefyra connections connect` again. The connection process will be superfast this time.
::note
If you want to delete a connection, and thus release the Gefyra client in the cluster, you can run
`gefyra connections remove`
. If you want to reconnect later, you will need a
*client file*
again.
::
### Connection Names
You can assign (and have to) names to your connections if you have more than one. Almost all commands of the Gefyra CLI support the `--connection-name` option to specify the connection a certain command is targeting. Most importantly, for `gefyra run --connection-name` you specify to which cluster a local container is connected.
To create a new connection with a name (in this example `my-conn1`), please run the following to set up a connection with a given name:
```sh
gefyra connections connect --connection-name my-conn1 ...
```
The connection will show up in the connection list:
```sh
> gefyra connections list
NAME VERSION CREATED STATUS
default 2.0.0 2023-10-10T18:36:15.519969679Z running
my-conn1 2.0.1 2023-10-12T12:14:11.48715/726Z running
```
You can manage connections based on the local names, i.e. halt the connection, reconnect, remove it, and run containers with it.
## Simultaneous Connections
As you can see above, it is possible to create a list of connections simultaneously. They can be individually managed, like started and stopped, even at the same time.
It is possible to have multiple connections to one cluster, too.
# Setting up Shared Kubernetes Clusters
Hey! We would be very happy to know about your Kubernetes development setup. If you can't find your distribuition in this list, please request a guide by creating [a GitHub issue using this template](https://github.com/gefyrahq/gefyra/issues/new?assignees=&labels=enhancement&template=guide-request.md&title=%5BGuide+request%5D%3A+){rel=""nofollow""}.
It's that simple and very helpful.
Select your preferred Kubernetes provider from below to start working with Gefyra.
::card-group
:::card
---
icon: i-material-icon-theme:gcp
title: Google Cloud Platform (GCP)
to: https://gefyra.dev/en/remote-k8s/gcp
---
This guide will show you how to use Gefyra for the remote development of a Kubernetes Application running in the Google Kubernetes Engine (GKE).
:::
:::card
---
icon: i-simple-icons-amazoneks
title: Elastic Kubernetes Service (EKS)
to: https://gefyra.dev/en/remote-k8s/eks
---
This guide will show you how to use Gefyra for the remote development of a Kubernetes
:::
:::card
---
icon: i-simple-icons-kubernetes
title: SysEleven MetaKube
to: https://gefyra.dev/en/remote-k8s/sys11
---
This guide will show you how to use Gefyra for the remote development of a Kubernetes Application running on MetaKube.
:::
::
# Getting started with Gefyra and the Google Cloud Platform
## Prerequisites
1. You have the [gcloud](https://cloud.google.com/sdk/docs/install-sdk){rel=""nofollow""} command installed
2. Follow the [installation](https://gefyra.dev/en/quick-start/installation) of Gefyra for your preferred platform
Additionally you need an account for the Google Cloud Platform including the permission to create a new cluster. Make sure your gcloud is using the right project configuration. Googles documentation is available [here](https://cloud.google.com/sdk/docs/install-sdk){rel=""nofollow""}.
## Setup a cluster
1. The easiest way to create a new cluster is using gcloud:
```sh
gcloud container clusters create spacecraft
```
This may take a few minutes, there will be 3 VM instances running a kubernetes cluster ready to serve your applications. gcloud will set your kubectl context to the created cluster, nothing to worry about!
2. The last thing we need to do is open a port in the firewall. This allows gefyra to connect to the cluster using wireguard:
```sh
gcloud compute firewall-rules create gefyra --allow udp:31820
```
3. Apply some workload, for example from the testing directory of this repo:
```sh
kubectl apply -f https://raw.githubusercontent.com/gefyrahq/gefyra/main/testing/workloads/hello_dd.yaml
```
## Running Gefyra
1. At first, we need a host IP of one of our compute instances. You can get
them with running `gcloud compute instances list`. Pick one of them.
2. Now you can run `gefyra up --host `
3. Run a local Docker image with Gefyra in order to make it part of the cluster.
1. Build your Docker image with a local tag, for example from the testing directory:
```sh
cd testing/images/ && docker build -f Dockerfile.local . -t pyserver
```
2. Execute Gefyra's run command:
```sh
gefyra run -i pyserver -N mypyserver -n default
```
3. *Exec* into the running container and look around. You will find the container to run within your Kubernetes cluster.
```sh
docker exec -it mypyserver bash
```
4. Print out the website of the cluster service *hello-nginx* from within the cluster.
```sh
wget -O- hello-nginx
```
4. Create a bridge in order to intercept the traffic to the cluster application with the one running locally:
```sh
gefyra bridge -N mypyserver -n default --port 80:8000 --target deploy/hello-nginxdemo/hello-nginx
```
5. List all running *bridges*:
```sh
gefyra list --bridges
```
6. *Unbridge* the local container and reset the cluster to its original state:
```sh
gefyra unbridge -N mypybridge
```
## Cleaning up
Remove Gefyra's components from the cluster with `gefyra down`
::card
Did everything work as expected? How was the experience of using Gefyra? We'd appreciate if you could take 2 minutes of your time to fill out our
[feedback form](https://forms.gle/AWT9NparpTVk8E978){rel=""nofollow""}
.
#title
Please provide us with your feedback
::
# Getting started with Gefyra and Elastic Kubernetes Service (EKS)
## Prerequisites
1. You have the [aws](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html){rel=""nofollow""} command installed and configured
2. Follow the [installation](https://gefyra.dev/en/quick-start/installation) of Gefyra for your preferred platform
Additionally, you need an account for the Amazon Web Services including the permission to create a new cluster. Make sure your `aws` is using the right project configuration and/or profile.
## Setup a cluster
1. The easiest way to create a new cluster is using `aws`:
```sh
aws eks create-cluster --name gefyra --kubernetes-version 1.22 --role-arn arn:aws:iam::111122223333:role/myAmazonEKSClusterRole --resources-vpc-config subnetIds=subnet-ExampleID1,subnet-ExampleID2,securityGroupIds=sg-ExampleID1
```
This may take a long time. You can check the cluster status with:
```sh
> aws eks describe-cluster --name gefyra --query "cluster.status"
"ACTIVE"
```
2. Depending on your way of creating the cluster, you may have to add a `NodeGroup` to the cluster, so you can actually run workloads.
3. Pull the `kubectl` configuration to connect to the cluster, with:
```sh
aws eks update-kubeconfig --name gefyra
```
Now you should be able to run any `kubectl` command in that cluster.
4. Apply some workload, for example from the testing directory of this repo:
```sh
kubectl apply -f https://raw.githubusercontent.com/gefyrahq/gefyra/main/testing/workloads/hello_dd.yaml
```
5. **Important:** before Gefyra can connect from outside the cluster, you must set the security group of the nodes to allow UDP traffic on port 31820.
Find out the security group of the cluster. Then, create the required inbound traffic rule:
```sh
> aws eks describe-cluster --name gefyra --query "cluster.resourcesVpcConfig.clusterSecurityGroupId"
```
```sh
aws ec2 authorize-security-group-ingress --group-id "" --protocol udp --port 31820 --cidr 0.0.0.0/0
```
## Running Gefyra
1. At first, we need a host IP of one of our nodes. You can get
them by running
```sh
kubectl get nodes -o wide | awk {'print $1" " $2 " " $7'} | column -t
```
Pick one of them from the `EXTERNAL-IP` column.
2. Now you can run
```sh
gefyra up --host
```
3. Run a local Docker image with Gefyra to make it part of the cluster.
1. Build your Docker image with a local tag, for example from the testing directory:
```sh
cd testing/images/ && docker build -f Dockerfile.local . -t pyserver
```
2. Execute Gefyra's run command:
```sh
gefyra run -i pyserver -N mypyserver -n default
```
3. *Exec* into the running container and look around. You will find the container to run within your Kubernetes cluster.
```sh
docker exec -it mypyserver bash
```
4. Print out the website of the cluster service *hello-nginx* from within the cluster.
```sh
wget -O- hello-nginx
```
4. Create a bridge to intercept the traffic to the cluster application with the one running locally:
```sh
gefyra bridge -N mypyserver -n default --port 80:8000 --target deploy/hello-nginxdemo/hello-nginx
```
5. List all running *bridges*:
```sh
gefyra list --bridges
```
6. *Unbridge* the local container and reset the cluster to its original state:
```sh
gefyra unbridge -N mypybridge
```
## Cleaning up
Remove Gefyra's components from the cluster with `gefyra down`
::card
Did everything work as expected? How was the experience of using Gefyra? We'd appreciate if you could take 2 minutes of your time to fill out our
[feedback form](https://forms.gle/AWT9NparpTVk8E978){rel=""nofollow""}
.
#title
Please provide us with your feedback
::
# Getting started with Gefyra and SysEleven MetaKube
## Prerequisites
1. You have a [MetaKube](https://metakube.syseleven.de/){rel=""nofollow""} account and privileges to create a new cluster
2. Follow the [installation](https://gefyra.dev/en/quick-start/installation) of Gefyra for your preferred platform
## Setup a cluster
You may follow [this guide to create a cluster using the MetaKube management console](https://docs.syseleven.de/metakube/en/tutorials/create-a-cluster){rel=""nofollow""}.
This guide assumes you are running an **OpenStack**-based Kubernetes cluster on SysEleven.
{.w-full}
**Important:** Before Gefyra can connect from outside the cluster, you must set the security group of the nodes to allow UDP traffic on port 31820.
{.w-full}
Please set the direction to *Ingress* and the protocol to *UDP*. The port range should be set to *31820* and the source
CIDR to *0.0.0.0/0*. That way, Gefyra can connect to any data plane node of the cluster using a [Floating-IP](https://docs.syseleven.de/syseleven-stack/en/reference/network){rel=""nofollow""}.
After all of the MetaKube components are ready, you can download the *kubeconfig* to access the cluster using `kubectl`. Just click on the "Download Config" button in the MetaKube management console and save the file to your local machine.
## Running Gefyra
1. You may apply some workload, for example from Gefyra's testing directory:
```sh
kubectl apply -f https://raw.githubusercontent.com/gefyrahq/gefyra/main/testing/workloads/hello_dd.yaml
```
2. At first, we need a host IP of one of our nodes. You can get it by running:
```sh
kubectl get nodes -o wide | awk {'print $1" " $2 " " $7'} | column -t
```
Pick one of them from the `EXTERNAL-IP` column.
3. Now you can run
```sh
gefyra up --host
```
using the IP you just picked. This will create the Gefyra components in your cluster and local host.
4. Run a local Docker image with Gefyra to make it part of the cluster.
1. Build your Docker image with a local tag, for example from Gefyra's testing directory (in the repo):
```sh
cd testing/images/ && docker build -f Dockerfile.local . -t pyserver
```
2. Execute Gefyra's run command:
```sh
gefyra run -i pyserver -N mypyserver -n default
```
3. *Exec* into the running container and look around. You will find the container to run within your Kubernetes cluster.
```sh
docker exec -it mypyserver bash
```
4. Print out the website of the cluster service *hello-nginx* from within the cluster.
```sh
wget -O- hello-nginx
```
5. Create a bridge to redirect the traffic from the cluster application to the one running locally:
```sh
gefyra bridge -N mypyserver -n default --ports 80:8000 --target deploy/hello-nginxdemo/hello-nginx
```
6. List all running *bridges*:
```sh
gefyra list --bridges
```
7. *Unbridge* the local container and reset the cluster to its original state:
```sh
gefyra unbridge --all
```
## Cleaning up
Remove Gefyra's components from the cluster with `gefyra down`
::card
Did everything work as expected? How was the experience of using Gefyra? We'd appreciate if you could take 2 minutes of your time to fill out our
[feedback form](https://forms.gle/AWT9NparpTVk8E978){rel=""nofollow""}
.
#title
Please provide us with your feedback
::
# Use Cases and Demos
::card-group
:::card
---
icon: i-simple-icons-go
title: Developing Go Applications with Gefyra
to: https://gefyra.dev/en/usecases-and-demos/golang
---
This guide will show you how to use Gefyra for the remote development of a Go application.
:::
:::card
---
icon: i-devicon-plain:oauth
title: OAuth2 Demo with a Sidecar
to: https://gefyra.dev/en/usecases-and-demos/oauth2-demo
---
This guide will show you how to use Gefyra for the remote development of a OAuth2 demo with a sidecar.
:::
:::card
---
icon: i-material-icon-theme:gcp
title: Remote Development on Google Kubernetes Engine (GKE)
to: https://gefyra.dev/en/usecases-and-demos/remote-gke
---
This guide will show you how to use Gefyra for the remote development of a Kubernetes Application running on MetaKube.
:::
:::card
---
icon: i-simple-icons-ubuntu
title: Run an Ubuntu Container in a Namespace
to: https://gefyra.dev/en/usecases-and-demos/ubuntu-in-namespace
---
This example demonstrates how to run a local Ubuntu container instance as part of your Kubernetes namespace.
:::
::
# Developing Go Applications with Gefyra
::tip
Simple Usecase
::
## What you will learn
- Running a Go application in a local container with hot code reloading
- Using Gefyra to bridge the container into a Kubernetes cluster
## What you will need
- [Gefyra](https://gefyra.dev/en/quick-start/installation)
- [Getdeck](https://github.com/Getdeck/getdeck){rel=""nofollow""} for setting up the development infrastructure (runs on `k3d`)
- A copy of {rel=""nofollow""}
- Optionally: [k3d](https://k3d.io){rel=""nofollow""} or any other preferred Kubernetes cluster
## Creating the Development Infrastructure
After cloning the gefyra-demos repository, you can start a local k3d based Kubernetes cluster with the Go demo workload by running
```sh
cd golang-demo
deck get deck.yaml
```
Once everything is up and running, you can visit {rel=""nofollow""} to verify that everything worked as expected.
## The Demo Application
You can look at and tweak the code for the demo application in `app/main.go`. You will find a very simple HTTP API that returns a String when it receives GET requests at the base route.
In the `app`-directory, you'll also find the Dockerfile that is used to build the container image containing our application.
**Note**: In the Dockerfile, we install [air](https://github.com/cosmtrek/air){rel=""nofollow""}, a hot reloading utillity for Go development. In a production Dockerfile, you'd want to specify a dedicated
build target to install air.
## Enter Gefyra
In order to connect a locally running container to a Kubernetes cluster, we use Gefyra.
First of all, we need to build an image on our development machine like so:
```sh
cd app
docker build . -t gefyra-golang-example
```
Once the build is finished, we are ready to get started with Gefyra:
```sh
gefyra up
gefyra run -i gefyra-golang-example -N gefyra-golang-example -n golang-demo -c air -v $(pwd):/app
gefyra bridge -N gefyra-golang-example --container-name gefyra-golang-demo --deployment gefyra-golang-demo --port 3333:3333 -n golang-example
```
`gefyra up` will start the cluster and client side components needed for Gefyra to do it's thing.
The `gefyra run` command will then start a container from the image that we just build in the development infrastructure that we created before.
Finally, 'gefyra bridge' will overlay our local container over the one that we specified in the run command.
Once Gefyra tells you that the bridge is established, you're ready to make some changes and check out hot code reloading in Kubernetes in action.
Visit {rel=""nofollow""} in your browser and try changing the contents of the
`io.WriteString` function. Since we mounted our code into the container during `gefyra run`, air will detect the changes and rebuild/restart our application.
Refresh your browser and check out the results!
# Create a Backend Application with a Sidecar and OAuth2 Authentication
::warning
Advanced Usecase
::
This is more of an advanced use-case, if you just want an easy example of how Gefyra works, check out the [getting started guide](https://gefyra.dev/en/local-environments/getting-started).
## What you will learn
- Create a (Python-based) backend application that reads a JWT (JSON web token)
- Get a local identity provider with [Keycloak](https://www.keycloak.org/){rel=""nofollow""}
- Apply the Kubernetes sidecar pattern with [OAuth2-Proxy](https://oauth2-proxy.github.io/oauth2-proxy/){rel=""nofollow""} and connect the app to Keycloak
- Find and fix a bug
- Start coding locally within the Kubernetes cluster having the sidecar active
## What you will need
- [Gefyra](https://gefyra.dev/en/quick-start/installation)
- [Getdeck](https://github.com/Getdeck/getdeck){rel=""nofollow""} for setting up the development infrastructure (runs on `k3d`)
- `kubectl`
- A copy of {rel=""nofollow""}
- Optionally: [k3d](https://k3d.io){rel=""nofollow""} or any other preferred Kubernetes cluster
- Optionally: VSCode with Python debugger installed (or any other preferred IDE)
That's about it. Let's get started.
## Creating the Development Infrastructure
First, we need a Kubernetes-based development infrastructure which contains all required components. Luckily this can
be achieved quite easily with the [`Deck CLI` from here](https://github.com/Getdeck/getdeck){rel=""nofollow""}.
Just run:
```sh
deck get --name oauth2-demo https://github.com/gefyrahq/gefyra-demos.git
```
and you will get a fresh `k3d` cluster running locally with all required components installed.
**Important:** These workloads are intended for demonstration purposes and are not safe for production deployments.
**Optional:** If you don't want to create the development infrastructure using `Getdeck` you can also provide it
yourself. You need:
- a Kubernetes cluster
- an identity provider (preferably Keycloak)
- a custom realm with an oauth2 client for the backend service
- a test user with required privileges
- ingress config that supports a full-fledged oauth2 login flow
- the workload manifests for the backend application with the OAuth2-Proxy sidecar
## Getting the App Running
**Optional:** In order to observe the workload booting up, check out
[the Kubernetes dashboard](http://dashboard.127.0.0.1.nip.io:8080/#/workloads?namespace=oauth2-demo){rel=""nofollow""} coming with this `deck`.
A healthy cluster looks like this:
{.w-full}
Once you have the workload running in Kubernetes, head over to
{rel=""nofollow""}.
The following page should come up asking you to sign in with *OpenID Connect*:
{.mx-auto}
Once you click the button you will be redirected to the central login of Keycloak, which looks like this:
{.mx-auto}
Please notice how you got redirected to the local domain of Keycloak [http://keycloak.127.0.0.1.nip.io:8080/...](http://keycloak.127.0.0.1.nip.io:8080/){rel=""nofollow""}.
The demo workload contains a prepared user in Keycloak's database. You can use it to perform a login. The credentials are as
follows:
**Username**: ****Password**: **
Once you hit the *Sign In* button you will be redirected back to the beginning, but this time you will see the json output of
the backend service:
```json
{"Hello":"World"}
```
Voilà , we have a full-fledged [OpenID Connect](https://openid.net/connect/){rel=""nofollow""} login flow running in a Kubernetes cluster.
So are we done yet? Not quite. Let's move on to the internals.
## The Scheme of the Infrastructure
### Kubernetes Overview
The Kubernetes cluster is running three important components for this use case:
- Keycloak: the identity provider compatible with OpenID Connect (OIDC)
- OAuth2-Proxy: a reverse proxy compatible with OpenID Connect
- Backend Application: a [FastAPI](https://fastapi.tiangolo.com/){rel=""nofollow""} application
The OAuth2-Proxy is implemented as a sidecar and runs side-by-side in each [*Pod*](https://kubernetes.io/docs/concepts/workloads/pods/){rel=""nofollow""} with the backend application. If you are
not yet familiar with the sidecar pattern [please check out this resource](https://www.oreilly.com/library/view/designing-distributed-systems/9781491983638/ch02.html){rel=""nofollow""}.
Keycloak runs in a *StatefulSet* and is connected to a *PostgreSQL* database.
The Kubernetes objects of the workload are as follows:
{.w-full}
In this picture you can find two [*Ingresses*](https://kubernetes.io/docs/concepts/services-networking/ingress/){rel=""nofollow""}
definitions: one is serving the application [*Deployment*](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/){rel=""nofollow""} *oauth2-demo*
which schedules one *Pod* under [oauth2-demo.127.0.0.1.nip.io:8080](http://oauth2-demo.127.0.0.1.nip.io:8080){rel=""nofollow""}, the other is
serving Keycloak under [keycloak.127.0.0.1.nip.io:8080](http://keycloak.127.0.0.1.nip.io:8080){rel=""nofollow""}.
**Important:** Please mind that port *8080* is a port mapping. From within the cluster you will see it running on port *80*.
You can introspect the Ingress also with `kubectl`:
```sh
> kubectl --namespace oauth2-demo get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
keycloak keycloak.127.0.0.1.nip.io 172.23.0.2 80, 443 56m
keycloak-console keycloak.127.0.0.1.nip.io 172.23.0.2 80, 443 56m
oauth2-demo oauth2-demo.127.0.0.1.nip.io 172.23.0.2 80 56m
dashboard-kubernetes-dashboard dashboard.127.0.0.1.nip.io 172.23.0.2 80 56m
```
The next layer adds the Kubernetes [*Service*](https://kubernetes.io/docs/concepts/services-networking/service/){rel=""nofollow""} objects which are
required to access a Pod.
You can introspect the Services also with `kubectl`:
```sh
> kubectl --namespace oauth2-demo get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
keycloak-http ClusterIP 10.43.40.200 80/TCP,8443/TCP,9990/TCP 62m
keycloak-headless ClusterIP None 80/TCP 62m
keycloak-postgresql ClusterIP 10.43.231.210 5432/TCP 62m
keycloak-postgresql-headless ClusterIP None 5432/TCP 62m
oauth2-demo ClusterIP 10.43.160.68 8080/TCP 62m
dashboard-kubernetes-dashboard ClusterIP 10.43.159.219 61348/TCP 62m
```
Please ignore the other services as they are not important for this example.
Finally, please also check out the Pods in the cluster's namespace with `kubectl`. It should be similar to:
```sh
> kubectl --namespace oauth2-demo get pod
NAME READY STATUS RESTARTS AGE
oauth2-demo-675f5c55b5-xxj57 2/2 Running 0 63m
dashboard-kubernetes-dashboard-65dbdd8978-gd9jt 1/1 Running 0 63m
keycloak-postgresql-0 1/1 Running 0 63m
keycloak-0 1/1 Running 0 63m
```
### The OAuth2-Demo Sidecar Workload
If you want to know more about the implementation of the sidecar pattern in this example please head over to the
[workload manifest](https://github.com/gefyrahq/gefyra-demos/blob/main/oauth2-demo/oauth2-demo.yaml#L37){rel=""nofollow""}.
The important part is that the Pod template specifies two containers. The first is *name: oauth2-proxy* and the second is
*name: oauth2-demo-app*:
```yaml
[...]
containers:
- name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.2.1
imagePullPolicy: IfNotPresent
[...]
ports:
- containerPort: 8809
protocol: TCP
name: http
envFrom:
- configMapRef:
name: oauth2-oauth2proxy
- name: oauth2-demo-app
[...]
image: "quay.io/gefyra/oauth2-demo:latest"
imagePullPolicy: Always
ports:
- name: http-intern
containerPort: 8155
protocol: TCP
[...]
```
Please have a closer look at the port configuration. The oauth2-proxy runs on port *8809* (with name *http*) and oauth2-demo-app
runs on port *8155*. You can describe the associated service with `kubectl` to see which of both ports the traffic is pointed to:
```sh
> kubectl -n oauth2-demo describe service oauth2-demo
Name: oauth2-demo
Namespace: oauth2-demo
Labels: app.kubernetes.io/instance=gefyra-demos
app.kubernetes.io/name=oauth2-demo
Annotations:
Selector: app.kubernetes.io/instance=gefyra-demos,app.kubernetes.io/name=oauth2-demo
Type: ClusterIP
IP Families:
IP: 10.43.160.68
IPs: 10.43.160.68
Port: http 8080/TCP
TargetPort: http/TCP
Endpoints: 10.42.1.4:8809
Session Affinity: None
Events:
```
For the sidecar pattern to function, the service speaks to the target Pod on port *8809* which is served by the oauth2-proxy.
A closer review of oauth2-proxy's configuration reveals to which address the proxy upstreams all requests:
```yaml
[...]
OAUTH2_PROXY_UPSTREAMS: "http://127.0.0.1:8155"
[...]
```
This is precisely the connection to the backend application **in each Pod**.
### The OpenID Connect Flow in Brief
The following image depicts the OpenID Connect flow in brief how it is working in this example:
{.w-full}
As you can see, the OAuth2-Proxy only passes authenticated traffic to the backend application. That breaks
the application free from (potentially unsafe) custom OIDC code and authorization handling. **This is standard procedure
and should not be part of your code**. Make use of this pattern when having this requirement.
Ok! Enough for the workload internals. Let's check out how Gefyra helps out with fixing nasty bugs.
## The Example Bug
If you hit the troublesome route {rel=""nofollow""}
(with *123* as an example for any int value) you will face the `Internal Server Error` message. That is a *HTTP 500* status.
The code being executed can be found
here: {rel=""nofollow""}
```py
@app.get("/items/{item_id}")
async def get_item(item_id: int, x_forwarded_access_token: Optional[str] = Header(None)):
if x_forwarded_access_token:
data = jwt.decode(x_forwarded_access_token, options={"verify_signature": False})
mail = data["Email"]
return {"item_id": item_id, "Email": mail}
else:
return {"item_id": item_id, "Email": "not given"}
```
Of course, you are a very attentive reader and found the mistake immediately, but let's move on for the sake of this example.
## Gefyra to the Rescue
As always, the first would be to spin up Gefyra with
`gefyra up`. Please be sure to still have the development cluster active in your current `kubectl` context.
### Running a Development Instance of the Container
In order to inspect the application and pinpoint the bug, it requires a local instance of the container. Ideally with a
debug server running. Since you need the sidecar in place (for the OIDC logic), the development instance must be placed
in a Pod with the sidecar pattern. Gefyra offers you a unique mechanism to achieve exactly that.
Start the development instance like so (set `LOCAL_DIR` to the directory where you've copied/cloned `gefyra-demos` to):
```sh
export LOCAL_DIR=/home/<...>/gefyra-demos/oauth2-demo/app
gefyra run -i quay.io/gefyra/oauth2-demo -N myfastapi-demo \
-n oauth2-demo -v $LOCAL_DIR:/app \
-c "bash -c 'python -m debugpy --wait-for-client --listen 0.0.0.0:5678 -m uvicorn main:app --host 0.0.0.0 --port 8155 --reload'"
```
No worries, the following explains the parameter list:
- *-i quay.io/gefyra/oauth2-demo*: run the Docker image which is also running in the cluster
- *-N myfastapi-demo*: name this local Docker instance *myfastapi-demo* for further reference
- *-n oauth2-demo*: place this Docker instance in the Kubernetes namespace *oauth2-demo* (where this example plays)
- *-v /home/<...>/gefyra-demos/oauth2-demo/app\:/app*: mount the source code on your disk to this Docker instance at */app*
- *-c "CMD"*: start this Docker instance with [*debugpy*](https://github.com/microsoft/debugpy){rel=""nofollow""}, the rest is like from the Kubernetes workload manifest of the application
[debugpy](https://github.com/microsoft/debugpy){rel=""nofollow""} is an implementation of the *Debug Adapter Protocol* for Python. This protocol
is also available for a countless number of programming languages. It basically spins up a server, in this case waiting for
a debugger client to connect, and runs the application wrapped in with debugging capabilities.
### Attaching a Debugger to the Development Instance
Now that you are running a development instance with this Docker image locally, you need to connect the debugger client.
This example is prepared with *VSCode* and the Python extension installed.
In order to do that, you need to find out the local IP address Gefyra assigned to your container with:
```sh
docker inspect -f '{{range.NetworkSettings.Networks}}{{.IPAddress}}{{end}}' myfastapi-demo
```
This will be part of the CLI soon (or maybe it already is). The command shown tells the IP of the container which is
needed for VSCode.
Please get the code for the backend application from [the repository](https://github.com/gefyrahq/gefyra-demos/tree/main/oauth2-demo/app){rel=""nofollow""} and
open up VSCode.
Select the *Remote Attach* option to connect to the running debugpy instance at the given IP. The port is *5678* (please review the command above).
{.w-full}
In the *DEBUG CONSOLE* it will display the following output:
```text
INFO: Will watch for changes in these directories: ['/app']
INFO: Uvicorn running on http://0.0.0.0:8155 (Press CTRL+C to quit)
INFO: Started reloader process [438166] using watchgod
```
Awesome. You have a debugger connected to the development instance. Now it's time to receive a request from the oauth2-proxy container.
### Bridging the Development Instance in the Cluster
In order to receive requests (i.e. traffic) from within the cluster, basically when you hit the route {rel=""nofollow""}
in your browser, a `gefyra bridge ...` is needed.
Just create a bridge with:
```sh
> gefyra bridge -N myfastapi-demo -n oauth2-demo \
--target deploy/oauth2-demo/oauth2-demo-app \
--port 8155:8155
[INFO] Creating bridge for Pod oauth2-demo-675f5c55b5-xxj57
[INFO] Waiting for the bridge(s) to become active
[INFO] Bridge myfastapi established
```
The parameter list specifies the following:
- *-N myfastapi-demo*: the bridge targets (on one end) the local Docker instance with the name *myfastapi-demo*
- *-n oauth2-demo*: the target workload (the other end of the bridge) is in the Kubernetes namespace *oauth2-demo*
- *--deployment oauth2-demo*: Gefyra intercepts all Pods of the Deployment *oauth2-demo* (don't confuse it with the name of the namespace)
- *--port 8155:8155*: the bridge to map port 8155 of the container in the cluster to 8155 on the local instance
- *--container-name oauth2-demo-app*: since this Pod contains multiple containers (see the sidecar pattern above), Gefyra is asked to intercept the application container *oauth2-demo-app*
### Debugging the Application
Now you are ready to stop the execution of the code in your VSCode debugger.
Place the breakpoint anywhere near the position you would expect the error to happen:
{.w-full}
Point your browser to {rel=""nofollow""} again.
Once you hit the breakpoint, you can easily look around and introspect the JWT (json web token) issued from Keycloak and
verified with OAuth2-Proxy.
{.w-full}
As you may see, the key in the token is written in a lowercase "email". This is causing the *KeyError: 'Email'* resulting
in a 500 error.
**Remark:** Of course you could have found this out reading the logs, but where is the fun? Anyway, debugging software is
a tool for hunting down causes of way more complex misbehaving then in this example.
### Fixing the Bug
Since the development instance is started with your local source code mounted into the container and the *--reload* flag turned on,
please move on and fix this bug. The fix looks like this:
```py
[...]
data = jwt.decode(x_forwarded_access_token, options={"verify_signature": False})
mail = data["email"] # the key is with a lowercase 'email'
return {"item_id": item_id, "Email": mail}
[...]
```
Once you have saved the changes, the application is immediately restarted with the fixed code.
The output of the route {rel=""nofollow""} is
now in the browser:
```json
{"item_id":123,"Email":"john@gefyra.dev"}
```
Awesome! Commit and push.
This way you can be quite sure that this will work in all Kubernetes environments provisioned with these workloads.
**Remark:** Gefyra is able to run and bridge as many applications as you need. This is useful in complex request/response
scenarios with multiple involved services - and potentially all with a debugger attached. Isn't that neat?
### Shutting Down Gefyra
In order to clean everything up, you can run `gefyra down`. This will remove the running bridges and shut down the development
container instances. You will now find the cluster reset to the state with the original bug around. For the fix to become persistent
you will need to roll out a new version of the container image specified in the Kubernetes workload manifest.
## Remove the Development Infrastructure
If you have initially created the development infrastructure using `Getdeck` you can now run:
```sh
> deck remove --cluster https://github.com/gefyrahq/gefyra-demos.git
[INFO] Deleting the k3d cluster with name gefyra-demos
```
If you created the infrastructure yourself, you probably already know how to get rid of everything yourself ;-)
## Additional Notes
If you are developing django applications, be sure to check out [Django-Hurricane](https://django-hurricane.io/){rel=""nofollow""}, a Kubernetes-native
stack specifically created for django and [Pycloak](https://github.com/Blueshoe/pycloak){rel=""nofollow""}, a package that's makes it super easy to integrate
OpenID Connect/OAuth2 workflows in django.
# Developing a backend application with Django on the Google Kubernetes Engine (GKE)
::note
Intermediate Usecase
::
This is more of an advanced use-case, if you just want an easy example of how Gefyra works, check out the [getting started guide](https://gefyra.dev/en/local-environments/getting-started).
## What you will learn
- How to set up a Kubernetes cluster with the Google Kubernetes Engine
- Deploy a Django-based demo application
- Set out with Gefyra to run a local container instance as part of the remote cluster
To follow this guide, you need to have the following tools installed:
- [gcloud](https://cloud.google.com/sdk/docs/install-sdk){rel=""nofollow""}
- [kubectl](https://kubernetes.io/docs/tasks/tools/){rel=""nofollow""}
- [Helm](https://helm.sh/docs/intro/install/){rel=""nofollow""}
- [Gefyra](https://gefyra.dev/en/quick-start/installation)
Additionally you need an account for the Google Cloud Platform including the permission to create a new cluster. Make sure your gcloud is using the right project configuration. Googles documentation is available [here](https://cloud.google.com/docs/get-started){rel=""nofollow""}.
## Setup a cluster
In this guide we will spin up a small demo application called spacecrafts,
featuring Django Hurricane. If you already have a cluster running, you are free
to use this as well.
The easiest way to create a new cluster is using `gcloud`:
`gcloud container clusters create spacecraft`.
This may take a few minutes, there will be 3 VM instances running a kubernetes
cluster ready to serve your applications. `gcloud` will set your
kubectl context to the created cluster, nothing to worry about!
The last thing we need to do is open a port in the firewall. This allows gefyra
to connect to the cluster using wireguard:
`gcloud compute firewall-rules create gefyra --allow udp:31820`
## Running the Spacecrafts Demo
To have some actual application to develop against, we want to deploy our
spacecrafts demo to our cluster. Clone the repository and deploy it using helm:
```sh
git clone https://github.com/django-hurricane/spacecrafts-demo.git
cd spacecrafts-demo/helm
helm install spacecrafts spacecrafts/
```
Check if everything is up and running with `kubectl get pods`.
Now we need to deploy a load balancer so Google exposes our service on a public
IP. Use the following service definition with `kubectl apply -f service.yaml`:
```yaml [service.yaml]
apiVersion: v1
kind: Service
metadata:
name: hello
spec:
type: LoadBalancer
selector:
app.kubernetes.io/name: spacecrafts
strategy:
ports:
- port: 80
targetPort: 8080
---
```
It takes some time to actually get an IP. You can check the state running
`kubectl get service`. There will be a service named `hello` of the type
`LoadBalancer`. As soon as an IP is available, feel free to visit it in your
browser. If you can see a 404 error from Django, everything is alright!
## Setting up Gefyra
Now we can run `gefyra up`. This way gefyra sets up all requirements
to enjoy local development supported by services in the cluster.
At first, we need a host IP of one of our compute instances. You can get
them with running `gcloud compute instances list`. Pick one of them.
Now you can run `gefyra up --host `.
Gefyra now sets up a wireguard connection into the cluster and prepares
everything to allow us to run local containers linked to the cluster.
## Local development backed by the cluster
Lets say we want to debug and fix the 404 on the index page. It's possible to do
this in the remote cluster, but Gefyra enables us to do this on your machine!
The following command will spin your local development container for spacecrafts
up. Please note you need to adjust the name of the container, run `kubectl get pods` to get the right identifier.
```sh
export podname=$(kubectl get pods --no-headers -o custom-columns=":metadata.name" | grep -v postgres)
gefyra run --env-from $podname/spacecrafts \
-i quay.io/django-hurricane/spacecrafts-demo \
-N myspacecraft \
-v src/:/app \
-c "python manage.py serve
--autoreload
--static
--command 'collectstatic
--noinput'
--command 'migrate'"
```
Some explanation: We pass the image for the container with `-i`, name the container with `-N`, mount our
source directory inside the container for hot-reloading using `-v` and specify the command to be executed
on startup.
Thats it. To get the IP of the container, run
```sh
gefyra list --containers
```
Now you can open your browser at `:8000` and get the same `404-Error`. You can watch the logs using
```sh
docker logs -f myspacecraft
```
The reason why we get a 404 not found is simply a missing route. We should add one:
```diff [src/configuration/urls.py]
urlpatterns = [
# django-admin:
+ path("", csrf_exempt(GraphQLView.as_view(graphiql=True))),
path("admin/doc/", include(admindocs_urls)), # noqa: DJ05
path("admin/", admin.site.urls),
path("graphql/", csrf_exempt(GraphQLView.as_view(graphiql=True))),
```
If you now reload your browser tab, you should see a graphql input field!
# Making any container part of your Kubernetes namespace
::tip
Simple Usecase
::
## What you will learn
- Run a Ubuntu container as part of a Kubernetes namespace
- Install additional software to that instance
- Use this container to call Kubernetes services
## What you will need
- [Gefyra](https://gefyra.dev/en/quick-start/installation)
- [Getdeck](https://github.com/Getdeck/getdeck){rel=""nofollow""} for setting up the development infrastructure (runs on `k3d`)
- [kubectl](https://kubernetes.io/docs/tasks/tools/){rel=""nofollow""}
- Optionally: [k3d](https://k3d.io){rel=""nofollow""} or any other preferred Kubernetes cluster
## Creating the local development infrastructure
First, we need a Kubernetes-based development infrastructure which contains all required components. Luckily this can
be achieved quite easily with the [`Deck CLI` from here](https://github.com/Getdeck/getdeck){rel=""nofollow""}.
Just run:
```sh
deck get https://github.com/Blueshoe/buzzword-charts.git
```
and you will get a fresh `k3d` cluster running locally with all required components installed.
**Important:** These workloads are intended for demonstration purposes and are not safe for production deployments.
**Optional:** If you don't want to create the development infrastructure using `Getdeck` you can also provide it
yourself. You need:
- a Kubernetes cluster
- some workload, you can choose the example
from [here](https://github.com/Blueshoe/buzzword-charts/tree/main/buzzword-counter){rel=""nofollow""} and `helm install` it yourself
- a node port at 31820:31820/UDP (if running it locally)
## Getting the App Running
**Optional:** In order to observe the workload booting up, check out
[the Kubernetes dashboard](http://dashboard.127.0.0.1.nip.io:8080/#/workloads?namespace=buzzword){rel=""nofollow""} coming with this `deck`.
## Connecting Gefyra to the Kubernetes cluster
The first would be to spin up Gefyra with `gefyra up`. Please be sure to still have the development cluster
active in your current `kubectl` context.
**Important:** If you are running a remote Kubernetes cluster you need to specify the `--host` argument with *IP*
of one of your data plane nodes. The default port is *31820* (`--port`), it may be different depending on firewalls and the cluster
networking.
## Running a container in a Kubernetes namespace
In this example, a Ubuntu will become part of the cluster namespace *buzzword*.
Start the container instance like so :
```sh
> gefyra run -i ubuntu -N myubuntu -n buzzword -c "bash -c 'tail -f /dev/null'"
[INFO] Container image 'ubuntu:latest' started with name 'myubuntu' in Kubernetes namespace 'buzzword'
```
No worries, the following explains the parameter list:
- *-i ubuntu*: run the public Docker image ob Ubuntu from here: {rel=""nofollow""}
- *-N myubuntu*: name this local Docker instance *myubuntu* for further reference
- *-n buzzword*: place this Docker instance in the Kubernetes namespace *buzzword* (where this example plays)
- *-c "bash -c 'tail -f /dev/null'"*: start this Docker instance and keep it running forever
You can check the output of `docker ps` to see your container instance running. It should look something like this:
```text
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
660ce52ce4e1 ubuntu "bash -c 'tail -f /d…" 9 seconds ago Up 8 seconds myubunut
e0add97dee80 gefyra-cargo:20220426153151 "/init" 14 seconds ago Up 13 seconds gefyra-cargo
97f9908c55df rancher/k3d-proxy:4.4.8 "/bin/sh -c nginx-pr…" 12 minutes ago Up 12 minutes 0.0.0.0:8080->80/tcp, :::8080->80/tcp, 0.0.0.0:34089->6443/tcp k3d-another-cluster-serverlb
1dccf93fc087 rancher/k3s:v1.20.4-k3s1 "/bin/k3s agent" 12 minutes ago Up 12 minutes 0.0.0.0:31820->31820/udp, :::31820->31820/udp k3d-another-cluster-agent-0
91ef49d000b5 rancher/k3s:v1.20.4-k3s1 "/bin/k3s server --t…" 12 minutes ago Up 12 minutes k3d-another-cluster-server-0
```
### Enter the container and call a service
Now that the container is running, you can enter a bash by running: `docker exec -it myubuntu bash`
```sh
root@6178770cd6b1:/#
```
In order to call an http service from this Kubernetes namespace a terminal application could be handy. The official
Ubuntu Docker image does not provide on of my favorites out of the box, but it is easy to add it.
```sh
root@6178770cd6b1:/# apt update && apt install wget -y
[...]
```
On another terminal (so not in your Ubuntu bash) you can consult `kubectl` to inspect the services in the *buzzword* namespace. For this example it
tells:
```sh
> kubectl -n buzzword get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dashboard-kubernetes-dashboard ClusterIP 10.43.147.1 8080/TCP 18m
[...]
buzzword-counter ClusterIP 10.43.221.222 9000/TCP 18m
buzzword-counter-postgresql ClusterIP 10.43.140.176 5432/TCP 18m
buzzword-counter-postgresql-headless ClusterIP None 5432/TCP 18m
buzzword-counter-rabbitmq ClusterIP 10.43.0.48 4369/TCP,5672/TCP,25672/TCP,15672/TCP 18m
buzzword-counter-rabbitmq-headless ClusterIP None 4369/TCP,5672/TCP,25672/TCP,15672/TCP 18m
```
Let's see how this works. From within your running Ubuntu bash, you can now call the *buzzword-counter* service on port
9000:
```sh
root@6178770cd6b1:/# wget -O- buzzword-counter:9000
--2022-04-26 13:41:43-- http://buzzword-counter:9000/
Resolving buzzword-counter (buzzword-counter)... 10.43.221.222
Connecting to buzzword-counter (buzzword-counter)|10.43.221.222|:9000... connected.
HTTP request sent, awaiting response... 200 OK
Length: 565 [text/html]
Saving to: 'STDOUT'
- 0%[ ] 0 --.-KB/s Buzzwords
- 100%[==================================================================================================>] 565 --.-KB/s in 0s
2022-04-26 13:41:43 (18.9 MB/s) - written to stdout [565/565]
```
Et voila! The service responded to the HTTP Get request with the same answer you would get with your browser at:
{rel=""nofollow""}.
You can now look around and make yourself familiar with the services
in this namespace - or even connect with the `psql` client to the *PostgreSQL* instance running in the cluster.
### Remove the Ubuntu container
Once you are done with your work, you can remove this Ubuntu instance again with:
`docker kill myubuntu`. That's it.
## Remove the Development Infrastructure
First run `gefyra down` to uninstall Gefyra's components. If you have initially created the development infrastructure using `Getdeck` you can now run:
```sh
> deck remove --cluster https://github.com/Blueshoe/buzzword-charts.git
[INFO] Deleting the k3d cluster with name another-cluster
```
If you created the infrastructure yourself, you probably already know how to get rid of everything yourself ;-)
# How does it work?
{.mx-auto}
With these components, Gefyra is able to control a local development machine, and the development cluster, too. Both sides are now in the hand of
Gefyra.
Once the developer's work is done, Gefyra well and truly removes all components from the cluster without leaving a trace.
A few things are required in order to achieve this:
- a *tunnel* between the local development machine and the Kubernetes cluster
- a local end of that tunnel to steer the traffic, DNS, and encrypt everything passing over the line
- a cluster end of the tunnel, forwarding traffic, taking care of the encryption
- a local DNS resolver that behaves like the cluster DNS
- sophisticated IP routing mechanisms
- a traffic interceptor for containers already running withing the Kubernetes cluster
Gefyra builds on top of the following popular open-source technologies:
## Docker
[*Docker*](https://docker.io){rel=""nofollow""} is currently used in order to manage the local container-based development setup, including the
host, networking and container management procedures.
## Wireguard
[*Wireguard*](https://wireguard.com){rel=""nofollow""} is used to establish the connection tunnel between the two ends. It securely encrypts the UDP-based traffic
and allows to create a *site-to-site* network for Gefyra. That way, the development setup becomes part of the cluster and containers running locally
are actually able to reach cluster-based resources, such as databases, other (micro)services and so on.
## CoreDNS
[*CoreDNS*](https://coredns.io){rel=""nofollow""} provides local DNS functionality. It allows resolving resources running within the Kubernetes cluster.
## Nginx
[*Nginx*](https://www.nginx.com/){rel=""nofollow""} is used for all kinds of proxying and reverse-proxying traffic, including the interceptions of already running containers
in the cluster.
## Architecture of the entire development system
### Local development setup
The local development happens with a running container instance of the application in question on the developer machine.
Gefyra takes care of the local Docker host setup, and hence needs access to it. It creates a dedicated Docker network
which the container is deployed to. Next to the developed application, Gefyra places a *sidecar* container. This container,
as a component of Gefyra, is called *Cargo*.
Cargo acts as a network gateway for the app container and, as such, takes care of the IP routing into and from the cluster.
In addition, Cargo provides a CoreDNS server which forwards all requests to the cluster. That way, the app container will be
able to reach resources running within the Kubernetes cluster.
{.mx-auto}
This local setup allows developers to use their existing tooling, including their favorite code editor and debuggers. The
application, when it is supported, can perform code-hot-reloading upon changes and pipe logging output to a local shell
(or other systems).
Of course, developers are able to mount local storage volumes into the container, override environment variables and modify
everything as they'd like to.
Replacing a container in the cluster with a local instance is called *bridge*: from an architectural perspective the local
application is *bridged* into the cluster.
If the container is already running within a Kubernetes Pod, it gets replaced and all traffic to the originally running
container is proxied to the one on the developer machine.
During the container startup of the application, Gefyra modifies the container's networking from the outside and sets the
*default gateway* to Cargo. That way, all container's traffic is passed to the cluster via Cargo's encrypted tunnel. The
same procedure can be applied for multiple app containers at the same time.
The neat part is that with a debugger and two or more *bridged* containers, developers can introspect requests from the source
to the target and back around while being attached to both ends.
## The *bridge* operation in action
This chapter covers the important *bridge* operation by following an example.
### Before the bridge operation
Think of a provisioned Kubernetes cluster running some workload. There is an Ingress, Kubernetes Services and Pods running
containers. Some of them use the [*sidecar*](https://medium.com/nerd-for-tech/microservice-design-pattern-sidecar-sidekick-pattern-dbcea9bed783){rel=""nofollow""} pattern.
{.mx-auto}
### Preparing the bridge operation
Before the *brigde* can happen, Gefyra installs all required components to the cluster. A valid and privileged connection
must be available on the developer machine to do so.
The main component is the cluster agent called *Stowaway*. The Stowaway controls the cluster side of the tunnel connection.
It is operated by [Gefyra's Operator application](https://github.com/gefyrahq/gefyra/tree/main/operator){rel=""nofollow""}.
{.mx-auto}
Stowaway boots up and dynamically creates Wireguard connection secrets (private/public key-pair) for itself and Cargo.
Gefyra copies these secrets to Cargo for it to establish a connection. This is a UDP connection. It requires a Kubernetes
Service of kind *nodeport* to allow the traffic to pass through *for the time of an active development session*. Gefyra's
operator installs these components with the requested parameters and removes it after the session terminates.
By the way: Gefyra's operator removes all components and itself from the cluster in case the connection was disrupted
for some time, too.
Once a connection could be establised from Cargo to Stowaway (after running `gefyra up`), Gefyra can spin up the app container on the local side for the
developer to start working (by running `gefyra run ...`).
Another job of Gefyra's operator is to rewrite the target pods, i.e. exchange the running container through Gefyras proxy,
called *Carrier* (upon running `gefyra bridge ...`).
For that, it creates a temporary Kubernetes Service that channels the Ingress traffic (or any other kind of cluster internal
traffic) to the container through Stowaway and Cargo to the locally running app container.
### During the bridge operation
A bridge can robustly run as long as it is required to (given the connection does not drop in the meanwhile).
Looking at the example, Carrier was installed in pod \ on port *XY*. That port was previously occupied by the container
running there originally. In most cases, the local app container represents the development version of that originally
provisioned container. Traffic coming from the Ingress, passing on to the Service \ hits Carrier (the proxy). Carrier
bends the request to flow through Gefyras Service to the local app container via Stowaway and Cargo's tunnel. This works
since the app container's IP is routable from within the cluster.
The local app container does not simply return a response, but fires up another subsequent request by itself to
Service \. The request roams from the local app container back into the cluster and hits Pod \'s container via
Service \. The response is awaited.
Once the local app container is done with constructing its initial answer the response gets back to Carrier and afterwards
to the Ingress and back to the client.
{.mx-auto}
With that, the local development container is reachable exactly the same way another container from within the cluster
would be. That fact is a major advantage, especially for frontend applications or domain-sensitive services.
Developers now can run local integration tests with new software while having access to all interdependent services.
Once the development job is done, Gefyra properly removes everything, resets Pod \ to its original configuration,
and decommissions Carrier and Stowaway.
# What is Gefyra?
{.mx-auto}
(*Kubectl* is not really required but kinda makes sense to be in this picture)
In order for this to work, a few requirements have to be satisfied:
- a Docker host must be available for the user on the development machine (it is convenient if [docker can be run without sudo-privileges](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user){rel=""nofollow""})
- Overlay networking must be supported by the Docker host
- there are a few container capabilities required on both sides, within the Kubernetes cluster and on the local computer
- a node port must be opened on the development cluster for the duration of the development work
Gefyra makes sure your development container runs as part of the cluster while you still have full access to it. In addition,
Gefyra is able to intercept the target application running within the cluster, i.e. a container in a Pod, and tunnels all traffic hitting said container to the one running
locally.
Now, developers can add new code or fix bugs and run it right away in the Kubernetes cluster, or simply introspect the traffic.
Gefyra provides the entire infrastructure to do so and provides a high level of developer convenience.
## Did I hear developer convenience?
The idea is to relieve developers from the hassle to go back and forth to the integration system with containers. Instead, take
the integration system closer to the developer and make the development cycles as short as possible. No more waiting for the CI to complete
just to see the service failing on the first request. Cloud-native (or Kubernetes-native) technologies have completely changed the
developer experience: infrastructure is increasingly becoming part of developer's business with all the barriers and obstacles, but also chances
to turn the software for the better.
Gefyra is here to provide a development workflow with the highest convenience possible. It brings low setup times, rapid development,
high release cadence and super-satisfied managers.
## Gotchas & Current Limitations
- Gefyra's VPN needs a reachable `NodePort`. In most non-local Kubernetes scenarios this requires to set a firewall rule
in order to **allow port 31820 for UDP traffic**. It's simple for most Cloud-providers ("Hyperscaler") and
doable for custom installations, too.
- Kubernetes-probes can be faked by Gefyra's Pod component ("Carrier") in order to keep Kubernetes from removing *bridged* Pods.
However, this is currently only supported for `httpGet` probes. Otherwise, you need to turn off probes during development.
- You will experience issues if you want to *bridge* containers in Pods which specify a specific `command` (other than common shells).
- This project is in a quite early stage. I assume there are still a few bugs around.
## Why "Gefyra"?
"Gefyra" is the Greek word for "Bridge" and fits nicely with Kubernetes' nautical theme.
# Run vs. Bridge Operation
| | Run | Bridge |
| ---------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| What | Run a local container and connect it to a Kubernetes cluster | Build on top of run. Connect a local container to a Kubernetes cluster and reroute traffic to it |
| Multi-User | Multiple users can run multiple containers connected to the same cluster | Multiple users cannot bridge the same workload |
| When | When you want to test a service in the cluster or write code that depends on Kubernetes resources | When you want to expose a local container to other services within the cluster |
## Run Operation
**Run** - allows to run a local container and connect it to a Kubernetes cluster. It is executed within a given namespace and can communicate
with other services running in the cluster. This allows your local container to talk to things databases or internal APIs within the cluster
you connected it to. Multiple users can run multiple containers connected to the same cluster.
## Bridge Operation
**Bridge** - builds on top of `Run`. In certain situation you want other services to connect to your local container. For this, your local container
needs some kind of representation within the Kubernetes cluster it is connected to. With `Bridge` Gefyra patches a given workload within your
Kubernetes cluster and reroutes all the incoming traffic to your local container. Multiple users cannot bridge the same workload.
# What changed between Gefyra v1 and Gefyra v2?
**Operator** - Gefyra's operator was completely refactored. It now acts as a state machine and shows much more stable and consistent
behaviour. It manages 2 custom resources - `GefyraClients` and `GefyraBridges`.
**Access Management** - While Gefyra `v1` just installed its operator into the cluster via the `up` command, Gefyra 2 allows for a more
fine grained control. `gefyra up` was split into `gefyra install`, `gefyra client` and the `gefyra connection` commands. Every connection to the
cluster is now controlled by a `GefyraClient` object which represents an indiviual client connection to the cluster.
For every `GefyraClient` a separate service account is created.
**Load Balancer Presets** - Not every cluster is just reachable through a public IP. To expose it for Gefyra's connection purposes we allow you to use
*Load Balancer Presets* which expose the necessary parts of Gefyra to make things work.
**CLI** - Gefyra's command line interface has been refactored - it's now written in [Click](https://click.palletsprojects.com/){rel=""nofollow""}.
The TUI is much more readable, it includes some progress bars - generally a much nicer experience.
**API** - Gefyra's core functionality is now moved into a separate Python package. It provides an API to control Gefyra's processes -
like `install`, `run`, `bridge`.
# Media
## Conferences
**Local containers on board! Connect your local containers to K8s using Gefyra | Kubernetes Community Days Munich 2022, Munich**
:gefyra-youtube{video-id="-HtBGPtaVo8"}
**Debugging a container with a sidecar using Gefyra | Cloud-native Rejects 2022, Valencia**
:gefyra-youtube{video-id="P6LKFCwelvo"}
**Debugging a container with a sidecar using Gefyra | Conf42 Cloud Native 2022**
:gefyra-youtube{video-id="FazRUwBWPUI"}
## Podcasts
**Accelerate And Simplify Cloud Native Development For Kubernetes Environments With Gefyra - Episode 359**
:gefyra-youtube{video-id="82qp1QFd+pR6zngj0"}
## Other Presentations
**Gefyra Docker Desktop Extension Demo April 2023**
:gefyra-youtube{video-id="EBArR1O2BGk"}
**Gefyra Docker Desktop Extension Demo Feb 2023**
:gefyra-youtube{video-id="4xmaOVul5Ww"}
**Gefyra Docker Desktop Extension Demo Jan 2023**
:gefyra-youtube{video-id="k1HsJNnRS3w"}
## Development Sessions
:gefyra-youtube{video-id="9BWeokWlYnQ"}
:gefyra-youtube{video-id="DApYfK4v8_g"}
:gefyra-youtube{video-id="zGxoLcOQh2U"}
## Blog
- **An alternative to Telepresence 2: Gefyra**{rel=""nofollow""}
- **Creating a Python CLI with Go(lang)-comparable startup times**{rel=""nofollow""}
- **How does local Kubernetes development work?**{rel=""nofollow""}
# About Gefyra
## License
Gefyra is distributed by an [Apache-2.0 License](https://github.com/gefyrahq/gefyra/tree/main/LICENSE){rel=""nofollow""}.
## Contributors
This open-source project is currently mainly carried out by [Michael Schilonka](https://github.com/Schille){rel=""nofollow""}. Follow me on [LinkedIn](https://www.linkedin.com/in/michael-schilonka){rel=""nofollow""}.
## Sponsors
This project is sponsored by [Blueshoe GmbH](https://blueshoe.io){rel=""nofollow""}.