首页 > 解决方案 > 使用 Ingress Nginx 控制器公开 Redis

问题描述

您好,当我使用节点端口公开我的 redis 服务时,它工作正常。我可以访问它。但是,如果我尝试切换到 Ingress Nginx 控制器,它会拒绝连接。其他应用程序可以在入口处正常工作。

这是我的服务:

apiVersion: v1
kind: Service
metadata:
  name: redis-svc
spec:
#  type: NodePort
  ports:
    - name: http
      port: 6379
      targetPort: 6379
      protocol: TCP
#      nodePort: 30007
  selector:
    app: redis

这是入口:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: redis-ing
  annotations:
     kubernetes.io/ingress.class: "nginx"
     ingress.kubernetes.io/ssl-redirect: "true"
     nginx.ingress.kubernetes.io/ssl-redirect: "true"
     nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
     cert-manager.io/cluster-issuer: "letsencrypt-prod"
    #  nginx.ingress.kubernetes.io/enable-cors: "true"
    #  nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS"
    #  nginx.ingress.kubernetes.io/cors-allow-origin: "https://test.hefest.io"
    #  nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
spec:
  tls:
  - secretName: letsencrypt-prod
    hosts:
      - redis-dev.domain.com
  rules:
  - host: redis-dev.domain.com
    http:
      paths:
      - path: /
        backend:
          serviceName: redis-svc
          servicePort: 6379

知道可能是什么问题吗?

我正在使用这个入口控制器:https ://github.com/nginxinc/kubernetes-ingress

标签: kubernetesredisnginx-ingress

解决方案


Redis 在非 HTTP 端口 (80,443) 的 6379 上工作。所以你需要在 nginx 入口控制器中启用TCP/UDP 支持。此处的 minikube 文档展示了如何为 redis 执行此操作。

更新 TCP 和/或 UDP 服务配置映射

借鉴关于使用 ingress nginx 控制器配置 TCP 和 UDP 服务的教程,我们需要编辑启用 minikube 入口插件时默认安装的 configmap。

有 2 个配置映射,1 个用于 TCP 服务,1 个用于 UDP 服务。默认情况下,它们看起来像这样:

apiVersion: v1
kind: ConfigMap
metadata:
  name: tcp-services
  namespace: ingress-nginx
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: udp-services
  namespace: ingress-nginx

由于这些 configmap 是集中式的并且可能包含配置,因此最好只修补它们而不是完全覆盖它们。

让我们以这个 redis 部署为例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-deployment
  namespace: default
  labels:
    app: redis
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - image: redis
        imagePullPolicy: Always
        name: redis
        ports:
        - containerPort: 6379
          protocol: TCP

创建一个文件redis-deployment.yaml并粘贴上面的内容。然后使用以下命令安装 redis 部署:

kubectl apply -f redis-deployment.yaml

接下来我们需要创建一个可以将流量路由到我们的 Pod 的服务:

apiVersion: v1
kind: Service
metadata:
  name: redis-service
  namespace: default
spec:
  selector:
    app: redis
  type: ClusterIP
  ports:
    - name: tcp-port
      port: 6379
      targetPort: 6379
      protocol: TCP

创建一个文件redis-service.yaml并粘贴上面的内容。然后使用以下命令安装redis服务:

kubectl apply -f redis-service.yaml

要将 TCP 服务添加到 nginx 入口控制器,您可以运行以下命令:

kubectl patch configmap tcp-services -n kube-system --patch '{"data":{"6379":"default/redis-service:6379"}}'

在哪里:

6379:您的服务应该从 minikube 虚拟机外部监听的端口

default: 安装服务的命名空间

redis-service:服务的名称

我们可以使用以下命令验证我们的资源是否已修补:

kubectl get configmap tcp-services -n kube-system -o yaml

我们应该看到这样的东西:

apiVersion: v1
data:
  "6379": default/redis-service:6379
kind: ConfigMap
metadata:
  creationTimestamp: "2019-10-01T16:19:57Z"
  labels:
    addonmanager.kubernetes.io/mode: EnsureExists
  name: tcp-services
  namespace: kube-system
  resourceVersion: "2857"
  selfLink: /api/v1/namespaces/kube-system/configmaps/tcp-services
  uid: 4f7fac22-e467-11e9-b543-080027057910

您需要验证的唯一值是 data 属性下的值如下所示:

"6379": default/redis-service:6379

修补 ingress-nginx-controller

为了从外部集群获得连接,必须完成最后一步。我们需要修补我们的 nginx 控制器,以便它侦听端口 6379 并可以将流量路由到您的服务。为此,我们需要创建一个补丁文件。

spec:
  template:
    spec:
      containers:
      - name: ingress-nginx-controller
        ports:
         - containerPort: 6379
           hostPort: 6379

创建一个名为ingress-nginx-controller-patch.yaml并粘贴上面的内容的文件。

接下来使用以下命令应用更改:

kubectl patch deployment ingress-nginx-controller --patch "$(cat ingress-nginx-controller-patch.yaml)" -n kube-system

推荐阅读