<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>The Ops Community ⚙️: jose luis pujol</title>
    <description>The latest articles on The Ops Community ⚙️ by jose luis pujol (@sosan).</description>
    <link>https://community.ops.io/sosan</link>
    <image>
      <url>https://community.ops.io/images/EBzBynCNM7819lGKR9Twp7y2F9FwFIzV04DZEhHy00o/rs:fill:90:90/g:sm/mb:500000/ar:1/aHR0cHM6Ly9jb21t/dW5pdHkub3BzLmlv/L3JlbW90ZWltYWdl/cy91cGxvYWRzL3Vz/ZXIvcHJvZmlsZV9p/bWFnZS8xNDYvMGNm/NzVhZGEtOWQ2OS00/OTY5LWJhMTctYjhh/OTEzNWNiMDc3Lmpw/Zw</url>
      <title>The Ops Community ⚙️: jose luis pujol</title>
      <link>https://community.ops.io/sosan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://community.ops.io/feed/sosan"/>
    <language>en</language>
    <item>
      <title>🔍📚 ¿Qué es eso de "Full Text Search" en PostgreSQL? ¡Te lo explicamos con flow!</title>
      <dc:creator>jose luis pujol</dc:creator>
      <pubDate>Fri, 14 Mar 2025 20:17:09 +0000</pubDate>
      <link>https://community.ops.io/sosan/que-es-eso-de-full-text-search-en-postgresql-te-lo-explicamos-con-flow-325g</link>
      <guid>https://community.ops.io/sosan/que-es-eso-de-full-text-search-en-postgresql-te-lo-explicamos-con-flow-325g</guid>
      <description>&lt;p&gt;¿Cansado de hacer búsquedas con &lt;code&gt;LIKE&lt;/code&gt; y que no encuentres ni el nombre de tu gato? 😿 Pues prepárate, porque llega la joya de la corona en el mundo de las búsquedas: ¡Full Text Search (FTS)! 🎯✨&lt;/p&gt;

&lt;p&gt;Full Text Search es ese superpoder que permite encontrar documentos o registros que contienen ciertas palabras o frases, aunque no coincidan exactamente con lo que escribiste 🙃. Es como decirle a PostgreSQL: “🧠 piensa un poco y búscame esto bien, no seas literal…”&lt;/p&gt;

&lt;p&gt;A diferencia de las búsquedas básicas (&lt;code&gt;LIKE '%algo%'&lt;/code&gt;), FTS tiene en cuenta:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧬 La morfología del lenguaje (sí, PostgreSQL no solo sabe SQL, también sabe idiomas 🤓).&lt;/li&gt;
&lt;li&gt;🕳️ Las palabras vacías (esas como “el”, “de”, “y”, que no aportan mucho pero siempre están) (stop words).&lt;/li&gt;
&lt;li&gt;🏆 La relevancia: ordena los resultados según qué tan bien encajan con lo que pediste, como un buen DJ ordenando temazos en una playlist 🎶.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Y lo mejor de todo… ¡esto ya viene incorporado en PostgreSQL! 🐘✨&lt;/p&gt;

&lt;p&gt;Incluye:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tipos de datos especiales (&lt;code&gt;tsvector&lt;/code&gt; y &lt;code&gt;tsquery&lt;/code&gt;) 🔠&lt;/li&gt;
&lt;li&gt;Funciones mágicas como &lt;code&gt;to_tsvector&lt;/code&gt;, &lt;code&gt;to_tsquery&lt;/code&gt;, &lt;code&gt;plainto_tsquery&lt;/code&gt; 🪄&lt;/li&gt;
&lt;li&gt;Y hasta índices GIN/GiST para que todo vaya como un cohete 🚀💨&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Perfecto para:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📝 Blogs&lt;/li&gt;
&lt;li&gt;🛍️ Tiendas online&lt;/li&gt;
&lt;li&gt;📂 Documentos&lt;/li&gt;
&lt;li&gt;Y cualquier proyecto donde buscar texto no sea un drama sino una experiencia ✨&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🏆 Componentes principales:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;📌 &lt;code&gt;tsvector&lt;/code&gt;: es una estructura que almacena el texto en forma de léxemas (tokens), teniendo en cuenta sus posiciones. Por ejemplo, el texto "PostgreSQL es la mejor base de datos" se transforma en: 'bas':5 'dat':7 'mejor':4 'postgresql':1. Es básicamente un diccionario indexado que contiene todas las palabras en su forma normalizada, excluyendo las llamadas palabras vacías (preposiciones, conjunciones, etc., según el idioma elegido).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;📌 &lt;code&gt;tsquery&lt;/code&gt;: representa la consulta de búsqueda que se comparan contra &lt;code&gt;tsvector&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;📌 Operador &lt;code&gt;@@&lt;/code&gt;: compara un tsvector con un tsquery para ver si hay coincidencia.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;📌 &lt;code&gt;ts_rank&lt;/code&gt;: calcula la relevancia de la coincidencia. Se puede usar para ordenar los resultados (ORDER BY rank DESC).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;📌 &lt;code&gt;ts_rank_cd&lt;/code&gt;: similar a ts_rank, pero también tiene en cuenta la densidad, es decir, cuán cerca están las palabras del término buscado dentro del texto. Es útil cuando importa que las palabras estén próximas entre sí.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para acelerar FTS(Full Text Search), se pueden usar los índices &lt;code&gt;GIN&lt;/code&gt; o &lt;code&gt;GiST&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  1️⃣ Configurar Full Text Search:
&lt;/h2&gt;

