<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>beething</title><generator>teletype.in</generator><description><![CDATA[beething]]></description><image><url>https://img4.teletype.in/files/fc/b1/fcb171ae-3159-4708-8971-01b8d8fd330b.png</url><title>beething</title><link>https://teletype.in/@beething</link></image><link>https://teletype.in/@beething?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beething</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/beething?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/beething?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Thu, 16 Apr 2026 05:49:48 GMT</pubDate><lastBuildDate>Thu, 16 Apr 2026 05:49:48 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@beething/obiWlwK-PcM</guid><link>https://teletype.in/@beething/obiWlwK-PcM?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beething</link><comments>https://teletype.in/@beething/obiWlwK-PcM?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=beething#comments</comments><dc:creator>beething</dc:creator><title>HAQQ. Kubernetes guide</title><pubDate>Tue, 23 Aug 2022 20:24:36 GMT</pubDate><media:content medium="image" url="https://img4.teletype.in/files/37/31/3731af29-ed48-4f30-8447-25083925ee52.png"></media:content><description><![CDATA[<img src="https://img2.teletype.in/files/d1/42/d1428429-bbda-49af-a11a-675cfc425246.png"></img>Hi !]]></description><content:encoded><![CDATA[
  <p id="nryp">Hi !</p>
  <p id="kCjx">Сегодня мы рассмотрим установку и настройку валидатора для проекта haqq.</p>
  <p id="jW7t">Это будет не типичный гайд с набором однострочников, копипастом которых вы сможете развернуть валидатора.<br />Однако из данного гайда вы сможете немного попрактиковаться в разворачивании проекта в kubernetes.<br />Cтоит понимать что наш гайд не будет затрагивать множества тонкостей и предполагает наличия базовых знаний по контейнерам (docker)<br />За время инсталляции, нам придётся пройтись по следующим основным шагам</p>
  <ol id="4swm">
    <li id="bmzV"><a href="#xcmH">Развертывание kubernetes кластера в облачном провайдер при помощи terraform.</a></li>
    <li id="A6V0"><a href="#vuiZ">Развертывание приложения.</a></li>
    <li id="d6kQ"><a href="#UMvW">Запуск валидатора</a></li>
    <li id="UH0O"><a href="#yxVa">Удаление кластера</a></li>
  </ol>
  <p id="qCzm">И хотя существенная часть шагов будет специфична для проекта, адаптировать полученный опыт вы сможете и для множества других ваших проектов.</p>
  <p id="oUf0"></p>
  <h3 id="tLkt">Подготовка</h3>
  <p id="3m4B">Мы будем разворачивать наш кластер в европейском провайдере scaleway<br />Для начала нам потребуется скачать и установить terraform<br />Сделать это вы можете практически на любой операционной системе.<br />Здесь можно найти официальный урок, как это делается<br /><a href="https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started" target="_blank">https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started</a></p>
  <p id="jFFk">Мы в качестве примера будем использовать ручную установку для macos/linux.</p>
  <ol id="PULk">
    <li id="ajgM">Переходим на страницу загрузки https://www.terraform.io/downloads</li>
    <li id="EYE2">Выбираем операционную систему и архитектуру, и скачиваем версию.</li>
    <li id="tUhN">Копируем скачаный файл в директорию /usr/local/bin<br /><br /><code>mv ~/Downloads/terraform /usr/local/bin</code></li>
    <li id="OtG3">Добавляем права на запуск<br /><br /><code>chmod 755 /usr/local/bin/terraform</code></li>
    <li id="eKOl">Проверяем что наш скачанный бинарник запускается, и показывает версию<br /><br /><code>terraform version</code></li>
  </ol>
  <p id="MDpV"></p>
  <h3 id="xcmH">Развертывание kubernetes кластера</h3>
  <p id="0yTf">В качестве оператора k8s мы возьмём облачного провайдера scaleway<br />Он отличается довольно демократичными ценами, среди тех операторов которые предоставляют услугу k8s как сервис.</p>
  <p id="DMUx">Для начала создадим директорию в которой будет храниться вся наша конфигурация.</p>
  <pre id="DvJ2" data-lang="bash">mkdir haqq-tf
