- Device|Discovery Services
- Golang
- Docker
- Kubernetes
- Helm
- gRPC Broker|Client
- Protoc
- Container Build
- Golang
- Healthcheck
The former devices
service has been split into two:
device
discovery
This overcomes an unanticipated problem with devices
in that its discovery endpoint was bound to a single host address at runtime.
The new services can be run:
go run ./cmd/device \
--path="/sensor1" \
--path="/sensor2" \
...
And:
go run ./cmd/discovery \
--device="device:8000" \
--device="device:8001" \
...
Which is more useful when running under Docker:
USER="..."
TAG=$(git rev-parse HEAD)
# Create devices on ports 8000:8009
DISCOVERY=()
for PORT in {8000..8009}
do
# Create the device on ${PORT}
# For Docker only: name each device: device-${PORT}
docker run \
--rm --detach=true \
--name=device-${PORT} \
--publish=${PORT}:8080 \
ghcr.io/${USER}/akri-http-device:${TAG} \
--path="/sensor1" \
--path="/sensor2" \
# Add the device to the discovery document
DISCOVERY+=("--device=http://localhost:${PORT} ")
done
# Create a discovery server for these devices
docker run \
--rm --detach=true \
--name=discovery \
--publish=9999:9999 \
ghcr.io/${USER}/akri-http-discovery:${TAG} ${DISCOVERY[@]}
Test:
curl http://localhost:9999/
http://localhost:8000
http://localhost:8001
http://localhost:8002
http://localhost:8003
http://localhost:8004
http://localhost:8005
http://localhost:8006
http://localhost:8007
http://localhost:8008
http://localhost:8009
curl http://localhost:8006/sensor
To stop:
USER="..."
TAG=$(git rev-parse HEAD)
# Delete devices on ports 8000:8009
for PORT in {8000..8009}
do
docker stop device-${PORT}
done
# Delete discovery server
docker stop discovery
And most useful on Kubernetes because one (!) or more devices can be created and then discovery can be created with correct DNS names.
Ensure the image
references are updated in ./kubernetes/v2/device.yaml
and ./kubernetes/v2/discovery.yaml
Then:
# Create one device deployment
kubectl apply --filename=./device.yaml
# But multiple Services against the single Pod
for NUM in {1..9}
do
# Services are uniquely named
# The service uses the Pods port: 8080
kubectl expose deployment/device \
--name=device-${NUM} \
--port=8080 \
--target-port=8080
done
service/device-1 exposed
service/device-2 exposed
service/device-3 exposed
service/device-4 exposed
service/device-5 exposed
service/device-6 exposed
service/device-7 exposed
service/device-8 exposed
service/device-9 exposed
# Create one discovery deployment
kubectl apply --filename=./discovery.yaml
# Expose Discovery as a service on its default port: 9999
# The Discovery service spec is statically configured for devices 1-9
kubectl expose deployment/discovery \
--name=discovery \
--port=9999 \
--target-port=9999
kubectl run curl --image=radial/busyboxplus:curl --stdin --tty --rm
curl http://discovery:9999
http://device-1:8080
http://device-2:8080
http://device-3:8080
http://device-4:8080
http://device-5:8080
http://device-6:8080
http://device-7:8080
http://device-8:8080
http://device-9:8080
Delete:
kubectl delete deployment/discovery
kubectl delete deployment/device
kubectl delete service/discovery
for NUM in {1..9}
do
kubectl delete service/device-${NUM}
done
```bash
VERS="3.5.2"
alias helm3="docker run \
--interactive --tty --rm \
--volume=${HOME}/.kube:/root/.kube \
--volume=${PWD}/.helm:/root/.helm \
--volume=${PWD}/.config/helm:/root/.config/helm \
--volume=${PWD}/.cache/helm:/root/.cache/helm \
--volume=${PWD}:/apps \
alpine/helm:${VERS}"
Then:
helm3 install akri-http ./helm \
--namespace=${NAMESPACE} \
--set=device.count=5 \
--set=device.name="device" \
--set=device.port=8080 \
--set=discovery.name="discovery" \
--set=discovery.port=9999
And:
kubectl run curl \
--stdin --tty --rm \
--image=curlimages/curl \
--namespace=${NAMESPACE} \
-- sh
/ $ curl http://discovery:9999
http://device-00:8080
http://device-01:8080
http://device-02:8080
http://device-03:8080
http://device-04:8080
/ $ curl http://device-03:8080
0.792962080942022/ $
And, when done:
helm uninstall akri-http \
--namespace=${NAMESPACE}
Requires protoc
in the path
MODULE="github.com/DazWilkin/akri-http"
protoc \
--proto_path=./protos \
--go_out=plugins=grpc,module=${MODULE}:. \
./protos/http.proto
USER="dazwilkin" # Or your GitHub username
REPO="akri-http" # Or your preferred GHCR repo
TAGS="$(git rev-parse HEAD)"
docker build \
--tag=ghcr.io/${USER}/${REPO}:${TAGS} \
--file=./deployment/Dockerfile \
.
Then run the gRPC Broker:
PORT=50051
go run ./cmd/broker --grpc_endpoint=:${PORT}
The run the gRPC Client
go run ./cmd/client --grpc_endpoint=:${PORT}
These are containerized too:
docker run \
--rm --interactive --tty \
--net=host \
--name=grpc-broker-golang \
--env=AKRI_HTTP_DEVICE_ENDPOINT=localhost:8005 \
ghcr.io/dazwilkin/akri-http-grpc-broker-golang:latest \
--grpc_endpoint=:50051
And:
docker run \
--rm --interactive --tty \
--net=host \
--name=grpc-client-golang \
ghcr.io/dazwilkin/akri-http-grpc-client-golang:latest \
--grpc_endpoint=:50051
The Broker implements gRPC Healthchecking:
Optional: Install grpc_health_probe
VERSION=v0.3.1 && \
wget \
--quiet \
--output-document=./grpc_health_probe \
https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${VERSION}/grpc_health_probe-linux-amd64 && \
chmod +x ./grpc_health_probe
Run a Device:
TAG="e137ed7816d9d39c4277e556b9cadec4b97ed98a"
PORT="8007"
docker run \
--interactive --tty --rm \
--name=device-8007 \
--publish=${PORT}:8080 \
ghcr.io/dazwilkin/akri-http-device:${TAG} \
--path="/sensor1" \
--path="/sensor2"
Then the Broker:
GRPC="50051"
AKRI_HTTP_DEVICE_ENDPOINT=http://localhost:${PORT} \
go run ./cmd/broker --grpc_endpoint=0.0.0.0:${GRPC}
2020/11/12 08:45:43 [main] Starting gRPC server
2020/11/12 08:45:43 [main] Starting gRPC Listener [:50051]
Then the Healthchecker:
./grpc_health_probe --addr=0.0.0.0:${GRPC}
status: SERVING