{"id":70954,"date":"2020-02-23T00:58:17","date_gmt":"2020-02-22T21:58:17","guid":{"rendered":"https:\/\/prohoster.info\/blog\/ustrojstvo-helm-i-ego-podvodnye-kamni"},"modified":"2020-03-03T16:14:40","modified_gmt":"2020-03-03T13:14:40","slug":"ustrojstvo-helm-i-ego-podvodnye-kamni","status":"publish","type":"post","link":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/ustrojstvo-helm-i-ego-podvodnye-kamni","title":{"rendered":"Understanding Helm and Its Pitfalls","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Understanding Helm and Its Pitfalls\" src=\"\/wp-content\/uploads\/2020\/02\/b825bfb312b883f5f9c1535036f0c6e8.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/www.artstation.com\/artwork\/YaabJq\">Typhon freight hauler concept, Anton Swanepoel<\/a><\/noindex><\/p>\n<p>My name is Dmitry Sugrobov, I am a developer at 'Leroy Merlin'. In this article, I will explain why Helm is needed, how it simplifies working with Kubernetes, what has changed in the third version, and how to update applications in production without downtime.<\/p>\n<p>This is a summary based on a presentation at the conference <noindex><a rel=\"nofollow\" href=\"https:\/\/corp.mail.ru\/ru\/press\/events\/at-kubernetes-conference\/\">@Kubernetes Conference<\/a><\/noindex> by <noindex><a rel=\"nofollow\" href=\"https:\/\/mcs.mail.ru\">Mail.ru Cloud Solutions<\/a><\/noindex> \u2014 if you don't want to read, watch the video.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\n<center><div class=\"youtube-placeholder\" data-id=\"w1PhTe9gnOI\" onclick=\"loadVideo(this)\">\r\n        <img decoding=\"async\" src=\"https:\/\/img.youtube.com\/vi\/w1PhTe9gnOI\/hqdefault.jpg\" alt=\"Play video\" loading=\"lazy\" width=\"480\" height=\"360\" style=\"width:100%;height:auto;\">\r\n        <div class=\"play-button\"><\/div>\r\n    <\/div><\/center><\/p>\n<h2>Why we use Kubernetes in production<\/h2>\n<p>\n'Leroy Merlin' is a leader in the DIY retail market in Russia and Europe. Our company has over a hundred developers, 33,000 internal employees, and a huge number of people visiting hypermarkets and the website. To make them all happy, we decided to adhere to standard approaches in the industry. We develop new applications using microservice architecture, employ containers for environment isolation and proper delivery, and use Kubernetes for orchestration. The cost of using orchestrators is rapidly decreasing: the market is seeing more engineers skilled in the technology, and providers offering Kubernetes as a service are emerging.<\/p>\n<p>Everything Kubernetes does can certainly be achieved through other means, for example, by slapping scripts onto some Jenkins and docker-compose, but why complicate life when there's a ready and reliable solution? That's why we turned to Kubernetes and have been using it in production for a year now. Currently, we have twenty-four Kubernetes clusters, the oldest of which is over a year old and houses about two hundred pods.<\/p>\n<h2>The curse of numerous YAML files in Kubernetes<\/h2>\n<p>\nTo deploy a microservice in Kubernetes, we create at least five YAML files: for Deployment, Service, Ingress, ConfigMap, and Secrets \u2014 and send them to the cluster. For the next application, we'll write the same set of YAML files, another one for the third application, and so on. Multiplying the number of documents by the number of environments already gives us hundreds of files, not to mention dynamic environments.<\/p>\n<p><img decoding=\"async\" alt=\"Understanding Helm and Its Pitfalls\" src=\"\/wp-content\/uploads\/2020\/02\/c46c3f5ae49cbefa4851cbb388bfd051.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nAdam Reese, core maintainer of Helm, introduced the concept of '<noindex><a rel=\"nofollow\" href=\"https:\/\/youtu.be\/cZ1S2Gp47ng?t=323\">Development Cycle in Kubernetes<\/a><\/noindex>', which looks like this:<\/p>\n<ol>\n<li>Copy YAML \u2014 copy the YAML file.<\/li>\n<li>Paste YAML \u2014 paste it.<\/li>\n<li>Fix Indents \u2014 fix the indents.<\/li>\n<li>Repeat \u2014 repeat again.<\/li>\n<\/ol>\n<p>\nThis method works but requires repeatedly copying YAML files. To change this cycle, Helm was invented.<\/p>\n<h3>What is Helm<\/h3>\n<p>\nFirst of all, Helm \u2014<strong> package manager<\/strong>, helping find and install the necessary programs. To install something like MongoDB, there's no need to visit the official website and download binaries; just execute the command <code>helm install stable\/mongodb<\/code>.<\/p>\n<p>Secondly, Helm \u2014 <strong>a templater<\/strong>, helps parameterize files. Let's return to the situation with YAML files in Kubernetes. It\u2019s easier to write the same YAML file, add some placeholders, into which Helm will substitute values. This means instead of a large set of YAML files, there will be a set of templates where the required values will be inserted at the right moment.<\/p>\n<p>Thirdly, Helm \u2014 <strong>masters deployment<\/strong>. With it, applications can be installed, rolled back, and updated. Let's figure out how to do this.<\/p>\n<p><img decoding=\"async\" alt=\"Understanding Helm and Its Pitfalls\" src=\"\/wp-content\/uploads\/2020\/02\/8b517dbcf503ced229569fe3726418c8.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h3>How to use Helm for deploying your own applications<\/h3>\n<p>\nWe will install the Helm client on the computer, following the official <noindex><a rel=\"nofollow\" href=\"https:\/\/helm.sh\/docs\/intro\/install\/\">the instructions<\/a><\/noindex>. Then we will create a set of YAML files. Instead of specifying concrete values, we\u2019ll leave placeholders that Helm will fill with information later. This set of files is called a Helm chart. There are three ways to send it to the Helm console client:<\/p>\n<ul>\n<li>specifying the folder with the templates;<\/li>\n<li>packing it into a .tar archive and pointing to it;<\/li>\n<li>placing the template in a remote repository and adding the repository link to the Helm client.<\/li>\n<\/ul>\n<p>\nAdditionally, we need a file with values \u2014 values.yaml. Data from there will be inserted into the template. Let\u2019s create that too.<\/p>\n<p><img decoding=\"async\" alt=\"Understanding Helm and Its Pitfalls\" src=\"\/wp-content\/uploads\/2020\/02\/c0fe24cc8186640147f95ce201794d96.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nIn the second version of Helm, there is an additional server application \u2014 Tiller. It runs outside of Kubernetes and waits for requests from the Helm client, and when called, substitutes the necessary values into the template and sends it to Kubernetes.<\/p>\n<p><img decoding=\"async\" alt=\"Understanding Helm and Its Pitfalls\" src=\"\/wp-content\/uploads\/2020\/02\/6b821a0bb4680829d5ce9982d2bb4c55.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nHelm 3 is simpler: instead of processing templates on the server, information is now completely processed on the Helm client side and sent directly to the Kubernetes API. This simplification enhances the cluster's security and simplifies the rollout process.<\/p>\n<p><strong>How it all works<\/strong><\/p>\n<p>We run the command <code>helm install<\/code>. We will specify the release name of the application, give the path to values.yaml. Finally, we will specify the repository where the chart is located and the name of the chart. In this example, these are \"lmru\" and \"bestchart\", respectively.<\/p>\n<pre><code class=\"plaintext\">helm install --name bestapp --values values.yaml lmru\/bestchart\n<\/code><\/pre>\n<p>\nThe command can only be executed once; upon re-execution instead of <code>install<\/code> needs to use <code>upgrade<\/code>. For simplicity, instead of two commands, the command can be run <code>upgrade<\/code> with an additional flag <code>--install<\/code>When Helm is first executed, it will send a command to install the release, and subsequently it will update it.<\/p>\n<pre><code class=\"plaintext\">helm upgrade --install bestapp --values values.yaml lmru\/bestchart\n<\/code><\/pre>\n<p><\/p>\n<h2>Pitfalls of deploying new versions of application with Helm<\/h2>\n<p>\n<i>At this point in the story, I am playing with the audience in 'Who Wants to Be a Millionaire,' and we are figuring out how to make Helm update the application version. <\/i><noindex><a rel=\"nofollow\" href=\"https:\/\/youtu.be\/w1PhTe9gnOI?list=PLQzTaxmOHjnv0tP_HDxsIvcuac2kkIJTQ&amp;t=778\"><i>Watch the video<\/i><\/a><\/noindex>.<\/p>\n<p>When I was studying the workings of Helm, I was surprised by the unusual behavior when trying to update the versions of deployed applications. The application code was updated, a new image was uploaded to the Docker registry, I sent a command to deploy \u2014 and nothing happened. Below are a few not-so-successful ways to update applications. Delving into each one in more detail helps you understand the internal workings of the tool and the reasons for such unexpected behavior.<\/p>\n<p><strong>Method 1. Do not change information since the last launch<\/strong><\/p>\n<p>As it is said <noindex><a rel=\"nofollow\" href=\"https:\/\/helm.sh\/docs\/intro\/using_helm\/#helm-upgrade-and-helm-rollback-upgrading-a-release-and-recovering-on-failure\">the official website<\/a><\/noindex> Helm, 'Kubernetes charts can be large and complex, so Helm tries to not interfere unnecessarily.' Therefore, if you update the latest version of the application image in the Docker registry and execute the command <code>helm upgrade<\/code>, nothing will happen. Helm will think that nothing has changed, and there is no need to send a command to Kubernetes to update the application.<\/p>\n<blockquote><p>Here and further, the latest tag is shown solely as an example. When using this tag, Kubernetes will download the image from the Docker registry every time, regardless of the imagePullPolicy. Using latest in production is not recommended and can lead to side effects.<\/p><\/blockquote>\n<p>\n<strong>Method 2. Update the LABEL in the image<\/strong><\/p>\n<p>As stated in the same <noindex><a rel=\"nofollow\" href=\"https:\/\/helm.sh\/docs\/intro\/using_helm\/#helm-upgrade-and-helm-rollback-upgrading-a-release-and-recovering-on-failure\">the documentation<\/a><\/noindex>, 'Helm will only update the application if it has changed since the last release.' A logical option for this would seem to be updating the LABEL in the Docker image itself. However, Helm does not look into application images and has no concept of any changes in them. Accordingly, when updating labels in the image, Helm will not be aware of them, and the command to update the application in Kubernetes will not be sent.<\/p>\n<p><strong>Method 3. Use the key <code>--force<\/code><\/strong><\/p>\n<p><img decoding=\"async\" alt=\"Understanding Helm and Its Pitfalls\" src=\"\/wp-content\/uploads\/2020\/02\/4888cddfb7698b7044ab31b6f6070063.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nLet's refer to the manuals and search for the necessary key. The key that makes the most sense is <code>--force<\/code>Despite the descriptive name, the behavior differs from what is expected. Instead of forcing an application update, its actual purpose is to restore a release that is in FAILED status. If this key is not used, the commands must be executed sequentially. <code>helm delete &amp;&amp; helm install --replace<\/code>Instead, it is recommended to use the key <code>--force<\/code>, which automates the sequential execution of these commands. More information in this <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/helm\/helm\/pull\/3597\">pull request.<\/a><\/noindex>To tell Helm to update the application version, unfortunately, this key will not work.<\/p>\n<p><strong>Method 4. Change labels directly in Kubernetes.<\/strong><\/p>\n<p><img decoding=\"async\" alt=\"Understanding Helm and Its Pitfalls\" src=\"\/wp-content\/uploads\/2020\/02\/0a35e7aaa7479685f07dd5b935c95eb1.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nUpdating a label directly in the cluster using the command <code>kubectl edit<\/code> \u2014 is a bad idea. This action will lead to inconsistencies between the running application and what was originally deployed. Helm's behavior during deployment in this case differs from its version: Helm 2 will do nothing, while Helm 3 will deploy a new version of the application. To understand the reason, one needs to understand how Helm works.<\/p>\n<h3>How Helm Works<\/h3>\n<p>\nTo determine if the application has changed since the last release, Helm can utilize:<\/p>\n<ul>\n<li>the running application in Kubernetes;<\/li>\n<li>a new values.yaml and the current chart;<\/li>\n<li>Helm's internal information about releases.<\/li>\n<\/ul>\n<p><b class=\"spoiler_title\">For the most curious: where does Helm store its internal information about releases?<\/b>By executing the command <code>helm history<\/code>, we will get all the information about the versions installed using Helm.<\/p>\n<p><img decoding=\"async\" alt=\"Understanding Helm and Its Pitfalls\" src=\"\/wp-content\/uploads\/2020\/02\/0bf3afeb9c4947220474af648a1fa1ad.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nThere is also detailed information about the submitted templates and values. We can request it:<\/p>\n<p><img decoding=\"async\" alt=\"Understanding Helm and Its Pitfalls\" src=\"\/wp-content\/uploads\/2020\/02\/858560c0f4adf7375060cec339df7574.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nIn the second version of Helm, this information is stored in the same namespace where Tiller is running (by default \u2014 kube-system), in a ConfigMap labeled \"OWNER=TILLER\":<\/p>\n<p><img decoding=\"async\" alt=\"Understanding Helm and Its Pitfalls\" src=\"\/wp-content\/uploads\/2020\/02\/ba665a079ccddeb4ca7049822c42a498.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nWith the arrival of the third version of Helm, the information moved to secrets, in the same namespace where the application is running. This made it possible to run multiple applications simultaneously in different namespaces with the same release name. In the second version, this was a significant headache, as namespaces are isolated but can affect each other.<\/p>\n<p><img decoding=\"async\" alt=\"Understanding Helm and Its Pitfalls\" src=\"\/wp-content\/uploads\/2020\/02\/b9b82b7c86320a0e3642e4265a1f0241.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p>\nThe second Helm, when trying to determine if an update is needed, uses only two sources of information: what has been provided to it now and the internal release information stored in the ConfigMap.<\/p>\n<p><img decoding=\"async\" alt=\"Understanding Helm and Its Pitfalls\" src=\"\/wp-content\/uploads\/2020\/02\/0550ba5f6ce7be1e7f666dfc65e639ad.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nThe third Helm uses a three-way merge strategy: in addition to the existing information, it also takes into account the application currently running in Kubernetes.<\/p>\n<p><img decoding=\"async\" alt=\"Understanding Helm and Its Pitfalls\" src=\"\/wp-content\/uploads\/2020\/02\/252085adb83e097e01b4a0655706ede5.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nFor this reason, the old version of Helm will not do anything since it does not consider application information in the cluster, while Helm 3 will take the changes and deploy a new application.<\/p>\n<p><strong>Method 5. Use the key \u2014recreate-pods<\/strong><\/p>\n<p>By using the key <code>--recreate-pods<\/code> it is possible to achieve what was initially planned with the key <code>--force<\/code>. Containers will restart, and according to the imagePullPolicy: Always policy for the latest tag (as mentioned in the footnote above), Kubernetes will download and run the new version of the image. This will not be done in the best way: not considering the deployment's StrategyType, it will abruptly shut down all old application instances and start new ones. During the restart, the system will not function, and users will be affected.<\/p>\n<p>In Kubernetes itself, a similar problem also existed for a long time. And now, four years after the issue was opened, <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/kubernetes\/kubernetes\/issues\/13488\">Issue<\/a><\/noindex>, the problem has been fixed, and starting with version 1.15 of Kubernetes, rolling-restart of pods is possible.<\/p>\n<p>Helm simply shuts down all applications and launches new containers alongside them. This should not be done in production to avoid application downtime. Such actions are only needed for development purposes and should be performed solely in staging environments.<\/p>\n<h2>How to update the application version using Helm?<\/h2>\n<p>\nWe will change the values sent to Helm. Generally, these are the values substituted for the image tag. In the case of latest, often used for non-production environments, the changable information is represented by an annotation, which is useless for Kubernetes but serves as a signal for Helm to update the application. Options for filling in the annotation value include:<\/p>\n<ol>\n<li><strong>A random value<\/strong> using the standard function \u2014 <code>{{ randAlphaNum 6 }}<\/code>. <br \/>\nThere's a catch: after each deploy using a chart with such a variable, the annotation value will be unique, and Helm will assume that there are changes. This means we will always restart the application, even if we haven't changed its version. This is not critical, as there will be no downtime, but it is still inconvenient.<\/li>\n<li>Insert the current <strong>date and time<\/strong> \u2014 <code>{{ .Release.Date }}<\/code>. <br \/>\nThis option is similar to the random value with a continuously unique variable.<\/li>\n<li>A better way is to use <strong>checksums<\/strong>. This is the SHA of the image or the SHA of the latest commit in Git \u2014 <code>{{ .Values.sha }}<\/code>. <br \/>\nThey need to be calculated and sent to the Helm client on the calling side, for example in Jenkins. If the application changes, the checksum will also change. Consequently, Helm will update the application only when necessary.<\/li>\n<\/ol>\n<p><\/p>\n<h2>Let's summarize our attempts<\/h2>\n<p><\/p>\n<ul>\n<li>Helm makes changes in the least invasive way, so any change at the application image level in the Docker Registry will not lead to an update: after executing the command, nothing will happen.<\/li>\n<li>\u2014 some characteristic of the node (for example, a number). The key is needed to identify the element of the tree corresponding to this key. Example of a binary search tree: <code>--force<\/code> is used to roll back problematic releases and is not related to forced updates.<\/li>\n<li>\u2014 some characteristic of the node (for example, a number). The key is needed to identify the element of the tree corresponding to this key. Example of a binary search tree: <code>--recreate-pods<\/code> will forcibly update applications but will do it in a destructive way: it will abruptly shut down all containers. This will affect users, and it shouldn't be done in production.<\/li>\n<li>Directly making changes to the Kubernetes cluster using the command <code>kubectl edit<\/code> should not be done: it will disrupt consistency, and behavior will vary depending on the Helm version.<\/li>\n<li>With the release of the new version of Helm, many nuances have emerged. Issues in the Helm repository are described in an understandable way, they will help clarify the details.<\/li>\n<li>Adding a mutable annotation to the chart will make it more flexible. This will allow rolling out the application correctly, without downtime.<\/li>\n<\/ul>\n<p>\nA thought from the realm of \"peace on Earth,\" applicable in all areas of life: read the instructions before use, not after. Only with complete information can reliable systems be built and users made happy.<\/p>\n<p><strong>Other links on the topic:<\/strong><\/p>\n<ol>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/453734\/\">Getting to know <i>Helm<\/i> 3<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/helm.sh\/\">Official Helm website<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/helm\/helm\">Helm repository on GitHub<\/a><\/noindex><\/li>\n<li><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/mailru\/blog\/425343\/\">25 useful Kubernetes tools: deployment and management<\/a><\/noindex><\/li>\n<\/ol>\n<p>\nThis presentation was first given at <noindex><a rel=\"nofollow\" href=\"https:\/\/corp.mail.ru\/ru\/press\/events\/at-kubernetes-conference\/\">@Kubernetes Conference<\/a><\/noindex> by Mail.ru Cloud Solutions. See <noindex><a rel=\"nofollow\" href=\"https:\/\/www.youtube.com\/playlist?list=PLQzTaxmOHjnv0tP_HDxsIvcuac2kkIJTQ\">video<\/a><\/noindex> other presentations and subscribe for event announcements on Telegram <noindex><a rel=\"nofollow\" href=\"https:\/\/t.me\/k8s_mail\">Around Kubernetes at Mail.ru Group<\/a><\/noindex>.<br \/>\n<br \/>Source: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/mailru\/blog\/488192\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>Typhon freight hauler concept, Anton Swanepoel \u041c\u0435\u043d\u044f \u0437\u043e\u0432\u0443\u0442 \u0414\u043c\u0438\u0442\u0440\u0438\u0439 \u0421\u0443\u0433\u0440\u043e\u0431\u043e\u0432, \u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0432 \u00ab\u041b\u0435\u0440\u0443\u0430 \u041c\u0435\u0440\u043b\u0435\u043d\u00bb. \u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443, \u0437\u0430\u0447\u0435\u043c \u043d\u0443\u0436\u0435\u043d Helm, \u043a\u0430\u043a \u043e\u043d \u0443\u043f\u0440\u043e\u0449\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 Kubernetes, \u0447\u0442\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u043b\u043e\u0441\u044c \u0432 \u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u0438 \u043a\u0430\u043a \u0441 \u0435\u0433\u043e \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 \u0431\u0435\u0437 \u043f\u0440\u043e\u0441\u0442\u043e\u044f. \u042d\u0442\u043e \u043a\u043e\u043d\u0441\u043f\u0435\u043a\u0442 \u043f\u043e \u043c\u043e\u0442\u0438\u0432\u0430\u043c \u0432\u044b\u0441\u0442\u0443\u043f\u043b\u0435\u043d\u0438\u044f \u043d\u0430 \u043a\u043e\u043d\u0444\u0435\u0440\u0435\u043d\u0446\u0438\u0438 @Kubernetes Conference by Mail.ru Cloud [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":70955,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-70954","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/ustrojstvo-helm-i-ego-podvodnye-kamni\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e Helm \u0438 \u0435\u0433\u043e \u043f\u043e\u0434\u0432\u043e\u0434\u043d\u044b\u0435 \u043a\u0430\u043c\u043d\u0438 | ProHoster\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/ustrojstvo-helm-i-ego-podvodnye-kamni\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-02-22T21:58:17+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-03-03T13:14:40+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47The device of Helm and its pitfalls | ProHoster","description":"","canonical_url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/ustrojstvo-helm-i-ego-podvodnye-kamni","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"en_US","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e Helm \u0438 \u0435\u0433\u043e \u043f\u043e\u0434\u0432\u043e\u0434\u043d\u044b\u0435 \u043a\u0430\u043c\u043d\u0438 | ProHoster","og:url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/ustrojstvo-helm-i-ego-podvodnye-kamni","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-02-22T21:58:17+00:00","article:modified_time":"2020-03-03T13:14:40+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"70954","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 19:11:23","updated":"2022-09-30 13:54:53","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/70954","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/comments?post=70954"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/70954\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media\/70955"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media?parent=70954"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/categories?post=70954"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/tags?post=70954"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}