CKA - Challenge 1 - Configurer un kubectl en remote

Introduction

Dans le cadre de ma préparation à l’examen de certifiation d’administration Kubernetes (CKA), je me prépare quelques exercices pratiques à mettre en oeuvre. Si vous êtes intéressés, je vous propose ceux-ci, avec une solution possible. N’hésitez pas à me faire part de vos commentaires, critiques ou de vos propres solutions pour en discuter !

Challenge

Un nouveau collaborateur Bobby vient d’arriver dans votre société, et il souhaite pouvoir se connecter à un cluster Kubernetes existant avec kubectl afin de gérer complètement le namespace developer.

Comment faire?

Solution

Note

Au moment de l’écriture de ce billet, l’examen CKA est basé sur Kubernetes 1.18.

Les solutions proposées sont donc basées sur cette version.

Création d’un certificat Client

La première chose à faire est de générer une CSR (Certificate Signing Request). Il est possible d’utiliser OpenSSL pour cela, mais pour cette fois c’est CFSSL qui sera utilisé.

Pour cela, il faut préparer un fichier JSON qui décrit les informations du certificat que l’on souhaite générer :

{
  "CN": "bobby",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "O": "developers"
    }
  ]
}

Nous le passons ensuite à CFSSL pour la génération proprement dite:

cfssl genkey bobby-admin.json | cfssljson -bare bobby-admin

Le résultat de cette commande est la création de deux fichiers :

  • bobby-admin-key.pem : la clé privée
  • bobby-admin-key.csr : la demande de signature

Signature de la CSR par Kubernetes

Il faut maintenant signer la CSR par l’autorité de notre cluster Kubernetes afin de récupérer un certificat valide qui sera utilisé pour l’authentification.

Pour cela, nous allons créer une resource de type CertificateSigningRequest de l’API certificates.k8s.io/v1beta1, dont la représentation YAML peut être créée via cette commande :

cat > bobby-admin-csr.yml <<EOF
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
  name: bobby-authentication
spec:
  groups:
  - system:authenticated
  request: $(cat bobby-admin.csr | base64 | tr -d '\n')
  usages:
  - digital signature
  - key encipherment
  - server auth
  - client auth
EOF

Celle-ci est ensuite importée dans Kubernetes via kubectl :

$> kubectl apply -f bobby-authentication.yaml

certificatesigningrequest.certificates.k8s.io/bobby-authentication

On peut vérifier que cette CSR est bien présente, et en attente d’être validée :

$> kubectl get csr bobby-authentication
NAME                       AGE     SIGNERNAME                     REQUESTOR          CONDITION
bobby-authentication   4m50s   kubernetes.io/legacy-unknown   kubernetes-admin   Pending

Pour signer celle-ci, kubectl est une nouvelle fois notre ami :

# Validation de la CSR
$> kubectl certificate approve bobby-authentication
certificatesigningrequest.certificates.k8s.io/bobby-authentication approved

# Vérification de l'état de la CSR, qui est bien approuvée
$> kubectl get csr bobby-authentication
NAME                       AGE     SIGNERNAME                     REQUESTOR          CONDITION
bobby-authentication   6m33s   kubernetes.io/legacy-unknown   kubernetes-admin   Approved,Issued

Reste maintenant à extraine le certificat généré via kubectl :

kubectl get csr bobby-authentication -o jsonpath='{.status.certificate}' | base64 --decode > bobby-admin.crt

Configuration de kubectl

Tip

Dans les exemples de commandes suivantes, le paramètre --kubeconfig=bobby-config est proposé à chaque commande afin de permettre de différencier les commandes kubectl utilisée par un utilisateur admin existant, des commandes kubectl sur le poste de Bobby.

Il serait cependant possiblle de définir la variables d’environment KUBECONFIG pointant vers ce fichier afin d’éviter cette verbosité :

# Un seul fichier specifique
export KUBECONFIG=/path/to/bobby-config

# Ou si l'on souhaite avoir plusieurs fichiers de configuration
export KUBECONFIG=/path/to/bobby-config:/path/to/other-config

Afin de configurer kubectl, il est nécessaire d’avoir :

  • Le certificat de l’autorité de certification, que l’on peut trouver sur le master dans /etc/kubernetes/pki/ca.crt
  • L’URL de l’API server
  • Le certificat client, qui vient d’être généré
  • La clé privée liée à ce certificat
API_URL=https://10.0.1.100:6443


kubectl config --kubeconfig=bobby-config set-cluster development --server=$API_URL --certificate-authority=ca.crt

kubectl config --kubeconfig=bobby-config set-credentials bobby-creds --client-certificate=bobby-admin.crt --client-key=bobby-admin-key.pem

kubectl config --kubeconfig=bobby-config set-context bobby --cluster=development --namespace=developer --user=bobby-creds

kubectl --kubeconfig=bobby-config use-context bobby

Si tout s’est passé correctement, nous devrions pouvoir appeler notre cluster avec kubectl en distant. Tentons de lister les pods dans le namespace developer

$> kubectl  --kubeconfig=bobby-config get pods

Error from server (Forbidden): pods is forbidden: User "developer-admin" cannot list resource "pods" in API group "" in the namespace "developer"

La connexion est opérationnelle, mais actuellement, notre utilisateur n’a aucun droit sur le namespace developer. Il ne peut rien faire pour le moment !

Configuration RBAC pour l’utilisateur

La première chose à faire est de créer un role dans notre namespace. Le YAML suivant pourrait faire l’affaire :

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: developer-admin-role
  namespace: developer
rules:
- apiGroups: ["", "extensions", "apps"]
  resources: ["*"]
  verbs: ["*"]
- apiGroups: ["batch"]
  resources:
  - jobs
  - cronjobs
  verbs: ["*"]

Un coup de kubectl apply -f developer-admin-role.yml pour créer le rôle et il l’étape suivant sera de lier l’utilisateur bobby à ce rôle :

$> kubectl create rolebinding bobby-developer-admin-role --role=developer-admin-role --user=bobby -n developer

rolebinding.rbac.authorization.k8s.io/developer-admin-role created

Et tada :

$> kubectl --kubeconfig=bobby-config run test-nginx  --image nginx

pod/test-nginx created

$> kubectl --kubeconfig=bobby-config get pods

NAME         READY   STATUS    RESTARTS   AGE
test-nginx   1/1     Running   0          37s

Et voila :-)

D’autres exercices ?

D’autres petits challenges viendront sans doute par la suite, mais en attendant si vous voulez vous entrainer pour l’examen CKA, je vous conseille ces deux sites (en anglais):

Ce dernier est payant, mais franchement bien fait ! Et a priori dans les mêmes conditions que l’examen lui même (Web Interface, plusieurs contextes/clusters), et a priori un peu plus compliqué que l’examen (d’après les retours que j’ai pu lire, n’ayant pas encore passé moi même l’examen).

Remerciements

Merci à Aurélie Vache pour la relecture :-)

comments powered by Disqus