在Kubernetes中使用Nginx进行外部OAuth身份验证

时间:2020-10-29 11:32:39

标签: nginx kubernetes

在nginx入口后面为Web应用程序设置外部身份验证时遇到麻烦。当我尝试从外部访问URL https://site.example.com时,我没有重定向到Github登录,而是直接访问Web应用程序。

在我的环境中运行Pod:

NAME                              READY   STATUS   
nginx-ingress-68df4dfc4f-wpj5t    1/1     Running  
oauth2-proxy-6675d4b57c-cspw8     1/1     Running   
web-deployment-7d4bd85b46-blxb8   1/1     Running   
web-deployment-7d4bd85b46-nqjgl   1/1     Running   

活动服务:

NAME            TYPE           CLUSTER-IP       EXTERNAL-IP    PORT(S)                      
nginx-ingress   LoadBalancer   10.96.156.157    192.168.1.82   80:31613/TCP,443:32437/TCP   
oauth2-proxy    ClusterIP      10.100.101.251   <none>         4180/TCP                     
web-service     ClusterIP      10.108.237.188   <none>         8080/TCP                     

两个Ingress资源:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
  namespace: nginx-ingress
  annotations:
     kubernetes.io/ingress.class: nginx
     nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
     nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$request_uri"
  labels:
    app: webapp
spec:
  rules:
  - host: site.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: web-service
          servicePort: 8080
  tls:
  - hosts:
    - site.example.com
    secretName: example-tls

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: oauth2-proxy
  namespace: nginx-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
  labels:
    app: oauth2-proxy
spec:
  rules:
  - host: site.example.com
    http:
      paths:
      - backend:
          serviceName: oauth2-proxy
          servicePort: 4180
        path: /oauth2

  tls:
  - hosts:
    - site.example.com
    secretName: example-tls

入口输出:

NAME           CLASS    HOSTS              ADDRESS        PORTS     
ingress        <none>   site.example.com   192.168.1.82   80, 443   
oauth2-proxy   <none>   site.example.com                  80, 443   

我在Ingress oauth2-proxy事件中看到以下错误:

Events:
  Type     Reason    Age   From                      Message
  ----     ------    ----  ----                      -------
  Warning  Rejected  54m   nginx-ingress-controller  All hosts are taken by other resources

根据在我的Github帐户中创建的OAuth应用,通过部署here使用客户端ID,客户端密钥和SECRET构建的Oauth2-proxy。

我想在oauth2-proxy日志中找不到日志,因为它没有在该过程中被调用。

更新

这个问题是不完整的,我忘了提到丰富的NGINX映像(installation guide中的NGINX 1.9.0)。

使用以下更改图像:

NGINX Ingress controller
Release: v0.41.2
Build: d8a93551e6e5798fc4af3eb910cef62ecddc8938
Repository: https://github.com/kubernetes/ingress-nginx
nginx version: nginx/1.19.4

错误消失。简而言之,两个Ingress配置都有效,一个来自我的问题,另一个来自答案。

1 个答案:

答案 0 :(得分:1)

在您的配置中,您正在使用2 Ingress。如您oauth2-proxy Ingress所述,在Event部分中,您可以找到信息:

所有主机都被其他资源占用

您在这里遇到的问题称为Host Collisions。就像您使用过的两个Ingress一样发生:

spec:
  rules:
  - host: site.example.com

在这种情况下,Ingress使用称为Choosing the Winner的默认算法。

如果有多个资源争用同一台主机,则Ingress Controller将根据资源的creationTimestamp选择赢家:最早的资源将获胜。

针对您的问题的快速解决方案是创建一个具有2条路径的Ingress

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress
  namespace: nginx-ingress
  annotations:
     kubernetes.io/ingress.class: nginx
     nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
     nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$request_uri"
spec:
  rules:
  - host: site.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: web-service
          servicePort: 8080
      - path: /oauth2
        backend:
          serviceName: oauth2-proxy
          servicePort: 4180      
  tls:
  - hosts:
    - site.example.com
    secretName: example-tls

解决此问题的另一种方法是使用Merging Configuration for the Same Host,但是在这种情况下不应该使用它。

最后,您可以按照Nginx Ingress官方教程-External OAUTH Authentication

请告诉我这是否有帮助。