&lt;p&gt;Creamos una tabla con datos de texto:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;articles&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;article_id&lt;/span&gt; &lt;span class="nb"&gt;SERIAL&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;content_tsvector&lt;/span&gt; &lt;span class="n"&gt;TSVECTOR&lt;/span&gt;
    &lt;span class="n"&gt;publication_date&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;content_tsvector&lt;/code&gt; almacenará la versión procesada del contenido para búsquedas rápidas&lt;/p&gt;

&lt;p&gt;Datos de ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;articles&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;publication_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Introducción a PostgreSQL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'PostgreSQL es una base de datos relacional de código abierto, ideal para proyectos pequeños y grandes.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2024-12-15'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Guía avanzada de búsqueda de texto completo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'La búsqueda de texto completo permite encontrar información relevante en grandes volúmenes de texto.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2025-01-10'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'PostgreSQL y su integración con otras herramientas'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Descubre cómo PostgreSQL se integra con herramientas modernas de análisis y visualización.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2024-11-05'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Optimización de consultas SQL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Aprende a optimizar tus consultas SQL para mejorar el rendimiento en bases de datos grandes.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2023-09-01'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Toguapo y el mundo del desarrollo backend'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Toguapo comparte su experiencia con PostgreSQL y cómo mejorar el backend de tus aplicaciones.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2025-02-18'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Tutorial: Full Text Search con PostgreSQL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Este tutorial muestra paso a paso cómo implementar búsquedas rápidas y precisas usando FTS.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2025-01-20'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Comparativa entre Elasticsearch y PostgreSQL FTS'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Aunque PostgreSQL tiene FTS integrado, Elasticsearch ofrece más flexibilidad en algunos escenarios.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2023-12-01'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Cómo hacer búsquedas más precisas en contenido textual'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Usar ts_rank y ts_headline mejora la experiencia de búsqueda y permite ordenar por relevancia.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2024-06-11'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Gestión documental con PostgreSQL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Una solución práctica para gestionar documentos, aplicar búsquedas por texto y clasificar resultados.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2025-02-01'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Novedades en PostgreSQL 16'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'La versión 16 de PostgreSQL incluye mejoras en rendimiento, FTS y más funciones analíticas.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2024-10-10'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Viaje gastronómico por España'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Exploramos los sabores auténticos del norte de España, desde pintxos hasta mariscos.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2025-01-22'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Cómo cuidar tus plantas en casa'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Consejos prácticos para mantener tus plantas saludables todo el año.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2023-08-15'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Tendencias de moda 2025'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Descubre los colores, estilos y tejidos que marcarán tendencia este año.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2025-01-05'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Guía básica de fotografía para principiantes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Aprende sobre composición, luz y enfoque en tus primeras fotos.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2024-05-30'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rellenamos el &lt;code&gt;tsvector&lt;/code&gt; usando la función &lt;code&gt;to_tsvector&lt;/code&gt; que convierte texto a &lt;code&gt;tsvector&lt;/code&gt;, haciéndolo buscable.&lt;/p&gt;

&lt;p&gt;Ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;articles&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;content_tsvector&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;to_tsvector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'spanish'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Aquí, 'spanish' indica que se usa la morfología del idioma eh!pañol, procesa el contenido y lo convierte en un tsvector buscable.&lt;/p&gt;

&lt;p&gt;Para mejorar el rendimiento de búsqueda, creamos un índice &lt;code&gt;GIN&lt;/code&gt; sobre la columna tsvector.&lt;/p&gt;

&lt;p&gt;Ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_content_tsvector&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;articles&lt;/span&gt; &lt;span class="k"&gt;USING&lt;/span&gt; &lt;span class="n"&gt;gin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content_tsvector&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este índice mejora el rendimiento de las búsquedas, especialmente con grandes volúmenes de datos.&lt;/p&gt;

&lt;p&gt;¡Y listo! Ya podemos usar FTS en nuestra tabla 😁&lt;/p&gt;

&lt;h2&gt;
  
  
  Ejemplos de consultas
&lt;/h2&gt;

&lt;p&gt;✅ Buscar una palabra:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;articles&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;content_tsvector&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt; &lt;span class="n"&gt;to_tsquery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'spanish'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'postgresql'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta consulta busca el término "postgresql" en el campo &lt;code&gt;content_tsvector&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;✅ Buscar una frase&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;articles&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;content_tsvector&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt; &lt;span class="n"&gt;to_tsquery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'spanish'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'postgresql &amp;amp; toguapo'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este ejemplo busca artículos que contengan tanto "postgresql" como "toguapo".&lt;/p&gt;

