当前位置: 首页 > 知识库问答 >
问题:

库伯内特斯Minikube nginx入口与基本身份验证,cors和会话返回403

邹英悟
2023-03-14

我正在使用Minikube部署一个简单的spring boot应用程序,您可以在这里找到:https://github.com/shopKubernetesSpringboot

minikube v1.9.2 on Ubuntu 18.04
Kubernetes v1.17.0 on Docker 19.03.5 ...

我正在使用cors,会话,基本身份验证。它在Minikube集群之外工作(使用嵌入式spring boot netty服务器),但我无法让它在nginx ingress中工作。

它基本上是两个微服务产品和购物车。产品

XHRPOST http://192.168.39.94/cart/add
[HTTP/1.1 403 Forbidden 37ms]
CSRF Token has been associated to this client

后端正在接收X-XSRF-TOKEN

[or-http-epoll-3]o.s.w.s.适配器。HttpWebHandlerAdapter:[e8b45b1f-2]HTTP POST“/购物车/添加”,headers=[Host:“192.168.39.94”,X-Request-ID:“dc741d2765b9d0c585b7f73d0e2bab95”,X-Real-IP:“192.168.39.1”,X-Forwarded-For:“192.168.39.1”,X-Forwarded-Host:“192.168.39.94”,X-Forwarded-Port:“80”,X-Forwarded-Proto:“http”,X-Scheme:“http”,内容长度:“120”,用户代理:“Mozilla/5.0(X11;Ubuntu;Linux x86;rv:75.0)Gecko/20100101/75.0”,接受:“application/json,text/plain,/”,接受语言:“en-GB,en;q=0.5”,接受编码:“gzip,deflate”,内容类型:“application/json;charset=utf-8”,授权:“Basic dXNlcjp1c2Vy”,X-XSRF-TOKEN:“17e1b013-98b3-4064-8173-bf3af4ce8bc7”,来源:http://localhost:3000,引用者:http://localhost:3000/"]

[or-http-epoll-3]o.s.w.s.适配器。HttpWebHandlerAdapter:[e8b45b1f-2]已完成403禁止,标题=[变化:“来源”,“访问控制请求方法”,“访问控制请求标题”,访问控制允许来源:http://localhost:3000,访问控制允许凭据:“true”,内容类型:“text/plain”,缓存控制:“no Cache,no store,max age=0,必须重新验证”,Pragma:“no Cache”,Expires:“0”,X-Content-Type-Options:“nosniff”,X-Frame-Options:“DENY”,X-XSS-Protection:“1;模式=阻止”,推荐人策略:“无推荐人”,内容长度:“45”]

我的入口看起来是这样的:

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      name: shop-ingress
      annotations:
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/ssl-redirect: "false"
        nginx.ingress.kubernetes.io/affinity: cookie
        nginx.ingress.kubernetes.io/session-cookie-name: session
        nginx.ingress.kubernetes.io/session-cookie-expires: "172800"
        nginx.ingress.kubernetes.io/session-cookie-max-age: "172800"
        nginx.ingress.kubernetes.io/enable-cors: "true"
        nginx.ingress.kubernetes.io/cors-allow-origin: "http://localhost:3000"
        nginx.ingress.kubernetes.io/cors-allow-headers: X-XSRF-TOKEN,Accept,Accept-Encoding,Accept-Language,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,Origin,Connection,Content-Length,Content-Type,Host,Referer,User-Agent
        nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
        nginx.ingress.kubernetes.io/session-cookie-path: /cart
    spec:
      rules:
        - http:
            paths:
              - path: /product
                backend:
                  serviceName: product-svc
                  servicePort: 80
              - path: /cart
                backend:
                  serviceName: cart-svc
                  servicePort: 80

购物车服务

apiVersion: v1
kind: Service
metadata:
  name: cart-svc
  labels:
    app: shop
    name: cart
    tier: backend
spec:
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 120
  selector:
    app: shop
    name: cart
    tier: backend
  ports:
    - protocol: TCP
      port: 80
      targetPort: rest-api-port
---
apiVersion: v1
kind: Pod
metadata:
  name: cart-pod
  labels:
    app: shop
    name: cart
    tier: backend
spec:
  containers:
    - name: cart
      image: davidgfolch/shop-cart:latest
      ports:
        - containerPort: 8080
          name: rest-api-port
      env:
        - name: SPRING_PROFILES_ACTIVE
          value: "prod"

SpringSecurityConfig.java

@Configuration
@Slf4j
public class SecurityConfig {

    @Value("${com.dgf.shopCart.cors.origins}")
    private String corsOrigins;

    @Bean
    SecurityWebFilterChain springWebFilterChain(ServerHttpSecurity http) {
        return http
                .csrf().csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse()).and()
                .cors(c -> c.configurationSource(cors()))
                .authorizeExchange()
                .anyExchange().authenticated()
                .and()
                .httpBasic()
                .and()
                .build();
    }

    private UrlBasedCorsConfigurationSource cors() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin(corsOrigins);
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return source;
    }
}

对于Kubernetes会话,cookie未到达后端(如日志所示):

