spring-cloud / spring-cloud-dataflow

A microservices-based Streaming and Batch data processing in Cloud Foundry and Kubernetes
https://dataflow.spring.io
Apache License 2.0
1.11k stars 583 forks source link

Config "deploymentServiceAccountName" in spring-cloud-dataflow server is not used #4488

Closed klopfdreh closed 3 years ago

klopfdreh commented 3 years ago

Description: The property to configure the ServiceAccount which is used to spawn / list / etc. tasks within docker container in a kubernetes environment is not working properly.

Release versions: spring-cloud-dataflow-server:2.7.1

Custom apps:

Steps to reproduce: Use the kubernetes quick start and set the service account for tasks like in the following snippet:

  spring:
    cloud:
      dataflow:
          task:
            platform:
              kubernetes:
                accounts:
                  default:
                    deploymentServiceAccountName: MyServiceAccount
                    namespace: MyNamespace
                    imagePullPolicy: Always
                    limits:
                      cpu: 4

The server fails with the information

io.fabric8.kubernetes.client.KubernetesClientException: Failure executing: GET at: https://xx.xx.xx.xx/api/v1/namespaces/MyNamespace/pods/spring-cloud-data-flow-server-b545cf4f9-54ptn. Message: Forbidden!Configured service account doesn't have access. Service account may have been revoked. pods "spring-cloud-data-flow-server-b545cf4f9-54ptn" is forbidden: User "system:serviceaccount:MyNamespace:default" cannot get resource "pods" in API group "" in the namespace "MyNamespace".

As you can see in the error message the user is "default" instead of "MyServiceAccount".

The RoleBinding and the Role were configured correctly.

Screenshots:

Additional context: The error message above appears, because the default account doesn't have list permissions on Pods. Applying the admin role to the "default" user fixes this issue, showing that the actual configured MyServiceAccount is completely ignored.

Not working (with RoleBinding to a specific ServiceAccount)

...
subjects:
  - kind: ServiceAccount
    name: MyServiceAccount
    namespace: MyNamespace
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: admin
...

Working: (with RoleBinding to the default user "default")

...
subjects:
  - kind: ServiceAccount
    name: default
    namespace: MyServiceAccount
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: admin
...
chrisjs commented 3 years ago

i'm not able to reproduce this, using:

    Image:          springcloud/spring-cloud-dataflow-server:2.7.1 

and adding the following to server-config.yaml:

...
...
data:
  application.yaml: |-
    spring:
      cloud:
          task:
            platform:
              kubernetes:
                accounts:
                  default:
                    deploymentServiceAccountName: scdf-sa
...
...
...

i then added task docker apps to dataflow server, created a timestamp task and executed it. the task executed and completed as expected with the following service account that was set per above:

$ kubectl get pod/ts1-2jdel8wego -o yaml | grep -i serviceAccount
...
...
  serviceAccount: scdf-sa
  serviceAccountName: scdf-sa

if you have specific steps to reproduce, feel free to open but looks like everything is working as expected

klopfdreh commented 3 years ago

Hi @chrisjs / @sabbyanandan - have you also checked that the user which was configured in the pod was used to execute the operations? I also saw that it in the pod yaml when I launched the tasked, but it was not used for operations from the scdf which is the actual issue.

klopfdreh commented 3 years ago

After a lot of debugging we found out that the scdf server uses the service account the server itself was started with (at pod definition level) to call the k8s APIs. The deploymentServiceAccountName at the previous mentioned configuration level is only for the tasks themself.

Maybe it is worth to mention this in the documentation, but all is working like expected. 👍