&lt;p&gt;✅ Resaltar Resultados de Búsqueda:&lt;/p&gt;

&lt;p&gt;La función &lt;code&gt;ts_headline&lt;/code&gt; resalta los términos buscados en los resultados.&lt;/p&gt;

&lt;p&gt;Ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ts_headline&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'spanish'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;to_tsquery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'full &amp;amp; text &amp;amp; search'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;preview&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;articles&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;content_tsvector&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt; &lt;span class="n"&gt;to_tsquery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'spanish'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'full &amp;amp; text &amp;amp; search'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto resalta las ocurrencias de "full text search" en una vista previa del contenido.&lt;/p&gt;

&lt;p&gt;✅ Clasificar Resultados por Relevancia:&lt;/p&gt;

&lt;p&gt;Usa &lt;code&gt;ts_rank&lt;/code&gt; o &lt;code&gt;ts_rank_cd&lt;/code&gt; para clasificar los resultados según su relevancia con respecto a la consulta.&lt;/p&gt;

&lt;p&gt;Ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ts_rank&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;content_tsvector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;to_tsquery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'postgresql'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;rank&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;articles&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;content_tsvector&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt; &lt;span class="n"&gt;to_tsquery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'postgresql'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;rank&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto ordena los artículos según su relevancia con el término "postgresql".&lt;/p&gt;

&lt;p&gt;✅ Combinar Full Text Search con Filtros SQL:&lt;br&gt;
Puedes combinar búsqueda de texto completo con otras condiciones SQL.&lt;/p&gt;

&lt;p&gt;Ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;articles&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;content_tsvector&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt; &lt;span class="n"&gt;to_tsquery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'postgresql'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;publication_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'2025-01-01'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esto busca artículos que contengan "database" y que hayan sido publicados después del 1 de enero de 2025.&lt;/p&gt;

&lt;p&gt;✅ Búsqueda de Frases con &lt;code&gt;plainto_tsquery&lt;/code&gt;:&lt;br&gt;
Si deseas que un término de búsqueda sea tratado como una frase completa, plainto_tsquery lo convierte en un tsquery.&lt;/p&gt;

&lt;p&gt;Ejemplo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;articles&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;content_tsvector&lt;/span&gt; &lt;span class="o"&gt;@@&lt;/span&gt; &lt;span class="n"&gt;plainto_tsquery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'spanish'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'full text search'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Esta consulta busca la frase exacta "full text search".&lt;/p&gt;

&lt;p&gt;✅ Agregar Triggers para Actualización Automática:&lt;/p&gt;

&lt;p&gt;Para mantener content_tsvector actualizado al cambiar el contenido, se puede usar un trigger.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;FUNCTION&lt;/span&gt; &lt;span class="n"&gt;update_tsvector&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;RETURNS&lt;/span&gt; &lt;span class="k"&gt;TRIGGER&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="err"&gt;$$&lt;/span&gt;
&lt;span class="k"&gt;BEGIN&lt;/span&gt;
    &lt;span class="k"&gt;NEW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content_tsvector&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;to_tsvector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'spanish'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;NEW&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;RETURN&lt;/span&gt; &lt;span class="k"&gt;NEW&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;$$&lt;/span&gt; &lt;span class="k"&gt;LANGUAGE&lt;/span&gt; &lt;span class="n"&gt;plpgsql&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TRIGGER&lt;/span&gt; &lt;span class="n"&gt;tsvectorupdate&lt;/span&gt; 
&lt;span class="k"&gt;BEFORE&lt;/span&gt; &lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;articles&lt;/span&gt; 
&lt;span class="k"&gt;FOR&lt;/span&gt; &lt;span class="k"&gt;EACH&lt;/span&gt; &lt;span class="k"&gt;ROW&lt;/span&gt; &lt;span class="k"&gt;EXECUTE&lt;/span&gt; &lt;span class="k"&gt;FUNCTION&lt;/span&gt; &lt;span class="n"&gt;update_tsvector&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Este trigger actualiza automáticamente &lt;code&gt;content_tsvector&lt;/code&gt; cuando el contenido cambia.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>español</category>
      <category>postgresql</category>
    </item>
    <item>
      <title>Debug nodos kubernetes</title>
      <dc:creator>jose luis pujol</dc:creator>
      <pubDate>Mon, 01 Jan 2024 00:19:21 +0000</pubDate>
      <link>https://community.ops.io/sosan/debug-nodos-kubernetes-e8h</link>
      <guid>https://community.ops.io/sosan/debug-nodos-kubernetes-e8h</guid>
      <description>&lt;p&gt;Los nodos son un componente vital de un clúster de Kubernetes y son responsables de ejecutar las pods. Dependiendo de la configuración de tu clúster, un nodo puede ser una máquina física o virtual. &lt;br&gt;
