網上關於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