Kubectl est un outil CLI qui nous permet d'intéragir avec Kubernetes. kubectl utilise l'API k8s afin de communiquer avec le cluster.
On peut utiliser kubectl pour déployer des apps, inspecter les objets, gérer les ressources et voir les logs.
Dans cette partie, je vais utiliser le pod suivant :
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: busybox
image: radial/busyboxplus:curl
command: ['sh', '-c', 'while true; do sleep 3600; done']
$ kubectl get <type objet> [<nom objet> -o <output> --sort-by <JSONPath> --selector <selector>]
Ou :
Paramètre | Utilité |
---|---|
-o | Format de sortie (wide, json, yaml) |
--sort-by | Tri l'output en utilisant un filtre (JSONPath expresion) |
--selector | Filtre avec un label spécifique |
En pratique :
# Soit
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
my-pod 1/1 Running 0 28s
$ kubectl get pod -n kube-system calico-node-5hzhz
NAME READY STATUS RESTARTS AGE
calico-node-5hzhz 1/1 Running 3 5d18h
Utilisation du paramètre -o afin d'étendre la sortie ou changer le type de sortie (yaml, json) :
$ kubectl get pod -o wide # Affiche plus d'informations sur les pods
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-pod 1/1 Running 0 74s 192.168.126.9 k8s-worker2 <none> <none>
$ kubectl get pod -o json # Existe aussi pour yaml
{
"apiVersion": "v1",
"items": [
{
"apiVersion": "v1",
"kind": "Pod",
...
Utilisation du paramètre --sort-by afin de lister les pods dans l'ordre des noms de noeud :
$ kubectl get pods -n kube-system -o wide --sort-by .spec.nodeName
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
kube-apiserver-k8s-control 1/1 Running 1 81m 172.31.28.195 k8s-control <none> <none>
...
calico-node-wdmxr 1/1 Running 3 5d18h 172.31.24.234 k8s-worker1 <none> <none>
kube-proxy-6z7tv 1/1 Running 1 80m 172.31.24.234 k8s-worker1 <none> <none>
calico-node-5hzhz 1/1 Running 3 5d18h 172.31.31.176 k8s-worker2 <none> <none>
kube-proxy-jb86g 1/1 Running 1 80m 172.31.31.176 k8s-worker2 <none> <none>
Utilisation du paramètre --selector afin d'afficher les pods qui contiennent ce label :
$ kubectl get pods -n kube-system --selector k8s-app=calico-node
NAME READY STATUS RESTARTS AGE
calico-node-5hzhz 1/1 Running 3 5d18h
calico-node-7k2jb 1/1 Running 3 5d18h
calico-node-wdmxr 1/1 Running 3 5d18h
$ kubectl describe <type objet> <nom objet>
En pratique :
$ kubectl describe pod my-pod
Name: my-pod
Namespace: default
Priority: 0
Node: k8s-worker2/172.31.31.176
Start Time: Sat, 03 Jul 2021 15:24:28 +0000
Labels: <none>
Annotations: cni.projectcalico.org/podIP: 192.168.126.9/32
cni.projectcalico.org/podIPs: 192.168.126.9/32
Status: Running
IP: 192.168.126.9
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 10m default-scheduler Successfully assigned default/my-pod to k8s-worker2
Normal Pulling 10m kubelet Pulling image "radial/busyboxplus:curl"
$ kubectl create -f <fichier yml>
Si on essaie de créer un objet qui existe déjà, celà produira une erreur !
En pratique :
$ kubectl create -f pod.yml
pod/my-pod created
$ kubectl create -f pod.yml
Error from server (AlreadyExists): error when creating "pod2.yml": pods "my-pod" already exists
$ kubectl apply -f <fichier>
En pratique :
$ kubectl create -f pod.yml
pod/my-pod created
$ kubectl apply -f pod.yml
pod/my-pod unchanged
$ kubectl exec <nom pod> [-c <nom container>] -- <commande>
En pratique :
$ kubectl exec my-pod -- echo "Enjoy your reading"
Enjoy your reading
$ kubectl delete <type objet> <nom objet>
En pratique :
$ kubectl delete pod my-pod
pod "my-pod" deleted
$ kubectl api-resources
NAME SHORTNAMES APIVERSION NAMESPACED KIND
bindings v1 true Binding
componentstatuses cs v1 false ComponentStatus
configmaps cm v1 true ConfigMap
endpoints ep v1 true Endpoints
...
Certaines ressources possèdent leur propre raccourci. "Deployment" par exemple possède le raccourci "deploy" on peut donc faire kubectl get deploy.
Je conseille d'activer l'autocompletion des commandes ainsi que de mettre un alias sur la commande kubectl :
source <(kubectl completion bash) # active l'auto-complétion pour bash dans le shell courant, le paquet bash-completion devant être installé au préalable
echo "source <(kubectl completion bash)" >> ~/.bashrc # ajoute l'auto-complétion de manière permanente à votre shell bash
alias k=kubectl
complete -F __start_kubectl k
Comme son nom l'indique, de temps en temps, il peut être préférable d'utiliser la commande plutôt que de créer un fichier YAML puis l'appliquer :
$ kubectl create deployment my-deployment --image=nginx # créera un déploiement nginx avec un label app=my-deployment et les paramètres de bases
Le paramètre --dry-run=client (qui permet de tester la commande mais de ne pas l'appliquer) peut permetre d'avoir la base d'un fichier YAML très facilement :
$ kubectl create deployment my-deployment --image=nginx --dry-run=client -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: my-deployment
name: my-deployment
spec:
replicas: 1
selector:
matchLabels:
app: my-deployment
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: my-deployment
spec:
containers:
- image: nginx
name: nginx
resources: {}
status: {}
Permet d'écrire la commande exécutée dans l'annotation de ressource kubernetes.io/change-cause
:
$ kubectl scale deployment my-deployment --replicas=5 --record
$ kubectl describe deployments.apps my-deployment | head -6
Name: my-deployment
Namespace: default
CreationTimestamp: Sat, 03 Jul 2021 16:02:09 +0000
Labels: app=my-deployment
Annotations: deployment.kubernetes.io/revision: 1
kubernetes.io/change-cause: kubectl scale deployment my-deployment --replicas=5 --record=true
Pendant l'exament, la documentation est autorisée ! Il y a beaucoup d'exemples sur cette doc. N'hésitez pas à vous en inspirer.
RBAC dans Kubernetes permet de contrôler à quoi les utilisateurs ont accès dans le cluster.
On peut par exemple autoriser les développeurs à lire les métadata et les logs. Ils ne peuvent cependant pas modifier les objets.
Il existe différents objets RBAC :
Roles et ClusterRoles définissent un ensemble de permissions. Ces permissions permettent de définir ce que l'utilisateur peut faire dans le cluster.
RoleBinding et ClusterRoleBinding après avoir créé les Roles et les ClusterRoles, il faut les assigner à des utilisateurs. RoleBinding et ClusterRoleBinding sont là pour ça.
On va créer un fichier role.yml
:
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "watch", "list"]
Et un role-binding.yml
:
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: pod-reader
namespace: default
subjects:
- kind: User
name: dev # Nom de l'user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader # Role créé au-dessus
apiGroup: rbac.authorization.k8s.io
On va maintenant lister les roles et rolebindings :
$ kubectl get role
NAME CREATED AT
pod-reader 2021-07-03T17:36:39Z
$ kubectl get rolebindings
NAME ROLE AGE
pod-reader Role/pod-reader 26s
Dans Kubernetes, un compte de service (service account) est un compte utiliser par les process des containers afin de s'authentifier avec l'API k8s.
Si un pod doit avoir accès à l'API k8s, il faut donc créer un compte de service au préalable.
La configuration basique d'un ServiceAccount est la suivante :
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-serviceaccount
Ou via la commande create :
kubectl create sa my-serviceaccount2 -n default
Comme tout objet, on peut contrôler l'accès aux comptes de service via la RBAC.
Il faut lier le ServiceAccount avec un ClusterRole ou ClusterRoleBinding afin de fournir l'accès à l'API k8s.
Voici un exemple de RoleBinding :
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: sa-pod-reader
namespace: default
subjects:
- kind: ServiceAccount
name: my-serviceaccount
namespace: default
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
On va donc donner accès à ce ServiceAccount au Role pod-reader.
Afin de pouvoir voir les métriques de chaque pod, nous avons besoin d'installer un add-on pour collecter et fournir les informations nécessaires. L'add-on que nous allons utiliser est "Kubernetes Metrics Server".
On va donc installer cet add-on :
$ kubectl apply -f https://raw.githubusercontent.com/linuxacademy/content-cka-resources/master/metrics-server-components.yaml
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
Warning: apiregistration.k8s.io/v1beta1 APIService is deprecated in v1.19+, unavailable in v1.22+; use apiregistration.k8s.io/v1 APIService
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
serviceaccount/metrics-server created
deployment.apps/metrics-server created
service/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
La commande kubectl top permet de voir les informations à propos de l'utilisation des ressources dans un pods et sur le noeud.
Les paramètres --sort-by et --selector peuvent être utilisés :
$ kubectl top pod --short-by <JSONEXP> --selector <selector>
$ kubectl top pod
NAME CPU(cores) MEMORY(bytes)
my-deployment-5f85c44867-2xqrq 0m 3Mi
my-deployment-5f85c44867-tnvlv 0m 3Mi
$ kubectl top pod --sort-by cpu
$ kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8s-control 243m 12% 1600Mi 42%
k8s-worker1 84m 4% 868Mi 22%
k8s-worker2 149m 7% 859Mi 22%