cd haqq-tf</pre>
  <p id="k4wA">Далее, мы всегда будем работать внутри этой директории</p>
  <p id="2Y1l">Для начала нам нужно подключить модуль terraform который позволяет нам управлять облаком scaleway.<br />Модуль этот является официальным и поддерживается самим scaleway и найти документацию по нему можно здесь<br /><a href="https://registry.terraform.io/providers/scaleway/scaleway" target="_blank">https://registry.terraform.io/providers/scaleway/scaleway</a></p>
  <p id="f3yw"></p>
  <p id="ctnk"><strong>1. Получаем конфигурационный файл нашего оператора</strong><br />Для начала нам нужно зарегистрироваться, и подтвердить свою почту, надеюсь у вас не возникнет с этим проблем.<br />Следующем шагом, нам необходимо будет сгенерировать ключи доступа для terraform.<br />Делается это в профиле, в разделе credentials<br /></p>
  <figure id="SGrH" class="m_column">
    <img src="https://img2.teletype.in/files/d1/42/d1428429-bbda-49af-a11a-675cfc425246.png" width="2726" />
  </figure>
  <p id="74pl">Здесь нажимаем &quot;<em>generate api key</em>&quot;, вводим название, и из появившегося окна с ключами, cохраняем <em><strong>access_key</strong></em> и <em><strong>secret_key</strong></em>.</p>
  <figure id="31kz" class="m_column">
    <img src="https://img3.teletype.in/files/60/ff/60ff2eb9-0cc6-4770-8396-d7eef37327fd.png" width="1752" />
  </figure>
  <p id="N9vz"><br />Очень важно их сохранить, потому что посмотреть их повторно будет нельзя.<br />Так же нельзя допустить утечку этих ключей, иначе злоумышленники, смогут за ваш счёт создать кучу серверов от вашего имени и оператор может выставить вам некислый счёт.<br />Также отсюда следует сохранить <em><strong>project_id</strong></em> он нам потребуется в дальнейшем.</p>
  <p id="ouyS"><strong>2. Создаем файл variables.tf, где пропишем наши только что полученные ключи.</strong></p>
  <pre id="YfyC" data-lang="toml">variable &quot;project_id&quot; {
  default = &quot;87432-d326-0474-91b8-d52a6789ccc5&quot;
}
variable &quot;access_key&quot; {
  default = &quot;SCW7141234562F0W60&quot;
}
variable &quot;secret_key&quot; {
  default = &quot;0dde9e8d-8e5a-4b5e-9499-da4c17bd5fc6&quot;
}</pre>
  <p id="sABm"><strong>3. Создаём файл с описанием модулей, назовём его providers.tf</strong></p>
  <pre id="CFuc" data-lang="toml">terraform {
  required_providers {
    scaleway = {
      source = &quot;scaleway/scaleway&quot;
      version = &quot;2.2.8&quot;
    }
  }
}

