【问题标题】:Exposing Redis with Ingress Nginx Controller使用 Ingress Nginx 控制器暴露 Redis
【发布时间】:2022-03-09 23:48:28
【问题描述】:

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

这是我的服务:

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

【问题讨论】:

    标签: kubernetes redis nginx-ingress


    【解决方案1】:

    Redis 在非 HTTP 端口 (80,443) 的 6379 上工作。所以你需要在 nginx 入口控制器中启用TCP/UDP support。 minikube 文档here 展示了如何为 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
    

    【讨论】:

    【解决方案2】:

    我让它工作的方法是在 nginx-ingress 控制器上启用ssl-passthrough。 修补我的 nginx-ingress 控制器后,我就可以连接了。

    ingress.yaml

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: redis-ingress
      namespace: default
      annotations:
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/ssl-passthrough: 'true'
    spec:
      tls:
        - hosts:
          - <host_address>
          secretName: <k8s_secret_name>
      rules:
        - host: <host_address>
          http:
            paths:
              - path: "/"
                pathType: Prefix
                backend:
                  service:
                    name: redis-service
                    port:
                      number: 6380
    

    python sn -p 连接

    import redis
    
    r = redis.StrictRedis(host='<host_address>',
                    port=443, db=0, ssl=True,
                    ssl_ca_certs='server.pem')
    
    print(r.ping())
    

    在我的情况下,我确实使用 redistls

    【讨论】:

    • 我认为使用预定义端口(即用于 HTTPS 协议的 443)不是一个好主意
    • nginx 入口仅适用于端口 80/443。因此,在这种特定情况下,这是唯一可用的端口。
    猜你喜欢
    • 2019-02-24
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    • 2022-01-16
    • 1970-01-01
    • 2022-07-11
    • 2020-01-31
    • 1970-01-01
    相关资源
    最近更新 更多