I have implemented a gRPC client server in Go. I have now set them up in Kubernetes as client and server pods where the client connects to the server. I've set this cluster up using vagrant (centos/7) on my PC. My issue is that the client wants to hit the port 8090 (sever serves on this port) and send a message to the server, but as they are in different pods the client cannot hit localhost 8090 and therefore the pod fails. How do I solve this problem?
func main() {
conn, err := grpc.Dial(":8090", grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect :%v", err)
}
cli := proto.NewPingClient(conn)
as seen it tries to dial 8090, but not able to map it to the localhost of the server pod.
You cannot, you need to use a kubernetes Service object and then dns to get the IP of the proxy to the other pod. Pods share localhost within themselves, between containers of the same pod, but that’s it.
The most standard solution for this problem is to forget about connecting to localhost, then create ClusterIP service connected to the selected server pod in the same namespace:
apiVersion: v1
kind: Service
metadata:
name: server-service
labels:
app: your-label
spec:
type: ClusterIP
ports:
- port: 8090
targetPort: 8090
protocol: TCP
selector:
app: your-label
Remember to use the same metadata.labels.app
value in your pod description, otherwise the two will not be connected to each other.
If you have your cluster configured properly, and CoreDNS up and running, you should be able to access the server using server-service:8090
if you are running your client and server pods in the same namespace.
localhost
can only be used to address the group of containers running in a single Pod.
Pod to Pod communications should go via a Service.
The following example service will forward traffic to any Pods labelled with app: grpc-app
apiVersion: v1
kind: Service
metadata:
name: grpc-service
spec:
selector:
app: grpc-app
ports:
- protocol: TCP
port: 8090
targetPort: 8090
You will then have a DNS hostname to access the service with.
grpc-service.<namespace>.svc.<cluster-domain>
which is usuallygrpc-service.default.svc.cluster.local
func main() {
conn, err := grpc.Dial("name-of-your-grpc-service:8090", grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect :%v", err)
}
cli := proto.NewPingClient(conn)