Permalink
Fetching contributors…
Cannot retrieve contributors at this time
184 lines (141 sloc) 7.48 KB

+++ dep = 7 title = "Draft Connect" authors = [ "Radu Matei matei.radu94@gmail.com" ] created = 2018-03-23 +++

Introduction

draft connect is the command used to interact with the application deployed on your cluster. It works by creating proxy connections to the ports exposed by the containers in your pod, while also streaming the logs from all containers.

Specifying local ports

Draft will create local tunnels to all ports exposed by containers in your pod. By default, the local ports used are chosen at random, based on the available ports. However, you can speficy the port mapping.

Let's consider part of a deployment.yaml file that has an additional container with two ports, 80 and 81.

      containers:
      - name: {{ .Chart.Name }}
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        ports:
        - containerPort: {{ .Values.service.internalPort }}

      - name: multi-port
        image: radumatei/multi-port
        ports:
        - containerPort: 80
        - containerPort: 81

The image radumatei/multi-port is simply an nginx with two websites, one on port 80 and one on port 81.

.Values.service.internalPort is set in values.yaml to 8080.

If we draft connect without any options, we will get three localhost URLs with random local ports:

$ draft connect
Connect to go:8080 on localhost:49591
Connect to multi-port:80 on localhost:49593
Connect to multi-port:81 on localhost:49595
<streaming logs from all containers in pod>

Now you can access the endpoints of your application using the random local ports.

Using the -p flag for draft connect

You can specify the port mapping every time you need to connect to the application using the -p flag for draft connect: draft connect -p <local-port>:<remote port> -p <other-local-port>:<other-remote-port>. This will forward <remote-port> in your pod to localhost:<local-port> and <other-remote-port> to localhost:<other-local-port>.

Using the example above, we can pass the -p flag to specify the local ports:

$ draft connect -p 8080:8080 -p 9090:80 -p 9191:81
Connect to go:8080 on localhost:8080
Connect to multi-port:80 on localhost:9090
Connect to multi-port:81 on localhost:9191
<streaming logs from all containers in pod>

Now you can connect to your application on the local ports you specified, 8080, 9090 and 9191.

Using the override-ports field in draft.toml

If you are regularly using the same local ports to connect to your application and do not want to keep passing them as flags, you can setup the default ports to be used when connecting in draft.toml using the override-ports field. The corresponding value for the mapping above is:

    override-ports = ["8080:8080", "9090:80", "9191:81"]

Now you simply do draft connect and the port mapping is preserved:

$ draft connect
Connect to go:8080 on localhost:8080
Connect to multi-port:80 on localhost:9090
Connect to multi-port:81 on localhost:9191
<streaming logs from all containers in pod>

The -p flag in draft connect takes precedence over the override-ports field in draft.toml

If one of the <remote-port> values you are trying to map is not exposed on the pod, Draft will continue to connect to the rest of the ports in the pod without returning an error.

If the local port you are trying to map is not available, an error will be returned and the command will exit.

Specifying what container to connect to

By default, Draft will create tunnels to all ports in all containers in the pod. However, you can specify a container name using the --container or -c flags, followed by the name of the target container and Draft will only create tunnels to the ports exposed by that container in your pod, preserving the port mapping relevant to the ports of the specified container. Keeping the draft.toml port mapping from the example below (override-ports = ["8080:8080", "9090:80", "9191:81"]), if we only connect to the multi-port container we get:

$ draft connect -c multi-port
Connect to multi-port:80 on localhost:9090
Connect to multi-port:81 on localhost:9191
<streaming logs from multi-port>

And if we connect to the other container (which by default has the name of the chart, in this case go):

$ draft connect -c go
Connect to go:8080 on localhost:8080
<streaming logs from go>

We can override the port mapping using the -p flag for draft connect:

$ draft connect -c go -p 8081:8080
Connect to go:8080 on localhost:8081
<streaming logs from go>

Notice how in all cases we only get localhost tunnels to the container we specified as target container.

If the container passed does not exist, you will get an error: Error: container 'abc' not found and the execution will stop.

Auto-connecting to your application after draft up

If your workflow requires to automatically connect to your application after deploying it (or after updating it), you can do it in the following ways:

Using the --auto-connect flag for draft up

If we keep the example above:

$ draft up --auto-connect
Draft Up Started: 'example-go'
example-go: Building Docker Image: SUCCESS ⚓  (1.0038s)
example-go: Pushing Docker Image: SUCCESS ⚓  (6.0119s)
example-go: Releasing Application: SUCCESS ⚓  (0.7106s)
example-go: Build ID: 01C9HJKRQ7VZ3C4G9KBCS41BFJ
Inspect the logs with `draft logs 01C9HJKRQ7VZ3C4G9KBCS41BFJ`

Connect to go:8080 on localhost:8080
Connect to multi-port:80 on localhost:9090
Connect to multi-port:81 on localhost:9191
<streaming logs from all containers in pod>

Notice that the port mapping that was setup in draft.toml as override-ports = ["8080:8080", "9090:80", "9191:81"] was kept.

Using the auto-connect field in draft.toml

If you regularly want to automatically connect after upgrading the application, you can add a field in draft.toml that will have the same effect as passing --auto-connect, called auto-connect, and keeping the port mapping config:

    override-ports = ["8080:8080", "9090:80", "9191:81"]
    auto-connect = true
$ draft up
Draft Up Started: 'example-go'
example-go: Building Docker Image: SUCCESS ⚓  (6.0165s)
example-go: Pushing Docker Image: SUCCESS ⚓  (15.0178s)
example-go: Releasing Application: SUCCESS ⚓  (0.7882s)
example-go: Build ID: 01C9HRRMGMZ4ARFCY0ERNRJYDT
Inspect the logs with `draft logs 01C9HRRMGMZ4ARFCY0ERNRJYDT`

Connect to go:8080 on localhost:8080
Connect to multi-port:80 on localhost:9090
Connect to multi-port:81 on localhost:9191
<streaming logs from all containers in pod>

Detaching from connect

Using the --detach flag in draft connect will spawn a new Draft process that exports the tunnel connection environment to standard out. All flags, excluding --detach will be propagated to the detached Draft process. A hidden --export flag is appended to this set of flags which instructs Draft to export the connection environment. As a result, container logs are lost if Draft is connected in detach mode.

Continuing with the examples above:

$ eval $(draft connect -p 8081:8080 -c go --detach)
$ curl localhost:8081
Hello World, I'm Golang!

Note that re-executing draft connect --detach will establish a new tunnel. In addition, Draft does not track the state of detached Draft tunnel connections and it is the responsibility of the user to terminate detached Draft processes.

To illustate terminating a detached draft connection:

$ kill $(ps -a | grep -m1 draft | awk '{print $1}')