hisamounaのブログ

アウトプットを習慣化するためのブログ

gRPC-GatewayのtutorialsをDockerでやってみる

はじめに

gRPC-Gatewaytutorialsをコンテナで動かして疎通できるようにしたいと考えています。

作業リポジトリ: grpc-gateway-tutorial

tutorialsをもとにserverとgatewayでエントリーポイントを分離

serverのmain.go

func main() {
    lis, err := net.Listen("tcp", ":8080")
    if err != nil {
        log.Fatal("Failed to listen", err)
    }

    s := grpc.NewServer()
    helloworldpb.RegisterGreeterServer(s, &server{})
    log.Println("Serving gRPC on 0.0.0.0:8080")
    log.Fatal(s.Serve(lis))
}

gatewayのmain.go

func main() {
    conn, err := grpc.DialContext(
        context.Background(),
        "0.0.0.0:8080",
        grpc.WithBlock(),
        grpc.WithInsecure(),
    )
    if err != nil {
        log.Fatalln("Failed to dial server: ", err)
    }

    gwmux := runtime.NewServeMux()
    // Register Greeter
    err = helloworldpb.RegisterGreeterHandler(context.Background(), gwmux, conn)
    if err != nil {
        log.Fatalln("Failed to register gateway:", err)
    }

    gwServer := &http.Server{
        Addr:    ":8090",
        Handler: gwmux,
    }

    log.Println("Serving gRPC-Gateway on http://0.0.0.0:8090")
    log.Fatalln(gwServer.ListenAndServe())
}

ホスト上でそれぞれgo runして、疎通確認OK

└─> go run cmd/server/main.go
2021/08/02 23:30:10 Serving gRPC on 0.0.0.0:8080

└─> go run cmd/gateway/main.go
2021/08/02 23:30:17 Serving gRPC-Gateway on http://0.0.0.0:8090

└─> curl -X POST -k http://localhost:8090/v1/example/echo -d '{"name": " hello"}'
{"message":" hello world"}%

コンテナ化したところcurlが通らなくなった

└─> docker compose up -d --build
[+] Running 2/2
 ⠿ Container gateway  Started                                                                                                                           5.2s
 ⠿ Container server   Started

└─> docker ps
CONTAINER ID   IMAGE                           COMMAND      CREATED          STATUS         PORTS                    NAMES
d5def9f4fcc6   grpc-gateway-tutorial_gateway   "/gateway"   14 seconds ago   Up 9 seconds   0.0.0.0:8090->8090/tcp   gateway
54ad371b15f7   grpc-gateway-tutorial_server    "/server"    14 seconds ago   Up 7 seconds   0.0.0.0:8080->8080/tcp   server

└─> curl -X POST -k http://localhost:8090/v1/example/echo -d '{"name": " hello"}'
curl: (52) Empty reply from server

gatewayコンテナの/etc/hostsを確認

distrolessのdebug方法はこれから勉強します、、、

└─> docker cp gateway:/etc/hosts gateway_hosts

└─> cat gateway_hosts
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.20.0.2  d5def9f4fcc6

serverコンテナ(d5def9f4fcc6)のIPアドレスは172.20.0.2

0.0.0.0だと127.0.0.1に対して通信しに行くので、serverコンテナへはリクエストがいかない。

参考 0.0.0.0にはアクセスしないこと

0.0.0.0をserverに修正

  conn, err := grpc.DialContext(
        context.Background(),
        "server:8080",
        grpc.WithBlock(),
        grpc.WithInsecure(),
    )

期待通り gateway -> serverの通信が通るように

└─> docker compose up -d --force-recreate --build

└─> curl -X POST -k http://localhost:8090/v1/example/echo -d '{"name": " hello"}'
{"message":" hello world"}

kindでArgo Rolloutを試す

kindでクラスタ構築

└─> kind version
kind v0.6.1 go1.13.4 darwin/amd64

└─> kind create cluster --name kinda --image kindest/node:v1.18.15 --kubeconfig $HOME/.kube/kind_config
Creating cluster "kinda" ...
.
.
.
Thanks for using kind! 😊