Un clúster típicamente tiene uno o varios nodos, los cuales son gestionados por el &lt;code&gt;control plane&lt;/code&gt;.&lt;br&gt;
Debido a que los nodos realizan la mayor parte del trabajo de la gestión de carga, es importante asegurarse de que todos tus nodos estén funcionando correctamente. El comando &lt;code&gt;kubectl get nodes&lt;/code&gt; se utiliza para verificar el estado de tus nodos.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME           STATUS   ROLES           AGE     VERSION
controlplane   Ready    control-plane   2d11h   v1.29.0
node01         Ready    &amp;lt;none&amp;gt;          2d10h   v1.29.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Un nodo con un estado &lt;code&gt;NotReady&lt;/code&gt; significa que no se puede utilizar para ejecutar una pod debido a un problema interno.&lt;br&gt;
Posibles razones por las cuales un nodo puede entrar en el estado NotReady y cómo depurarlo.&lt;/p&gt;
&lt;h2&gt;
  
  
  Estados
&lt;/h2&gt;

&lt;p&gt;Antes de programar un pod en un nodo, Kubernetes verifica si el nodo es capaz de ejecutar la pod o no. La columna STATUS en la salida de &lt;code&gt;kubectl get nodes&lt;/code&gt; representa el estado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME           STATUS   ROLES           AGE     VERSION
controlplane   Ready    control-plane   2d10h   v1.29.0
node01         Ready    &amp;lt;none&amp;gt;          2d10h   v1.29.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Los posibles valores en &lt;code&gt;STATUS&lt;/code&gt; son:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Ready&lt;/code&gt;: El nodo está listo para aceptar pods.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;NotReady&lt;/code&gt;: El nodo ha encontrado algún problema y no se puede programar un pod en él.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SchedulingDisabled&lt;/code&gt;: El nodo está marcado como no programable. Esta marca se puede realizar mediante el comando &lt;code&gt;kubectl cordon&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Unknown&lt;/code&gt;: El nodo no es alcanzable por el &lt;code&gt;control plane&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tener un nodo en estado &lt;code&gt;NotReady&lt;/code&gt; significa que el nodo está sin usar y sin participar en la ejecución de pods. &lt;/p&gt;

&lt;p&gt;Posibles causas del estado &lt;code&gt;NotReady&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Escasez de recursos&lt;/strong&gt;. Para operar normalmente, un nodo debe tener suficiente espacio en disco, memoria y capacidad de procesamiento. Si un nodo tiene poco espacio en disco o la memoria disponible es baja, entrará en el estado &lt;code&gt;NotReady&lt;/code&gt;. Si hay demasiados procesos ejecutándose en el nodo, también cambiará al estado "NotReady".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuración de red incorrecta&lt;/strong&gt;. Si la red no se ha configurado correctamente en el nodo, el nodo no podrá comunicarse con el nodo maestro y se mostrará como &lt;code&gt;NotReady&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Problemas con el proceso &lt;code&gt;kubelet&lt;/code&gt;&lt;/strong&gt;. Kubelet es un componente esencial de Kubernetes y opera en cada nodo del clúster como un agente. Su papel principal es servir de enlace entre el nodo y la API de Kubernetes. &lt;code&gt;Kubelet&lt;/code&gt; informa a la API de Kubernetes sobre el estado del nodo, incluyendo detalles como los recursos disponibles y la salud general del nodo. Además, &lt;code&gt;Kubelet&lt;/code&gt; registra el nodo en el clúster de Kubernetes, permitiendo que el nodo sea reconocido y utilizado para desplegar aplicaciones. Si &lt;code&gt;Kubelet&lt;/code&gt; se bloquea o se detiene por alguna razón, su comunicación con la API de Kubernetes se interrumpe. Esto impide que el nodo informe de su estado y reciba instrucciones de la API. Como resultado, el nodo se marca con el estado &lt;code&gt;NotReady&lt;/code&gt;, lo que indica que NO está preparado para recibir nuevas cargas de trabajo hasta que se resuelva el problema de &lt;code&gt;Kubelet&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Problemas con Kube-proxy&lt;/strong&gt;. Kube-proxy es un componente de Kubernetes y opera en cada nodo como un proxy. Mantiene las reglas de red que facilitan la comunicación con los pods, tanto interna como externamente. Si &lt;code&gt;kube-proxy&lt;/code&gt; se bloquea o se detiene, el nodo se marca como &lt;code&gt;NotReady&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Problemas específicos del proveedor cloud&lt;/strong&gt;. Supongamos que estás utilizando una solución alojada en la nube como GKE, EKS, AKS, .... En ese caso, algunos problemas específicos del proveedor pueden estar impidiendo que tus nodos funcionen normalmente y se comuniquen con el &lt;code&gt;control plane&lt;/code&gt;. Estos problemas podrían ser por una configuración incorrecta de IAM, por reglas de red mal configuradas, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Debug del estado &lt;code&gt;NotReady&lt;/code&gt; mas detallado
&lt;/h2&gt;

&lt;p&gt;El estado &lt;code&gt;NotReady&lt;/code&gt; puede ser causado por una multitud de problemas. Es esencial entender que la forma de solucionar estos problemas depende de la causa exacta y de la configuración del clúster. &lt;br&gt;
No hay soluciones universales. Pero, una vez que identifiques la causa raíz, debería ser más fácil resolverla.&lt;/p&gt;
&lt;h3&gt;
  
  
  Problemas Kube-Proxy
