我正试图从K8s控制器访问我的ETCD数据库,但在try 打开ETCD客户端时出现rpc错误/EOF.

我的设置:

  • ETCD服务部署在我的K8s集群中,并包含在我的Istio服务网格中(其DNS记录:my-etcd-cluster.my-etcd-namespace.svc.cluster.local)
  • 我有一个使用Kubebuilder框架开发的定制K8s控制器,部署在同一集群、不同名称空间中,但配置为同一Istio服务网格的一部分
  • 我正在try 使用Go client SDK library for ETCD从控制器连接到ETCD数据库

以下是我受影响的Go代码:

cli, err := clientv3.New(clientv3.Config{
    Endpoints:   []string{"http://my-etcd-cluster.my-etcd-namespace.svc.cluster.local:2379"},
    DialTimeout: 5 * time.Second,
    Username:    username,
    Password:    password,
})

if err != nil {
    return nil, fmt.Errorf("opening ETCD client failed: %v", err)
}

当执行clientv3.New(...)时,我得到了一个错误:

{"level":"warn","ts":"2022-03-16T23:37:42.174Z","logger":"etcd-client","caller":"v3@v3.5.0/retry_interceptor.go:62","msg":"retrying of unary invoker failed",
"target":"etcd-endpoints://0xc00057f500/#initially=[http://my-etcd-cluster.my-etcd-namespace.svc.cluster.local:2379]","attempt":0,
"error":"rpc error: code = Unavailable desc = error reading from server: EOF"}
...
1.647473862175209e+09   INFO    controller.etcdclient   Finish reconcile loop for some-service/test-svc-client  {"reconciler group": "my-controller.something.io", "reconciler kind": "ETCDClient", "name": "test-svc-client", "namespace": "some-service", "reconcile-etcd-client": "some-service/test-svc-client"}
1.6474738621752858e+09  ERROR   controller.etcdclient   Reconciler error        {"reconciler group": "my-controller.something.io", "reconciler kind": "ETCDClient", "name": "test-svc-client", "namespace": "some-service", "error": "opening ETCD client failed: rpc error: code = Unavailable desc = error reading from server: EOF"}
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem
        /go/pkg/mod/sigs.k8s.io/controller-runtime@v0.11.0/pkg/internal/controller/controller.go:266
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2.2
        /go/pkg/mod/sigs.k8s.io/controller-runtime@v0.11.0/pkg/internal/controller/controller.go:227

当我传递一些虚假的、无效的凭据时,也会发生同样的错误.

然而,当我试图以HTTP API方式访问数据库时:

postBody, _ := json.Marshal(map[string]string{
    "name":     username,
    "password": password,
})
responseBody := bytes.NewBuffer(postBody)

resp, err := http.Post("http://my-etcd-cluster.my-etcd-namespace.svc.cluster.local:2379/v3/auth/authenticate", "application/json", responseBody)
if err != nil {
    return ctrl.Result{}, fmt.Errorf("an error occured %w", err)
}
l.Info(fmt.Sprintf("code: %d", resp.StatusCode))
defer resp.Body.Close()

...我得到了200个OK和一个合适的令牌(这是预期的),所以我相信我的Istio配置是OK的,我的控制器应该能够看到ETCD db服务.我不知道为什么在遵循客户端SDK方法时这不起作用.

当我使用ETCD服务的端口转发并在本地访问它时,clientv3.New()和其他客户端SDK方法工作得很好.我错过了什么?如果有任何建议,我将不胜感激.

编辑:

apiVersion: v1
kind: Pod
metadata:
  name: test-pod
  namespace: my-controller-namespace
spec:
  containers:
  - name: etcdctl
    image: bitnami/etcd
    command:
    - sleep
    - infinity

通过kubectl exec登录到容器时,我可以访问我的数据库:

$ etcdctl --endpoints=my-etcd-cluster.my-etcd-namespace.svc.cluster.local:2379 --user="user" --password="password" put foo bob
OK

我猜问题出在SDK的某个地方?

推荐答案

结果是版本不匹配——我的ETCD数据库是v3.我使用的clientv3库是v3.5.0.

enter image description here

Go相关问答推荐

如何获得与cksum相同的CRC 32?

为什么我不能使用Docker从本地访问我的Gin应用程序?

Docker Compose Health Check未退出,错误为无法启动

在nixos上找不到XInput2.h头文件的包

Golang Gorm Fiber / argon2.Config 未定义

在运行时更改 Go lang slog 的日志(log)级别

这是go语言gin提供的关于TypeEngine和RouterGroup的问题

Golang Gorm Fiber - 如何将定义为别名的名称发送到索引模板?

Golang telegram 机器人

将值发送到 Channel 并在就绪时读取输出

整理时转换值

使用 golang 生成 vim

如何模仿联合类型

仅在工作日运行 cron

如何在 helm 中将字符串连接到 .AsConfig 的结果?

在 Go 中发送 ack 和 term 后消息仍在 nats 限制队列中

httprouterhttp.HandlerFunc() 是如何工作的?

实现接口的指针的泛型类型是什么?

如何在测试中传递用户名和密码等参数

Golang 将类型 [N]byte 转换为 []byte