kubernetes - 在Google Cloud Kubernetes中运行Traefik时,LoadBalancer Healthy失败

标签 kubernetes google-cloud-platform traefik traefik-ingress

我正在尝试在Google Cloud Kubernetes中配置Traefik,正在创建集群,并使用以下文件配置集群。

我的代码是从这里开始的:

  • https://supergiant.io/blog/using-traefik-as-ingress-controller-for-your-kubernetes-cluster/
  • https://docs.traefik.io/user-guide/kubernetes/


  • run.sh

    #!/usr/bin/env bash
    
    PROJECT="my-beautiful-project" # Replace This
    CLUSTER_NAME="cluster-traefik-x"
    
    # Create Cluster
    gcloud container clusters create $CLUSTER_NAME --zone europe-west4-c
    
    # Connect to Cluster:
    gcloud container clusters get-credentials $CLUSTER_NAME --zone europe-west4-c --project $PROJECT
    
    # Reserve IPs
    gcloud compute addresses create my-web-static-ip-rui --global
    gcloud compute addresses create my-web-static-ip-rui-dashboard --global
    
    # Setup Traefik
    kubectl apply -f 10-traefik-service-acc.yaml
    kubectl apply -f 20-traefik-cr.yaml
    kubectl apply -f 30-traefik-crb.yaml
    
    kubectl apply -f 40-traefik-deployment.yaml
    kubectl apply -f 50-traefik-svc.yaml
    
    # gcloud container clusters get-credentials $CLUSTER_NAME --zone europe-west4-c --project $PROJECT && kubectl port-forward --namespace kube-system $(kubectl get pod --namespace kube-system --selector="k8s-app=traefik-ingress-lb" --output jsonpath='{.items[0].metadata.name}') 8080:8080 # DASHBOARD
    # gcloud container clusters get-credentials $CLUSTER_NAME --zone europe-west4-c --project $PROJECT && kubectl port-forward --namespace kube-system $(kubectl get pod --namespace kube-system --selector="k8s-app=traefik-ingress-lb" --output jsonpath='{.items[0].metadata.name}') 8081:80 # HTTP
    
    kubectl apply -f 60-traefik-webui-svc.yaml
    # gcloud container clusters get-credentials $CLUSTER_NAME --zone europe-west4-c --project $PROJECT && kubectl port-forward --namespace kube-system $(kubectl get pod --namespace kube-system --selector="k8s-app=traefik-ingress-lb" --output jsonpath='{.items[0].metadata.name}') 8082:8080 # DASHBOARD
    
    kubectl apply -f 70-traefik-ingress.yaml
    kubectl apply -f 75-traefik-ingress-lb-rui.yaml
    kubectl apply -f 210-ws-rui-deployment.yaml
    kubectl apply -f 220-ws-rui-svc.yaml
    kubectl apply -f 230-ws-rui-ingress.yaml
    
    # curl http://127.0.0.1:8081/hello # Should fail
    # curl -H host:api.my-domain.com http://127.0.0.1:8081/hello # Returns ok
    

    10-traefik-service-acc.yaml:
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: traefik-ingress
      namespace: kube-system
    

    20-traefik-cr.yaml
    kind: ClusterRole
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      name: traefik-ingress
    rules:
      - apiGroups:
          - ""
        resources:
          - services
          - endpoints
          - secrets
        verbs:
          - get
          - list
          - watch
      - apiGroups:
          - extensions
        resources:
          - ingresses
        verbs:
          - get
          - list
          - watch
    

    30-traefik-crb.yaml
    kind: ClusterRoleBinding
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      name: traefik-ingress
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: traefik-ingress
    subjects:
    - kind: ServiceAccount
      name: traefik-ingress
      namespace: kube-system
    

    40-traefik-deployment.yaml
    kind: Deployment
    apiVersion: extensions/v1beta1
    metadata:
      name: traefik-ingress
      namespace: kube-system
      labels:
        k8s-app: traefik-ingress-lb
    spec:
      replicas: 1
      selector:
        matchLabels:
          k8s-app: traefik-ingress-lb
      template:
        metadata:
          labels:
            k8s-app: traefik-ingress-lb
            name: traefik-ingress-lb
        spec:
          serviceAccountName: traefik-ingress
          terminationGracePeriodSeconds: 60
          containers:
          - image: traefik
            name: traefik-ingress-lb
            ports:
            - name: http
              containerPort: 80 # LOADBALANCER
            - name: admin
              containerPort: 8080 # DASHBOARD
            args:
            - --api
            - --kubernetes
            - --logLevel=DEBUG # INFO | DEBUG
    

    50-traefik-svc.yaml
    kind: Service
    apiVersion: v1
    metadata:
      name: traefik-ingress-service
      namespace: kube-system
    spec:
      selector:
        k8s-app: traefik-ingress-lb
      ports:
        - protocol: TCP
          port: 80
          name: web # LOADBALANCER
        - protocol: TCP
          port: 8080
          name: admin # DASHBOARD
      type: NodePort # -> https://docs.traefik.io/user-guide/kubernetes/
    # I read in internet some examples with NodePort and some with LoadBalancer. 
    # I think that the most correct is NodePort
    #  type: LoadBalancer
    #  loadBalancerIP: 130.211.20.21 # Use when type is LoadBalancer # THIS DOES NOT WORK WITH RESERVED IPs
    

    60-traefik-webui-svc.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: traefik-web-ui
      namespace: kube-system
    spec:
      type: NodePort
    #  type: ClusterIP # ClusterIP is the default ServiceType. The examples that I saw don't have anything, then is ClusterIP by default, but Kubernetes Ingress says: `error while evaluating the ingress spec: service "kube-system/traefik-web-ui" is type "ClusterIP", expected "NodePort" or "LoadBalancer"` then, I choose NodePort
      selector:
        k8s-app: traefik-ingress-lb
      ports:
      - name: web
        port: 80
        targetPort: 8080 # DASHBOARD
    

    70-traefik-ingress.yaml
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: traefik-web-ui
      namespace: kube-system
      annotations:
    #    kubernetes.io/ingress.class: traefik # SHOULD I USE THIS HERE?
        kubernetes.io/ingress.global-static-ip-name: "my-web-static-ip-rui-dashboard"
    spec:
      rules:
        - host: dashboard.api.my-domain.com
          http:
            paths:
            - path: /
              backend:
                serviceName: traefik-web-ui
                servicePort: web
    

    75-traefik-ingress-lb-rui.yaml
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: traefik-lb-ingress
      namespace: kube-system
      annotations:
    #    kubernetes.io/ingress.class: traefik # SHOULD I USE THIS HERE?
        kubernetes.io/ingress.global-static-ip-name: "my-web-static-ip-rui"
    
    spec:
      rules:
        - host: api.my-domain.com
          http:
            paths:
            - path: /
              backend:
                serviceName: traefik-ingress-service
                servicePort: web
    

    210-ws-rui-deployment.yaml
    
    kind: Deployment
    apiVersion: extensions/v1beta1
    metadata:
      name: ws-rui-hello-world
      labels:
        app: animals
        animal: bear
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: animals
          task: bear
      template:
        metadata:
          labels:
            app: animals
            task: bear
            version: v0.0.1
        spec:
          containers:
          - name: bear
    #        image: supergiantkir/animals:bear
            image: registry.hub.docker.com/ruimartinsptl/python-user-web-service-lixo
            ports:
            - containerPort: 80
    

    220-ws-rui-svc.yaml
    
    apiVersion: v1
    kind: Service
    metadata:
      name: ws-rui-hello-world
    spec:
      type: NodePort
      ports:
      - name: http
        targetPort: 80
        port: 80
      selector:
        app: animals
        task: bear
    

    230-ws-rui-ingress.yaml
    
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: ws-rui-ingress
      annotations:
        kubernetes.io/ingress.class: traefik
    spec:
      rules:
      - host: api.my-domain.com
        http:
          paths:
          # - path: / # SHOULD I USE also `/`?
          #   backend:
          #     serviceName: ws-rui-hello-world
          #     servicePort: http
          - path: /hello
            backend:
              serviceName: ws-rui-hello-world
              servicePort: http
    

    但是,我遇到了一些问题:
  • 我可以映射localhost中的服务端口,并运行curl -H host:api.my-domain.com http://127.0.0.1:8081/hellocurl -H host:dashboard.api.my-domain.com http://127.0.0.1:8080/dashboard。但是我无法从外部获得服务。

  • 这是我的Kubernetes集群:

    部署部署良好:

    enter image description here

    IP创建得很好
    enter image description here

    服务创建得很好,但是入口在运行状况检查中失败,并且由于域而不会出现问题,因为我已经尝试过使用域。
    enter image description here

    这是健康检查:
    enter image description here

    端口31398存在运行状况检查问题:
    enter image description here

    这是通过身份验证创建的健康检查:
    enter image description here

    但是,如果我从该端口到本地主机进行端口转发,则其工作如下:

    enter image description here

    enter image description here

    但是,当我尝试访问realdomain时,总是会收到404错误。
    有人可以帮我吗?

    有人已经在Google Cloud Platform中配置Traefik?

    欢迎所有技巧:)🙏

    更新:解决方案

    Traefik服务应该是LoadBalancer类型而不是NodePort(文件50-traefik-svc.yaml),那么我不需要为Traefik创建入口(文件70-traefik-ingress.yaml可以被删除)

    我还需要在loadBalancerIP: xxx.xxx.xxx.xxx中插入50-traefik-svc.yaml,而不是在kubernetes.io/ingress.global-static-ip-name: "my-web-static-ip-rui-dashboard"中插入70-traefik-ingress.yaml。 (此IP有时需要很长时间才能设置为〜15分钟)

    感谢所有试图帮助我的人:)

    最佳答案

    显然,您知道自己在做什么,并且我不知道有关该工具的详细信息。

    但是我看到这个问题偶尔会出现……如果您在某种“托管”环境中运行,其中安全人员会自动“修复”安全漏洞,那么这尤其重要。

    1)是否有人删除允许GCP健康状况检查程序访问您IP的规则? (该规则本来是自动创建的,但有时“安全人员”会将其删除

    2)是否有人从公开的API中删除了0.0.0.0/0规则。 (因为您的健康检查失败而无法猜测)。

    检查日志文件中是否有任何PATCH到防火墙的规则。

    关于kubernetes - 在Google Cloud Kubernetes中运行Traefik时,LoadBalancer Healthy失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56941015/

    相关文章:

    go - 每个前端的 Traefik 转发授权

    networking - 如何使入口连接到我网络中的 pod

    google-cloud-platform - GCP Dataproc - 错误 : Unknown name "optionalComponents" at 'cluster.config' : Cannot find field

    amazon-web-services - Google Cloud 是否为其计算实例提供公共(public)主机名?

    ssl - Traefik & LetsEncrypt - DNS prob lem NXDOMAIN looking up up for example.com

    amazon-route53 - 如何在 Traefik 中使用 Route 53 作为 Lets Encrypt 的 DNS 挑战?

    kubernetes - namespace 中的Istio自定义网关

    kubernetes - 带有 Kubernetes 内存控制的 Java jib-maven-plugin

    networking - Kubernetes 网络问题 - 外部无法访问服务nodePort

    mysql - 自动将 Amazon S3 文件或 Google Cloud Storage 的链接添加到 Google Cloud SQL 表