I used the following config:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: api-role
namespace: default
labels:
app: tools-rbac
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: global-rolebinding
namespace: default
labels:
type: spring-app
subjects:
- kind: Group
name: system:serviceaccounts
apiGroup: rbac.authorization.k8s.io
namespace: default
roleRef:
kind: Role
name: api-role
apiGroup: ""
And got this exception:
2020-04-24 23:51:49.359 WARN 1 --- [ main] o.s.c.k.config.ConfigMapPropertySource : Can't read configMap with name: [ribbon-config] in namespace:[default]. Ignoring.
io.fabric8.kubernetes.client.KubernetesClientException: Operation: [get] for kind: [ConfigMap] with name: [ribbon-config] in namespace: [default] failed.
at io.fabric8.kubernetes.client.KubernetesClientException.launderThrowable(KubernetesClientException.java:64) ~[kubernetes-client-4.4.1.jar!/:na]
at io.fabric8.kubernetes.client.KubernetesClientException.launderThrowable(KubernetesClientException.java:72) ~[kubernetes-client-4.4.1.jar!/:na]
at io.fabric8.kubernetes.client.dsl.base.BaseOperation.getMandatory(BaseOperation.java:229) ~[kubernetes-client-4.4.1.jar!/:na]
at io.fabric8.kubernetes.client.dsl.base.BaseOperation.get(BaseOperation.java:162) ~[kubernetes-client-4.4.1.jar!/:na]
at org.springframework.cloud.kubernetes.config.ConfigMapPropertySource.getData(ConfigMapPropertySource.java:95) [spring-cloud-kubernetes-config-1.1.2.RELEASE.jar!/:1.1.2.RELEASE]
at org.springframework.cloud.kubernetes.config.ConfigMapPropertySource.<init>(ConfigMapPropertySource.java:76) [spring-cloud-kubernetes-config-1.1.2.RELEASE.jar!/:1.1.2.RELEASE]
at org.springframework.cloud.kubernetes.config.ConfigMapPropertySourceLocator.getMapPropertySourceForSingleConfigMap(ConfigMapPropertySourceLocator.java:95) [spring-cloud-kubernetes-config-1.1.2.RELEASE.jar!/:1.1.2.RELEASE]
at org.springframework.cloud.kubernetes.config.ConfigMapPropertySourceLocator.lambda$locate$0(ConfigMapPropertySourceLocator.java:78) [spring-cloud-kubernetes-config-1.1.2.RELEASE.jar!/:1.1.2.RELEASE]
at java.util.ArrayList.forEach(ArrayList.java:1257) ~[na:1.8.0_252]
at org.springframework.cloud.kubernetes.config.ConfigMapPropertySourceLocator.locate(ConfigMapPropertySourceLocator.java:77) [spring-cloud-kubernetes-config-1.1.2.RELEASE.jar!/:1.1.2.RELEASE]
at org.springframework.cloud.bootstrap.config.PropertySourceLocator.locateCollection(PropertySourceLocator.java:52) ~[spring-cloud-context-2.2.2.RELEASE.jar!/:2.2.2.RELEASE]
at org.springframework.cloud.bootstrap.config.PropertySourceLocator.locateCollection(PropertySourceLocator.java:47) ~[spring-cloud-context-2.2.2.RELEASE.jar!/:2.2.2.RELEASE]
at org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration.initialize(PropertySourceBootstrapConfiguration.java:97) ~[spring-cloud-context-2.2.2.RELEASE.jar!/:2.2.2.RELEASE]
at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:626) ~[spring-boot-2.2.6.RELEASE.jar!/:2.2.6.RELEASE]
at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:370) ~[spring-boot-2.2.6.RELEASE.jar!/:2.2.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:314) ~[spring-boot-2.2.6.RELEASE.jar!/:2.2.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[spring-boot-2.2.6.RELEASE.jar!/:2.2.6.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215) ~[spring-boot-2.2.6.RELEASE.jar!/:2.2.6.RELEASE]
at com.github.saphyra.apphub.service.platform.main_gateway.MainGatewayApplication.main(MainGatewayApplication.java:9) ~[classes!/:0.0.1-SNAPSHOT]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_252]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_252]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_252]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_252]
at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:48) ~[application.jar:0.0.1-SNAPSHOT]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:87) ~[application.jar:0.0.1-SNAPSHOT]
at org.springframework.boot.loader.Launcher.launch(Launcher.java:51) ~[application.jar:0.0.1-SNAPSHOT]
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:52) ~[application.jar:0.0.1-SNAPSHOT]
Caused by: java.net.SocketException: Broken pipe (Write failed)
at java.net.SocketOutputStream.socketWrite0(Native Method) ~[na:1.8.0_252]
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111) ~[na:1.8.0_252]
at java.net.SocketOutputStream.write(SocketOutputStream.java:155) ~[na:1.8.0_252]
at sun.security.ssl.OutputRecord.writeBuffer(OutputRecord.java:431) ~[na:1.8.0_252]
at sun.security.ssl.OutputRecord.write(OutputRecord.java:417) ~[na:1.8.0_252]
at sun.security.ssl.SSLSocketImpl.writeRecordInternal(SSLSocketImpl.java:894) ~[na:1.8.0_252]
at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:865) ~[na:1.8.0_252]
at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:123) ~[na:1.8.0_252]
at okio.Okio$1.write(Okio.java:79) ~[okio-1.17.2.jar!/:na]
at okio.AsyncTimeout$1.write(AsyncTimeout.java:180) ~[okio-1.17.2.jar!/:na]
at okio.RealBufferedSink.flush(RealBufferedSink.java:224) ~[okio-1.17.2.jar!/:na]
at okhttp3.internal.http2.Http2Writer.settings(Http2Writer.java:185) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.http2.Http2Connection.start(Http2Connection.java:531) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.http2.Http2Connection.start(Http2Connection.java:521) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.connection.RealConnection.startHttp2(RealConnection.java:315) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:304) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:185) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.java:224) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.java:108) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.java:88) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.connection.Transmitter.newExchange(Transmitter.java:169) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:41) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:94) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:88) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117) ~[okhttp-3.14.7.jar!/:na]
at io.fabric8.kubernetes.client.utils.BackwardsCompatibilityInterceptor.intercept(BackwardsCompatibilityInterceptor.java:119) ~[kubernetes-client-4.4.1.jar!/:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117) ~[okhttp-3.14.7.jar!/:na]
at io.fabric8.kubernetes.client.utils.ImpersonatorInterceptor.intercept(ImpersonatorInterceptor.java:68) ~[kubernetes-client-4.4.1.jar!/:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117) ~[okhttp-3.14.7.jar!/:na]
at io.fabric8.kubernetes.client.utils.HttpClientUtils.lambda$createHttpClient$3(HttpClientUtils.java:110) ~[kubernetes-client-4.4.1.jar!/:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:142) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:117) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:229) ~[okhttp-3.14.7.jar!/:na]
at okhttp3.RealCall.execute(RealCall.java:81) ~[okhttp-3.14.7.jar!/:na]
at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleResponse(OperationSupport.java:404) ~[kubernetes-client-4.4.1.jar!/:na]
at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleResponse(OperationSupport.java:365) ~[kubernetes-client-4.4.1.jar!/:na]
at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleGet(OperationSupport.java:330) ~[kubernetes-client-4.4.1.jar!/:na]
at io.fabric8.kubernetes.client.dsl.base.OperationSupport.handleGet(OperationSupport.java:311) ~[kubernetes-client-4.4.1.jar!/:na]
at io.fabric8.kubernetes.client.dsl.base.BaseOperation.handleGet(BaseOperation.java:810) ~[kubernetes-client-4.4.1.jar!/:na]
at io.fabric8.kubernetes.client.dsl.base.BaseOperation.getMandatory(BaseOperation.java:218) ~[kubernetes-client-4.4.1.jar!/:na]
... 24 common frames omitted
I also tried many other configurations, but could not find out what is wrong.
I'm using Minikube on Windows.
I'd appreciate a solution what works for random namespaces (My plan is to set up a namespace with a random name for testing purposes during the deployment)
EDIT: I changed to using ClusterRoles for cross-namespace solution:
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: global-config-role
rules:
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: global-config-binding
subjects:
- kind: Group
name: system:serviceaccounts
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: global-config-role
apiGroup: rbac.authorization.k8s.io
Command kubectl auth can-i get configmap --as=system:serviceaccount:default:default Returned true for both default and test-0 namespace.
Check the permission of the service account(default) used by spring boot app
kubectl auth can-i get configmap --as=system:serviceaccount:default:default -n default
If the above command returns true then permission is setup properly.Maybe then the spring boot app is not using the service account default
Edit:
As per the doc the role and rolebinding should be as below.
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: YOUR-NAME-SPACE
name: namespace-reader
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["configmaps", "pods", "services", "endpoints", "secrets"]
verbs: ["get", "list", "watch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: namespace-reader-binding
namespace: YOUR-NAME-SPACE
subjects:
- kind: ServiceAccount
name: default
apiGroup: ""
roleRef:
kind: Role
name: namespace-reader
apiGroup: ""