网上关于grpc在k8s上的负载均衡不少,我这里就不在重复了,直接看代码吧: 个人grpc客户端和服务段都是用beego实现的,【我这里比较偷懒,直接把源码放到 k8s的一个master上】,首先须要说明如下个人k8s版本html
协议在protos\hello.proto以下:node
syntax = "proto3"; option go_package = "./;proto"; package protos; service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) ; } message HelloRequest { string name = 1; } message HelloReply { string message = 1; }
而后到路径下 执行 protoc --go_out=plugins=grpc:./ ./hello.protolinux
服务端我为了省事直接在main.go文件添加方法:nginx
package main import ( "context" "fmt" pb "grpcdemo/protos" _ "grpcdemo/routers" "net" "github.com/astaxie/beego" "google.golang.org/grpc" "google.golang.org/grpc/reflection" ) func main() { go GPRCServer() beego.Run() } type server struct{} func NewServer() *server { return &server{} } func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) { msg := "Resuest By:" + in.Name + " Response By :" + LocalIp() fmt.Println("GRPC Send: ", msg) return &pb.HelloReply{Message: msg}, nil } func GPRCServer() { // 监听本地端口 listener, err := net.Listen("tcp", ":9090") if err != nil { return } s := grpc.NewServer() // 建立GRPC pb.RegisterGreeterServer(s, &server{}) // 在GRPC服务端注册服务 reflection.Register(s) fmt.Println("grpc serve 9090") err = s.Serve(listener) if err != nil { fmt.Println(fmt.Sprintf("failed to serve: %v", err)) } } func LocalIp() string { addrs, _ := net.InterfaceAddrs() var ip string = "localhost" for _, address := range addrs { if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { if ipnet.IP.To4() != nil { ip = ipnet.IP.String() } } } return ip }
服务的其余几个文件以下:Dockerfilegit
FROM golang:1.15.6 RUN mkdir -p /app RUN mkdir -p /app/conf RUN mkdir -p /app/logs WORKDIR /app ADD main /app/main EXPOSE 8080 EXPOSE 9090 CMD ["./main"]
build.shgithub
#!/bin/bash #cd $WORKSPACE export GOPROXY=https://goproxy.io #根据 go.mod 文件来处理依赖关系。 go mod tidy # linux环境编译 CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main # 构建docker镜像,项目中须要在当前目录下有dockerfile,不然构建失败 docker build -t grpcserver . docker tag grpcserver 192.168.100.30:8080/go/grpcserver:2021 docker login -u admin -p '123456' 192.168.100.30:8080 docker push 192.168.100.30:8080/go/grpcserver docker rmi grpcserver docker rmi 192.168.100.30:8080/go/grpcserver:2021
deploy.yamlgolang
apiVersion: apps/v1 kind: Deployment metadata: name: grpcserver namespace: go labels: name: grpcserver spec: replicas: 3 minReadySeconds: 10 selector: matchLabels: name: grpcserver template: metadata: labels: name: grpcserver spec: imagePullSecrets: - name: regsecret containers: - name: grpcserver image: 192.168.100.30:8080/go/grpcserver:2021 ports: - containerPort: 8080 - containerPort: 9090 imagePullPolicy: Always --- apiVersion: v1 kind: Service metadata: name: grpcserver namespace: go spec: ports: - port: 8080 targetPort: 8080 name: httpserver protocol: TCP - port: 9090 targetPort: 9090 name: grpcserver protocol: TCP selector: name: grpcserver --- apiVersion: extensions/v1beta1 kind: Ingress metadata: namespace: go name: grpcserver annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/backend-protocol: "GRPC" spec: rules: - host: rpc.ingress.local http: paths: - backend: serviceName: grpcserver servicePort: 9090 tls: - secretName: grpcs-secret hosts: - rpc.ingress.local
调用主要在controllers/default.godocker
其余相关文件:Dockerfilevim
FROM golang:1.15.6 RUN mkdir -p /app RUN mkdir -p /app/conf RUN mkdir -p /app/logs WORKDIR /app ADD main /app/main EXPOSE 8080 CMD ["./main"]
build.shapi
#!/bin/bash #cd $WORKSPACE export GOPROXY=https://goproxy.io #根据 go.mod 文件来处理依赖关系。 go mod tidy # linux环境编译 CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o main # 构建docker镜像,项目中须要在当前目录下有dockerfile,不然构建失败 docker build -t grpcclient . docker tag grpcclient 192.168.100.30:8080/go/grpcclient:2021 docker login -u admin -p '123456' 192.168.100.30:8080 docker push 192.168.100.30:8080/go/grpcclient docker rmi grpcclient docker rmi 192.168.100.30:8080/go/grpcclient:2021
deploy.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: grpcclient namespace: go labels: name: grpcclient spec: replicas: 3 minReadySeconds: 10 selector: matchLabels: name: grpcclient template: metadata: labels: name: grpcclient spec: imagePullSecrets: - name: regsecret containers: - name: grpcserver image: 192.168.100.30:8080/go/grpcclient:2021 ports: - containerPort: 8080 - containerPort: 9090 imagePullPolicy: Always --- apiVersion: v1 kind: Service metadata: name: grpcclient namespace: go spec: type: ClusterIP ports: - port: 8080 targetPort: 8080 protocol: TCP selector: name: grpcclient
准备阶段:
#安装grpcurl wget https://github.com/fullstorydev/grpcurl/releases/download/v1.8.0/grpcurl_1.8.0_linux_x86_64.tar.gz tar -xvf grpcurl_1.8.0_linux_x86_64.tar.gz chmod +x grpcurl #我本地是有共的环境 mv grpcurl /usr/local/go/bin #证书 openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout grpcs.key -out grpcs.crt -subj "/CN=*.ingress.local/O=ingress.local" ls grpcs.crt grpcs.key kubectl create secret tls grpcs-secret --key grpcs.key --cert grpcs.crt #kubectl delete secret grpcs-secret
部署都是进入目录 执行build.sh 而后 kubectl apply -f deploy.yaml
如今咱们修改程序 让grpc client用长链接 在controller下面新建init.go文件
package controllers import ( "fmt" pb "grpcclient/protos" "github.com/astaxie/beego/logs" "google.golang.org/grpc" ) var GrpcClient pb.GreeterClient func init() { conn, err := grpc.Dial("grpcserver:9090", grpc.WithInsecure()) if err != nil { msg := fmt.Sprintf("grpc client did not connect: %v\r\n", err) logs.Error(msg) } GrpcClient = pb.NewGreeterClient(conn) }
default.go 以下:
package controllers import ( "context" "fmt" pb "grpcclient/protos" "net" "github.com/astaxie/beego" ) type MainController struct { beego.Controller } func (c *MainController) Get() { client := GrpcClient req := pb.HelloRequest{Name: "gavin_" + LocalIp()} res, err := client.SayHello(context.Background(), &req) if err != nil { msg := fmt.Sprintf("grpc client client.SayHello has err:%v\r\n", err) c.Ctx.WriteString(msg) return } c.Ctx.WriteString("GRPC Clinet Received:" + res.Message) } func LocalIp() string { addrs, _ := net.InterfaceAddrs() var ip string = "localhost" for _, address := range addrs { if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() { if ipnet.IP.To4() != nil { ip = ipnet.IP.String() } } } return ip }
运行结果:
3 clusterIP=None有值的结果以下:
用 kubectl get ingress -n go 查看信息 而后 修改 vim /etc/hosts
kubectl get ingress -n go grpcurl -insecure rpc.ingress.local:443 list grpcurl -insecure -d '{"name": "gRPC"}' rpc.ingress.local:443 protos.Greeter.SayHello
个人grpc客服端没有跑通【go在新版本的tsl有些区别,能够参考 go学习笔记 Windows Go 1.15 以上版本的 GRPC 通讯【自签CA和双向认证】 】,用其余域名也出现过其余错误【不知道是否是ingress的问题】
安装:
#https://istio.io/latest/docs/setup/getting-started/ curl -L https://istio.io/downloadIstio | sh - #curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.9.2 TARGET_ARCH=x86_64 sh - cd istio-1.9.2 istioctl install --set profile=demo -y 为指定namespace注入istio的sidecar功能 # kubectl label namespace default istio-injection=enable 禁止注入istio的sidecar功能 # kubectl label namespace default istio-injection- 查看istio的sidecar的信息 kubectl get namespace -L istio-injection #kubectl apply -f samples/addons #kubectl get svc -n istio-system
科普一下:
Istio 提供一种简单的方式来为已部署的服务创建网络,该网络具备负载均衡、服务间认证、监控等功能,只须要对服务的代码进行一点或不须要作任何改动。想要让服务支持 Istio,只须要在您的环境中部署一个特殊的 sidecar 代理,使用 Istio 控制平面功能配置和管理代理,拦截微服务之间的全部网络通讯:
Istio 旨在实现可扩展性,知足各类部署需求
stio简单的几个概念
在Service Mesh中,咱们须要了解Data Plane和Control Plane两个概念:
Istio核心组件
Istio可视化管理组件
参考:
http://www.kailing.pub/article/index/arcid/327.html
https://blog.csdn.net/weixin_38166686/article/details/102452691
https://blog.csdn.net/weixin_33782386/article/details/89729502