provider &quot;scaleway&quot; {
  project_id = var.project_id
  access_key = var.access_key
  secret_key = var.secret_key
  zone   = &quot;fr-par-1&quot;
  region = &quot;fr-par&quot;
}</pre>
  <p id="6oDr">Мы делаем регионом по умолчанию Францию, вы можете выбрать любой другой регион, со списком можно ознакомиться здесь <a href="https://registry.terraform.io/providers/scaleway/scaleway/latest/docs/guides/regions_and_zones" target="_blank">https://registry.terraform.io/providers/scaleway/scaleway/latest/docs/guides/regions_and_zones</a></p>
  <p id="JcQo"><strong>4. Переходим к описанию нашего кластера.</strong><br />Для начала нам потребуется описать сам кластер кубернетеса.<br />Создадим файл с его описанием kubernetes.tf</p>
  <pre id="UGDc" data-lang="toml">resource &quot;scaleway_k8s_cluster&quot; &quot;haqq&quot; {
  name    = &quot;haqq&quot;
  version = &quot;1.24.3&quot;
  cni     = &quot;calico&quot;
}</pre>
  <p id="zHQT">Далее опишем ноды, которые будут в нашем кластере в файле kubernetes-nodes.tf</p>
  <pre id="K3It" data-lang="toml">resource &quot;scaleway_k8s_pool&quot; &quot;haqq-nodes1&quot; {
  cluster_id  = scaleway_k8s_cluster.haqq.id
  name        = &quot;nodes1&quot;
  node_type   = &quot;DEV1-L&quot;
  size        = 1
  autoscaling = false
  autohealing = true
  min_size    = 1
  max_size    = 1
}</pre>
  <p id="TsgB">Здесь я обращу внимание на параметры.<br /><em><strong>node_type</strong></em> - это тип серверов которые мы добавляем в кластер.<br />Scaleway предоставляет множество различных узлов, и вы их можете комбинировать в своём кластере.<br />Актуальные названия инстансов можно посмотреть здесь <a href="https://www.scaleway.com/en/docs/faq/instances/" target="_blank">https://www.scaleway.com/en/docs/faq/instances/</a><br /><strong><em>size </em></strong>- количество серверов которые мы создаем в кластере<br /><strong><em>min_size / max_size </em></strong>- в нашем случае равны size поскольку мы не используем автоматическое масштабирование кластера.</p>
  <p id="lF7i"><strong>5. Мы готовы начинать !</strong><br />Попробуем развернуть наш кластер.<br />Для этого, нам нужно произвести инициализацию конфигурации</p>
  <pre id="Vpdg">terrafrom init</pre>
  <p id="xTHX">Далее попробуем сделать plan, то есть посмотрим, какие изменения попытается сделать наша созданная конфигурация.</p>
  <pre id="m95b">terrafrom plan</pre>
  <p id="e7DU">Если план проходит без проблем, попробуем развернуть наш кластер</p>
  <pre id="sOlu">terraform apply</pre>
  <p id="nDUw">После этого вас попросят ввести <code>yes</code> подтвердив создание кластера.</p>
  <p id="4PYM">После этого вы должны увидеть примерно следующий вывод в консоли</p>
  <pre id="zdIx">scaleway_k8s_cluster.haqq: Creating...
