How to Run Tableau Server in GKE(Google Kubernetes Engine)


TL; DR: here are my notes to host a fully working Tableau Server in a GKE cluster. It’s not fully Kubernetes native but still I think it’s better than running as a VM. This is correct as of Dec 2023.

The Docker Container Image

There doesn’t seem to have an official docker image for Tableau Server. But there’s a guild to build the image yourself here. Basically you’d need to register a tableau.com account with your email, then you can download the files needed to build the image.

There’s a strange requirement though. When running the container setup tool, it will bail out if the system has less than 64GB of memory! This is probably inherited from its VM setup script and probably it can be hacked to ignore this requirement. But it’s even easier to just build the docker image from a big VM(if you don’t have a computer with 64GB of memory at home). In my case, I spun up a Centos 9 VM with 64GB memory in GCE(Google Compute Engine).

Also it’s a good idea to store the installation files in a GCS bucket, instead of in the VM directly, just in case you need to rebuild the VM. Files in the VM look like:

# in tableau-test dirctory
$ ls
tableau-server-2023-3-0.x86_64.rpm	     tableau-server-container-setup-tool-2023.3.0.tar.gz
postgresql-42.7.0.jar

# unpack the setup-tool
$ tar -xzvf tableau-server-container-setup-tool-2023.3.0.tar.gz
...
$ cd tableau-server-container-setup-tool-2023.3.0
# in tableau-test/tableau-server-container-setup-tool-2023.3.0
$ ./build-image  --accepteula -i ../tableau-server-2023-3-0.x86_64.rpm
...

After the image is built in the VM, it can then be tagged and pushed to an image repository such as Google Artifact Registry.

The Deployment

This part looks simple because a set of sample manifest files already exists here. Keep this in mind: The node for the Tableau server should have at least 64GB of memory, same reason as above.

I also made a few improvements on top of the official manifests:

# keep secrets in secrets
# in stateful set:
        containers:
        - envFrom:
          - secretRef:
              name: tableau-envs
              
# in the secret
data:
  LICENSE_KEY: ...
  TABLEAU_PASSWORD: ...
  TABLEAU_USERNAME: ...
  TSM_REMOTE_PASSWORD: ...
  TSM_REMOTE_USERNAME: ...

The Trouble

After the pod is running, I tried to connect to the admin UI on port 8850 via port forwarding

k port-forward tableau-0 8850:8850

Then I could access https://localhost:8850 in my browser, ignoring the TLS error of course as the cert is just a self-signed one. However I could not login using the TSM_REMOTE_USERNAME and TSM_REMOTE_PASSWORD combo I set as environment variables. Here are my troubleshooting steps:

# get an interactive shell
$ k exec -ti tableau-0 -- bash
[tableau@tableau-0 /]$ cd /docker
[tableau@tableau-0 docker]$ ls
alive-check	env		     install-process-manager  server-ready-check	   start-process-manager  user
config		external-repository  rpasswd		      single-service		   tmp
customer-files	install_fnp.log      run-tableau-server       stack-traces-from-coredumps  upgrade
# the start-process-manager is the entry-point script
# there's setup_remote_user function in the script which I think responsible to setup the TSM_REMOTE_USERNAME
# I had a look into setup_remote_user and found out it actually didn't do anything!

# in setup_remote_user
setup_remote_user() {
    # If the password is not set su command should be success irrespective of password passed.
    # If su command fails, it is assumed that password is set so return from function.
    dummy_password=""
    if ! echo "${dummy_password}" | su "${TSM_REMOTE_USERNAME}" -c true &> /dev/null ; then
        return
    fi
    ...
# it will always return because the user $TSM_REMOTE_USERNAME doesn't exist, lol

Since the container is running as an unprivileged user tableau I can’t run adduser on-the -fly. A quick hack is to add the user and set the password in the docker image during build stage. I know, it’s not ideal but it works.

# use the above image as the base
FROM gcr.io/my-gcp-project/tableau-server:20233.23.1017.0948
ARG TSM_REMOTE_PASSWORD='change-me'

USER root
ENV TSM_REMOTE_USERNAME=tsmadmin

RUN adduser -G tsmadmin ${TSM_REMOTE_USERNAME} && echo -e "${TSM_REMOTE_PASSWORD}\n${TSM_REMOTE_PASSWORD}\n\n" |passwd ${TSM_REMOTE_USERNAME}

# use a modified start-proccess-manager script with a dummy setup_remote_user function
COPY ./config/start-process-manager /docker/start-process-manager

USER tableau

Using this patched image, I could finally use the user name and password to login into the admin UI on port 8850.

🙂