CockroachDB Kubernetes集群Ingress配置失败:域名带证书访问数据库求助
问题描述
需要通过db.test.com域名,携带SSL证书访问部署在Kubernetes中的CockroachDB,计划使用cert-manager结合Let's Encrypt签发证书,且Cloudflare需运行在非代理模式(因CF不支持该TCP代理)。
通过kubectl port-forward测试可正常访问,但配置ingress-nginx的Ingress资源后连接失败,日志出现400状态码及\x20特殊字符。不过CockroachDB的Web UI已成功配置并正常运行。
已尝试的Ingress配置
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: tcp-example-ingress namespace: default annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/tcp-services: "cluster-cockroachdb-public" nginx.ingress.kubernetes.io/tcp-service-port: "26257" nginx.ingress.kubernetes.io/backend-protocol: "TCP" nginx.ingress.kubernetes.io/rewrite-target: / spec: tls: - hosts: - db.test.com secretName: db-access-ssl-cert-production rules: - host: db.test.com http: paths: - path: / pathType: Prefix backend: service: name: cluster-cockroachdb-public port: number: 26257
正常运行的Web UI配置(values.yaml)
conf: cache: "2Gi" max-sql-memory: "2Gi" # My WEB-UI that works ingress: enabled: true labels: {} annotations: kubernetes.io/ingress.class: nginx cert-manager.io/cluster-issuer: letsencrypt-production paths: [/] hosts: - db-ui.test.com tls: - hosts: [db-ui.test.com] secretName: ssl-cert-production
解决方案
你的核心问题是用HTTP Ingress资源配置TCP服务——nginx-ingress的Ingress资源默认仅处理HTTP/HTTPS流量,TCP/UDP服务需要通过单独的ConfigMap和控制器配置来实现,而非在Ingress中添加TCP相关注解。
步骤1:配置TCP服务映射的ConfigMap
创建或修改nginx-ingress命名空间下的tcp-services ConfigMap,将外部端口26257映射到CockroachDB服务:
apiVersion: v1 kind: ConfigMap metadata: name: tcp-services namespace: nginx-ingress # 替换为你的nginx-ingress实际部署命名空间 data: 26257: "default/cluster-cockroachdb-public:26257" # 格式:外部端口:目标命名空间/服务名:服务端口
步骤2:更新nginx-ingress控制器的DaemonSet
修改nginx-ingress控制器的DaemonSet(或Deployment),添加端口映射并挂载上述ConfigMap:
- 在
spec.template.spec.containers[0].ports中添加TCP端口映射:
- name: cockroachdb-tcp containerPort: 26257 hostPort: 26257 # 若用LoadBalancer可省略,直接通过LB暴露端口
- 在
spec.template.spec.volumes中添加ConfigMap挂载:
- name: tcp-services configMap: name: tcp-services
- 在
spec.template.spec.containers[0].volumeMounts中添加挂载路径:
- name: tcp-services mountPath: /etc/nginx/tcp-services.d readOnly: true
步骤3:配置SSL终止(可选)
如果需要在nginx-ingress层处理TCP流量的SSL加密,需额外配置:
- 确保cert-manager已为
db.test.com签发证书,存储在db-access-ssl-cert-productionSecret中。 - 修改
tcp-servicesConfigMap,添加SSL证书路径:
data: 26257: "default/cluster-cockroachdb-public:26257::/etc/nginx/ssl/db-access-ssl-cert-production/tls.crt:/etc/nginx/ssl/db-access-ssl-cert-production/tls.key"
- 在nginx-ingress DaemonSet中挂载证书Secret:
- 在
volumes中添加:- name: db-access-ssl-cert secret: secretName: db-access-ssl-cert-production - 在
volumeMounts中添加:- name: db-access-ssl-cert mountPath: /etc/nginx/ssl/db-access-ssl-cert-production readOnly: true
- 在
步骤4:验证配置
- 应用配置并重启控制器:
kubectl apply -f tcp-services-configmap.yaml kubectl rollout restart daemonset nginx-ingress-controller -n nginx-ingress
- 测试CockroachDB连接:
cockroach sql --host=db.test.com --port=26257 --sslmode=verify-full --sslrootcert=/path/to/ca.crt
关键说明
- 普通Ingress资源仅适配HTTP/HTTPS场景,TCP服务必须通过nginx-ingress的专用ConfigMap配置,这是之前配置失败的根本原因。
- Cloudflare非代理模式下,需确保域名解析直接指向nginx-ingress的节点IP(或LoadBalancer IP),同时开放26257端口的防火墙规则。
- Web UI能正常运行是因为它属于HTTP服务,符合Ingress的原生使用场景。
内容的提问来源于stack exchange,提问作者Immutable
相关产品推荐
相关产品推荐