scaleway_k8s_cluster.haqq: Creation complete after 6s [id=fr-par/505b2785-9d2f-4249-90d1-216190f1ef41]
scaleway_k8s_pool.haqq-pool-1: Creating...
scaleway_k8s_pool.haqq-pool-1: Still creating... [10s elapsed]
scaleway_k8s_pool.haqq-pool-1: Still creating... [20s elapsed]
.....
.....
scaleway_k8s_pool.haqq-pool-1: Still creating... [5m41s elapsed]
scaleway_k8s_pool.haqq-pool-1: Still creating... [5m51s elapsed]
scaleway_k8s_pool.haqq-pool-1: Creation complete after 5m59s [id=fr-par/730c89aa-99bb-494b-85e1-b2f6f22fc671]</pre>
  <p id="VpoV">В веб интерфейсе scaleway в разделе Project Dasboard должна появится информация о только что созданных кластере и инстансе.</p>
  <figure id="FcbI" class="m_column">
    <img src="https://img4.teletype.in/files/f2/ff/f2ff92dd-26a0-42b1-82ef-d91ced4ee030.png" width="1502" />
  </figure>
  <figure id="KmRm" class="m_column">
    <img src="https://img1.teletype.in/files/81/19/81194e20-efd9-4270-b7e7-a846ac5c9b9c.png" width="2374" />
  </figure>
  <figure id="4qyS" class="m_column">
    <img src="https://img4.teletype.in/files/b9/27/b927c806-c0ec-4976-977d-bce487be538f.png" width="2376" />
  </figure>
  <p id="0m7W"></p>
  <h3 id="vuiZ">Развертывание приложения</h3>
  <p id="Z6sT">Теперь мы можем приступить к развертыванию самого приложения.</p>
  <p id="M7m0">Но перед тем как мы начнём писать конфигурацию, нам необходимо сконфигурировать terraform для того чтобы он умел работать с kubernetes</p>
  <p id="505E">Для этого мы возьмём официальный модуль для работы с kubernetes, документацию по нему вы можете найти здесь <a href="https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/deployment" target="_blank">https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/deployment</a></p>
  <p id="cJPC">Чтобы подключить данный модуль, нам необходимо в файле providers.tf в секции requred_providers добавить нового провайдера</p>
  <pre id="OtaT" data-lang="toml">kubernetes = {
      source  = &quot;hashicorp/kubernetes&quot;
      version = &quot;2.13.0&quot;
}</pre>
  <p id="4YN9">По аналогии, как мы это делали с провайдером <code>scaleway</code></p>
  <p id="MHmJ">Далее, нам необходимо сконфигурировать этого провайдера. Сделать мы это можем также по аналогии с тем как конфигурировали scaleway, добавив в том же самом файле providers.tf конфигурацию вида</p>
  <pre id="3LdZ" data-lang="toml">provider &quot;kubernetes&quot; {
  host                   = scaleway_k8s_cluster.haqq.kubeconfig.host
  token                  = scaleway_k8s_cluster.haqq.kubeconfig.token
  cluster_ca_certificate = scaleway_k8s_cluster.haqq.kubeconfig.cluster_ca_certificate
}</pre>
  <p id="rDHp">Мы не будем вдаваться в подробности описания конфигурации, вы всегда можете почитать документацию модуля, по тому что все эти параметры означают.</p>
  <p id="Vp2b">Теперь вернемся к нашим файлам конфигурации приложения</p>
  <p id="rw6V">Нам понадобится описать ряд компонентов kubernetes которые и будут отвечать за наше приложение.</p>
  <p id="h2aP">У нас это будут</p>
  <ol id="qbNI">
    <li id="31hN">StatefulSet- собственно сам docker контейнер с конфигурацией нашего сервиса и томом, в котором будут хранится наши данные.</li>
    <li id="b1su">ConfigMap - объект хранящий скрипт инициализации для первичного запуска.</li>
  </ol>
  <p id="ocLJ">Для начала напишем скрипт инициализации сети, и положим его в файл k8s_init.sh</p>
  <pre id="H6j5" data-lang="bash">#!/bin/bash

NETWORK=haqq_53211-1
MONIKER=beething

if [ -f &quot;/root/.haqqd/haqq-k8s-init&quot; ]; then
    echo already init
else
    haqqd config chain-id $NETWORK
    haqqd init $MONIKER -o --chain-id $NETWORK
    touch /root/.haqqd/haqq-k8s-init
fi

if [ -f &quot;/root/.haqqd/haqq-k8s-genesis&quot; ]; then
    echo already downloaded
else
    wget https://storage.googleapis.com/haqq-testedge-snapshots/genesis.json -O /root/.haqqd/config/genesis.json
    touch /root/.haqqd/haqq-k8s-genesis
fi

if [ -f &quot;/root/.haqqd/haqq-k8s-state-sync&quot; ]; then
    echo state-sync already configured
else
    wget https://raw.githubusercontent.com/haqq-network/testnets/main/TestEdge/state_sync.sh -O state_sync.sh
    bash state_sync.sh
    touch /root/.haqqd/haqq-k8s-state-sync
