Here are the steps for running the demo.
- Docker
- GNU Make
- Go
- Kubernetes (using Kind)
- Telepresence CLI
The demo begins with deploying the first version of the wizards listing application to a Kubernetes cluster. This demo will use Kind, but any Kubernetes cluster will do where the user has administrative access to deploy services to.
Creating cluster "kind" ...
✓ Ensuring node image (kindest/node:v1.21.1) 🖼
✓ Preparing nodes 📦
✓ Writing configuration 📜
✓ Starting control-plane 🕹️
✓ Installing CNI 🔌
✓ Installing StorageClass 💾
Set kubectl context to "kind-kind"
You can now use your cluster with:
kubectl cluster-info --context kind-kind
Make sure the kind-kind
cluster is set to the current context in kubeconfig.
kubectl config current-context
kind-kind
Check cluster access
kubectl get all --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system pod/coredns-558bd4d5db-4kpp2 1/1 Running 0 3m23s
kube-system pod/coredns-558bd4d5db-gprnq 1/1 Running 0 3m23s
kube-system pod/etcd-kind-control-plane 1/1 Running 0 3m25s
kube-system pod/kindnet-bntcb 1/1 Running 0 3m23s
kube-system pod/kube-apiserver-kind-control-plane 1/1 Running 0 3m25s
kube-system pod/kube-controller-manager-kind-control-plane 1/1 Running 0 3m25s
kube-system pod/kube-proxy-4bm4n 1/1 Running 0 3m23s
kube-system pod/kube-scheduler-kind-control-plane 1/1 Running 0 3m25s
local-path-storage pod/local-path-provisioner-547f784dff-5j89p 1/1 Running 0 3m23s
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3m38s
kube-system service/kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 3m36s
NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-system daemonset.apps/kindnet 1 1 1 1 1 <none> 3m35s
kube-system daemonset.apps/kube-proxy 1 1 1 1 1 kubernetes.io/os=linux 3m36s
NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE
kube-system deployment.apps/coredns 2/2 2 2 3m36s
local-path-storage deployment.apps/local-path-provisioner 1/1 1 1 3m34s
NAMESPACE NAME DESIRED CURRENT READY AGE
kube-system replicaset.apps/coredns-558bd4d5db 2 2 2 3m23s
local-path-storage replicaset.apps/local-path-provisioner-547f784dff 1 1 1 3m23s
Everything looks good. Let's build and deploy v1 of the app.
Kind comes with the ability to load images into the cluster. Within the repo, there is a make
target to build the images and load them into Kind
make all
This target will build both the client and the server and load them into Kind.
Now that the images have been build and loaded into Kind, let's apply the yaml in the infra
directory to deploy the applications.
kubectl apply -f infra/
deployment.apps/mongo created
service/mongo created
configmap/wizards-client-configmap created
deployment.apps/wizards-client created
configmap/wizards-server-configmap created
deployment.apps/wizards-server created
service/wizards-server created
Check the pods.
kubectl get pods
NAME READY STATUS RESTARTS AGE
mongo-6844bdfcdd-f9ts4 0/1 ContainerCreating 0 23s
wizards-client-66cfb96b7f-9g5z5 1/1 Running 0 23s
wizards-server-c445d54d6-zx9d9 0/1 Error 2 23s
The wizards-server
pod here is failing because the MongoDB pod is not up. Wait a few minutes for the MongoDB pod to come up and the server pod should recover.
kubectl get pods
NAME READY STATUS RESTARTS AGE
mongo-6844bdfcdd-tk52m 1/1 Running 0 83s
wizards-client-66cfb96b7f-9g5z5 1/1 Running 0 83s
wizards-server-c445d54d6-2phq2 1/1 Running 1 83s
Version one of the application has been deployed.
The only way for an external user to interact with the application is to tail the logs. Let's look at the server logs first by running `kubectl logs .
kubectl logs wizards-server-c445d54d6-2phq2
...
2021/06/15 18:25:11 # -------------------------------------- #
2021/06/15 18:25:11 sending list of wizards to client
2021/06/15 18:25:11 # -------------------------------------- #
2021/06/15 18:25:11 sending wizard to client: Harry Potter
2021/06/15 18:25:11 sending wizard to client: Ron Weasley
2021/06/15 18:25:11 sending wizard to client: Hermione Granger
2021/06/15 18:25:11 sending wizard to client: Cho Chang
2021/06/15 18:25:11 sending wizard to client: Luna Lovegood
2021/06/15 18:25:11 sending wizard to client: Sybill Trelawney
2021/06/15 18:25:11 sending wizard to client: Pomona Sprout
2021/06/15 18:25:11 sending wizard to client: Cedric Diggory
2021/06/15 18:25:11 sending wizard to client: Newton Scamander
2021/06/15 18:25:11 sending wizard to client: Draco Malfoy
2021/06/15 18:25:11 sending wizard to client: Bellatrix Lestrange
2021/06/15 18:25:11 sending wizard to client: Severus Snape
2021/06/15 18:25:11 # -------------------------------------- #
2021/06/15 18:25:11 done sending list of wizards to client
2021/06/15 18:25:11 # -------------------------------------- #
Here is a complete batch of wizards retrieved from the database and sent to the client upon request. Let's look at the client by accessing its logs.
kubectl logs wizards-client-66cfb96b7f-9g5z5
2021/06/15 18:29:24 # -------------------------------------- #
2021/06/15 18:29:24 requesting list of wizards from the server
2021/06/15 18:29:24 # -------------------------------------- #
2021/06/15 18:29:24 wizard received: Harry Potter
2021/06/15 18:29:24 wizard received: Ron Weasley
2021/06/15 18:29:24 wizard received: Hermione Granger
2021/06/15 18:29:24 wizard received: Cho Chang
2021/06/15 18:29:24 wizard received: Luna Lovegood
2021/06/15 18:29:24 wizard received: Sybill Trelawney
2021/06/15 18:29:24 wizard received: Pomona Sprout
2021/06/15 18:29:24 wizard received: Cedric Diggory
2021/06/15 18:29:24 wizard received: Newton Scamander
2021/06/15 18:29:24 wizard received: Draco Malfoy
2021/06/15 18:29:24 wizard received: Bellatrix Lestrange
2021/06/15 18:29:24 wizard received: Severus Snape
2021/06/15 18:29:24 # --------------------------------------#
2021/06/15 18:29:24 received list of wizards from the server
2021/06/15 18:29:24 # ------------------------------------- #
Here is a complete batch of logging from the response sent back from the server. This process happens every second.
The application is in good health. Now let's make some modifications.
This application by default is not accessable from outside of the cluster. Looking at the services, they are all of type ClusterIP which means the pods behind those services are only accessable within the cluster.
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 19m
mongo ClusterIP 10.96.218.75 <none> 27017/TCP 15m
wizards-server ClusterIP 10.96.57.15 <none> 9999/TCP 15m
Those 10.x IP addresses are only local to the cluster. Trying to access the MongoDB service via its IP or DNS name from outside of the cluster times out.
curl -m 1 10.96.218.75:27017
curl: (28) Connection timed out after 1001 milliseconds
curl -m 1 mongo.default.svc.cluster.local:27017
curl: (6) Could not resolve host: mongo.default.svc.cluster.local
In the case of the DNS name, the local DNS could not resolve the requested DNS name. That name only lives within cluster DNS. Running either the server or the client application will fail unless they are both running at the sametime outside of the cluster and if there is an installation of MongoDB outside of the cluster. However, the problems there are:
- all dependencies will have to be installed on the developer's workstation
- dependencies change and there could be environment drift from local development to a deployed cluster
- there may be other cluster resources not available on the workstation
- a local database may have outdated or wrong data
These are to name a few.
Telepresence alleviates all the above problems. and sets up the networking to make it appear that the laptop is in the cluster and has access to the same dependencies as the deployed applications do.
Connect to the cluster with Telepresence.
telepresence connect
Launching Telepresence Daemon v2.3.0 (api v3)
Connecting to traffic manager...
Connected to context kind-kind (https://127.0.0.1:36891)
This command creates a new namespace named ambassador
and installs everything Telepresence needs on the cluster side.
kubectl get all -n ambassador
NAME READY STATUS RESTARTS AGE
pod/traffic-manager-759568df76-vbx27 1/1 Running 0 94s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/traffic-manager ClusterIP None <none> 8081/TCP 94s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/traffic-manager 1/1 1 1 94s
NAME DESIRED CURRENT READY AGE
replicaset.apps/traffic-manager-759568df76 1 1 1 94s
Now, let's try to connect to MongoDB.
curl -m 1 mongo.default.svc.cluster.local:27017
It looks like you are trying to access MongoDB over HTTP on the native driver port.
We now get a response from MongoDB and can use its DNS name. It is as if the local workstation is in the cluster. We can now make local modifications to the application code and validate them against a deployed environement.
Let's first make an update to the server. The change made will be updating the log messages on the List
GRPC service.
First, install the Go dependencies for the server.
Install the protobuf compiler from these instructions for your OS/Arch.
Install Go specific protobuf plugins.
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest && go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
Install the applications' dependencies.
go mod download
Finally, build the protobuf files using the included Make target.
make proto
Start the server.
go run cmd/server/main.go
2021/06/15 14:50:51 starting wizards server
2021/06/15 14:50:51 checking for configMap file at: ./wizards-server-configMap.txt
2021/06/15 14:50:51 did not find config file: ./wizards-server-configMap.txt. using Kubernetes environment
2021/06/15 14:50:51 printing MONGO_HOST:
2021/06/15 14:50:51 dropping the wizards collection and seeding database
2021/06/15 14:50:52 error pinging DB: server selection error: context deadline exceeded, current topology: { Type: Unknown, Servers: [{ Addr: :27017, Type: Unknown, Average RTT: 0, Last error: connection() error occured during connection handshake: dial tcp :27017: connect: connection refused }, ] }
exit status 1
The server immediately starts up and fails. Logs show the server doesn't know where the database is. Let's intercept cluster traffic bound for the deployed server and create a config file based on the environment of the deployed server so that the local config matches exactly with the deployed configuration. This is done with Telepresence.
telepresence intercept wizards-server --namespace default --port 9999:9999 --env-file wizards-server-configMap.txt
An update of telepresence from version 2.3.0 to 2.3.1 is available. Please visit https://www.getambassador.io/docs/telepresence/latest/install/upgrade/ for more info.
Using Deployment wizards-server
intercepted
Intercept name : wizards-server-default
State : ACTIVE
Workload kind : Deployment
Destination : 127.0.0.1:9999
Service Port Identifier: 9999
Volume Mount Error : sshfs is not installed on your local machine
Intercepting : all TCP connections
The command tells Kubernetes to intercept any traffic for the wizards-server
deployment in the default
namespace at port 9999
, proxy it to the local workstation on port 9999
, and to take the environment of the pods in the wizards-server
deployment and make a local file wizards-server-configMap.txt. Open this file and notice there are a bunch of key=value pairs. These are the environment variables inside of the wizard-server
pod. We will use this file later.
Now, requests from the client are going to the local workstation and are going unanswered. Tail the logs from the client.
kubectl logs -f wizards-client-66cfb96b7f-9g5z5
2021/06/15 18:54:47 # --------------------------------------#
2021/06/15 18:54:47 received list of wizards from the server
2021/06/15 18:54:47 # ------------------------------------- #
2021/06/15 18:54:48 # -------------------------------------- #
2021/06/15 18:54:48 requesting list of wizards from the server
2021/06/15 18:54:48 # -------------------------------------- #
2021/06/15 18:54:49 wizard received: Harry Potter
2021/06/15 18:54:49 wizard received: Ron Weasley
2021/06/15 18:54:49 wizard received: Hermione Granger
2021/06/15 18:54:49 wizard received: Cho Chang
2021/06/15 18:54:49 wizard received: Luna Lovegood
2021/06/15 18:54:49 wizard received: Sybill Trelawney
2021/06/15 18:54:49 wizard received: Pomona Sprout
2021/06/15 18:54:49 wizard received: Cedric Diggory
2021/06/15 18:54:49 wizard received: Newton Scamander
2021/06/15 18:54:49 wizard received: Draco Malfoy
2021/06/15 18:54:49 wizard received: Bellatrix Lestrange
2021/06/15 18:54:49 wizard received: Severus Snape
2021/06/15 18:54:49 # --------------------------------------#
2021/06/15 18:54:49 received list of wizards from the server
2021/06/15 18:54:49 # ------------------------------------- #
2021/06/15 18:54:50 # -------------------------------------- #
2021/06/15 18:54:50 requesting list of wizards from the server
2021/06/15 18:54:50 # -------------------------------------- #
The logs have stopped updating every second because the client reaches out on port 9999
, but nothing on the local workstation is listening on port 9999
. Open up another terminal and start the server.
go run cmd/server/main.go
2021/06/15 15:00:15 starting wizards server
2021/06/15 15:00:15 checking for configMap file at: ./wizards-server-configMap.txt
2021/06/15 15:00:15 found ./wizards-server-configMap.txt file. setting environment variables
2021/06/15 15:00:15 done setting environment variables
2021/06/15 15:00:15 printing MONGO_HOST: mongo.default.svc.cluster.local
2021/06/15 15:00:15 dropping the wizards collection and seeding database
2021/06/15 15:00:15 connected to the database
2021/06/15 15:00:15 inserted document for wizard: Harry Potter
2021/06/15 15:00:15 inserted document for wizard: Ron Weasley
2021/06/15 15:00:15 inserted document for wizard: Hermione Granger
2021/06/15 15:00:15 inserted document for wizard: Cho Chang
2021/06/15 15:00:15 inserted document for wizard: Luna Lovegood
2021/06/15 15:00:15 inserted document for wizard: Sybill Trelawney
2021/06/15 15:00:15 inserted document for wizard: Pomona Sprout
2021/06/15 15:00:15 inserted document for wizard: Cedric Diggory
2021/06/15 15:00:15 inserted document for wizard: Newton Scamander
2021/06/15 15:00:15 inserted document for wizard: Draco Malfoy
2021/06/15 15:00:15 inserted document for wizard: Bellatrix Lestrange
2021/06/15 15:00:15 inserted document for wizard: Severus Snape
2021/06/15 15:00:15 inserted 13 documents
2021/06/15 15:00:15 finished seeding the database
2021/06/15 15:00:15 # ----------------------------------- #
2021/06/15 15:00:15 running grpc server on port: 9999
2021/06/15 15:00:15 # ----------------------------------- #
Now the server successfully starts up because upon start up, it read the environment file and got the same configs that are available to the deployed application.
Notice how after a few seconds the client started updating every second and the server logs started updating? The deployed client is now able to access the locally running Go process. If you were to open another terminal and tail the logs of the deployed server, they would not be updating. It receives no traffic, while the local process does.
Great, now let's update the local process.
There needs to be an update to the server. These logs are fine, but users complain that the logs need more flair. Let's respond to this feature request.
Open the server file. There's a for loop at lines 110-137
with commented out code:
for cursor.Next(context.Background()) {
var wizard pb.Wizard
err := cursor.Decode(&wizard)
if err != nil {
log.Printf("unable to decode wizard cursor into struct: %v", err)
}
// Commenting out. Uncomment when making the server change in the demo
// switch house := wizard.House; house {
// case "Gryffindor":
// log.Printf("%v - sending wizard to client: %v", emoji.Eagle, wizard.GetName())
// case "Ravenclaw":
// log.Printf("%v - sending wizard to client: %v", emoji.Bird, wizard.GetName())
// case "Hufflepuff":
// log.Printf("%v - sending wizard to client: %v", emoji.Badger, wizard.GetName())
// case "Slytherin":
// log.Printf("%v - sending wizard to client: %v", emoji.Snake, wizard.GetName())
// }
// comment this log statement as part of the server demo
log.Printf("sending wizard to client: %v", wizard.GetName())
err = srv.Send(&wizard)
if err != nil {
log.Printf("send error: %v", err)
}
}
Let's uncomment the commented lines and comment out line 131. It should look like this:
for cursor.Next(context.Background()) {
var wizard pb.Wizard
err := cursor.Decode(&wizard)
if err != nil {
log.Printf("unable to decode wizard cursor into struct: %v", err)
}
// Commenting out. Uncomment when making the server change in the demo
switch house := wizard.House; house {
case "Gryffindor":
log.Printf("%v - sending wizard to client: %v", emoji.Eagle, wizard.GetName())
case "Ravenclaw":
log.Printf("%v - sending wizard to client: %v", emoji.Bird, wizard.GetName())
case "Hufflepuff":
log.Printf("%v - sending wizard to client: %v", emoji.Badger, wizard.GetName())
case "Slytherin":
log.Printf("%v - sending wizard to client: %v", emoji.Snake, wizard.GetName())
}
// comment this log statement as part of the server demo
// log.Printf("sending wizard to client: %v", wizard.GetName())
err = srv.Send(&wizard)
if err != nil {
log.Printf("send error: %v", err)
}
}
You will need to install and import the emoji
package: go get github.com/enescakir/emoji && go mod tidy
.
Restart the server by pressing ctrl+c
and running the go run
command again.
Now the logs print out some ASCII emojis based on the wizard's house they belong to:
2021/06/15 15:09:43 # -------------------------------------- #
2021/06/15 15:09:43 sending list of wizards to client
2021/06/15 15:09:43 # -------------------------------------- #
2021/06/15 15:09:43 🦅 - sending wizard to client: Harry Potter
2021/06/15 15:09:43 🦅 - sending wizard to client: Ron Weasley
2021/06/15 15:09:43 🦅 - sending wizard to client: Hermione Granger
2021/06/15 15:09:43 🐦 - sending wizard to client: Cho Chang
2021/06/15 15:09:43 🐦 - sending wizard to client: Luna Lovegood
2021/06/15 15:09:43 🐦 - sending wizard to client: Sybill Trelawney
2021/06/15 15:09:43 🦡 - sending wizard to client: Pomona Sprout
2021/06/15 15:09:43 🦡 - sending wizard to client: Cedric Diggory
2021/06/15 15:09:43 🦡 - sending wizard to client: Newton Scamander
2021/06/15 15:09:43 🐍 - sending wizard to client: Draco Malfoy
2021/06/15 15:09:43 🐍 - sending wizard to client: Bellatrix Lestrange
2021/06/15 15:09:43 🐍 - sending wizard to client: Severus Snape
2021/06/15 15:09:43 # -------------------------------------- #
2021/06/15 15:09:43 done sending list of wizards to client
2021/06/15 15:09:43 # -------------------------------------- #
This is a much better user experience and fulfills the feature reqeust. If you still have the deployed server terminal open, it should not be updating, nor should the client logs be impacted.
Telepresence intercept is a great way to make local changes to an application and validate them with deployed applications, configurations, and data. It is far more likely that a regression could be caught in development since there is the ability to do some integration testing right on the developer's workstation before the code is even deployed.
Let's clean up.
Stop the server process with ctrl+c
.
List out the Telepresence intercepts.
telepresence list
mongo : ready to intercept (traffic-agent not yet installed)
wizards-server: intercepted
Intercept name : wizards-server-default
State : ACTIVE
Workload kind : Deployment
Destination : 127.0.0.1:9999
Service Port Identifier: 9999
Intercepting : all TCP connections
This command shows all applications that can be intercepted. In this case, it is all of the deployments who have a service associated with them. Since the client does not have a service, it cannot (nor does it need to be) intercepted.
Disconnect from the server and list the connections.
telepresence leave wizards-server-default
telepresence list
mongo : ready to intercept (traffic-agent not yet installed)
wizards-server: ready to intercept (traffic-agent already installed)
Now both available intercepts are ready to be started. You should also notice that both the deployed client and deployed server have begun updating their logs again.
Now, let's update the client and validate against the deployed server.
Running the client now that the wizards-server-configMap.txt
file has been created is much easier than running the server. There are not intercepts that need to be done. Running the client is a simple command.
go run cmd/client/main.go
2021/06/15 15:21:06 checking for configMap file at: ./wizards-server-configMap.txt
2021/06/15 15:21:06 found ./wizards-server-configMap.txt file. setting environment variables
2021/06/15 15:21:06 done setting environemnt variables
2021/06/15 15:21:07 # -------------------------------------- #
2021/06/15 15:21:07 requesting list of wizards from the server
2021/06/15 15:21:07 # -------------------------------------- #
2021/06/15 15:21:07 wizard received: Harry Potter
2021/06/15 15:21:07 wizard received: Ron Weasley
2021/06/15 15:21:07 wizard received: Hermione Granger
2021/06/15 15:21:07 wizard received: Cho Chang
2021/06/15 15:21:07 wizard received: Luna Lovegood
2021/06/15 15:21:07 wizard received: Sybill Trelawney
2021/06/15 15:21:07 wizard received: Pomona Sprout
2021/06/15 15:21:07 wizard received: Cedric Diggory
2021/06/15 15:21:07 wizard received: Newton Scamander
2021/06/15 15:21:07 wizard received: Draco Malfoy
2021/06/15 15:21:07 wizard received: Bellatrix Lestrange
2021/06/15 15:21:07 wizard received: Severus Snape
2021/06/15 15:21:07 # --------------------------------------#
2021/06/15 15:21:07 received list of wizards from the server
2021/06/15 15:21:07 # ------------------------------------- #
The client starts up, finds the config file, and begins asking the deployed server for a list of wizards.
Let's make a change to this local client. Our users have asked us to alert them if a wizard in the return list is a Death Eater. We can deliver this reqeust easily since Mongo already has that data stored.
Open the client file.
There are a few commented out lines at 75-77
and a whole function is commented out at 82-86
. This will enable to functionality to update the logs if a Death Eater is found in the response from the server.
// commenting out for the demo. uncomment during demo of the client
// if resp.GetDeathEater() {
// alertDeathEather(resp)
// }
}
}
// commenting out for the demo. uncomment during demo of the client
// func alertDeathEather(w *pb.Wizard) {
// log.Println("")
// log.Printf("Oh no! %s is a Death Eater!", w.GetName())
// log.Println("")
// }
Uncomment the lines to look like this:
// commenting out for the demo. uncomment during demo of the client
if resp.GetDeathEater() {
alertDeathEather(resp)
}
}
}
// commenting out for the demo. uncomment during demo of the client
func alertDeathEather(w *pb.Wizard) {
log.Println("")
log.Printf("Oh no! %s is a Death Eater!", w.GetName())
log.Println("")
}
Save the file.
Restart the client by pressing ctrl+c
and running go run cmd/client/main.go
2021/06/15 15:27:30 checking for configMap file at: ./wizards-server-configMap.txt
2021/06/15 15:27:30 found ./wizards-server-configMap.txt file. setting environment variables
2021/06/15 15:27:30 done setting environemnt variables
2021/06/15 15:27:31 # -------------------------------------- #
2021/06/15 15:27:31 requesting list of wizards from the server
2021/06/15 15:27:31 # -------------------------------------- #
2021/06/15 15:27:31 wizard received: Harry Potter
2021/06/15 15:27:31 wizard received: Ron Weasley
2021/06/15 15:27:31 wizard received: Hermione Granger
2021/06/15 15:27:31 wizard received: Cho Chang
2021/06/15 15:27:31 wizard received: Luna Lovegood
2021/06/15 15:27:31 wizard received: Sybill Trelawney
2021/06/15 15:27:31 wizard received: Pomona Sprout
2021/06/15 15:27:31 wizard received: Cedric Diggory
2021/06/15 15:27:31 wizard received: Newton Scamander
2021/06/15 15:27:31 wizard received: Draco Malfoy
2021/06/15 15:27:31
2021/06/15 15:27:31 Oh no! Draco Malfoy is a Death Eater!
2021/06/15 15:27:31
2021/06/15 15:27:31 wizard received: Bellatrix Lestrange
2021/06/15 15:27:31
2021/06/15 15:27:31 Oh no! Bellatrix Lestrange is a Death Eater!
2021/06/15 15:27:31
2021/06/15 15:27:31 wizard received: Severus Snape
2021/06/15 15:27:31 # --------------------------------------#
2021/06/15 15:27:31 received list of wizards from the server
2021/06/15 15:27:31 # ------------------------------------- #
Now the client starts up, requests a list of wizards from the server, and if it finds that a wizard is a Death Eater, there is a warning printed in the logs.
Good. Our users will be happy with this change.
This concludes the demo.
We should be good stewards and clean up.
First, disconnect Telepresence from the cluster.
telepresence quit
Telepresence Daemon quitting...done
telepresence status
Root Daemon: Not running
User Daemon: Not running
Telepresence is now no longer connected the workstation to the cluster.
The cluster resources can now be cleaned up.
kind delete cluster
Deleting cluster "kind" ...
This concludes the demo.