在 Kubernetes 中为 Traefik 提供 ArgoCD 服务

在 Kubernetes 中为 Traefik 提供 ArgoCD 服务

我想在 Traefik 后面运行 ArgoCD,这样我既可以访问 ArgoCD Web UI,又可以使用argocd命令行工具与 API 交互。

  • 我已经将 ArgoCD 部署到 Kubernetes 集群中上游清单

  • 我已经将 Traefik 部署为入口服务器掌舵图。除了日志级别之外,我没有设置任何图表值。

  • 我正在使用以下 Ingress 资源:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: argocd
    
    spec:
      tls:
        - hosts:
          - argocd.internal
          secretName: argocd-certificate
      rules:
        - host: argocd.internal
          http:
            paths:
              - path: /
                pathType: Prefix
                backend:
                  service:
                    name: argocd-server
                    port:
                      name: http
    
  • 该秘密存在,并且argocd-certificate具有有效的证书和密钥。tls.crttls.key

有了这个,我可以在 访问 ArgoCD http://argocd.internal,但尝试在 访问它时https://argocd.internal失败,原因如下:

$ curl https://argocd.internal
404 page not found

(请注意,没有证书错误;端点正在提供 Ingress 资源中配置的证书。)

我不确定这里发生了什么:我没有将其绑定到任何特定的 Traefik 端点,所以我希望它在所有端点上都可用……当我们查询 Traefik API 时,我们会看到:

$ curl -sf 'http://localhost:9000/api/http/routers?search=&status=&per_page=6&page=1' |
  jq '.[]|select(.service == "argocd-argocd-server-80")'
{
  "entryPoints": [
    "metrics",
    "web",
    "websecure"
  ],
  "service": "argocd-argocd-server-80",
  "rule": "Host(`argocd.internal`) && PathPrefix(`/`)",
  "status": "enabled",
  "using": [
    "metrics",
    "web",
    "websecure"
  ],
  "name": "argocd-argocd-argocd-internal@kubernetes",
  "provider": "kubernetes"
}

这确认路由器在所有端点上都可用。

这是怎么回事——为什么这似乎只有在通过http://而不是通过访问时才能做正确的事情https://

如果有帮助的话,该argocd-server服务看起来像:

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/component: server
    app.kubernetes.io/name: argocd-server
    app.kubernetes.io/part-of: argocd
  name: argocd-server
  namespace: argocd
spec:
  clusterIP: 10.96.117.77
  clusterIPs:
  - 10.96.117.77
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - name: http
    port: 80
    targetPort: 8080
  - name: https
    port: 443
    targetPort: 8080
  selector:
    app.kubernetes.io/name: argocd-server

答案1

我能够用一对入口路由资源:

  1. 一个用于http://端点:

    
    apiVersion: traefik.containo.us/v1alpha1
    kind: IngressRoute
    metadata:
      name: argocd-http
    spec:
      entryPoints:
        - web
      routes:
      - kind: Rule
        match: Host(`argocd.internal`)
        priority: 10
        middlewares:
          - name: redirect-http-https
        services:
        - kind: Service
          name: argocd-server
          port: http
    

    这使用重定向中间件将所有请求重定向到https://端点:

    apiVersion: traefik.containo.us/v1alpha1
    kind: Middleware
    metadata:
      name: redirect-http-https
    spec:
      redirectScheme:
        scheme: https
        permanent: true
    

    这意味着该services:部分IngressRoute实际上是无操作,但它是模式所要求的。

  2. 一个用于https://端点:

    apiVersion: traefik.containo.us/v1alpha1
    kind: IngressRoute
    metadata:
      name: argocd-https
    spec:
      entryPoints:
        - websecure
      routes:
      - kind: Rule
        match: Host(`argocd.internal`)
        priority: 10
        services:
        - kind: Service
          name: argocd-server
          port: http
      - kind: Rule
        match: Host(`argocd.internal`) && Headers(`Content-Type`, `application/grpc`)
        priority: 11
        services:
        - kind: Service
          name: argocd-server
          port: http
          scheme: h2c
      tls:
        secretName: argocd-certificate
    

    我们使用来Content-Type区分 gRPC 请求和 HTTP 请求,并使用适当的协议方案来连接后端服务器。

答案2

验证您的服务本身是否正常运行。Traefik 可能正常运行,但由于健康检查失败、标签或安全策略不匹配,服务可能不可用。

尝试使用digpingtelnet从 Kubernetes 内部访问它,例如使用netshoot容器镜像。

使用内部服务名称作为主机名:

<name>.<namespace>.svc.cluster.local

相关内容