<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"><channel><title>pornoHARDWARE.com</title><link>https://pornohardware.com/</link><description>El blog de un administrador de sistemas, friki, programador, padre y alienígena a partes iguales.</description><lastBuildDate>Sat, 27 Feb 2021 03:54:02 +0100</lastBuildDate><item><title>Unifica el estilo del código de un proyecto con Editorconfig</title><link>https://pornohardware.com/2021/02/27/unifica-el-estilo-del-codigo-de-un-proyecto-con-editorconfig/</link><description>&lt;p&gt;Dicen que en la variedad está el gusto. Y efectivamente, siempre es mejor tener muchas opciones para poder elegir entre
ellas la que más nos guste. Pero cuando por &lt;em&gt;variedad&lt;/em&gt; no nos referimos a los sabores de un helado sino a que en un
mismo proyecto tenemos gente que usa un editor de código que finaliza los archivos con una nueva linea mientras que
otros usan otro editor que no, unos indentan los archivos con espacios y otros con tabuladores, unos tienen el tamaño máximo
de cada línea de 80 carácteres y otros de 120... al final acabamos con un popurrí de estilos que en el mejor de los
casos hará que las revisiones de código sean un infierno y que haya cambios en el código cuya aprobación dependerá
subjetivamente de la persona que esté revisándolos en ese momento. La variedad ahora ya no está tan bien, ¿verdad?&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Sat, 27 Feb 2021 03:54:02 +0100</pubDate><guid isPermaLink="false">tag:pornohardware.com,2021-02-27:/2021/02/27/unifica-el-estilo-del-codigo-de-un-proyecto-con-editorconfig/</guid><category>Varios</category><category>Programación</category></item><item><title>Alta disponibilidad en etcd: Desplegando un cluster paso a paso</title><link>https://pornohardware.com/2018/05/06/alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/</link><description>&lt;p&gt;Si estas intentando montar un &lt;a href="https://es.wikipedia.org/wiki/Cl%C3%BAster_de_alta_disponibilidad"&gt;cluster&lt;/a&gt; de &lt;a href="https://kubernetes.io/"&gt;Kubernetes&lt;/a&gt; en alta disponibilidad, o bien tienes alguna experiencia en esto porque lo has visto anteriormente o porque ya has trabajado con ello antes, o bien has llegado a este artículo buscando ayuda en Internet después de haber pasado un buen rato intentando seguir sin éxito los pasos de la incorrecta documentación oficial de &lt;em&gt;multi-master&lt;/em&gt; en Kubernetes &lt;a href="https://kubernetes.io/docs/setup/independent/high-availability/"&gt;que hay publicada al respecto&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Bien por este motivo o bien porque quieres tener un servicio de &lt;a href="https://coreos.com/etcd/docs/latest/"&gt;etcd&lt;/a&gt; tolerante a fallos para tu proyecto, espero que con este artículo no te quede ninguna duda sobre cómo montar un cluster para conseguir alta disponibilidad y comunicaciones totalmente cifradas con SSL en el servicio de &lt;em&gt;etcd&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Así que basta ya de hablar y vamos &lt;em&gt;al turrón&lt;/em&gt;...&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Sun, 06 May 2018 00:14:02 +0100</pubDate><guid isPermaLink="false">tag:pornohardware.com,2018-05-06:/2018/05/06/alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/</guid><category>Varios</category><category>Linux</category><category>Kubernetes</category></item><item><title>High availability in etcd: Deploying a cluster step by step</title><link>https://pornohardware.com/en/2018/05/06/alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/</link><description>&lt;p&gt;Si estas intentando montar un &lt;a href="https://es.wikipedia.org/wiki/Cl%C3%BAster_de_alta_disponibilidad"&gt;cluster&lt;/a&gt; de &lt;a href="https://kubernetes.io/"&gt;Kubernetes&lt;/a&gt; en alta disponibilidad, o bien tienes alguna experiencia en esto porque lo has visto anteriormente o porque ya has trabajado con ello antes, o bien has llegado a este artículo buscando ayuda en Internet después de haber pasado un buen rato intentando seguir sin éxito los pasos de la incorrecta documentación oficial de &lt;em&gt;multi-master&lt;/em&gt; en Kubernetes &lt;a href="https://kubernetes.io/docs/setup/independent/high-availability/"&gt;que hay publicada al respecto&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Bien por este motivo o bien porque quieres tener un servicio de &lt;a href="https://coreos.com/etcd/docs/latest/"&gt;etcd&lt;/a&gt; tolerante a fallos para tu proyecto, espero que con este artículo no te quede ninguna duda sobre cómo montar un cluster para conseguir alta disponibilidad y comunicaciones totalmente cifradas con SSL en el servicio de &lt;em&gt;etcd&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Así que basta ya de hablar y vamos &lt;em&gt;al turrón&lt;/em&gt;...&lt;/p&gt;
&lt;!-- more --&gt;

&lt;p&gt;Para intentar organizarlo un poco, voy a dividir el artículo en varias partes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="#whatis"&gt;¿Qué es etcd?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#init"&gt;Consideraciones iniciales de nuestro cluster&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#ssl"&gt;Creación de los certificados SSL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#install"&gt;Instalación y configuración del cluster&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#admin"&gt;Administración básica&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="#refs"&gt;Referencias&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;¿Qué es etcd?&lt;a name="whatis"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/coreos/etcd"&gt;Etcd&lt;/a&gt; es un servidor de almacenamiento de datos de tipo clave-valor (similar a &lt;a href="https://redis.io/"&gt;Redis&lt;/a&gt;, aunque con bastantes diferencias) diseñado para funcionar de forma distribuida, rápida y estable.&lt;/p&gt;
&lt;p&gt;Forma parte del sistema &lt;a href="https://coreos.com/"&gt;CoreOS&lt;/a&gt;, y es un proyecto de &lt;a href="https://es.wikipedia.org/wiki/C%C3%B3digo_abierto"&gt;código abierto&lt;/a&gt; escrito en &lt;a href="https://golang.org/"&gt;Go&lt;/a&gt; y liberado bajo licencia &lt;a href="https://github.com/coreos/etcd/blob/master/LICENSE"&gt;Apache 2.0&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Etcd es un proyecto maduro y que lleva muchos años en desarrollo constante por lo que muchos grandes proyectos lo utilizan para almacenar sus configuraciones debido a su gran estabilidad y rapidez, pero últimamente su desarrollo se ha visto potenciado aún más sobre todo por el auge que está teniendo &lt;a href="https://kubernetes.io/"&gt;Kubernetes&lt;/a&gt;, que es uno de estos grandes proyectos que utilizan &lt;em&gt;etcd&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Toda la comunicación con &lt;em&gt;etcd&lt;/em&gt; se realiza a través de una &lt;a href="https://es.wikipedia.org/wiki/Interfaz_de_programaci%C3%B3n_de_aplicaciones"&gt;API&lt;/a&gt; que puede ser explotada mediante &lt;a href="http://json.org/"&gt;JSON&lt;/a&gt; a través de &lt;a href="https://es.wikipedia.org/wiki/Protocolo_de_transferencia_de_hipertexto"&gt;HTTP/HTTPS&lt;/a&gt; o a través del cliente &lt;a href="https://github.com/coreos/etcd/tree/master/etcdctl"&gt;etcdctl&lt;/a&gt; para linea de comandos.&lt;/p&gt;
&lt;p&gt;A principios de año (enero de 2018), CoreOS (y por lo tanto &lt;em&gt;etcd&lt;/em&gt;) fué comprado por &lt;a href="https://www.redhat.com"&gt;Redhat&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Consideraciones iniciales de nuestro cluster&lt;a name="init"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Como recomendación general, para montar un cluster en alta disponibilidad debemos utilizar el mayor número posible de nodos.&lt;/p&gt;
&lt;p&gt;En cualquier caso, debemos utilizar &lt;strong&gt;al menos 3 nodos&lt;/strong&gt; para el cluster ya que aunque teóricamente bastaría con 2 nodos para tener tolerancia a fallos, en un cluster de &lt;em&gt;etcd&lt;/em&gt; siempre debe haber un nodo &lt;em&gt;principal&lt;/em&gt; (llamado &lt;em&gt;leader&lt;/em&gt;) que es el que tendrá el control de determinadas funciones del cluster, y si ese nodo &lt;em&gt;leader&lt;/em&gt; quedara fuera de servicio por algún motivo, los demás nodos del cluster utilizarían un &lt;em&gt;quórum&lt;/em&gt; para designar quién sería el nuevo &lt;em&gt;leader&lt;/em&gt;. El algoritmo que se utiliza para obtener dicho quórum es &lt;a href="https://raft.github.io/"&gt;Raft&lt;/a&gt;, usado no solo para este proyecto sino para muchísimos otros, por lo tanto debe haber al menos 3 nodos para que si se pierde el nodo &lt;em&gt;leader&lt;/em&gt; los otros 2 puedan designar un &lt;em&gt;sustituto&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Así que en este artículo vamos a crear un cluster con 3 nodos que tendrán estas características:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th align="left"&gt;#&lt;/th&gt;
&lt;th align="left"&gt;Nombre&lt;/th&gt;
&lt;th align="left"&gt;IP&lt;/th&gt;
&lt;th align="left"&gt;RAM&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td align="left"&gt;1&lt;/td&gt;
&lt;td align="left"&gt;etcd01&lt;/td&gt;
&lt;td align="left"&gt;192.168.1.83&lt;/td&gt;
&lt;td align="left"&gt;2 Gb&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;2&lt;/td&gt;
&lt;td align="left"&gt;etcd02&lt;/td&gt;
&lt;td align="left"&gt;192.168.1.84&lt;/td&gt;
&lt;td align="left"&gt;2 Gb&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td align="left"&gt;3&lt;/td&gt;
&lt;td align="left"&gt;etcd03&lt;/td&gt;
&lt;td align="left"&gt;192.168.1.85&lt;/td&gt;
&lt;td align="left"&gt;2 Gb&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Todas estas máquinas parten de una instalación limpia de mi sistema operativo favorito (&lt;a href="https://www.debian.org"&gt;Debian&lt;/a&gt;, concretamente la versión &lt;em&gt;stable&lt;/em&gt; 9.4) pero debería funcionar prácticamente igual (con ligeros cambios en algunos &lt;em&gt;paths&lt;/em&gt; o en el nombre de algún paquete) en cualquier otra distribución de Linux.&lt;/p&gt;
&lt;p&gt;Antes de empezar, asegúrate de que todos estos servidores tienen conectividad entre ellos, y que resuelven los nombres de los demás. Lo mejor sería que tuvieras tu propio servidor &lt;a href="https://es.wikipedia.org/wiki/Sistema_de_nombres_de_dominio"&gt;DNS&lt;/a&gt; (&lt;a href="https://www.isc.org/downloads/bind/1"&gt;bind&lt;/a&gt; o similar) configurado en tu red para resolver todos los nombres de tus servidores, pero sino, puedes añadir las 3 direcciones IP con sus respectivos nombres al archivo &lt;code&gt;/etc/hosts&lt;/code&gt; de cada uno de ellos:&lt;/p&gt;
&lt;figure class='code'&gt;
&lt;figcaption&gt;&lt;span class="liquid-tags-code-title"&gt;/etc/hosts&lt;/span&gt;&lt;a href='/files/2018-05-06-alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/hosts'&gt;download&lt;/a&gt;&lt;/figcaption&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="mi"&gt;127&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;       &lt;span class="n"&gt;localhost&lt;/span&gt;
&lt;span class="mi"&gt;192&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;83&lt;/span&gt;    &lt;span class="n"&gt;etcd01&lt;/span&gt;
&lt;span class="mi"&gt;192&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;84&lt;/span&gt;    &lt;span class="n"&gt;etcd02&lt;/span&gt;
&lt;span class="mi"&gt;192&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;168&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;85&lt;/span&gt;    &lt;span class="n"&gt;etcd03&lt;/span&gt;