fi</pre>
  <p id="TuIv"></p>
  <p id="p9JA">Далее, создадим объект configMap который будет содержать наш скрипт.</p>
  <p id="7w3I">Для простоты создадим файл haqq.tf и всю конфигурацию компонентов kubernetes будем описывать в нём</p>
  <pre id="FXmS" data-lang="toml">resource &quot;kubernetes_config_map&quot; &quot;haqq-init&quot; {
  metadata {
    name = &quot;haqq-init&quot;
  }

  data = {
    &quot;haqq_init.sh&quot; = &quot;${file(&quot;${path.module}/k8s_init.sh&quot;)}&quot;
  }

}</pre>
  <p id="Jdak"></p>
  <p id="Loby">Далее опишем наш StatefulSet</p>
  <pre id="8efv" data-lang="toml">resource &quot;kubernetes_stateful_set&quot; &quot;haqq&quot; {
  metadata {
    name   = &quot;haqq-node&quot;
    labels = { test = &quot;haqq-node&quot; }
  }

  spec {
    replicas     = 1
    service_name = &quot;haqq&quot;
    selector { match_labels = { test = &quot;haqq-node&quot; } }

    template {
      metadata { labels = { test = &quot;haqq-node&quot; } }

      spec {

        volume {
          name = &quot;haqq-init&quot;
          config_map {
            name = &quot;haqq-init&quot;
          }
        }

        init_container {
          name    = &quot;init&quot;
          image   = &quot;alhaqq/haqq:v1.0.3&quot;
          command = [&quot;/bin/bash&quot;, &quot;-c&quot;, &quot;bash /root/haqq_init.sh&quot;]

          volume_mount {
            name       = &quot;haqq-init&quot;
            mount_path = &quot;/root/haqq_init.sh&quot;
            sub_path   = &quot;haqq_init.sh&quot;
            read_only  = true
          }

          volume_mount {
            name       = &quot;haqq-data&quot;
            mount_path = &quot;/root/.haqqd&quot;
          }
        }

        container {
          image   = &quot;alhaqq/haqq:v1.0.3&quot;
          name    = &quot;haqq-node&quot;
          command = [&quot;haqqd&quot;, &quot;start&quot;, &quot;--x-crisis-skip-assert-invariants&quot;]

          resources {
            limits   = { cpu = &quot;1&quot;, memory = &quot;4G&quot; }
            requests = { cpu = &quot;1&quot;, memory = &quot;4G&quot; }
          }

          volume_mount {
            name       = &quot;haqq-data&quot;
            mount_path = &quot;/root/.haqqd&quot;
          }

        }
      }
    }

    volume_claim_template {
      metadata {
        name = &quot;haqq-data&quot;
      }

      spec {
        access_modes = [&quot;ReadWriteOnce&quot;]

        resources {
          requests = {
            storage = &quot;10G&quot;
          }
        }
      }
    }

  }
}</pre>
  <p id="fl4i"></p>
  <p id="Gfqt">На этом моменте, мы уже можем запускать нашу ноду !</p>
  <p id="wvuP">Поскольку мы добавили новые модули, делаем повторно <code>terraform init</code>и  <code>terraform apply</code></p>
  <p id="5apg">После того как все применилось нам необходимо убедиться, что все запустилось нормально. Для этого нам понадобиться утилита для доступа к нашему кластеру - kubectl</p>
  <p id="GduN">Как установить kubectl для вашей операционной системы вы можете найти в официальной документации <a href="https://kubernetes.io/docs/tasks/tools/" target="_blank">Install Tools | Kubernetes</a></p>
  <p id="tOBb">Мы же снова рассмотрим пример инсталяции для macOS. </p>
  <p id="iNm6">Всё по аналогии с terraform потому не буду описывать что делает каждая команда</p>
  <p id="c3mD"></p>
  <pre id="zUiw" data-lang="bash">curl -LO &quot;https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/amd64/kubectl&quot;
