Téléchargement de la documentation
Veuillez patienter pendant que le téléchargement se lance...
Building a Local Application Development Environment for Kubernetes with the Gefyra Docker Extension (05-03-2023)
This article was fetched from an rss feed
If you’re using a Docker-based development approach, you’re already well on your way toward creating cloud-native software. Containerizing your software ensures that you have all the system-level dependencies, language-specific requirements, and application configurations managed in a containerized way, bringing you closer to the environment in which your code will eventually run.
In complex systems, however, you may need to connect your code with several auxiliary services, such as databases, storage volumes, APIs, caching layers, message brokers, and others. In modern Kubernetes-based architectures, you also have to deal with service meshes and cloud-native deployment patterns, such as probes, configuration, and structural and behavioral patterns.
Kubernetes offers a uniform interface for orchestrating scalable, resilient, and services-based applications. However, its complexity can be overwhelming, especially for developers without extensive experience setting up Kubernetes clusters. That’s where Gefyra comes in, making it easier for developers to work with Kubernetes and improve the process of creating secure, reliable, and scalable software.
What is Gefyra?
Gefyra, named after the Greek word for “bridge,” is a comprehensive toolkit that facilitates Docker-based development with Kubernetes. If you plan to use Kubernetes as your production platform, it’s essential to work with the same environment during development. This approach ensures that you have the highest possible “dev/prod-parity,” minimizing friction when transitioning from development to production.
Gefyra is an open source project that provides docker run
on steroids. It allows you to connect your local Docker with any Kubernetes cluster and run a container locally that behaves as if it would run in the cluster. You can write code locally in your favorite code editor using the tools you love.
Additionally, Gefyra does not require you to build a container image from your code changes, push the image to a registry, or trigger a restart in the cluster. Instead, it saves you from this tedious cycle by connecting your local code right into the cluster without any changes to your existing Dockerfile. This approach is useful not only for new code but also when introspecting existing code with a debugger that you can attach to a running container. That makes Gefyra a productivity superstar for any Kubernetes-based development work.
How does Gefyra work?
Gefyra installs several cluster-side components that enable it to control the local development machine and the development cluster. These components include a tunnel between the local development machine and the Kubernetes cluster, a local DNS resolver that behaves like the cluster DNS, and sophisticated IP routing mechanisms. Gefyra uses popular open source technologies, such as Docker, WireGuard, CoreDNS, Nginx, and Rsync, to build on top of these components.
The local development setup involves running a container instance of the application on the developer machine, with a sidecar container called Cargo that acts as a network gateway and provides a CoreDNS server that forwards all requests to the cluster (Figure 1). Cargo encrypts all the passing traffic with WireGuard using ad hoc connection secrets. Developers can use their existing tooling, including their favorite code editor and debuggers, to develop their applications.
Figure 1: Local development setup.
Gefyra manages two ends of a WireGuard connection and automatically establishes a VPN tunnel between the developer and the cluster, making the connection robust and fast without stressing the Kubernetes API server (Figure 2). Additionally, the client side of Gefyra manages a local Docker network with a VPN endpoint, allowing the container to join the VPN that directs all traffic into the cluster.
Figure 2: Connecting developer machine and cluster.
Gefyra also allows bridging existing traffic from the cluster to the local container, enabling developers to test their code with real-world requests from the cluster and collaborate on changes in a team. The local container instance remains connected to auxiliary services and resources in the cluster while receiving requests from other Pods, Services, or the Ingress. This setup eliminates the need for building container images in a continuous integration pipeline and rolling out a cluster update for simple changes.
Why run Gefyra as a Docker Extension?
Gefyra’s core functionality is contained in a Python library available in its repository. The CLI that comes with the project has a long list of arguments that may be overwhelming for some users. To make it more accessible, Gefyra developed the Docker Desktop extension, which is easy for developers to use without having to delve into the intricacies of Gefyra.
The Gefyra extension for Docker Desktop enables developers to work with a variety of Kubernetes clusters, including the built-in Kubernetes cluster, local providers such as Minikube, K3d, or Kind, Getdeck Beiboot, or any remote clusters. Let’s get started.
Installing the Gefyra Docker Desktop
Prerequisites: Docker Desktop 4.8 or later.
Step 1: Initial setup
In Docker Desktop, confirm that the Docker Extensions feature is enabled. (Docker Extensions should be enabled by default.) In Settings | Extensions select the Enable Docker Extensions box (Figure 3).
![ Screenshot showing Docker Desktop interface with "Enable Docker Extensions" selected.](https://www.docker.com/wp-content/uploads/2023/06/F3-Gefyra-Enable-Docker-Extensions-1110x628.png "Screenshot showing Docker Desktop interface with "Enable Docker Extensions" selected. - F3 Gefyra Enable Docker Extensions")
Figure 3: Enable Docker Extensions.
You must also enable Kubernetes under Settings (Figure 4).
![Screenshot of Docker Desktop with "Enable Kubernetes" and "Show system containers (advanced)" selected.](https://www.docker.com/wp-content/uploads/2023/06/F4-Gefyra-Enable-Kubernetes-1110x594.png "Screenshot of Docker Desktop with "Enable Kubernetes" and "Show system containers (advanced)" selected. - F4 Gefyra Enable Kubernetes")
Figure 4: Enable Kubernetes.
Gefyra is in the Docker Extensions Marketplace. In the following instructions, we’ll install Gefyra in Docker Desktop.
Step 2: Add the Gefyra extension
Open Docker Desktop and select Add Extensions to find the Gefyra extension in the Extensions Marketplace (Figure 5).
![Screenshot showing search for "Gefyra" in Docker Extensions Marketplace.](https://www.docker.com/wp-content/uploads/2023/06/F5-Gefyra-Extensions-Marketplace-1110x635.png "Screenshot showing search for "Gefyra" in Docker Extensions Marketplace. - F5 Gefyra Extensions Marketplace")
Figure 5: Locate Gefyra in the Docker Extensions Marketplace.
Once Gefyra is installed, you can open the extension and find the start screen of Gefyra that lists all containers that are connected to a Kubernetes cluster. Of course, this section is empty on a fresh install.
To launch a local container with Gefyra, just like with Docker, you need to click on the Run Container button at the top right (Figure 6).
Figure 6: Gefyra start screen.
The next steps will vary based on whether you’re working with a local or remote Kubernetes cluster. If you’re using a local cluster, simply select the matching kubeconfig file and optionally set the context (Figure 7).
For remote clusters, you may need to manually specify additional parameters. Don’t worry if you’re unsure how to do this, as the next section will provide a detailed example for you to follow along with.
![Screenshot of Gefyra interface showing blue "Choose Kubeconfig" button.](https://www.docker.com/wp-content/uploads/2023/06/F7-Select-Kubeconfig-1110x628.png "Screenshot of Gefyra interface showing blue "Choose Kubeconfig" button. - F7 Select Kubeconfig")
Figure 7: Selecting Kubeconfig.
The Kubernetes demo workloads
The following example showcases how Gefyra leverages the Kubernetes functionality included in Docker Desktop to create a development environment for a simple application that consists of two services — a backend
and a frontend
(Figure 8).
Both services are implemented as Python processes, and the frontend service uses a color property obtained from the backend to generate an HTML document. Communication between the two services is established via HTTP, with the backend address being passed to the frontend as an environment variable.
Figure 8: Frontend and backend services.
The Gefyra team has created a repository for the Kubernetes demo workloads, which can be found on GitHub.
If you prefer to watch a video explaining what’s covered in this tutorial, check out this video on YouTube.
Prerequisite
Ensure that the current Kubernetes context is switched to Docker Desktop. This step allows the user to interact with the Kubernetes cluster and deploy applications to it using kubectl
.
kubectl config current-context docker-desktop
Clone the repository
The next step is to clone the repository:
git clone https://github.com/gefyrahq/gefyra-demos
Applying the workload
The following YAML file sets up a simple two-tier app consisting of a backend service and a frontend service with communication between the two services established via the SVC_URL
environment variable passed to the frontend
container.
It defines two pods, named backend
and frontend
, and two services, named backend
and frontend
, respectively. The backend
pod is defined with a container that runs the quay.io/gefyra/gefyra-demo-backend
image on port 5002. The frontend
pod is defined with a container that runs the quay.io/gefyra/gefyra-demo-frontend
image on port 5003. The frontend
container also includes an environment variable named SVC_URL
, which is set to the value backend.default.svc.cluster.local:5002
.
The backend
service is defined to select the backend
pod using the app: backend
label, and expose port 5002. The frontend
service is defined to select the frontend
pod using the app: frontend
label, and expose port 80 as a load balancer, which routes traffic to port 5003 of the frontend
container.
/gefyra-demos/kcd-munich> kubectl apply -f manifests/demo.yaml pod/backend created pod/frontend created service/backend created service/frontend created
Let’s watch the workload getting ready:
kubectl get pods NAME READY STATUS RESTARTS AGE backend 1/1 Running 0 2m6s frontend 1/1 Running 0 2m6s
After ensuring that the backend and frontend pods have finished initializing (check for the READY
column in the output), you can access the application by navigating to http://localhost in your web browser. This URL is served from the Kubernetes environment of Docker Desktop.
Upon loading the page, you will see the application’s output displayed in your browser. Although the output may not be visually stunning, it is functional and should provide the necessary functionality for your needs.
![Blue bar displaying "Hello World" in black text.](https://www.docker.com/wp-content/uploads/2023/06/hello-world-e1682692682514.png "Blue bar displaying "Hello World" in black text. - hello world e1682692682514")
Now, let’s explore how we can correct or adjust the color of the output generated by the frontend component.
Using Gefyra “Run Container” with the frontend process
In the first part of this section, you will see how to execute a frontend process on your local machine that is associated with a resource based on the Kubernetes cluster: the backend API. This can be anything ranging from a database to a message broker or any other service utilized in the architecture.
Kick off a local container with Run Container from the Gefyra start screen (Figure 9).
![Screenshot of Gefyra interface showing blue "Run container" button.](https://www.docker.com/wp-content/uploads/2023/06/F9-Run-local-container-1110x626.png "Screenshot of Gefyra interface showing blue "Run container" button. - F9 Run local container")
Figure 9: Run a local container.
Once you’ve entered the first step of this process, you will find the kubeconfig
` and context to be set automatically. That’s a lifesaver if you don’t know where to find the default kubeconfig on your host.
Just hit the Next button and proceed with the container settings (Figure 10).
![Screenshot of Gefyra interface showing the "Set Kubernetes Settings" step.](https://www.docker.com/wp-content/uploads/2023/06/F10-Gefyra-containers-1110x628.png "Screenshot of Gefyra interface showing the "Set Kubernetes Settings" step. - F10 Gefyra containers")
Figure 10: Container settings.
In the Container Settings step, you can configure the Kubernetes-related parameters for your local container. In this example, everything happens in the default Kubernetes namespace. Select it in the first drop-down input (Figure 11).
In the drop-down input below Image, you can specify the image to run locally. Note that it lists all images that are being used in the selected namespace (from the Namespace selector). Isn’t that convenient? You don’t need to worry about the images being used in the cluster or find them yourself. Instead, you get a suggestion to work with the image at hand, as we want to do in this example (Figure 12). You could still specify any arbitrary images if you like, for example, a completely new image you just built on your machine.
![Screenshot of Gefyra interface showing "Select a Workload" drop-down menu under Container Settings.](https://www.docker.com/wp-content/uploads/2023/06/F11-Gefyra-namespace-1110x634.png "Screenshot of Gefyra interface showing "Select a Workload" drop-down menu under Container Settings. - F11 Gefyra namespace")
Figure 11: Select namespace and workload.
Figure 12: Select image to run.
To copy the environment of the frontend container running in the cluster, you will need to select pod/frontend from the Copy Environment From selector (Figure 13). This step is important because you need the backend service address, which is passed to the pod in the cluster using an environment variable.
Finally, for the upper part of the container settings, you need to overwrite the following run command of the container image to enable code reloading:
poetry run flask --app app debug run --port 5002 --host 0.0.0.0
![Screenshot of Gefyra interface showing selection of “pod/frontend” under “Copy Environment From."](https://www.docker.com/wp-content/uploads/2023/06/F13-Copy-frontend-1110x628.png "Screenshot of Gefyra interface showing selection of “pod/frontend” under “Copy Environment From." - F13 Copy frontend")
Figure 13: Copy environment of frontend container.
Let’s start the container process on port 5002 and expose this port on the local machine. In addition, let’s mount the code directory (/gefyra-demos/kcd-munich/frontend
) to make code changes immediately visible. That’s it for now. A click on the Run button starts the process.
Figure 14: Installing Gefyra components.
It takes a few seconds to install Gefyra’s cluster-side components, prepare the local networking part, and pull the container image to start locally (Figure 14). Once this is ready, you will get redirected to the native container view of Docker Desktop from this container (Figure 15).
Figure 15: Log view.
You can look around in the container using the Terminal tab (Figure 16). Type in the env
command in the shell, and you will see all the environment variables coming with Kubernetes.
Figure 16: Terminal view.
We’re particularly interested in the SVC_URL
variable that points the frontend to the backend process, which is, of course, still running in the cluster. Now, when browsing to the URL http://localhost:5002, you will get a slightly different output:
![Blue bar displaying "Hello KCD" in black text](https://www.docker.com/wp-content/uploads/2023/06/Hello-KCD.png "Blue bar displaying "Hello KCD" in black text - Hello KCD")
Why is that? Let’s look at the code that we already mounted into the local container, specifically the app.py
that runs a Flask server (Figure 17).
Figure 17: App.py code.
The last line of the code in the Gefyra example displays the text Hello KCD!
, and any changes made to this code are immediately updated in the local container. This feature is noteworthy because developers can freely modify the code and see the changes reflected in real-time without having to rebuild or redeploy the container.
Line 12 of the code in the Gefyra example sends a request to a service URL, which is stored in the variable SVC. The value of SVC is read from an environment variable named SVC_URL
, which is copied from the pod in the Kubernetes cluster. The URL, backend.default.svc.cluster.local:5002
, is a fully qualified domain name (FQDN) that points to a Kubernetes service object and a port.
These URLs are commonly used by applications in Kubernetes to communicate with each other. The local container process is capable of sending requests to services running in Kubernetes using the native connection parameters, without the need for developers to make any changes, which may seem like magic at times.
In most development scenarios, the capabilities of Gefyra we just discussed are sufficient. In other words, you can use Gefyra to run a local container that can communicate with resources in the Kubernetes cluster, and you can access the app on a local port. However, what if you need to modify the backend while the frontend is still running in Kubernetes? This is where the “bridge” feature of Gefyra comes in, which we will explore next.
Gefyra “bridge” with the backend process
We could choose to run the frontend process locally and connect it to the backend process running in Kubernetes through a bridge. However, this approach may not always be necessary or desirable, especially for backend developers who may not be interested in the frontend. In this case, it may be more convenient to leave the frontend running in the cluster and stop the local instance by selecting the stop button in Docker Desktop’s container view.
First of all, we have to run a local instance of the backend service. It’s the same as with the frontend, but this time with the backend container image (Figure 18).
![Screenshot of Gefyra interface showing "pod/backend" setup.](https://www.docker.com/wp-content/uploads/2023/06/F18-Gefyra-Run-backend-1110x628.png "Screenshot of Gefyra interface showing "pod/backend" setup. - F18 Gefyra Run backend")
Figure 18: Running a backend container image.
Compared to the frontend example from above, you can run the backend container image (quay.io/gefyra/gefyra-demo-backend:latest
), which is suggested by the drop-down selector. This time we need to copy the environment from the backend pod running in Kubernetes. Note that the volume mount is now set to the code of the backend service to make it work.
After starting the container, you can check http://localhost:5002/color, which serves the backend API response. Looking at the app.py
of the backend service shows the source of this response. In line 8, this app returns a JSON response with the color property set to green
(Figure 19).
![Screenshot showing app.py code with "color" set to "green".](https://www.docker.com/wp-content/uploads/2023/06/F19-Gefyra-Check-color.png "Screenshot showing app.py code with "color" set to "green". - F19 Gefyra Check color")
Figure 19: Checking the color.
At this point, keep in mind that we’re only running a local instance of the backend service. This time, a connection to a Kubernetes-based resource is not needed as this container runs without any external dependency.
The idea is to make the frontend process that serves from the Kubernetes cluster on http://localhost (still blue) pick up our backend information to render its output. That’s done using Gefyra’s bridge feature. In the next step, we will overlay the backend process running in the cluster with our local container instance so that the local code becomes effective in the cluster.
Getting back to the Gefyra container list on the start screen, you can find the Bridge column on each locally running container (Figure 20). Once you click this button, you can create a bridge of your local container into the cluster.
![Screenshot of Gefyra interface showing "Bridge" column on far right.](https://www.docker.com/wp-content/uploads/2023/06/F20-Gefyra-Bridge-1110x628.png "Screenshot of Gefyra interface showing "Bridge" column on far right. - F20 Gefyra Bridge")
Figure 20: The Bridge column is visible on the far right.
In the next dialog, we need to enter the bridge configuration (Figure 21).
Figure 21: Enter the bridge configuration.
Let’s set the “Target” for the bridge to the backend pod, which is currently serving the frontend process in the cluster, and set a timeout for the bridge to 60 seconds. We also need to map the port of the proxy running in the cluster with the local instance.
If your local container is configured to listen on a different port from the cluster, you can specify the mapping here (Figure 22). In this example, the service is running on port 5003 in both the cluster and on the local machine, so we need to map that port. After clicking the Bridge button, it takes a few seconds to return to the container list on Gefyra’s start view.
Figure 22: Specify port mapping.
Observe the change in the icon of the Bridge button, which now depicts a stop symbol (Figure 23). This means the bridge function is now operational and can be terminated by simply clicking this button again.
Figure 23: The Bridge column showing a stop symbol.
At this point, the local code is able to handle requests from the frontend process in the cluster by using the URL stored in the SVC_URL
variable, without making any changes to the frontend process itself. To confirm this, you can open http://localhost in your browser (which is served from the Kubernetes of Docker Desktop) and check that the output is now green. This is because the local code is returning the value green
for the color property. You can change this value to any valid one in your IDE, and it will be immediately reflected in the cluster. This is the amazing power of this tool.
Remember to release the bridge of your container once you are finished making changes to your backend. This will reset the cluster to its original state, and the frontend will display the original “beautiful” blue H1 again. This approach allows us to intercept containers running in Kubernetes with our local code without modifying the Kubernetes cluster itself. That’s because we did not make any changes to the Kubernetes cluster itself. Instead, we kind of intercepted containers running in Kubernetes with our local code and released that intercept afterwards.
Conclusion
Gefyra is an easy-to-use Docker Desktop extension that connects with Kubernetes to improve development workflows and team collaboration. It lets you run containers as usual while being connected with Kubernetes, thereby saving time and ensuring high dev/prod parity.
The Blueshoe development team would appreciate a star on GitHub and welcomes you to join their Discord community for more information.
About the Author
Michael Schilonka is a strong believer that Kubernetes can be a software development platform, too. He is the co-founder and managing director of the Munich-based agency Blueshoe and the technical lead of Gefyra and Getdeck. He talks about Kubernetes in general and how they are using Kubernetes for development. Follow him on LinkedIn to stay connected.