Home > Back-end >  How to configure kubectl to act as a service account?
How to configure kubectl to act as a service account?

Time:05-27

I wish to run a Drone CI/CD pipeline on a Raspberry Pi, including a stage to update a Kubernetes Deployment. Unfortunately, all the pre-built solutions that I've found for doing so (e.g. 1, e.g. ) are not built for arm64 architecture, so I believe I need to build my own.

I am attempting to adapt the commands from here (see also README.md, which describes the authorization required), but my attempt to contact the cluster still fails with authorization problems:

$ cat service-account-definition.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: drone-demo-service-account
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: drone-demo-service-account-clusterrolebinding
subjects:
  - kind: ServiceAccount
    name: drone-demo-service-account
    namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

$ kubectl apply -f service-account-definition.yaml
serviceaccount/drone-demo-service-account created
clusterrolebinding.rbac.authorization.k8s.io/drone-demo-service-account-clusterrolebinding created

$ kubectl get serviceaccount drone-demo-service-account
NAME                         SECRETS   AGE
drone-demo-service-account   1         10s

$ kubectl get secret $(kubectl get secrets | grep 'drone-demo-service-account-token' | cut -f1 -d' ') -o jsonpath='{.data.ca\.crt}' > secrets/cert

$ head -c 10 secrets/cert
LS0tLS1CRU%

$ kubectl get secret $(kubectl get secrets | grep 'drone-demo-service-account-token' | cut -f1 -d' ') -o jsonpath='{.data.token}' | base64 > secrets/token

$ head -c 10 secrets/token
WlhsS2FHSk%

$ cat Dockerfile
FROM busybox

COPY . .
CMD ["./script.sh"]

$ cat script.sh
#!/bin/sh

server=$(cat secrets/server) # Pre-filled
cert=$(cat secrets/cert)
# Added this `tr` call, which is not present in the source I'm working from, after noticing that
# the file-content contains newlines
token=$(cat secrets/token | tr -d '\n')

echo "DEBUG: server is $server, cert is $(echo $cert | head -c 10)..., token is $(echo $token | head -c 10)..."

# Cannot depend on the binami/kubectl image (https://hub.docker.com/r/bitnami/kubectl), because
# it's not available for arm64 - https://github.com/bitnami/charts/issues/7305
wget https://storage.googleapis.com/kubernetes-release/release/v1.19.2/bin/linux/arm64/kubectl
chmod  x kubectl
./kubectl config set-credentials default --token=$token
echo $cert | base64 -d > ca.crt
./kubectl config set-cluster default --server=$server --certificate-authority=ca.crt
./kubectl config set-context default --cluster=default --user=default
./kubectl config use-context default
echo "Done with setup, now cat-ing .kube/config"
echo
cat $HOME/.kube/config
echo "Attempting to get pods"
echo
./kubectl get pods

$ docker build -t stack-overflow-testing . && docker run stack-overflow-testing
Sending build context to Docker daemon  10.75kB
Step 1/3 : FROM busybox
 ---> 3c277069c6ae
Step 2/3 : COPY . .
 ---> 74c6a132d255
Step 3/3 : CMD ["./script.sh"]
 ---> Running in dc55f33f74bb
Removing intermediate container dc55f33f74bb
 ---> dc68a5d6ba9b
Successfully built dc68a5d6ba9b
Successfully tagged stack-overflow-testing:latest
DEBUG: server is https://rassigma.avril:6443, cert is LS0tLS1CRU..., token is WlhsS2FHSk...
Connecting to storage.googleapis.com (142.250.188.16:443)
wget: note: TLS certificate validation not implemented
saving to 'kubectl'
kubectl               18% |*****                           | 7118k  0:00:04 ETA
kubectl               43% |*************                   | 16.5M  0:00:02 ETA
kubectl               68% |**********************          | 26.2M  0:00:01 ETA
kubectl               94% |******************************  | 35.8M  0:00:00 ETA
kubectl              100% |********************************| 38.0M  0:00:00 ETA
'kubectl' saved
User "default" set.
Cluster "default" set.
Context "default" created.
Switched to context "default".
Done with setup, now cat-ing .kube/config

apiVersion: v1
clusters:
- cluster:
    certificate-authority: /ca.crt
    server: https://rassigma.avril:6443
  name: default
contexts:
- context:
    cluster: default
    user: default
  name: default
current-context: default
kind: Config
preferences: {}
users:
- name: default
  user:
    token: WlhsS2FHSkhZM[...REDACTED]
Attempting to get pods

error: You must be logged in to the server (Unauthorized)

If I copy the ~/.kube/config from my laptop to the docker container, kubectl commands succeed as expected - so, this isn't a networking issue, just an authorization one. I do note that my laptop-based ~/.kube/config lists client-certificate-data and client-key-data rather than token under users: user:, but I suspect that's because my base config is recording a non-service-account.

How can I set up kubectl to authorize as a service account?

Some reading I have done that didn't answer the question for me:

CodePudding user response:

It appears you have used | base64 instead of | base64 --decode

  • Related