Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
8f1677b7
Commit
8f1677b7
authored
Dec 19, 2016
by
deads2k
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
add service status detection to kubernetes-discovery
parent
d6046aab
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
226 additions
and
31 deletions
+226
-31
kubernetes-discover-pod.yaml
...y/artifacts/local-cluster-up/kubernetes-discover-pod.yaml
+18
-0
BUILD
cmd/kubernetes-discovery/pkg/apiserver/BUILD
+5
-0
apiserver.go
cmd/kubernetes-discovery/pkg/apiserver/apiserver.go
+29
-10
handler_apis.go
cmd/kubernetes-discovery/pkg/apiserver/handler_apis.go
+58
-13
handler_apis_test.go
cmd/kubernetes-discovery/pkg/apiserver/handler_apis_test.go
+72
-6
BUILD
cmd/kubernetes-discovery/pkg/cmd/server/BUILD
+2
-0
start.go
cmd/kubernetes-discovery/pkg/cmd/server/start.go
+14
-2
local-up-discovery.sh
hack/local-up-discovery.sh
+2
-0
policy.go
plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go
+8
-0
cluster-roles.yaml
...thorizer/rbac/bootstrappolicy/testdata/cluster-roles.yaml
+18
-0
No files found.
cmd/kubernetes-discovery/artifacts/local-cluster-up/kubernetes-discover-pod.yaml
View file @
8f1677b7
...
@@ -17,6 +17,24 @@ spec:
...
@@ -17,6 +17,24 @@ spec:
-
name
:
kubernetes-discovery
-
name
:
kubernetes-discovery
image
:
kubernetes-discovery:latest
image
:
kubernetes-discovery:latest
imagePullPolicy
:
Never
imagePullPolicy
:
Never
livenessProbe
:
failureThreshold
:
3
httpGet
:
path
:
/version
port
:
443
scheme
:
HTTPS
periodSeconds
:
10
successThreshold
:
1
timeoutSeconds
:
1
readinessProbe
:
failureThreshold
:
3
httpGet
:
path
:
/version
port
:
443
scheme
:
HTTPS
periodSeconds
:
10
successThreshold
:
1
timeoutSeconds
:
1
args
:
args
:
-
"
--proxy-client-cert-file=/var/run/auth-proxy-client/tls.crt"
-
"
--proxy-client-cert-file=/var/run/auth-proxy-client/tls.crt"
-
"
--proxy-client-key-file=/var/run/auth-proxy-client/tls.key"
-
"
--proxy-client-key-file=/var/run/auth-proxy-client/tls.key"
...
...
cmd/kubernetes-discovery/pkg/apiserver/BUILD
View file @
8f1677b7
...
@@ -34,6 +34,9 @@ go_library(
...
@@ -34,6 +34,9 @@ go_library(
"//pkg/apiserver/filters:go_default_library",
"//pkg/apiserver/filters:go_default_library",
"//pkg/auth/handlers:go_default_library",
"//pkg/auth/handlers:go_default_library",
"//pkg/client/cache:go_default_library",
"//pkg/client/cache:go_default_library",
"//pkg/client/clientset_generated/clientset:go_default_library",
"//pkg/client/informers/informers_generated:go_default_library",
"//pkg/client/listers/core/v1:go_default_library",
"//pkg/client/restclient:go_default_library",
"//pkg/client/restclient:go_default_library",
"//pkg/client/transport:go_default_library",
"//pkg/client/transport:go_default_library",
"//pkg/controller:go_default_library",
"//pkg/controller:go_default_library",
...
@@ -64,10 +67,12 @@ go_test(
...
@@ -64,10 +67,12 @@ go_test(
"//cmd/kubernetes-discovery/pkg/apis/apiregistration:go_default_library",
"//cmd/kubernetes-discovery/pkg/apis/apiregistration:go_default_library",
"//cmd/kubernetes-discovery/pkg/client/listers/apiregistration/internalversion:go_default_library",
"//cmd/kubernetes-discovery/pkg/client/listers/apiregistration/internalversion:go_default_library",
"//pkg/api:go_default_library",
"//pkg/api:go_default_library",
"//pkg/api/v1:go_default_library",
"//pkg/apis/meta/v1:go_default_library",
"//pkg/apis/meta/v1:go_default_library",
"//pkg/apiserver/request:go_default_library",
"//pkg/apiserver/request:go_default_library",
"//pkg/auth/user:go_default_library",
"//pkg/auth/user:go_default_library",
"//pkg/client/cache:go_default_library",
"//pkg/client/cache:go_default_library",
"//pkg/client/listers/core/v1:go_default_library",
"//pkg/runtime:go_default_library",
"//pkg/runtime:go_default_library",
"//pkg/util/diff:go_default_library",
"//pkg/util/diff:go_default_library",
"//pkg/util/sets:go_default_library",
"//pkg/util/sets:go_default_library",
...
...
cmd/kubernetes-discovery/pkg/apiserver/apiserver.go
View file @
8f1677b7
...
@@ -25,6 +25,9 @@ import (
...
@@ -25,6 +25,9 @@ import (
"k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/api/rest"
apiserverfilters
"k8s.io/kubernetes/pkg/apiserver/filters"
apiserverfilters
"k8s.io/kubernetes/pkg/apiserver/filters"
authhandlers
"k8s.io/kubernetes/pkg/auth/handlers"
authhandlers
"k8s.io/kubernetes/pkg/auth/handlers"
kubeclientset
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
kubeinformers
"k8s.io/kubernetes/pkg/client/informers/informers_generated"
v1listers
"k8s.io/kubernetes/pkg/client/listers/core/v1"
"k8s.io/kubernetes/pkg/genericapiserver"
"k8s.io/kubernetes/pkg/genericapiserver"
genericfilters
"k8s.io/kubernetes/pkg/genericapiserver/filters"
genericfilters
"k8s.io/kubernetes/pkg/genericapiserver/filters"
"k8s.io/kubernetes/pkg/registry/generic"
"k8s.io/kubernetes/pkg/registry/generic"
...
@@ -33,7 +36,7 @@ import (
...
@@ -33,7 +36,7 @@ import (
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis/apiregistration"
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis/apiregistration"
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis/apiregistration/v1alpha1"
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apis/apiregistration/v1alpha1"
clientset
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/clientset_generated/clientset"
discovery
clientset
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/clientset_generated/clientset"
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/clientset_generated/internalclientset"
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/informers"
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/informers"
listers
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/listers/apiregistration/internalversion"
listers
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/client/listers/apiregistration/internalversion"
...
@@ -44,7 +47,8 @@ import (
...
@@ -44,7 +47,8 @@ import (
const
legacyAPIServiceName
=
"v1."
const
legacyAPIServiceName
=
"v1."
type
Config
struct
{
type
Config
struct
{
GenericConfig
*
genericapiserver
.
Config
GenericConfig
*
genericapiserver
.
Config
CoreAPIServerClient
kubeclientset
.
Interface
// ProxyClientCert/Key are the client cert used to identify this proxy. Backing APIServices use
// ProxyClientCert/Key are the client cert used to identify this proxy. Backing APIServices use
// this to confirm the proxy's identity
// this to confirm the proxy's identity
...
@@ -73,6 +77,11 @@ type APIDiscoveryServer struct {
...
@@ -73,6 +77,11 @@ type APIDiscoveryServer struct {
// controller state
// controller state
lister
listers
.
APIServiceLister
lister
listers
.
APIServiceLister
// serviceLister is used by the discovery handler to determine whether or not to try to expose the group
serviceLister
v1listers
.
ServiceLister
// endpointsLister is used by the discovery handler to determine whether or not to try to expose the group
endpointsLister
v1listers
.
EndpointsLister
// proxyMux intercepts requests that need to be proxied to backing API servers
// proxyMux intercepts requests that need to be proxied to backing API servers
proxyMux
*
http
.
ServeMux
proxyMux
*
http
.
ServeMux
}
}
...
@@ -100,16 +109,19 @@ func (c *Config) SkipComplete() completedConfig {
...
@@ -100,16 +109,19 @@ func (c *Config) SkipComplete() completedConfig {
func
(
c
completedConfig
)
New
()
(
*
APIDiscoveryServer
,
error
)
{
func
(
c
completedConfig
)
New
()
(
*
APIDiscoveryServer
,
error
)
{
informerFactory
:=
informers
.
NewSharedInformerFactory
(
informerFactory
:=
informers
.
NewSharedInformerFactory
(
internalclientset
.
NewForConfigOrDie
(
c
.
Config
.
GenericConfig
.
LoopbackClientConfig
),
internalclientset
.
NewForConfigOrDie
(
c
.
Config
.
GenericConfig
.
LoopbackClientConfig
),
clientset
.
NewForConfigOrDie
(
c
.
Config
.
GenericConfig
.
LoopbackClientConfig
),
discovery
clientset
.
NewForConfigOrDie
(
c
.
Config
.
GenericConfig
.
LoopbackClientConfig
),
5
*
time
.
Minute
,
// this is effectively used as a refresh interval right now. Might want to do something nicer later on.
5
*
time
.
Minute
,
// this is effectively used as a refresh interval right now. Might want to do something nicer later on.
)
)
kubeInformers
:=
kubeinformers
.
NewSharedInformerFactory
(
nil
,
c
.
CoreAPIServerClient
,
5
*
time
.
Minute
)
proxyMux
:=
http
.
NewServeMux
()
proxyMux
:=
http
.
NewServeMux
()
// most API servers don't need to do this, but we need a custom handler chain to handle the special /apis handling here
// most API servers don't need to do this, but we need a custom handler chain to handle the special /apis handling here
c
.
Config
.
GenericConfig
.
BuildHandlerChainsFunc
=
(
&
handlerChainConfig
{
c
.
Config
.
GenericConfig
.
BuildHandlerChainsFunc
=
(
&
handlerChainConfig
{
informers
:
informerFactory
,
informers
:
informerFactory
,
proxyMux
:
proxyMux
,
proxyMux
:
proxyMux
,
serviceLister
:
kubeInformers
.
Core
()
.
V1
()
.
Services
()
.
Lister
(),
endpointsLister
:
kubeInformers
.
Core
()
.
V1
()
.
Endpoints
()
.
Lister
(),
})
.
handlerChain
})
.
handlerChain
genericServer
,
err
:=
c
.
Config
.
GenericConfig
.
SkipComplete
()
.
New
()
// completion is done in Complete, no need for a second time
genericServer
,
err
:=
c
.
Config
.
GenericConfig
.
SkipComplete
()
.
New
()
// completion is done in Complete, no need for a second time
...
@@ -124,6 +136,8 @@ func (c completedConfig) New() (*APIDiscoveryServer, error) {
...
@@ -124,6 +136,8 @@ func (c completedConfig) New() (*APIDiscoveryServer, error) {
proxyClientKey
:
c
.
ProxyClientKey
,
proxyClientKey
:
c
.
ProxyClientKey
,
proxyHandlers
:
map
[
string
]
*
proxyHandler
{},
proxyHandlers
:
map
[
string
]
*
proxyHandler
{},
lister
:
informerFactory
.
Apiregistration
()
.
InternalVersion
()
.
APIServices
()
.
Lister
(),
lister
:
informerFactory
.
Apiregistration
()
.
InternalVersion
()
.
APIServices
()
.
Lister
(),
serviceLister
:
kubeInformers
.
Core
()
.
V1
()
.
Services
()
.
Lister
(),
endpointsLister
:
kubeInformers
.
Core
()
.
V1
()
.
Endpoints
()
.
Lister
(),
proxyMux
:
proxyMux
,
proxyMux
:
proxyMux
,
}
}
...
@@ -141,6 +155,7 @@ func (c completedConfig) New() (*APIDiscoveryServer, error) {
...
@@ -141,6 +155,7 @@ func (c completedConfig) New() (*APIDiscoveryServer, error) {
s
.
GenericAPIServer
.
AddPostStartHook
(
"start-informers"
,
func
(
context
genericapiserver
.
PostStartHookContext
)
error
{
s
.
GenericAPIServer
.
AddPostStartHook
(
"start-informers"
,
func
(
context
genericapiserver
.
PostStartHookContext
)
error
{
informerFactory
.
Start
(
wait
.
NeverStop
)
informerFactory
.
Start
(
wait
.
NeverStop
)
kubeInformers
.
Start
(
wait
.
NeverStop
)
return
nil
return
nil
})
})
s
.
GenericAPIServer
.
AddPostStartHook
(
"apiservice-registration-controller"
,
func
(
context
genericapiserver
.
PostStartHookContext
)
error
{
s
.
GenericAPIServer
.
AddPostStartHook
(
"apiservice-registration-controller"
,
func
(
context
genericapiserver
.
PostStartHookContext
)
error
{
...
@@ -153,8 +168,10 @@ func (c completedConfig) New() (*APIDiscoveryServer, error) {
...
@@ -153,8 +168,10 @@ func (c completedConfig) New() (*APIDiscoveryServer, error) {
// handlerChainConfig is the config used to build the custom handler chain for this api server
// handlerChainConfig is the config used to build the custom handler chain for this api server
type
handlerChainConfig
struct
{
type
handlerChainConfig
struct
{
informers
informers
.
SharedInformerFactory
informers
informers
.
SharedInformerFactory
proxyMux
*
http
.
ServeMux
proxyMux
*
http
.
ServeMux
serviceLister
v1listers
.
ServiceLister
endpointsLister
v1listers
.
EndpointsLister
}
}
// handlerChain is a method to build the handler chain for this API server. We need a custom handler chain so that we
// handlerChain is a method to build the handler chain for this API server. We need a custom handler chain so that we
...
@@ -162,7 +179,7 @@ type handlerChainConfig struct {
...
@@ -162,7 +179,7 @@ type handlerChainConfig struct {
// the endpoints differently, since we're proxying all groups except for apiregistration.k8s.io.
// the endpoints differently, since we're proxying all groups except for apiregistration.k8s.io.
func
(
h
*
handlerChainConfig
)
handlerChain
(
apiHandler
http
.
Handler
,
c
*
genericapiserver
.
Config
)
(
secure
,
insecure
http
.
Handler
)
{
func
(
h
*
handlerChainConfig
)
handlerChain
(
apiHandler
http
.
Handler
,
c
*
genericapiserver
.
Config
)
(
secure
,
insecure
http
.
Handler
)
{
// add this as a filter so that we never collide with "already registered" failures on `/apis`
// add this as a filter so that we never collide with "already registered" failures on `/apis`
handler
:=
WithAPIs
(
apiHandler
,
h
.
informers
.
Apiregistration
()
.
InternalVersion
()
.
APIServices
())
handler
:=
WithAPIs
(
apiHandler
,
h
.
informers
.
Apiregistration
()
.
InternalVersion
()
.
APIServices
()
,
h
.
serviceLister
,
h
.
endpointsLister
)
handler
=
apiserverfilters
.
WithAuthorization
(
handler
,
c
.
RequestContextMapper
,
c
.
Authorizer
)
handler
=
apiserverfilters
.
WithAuthorization
(
handler
,
c
.
RequestContextMapper
,
c
.
Authorizer
)
...
@@ -223,8 +240,10 @@ func (s *APIDiscoveryServer) AddAPIService(apiService *apiregistration.APIServic
...
@@ -223,8 +240,10 @@ func (s *APIDiscoveryServer) AddAPIService(apiService *apiregistration.APIServic
// it's time to register the group discovery endpoint
// it's time to register the group discovery endpoint
groupPath
:=
"/apis/"
+
apiService
.
Spec
.
Group
groupPath
:=
"/apis/"
+
apiService
.
Spec
.
Group
groupDiscoveryHandler
:=
&
apiGroupHandler
{
groupDiscoveryHandler
:=
&
apiGroupHandler
{
groupName
:
apiService
.
Spec
.
Group
,
groupName
:
apiService
.
Spec
.
Group
,
lister
:
s
.
lister
,
lister
:
s
.
lister
,
serviceLister
:
s
.
serviceLister
,
endpointsLister
:
s
.
endpointsLister
,
}
}
// discovery is protected
// discovery is protected
s
.
GenericAPIServer
.
HandlerContainer
.
UnlistedRoutes
.
Handle
(
groupPath
,
groupDiscoveryHandler
)
s
.
GenericAPIServer
.
HandlerContainer
.
UnlistedRoutes
.
Handle
(
groupPath
,
groupDiscoveryHandler
)
...
...
cmd/kubernetes-discovery/pkg/apiserver/handler_apis.go
View file @
8f1677b7
...
@@ -24,6 +24,7 @@ import (
...
@@ -24,6 +24,7 @@ import (
apierrors
"k8s.io/kubernetes/pkg/api/errors"
apierrors
"k8s.io/kubernetes/pkg/api/errors"
metav1
"k8s.io/kubernetes/pkg/apis/meta/v1"
metav1
"k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/apiserver"
"k8s.io/kubernetes/pkg/apiserver"
v1listers
"k8s.io/kubernetes/pkg/client/listers/core/v1"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/runtime"
...
@@ -34,10 +35,12 @@ import (
...
@@ -34,10 +35,12 @@ import (
)
)
// WithAPIs adds the handling for /apis and /apis/<group: -apiregistration.k8s.io>.
// WithAPIs adds the handling for /apis and /apis/<group: -apiregistration.k8s.io>.
func
WithAPIs
(
handler
http
.
Handler
,
informer
informers
.
APIServiceInformer
)
http
.
Handler
{
func
WithAPIs
(
handler
http
.
Handler
,
informer
informers
.
APIServiceInformer
,
serviceLister
v1listers
.
ServiceLister
,
endpointsLister
v1listers
.
EndpointsLister
)
http
.
Handler
{
apisHandler
:=
&
apisHandler
{
apisHandler
:=
&
apisHandler
{
lister
:
informer
.
Lister
(),
lister
:
informer
.
Lister
(),
delegate
:
handler
,
delegate
:
handler
,
serviceLister
:
serviceLister
,
endpointsLister
:
endpointsLister
,
}
}
return
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
return
http
.
HandlerFunc
(
func
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
apisHandler
.
ServeHTTP
(
w
,
req
)
apisHandler
.
ServeHTTP
(
w
,
req
)
...
@@ -49,6 +52,9 @@ func WithAPIs(handler http.Handler, informer informers.APIServiceInformer) http.
...
@@ -49,6 +52,9 @@ func WithAPIs(handler http.Handler, informer informers.APIServiceInformer) http.
type
apisHandler
struct
{
type
apisHandler
struct
{
lister
listers
.
APIServiceLister
lister
listers
.
APIServiceLister
serviceLister
v1listers
.
ServiceLister
endpointsLister
v1listers
.
EndpointsLister
delegate
http
.
Handler
delegate
http
.
Handler
}
}
...
@@ -95,7 +101,10 @@ func (r *apisHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
...
@@ -95,7 +101,10 @@ func (r *apisHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if
len
(
apiGroupServers
[
0
]
.
Spec
.
Group
)
==
0
{
if
len
(
apiGroupServers
[
0
]
.
Spec
.
Group
)
==
0
{
continue
continue
}
}
discoveryGroupList
.
Groups
=
append
(
discoveryGroupList
.
Groups
,
*
newDiscoveryAPIGroup
(
apiGroupServers
))
discoveryGroup
:=
convertToDiscoveryAPIGroup
(
apiGroupServers
,
r
.
serviceLister
,
r
.
endpointsLister
)
if
discoveryGroup
!=
nil
{
discoveryGroupList
.
Groups
=
append
(
discoveryGroupList
.
Groups
,
*
discoveryGroup
)
}
}
}
json
,
err
:=
runtime
.
Encode
(
api
.
Codecs
.
LegacyCodec
(),
discoveryGroupList
)
json
,
err
:=
runtime
.
Encode
(
api
.
Codecs
.
LegacyCodec
(),
discoveryGroupList
)
...
@@ -108,18 +117,46 @@ func (r *apisHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
...
@@ -108,18 +117,46 @@ func (r *apisHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
}
}
}
}
func
newDiscoveryAPIGroup
(
apiServices
[]
*
apiregistrationapi
.
APIService
)
*
metav1
.
APIGroup
{
// convertToDiscoveryAPIGroup takes apiservices in a single group and returns a discovery compatible object.
// if none of the services are available, it will return nil.
func
convertToDiscoveryAPIGroup
(
apiServices
[]
*
apiregistrationapi
.
APIService
,
serviceLister
v1listers
.
ServiceLister
,
endpointsLister
v1listers
.
EndpointsLister
)
*
metav1
.
APIGroup
{
apiServicesByGroup
:=
apiregistrationapi
.
SortedByGroup
(
apiServices
)[
0
]
apiServicesByGroup
:=
apiregistrationapi
.
SortedByGroup
(
apiServices
)[
0
]
discoveryGroup
:=
&
metav1
.
APIGroup
{
var
discoveryGroup
*
metav1
.
APIGroup
Name
:
apiServicesByGroup
[
0
]
.
Spec
.
Group
,
PreferredVersion
:
metav1
.
GroupVersionForDiscovery
{
GroupVersion
:
apiServicesByGroup
[
0
]
.
Spec
.
Group
+
"/"
+
apiServicesByGroup
[
0
]
.
Spec
.
Version
,
Version
:
apiServicesByGroup
[
0
]
.
Spec
.
Version
,
},
}
for
_
,
apiService
:=
range
apiServicesByGroup
{
for
_
,
apiService
:=
range
apiServicesByGroup
{
// skip any API services without actual services
if
_
,
err
:=
serviceLister
.
Services
(
apiService
.
Spec
.
Service
.
Namespace
)
.
Get
(
apiService
.
Spec
.
Service
.
Name
);
err
!=
nil
{
continue
}
hasActiveEndpoints
:=
false
endpoints
,
err
:=
endpointsLister
.
Endpoints
(
apiService
.
Spec
.
Service
.
Namespace
)
.
Get
(
apiService
.
Spec
.
Service
.
Name
)
// skip any API services without endpoints
if
err
!=
nil
{
continue
}
for
_
,
subset
:=
range
endpoints
.
Subsets
{
if
len
(
subset
.
Addresses
)
>
0
{
hasActiveEndpoints
=
true
break
}
}
if
!
hasActiveEndpoints
{
continue
}
// the first APIService which is valid becomes the default
if
discoveryGroup
==
nil
{
discoveryGroup
=
&
metav1
.
APIGroup
{
Name
:
apiService
.
Spec
.
Group
,
PreferredVersion
:
metav1
.
GroupVersionForDiscovery
{
GroupVersion
:
apiService
.
Spec
.
Group
+
"/"
+
apiService
.
Spec
.
Version
,
Version
:
apiService
.
Spec
.
Version
,
},
}
}
discoveryGroup
.
Versions
=
append
(
discoveryGroup
.
Versions
,
discoveryGroup
.
Versions
=
append
(
discoveryGroup
.
Versions
,
metav1
.
GroupVersionForDiscovery
{
metav1
.
GroupVersionForDiscovery
{
GroupVersion
:
apiService
.
Spec
.
Group
+
"/"
+
apiService
.
Spec
.
Version
,
GroupVersion
:
apiService
.
Spec
.
Group
+
"/"
+
apiService
.
Spec
.
Version
,
...
@@ -136,6 +173,9 @@ type apiGroupHandler struct {
...
@@ -136,6 +173,9 @@ type apiGroupHandler struct {
groupName
string
groupName
string
lister
listers
.
APIServiceLister
lister
listers
.
APIServiceLister
serviceLister
v1listers
.
ServiceLister
endpointsLister
v1listers
.
EndpointsLister
}
}
func
(
r
*
apiGroupHandler
)
ServeHTTP
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
func
(
r
*
apiGroupHandler
)
ServeHTTP
(
w
http
.
ResponseWriter
,
req
*
http
.
Request
)
{
...
@@ -167,7 +207,12 @@ func (r *apiGroupHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
...
@@ -167,7 +207,12 @@ func (r *apiGroupHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
return
}
}
json
,
err
:=
runtime
.
Encode
(
api
.
Codecs
.
LegacyCodec
(),
newDiscoveryAPIGroup
(
apiServicesForGroup
))
discoveryGroup
:=
convertToDiscoveryAPIGroup
(
apiServicesForGroup
,
r
.
serviceLister
,
r
.
endpointsLister
)
if
discoveryGroup
==
nil
{
http
.
Error
(
w
,
""
,
http
.
StatusNotFound
)
return
}
json
,
err
:=
runtime
.
Encode
(
api
.
Codecs
.
LegacyCodec
(),
discoveryGroup
)
if
err
!=
nil
{
if
err
!=
nil
{
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusInternalServerError
)
http
.
Error
(
w
,
err
.
Error
(),
http
.
StatusInternalServerError
)
return
return
...
...
cmd/kubernetes-discovery/pkg/apiserver/handler_apis_test.go
View file @
8f1677b7
...
@@ -24,8 +24,10 @@ import (
...
@@ -24,8 +24,10 @@ import (
"testing"
"testing"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
corev1
"k8s.io/kubernetes/pkg/api/v1"
metav1
"k8s.io/kubernetes/pkg/apis/meta/v1"
metav1
"k8s.io/kubernetes/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/client/cache"
"k8s.io/kubernetes/pkg/client/cache"
v1listers
"k8s.io/kubernetes/pkg/client/listers/core/v1"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/util/diff"
"k8s.io/kubernetes/pkg/util/diff"
...
@@ -111,6 +113,10 @@ func TestAPIs(t *testing.T) {
...
@@ -111,6 +113,10 @@ func TestAPIs(t *testing.T) {
{
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v1.foo"
},
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v1.foo"
},
Spec
:
apiregistration
.
APIServiceSpec
{
Spec
:
apiregistration
.
APIServiceSpec
{
Service
:
apiregistration
.
ServiceReference
{
Namespace
:
"ns"
,
Name
:
"api"
,
},
Group
:
"foo"
,
Group
:
"foo"
,
Version
:
"v1"
,
Version
:
"v1"
,
Priority
:
10
,
Priority
:
10
,
...
@@ -119,6 +125,10 @@ func TestAPIs(t *testing.T) {
...
@@ -119,6 +125,10 @@ func TestAPIs(t *testing.T) {
{
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v1.bar"
},
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v1.bar"
},
Spec
:
apiregistration
.
APIServiceSpec
{
Spec
:
apiregistration
.
APIServiceSpec
{
Service
:
apiregistration
.
ServiceReference
{
Namespace
:
"ns"
,
Name
:
"api"
,
},
Group
:
"bar"
,
Group
:
"bar"
,
Version
:
"v1"
,
Version
:
"v1"
,
Priority
:
11
,
Priority
:
11
,
...
@@ -164,6 +174,10 @@ func TestAPIs(t *testing.T) {
...
@@ -164,6 +174,10 @@ func TestAPIs(t *testing.T) {
{
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v1.foo"
},
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v1.foo"
},
Spec
:
apiregistration
.
APIServiceSpec
{
Spec
:
apiregistration
.
APIServiceSpec
{
Service
:
apiregistration
.
ServiceReference
{
Namespace
:
"ns"
,
Name
:
"api"
,
},
Group
:
"foo"
,
Group
:
"foo"
,
Version
:
"v1"
,
Version
:
"v1"
,
Priority
:
20
,
Priority
:
20
,
...
@@ -172,6 +186,10 @@ func TestAPIs(t *testing.T) {
...
@@ -172,6 +186,10 @@ func TestAPIs(t *testing.T) {
{
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v2.bar"
},
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v2.bar"
},
Spec
:
apiregistration
.
APIServiceSpec
{
Spec
:
apiregistration
.
APIServiceSpec
{
Service
:
apiregistration
.
ServiceReference
{
Namespace
:
"ns"
,
Name
:
"api"
,
},
Group
:
"bar"
,
Group
:
"bar"
,
Version
:
"v2"
,
Version
:
"v2"
,
Priority
:
11
,
Priority
:
11
,
...
@@ -180,6 +198,10 @@ func TestAPIs(t *testing.T) {
...
@@ -180,6 +198,10 @@ func TestAPIs(t *testing.T) {
{
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v2.foo"
},
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v2.foo"
},
Spec
:
apiregistration
.
APIServiceSpec
{
Spec
:
apiregistration
.
APIServiceSpec
{
Service
:
apiregistration
.
ServiceReference
{
Namespace
:
"ns"
,
Name
:
"api"
,
},
Group
:
"foo"
,
Group
:
"foo"
,
Version
:
"v2"
,
Version
:
"v2"
,
Priority
:
1
,
Priority
:
1
,
...
@@ -188,6 +210,10 @@ func TestAPIs(t *testing.T) {
...
@@ -188,6 +210,10 @@ func TestAPIs(t *testing.T) {
{
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v1.bar"
},
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v1.bar"
},
Spec
:
apiregistration
.
APIServiceSpec
{
Spec
:
apiregistration
.
APIServiceSpec
{
Service
:
apiregistration
.
ServiceReference
{
Namespace
:
"ns"
,
Name
:
"api"
,
},
Group
:
"bar"
,
Group
:
"bar"
,
Version
:
"v1"
,
Version
:
"v1"
,
Priority
:
11
,
Priority
:
11
,
...
@@ -239,14 +265,26 @@ func TestAPIs(t *testing.T) {
...
@@ -239,14 +265,26 @@ func TestAPIs(t *testing.T) {
for
_
,
tc
:=
range
tests
{
for
_
,
tc
:=
range
tests
{
indexer
:=
cache
.
NewIndexer
(
cache
.
MetaNamespaceKeyFunc
,
cache
.
Indexers
{
cache
.
NamespaceIndex
:
cache
.
MetaNamespaceIndexFunc
})
indexer
:=
cache
.
NewIndexer
(
cache
.
MetaNamespaceKeyFunc
,
cache
.
Indexers
{
cache
.
NamespaceIndex
:
cache
.
MetaNamespaceIndexFunc
})
serviceIndexer
:=
cache
.
NewIndexer
(
cache
.
MetaNamespaceKeyFunc
,
cache
.
Indexers
{
cache
.
NamespaceIndex
:
cache
.
MetaNamespaceIndexFunc
})
endpointsIndexer
:=
cache
.
NewIndexer
(
cache
.
MetaNamespaceKeyFunc
,
cache
.
Indexers
{
cache
.
NamespaceIndex
:
cache
.
MetaNamespaceIndexFunc
})
delegate
:=
&
delegationHTTPHandler
{}
delegate
:=
&
delegationHTTPHandler
{}
handler
:=
&
apisHandler
{
handler
:=
&
apisHandler
{
lister
:
listers
.
NewAPIServiceLister
(
indexer
),
serviceLister
:
v1listers
.
NewServiceLister
(
serviceIndexer
),
delegate
:
delegate
,
endpointsLister
:
v1listers
.
NewEndpointsLister
(
endpointsIndexer
),
lister
:
listers
.
NewAPIServiceLister
(
indexer
),
delegate
:
delegate
,
}
}
for
_
,
o
:=
range
tc
.
apiservices
{
for
_
,
o
:=
range
tc
.
apiservices
{
indexer
.
Add
(
o
)
indexer
.
Add
(
o
)
}
}
serviceIndexer
.
Add
(
&
corev1
.
Service
{
ObjectMeta
:
corev1
.
ObjectMeta
{
Namespace
:
"ns"
,
Name
:
"api"
}})
endpointsIndexer
.
Add
(
&
corev1
.
Endpoints
{
ObjectMeta
:
corev1
.
ObjectMeta
{
Namespace
:
"ns"
,
Name
:
"api"
},
Subsets
:
[]
corev1
.
EndpointSubset
{
{
Addresses
:
[]
corev1
.
EndpointAddress
{{}}},
},
},
)
server
:=
httptest
.
NewServer
(
handler
)
server
:=
httptest
.
NewServer
(
handler
)
defer
server
.
Close
()
defer
server
.
Close
()
...
@@ -316,6 +354,10 @@ func TestAPIGroup(t *testing.T) {
...
@@ -316,6 +354,10 @@ func TestAPIGroup(t *testing.T) {
{
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v1.foo"
},
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v1.foo"
},
Spec
:
apiregistration
.
APIServiceSpec
{
Spec
:
apiregistration
.
APIServiceSpec
{
Service
:
apiregistration
.
ServiceReference
{
Namespace
:
"ns"
,
Name
:
"api"
,
},
Group
:
"foo"
,
Group
:
"foo"
,
Version
:
"v1"
,
Version
:
"v1"
,
Priority
:
20
,
Priority
:
20
,
...
@@ -324,6 +366,10 @@ func TestAPIGroup(t *testing.T) {
...
@@ -324,6 +366,10 @@ func TestAPIGroup(t *testing.T) {
{
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v2.bar"
},
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v2.bar"
},
Spec
:
apiregistration
.
APIServiceSpec
{
Spec
:
apiregistration
.
APIServiceSpec
{
Service
:
apiregistration
.
ServiceReference
{
Namespace
:
"ns"
,
Name
:
"api"
,
},
Group
:
"bar"
,
Group
:
"bar"
,
Version
:
"v2"
,
Version
:
"v2"
,
Priority
:
11
,
Priority
:
11
,
...
@@ -332,6 +378,10 @@ func TestAPIGroup(t *testing.T) {
...
@@ -332,6 +378,10 @@ func TestAPIGroup(t *testing.T) {
{
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v2.foo"
},
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v2.foo"
},
Spec
:
apiregistration
.
APIServiceSpec
{
Spec
:
apiregistration
.
APIServiceSpec
{
Service
:
apiregistration
.
ServiceReference
{
Namespace
:
"ns"
,
Name
:
"api"
,
},
Group
:
"foo"
,
Group
:
"foo"
,
Version
:
"v2"
,
Version
:
"v2"
,
Priority
:
1
,
Priority
:
1
,
...
@@ -340,6 +390,10 @@ func TestAPIGroup(t *testing.T) {
...
@@ -340,6 +390,10 @@ func TestAPIGroup(t *testing.T) {
{
{
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v1.bar"
},
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"v1.bar"
},
Spec
:
apiregistration
.
APIServiceSpec
{
Spec
:
apiregistration
.
APIServiceSpec
{
Service
:
apiregistration
.
ServiceReference
{
Namespace
:
"ns"
,
Name
:
"api"
,
},
Group
:
"bar"
,
Group
:
"bar"
,
Version
:
"v1"
,
Version
:
"v1"
,
Priority
:
11
,
Priority
:
11
,
...
@@ -369,13 +423,25 @@ func TestAPIGroup(t *testing.T) {
...
@@ -369,13 +423,25 @@ func TestAPIGroup(t *testing.T) {
for
_
,
tc
:=
range
tests
{
for
_
,
tc
:=
range
tests
{
indexer
:=
cache
.
NewIndexer
(
cache
.
MetaNamespaceKeyFunc
,
cache
.
Indexers
{
cache
.
NamespaceIndex
:
cache
.
MetaNamespaceIndexFunc
})
indexer
:=
cache
.
NewIndexer
(
cache
.
MetaNamespaceKeyFunc
,
cache
.
Indexers
{
cache
.
NamespaceIndex
:
cache
.
MetaNamespaceIndexFunc
})
serviceIndexer
:=
cache
.
NewIndexer
(
cache
.
MetaNamespaceKeyFunc
,
cache
.
Indexers
{
cache
.
NamespaceIndex
:
cache
.
MetaNamespaceIndexFunc
})
endpointsIndexer
:=
cache
.
NewIndexer
(
cache
.
MetaNamespaceKeyFunc
,
cache
.
Indexers
{
cache
.
NamespaceIndex
:
cache
.
MetaNamespaceIndexFunc
})
handler
:=
&
apiGroupHandler
{
handler
:=
&
apiGroupHandler
{
lister
:
listers
.
NewAPIServiceLister
(
indexer
),
lister
:
listers
.
NewAPIServiceLister
(
indexer
),
groupName
:
"foo"
,
serviceLister
:
v1listers
.
NewServiceLister
(
serviceIndexer
),
endpointsLister
:
v1listers
.
NewEndpointsLister
(
endpointsIndexer
),
groupName
:
"foo"
,
}
}
for
_
,
o
:=
range
tc
.
apiservices
{
for
_
,
o
:=
range
tc
.
apiservices
{
indexer
.
Add
(
o
)
indexer
.
Add
(
o
)
}
}
serviceIndexer
.
Add
(
&
corev1
.
Service
{
ObjectMeta
:
corev1
.
ObjectMeta
{
Namespace
:
"ns"
,
Name
:
"api"
}})
endpointsIndexer
.
Add
(
&
corev1
.
Endpoints
{
ObjectMeta
:
corev1
.
ObjectMeta
{
Namespace
:
"ns"
,
Name
:
"api"
},
Subsets
:
[]
corev1
.
EndpointSubset
{
{
Addresses
:
[]
corev1
.
EndpointAddress
{{}}},
},
},
)
server
:=
httptest
.
NewServer
(
handler
)
server
:=
httptest
.
NewServer
(
handler
)
defer
server
.
Close
()
defer
server
.
Close
()
...
@@ -386,8 +452,8 @@ func TestAPIGroup(t *testing.T) {
...
@@ -386,8 +452,8 @@ func TestAPIGroup(t *testing.T) {
continue
continue
}
}
if
resp
.
StatusCode
!=
http
.
StatusOK
{
if
resp
.
StatusCode
!=
http
.
StatusOK
{
httputil
.
DumpResponse
(
resp
,
true
)
response
,
_
:=
httputil
.
DumpResponse
(
resp
,
true
)
t
.
Errorf
(
"%s
"
,
tc
.
name
)
t
.
Errorf
(
"%s
: %v"
,
tc
.
name
,
string
(
response
)
)
continue
continue
}
}
bytes
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
bytes
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
...
...
cmd/kubernetes-discovery/pkg/cmd/server/BUILD
View file @
8f1677b7
...
@@ -16,6 +16,8 @@ go_library(
...
@@ -16,6 +16,8 @@ go_library(
"//cmd/kubernetes-discovery/pkg/apiserver:go_default_library",
"//cmd/kubernetes-discovery/pkg/apiserver:go_default_library",
"//cmd/kubernetes-discovery/pkg/legacy:go_default_library",
"//cmd/kubernetes-discovery/pkg/legacy:go_default_library",
"//pkg/api:go_default_library",
"//pkg/api:go_default_library",
"//pkg/client/clientset_generated/clientset:go_default_library",
"//pkg/client/restclient:go_default_library",
"//pkg/genericapiserver:go_default_library",
"//pkg/genericapiserver:go_default_library",
"//pkg/genericapiserver/filters:go_default_library",
"//pkg/genericapiserver/filters:go_default_library",
"//pkg/genericapiserver/options:go_default_library",
"//pkg/genericapiserver/options:go_default_library",
...
...
cmd/kubernetes-discovery/pkg/cmd/server/start.go
View file @
8f1677b7
...
@@ -27,6 +27,8 @@ import (
...
@@ -27,6 +27,8 @@ import (
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apiserver"
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/apiserver"
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/legacy"
"k8s.io/kubernetes/cmd/kubernetes-discovery/pkg/legacy"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api"
kubeclientset
"k8s.io/kubernetes/pkg/client/clientset_generated/clientset"
"k8s.io/kubernetes/pkg/client/restclient"
"k8s.io/kubernetes/pkg/genericapiserver"
"k8s.io/kubernetes/pkg/genericapiserver"
"k8s.io/kubernetes/pkg/genericapiserver/filters"
"k8s.io/kubernetes/pkg/genericapiserver/filters"
genericoptions
"k8s.io/kubernetes/pkg/genericapiserver/options"
genericoptions
"k8s.io/kubernetes/pkg/genericapiserver/options"
...
@@ -135,9 +137,19 @@ func (o DiscoveryServerOptions) RunDiscoveryServer() error {
...
@@ -135,9 +137,19 @@ func (o DiscoveryServerOptions) RunDiscoveryServer() error {
return
err
return
err
}
}
kubeconfig
,
err
:=
restclient
.
InClusterConfig
()
if
err
!=
nil
{
return
err
}
coreAPIServerClient
,
err
:=
kubeclientset
.
NewForConfig
(
kubeconfig
)
if
err
!=
nil
{
return
err
}
config
:=
apiserver
.
Config
{
config
:=
apiserver
.
Config
{
GenericConfig
:
genericAPIServerConfig
,
GenericConfig
:
genericAPIServerConfig
,
RESTOptionsGetter
:
&
restOptionsFactory
{
storageConfig
:
&
o
.
Etcd
.
StorageConfig
},
RESTOptionsGetter
:
&
restOptionsFactory
{
storageConfig
:
&
o
.
Etcd
.
StorageConfig
},
CoreAPIServerClient
:
coreAPIServerClient
,
}
}
config
.
ProxyClientCert
,
err
=
ioutil
.
ReadFile
(
o
.
ProxyClientCertFile
)
config
.
ProxyClientCert
,
err
=
ioutil
.
ReadFile
(
o
.
ProxyClientCertFile
)
...
...
hack/local-up-discovery.sh
View file @
8f1677b7
...
@@ -59,7 +59,9 @@ function start_discovery {
...
@@ -59,7 +59,9 @@ function start_discovery {
# grant permission to run delegated authentication and authorization checks
# grant permission to run delegated authentication and authorization checks
kubectl_core delete clusterrolebinding discovery:system:auth-delegator
>
/dev/null 2>&1
||
true
kubectl_core delete clusterrolebinding discovery:system:auth-delegator
>
/dev/null 2>&1
||
true
kubectl_core delete clusterrolebinding discovery:system:kubernetes-discovery
>
/dev/null 2>&1
||
true
kubectl_core create clusterrolebinding discovery:system:auth-delegator
--clusterrole
=
system:auth-delegator
--serviceaccount
=
kube-public:kubernetes-discovery
kubectl_core create clusterrolebinding discovery:system:auth-delegator
--clusterrole
=
system:auth-delegator
--serviceaccount
=
kube-public:kubernetes-discovery
kubectl_core create clusterrolebinding discovery:system:kubernetes-discovery
--clusterrole
=
system:kubernetes-discovery
--serviceaccount
=
kube-public:kubernetes-discovery
# make sure the resources we're about to create don't exist
# make sure the resources we're about to create don't exist
kubectl_core
-n
kube-public delete secret auth-proxy-client serving-etcd serving-discovery discovery-etcd
>
/dev/null 2>&1
||
true
kubectl_core
-n
kube-public delete secret auth-proxy-client serving-etcd serving-discovery discovery-etcd
>
/dev/null 2>&1
||
true
...
...
plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go
View file @
8f1677b7
...
@@ -231,6 +231,14 @@ func ClusterRoles() []rbac.ClusterRole {
...
@@ -231,6 +231,14 @@ func ClusterRoles() []rbac.ClusterRole {
},
},
},
},
{
{
// a role to use for the API registry, summarization, and proxy handling
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"system:kubernetes-discovery"
},
Rules
:
[]
rbac
.
PolicyRule
{
// it needs to see all services so that it knows whether the ones it points to exist or not
rbac
.
NewRule
(
Read
...
)
.
Groups
(
legacyGroup
)
.
Resources
(
"services"
,
"endpoints"
)
.
RuleOrDie
(),
},
},
{
// a role to use for bootstrapping the kube-controller-manager so it can create the shared informers
// a role to use for bootstrapping the kube-controller-manager so it can create the shared informers
// service accounts, and secrets that we need to create separate identities for other controllers
// service accounts, and secrets that we need to create separate identities for other controllers
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"system:kube-controller-manager"
},
ObjectMeta
:
api
.
ObjectMeta
{
Name
:
"system:kube-controller-manager"
},
...
...
plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-roles.yaml
View file @
8f1677b7
...
@@ -475,6 +475,24 @@ items:
...
@@ -475,6 +475,24 @@ items:
creationTimestamp
:
null
creationTimestamp
:
null
labels
:
labels
:
kubernetes.io/bootstrapping
:
rbac-defaults
kubernetes.io/bootstrapping
:
rbac-defaults
name
:
system:kubernetes-discovery
rules
:
-
apiGroups
:
-
"
"
attributeRestrictions
:
null
resources
:
-
endpoints
-
services
verbs
:
-
get
-
list
-
watch
-
apiVersion
:
rbac.authorization.k8s.io/v1alpha1
kind
:
ClusterRole
metadata
:
creationTimestamp
:
null
labels
:
kubernetes.io/bootstrapping
:
rbac-defaults
name
:
system:node
name
:
system:node
rules
:
rules
:
-
apiGroups
:
-
apiGroups
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment