2021年2月14日日曜日

Drone CIでRedisクラスターを使う

ちょっと前から話題になっている(らしい)オープンソースのCIツールDroneを仕事で使っています。

Goで(単なるRedisサーバーではなく)Redisクラスターを使ったコードをテストするために試行錯誤した奮闘記です。絶対もっとスマートな方法があるはずなので、いい方法を知っていたらご一報を。

前提

Goのコードは例えばこんな感じです。

package main

import (
	"context"
	"github.com/go-redis/redis/v8"
	"log"
)

func main() {
	ctx := context.Background()
	rdb := redis.NewClusterClient(&redis.ClusterOptions{
		Addrs: []string{"localhost:6379"},
	})

	rdb.Set(ctx, "key", "value", 0)
	result := rdb.Get(ctx, "key")
	log.Println(result.String())
}

接続先をハードコードしてるわエラー処理とかしてないわそもそもテストコードがないわと突っ込みたいかもしれませんが我慢してください。本当はちゃんとテストコードあります。

ダメだった方法

こんな感じの.drone.ymlを作ってCIを走らせてみました。

kind: pipeline
type: docker
name: Test
trigger:
  event:
  - push
steps:
- name: Redis cluster
  image: redis:6-alpine
  commands:
  - sleep 5
  - redis-cli -h redis-node -p 6379 CLUSTER ADDSLOTS $(seq 0 16383)
- name: test
  image: golang:1.14-alpine
  commands:
  - apk add git alpine-sdk
  - go build
  - go test ./...
  - go vet
services:
- name: redis-node
  image: redis:6-alpine
  commands:
  - redis-server --bind 0.0.0.0 --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000

Droneのサービスコンテナを使ってRedisをクラスターモードで起動し、テストの前にredis-cliでクラスターを構成しています。スロットに関しては先日の記事で間抜けなミスをしていました。本当はこの形にするまでに聞くも涙語るも涙の苦労の連続だったんですが、それはまたの機会に。

これを実行すると、こんなエラーが出てしまいました。

Set() error: dial tcp :6379: connect: connection refused

えっ。

うーん、何があかんのだ・・・?

うまくいった方法

紆余曲折は省いて、とりあえずうまくいった方法を晒します。

kind: pipeline
type: docker
name: Test
trigger:
  event:
  - push
steps:
- name: test
  image: golang:1.14-alpine
  commands:
  - apk add git alpine-sdk redis
  - redis-server --daemonize yes --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000
  - redis-cli CLUSTER ADDSLOTS $(seq 0 16383)
  - go build
  - go test ./...
  - go vet

何のことはない、単にテストと同じステップで事前にRedisを起動しておくだけです。

あまり美しくないけど、ぶっちゃけこのほうがコンテナの数も少ないし速いんじゃないですかね。

でも、なんでこれが通るのに最初のやつが通らないのかはよくわかっていません。Droneの仕様をちゃんと調べないとダメですね。誰か知っている人教えてください。

え?バレンタインなんてなかったよ?


0 件のコメント:

コメントを投稿