Question
We run Ververica Platform on Amazon EKS. For security reasons, my organization does not allow to access Amazon S3 based on credentials, nor based on EKS NodeInstanceRole. How can I configure Ververica Platform to allow platform pods and job pods to access Amazon S3 via IAM Role for Service Account (IRSA)?
Answer
Note: This section applies to Ververica Platform 2.4.3 (or later) and 2.5.1 (or later), combing with the Flink image 1.12.5-stream1 (or later) or 1.13.2-stream1 (or later).
Prerequisite
To access S3 (or other AWS resources) via IRSA, your EKS cluster must have an IAM OIDC Provider enabled. Follow this AWS doc if you have not enabled it.
Note: the remainder of the article uses the following variables:
- `$clusterName`: the name of the EKS cluster
- `$vvpNamespace`: the Kubernetes namespace where Ververica Platform runs
- `$jobNamespace`: the Kubernetes namespace where Ververica Platform deployments run
Create a Service Account in `$vvpNamespace` and attach an IAM Role
Run the following command to create a service account in `$vvpNamespace` and attach an IAM policy to it:
eksctl create iamserviceaccount \ --namespace $vvpNamespace \ --name vvp-sa \ --cluster $clusterName \ --attach-policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess \ --role-name vvp-full-s3-access \ --approve
If you already have an existing service account that you want to use, use the option `--override-existing-serviceaccounts` with the command.
Note: this command attaches the policy `AmazonS3FullAccess` to the service account. If desired, you can attach a policy that has the least and necessary privileges.
Configure Ververica Platform to Use the Service Account
Now you need to tell Ververica Platform to use this service account. To do so, create a Helm Values file:
rbac: create: false serviceAccountName: vvp-sa
then run:
helm upgrade --install vvp ververica/ververica-platform --version <version>
--namespace $vvpNamespace
--values <the Values file above>
... <any other options/Values files you need>
In order to allow this service account to create and manage job pods in `$jobNamespace`, you need to run the following commands, which are otherwise done automatically during Ververica Platform installation when `rbac.create` is set to `true`.
# create a Kubernetes role "vvp-role" in $jobNamespace cat << EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: vvp-role namespace: $jobNamespace rules: - apiGroups: [ "apps", "extensions" ] resources: [ "deployments" ] verbs: [ "create", "delete", "get", "list", "patch", "update", "watch" ] - apiGroups: [ "" ] resources: [ "configmaps", "pods", "services", "secrets", "serviceaccounts" ] verbs: [ "create", "delete", "get", "list", "patch", "update", "watch" ] - apiGroups: [ "batch" ] resources: [ "jobs" ] verbs: [ "create", "delete", "get", "list", "patch", "update", "watch" ] - apiGroups: [ "rbac.authorization.k8s.io" ] resources: [ "roles", "rolebindings" ] verbs: [ "create", "delete", "get", "list", "patch", "update", "watch" ] EOF # and bind it to the service account in $vvpNamespace cat << EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: vvp-rolebind namespace: $jobNamespace roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: vvp-role subjects: - kind: ServiceAccount name: vvp-sa namespace: $vvpNamespace EOF
Create a Service Account in `$jobNamespace` and attach an IAM Role
Since the Flink job pods also need to access S3 (e.g., to download job artifacts, create checkpoints/savepoints, or write job results), similarly, you need to have a service account in `$jobNamespace` and attach an IAM role to it:
eksctl create iamserviceaccount \ --namespace $jobNamespace \ --name flink-sa \ --cluster $clusterName \ --attach-policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess \ --role-name flink-full-s3-access \ --approve
In order for Kubernetes HA to work, the service account in `$jobNamespace` requires permissions to access Kubernetes ConfigMaps. To grant the permission:
# create a Kubernetes role in $jobNamespace cat << EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: flink-role namespace: $jobNamespace rules: - apiGroups: [ "" ] resources: [ "configmaps"] verbs: [ "create", "delete", "get", "list", "patch", "update", "watch" ] EOF # and bind it to the service account in $jobNamespace cat << EOF | kubectl apply -f - apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: flink-rolebind namespace: $jobNamespace roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: flink-role subjects: - kind: ServiceAccount name: flink-sa namespace: $jobNamespace EOF
Configure Ververica Platform Deployments to Use the Service Account
With the service account created in `$jobNamespace`, you can configure now Ververica Platform deployments to use it by adding the following into the deployment spec:
# set the service account in deployment spec: template: spec: kubernetes: jobManagerPodTemplate: spec: serviceAccountName: flink-sa taskManagerPodTemplate: spec: serviceAccountName: flink-sa
If your Flink job writes the job results to S3 (e.g., `s3a://bucket/path/object`) via StreamingFileSink using the flink-s3-fs-Hadoop dependency, you additionally need the following Flink configuration in your deployment spec:
fs.s3a.aws.credentials.provider: com.amazonaws.auth.WebIdentityTokenCredentialsProvider
Configure AWS SDK to use your regional STS service
If you need to use the AWS regional Security Token Service endpoint (e.g., sts.eu-central-1.amazonaws.com) because the global one (sts.amazonaws.com) is blocked in your environment for security reasons, please take the additional steps below:
1) Configure the S3 region for your blob storage:
vvp:
blobStorage:
baseUri: s3://vvp-bucket
s3:
region: eu-central-1
2) Add this annotation to the Service Account:
eks.amazonaws.com/sts-regional-endpoints=true
Debugging
If you still face issues, you can enable DEBUG logging by adding the following configuration into your helm chart:
topLevelConfig:
logging.level.com.dataartisans: DEBUG
logging.level.com.amazonaws: DEBUG
logging.level.com.ververica: DEBUG
logging.level.org.springframework: DEBUG
Warning: `topLevelConfig` is at the root level of the YAML file, it is not under `vvp`!
Note: These are VVP internals and may be changed in future versions of Ververica Platform.
Related Information
AWS Doc: Create an IAM OIDC provider for your cluster
AWS Blog: Introducing fine-grained IAM roles for service accounts
AWS Doc: AWS Security Token Service endpoints and quotas
Ververica Platform Doc: Flink Pod Templates
How to Turn on DEBUG Logging in Ververica Platform