{"id":94977,"date":"2020-09-24T07:43:00","date_gmt":"2020-09-24T05:43:00","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/nashi-vyvody-za-god-migraczii-gitlab-com-na-kubernetes"},"modified":"2020-09-24T07:43:00","modified_gmt":"2020-09-24T05:43:00","slug":"nashi-vyvody-za-god-migraczii-gitlab-com-na-kubernetes","status":"publish","type":"post","link":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/nashi-vyvody-za-god-migraczii-gitlab-com-na-kubernetes","title":{"rendered":"Our Findings on the Year of Migration of GitLab.com to Kubernetes","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><i><b>Note: translation.<\/b>: adapting Kubernetes in GitLab is considered one of the two main factors contributing to the company\u2019s growth. However, until recently, the infrastructure of the online service GitLab.com was built on virtual machines, and only about a year ago did the migration to K8s begin, which is still ongoing. We are pleased to present a translation of a recent article by a GitLab SRE engineer about how this is happening and what conclusions the engineers involved in the project are making.<\/i><\/p>\n<p><img decoding=\"async\" alt=\"Our Findings on the Year of Migration of GitLab.com to Kubernetes\" src=\"\/wp-content\/uploads\/2020\/09\/58429abf60cd19a49c5ce593051c2fca.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nFor about a year now, our infrastructure department has been migrating all services operating on GitLab.com to Kubernetes. During this time, we have encountered issues related not only to moving services to Kubernetes but also to managing a hybrid deployment during the transition. This article will discuss the valuable lessons we have learned.<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>From the very beginning, GitLab.com servers operated in the cloud on virtual machines. These virtual machines are managed by Chef, and their installation occurs through our <noindex><a rel=\"nofollow\" href=\"https:\/\/about.gitlab.com\/install\/#ubuntu\">official Linux package.<\/a><\/noindex>. <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-org\/release\/docs\/-\/blob\/master\/general\/deploy\/gitlab-com-deployer.md\">Deployment Strategy<\/a><\/noindex> in case an application needs updating, consists of simply updating the server pool in a coordinated sequential manner using a CI pipeline. This method\u2014though slow and a bit <noindex><a rel=\"nofollow\" href=\"https:\/\/about.gitlab.com\/handbook\/values\/#boring-solutions\">tedious\u2014<\/a><\/noindex> ensures that GitLab.com applies the same installation and configuration methods as users of standalone <i>(self-managed)<\/i> GitLab installations that use our Linux packages for this purpose.<\/p>\n<p>We use this method because it is crucial to experience all the joys and frustrations that ordinary community members face when installing and configuring their GitLab instances. This approach worked well for a while, but when the number of projects on GitLab exceeded 10 million, we realized it no longer met our needs for scaling and deployment.<\/p>\n<h2>First Steps Towards Kubernetes and Cloud-Native GitLab<\/h2>\n<p>\nIn 2017, the <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-org\/charts\">GitLab Charts project was created.<\/a><\/noindex> to prepare GitLab for deployment in the cloud, as well as to allow users to install GitLab in Kubernetes clusters. At that time, we knew that migrating GitLab to Kubernetes would enhance the scalability of the SaaS platform, simplify deployments, and improve computational resource efficiency. However, many functions of our application depended on mounted NFS volumes, which slowed the transition from virtual machines.<\/p>\n<p>The push towards cloud-native and Kubernetes enabled our engineers to plan a gradual transition, during which we eliminated some of the application\u2019s dependencies on network storage while simultaneously continuing to develop new features. Since we began planning the migration in the summer of 2019, many of these constraints have been addressed, and the process of transitioning GitLab.com to Kubernetes is now in full swing!<\/p>\n<h2>Features of GitLab.com running on Kubernetes<\/h2>\n<p>\nFor GitLab.com, we use a single regional GKE cluster that handles all application traffic. To minimize the complexity of the already intricate migration, we focus on services that do not rely on local storage or NFS. GitLab.com primarily utilizes a monolithic codebase on Rails, and we direct traffic based on workload characteristics to different endpoints, isolated into their own node pools.<\/p>\n<p>For the frontend, these types are divided into requests to web, API, Git SSH\/HTTPS, and Registry. For the backend, we split jobs in the queue based on various characteristics according to <noindex><a rel=\"nofollow\" href=\"https:\/\/about.gitlab.com\/blog\/2020\/06\/24\/scaling-our-use-of-sidekiq\/\">predetermined resource boundaries<\/a><\/noindex>, which allow us to set Service Level Objectives (SLOs) for various loads.<\/p>\n<p>All these services for GitLab.com are configured using an unmodified GitLab Helm chart. Configuration is done in sub-charts that can be selectively included as we gradually migrate services to the cluster. Even though it was decided not to include some of our stateful services, such as Redis, Postgres, GitLab Pages, and Gitaly, in the migration, using Kubernetes drastically reduces the number of VMs currently managed by Chef.<\/p>\n<h2>Transparency and configuration management of Kubernetes<\/h2>\n<p>\nAll settings are managed by GitLab itself. We use three configuration projects based on Terraform and Helm for this purpose. We strive to use GitLab itself wherever possible to run GitLab, but for operational tasks, we operate a separate GitLab installation. This is necessary to avoid dependence on the availability of GitLab.com during deployments and updates of GitLab.com.<\/p>\n<p>Although our pipelines for the Kubernetes cluster operate on a separate GitLab installation, the code repositories have mirrors publicly accessible at the following addresses:<\/p>\n<ul>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-com\/gl-infra\/k8s-workloads\/gitlab-com\">k8s-workloads\/gitlab-com<\/a><\/noindex> \u2014 the configuration wrapper for GitLab.com for the GitLab Helm chart;<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-com\/gl-infra\/k8s-workloads\/gitlab-helmfiles\/\">k8s-workloads\/gitlab-helmfiles<\/a><\/noindex> \u2014 contains configurations for services that are not directly related to the GitLab application. These include configurations for logging and monitoring the cluster, as well as for integrated tools like PlantUML;<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-com\/gitlab-com-infrastructure\">gitlab-com-infrastructure<\/a><\/noindex> \u2014 the Terraform configuration for Kubernetes and the old (legacy) VM infrastructure. Here, all resources necessary for launching the cluster are configured, including the cluster itself, node pools, service accounts, and IP address reservations.<\/li>\n<\/ul>\n<p>\n<img decoding=\"async\" alt=\"Our Findings on the Year of Migration of GitLab.com to Kubernetes\" src=\"\/wp-content\/uploads\/2020\/09\/612125403171d73106a081bf4244a52b.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>When changes are made, a public <\/i><noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-com\/gl-infra\/k8s-workloads\/gitlab-com\/-\/merge_requests\/315#note_390180361\"><i>summary<\/i><\/a><\/noindex><i> is displayed with a link to a detailed diff, which the SRE analyzes before making changes to the cluster.<\/i><\/p>\n<p>For SRE, the link leads to a detailed diff in the GitLab installation used for operations, which is access-restricted. This allows employees and the community without access to the operational project (which is open only to SRE) to review proposed changes in the configuration. By combining a public instance of GitLab for code with a private instance for CI pipelines, we maintain a unified workflow while ensuring independence from GitLab.com when updating the configuration.<\/p>\n<h2>What we learned during the migration<\/h2>\n<p>\nDuring the relocation process, we accumulated experience that we apply to new migrations and deployments in Kubernetes.<\/p>\n<h3>1. Increased costs due to traffic between availability zones<\/h3>\n<p>\n<img decoding=\"async\" alt=\"Our Findings on the Year of Migration of GitLab.com to Kubernetes\" src=\"\/wp-content\/uploads\/2020\/09\/3dce44b3f803ffcea13e0101e7343d91.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>Daily egress statistics (bytes per day) for the Git repositories on GitLab.com<\/i><\/p>\n<p>Google divides its network into regions. These, in turn, are broken down into availability zones (AZ). Git hosting is associated with large volumes of data, so it is important for us to control network egress. In the case of internal traffic, egress is free only if it remains within the boundaries of a single availability zone. At the time of writing this article, we are outputting about 100 TB of data on a typical working day (and that's just for Git repositories). Services that were in our old VM-based topology on the same virtual machines now operate in different Kubernetes pods. This means that some of the traffic that used to be local to the VM may potentially go beyond the availability zones.<\/p>\n<p>Regional GKE clusters allow spanning multiple availability zones for redundancy. We are considering <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-com\/gl-infra\/delivery\/-\/issues\/1175\">splitting the regional GKE cluster into single-zone clusters<\/a><\/noindex> for services that generate large volumes of traffic. This will help reduce egress costs while maintaining cluster-level redundancy.<\/p>\n<h3>2. Resource Limits, Requests, and Scaling<\/h3>\n<p>\n<img decoding=\"async\" alt=\"Our Findings on the Year of Migration of GitLab.com to Kubernetes\" src=\"\/wp-content\/uploads\/2020\/09\/6e2e1ca4d37666b49358d94cd8660c56.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>The number of replicas handling production traffic on registry.gitlab.com. Traffic peaks around ~15:00 UTC.<\/i><\/p>\n<p>Our migration story began in August 2019 when we moved our first service\u2014the GitLab Container Registry\u2014into Kubernetes. This mission-critical, high-traffic service was well suited for the first migration because it is a stateless application with few external dependencies. The first issue we encountered was a large number of evicted pods due to insufficient memory on the nodes. As a result, we had to adjust the requests and limits.<\/p>\n<p>It was discovered that for applications with increasing memory consumption over time, low request values (reserving memory for each pod) combined with a 'generous' hard limit on usage led to saturation. <i>(saturation)<\/i> of the nodes and a high eviction rate. To resolve this issue, we decided to increase requests and lower limits. <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-com\/gl-infra\/delivery\/-\/issues\/998#note_388983696\">It was decided to increase the requests and decrease the limits.<\/a><\/noindex>This relieved the pressure on the nodes and ensured a pod lifecycle that did not exert excessive strain on the node. Now we start migrations with generous (and nearly equal) request and limit values, adjusting them as necessary.<\/p>\n<h3>3. Metrics and Logs<\/h3>\n<p>\n<img decoding=\"async\" alt=\"Our Findings on the Year of Migration of GitLab.com to Kubernetes\" src=\"\/wp-content\/uploads\/2020\/09\/66d1fd47b57d5826f13defa6e6a7fe3c.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<i>The infrastructure department focuses on latencies, error percentages, and saturation against set <\/i><noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Service-level_objective\"><i>service level objectives<\/i><\/a><\/noindex><i> (SLOs) tied to <\/i><noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-com\/dashboards-gitlab-com\/-\/metrics\/sla-dashboard.yml?environment=1790496&amp;duration_seconds=86400\"><i>the overall availability of our system.<\/i><\/a><\/noindex><i>.<\/i><\/p>\n<p>Over the past year, one of the key events in the infrastructure department has been improvements in monitoring and working with SLOs. SLOs allowed us to set targets for individual services, which we closely monitored during the migration. But even with this improved observability, it is not always possible to immediately see problems using metrics and alerts. For example, by focusing on latencies and error percentages, we do not fully cover all scenarios of the service undergoing migration.<\/p>\n<p>This issue was discovered almost immediately after transferring part of the workloads to the cluster. It became particularly acute when verifying functions with a low number of requests but very specific configuration dependencies. One of the key lessons learned from the migration was the need to consider not only metrics in monitoring but also logs and the 'long tail' <i>(referring to <\/i><noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Long_tail\"><i>such distribution<\/i><\/a><\/noindex><i> on the graph - translator's note)<\/i> of errors. Now for each migration, we include a detailed list of log queries <i>(log queries)<\/i> and plan clear rollback procedures that can be handed from one shift to another in case of issues.<\/p>\n<p>Parallel servicing of the same requests on the old VM infrastructure and the new Kubernetes-based one presented a unique challenge. Unlike a lift-and-shift migration <i>(quickly moving applications 'as is' to new infrastructure; more details can be read, for example, <\/i><noindex><a rel=\"nofollow\" href=\"https:\/\/www.ibm.com\/cloud\/learn\/lift-and-shift\"><i>here<\/i><\/a><\/noindex><i> - translator's note)<\/i>, running parallel on \"old\" VMs and Kubernetes requires monitoring tools to be compatible with both environments and capable of combining metrics into a single view. It's essential that we use the same dashboards and log queries to achieve consistent observability during the transition period.<\/p>\n<h3>4. Switching traffic to the new cluster<\/h3>\n<p>\nFor GitLab.com, part of the servers is allocated for <noindex><a rel=\"nofollow\" href=\"https:\/\/about.gitlab.com\/handbook\/engineering\/#canary-testing\">the canary stage<\/a><\/noindex>. The canary cluster serves our internal projects and can also be <noindex><a rel=\"nofollow\" href=\"https:\/\/next.gitlab.com\/\">activated by users<\/a><\/noindex>. However, it is primarily designed to test changes made to the infrastructure and application. The first migrated service started by handling a limited amount of internal traffic, and we continue to use this method to ensure SLO compliance before directing all traffic to the cluster.<\/p>\n<p>In the case of migration, this means that initially requests to internal projects are directed to Kubernetes, and then we gradually switch the remaining traffic to the cluster by adjusting the weight for the backend through HAProxy. During the transition from VMs to Kubernetes, it became clear that having a straightforward method for redirecting traffic between the old and new infrastructure was highly beneficial, allowing us to keep the old infrastructure ready for a rollback in the first few days after migration.<\/p>\n<h3>5. Pod Reserve Capacity and Its Usage<\/h3>\n<p>\nAlmost immediately, the next problem was identified: the pods for the Registry service started quickly, but the launch of the pods for Sidekiq took up to <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-org\/charts\/gitlab\/-\/issues\/1775\">two minutes.<\/a><\/noindex>. The prolonged start-up of Sidekiq pods became problematic as we began migrating the workloads for the workers that needed to quickly process jobs and scale rapidly.<\/p>\n<p>In this case, the lesson was that although the Horizontal Pod Autoscaler (HPA) in Kubernetes effectively handles traffic growth, it's essential to consider the workload characteristics and allocate backup pod resources (especially under uneven demand distribution). In our situation, there was a sudden spike in jobs, leading to rapid scaling, which caused CPU resources to become saturated before we could scale the node pool.<\/p>\n<p>There's always a temptation to push the cluster to its limits, but having initially faced performance issues, we now start with a generous pod budget and reduce it later while closely monitoring the SLO. The launch of pods for the Sidekiq service has significantly accelerated and now averages around 40 seconds. <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/gitlab-org\/charts\/gitlab\/-\/issues\/1775\">From reducing pod launch times<\/a><\/noindex> both GitLab.com and our self-managed installation users working with the official GitLab Helm chart have benefited.<\/p>\n<h2>Conclusion<\/h2>\n<p>\nAfter migrating each service, we rejoiced in the advantages of using Kubernetes in production: faster and more secure application deployment, scaling, and more efficient resource allocation. Moreover, the benefits of migration extend beyond the GitLab.com service. Users also benefit from each improvement to the official Helm chart.<\/p>\n<p>I hope you enjoyed the story of our adventures with migrating to Kubernetes. We continue to migrate more and more services into the cluster. Additional information can be gleaned from the following publications:<\/p>\n<ul>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/about.gitlab.com\/handbook\/engineering\/infrastructure\/production\/kubernetes\/gitlab-com\/\">Why are we migrating to Kubernetes?<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/about.gitlab.com\/handbook\/engineering\/infrastructure\/production\/architecture\/#gitlab-com-on-kubernetes\">GitLab.com on Kubernetes<\/a><\/noindex>\u00bb;<\/li>\n<li> <noindex><a rel=\"nofollow\" href=\"https:\/\/gitlab.com\/groups\/gitlab-com\/gl-infra\/-\/epics\/112\">Epic on GitLab.com migration to Kubernetes<\/a><\/noindex>.<\/li>\n<\/ul>\n<p><\/p>\n<h2>P.S. from the translator<\/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\/519962\/\">3 years with Kubernetes in production: here's what we learned<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/504396\/\">10 common mistakes when using Kubernetes<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/335814\/\">Success stories of Kubernetes in production. Part 3: GitHub<\/a><\/noindex>\u00bb;<\/li>\n<li> \u00ab<noindex><a rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/440278\/\">Tinder's transition to Kubernetes<\/a><\/noindex>\u00bb.<\/li>\n<\/ul>\n<p>Source: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/flant\/blog\/520150\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041f\u0440\u0438\u043c. \u043f\u0435\u0440\u0435\u0432.: \u0430\u0434\u0430\u043f\u0442\u0430\u0446\u0438\u044e Kubernetes \u0432 GitLab \u0441\u0447\u0438\u0442\u0430\u044e\u0442 \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u0434\u0432\u0443\u0445 \u0433\u043b\u0430\u0432\u043d\u044b\u0445 \u0444\u0430\u043a\u0442\u043e\u0440\u043e\u0432, \u0441\u043f\u043e\u0441\u043e\u0431\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0440\u043e\u0441\u0442\u0443 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438. \u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435, \u0434\u043e \u043d\u0435\u0434\u0430\u0432\u043d\u0435\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043e\u043d\u043b\u0430\u0439\u043d-\u0441\u0435\u0440\u0432\u0438\u0441\u0430 GitLab.com \u0431\u044b\u043b\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d\u0430 \u043d\u0430 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0448\u0438\u043d\u0430\u0445, \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u043a\u043e\u043b\u043e \u0433\u043e\u0434\u0430 \u043d\u0430\u0437\u0430\u0434 \u043d\u0430\u0447\u0430\u043b\u0430\u0441\u044c \u0435\u0451 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044f \u0432 K8s, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0434\u043e \u0441\u0438\u0445 \u043f\u043e\u0440 \u043d\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u0430. \u0420\u0430\u0434\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u0435\u0440\u0435\u0432\u043e\u0434 \u043d\u0435\u0434\u0430\u0432\u043d\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 SRE-\u0438\u043d\u0436\u0435\u043d\u0435\u0440\u0430 GitLab \u043e \u0442\u043e\u043c, \u043a\u0430\u043a [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":94978,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-94977","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=\"\u041f\u0440\u0438\u043c. \u043f\u0435\u0440\u0435\u0432.: \u0430\u0434\u0430\u043f\u0442\u0430\u0446\u0438\u044e Kubernetes \u0432 GitLab \u0441\u0447\u0438\u0442\u0430\u044e\u0442 \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u0434\u0432\u0443\u0445 \u0433\u043b\u0430\u0432\u043d\u044b\u0445 \u0444\u0430\u043a\u0442\u043e\u0440\u043e\u0432, \u0441\u043f\u043e\u0441\u043e\u0431\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0440\u043e\u0441\u0442\u0443 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438.\" \/>\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\/nashi-vyvody-za-god-migraczii-gitlab-com-na-kubernetes\" \/>\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\u041d\u0430\u0448\u0438 \u0432\u044b\u0432\u043e\u0434\u044b \u0437\u0430 \u0433\u043e\u0434 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438 GitLab.com \u043d\u0430 Kubernetes | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041f\u0440\u0438\u043c. \u043f\u0435\u0440\u0435\u0432.: \u0430\u0434\u0430\u043f\u0442\u0430\u0446\u0438\u044e Kubernetes \u0432 GitLab \u0441\u0447\u0438\u0442\u0430\u044e\u0442 \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u0434\u0432\u0443\u0445 \u0433\u043b\u0430\u0432\u043d\u044b\u0445 \u0444\u0430\u043a\u0442\u043e\u0440\u043e\u0432, \u0441\u043f\u043e\u0441\u043e\u0431\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0440\u043e\u0441\u0442\u0443 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/nashi-vyvody-za-god-migraczii-gitlab-com-na-kubernetes\" \/>\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-09-24T05:43:00+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-09-24T05:43:00+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\udd47Our conclusions from a year of migrating GitLab.com to Kubernetes | ProHoster","description":"Translator's note: the adaptation of Kubernetes in GitLab is considered one of the two main factors contributing to the company's growth.","canonical_url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/nashi-vyvody-za-god-migraczii-gitlab-com-na-kubernetes","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\u041d\u0430\u0448\u0438 \u0432\u044b\u0432\u043e\u0434\u044b \u0437\u0430 \u0433\u043e\u0434 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u0438 GitLab.com \u043d\u0430 Kubernetes | ProHoster","og:description":"\u041f\u0440\u0438\u043c. \u043f\u0435\u0440\u0435\u0432.: \u0430\u0434\u0430\u043f\u0442\u0430\u0446\u0438\u044e Kubernetes \u0432 GitLab \u0441\u0447\u0438\u0442\u0430\u044e\u0442 \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u0434\u0432\u0443\u0445 \u0433\u043b\u0430\u0432\u043d\u044b\u0445 \u0444\u0430\u043a\u0442\u043e\u0440\u043e\u0432, \u0441\u043f\u043e\u0441\u043e\u0431\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0440\u043e\u0441\u0442\u0443 \u043a\u043e\u043c\u043f\u0430\u043d\u0438\u0438.","og:url":"https:\/\/prohoster.info\/en\/blog\/administrirovanie\/nashi-vyvody-za-god-migraczii-gitlab-com-na-kubernetes","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-09-24T05:43:00+00:00","article:modified_time":"2020-09-24T05:43:00+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"94977","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 11:14:45","updated":"2022-10-03 07:39:43","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\/94977","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=94977"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/posts\/94977\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media\/94978"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/media?parent=94977"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/categories?post=94977"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/en\/wp-json\/wp\/v2\/tags?post=94977"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}