{"id":1342758,"date":"2025-11-13T17:35:38","date_gmt":"2025-11-13T16:35:38","guid":{"rendered":"https:\/\/www.luklagroup.com\/uncategorized\/a-basic-structure-for-deploying-on-kubernetes\/"},"modified":"2026-01-21T14:51:35","modified_gmt":"2026-01-21T13:51:35","slug":"a-basic-structure-for-deploying-on-kubernetes","status":"publish","type":"post","link":"https:\/\/www.luklagroup.com\/en\/apps-data-en\/a-basic-structure-for-deploying-on-kubernetes\/","title":{"rendered":"A basic structure for deploying on Kubernetes"},"content":{"rendered":"\n<div class=\"wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-6c531013 wp-block-group-is-layout-flex\">\n<p>You&#8217;ve discovered all the features Kubernetes has to offer and you&#8217;re convinced?  <br\/>It&#8217;s exactly what you need for your website!<br\/><br\/>But now it&#8217;s time to get started. And where do you start <strong>when you&#8217;re starting from scratch<\/strong>? In this article, we propose a basic foundation that will enable you to get started with peace of mind, with a solution that is structured, readable and therefore easy to maintain. Please note, however, that in order to follow this article, and above all to implement this proposal, it is recommended that you have a thorough understanding of the basic concepts of Kubernetes.   <\/p>\n\n\n\n<p><\/p>\n<\/div>\n\n<h1 class=\"wp-block-heading\"><a href=\"#les-outils-de-base\"><\/a><strong><em>Basic tools<\/em><\/strong><\/h1>\n\n<p>First of all, here are the main tools we&#8217;ll be using:<\/p>\n\n<ul class=\"wp-block-list\">\n<li>kubectl<\/li>\n\n\n\n<li>helm (secrets\/diff)<\/li>\n\n\n\n<li>sops<\/li>\n\n\n\n<li>helmfile<\/li>\n\n\n\n<li>git<\/li>\n<\/ul>\n\n<p>To easily version your configurations and keep track of our deployments, we use <strong>helmfile<\/strong>, which, like docker compose, lets you <strong>declare environments<\/strong>. It&#8217;s much simpler than rewriting all helm commands from scratch (re-specifying namespace, values file etc.)! <\/p>\n\n<h1 class=\"wp-block-heading\"><a href=\"#architecture\"><\/a><strong><em>Architecture<\/em><\/strong><\/h1>\n\n<p>With kubernetes, when you start with an &#8220;empty&#8221; cluster, there are basically only the pods used to run the nodes, all in <strong>kube-* namespaces<\/strong>.<\/p>\n\n<p>To organize our resources properly, we&#8217;ll use several namespaces such as <code>reverse-proxy<\/code>, <code>monitoring<\/code>, <code>logging<\/code>&#8230; This will enable us to easily grant more detailed rights to users connected to the cluster. <\/p>\n\n<p>The first step is to divide our configurations into several git repositories:<\/p>\n\n<ul class=\"wp-block-list\">\n<li><strong>Kubernetes Common<\/strong>:<br\/>Enables the instantiation of elements that must be unique to the entire cluster. These include the kubernetes dashboard, reverse-proxy, monitoring and more&#8230; <\/li>\n\n\n\n<li><strong>Kubernetes your-site deployments<\/strong>:<br\/>Contains everything you need to deploy your site&#8217;s various environments. If you want to commit a new version of your site, this repository is the place to do it. <\/li>\n\n\n\n<li><strong>Helm Chart frontend<\/strong>:<br\/>This defines all the components needed to deploy your site. These can be <code>deployments<\/code>, <code>services<\/code>, <code>secrets<\/code>&#8230; <\/li>\n\n\n\n<li><strong>Helm Chart xxx<\/strong>:<br\/>All your other customized charts, such as an api or other&#8230;<\/li>\n<\/ul>\n\n<h1 class=\"wp-block-heading\"><a href=\"#%C3%A0-quoi-%C3%A7a-ressemble-\" target=\"_blank\" rel=\"noreferrer noopener\"><\/a><strong><em>What does it look like?<\/em><\/strong><\/h1>\n\n<h2 class=\"wp-block-heading\"><a href=\"#kubernetes-common\"><\/a>Kubernetes common<\/h2>\n\n<p>We start with a file <code>helmfile.yaml<\/code> which will contain the list of our helm releases. ex : <\/p>\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\nreleases:\n  - name: traefik\n  chart: traefik\/traefik\n  version: x.x.x\n  namespace: reverse-proxy\n  secrets:\n  - .\/traefik.values.encrypted.yml\n\n  - name: cert-manager\n  chart: jetstack\/cert-manager\n  version: x.x.x\n  namespace: reverse-proxy\n  values:\n  - .\/cert-manager.values.yml\n<\/pre><\/div>\n<pre id=\"code-135\" class=\"wp-block-code\"><code><\/code><\/pre>\n\n<p><code>cert-manager.yaml<\/code><\/p>\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\ncrds:\n  enabled: true\n  keep: true\n<\/pre><\/div>\n<p>Once we&#8217;ve configured our values for the various tools, all that&#8217;s left to do is run the <code>helmfile apply<\/code> command.<\/p>\n\n<p>It is sometimes necessary to include sensitive data in value files, such as a private key. You can encrypt these files using <a href=\"https:\/\/github.com\/getsops\/sops\" rel=\"noreferrer noopener\" target=\"_blank\">sops<\/a> and <a href=\"https:\/\/github.com\/jkroepke\/helm-secrets\" rel=\"noreferrer noopener\" target=\"_blank\">helm secrets<\/a>, allowing helm to decrypt the files before applying them. <\/p>\n\n<h2 class=\"wp-block-heading\"><a href=\"#kubernetes-votre-site-deployments\"><\/a><strong><em>Kubernetes your-site deployments<\/em><\/strong><\/h2>\n\n<p>This file will be different from the common one, because it will have an extra dimension: <strong>the environment<\/strong>.<\/p>\n\n<p><code>helmfile.yaml<\/code><\/p>\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: yaml; title: ; notranslate\" title=\"\">\nenvironments:\n  preprod: {}\n  prod: {}\n\nrepositories:\n  - name: ma-stack\n  url: https:\/\/url-du-repo\n\nreleases:\n  - name: frontend\n  chart: ma-stack\/frontend\n  version: 1.0.0\n  namespace: &quot;{{ .Environment.Name }}&quot;\n  secrets:\n  - .\/{{ .Environment.Name }}\/frontend.values.encrypted.yaml\n\n  - name: api\n  chart: ma-stack\/api\n  version: 1.0.0\n  namespace: prod\n  secrets:\n  - .\/prod\/api.values.encrypted.yaml\n\n  - name: api\n  chart: ma-stack\/api\n  version: 2.0.0\n  namespace: preprod\n  secrets:\n  - .\/preprod\/api.values.encrypted.yaml\n<\/pre><\/div>\n<p>Adding the notion of environment to this helmfile means you can deploy a specific version for each environment.<\/p>\n\n<p>In this example, version 1.0.0 of the frontend chart is deployed twice: once on the prod environment and once on the preprod environment. The difference may lie in the values file, which will contain different settings depending on the target environment.<br\/>For example, values files generally specify the tag of the deployed docker image, which in this case means that two different versions of the site can be deployed on each environment. <\/p>\n\n<p>Concerning the api, this one has a <strong>new version of the chart<\/strong> in preprod. This makes it possible to add a new kubernetes element, such as a new <code>service<\/code> or other&#8230; Hence the importance of extracting the chart from your front-end\/api in another repository.  <\/p>\n\n<p>After all that, we can apply this configuration with <code>helmfile apply<\/code> and it delivers all the necessary modifications on all environments!<\/p>\n\n<h1 class=\"wp-block-heading\"><a href=\"#ensuite-\"><\/a><strong><em>What&#8217;s next?<\/em><\/strong><\/h1>\n\n<p>With this distribution between different projects, all that remains is to implement the CD.<br\/>Configuration deployment can therefore be automatic, and our repositories will be the source of truth for the state of your cluster.<br\/>In your integration chain, updating an application will consist of committing to these repositories.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>You&#8217;ve discovered all the features Kubernetes has to offer and you&#8217;re convinced? It&#8217;s exactly what you need for your website! But now it&#8217;s time to get started. And where do you start when you&#8217;re starting from scratch? In this article, we propose a basic foundation that will enable you to get started with peace of [&hellip;]<\/p>\n","protected":false},"author":27,"featured_media":1016888,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_seopress_robots_primary_cat":"","_seopress_titles_title":"Getting started with Kubernetes: structure, tools and deployment","_seopress_titles_desc":"Discover how to structure your projects and deploy serenely with Kubernetes thanks to a clear architecture, key tools and concrete examples.","_seopress_robots_index":"","footnotes":""},"categories":[109,115],"tags":[289,288,287],"class_list":{"0":"post-1342758","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-apps-data-en","8":"category-web-marketing-en","9":"tag-architecture-en","10":"tag-code-en","11":"tag-kubernetes-en"},"_links":{"self":[{"href":"https:\/\/www.luklagroup.com\/en\/wp-json\/wp\/v2\/posts\/1342758","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.luklagroup.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.luklagroup.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.luklagroup.com\/en\/wp-json\/wp\/v2\/users\/27"}],"replies":[{"embeddable":true,"href":"https:\/\/www.luklagroup.com\/en\/wp-json\/wp\/v2\/comments?post=1342758"}],"version-history":[{"count":1,"href":"https:\/\/www.luklagroup.com\/en\/wp-json\/wp\/v2\/posts\/1342758\/revisions"}],"predecessor-version":[{"id":1342760,"href":"https:\/\/www.luklagroup.com\/en\/wp-json\/wp\/v2\/posts\/1342758\/revisions\/1342760"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.luklagroup.com\/en\/wp-json\/wp\/v2\/media\/1016888"}],"wp:attachment":[{"href":"https:\/\/www.luklagroup.com\/en\/wp-json\/wp\/v2\/media?parent=1342758"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.luklagroup.com\/en\/wp-json\/wp\/v2\/categories?post=1342758"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.luklagroup.com\/en\/wp-json\/wp\/v2\/tags?post=1342758"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}