&lt;/h3&gt;

&lt;p&gt;Asegúrate que cada nodo tenga un pod &lt;code&gt;kube-proxy&lt;/code&gt; y esté en el estado "Running".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pods -n kube-system -o wide
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;resultado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME                                      READY   STATUS    RESTARTS        AGE     IP            NODE           NOMINATED NODE   READINESS GATES
calico-kube-controllers-9d57d8f49-8smt7   1/1     Running   3 (4h30m ago)   2d10h   192.168.0.2   controlplane   &amp;lt;none&amp;gt;           &amp;lt;none&amp;gt;
canal-mpvd7                               2/2     Running   2 (4h30m ago)   2d10h   172.30.2.2    node01         &amp;lt;none&amp;gt;           &amp;lt;none&amp;gt;
canal-t59ms                               2/2     Running   2 (4h30m ago)   2d10h   172.30.1.2    controlplane   &amp;lt;none&amp;gt;           &amp;lt;none&amp;gt;
coredns-86b698fbb6-7dhfx                  1/1     Running   1 (4h30m ago)   2d10h   192.168.1.2   node01         &amp;lt;none&amp;gt;           &amp;lt;none&amp;gt;
coredns-86b698fbb6-c7h4v                  1/1     Running   1 (4h30m ago)   2d10h   192.168.1.3   node01         &amp;lt;none&amp;gt;           &amp;lt;none&amp;gt;
etcd-controlplane                         1/1     Running   2 (4h30m ago)   2d10h   172.30.1.2    controlplane   &amp;lt;none&amp;gt;           &amp;lt;none&amp;gt;
kube-apiserver-controlplane               1/1     Running   2 (4h30m ago)   2d10h   172.30.1.2    controlplane   &amp;lt;none&amp;gt;           &amp;lt;none&amp;gt;
kube-controller-manager-controlplane      1/1     Running   2 (4h30m ago)   2d10h   172.30.1.2    controlplane   &amp;lt;none&amp;gt;           &amp;lt;none&amp;gt;
kube-proxy-4rlmh                          1/1     Running   2 (4h30m ago)   2d10h   172.30.1.2    controlplane   &amp;lt;none&amp;gt;           &amp;lt;none&amp;gt;
kube-proxy-8whxf                          1/1     Running   1 (4h30m ago)   2d10h   172.30.2.2    node01         &amp;lt;none&amp;gt;           &amp;lt;none&amp;gt;
kube-scheduler-controlplane               1/1     Running   2 (4h30m ago)   2d10h   172.30.1.2    controlplane   &amp;lt;none&amp;gt;           &amp;lt;none&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;o más especifico para todos los kubeproxy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl get pods -n kube-system -o wide | grep kube-proxy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME                                      READY   STATUS    RESTARTS        AGE     IP            NODE           NOMINATED NODE   READINESS GATES
kube-proxy-4rlmh                          1/1     Running   2 (4h31m ago)   2d10h   172.30.1.2    controlplane   &amp;lt;none&amp;gt;           &amp;lt;none&amp;gt;
kube-proxy-8whxf                          1/1     Running   1 (4h31m ago)   2d10h   172.30.2.2    node01         &amp;lt;none&amp;gt;           &amp;lt;none&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si alguno de los pods &lt;code&gt;kube-proxy&lt;/code&gt; se encuentra en un estado diferente a &lt;code&gt;Running&lt;/code&gt;, utiliza el siguiente comando para obtener más información:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl describe pod POD_KUBEPROXY_EN_ESTADO_NO_RUNNING -n kube-system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;La sección de "Events" registra diversos eventos en el pod, y podría ser un excelente lugar para comenzar a buscar cualquier inconveniente.&lt;/p&gt;

&lt;p&gt;Puedes acceder a los logs del pod ejecutando el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl logs POD_KUBEPROXY_EN_ESTADO_NO_RUNNING -n kube-system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si el nodo que no esta &lt;code&gt;Ready&lt;/code&gt; NO tiene pod &lt;code&gt;kube-proxy&lt;/code&gt;, entonces debes inspeccionar el daemonset &lt;code&gt;kube-proxy&lt;/code&gt;.&lt;br&gt;
Un &lt;code&gt;daemonset&lt;/code&gt; es una forma de asegurar que todos los nodos en un clúster tengan una copia de un pod corriendo, el &lt;code&gt;daemonset&lt;/code&gt; se encarga automáticamente de asegurar que haya una copia de ese pod en cada nodo del clúster.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl describe daemonset kube-proxy -n kube-system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;resultado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Name:           kube-proxy
Selector:       k8s-app=kube-proxy
Node-Selector:  kubernetes.io/os=linux
Labels:         k8s-app=kube-proxy
Annotations:    deprecated.daemonset.template.generation: 1
Desired Number of Nodes Scheduled: 2
Current Number of Nodes Scheduled: 2
Number of Nodes Scheduled with Up-to-date Pods: 2
Number of Nodes Scheduled with Available Pods: 2
Number of Nodes Misscheduled: 0
Pods Status:  2 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:           k8s-app=kube-proxy
  Service Account:  kube-proxy
  Containers:
   kube-proxy:
    Image:      registry.k8s.io/kube-proxy:v1.29.0
    Port:       &amp;lt;none&amp;gt;
    Host Port:  &amp;lt;none&amp;gt;
    Command:
      /usr/local/bin/kube-proxy
      --config=/var/lib/kube-proxy/config.conf
      --hostname-override=$(NODE_NAME)
    Environment:
      NODE_NAME:   (v1:spec.nodeName)
    Mounts:
      /lib/modules from lib-modules (ro)
      /run/xtables.lock from xtables-lock (rw)
      /var/lib/kube-proxy from kube-proxy (rw)
  Volumes:
   kube-proxy:
    Type:      ConfigMap (a volume populated by a ConfigMap)
    Name:      kube-proxy
    Optional:  false
   xtables-lock:
    Type:          HostPath (bare host directory volume)
    Path:          /run/xtables.lock
    HostPathType:  FileOrCreate
   lib-modules:
    Type:               HostPath (bare host directory volume)
    Path:               /lib/modules
    HostPathType:       
  Priority Class Name:  system-node-critical
