{"id":96065,"date":"2020-10-07T13:42:09","date_gmt":"2020-10-07T11:42:09","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf"},"modified":"2020-10-07T13:42:09","modified_gmt":"2020-10-07T11:42:09","slug":"problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf","status":"publish","type":"post","link":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf","title":{"rendered":"The problem of 'intelligent' container image cleanup and its solution in werf","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"The problem of &#039;intelligent&#039; container image cleanup and its solution in werf\" src=\"\/wp-content\/uploads\/2020\/10\/1410cea46bb8dcdc3ac06db11ed5a402.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nThis article addresses the issue of cleaning up images that accumulate in container registries (Docker Registry and its analogs) in the context of modern CI\/CD pipelines for cloud-native applications deployed in Kubernetes. It outlines the main criteria for the relevance of images and the resulting challenges in automating cleanup, saving space, and meeting team needs. Finally, using a specific Open Source project as an example, we will discuss how these challenges can be overcome.<\/p>\n<h2>Introduction<\/h2>\n<p>\nThe number of images in a container registry can rapidly grow, taking up more storage space and consequently significantly increasing costs. To control, limit, or maintain acceptable growth of the space occupied in the registry, it is common to:<\/p>\n<ol>\n<li>use a fixed number of tags for images;<\/li>\n<li>somehow clean up images.<\/li>\n<\/ol>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nThe first limitation is sometimes acceptable for small teams. If developers can make do with permanent tags (<code>latest<\/code>, <code>main<\/code>, <code>test<\/code>, <code>boris<\/code> , etc.), the registry will not bloat in size, and there may be little need to think about cleanup for a long time. After all, all outdated images are overwritten, and there\u2019s simply no work left for cleanup (everything is handled by the built-in garbage collector).<\/p>\n<p>However, this approach severely limits development and is rarely applicable to the CI\/CD of modern projects. An integral part of development has become <strong>automation<\/strong>, which allows for much faster testing, deploying, and delivering new functionality to users. For example, in all our projects, a CI pipeline is automatically created with each commit. In it, an image is built, tested, deployed to various Kubernetes environments for debugging and remaining checks, and if everything goes well, the changes reach the end user. This has long ceased to be rocket science; for many, it\u2019s a routine matter\u2014likely for you as well, since you\u2019re reading this article.<\/p>\n<p>As bug fixes and new functionality development occur simultaneously, and releases can happen several times a day, it is clear that the development process is accompanied by a significant number of commits, which means\u2014 <strong>a large number of images in the registry.<\/strong>As a result, the question of organizing effective registry cleanup, i.e., removing outdated images, becomes pressing.<\/p>\n<p>But how can one even determine if an image is relevant?<\/p>\n<h2>Relevance Criteria for Images<\/h2>\n<p>\nIn the vast majority of cases, the main criteria will be as follows:<\/p>\n<p>1. The first (most obvious and critical of all) \u2014 these are the images that <strong>are currently in use in Kubernetes.<\/strong>Removing these images can lead to significant costs due to production downtime (for example, images may be required for replication) or negate the efforts of the team working on debugging in any of the environments. <i>(For this reason, we even created a special <\/i><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/flant\/k8s-image-availability-exporter\"><i>Prometheus exporter<\/i><\/a><\/noindex><i>, which monitors the absence of such images in any Kubernetes cluster.)<\/i><\/p>\n<p>2. The second (less obvious, but also very important and again related to operation) \u2014 images that <strong>are needed for rollback in case serious issues are detected<\/strong> in the current version. For example, with Helm, these are images used in saved release versions. (By the way, by default, Helm has a limit of 256 revisions, but it's unlikely that anyone actually needs to keep <i>that<\/i> many versions..) After all, we store versions specifically so that they can be used later, i.e., to \"rollback\" to them when necessary.<\/p>\n<p>3. The third \u2014 <strong>developer needs:<\/strong>all images related to their current work. For example, if we are considering a PR, it makes sense to keep the image that corresponds to the latest commit and, say, the previous commit: this way, the developer can quickly return to any task and work with the latest changes. <\/p>\n<p>4. The fourth \u2014 images that <strong>correspond to versions of our application<\/strong>, i.e., are the final product: v1.0.0, 20.04.01, sierra, etc.<\/p>\n<p>NB: The criteria outlined here were formulated based on experience working with dozens of development teams from various companies. However, of course, depending on the specifics of development processes and the infrastructure used (for example, if Kubernetes is not used), these criteria may differ. <\/p>\n<h2>Criteria Compliance and Existing Solutions<\/h2>\n<p>\nPopular container registry services typically offer their image cleanup policies: you can specify the conditions under which a tag is removed from the registry. However, the possibilities of these conditions are limited to parameters such as names, creation time, and the number of tags*.<\/p>\n<p><i>* It depends on the specific implementations of the container registry. We considered the capabilities of the following solutions: Azure CR, Docker Hub, ECR, GCR, GitHub Packages, GitLab Container Registry, Harbor Registry, JFrog Artifactory, Quay.io \u2014 as of September 2020.<\/i><\/p>\n<p>This set of parameters is quite sufficient to meet the fourth criterion \u2014 that is, to filter images that correspond to versions. However, for all other criteria, a compromise solution must be chosen (a stricter or, on the contrary, a more lenient policy) depending on expectations and financial capabilities.<\/p>\n<p>For instance, the third criterion \u2014 related to developers' needs \u2014 can be solved by organizing processes within teams: specific naming of images, maintaining special allow lists, and internal agreements. However, in the end, it still needs to be automated. And if the capabilities of ready-made solutions are insufficient, something custom must be created.<\/p>\n<p>The situation is similar for the first two criteria: they cannot be satisfied without obtaining data from an external system \u2014 that very system where applications are deployed (in our case, it's Kubernetes).<\/p>\n<h3>Workflow illustration in Git<\/h3>\n<p>\nSuppose you work in Git approximately like this:<\/p>\n<p><img decoding=\"async\" alt=\"The problem of &#039;intelligent&#039; container image cleanup and its solution in werf\" src=\"\/wp-content\/uploads\/2020\/10\/45c9bfb6755da1b4d6be05b51ab17429.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\n<i>The icon with a head on the diagram marks the container images currently deployed in Kubernetes for any users (end users, testers, managers, etc.) or used by developers for debugging and similar purposes.<\/i><\/p>\n<p>What will happen if the cleanup policies allow keeping (not deleting) images only <b>by specified tag names<\/b>?<\/p>\n<p><img decoding=\"async\" alt=\"The problem of &#039;intelligent&#039; container image cleanup and its solution in werf\" src=\"\/wp-content\/uploads\/2020\/10\/e57ff24cb818799d28e8eb006aea2eb5.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nClearly, such a scenario will please no one.<\/p>\n<p>What will change if the policies allow not deleting images <b>by a specified time interval \/ number of latest commits<\/b>?<\/p>\n<p><img decoding=\"async\" alt=\"The problem of &#039;intelligent&#039; container image cleanup and its solution in werf\" src=\"\/wp-content\/uploads\/2020\/10\/7743581e6e64affb0a207ee156c00f6e.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nThe result became significantly better, yet still far from ideal. After all, we still have developers who need images in the registry (or even deployed in K8s) for debugging bugs\u2026<\/p>\n<p>To summarize the market situation: the functions available in container registries do not provide sufficient flexibility in cleanup, and the main reason is \u2014 <strong>there is no way to interact with the outside world.<\/strong>It turns out that teams requiring such flexibility have to implement image deletion \"externally\" using the Docker Registry API (or the native API of the respective implementation).<\/p>\n<p>However, we were looking for a universal solution that would automate image cleanup for different teams using different registries\u2026<\/p>\n<h2>Our Path to Universal Image Cleanup<\/h2>\n<p>\nWhere does this need come from? The fact is that we are not just a separate group of developers, but a team that serves multiple such groups, helping to comprehensively address CI\/CD issues. And the main technical tool for this is an Open Source utility. <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.werf.io\/\">werf<\/a><\/noindex>Its feature is that it does not perform a single function but supports continuous delivery processes at all stages: from building to deployment.<\/p>\n<p>Publishing images in the registry* (immediately after they are built) is an obvious function of such a utility. And since images are stored there, if your storage is not unlimited, you also need to take responsibility for their subsequent cleanup. We will discuss how we succeeded in this while meeting all specified criteria.<\/p>\n<p><i>* Although the registries themselves can vary (Docker Registry, GitLab Container Registry, Harbor, etc.), their users face the same problems. In our case, the universal solution is independent of the registry implementation, as it operates outside the registries themselves and offers the same behavior for all.<\/i><\/p>\n<p>Although we use werf as an example of implementation, we hope that the approaches used will be useful to other teams facing similar challenges.<\/p>\n<p>So, we set about <i>external<\/i> implementation of a mechanism for image cleanup \u2014 instead of the capabilities already built into the registries for containers. The first step was to use the Docker Registry API to create the same basic policies regarding the number of tags and their creation time (mentioned above). <strong>An allow list based on images used in the deployed infrastructure was added,<\/strong>, i.e. Kubernetes. For the latter, it was sufficient to iterate through all deployed resources via the Kubernetes API and obtain a list of values. <code>image<\/code>.<\/p>\n<p>Such a trivial solution addressed the most critical problem (criterion #1), but it was only the beginning of our journey to improve the cleanup mechanism. The next \u2014 and much more interesting \u2014 step was the solution <strong>to link published images with Git history<\/strong>.<\/p>\n<h3>Tagging Schemes<\/h3>\n<p>\nInitially, we chose an approach where the final image had to store the necessary information for cleanup, and we built the process based on tagging schemes. When publishing an image, the user selected a specific tagging option (<code>git-branch<\/code>, <code>git-commit<\/code> or <code>git-tag<\/code>) and used the corresponding value. In CI systems, setting these values was done automatically based on environment variables. Essentially <strong>the final image was linked to a specific Git primitive<\/strong>, storing the necessary data for cleanup in labels.<\/p>\n<p>Within this approach, a set of policies emerged that allowed us to use Git as the single source of truth:<\/p>\n<ul>\n<li>When a branch\/tag was deleted in Git, any associated images in the registry were automatically removed.<\/li>\n<li>The number of images linked to Git tags and commits could be regulated by the number of tags used in the chosen scheme and the creation time of the related commit.<\/li>\n<\/ul>\n<p>\nOverall, the resulting implementation met our needs, but soon we faced a new challenge. During our use of tagging schemes based on Git primitives, we encountered a number of drawbacks. <i>(As their description goes beyond the scope of this article, anyone interested can find more details <\/i><noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/495112\/\"><i>here<\/i><\/a><\/noindex><i>.)<\/i> Thus, having decided to move to a more efficient approach to tagging (content-based tagging), we had to reconsider the implementation of image cleanup.<\/p>\n<h3>The new algorithm<\/h3>\n<p>\nWhy? In content-based tagging, each tag can satisfy multiple commits in Git. With image cleanup, we could no longer rely <i>only<\/i> on the commit during which the new tag was added to the registry.<\/p>\n<p>For the new cleanup algorithm, it was decided to move away from tagging schemes and build <strong>the process on meta-images<\/strong>, each of which stores a link of:<\/p>\n<ul>\n<li>the commit during which publishing took place (regardless of whether the image changed, was added, or remained the same in the container registry);<\/li>\n<li>and our internal identifier corresponding to the built image.<\/li>\n<\/ul>\n<p>\nIn other words, a connection was established <strong>between the published tags and commits in Git<\/strong>.<\/p>\n<h3>The final configuration and general algorithm<\/h3>\n<p>\nUsers configuring the cleanup now have access to policies that determine the selection of relevant images. Each such policy is defined by:<\/p>\n<ul>\n<li>a set of references, i.e., Git tags or Git branches that are used during scanning;<\/li>\n<li>and a limit on the number of images searched for each reference from the set.<\/li>\n<\/ul>\n<p>\nFor illustration \u2014 here's how the default policy configuration looks:<\/p>\n<pre><code class=\"plaintext\">cleanup:\n  keepPolicies:\n  - references:\n      tag: \/.*\/\/\n      limit:\n        last: 10\n  - references:\n      branch: \/.*\/\/\n      limit:\n        last: 10\n        in: 168h\n        operator: And\n    imagesPerReference:\n      last: 2\n      in: 168h\n      operator: And\n  - references:  \n      branch: \/^(main|staging|production)$\/\n    imagesPerReference:\n      last: 10\n<\/code><\/pre>\n<p>\nThis configuration contains three policies that adhere to the following rules:<\/p>\n<ol>\n<li>Keep an image for the 10 most recent Git tags (based on the tag creation date).<\/li>\n<li>Keep at most 2 images published in the last week for no more than 10 branches active in the last week.<\/li>\n<li>Keep 10 images for branches <code>main<\/code>, <code>staging<\/code> and <code>production<\/code>.<\/li>\n<\/ol>\n<p>\nThe resulting algorithm boils down to the following steps:<\/p>\n<ul>\n<li>Fetching manifests from the container registry.<\/li>\n<li>Excluding images used in Kubernetes, as we have already preselected them by querying the K8s API.<\/li>\n<li>Scanning the Git history and excluding images according to specified policies.<\/li>\n<li>Removing the remaining images.<\/li>\n<\/ul>\n<p>\nReturning to our illustration, here's what it looks like with werf:<\/p>\n<p><img decoding=\"async\" alt=\"The problem of &#039;intelligent&#039; container image cleanup and its solution in werf\" src=\"\/wp-content\/uploads\/2020\/10\/c453092dca23860a0dda604843845507.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nHowever, even if you're not using werf, a similar approach to advanced image cleanup \u2014 in one implementation or another (according to your preferred image tagging approach) \u2014 can also be applied in other systems\/utilities. It suffices to keep in mind the issues that arise and find the opportunities in your stack that allow you to integrate their solution most smoothly. We hope that the path we have taken will help you look at your specific case with new details and insights.<\/p>\n<h2>Conclusion<\/h2>\n<p><\/p>\n<ul>\n<li>Sooner or later, most teams face the problem of registry overflow. <\/li>\n<li>When searching for solutions, it is essential first to define the criteria for the relevance of the image.<\/li>\n<li>Tools offered by popular container registry services enable very simple cleanup processes that do not account for the \"external world\": images used in Kubernetes and the peculiarities of team workflows.<\/li>\n<li>A flexible and efficient algorithm should understand CI\/CD processes and operate not only on Docker image data.<\/li>\n<\/ul>\n<p><\/p>\n<h2>P.S.<\/h2>\n<p>\nAlso read in our blog:<\/p>\n<ul>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/495112\/\">Content-based tagging in the werf collector: why and how it works?<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/476646\/\">3-way merge in werf: deploying to Kubernetes with Helm \"on steroids\"<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/465131\/\">Support for monorepo and multirepo in werf and its connection to Docker Registry<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/493170\/\">Release of werf 1.1: improvements in the builder today and plans for the future<\/a><\/noindex>\u00bb.<\/li>\n<\/ul>\n<p>Source: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/522024\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0442\u0438\u043a\u0430 \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043e\u0431\u0440\u0430\u0437\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043a\u0430\u043f\u043b\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0432 \u0440\u0435\u0435\u0441\u0442\u0440\u0430\u0445 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 (Docker Registry \u0438 \u0435\u0433\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0430\u0445) \u0432 \u0440\u0435\u0430\u043b\u0438\u044f\u0445 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 CI\/CD-\u043f\u0430\u0439\u043f\u043b\u0430\u0439\u043d\u043e\u0432 \u0434\u043b\u044f cloud native-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0439, \u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u0432 Kubernetes. \u041f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u044b \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0438 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u0438 \u0432\u044b\u0442\u0435\u043a\u0430\u044e\u0449\u0438\u0435 \u0438\u0437 \u043d\u0438\u0445 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u043f\u0440\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0447\u0438\u0441\u0442\u043a\u0438, \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043c\u0435\u0441\u0442\u0430 \u0438 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u0435\u043d\u0438\u044f \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044f\u043c \u043a\u043e\u043c\u0430\u043d\u0434. \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e Open Source-\u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043c\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0435\u043c, \u043a\u0430\u043a \u044d\u0442\u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":96066,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-96065","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=\"description\" content=\"\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430.\" \/>\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\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf\" \/>\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\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u00ab\u0443\u043c\u043d\u043e\u0439\u00bb \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0438 \u0435\u0451 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 werf | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf\" \/>\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-10-07T11:42:09+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-10-07T11:42:09+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 challenge of \"smart\" container image cleanup and its solution in werf | ProHoster","description":"This article discusses.","canonical_url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf","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\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u00ab\u0443\u043c\u043d\u043e\u0439\u00bb \u043e\u0447\u0438\u0441\u0442\u043a\u0438 \u043e\u0431\u0440\u0430\u0437\u043e\u0432 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u043e\u0432 \u0438 \u0435\u0451 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0432 werf | ProHoster","og:description":"\u0412 \u0441\u0442\u0430\u0442\u044c\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430.","og:url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/problema-umnoj-ochistki-obrazov-kontejnerov-i-eyo-reshenie-v-werf","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-10-07T11:42:09+00:00","article:modified_time":"2020-10-07T11:42:09+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"96065","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 10:52:24","updated":"2022-10-01 08:58:07","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\/96065","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=96065"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/96065\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media\/96066"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media?parent=96065"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/categories?post=96065"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/tags?post=96065"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}