Diferencia entre revisiones de «Implementar un clúster de Kubernetes»
(Página creada con «{{#seo: |title=Implementar un clúster de Kubernetes |title_mode=append |keywords=Kubernetes |description=Kubernetes es una plataforma de código abierto para la gestión d...») |
|||
(No se muestran 27 ediciones intermedias de otro usuario) | |||
Línea 1: | Línea 1: | ||
+ | |||
{{#seo: | {{#seo: | ||
|title=Implementar un clúster de Kubernetes | |title=Implementar un clúster de Kubernetes | ||
Línea 7: | Línea 8: | ||
|image_alt=Wiki Logo | |image_alt=Wiki Logo | ||
}} | }} | ||
+ | |||
==¿Qué es kubernetes?== | ==¿Qué es kubernetes?== | ||
− | Kubernetes es una plataforma de código abierto para la gestión de cargas de trabajo y servicios en contenedores. Favorece la configuración declarativa escrita pero también la automatización. Kubernetes es un ecosistema grande y en rápida expansión. | + | [https://www.ikoula.es/es/cloud-vps/oneclick/kubernetes Kubernetes] es una plataforma de código abierto para la gestión de cargas de trabajo y servicios en contenedores. Favorece la configuración declarativa escrita pero también la automatización. Kubernetes es un ecosistema grande y en rápida expansión. |
Este procedimiento le permitirá implementar rápida y fácilmente un clúster Kubernetes (k8s) de tres nodos de tres instancias de CentOS 7 implementadas dentro de la misma red en la zona avanzada. | Este procedimiento le permitirá implementar rápida y fácilmente un clúster Kubernetes (k8s) de tres nodos de tres instancias de CentOS 7 implementadas dentro de la misma red en la zona avanzada. | ||
Una de estas tres instancias será nuestro nodo maestro y las otras dos serán nuestros nodos trabajadores. En resumen, el nodo maestro es el nodo desde el que gestionamos el clúster de Kubernetes (orquestador de contenedores) desde su API y los nodos trabajadores son los nodos en los que se ejecutarán los pods, es decir, los contenedores (Docker en nuestro caso). | Una de estas tres instancias será nuestro nodo maestro y las otras dos serán nuestros nodos trabajadores. En resumen, el nodo maestro es el nodo desde el que gestionamos el clúster de Kubernetes (orquestador de contenedores) desde su API y los nodos trabajadores son los nodos en los que se ejecutarán los pods, es decir, los contenedores (Docker en nuestro caso). | ||
Línea 20: | Línea 22: | ||
==Preparación del sistema e instalación del tutorial de Kubernetes :== | ==Preparación del sistema e instalación del tutorial de Kubernetes :== | ||
+ | |||
Las siguientes acciones deben realizarse en todas las instancias (maestra y trabajadoras) como root (o con los derechos de sudo necesarios). | Las siguientes acciones deben realizarse en todas las instancias (maestra y trabajadoras) como root (o con los derechos de sudo necesarios). | ||
+ | |||
Comience por completar el archivo / etc / hosts en cada una de sus instancias para que puedan resolver su nombre de host respectivo (normalmente ya es el caso en una red de zona avanzada donde el enrutador virtual está resolviendo DNS). | Comience por completar el archivo / etc / hosts en cada una de sus instancias para que puedan resolver su nombre de host respectivo (normalmente ya es el caso en una red de zona avanzada donde el enrutador virtual está resolviendo DNS). | ||
− | |||
+ | En nuestro ejemplo, esto proporciona el siguiente archivo / etc / hosts en nuestras tres instancias (adáptelo con el nombre y la ip de sus instancias) : | ||
+ | |||
+ | <syntaxhighlight lang="bash"> | ||
cat /etc/hosts | cat /etc/hosts | ||
127.0.0.1 localhost | 127.0.0.1 localhost | ||
::1 localhost | ::1 localhost | ||
− | |||
10.1.1.16 k8s-master | 10.1.1.16 k8s-master | ||
10.1.1.169 k8s-worker01 | 10.1.1.169 k8s-worker01 | ||
10.1.1.87 k8s-worker02 | 10.1.1.87 k8s-worker02 | ||
+ | </syntaxhighlight> | ||
− | Active el módulo puente y las reglas de iptables para este último a través de los siguientes tres comandos: | + | Active el módulo puente y las reglas de iptables para este último a través de los siguientes tres comandos : |
+ | <syntaxhighlight lang="bash"> | ||
modprobe bridge | modprobe bridge | ||
echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf | echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf | ||
sysctl -p /etc/sysctl.conf | sysctl -p /etc/sysctl.conf | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | '''==Agregue el repositorio de YUM Docker :==''' | ||
+ | |||
+ | <syntaxhighlight lang="bash"> | ||
− | |||
cat <<EOF > /etc/yum.repos.d/docker.repo | cat <<EOF > /etc/yum.repos.d/docker.repo | ||
[docker-ce-stable] | [docker-ce-stable] | ||
Línea 47: | Línea 58: | ||
gpgkey=https://download.docker.com/linux/centos/gpg | gpgkey=https://download.docker.com/linux/centos/gpg | ||
EOF | EOF | ||
+ | </syntaxhighlight> | ||
− | Agregue el depósito YUM Kubernetes: | + | '''Agregue el depósito YUM Kubernetes :''' |
+ | <syntaxhighlight lang="bash"> | ||
cat <<EOF > /etc/yum.repos.d/kubernetes.repo | cat <<EOF > /etc/yum.repos.d/kubernetes.repo | ||
[kubernetes] | [kubernetes] | ||
Línea 60: | Línea 73: | ||
https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg | https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg | ||
EOF | EOF | ||
+ | </syntaxhighlight> | ||
− | Instalar Docker: | + | '''Instalar Docker :''' |
+ | <syntaxhighlight lang="bash"> | ||
yum install -y docker-ce | yum install -y docker-ce | ||
+ | </syntaxhighlight> | ||
− | Luego instale los paquetes de Kubernetes necesarios: | + | ==Luego instale los paquetes de Kubernetes necesarios :== |
+ | syntaxhighlight lang="bash"> | ||
yum install -y kubeadm kubelet kubectl | yum install -y kubeadm kubelet kubectl | ||
+ | </syntaxhighlight> | ||
− | Edite el archivo de configuración de systemd kubelet (/etc/systemd/system/kubelet.service.d/10-kubeadm.conf) para agregar la siguiente línea en la sección "[Servicio]": | + | Edite el archivo de configuración de systemd kubelet (/etc/systemd/system/kubelet.service.d/10-kubeadm.conf) para agregar la siguiente línea en la sección "[Servicio]" : |
+ | <pre> | ||
Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs" | Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs" | ||
+ | </pre> | ||
− | + | Tal que : | |
− | + | <pre> | |
cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf | cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf | ||
# Note: This dropin only works with kubeadm and kubelet v1.11+ | # Note: This dropin only works with kubeadm and kubelet v1.11+ | ||
Línea 87: | Línea 107: | ||
ExecStart= | ExecStart= | ||
ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS | ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS | ||
+ | </pre> | ||
− | Vuelva a cargar la configuración, habilite y luego inicie los servicios docker y kubelet a través de los siguientes tres comandos: | + | Vuelva a cargar la configuración, habilite y luego inicie los servicios docker y kubelet a través de los siguientes tres comandos : |
− | + | <syntaxhighlight lang="bash"> | |
systemctl daemon-reload | systemctl daemon-reload | ||
systemctl enable docker kubelet | systemctl enable docker kubelet | ||
systemctl start docker kubelet | systemctl start docker kubelet | ||
+ | </syntaxhighlight> | ||
− | + | Deshabilite el intercambio del sistema (kubelet no admite la memoria de intercambio, recibirá un error durante las comprobaciones previas al vuelo al arrancar su clúster a través de kubeadmsi, no deshabilite este) : | |
− | Deshabilite el intercambio del sistema (kubelet no admite la memoria de intercambio, recibirá un error durante las comprobaciones previas al vuelo al arrancar su clúster a través de kubeadmsi, no deshabilite este): | + | <syntaxhighlight lang="bash"> |
− | |||
swapoff -a | swapoff -a | ||
− | + | </syntaxhighlight> | |
Recuerde también comentar / eliminar la línea de intercambio en el archivo / etc / fstab de cada una de sus instancias, como por ejemplo: | Recuerde también comentar / eliminar la línea de intercambio en el archivo / etc / fstab de cada una de sus instancias, como por ejemplo: | ||
− | + | <pre> | |
#/dev/mapper/vg01-swap swap swap defaults 0 0 | #/dev/mapper/vg01-swap swap swap defaults 0 0 | ||
+ | </pre> | ||
==Inicializando el clúster de Kubernetes== | ==Inicializando el clúster de Kubernetes== | ||
+ | Las siguientes acciones solo se deben realizar en la instancia del « Node Master » | ||
− | |||
Inicie la inicialización de su clúster de Kubernetes mediante el comando a continuación, y modifique el valor del parámetro "--apiserver-Advertise-Address =" con la dirección IP de su instancia maestra. | Inicie la inicialización de su clúster de Kubernetes mediante el comando a continuación, y modifique el valor del parámetro "--apiserver-Advertise-Address =" con la dirección IP de su instancia maestra. | ||
− | + | <syntaxhighlight lang="bash"> | |
kubeadm init --apiserver-advertise-address=<ip de votre instance master> --pod-network-cidr=10.244.0.0/16 | kubeadm init --apiserver-advertise-address=<ip de votre instance master> --pod-network-cidr=10.244.0.0/16 | ||
− | + | </syntaxhighlight> | |
Nota: No modifique la dirección IP de la red "10.244.0.0/16" indicada en el parámetro "--pod-network-cidr =" porque esta indica que usaremos el complemento CNI Flannel para administrar La parte de la red de nuestros pods. | Nota: No modifique la dirección IP de la red "10.244.0.0/16" indicada en el parámetro "--pod-network-cidr =" porque esta indica que usaremos el complemento CNI Flannel para administrar La parte de la red de nuestros pods. | ||
Así es como debería verse el retorno de este comando cuando el clúster se inicia correctamente: | Así es como debería verse el retorno de este comando cuando el clúster se inicia correctamente: | ||
− | [root@k8s-master ~]# kubeadm init --apiserver-advertise-address=10.1.1.16 --pod-network-cidr=10.244.0.0/16 | + | <syntaxhighlight lang="bash"> |
− | [init] using Kubernetes version: v1.12.2 | + | [ root@k8s-master ~]# kubeadm init --apiserver-advertise-address=10.1.1.16 --pod-network-cidr=10.244.0.0/16 |
− | [preflight] running pre-flight checks | + | [ init] using Kubernetes version: v1.12.2 |
− | [preflight/images] Pulling images required for setting up a Kubernetes cluster | + | [ preflight ] running pre-flight checks |
− | [preflight/images] This might take a minute or two, depending on the speed of your internet connection | + | [ preflight/images ] Pulling images required for setting up a Kubernetes cluster |
− | [preflight/images] You can also perform this action in beforehand using 'kubeadm config images pull' | + | [ preflight/images ] This might take a minute or two, depending on the speed of your internet connection |
− | [kubelet] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env" | + | [ preflight/images] You can also perform this action in beforehand using 'kubeadm config images pull' |
− | [kubelet] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" | + | [ kubelet] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env" |
− | [preflight] Activating the kubelet service | + | [ kubelet] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" |
− | [certificates] Generated ca certificate and key. | + | [ preflight] Activating the kubelet service |
− | [certificates] Generated apiserver-kubelet-client certificate and key. | + | [ certificates] Generated ca certificate and key. |
− | [certificates] Generated apiserver certificate and key. | + | [ certificates] Generated apiserver-kubelet-client certificate and key. |
− | [certificates] apiserver serving cert is signed for DNS names [k8s-master.cs437cloud.internal kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 10.1.1.16] | + | [ certificates] Generated apiserver certificate and key. |
− | [certificates] Generated front-proxy-ca certificate and key. | + | [ certificates] apiserver serving cert is signed for DNS names [k8s-master.cs437cloud.internal kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 10.1.1.16] |
− | [certificates] Generated front-proxy-client certificate and key. | + | [ certificates] Generated front-proxy-ca certificate and key. |
− | [certificates] Generated etcd/ca certificate and key. | + | [ certificates] Generated front-proxy-client certificate and key. |
− | [certificates] Generated etcd/server certificate and key. | + | [ certificates] Generated etcd/ca certificate and key. |
− | [certificates] etcd/server serving cert is signed for DNS names [k8s-master.cs437cloud.internal localhost] and IPs [127.0.0.1 ::1] | + | [ certificates] Generated etcd/server certificate and key. |
− | [certificates] Generated etcd/peer certificate and key. | + | [ certificates] etcd/server serving cert is signed for DNS names [k8s-master.cs437cloud.internal localhost] and IPs [127.0.0.1 ::1] |
− | [certificates] etcd/peer serving cert is signed for DNS names [k8s-master.cs437cloud.internal localhost] and IPs [10.1.1.16 127.0.0.1 ::1] | + | [ certificates] Generated etcd/peer certificate and key. |
− | [certificates] Generated etcd/healthcheck-client certificate and key. | + | [ certificates] etcd/peer serving cert is signed for DNS names [k8s-master.cs437cloud.internal localhost] and IPs [10.1.1.16 127.0.0.1 ::1] |
− | [certificates] Generated apiserver-etcd-client certificate and key. | + | [ certificates] Generated etcd/healthcheck-client certificate and key. |
− | [certificates] valid certificates and keys now exist in "/etc/kubernetes/pki" | + | [ certificates] Generated apiserver-etcd-client certificate and key. |
− | [certificates] Generated sa key and public key. | + | [ certificates] valid certificates and keys now exist in "/etc/kubernetes/pki" |
− | [kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf" | + | [ certificates] Generated sa key and public key. |
− | [kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf" | + | [ kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf" |
− | [kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/controller-manager.conf" | + | [ kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf" |
− | [kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/scheduler.conf" | + | [ kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/controller-manager.conf" |
− | [controlplane] wrote Static Pod manifest for component kube-apiserver to "/etc/kubernetes/manifests/kube-apiserver.yaml" | + | [ kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/scheduler.conf" |
− | [controlplane] wrote Static Pod manifest for component kube-controller-manager to "/etc/kubernetes/manifests/kube-controller-manager.yaml" | + | [ controlplane] wrote Static Pod manifest for component kube-apiserver to "/etc/kubernetes/manifests/kube-apiserver.yaml" |
− | [controlplane] wrote Static Pod manifest for component kube-scheduler to "/etc/kubernetes/manifests/kube-scheduler.yaml" | + | [ controlplane] wrote Static Pod manifest for component kube-controller-manager to "/etc/kubernetes/manifests/kube-controller-manager.yaml" |
− | [etcd] Wrote Static Pod manifest for a local etcd instance to "/etc/kubernetes/manifests/etcd.yaml" | + | [ controlplane] wrote Static Pod manifest for component kube-scheduler to "/etc/kubernetes/manifests/kube-scheduler.yaml" |
− | [init] waiting for the kubelet to boot up the control plane as Static Pods from directory "/etc/kubernetes/manifests" | + | [ etcd] Wrote Static Pod manifest for a local etcd instance to "/etc/kubernetes/manifests/etcd.yaml" |
− | [init] this might take a minute or longer if the control plane images have to be pulled | + | [ init] waiting for the kubelet to boot up the control plane as Static Pods from directory "/etc/kubernetes/manifests" |
− | [apiclient] All control plane components are healthy after 32.502898 seconds | + | [ init] this might take a minute or longer if the control plane images have to be pulled |
− | [uploadconfig] storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace | + | [ apiclient] All control plane components are healthy after 32.502898 seconds |
− | [kubelet] Creating a ConfigMap "kubelet-config-1.12" in namespace kube-system with the configuration for the kubelets in the cluster | + | [ uploadconfig] storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace |
− | [markmaster] Marking the node k8s-master.cs437cloud.internal as master by adding the label "node-role.kubernetes.io/master=''" | + | [ kubelet] Creating a ConfigMap "kubelet-config-1.12" in namespace kube-system with the configuration for the kubelets in the cluster |
− | [markmaster] Marking the node k8s-master.cs437cloud.internal as master by adding the taints [node-role.kubernetes.io/master:NoSchedule] | + | [ markmaster] Marking the node k8s-master.cs437cloud.internal as master by adding the label "node-role.kubernetes.io/master=''" |
− | [patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "k8s-master.cs437cloud.internal" as an annotation | + | [ markmaster] Marking the node k8s-master.cs437cloud.internal as master by adding the taints [node-role.kubernetes.io/master:NoSchedule] |
− | [bootstraptoken] using token: e83pes.u3igpccj2metetu8 | + | [ patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "k8s-master.cs437cloud.internal" as an annotation |
− | [bootstraptoken] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials | + | [ bootstraptoken] using token: e83pes.u3igpccj2metetu8 |
− | [bootstraptoken] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token | + | [ bootstraptoken] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials |
− | [bootstraptoken] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster | + | [ bootstraptoken] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token |
− | [bootstraptoken] creating the "cluster-info" ConfigMap in the "kube-public" namespace | + | [ bootstraptoken] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster |
− | [addons] Applied essential addon: CoreDNS | + | [ bootstraptoken] creating the "cluster-info" ConfigMap in the "kube-public" namespace |
− | [addons] Applied essential addon: kube-proxy | + | [ addons] Applied essential addon: CoreDNS |
+ | [ addons] Applied essential addon: kube-proxy | ||
Your Kubernetes master has initialized successfully! | Your Kubernetes master has initialized successfully! | ||
Línea 166: | Línea 189: | ||
To start using your cluster, you need to run the following as a regular user: | To start using your cluster, you need to run the following as a regular user: | ||
− | + | mkdir -p $HOME/.kube | |
− | + | sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config | |
− | + | sudo chown $(id -u):$(id -g) $HOME/.kube/config | |
You should now deploy a pod network to the cluster. | You should now deploy a pod network to the cluster. | ||
Línea 178: | Línea 201: | ||
kubeadm join 10.1.1.16:6443 --token e83pes.u3igpccj2metetu8 --discovery-token-ca-cert-hash sha256:7ea9169bc5ac77b3a2ec37e5129006d9a895ce040e306f3093ce77e7422f7f1c | kubeadm join 10.1.1.16:6443 --token e83pes.u3igpccj2metetu8 --discovery-token-ca-cert-hash sha256:7ea9169bc5ac77b3a2ec37e5129006d9a895ce040e306f3093ce77e7422f7f1c | ||
+ | </syntaxhighlight> | ||
− | Realizamos las operaciones solicitadas para finalizar la inicialización de nuestro clúster | + | Realizamos las operaciones solicitadas para finalizar la inicialización de nuestro clúster: |
+ | Creamos un directorio y un archivo de configuración en el directorio de nuestro usuario (root en nuestro caso): | ||
+ | |||
+ | <syntaxhighlight lang="bash"> | ||
mkdir -p $HOME/.kube | mkdir -p $HOME/.kube | ||
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config | cp -i /etc/kubernetes/admin.conf $HOME/.kube/config | ||
+ | </syntaxhighlight> | ||
Implementamos nuestra red « pod Flannel » para nuestro clúster : | Implementamos nuestra red « pod Flannel » para nuestro clúster : | ||
+ | <syntaxhighlight lang="bash"> | ||
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml | kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml | ||
clusterrole.rbac.authorization.k8s.io/flannel created | clusterrole.rbac.authorization.k8s.io/flannel created | ||
Línea 196: | Línea 225: | ||
daemonset.extensions/kube-flannel-ds-ppc64le created | daemonset.extensions/kube-flannel-ds-ppc64le created | ||
daemonset.extensions/kube-flannel-ds-s390x created | daemonset.extensions/kube-flannel-ds-s390x created | ||
+ | </syntaxhighlight> | ||
Nota: mantendremos el último comando proporcionado por el retorno del comando de inicialización desde el lado ("kubeadm join ...") para ejecutarlo en nuestras instancias de trabajo más tarde para unirlas a nuestro clúster. | Nota: mantendremos el último comando proporcionado por el retorno del comando de inicialización desde el lado ("kubeadm join ...") para ejecutarlo en nuestras instancias de trabajo más tarde para unirlas a nuestro clúster. | ||
+ | |||
Ahora podemos hacer las primeras verificaciones de nuestro clúster desde nuestra instancia maestra: | Ahora podemos hacer las primeras verificaciones de nuestro clúster desde nuestra instancia maestra: | ||
Escriba el comando "kubectl get node" para verificar los nodos presentes en su clúster: | Escriba el comando "kubectl get node" para verificar los nodos presentes en su clúster: | ||
+ | <syntaxhighlight lang="bash"> | ||
[root@k8s-master ~]# kubectl get nodes | [root@k8s-master ~]# kubectl get nodes | ||
− | NAME | + | NAME STATUS ROLES AGE VERSION |
k8s-master.cs437cloud.internal Ready master 41m v1.12.2 | k8s-master.cs437cloud.internal Ready master 41m v1.12.2 | ||
+ | </syntaxhighlight> | ||
Nota: actualmente solo existe su nodo maestro, lo cual es normal porque todavía no hemos agregado los otros nodos al clúster. | Nota: actualmente solo existe su nodo maestro, lo cual es normal porque todavía no hemos agregado los otros nodos al clúster. | ||
Escriba el comando "kubectl get pods --all-namespaces" para verificar los pod / contenedores actualmente presentes en su clúster: | Escriba el comando "kubectl get pods --all-namespaces" para verificar los pod / contenedores actualmente presentes en su clúster: | ||
− | + | <syntaxhighlight lang="bash"> | |
[root@k8s-master ~]# kubectl get pods --all-namespaces | [root@k8s-master ~]# kubectl get pods --all-namespaces | ||
NAMESPACE NAME READY STATUS RESTARTS AGE | NAMESPACE NAME READY STATUS RESTARTS AGE | ||
kube-system coredns-576cbf47c7-fwxj9 1/1 Running 0 41m | kube-system coredns-576cbf47c7-fwxj9 1/1 Running 0 41m | ||
kube-system coredns-576cbf47c7-t86s9 1/1 Running 0 41m | kube-system coredns-576cbf47c7-t86s9 1/1 Running 0 41m | ||
− | kube-system etcd-k8s-master.cs437cloud.internal | + | kube-system etcd-k8s-master.cs437cloud.internal 1/1 Running 0 41m |
− | kube-system kube-apiserver-k8s-master.cs437cloud.internal | + | kube-system kube-apiserver-k8s-master.cs437cloud.internal 1/1 Running 0 41m |
kube-system kube-controller-manager-k8s-master.cs437cloud.internal 1/1 Running 0 41m | kube-system kube-controller-manager-k8s-master.cs437cloud.internal 1/1 Running 0 41m | ||
kube-system kube-flannel-ds-amd64-wcm7v 1/1 Running 0 84s | kube-system kube-flannel-ds-amd64-wcm7v 1/1 Running 0 84s | ||
− | kube-system kube-proxy-h94bs | + | kube-system kube-proxy-h94bs 1/1 Running 0 41m |
− | kube-system kube-scheduler-k8s-master.cs437cloud.internal | + | kube-system kube-scheduler-k8s-master.cs437cloud.internal 1/1 Running 0 40m |
+ | </syntaxhighlight> | ||
Nota: Solo hay pods correspondientes a los componentes de Kubernetes necesarios para nuestro nodo maestro (kube-apiserver, etcd, kube-Scheduler, etc.). | Nota: Solo hay pods correspondientes a los componentes de Kubernetes necesarios para nuestro nodo maestro (kube-apiserver, etcd, kube-Scheduler, etc.). | ||
Línea 225: | Línea 259: | ||
El estado de estos componentes se puede verificar con el siguiente comando: | El estado de estos componentes se puede verificar con el siguiente comando: | ||
+ | <syntaxhighlight lang="bash"> | ||
[root@k8s-master ~]# kubectl get cs | [root@k8s-master ~]# kubectl get cs | ||
NAME STATUS MESSAGE ERROR | NAME STATUS MESSAGE ERROR | ||
Línea 230: | Línea 265: | ||
controller-manager Healthy ok | controller-manager Healthy ok | ||
etcd-0 Healthy {"health": "true"} | etcd-0 Healthy {"health": "true"} | ||
− | + | </syntaxhighlight> | |
==Agregar nodos trabajadores al clúster== | ==Agregar nodos trabajadores al clúster== | ||
Acciones a realizar solo en instancias / nodos trabajadores En cada una de sus instancias de trabajo (no lo haga en su instancia maestra), ejecute el comando "kubeadm join ..." provisto al final de la inicialización de su clúster un poco más arriba: | Acciones a realizar solo en instancias / nodos trabajadores En cada una de sus instancias de trabajo (no lo haga en su instancia maestra), ejecute el comando "kubeadm join ..." provisto al final de la inicialización de su clúster un poco más arriba: | ||
− | + | <syntaxhighlight lang="bash"> | |
[root@k8s-worker01 ~]# kubeadm join 10.1.1.16:6443 --token e83pes.u3igpccj2metetu8 --discovery-token-ca-cert-hash sha256:7ea9169bc5ac77b3a2ec37e5129006d9a895ce040e306f3093ce77e7422f7f1c | [root@k8s-worker01 ~]# kubeadm join 10.1.1.16:6443 --token e83pes.u3igpccj2metetu8 --discovery-token-ca-cert-hash sha256:7ea9169bc5ac77b3a2ec37e5129006d9a895ce040e306f3093ce77e7422f7f1c | ||
[preflight] running pre-flight checks | [preflight] running pre-flight checks | ||
Línea 296: | Línea 331: | ||
Run 'kubectl get nodes' on the master to see this node join the cluster. | Run 'kubectl get nodes' on the master to see this node join the cluster. | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==Comprobación del estado del clúster :== | ||
− | |||
Acciones a realizar desde la instancia maestra / node | Acciones a realizar desde la instancia maestra / node | ||
+ | |||
Compruebe que sus nodos de trabajo se hayan agregado a su clúster volviendo a ejecutar el comando "kubectl obtener nodos": | Compruebe que sus nodos de trabajo se hayan agregado a su clúster volviendo a ejecutar el comando "kubectl obtener nodos": | ||
+ | <syntaxhighlight lang="bash"> | ||
[root@k8s-master ~]# kubectl get nodes | [root@k8s-master ~]# kubectl get nodes | ||
NAME STATUS ROLES AGE VERSION | NAME STATUS ROLES AGE VERSION | ||
Línea 305: | Línea 344: | ||
k8s-worker01.cs437cloud.internal Ready <none> 103s v1.12.2 | k8s-worker01.cs437cloud.internal Ready <none> 103s v1.12.2 | ||
k8s-worker02.cs437cloud.internal Ready <none> 48s v1.12.2 | k8s-worker02.cs437cloud.internal Ready <none> 48s v1.12.2 | ||
+ | </syntaxhighlight> | ||
Nota: Podemos ver nuestros dos nodos de trabajo (k8s-worker01 y k8s-worker02), por lo que se han agregado a nuestro clúster. Reiniciemos el comando "kubectl get pods --all-namespaces": | Nota: Podemos ver nuestros dos nodos de trabajo (k8s-worker01 y k8s-worker02), por lo que se han agregado a nuestro clúster. Reiniciemos el comando "kubectl get pods --all-namespaces": | ||
+ | <syntaxhighlight lang="bash"> | ||
[root@k8s-master ~]# kubectl get pods --all-namespaces | [root@k8s-master ~]# kubectl get pods --all-namespaces | ||
NAMESPACE NAME READY STATUS RESTARTS AGE | NAMESPACE NAME READY STATUS RESTARTS AGE | ||
Línea 321: | Línea 362: | ||
kube-system kube-proxy-m2f5r 1/1 Running 0 70s | kube-system kube-proxy-m2f5r 1/1 Running 0 70s | ||
kube-system kube-scheduler-k8s-master.cs437cloud.internal 1/1 Running 0 46m | kube-system kube-scheduler-k8s-master.cs437cloud.internal 1/1 Running 0 46m | ||
+ | </syntaxhighlight> | ||
+ | |||
Nota: Podemos ver que hay tantos pods / contenedores "kube-flannel" y "kube-proxy" que tenemos nodos en nuestro clúster. | Nota: Podemos ver que hay tantos pods / contenedores "kube-flannel" y "kube-proxy" que tenemos nodos en nuestro clúster. | ||
+ | ==Implementar un primer pod== | ||
− | + | Implementaremos nuestro primer pod en nuestro clúster de Kubernetes. | |
− | Implementaremos nuestro primer pod en nuestro clúster de Kubernetes. Por simplicidad, | + | |
− | elegimos implementar un pod (sin replicar) llamado "nginx" y usando la imagen "nginx": | + | Por simplicidad, elegimos implementar un pod (sin replicar) llamado "nginx" y usando la imagen "nginx": |
+ | <syntaxhighlight lang="bash"> | ||
[root@k8s-master ~]# kubectl create deployment nginx --image=nginx | [root@k8s-master ~]# kubectl create deployment nginx --image=nginx | ||
deployment.apps/nginx created | deployment.apps/nginx created | ||
+ | </syntaxhighlight> | ||
Si verificamos, aparecerá en el regreso del comando que enumera los pods de nuestro clúster: | Si verificamos, aparecerá en el regreso del comando que enumera los pods de nuestro clúster: | ||
+ | <syntaxhighlight lang="bash"> | ||
[root@k8s-master ~]# kubectl get pods --all-namespaces | [root@k8s-master ~]# kubectl get pods --all-namespaces | ||
NAMESPACE NAME READY STATUS RESTARTS AGE | NAMESPACE NAME READY STATUS RESTARTS AGE | ||
Línea 346: | Línea 393: | ||
kube-system kube-proxy-m2f5r 1/1 Running 0 12m | kube-system kube-proxy-m2f5r 1/1 Running 0 12m | ||
kube-system kube-scheduler-k8s-master.cs437cloud.internal 1/1 Running 0 57m | kube-system kube-scheduler-k8s-master.cs437cloud.internal 1/1 Running 0 57m | ||
+ | </syntaxhighlight> | ||
Está en la parte superior de la lista en un espacio de nombres diferente de "kube-system" ya que no es un componente específico para el funcionamiento de Kubernetes. | Está en la parte superior de la lista en un espacio de nombres diferente de "kube-system" ya que no es un componente específico para el funcionamiento de Kubernetes. | ||
También es posible no mostrar pods específicos del espacio de nombres del sistema kube haciendo este mismo comando sin el parámetro "--todos los espacios de nombres": | También es posible no mostrar pods específicos del espacio de nombres del sistema kube haciendo este mismo comando sin el parámetro "--todos los espacios de nombres": | ||
+ | |||
+ | <syntaxhighlight lang="bash"> | ||
[root@k8s-master ~]# kubectl get pods | [root@k8s-master ~]# kubectl get pods | ||
NAME READY STATUS RESTARTS AGE | NAME READY STATUS RESTARTS AGE | ||
nginx-55bd7c9fd-vs4fq 1/1 Running 0 3d2h | nginx-55bd7c9fd-vs4fq 1/1 Running 0 3d2h | ||
+ | </syntaxhighlight> | ||
+ | Para mostrar las etiquetas: | ||
− | + | <syntaxhighlight lang="bash"> | |
[root@k8s-master ~]# kubectl get pods --show-labels | [root@k8s-master ~]# kubectl get pods --show-labels | ||
NAME READY STATUS RESTARTS AGE LABELS | NAME READY STATUS RESTARTS AGE LABELS | ||
nginx-55bd7c9fd-ckltn 1/1 Running 0 8m2s app=nginx,pod-template-hash=55bd7c9fd | nginx-55bd7c9fd-ckltn 1/1 Running 0 8m2s app=nginx,pod-template-hash=55bd7c9fd | ||
− | + | </syntaxhighlight> | |
También podemos verificar nuestras implementaciones mediante el siguiente comando: | También podemos verificar nuestras implementaciones mediante el siguiente comando: | ||
+ | <syntaxhighlight lang="bash"> | ||
[root@k8s-master ~]# kubectl get deployments | [root@k8s-master ~]# kubectl get deployments | ||
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE | NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE | ||
nginx 1 1 1 1 93m | nginx 1 1 1 1 93m | ||
+ | </syntaxhighlight> | ||
+ | Por lo tanto, tenemos un pod nginx implementado e iniciado, pero actualmente no se puede acceder desde el exterior. Para hacerlo accesible desde el exterior, debemos exponer el puerto de nuestro pod creando el servicio (de tipo NodePort) mediante el siguiente comando: | ||
− | + | <syntaxhighlight lang="bash"> | |
[root@k8s-master ~]# kubectl create service nodeport nginx --tcp=80:80 | [root@k8s-master ~]# kubectl create service nodeport nginx --tcp=80:80 | ||
service/nginx created | service/nginx created | ||
+ | </syntaxhighlight> | ||
Nuestro servicio se crea así: | Nuestro servicio se crea así: | ||
+ | <syntaxhighlight lang="bash"> | ||
[root@k8s-master ~]# kubectl get svc | [root@k8s-master ~]# kubectl get svc | ||
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE | NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE | ||
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 147m | kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 147m | ||
nginx NodePort 10.108.251.178 <none> 80:30566/TCP 20s | nginx NodePort 10.108.251.178 <none> 80:30566/TCP 20s | ||
+ | </syntaxhighlight> | ||
+ | Nota: Escucha en el puerto 80 / tcp y estará disponible / expuesto desde el exterior en el puerto 30566 / tcp Podemos obtener la franela ip de nuestro pod, así como el nombre del nodo en el que se está ejecutando actualmente a través del siguiente comando : | ||
− | + | <syntaxhighlight lang="bash"> | |
[root@k8s-master ~]# kubectl get pods --selector="app=nginx" --output=wide | [root@k8s-master ~]# kubectl get pods --selector="app=nginx" --output=wide | ||
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE | NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE | ||
nginx-55bd7c9fd-vs4fq 1/1 Running 0 174m 10.244.2.2 k8s-worker02.cs437cloud.internal <none> | nginx-55bd7c9fd-vs4fq 1/1 Running 0 174m 10.244.2.2 k8s-worker02.cs437cloud.internal <none> | ||
+ | </syntaxhighlight> | ||
Aquí nuestro pod nginx tiene ip 10.244.2.2 y se ejecuta en nuestro nodo k8s-worker02. También puede simplemente ejecutar un comando o abrir un shell en nuestro pod nginx a través del siguiente comando (muy similar al comando docker): | Aquí nuestro pod nginx tiene ip 10.244.2.2 y se ejecuta en nuestro nodo k8s-worker02. También puede simplemente ejecutar un comando o abrir un shell en nuestro pod nginx a través del siguiente comando (muy similar al comando docker): | ||
+ | <syntaxhighlight lang="bash"> | ||
[root@k8s-master ~]# kubectl exec -it nginx-55bd7c9fd-vs4fq -- /bin/bash | [root@k8s-master ~]# kubectl exec -it nginx-55bd7c9fd-vs4fq -- /bin/bash | ||
root@nginx-55bd7c9fd-vs4fq:/# | root@nginx-55bd7c9fd-vs4fq:/# | ||
+ | </syntaxhighlight> | ||
Todo lo que tiene que hacer es crear su regla de equilibrio de carga en su red Cloud Ikoula One para acceder / publicitar su servidor web (pod nginx): | Todo lo que tiene que hacer es crear su regla de equilibrio de carga en su red Cloud Ikoula One para acceder / publicitar su servidor web (pod nginx): | ||
− | + | ||
− | + | * Inicie sesión en la interfaz de Cloud Ikoula One [https://cloudstack.ikoula.com/client/] | |
− | + | * vaya a "Red" en el menú vertical izquierdo | |
− | + | * haga clic en su red en la que ha implementado sus instancias de Kubernetes, luego en "Ver direcciones IP" y en su IP de origen NAT y vaya a la pestaña "Configuración" | |
+ | * haga clic en "Load Balancing" y cree su regla especificando un nombre, el puerto público "80" en nuestro caso, el puerto privado "30566" en nuestro caso (ver arriba), eligiendo un algoritmo LB (ej: round-robin) como: | ||
+ | |||
+ | [[File:faq_k8s_regle_lb-01.png|Instance Kubernetes]] | ||
- verifique todas sus instancias de trabajador : | - verifique todas sus instancias de trabajador : | ||
+ | |||
+ | [[File:kubernet.png|Cocher vos instance worker kubernetes]] | ||
Pruebe el acceso a su servidor web / pod nginx desde su navegador (a través de la IP pública de su red en la que creó la regla LB): | Pruebe el acceso a su servidor web / pod nginx desde su navegador (a través de la IP pública de su red en la que creó la regla LB): | ||
+ | |||
+ | [[File:faq_k8s_browser_nginx.png|Accès à votre server web]] | ||
La esperanza de que pueda acceder a estos canales es posible gracias al componente "kube-proxy", que es responsable de realizar un seguimiento de los nodos tan pronto como se hace (en caso de réplicas). | La esperanza de que pueda acceder a estos canales es posible gracias al componente "kube-proxy", que es responsable de realizar un seguimiento de los nodos tan pronto como se hace (en caso de réplicas). |
Revisión actual del 17:09 7 oct 2021
¿Qué es kubernetes?
Kubernetes es una plataforma de código abierto para la gestión de cargas de trabajo y servicios en contenedores. Favorece la configuración declarativa escrita pero también la automatización. Kubernetes es un ecosistema grande y en rápida expansión. Este procedimiento le permitirá implementar rápida y fácilmente un clúster Kubernetes (k8s) de tres nodos de tres instancias de CentOS 7 implementadas dentro de la misma red en la zona avanzada. Una de estas tres instancias será nuestro nodo maestro y las otras dos serán nuestros nodos trabajadores. En resumen, el nodo maestro es el nodo desde el que gestionamos el clúster de Kubernetes (orquestador de contenedores) desde su API y los nodos trabajadores son los nodos en los que se ejecutarán los pods, es decir, los contenedores (Docker en nuestro caso). Asumiremos que sus 3 instancias de CentOS 7 ya están implementadas y que tiene acceso a ellas en ssh para ejecutar los comandos que seguirán. Aquí está la configuración que tenemos en nuestro ejemplo y que servirá como ejemplo a lo largo de este procedimiento :
- Node master : "k8s-master" / 10.1.1.16
- Premier node worker : "k8s-worker01" / 10.1.1.169
- Second node worker : "k8s-worker02" / 10.1.1.87
Preparación del sistema e instalación del tutorial de Kubernetes :
Las siguientes acciones deben realizarse en todas las instancias (maestra y trabajadoras) como root (o con los derechos de sudo necesarios).
Comience por completar el archivo / etc / hosts en cada una de sus instancias para que puedan resolver su nombre de host respectivo (normalmente ya es el caso en una red de zona avanzada donde el enrutador virtual está resolviendo DNS).
En nuestro ejemplo, esto proporciona el siguiente archivo / etc / hosts en nuestras tres instancias (adáptelo con el nombre y la ip de sus instancias) :
cat /etc/hosts
127.0.0.1 localhost
::1 localhost
10.1.1.16 k8s-master
10.1.1.169 k8s-worker01
10.1.1.87 k8s-worker02
Active el módulo puente y las reglas de iptables para este último a través de los siguientes tres comandos :
modprobe bridge
echo "net.bridge.bridge-nf-call-iptables = 1" >> /etc/sysctl.conf
sysctl -p /etc/sysctl.conf
==Agregue el repositorio de YUM Docker :==
cat <<EOF > /etc/yum.repos.d/docker.repo
[docker-ce-stable]
name=Docker CE Stable - \$basearch
baseurl=https://download.docker.com/linux/centos/7/\$basearch/stable
enabled=1
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
EOF
Agregue el depósito YUM Kubernetes :
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
EOF
Instalar Docker :
yum install -y docker-ce
Luego instale los paquetes de Kubernetes necesarios :
syntaxhighlight lang="bash"> yum install -y kubeadm kubelet kubectl </syntaxhighlight>
Edite el archivo de configuración de systemd kubelet (/etc/systemd/system/kubelet.service.d/10-kubeadm.conf) para agregar la siguiente línea en la sección "[Servicio]" :
Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"
Tal que :
cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf # Note: This dropin only works with kubeadm and kubelet v1.11+ [Service] Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf" Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml" *Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"* # This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env # This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use # the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file. EnvironmentFile=-/etc/sysconfig/kubelet ExecStart= ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS
Vuelva a cargar la configuración, habilite y luego inicie los servicios docker y kubelet a través de los siguientes tres comandos :
systemctl daemon-reload
systemctl enable docker kubelet
systemctl start docker kubelet
Deshabilite el intercambio del sistema (kubelet no admite la memoria de intercambio, recibirá un error durante las comprobaciones previas al vuelo al arrancar su clúster a través de kubeadmsi, no deshabilite este) :
swapoff -a
Recuerde también comentar / eliminar la línea de intercambio en el archivo / etc / fstab de cada una de sus instancias, como por ejemplo:
#/dev/mapper/vg01-swap swap swap defaults 0 0
Inicializando el clúster de Kubernetes
Las siguientes acciones solo se deben realizar en la instancia del « Node Master »
Inicie la inicialización de su clúster de Kubernetes mediante el comando a continuación, y modifique el valor del parámetro "--apiserver-Advertise-Address =" con la dirección IP de su instancia maestra.
kubeadm init --apiserver-advertise-address=<ip de votre instance master> --pod-network-cidr=10.244.0.0/16
Nota: No modifique la dirección IP de la red "10.244.0.0/16" indicada en el parámetro "--pod-network-cidr =" porque esta indica que usaremos el complemento CNI Flannel para administrar La parte de la red de nuestros pods.
Así es como debería verse el retorno de este comando cuando el clúster se inicia correctamente:
[ root@k8s-master ~]# kubeadm init --apiserver-advertise-address=10.1.1.16 --pod-network-cidr=10.244.0.0/16
[ init] using Kubernetes version: v1.12.2
[ preflight ] running pre-flight checks
[ preflight/images ] Pulling images required for setting up a Kubernetes cluster
[ preflight/images ] This might take a minute or two, depending on the speed of your internet connection
[ preflight/images] You can also perform this action in beforehand using 'kubeadm config images pull'
[ kubelet] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[ kubelet] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[ preflight] Activating the kubelet service
[ certificates] Generated ca certificate and key.
[ certificates] Generated apiserver-kubelet-client certificate and key.
[ certificates] Generated apiserver certificate and key.
[ certificates] apiserver serving cert is signed for DNS names [k8s-master.cs437cloud.internal kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 10.1.1.16]
[ certificates] Generated front-proxy-ca certificate and key.
[ certificates] Generated front-proxy-client certificate and key.
[ certificates] Generated etcd/ca certificate and key.
[ certificates] Generated etcd/server certificate and key.
[ certificates] etcd/server serving cert is signed for DNS names [k8s-master.cs437cloud.internal localhost] and IPs [127.0.0.1 ::1]
[ certificates] Generated etcd/peer certificate and key.
[ certificates] etcd/peer serving cert is signed for DNS names [k8s-master.cs437cloud.internal localhost] and IPs [10.1.1.16 127.0.0.1 ::1]
[ certificates] Generated etcd/healthcheck-client certificate and key.
[ certificates] Generated apiserver-etcd-client certificate and key.
[ certificates] valid certificates and keys now exist in "/etc/kubernetes/pki"
[ certificates] Generated sa key and public key.
[ kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"
[ kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"
[ kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/controller-manager.conf"
[ kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/scheduler.conf"
[ controlplane] wrote Static Pod manifest for component kube-apiserver to "/etc/kubernetes/manifests/kube-apiserver.yaml"
[ controlplane] wrote Static Pod manifest for component kube-controller-manager to "/etc/kubernetes/manifests/kube-controller-manager.yaml"
[ controlplane] wrote Static Pod manifest for component kube-scheduler to "/etc/kubernetes/manifests/kube-scheduler.yaml"
[ etcd] Wrote Static Pod manifest for a local etcd instance to "/etc/kubernetes/manifests/etcd.yaml"
[ init] waiting for the kubelet to boot up the control plane as Static Pods from directory "/etc/kubernetes/manifests"
[ init] this might take a minute or longer if the control plane images have to be pulled
[ apiclient] All control plane components are healthy after 32.502898 seconds
[ uploadconfig] storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[ kubelet] Creating a ConfigMap "kubelet-config-1.12" in namespace kube-system with the configuration for the kubelets in the cluster
[ markmaster] Marking the node k8s-master.cs437cloud.internal as master by adding the label "node-role.kubernetes.io/master=''"
[ markmaster] Marking the node k8s-master.cs437cloud.internal as master by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[ patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "k8s-master.cs437cloud.internal" as an annotation
[ bootstraptoken] using token: e83pes.u3igpccj2metetu8
[ bootstraptoken] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[ bootstraptoken] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[ bootstraptoken] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[ bootstraptoken] creating the "cluster-info" ConfigMap in the "kube-public" namespace
[ addons] Applied essential addon: CoreDNS
[ addons] Applied essential addon: kube-proxy
Your Kubernetes master has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
You can now join any number of machines by running the following on each node
as root:
kubeadm join 10.1.1.16:6443 --token e83pes.u3igpccj2metetu8 --discovery-token-ca-cert-hash sha256:7ea9169bc5ac77b3a2ec37e5129006d9a895ce040e306f3093ce77e7422f7f1c
Realizamos las operaciones solicitadas para finalizar la inicialización de nuestro clúster:
Creamos un directorio y un archivo de configuración en el directorio de nuestro usuario (root en nuestro caso):
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
Implementamos nuestra red « pod Flannel » para nuestro clúster :
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.extensions/kube-flannel-ds-amd64 created
daemonset.extensions/kube-flannel-ds-arm64 created
daemonset.extensions/kube-flannel-ds-arm created
daemonset.extensions/kube-flannel-ds-ppc64le created
daemonset.extensions/kube-flannel-ds-s390x created
Nota: mantendremos el último comando proporcionado por el retorno del comando de inicialización desde el lado ("kubeadm join ...") para ejecutarlo en nuestras instancias de trabajo más tarde para unirlas a nuestro clúster.
Ahora podemos hacer las primeras verificaciones de nuestro clúster desde nuestra instancia maestra:
Escriba el comando "kubectl get node" para verificar los nodos presentes en su clúster:
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master.cs437cloud.internal Ready master 41m v1.12.2
Nota: actualmente solo existe su nodo maestro, lo cual es normal porque todavía no hemos agregado los otros nodos al clúster.
Escriba el comando "kubectl get pods --all-namespaces" para verificar los pod / contenedores actualmente presentes en su clúster:
[root@k8s-master ~]# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-576cbf47c7-fwxj9 1/1 Running 0 41m
kube-system coredns-576cbf47c7-t86s9 1/1 Running 0 41m
kube-system etcd-k8s-master.cs437cloud.internal 1/1 Running 0 41m
kube-system kube-apiserver-k8s-master.cs437cloud.internal 1/1 Running 0 41m
kube-system kube-controller-manager-k8s-master.cs437cloud.internal 1/1 Running 0 41m
kube-system kube-flannel-ds-amd64-wcm7v 1/1 Running 0 84s
kube-system kube-proxy-h94bs 1/1 Running 0 41m
kube-system kube-scheduler-k8s-master.cs437cloud.internal 1/1 Running 0 40m
Nota: Solo hay pods correspondientes a los componentes de Kubernetes necesarios para nuestro nodo maestro (kube-apiserver, etcd, kube-Scheduler, etc.).
El estado de estos componentes se puede verificar con el siguiente comando:
[root@k8s-master ~]# kubectl get cs
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health": "true"}
Agregar nodos trabajadores al clúster
Acciones a realizar solo en instancias / nodos trabajadores En cada una de sus instancias de trabajo (no lo haga en su instancia maestra), ejecute el comando "kubeadm join ..." provisto al final de la inicialización de su clúster un poco más arriba:
[root@k8s-worker01 ~]# kubeadm join 10.1.1.16:6443 --token e83pes.u3igpccj2metetu8 --discovery-token-ca-cert-hash sha256:7ea9169bc5ac77b3a2ec37e5129006d9a895ce040e306f3093ce77e7422f7f1c
[preflight] running pre-flight checks
[WARNING RequiredIPVSKernelModulesAvailable]: the IPVS proxier will not be used, because the following required kernel modules are not loaded: [ip_vs_sh ip_vs ip_vs_rr ip_vs_wrr] or no builtin kernel ipvs support: map[ip_vs:{} ip_vs_rr:{} ip_vs_wrr:{} ip_vs_sh:{} nf_conntrack_ipv4:{}]
you can solve this problem with following methods:
==Comprobación del estado del clúster==
Acciones a realizar desde la instancia maestra / node
Compruebe que sus nodos de trabajo se hayan agregado a su clúster volviendo a ejecutar el comando "kubectl obtener nodos":
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master.cs437cloud.internal Ready master 46m v1.12.2
k8s-worker01.cs437cloud.internal Ready <none> 103s v1.12.2
k8s-worker02.cs437cloud.internal Ready <none> 48s v1.12.2
1. Run 'modprobe -- ' to load missing kernel modules;
2. Provide the missing builtin kernel ipvs support
[discovery] Trying to connect to API Server "10.1.1.16:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://10.1.1.16:6443"
[discovery] Requesting info from "https://10.1.1.16:6443" again to validate TLS against the pinned public key
[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "10.1.1.16:6443"
[discovery] Successfully established connection with API Server "10.1.1.16:6443"
[kubelet] Downloading configuration for the kubelet from the "kubelet-config-1.12" ConfigMap in the kube-system namespace
[kubelet] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[preflight] Activating the kubelet service
[tlsbootstrap] Waiting for the kubelet to perform the TLS Bootstrap...
[patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "k8s-worker01.cs437cloud.internal" as an annotation
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the master to see this node join the cluster.
[root@k8s-worker02 ~]# kubeadm join 10.1.1.16:6443 --token e83pes.u3igpccj2metetu8 --discovery-token-ca-cert-hash sha256:7ea9169bc5ac77b3a2ec37e5129006d9a895ce040e306f3093ce77e7422f7f1c
[preflight] running pre-flight checks
[WARNING RequiredIPVSKernelModulesAvailable]: the IPVS proxier will not be used, because the following required kernel modules are not loaded: [ip_vs_wrr ip_vs_sh ip_vs ip_vs_rr] or no builtin kernel ipvs support: map[ip_vs:{} ip_vs_rr:{} ip_vs_wrr:{} ip_vs_sh:{} nf_conntrack_ipv4:{}]
you can solve this problem with following methods:
1. Run 'modprobe -- ' to load missing kernel modules;
2. Provide the missing builtin kernel ipvs support
[discovery] Trying to connect to API Server "10.1.1.16:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://10.1.1.16:6443"
[discovery] Requesting info from "https://10.1.1.16:6443" again to validate TLS against the pinned public key
[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "10.1.1.16:6443"
[discovery] Successfully established connection with API Server "10.1.1.16:6443"
[kubelet] Downloading configuration for the kubelet from the "kubelet-config-1.12" ConfigMap in the kube-system namespace
[kubelet] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[preflight] Activating the kubelet service
[tlsbootstrap] Waiting for the kubelet to perform the TLS Bootstrap...
[patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "k8s-worker02.cs437cloud.internal" as an annotation
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the master to see this node join the cluster.
Comprobación del estado del clúster :
Acciones a realizar desde la instancia maestra / node
Compruebe que sus nodos de trabajo se hayan agregado a su clúster volviendo a ejecutar el comando "kubectl obtener nodos":
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master.cs437cloud.internal Ready master 46m v1.12.2
k8s-worker01.cs437cloud.internal Ready <none> 103s v1.12.2
k8s-worker02.cs437cloud.internal Ready <none> 48s v1.12.2
Nota: Podemos ver nuestros dos nodos de trabajo (k8s-worker01 y k8s-worker02), por lo que se han agregado a nuestro clúster. Reiniciemos el comando "kubectl get pods --all-namespaces":
[root@k8s-master ~]# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-576cbf47c7-fwxj9 1/1 Running 0 46m
kube-system coredns-576cbf47c7-t86s9 1/1 Running 0 46m
kube-system etcd-k8s-master.cs437cloud.internal 1/1 Running 0 46m
kube-system kube-apiserver-k8s-master.cs437cloud.internal 1/1 Running 0 46m
kube-system kube-controller-manager-k8s-master.cs437cloud.internal 1/1 Running 0 46m
kube-system kube-flannel-ds-amd64-724nl 1/1 Running 0 2m6s
kube-system kube-flannel-ds-amd64-wcm7v 1/1 Running 0 6m31s
kube-system kube-flannel-ds-amd64-z7mwg 1/1 Running 3 70s
kube-system kube-proxy-8r7wg 1/1 Running 0 2m6s
kube-system kube-proxy-h94bs 1/1 Running 0 46m
kube-system kube-proxy-m2f5r 1/1 Running 0 70s
kube-system kube-scheduler-k8s-master.cs437cloud.internal 1/1 Running 0 46m
Nota: Podemos ver que hay tantos pods / contenedores "kube-flannel" y "kube-proxy" que tenemos nodos en nuestro clúster.
Implementar un primer pod
Implementaremos nuestro primer pod en nuestro clúster de Kubernetes.
Por simplicidad, elegimos implementar un pod (sin replicar) llamado "nginx" y usando la imagen "nginx":
[root@k8s-master ~]# kubectl create deployment nginx --image=nginx
deployment.apps/nginx created
Si verificamos, aparecerá en el regreso del comando que enumera los pods de nuestro clúster:
[root@k8s-master ~]# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
default nginx-55bd7c9fd-5bghl 1/1 Running 0 104s
kube-system coredns-576cbf47c7-fwxj9 1/1 Running 0 57m
kube-system coredns-576cbf47c7-t86s9 1/1 Running 0 57m
kube-system etcd-k8s-master.cs437cloud.internal 1/1 Running 0 57m
kube-system kube-apiserver-k8s-master.cs437cloud.internal 1/1 Running 0 57m
kube-system kube-controller-manager-k8s-master.cs437cloud.internal 1/1 Running 0 57m
kube-system kube-flannel-ds-amd64-724nl 1/1 Running 0 13m
kube-system kube-flannel-ds-amd64-wcm7v 1/1 Running 0 17m
kube-system kube-flannel-ds-amd64-z7mwg 1/1 Running 3 12m
kube-system kube-proxy-8r7wg 1/1 Running 0 13m
kube-system kube-proxy-h94bs 1/1 Running 0 57m
kube-system kube-proxy-m2f5r 1/1 Running 0 12m
kube-system kube-scheduler-k8s-master.cs437cloud.internal 1/1 Running 0 57m
Está en la parte superior de la lista en un espacio de nombres diferente de "kube-system" ya que no es un componente específico para el funcionamiento de Kubernetes. También es posible no mostrar pods específicos del espacio de nombres del sistema kube haciendo este mismo comando sin el parámetro "--todos los espacios de nombres":
[root@k8s-master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-55bd7c9fd-vs4fq 1/1 Running 0 3d2h
Para mostrar las etiquetas:
[root@k8s-master ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-55bd7c9fd-ckltn 1/1 Running 0 8m2s app=nginx,pod-template-hash=55bd7c9fd
También podemos verificar nuestras implementaciones mediante el siguiente comando:
[root@k8s-master ~]# kubectl get deployments
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
nginx 1 1 1 1 93m
Por lo tanto, tenemos un pod nginx implementado e iniciado, pero actualmente no se puede acceder desde el exterior. Para hacerlo accesible desde el exterior, debemos exponer el puerto de nuestro pod creando el servicio (de tipo NodePort) mediante el siguiente comando:
[root@k8s-master ~]# kubectl create service nodeport nginx --tcp=80:80
service/nginx created
Nuestro servicio se crea así:
[root@k8s-master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 147m
nginx NodePort 10.108.251.178 <none> 80:30566/TCP 20s
Nota: Escucha en el puerto 80 / tcp y estará disponible / expuesto desde el exterior en el puerto 30566 / tcp Podemos obtener la franela ip de nuestro pod, así como el nombre del nodo en el que se está ejecutando actualmente a través del siguiente comando :
[root@k8s-master ~]# kubectl get pods --selector="app=nginx" --output=wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
nginx-55bd7c9fd-vs4fq 1/1 Running 0 174m 10.244.2.2 k8s-worker02.cs437cloud.internal <none>
Aquí nuestro pod nginx tiene ip 10.244.2.2 y se ejecuta en nuestro nodo k8s-worker02. También puede simplemente ejecutar un comando o abrir un shell en nuestro pod nginx a través del siguiente comando (muy similar al comando docker):
[root@k8s-master ~]# kubectl exec -it nginx-55bd7c9fd-vs4fq -- /bin/bash
root@nginx-55bd7c9fd-vs4fq:/#
Todo lo que tiene que hacer es crear su regla de equilibrio de carga en su red Cloud Ikoula One para acceder / publicitar su servidor web (pod nginx):
- Inicie sesión en la interfaz de Cloud Ikoula One [1]
- vaya a "Red" en el menú vertical izquierdo
- haga clic en su red en la que ha implementado sus instancias de Kubernetes, luego en "Ver direcciones IP" y en su IP de origen NAT y vaya a la pestaña "Configuración"
- haga clic en "Load Balancing" y cree su regla especificando un nombre, el puerto público "80" en nuestro caso, el puerto privado "30566" en nuestro caso (ver arriba), eligiendo un algoritmo LB (ej: round-robin) como:
- verifique todas sus instancias de trabajador :
Pruebe el acceso a su servidor web / pod nginx desde su navegador (a través de la IP pública de su red en la que creó la regla LB):
La esperanza de que pueda acceder a estos canales es posible gracias al componente "kube-proxy", que es responsable de realizar un seguimiento de los nodos tan pronto como se hace (en caso de réplicas). Acaba de desplegar un clúster Kubernetes de 3 nodos con un maestro y unos trabajadores traseros.
Ir más lejos
Puede ir más allá implementando el panel de control de Kubernetes o creando volúmenes persistentes para sus pods, por ejemplo, aumentando el número de trabajadores de sus nodos, o incluso redundando el rol maestro para lograr una alta disponibilidad o incluso dedicar nodos a ciertos componentes como Etcd, por ejemplo. .