Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
水淹萌龙
kubesphere
提交
845887a3
K
kubesphere
项目概览
水淹萌龙
/
kubesphere
与 Fork 源项目一致
Fork自
KubeSphere / kubesphere
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kubesphere
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
未验证
提交
845887a3
编写于
6月 02, 2020
作者:
Z
zryfish
提交者:
GitHub
6月 02, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix proxy bug (#2146)
上级
68029de6
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
49 addition
and
30 deletion
+49
-30
pkg/apiserver/dispatch/dispatch.go
pkg/apiserver/dispatch/dispatch.go
+21
-22
pkg/kapis/cluster/v1alpha1/handler.go
pkg/kapis/cluster/v1alpha1/handler.go
+27
-7
pkg/kapis/cluster/v1alpha1/handler_test.go
pkg/kapis/cluster/v1alpha1/handler_test.go
+1
-1
未找到文件。
pkg/apiserver/dispatch/dispatch.go
浏览文件 @
845887a3
...
...
@@ -39,6 +39,8 @@ import (
const
proxyURLFormat
=
"/api/v1/namespaces/kubesphere-system/services/:ks-apiserver:/proxy%s"
// Dispatcher defines how to forward request to designated cluster based on cluster name
// This should only be used in host cluster when multicluster mode enabled, use in any other cases may cause
// unexpected behavior
type
Dispatcher
interface
{
Dispatch
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
,
handler
http
.
Handler
)
}
...
...
@@ -127,35 +129,32 @@ func (c *clusterDispatch) Dispatch(w http.ResponseWriter, req *http.Request, han
transport
:=
http
.
DefaultTransport
// change request host to actually cluster hosts
u
:=
*
req
.
URL
u
.
Path
=
strings
.
Replace
(
u
.
Path
,
fmt
.
Sprintf
(
"/clusters/%s"
,
info
.
Cluster
),
""
,
1
)
// change request host to actually cluster hosts
if
info
.
IsKubernetesRequest
{
u
.
Host
=
innCluster
.
kubernetesURL
.
Host
// if cluster connection is direct and kubesphere apiserver endpoint is empty
// we use kube-apiserver proxy way
if
cluster
.
Spec
.
Connection
.
Type
==
clusterv1alpha1
.
ConnectionTypeDirect
&&
len
(
cluster
.
Spec
.
Connection
.
KubeSphereAPIEndpoint
)
==
0
{
u
.
Scheme
=
innCluster
.
kubernetesURL
.
Scheme
u
.
Host
=
innCluster
.
kubernetesURL
.
Host
u
.
Path
=
fmt
.
Sprintf
(
proxyURLFormat
,
u
.
Path
)
transport
=
innCluster
.
transport
// The reason we need this is kube-apiserver doesn't behave like a standard proxy, it will strip
// authorization header of proxy requests. Use custom header to avoid stripping by kube-apiserver.
// https://github.com/kubernetes/kubernetes/issues/38775#issuecomment-277915961
// We first copy req.Header['Authorization'] to req.Header['X-KubeSphere-Authorization'] before sending
// designated cluster kube-apiserver, then copy req.Header['X-KubeSphere-Authorization'] to
// req.Header['Authorization'] before authentication.
req
.
Header
.
Set
(
"X-KubeSphere-Authorization"
,
req
.
Header
.
Get
(
"Authorization"
))
}
else
{
// everything else goes to ks-apiserver, since our ks-apiserver has the ability to proxy kube-apiserver requests
u
.
Host
=
innCluster
.
kubesphereURL
.
Host
u
.
Scheme
=
innCluster
.
kubesphereURL
.
Scheme
// if cluster connection is direct and kubesphere apiserver endpoint is empty
// we use kube-apiserver proxy way
if
cluster
.
Spec
.
Connection
.
Type
==
clusterv1alpha1
.
ConnectionTypeDirect
&&
len
(
cluster
.
Spec
.
Connection
.
KubeSphereAPIEndpoint
)
==
0
{
u
.
Scheme
=
innCluster
.
kubernetesURL
.
Scheme
u
.
Host
=
innCluster
.
kubernetesURL
.
Host
u
.
Path
=
fmt
.
Sprintf
(
proxyURLFormat
,
u
.
Path
)
transport
=
innCluster
.
transport
// The reason we need this is kube-apiserver doesn't behave like a standard proxy, it will strip
// authorization header of proxy requests. Use custom header to avoid stripping by kube-apiserver.
// https://github.com/kubernetes/kubernetes/issues/38775#issuecomment-277915961
// We first copy req.Header['Authorization'] to req.Header['X-KubeSphere-Authorization'] before sending
// designated cluster kube-apiserver, then copy req.Header['X-KubeSphere-Authorization'] to
// req.Header['Authorization'] before authentication.
req
.
Header
.
Set
(
"X-KubeSphere-Authorization"
,
req
.
Header
.
Get
(
"Authorization"
))
}
}
httpProxy
:=
proxy
.
NewUpgradeAwareHandler
(
&
u
,
transport
,
false
,
false
,
c
)
...
...
pkg/kapis/cluster/v1alpha1/handler.go
浏览文件 @
845887a3
...
...
@@ -243,7 +243,7 @@ func (h *handler) ValidateCluster(request *restful.Request, response *restful.Re
return
}
_
,
err
=
validateKubeSphereAPIServer
(
cluster
.
Spec
.
Connection
.
KubeSphereAPIEndpoint
)
_
,
err
=
validateKubeSphereAPIServer
(
cluster
.
Spec
.
Connection
.
KubeSphereAPIEndpoint
,
cluster
.
Spec
.
Connection
.
KubeConfig
)
if
err
!=
nil
{
api
.
HandleBadRequest
(
response
,
request
,
fmt
.
Errorf
(
"unable validate kubesphere endpoint, %v"
,
err
))
return
...
...
@@ -286,18 +286,38 @@ func loadKubeConfigFromBytes(kubeconfig []byte) (*rest.Config, error) {
}
// validateKubeSphereAPIServer uses version api to check the accessibility
func
validateKubeSphereAPIServer
(
ksEndpoint
string
)
(
*
version
.
Info
,
error
)
{
_
,
err
:=
url
.
Parse
(
ksEndpoint
)
if
err
!=
nil
{
return
nil
,
err
// If ksEndpoint is empty, use
func
validateKubeSphereAPIServer
(
ksEndpoint
string
,
kubeconfig
[]
byte
)
(
*
version
.
Info
,
error
)
{
if
len
(
ksEndpoint
)
==
0
&&
len
(
kubeconfig
)
==
0
{
return
nil
,
fmt
.
Errorf
(
"neither kubesphere api endpoint nor kubeconfig was provided"
)
}
path
:=
fmt
.
Sprintf
(
"%s/kapis/version"
,
ksEndpoint
)
client
:=
http
.
Client
{
Timeout
:
defaultTimeout
,
}
path
:=
fmt
.
Sprintf
(
"%s/kapis/version"
,
ksEndpoint
)
if
len
(
ksEndpoint
)
!=
0
{
_
,
err
:=
url
.
Parse
(
ksEndpoint
)
if
err
!=
nil
{
return
nil
,
err
}
}
else
{
config
,
err
:=
loadKubeConfigFromBytes
(
kubeconfig
)
if
err
!=
nil
{
return
nil
,
err
}
transport
,
err
:=
rest
.
TransportFor
(
config
)
if
err
!=
nil
{
return
nil
,
err
}
client
.
Transport
=
transport
path
=
fmt
.
Sprintf
(
"%s/api/v1/namespaces/kubesphere-system/services/:ks-apiserver:/proxy/kapis/version"
,
config
.
Host
)
}
response
,
err
:=
client
.
Get
(
path
)
if
err
!=
nil
{
return
nil
,
err
...
...
pkg/kapis/cluster/v1alpha1/handler_test.go
浏览文件 @
845887a3
...
...
@@ -263,7 +263,7 @@ func TestValidateKubeSphereEndpoint(t *testing.T) {
svr
:=
httptest
.
NewServer
(
http
.
HandlerFunc
(
endpoint
))
defer
svr
.
Close
()
got
,
err
:=
validateKubeSphereAPIServer
(
svr
.
URL
)
got
,
err
:=
validateKubeSphereAPIServer
(
svr
.
URL
,
nil
)
if
err
!=
nil
{
t
.
Fatal
(
err
)
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录