This is a reproduction of the official gRPC Server - Go example from knative. gRPC support was added to knative and to kong.
Start minikube cluster, install knative, connect to the cluster's docker:
minikube start --driver=virtualbox
../knative_install.sh
eval $(minikube -p minikube docker-env)
Build the image:
docker build -t dev.local/grpc-ping-go .
minikube ssh
docker run --rm -d -p 8080:8080 --name grpc-ping-go dev.local/grpc-ping-go
docker run --rm dev.local/grpc-ping-go /client -server_addr="172.17.0.1:8080" -insecure
2020/09/08 09:08:30 Ping got hello - pong # <-- It works
docker stop grpc-ping-go
Here 172.17.0.1 is the address of docker's host machine. Because client is run in another container, it need to connect to a host's port to comminicate with the server container. And this host's port in its turn is bound to a port inside of the server container. Port numbers are the same because we run the server with -p 8080:8080
and host address is the address of the docker0
interface (https://stackoverflow.com/questions/31324981/how-to-access-host-port-from-docker-container): ip addr show docker0
.
kubectl apply -f service_plain.yaml
export GREETER_PORT=$(kubectl get services/grpc-ping-go-service -o go-template='{{(index .spec.ports 0).nodePort}}')
docker run --rm dev.local/grpc-ping-go /client -server_addr=172.17.0.1:$GREETER_PORT -insecure
2020/09/08 09:39:55 Ping got hello - pong # <-- It works
kubectl delete -f service_plain.yaml
For some reason the latest
image is failed to pull:
Warning Failed 2m58s kubelet, minikube Failed to pull image "dev.local/grpc-ping-go": rpc error: code = Unknown desc = Error response from daemon: Get https://dev.local/v2/: dial tcp: lookup dev.local on 10.0.2.3:53: read udp 10.0.2.15:44690->10.0.2.3:53: i/o timeout
So we need to add a version tag:
docker tag dev.local/grpc-ping-go dev.local/grpc-ping-go:v0
Deploy the service and get proxy port (be sure that tag resolution is disabled for dev.local
):
kubectl apply -f service_knative.yaml
kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
grpc-ping ExternalName <none> grpc-ping.default.example.com <none> 69m
grpc-ping-xnbts ClusterIP 10.109.91.68 <none> 81/TCP 69m
grpc-ping-xnbts-private ClusterIP 10.96.4.148 <none> 80/TCP,9090/TCP,9091/TCP,8022/TCP 69m
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d23h
kubectl get service -n kong
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kong-proxy LoadBalancer 10.98.127.254 <pending> 80:32188/TCP,443:32637/TCP 4d23h
Test steps are described in gRPC PR for knative.
curl -H "Host: grpc-ping.default.example.com" http://$(minikube ip):32188
net/http: HTTP/1.x transport connection broken: malformed HTTP response "\x00\x00\x06\x04\x00\x00\x00\x00\x00\x00\x05\x00\x00@\x00"
kubectl get pod
NAME READY STATUS RESTARTS AGE
grpc-ping-xnbts-deployment-ddd8f5d4-xhb2n 2/2 Running 0 21s
kubectl logs grpc-ping-xnbts-deployment-ddd8f5d4-xhb2n user-container
Starting server at port 8080 # <-- Server is working
curl doesn't understand grpc answer, but we can see that grpc service was started in a pod.
Make sure you have grpcurl installed. Try to call the service:
grpcurl -plaintext -proto ./proto/ping.proto \
-authority grpc-ping.default.example.com \
-H "Host: grpc-ping.default.example.com" \
-format json \
-d '{"msg": "TEST"}' \
$(minikube ip):32188 ping.PingService/Ping
Failed to dial target host "192.168.99.107:32188": context deadline exceeded
Doesn't work. Seems kong refuses to proxy grpc requests at all. No pods are run. Deployment is not kicked - kubectl describe deployment
shows events "Scaled up replica ... to 1" then "Scaled down replica ... to 0", and these events relate to the previous curl run.
Probably some additional kong configuration is required.
Extract the client app from the container and use is on minikube vm:
minikube ssh
docker inspect dev.local/grpc-ping-go:v0
... # Search for something like:
"UpperDir": "/var/lib/docker/overlay2/aa810f01497fc601617cde8aa0d8ec89a4aebfe12440a41b421e6a395c534510/diff",
...
sudo ls /var/lib/docker/overlay2/aa810f01497fc601617cde8aa0d8ec89a4aebfe12440a41b421e6a395c534510/diff
client # <-- Here you are!
# Extract to some common place
sudo cp /var/lib/docker/overlay2/
aa810f01497fc601617cde8aa0d8ec89a4aebfe12440a41b421e6a395c534510/diff/client /tmp
# run outside of container
/tmp/client -server_addr=$PROXY_ADDR -insecure -server_host_override=grpc-ping.default.example.com
/tmp/client -server_addr=$PROXY_ADDR -insecure -server_host_override=grpc-ping.default.svc.cluster.local
Doesn't work. Tried different address-port combinations that can be obtained from kubectl describe service kong-proxy -n kong
. Most of them get "Connection refused". Seems one of them got "context deadline exceeded" so it was the correct combination. Don't remembed what of them it was, repeat the experiment.