Skip to main content

Programación Manual

Por defecto todos los Nodos son elegibles por el kube-scheduler si no definimos en spec un nodeName.

apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 8080
#nodeName: <<<<<

Si no existe un Scheduler (kube-scheduler por ejemplo) para definir cuál Nodo elegir, el Pod quedaría en estado de Pending.

Caso no exista un Scheduler y se defina un Nodo específico para el Pod, este se levantará en el Nodo definido si existe y tiene recursos suficientes.

Vamos a levantar el Pod con un nodeName que no existe.

kubectl get nodes
NAME STATUS ROLES AGE VERSION
k3d-k3d-cluster-agent-1 Ready <none> 69d v1.27.4+k3s1
k3d-k3d-cluster-agent-2 Ready <none> 69d v1.27.4+k3s1
k3d-k3d-cluster-agent-0 Ready <none> 69d v1.27.4+k3s1
k3d-k3d-cluster-server-0 Ready control-plane,master 69d v1.27.4+k3s1

cat <<EOF > pod-node-name.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 8080
nodeName: node01
EOF

# Intentando levantar un Pod en un Nodo que no existe en el cluster
kubectl apply -f pod-node-name.yaml
pod/nginx created

kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx 0/1 Pending 0 4s

Aunque exista un Scheduler no encontró el Nodo seleccionado, porque no tenemos el node01, entonces quedó en pending y después desapareció.

Cambiar el nodeName de un Pod no está permitido por Kubernetes, ya que no es posible mover un Pod de un Nodo a otro. Es necesario recrearlo, es decir, borrar primero y después crear.

Para hacer esto con kubectl apply podemos usar kubectl replace --force

# Intento de cambio alterando el archivo de node01 para node02 que tampoco existe
cat <<EOF > pod-node-name.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 8080
nodeName: node02
EOF

kubectl apply -f ./files/pod-node-name.yaml
pod/nginx created
kubectl apply -f ./files/pod-node-name.yaml
The Pod "nginx" is invalid: spec: Forbidden: pod updates may not change fields other than `spec.containers[*].image`,`spec.initContainers[*].image`,`spec.activeDeadlineSeconds`,`spec.tolerations` (only additions to existing tolerations),`spec.terminationGracePeriodSeconds` (allow it to be set to 1 if it was previously negative)
core.PodSpec{
... // 9 identical fields
ServiceAccountName: "default",
AutomountServiceAccountToken: nil,
- NodeName: "node01",
+ NodeName: "node02",
SecurityContext: &{},
ImagePullSecrets: nil,
... // 19 identical fields
}

kubectl replace --force -f ./files/pod-node-name.yaml
pod "nginx" deleted
pod/nginx replaced

# El comando watch queda monitoreando, como no tenemos el node02 se finalizó y no continuó intentando levantarse porque es solamente un Pod sin un ReplicaSet para controlarlo
kubectl get pods -o wide --watch
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 0/1 Pending 0 12s <none> node02 <none> <none>
nginx 0/1 Failed 0 49s <none> node02 <none> <none>
nginx 0/1 Terminating 0 49s <none> node02 <none> <none>
nginx 0/1 Terminating 0 49s <none> node02 <none> <none>

Claro que si pusiéramos un Nodo que existe todo funcionaría correctamente.