一.部署成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)
})
}
}
部署上去基本就没有问题了