chmod +x ./kubectl 
sudo mv ./kubectl /usr/local/bin/kubectl
sudo chown root: /usr/local/bin/kubectl
kubectl version --client</pre>
  <p id="sf6b"></p>
  <p id="PalF">Далее, нам нужно получить конфигурацию для доступа в кластер, сделать это мы можем опять же при помощи terraform.</p>
  <p id="c3HQ">Модуль scaleway который помогал нам создать кластер, предоставляет нам функционал, позволяющий получить его.</p>
  <p id="G7VS">Воспользуемся им и опишем следующий ресурс</p>
  <pre id="szIz" data-lang="toml">resource &quot;local_file&quot; &quot;haqq-kubeconfig&quot; {
  content  = scaleway_k8s_cluster.haqq.kubeconfig.0.config_file
  filename = &quot;haqq.kubeconfig&quot;
}</pre>
  <p id="iSqg">Далее чтобы им воспользоваться, необходим прописать в переменную окружения KUBECONFIG путь до нашего конфига.</p>
  <p id="ISSi"><code>export KUBECONFIG=haqq.kubeconfig</code></p>
  <p id="VkQP">После чего мы можем выполнить </p>
  <p id="X8yt"><code>kubect get pods</code></p>
  <p id="g1X8">И увидим примерно следующую картинку </p>
  <pre id="rD8A" data-lang="shell">NAME          READY   STATUS    RESTARTS   AGE
haqq-node-0   1/1     Running   0          23m</pre>
  <p id="BI89">Значение 1/1 означает что наш узел запущен и работает</p>
  <p id="nLjU">Его логи можно посмотреть командой </p>
  <p id="p2ux"><code>kubectl logs -f haqq-node-0</code></p>
  <p id="6BzX">Вот и всё ! Мы запустили ноду, теперь можно приступать к созданию валидатора !</p>
  <p id="Dw12"></p>
  <h3 id="UMvW">Запуск валидатора</h3>
  <p id="rsMT">Поскольку запуск валидатора сопряжен с размещением приватных ключей и к тому же является одноразовой процедурой, мы никаким особенным образом не будем автоматизировать это.</p>
  <p id="M8fI">Мы просто зайдём в контейнер нашей ноды и зарегистрируем валидатора.</p>
  <p id="pRMF">Для начала проверим, что нода синхронизировалась.</p>
  <p id="20ZI">Сделаем это зайдя внутрь ноды при помощи kubectl</p>
  <p id="Ci8s">Имя контейнера можно взять из вывода, который мы делали в конце предыдущего этапа. В нашем случае это <code>haqq-node-0</code></p>
  <pre id="2mMv">kubectl exec -it haqq-node-0 bash</pre>
  <p id="9GfK">Оказавшись внутри контейнера делаем</p>
  <pre id="WbuQ">haqqd status | jq .&quot;SyncInfo&quot;.catching_up</pre>
  <p id="Ux0U">Если значение <code>false</code> значит нода успешно синхронизирована.</p>
  <p id="PMum">Перед активацией, забираем необходимые токены с крана на свой кошелек, и добавляем это кошелек на ноде из нашей seed фразы</p>
  <pre id="0FoG">haqqd keys add &lt;key_name&gt; --recover</pre>
  <p id="02mO">Далее можем регистрировать валидатора !</p>
  <pre id="oGvQ">haqqd tx staking create-validator \
  --amount=1000000000000aISLM \
  --pubkey=$(haqqd tendermint show-validator) \
  --moniker=&lt;your_moniker_name&gt; \
  --chain-id=&lt;chain_id&gt; \
  --commission-rate=&quot;0.10&quot; \
  --commission-max-rate=&quot;0.20&quot; \
  --commission-max-change-rate=&quot;0.01&quot; \
  --min-self-delegation=&quot;1000000&quot; \
  --gas=&quot;auto&quot; \
  --gas-prices=&quot;0.025aISLM&quot; \
  --from=&lt;key_name&gt; \
  --node https://rpc.tm.testedge.haqq.network:443</pre>
  <p id="6f0Z">Далее подтверждаем транзакцию и готово !</p>
  <p id="VOXH">Далее как и в шаге выше, можете проверить что в логах всё хорошо</p>
  <pre id="c7Jq">kubectl logs -f haqq-node-0</pre>
  <p id="6QV5"></p>
  <h3 id="yxVa">Удаление кластера</h3>
  <p id="4gJx">Для того чтобы удалить весь кластер, со всеми виртуалками, данными и т д, достаточно ввести всего лишь одну команду</p>
  <pre id="Nz9O">terraform destroy</pre>

]]></content:encoded></item></channel></rss>