├── .gitignore ├── LICENSE ├── README.md ├── diagrams ├── do-creating-kubernetes-cluster.png ├── do-token.png ├── flux-overview.svg ├── github-deploy-keys.png ├── github-fork.png ├── terraform-advance-options.png ├── terraform-apply.png ├── terraform-auto-apply.png ├── terraform-digitalocean-kubernetes.svg ├── terraform-envs.png ├── terraform-github.png ├── terraform-organization.png └── terraform-queue-plan.png ├── docs ├── en │ ├── 01-client-tools.md │ ├── 02-setup-repository.md │ ├── 03-setup-digital-ocean.md │ ├── 04-setup-terraform-cloud.md │ ├── 05-create-cluster.md │ ├── 06-install-fluxcd.md │ ├── 07-syncronice-github-fluxcd.md │ ├── 08-sealed-secrests.md │ └── 09-cleaning-up.md └── es │ ├── 01-client-tools.md │ ├── 02-setup-repository.md │ ├── 03-setup-digital-ocean.md │ ├── 04-setup-terraform.md │ ├── 05-create-cluster.md │ ├── 06-install-fluxcd.md │ ├── 07-syncronice-github-fluxcd.md │ ├── 08-sealed-secrests.md │ ├── 09-cleaning-up.md │ └── README.md ├── infra └── cluster.tf ├── namespaces ├── admin │ ├── namespace.yaml │ └── sealed-secrets │ │ └── sealed-secrets.yaml ├── client-abc │ ├── deployment.yaml │ └── namespace.yaml ├── client-def │ ├── deployment.yaml │ └── namespace.yaml ├── flux-system │ └── namespace.yaml └── kube-system │ ├── kube-state-metrics │ └── kube-state-metrics.yaml │ └── metrics-server │ └── metrics-server.yaml └── scripts └── install.sh /.gitignore: -------------------------------------------------------------------------------- 1 | # Local .terraform directories 2 | **/.terraform/* 3 | 4 | # .tfstate files 5 | *.tfstate 6 | *.tfstate.* 7 | 8 | # Crash log files 9 | crash.log 10 | 11 | # Ignore any .tfvars files that are generated automatically for each Terraform run. Most 12 | # .tfvars files are managed as part of configuration and so should be included in 13 | # version control. 14 | # 15 | # example.tfvars 16 | 17 | # Ignore override files as they are usually used to override resources locally and so 18 | # are not checked in 19 | override.tf 20 | override.tf.json 21 | *_override.tf 22 | *_override.tf.json 23 | 24 | # Include override files you do wish to add to version control using negated pattern 25 | # 26 | # !example_override.tf 27 | 28 | # Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan 29 | # example: *tfplan* 30 | 31 | # General 32 | .DS_Store 33 | .AppleDouble 34 | .LSOverride 35 | 36 | # Icon must end with two \r 37 | Icon 38 | 39 | # Thumbnails 40 | ._* 41 | 42 | # Files that might appear in the root of a volume 43 | .DocumentRevisions-V100 44 | .fseventsd 45 | .Spotlight-V100 46 | .TemporaryItems 47 | .Trashes 48 | .VolumeIcon.icns 49 | .com.apple.timemachine.donotpresent 50 | 51 | # Directories potentially created on remote AFP share 52 | .AppleDB 53 | .AppleDesktop 54 | Network Trash Folder 55 | Temporary Items 56 | .apdisk 57 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Manuel Morejón 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gitops-get-started 2 | 3 | Si lo desea puede leer la documentación en [Español](docs/es/README.md). 4 | 5 | Project to take the first steps in the GitOps work philosophy using Flux CD. 6 | 7 | The project shows how to configure a Kubernetes cluster based on GitOps. The organization of folders and services deployed correspond to a hypothetical cluster used for development or staging environments. This cluster configuration is not ready to be used in production. 8 | 9 | To get more out of the repository it is recommended to have basic knowledge about the GitOps work philosophy. You can expand your knowledge on this topic through [this link from the Weaveworks website](https://www.weave.works/technologies/gitops/). 10 | 11 | The systems used during the exercise were: [Git](https://git-scm.com/), [Terraform](https://www.terraform.io/), [Docker](https://www.docker.com/), [Flux CD](https://fluxcd.io/) y [Kubernetes](https://kubernetes.io/). The platform used to create the Kubernetes cluster is [Digital Ocean](https://www.digitalocean.com/), but [Minikube](https://minikube.sigs.k8s.io/) can also be used. 12 | 13 | Flow to manage the infrastructure 14 | 15 | ![Infrastructure Overview](diagrams/terraform-digitalocean-kubernetes.svg) 16 | 17 | ---- 18 | 19 | Flow to manage the Kubernetes 20 | 21 | ![Flux Overview](diagrams/flux-overview.svg) 22 | 23 | ## Folder structure 24 | 25 | ```bash 26 | ├── infra 27 | │ └── cluster.tf 28 | ├── namespaces 29 | │ ├── admin 30 | │ │ ├── namespace.yaml 31 | │ │ └── sealed-secrets 32 | │ │ └── sealed-secrets.yaml 33 | │ ├── client-abc 34 | │ │ ├── deployment.yaml 35 | │ │ └── namespace.yaml 36 | │ ├── client-def 37 | │ │ ├── deployment.yaml 38 | │ │ └── namespace.yaml 39 | │ ├── flux-system 40 | │ │ └── namespace.yaml 41 | │ └── kube-system 42 | │ ├── kube-state-metrics 43 | │ │ └── kube-state-metrics.yaml 44 | │ └── metrics-server 45 | │ └── metrics-server.yaml 46 | └── scripts 47 | └── install.sh 48 | ``` 49 | 50 | | Folder | Description | 51 | | ---------- | ------ | 52 | | infra | Terraforms files to create the infrastructure in Digital Ocean. (Optional) | 53 | | namespaces | Structure of namespaces used in the cluster. Within each namespace are the applications that will be deployed. | 54 | | scripts | General utility folder. | 55 | 56 | ## Case Study Sections 57 | 58 | The following links will guide you in the creation of a Kubernetes cluster using the GitOps work philosophy. 59 | 60 | * [Tools needed](docs/en/01-client-tools.md) 61 | * [Setup the repository](docs/en/02-setup-repository.md) 62 | * [Setup Digital Ocean](docs/en/03-setup-digital-ocean.md) 63 | * [Setup Terraform Cloud](docs/en/04-setup-terraform-cloud.md) 64 | * [Create Kubernetes cluster](docs/en/05-create-cluster.md) 65 | * [Install Flux CD](docs/en/06-install-fluxcd.md) 66 | * [Synchronize GitHub <-> Flux CD](docs/en/07-syncronice-github-fluxcd.md) 67 | * [Manage Secrets using Sealed Secrets](docs/en/08-sealed-secrests.md) 68 | * [Cleaning Up](docs/en/09-cleaning-up.md) 69 | -------------------------------------------------------------------------------- /diagrams/do-creating-kubernetes-cluster.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmorejon/gitops-get-started/780f11d3ef7401a9ae35292e972eeb1654a6a56c/diagrams/do-creating-kubernetes-cluster.png -------------------------------------------------------------------------------- /diagrams/do-token.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmorejon/gitops-get-started/780f11d3ef7401a9ae35292e972eeb1654a6a56c/diagrams/do-token.png -------------------------------------------------------------------------------- /diagrams/github-deploy-keys.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmorejon/gitops-get-started/780f11d3ef7401a9ae35292e972eeb1654a6a56c/diagrams/github-deploy-keys.png -------------------------------------------------------------------------------- /diagrams/github-fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmorejon/gitops-get-started/780f11d3ef7401a9ae35292e972eeb1654a6a56c/diagrams/github-fork.png -------------------------------------------------------------------------------- /diagrams/terraform-advance-options.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmorejon/gitops-get-started/780f11d3ef7401a9ae35292e972eeb1654a6a56c/diagrams/terraform-advance-options.png -------------------------------------------------------------------------------- /diagrams/terraform-apply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmorejon/gitops-get-started/780f11d3ef7401a9ae35292e972eeb1654a6a56c/diagrams/terraform-apply.png -------------------------------------------------------------------------------- /diagrams/terraform-auto-apply.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmorejon/gitops-get-started/780f11d3ef7401a9ae35292e972eeb1654a6a56c/diagrams/terraform-auto-apply.png -------------------------------------------------------------------------------- /diagrams/terraform-digitalocean-kubernetes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 |
commit
commit
trigger
trigger
Digital Ocean
API
Digital Ocean...
terraform apply
terraform apply
Kubernetes
Kubernetes
Node Pool
Node Pool
terraform apply
terraform apply
Viewer does not support full SVG 1.1
-------------------------------------------------------------------------------- /diagrams/terraform-envs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmorejon/gitops-get-started/780f11d3ef7401a9ae35292e972eeb1654a6a56c/diagrams/terraform-envs.png -------------------------------------------------------------------------------- /diagrams/terraform-github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmorejon/gitops-get-started/780f11d3ef7401a9ae35292e972eeb1654a6a56c/diagrams/terraform-github.png -------------------------------------------------------------------------------- /diagrams/terraform-organization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmorejon/gitops-get-started/780f11d3ef7401a9ae35292e972eeb1654a6a56c/diagrams/terraform-organization.png -------------------------------------------------------------------------------- /diagrams/terraform-queue-plan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mmorejon/gitops-get-started/780f11d3ef7401a9ae35292e972eeb1654a6a56c/diagrams/terraform-queue-plan.png -------------------------------------------------------------------------------- /docs/en/01-client-tools.md: -------------------------------------------------------------------------------- 1 | # Tools needed 2 | 3 | In this section you will know the command line tools that you will need throughout the exercise. 4 | 5 | ## Kubectl 6 | 7 | `kubectl` is the tool that will allow you to interact with the Kubernetes cluster. 8 | 9 | It is necessary to have `kubectl` installed in a version equal to or greater than `v1.16.3`. 10 | 11 | Use the following link to access the installation instructions: 12 | 13 | ```bash 14 | kubectl version --client 15 | 16 | Client Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.3", GitCommit:"b3cbbae08ec52a7fc73d334838e18d17e8512749", GitTreeState 17 | :"clean", BuildDate:"2019-11-14T04:24:29Z", GoVersion:"go1.12.13", Compiler:"gc", Platform:"darwin/amd64"} 18 | ``` 19 | 20 | ## Helm 3 21 | 22 | `helm` is the tool that will allow you to package and manage Kubernetes applications. 23 | 24 | It is necessary to have `helm` installed in a version equal to or greater than `v3.1.1`. 25 | 26 | Use the following link to access the installation instructions: 27 | 28 | ```bash 29 | helm version 30 | 31 | version.BuildInfo{Version:"v3.1.1", GitCommit:"afe70585407b420d0097d07b21c47dc511525ac8", GitTreeState:"clean", GoVersion:"go1.13.8"} 32 | ``` 33 | 34 | Add FluxCD repository to Helm repos: 35 | 36 | ```bash 37 | helm repo add fluxcd https://charts.fluxcd.io 38 | ``` 39 | 40 | Update Helm repositories 41 | 42 | ```bash 43 | helm repo update 44 | 45 | Hang tight while we grab the latest from your chart repositories... 46 | ...Successfully got an update from the "fluxcd" chart repository 47 | ...Successfully got an update from the "stable" chart repository 48 | Update Complete. ⎈ Happy Helming!⎈ 49 | ``` 50 | 51 | ## Flux CD 52 | 53 | `fluxctl` is the tool that will allow you to access the Flux CD service installed in the Kubernetes cluster. 54 | 55 | It is necessary to have `fluxctl` installed in a version equal to or greater than `1.19.0`. 56 | 57 | Use the following link to access the installation instructions: 58 | 59 | ```bash 60 | fluxctl version 61 | 62 | 1.19.0 63 | ``` 64 | 65 | Next: [Setup the repository](02-setup-repository.md) 66 | -------------------------------------------------------------------------------- /docs/en/02-setup-repository.md: -------------------------------------------------------------------------------- 1 | # Setup the repository 2 | 3 | This section will indicate the steps to follow to configure the code repository. 4 | 5 | ## Fork the repository 6 | 7 | Make a fork of the repository to your work area in GitHub. This way you can modify the code freely. 8 | 9 | ![GitHub fork](../../diagrams/github-fork.png) 10 | 11 | ## Clone the repository 12 | 13 | Clone the repository to your computer: 14 | 15 | > Change `YOUR-GITHUB-USER` by your user on GitHub. 16 | 17 | ```bash 18 | git clone git@github.com:YOUR-GITHUB-USER/gitops-get-started.git 19 | ``` 20 | 21 | Access the cloned repository directory: 22 | 23 | ```bash 24 | cd gitops-get-started 25 | ``` 26 | 27 | ## Modify the installation file 28 | 29 | Modify the installation file so that it uses your repository as the source of origin: 30 | 31 | > Change `YOUR-GITHUB-USER` by your user on GitHub. 32 | 33 | ```bash 34 | sed -i "" "s/mmorejon/YOUR-GITHUB-USER/g" scripts/install.sh 35 | ``` 36 | 37 | Commit the changes and send them to your repository on GitHub: 38 | 39 | ```bash 40 | git add scripts/install.sh 41 | git commit -sm 'Change github repository.' 42 | git push origin master 43 | ``` 44 | 45 | Next: [Setup Digital Ocean](03-setup-digital-ocean.md) 46 | -------------------------------------------------------------------------------- /docs/en/03-setup-digital-ocean.md: -------------------------------------------------------------------------------- 1 | # Setup Digital Ocean 2 | 3 | Digital Ocean is the platform selected to create the Kubernetes cluster. If this is the first time you have heard about this platform, do not worry, because all your services can be accessed easily and easily. 4 | 5 | ## Create new user on Digital Ocean 6 | 7 | If you do not have a user on the Digital Ocean platform, you can [use this link to create an account with $ 100 of credit at startup](https://m.do.co/c/fb2c605da7ee). The cost of the exercise performed in this laboratory is $ 20 per month (**$ 0.030 per hour**). 8 | 9 | ## Create a personal token 10 | 11 | The personal access token will be used to manage the components of the platform through the `doctl` client. 12 | 13 | * Access the [API section](https://cloud.digitalocean.com/account/api/tokens) and generate a new token with read and write permissions. 14 | * Copy and save the generated code securely for used in the next sections. 15 | 16 | After creating the token you should obtain a result similar to the one shown in the following image. 17 | 18 | ![Digital Ocean Token](../../diagrams/do-token.png) 19 | 20 | ## Intall doctl 21 | 22 | `doctl` is the Digital Ocean client. Through this system you can access to all the resources of the platform from the Terminal. 23 | 24 | Use the following link to install `doctl`: 25 | 26 | The version to be installed must be equal to or greater than `1.41.0`. 27 | 28 | ```bash 29 | doctl version 30 | 31 | doctl version 1.41.0-release 32 | ``` 33 | 34 | ## Setup doctl 35 | 36 | Use the `auth init` command to authenticate the `doctl` client with the platform. Use the token generated in the previous section as the input parameter. 37 | 38 | ```bash 39 | doctl auth init 40 | 41 | DigitalOcean access token: 42 | Validating token... OK 43 | ``` 44 | 45 | Check that there is good communication between the `doctl` client and the platform. List the Kubernetes available versions in the platform using the following command: 46 | 47 | ```bash 48 | doctl kubernetes options versions 49 | 50 | Slug Kubernetes Version 51 | 1.16.6-do.2 1.16.6 52 | 1.15.9-do.2 1.15.9 53 | 1.14.10-do.2 1.14.10 54 | ``` 55 | 56 | Next: [Setup Terraform Cloud](04-setup-terraform-cloud.md) 57 | -------------------------------------------------------------------------------- /docs/en/04-setup-terraform-cloud.md: -------------------------------------------------------------------------------- 1 | # Setup Terraform Cloud 2 | 3 | The Terraform Cloud platform uses Infrastructure as a Code to manage and provide any cloud environment, infrastructure or service. 4 | 5 | ## Create a new user on Terraform Cloud 6 | 7 | If you do not have a user on this platform, use [this following link to create a new one](https://app.terraform.io/signup/account?utm_source=docs_banner) in the free plan. 8 | 9 | ## Create a new organization 10 | 11 | Set up a new organization to manage the project. You can use [this link](https://app.terraform.io/app/organizations/new) to access to your organizations in Terraform. 12 | 13 | ![Terraform Organization](../../diagrams/terraform-organization.png) 14 | 15 | Then, link your workspace in Terraform Cloud with your repository in GitHub. 16 | 17 | ![Terraform GitHub](../../diagrams/terraform-github.png) 18 | 19 | List the advanced options to specify the `infra` folder as the source of terraform files within the entire directory. 20 | 21 | ![Terraform Advance Options](../../diagrams/terraform-advance-options.png) 22 | 23 | ## Create environment value 24 | 25 | Configure the environment variables in Terraform Cloud to connect this platform with Digital Ocean. 26 | 27 | Add the environment variable `DIGITALOCEAN_TOKEN` together with the Digital Ocean token obtained in the previous section. 28 | 29 | > Don't forget to check the `Sensitive` box to hide the value of the token. 30 | 31 | ![Terraform Environment Values](../../diagrams/terraform-envs.png) 32 | 33 | Next: [Create Kubernetes cluster](05-create-cluster.md) 34 | -------------------------------------------------------------------------------- /docs/en/05-create-cluster.md: -------------------------------------------------------------------------------- 1 | # Create Kubernetes cluster 2 | 3 | The creation of the Kubernetes cluster will be done from Terraform Cloud. The workspace configured in the previous section will create the infrastructure from the existing code in the GitHub repository. 4 | 5 | ## Auto Apply in Terraform Cloud 6 | 7 | Terraform Cloud has two ways of setting changes: Manual and Automatic. 8 | 9 | For production environments it is advisable to use the Manual mode, in this way the other members of the team can analyze the changes and give their criteria. 10 | 11 | However, the exercise to be performed at this time does not include this scenario, therefore, the changes will be configured automatically. 12 | 13 | Access the settings of your workspace and select the `Auto apply` option. 14 | 15 | ![Terraform Auto Apply](../../diagrams/terraform-auto-apply.png) 16 | 17 | ## Create a cluster on Digital Ocean 18 | 19 | The description of the Kubernetes cluster is in the `infra / cluster.tf` file. 20 | 21 | ```bash 22 | cat infra/cluster.tf 23 | 24 | # kubernetes cluster 25 | resource "digitalocean_kubernetes_cluster" "staging" { 26 | name = "staging" 27 | region = "ams3" 28 | version = "1.16.6-do.0" 29 | tags = ["staging"] 30 | 31 | node_pool { 32 | name = "worker-pool" 33 | size = "s-1vcpu-2gb" 34 | auto_scale = true 35 | min_nodes = 2 36 | max_nodes = 5 37 | } 38 | } 39 | ``` 40 | 41 | To create the cluster use the `Queue plan` button located above and to the right of the Terraform platform. 42 | 43 | ![Terraform Queue plan](../../diagrams/terraform-queue-plan.png) 44 | 45 | Once the plan is started, you can see on your screen how the Terraform changes are applied. This action may take about 7 minutes. 46 | 47 | ![Terraform Apply](../../diagrams/terraform-apply.png) 48 | 49 | Access the Kubernetes section in Digital Ocean and note that a cluster of Kubernetes with the name `staging` has been started. 50 | 51 | ![Digital Ocean creating kubernetes cluster](../../diagrams/do-creating-kubernetes-cluster.png) 52 | 53 | Wait for the cluster to be created to perform the next step. 54 | 55 | ## Access the cluster from Kubectl 56 | 57 | Once the cluster is created, it is necessary to be able to access it from the `kubectl` tool. To achieve this, you will need to obtain the credentials of the new cluster, as well as the URL to access the Kubernetes API. 58 | 59 | Use the following command to configure the `~/.kube/config` file with the credentials of the Digital Ocean cluster: 60 | 61 | ```bash 62 | doctl kubernetes cluster kubeconfig save staging 63 | 64 | Notice: adding cluster credentials to kubeconfig file found in "/Users/......./.kube/config" 65 | Notice: setting current-context to do-ams3-staging 66 | ``` 67 | 68 | Verify that the configuration was successful. List the cluster nodes: 69 | 70 | ```bash 71 | kubectl get nodes 72 | 73 | NAME STATUS ROLES AGE VERSION 74 | worker-pool-0uc4 Ready 4m43s v1.16.6 75 | worker-pool-0uch Ready 5m38s v1.16.6 76 | ``` 77 | 78 | Next: [Install Flux CD](06-install-fluxcd.md) 79 | -------------------------------------------------------------------------------- /docs/en/06-install-fluxcd.md: -------------------------------------------------------------------------------- 1 | # Install Flux CD 2 | 3 | Once the cluster is created, the next step is to install Flux CD. This will be the only occasion that you will need to use the `kubectl` tool to establish the changes in the cluster. 4 | 5 | ## Install Flux 6 | 7 | Use the `scripts/install.sh` file to install the following services in the cluster: 8 | 9 | |Tool |Description| 10 | |-----------------|-----------| 11 | |`flux` |Tool to automate deployments in Kubernetes. It is based on the GitOps work philosophy.| 12 | |`helm-operator` |System responsible for managing Helm charts in the `flux` tool.| 13 | |`flux-memcached` |System responsible for keeping track of images and changes in the `flux` tool.| 14 | 15 | > Check in the `install.sh` file that the `--set git.url` parameter is set with your directory in GitHub. 16 | 17 | ```bash 18 | ./scripts/install.sh 19 | ``` 20 | 21 | List the services created in the namespace `flux-system` when the script finishes running: 22 | 23 | ```bash 24 | kubectl get pods -n flux-system 25 | 26 | NAME READY STATUS RESTARTS AGE 27 | flux-59bb67c8b4-h2kcp 1/1 Running 0 4m3s 28 | flux-memcached-8647794c5f-hhdzc 1/1 Running 0 4m3s 29 | helm-operator-77cb687cc7-wdcfg 1/1 Running 0 3m23s 30 | ``` 31 | 32 | You can check that all services are working correctly. 33 | 34 | Next: [Synchronize GitHub <-> Flux CD](07-syncronice-github-fluxcd.md) 35 | -------------------------------------------------------------------------------- /docs/en/07-syncronice-github-fluxcd.md: -------------------------------------------------------------------------------- 1 | # Synchronize GitHub <-> Flux CD 2 | 3 | In order for Flux to obtain the information stored in the GitHub repository, it is necessary to enable read permissions. 4 | 5 | ## Get ssh key 6 | 7 | Flux generates an ssh key when starting the system. To obtain this key use the following command: 8 | 9 | ```bash 10 | fluxctl identity --k8s-fwd-ns flux-system 11 | 12 | ssh-rsa AAAAB....... 13 | ``` 14 | 15 | ## Register key in GitHub 16 | 17 | Access the *Deploy keys* section within the repository created in GitHub. You can use the following link to achieve this: 18 | 19 | > Change `YOUR-GITHUB-USER` by your user on GitHub. 20 | 21 | 22 | 23 | Add the ssh public key generated in the previous step. 24 | 25 | > Also enable write permissions if you want Flux to make changes to the repository. 26 | 27 | ![Terraform Apply](../../diagrams/github-deploy-keys.png) 28 | 29 | ## Synchronize Flux with the repository 30 | 31 | Flux synchronizes existing changes in the repository automatically based on the time set in the `git.pollInterval` parameter. By default the value is `5m`, but if you do not want to wait this time you can use the following command: 32 | 33 | ```bash 34 | fluxctl sync --k8s-fwd-ns flux-system 35 | ``` 36 | 37 | This command line tells the flux system to synchronize the state of the cluster objects with the existing elements in the git repository. 38 | 39 | ### Logs in Flux 40 | 41 | Access the flux system logs and verify that you have successfully accessed GitHub. 42 | 43 | ```bash 44 | kubectl -n flux-system logs -l app=flux 45 | ``` 46 | 47 | ### Synchronized folders 48 | 49 | Once synchronization between Flux CD and GitHub is achieved, you can see that all the existing elements in the `namespaces` folder have been created in the cluster. 50 | 51 | ```bash 52 | kubectl get namespaces 53 | 54 | NAME STATUS AGE 55 | admin Active 17m 56 | client-abc Active 17m 57 | client-def Active 17m 58 | default Active 107m 59 | flux-system Active 60m 60 | kube-node-lease Active 107m 61 | kube-public Active 107m 62 | kube-system Active 107m 63 | ``` 64 | 65 | List the existing Pods in these namespaces and you will notice the correspondence with the services described in the GitHub repository. 66 | 67 | ```bash 68 | kubectl get pods -n client-abc && kubectl get pods -n client-def 69 | 70 | NAME READY STATUS RESTARTS AGE 71 | app-abc-6b6c9d5599-kbddb 1/1 Running 0 24m 72 | app-abc-6b6c9d5599-ltql7 1/1 Running 0 24m 73 | NAME READY STATUS RESTARTS AGE 74 | app-def-5bd5d956c5-d64r7 1/1 Running 0 24m 75 | app-def-5bd5d956c5-md5vz 1/1 Running 0 24m 76 | app-def-5bd5d956c5-vdjx2 1/1 Running 0 24m 77 | ``` 78 | 79 | ## Workflow using GitOps 80 | 81 | At this time you can manage your cluster through the GitOps work philosophy. 82 | 83 | All changes established in the cluster must be in the Git repository and it will be Flux CD who has the responsability for keeping the state of the objects in Kubernetes synchronized. 84 | 85 | ![Terraform Apply](../../diagrams/flux-overview.svg) 86 | 87 | I suggest you that from this moment modify the existing components and evaluate how they react. It is important that you understand that the existing structure in this repository corresponds to an example case, you should identify which repository structure best corresponds to your business. 88 | 89 | Next: [Manage Secrets using Sealed Secrets](08-sealed-secrests.md) 90 | -------------------------------------------------------------------------------- /docs/en/08-sealed-secrests.md: -------------------------------------------------------------------------------- 1 | # Manage Secrets using Sealed Secrets 2 | 3 | So far it has been established that all components must be registered in the code repository as the only reliable source to establish the changes, but what about the Secrets objects? 4 | 5 | Secrets cannot be managed in the same way. Before being added to version control it is important to protect the information inside. To achieve this objective, the service [Sealed Secrets developed by Bitnami](https://github.com/bitnami-labs/sealed-secrets) has been deployed in the cluster. 6 | 7 | ```bash 8 | kubectl -n admin get pods 9 | 10 | NAME READY STATUS RESTARTS AGE 11 | sealed-secrets-769745f6db-4cmkb 1/1 Running 0 59m 12 | ``` 13 | 14 | The following steps will help you create a Secret in Kubernetes while maintaining the GitOps workflow. 15 | 16 | ## Install kubeseal client 17 | 18 | `kubeseal` is the tool that will allow you to encrypt Secret information before storing it in the version controller. 19 | 20 | It is necessary to have `kubeseal` installed in a version equal to or greater than `v0.12.1`. 21 | 22 | Use the following link to access the installation instructions: 23 | 24 | ```bash 25 | kubeseal --version \ 26 | --controller-namespace=admin \ 27 | --controller-name=sealed-secrets 28 | 29 | kubeseal version: v0.12.1 30 | ``` 31 | 32 | ## Get public key 33 | 34 | When starting this service, the public and private key that will be used during the encryption processes is generated. 35 | 36 | Use the following command line to obtain the public key: 37 | 38 | ```bash 39 | kubeseal --fetch-cert \ 40 | --controller-namespace=admin \ 41 | --controller-name=sealed-secrets \ 42 | > pub-cert.pem 43 | ``` 44 | 45 | Generate a Kubernetes Secret using `kubectl`: 46 | 47 | ```bash 48 | kubectl -n client-def create secret generic magic-text \ 49 | --from-literal incantation=kubernetes \ 50 | --dry-run \ 51 | -o json > magic-text.json 52 | ``` 53 | 54 | Encrypt the Secret using `kubeseal`: 55 | 56 | ```bash 57 | kubeseal --format=yaml --cert=pub-cert.pem < magic-text.json > magic-text.yaml 58 | ``` 59 | 60 | Check that the `magic-text.yaml` file contains the encrypted information and add it to the GitHub repository. 61 | 62 | ```bash 63 | mv magic-text.yaml namespaces/client-def 64 | git add namespaces/client-def/magic-text.yaml 65 | git commit -sm 'Add magic text secret' 66 | git push origin master 67 | ``` 68 | 69 | Use `fluxctl` to synchronize the repository with the cluster: 70 | 71 | ```bash 72 | fluxctl sync --k8s-fwd-ns flux-system 73 | ``` 74 | 75 | Now list the Secrets present in the namespace `client-def`: 76 | 77 | ```bash 78 | kubectl -n client-def get secrets 79 | ``` 80 | 81 | Check that the value of the text stored in the Secret is correct: 82 | 83 | ```bash 84 | kubectl -n client-def get secrets magic-text -o jsonpath='{.data.incantation}' | base64 --decode 85 | ``` 86 | 87 | Next: [Cleaning Up](09-cleaning-up.md) 88 | -------------------------------------------------------------------------------- /docs/en/09-cleaning-up.md: -------------------------------------------------------------------------------- 1 | # Cleaning Up 2 | 3 | In this section you will delete the cluster created in Digital Ocean. 4 | 5 | ```bash 6 | doctl kubernetes cluster delete staging 7 | 8 | Warning: Are you sure you want to delete this Kubernetes cluster (y/N) ? yes 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/es/01-client-tools.md: -------------------------------------------------------------------------------- 1 | # Herramientas necesarias 2 | 3 | En esta sección conocerá las herramientas de líneas de comandos que va a necesitar a lo largo del ejercicio. 4 | 5 | ## Kubectl 6 | 7 | `kubectl` es la herramienta que le permitirá interactuar con el cluster de Kubernetes. 8 | 9 | Es necesario tener instalado `kubectl` en una versión igual o superior a la `v1.16.3`. 10 | 11 | Utilice el siguiente enlace para acceder a las instrucciones de la instalación: 12 | 13 | ```bash 14 | kubectl version --client 15 | 16 | Client Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.3", GitCommit:"b3cbbae08ec52a7fc73d334838e18d17e8512749", GitTreeState 17 | :"clean", BuildDate:"2019-11-14T04:24:29Z", GoVersion:"go1.12.13", Compiler:"gc", Platform:"darwin/amd64"} 18 | ``` 19 | 20 | ## Helm 3 21 | 22 | `helm` es la herramienta que le permitirá empaquetar y gestionar las aplicaciones de Kubernetes. 23 | 24 | Es necesario tener instalado `helm` en una versión igual o superior a la `v3.1.1`. 25 | 26 | Utilice el siguiente enlace para acceder a las instrucciones de la instalación: 27 | 28 | ```bash 29 | helm version 30 | 31 | version.BuildInfo{Version:"v3.1.1", GitCommit:"afe70585407b420d0097d07b21c47dc511525ac8", GitTreeState:"clean", GoVersion:"go1.13.8"} 32 | ``` 33 | 34 | Agrege el repositorio de Flux CD a los repositorios de Helm 35 | 36 | ```bash 37 | helm repo add fluxcd https://charts.fluxcd.io 38 | ``` 39 | 40 | Actualice los repositorios 41 | 42 | ```bash 43 | helm repo update 44 | 45 | Hang tight while we grab the latest from your chart repositories... 46 | ...Successfully got an update from the "fluxcd" chart repository 47 | ...Successfully got an update from the "stable" chart repository 48 | Update Complete. ⎈ Happy Helming!⎈ 49 | ``` 50 | 51 | ## Flux CD 52 | 53 | `fluxctl` es la herramienta que le permitirá acceder al servicio Flux CD instalado en el cluster de Kubernetes. 54 | 55 | Es necesario tener instalado `fluxctl` en una versión igual o superior a la `1.19.0`. 56 | 57 | Utilice el siguiente enlace para acceder a las instrucciones de la instalación: 58 | 59 | ```bash 60 | fluxctl version 61 | 62 | 1.19.0 63 | ``` 64 | 65 | Siguiente: [Configurar el repositorio](02-setup-repository.md) 66 | -------------------------------------------------------------------------------- /docs/es/02-setup-repository.md: -------------------------------------------------------------------------------- 1 | # Configurar el repositorio 2 | 3 | En esta sección se indicarán los pasos a seguir para configurar el repositorio de código. 4 | 5 | ## Crear una bifurcación del repositorio 6 | 7 | Realice una bifurcación del repositorio hacia su área de trabajo en GitHub. De esta forma podrá modificar el código libremente. 8 | 9 | ![GitHub fork](../../diagrams/github-fork.png) 10 | 11 | ## Clonar el repositorio 12 | 13 | Clone el repositorio hacia su ordenador: 14 | 15 | > Cambie `YOUR-GITHUB-USER` por su usuario en GitHub. 16 | 17 | ```bash 18 | git clone git@github.com:YOUR-GITHUB-USER/gitops-get-started.git 19 | ``` 20 | 21 | Acceda al directorio del repositorio clonado: 22 | 23 | ```bash 24 | cd gitops-get-started 25 | ``` 26 | 27 | ## Modificar el fichero de instalación 28 | 29 | Modifique el fichero de instalación para que utilice su repositorio como fuente de origen: 30 | 31 | > Cambie `YOUR-GITHUB-USER` por su usuario en GitHub. 32 | 33 | ```bash 34 | sed -i "" "s/mmorejon/YOUR-GITHUB-USER/g" scripts/install.sh 35 | ``` 36 | 37 | Establezca los cambios y envíelos a su repositorio en GitHub: 38 | 39 | ```bash 40 | git add scripts/install.sh 41 | git commit -sm 'Change github repository.' 42 | git push origin master 43 | ``` 44 | 45 | Siguiente: [Configurar Digital Ocean](03-setup-digital-ocean.md) 46 | -------------------------------------------------------------------------------- /docs/es/03-setup-digital-ocean.md: -------------------------------------------------------------------------------- 1 | # Configurar Digital Ocean 2 | 3 | Digital Ocean es la plataforma seleccionada para crear el cluster de Kubernetes. Si es la primera vez que escucha hablar de esta plataforma no se preocupe, porque todos sus servicios pueden ser accedidos de forma fácil y sencilla. 4 | 5 | ## Crear usuario en Digital Ocean 6 | 7 | Si no tienes usuario en la plataforma Digital Ocean puedes utilizar [este enlace para crearse una cuenta con $100 de crédito al iniciar](https://m.do.co/c/fb2c605da7ee). El costo del ejercicio realizado en este laboratorio es de $20 al mes (**$0.030 la hora**). 8 | 9 | ## Crear token personal 10 | 11 | El token de acceso personal será utilizado para gestionar los componentes de la plataforma a través del cliente `doctl`. 12 | 13 | * Acceda a la [sección API](https://cloud.digitalocean.com/account/api/tokens) y genere un token nuevo con permisos de lectura y escritura. 14 | * Copie y guarde de forma segura el código generado para utilizarlo en las próximas secciones. 15 | 16 | Al crear el token debe obtener un resultado similar al mostrado en la siguiente imagen. 17 | 18 | ![Digital Ocean Token](../../diagrams/do-token.png) 19 | 20 | ## Instalar doctl 21 | 22 | `doctl` es el cliente de Digital Ocean. A través de este sistema podrá acceder a todos los recursos de la plataforma desde el Terminal. 23 | 24 | Utilice el siguiente enlace para instalar `doctl`: 25 | 26 | La versión a instalar debe ser igual o mayor a la `1.59.0`. 27 | 28 | ```bash 29 | doctl version 30 | 31 | doctl version 1.59.0-release 32 | ``` 33 | 34 | ## Configurar doctl 35 | 36 | Utilice el comando `auth init` para autenticar el cliente `doctl` con la plataforma. Utilice el token generado en la sección anterior como parámetro de entrada. 37 | 38 | ```bash 39 | doctl auth init 40 | 41 | DigitalOcean access token: 42 | Validating token... OK 43 | ``` 44 | 45 | Compruebe que existe una buena comunicación entre el cliente `doctl` y la plataforma. Liste las versiones de Kubernetes que tiene disponible la plataforma utilizando el siguiente comando: 46 | 47 | ```bash 48 | doctl kubernetes options versions 49 | 50 | Slug Kubernetes Version 51 | 1.16.6-do.2 1.16.6 52 | 1.15.9-do.2 1.15.9 53 | 1.14.10-do.2 1.14.10 54 | ``` 55 | 56 | Siguiente: [Configurar Terraform Cloud](04-setup-terraform.md) 57 | -------------------------------------------------------------------------------- /docs/es/04-setup-terraform.md: -------------------------------------------------------------------------------- 1 | # Configurar Terraform Cloud 2 | 3 | La plataforma Terraform Cloud utiliza la Infraestructura como Código para gestionar y proveer cualquier entorno en la nube, infraestructura o servicio. 4 | 5 | ## Crear usuario en Terraform Cloud 6 | 7 | Si no tiene usuario en esta plataforma utilice [este siguiente enlace para crearse uno nuevo](https://app.terraform.io/signup/account?utm_source=docs_banner) en el plan gratis. 8 | 9 | ## Crear nueva organización 10 | 11 | Configure una nueva organización para gestionar el proyecto. Puede utilizar [este enlace](https://app.terraform.io/app/organizations/new) para acceder a las organizaciones en Terraform. 12 | 13 | ![Terraform Organization](../../diagrams/terraform-organization.png) 14 | 15 | Luego enlace su área de trabajo en Terraform Cloud con su repositorio en GitHub. 16 | 17 | ![Terraform GitHub](../../diagrams/terraform-github.png) 18 | 19 | Liste las opciones avanzadas para especificar la carpeta `infra` como la fuente de ficheros terraform dentro de todo el directorio. 20 | 21 | ![Terraform Advance Options](../../diagrams/terraform-advance-options.png) 22 | 23 | ## Crear variables de entorno 24 | 25 | Configure las variables en Terraform Cloud para conectar esta plataforma con Digital Ocean. 26 | 27 | Adicione la variable de entorno `DIGITALOCEAN_TOKEN` junto con el token de Digital Ocean obtenido en la sección anterior. 28 | 29 | > No olvide marcar la casilla `Sensitive` para ocultar el valor del token. 30 | 31 | ![Terraform Environment Values](../../diagrams/terraform-envs.png) 32 | 33 | Siguiente: [Crear cluster de Kubernetes](05-create-cluster.md) 34 | -------------------------------------------------------------------------------- /docs/es/05-create-cluster.md: -------------------------------------------------------------------------------- 1 | # Crear cluster de Kubernetes 2 | 3 | La creación del cluster de Kubernetes se realizará desde Terraform Cloud. El área de trabajo configurada en la sección anterior va a crear la infraestructura a partir del código existente en el repositorio GitHub. 4 | 5 | ## Cambios automáticos en Terraform Cloud 6 | 7 | Terraform Cloud tiene dos formas de establecer los cambios: Manual y Automático. 8 | 9 | Para entornos de producción es recomendable utilizar el modo Manual, de esta forma los demás integrantes del equipo podrán analizar los cambios y dar su criterio. 10 | 11 | Sin embargo, el ejercicio a realizar en este momento no incluye este escenario, por lo tanto, se van a configurar los cambios de forma Automática. 12 | 13 | Acceda a las configuraciones de su área de trabajo y seleccione la opción `Auto apply`. 14 | 15 | ![Terraform Auto Apply](../../diagrams/terraform-auto-apply.png) 16 | 17 | ## Crear el cluster en Digital Ocean 18 | 19 | La descripción del cluster de Kubernetes se encuentra en el fichero `infra/cluster.tf`. 20 | 21 | ```bash 22 | cat infra/cluster.tf 23 | 24 | # kubernetes cluster 25 | resource "digitalocean_kubernetes_cluster" "staging" { 26 | name = "staging" 27 | region = "ams3" 28 | version = "1.20.2-do.0" 29 | tags = ["staging"] 30 | 31 | node_pool { 32 | name = "worker-pool" 33 | size = "s-1vcpu-2gb" 34 | auto_scale = true 35 | min_nodes = 2 36 | max_nodes = 5 37 | } 38 | } 39 | ``` 40 | 41 | Para crear el cluster utilice el botón `Queue plan` ubicado arriba y a la derecha de la plataforma Terraform. 42 | 43 | ![Terraform Queue plan](../../diagrams/terraform-queue-plan.png) 44 | 45 | Una vez iniciado el plan podrá ver en su pantalla cómo se aplican los cambios de Terraform. Esta acción puede demorar unos 7 minutos. 46 | 47 | ![Terraform Apply](../../diagrams/terraform-apply.png) 48 | 49 | Acceda a la sección de Kubernetes en Digital Ocean y observe que se ha iniciado un cluster de Kubernetes con el nombre `staging`. 50 | 51 | ![Digital Ocean creating kubernetes cluster](../../diagrams/do-creating-kubernetes-cluster.png) 52 | 53 | Espere a que termine de crearse el cluster para realizar el próximo paso. 54 | 55 | ## Acceder al cluster desde Kubectl 56 | 57 | Una vez creado el cluster será necesario acceder el desde la herramienta `kubectl`. Para lograrlo necesitará obtener las credenciales del nuevo cluster, así como la URL de acceso al API de Kubernetes. 58 | 59 | Utilice el siguiente comando para configurar el fichero `~/.kube/config` con las credenciales del cluster de Digital Ocean: 60 | 61 | ```bash 62 | doctl kubernetes cluster kubeconfig save staging 63 | 64 | Notice: adding cluster credentials to kubeconfig file found in "/Users/......./.kube/config" 65 | Notice: setting current-context to do-ams3-staging 66 | ``` 67 | 68 | Compruebe que la configuración se ha realizado correctamente. Liste los nodos del cluster: 69 | 70 | ```bash 71 | kubectl get nodes 72 | 73 | NAME STATUS ROLES AGE VERSION 74 | worker-pool-8jk9f Ready 23m v1.20.2 75 | worker-pool-8jk9q Ready 23m v1.20.2 76 | ``` 77 | 78 | Siguiente: [Instalar Flux CD](06-install-fluxcd.md) 79 | -------------------------------------------------------------------------------- /docs/es/06-install-fluxcd.md: -------------------------------------------------------------------------------- 1 | # Instalar Flux CD 2 | 3 | Una vez creado el cluster el próximo paso es instalar Flux CD. Esta será la única ocasión que necesitará utilizar la herramienta `kubectl` para establecer los cambios en el cluster. 4 | 5 | ## Instalar Flux 6 | 7 | Utilice el fichero `scripts/install.sh` para instalar los siguientes servicios en el cluster: 8 | 9 | | Herramienta | Descripción | 10 | | ---------------- | ---------------------------------------------------------------------------------------------------------- | 11 | | `flux` | Herramienta para automatizar los despliegues en Kubernetes. Está basada en la filosofía de trabajo GitOps. | 12 | | `helm-operator` | Sistema encargado de gestionar los charts de Helm en la herramienta `flux`. | 13 | | `flux-memcached` | Sistema encargado de llevar el registro de imágenes y cambios en la herramienta `flux`. | 14 | 15 | > Compruebe en el fichero `install.sh` que el parámetro `--set git.url` esté configurado con su directorio en GitHub. 16 | 17 | ```bash 18 | ./scripts/install.sh 19 | ``` 20 | 21 | Liste los servicios creados en el namespace `flux-system` cuando termine de ejecutarse el script: 22 | 23 | ```bash 24 | kubectl get pods -n flux-system 25 | 26 | NAME READY STATUS RESTARTS AGE 27 | flux-59bb67c8b4-h2kcp 1/1 Running 0 4m3s 28 | flux-memcached-8647794c5f-hhdzc 1/1 Running 0 4m3s 29 | helm-operator-77cb687cc7-wdcfg 1/1 Running 0 3m23s 30 | ``` 31 | 32 | Podrá comprobar que los tres servicios están funcionando correctamente. 33 | 34 | Siguiente: [Sincronizar GitHub <-> Flux CD](07-syncronice-github-fluxcd.md) 35 | -------------------------------------------------------------------------------- /docs/es/07-syncronice-github-fluxcd.md: -------------------------------------------------------------------------------- 1 | # Sincronizar GitHub <-> Flux CD 2 | 3 | Para que Flux pueda obtener la información almacenada en el repositorio de GitHub es necesario habilitar los permisos de lectura. 4 | 5 | ## Obtener llave ssh 6 | 7 | Flux genera una llave ssh al iniciar el sistema. Para obtener esta llave utilice el siguiente comando: 8 | 9 | ```bash 10 | fluxctl identity --k8s-fwd-ns flux-system 11 | 12 | ssh-rsa AAAAB....... 13 | ``` 14 | 15 | ## Registrar llave en GitHub 16 | 17 | Acceda a la sección *Deploy keys* dentro del repositorio creado en GitHub. Puede utilizar el siguiente enlace para lograrlo: 18 | 19 | > Cambie `YOUR-GITHUB-USER` por su usuario en GitHub. 20 | 21 | 22 | 23 | Adicione la llave pública ssh generada en el paso anterior. 24 | 25 | > Habilite también los permisos de escritura si desea que Flux pueda realizar cambios en el repositorio. 26 | 27 | ![Terraform Apply](../../diagrams/github-deploy-keys.png) 28 | 29 | ## Sincronizar Flux con el repositorio 30 | 31 | Flux sincroniza los cambios existentes en el repositorio de forma automática basándose en el tiempo establecido en el parámetro `git.pollInterval`. Por defecto el valor es `5m`, pero si no desea esperar este tiempo puede utilizar el siguiente comando: 32 | 33 | ```bash 34 | fluxctl sync --k8s-fwd-ns flux-system 35 | ``` 36 | 37 | Esta línea de comando le indica al sistema flux que sincronice el estado de los objetos del cluster con los elementos existentes en el repositorio git. 38 | 39 | ### Registros en Flux 40 | 41 | Acceda a los registros del sistema flux y compruebe que ha podido acceder correctamente a GitHub. 42 | 43 | ```bash 44 | kubectl -n flux-system logs -l app=flux 45 | ``` 46 | 47 | ### Carpetas sincronizadas 48 | 49 | Una vez lograda la sincronización entre Flux CD y GitHub podrá observar que todos los elementos existentes en la carpeta `namespaces` han sido creados en el cluster. 50 | 51 | ```bash 52 | kubectl get namespaces 53 | 54 | NAME STATUS AGE 55 | admin Active 17m 56 | client-abc Active 17m 57 | client-def Active 17m 58 | default Active 107m 59 | flux-system Active 60m 60 | kube-node-lease Active 107m 61 | kube-public Active 107m 62 | kube-system Active 107m 63 | ``` 64 | 65 | Liste los Pods existentes en estos namespaces y notará la correspondencia con los servicios descritos en el repositorio de GitHub. 66 | 67 | ```bash 68 | kubectl get pods -n client-abc && kubectl get pods -n client-def 69 | 70 | NAME READY STATUS RESTARTS AGE 71 | app-abc-6b6c9d5599-kbddb 1/1 Running 0 24m 72 | app-abc-6b6c9d5599-ltql7 1/1 Running 0 24m 73 | NAME READY STATUS RESTARTS AGE 74 | app-def-5bd5d956c5-d64r7 1/1 Running 0 24m 75 | app-def-5bd5d956c5-md5vz 1/1 Running 0 24m 76 | app-def-5bd5d956c5-vdjx2 1/1 Running 0 24m 77 | ``` 78 | 79 | ## Flujo de trabajo utilizando GitOps 80 | 81 | En este momento usted podrá gestionar su cluster a través de la filosofía de trabajo GitOps. 82 | 83 | Los cambios establecidos en el cluster deberán estar en el repositorio Git y será Flux CD quién se encargue de mantener sincronizado el estado de los objetos en Kubernetes. 84 | 85 | ![Terraform Apply](../../diagrams/flux-overview.svg) 86 | 87 | Le sugiero que a partir de este momento modifique los componentes existentes y evalúe cómo reaccionan. Es importante que entienda que la estructura existente en este repositorio corresponde con un caso de ejemplo, usted deberá identificar cuál es la estructura de repositorio que mejor corresponde con su negocio. 88 | 89 | Siguiente: [Gestionar Secrets utilizando Sealed Secrets](08-sealed-secrests.md) 90 | -------------------------------------------------------------------------------- /docs/es/08-sealed-secrests.md: -------------------------------------------------------------------------------- 1 | # Gestionar Secrets utilizando Sealed Secrets 2 | 3 | Hasta el momento se ha establecido que todos los componentes deben ser registrados en el repositorio de código como única fuente confiable para establecer los cambios, pero ¿qué pasa con los objetos Secrets? 4 | 5 | Los Secrets no pueden ser gestionados de igual forma. Antes de ser adicionados al control de versiones es importante proteger la información que llevan dentro. Para lograr este objetivo se ha desplegado en el cluster el servicio [Sealed Secrets desarrollado por Bitnami](https://github.com/bitnami-labs/sealed-secrets). 6 | 7 | ```bash 8 | kubectl -n admin get pods 9 | 10 | NAME READY STATUS RESTARTS AGE 11 | sealed-secrets-769745f6db-4cmkb 1/1 Running 0 59m 12 | ``` 13 | 14 | Los siguientes pasos le ayudarán a crear un Secret en Kubernetes manteniendo el flujo de trabajo GitOps. 15 | 16 | ## Instalar el cliente kubeseal 17 | 18 | `kubeseal` es la herramienta que le permitirá encriptar la información del Secret antes de almacenarlo en el controlador de versiones. 19 | 20 | Es necesario tener instalado `kubeseal` en una versión igual o superior a la `v0.12.1`. 21 | 22 | Utilice el siguiente enlace para acceder a las instrucciones de la instalación: 23 | 24 | ```bash 25 | kubeseal --version \ 26 | --controller-namespace=admin \ 27 | --controller-name=sealed-secrets 28 | 29 | kubeseal version: v0.12.1 30 | ``` 31 | 32 | ## Obtener llave pública 33 | 34 | Al iniciar este servicio se genera la llave pública y privada que serán utilizadas durante los procesos de encriptación. 35 | 36 | Utilice la siguiente línea de comando para obtener la llave pública: 37 | 38 | ```bash 39 | kubeseal --fetch-cert \ 40 | --controller-namespace=admin \ 41 | --controller-name=sealed-secrets \ 42 | > pub-cert.pem 43 | ``` 44 | 45 | Genere un Secret de Kubernetes utilizando `kubectl`: 46 | 47 | ```bash 48 | kubectl -n client-def create secret generic magic-text \ 49 | --from-literal incantation=kubernetes \ 50 | --dry-run \ 51 | -o json > magic-text.json 52 | ``` 53 | 54 | Encripte el Secret utilizando `kubeseal`: 55 | 56 | ```bash 57 | kubeseal --format=yaml --cert=pub-cert.pem < magic-text.json > magic-text.yaml 58 | ``` 59 | 60 | Compruebe que el fichero `magic-text.yaml` contenga la información encriptada y adiciónelo al repositorio de GitHub. 61 | 62 | ```bash 63 | mv magic-text.yaml namespaces/client-def 64 | git add namespaces/client-def/magic-text.yaml 65 | git commit -sm 'Add magic text secret' 66 | git push origin master 67 | ``` 68 | 69 | Utilice `fluxctl` para sincronizar el repositorio con el cluster: 70 | 71 | ```bash 72 | fluxctl sync --k8s-fwd-ns flux-system 73 | ``` 74 | 75 | Ahora liste los Secrets presentes en el namespace `client-def`: 76 | 77 | ```bash 78 | kubectl -n client-def get secrets 79 | ``` 80 | 81 | Compruebe que el valor del texto almacenado en el Secret es correcto: 82 | 83 | ```bash 84 | kubectl -n client-def get secrets magic-text -o jsonpath='{.data.incantation}' | base64 --decode 85 | ``` 86 | 87 | Siguiente: [Limpiar](09-cleaning-up.md) 88 | -------------------------------------------------------------------------------- /docs/es/09-cleaning-up.md: -------------------------------------------------------------------------------- 1 | # Limpiar 2 | 3 | En esta sección va a eliminar el cluster creado en Digital Ocean. 4 | 5 | ```bash 6 | doctl kubernetes cluster delete staging 7 | 8 | Warning: Are you sure you want to delete this Kubernetes cluster (y/N) ? yes 9 | ``` 10 | -------------------------------------------------------------------------------- /docs/es/README.md: -------------------------------------------------------------------------------- 1 | # gitops-get-started 2 | 3 | Proyecto para dar los primeros pasos en la filosofía de trabajo GitOps utilizando Flux CD. 4 | 5 | El proyecto muestra cómo configurar un cluster de Kubernetes basándose en GitOps. La organización de carpetas y servicios desplegados corresponden con un hipotético cluster utilizado para entornos de desarrollo o pruebas. Esta configuración del cluster no está lista para ser utilizada en producción. 6 | 7 | Para sacar mayor provecho del repositorio se recomienda tener conocimientos básicos sobre la filosofía de trabajo GitOps. Puede ampliar sus conocimientos sobre este tema a través de [este enlace del sitio Weaveworks](https://www.weave.works/technologies/gitops/). 8 | 9 | Los sistemas utilizados durante el ejercicio fueron: [Git](https://git-scm.com/), [Terraform](https://www.terraform.io/), [Flux CD](https://fluxcd.io/) y [Kubernetes](https://kubernetes.io/). La plataforma utilizada para crear el cluster de Kubernetes es [Digital Ocean](https://www.digitalocean.com/), pero también puede utilizarse [Minikube](https://minikube.sigs.k8s.io/). 10 | 11 | Flujo para gestionar la infraestructura 12 | 13 | ![Infraestructura Vista General](../../diagrams/terraform-digitalocean-kubernetes.svg) 14 | 15 | ---- 16 | 17 | Flujo para gestionar Kubernetes 18 | 19 | ![Flux Vista General](../../diagrams/flux-overview.svg) 20 | 21 | ## Estructura de carpetas 22 | 23 | ```bash 24 | ├── infra 25 | │   └── cluster.tf 26 | ├── namespaces 27 | │   ├── admin 28 | │   │   ├── namespace.yaml 29 | │   │   └── sealed-secrets 30 | │   │   └── sealed-secrets.yaml 31 | │   ├── client-abc 32 | │   │   ├── deployment.yaml 33 | │   │   └── namespace.yaml 34 | │   ├── client-def 35 | │   │   ├── deployment.yaml 36 | │   │   └── namespace.yaml 37 | │   ├── flux-system 38 | │   │   └── namespace.yaml 39 | │   └── kube-system 40 | │   ├── kube-state-metrics 41 | │   │   └── kube-state-metrics.yaml 42 | │   └── metrics-server 43 | │   └── metrics-server.yaml 44 | └── scripts 45 | └── install.sh 46 | ``` 47 | 48 | | Carpeta | Descripción | 49 | | ---------- | ----------- | 50 | | infra | Ficheros terraforms para crear la infraestructura en Digital Ocean. (Opcional) | 51 | | namespaces | Estructura de namespaces utilizados en el cluster. Dentro de cada namespace se encuentran las aplicaciones que serán desplegadas. | 52 | | scripts | Carpeta de utilidades generales.| 53 | 54 | ## Secciones del caso práctico 55 | 56 | Los siguientes enlaces le van a guiar en la creación de un cluster de Kubernetes utilizando la filosofía de trabajo GitOps. 57 | 58 | * [Herramientas necesarias](01-client-tools.md) 59 | * [Configurar el repositorio](02-clone-repository.md) 60 | * [Configurar Digital Ocean](03-setup-digital-ocean.md) 61 | * [Configurar Terraform](04-setup-terraform-cloud.md) 62 | * [Crear cluster de Kubernetes](05-create-cluster.md) 63 | * [Instalar Flux CD](06-install-fluxcd.md) 64 | * [Sincronizar GitHub <-> Flux CD](07-syncronice-github-fluxcd.md) 65 | * [Gestionar Secrets utilizando Sealed Secrets](08-sealed-secrests.md) 66 | * [Limpiar](09-cleaning-up.md) 67 | -------------------------------------------------------------------------------- /infra/cluster.tf: -------------------------------------------------------------------------------- 1 | # required provider 2 | terraform { 3 | required_providers { 4 | digitalocean = { 5 | source = "digitalocean/digitalocean" 6 | } 7 | } 8 | } 9 | 10 | # kubernetes cluster 11 | resource "digitalocean_kubernetes_cluster" "staging" { 12 | name = "staging" 13 | region = "ams3" 14 | version = "1.20.2-do.0" 15 | tags = ["staging"] 16 | 17 | node_pool { 18 | name = "worker-pool" 19 | size = "s-1vcpu-2gb" 20 | auto_scale = true 21 | min_nodes = 2 22 | max_nodes = 5 23 | } 24 | } -------------------------------------------------------------------------------- /namespaces/admin/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: admin 5 | annotations: 6 | linkerd.io/inject: disabled 7 | labels: 8 | istio-injection: disabled 9 | appmesh.k8s.aws/sidecarInjectorWebhook: disabled -------------------------------------------------------------------------------- /namespaces/admin/sealed-secrets/sealed-secrets.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: sealed-secrets 5 | namespace: admin 6 | spec: 7 | releaseName: sealed-secrets 8 | chart: 9 | repository: https://kubernetes-charts.storage.googleapis.com/ 10 | name: sealed-secrets 11 | version: 1.9.0 -------------------------------------------------------------------------------- /namespaces/client-abc/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: app-abc 5 | labels: 6 | name: client-abc 7 | namespace: client-abc 8 | spec: 9 | replicas: 2 10 | selector: 11 | matchLabels: 12 | name: client-abc 13 | strategy: 14 | type: RollingUpdate 15 | template: 16 | metadata: 17 | labels: 18 | name: client-abc 19 | spec: 20 | containers: 21 | - image: mmorejon/erase-una-vez-1:0.2.0 22 | name: erase-una-vez 23 | env: 24 | - name: CHARACTER 25 | value: "la app ABC." 26 | - name: SLEEP_TIME 27 | value: "3" 28 | resources: 29 | requests: 30 | memory: "10Mi" 31 | cpu: "10m" 32 | limits: 33 | memory: "100Mi" 34 | cpu: "100m" -------------------------------------------------------------------------------- /namespaces/client-abc/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: client-abc 5 | labels: 6 | name: client-abc -------------------------------------------------------------------------------- /namespaces/client-def/deployment.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: app-def 6 | labels: 7 | name: client-def 8 | annotations: 9 | fluxcd.io/automated: "true" 10 | fluxcd.io/tag.erase-una-vez: semver:~0.2 11 | namespace: client-def 12 | spec: 13 | replicas: 3 14 | selector: 15 | matchLabels: 16 | name: client-def 17 | strategy: 18 | type: RollingUpdate 19 | template: 20 | metadata: 21 | labels: 22 | name: client-def 23 | spec: 24 | containers: 25 | - image: mmorejon/erase-una-vez-1:0.2.0 26 | name: erase-una-vez 27 | env: 28 | - name: CHARACTER 29 | value: "la app DEF." 30 | - name: SLEEP_TIME 31 | value: "3" 32 | resources: 33 | requests: 34 | memory: "10Mi" 35 | cpu: "10m" 36 | limits: 37 | memory: "100Mi" 38 | cpu: "100m" 39 | -------------------------------------------------------------------------------- /namespaces/client-def/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: client-def 5 | labels: 6 | name: client-def -------------------------------------------------------------------------------- /namespaces/flux-system/namespace.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: flux-system 5 | annotations: 6 | linkerd.io/inject: disabled 7 | labels: 8 | istio-injection: disabled 9 | appmesh.k8s.aws/sidecarInjectorWebhook: disabled -------------------------------------------------------------------------------- /namespaces/kube-system/kube-state-metrics/kube-state-metrics.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: kube-state-metrics 5 | namespace: kube-system 6 | spec: 7 | releaseName: kube-state-metrics 8 | chart: 9 | repository: https://kubernetes-charts.storage.googleapis.com/ 10 | name: kube-state-metrics 11 | version: 2.6.4 -------------------------------------------------------------------------------- /namespaces/kube-system/metrics-server/metrics-server.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: helm.fluxcd.io/v1 2 | kind: HelmRelease 3 | metadata: 4 | name: metrics-server 5 | namespace: kube-system 6 | spec: 7 | releaseName: metrics-server 8 | chart: 9 | repository: https://kubernetes-charts.storage.googleapis.com/ 10 | name: metrics-server 11 | version: 2.9.0 12 | values: 13 | args: 14 | - "--kubelet-insecure-tls" 15 | - "--kubelet-preferred-address-types=InternalIP" -------------------------------------------------------------------------------- /scripts/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # create namespace 4 | kubectl apply -f namespaces/flux-system/namespace.yaml 5 | 6 | # install flux 7 | helm upgrade flux fluxcd/flux --wait \ 8 | --install \ 9 | --namespace flux-system \ 10 | --version=1.3.0 \ 11 | --set git.url=git@github.com:mmorejon/gitops-get-started \ 12 | --set git.branch=main \ 13 | --set git.path=namespaces \ 14 | --set git.pollInterval=5m \ 15 | --set sync.interval=2m \ 16 | --set manifestGeneration=false \ 17 | --set registry.automationInterval=2m \ 18 | --set registry.includeImage="*/mmorejon/*" \ 19 | --set syncGarbageCollection.enabled=true \ 20 | --set syncGarbageCollection.dry=true \ 21 | --set memcached.hostnameOverride=flux-memcached.flux-system 22 | 23 | # install flux-helm-operator 24 | helm upgrade helm-operator fluxcd/helm-operator --wait \ 25 | --install \ 26 | --namespace flux-system \ 27 | --version=1.0.1 \ 28 | --set createCRD=false \ 29 | --set git.ssh.secretName=flux-git-deploy \ 30 | --set chartsSyncInterval=2m \ 31 | --set helm.versions=v3 32 | --------------------------------------------------------------------------------