Events:                 &amp;lt;none&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Problemas Recursos
&lt;/h3&gt;

&lt;p&gt;El siguiente comando sirve para obtener información detallada sobre un nodo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl describe node NODO_NOT_READY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;resultado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Name:               node01
Roles:              &amp;lt;none&amp;gt;
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=node01
                    kubernetes.io/os=linux
Annotations:        flannel.alpha.coreos.com/backend-data: {"VNI":1,"VtepMAC":"f6:5a:70:e7:20:39"}
                    flannel.alpha.coreos.com/backend-type: vxlan
                    flannel.alpha.coreos.com/kube-subnet-manager: true
                    flannel.alpha.coreos.com/public-ip: 172.30.2.2
                    kubeadm.alpha.kubernetes.io/cri-socket: unix:///var/run/containerd/containerd.sock
                    node.alpha.kubernetes.io/ttl: 0
                    projectcalico.org/IPv4Address: 172.30.2.2/24
                    projectcalico.org/IPv4IPIPTunnelAddr: 192.168.1.1
                    volumes.kubernetes.io/controller-managed-attach-detach: true
[...]
Conditions:
  Type                 Status  LastHeartbeatTime                 LastTransitionTime                Reason                       Message
  ----                 ------  -----------------                 ------------------                ------                       -------
  NetworkUnavailable   False   Sun, 31 Dec 2023 18:57:52 +0000   Sun, 31 Dec 2023 18:57:52 +0000   FlannelIsUp                  Flannel is running on this node
  MemoryPressure       False   Sun, 31 Dec 2023 23:37:39 +0000   Fri, 29 Dec 2023 13:10:41 +0000   KubeletHasSufficientMemory   kubelet has sufficient memory available
  DiskPressure         False   Sun, 31 Dec 2023 23:37:39 +0000   Fri, 29 Dec 2023 13:10:41 +0000   KubeletHasNoDiskPressure     kubelet has no disk pressure
  PIDPressure          False   Sun, 31 Dec 2023 23:37:39 +0000   Fri, 29 Dec 2023 13:10:41 +0000   KubeletHasSufficientPID      kubelet has sufficient PID available
  Ready                True    Sun, 31 Dec 2023 23:37:39 +0000   Fri, 29 Dec 2023 13:10:50 +0000   KubeletReady                 kubelet is posting ready status. AppArmor enabled
Addresses:
  InternalIP:  172.30.2.2
  Hostname:    node01
Capacity:
  cpu:                1
  ephemeral-storage:  20134592Ki
  hugepages-2Mi:      0
  memory:             2030940Ki
  pods:               110
Allocatable:
  cpu:                1
  ephemeral-storage:  19586931083
  hugepages-2Mi:      0
  memory:             1928540Ki
  pods:               110
System Info:
  Machine ID:                 388a2d0f867a4404bc12a0093bd9ed8d
  System UUID:                1d3e87e7-ec41-400e-9e8a-9fbba2d3adc8
  Boot ID:                    0f813b78-e5d3-4cca-b969-763745e13991
  Kernel Version:             5.4.0-131-generic
  OS Image:                   Ubuntu 20.04.5 LTS
  Operating System:           linux
  Architecture:               amd64
  Container Runtime Version:  containerd://1.6.12
  Kubelet Version:            v1.29.0
  Kube-Proxy Version:         v1.29.0
PodCIDR:                      192.168.1.0/24
PodCIDRs:                     192.168.1.0/24
Non-terminated Pods:          (4 in total)
  Namespace                   Name                        CPU Requests  CPU Limits  Memory Requests  Memory Limits  Age
  ---------                   ----                        ------------  ----------  ---------------  -------------  ---
  kube-system                 canal-mpvd7                 25m (2%)      0 (0%)      0 (0%)           0 (0%)         2d10h
  kube-system                 coredns-86b698fbb6-7dhfx    50m (5%)      0 (0%)      50Mi (2%)        170Mi (9%)     2d10h
  kube-system                 coredns-86b698fbb6-c7h4v    50m (5%)      0 (0%)      50Mi (2%)        170Mi (9%)     2d10h
  kube-system                 kube-proxy-8whxf            0 (0%)        0 (0%)      0 (0%)           0 (0%)         2d10h
