supplant

command module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Nov 30, 2021 License: MIT Imports: 1 Imported by: 0

README

supplant

Overview

supplant is a tool used for improve the development experience with Kubernetes. The concept is to start with a working cluster with all of the deployed services in your application and then to supplant or replace a service by replacing the K8s service by a new service without a selector and creating an endpoint that points to your local machine. The end result is that from within the cluster, the service now points to a port on your machine outside the cluster. To allow the service are developing that exists outside the cluster to reach any dependent services inside the cluster, those services are exposed individually via port forwarding

supplant Diagram

Why?

  • Pushing new images to test a change works, but the code/test cycle is very slow
  • It's convenient to run all of your existing tooling including running the service under a debugger on your machine
  • Telepresence is another more seamless approach at doing this, but it has to use a bit of networking magic to make it happen and I've had a few reliability issues with it.

Production Use

Please don't run this against a production cluster. It attempts to replace and un-replace

Sample Usage

We'll launch and expose two deployments via services that listen on port 80 and 81 respectively.

# launch the first
$ kubectl create deployment hello-1 --image=k8s.gcr.io/echoserver:1.4
$ kubectl expose deployment hello-1 --port 80 --target-port 8080

# launch the second
$ kubectl create deployment hello-2 --image=k8s.gcr.io/echoserver:1.4
$ kubectl expose deployment hello-2 --port 81 --target-port 8080

# generate our config file
$ supplant config create test.yml

The generated test.yml will now look something like this, where each of the two services is listed under a supplant and an external section within the YAML file.

supplant:
- name: hello-1
  namespace: default
  enabled: false
  ports:
  - protocol: TCP
    port: 80
    listenport: 8080
- name: hello-2
  namespace: default
  enabled: false
  ports:
  - protocol: TCP
    port: 81
    listenport: 8080
external:
- name: hello-1
  namespace: default
  enabled: false
  ports:
  - protocol: TCP
    targetport: 8080
    localport: 0
- name: hello-2
  namespace: default
  enabled: false
  ports:
  - protocol: TCP
    targetport: 8080
    localport: 0

We want to replace the hello-1 service, but have our replacement be able to access the hello-2 service. So we enable those two, and then clean our config file which removes the disabled services which are the services we will not be replacing or providing port forwarding to.

$ ./supplant config clean test.yml

The test.yml now looks like this:

supplant:
- name: hello-1
  namespace: default
  enabled: true
  ports:
  - protocol: TCP
    port: 80
    listenport: 8080
external:
- name: hello-2
  namespace: default
  enabled: true
  ports:
  - protocol: TCP
    targetport: 8080
    localport: 0

We can now run supplant on this configuration file:

$ supplant test.yml
=> connecting to K8s
=> K8s version: v1.21.1
=> updating service hello-1
 - 192.168.88.128:8080 is now the endpoint for hello-1:80
=> forwarding for hello-2
 - 127.0.0.1:38989 points to remote hello-2:8080
forwarding ports, hit Ctrl+C to exit

It lets us know that from within our cluster, anything trying to reach the hello-1 service will connect to 192.168.88.128:8080. supplant has also forwarded our local port 38989 to the hello-2 service at hello-2:8080. We can verify tat we have replaced the hello-1 service by trying to reach it from the hello-2 pod which fails as we haven't started anything listening on port 8080 yet.

$ kubectl exec -it deployment/hello-2 -- curl hello-1:80
curl: (7) Failed to connect to hello-1 port 80: Connection refused
command terminated with exit code 7

If we start a web server locally on port 8080, the connection will then work. In a separate shell we start a web server:

$ python3 -m http.server 8080                           
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...

And then retry the connection to the hello-1 service, which now hits our Python web server.

$  kubectl exec -it deployment/hello-2 -- curl hello-1:80
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Directory listing for /</title>
</head>
...

Lastly, we can verify that the port forward works locally as we can reach the hello-2 service. This allows our local service to access any resources inside the cluster that it needs to.

$ curl 127.0.0.1:38989
CLIENT VALUES:
client_address=127.0.0.1
command=GET
real path=/
query=nil
request_version=1.1
request_uri=http://127.0.0.1:8080/

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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