In this chapter, we will deploy a demo app in Kubernetes cluster, use KtConnect to access it from local environment, and redirect request in cluster to a local service.
Let's create a simple tomcat deployment, expose it as a service, and put a default html file as index page.
$ kubectl create deployment tomcat --image=tomcat:9 --port=8080
deployment.apps/tomcat created
$ kubectl expose deployment tomcat --port=8080 --target-port=8080
service/tomcat exposed
$ kubectl exec deployment/tomcat -c tomcat -- /bin/bash -c 'mkdir webapps/ROOT; echo "kt-connect demo v1" > webapps/ROOT/index.html'
Fetch information of pod and service created above.
$ kubectl get pod -o wide --selector app=tomcat
NAME READY STATUS RESTARTS AGE IP ...
tomcat 1/1 Running 0 34s 10.51.0.162 ...
$ kubectl get svc tomcat
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
tomcat ClusterIP 172.16.255.111 <none> 8080/TCP 34s
Remember the Pod IP (10.51.0.162
) and Cluster IP (172.16.255.111
) of tomcat service, they'll be used in following steps.
KtConnect use command connect
to let all cluster resources accessible from local (Root/Administrator permission is required).
Execute ktctl connect
command on Mac/Linux with sudo
:
$ sudo ktctl connect
00:00AM INF KtConnect start at <PID>
... ...
00:00AM INF ---------------------------------------------------------------
00:00AM INF All looks good, now you can access to resources in the kubernetes cluster
00:00AM INF ---------------------------------------------------------------
On Windows, execute ktctl connect
command in terminal (If you are not login as Administrator, you should right-click on CMD and PowerShell icon, choose "Run as Administrator" to open a terminal):
> ktctl connect
00:00AM INF KtConnect start at <PID>
... ...
00:00AM INF ---------------------------------------------------------------
00:00AM INF All looks good, now you can access to resources in the kubernetes cluster
00:00AM INF ---------------------------------------------------------------
Now any resource in the cluster can be directly accessed from local, you could use curl
or web browser to verify.
Note:In Windows PowerShell, the
curl
tool is conflict with a build-in command, please typecurl.exe
instead ofcurl
.
$ curl http://10.51.0.162:8080 # access Pod IP from local
kt-connect demo v1
$ curl http://172.21.6.39:8080 # access Cluster IP from local
kt-connect demo v1
$ curl http://tomcat:8080 # access Service via its name as domain name
kt-connect demo v1
$ curl http://tomcat.default:8080 # access Service via its name and namespace as domain name
kt-connect demo v1
$ curl http://tomcat.default.svc.cluster.local:8080 # access Service via fully qualified domain name
kt-connect demo v1
In order to verify the scenarios where the service in cluster access services at local, we also start a Tomcat service locally and create an index page with different content.
$ docker run -d --name tomcat -p 8080:8080 tomcat:9
$ docker exec tomcat /bin/bash -c 'mkdir webapps/ROOT; echo "kt-connect local v2" > webapps/ROOT/index.html'
KtConnect offers 2 commands for accessing local service from cluster in different cases.
- Exchange:redirect all request to specified service in cluster to local
- Mesh:redirect partial request to specified service in cluster (base on mesh rule) to local
Intercept and forward all requests to the specified service in the cluster to specified local port, which is usually used to debug service in the test environment at the middle of an invocation-chain.
┌──────────┐ ┌─ ── ── ── ┌──────────┐
│ ServiceA ├─┬─►x│ ServiceB │ ┌─►│ ServiceC │
└──────────┘ │ ── ── ── ─┘ │ └──────────┘
exchange │
│ ┌──────────┐ │
└──►│ ServiceB'├─┘ (Local Instance)
└──────────┘
Below command will transfer all the traffic of the tomcat
service previously deployed in the cluster to 8080
port of developer's laptop.
$ ktctl exchange tomcat --expose 8080
00:00AM INF KtConnect start at <PID>
... ...
---------------------------------------------------------------
Now all request to service 'tomcat' will be redirected to local
---------------------------------------------------------------
... ...
Visit the tomcat
service deployed to the cluster, and view the output result.
Note: you could also execute below command from any pod in the cluster to verify result, if you didn't run
ktctl connect
command locally.
$ curl http://tomcat:8080
kt-connect local v2
The request to tomcat
service in the cluster is now routed to the local Tomcat instance, thus you can directly debug this service locally.
Intercept and forward part of requests to the specified service in the cluster to specified local port. Usual used in team cooperation, one developer need to debug a service while do not want to disturb other developers.
┌──────────┐ ┌──────────┐ ┌──────────┐
│ ServiceA ├─┬──►│ ServiceB │─┬─►│ ServiceC │
└──────────┘ │ └──────────┘ │ └──────────┘
mesh │
│ ┌──────────┐ │
└──►│ ServiceB'├─┘ (Local Instance)
└──────────┘
Mesh command has 2 execution modes. The default auto
mode will automatically create corresponding routing rules for you without extra service mesh component.
In order to verify the results, firstly let's reset the content of the index page of the Tomcat service in the cluster, then use ktctl mesh
command to create a traffic rule:
$ kubectl exec deployment/tomcat -c tomcat -- /bin/bash -c 'mkdir webapps/ROOT; echo "kt-connect demo v1" > webapps/ROOT/index.html'
$ ktctl mesh tomcat --expose 8080
00:00AM INF KtConnect start at <PID>
... ...
--------------------------------------------------------------
Now you can access your service by header 'VERSION: feo3x'
--------------------------------------------------------------
At the end of command log, a special HTTP Header is printed. Now if you access the tomcat
service as normal, the traffic would come into the original pods.
$ curl http://tomcat:8080
kt-connect demo v1
If a request contains the HTTP Header shown by mesh command, the traffic will be redirected to local.
$ curl -H 'VERSION: feo3x' http://tomcat:8080
kt-connect local v2
In actual use, it can be combined with the ModHeader plugin, so that only the requests made by developers from their browsers will access their local service processes.
The manual
mode of mesh command provides possibility of more flexible route rule. In this mode, KtConnect will not automatically create the corresponding routing rules for you, the traffic accessing the service will randomly access the service in cluster and service at local. You can use any Service Mesh tool (such as Istio) to create routing rules based on the version
label of shadow pod to forward specific traffic to the local. Read Mesh Best Practice doc for more detail
The most significant difference between ktctl mesh
and ktctl exchange
commands is that the latter will completely replace the original application instance, while the former will still retain the original service pod after the shadow pod is created, and the router pod will dynamically generate a version
header (or label), so only specified traffic will be redirected to local, while ensuring that the normal traffic in the test environment is not effected.
In addition to the services that have been deployed to the cluster, during the development process, KtConnect can also be used to quickly "put" a local service to the cluster and turn it into a temporary service for other developers or other services in the cluster to use.
- Preview: Register a local service as a service in the cluster
- Forward: Redirect a local port to a cluster service. Can achieve to access services run on other developer's laptop via localhost while combining with
preview
command
Register a local service instance to cluster. Unlike the previous two commands, ktctl preview
is mainly used to debug or preview a services under developing.
The following command will register the service running on the port 8080
locally to the cluster as a service named tomcat-v2
.
$ ktctl preview tomcat-v2 --expose 8080
00:00AM INF KtConnect start at <PID>
... ...
---------------------------------------------------------------
Now you can access your local service in cluster by name 'tomcat-v2'
---------------------------------------------------------------
... ...
Now other services in the cluster can access the locally exposed service instance through the service name of tomcat-v2
, and other developers can also preview the service directly through service name tomcat-v2
after executing ktctl connect
on their laptops.
$ curl http://tomcat-v2:8080
kt-connect local v2
Redirect specified local port to any IP or service in the cluster. It is used to easily access a specific IP or service in the cluster using the localhost
address during testing. The typical scenario is to access local services of other developers registered by preview
command.
┌─────────────────────────────┐
forward | preview
┌────────┴───────┐ | ┌───────▼──────┐
│ localhost:8080 │ | │ local tomcat │
└────────────────┘ | └──────────────┘
Developer B | Developer A
For example, after a developer A runs the aforementioned preview
command, another developer B can use the ktctl forward
command to map it to its own local 6060
port.
$ ktctl forward tomcat-v2 6060:8080
00:00AM INF KtConnect start at <PID>
... ...
---------------------------------------------------------------
Now you can access port 8080 of service 'tomcat-v2' via 'localhost:6060'
---------------------------------------------------------------
Now developer B can use the localhost:6060
address to access the Tomcat service running locally by developer A.
When the forwarded traffic source is a service name in the cluster, the result is similar to the kubectl port-forward
command, except the additional ability to automatically reconnect when the network is disconnected.