gRPC 2 kubernetes

这里因为 为了更好的看出 被访问的目标pod,我对server端代码进行了一些修改,所以干脆就把所有代码再贴一遍

先看目录结构

/home/lizhe/works/grpc_helloworld_golang/pbfiles/Hi.proto

syntax="proto3";  //
package services;
option go_package = "../services";
message HiRequest {
  string say = 1;
}
message HiResponse {
  string responed = 1;
}
service HiService {
    rpc GetHiResponed(HiRequest) returns (HiResponse);
}

生成 proto 代码

cd pbfiles

protoc –go_out=plugins=grpc:. Hi.proto

这里改动比较大,主要是为了输出 pod 的 ip 地址

/home/lizhe/works/grpc_helloworld_golang/services/HiService.go

package services

import (
    "context"
    "errors"
    "fmt"
    "net"
)

type HiService struct {
}

func externalIP() (net.IP, error) {
    ifaces, err := net.Interfaces()
    if err != nil {
        return nil, err
    }
    for _, iface := range ifaces {
        if iface.Flags&net.FlagUp == 0 {
            continue // interface down
        }
        if iface.Flags&net.FlagLoopback != 0 {
            continue // loopback interface
        }
        addrs, err := iface.Addrs()
        if err != nil {
            return nil, err
        }
        for _, addr := range addrs {
            ip := getIpFromAddr(addr)
            if ip == nil {
                continue
            }
            return ip, nil
        }
    }
    return nil, errors.New("connected to the network?")
}

func getIpFromAddr(addr net.Addr) net.IP {
    var ip net.IP
    switch v := addr.(type) {
    case *net.IPNet:
        ip = v.IP
    case *net.IPAddr:
        ip = v.IP
    }
    if ip == nil || ip.IsLoopback() {
        return nil
    }
    ip = ip.To4()
    if ip == nil {
        return nil // not an ipv4 address
    }

    return ip
}

func (hs HiService) GetHiResponed(ctx context.Context, request *HiRequest) (*HiResponse, error) {
    fmt.Println("Say:" + request.Say)
    ip, _ := externalIP()

    return &HiResponse{Responed: " helloworld " + ip.To4().String()}, nil
}

/home/lizhe/works/grpc_helloworld_golang/client.go 

package main

import (
    "context"
    "fmt"
    "helloworld/services"
    "log"
    "os"

    "google.golang.org/grpc"
)

func main() {
    args := os.Args
    url := args[1]
    conn, err := grpc.Dial(url+":30010", grpc.WithInsecure())
    if err != nil {
        log.Println(err)
    }
    defer conn.Close()
    client := services.NewHiServiceClient(conn)
    resp, err := client.GetHiResponed(context.Background(), &services.HiRequest{Say: "Hello"})
    if err != nil {
        log.Println(err)
    }
    fmt.Println(resp.Responed)

}

/home/lizhe/works/grpc_helloworld_golang/server.go

package main

import (
    "helloworld/services"
    "net"

    "google.golang.org/grpc"
)

func main() {
    rpcServer := grpc.NewServer()                                        // 创建grpc服务
    services.RegisterHiServiceServer(rpcServer, new(services.HiService)) // 注册,new方法中的是services包中定义的结构体HiService
    lis, _ := net.Listen("tcp", ":30010")                                // 开启一个监听端口
    rpcServer.Serve(lis)                                                 // 启动服务
}
 

/home/lizhe/works/grpc_helloworld_golang/go.mod

module helloworld

require (
    google.golang.org/grpc v1.29.1
    google.golang.org/protobuf v1.25.0
)

go 1.13
 

/home/lizhe/works/grpc_helloworld_golang/Dockerfile

FROM golang as golang   

RUN mkdir -p /root/grpc
COPY ./ /root/grpc

WORKDIR /root/grpc/output
RUN go build /root/grpc/server.go
RUN go build /root/grpc/client.go

FROM ubuntu as ubuntu

RUN mkdir -p /root/grpc
COPY --from=golang --chown=root:root /root/grpc /root/grpc
COPY --from=golang --chown=root:root /root/grpc/output /root/grpc

CMD /bin/bash
 

给 server 端和 client 端分别创建多个 pod 

这里实际是为了测试 grpc 在 k8s 上的负载均衡状态

/root/grpc

/bin/bash -c ./server

client使用 go run ./client.go 192.168.204.128 30010