HTTP POST"/car/add", Headers=[主机:"192.168.39.94", X-请求-ID:"aba957e6cc3c8803c1734a2724a75fbf", X-真实IP:"192.168.39.1", X-转发-For:"192.168.39.1", X-转发-主机:"192.168.39.94", X-转发端口:80,X-转发原型:超文本传输协议,X-方案:超文本传输协议,内容长度:120,用户代理:Mozilla/5.0(X11;Ubuntu;Linuxx86_64;rv:75.0)Gecko/20100101 Firefox/75.0,接受:应用程序/json,文本/普通,/", Accept-Language:"en-GB, en; q=0.5", Accept-Encode:"gzip, flate", Content-Type:"Application/json; charset=utf-8", Authoration:"Basic dXNlcjp1c2Vy", X-XSRF-TOKEN:"17e1b013-98b3-4064-8173-bf3af4ce8bc7", Origin:"http://localhost:3000", Referer:"http://localhost:3000/"]

没有库伯内特斯,他们做到了:

HTTP POST“/cart/add”,headers=[Host:“localhost:8080”,用户代理:“Mozilla/5.0(X11;Ubuntu;Linux x86_64;rv:75.0)Gecko/20100101 Firefox/75.0”,接受:“application/json,text/plain,/”,接受语言:“en-GB,en;q=0.5”,接受编码:“gzip,deflate”,内容类型:“application/json;charset=utf-8”,授权:“Basic nlcjjp1c2vy”,X-XSRF-TOKEN:“17e1b013-98b3-4064-8173-bf3af4ce8bc7”,内容长度:“120”,来源:http://localhost:3000,连接:“保持活动”,引用者:http://localhost:3000/,Cookie:“Idea-c3de9a37=a5f5270f-e0e1-4807-92e2-79c126b768fc;XSRF-TOKEN=17e1b013-98b3-4064-8173-bf3af4ce8bc7;会话=eddb22e9-15f7-4b28-a422-36faa8a7f285“]

有什么建议吗?我错过了什么?

共有1个答案

宦源
2023-03-14

我最终发现,如果没有为v.0.27.0之前的nginx-ingress版本指定spec.host,粘性会话就不起作用。请参见拉取请求。

因此,应该将nginx入口更新为0.27.0版,以使上述配置工作,或者设置spec.host,并(我希望)启用DNS插件使其工作。通过主机dns名称进行访问:

    spec:
      host: myapp.example.com
      rules:
        - http:
            paths:
              - path: /product
                backend:
                  serviceName: product-svc
                  servicePort: 80
              - path: /cart
                backend:
                  serviceName: cart-svc
                  servicePort: 80

在这里您可以找到一些相关链接:

  • 粘性会话官方示例

一旦我得到一个有效的版本,我就会对这个答案进行微调。

  1. 将minikube docker入口控制器更新为0.27.0(注意:尚未工作):
#minikube docker-env
#eval $(minikube -p minikube docker-env)
#docker images | grep ingress
#docker pull quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.27.1
#minikube stop && minikube start
#eval $(minikube -p minikube docker-env)
kubectl delete -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.26.1/deploy/static/mandatory.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.27.1/deploy/static/mandatory.yaml
minikube stop && minikube start
 类似资料:
  • 我正试图通过nginx入口从客户端上传文件。在收到413响应后,我在入口上设置了以下注释; 客户端是一个Angular应用程序。它在请求正文中发送文件的bas64字符串。我尝试过上传一些KB的图像,所以我绝对没有达到这些限制。我是库伯内特斯的新手。我是否需要重新启动入口以使这些注释生效? 我也尝试过创建一个ConfigMap; 仍然得到502。 不知道如何通过kubectl访问nginx.conf

  • 我试图设置Kubernetes入口,将外部http流量路由到前端pod(路径/)和后端pod(路径/rest/*),但我总是得到400错误,而不是主nginx索引。html。 所以我在第https://cloud.google.com/kubernetes-engine/docs/tutorials/http-balancer页尝试了谷歌库伯内特斯的例子,但我总是得到400个错误。有什么想法吗?

  • 在库伯内特斯,要启用客户端证书AuthN,注释nginx.ingress.kubernetes.io/auth-tls-verify-client可以在入口中使用。即使我不在该入口中执行TLS终止,客户端证书AuthN是否仍然有效?例如,在这个入口中,如果我从入口中删除tls块,客户端证书AuthN是否仍然有效? (更多信息:我有两个入口用于同一主机,一个具有TLS部分,另一个入口具有特定api路

  • 新来的。我想知道是否有人可以帮助我区分我可以用来识别入口控制器和通过YAML和服务识别入口的特征。我有一个预先存在的集群,我认为入口控制器可能是通过helm安装的,但我不确定。有没有办法了解helm在安装nginx ingress控制器时使用的yaml?

  • 我怎样才能使用入口呢?我尝试使用NodePort和--Target etPort=1001,我在servicePort中添加了80在。 kubectl公开部署测试--Target-port=1001--type=NodePort 我得到了错误 找不到后端-404 我使用的是正确的方法还是需要遵循其他方法?

  • 是否可以在库伯内特斯中配置入口控制器,仅当传入请求的标头具有特定值时才将HTTP请求路由到服务? 实例 带有以下标头的HTTP请求 应该转发给服务1 带有以下标头的HTTP请求 应该被阻止 如果可能的话,你能详细一点或指向一些文档,因为我找不到这种用例的文档吗