Allocated resources:
  (Total limits may be over 100 percent, i.e., overcommitted.)
  Resource           Requests    Limits
  --------           --------    ------
  cpu                125m (12%)  0 (0%)
  memory             100Mi (5%)  340Mi (18%)
  ephemeral-storage  0 (0%)      0 (0%)
  hugepages-2Mi      0 (0%)      0 (0%)
Events:              &amp;lt;none&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En la sección &lt;code&gt;Conditions&lt;/code&gt; muestra si el nodo se está quedando sin recursos o no. Posibles estados:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MemoryPressure: Si es Verdadero, indica que el nodo se está quedando sin memoria.&lt;/li&gt;
&lt;li&gt;DiskPressure: Si es Verdadero, indica que al nodo le falta espacio.&lt;/li&gt;
&lt;li&gt;PIDPressure: Si es Verdadero, indica que hay demasiados procesos en ejecución en el nodo.&lt;/li&gt;
&lt;li&gt;NetworkUnavailable: Si es Verdadero, indica que la red del nodo no está configurada correctamente.&lt;/li&gt;
&lt;li&gt;Ready: Un valor Falso en este campo es equivalente al estado &lt;code&gt;NotReady&lt;/code&gt;. Si el controlador del nodo no ha tenido noticias del &lt;code&gt;node-monitor-grace-period&lt;/code&gt; (por defecto, 40 segundos), el valor será &lt;code&gt;Unknown&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Si alguna de las primeras cuatro condiciones es Verdadera, habrás identificado el problema.&lt;/p&gt;

&lt;h3&gt;
  
  
  Problemas Kubelet
&lt;/h3&gt;

&lt;p&gt;Si todos los campos de &lt;code&gt;Conditions&lt;/code&gt; estan en &lt;code&gt;Unknown&lt;/code&gt;, podría indicar que &lt;code&gt;kubelet&lt;/code&gt; esta caido.&lt;/p&gt;

&lt;p&gt;Para realizar debug, primero accede por SSH al nodo y verifica el estado del proceso kubelet.&lt;br&gt;
Si se está ejecutando como un servicio de systemd, utiliza el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;systemctl status kubelet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;resultado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;● kubelet.service - kubelet: The Kubernetes Node Agent
     Loaded: loaded (/lib/systemd/system/kubelet.service; enabled; vendor preset: enabled)
    Drop-In: /usr/lib/systemd/system/kubelet.service.d
             └─10-kubeadm.conf
     Active: active (running) since Sun 2023-12-31 18:56:43 UTC; 4h 48min ago
       Docs: https://kubernetes.io/docs/
   Main PID: 1650 (kubelet)
      Tasks: 11 (limit: 2338)
     Memory: 61.6M
     CGroup: /system.slice/kubelet.service
             └─1650 /usr/bin/kubelet --bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --config=/var/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si el campo &lt;code&gt;Active&lt;/code&gt; muestra "inactive (dead)", significa que el proceso kubelet se ha detenido.&lt;/p&gt;

&lt;p&gt;Para descubrir la posible razón del fallo, verifica los logs con el siguiente comando:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;journalctl -u kubelet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Una vez que has realizado fix, reinicia el kubelet con:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;systemctl restart kubelet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Problemas conectividad
&lt;/h3&gt;

&lt;p&gt;Si &lt;code&gt;Conditions&lt;/code&gt; muestra &lt;code&gt;NetworkUnavailable&lt;/code&gt;, indica un problema en la comunicación de red entre el nodo y la API Kubernetes.&lt;/p&gt;