毎回--kubeconfig指定するのが面倒なので、aliasをセット

└─> alias kindctl='kubectl --kubeconfig=$HOME/.kube/kind_config'

└─> kindctl get nodes
NAME                  STATUS   ROLES    AGE     VERSION
kinda-control-plane   Ready    master   8m17s   v1.18.15

Argo Rolloutsのデプロイ

Argo Rolloutsインストール

└─> kindctl create namespace argo-rollouts
namespace/argo-rollouts created

└─> kindctl apply -n argo-rollouts -f https://github.com/argoproj/argo-rollouts/releases/latest/download/install.yaml

Rollout デプロイ

└─> cat rollout.yaml
apiVersion: argoproj.io/v1alpha1
kind: Rollout
metadata:
  name: rollout-canary
spec:
  replicas: 1
  selector:
    matchLabels:
      app: rollout-canary
  template:
    metadata:
      labels:
        app: rollout-canary
    spec:
      containers:
      - name: nginx
        image: nginx:1.20
        ports:
        - containerPort: 80
  strategy:
    canary:
      steps:
      - setWeight: 20
      - pause: {duration: 5s}
      - setWeight: 40
      - pause: {duration: 5s}
      - setWeight: 60
      - pause: {duration: 5s}
      - setWeight: 80
      - pause: {duration: 10s}

└─> kindctl apply -f rollout.yaml

└─> kindctl get rollout
NAME             DESIRED   CURRENT   UP-TO-DATE   AVAILABLE
rollout-canary   1         1         1            1

アップデート

└─> kubectl argo rollouts --kubeconfig=$HOME/.kube/kind_config set image rollout-canary nginx=nginx:1.21

└─> kubectl argo rollouts get rollout --kubeconfig=$HOME/.kube/kind_config rollout-canary -w
Name:            rollout-canary
Namespace:       default
Status:          ॥ Paused
Message:         CanaryPauseStep
Strategy:        Canary
  Step:          1/8
  SetWeight:     20
  ActualWeight:  50
Images:          nginx:1.20 (stable)
                 nginx:1.21 (canary)
Replicas:
  Desired:       1
  Current:       2
  Updated:       1
  Ready:         2
  Available:     2

NAME                                        KIND        STATUS     AGE    INFO
⟳ rollout-canary                            Rollout     ॥ Paused   3m8s
├──# revision:4
│  └──⧉ rollout-canary-7698477559           ReplicaSet  ✔ Healthy  2m56s  canary
│     └──□ rollout-canary-7698477559-j8wn5  Pod         ✔ Running  3s     ready:1/1
└──# revision:3
   └──⧉ rollout-canary-6dbf69d976           ReplicaSet  ✔ Healthy  3m8s   stable
      └──□ rollout-canary-6dbf69d976-6fk5m  Pod         ✔ Running  2m8s   ready:1/1
.
.
.
Name:            rollout-canary
Namespace:       default
Status:          ✔ Healthy
Strategy:        Canary
  Step:          8/8
  SetWeight:     100
  ActualWeight:  100
Images:          nginx:1.21 (stable)
Replicas:
  Desired:       1
  Current:       1
  Updated:       1
  Ready:         1
  Available:     1

NAME                                        KIND        STATUS        AGE    INFO
⟳ rollout-canary                            Rollout     ✔ Healthy     3m50s
├──# revision:4
│  └──⧉ rollout-canary-7698477559           ReplicaSet  ✔ Healthy     3m38s  stable
│     └──□ rollout-canary-7698477559-j8wn5  Pod         ✔ Running     45s    ready:1/1
└──# revision:3
   └──⧉ rollout-canary-6dbf69d976           ReplicaSet  • ScaledDown  3m50s

クリーンアップ

└─> kindctl delete -f rollout.yaml
rollout.argoproj.io "rollout-canary" deleted

└─> kind delete cluster --name kinda
Deleting cluster "kinda" ...