sping cloud gateway和k8s的部署和坑

一.部署成k8s的pod、

如何搭建gateway请看gateway搭建
接下来我添加新的依赖

implementation("org.springframework.cloud:spring-cloud-commons")

implementation("org.springframework.cloud:spring-cloud-kubernetes-core")
implementation("org.springframework.cloud:spring-cloud-kubernetes-discovery")

implementation("org.springframework.cloud:spring-cloud-starter-kubernetes-ribbon")
implementation("org.springframework.cloud:spring-cloud-starter-netflix-ribbon")
implementation("org.springframework.cloud:spring-cloud-starter-netflix-hystrix")
implementation("org.springframework.boot:spring-boot-starter-webflux")

这里主要,和篇不同我用的是gradle,不过其实也差不多
完整yaml如下

server:
  port: 8888
spring:
  redis:
    host: 容器服务名
    port: 6379
  cloud:
    gateway:
      enabled: true
      discovery:
        locator:
          enabled: true
      routes:
        - id: all
          uri: lb:// 容器服务名/
          predicates:
            - Path=/**
          filters:
            - name: RequestRateLimiter
              args:
                rate-limiter: "#{@userLevelRedisRateLimiter}"
                key-resolver: "#{@userKeyResolver}"
                redis-rate-limiter.replenishRate: 1
                redis-rate-limiter.burstCapacity: 3
logging:
  level:
    org.springframework.cloud.gateway: debug
    org.springframework.web: debug
product-infra-service:
  ribbon:
    KubernetesNamespace: default

backend:
  ribbon:
    eureka:
      enabled: false
    client:
      enabled: true
    ServerListRefreshInterval: 5000

hystrix:
  command:
    BackendCall:
      execution:
        isolation:
          thread:
            timeoutInMilliseconds: 5000
  threadpool:
    BackendCallThread:
      coreSize: 5
feign:
  hystrix:
    enabled: true

docker打包成镜像后
k8s 部署yaml

apiVersion: v1
kind: ReplicationController
metadata:
  name: gateway
  labels:
    name: gateway
spec:
  replicas: 1
  selector:
    name: gateway
  template:
    metadata:
      labels:
        name: gateway
    spec:
      containers:
        - name: gateway
          image: 镜像
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8888

service

apiVersion: v1
kind: Service
metadata:
  name: gateway
  labels:
    name: gateway
spec:
  type: NodePort
  ports:
    - port: 8888
      nodePort: 32223
  selector:
    name: gateway

命令kubectl create -f 文件名.yaml
之后 minikube service gateway --url 可以看service 外部访问路径是多少,便于测试
但是这样是有问题的,会出现service找不到的情况,原因是没有权限

# NOTE: The service account `default:default` already exists in k8s cluster.
# You can create a new account following like this:
#---
#apiVersion: v1
#kind: ServiceAccount
#metadata:
#  name: <new-account-name>
#  namespace: <namespace>

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: fabric8-rbac
subjects:
  - kind: ServiceAccount
    # Reference to upper's `metadata.name`
    name: default
    # Reference to upper's `metadata.namespace`
    namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

添加已上就可以了。

一.gateway会影响项目可能的点

第一点: 如果通过路由转发到gateway 容器,在转发到业务容器中

request 的header: x-forwarded-for 会记录两次的IP,的做转换的时候会有问题。

第二点: gateway 跨域的问题

当请求发送到gateway容器的时候,如果跨域的了,会报403 错误,这边我们需要添加代码(我这边用的kotlin ,请相应的转化为Java)

  @Bean
    fun corsFilter(): CorsWebFilter {
        val config = CorsConfiguration()
        config.addAllowedMethod("*")
        config.addAllowedOrigin("*")
        config.addAllowedHeader("*")

        val source = UrlBasedCorsConfigurationSource(PathPatternParser())
        source.registerCorsConfiguration("/**", config)

        return CorsWebFilter(source)
    }

但是有的人还是没有解决问题,因为403不报错了,但是又出现cors 重复头顶的问题(Access-Control-Allow-Origin 会出现两个)
这个gateway 的bug 不知道先在版本改了没有,这边需要添加

class CorsResponseHeaderFilter : GlobalFilter, Ordered {
    override fun getOrder(): Int { //如果是结合gateway限流。建议将return Ordered.LOWEST_PRECEDENCE
      //因为在gateway的filter前 先执行这个filter会有影响
        return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1
    }

    override fun filter(exchange: ServerWebExchange, chain: GatewayFilterChain): Mono<Void> {
        val log = LogFactory.getLog(this.javaClass)
        log.info("CorsResponseHeaderFilter执行")
        return chain.filter(exchange).then(Mono.defer {
            exchange.response.headers.entries
                .filter { kv -> kv.value.size > 1 }
                .filter { kv -> kv.key == HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN || kv.key == HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS }
                .forEach { kv ->
                    kv.setValue(arrayListOf(kv.value[0]))
                }
            chain.filter(exchange)
        })
    }
}

部署上去基本就没有问题了

如果还有重复头的问题,那就需要检查业务容器是否有对cors 也进行了配置,造成了影响

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值