&lt;p&gt;Algunas posibles soluciones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Si el nodo está configurado para usar un proxy, verifica que el proxy permita el acceso a los endpoints de la API Kubernetes.&lt;/li&gt;
&lt;li&gt;Asegúrate de que las tablas de enrutamiento estén configuradas adecuadamente para evitar bloquear la comunicación con la API Kubernetes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Para obtener la dirección de la API, ejecuta:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl cluster-info
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;resultado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Kubernetes control plane is running at https://172.30.1.2:6443
CoreDNS is running at https://172.30.1.2:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Puedes ejecutar el siguiente comando desde dentro del nodo para verificar que pueda alcanzar el servidor API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nc -vz IP_CONTROL_PLANE_O_ENDPOINT PUERTO
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;resultado:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connection to 172.30.1.2 6443 port [tcp/*] succeeded!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si el resultado es &lt;code&gt;succeeded&lt;/code&gt;, la comunicacion de red funciona correctamente.&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>español</category>
    </item>
    <item>
      <title>Despliegue Kubernetes cluster y LoadBalancer en DO con terraform desde github self-runner</title>
      <dc:creator>jose luis pujol</dc:creator>
      <pubDate>Mon, 27 Jun 2022 09:55:00 +0000</pubDate>
      <link>https://community.ops.io/sosan/despliegue-kubernetes-cluster-y-loadbalancer-en-do-con-terraform-desde-github-self-runner-399h</link>
      <guid>https://community.ops.io/sosan/despliegue-kubernetes-cluster-y-loadbalancer-en-do-con-terraform-desde-github-self-runner-399h</guid>
      <description>&lt;ul&gt;
&lt;li&gt;diferentes runners segun el entorno: &lt;a href="https://jonico.github.io/awesome-runners/"&gt;https://jonico.github.io/awesome-runners/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;aspectos de seguridad: &lt;a href="https://github.com/dduzgun-security/github-self-hosted-runners"&gt;https://github.com/dduzgun-security/github-self-hosted-runners&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Link directo a los runners:&lt;br&gt;
&lt;a href="https://github.com/sosan/TU_REPO/actions/runners"&gt;https://github.com/sosan/TU_REPO/actions/runners&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Esta en Settings -&amp;gt; Actions/Runners&lt;/p&gt;

&lt;p&gt;click boton New self hosted runner&lt;br&gt;
copiamos el token del self runner AAPYBGPKXXXQ3UMKEO5QECBGxXXXXXXXXC3CXCH4I(ejemplo)&lt;/p&gt;

&lt;p&gt;En el vps, tenemos montado un docker sin rootless (TODO: rootless)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NOTA: si seguimos las instrucciones del github, se ejecutara un runner, y cuando queramos borrarlo podemos ir al github y click boton borrar y se borraran los servicios del vps referentes al github runner&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;usando imagen &lt;a href="https://hub.docker.com/r/myoung34/github-runner"&gt;https://hub.docker.com/r/myoung34/github-runner&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Config basica runner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -d --restart always --name github-runner \
  -e REPO_URL="https://github.com/sosan/github-self-runner-digitalocean" \
  -e RUNNER_NAME="linux-terraform" \
  -e RUNNER_TOKEN="AAPYBGPKQXXXXXXX3UMKEO5QECBGC3CXCH4I" \
  -e RUNNER_WORKDIR="/tmp/github-self-runner-digitalocean" \
  -v /tmp/github-self-runner-digitalocean:/tmp/github-self-runner-digitalocean \
  -v /var/run/docker.sock:/var/run/docker.sock \
  myoung34/github-runner:latest 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker logs github-runner
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;muestra:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Authentication
√ Connected to GitHub
# Runner Registration
√ Runner successfully added
√ Runner connection is good
# Runner settings
√ Settings Saved.
√ Connected to GitHub
Current runner version: '2.294.0'
2022-06-26 15:58:21Z: Listening for Jobs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;en el github seccion actions/runners tendria que poner idle&lt;/p&gt;

&lt;p&gt;mas info:&lt;br&gt;
&lt;a href="https://docs.github.com/en/actions/hosting-your-own-runners/adding-self-hosted-runners#adding-a-self-hosted-runner-to-a-repository"&gt;https://docs.github.com/en/actions/hosting-your-own-runners/adding-self-hosted-runners#adding-a-self-hosted-runner-to-a-repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Desde github añadimos un token llamado: &lt;code&gt;DIGITALOCEAN_ACCESS_TOKEN&lt;/code&gt; con el PAT de digitalocean&lt;/p&gt;

&lt;p&gt;DIGITALOCEAN_ACCESS_TOKEN=dop_v1_d8eeed703665XXXXXXXXXXX18d0021319XXXXXXXXX(ejemplo)&lt;/p&gt;

&lt;p&gt;Imagen despliegue:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://community.ops.io/images/6e8v5dbUXOqUmlYQs_dCMwU8hPf9Ggp8YWxRrAccQTw/w:880/mb:500000/ar:1/aHR0cHM6Ly9naXRo/dWIuY29tL3Nvc2Fu/L2dpdGh1Yi1zZWxm/LXJ1bm5lci1kaWdp/dGFsb2NlYW4vcmF3/L21haW4vZG9fY2Fw/dHVyYS5wbmc" class="article-body-image-wrapper"&gt;&lt;img src="https://community.ops.io/images/6e8v5dbUXOqUmlYQs_dCMwU8hPf9Ggp8YWxRrAccQTw/w:880/mb:500000/ar:1/aHR0cHM6Ly9naXRo/dWIuY29tL3Nvc2Fu/L2dpdGh1Yi1zZWxm/LXJ1bm5lci1kaWdp/dGFsb2NlYW4vcmF3/L21haW4vZG9fY2Fw/dHVyYS5wbmc" alt="imagen" width="880" height="231"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mejoras TODO:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Despligue desde merge-pull-request&lt;/li&gt;
&lt;li&gt;Rootless docker&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Codigo fuente:&lt;br&gt;
&lt;a href="https://github.com/sosan/github-self-runner-digitalocean"&gt;https://github.com/sosan/github-self-runner-digitalocean&lt;/a&gt;&lt;/p&gt;

</description>
      <category>digitalocean</category>
      <category>terraform</category>
      <category>español</category>
    </item>
  </channel>
</rss>
