Question

How to authorize a kubernetes service account without doctl?

So I am trying to launch to production via a popular CI tool, and I cannot yet understand why doctl is necessary. Can it be done without doctl? Here is my rationale and the issues I am facing.

My main motivation is that there some principle of giving the lowest amount of access as is necessary. A doctl API token has control over my whole DO account and I do not think it is wise to have that level of access on my CI. I would prefer to use some sort of Service Account as creating a service account and using the token to access the cluster should be doable and acceptable Kubernetes Authorization Docs.

Also, each time I download the config or when I create a new service account using the CLI a new DO API token is automatically generated. For the service accounts I do not get to see the secret token because I created the service account using the CLI. I figured that the token in the ClusterRoleBinding would work or be equivalent to the auto generated API token but it is not.

What is the right way to do this?

If it should be working here is what I am working with:

Using the handy download config options provided by DigitalOcean I have copied the format and inserted my service account name and base 64 decoded service account token (shown below). This kubeconfig file which I can encrypt and pass to my CI to use when making kubectl commands to my cluster. The problem is it hangs my CI asking for a UserName and Password. So…

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: <CADATA>
    server: <SERVER>
  name: <CLUSTERNAME>
contexts:
- context:
    cluster: <CLUSTERNAME>
    user: <CLUSTERNAME>-admin
  name: <CLUSTERNAME>
current-context: <CLUSTERNAME>
kind: Config
preferences: {}
users:
- name: <SERVICEACCOUNT-USERNAME>
  user:
    token: <BASE64 decoded SERVICE ACCOUNT Token>

So I rechecked my kubeconfig file on my desktop that is using doctl and found a few extra lines to add to this file. But now I am getting “Error: Unable to initialize DigitalOcean API client: access token is required. (hint: run ‘doctl auth init’)”

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: <CADATA>
    server: <SERVER>
  name: <CLUSTERNAME>
contexts:
- context:
    cluster: <CLUSTERNAME>
    user: <CLUSTERNAME>-admin
  name: <CLUSTERNAME>
current-context: <CLUSTERNAME>
kind: Config
preferences: {}
users:
- name: <CLUSTERNAME>-admin
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      args:
      - kubernetes
      - cluster
      - kubeconfig
      - exec-credential
      - --version=v1beta1
      - --context=default
      - <SERVERID>
      command: /home/<ME>/doctl
      env: null
      provideClusterInfo: false
- name: <SERVICEACCOUNT-USERNAME>
  user:
    token: <BASE64 decoded SERVICE ACCOUNT Token>

So any suggestions? Thanks in advance for your help.


Submit an answer


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Sign In or Sign Up to Answer

These answers are provided by our Community. If you find them useful, show some love by clicking the heart. If you run into issues leave a comment, or add your own answer to help others.

Andrew SB
DigitalOcean Employee
DigitalOcean Employee badge
February 19, 2021
Accepted Answer

I cannot yet understand why doctl is necessary. Can it be done without doctl?

doctl is not necessary to connect to a DigitalOcean managed Kubernetes cluster. It is just a tool used to download a kubeconfig file. If you already have a working one (e.g. downloaded from the control panel), you don’t need doctl.

each time I download the config or when I create a new service account using the CLI a new DO API token is automatically generated.

If you are worried about the number of tokens being generated, the doctl kubernetes cluster kubeconfig save takes an --expiry-seconds flag. This can be useful for creating short lived tokens for CI/CD.

Like @nabsul said, I think you were almost there. In addition to decoding the base64 encoded token and putting the decoded version in the token entry, it looks like you also need to adjust the username for the context:

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: <CADATA>
    server: <SERVER>
  name: <CLUSTERNAME>
contexts:
- context:
    cluster: <CLUSTERNAME>
    user: <CLUSTERNAME>-admin
  name: <CLUSTERNAME>
current-context: <CLUSTERNAME>
kind: Config
preferences: {}
users:
- name: <SERVICEACCOUNT-USERNAME>
  user:
    token: <BASE64 decoded SERVICE ACCOUNT Token>

Rather than the admin user, you want the service account user. The highlighted fields should match.

In GitHub actions you just give the “Kubernetes set context” task the whole secret yaml and it handles the rest automatically.

However, I did a little experimenting, and I think I know the solution.

I think you were almost there. You just need to decode the base64 and put the decoded version in the token entry.

I’ve done this before for the purpose of using github actions deploy to my DO cluster. When you create a service account, there’s automatically a secret with the name format [accountname]-token-[somerandomstring].

You can use that secret to connect to the cluster. In the case of github actions I just needed to copy the whole yaml output. It might be a little different for you depending on what you’re using.

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel