Instalación del cliente kubectl en Ubuntu y conectarnos a un Cluster de Kubernetes

Para evitar errores en las validaciones de las API que utiliza kubernetes es necesario instalar la misma versión de kubectl que la versión de kubernetes que corre en nuestro Cluster.

Para este ejemplo vamos a utilizar un cluster basado en minikube. Como todos sabemos minikube es un cluster formado por una sola máquina y que podemos utilizar cuando queremos formarnos y comprender como kubernetes funciona.

Este artículo no pretende dar los pasos necesario para conectarnos a un cluster de producción si no identificar los recursos que intervienen entre un cliente kubectl y un Cluster de kubernetes. Como en casi todos estos sistemas todo esta basado en una autenticación basada en certificados.

Instalación en un sistema linux

$ curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.7.0/bin/linux/amd64/kubectl
$ chmod +x ./kubectl
$ sudo mv ./kubectl /usr/local/bin/kubectl

Configurar el acceso al Cluster

La configuración de acceso a un Cluster se encuentra normalmente en

~/.kube/config

En el caso que nos ocupa estamos utilizando minikube en un sistema Windows y lo que queremos es poder conectarnos desde una maquina virtual Ubuntu al cluster de minikube. Copiamos la configuración de nuestro sistema en nuestro Ubuntu.

Lo normal no es hacerlo así, si no que nos proporcionen un certificado cliente para nosotros y así autenticarnos con el cluster, o bien generar nosotros una petición de firma de certificado y que la CA nos la firme.

La configuración en nuestro sistema Windows es la siguiente:

$ cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
    certificate-authority: C:\Software\minikube\.minikube\ca.crt
    server: https://192.168.99.100:8443
  name: minikube
contexts:
- context:
    cluster: minikube
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
  user:
    client-certificate: C:\Software\minikube\.minikube\apiserver.crt
    client-key: C:\Software\minikube\.minikube\apiserver.key

$ kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority: C:\Software\minikube\.minikube\ca.crt
    server: https://192.168.99.100:8443
  name: minikube
contexts:
- context:
    cluster: minikube
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
  user:
    client-certificate: C:\Software\minikube\.minikube\apiserver.crt
    client-key: C:\Software\minikube\.minikube\apiserver.key

Copiamos dicha configuración en Ubuntu en
~/.kube/config
y modificamos la ruta de los certificados. Como vemos tenemos

  • el certificado de la CA

y

  • clave privada de cliente y el certificado de cliente

que nuestro administrador de kubernetes nos ha generado para nosotros.

Nuestra configuración en Ubuntu quedaría:

$ find /var/minikube/
/var/minikube/
/var/minikube/.minikube
/var/minikube/.minikube/ca.crt
/var/minikube/.minikube/apiserver.key
/var/minikube/.minikube/apiserver.crt

$ cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
    certificate-authority: /var/minikube/.minikube/ca.crt
    server: https://192.168.99.100:8443
  name: minikube
contexts:
- context:
    cluster: minikube
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
  user:
    client-certificate: /var/minikube/.minikube/apiserver.crt
    client-key: /var/minikube/.minikube/apiserver.key

Validamos la configuración

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.0", GitCommit:"d3ada0119e776222f11ec7945e6d860061339aad", GitTreeState:"clean", BuildDate:"2017-06-29T23:15:59Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"7", GitVersion:"v1.7.0", GitCommit:"d3ada0119e776222f11ec7945e6d860061339aad", GitTreeState:"clean", BuildDate:"2017-07-26T00:12:31Z", GoVersion:"go1.8.3", Compiler:"gc", Platform:"linux/amd64"}

$ kubectl get all
NAME                                   READY     STATUS    RESTARTS   AGE
po/frontend-3872149310-0qz3m           1/1       Running   4          1d
po/hello-1243552595-bv62v              1/1       Running   2          1d
po/hello-1243552595-h9fdd              1/1       Running   2          1d
po/hello-1243552595-jmwp2              1/1       Running   2          1d
po/hello-1243552595-k3q4d              1/1       Running   2          1d
po/hello-1243552595-w4sw1              1/1       Running   2          1d
po/hello-1243552595-xb96t              1/1       Running   2          1d
po/hello-1243552595-xvw2q              1/1       Running   2          1d
po/hello-minikube-180744149-b7g45      1/1       Running   5          48d
po/nginx-deployment-2078889897-mcdz4   1/1       Running   3          2d
po/nginx-deployment-2078889897-qc4dk   1/1       Running   3          2d
po/nginx-deployment-2078889897-xnzzh   1/1       Running   3          2d

NAME                 CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE
svc/frontend         10.0.0.30         80:31303/TCP     1d
svc/hello            10.0.0.6             80/TCP           1d
svc/hello-minikube   10.0.0.201        8080:31033/TCP   48d
svc/kubernetes       10.0.0.1             443/TCP          49d

NAME                      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
deploy/frontend           1         1         1            1           1d
deploy/hello              7         7         7            7           1d
deploy/hello-minikube     1         1         1            1           48d
deploy/nginx-deployment   3         3         3            3           2d

NAME                             DESIRED   CURRENT   READY     AGE
rs/frontend-3872149310           1         1         1         1d
rs/hello-1243552595              7         7         7         1d
rs/hello-minikube-180744149      1         1         1         48d
rs/nginx-deployment-2078889897   3         3         3         2d
rs/nginx-deployment-2558903419   0         0         0         2d
rs/nginx-deployment-3896099094   0         0         0         2d

Configurar el acceso a más de un cluster

Desde nuestr cliente kubectl podemos conectarnos a más de un cluster. Solo tenemos que modificar el fichero de configuración añadiendo la nueva entrada. Si nos fijamos tenemos varias secciones para indicar la configuración de mas de un cluster y el mecanismo de autenticación para cada uno de ellos.

Estas secciones son <strong>clusters</strong>, <strong>context</strong> y <strong>users</strong>.

Para cambiarnos y apuntar a otro cluster diferente de donde nos encontremos es bastante sencillo. Solo tenemos que apuntar al contexto que queremos.

En este caso solo tenemos 1 contexto, es decir 1 configuración a cluster. El comando sería:

$ kubectl config use-context minikube
Switched to context "minikube"
Anuncios

Kubernetes – Vídeos resumen de la arquitectura detrás Kubernetes

Vídeos de diferentes canales donde resumen de forma muy esquemática y clara la arquitectura detrás de Kubernetes.

Son vídeos extraídos de los canales siguientes:

Kubernetes in 5 minutes
kubernete 101. Master
Kubernetes 101. Nodes
Kubernetes. Master and Scheduler
Kubernetes. Understanding Resources via YAML, Deployments, Replica Sets and Pods
Kubernetes: Cluster Integration: Services: Getting in and out of the cluster
Kubernetes: DNS and Name discovery
Networking with Kubernetes

elasticsearch, analizador spanish con filtro fonético

Pasos a seguir para crear un indice con un analizdor en español con reconocimiento de fonético.

Especialmente util si queremos buscar para un texto como este:

  • “Habia una vez un barquito chiquitito que navegaba ….”

palabras como

  • avia, nabegava

es decir, palabras mal escritas pero que se pronuncian igual.

Pasos previo necesarios

Instalar plugin

En cada nodo debemos instalar el plugin y reiniciar.

sudo bin/plugin install analysis-phonetic

Crear el indice y el mapping

curl -XDELETE http://localhost:9201/indice_fonetico

curl -XPUT http://localhost:9201/indice_fonetico

curl -XPOST http://localhost:9201/indice_fonetico/_close

curl -XPUT http://localhost:9201/indice_fonetico/_settings?pretty -d '{
  "analysis" : {
    "analyzer":{
      "spanish_no_accent": {
          "tokenizer": "standard",
          "filter":  [ "lowercase", "asciifolding", "spanish_stop", "filtro_fonetico", "spanish_stemmer" ]
          }
    },
    "filter" : {
            "spanish_stemmer" : {
                "type" : "stemmer",
                "name" : "spanish"
            },
            "spanish_stop": {
                             "type":        "stop",
                             "stopwords": [ "_spanish_" ]
      },
      "filtro_fonetico": {
          "type": "phonetic",
          "encoder": "beidermorse",
          "replace": false,
          "languageset": ["spanish"]
      }
          }
  }
}'

curl -XPOST http://localhost:9201/indice_fonetico/_open

curl -XPUT http://localhost:9201/indice_fonetico/_mapping/documento?pretty -d '{
"properties":{
  "documento":{
     "type":"string",
     "analyzer":"spanish_no_accent"
  }
 }
}'

Indexar datos y preparar una query

Indexamos un documento

PUT indice_fonetico/documento/1
{
  "documento": "Habia una vez un barquito chiquitito que navegaba ...."
}

Realizamos una búsqueda

  • avia

Query y respuesta

GET indice_fonetico/documento/_search
{
  "query": {
    "match": {
      "documento": {
        "query": "avia"
      }
    }
  }
}
{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 1.7499999,
    "hits": [
      {
        "_index": "indice_fonetico",
        "_type": "documento",
        "_id": "4",
        "_score": 1.7499999,
        "_source": {
          "documento": "Habia una vez un barquito chiquitito que navegaba ...."
        }
      }
    ]
  }
}

Términos generados por este analizador

En cualquier momento podemos ver los términos que genera este analizador, para entender mejor las búsquedas que podemos realizar con este analizador y el nuevo filtro fonético.

Invocación del analizador

POST prueba_fonetica/_analyze
{
  "analyzer": "spanish_no_accent",
  "text":     "barquito"
}

Términos generados por el analizador

{
  "tokens": [
    {
      "token": "barkit",
      "start_offset": 0,
      "end_offset": 8,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "borkit",
      "start_offset": 0,
      "end_offset": 8,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "varkit",
      "start_offset": 0,
      "end_offset": 8,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "vorkit",
      "start_offset": 0,
      "end_offset": 8,
      "type": "<ALPHANUM>",
      "position": 0
    }
  ]
}

Para entender mejor el comportamiento de este filtro fonético podemos crear un analizador donde solamente tengamos como filtro el filtro fonético.

curl -XPUT http://localhost:9201/indice_fonetico/_settings?pretty -d '{
  "analysis" : {
    "analyzer":{
      "spanish_no_accent": {
          "tokenizer": "standard",
          "filter":  [ "lowercase", "filtro_fonetico" ]
          }
    },
    "filter" : {
      "filtro_fonetico": {
          "type": "phonetic",
          "encoder": "beidermorse",
          "replace": false,
          "languageset": ["spanish"]
      }
    }
  }
}'

Git Cookbook. Cambiar en nuestro repositorio local la rama del repositorio remoto que seguimos

Git

Para la elaboración de este artículo se ha utilizado la versión de git 2.7.4

Esta situación nos la encontramos cuando trabajamos con multiples repositorios remotos en nuestro repositorio local y en un momento determinado queremos dejar de seguir a la rama del repositorio remoto por defecto origin por otra rama de otro repositorio remoto diferente.

Para verlo con más claridad vamos a verlo con una secuencia de comandos.

Estado local de nuestro repositorio

$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean

Listado de los repositorios remotos

$ git remote -v
gitlab  ssh://... (fetch)
gitlab  ssh://... (push)
origin  ssh://... (fetch)
origin  ssh://... (push)

Cambiar el repositorio remoto por defecto al que seguimos

La opción -u es la misma que –set-upstream-to.

$ git branch -u gitlab/master
Branch master set up to track remote branch master from gitlab.

$ git status
On branch master
Your branch is up-to-date with 'gitlab/master'.
nothing to commit, working directory clean

A partir de este momento cada vez que hagamos cualquier operación con git donde interviene el repositorio, si no le indicamos nada, el repositorio por defecto donde se hace las operaciones es gitlab

Por ejemplo, cambiamos un fichero y hacemos un git push. Por defecto se va al repositorio remoto gitlab. Si no cambiamos el repositorio remoto por defecto al que seguimos, para enviar los cambios a origin tendriamos que hacer un git push origin master.

Vamos a seguir con la secuencia de comandos.

$ echo "Readme.md" > README.md
$ git add .
$ git commit -m "fichero readme"

# diferencia entre repositorio local y el remoto origin
#
$ git diff origin/master --name-only
README.md

# diferencia entre repositorio local y el remoto gitlab
#
$ git diff gitlab/master --name-only
README.md

# realizamos un push sin indicar el repositorio remoto. Los cambios van por defecto al repositorio *gitlab*
#
$ git push
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 299 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To ssh://...
   2c0999b..61dbe03  master -> master

# diferencia entre repositorio local y el remoto gitlab. En este caso no hay ninguna diferencia
#  
$ git diff gitlab/master --name-only

# diferencia entre repositorio local y el remoto origin. En este caso sigue existiendo el fichero modificado
#
$ git diff origin/master --name-only
README.md

# Subir los cambios al *origin* sin modificar el repositorio remoto que seguimos
#
$ git push origin master
Password authentication
Password:
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 299 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
remote: Resolving deltas: 100% (1/1)
remote: Updating references: 100% (1/1)
To ssh://...
   2c0999b..61dbe03  master -> master

# Ya no existe diferencia entre repositorio local y el remoto origin.
#
$ git diff origin/master --name-only

Creación de un cluster con docker swarm

Docker Logo

El artículo se ha escrito utilizando docker 1.12 y 4 máquinas ubuntu 16.04.1 LTS virtualizadas con VirtualBox, de las cuales solo 1 de ellas tenia instalado docker-machine.

Este artículo es una guia rápida de creación de un cluster de nodos de docker, gestionados de forma nativa por docker swarm.

Algunos de los conceptos manejados por docker swarm son:

  • nodos. Diferentes equipos ejecutando docker
  • manager. Uno de los nodos del cluster actúan de manager y es el responsable de gestionar los nodos del cluster.
  • worker. El resto de nodos son los workers. Estos con los responsables de ejecutar las tareas que el manager le indica, creando y ejecutando los contenedores. El manager también puede actuar como worker.

Cuando desplegamos una aplicación en un cluster de docker swarm, creamos una definición de un servicio. Esta definición del servicio la enviamos al manager. El manager divide el servicio en tareas o tasks y las envia a los workers, que son los que finalmente ejecutan las tareas. Estas tareas o tasks se traducen en la creación de los contenedores que son los que finalmente ejecutan nuestra aplicación.

Sigue leyendo

Aprovisionar o instalar docker en una máquina remota utilizando docker-machine

Docker Logo

Para la elaboración del artículo hemos utilizado docker 1.12 y dos equipos ubuntu 16.04.1 LTS virtualizados con Virtualbox

Guía rápida de aprovisionamiento de una máquina remota utilizando docker-machine y el driver genérico. Se trata por tanto de instalar de docker forma remota desde un equipo local.

Para el artículo vamos a suponer que

  • la máquina remota se llama remotehost
  • la cuenta del usuario del equipo remoto es udocker
  • la maquina local donde ejecutamos docker-machine es sourcehost

Sigue leyendo

Realizar un login remoto o ssh utilizando autenticación por certificado RSA

ssh

… o lo que es lo mismo realizar un login remoto o ssh sin utilizar usuario y contraeña.

Es el caso en el que queremos realizar un login remoto o login por ssh desde un equipo A a un equipo B (o a ‘n’ equipos) y no queremos utilizar el usuario y contraseña cada vez que realizamos el login.

Los pasos son los siguientes:

  • Relizar el login en el equipo A
  • Generar la clave rsa para autenticación
  • Copiar la clave rsa generada en el equipo B
  • Realizar el login en el equipo B utilizando la clave recién generada

Como podemos imaginarnos necesitamos tener cuentas en ambos equipos para poder realizar estos pasos

Generar las claves para autenticación desde el equipo A

El comando ssh-keygen genera las claves de autenticación que podemos utilizar para el protocolo ssh de versiones 1 y 2. En este caso dejamos en blanco la passphrase.

La cuenta de usuario en este equipo se corresponde con user1.

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user1/.ssh/id_rsa):
/home/user1/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user1/.ssh/id_rsa.
Your public key has been saved in /home/user1/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:a3xg5xjLeq8t7qYVwcaa/m4wK/K+zn/ugE5GTxW8WHE user1@equipoa
The key's randomart image is:
+---[RSA 2048]----+
...
...
+----[SHA256]-----+

Copiar la clave recién generada en el equipo B desde la cuenta de usuario del equipo A

La cuenta de usuario en el equipo B se corresponde con user2.

$ ssh-copy-id user2@equipob
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/user1/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
user2@equipob's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'user2@equipob'"
and check to make sure that only the key(s) you wanted were added.

Realizar el login ssh desde el equipo A en el equipo remoto B utilizando la clave recién copiada

$ ssh user2@equipob
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-31-generic x86_64)

A partir de ahora cada vez que realicemos el login en el equipo B no necesitaremos realizar el login ssh con la contraseña.