&lt;span class="o"&gt;#&lt;/span&gt; &lt;span class="n"&gt;The&lt;/span&gt; &lt;span class="n"&gt;following&lt;/span&gt; &lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="k"&gt;are&lt;/span&gt; &lt;span class="n"&gt;desirable&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;IPv6&lt;/span&gt; &lt;span class="n"&gt;capable&lt;/span&gt; &lt;span class="n"&gt;hosts&lt;/span&gt;
&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;     &lt;span class="n"&gt;localhost&lt;/span&gt; &lt;span class="n"&gt;ip6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;localhost&lt;/span&gt; &lt;span class="n"&gt;ip6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;loopback&lt;/span&gt;
&lt;span class="n"&gt;ff02&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;ip6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;allnodes&lt;/span&gt;
&lt;span class="n"&gt;ff02&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="n"&gt;ip6&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;allrouters&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/figure&gt;
&lt;p&gt;Ni qué decir tiene que es recomendable asegurarse siempre de que partimos de un sistema actualizado:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ sudo apt-get update
$ sudo apt-get dist-upgrade
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;En mi caso, las últimas versiones disponibles en el momento de escribir este artículo son (no te preocupes si alguno no te suena, los iremos viendo a medida que los vayamos necesitando):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Etcd: 3.3.4&lt;/li&gt;
&lt;li&gt;cfssl: 1.2&lt;/li&gt;
&lt;li&gt;cfssljson: 1.2&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Creación de los certificados SSL&lt;a name="ssl"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Como acabo de comentar, toda la comunicación tanto entre el cliente y el servidor de &lt;em&gt;etcd&lt;/em&gt; como entre los propios servidores de &lt;em&gt;etcd&lt;/em&gt; de un cluster puede realizarse por SSL, cifrando de esa forma todas las comunicaciones y aportando otra capa de seguridad al sistema.&lt;/p&gt;
&lt;p&gt;Aunque podríamos montar el cluster utilizando únicamente HTTP, es muy sencillo generar unos certificados y configurar &lt;em&gt;etcd&lt;/em&gt; para que los use, por lo que vamos a hacerlo de esta forma.&lt;/p&gt;
&lt;p&gt;Lo primero que debemos hacer será generar los certificados que vamos a necesitar, que son:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cliente&lt;/strong&gt;: Este certificado es el que usaremos nosotros (o la aplicación que se vaya a conectar a &lt;em&gt;etcd&lt;/em&gt;, como por ejemplo &lt;em&gt;Kubernetes&lt;/em&gt;) para conectarnos al cluster.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Servidor&lt;/strong&gt;: Este certificado es el que usará cada uno de los nodos de nuestro cluster para cifrar las comunicaciones.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Peer&lt;/strong&gt; (&lt;em&gt;no se muy bien como traducirlo&lt;/em&gt;): Este certificado es el que usará cada nodo para conectarse a los demás nodos del cluster (muy similar al certificado de cliente, pero generaremos ambos para diferenciar unas conexiones de otras).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La explicación sobre el intercambio de certificados en una comunicación SSL, los tipos de certificados, su firma, etc. es algo que queda fuera del ámbito de este artículo por lo que no voy a explicarlo con demasiado detalle. Si alguno de estos conceptos no te queda claro, te recomiendo que investigues un poco acerca del funcionamiento de estos certificados (intentaré escribir otro artículo sobre SSL algún dia).&lt;/p&gt;
&lt;p&gt;Para generar los certificados vamos a utilizar &lt;a href="https://cfssl.org/"&gt;&lt;code&gt;cfssl&lt;/code&gt;&lt;/a&gt;, que es una herramienta de código-abierto desarrollada por &lt;a href="https://www.cloudflare.com/es/"&gt;CloudFlare&lt;/a&gt; muy fácil de utilizar y que nos permite generar y firmar certificados desde la linea de comandos.&lt;/p&gt;
&lt;p&gt;En lugar de ir nodo por nodo, vamos a instalar la herramienta en nuestra máquina local para generar los certificados, y una vez generados los copiaremos a los 3 nodos.&lt;/p&gt;
&lt;p&gt;Como dije antes, en el momento de escribir este artículo la última versión de &lt;code&gt;cfssl&lt;/code&gt; era la 1.2, por lo que os recomiendo que antes de instalarla comprobéis en su página (&lt;a href="https://pkg.cfssl.org/"&gt;https://pkg.cfssl.org/&lt;/a&gt;) que no haya ninguna versión más reciente, y en caso de haberla, cambiad las siguientes URLs según corresponda para poder instalar la aplicación actualizada:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ sudo curl -o /usr/local/bin/cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
$ sudo curl -o /usr/local/bin/cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
$ sudo chmod +x /usr/local/bin/cfssl*
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Creamos un directorio en cualquier parte de nuestro disco duro (y nos situamos en él) para ir guardando los certificados de forma temporal hasta que los hayamos copiado a los nodos de nuestro cluster:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ mkdir &lt;span class="nv"&gt;$HOME&lt;/span&gt;/etcd-certs
$ &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/etcd-certs
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Y ahora vamos creando los certificados necesarios:&lt;/p&gt;
&lt;h3&gt;Certificado de la Autoridad de Certificación (CA)&lt;/h3&gt;
&lt;p&gt;Primero, crearemos un archivo &lt;code&gt;JSON&lt;/code&gt; llamado &lt;code&gt;ca-config.json&lt;/code&gt; con la configuración de la &lt;a href="https://es.wikipedia.org/wiki/Autoridad_de_certificaci%C3%B3n"&gt;&lt;em&gt;Autoridad de Certificación (CA)&lt;/em&gt;&lt;/a&gt; que va a firmar los certificados que vamos a generar.&lt;/p&gt;
&lt;p&gt;En él definiremos la expiración de los certificados, el uso que les vamos a dar (autenticación, firma, ...), etc:&lt;/p&gt;
&lt;figure class='code'&gt;
&lt;figcaption&gt;&lt;span class="liquid-tags-code-title"&gt;ca-config.json&lt;/span&gt;&lt;a href='/files/2018-05-06-alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/ca-config.json'&gt;download&lt;/a&gt;&lt;/figcaption&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;signing&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;default&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;expiry&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;43800h&amp;quot;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;profiles&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;server&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;quot;expiry&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;43800h&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;quot;usages&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="s2"&gt;&amp;quot;signing&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;&amp;quot;key encipherment&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;&amp;quot;server auth&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;&amp;quot;client auth&amp;quot;&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;client&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;quot;expiry&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;43800h&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;quot;usages&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="s2"&gt;&amp;quot;signing&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;&amp;quot;key encipherment&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;&amp;quot;client auth&amp;quot;&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;peer&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;quot;expiry&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;43800h&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;quot;usages&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="s2"&gt;&amp;quot;signing&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;&amp;quot;key encipherment&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;&amp;quot;server auth&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;&amp;quot;client auth&amp;quot;&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/figure&gt;
&lt;p&gt;Después crearemos otro archivo llamado &lt;code&gt;ca-csr.json&lt;/code&gt; donde irá la configuración de la &lt;a href="https://es.wikipedia.org/wiki/Autoridad_de_certificaci%C3%B3n#Solicitud_de_un_certificado"&gt;&lt;em&gt;solicitud de certificación (CSR)&lt;/em&gt;&lt;/a&gt;, donde indicaremos el algoritmo de cifrado que queremos utilizar, la longitud de la clave, los datos del certificado, etc:&lt;/p&gt;
&lt;figure class='code'&gt;
&lt;figcaption&gt;&lt;span class="liquid-tags-code-title"&gt;ca-csr.json&lt;/span&gt;&lt;a href='/files/2018-05-06-alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/ca-csr.json'&gt;download&lt;/a&gt;&lt;/figcaption&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;CN&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;etcd&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;key&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;algo&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;rsa&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;size&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;2048&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;names&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;ES&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;L&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Madrid&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;O&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;PornoHardware S.L.U.&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;OU&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Tech department&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;ST&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Spain&amp;quot;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/figure&gt;
&lt;p&gt;Generamos los certificados de nuestra &lt;em&gt;Autoridad de Certificación&lt;/em&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ cfssl gencert -initca ca-csr.json &lt;span class="p"&gt;|&lt;/span&gt; cfssljson -bare ca -
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Una vez ejecutado el comando habremos obtenido 3 nuevos archivos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ca.csr&lt;/code&gt;: La &lt;em&gt;petición&lt;/em&gt; de generación de certificado.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ca.pem&lt;/code&gt;: El certificado &lt;em&gt;raíz&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ca-key.pem&lt;/code&gt;: La &lt;em&gt;clave&lt;/em&gt; del certificado &lt;em&gt;raíz&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ya tenemos nuestro certificado &lt;em&gt;raíz&lt;/em&gt;, vamos a seguir con los demas...&lt;/p&gt;
&lt;h3&gt;Certificado de cliente&lt;/h3&gt;
&lt;p&gt;Este certificado es el que usaremos nosotros mismos para conectarnos al cluster y lanzar los comandos que queramos ejecutar de forma segura.&lt;/p&gt;
&lt;p&gt;Creamos el archivo &lt;code&gt;client.json&lt;/code&gt;:&lt;/p&gt;
&lt;figure class='code'&gt;
&lt;figcaption&gt;&lt;span class="liquid-tags-code-title"&gt;client.json&lt;/span&gt;&lt;a href='/files/2018-05-06-alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/client.json'&gt;download&lt;/a&gt;&lt;/figcaption&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;CN&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;client&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;key&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;algo&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;ecdsa&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;size&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/figure&gt;
&lt;p&gt;Y utilizando el recién creado certificado &lt;em&gt;raíz&lt;/em&gt; y la configuración que habíamos definido al principio, generamos el certificado de cliente:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ cfssl gencert -ca&lt;span class="o"&gt;=&lt;/span&gt;ca.pem -ca-key&lt;span class="o"&gt;=&lt;/span&gt;ca-key.pem -config&lt;span class="o"&gt;=&lt;/span&gt;ca-config.json -profile&lt;span class="o"&gt;=&lt;/span&gt;client client.json &lt;span class="p"&gt;|&lt;/span&gt; cfssljson -bare client
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Una vez ejecutado el comando habremos obtenido 3 nuevos archivos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;client.csr&lt;/code&gt;: La &lt;em&gt;petición&lt;/em&gt; de generación de certificado.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;client.pem&lt;/code&gt;: El certificado de cliente.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;client-key.pem&lt;/code&gt;: La &lt;em&gt;clave&lt;/em&gt; del certificado de cliente.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Certificados &lt;em&gt;peer&lt;/em&gt; y de servidor&lt;/h3&gt;
&lt;p&gt;Cada uno de los nodos necesita también un certificado para cifrar las conexiones que los demás nodos se hagan entre si (peer). Este certificado necesita generarse para un nombre de host y una IP en concreto (la de cada servidor), por lo tanto necesitamos generar 3 certificados diferentes (uno para cada nodo de nuestro cluster).&lt;/p&gt;
&lt;p&gt;Creamos &lt;strong&gt;un archivo de configuración por cada nodo&lt;/strong&gt;, donde indicaremos el nombre del servidor y su IP, entre otras cosas:&lt;/p&gt;
&lt;p&gt;Para el nodo 1:&lt;/p&gt;
&lt;figure class='code'&gt;
&lt;figcaption&gt;&lt;span class="liquid-tags-code-title"&gt;config-etcd01.json&lt;/span&gt;&lt;a href='/files/2018-05-06-alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/config-etcd01.json'&gt;download&lt;/a&gt;&lt;/figcaption&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;CN&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;etcd01&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;hosts&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;etcd01&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;etcd01.local&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;192.168.1.83&amp;quot;&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;key&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;algo&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;ecdsa&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;size&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;names&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;ES&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;L&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Madrid&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;ST&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Spain&amp;quot;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/figure&gt;
&lt;p&gt;Para el nodo 2:&lt;/p&gt;
&lt;figure class='code'&gt;
&lt;figcaption&gt;&lt;span class="liquid-tags-code-title"&gt;config-etcd02.json&lt;/span&gt;&lt;a href='/files/2018-05-06-alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/config-etcd02.json'&gt;download&lt;/a&gt;&lt;/figcaption&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;CN&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;etcd02&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;hosts&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;etcd02&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;etcd02.local&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;192.168.1.84&amp;quot;&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;key&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;algo&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;ecdsa&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;size&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;names&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;ES&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;L&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Madrid&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;ST&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Spain&amp;quot;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/figure&gt;
&lt;p&gt;Para el nodo 3:&lt;/p&gt;
&lt;figure class='code'&gt;
&lt;figcaption&gt;&lt;span class="liquid-tags-code-title"&gt;config-etcd03.json&lt;/span&gt;&lt;a href='/files/2018-05-06-alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/config-etcd03.json'&gt;download&lt;/a&gt;&lt;/figcaption&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;CN&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;etcd03&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;hosts&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;etcd03&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;etcd03.local&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s2"&gt;&amp;quot;192.168.1.85&amp;quot;&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;key&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;algo&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;ecdsa&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;quot;size&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;256&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;quot;names&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;C&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;ES&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;L&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Madrid&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;quot;ST&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;Spain&amp;quot;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/figure&gt;
&lt;p&gt;Como todos los certificados que vamos a generar tendrán el mismo nombre (&lt;code&gt;server.pem&lt;/code&gt;, &lt;code&gt;server-key.pem&lt;/code&gt;, ...) independientemente del nodo al que correspondan, vamos a crear un subdirectorio por cada nodo y a generar los certificados de cada uno de ellos en su respectivo directorio.&lt;/p&gt;
&lt;p&gt;Creamos el subdirectorio, entramos en él, generamos los certificados (tanto los de servidor como los &lt;em&gt;peer&lt;/em&gt;) y continuamos con el siguiente sucesivamente hasta que hayamos generado los certificados de los 3 servidores:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ mkdir &lt;span class="nv"&gt;$HOME&lt;/span&gt;/etcd-certs/etcd01
$ &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/etcd-certs/etcd01
$ cfssl gencert -ca&lt;span class="o"&gt;=&lt;/span&gt;../ca.pem -ca-key&lt;span class="o"&gt;=&lt;/span&gt;../ca-key.pem -config&lt;span class="o"&gt;=&lt;/span&gt;../ca-config.json -profile&lt;span class="o"&gt;=&lt;/span&gt;server ../config-etcd01.json &lt;span class="p"&gt;|&lt;/span&gt; cfssljson -bare server
$ cfssl gencert -ca&lt;span class="o"&gt;=&lt;/span&gt;../ca.pem -ca-key&lt;span class="o"&gt;=&lt;/span&gt;../ca-key.pem -config&lt;span class="o"&gt;=&lt;/span&gt;../ca-config.json -profile&lt;span class="o"&gt;=&lt;/span&gt;peer ../config-etcd01.json &lt;span class="p"&gt;|&lt;/span&gt; cfssljson -bare peer
$ mkdir &lt;span class="nv"&gt;$HOME&lt;/span&gt;/etcd-certs/etcd02
$ &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/etcd-certs/etcd02
$ cfssl gencert -ca&lt;span class="o"&gt;=&lt;/span&gt;../ca.pem -ca-key&lt;span class="o"&gt;=&lt;/span&gt;../ca-key.pem -config&lt;span class="o"&gt;=&lt;/span&gt;../ca-config.json -profile&lt;span class="o"&gt;=&lt;/span&gt;server ../config-etcd02.json &lt;span class="p"&gt;|&lt;/span&gt; cfssljson -bare server
$ cfssl gencert -ca&lt;span class="o"&gt;=&lt;/span&gt;../ca.pem -ca-key&lt;span class="o"&gt;=&lt;/span&gt;../ca-key.pem -config&lt;span class="o"&gt;=&lt;/span&gt;../ca-config.json -profile&lt;span class="o"&gt;=&lt;/span&gt;peer ../config-etcd02.json &lt;span class="p"&gt;|&lt;/span&gt; cfssljson -bare peer
$ mkdir &lt;span class="nv"&gt;$HOME&lt;/span&gt;/etcd-certs/etcd03
$ &lt;span class="nb"&gt;cd&lt;/span&gt; &lt;span class="nv"&gt;$HOME&lt;/span&gt;/etcd-certs/etcd03
$ cfssl gencert -ca&lt;span class="o"&gt;=&lt;/span&gt;../ca.pem -ca-key&lt;span class="o"&gt;=&lt;/span&gt;../ca-key.pem -config&lt;span class="o"&gt;=&lt;/span&gt;../ca-config.json -profile&lt;span class="o"&gt;=&lt;/span&gt;server ../config-etcd03.json &lt;span class="p"&gt;|&lt;/span&gt; cfssljson -bare server
$ cfssl gencert -ca&lt;span class="o"&gt;=&lt;/span&gt;../ca.pem -ca-key&lt;span class="o"&gt;=&lt;/span&gt;../ca-key.pem -config&lt;span class="o"&gt;=&lt;/span&gt;../ca-config.json -profile&lt;span class="o"&gt;=&lt;/span&gt;peer ../config-etcd03.json &lt;span class="p"&gt;|&lt;/span&gt; cfssljson -bare peer
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Una vez ejecutados todos los comandos habremos obtenido 6 nuevos archivos en cada subdirectorio:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;peer.csr&lt;/code&gt;: La &lt;em&gt;petición&lt;/em&gt; de generación de certificado.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;peer.pem&lt;/code&gt;: El certificado &lt;em&gt;peer&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;peer-key.pem&lt;/code&gt;: La &lt;em&gt;clave&lt;/em&gt; del certificado &lt;em&gt;peer&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;server.csr&lt;/code&gt;: La &lt;em&gt;petición&lt;/em&gt; de generación de certificado.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;server.pem&lt;/code&gt;: El certificado de servidor.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;server-key.pem&lt;/code&gt;: La &lt;em&gt;clave&lt;/em&gt; del certificado de servidor.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si todo ha ido bien, ahora deberíamos tener todos los certificados necesarios para nuestro cluster generados en &lt;code&gt;$HOME/etcd-certs/&lt;/code&gt;, por lo que deberíamos tener algo parecido a ésto:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="err"&gt;├─ $HOME/etcd-certs/&lt;/span&gt;
&lt;span class="err"&gt;│  ├─ ca.csr&lt;/span&gt;
&lt;span class="err"&gt;│  ├─ ca.pem&lt;/span&gt;
&lt;span class="err"&gt;│  ├─ ca-config.json&lt;/span&gt;
&lt;span class="err"&gt;│  ├─ ca-csr.json&lt;/span&gt;
&lt;span class="err"&gt;│  ├─ ca-key.pem&lt;/span&gt;
&lt;span class="err"&gt;│  ├─ client.csr&lt;/span&gt;
&lt;span class="err"&gt;│  ├─ client.json&lt;/span&gt;
&lt;span class="err"&gt;│  ├─ client.pem&lt;/span&gt;
&lt;span class="err"&gt;│  ├─ client-key.pem&lt;/span&gt;
&lt;span class="err"&gt;│  ├─ config-etcd01.json&lt;/span&gt;
&lt;span class="err"&gt;│  ├─ config-etcd02.json&lt;/span&gt;
&lt;span class="err"&gt;│  ├─ config-etcd02.json&lt;/span&gt;
&lt;span class="err"&gt;│  ├─ etcd01/&lt;/span&gt;
&lt;span class="err"&gt;│  │  ├─ peer.csr&lt;/span&gt;
&lt;span class="err"&gt;│  │  ├─ peer.pem&lt;/span&gt;
&lt;span class="err"&gt;│  │  ├─ peer-key.pem&lt;/span&gt;
&lt;span class="err"&gt;│  │  ├─ server.csr&lt;/span&gt;
&lt;span class="err"&gt;│  │  ├─ server.pem&lt;/span&gt;
&lt;span class="err"&gt;│  │  └─ server-key.pem&lt;/span&gt;
&lt;span class="err"&gt;│  ├─ etcd02/&lt;/span&gt;
&lt;span class="err"&gt;│  │  ├─ peer.csr&lt;/span&gt;
&lt;span class="err"&gt;│  │  ├─ peer.pem&lt;/span&gt;
&lt;span class="err"&gt;│  │  ├─ peer-key.pem&lt;/span&gt;
&lt;span class="err"&gt;│  │  ├─ server.csr&lt;/span&gt;
&lt;span class="err"&gt;│  │  ├─ server.pem&lt;/span&gt;
&lt;span class="err"&gt;│  │  └─ server-key.pem&lt;/span&gt;
&lt;span class="err"&gt;│  └─ etcd03/&lt;/span&gt;
&lt;span class="err"&gt;│     ├─ peer.csr&lt;/span&gt;
&lt;span class="err"&gt;│     ├─ peer.pem&lt;/span&gt;
&lt;span class="err"&gt;│     ├─ peer-key.pem&lt;/span&gt;
&lt;span class="err"&gt;│     ├─ server.csr&lt;/span&gt;
&lt;span class="err"&gt;│     ├─ server.pem&lt;/span&gt;
&lt;span class="err"&gt;│     └─ server-key.pem&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ya tenemos todos los archivos que necesitamos para poder configurar nuestro cluster de &lt;em&gt;etcd&lt;/em&gt; utilizando SSL, por lo que ya solo nos queda copiarlos a cada uno de los nodos.&lt;/p&gt;
&lt;p&gt;No hace falta que copiemos todos los archivos a cada nodo, únicamente vamos a necesitar estos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ca.pem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;client.pem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;client-key.pem&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Y para cada uno de los nodos únicamente los de su respectivo subdirectorio:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;etcdXX/server.pem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;etcdXX/server-key.pem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;etcdXX/peer.pem&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;etcdXX/peer-key.pem&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Como ya comenté antes, en mi caso estoy montando este cluster de &lt;em&gt;etcd&lt;/em&gt; para su uso con Kubernetes por lo que voy a copiar los certificados al directorio &lt;code&gt;/etc/kubernetes/pki/etcd&lt;/code&gt; de cada nodo, pero vosotros podéis copiarlos al directorio que queráis (&lt;code&gt;/etc/etcd/certs&lt;/code&gt;, por ejemplo).&lt;/p&gt;
&lt;p&gt;Una vez copiados estos 7 archivos a cada nodo ya podemos empezar con la configuración del cluster.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Importante: Aunque no todos los archivos generados hacen falta os recomiendo que los guardéis igualmente (sobre todo los archivos de configuración) por si en un futuro necesitáis volver a generar los certificados de alguno de los servidores o generar nuevos certificados para un nuevo nodo con el que ampliar el cluster.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Instalación y configuración del cluster&lt;a name="install"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Antes de nada, si los nodos que vas a utilizar para el cluster tienen algún &lt;em&gt;firewall&lt;/em&gt; configurado, debemos abrir los puertos necesarios para poder conectarnos.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Etcd&lt;/em&gt; utiliza estos puertos por defecto:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;2379&lt;/strong&gt;: Para las conexiones de los clientes&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;2380&lt;/strong&gt;: Para las conexiones entre los demás nodos del cluster&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Por lo tanto debemos asegurarnoss de que podemos conectarnos al puerto 2380 de cualquier nodo desde cualquier nodo y al puerto 2379 de cualquier nodo desde donde vayamos a hacer peticiones al cluster.&lt;/p&gt;
&lt;p&gt;Es importante comprobar que no tengamos en nuestros nodos ninguna versión de &lt;em&gt;etcd&lt;/em&gt; ya instalada. Si es así, hay que desinstalarla primero.&lt;/p&gt;
&lt;p&gt;Antes de instalar una nueva versión de &lt;em&gt;etcd&lt;/em&gt; tenemos que saber cuál es esa última versión, por lo que vamos a la zona de &lt;em&gt;releases&lt;/em&gt; de su página de Github (&lt;a href="https://github.com/coreos/etcd/releases"&gt;https://github.com/coreos/etcd/releases&lt;/a&gt;) y lo comprobamos.&lt;/p&gt;
&lt;p&gt;En este momento la última versión es la 3.3.4, por lo que descargamos e instalamos dicha versión &lt;strong&gt;en cada uno de los nodos&lt;/strong&gt; de nuestro cluster:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;v3.3.4
$ curl -sSL https://github.com/coreos/etcd/releases/download/&lt;span class="nv"&gt;$VERSION&lt;/span&gt;/etcd-&lt;span class="nv"&gt;$VERSION&lt;/span&gt;-linux-amd64.tar.gz &lt;span class="p"&gt;|&lt;/span&gt; sudo tar -xzv --strip-components&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt; -C /usr/local/bin/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ahora que ya tenemos &lt;em&gt;etcd&lt;/em&gt; instalado en los 3 nodos, vamos a configurarlo.&lt;/p&gt;
&lt;p&gt;Creamos un archivo &lt;code&gt;/etc/etdc.env&lt;/code&gt; en &lt;strong&gt;cada uno de los nodos&lt;/strong&gt; con el nombre e IP de cada servidor:&lt;/p&gt;
&lt;p&gt;Para el nodo 1:&lt;/p&gt;
&lt;figure class='code'&gt;
&lt;figcaption&gt;&lt;span class="liquid-tags-code-title"&gt;/etc/etcd.env&lt;/span&gt;&lt;a href='/files/2018-05-06-alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/etcd01/etcd.env'&gt;download&lt;/a&gt;&lt;/figcaption&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="na"&gt;PEER_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;etcd01&lt;/span&gt;
&lt;span class="na"&gt;PRIVATE_IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;192.168.1.83&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/figure&gt;
&lt;p&gt;Para el nodo 2:&lt;/p&gt;
&lt;figure class='code'&gt;
&lt;figcaption&gt;&lt;span class="liquid-tags-code-title"&gt;/etc/etcd.env&lt;/span&gt;&lt;a href='/files/2018-05-06-alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/etcd02/etcd.env'&gt;download&lt;/a&gt;&lt;/figcaption&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="na"&gt;PEER_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;etcd02&lt;/span&gt;
&lt;span class="na"&gt;PRIVATE_IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;192.168.1.84&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/figure&gt;
&lt;p&gt;Para el nodo 3:&lt;/p&gt;
&lt;figure class='code'&gt;
&lt;figcaption&gt;&lt;span class="liquid-tags-code-title"&gt;/etc/etcd.env&lt;/span&gt;&lt;a href='/files/2018-05-06-alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/etcd03/etcd.env'&gt;download&lt;/a&gt;&lt;/figcaption&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="na"&gt;PEER_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;etcd03&lt;/span&gt;
&lt;span class="na"&gt;PRIVATE_IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;192.168.1.85&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/figure&gt;
&lt;p&gt;Ahora vamos a crear los archivos de configuración de &lt;a href="https://freedesktop.org/wiki/Software/systemd/"&gt;systemd&lt;/a&gt; para que podamos arrancar, reiniciar y parar el servicio de &lt;em&gt;etcd&lt;/em&gt; como haríamos con cualquier otro servicio.&lt;/p&gt;
&lt;p&gt;Para eso, creamos un archivo &lt;code&gt;/etc/systemd/system/etcd.service&lt;/code&gt; en &lt;strong&gt;cada uno de los nodos&lt;/strong&gt;, indicando los argumentos que se le pasarán al programa &lt;em&gt;etcd&lt;/em&gt; cuando arranque, y que son básicamente el nombre e IP del servidor, el nombre e IP de los demás nodos del cluster, la ruta a los certificados que generamos en el paso anterior, etc.&lt;/p&gt;
&lt;p&gt;El archivo quedaría más o menos así para el nodo 1:&lt;/p&gt;
&lt;figure class='code'&gt;
&lt;figcaption&gt;&lt;span class="liquid-tags-code-title"&gt;/etc/systemd/system/etcd.service&lt;/span&gt;&lt;a href='/files/2018-05-06-alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/etcd01/etcd.service'&gt;download&lt;/a&gt;&lt;/figcaption&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;etcd&lt;/span&gt;
&lt;span class="na"&gt;Documentation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;https://github.com/coreos/etcd&lt;/span&gt;
&lt;span class="na"&gt;Conflicts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;etcd.service&lt;/span&gt;
&lt;span class="na"&gt;Conflicts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;etcd2.service&lt;/span&gt;

&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;span class="na"&gt;EnvironmentFile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/etc/etcd.env&lt;/span&gt;
&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;notify&lt;/span&gt;
&lt;span class="na"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;
&lt;span class="na"&gt;RestartSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5s&lt;/span&gt;
&lt;span class="na"&gt;LimitNOFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;40000&lt;/span&gt;
&lt;span class="na"&gt;TimeoutStartSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;

&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/local/bin/etcd \&lt;/span&gt;
&lt;span class="s"&gt;  --name etcd01 \&lt;/span&gt;
&lt;span class="s"&gt;  --data-dir /var/lib/etcd \&lt;/span&gt;
&lt;span class="s"&gt;  --initial-advertise-peer-urls https://192.168.1.83:2380 \&lt;/span&gt;
&lt;span class="s"&gt;  --listen-peer-urls https://192.168.1.83:2380 \&lt;/span&gt;
&lt;span class="s"&gt;  --listen-client-urls https://192.168.1.83:2379,https://127.0.0.1:2379 \&lt;/span&gt;
&lt;span class="s"&gt;  --advertise-client-urls https://192.168.1.83:2379 \&lt;/span&gt;
&lt;span class="s"&gt;  --initial-cluster-token etcd-cluster-1 \&lt;/span&gt;
&lt;span class="s"&gt;  --initial-cluster etcd01=https://192.168.1.83:2380,etcd02=https://192.168.1.84:2380,etcd03=https://192.168.1.85:2380 \&lt;/span&gt;
&lt;span class="s"&gt;  --initial-cluster-state new \&lt;/span&gt;
&lt;span class="s"&gt;  --cert-file=/etc/kubernetes/pki/etcd/server.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --key-file=/etc/kubernetes/pki/etcd/server-key.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --client-cert-auth \&lt;/span&gt;
&lt;span class="s"&gt;  --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --peer-cert-file=/etc/kubernetes/pki/etcd/peer.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --peer-key-file=/etc/kubernetes/pki/etcd/peer-key.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --peer-client-cert-auth \&lt;/span&gt;
&lt;span class="s"&gt;  --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem&lt;/span&gt;

&lt;span class="k"&gt;[Install]&lt;/span&gt;
&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/figure&gt;
&lt;p&gt;Para el nodo 2:&lt;/p&gt;
&lt;figure class='code'&gt;
&lt;figcaption&gt;&lt;span class="liquid-tags-code-title"&gt;/etc/systemd/system/etcd.service&lt;/span&gt;&lt;a href='/files/2018-05-06-alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/etcd02/etcd.service'&gt;download&lt;/a&gt;&lt;/figcaption&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;etcd&lt;/span&gt;
&lt;span class="na"&gt;Documentation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;https://github.com/coreos/etcd&lt;/span&gt;
&lt;span class="na"&gt;Conflicts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;etcd.service&lt;/span&gt;
&lt;span class="na"&gt;Conflicts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;etcd2.service&lt;/span&gt;

&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;span class="na"&gt;EnvironmentFile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/etc/etcd.env&lt;/span&gt;
&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;notify&lt;/span&gt;
&lt;span class="na"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;
&lt;span class="na"&gt;RestartSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5s&lt;/span&gt;
&lt;span class="na"&gt;LimitNOFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;40000&lt;/span&gt;
&lt;span class="na"&gt;TimeoutStartSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;

&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/local/bin/etcd \&lt;/span&gt;
&lt;span class="s"&gt;  --name etcd02 \&lt;/span&gt;
&lt;span class="s"&gt;  --data-dir /var/lib/etcd \&lt;/span&gt;
&lt;span class="s"&gt;  --initial-advertise-peer-urls https://192.168.1.84:2380 \&lt;/span&gt;
&lt;span class="s"&gt;  --listen-peer-urls https://192.168.1.84:2380 \&lt;/span&gt;
&lt;span class="s"&gt;  --listen-client-urls https://192.168.1.84:2379,https://127.0.0.1:2379 \&lt;/span&gt;
&lt;span class="s"&gt;  --advertise-client-urls https://192.168.1.84:2379 \&lt;/span&gt;
&lt;span class="s"&gt;  --initial-cluster-token etcd-cluster-1 \&lt;/span&gt;
&lt;span class="s"&gt;  --initial-cluster etcd01=https://192.168.1.83:2380,etcd02=https://192.168.1.84:2380,etcd03=https://192.168.1.85:2380 \&lt;/span&gt;
&lt;span class="s"&gt;  --initial-cluster-state new \&lt;/span&gt;
&lt;span class="s"&gt;  --cert-file=/etc/kubernetes/pki/etcd/server.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --key-file=/etc/kubernetes/pki/etcd/server-key.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --client-cert-auth \&lt;/span&gt;
&lt;span class="s"&gt;  --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --peer-cert-file=/etc/kubernetes/pki/etcd/peer.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --peer-key-file=/etc/kubernetes/pki/etcd/peer-key.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --peer-client-cert-auth \&lt;/span&gt;
&lt;span class="s"&gt;  --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem&lt;/span&gt;

&lt;span class="k"&gt;[Install]&lt;/span&gt;
&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/figure&gt;
&lt;p&gt;Para el nodo 3:&lt;/p&gt;
&lt;figure class='code'&gt;
&lt;figcaption&gt;&lt;span class="liquid-tags-code-title"&gt;/etc/systemd/system/etcd.service&lt;/span&gt;&lt;a href='/files/2018-05-06-alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/etcd03/etcd.service'&gt;download&lt;/a&gt;&lt;/figcaption&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;etcd&lt;/span&gt;
&lt;span class="na"&gt;Documentation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;https://github.com/coreos/etcd&lt;/span&gt;
&lt;span class="na"&gt;Conflicts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;etcd.service&lt;/span&gt;
&lt;span class="na"&gt;Conflicts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;etcd2.service&lt;/span&gt;

&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;span class="na"&gt;EnvironmentFile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/etc/etcd.env&lt;/span&gt;
&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;notify&lt;/span&gt;
&lt;span class="na"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;
&lt;span class="na"&gt;RestartSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5s&lt;/span&gt;
&lt;span class="na"&gt;LimitNOFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;40000&lt;/span&gt;
&lt;span class="na"&gt;TimeoutStartSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;

&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/local/bin/etcd \&lt;/span&gt;
&lt;span class="s"&gt;  --name etcd03 \&lt;/span&gt;
&lt;span class="s"&gt;  --data-dir /var/lib/etcd \&lt;/span&gt;
&lt;span class="s"&gt;  --initial-advertise-peer-urls https://192.168.1.85:2380 \&lt;/span&gt;
&lt;span class="s"&gt;  --listen-peer-urls https://192.168.1.85:2380 \&lt;/span&gt;
&lt;span class="s"&gt;  --listen-client-urls https://192.168.1.85:2379,https://127.0.0.1:2379 \&lt;/span&gt;
&lt;span class="s"&gt;  --advertise-client-urls https://192.168.1.85:2379 \&lt;/span&gt;
&lt;span class="s"&gt;  --initial-cluster-token etcd-cluster-1 \&lt;/span&gt;
&lt;span class="s"&gt;  --initial-cluster etcd01=https://192.168.1.83:2380,etcd02=https://192.168.1.84:2380,etcd03=https://192.168.1.85:2380 \&lt;/span&gt;
&lt;span class="s"&gt;  --initial-cluster-state new \&lt;/span&gt;
&lt;span class="s"&gt;  --cert-file=/etc/kubernetes/pki/etcd/server.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --key-file=/etc/kubernetes/pki/etcd/server-key.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --client-cert-auth \&lt;/span&gt;
&lt;span class="s"&gt;  --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --peer-cert-file=/etc/kubernetes/pki/etcd/peer.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --peer-key-file=/etc/kubernetes/pki/etcd/peer-key.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --peer-client-cert-auth \&lt;/span&gt;
&lt;span class="s"&gt;  --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem&lt;/span&gt;

&lt;span class="k"&gt;[Install]&lt;/span&gt;
&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/figure&gt;
&lt;p&gt;Ya solo nos queda reiniciar el demonio de &lt;em&gt;systemd&lt;/em&gt; de cada nodo para que lea el archivo que acabamos de crear:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ sudo systemctl daemon-reload
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Y ahora ya podemos gestionar el demonio de &lt;em&gt;etcd&lt;/em&gt; con el comando &lt;em&gt;systemctl&lt;/em&gt; o con &lt;em&gt;service&lt;/em&gt;, por lo que vamos a levantar el proceso y a configurarlo para que se inicie automáticamente al arrancar el servidor:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ sudo systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; etcd
$ sudo systemctl start etcd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Si todo ha ido bien, ahora mismo ya tendremos el servicio de &lt;em&gt;etcd&lt;/em&gt; levantado, por lo que hacemos lo mismo en los otros 2 nodos.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Si es la primera vez que estas levantando el servicio, hay veces en las que al invocar a &lt;em&gt;systemctl&lt;/em&gt; se queda el proceso &lt;em&gt;esperando eternamente&lt;/em&gt; (hasta que salta el &lt;em&gt;más-que-generoso-timeout(TM)&lt;/em&gt;, me refiero). La mayoría de las veces se debe a que el proceso se demonio de &lt;em&gt;etcd&lt;/em&gt; se inicia correctamente, pero se queda intentando conectarse con los otros 2 nodos del cluster, por lo que si aún no los hemos levantado, el proceso lo reintenta indefinidamente y parece que se queda &lt;em&gt;congelado&lt;/em&gt;...
&lt;br /&gt;&lt;br /&gt;
En estos casos, puesto que el proceso se levanta correctamente, o bien sales con &lt;code&gt;CTRL&lt;/code&gt; + &lt;code&gt;C&lt;/code&gt;, o bien levantas los demonios en los otros 2 nodos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Puedes comprobar si el servicio se ha levantado correctamente con:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt; sudo systemctl status etcd
&lt;span class="go"&gt;- etcd.service - etcd&lt;/span&gt;
&lt;span class="go"&gt;   Loaded: loaded (/etc/systemd/system/etcd.service; enabled; vendor preset: enabled)&lt;/span&gt;
&lt;span class="go"&gt;   Active: active (running) since Tue 2018-05-06 00:21:53 CEST; 11s ago&lt;/span&gt;
&lt;span class="go"&gt;     Docs: https://github.com/coreos/etcd&lt;/span&gt;
&lt;span class="go"&gt; Main PID: 9426 (etcd)&lt;/span&gt;
&lt;span class="go"&gt;    Tasks: 18 (limit: 4915)&lt;/span&gt;
&lt;span class="go"&gt;   Memory: 10.1M&lt;/span&gt;
&lt;span class="go"&gt;      CPU: 145ms&lt;/span&gt;
&lt;span class="go"&gt;   CGroup: /system.slice/etcd.service&lt;/span&gt;
&lt;span class="go"&gt;           └─9426 /usr/local/bin/etcd --name etcd01 --data-dir /var/lib/etcd --initial-advertise-peer-urls https://192.168.1.83:2380 --listen-peer-urls https://192.168.1.83:2380 --listen-client-urls https://192.168.1.83:2379,https://127.0.0.1:2379 --advertise-client-urls&lt;/span&gt;

&lt;span class="go"&gt;May 06 00:21:53 etcd01 etcd[20483]: established a TCP streaming connection with peer c37956d0928a73d9 (stream Message reader)&lt;/span&gt;
&lt;span class="go"&gt;May 06 00:21:53 etcd01 etcd[20483]: established a TCP streaming connection with peer c37956d0928a73d9 (stream MsgApp v2 reader)&lt;/span&gt;
&lt;span class="go"&gt;May 06 00:21:53 etcd01 etcd[20483]: raft.node: 1e9f81657a2688f9 elected leader b5a3b7906f500074 at term 1291&lt;/span&gt;
&lt;span class="go"&gt;May 06 00:21:53 etcd01 etcd[20483]: 1e9f81657a2688f9 initialzed peer connection; fast-forwarding 8 ticks (election ticks 10) with 2 active peer(s)&lt;/span&gt;
&lt;span class="go"&gt;May 06 00:21:53 etcd01 etcd[20483]: published {Name:etcd01 ClientURLs:[&amp;quot;https://192.168.1.83:2379&amp;quot;]} to cluster e47a206dc7abb150&lt;/span&gt;
&lt;span class="go"&gt;May 06 00:21:53 etcd01 etcd[20483]: ready to serve client requests&lt;/span&gt;
&lt;span class="go"&gt;May 06 00:21:53 etcd01 etcd[20483]: ready to serve client requests&lt;/span&gt;
&lt;span class="go"&gt;May 06 00:21:53 etcd01 systemd[1]: Started etcd.&lt;/span&gt;
&lt;span class="go"&gt;May 06 00:21:53 etcd01 etcd[20483]: serving client requests on 127.0.0.1:2379&lt;/span&gt;
&lt;span class="go"&gt;May 06 00:21:53 etcd01 etcd[20483]: serving client requests on 192.168.1.83:2379&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Esto significa que ya tenemos nuestro cluster funcionando y aceptando conexiones por el puerto 2379!&lt;/p&gt;
&lt;h2&gt;Administración básica&lt;a name="admin"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Ahora que ya tenemos el cluster funcionando, vamos a ver algunos comandos que nos serán de utilidad a la hora de administrar el cluster, comprobar su estado, añadir un nuevo nodo, etc.&lt;/p&gt;
&lt;p&gt;Recuerda que hemos configurado nuestro cluster para usar SSL en cualquier conexión, por lo que necesitaremos el certificado de cliente en cualquier sitio desde el que nos queramos conectar al cluster.&lt;/p&gt;
&lt;p&gt;Al servidor &lt;em&gt;etcd&lt;/em&gt; se accede utilizando la API, como ya expliqué al principio del artículo, pero existe una utilidad llamada &lt;code&gt;etcdctl&lt;/code&gt; que nos permite acceder a dicha API desde la linea de comandos. Vamos a ver sus opciones, pero antes tenemos que establecer la variable de sesión &lt;code&gt;ETCDCTL_API=3&lt;/code&gt; ya que de lo contrario la utilidad nos mostrará opciones &lt;em&gt;obsoletas&lt;/em&gt; (luego explicaré el tema de las variables de sesión):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt; &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;ETCDCTL_API&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;
&lt;span class="gp"&gt;$&lt;/span&gt; etcdctl --help
&lt;span class="go"&gt;NAME:&lt;/span&gt;
&lt;span class="go"&gt;    etcdctl - A simple command line client for etcd3.&lt;/span&gt;

&lt;span class="go"&gt;USAGE:&lt;/span&gt;
&lt;span class="go"&gt;    etcdctl&lt;/span&gt;

&lt;span class="go"&gt;VERSION:&lt;/span&gt;
&lt;span class="go"&gt;    3.3.4&lt;/span&gt;

&lt;span class="go"&gt;API VERSION:&lt;/span&gt;
&lt;span class="go"&gt;    3.3&lt;/span&gt;


&lt;span class="go"&gt;COMMANDS:&lt;/span&gt;
&lt;span class="go"&gt;    get         Gets the key or a range of keys&lt;/span&gt;
&lt;span class="go"&gt;    put         Puts the given key into the store&lt;/span&gt;
&lt;span class="go"&gt;    del         Removes the specified key or range of keys [key, range_end)&lt;/span&gt;
&lt;span class="go"&gt;    txn         Txn processes all the requests in one transaction&lt;/span&gt;
&lt;span class="go"&gt;    compaction      Compacts the event history in etcd&lt;/span&gt;
&lt;span class="go"&gt;    alarm disarm        Disarms all alarms&lt;/span&gt;
&lt;span class="go"&gt;    alarm list      Lists all alarms&lt;/span&gt;
&lt;span class="go"&gt;    defrag          Defragments the storage of the etcd members with given endpoints&lt;/span&gt;
&lt;span class="go"&gt;    endpoint health     Checks the healthiness of endpoints specified in `--endpoints` flag&lt;/span&gt;
&lt;span class="go"&gt;    endpoint status     Prints out the status of endpoints specified in `--endpoints` flag&lt;/span&gt;
&lt;span class="go"&gt;    endpoint hashkv     Prints the KV history hash for each endpoint in --endpoints&lt;/span&gt;
&lt;span class="go"&gt;    move-leader     Transfers leadership to another etcd cluster member.&lt;/span&gt;
&lt;span class="go"&gt;    watch           Watches events stream on keys or prefixes&lt;/span&gt;
&lt;span class="go"&gt;    version         Prints the version of etcdctl&lt;/span&gt;
&lt;span class="go"&gt;    lease grant     Creates leases&lt;/span&gt;
&lt;span class="go"&gt;    lease revoke        Revokes leases&lt;/span&gt;
&lt;span class="go"&gt;    lease timetolive    Get lease information&lt;/span&gt;
&lt;span class="go"&gt;    lease list      List all active leases&lt;/span&gt;
&lt;span class="go"&gt;    lease keep-alive    Keeps leases alive (renew)&lt;/span&gt;
&lt;span class="go"&gt;    member add      Adds a member into the cluster&lt;/span&gt;
&lt;span class="go"&gt;    member remove       Removes a member from the cluster&lt;/span&gt;
&lt;span class="go"&gt;    member update       Updates a member in the cluster&lt;/span&gt;
&lt;span class="go"&gt;    member list     Lists all members in the cluster&lt;/span&gt;
&lt;span class="go"&gt;    snapshot save       Stores an etcd node backend snapshot to a given file&lt;/span&gt;
&lt;span class="go"&gt;    snapshot restore    Restores an etcd member snapshot to an etcd directory&lt;/span&gt;
&lt;span class="go"&gt;    snapshot status     Gets backend snapshot status of a given file&lt;/span&gt;
&lt;span class="go"&gt;    make-mirror     Makes a mirror at the destination etcd cluster&lt;/span&gt;
&lt;span class="go"&gt;    migrate         Migrates keys in a v2 store to a mvcc store&lt;/span&gt;
&lt;span class="go"&gt;    lock            Acquires a named lock&lt;/span&gt;
&lt;span class="go"&gt;    elect           Observes and participates in leader election&lt;/span&gt;
&lt;span class="go"&gt;    auth enable     Enables authentication&lt;/span&gt;
&lt;span class="go"&gt;    auth disable        Disables authentication&lt;/span&gt;
&lt;span class="go"&gt;    user add        Adds a new user&lt;/span&gt;
&lt;span class="go"&gt;    user delete     Deletes a user&lt;/span&gt;
&lt;span class="go"&gt;    user get        Gets detailed information of a user&lt;/span&gt;
&lt;span class="go"&gt;    user list       Lists all users&lt;/span&gt;
&lt;span class="go"&gt;    user passwd     Changes password of user&lt;/span&gt;
&lt;span class="go"&gt;    user grant-role     Grants a role to a user&lt;/span&gt;
&lt;span class="go"&gt;    user revoke-role    Revokes a role from a user&lt;/span&gt;
&lt;span class="go"&gt;    role add        Adds a new role&lt;/span&gt;
&lt;span class="go"&gt;    role delete     Deletes a role&lt;/span&gt;
&lt;span class="go"&gt;    role get        Gets detailed information of a role&lt;/span&gt;
&lt;span class="go"&gt;    role list       Lists all roles&lt;/span&gt;
&lt;span class="go"&gt;    role grant-permission   Grants a key to a role&lt;/span&gt;
&lt;span class="go"&gt;    role revoke-permission  Revokes a key from a role&lt;/span&gt;
&lt;span class="go"&gt;    check perf      Check the performance of the etcd cluster&lt;/span&gt;
&lt;span class="go"&gt;    help            Help about any command&lt;/span&gt;

&lt;span class="go"&gt;OPTIONS:&lt;/span&gt;
&lt;span class="go"&gt;      --cacert=&amp;quot;&amp;quot;               verify certificates of TLS-enabled secure servers using this CA bundle&lt;/span&gt;
&lt;span class="go"&gt;      --cert=&amp;quot;&amp;quot;                 identify secure client using this TLS certificate file&lt;/span&gt;
&lt;span class="go"&gt;      --command-timeout=5s          timeout for short running command (excluding dial timeout)&lt;/span&gt;
&lt;span class="go"&gt;      --debug[=false]               enable client-side debug logging&lt;/span&gt;
&lt;span class="go"&gt;      --dial-timeout=2s             dial timeout for client connections&lt;/span&gt;
&lt;span class="go"&gt;  -d, --discovery-srv=&amp;quot;&amp;quot;            domain name to query for SRV records describing cluster endpoints&lt;/span&gt;
&lt;span class="go"&gt;      --endpoints=[127.0.0.1:2379]      gRPC endpoints&lt;/span&gt;
&lt;span class="go"&gt;      --hex[=false]             print byte strings as hex encoded strings&lt;/span&gt;
&lt;span class="go"&gt;      --insecure-discovery[=true]       accept insecure SRV records describing cluster endpoints&lt;/span&gt;
&lt;span class="go"&gt;      --insecure-skip-tls-verify[=false]    skip server certificate verification&lt;/span&gt;
&lt;span class="go"&gt;      --insecure-transport[=true]       disable transport security for client connections&lt;/span&gt;
&lt;span class="go"&gt;      --keepalive-time=2s           keepalive time for client connections&lt;/span&gt;
&lt;span class="go"&gt;      --keepalive-timeout=6s            keepalive timeout for client connections&lt;/span&gt;
&lt;span class="go"&gt;      --key=&amp;quot;&amp;quot;                  identify secure client using this TLS key file&lt;/span&gt;
&lt;span class="go"&gt;      --user=&amp;quot;&amp;quot;                 username[:password] for authentication (prompt if password is not supplied)&lt;/span&gt;
&lt;span class="go"&gt;  -w, --write-out=&amp;quot;simple&amp;quot;          set the output format (fields, json, protobuf, simple, table)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Como puedes ver este comando tiene bastantes parámetros, por lo que vamos a echar un ojo a los más importantes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--endpoints&lt;/code&gt;: Aqui debemos especificar todos los nodos de nuestro cluster (host y puerto) separados por comas, de forma que si uno de ellos estuviera caído nuestra consulta sería enviada de forma automática a otro de los nodos. Por ejemplo, en nuestro caso sería: &lt;code&gt;https://etcd01:2379,https://etcd02:2379,https://etcd03:2379&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--cert&lt;/code&gt;: La ruta del certificado de cliente que vamos a utilizar para conectarnos. En nuestro caso sería: &lt;code&gt;/etc/kubernetes/pki/etcd/client.pem&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--key&lt;/code&gt;: La ruta de la clave del certificado de cliente. En nuestro caso sería: &lt;code&gt;/etc/kubernetes/pki/etcd/client-key.pem&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--cacert&lt;/code&gt;: La ruta hacia la &lt;em&gt;entidad certificadora&lt;/em&gt; con la que hemos generado los certificados. En nuestro caso sería: &lt;code&gt;/etc/kubernetes/pki/etcd/ca.pem&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--write-out&lt;/code&gt;: Aqui indicamos cómo queremos que nos devuelva al respuesta del comando que vamos a lanzar al cluster. Puede ser &lt;code&gt;simple&lt;/code&gt;, &lt;code&gt;json&lt;/code&gt;, &lt;code&gt;table&lt;/code&gt;, etc.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--debug&lt;/code&gt;: Con esta opción podemos ver las llamadas HTTP/HTTPS que se estan lanzando a la API del cluster para ejecutar el comando que vayamos a ejecutar. Muy util para depurar el proceso si tenemos algún problema con los datos que estamos obteniendo.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Por comodidad, tener que estar introduciendo las rutas de todos los certificados y la lista de &lt;em&gt;endpoints&lt;/em&gt; cada vez que lancemos un comando puede resultar una auténtica tortura. Por suerte, podemos definir una serie de variables de entorno que una vez definidas permitirán a &lt;code&gt;etcdctl&lt;/code&gt; conocer el valor de todos estos parámetros sin que tengamos que estar tecleándolos constantemente. Estas variables son:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ETCDCTL_CERT&lt;/code&gt;: La ruta que pondríamos en el parámetro &lt;code&gt;--cert-file&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ETCDCTL_KEY&lt;/code&gt;: La ruta que pondríamos en el parámetro &lt;code&gt;--key-file&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ETCDCTL_CACERT&lt;/code&gt;: La ruta que pondríamos en el parámetro &lt;code&gt;--ca-file&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ETCDCTL_ENDPOINTS&lt;/code&gt;: La lista (separada por comas) de endpoints (host y puerto) de nuestro cluster.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ETCDCTL_API&lt;/code&gt;: Versión de la API que queramos utilizar. Puede ser &lt;code&gt;2&lt;/code&gt; o &lt;code&gt;3&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Una vez que hemos visto los parámetros, vamos con algunos de los comandos disponibles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;get&lt;/code&gt;: Devuelve el valor de una clave.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;put&lt;/code&gt;: Establece el valor de una clave.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;endpoint health&lt;/code&gt;: Muestra el estado de los nodos del cluster.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;check perf&lt;/code&gt;: Realiza un informe de rendimiento del cluster.&lt;/li&gt;
&lt;li&gt;Etc... (esta vez me refiero a &lt;em&gt;etcétera&lt;/em&gt;, no al nombre del programa del que estamos hablando xDDD)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Vamos a probar alguno de ellos...&lt;/p&gt;
&lt;p&gt;Nos conectamos a cualquiera de los nodos (por ejemplo al primero: &lt;code&gt;etcd01&lt;/code&gt;) y definimos las variables de sesión con los valores necesarios para no tener que preocuparnos de ellos en cada ejecución del comando &lt;code&gt;etcdctl&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;ETCDCTL_CERT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/etc/kubernetes/pki/etcd/client.pem
$ &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;ETCDCTL_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/etc/kubernetes/pki/etcd/client-key.pem
$ &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;ETCDCTL_CACERT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/etc/kubernetes/pki/etcd/ca.pem
$ &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;ETCDCTL_ENDPOINTS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;https://etcd01:2379,https://etcd02:2379,https://etcd03:2379
$ &lt;span class="nb"&gt;export&lt;/span&gt; &lt;span class="nv"&gt;ETCDCTL_API&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="m"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Ahora vamos a lanzar el comando &lt;code&gt;endpoint health&lt;/code&gt; para ver &lt;em&gt;la salud&lt;/em&gt; de nuestro recién creado cluster:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt; etcdctl endpoint health
&lt;span class="go"&gt;https://etcd02:2379 is healthy: successfully committed proposal: took = 2.397419ms&lt;/span&gt;
&lt;span class="go"&gt;https://etcd01:2379 is healthy: successfully committed proposal: took = 1.535434ms&lt;/span&gt;
&lt;span class="go"&gt;https://etcd03:2379 is healthy: successfully committed proposal: took = 2.331939ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Que indica que los 3 nodos estan funcionando correctamente (&lt;em&gt;...is healthy&lt;/em&gt;).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Si en lugar del resultado os muestra algún error relacionado con los certificados significa que no habeis puesto bien las rutas de las variables de sesión, o que vuestro usuario no tiene permiso para leer dichos archivos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Ahora vamos a introducir una clave de prueba y su valor. Por ejemplo:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ etcdctl put clavePrueba &lt;span class="s2"&gt;&amp;quot;Esto es una prueba&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Leemos el valor de la clave &lt;code&gt;clavePrueba&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt; etcdctl get clavePrueba
&lt;span class="go"&gt;Esto es una prueba&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Vamos ahora con algo más &lt;em&gt;delicado&lt;/em&gt;: gestionar nuevos nodos.
Supongamos que queremos añadir un nuevo nodo a nuestro cluster. Por comodidad y para &lt;em&gt;matar dos pájaros de un tiro&lt;/em&gt; vamos primero a quitar uno de los nodos del cluster y luego lo volveremos a meter.&lt;/p&gt;
&lt;p&gt;Con el comando &lt;code&gt;member list&lt;/code&gt; vemos la lista de nodos que componen nuestro cluster, y el &lt;a href="https://es.wikipedia.org/wiki/Identificador"&gt;ID&lt;/a&gt; de cada uno de ellos:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt; etcdctl member list
&lt;span class="go"&gt;b5a3b7906f500074, started, etcd01, https://192.168.1.83:2380, https://192.168.1.83:2379&lt;/span&gt;
&lt;span class="go"&gt;c37956d0928a73d9, started, etcd02, https://192.168.1.84:2380, https://192.168.1.84:2379&lt;/span&gt;
&lt;span class="go"&gt;1e9f81657a2688f9, started, etcd03, https://192.168.1.85:2380, https://192.168.1.85:2379&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Para eliminar uno de ellos, por ejemplo el nodo 3 (&lt;code&gt;etcd03&lt;/code&gt;), ejecutamos el comando &lt;code&gt;member remove&lt;/code&gt; indicando el ID del nodo que queremos eliminar de nuestro cluster:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt; etcdctl member remove 1e9f81657a2688f9
&lt;span class="go"&gt;Member 1e9f81657a2688f9 removed from cluster e47a206dc7abb150&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Si volvemos a obtener la lista de nodos del cluster veremos que ya solo tenemos 2:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt; etcdctl member list
&lt;span class="go"&gt;b5a3b7906f500074, started, etcd01, https://192.168.1.83:2380, https://192.168.1.83:2379&lt;/span&gt;
&lt;span class="go"&gt;c37956d0928a73d9, started, etcd02, https://192.168.1.84:2380, https://192.168.1.84:2379&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;El procedimiento para añadir un nodo es tambien muy sencillo, pero si el nodo que queremos añadir ya ha formado parte de un cluster &lt;em&gt;etcd&lt;/em&gt; anteriormente (como es nuestro caso ya que lo acabamos de eliminar ahora mismo) hay que hacer un par de cosas antes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Detener el servicio de &lt;em&gt;etcd&lt;/em&gt; en el nuevo nodo que queremos añadir: &lt;code&gt;$ sudo systemctl stop etcd&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Eliminar el directorio donde se guardan los datos de &lt;em&gt;etcd&lt;/em&gt; para que al añadirlo al cluster se sincronice de nuevo con el resto de nodos: &lt;code&gt;$ sudo rm -rf /var/lib/etcd/member&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Una vez hecho esto, ya podemos continuar con el proceso para añadirlo a nuestro cluster.&lt;/p&gt;
&lt;p&gt;Ejecutamos el comando &lt;code&gt;member add&lt;/code&gt; junto con el nombre y el endpoint de &lt;em&gt;peer&lt;/em&gt; del nuevo nodo que queremos añadir:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt; etcdctl member add etcd03 --peer-urls&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;https://192.168.1.85:2380&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;Member c398e05912695024 added to cluster e47a206dc7abb150&lt;/span&gt;
&lt;span class="go"&gt;ETCD_NAME=&amp;quot;etcd03&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;ETCD_INITIAL_CLUSTER=&amp;quot;etcd01=https://192.168.1.83:2380,etcd02=https://192.168.1.84:2380,etcd03=https://192.168.1.85:2380&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;ETCD_INITIAL_ADVERTISE_PEER_URLS=&amp;quot;https://192.168.1.85:2380&amp;quot;&lt;/span&gt;
&lt;span class="go"&gt;ETCD_INITIAL_CLUSTER_STATE=&amp;quot;existing&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;El comando muestra los datos del nuevo nodo que hemos añadido (nombre, endpoints, etc) así como su estado actual, que es &lt;code&gt;existing&lt;/code&gt;. Esto significa que aunque el nodo se ha añadido al cluster, aún no está &lt;em&gt;operativo&lt;/em&gt;. Podemos verlo si de nuevo volvemos a pedir el listado de nodos:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt; etcdctl member list
&lt;span class="go"&gt;b5a3b7906f500074, started, etcd01, https://192.168.1.83:2380, https://192.168.1.83:2379&lt;/span&gt;
&lt;span class="go"&gt;c37956d0928a73d9, started, etcd02, https://192.168.1.84:2380, https://192.168.1.84:2379&lt;/span&gt;
&lt;span class="go"&gt;c398e05912695024, unstarted, , https://192.168.1.85:2380,&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Como ves, el nuevo nodo está &lt;code&gt;unstarted&lt;/code&gt;, por lo que aún no está funcionando (como es lógico).&lt;/p&gt;
&lt;p&gt;Para &lt;em&gt;iniciarlo&lt;/em&gt;, nos conectamos a dicho nodo y editamos el archivo de configuración de &lt;code&gt;systemctl&lt;/code&gt; del &lt;em&gt;etcd&lt;/em&gt; (el archivo &lt;code&gt;/etc/systemd/system/etcd.service&lt;/code&gt; que creamos cuando estábamos configurando el cluster). Tenemos que sustituir la linea &lt;code&gt;--initial-cluster-state new&lt;/code&gt; por &lt;code&gt;--initial-cluster-state existing&lt;/code&gt;, por lo que el archivo quedaría así:&lt;/p&gt;
&lt;figure class='code'&gt;
&lt;figcaption&gt;&lt;span class="liquid-tags-code-title"&gt;/etc/systemd/system/etcd.service&lt;/span&gt;&lt;a href='/files/2018-05-06-alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/etcd03-new/etcd.service'&gt;download&lt;/a&gt;&lt;/figcaption&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;etcd&lt;/span&gt;
&lt;span class="na"&gt;Documentation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;https://github.com/coreos/etcd&lt;/span&gt;
&lt;span class="na"&gt;Conflicts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;etcd.service&lt;/span&gt;
&lt;span class="na"&gt;Conflicts&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;etcd2.service&lt;/span&gt;

&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;span class="na"&gt;EnvironmentFile&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/etc/etcd.env&lt;/span&gt;
&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;notify&lt;/span&gt;
&lt;span class="na"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;
&lt;span class="na"&gt;RestartSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;5s&lt;/span&gt;
&lt;span class="na"&gt;LimitNOFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;40000&lt;/span&gt;
&lt;span class="na"&gt;TimeoutStartSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;0&lt;/span&gt;

&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/local/bin/etcd \&lt;/span&gt;
&lt;span class="s"&gt;  --name etcd03 \&lt;/span&gt;
&lt;span class="s"&gt;  --data-dir /var/lib/etcd \&lt;/span&gt;
&lt;span class="s"&gt;  --initial-advertise-peer-urls https://192.168.1.85:2380 \&lt;/span&gt;
&lt;span class="s"&gt;  --listen-peer-urls https://192.168.1.85:2380 \&lt;/span&gt;
&lt;span class="s"&gt;  --listen-client-urls https://192.168.1.85:2379,https://127.0.0.1:2379 \&lt;/span&gt;
&lt;span class="s"&gt;  --advertise-client-urls https://192.168.1.85:2379 \&lt;/span&gt;
&lt;span class="s"&gt;  --initial-cluster-token etcd-cluster-1 \&lt;/span&gt;
&lt;span class="s"&gt;  --initial-cluster etcd01=https://192.168.1.83:2380,etcd02=https://192.168.1.84:2380,etcd03=https://192.168.1.85:2380 \&lt;/span&gt;
&lt;span class="s"&gt;  --initial-cluster-state existing \&lt;/span&gt;
&lt;span class="s"&gt;  --cert-file=/etc/kubernetes/pki/etcd/server.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --key-file=/etc/kubernetes/pki/etcd/server-key.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --client-cert-auth \&lt;/span&gt;
&lt;span class="s"&gt;  --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --peer-cert-file=/etc/kubernetes/pki/etcd/peer.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --peer-key-file=/etc/kubernetes/pki/etcd/peer-key.pem \&lt;/span&gt;
&lt;span class="s"&gt;  --peer-client-cert-auth \&lt;/span&gt;
&lt;span class="s"&gt;  --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.pem&lt;/span&gt;

&lt;span class="k"&gt;[Install]&lt;/span&gt;
&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/figure&gt;
&lt;p&gt;Recargamos la configuración de &lt;code&gt;systemctl&lt;/code&gt; e iniciamos el servicio de &lt;em&gt;etcd&lt;/em&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ sudo systemctl daemon-reload
$ sudo systemctl start etcd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Al cabo de unos pocos segundos (dependiendo del tamaño de la base de datos de &lt;em&gt;etcd&lt;/em&gt; que tengamos en nuestro cluster), el nuevo nodo se habrá sincronizado y si pedimos de nuevo la lista de nodos tendríamos que ver que el nuevo nodo ya está funcionando como los demás:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt; etcdctl member list
&lt;span class="go"&gt;b5a3b7906f500074, started, etcd01, https://192.168.1.83:2380, https://192.168.1.83:2379&lt;/span&gt;
&lt;span class="go"&gt;c37956d0928a73d9, started, etcd02, https://192.168.1.84:2380, https://192.168.1.84:2379&lt;/span&gt;
&lt;span class="go"&gt;736e5742db963896, started, etcd03, https://192.168.1.85:2380, https://192.168.1.85:2379&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;Por coherencia con el resto de nodos, yo recomiendo que una vez se ha añadido el nuevo nodo al cluster y todo está funcionando, editemos de nuevo el archivo &lt;code&gt;/etc/systemd/system/etcd.service&lt;/code&gt; y volvamos a cambiar el &lt;code&gt;--initial-cluster-state existing&lt;/code&gt; por &lt;code&gt;--initial-cluster-state new&lt;/code&gt; para dejarlo como estaba (igual que en el resto de nodos) pero realmente daría igual ya que una vez iniciado el servicio por primera vez, ese parámetro ya no se vuelve a tener en cuenta.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Bueno, pues ya tenemos el cluster otra vez &lt;em&gt;completo&lt;/em&gt;, ¿pero cómo sabemos que realmente esta funcionando en alta disponibilidad, y va a seguir haciéndolo aunque alguno de sus nodos se quede fuera de servicio? Vamos a comprobarlo:&lt;/p&gt;
&lt;p&gt;Detenemos el servicio de &lt;em&gt;etcd&lt;/em&gt; en el nodo 1 (&lt;code&gt;etcd01&lt;/code&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;$ sudo systemctl stop etcd
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Y volvemos a preguntar por el valor de la clave que guardamos antes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt; etcdctl get clavePrueba
&lt;span class="go"&gt;Esto es una prueba&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Como ves, obtenemos el valor de la clave sin problemas aún con el nodo 1 fuera de servicio.&lt;/p&gt;
&lt;p&gt;Ahora, levantamos de nuevo el servicio &lt;em&gt;etcd&lt;/em&gt; en el nodo 1, lo detenemos el nodo 2 y volvemos a preguntar por la clave (es importante que ANTES de detener el nodo 2 vuelvas a iniciar el nodo 1, ya que un cluster de 3 nodos puede &lt;em&gt;sobrevivir&lt;/em&gt; si falla 1 nodo, pero no si fallan 2):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt; etcdctl get clavePrueba
&lt;span class="go"&gt;Esto es una prueba&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;De nuevo sigue funcionando... así que vamos con la última prueba: levantamos de nuevo el servicio &lt;em&gt;etcd&lt;/em&gt; en el nodo 2, lo detenemos en el nodo 3 y volvemos a preguntar por la clave:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt; etcdctl get clavePrueba
&lt;span class="go"&gt;Esto es una prueba&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Como ves, el cluster sigue funcionando aunque cualquiera de sus nodos deje de hacerlo.&lt;/p&gt;
&lt;p&gt;Ya tienes tu cluster montado y funcionado, así que ya puedes empezar a utilizarlo sin problemas!&lt;/p&gt;
&lt;p&gt;Como siempre, espero que el artículo os haya resultado de utilidad! Y por supuesto, no dudéis en distribuirlo y compartirlo con todo el mundo (pero por favor, citad siempre la fuente original de éste artículo).&lt;/p&gt;
&lt;p&gt;Alaaaaaaaaaaaaaaaaaaaaaaa!&lt;/p&gt;
&lt;h2&gt;Referencias&lt;a name="refs"&gt;&lt;/a&gt;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://coreos.com/etcd"&gt;https://coreos.com/etcd&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/coreos/etcd/tree/master/etcdctl"&gt;https://github.com/coreos/etcd/tree/master/etcdctl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/coreos/etcd/blob/master/Documentation/faq.md"&gt;https://github.com/coreos/etcd/blob/master/Documentation/faq.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/coreos/etcd/blob/master/Documentation/op-guide/configuration.md"&gt;https://github.com/coreos/etcd/blob/master/Documentation/op-guide/configuration.md&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.cloudflare.com/introducing-cfssl"&gt;https://blog.cloudflare.com/introducing-cfssl&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Sun, 06 May 2018 00:14:02 +0100</pubDate><guid isPermaLink="false">tag:pornohardware.com,2018-05-06:/en/2018/05/06/alta-disponibilidad-en-etcd-desplegando-un-cluster-paso-a-paso/</guid><category>Varios</category><category>Linux</category><category>Kubernetes</category></item><item><title>Implementa tests en tus roles de Ansible con Molecule</title><link>https://pornohardware.com/2018/03/12/implementa-tests-en-tus-roles-de-ansible-con-molecule/</link><description>&lt;p&gt;Hoy en dia nadie concibe (o nadie debería concebir, mejor dicho) empezar un proyecto de programación sin sus correspondientes tests. Tranquilidad en el desarrollo, código más robusto, anticiparnos a los errores, etc. son algunas de las &lt;em&gt;maravillas&lt;/em&gt; que nos ofrece el mundo del &lt;em&gt;testing&lt;/em&gt;, así que si tiene tantas ventajas... ¿porqué no íbamos a aplicarlo también a otros ámbitos que no sean exclusivamente los de la programación?&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.ansible.com/"&gt;Ansible&lt;/a&gt; es una de esas herramientas indispensables para cualquiera que administre servidores, automatizando la instalación de nuevos servicios, el despliegue de aplicaciones, configuraciones, etc. permitiendo que llevemos a cabo todas esas tareas de forma sencilla, rápida y automatizada ya sea en un servidor, en diez o en miles de ellos mediante la creación de &lt;a href="https://docs.ansible.com/ansible/latest/playbooks_reuse_roles.html"&gt;&lt;em&gt;roles&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;En este artículo voy a explicar cómo implementar el &lt;em&gt;framework&lt;/em&gt; &lt;a href="https://molecule.readthedocs.io"&gt;Molecule&lt;/a&gt; en dichos roles para poder testear su sintaxis, su &lt;a href="https://es.wikipedia.org/wiki/Idempotencia"&gt;idempotencia&lt;/a&gt; (me encanta esta palabra) y su ejecución en diferentes instancias con diferentes sistemas operativos y configuraciones.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Mon, 12 Mar 2018 16:12:40 +0100</pubDate><guid isPermaLink="false">tag:pornohardware.com,2018-03-12:/2018/03/12/implementa-tests-en-tus-roles-de-ansible-con-molecule/</guid><category>Varios</category><category>Linux</category></item><item><title>Correcta instalación de Java en Debian mediante paquetes DEB</title><link>https://pornohardware.com/2017/11/12/correcta-instalacion-de-java-en-debian-mediante-paquetes-deb/</link><description>&lt;p&gt;Hay muchas formas de instalar diferentes versiones de Java en nuestros sistemas: en la propia web de &lt;a href="www.oracle.com/technetwork/java/javase/downloads/"&gt;Oracle&lt;/a&gt; (que como todos sabéis, es el &lt;a href="https://elpais.com/tecnologia/2009/04/20/actualidad/1240216080_850215.html"&gt;propietario de Java&lt;/a&gt; desde hace varios años) podemos descargar diferentes versiones (9, 8, 7, ...), en diferentes formatos (comprimido con &lt;em&gt;tar.gz&lt;/em&gt;, paquetes para &lt;a href="https://www.centos.org/"&gt;CentOS&lt;/a&gt;/&lt;a href="https://www.redhat.com/"&gt;RedHat&lt;/a&gt;, ejecutables binarios, ...) y para diferentes sistemas operativos (Linux, MacOS, Windows y SPARC).&lt;/p&gt;
&lt;p&gt;Incluso hay repositorios no-oficiales que ponen a disposición de todo el mundo los paquetes de instalación de Java en otros formatos, por lo que a simple vista cualquiera diría que existiendo tanta variedad incluso nosotros (fieles y exigentes defensores de &lt;a href="https://www.debian.org/index.es.html"&gt;Debian&lt;/a&gt; y de la &lt;a href="https://es.wikipedia.org/wiki/Mantenibilidad"&gt;mantenibilidad&lt;/a&gt; de los sistemas) estaríamos contentos, verdad?&lt;/p&gt;
&lt;p&gt;Pues va a ser que no...&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Sun, 12 Nov 2017 15:58:52 +0100</pubDate><guid isPermaLink="false">tag:pornohardware.com,2017-11-12:/2017/11/12/correcta-instalacion-de-java-en-debian-mediante-paquetes-deb/</guid><category>Varios</category><category>Linux</category><category>Java</category><category>Programación</category></item><item><title>Firmando emails con OpenDKIM</title><link>https://pornohardware.com/2017/11/10/firmando-emails-con-opendkim/</link><description>&lt;p&gt;El &lt;a href="http://es.wikipedia.org/wiki/Spam"&gt;SPAM&lt;/a&gt; es una de las mayores &lt;em&gt;lacras&lt;/em&gt; que inundan Internet desde el principio de su creación. Genera &lt;a href="https://www.aeaweb.org/articles?id=10.1257/jep.26.3.87"&gt;cien veces más pérdidas a la sociedad que beneficio a sus creadores&lt;/a&gt; y supone el &lt;a href="https://mybroadband.co.za/news/internet/14250-spam-a-whopping-84-of-email-traffic.html"&gt;84% de los emails que recibimos&lt;/a&gt;. Y este mal existe, entre otras cosas, porque el sistema de correo electrónico de Internet se diseñó dando por hecho que toda la gente que lo iba a utilizar lo haría &lt;em&gt;de buena fe&lt;/em&gt;: craso error.&lt;/p&gt;
&lt;p&gt;Pensar que nadie iba a utilizar el correo electrónico para &lt;em&gt;hacer cosas malas&lt;/em&gt; hizo que se diseñara, entre otras muchas cosas, sin ningún sistema que garantice a quien los recibe que dichos mensajes no han sido &lt;em&gt;manipulados por el camino&lt;/em&gt; o escritos por remitentes falsos.&lt;/p&gt;
&lt;p&gt;Por estos motivos, &lt;em&gt;Internet&lt;/em&gt; lleva años desarrollando herramientas y sistemas que ayuden a &lt;em&gt;paliar&lt;/em&gt; los problemas de diseño que el correo electrónico tiene de base.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.dkim.org/"&gt;DKIM&lt;/a&gt; es uno de estos mecanismos, y permite a los destinatarios de un mensaje de correo electrónico saber si un email ha sido realmente enviado por el remitente y no por alguien haciéndose pasar por él (esta práctica se denomina &lt;a href="https://es.wikipedia.org/wiki/Email_spoofing"&gt;mail spoofing&lt;/a&gt;).&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Fri, 10 Nov 2017 23:50:06 +0100</pubDate><guid isPermaLink="false">tag:pornohardware.com,2017-11-10:/2017/11/10/firmando-emails-con-opendkim/</guid><category>Varios</category><category>Linux</category><category>Internet</category></item><item><title>Integración Continua en Pelican usando Gitlab-CI</title><link>https://pornohardware.com/2017/04/24/integracion-continua-en-pelican-usando-gitlab-ci/</link><description>&lt;p&gt;A estas alturas no creo que haya nadie (o casi nadie) &lt;em&gt;en este mundillo&lt;/em&gt; que todavía no sepa qué es la &lt;a href="https://es.wikipedia.org/wiki/Integraci%C3%B3n_continua"&gt;&lt;em&gt;integración continua&lt;/em&gt;&lt;/a&gt;, sin embargo la inmensa mayoría no lo utiliza aún en sus proyectos.&lt;/p&gt;
&lt;p&gt;Hay muchas excusas para justificar este hecho, como por ejemplo que "&lt;em&gt;es un proyecto pequeño&lt;/em&gt;", o que "&lt;em&gt;es un proyecto personal en el que solo trabajo yo&lt;/em&gt;", o que "&lt;em&gt;el proyecto tiene unos plazos muy ajustados y no hay tiempo para más &lt;strike&gt;tonterías&lt;/strike&gt; desarrollos&lt;/em&gt;", o incluso que "&lt;em&gt;no merece la pena el esfuerzo extra que hay que dedicarle&lt;/em&gt;"... pero ninguna de ellas es válida, así que si alguna vez en tu vida has usado alguna de estas excusas para no utilizar un sistema de integración continua, eres un &lt;em&gt;merluzo&lt;/em&gt;, compañero... pero no temas, que eso va a cambiar hoy...&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Mon, 24 Apr 2017 22:08:25 +0100</pubDate><guid isPermaLink="false">tag:pornohardware.com,2017-04-24:/2017/04/24/integracion-continua-en-pelican-usando-gitlab-ci/</guid><category>Varios</category><category>Blogs</category><category>Integración Continua</category></item><item><title>Adios Octopress, hola Pelican!</title><link>https://pornohardware.com/2017/03/23/adios-octopress-hola-pelican/</link><description>&lt;p&gt;Efectivamente, ha llegado la hora de &lt;em&gt;enterrar&lt;/em&gt; a nuestro antiguo &lt;a href="http://octopress.org/"&gt;Octopress&lt;/a&gt; y dar la bienvenida al nuevo &lt;a href="https://www.getpelican.com"&gt;Pelican&lt;/a&gt;.
Y no solo porque este último esté hecho en &lt;a href="https://www.python.org/"&gt;Python&lt;/a&gt; (que me gusta mil veces más que &lt;a href="https://www.ruby-lang.org/es/"&gt;Ruby&lt;/a&gt;, todo sea dicho) sino porque estoy más que harto de esperar la &lt;em&gt;maldita&lt;/em&gt; versión 3 de Octopress desde hace literalmente &lt;strong&gt;más de 2 años&lt;/strong&gt;, y no solo no ha salido aún (de hecho, ha pasado más de 1 año desde el último &lt;em&gt;commit&lt;/em&gt; que hicieron en cualquiera de las ramas de su repositorio de &lt;a href="https://github.com/imathis/octopress"&gt;Github&lt;/a&gt;) sino que además sus desarrolladores han anunciado que ésta nueva versión &lt;strong&gt;NO&lt;/strong&gt; es compatible con las anteriores, por lo que ni siquiera puedo migrar el blog. Tendría que hacerlo de nuevo desde cero (incluyendo los plugins que he hecho, el &lt;em&gt;theme&lt;/em&gt;, etc).&lt;/p&gt;
&lt;p&gt;Así que como se suele decir: &lt;em&gt;Con Octopress, va a ser que no&lt;/em&gt;...&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Thu, 23 Mar 2017 23:24:54 +0100</pubDate><guid isPermaLink="false">tag:pornohardware.com,2017-03-23:/2017/03/23/adios-octopress-hola-pelican/</guid><category>Varios</category><category>Blogs</category></item><item><title>Accede a tu biblioteca multimedia (audio y video) desde cualquier parte con Ampache</title><link>https://pornohardware.com/2015/12/28/accede-a-tu-biblioteca-multimedia-audio-y-video-desde-cualquier-parte-con-ampache/</link><description>&lt;p&gt;Según la definición que aparece en &lt;a href="https://es.wikipedia.org"&gt;Wikipedia&lt;/a&gt;, &lt;a href="https://github.com/ampache/ampache/"&gt;Ampache&lt;/a&gt; es un &lt;a href="https://es.wikipedia.org/wiki/Administrador_de_archivos"&gt;administrador de archivos&lt;/a&gt; y servidor de &lt;a href="https://es.wikipedia.org/wiki/Streaming"&gt;streaming&lt;/a&gt; multimedia que se ejecuta sobre un &lt;a href="https://es.wikipedia.org/wiki/Servidor_web"&gt;servidor web&lt;/a&gt;. Es decir, un software que os permitirá mantener organizada vuestra biblioteca multimedia (generalmente música y películas) y que os permitirá reproducir dicha biblioteca desde un navegador, un smartphone, una tablet, etc.&lt;/p&gt;
&lt;p&gt;&lt;img class="right" src="/images/logos/logo_ampache.png"/&gt;
Empresas como &lt;a href="https://www.spotify.com"&gt;Spotify&lt;/a&gt;, &lt;a href="http://www.deezer.com"&gt;Deezer&lt;/a&gt;, &lt;a href="https://www.jamendo.com"&gt;Jamendo&lt;/a&gt;, los &lt;em&gt;asquerosos&lt;/em&gt; de &lt;a href="https://play.google.com/music/"&gt;Google Play Music&lt;/a&gt; o la recién llegada &lt;a href="http://www.apple.com/es/music"&gt;Apple Music&lt;/a&gt; (entre muchas otras) ofrecen casi toda la música del mundo a solo un par de &lt;em&gt;clicks&lt;/em&gt; de distancia, y como cada vez hay más competencia en este tipo de servicios de audio en &lt;a href="https://es.wikipedia.org/wiki/Streaming"&gt;streaming&lt;/a&gt;, todas ellas se esfuerzan en mejorar la calidad de sus servicios, aumentar su catálogo y mejorar sus cada vez más atractivos precios de suscripción.&lt;/p&gt;
&lt;p&gt;¿Porqué montar entonces un servicio propio de streaming? Intentaré explicarlo para que &lt;strong&gt;incluso tu&lt;/strong&gt;, insignificante humano, lo entiendas...&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Mon, 28 Dec 2015 17:13:04 +0100</pubDate><guid isPermaLink="false">tag:pornohardware.com,2015-12-28:/2015/12/28/accede-a-tu-biblioteca-multimedia-audio-y-video-desde-cualquier-parte-con-ampache/</guid><category>Varios</category><category>Multimedia</category><category>Linux</category></item><item><title>Creación de un bot de Telegram en PHP</title><link>https://pornohardware.com/2015/08/12/creacion-de-un-bot-de-telegram-en-php/</link><description>&lt;p&gt;Siempre defiendo que &lt;a href="https://telegram.org/"&gt;Telegram&lt;/a&gt; es &lt;a href="/2014/11/18/telegram-aun-hay-esperanza-para-las-apps-de-mensajeria"&gt;la mejor app de mensajería&lt;/a&gt; que existe a día de hoy, no solo porque de verdad se preocupen por la seguridad y privacidad de las comunicaciones de sus usuarios (no como &lt;a href="https://www.eff.org/who-has-your-back-government-data-requests-2015#whatsapp-report"&gt;otros&lt;/a&gt;), ni por la calidad de sus apps frente a las de sus &lt;em&gt;competidores&lt;/em&gt;, sino porque entre muchas otras cosas, mantienen un ritmo muy alto de actualizaciones que hacen que cada poco tiempo tengamos disponibles nuevas versiones con nuevas y mejores funcionalidades.&lt;/p&gt;
&lt;p&gt;En este artículo hablaré de una de sus últimas funcionalidades, concretamente de la &lt;a href="https://es.wikipedia.org/wiki/Interfaz_de_programaci%C3%B3n_de_aplicaciones"&gt;API&lt;/a&gt; que la gente de Telegram ha liberado para su uso público, y que permite a cualquier programador crear &lt;a href="https://es.wikipedia.org/wiki/Bot"&gt;bots&lt;/a&gt; para interactuar con otros usuarios a través de conversaciones de Telegram.&lt;/p&gt;
&lt;p&gt;Y no solo a programadores, sino que gracias a algunas herramientas (como por ejemplo &lt;a href="http://paquebot.io/"&gt;paquebot.io&lt;/a&gt;) cualquier persona con un mínimo de interés y ganas de &lt;em&gt;trastear&lt;/em&gt; un poco puede hacerlo.&lt;/p&gt;
&lt;p&gt;Pero esto es un blog técnico, no una web de noticias para &lt;a href="https://es.wikipedia.org/wiki/Luser"&gt;&lt;em&gt;lusers&lt;/em&gt;&lt;/a&gt;, así que déjate de asistentes, &lt;a href="https://es.wikipedia.org/wiki/Interfaz_gr%C3%A1fica_de_usuario"&gt;GUIs&lt;/a&gt; y demás &lt;em&gt;mariconadas&lt;/em&gt; y vamos a programar...&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Wed, 12 Aug 2015 19:48:53 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2015-08-12:/2015/08/12/creacion-de-un-bot-de-telegram-en-php/</guid><category>Varios</category><category>Apps</category><category>PHP</category><category>Programación</category></item><item><title>LCARS: el sistema operativo de la Flota Estelar</title><link>https://pornohardware.com/2015/07/02/lcars-el-sistema-operativo-de-la-flota-estelar/</link><description>&lt;p&gt;Hace tiempo que quería escribir este artículo, sobre todo porque se dice que hay gente por ahí que no saben qué es LCARS (si, lo se... es alucinante..  yo tampoco me lo creía) y como a mi siempre me ha parecido un tema curioso, a partir de ahora cuando hable de este tema con alguien que no lo conozca me resultará mucho más fácil enviarle el enlace a éste artículo que tener que explicar una y otra vez de qué va ésto.&lt;/p&gt;
&lt;p&gt;Antes de seguir, y sobre todo si eres una de esas &lt;em&gt;personas&lt;/em&gt; (por llamarte de alguna forma) que no ha oido nunca hablar de LCARS, quiero dejar claro que éste artículo no trata de tecnología real, ni de un nuevo sistema operativo, ni de ninguna nueva plataforma de desarrollo asombrosa para que la implementes en tus proyectos.&lt;/p&gt;
&lt;p&gt;LCARS &lt;strong&gt;NO EXISTE&lt;/strong&gt;, es pura fantasía, y solo un pequeño e inocente niño pensaría que realmente existe más allá de la imaginación de algunos (al igual que los &lt;a href="https://es.wikipedia.org/wiki/Reyes_Magos"&gt;Reyes Magos&lt;/a&gt;, el &lt;a href="https://es.wikipedia.org/wiki/Ratoncito_P%C3%A9rez"&gt;Ratoncito Pérez&lt;/a&gt; o la &lt;a href="http://www.eldiario.es/economia/Rajoy-millones-desempleados-afiliados-legislatura_0_458454228.html"&gt;política de empleo de Mariano Rajoy&lt;/a&gt;.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Thu, 02 Jul 2015 23:03:45 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2015-07-02:/2015/07/02/lcars-el-sistema-operativo-de-la-flota-estelar/</guid><category>Varios</category><category>Ciencia Ficción</category></item><item><title>Teclados mecánicos: ¿a qué esperas para comprarte uno?</title><link>https://pornohardware.com/2015/03/15/teclados-mecanicos-a-que-esperas-para-comprarte-uno/</link><description>&lt;p&gt;&lt;img class="left" height="292" src="/images/posts/mech-keyboard/keyboard.jpg" width="334"/&gt;
La inmensa mayoría de las personas que utilizan un ordenador a diario utilizan teclados de membrana, y la inmensa mayoría de ellos ni siquiera saben de la existencia de otros tipos de teclados.&lt;/p&gt;
&lt;p&gt;En éste artículo explicaré las características más representativas de los teclados mecánicos, los diferentes tipos de mecanismos de teclas que existen para éstos teclados y en definitiva, todas las &lt;em&gt;sensaciones&lt;/em&gt; que aporta el uso de uno de éstos teclados.&lt;/p&gt;
&lt;p&gt;Y es que al contrario de lo que piensa la mayoría, estos teclados no solo para &lt;a href="http://es.wikipedia.org/wiki/Jugador_de_videojuegos"&gt;gamers&lt;/a&gt;, sino para cualquier persona o político que utilice un ordenador habitualmente..&lt;/p&gt;
&lt;p&gt;Solo existen 2 tipos de personas en el mundo: los que adoran los teclados mecánicos, y los que aún no los han probado.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Sun, 15 Mar 2015 00:58:48 +0100</pubDate><guid isPermaLink="false">tag:pornohardware.com,2015-03-15:/2015/03/15/teclados-mecanicos-a-que-esperas-para-comprarte-uno/</guid><category>Varios</category><category>Hardware</category></item><item><title>Instalación y configuración de un servidor de correo completo en Linux</title><link>https://pornohardware.com/2015/01/01/instalacion-y-configuracion-de-un-servidor-de-correo-completo-en-linux/</link><description>&lt;p&gt;&lt;img class="right" src="/images/logos/logo_email.png"/&gt;
Uno de los servicios más importantes de Internet es sin duda el correo electrónico, y al igual que con muchos otros servicios, no hay nada que gestione mejor el correo que GNU/Linux.&lt;/p&gt;
&lt;p&gt;Hay muchos proyectos conocidísimos y de gran importancia en el mundo de GNU/Linux, como por ejemplo el servidor web &lt;a href="https://projects.apache.org/project.html?httpd-http_server"&gt;Apache&lt;/a&gt;, las bases de datos &lt;a href="http://dev.mysql.com/"&gt;MySQL&lt;/a&gt; y &lt;a href="http://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt;, el servidor de nombres &lt;a href="http://www.isc.org/downloads/bind/"&gt;Bind&lt;/a&gt; y muchísimos más... pero hay 2 de estos grandísimos proyectos que no suelen ser tan conocidos para &lt;em&gt;el ciudadano de a pié&lt;/em&gt;, y sin embargo son una parte fundamental de Internet. Me estoy refiriendo a &lt;a href="http://www.postfix.org/"&gt;Postfix&lt;/a&gt; y a &lt;a href="http://www.courier-mta.org/"&gt;Courier&lt;/a&gt;, la pareja perfecta para hacerse cargo de algo tan importante hoy en dìa como es el correo electrónico.&lt;/p&gt;
&lt;p&gt;Y es que la combinación de estos 2 sistemas no solo funciona, sino que además lo hace increíblemente bien.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Thu, 01 Jan 2015 11:03:39 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2015-01-01:/2015/01/01/instalacion-y-configuracion-de-un-servidor-de-correo-completo-en-linux/</guid><category>Varios</category><category>Linux</category><category>Internet</category></item><item><title>Inicio automático de máquinas virtuales con XenServer</title><link>https://pornohardware.com/2014/12/24/inicio-automatico-de-maquinas-virtuales-con-xenserver/</link><description>&lt;p&gt;Cuando se habla de virtualización a nivel &lt;em&gt;usuario&lt;/em&gt;, la mayoría de la gente piensa en &lt;a href="https://www.virtualbox.org/"&gt;Virtualbox&lt;/a&gt; (que es una genial aplicación), y cuando se habla de virtualización a nivel &lt;em&gt;empresarial&lt;/em&gt;, el software en el que casi todo el mundo piensa es &lt;a href="http://www.vmware.com/es/"&gt;VMWare&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img class="right" src="/images/logos/logo_citrix_xenserver.png"/&gt;
Ambos son grandísimos productos, maduros y estables... pero desde que probé &lt;a href="http://www.citrix.com/products/xenserver/overview.html?posit=glnav"&gt;XenServer&lt;/a&gt;, éste genial sistema de virtualización de la empresa &lt;a href="http://www.citrix.com/"&gt;Citrix&lt;/a&gt; es el que más me gusta.&lt;/p&gt;
&lt;p&gt;XenServer es (al igual que el resto de productos de Citrix) un software cerrado y de pago, pero también existe una version gratuita que se puede usar libremente en entornos de producción empresarial. Ésta versión gratuita únicamente tiene algunas limitaciones con respecto a la versión de pago, y una de ellas es precisamente la de configurar las máquinas virtuales para que se inicien automáticamente cuando se inicia el servidor.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Wed, 24 Dec 2014 12:04:34 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2014-12-24:/2014/12/24/inicio-automatico-de-maquinas-virtuales-con-xenserver/</guid><category>Varios</category><category>Linux</category><category>Virtualización</category></item><item><title>Promoción de Navidad de Leroy Merlin: Un buen ejemplo de como NO hacer las cosas</title><link>https://pornohardware.com/2014/12/11/promocion-de-navidad-de-leroy-merlin-un-buen-ejemplo-de-como-no-hacer-las-cosas/</link><description>&lt;p&gt;&lt;img class="right" src="/images/posts/sms_pdu/leroy_merlin.png"/&gt;
Dice mi mujer que cada vez tengo peor carácter, y que al final me acabaré convirtiendo en el típico viejo amargado que protesta por todo... y quizás tenga razón, pero no puedo evitarlo: no soporto la &lt;em&gt;chulería&lt;/em&gt; ni los malos modales de la gente, y menos aún cuando no solo NO tienen razón sino que además se supone que deberían ser amables con sus propios clientes.&lt;/p&gt;
&lt;p&gt;Pero empecemos desde el principio: os voy a contar la breve historia de lo que me sucedió la semana pasada con ésta conocida cadena de &lt;em&gt;herramientas y bricolaje&lt;/em&gt;, y de cómo conseguí lo que me correspondía usando nuestra &lt;strong&gt;Querida Tecnología(TM)&lt;/strong&gt;.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Thu, 11 Dec 2014 20:57:54 +0100</pubDate><guid isPermaLink="false">tag:pornohardware.com,2014-12-11:/2014/12/11/promocion-de-navidad-de-leroy-merlin-un-buen-ejemplo-de-como-no-hacer-las-cosas/</guid><category>Varios</category><category>Personal</category><category>Internet</category></item><item><title>Modificar el espacio reservado en particiones con sistemas de archivos ext3 o ext4</title><link>https://pornohardware.com/2014/12/08/modificar-el-espacio-reservado-en-particiones-con-sistemas-de-archivos-ext3-o-ext4/</link><description>&lt;p&gt;&lt;img class="left" src="/images/posts/hdd.png"/&gt;
Si llevais algun tiempo usando &lt;a href="http://www.gnu.org/gnu/linux-and-gnu.html"&gt;GNU/Linux&lt;/a&gt; y sois mínimamente observadores, habreis notado que siempre que montais un nuevo disco y lo formateais utilizando &lt;a href="http://es.wikipedia.org/wiki/Ext3"&gt;ext3&lt;/a&gt; o &lt;a href="http://es.wikipedia.org/wiki/Ext4"&gt;ext4&lt;/a&gt; como sistema de archivos, nunca se obtiene el 100% de la capacidad del disco.&lt;/p&gt;
&lt;p&gt;Ésto se debe a que éstos sistemas de archivos reservan por defecto un 5% de la capacidad total del disco para uso del usuario &lt;em&gt;root&lt;/em&gt; (para que en caso de llenar por completo el disco, todavía podamos acceder y realizar tareas de administración) y para prevenir problemas derivados de la fragmentación de archivos.&lt;/p&gt;
&lt;p&gt;Y hace años, cuando el tamaño de los discos duros era ínfimo (comparado con el tamaño actual, quiero decir) éste valor podía tener sentido... pero hoy en dia, teniendo discos &lt;a href="http://es.wikipedia.org/wiki/Serial_ATA"&gt;SATA&lt;/a&gt; de hasta 6 TB, reservar un 5% es una &lt;em&gt;salvajada&lt;/em&gt; que solo serviría para &lt;em&gt;perder&lt;/em&gt; 300 GB!&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Mon, 08 Dec 2014 00:23:20 +0100</pubDate><guid isPermaLink="false">tag:pornohardware.com,2014-12-08:/2014/12/08/modificar-el-espacio-reservado-en-particiones-con-sistemas-de-archivos-ext3-o-ext4/</guid><category>Varios</category><category>Linux</category></item><item><title>Telegram: aún hay esperanza para las apps de mensajería</title><link>https://pornohardware.com/2014/11/18/telegram-aun-hay-esperanza-para-las-apps-de-mensajeria/</link><description>&lt;p&gt;&lt;img class="right" src="/images/logos/logo_telegram.png"/&gt;
Por si implementar un robusto &lt;a href="https://es.wikipedia.org/wiki/Criptograf%C3%ADa"&gt;protocolo de encriptación&lt;/a&gt;, tener una &lt;em&gt;app&lt;/em&gt; para casi todos los sistemas operativos móviles mayoritarios que existen, haber &lt;a href="https://telegram.org/apps#source-code"&gt;publicado su código fuente&lt;/a&gt;, disponer de una &lt;a href="https://core.telegram.org/api"&gt;API pública&lt;/a&gt; para que cualquier desarrollador pueda integrar &lt;a href="https://telegram.org/"&gt;Telegram&lt;/a&gt; en sus programas o haber garantizado desde el primer momento que su sistema será &lt;strong&gt;gratis y libre de publicidad para siempre&lt;/strong&gt; no fueran argumentos suficientes como para erigir a Telegram como &lt;em&gt;la mejor aplicación de mensajería instantánea que existe hoy en día&lt;/em&gt;, ahora van y sacan aplicaciones de escritorio para Linux y Mac!! &lt;em&gt;(vaaaaale, para Windows también... pero a quién le importa ésto último?)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Y nada de &lt;a href="https://es.wikipedia.org/wiki/Aplicaci%C3%B3n_web"&gt;webapps&lt;/a&gt; (aunque si quieres, &lt;a href="https://web.telegram.org/"&gt;también las tiene&lt;/a&gt;) sino que se trata de aplicaciones nativas para cada sistema operativo (cuyo código fuente, además, &lt;a href="https://github.com/telegramdesktop/tdesktop"&gt;también han publicado&lt;/a&gt;).&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Tue, 18 Nov 2014 20:57:44 +0100</pubDate><guid isPermaLink="false">tag:pornohardware.com,2014-11-18:/2014/11/18/telegram-aun-hay-esperanza-para-las-apps-de-mensajeria/</guid><category>Varios</category><category>Apps</category><category>Linux</category></item><item><title>POODLE: En qué consiste esta vulnerabilidad del protocolo SSL y qué hacer para evitarla</title><link>https://pornohardware.com/2014/10/20/poodle-en-que-consiste-esta-vulnerabilidad-del-protocolo-ssl-y-que-hacer-para-evitarla/</link><description>&lt;p&gt;&lt;img class="right" src="/images/logos/logo_poodlebleed.png"/&gt;&lt;/p&gt;
&lt;p&gt;Ha sido un duro golpe el que ha recibido nuestro querido &lt;a href="https://es.wikipedia.org/wiki/Transport_Layer_Security#SSL_3.0_2"&gt;SSL&lt;/a&gt; (concretamente su versión 3.0) con el descubrimiento de ésta vulnerabilidad, ya que no existe una solución de verdad al problema salvo la de &lt;strong&gt;no utilizar&lt;/strong&gt; esa versión en concreto.&lt;/p&gt;
&lt;p&gt;Ésta vulnerabilidad no provoca una denegación de servicio (&lt;a href="https://es.wikipedia.org/wiki/Ataque_de_denegaci%C3%B3n_de_servicio"&gt;DoS&lt;/a&gt;), ni otorga acceso de administración a los servidores vulnerables, ni se puede utilizar para eliminar archivos, sino que permite a un atacante (mediante ataques &lt;em&gt;&lt;a href="https://es.wikipedia.org/wiki/Ataque_Man-in-the-middle"&gt;man in the middle&lt;/a&gt;&lt;/em&gt;) acceder a la información que se transmite en una conexión que hasta ese momento se pensaba que era segura y privada, sin que los interlocutores de dicha comunicación lo sepan.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Mon, 20 Oct 2014 10:34:19 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2014-10-20:/2014/10/20/poodle-en-que-consiste-esta-vulnerabilidad-del-protocolo-ssl-y-que-hacer-para-evitarla/</guid><category>Varios</category><category>Seguridad</category></item><item><title>jekyll-vimeo-lazyloading: Un nuevo plugin para mostrar videos de Vimeo en Octopress</title><link>https://pornohardware.com/2014/09/27/jekyll-vimeo-lazyloading-un-nuevo-plugin-para-mostrar-videos-de-vimeo-en-octopress/</link><description>&lt;p&gt;&lt;img class="left" src="/images/logos/logo_vimeo.png"/&gt;
Lo prometido es deuda... y tal y como comenté en mi artículo sobre &lt;a href="/2014/07/12/seleccion-de-plugins-para-octopress"&gt;plugins para Octopress&lt;/a&gt;, finalmente he desarrollado un nuevo plugin para mostrar los videos del genial &lt;a href="https://www.vimeo.com"&gt;Vimeo&lt;/a&gt; en aquellos blogs basados en &lt;a href="http://jekyllrb.com/"&gt;Jekyll&lt;/a&gt; y &lt;a href="http://octopress.org/"&gt;Octopress&lt;/a&gt; de forma que el reproductor embebido no se cargue hasta que el usuario no haga &lt;em&gt;click&lt;/em&gt; en dicho video.&lt;/p&gt;
&lt;p&gt;De ésta forma evitamos la carga innecesaria del &lt;code&gt;iframe&lt;/code&gt; de Vimeo en aquellas páginas en las que el usuario no está interesado en reproducir los videos que hay en ella.&lt;/p&gt;
&lt;p&gt;¿Nunca os ha pasado que al entrar en una página, varios videos (sobre todo del &lt;em&gt;asqueroso&lt;/em&gt; &lt;a href="https://www.youtube.com/"&gt;Youtube&lt;/a&gt;) comienzan a reproducirse automaticamente (con audio incluido), molestandoos no solo a vosotros sino a todos los que os rodean (en caso de tener el volumen activado)?&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Sat, 27 Sep 2014 02:13:36 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2014-09-27:/2014/09/27/jekyll-vimeo-lazyloading-un-nuevo-plugin-para-mostrar-videos-de-vimeo-en-octopress/</guid><category>Varios</category><category>Blogs</category></item><item><title>Diagramas, mapas de red y demás gráficas estructuradas con Graphviz</title><link>https://pornohardware.com/2014/09/18/diagramas-mapas-de-red-y-demas-graficas-estructuradas-con-graphviz/</link><description>&lt;p&gt;Hoy voy a hablar de &lt;a href="http://www.graphviz.org"&gt;Graphviz&lt;/a&gt;, un proyecto que tiene ya unos cuantos años, y que si has ido a la universidad seguramente ya conozcas (al parecer se usa en muchas de ellas).&lt;/p&gt;
&lt;p&gt;&lt;img class="right" src="/images/logos/logo_graphviz.png"/&gt;
Para los que no, es algo que os puede resultar muy util a la hora de hacer gráficas relacionales, mapas de red, diagramas de flujo y cualquier otro tipo de representación gráfica similar. Libre, gratuito, facil de usar, potente y se maneja desde la linea de comandos de Linux... es decir, que es uno de esos programas a los que solo les falta &lt;em&gt;tener tetas&lt;/em&gt; para ser perfecto...&lt;/p&gt;
&lt;p&gt;Graphviz permite generar imágenes (&lt;a href="http://es.wikipedia.org/wiki/Portable_Network_Graphics"&gt;PNG&lt;/a&gt;, &lt;a href="http://es.wikipedia.org/wiki/Scalable_Vector_Graphics"&gt;SVG&lt;/a&gt;, &lt;a href="http://es.wikipedia.org/wiki/Graphics_Interchange_Format"&gt;GIF&lt;/a&gt;, etc) a partir de los datos que definamos mediante texto plano en un archivo, y el resultado no tiene nada que envidiar a algunos de los mejores servicios &lt;em&gt;online&lt;/em&gt; de diseño de gráficas de éste tipo (como por ejemplo el genial &lt;a href="https://www.gliffy.com"&gt;Gliffy&lt;/a&gt;, que esta muy bien y es gratuito para un par de gráficas... pero cuando necesitas hacer más o usar opciones avanzadas, hay que pagar, y no es NADA barato).&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Thu, 18 Sep 2014 09:53:36 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2014-09-18:/2014/09/18/diagramas-mapas-de-red-y-demas-graficas-estructuradas-con-graphviz/</guid><category>Varios</category><category>Linux</category><category>Diseño gráfico</category></item><item><title>Instalación de Raspbian en la Raspberry Pi B+</title><link>https://pornohardware.com/2014/08/01/instalacion-de-raspbian-en-la-nueva-raspberry-pi-b-plus/</link><description>&lt;p&gt;&lt;img class="left" src="/images/logos/logo_raspberrypi.png"/&gt;
Si tuviera que decir uno de los &lt;em&gt;inventos&lt;/em&gt; que más posibilidades tiene de los últimos años, o el que más horas de diversión puede proporcionar a un coste verdaderamente asequible, sin duda uno de los primeros que se me pasaría por la cabeza sería la genial &lt;a href="http://www.raspberrypi.org/"&gt;Raspberry Pi&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Supongo que la mayoría de vosotros, consumidores habituales del &lt;em&gt;pornohardware&lt;/em&gt; más variado, obviamente conoceréis este increíble proyecto... pero para aquellos que hayan pasado los últimos años aislados en una cueva sin poder salir o en una isla desierta alimentándose únicamente de cocos y ostras y sin el más mínimo contacto con &lt;em&gt;la civilización&lt;/em&gt;, os comentaré a modo de resumen rápido que Raspberry Pi es un ordenador del tamaño de un paquete de tabaco, y que cuesta aproximadamente 35 € (dependiendo del sitio donde la compréis). Esta descripción debería ser suficiente como para que aquellos que no la conocíais sintáis en éste momento la necesidad de tocaros...&lt;/p&gt;
&lt;p&gt;A dia de hoy (salen nuevos modelos más potentes y con nuevas funcionalidades cada cierto tiempo) funciona con un procesador &lt;a href="http://es.wikipedia.org/wiki/Arquitectura_ARM"&gt;ARM&lt;/a&gt; a 700MHz (aunque se puede hacer &lt;a href="http://es.wikipedia.org/wiki/Overclock"&gt;&lt;em&gt;overclocking&lt;/em&gt;&lt;/a&gt; hasta los 1000MHz), por lo que se puede instalar cualquier distribución de Linux que soporte dicha arquitectura. En nuestro caso, y como no podía ser de otra manera, utilizaremos &lt;a href="http://www.raspbian.org"&gt;Raspbian&lt;/a&gt;: una &lt;em&gt;Debian adaptada a la Raspberry Pi&lt;/em&gt;.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Fri, 01 Aug 2014 23:35:44 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2014-08-01:/2014/08/01/instalacion-de-raspbian-en-la-nueva-raspberry-pi-b-plus/</guid><category>Varios</category><category>Raspberry PI</category></item><item><title>Feliz dia del Administrador de Sistemas!</title><link>https://pornohardware.com/2014/07/25/feliz-dia-del-administrador-de-sistemas/</link><description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Las organizaciones gastan millones de dólares en firewalls y dispositivos de seguridad, pero tiran el dinero porque ninguna de estas medidas cubren el eslabón más débil de la cadena de seguridad: la gente que usa y administra los ordenadores."&lt;/em&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;a href="http://es.wikipedia.org/wiki/Kevin_Mitnick"&gt;Kevin Mitnick&lt;/a&gt;. Hacker, cracker, phreaker, leyenda.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Y si no sabes de qué va éste post, échale un ojo a &lt;a href="http://sysadminday.com"&gt;http://sysadminday.com&lt;/a&gt; (o a su versión &lt;a href="http://www.diadeladministradordesistemas.com/"&gt;en español&lt;/a&gt;).&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Fri, 25 Jul 2014 10:49:55 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2014-07-25:/2014/07/25/feliz-dia-del-administrador-de-sistemas/</guid><category>Varios</category></item><item><title>Búsquedas por similitud de trigramas en PostgreSQL con pg_trgm</title><link>https://pornohardware.com/2014/07/23/busqueda-por-similitud-de-trigramas-en-postgresql-con-pg-trgm/</link><description>&lt;p&gt;&lt;a href="https://es.wikipedia.org/wiki/Oracle"&gt;Oracle&lt;/a&gt; es la leche, eso no creo que haya nadie que pueda negarlo.
Sin duda es una de las mejores (si no la mejor) bases de datos del mundo... pero por desgracia para el común de &lt;em&gt;vosotros&lt;/em&gt; los humanos, su código es privativo y su precio prohibitivo (&lt;em&gt;y juro que el pareado ha sido espontáneo!&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;Pero no desesperéis... no hace falta que recurráis a &lt;a href="https://www.microsoft.com/es-es/sql-server/"&gt;&lt;em&gt;soluciones&lt;/em&gt; inferiores&lt;/a&gt; ni nada parecido.
Gracias a &lt;a href="http://en.wikipedia.org/wiki/Lords_of_Kobol"&gt;los Dioses&lt;/a&gt; tenemos &lt;a href="http://www.postgresql.org/"&gt;PostgreSQL&lt;/a&gt;, aunque en éste artículo no vamos a hablar de éste genial motor de base de datos, sino de uno de los módulos adicionales que incorpora para realizar búsquedas basandose en la similitud entre los trigramas de una cadena: &lt;a href="http://www.postgresql.org/docs/current/static/pgtrgm.html"&gt;pg_trgm&lt;/a&gt;.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Wed, 23 Jul 2014 20:54:53 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2014-07-23:/2014/07/23/busqueda-por-similitud-de-trigramas-en-postgresql-con-pg-trgm/</guid><category>Varios</category><category>PostgreSQL</category><category>DB</category></item><item><title>Selección de plugins para Octopress</title><link>https://pornohardware.com/2014/07/12/seleccion-de-plugins-para-octopress/</link><description>&lt;p&gt;Ya sea a modo de &lt;em&gt;chuleta&lt;/em&gt; para mi mismo sobre los que utilizo en el blog, o bien por si a alguien le resulta útil, voy a escribir en éste artículo la lista de los mejores y más interesantes plugins para Octopress que he encontrado...&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Sat, 12 Jul 2014 02:29:36 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2014-07-12:/2014/07/12/seleccion-de-plugins-para-octopress/</guid><category>Varios</category><category>Blogs</category></item><item><title>Un paseo por el datacenter en el que vivo</title><link>https://pornohardware.com/2014/07/09/un-paseo-por-el-datacenter-en-el-que-vivo/</link><description>&lt;p&gt;Y no, no estoy hablando en sentido metafórico... hoy voy a enseñaros el &lt;em&gt;pequeño&lt;/em&gt; &lt;a href="https://es.wikipedia.org/wiki/Centro_de_procesamiento_de_datos"&gt;datacenter&lt;/a&gt; que tengo montado en mi casa, donde &lt;strike&gt;mis servidores&lt;/strike&gt; &lt;em&gt;mis niñas&lt;/em&gt; funcionan sin interrupción para dar servicio tanto a mis &lt;em&gt;frikadas&lt;/em&gt; como a algunas otras cosas un poco más serias.&lt;/p&gt;
&lt;p&gt;Y cuando digo &lt;em&gt;datacenter&lt;/em&gt; no me refiero a un par de ordenadores viejos sin monitor en una esquina del dormitorio, como teneis algunos (y vosotros os llamais &lt;em&gt;frikis&lt;/em&gt;? &lt;strong&gt;debería daros vergüenza!&lt;/strong&gt;), sino a varios racks con decenas de servidores, SAI's, cabinas de discos duros en RAID, switches redundantes y mil cosas más (como tenemos los &lt;em&gt;frikis&lt;/em&gt; de verdad... así que tomar nota!!) xDD&lt;/p&gt;
&lt;p&gt;Ha sido un proceso muy largo, y mentiría si dijera que ya ha terminado y que no voy a seguir &lt;em&gt;ampliando la infraestructura&lt;/em&gt; de mi datacenter... pero a dia de hoy (mediados de 2014) puedo decir que (por suerte para mi y por desgracia para mi mujer) una de las habitaciones de mi casa tiene ésta pinta:&lt;/p&gt;
&lt;p&gt;&lt;img class="center" src="/images/posts/datacenter/datacenter_current.jpg"/&gt;&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Wed, 09 Jul 2014 20:38:17 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2014-07-09:/2014/07/09/un-paseo-por-el-datacenter-en-el-que-vivo/</guid><category>Varios</category><category>Hardware</category><category>Personal</category></item><item><title>Markdown, el lenguaje de marcado para texto plano</title><link>https://pornohardware.com/2014/07/02/markdown-el-lenguaje-de-marcado-para-texto-plano/</link><description>&lt;p&gt;Cuando vosotros (&lt;em&gt;los humanos&lt;/em&gt;) necesitais formatear un texto de forma rápida y sencilla, y además teneis que hacerlo en texto plano, la mayoría intentará hacerlo con &lt;a href="http://es.wikipedia.org/wiki/HTML"&gt;HTML&lt;/a&gt; (si va a ser interpretado por un navegador web) o incluso con &lt;a href="http://es.wikipedia.org/wiki/Bbcode"&gt;BBCode&lt;/a&gt; (si se trata de un post en un foro)... y ambas opciones no estan mal, pero existe otra opción especialmente diseñada para ese fin, que muy pocos conocen y aún menos utilizan: el lenguaje de marcado web &lt;a href="https://es.wikipedia.org/wiki/Markdown"&gt;Markdown&lt;/a&gt;.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Wed, 02 Jul 2014 21:23:07 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2014-07-02:/2014/07/02/markdown-el-lenguaje-de-marcado-para-texto-plano/</guid><category>Varios</category><category>Blogs</category></item><item><title>Mejorando un poco el SEO de Octopress (o de cualquier web en general)</title><link>https://pornohardware.com/2014/06/26/mejorando-el-seo-de-octopress/</link><description>&lt;p&gt;Se entiende por &lt;em&gt;SEO&lt;/em&gt; (&lt;a href="http://es.wikipedia.org/wiki/Posicionamiento_en_motores_de_b%C3%BAsqueda"&gt;Search Engine Optimization&lt;/a&gt;) el proceso de mejora de la visibilidad de un sitio web en los resultados de un buscador. Es decir, aquellos mecanismos que utilizamos para que nuestra web aparezca mejor posicionada que las demás en las páginas de resultados de los buscadores.&lt;/p&gt;
&lt;p&gt;Hay todo un mundo detrás del SEO, donde la mayoría de las &lt;em&gt;pautas&lt;/em&gt; son generales para todos los buscadores, pero donde también se pueden encontrar comportamientos y formas de hacer las cosas únicamente para favorecer los resultados en un buscador en concreto. En cualquier caso, en éste artículo solo nos vamos a centrar en 3 cosas muy concretas que nuestro querido &lt;a href="http://www.octopress.org"&gt;Octopress&lt;/a&gt; no hace del todo bien, pero que bastan unos sencillos cambios para solucionarlo.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Thu, 26 Jun 2014 22:22:01 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2014-06-26:/2014/06/26/mejorando-el-seo-de-octopress/</guid><category>Varios</category><category>Octopress</category><category>SEO</category></item><item><title>Replicación de bases de datos PostgreSQL con Slony en CentOS</title><link>https://pornohardware.com/2014/06/24/replicacion-de-bases-de-datos-postgresql-con-slony-en-linux-centos/</link><description>&lt;p&gt;&lt;a href="http://www.slony.info"&gt;Slony1&lt;/a&gt; es un software para la replicación de datos entre servidores &lt;a href="http://www.postgresql.org"&gt;PostgreSQL&lt;/a&gt;, creando clusters formados por un nodo maestro y uno o varios nodos esclavos.&lt;/p&gt;
&lt;p&gt;&lt;img class="right" src="/images/logos/logo_slony.png"/&gt;
Aunque soy &lt;a href="http://www.debian.org"&gt;Debianita a muerte&lt;/a&gt;, muchas veces me veo obligado a usar otras distribuciones de Linux (sobre todo en el curro), como por ejemplo &lt;a href="http://www.centos.org"&gt;CentOS&lt;/a&gt;. Y puesto que éste artículo lo escribí hace ya varios años como &lt;em&gt;chuleta personal&lt;/em&gt; precisamente para el curro, está hecho sobre esa distribución... pero como casi siempre en éstos casos, debería ser perfectamente válido para cualquier otro Linux.&lt;/p&gt;
&lt;p&gt;Partimos de la base de que ya tenemos instalados y configurados los servidores de base de datos PostgreSQL en los nodos que vamos a usar.&lt;/p&gt;
&lt;p&gt;Es de vital importancia que todos los nodos que van a formar el cluster tengan la misma codificación. Es decir, si vamos a usar &lt;code&gt;UTF8&lt;/code&gt;, TODOS los servidores y bases de datos deben estar en &lt;code&gt;UTF8&lt;/code&gt;, y si vamos a usar &lt;code&gt;LATIN1&lt;/code&gt;, TODOS deben estar en &lt;code&gt;LATIN1&lt;/code&gt;. De lo contrario, al inicializar la replicación por primera vez, se comenzaran a copiar algunas tablas, y de repente el proceso parará y empezará de nuevo a copiar la primera tabla, y así sucesivamente en un bucle sin fin, sin que ningun log muestre ninguna pista al respecto, así que hay que tenerlo muy presente antes de empezar.&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Tue, 24 Jun 2014 23:02:38 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2014-06-24:/2014/06/24/replicacion-de-bases-de-datos-postgresql-con-slony-en-linux-centos/</guid><category>Varios</category><category>PostgreSQL</category><category>Slony</category><category>DB</category></item><item><title>Instalación y configuración de Octopress en Linux</title><link>https://pornohardware.com/2014/06/20/instalacion-y-configuracion-de-octopress-en-linux/</link><description>&lt;p&gt;&lt;img class="right" src="/images/logos/logo_octopress.png"/&gt;
Voy a intentar explicar de la forma más clara posible cómo instalar y configurar &lt;a href="http://octopress.org/"&gt;Octopress&lt;/a&gt;, un framework Open Source para construir blogs basados en el proyecto &lt;a href="https://github.com/jekyll/jekyll]"&gt;Jekyll&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Es un software muy potente que permite crear blogs totalmente estáticos, es decir, una vez configurado, basta con ejecutar un comando para que se nos genere en un directorio toda la escructura de archivos y directorios en texto plano (archivos HTML, JS y CSS) que necesitaremos para nuestro blog.&lt;/p&gt;
&lt;p&gt;Estos archivos estáticos estarían listos para servir a través de un servidor web cualquiera, sin necesidad de bases de datos, scripts o lenguajes de programación en el lado del servidor, lo que permite ahorrar muchos recursos, tiempo y por supuesto hardware. De hecho, una vez configurado, bastaría con ejecutar otro comando para que Octopress subiera éstos archivos a nuestro servidor de forma totalmente automática (deploy).&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Fri, 20 Jun 2014 20:33:02 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2014-06-20:/2014/06/20/instalacion-y-configuracion-de-octopress-en-linux/</guid><category>Varios</category><category>Blogs</category></item><item><title>Instalación de Sphinx en Debian y su librería de acceso desde PHP</title><link>https://pornohardware.com/2012/04/09/instalacion-de-sphinx-en-debian-y-su-libreria-de-acceso-desde-php/</link><description>&lt;p&gt;&lt;a href="http://sphinxsearch.com"&gt;Sphinx Search&lt;/a&gt; es un genial motor de búsqueda Open Source especialmente útil cuando tenemos muchos datos a los que tenemos que acceder de forma rápida.&lt;/p&gt;
&lt;p&gt;&lt;img class="left" src="/images/logos/logo_sphinx.png"/&gt;
Su principal virtud es la de crear unos índices conteniendo la información que nosotros le hayamos configurado, que pueden ser accedidos desde nuestros programas (C, PHP, etc) para recuperar la información mucho más rápido que si lo hiciéramos directamente a una base de datos (normalmente se usa como complemento de éstas, cuando la cantidad de información que tenemos en dicha base de datos es demasiado grande y sus propios índices no son todo lo efectivos que nos gustaría).
&lt;br/&gt;&lt;br/&gt;
&lt;strike&gt;A dia de hoy no existen paquetes precompilados para nuestra querida Debian, por lo que vamos a generarlos nosotros a partir de su código fuente.&lt;/strike&gt; Ya existen paquetes precompilados para las distribuciones de Linux más importantes, los cuales se pueden descargar desde: &lt;a href="http://sphinxsearch.com/downloads/release/"&gt;http://sphinxsearch.com/downloads/release/&lt;/a&gt;&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Mon, 09 Apr 2012 00:59:35 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2012-04-09:/2012/04/09/instalacion-de-sphinx-en-debian-y-su-libreria-de-acceso-desde-php/</guid><category>Varios</category><category>Linux</category><category>PHP</category><category>Programación</category></item><item><title>Instalacion y configuración de QNOTIFIER en Debian y CentOS</title><link>https://pornohardware.com/2009/06/11/instalacion-y-configuracion-de-qnotifier-en-debian-y-centos/</link><description>&lt;p&gt;QNotifier es una aplicación desarrollada en Ruby para monitorizar servidores desde un iPhone / iPad (con avisos push).&lt;/p&gt;
&lt;p&gt;Este manual explica la instalacion del servicio qnotifier en cada servidor que queramos monitorizar, por lo que partimos de la base de que ya tenemos la aplicación qnotifier instalada en el iPhone / Pad que vamos a utilizar (aplicación disponible en la App Store).&lt;/p&gt;
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">BhEaN</dc:creator><pubDate>Thu, 11 Jun 2009 11:39:06 +0200</pubDate><guid isPermaLink="false">tag:pornohardware.com,2009-06-11:/2009/06/11/instalacion-y-configuracion-de-qnotifier-en-debian-y-centos/</guid><category>Varios</category><category>Monitorización</category><category>Apps</category></item></channel></rss>