Create a namesepace:
$ kubectl create ns service-ns
namespace/service-ns createdCheck serviceaccounts
$ kubectl -n service-ns get serviceaccounts
NAME SECRETS AGE
default 0 48sRun a pod:
$ kubectl -n service-ns run test-service --image alpine -- sleep infinity
pod/test-service createdEnter the pod:
$ kubectl -n service-ns exec -it test-service -- sh
/ #Inside pod, check apiserver access:
$ apk add curl
fetch https://dl-cdn.alpinelinux.org/alpine/v3.22/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.22/community/x86_64/APKINDEX.tar.gz
(1/9) Installing brotli-libs (1.1.0-r2)
(2/9) Installing c-ares (1.34.5-r0)
(3/9) Installing libunistring (1.3-r0)
(4/9) Installing libidn2 (2.3.7-r0)
(5/9) Installing nghttp2-libs (1.65.0-r0)
(6/9) Installing libpsl (0.21.5-r3)
(7/9) Installing zstd-libs (1.5.7-r0)
(8/9) Installing libcurl (8.14.1-r1)
(9/9) Installing curl (8.14.1-r1)
Executing busybox-1.37.0-r18.trigger
OK: 12 MiB in 25 packages
$ curl -Lo /usr/bin/kubectl "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 138 100 138 0 0 974 0 --:--:-- --:--:-- --:--:-- 985
100 57.3M 100 57.3M 0 0 145M 0 --:--:-- --:--:-- --:--:-- 145M
$ chmod +x /usr/bin/kubectl
$ kubectl version
Client Version: v1.33.4
Kustomize Version: v5.6.0
Server Version: v1.33.1+k3s1
$ CA_CERT=/run/secrets/kubernetes.io/serviceaccount/ca.crt
$ TOKEN=$(cat /run/secrets/kubernetes.io/serviceaccount/token)
$ NAMESPACE=$(cat /run/secrets/kubernetes.io/serviceaccount/namespace)
$ curl --cacert $CA_CERT --header "Authorization: Bearer ${TOKEN}" -X GET https://kubernetes.default.svc/api; echo
{
"kind": "APIVersions",
"versions": [
"v1"
],
"serverAddressByClientCIDRs": [
{
"clientCIDR": "0.0.0.0/0",
"serverAddress": "10.108.0.228:6443"
}
]
}Create kubeconfig:
$ CACERT=$(cat $CA_CERT | base64 -w0)
$ mkdir -p ~/.kube
$ chmod 700 ~/.kube
$ tee ~/.kube/config <<EOF
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: ${CACERT}
server: https://kubernetes.default.svc
name: builder
contexts:
- context:
cluster: builder
namespace: ${NAMESPACE}
user: builder
name: builder
current-context: builder
kind: Config
users:
- name: builder
user:
token: ${TOKEN}
EOF
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJ...
server: https://kubernetes.default.svc
name: builder
contexts:
- context:
cluster: builder
namespace: service-ns
user: builder
name: builder
current-context: builder
kind: Config
users:
- name: builder
user:
token: eyJhbGciOiJSUzI1NiIsI...Check kubeconfig:
$ kubectl get pod
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:service-ns:default" cannot list resource "pods" in API group "" in the namespace "service-ns"
exitOK, kubeconfig working properly but current serviceaccount does not have any access rights.
Grant access for serviceaccount (outside the pod):
$ kubectl -n service-ns apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: runner-role
namespace: service-ns
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- '*'
EOF
role.rbac.authorization.k8s.io/runner-role created
$ kubectl -n service-ns apply -f - <<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: runner-role-binding
namespace: service-ns
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: runner-role
subjects:
- kind: ServiceAccount
name: default
EOF
rolebinding.rbac.authorization.k8s.io/runner-role-binding createdTest inside the pod:
# entering in the pod
$ kubectl -n service-ns exec -it test-service -- sh
/ #
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
test-service 1/1 Running 0 82mDONE!