diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..3f37e85 Binary files /dev/null and b/.DS_Store differ diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b242572 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "githubPullRequests.ignoredPullRequestBranches": [ + "main" + ] +} \ No newline at end of file diff --git a/2022/Days/day14.md b/2022/Days/day14.md index 8ad7b21..f9ca926 100644 --- a/2022/Days/day14.md +++ b/2022/Days/day14.md @@ -40,6 +40,8 @@ Next up we also need to get [Virtual Box](https://www.virtualbox.org/wiki/Downlo Both installations are pretty straightforward and both have great communitites around them so feel free to reach out if you have issues and I can try and assist too. +> If you are using m1 macOS, I recommend to use [multiplass]([url](https://multipass.run/)) instead of Vagrant and VirtualBox. (reference : https://github.com/MichaelCade/90DaysOfDevOps/issues/365) + ## Our first VAGRANTFILE The VAGRANTFILE describes the type of machine we want to deploy. It also defines the configuration and provisioning for this machine. diff --git a/2022/Days/day19.md b/2022/Days/day19.md index 536208f..19fdd90 100644 --- a/2022/Days/day19.md +++ b/2022/Days/day19.md @@ -92,7 +92,7 @@ This way when and where we use `$challenge` in our code, if we change the variab If we now run our `sh` script you will see the printout that was added to our script. -![](Images/Day19_Linux5.png) +![](Images/Day19_Linux6.png) We can also ask for user input that can set our variables using the following: diff --git a/2022/Days/day34.md b/2022/Days/day34.md index bece950..d32daac 100644 --- a/2022/Days/day34.md +++ b/2022/Days/day34.md @@ -179,7 +179,7 @@ Following [Module 09a](https://microsoftlearning.github.io/AZ-104-MicrosoftAzure - Task 6: Configure and test autoscaling of the Azure web app -This script I am using can be found in (Cloud/05Serverless) +This script I am using can be found in (Cloud/04Serverless) ![](Images/Day34_Cloud36.png) diff --git a/2022/Days/day37.md b/2022/Days/day37.md index 8f2c54b..692a974 100644 --- a/2022/Days/day37.md +++ b/2022/Days/day37.md @@ -71,10 +71,10 @@ I have taken these from [atlassian](https://www.atlassian.com/git/tutorials/atla | Command | Example | Description | | ------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | git init | `git init ` | Create an empty git repository in the specified directory. | -| git clone | `git clone ` | Clone repository located at onto local machine. | +| git clone | `git clone ` | Clone repository located at \ onto local machine. | | git config | `git config user.name` | Define author name to be used for all commits in current repository `system`, `global`, `local` flag to set config options. | -| git add | `git add ` | Stage all changes in for the next commit. We can also add and <.> for everything. | -| git commit -m | `git commit -m ""` | Commit the staged snapshot, use to detail what is being committed. | +| git add | `git add ` | Stage all changes in \ for the next commit. We can also add \ and \<.> for everything. | +| git commit -m | `git commit -m ""` | Commit the staged snapshot, use \ to detail what is being committed. | | git status | `git status` | List files that are staged, unstaged and untracked. | | git log | `git log` | Display all commit history using the default format. There are additional options with this command. | | git diff | `git diff` | Show unstaged changes between your index and working directory. | @@ -83,8 +83,8 @@ I have taken these from [atlassian](https://www.atlassian.com/git/tutorials/atla | Command | Example | Description | | ---------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | -| git revert | `git revert ` | Create a new commit that undoes all of the changes made in then apply it to the current branch. | -| git reset | `git reset ` | Remove from the staging area, but leave the working directory unchanged. This unstaged a file without overwriting any changes. | +| git revert | `git revert ` | Create a new commit that undoes all of the changes made in \ then apply it to the current branch. | +| git reset | `git reset ` | Remove \ from the staging area, but leave the working directory unchanged. This unstaged a file without overwriting any changes. | | git clean | `git clean -n` | Shows which files would be removed from the working directory. Use `-f` in place of `-n` to execute the clean. | ### Git Rewriting History @@ -92,25 +92,25 @@ I have taken these from [atlassian](https://www.atlassian.com/git/tutorials/atla | Command | Example | Description | | ---------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | | git commit | `git commit --amend` | Replace the last commit with the staged changes and the last commit combined. Use with nothing staged to edit the last commit’s message. | -| git rebase | `git rebase ` | Rebase the current branch onto . can be a commit ID, branch name, a tag, or a relative reference to HEAD. | +| git rebase | `git rebase ` | Rebase the current branch onto \. \ can be a commit ID, branch name, a tag, or a relative reference to HEAD. | | git reflog | `git reflog` | Show a log of changes to the local repository’s HEAD. Add --relative-date flag to show date info or --all to show all refs. | ### Git Branches | Command | Example | Description | | ------------ | -------------------------- | ------------------------------------------------------------------------------------------------------------- | -| git branch | `git branch` | List all of the branches in your repo. Add a argument to create a new branch with the name . | -| git checkout | `git checkout -b ` | Create and check out a new branch named . Drop the -b flag to checkout an existing branch. | -| git merge | `git merge ` | Merge into the current branch. | +| git branch | `git branch` | List all of the branches in your repo. Add a \ argument to create a new branch with the name \. | +| git checkout | `git checkout -b ` | Create and check out a new branch named \. Drop the -b flag to checkout an existing branch. | +| git merge | `git merge ` | Merge \ into the current branch. | ### Git Remote Repositories | Command | Example | Description | | -------------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| git remote add | `git remote add ` | Create a new connection to a remote repo. After adding a remote, you can use as a shortcut for in other commands. | -| git fetch | `git fetch ` | Fetches a specific , from the repo. Leave off to fetch all remote refs. | +| git remote add | `git remote add ` | Create a new connection to a remote repo. After adding a remote, you can use \ as a shortcut for \ in other commands. | +| git fetch | `git fetch ` | Fetches a specific \, from the repo. Leave off \ to fetch all remote refs. | | git pull | `git pull ` | Fetch the specified remote’s copy of current branch and immediately merge it into the local copy. | -| git push | `git push ` | Push the branch to , along with necessary commits and objects. Creates named branch in the remote repo if it doesn’t exist. | +| git push | `git push ` | Push the branch to \, along with necessary commits and objects. Creates named branch in the remote repo if it doesn’t exist. | ### Git Diff @@ -123,23 +123,23 @@ I have taken these from [atlassian](https://www.atlassian.com/git/tutorials/atla | Command | Example | Description | | ---------------------------------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | -| git config --global user.name | `git config --global user.name ` | Define the author name to be used for all commits by the current user. | -| git config --global user.email | `git config --global user.email ` | Define author email to be used for all commits by the current user. | -| git config --global alias | `git config --global alias ` | Create shortcut for a git command . | -| git config --system core.editor | `git config --system core.editor ` | Set the text editor to be used by commands for all users on the machine. arg should be the comamnd that launches the desired editor. | +| git config --global user.name \ | `git config --global user.name ` | Define the author name to be used for all commits by the current user. | +| git config --global user.email \ | `git config --global user.email ` | Define author email to be used for all commits by the current user. | +| git config --global alias \ \ | `git config --global alias ` | Create shortcut for a git command . | +| git config --system core.editor \ | `git config --system core.editor ` | Set the text editor to be used by commands for all users on the machine. \ arg should be the comamnd that launches the desired editor. | | git config --global --edit | `git config --global --edit ` | Open the global configuration file in a text editor for manual editing. | ### Git Rebase | Command | Example | Description | | -------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| git rebase -i | `git rebase -i ` | Interactively rebase current branch onto . Launches editor to enter commands for how each commit will be transferred to the new base. | +| git rebase -i \ | `git rebase -i ` | Interactively rebase current branch onto \. Launches editor to enter commands for how each commit will be transferred to the new base. | ### Git Pull | Command | Example | Description | | -------------------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | -| git pull --rebase | `git pull --rebase ` | Fetch the remote’s copy of current branch and rebases it into the local copy. Uses git rebase instead of the merge to integrate the branches. | +| git pull --rebase \ | `git pull --rebase ` | Fetch the remote’s copy of current branch and rebases it into the local copy. Uses git rebase instead of the merge to integrate the branches. | ### Git Reset @@ -147,16 +147,16 @@ I have taken these from [atlassian](https://www.atlassian.com/git/tutorials/atla | ------------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | git reset | `git reset ` | Reset the staging area to match the most recent commit but leave the working directory unchanged. | | git reset --hard | `git reset --hard` | Reset staging area and working directory to match most recent commit and overwrites all changes in the working directory | -| git reset | `git reset ` | Move the current branch tip backwards to , reset the staging area to match, but leave the working directory alone | -| git reset --hard | `git reset --hard ` | Same as previous, but resets both the staging area & working directory to match. Deletes uncommitted changes, and all commits after . | +| git reset \ | `git reset ` | Move the current branch tip backwards to \, reset the staging area to match, but leave the working directory alone | +| git reset --hard \ | `git reset --hard ` | Same as previous, but resets both the staging area & working directory to match. Deletes uncommitted changes, and all commits after \. | ### Git Push | Command | Example | Description | | ------------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -| git push --force | `git push --force` | Forces the git push even if it results in a non-fast-forward merge. Do not use the --force flag unless you’re sure you know what you’re doing. | -| git push --all | `git push --all` | Push all of your local branches to the specified remote. | -| git push --tags | `git push --tags` | Tags aren’t automatically pushed when you push a branch or use the --all flag. The --tags flag sends all of your local tags to the remote repo. | +| git push \ --force | `git push --force` | Forces the git push even if it results in a non-fast-forward merge. Do not use the --force flag unless you’re sure you know what you’re doing. | +| git push \ --all | `git push --all` | Push all of your local branches to the specified remote. | +| git push \ --tags | `git push --tags` | Tags aren’t automatically pushed when you push a branch or use the --all flag. The --tags flag sends all of your local tags to the remote repo. | ## Resources diff --git a/2022/Days/day55.md b/2022/Days/day55.md index 0f9d777..19909a2 100644 --- a/2022/Days/day55.md +++ b/2022/Days/day55.md @@ -102,7 +102,7 @@ We also have two other types of volumes that we will not get into detail on but In the session yesterday we walked through creating a stateless application, here we want to do the same but we want to use our minikube cluster to deploy a stateful workload. -A recap on the minikube command we are using to have the capability and addons to use persistence is `minikube start --addons volumesnapshots,csi-hostpath-driver --apiserver-port=6443 --container-runtime=containerd -p mc-demo --Kubernetes-version=1.21.2` +A recap on the minikube command we are using to have the capability and addons to use persistence is `minikube start --addons volumesnapshots,csi-hostpath-driver --apiserver-port=6443 --container-runtime=containerd -p mc-demo --kubernetes-version=1.21.2` This command uses the CSI-hostpath-driver which is what gives us our storageclass, something I will show later. @@ -208,7 +208,7 @@ We can then create this in our ingress namespace with `kubectl create -f Pacman- ![](Images/Day55_Kubernetes15.png) -Then if we run `kubectl get ingress -n Pacman +Then if we run `kubectl get ingress -n Pacman` ![](Images/Day55_Kubernetes16.png) diff --git a/2022/Days/day64.md b/2022/Days/day64.md index 59c6cb6..a235bce 100644 --- a/2022/Days/day64.md +++ b/2022/Days/day64.md @@ -37,7 +37,7 @@ Before we then start to look at controlling other nodes in our environment, we c ![](Images/Day64_config2.png) -Or an actual real-life use for a module might be something like `ansible webservers --m service -a "name=httpd state=started"` this will tell us if all of our webservers have the httpd service running. I have glossed over the webservers term used in that command. +Or an actual real-life use for a module might be something like `ansible webservers -m service -a "name=httpd state=started"` this will tell us if all of our webservers have the httpd service running. I have glossed over the webservers term used in that command. ### hosts diff --git a/2022/es/Days/Images/Day41_Git16.png b/2022/es/Days/Images/Day41_Git16.png new file mode 100644 index 0000000..41b0c79 Binary files /dev/null and b/2022/es/Days/Images/Day41_Git16.png differ diff --git a/2022/es/Days/day36.md b/2022/es/Days/day36.md index 20e9563..f72d141 100644 --- a/2022/es/Days/day36.md +++ b/2022/es/Days/day36.md @@ -1,138 +1,140 @@ -## Installing & Configuring Git +## Instalación y configuración de Git -Git is an open source, cross-platform tool for version control. If you are like me, using Ubuntu or most Linux environments you might find that you already have git installed but we are going to run through the install and configuration. +Git es una herramienta multiplataforma de código abierto para el control de versiones. En la mayoría de entornos Linux viene instalado por defecto, pero de todas formas vamos a repasar la instalación y configuración. -Even if you already have git installed on your system it is also a good idea to make sure we are up to date. +Incluso si ya tienes git instalado en tu sistema es una buena idea asegurarse de que está actualizado. -### Installing Git +### Instalación de Git -As already mentioned Git is cross-platform, we will be running through Windows and Linux but you can find macOS also listed [here](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) +Como ya se ha mencionado Git es multiplataforma, vamos a ver Windows y Linux, pero también puedes encontrar macOS en la lista de [descargas](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) -For [Windows](https://git-scm.com/download/win) we can grab our installers from the official site. +Para [Windows](https://git-scm.com/download/win) podemos obtener nuestros instaladores desde el sitio oficial o también puedes usar `winget`, Windows Application Package Manager. -You could also use `winget` on your Windows machine, think of this as your Windows Application Package Manager. - -Before we install anything let's see what version we have on our Windows Machine. Open a PowerShell window and run `git --version` +Antes de instalar nada vamos a ver qué versión tenemos en nuestra máquina Windows. Abre una ventana de PowerShell y ejecuta `git --version`. ![](Images/Day36_Git1.png) -We can also check our WSL Ubuntu version of Git as well. +También podemos comprobar nuestra versión en el [WSL](https://es.wikipedia.org/wiki/Subsistema_de_Windows_para_Linux) Ubuntu. ![](Images/Day36_Git2.png) -At the time of writing the latest Windows release is `2.35.1` so we have some updating to do there which I will run through. I expect the same for Linux. +En el momento de escribir esto la última versión de Windows es `2.35.1` por lo que tenemos que actualizarla. Lo mismo con Linux. -I went ahead and downloaded the latest installer and ran through the wizard and will document that here. The important thing to note is that git will uninstall previous versions before installing the latest. +Descargué el último instalador y ejecuté el asistente. Lo importante a tener en cuenta es que git desinstalará las versiones anteriores antes de instalar la última. Lo que significa que el proceso que se muestra a continuación es también el mismo proceso en su mayor parte como si estuviera instalando por primera vez. -Meaning that the process shown below is also the same process for the most part as if you were installing from no git. - -It is a very simple installation. Once downloaded double click and get started. Read through the GNU license agreement. But remember this is free and open-source software. +Es una instalación muy sencilla. Una vez descargado haga doble clic y comience. Lea el acuerdo de licencia GNU. Pero recuerde que este es un software libre y de código abierto. ![](Images/Day36_Git3.png) -Now we can choose additional components that we would like to also install but also associate with git. On Windows, I always make sure I install Git Bash as this allows us to run bash scripts on Windows. +Ahora podemos elegir componentes adicionales que nos gustaría también instalar para asociar con git. En Windows, siempre me aseguro de instalar Git Bash ya que nos permite ejecutar scripts bash en Windows. ![](Images/Day36_Git4.png) -We can then choose which SSH Executable we wish to use. IN leave this as the bundled OpenSSH that you might have seen in the Linux section. +Podemos entonces elegir qué ejecutable SSH deseamos utilizar. ![](Images/Day36_Git5.png) -We then have experimental features that we may wish to enable, for me I don't need them so I don't enable them, you can always come back in through the installation and enable these later on. +Luego tenemos características experimentales que podemos habilitar, yo no las necesito así que no las habilito, siempre puedes volver a la instalación y habilitarlas más tarde. ![](Images/Day36_Git6.png) -Installation complete, we can now choose to open Git Bash and or the latest release notes. +Instalación completada, ahora podemos elegir abrir Git Bash y o las últimas notas de la versión. ![](Images/Day36_Git7.png) -The final check is to take a look in our PowerShell window at what version of git we have now. +La comprobación final es echar un vistazo en PowerShell la versión actual de git. ![](Images/Day36_Git8.png) -Super simple stuff and now we are on the latest version. On our Linux machine, we seemed to be a little behind so we can also walk through that update process. +Super simple y ahora estamos en la última versión. -I simply run the `sudo apt-get install git` command. +En nuestra máquina Linux el proceso de actualización resulta más directo ejecutando el comando `sudo apt-get install git`. ![](Images/Day36_Git9.png) -You could also run the following which will add the git repository for software installations. +También puedes añadir el repositorio git para las actualizaciones del software. -``` +```shell sudo add-apt-repository ppa:git-core/ppa -y sudo apt-get update -sudo apt-get install git -y +sudo apt-get install git -yinstalaciones git --version ``` -### Configuring Git +### Configurando Git -When we first use git we have to define some settings, +Cuando usamos git por primera vez tenemos que definir algunas configuraciones, -- Name -- Email -- Default Editor -- Line Ending +- Nombre de usuario +- Correo electrónico +- Editor por defecto +- Fin de línea -This can be done at three levels +Esto se puede hacer en tres niveles -- System = All users -- Global = All repositories of the current user -- Local = The current repository +- Sistema = Todos los usuarios +- Global = Todos los repositorios del usuario actual +- Local = El repositorio actual -Example: -`git config --global user.name "Michael Cade"` -`git config --global user.email Michael.Cade@90DaysOfDevOPs.com"` -Depending on your Operating System will determine the default text editor. In my Ubuntu machine without setting the next command is using nano. The below command will change this to visual studio code. +Ejemplo: +```shell +git config --global user.name "Michael Cade" +git config --global user.email "Michael.Cade@90DaysOfDevOPs.com" +``` +Dependiendo del sistema operativo se determinará el editor de texto por defecto. En Ubuntu sin configurar el siguiente comando está utilizando nano. El siguiente comando cambiará esto a visual studio code. -`git config --global core.editor "code --wait"` +```shell +git config --global core.editor "code --wait" +``` -now if we want to be able to see all git configurations then we can use the following command. +Podemos ver todas las configuraciones de git con el siguiente comando. -`git config --global -e` +```shell +git config --global -e +``` ![](Images/Day36_Git10.png) -On any machine this file will be named `.gitconfig` on my Windows machine you will find this in your user account directory. +En cualquier máquina este archivo se llamará `.gitconfig`. En Windows lo encontrarás en el directorio de la cuenta de usuario. ![](Images/Day36_Git11.png) -### Git Theory +### Teoría Git -I mentioned in the post yesterday that there were other version control types and we can split these down into two different types. One is Client Server and the other is Distributed. +Mencioné en el post de ayer que había otros tipos de control de versiones y podemos dividirlos en dos tipos diferentes. Los que son Cliente-Servidor y los que son Distribuidos. -### Client-Server Version Control +### Control de versiones Cliente-Servidor -Before git was around Client-Server was the defacto method for version control. An example of this would be [Apache Subversion](https://subversion.apache.org/) which is an open source version control system founded in 2000. +Antes de que existiera git, el tipo de Cliente-Servidor era el método de facto para el control de versiones. Un ejemplo de esto sería [Apache Subversion](https://subversion.apache.org/) que es un sistema de control de versiones de código abierto fundado en el año 2000. -In this model of Client-Server version control, the first step the developer downloads the source code and the actual files from the server. This doesn't remove the conflicts but it does remove the complexity of the conflicts and how to resolve them. +En este modelo de control de versiones Cliente-Servidor, el primer paso que da el desarrollador es descargar el código fuente y los archivos reales del servidor. Esto no elimina los conflictos, pero sí la complejidad de los conflictos y cómo resolverlos. ![](Images/Day36_Git12.png) -Now for example let's say we have two developers working on the same files and one wins the race and commits or uploads their file back to the server first with their new changes. When the second developer goes to update they have a conflict. +Ahora, por ejemplo, digamos que tenemos dos desarrolladores trabajando en los mismos archivos y uno gana la carrera y confirma o sube su archivo de nuevo al servidor en primer lugar con sus nuevos cambios. Cuando el segundo desarrollador va a actualizar tiene un conflicto. ![](Images/Day36_Git13.png) -So now the Dev needs to pull down the first devs code change next to their check and then commit once those conflicts have been settled. +Así que ahora el desarrollador tiene que tirar hacia abajo el primer cambio de código junto a su cheque y luego confirmar una vez que los conflictos se han resuelto. ![](Images/Day36_Git15.png) -### Distributed Version Control +### Control de versiones distribuido -Git is not the only distributed version control system. But it is very much the defacto. +Git no es el único sistema de control de versiones distribuido. Pero es en gran medida el defacto. -Some of the major benefits of Git are: +Algunos de los principales beneficios de Git son: -- Fast -- Smart +- Rápido +- Inteligente - Flexible -- Safe & Secure +- Seguro -Unlike the Client-Server version control model, each developer downloads the source repository meaning everything. History of commits, all the branches etc. +A diferencia del modelo de control de versiones Cliente-Servidor, cada desarrollador descarga el repositorio fuente, es decir, todo. Historial de commits, todas las ramas, etc. ![](Images/Day36_Git16.png) -## Resources +## Recursos - [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) - [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) @@ -140,5 +142,13 @@ Unlike the Client-Server version control model, each developer downloads the sou - [Git for Professionals Tutorial](https://www.youtube.com/watch?v=Uszj_k0DGsg) - [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) - [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) +- [En español] [Comandos Git](https://gitea.vergaracarmona.es/man-linux/comandos-git) +- [En español][Apuntes Curso de Git](https://vergaracarmona.es/wp-content/uploads/2022/10/Curso-git_vergaracarmona.es_.pdf) de [Juan Carlos Rubio](https://www.linkedin.com/in/juan-carlos-rubio-pineda/Curso-git_vergaracarmona-es). +- [En español] En los [apuntes](https://vergaracarmona.es/apuntes/) del traductor: + - ["Instalar git en ubuntu"](https://vergaracarmona.es/instalar-git-en-ubuntu/) + - ["Comandos de git"](https://vergaracarmona.es/comandos-de-git/) + - ["Estrategias de fusión en git: Ship / Show / Ask"](https://vergaracarmona.es/estrategias-bifurcacion-git-ship-show-ask/) + - ["Resolver conflictos en Git. Merge, Squash, Rebase o Pull"](https://vergaracarmona.es/merge-squash-rebase-pull/) + - ["Borrar commits de git: reset, rebase y cherry-pick"](https://vergaracarmona.es/reset-rebase-cherry-pick/) -See you on [Day 37](day37.md) +Nos vemos en el [Día 37](day37.md) diff --git a/2022/es/Days/day37.md b/2022/es/Days/day37.md index 4cdbfef..094439e 100644 --- a/2022/es/Days/day37.md +++ b/2022/es/Days/day37.md @@ -1,154 +1,161 @@ -## Gitting to know Git +## Conociendo a Git -Apologies for the terrible puns in the title and throughout. I am surely not the first person to turn Git into a dad joke! +Pido disculpas por los terribles juegos de palabras del título (Título original: *Gitting to know Git*). Seguro que no soy la primera persona que convierte Git en un chiste de padres. -In the last two posts we learnt about version control systems, and some of the fundamental workflows of git as a version control system [Day 35](day35.md) Then we got git installed on our system, updated and configured. We also went a little deeper into the theory between the Client-Server version control system and Git which is a distributed version control system [Day 36](day36.md). +En los dos últimos posts aprendimos acerca de los sistemas de control de versiones, y algunos de los flujos de trabajo fundamentales de git ([Día 35](day35.md)). Luego conseguimos instalar git en nuestro sistema, actualizarlo y configurarlo. También vimos algo de la teoría entre los tipos de sistema de control de versiones Cliente-Servidor y los distribuidos en el [Día 36](day36.md). -Now we are going to run through some of the commands and use cases that we will all commonly see with git. +Ahora vamos a repasar algunos de los comandos y casos de uso habituales con git. -### Where to git help with git? +### Git ayuda con git -There are going to be times when you just cannot remember or just don't know the command you need to get things done with git. You are going to need help. +Habrá momentos en los que simplemente no recuerdes o no sepas el comando que necesitas para hacer algo con git. Necesitarás ayuda. Google o cualquier motor de búsqueda será probablemente tu primer puerto de escala cuando busques ayuda. (También las IAs) -Google or any search engine is likely to be your first port of call when searching for help. - -Secondly, the next place is going to be the official git site and the documentation. [git-scm.com/docs](http://git-scm.com/docs) Here you will find not only a solid reference to all the commands available but also lots of different resources. +El siguiente lugar, sobretodo a modo de confirmación, va a ser el sitio oficial de git y la documentación: [git-scm.com/docs](http://git-scm.com/docs). Aquí no sólo encontrarás una referencia sólida de todos los comandos disponibles, sino también un montón de recursos diferentes. ![](Images/Day37_Git1.png) -We can also access this same documentation which is super useful if you are without connectivity from the terminal. If we chose the `git add` command for example we can run `git add --help` and we see below the manual. +También podemos acceder a esta misma documentación desde la terminal, lo cual es muy útil si trabajas sin conexión. Si elegimos el comando `git add` por ejemplo podemos ejecutar `git add --help` y veremos el manual concreto del subcomando. ![](Images/Day37_Git2.png) -We can also in the shell use `git add -h` which is going to give us a summary of the options we have available. +También podemos usar en la shell `git add -h` que nos va a dar un resumen de las opciones que tenemos disponibles. ![](Images/Day37_Git3.png) -### Myths surrounding Git +### Mitos en torno a Git -"Git has no access control" - You can empower a leader to maintain source code. +"Git no tiene control de acceso" - Puedes autorizar a quien quieras a mantener el código fuente. -"Git is too heavy" - Git can provide shallow repositories which means a reduced amount of history if you have large projects. +"Git es demasiado pesado" - Git puede proporcionar repositorios poco profundos, lo que significa una cantidad reducida de historial si tienes proyectos grandes. -### Real shortcomings +### Deficiencias reales -Not ideal for Binary files. Great for source code but not great for executable files or videos for example. +No es ideal para archivos binarios. Es ideal para código fuente, pero no para archivos ejecutables o vídeos, por ejemplo. -Git is not user-friendly, the fact that we have to spend time talking about commands and functions of the tool is probably a key sign of that. +Git no es fácil de aprender, el hecho de que tengamos que pasar tiempo hablando de comandos y funciones de la herramienta es probablemente una señal de ello. Sin embargo, en general, git es difícil de aprender pero fácil de usar. -Overall though, git is hard to learn but easy to use. +### El ecosistema git -### The git ecosystem +Quiero cubrir brevemente el ecosistema alrededor de git pero no profundizar en estas áreas, pero creo que es importante señalarlas aquí a un alto nivel. -I want to briefly cover the ecosystem around git but not deep dive into some of these areas but I think it's important to note these here at a high level. +Casi todas las herramientas de desarrollo modernas soportan Git. -Almost all modern development tools support Git. - -- Developer tools - We have already mentioned visual studio code but you will find git plugins and integrations into sublime text and other text editors and IDEs. -- Team tools - Also mentioned around tools like Jenkins from a CI/CD point of view, Slack from a messaging framework and Jira for project management and issue tracking. - -- Cloud Providers - All the large cloud providers support git, Microsoft Azure, Amazon AWS, and Google Cloud Platform. -- Git-Based services - Then we have GitHub, GitLab and BitBucket which we will cover in more detail later on. I have heard of these services as the social network for code! +- **Herramientas para desarrolladores** - Ya hemos mencionado visual studio code pero encontrarás plugins de git e integraciones en sublime text y otros editores de texto e IDEs. +- **Herramientas de equipo** - También se han mencionado herramientas como Jenkins desde un punto de vista de CI/CD, Slack desde un marco de mensajería y Jira para la gestión de proyectos y seguimiento de incidencias. +- **Proveedores de nube** - Todos los grandes proveedores de nube soportan git: Microsoft Azure, Amazon AWS y Google Cloud Platform. +- **Servicios basados en Git** - Luego tenemos GitHub, GitLab y BitBucket que cubriremos en más detalle más adelante. Estos servicios se conocen como las redes sociales del código. ### The Git Cheatsheet -We have not covered most of these commands but having looked at some cheat sheets available online I wanted to document some of the git commands and what their purpose is. We don't need to remember these all, and with more hands-on practice and use you will pick at least the git basics. +No hemos cubierto la mayoría de comandos de git, ya que tiene un amplio abanico de posibilidades, pero después de haber mirado algunas hojas de trucos disponibles en línea vamos a documentar algunos de ellos y su propósito. No necesitamos recordarlos todos, ya que a través de la práctica y el uso aprenderás al menos mucho más de git. -I have taken these from [atlassian](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) but writing them down and reading the description is a good way to get to know what the commands are as well as getting hands-on in everyday tasks. +Estos comandos se han sacado de [atlassian](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet), escribirlos y leer la descripción es una buena forma de conocer su uso, así que manos a la obra en las tareas diarias: -### Git Basics +- [Conceptos básicos de Git](#conceptos-básicos-de-git) +- [Deshacer cambios Git](#deshacer-cambios-git) +- [Historial de reescritura de Git](#historial-de-reescritura-de-git) +- [Git Branches](#git-branches) +- [Repositorios remotos Git](#repositorios-remotos-git) +- [Git Diff](#git-diff) +- [Git Config](#git-config) +- [Git Rebase](#git-rebase) +- [Git Pull](#git-pull) +- [Git Reset](#git-reset) +- [Git Push](#git-push) -| Command | Example | Description | -| ------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------- | -| git init | `git init ` | Create an empty git repository in the specified directory. | -| git clone | `git clone ` | Clone repository located at onto local machine. | -| git config | `git config user.name` | Define author name to be used for all commits in current repository `system`, `global`, `local` flag to set config options. | -| git add | `git add ` | Stage all changes in for the next commit. We can also add and <.> for everything. | -| git commit -m | `git commit -m ""` | Commit the staged snapshot, use to detail what is being committed. | -| git status | `git status` | List files that are staged, unstaged and untracked. | -| git log | `git log` | Display all commit history using the default format. There are additional options with this command. | -| git diff | `git diff` | Show unstaged changes between your index and working directory. | +### Conceptos básicos de Git -### Git Undoing Changes +| Comando | Ejemplo | Descripción | +| ------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------- | +| git init | `git init ` | Crea un repositorio git vacío en el directorio especificado. | +| git clone | `git clone ` | Clona el repositorio ubicado en en la máquina local. | +| git config | `git config user.name` | Definir opciones que se usará para todos los commits según el entorno `system`, `global` o `local`. | +| git add | `git add ` | Prepara los cambios en para la próxima confirmación. También podemos añadir y <.> para todo. | +| git commit -m | `git commit -m ""` | Confirmar la instantánea preparada, usando para detallar lo que se está confirmando. | +| git status | `git status` | Lista los archivos que están organizados, no organizados y sin seguimiento. | +| git log | `git log` | Muestra todo el historial de confirmaciones usando el formato por defecto. Hay opciones adicionales con este comando. | +| git diff | `git diff` | Muestra los cambios no organizados entre tu índice y el directorio de trabajo. | -| Command | Example | Description | -| ---------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | -| git revert | `git revert ` | Create a new commit that undoes all of the changes made in then apply it to the current branch. | -| git reset | `git reset ` | Remove from the staging area, but leave the working directory unchanged. This unstaged a file without overwriting any changes. | -| git clean | `git clean -n` | Shows which files would be removed from the working directory. Use `-f` in place of `-n` to execute the clean. | +### Deshacer cambios Git -### Git Rewriting History +| Comando | Ejemplo | Descripción | +| ---------- | --------------------- | ------------------------------------------------------------------------------------------------------------------ | +| git revert | `git revert ` | Crear un nuevo commit que deshaga todos los cambios realizados en y aplicarlo a la rama actual. | +| git reset | `git reset ` | Elimina del área de preparación dejando el directorio de trabajo sin cambios. | +| git clean | `git clean -n` | Muestra qué archivos se eliminarán del directorio de trabajo. Usa `-f` en lugar de `-n` para ejecutar la limpieza. | -| Command | Example | Description | -| ---------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | -| git commit | `git commit --amend` | Replace the last commit with the staged changes and the last commit combined. Use with nothing staged to edit the last commit’s message. | -| git rebase | `git rebase ` | Rebase the current branch onto . can be a commit ID, branch name, a tag, or a relative reference to HEAD. | -| git reflog | `git reflog` | Show a log of changes to the local repository’s HEAD. Add --relative-date flag to show date info or --all to show all refs. | +### Historial de reescritura de Git + +| Comando | Ejemplo | Descripción | +| ---------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | +| git commit | `git commit --amend` | Reemplazar el último commit con los cambios en staged y el último commit combinados. Editas el mensaje del último commit. | +| git rebase | `git rebase ` | Rebase la rama actual en que puede ser un commit ID, un nombre de rama, una etiqueta o una referencia relativa a HEAD. | +| git reflog | `git reflog` | Muestra registro de cambios en el HEAD del repositorio local. Con --relative-date muestra información de fechas y --all para mostrar todas las referencias. | ### Git Branches -| Command | Example | Description | -| ------------ | -------------------------- | ------------------------------------------------------------------------------------------------------------- | -| git branch | `git branch` | List all of the branches in your repo. Add a argument to create a new branch with the name . | -| git checkout | `git checkout -b ` | Create and check out a new branch named . Drop the -b flag to checkout an existing branch. | -| git merge | `git merge ` | Merge into the current branch. | +| Comando | Ejemplo | Descripción | +| ------------ | -------------------------- | ---------------------------------------------------------------------------------------------------------------------- | +| git branch | `git branch` | Lista todas las ramas de tu repositorio. Añade un argumento para crear una nueva rama con el nombre . | +| git checkout | `git checkout -b ` | Crea y comprueba una nueva rama con el nombre . Elimina la opción -b para obtener una rama existent | +| git merge | `git merge ` | Fusiona en la rama actual. | -### Git Remote Repositories +### Repositorios remotos Git -| Command | Example | Description | -| -------------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| git remote add | `git remote add ` | Create a new connection to a remote repo. After adding a remote, you can use as a shortcut for in other commands. | -| git fetch | `git fetch ` | Fetches a specific , from the repo. Leave off to fetch all remote refs. | -| git pull | `git pull ` | Fetch the specified remote’s copy of current branch and immediately merge it into the local copy. | -| git push | `git push ` | Push the branch to , along with necessary commits and objects. Creates named branch in the remote repo if it doesn’t exist. | +| Comando | Ejemplo | Descripción | +| -------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| git remote add | `git remote add ` | Crea una nueva conexión a un repositorio remoto. Después de añadir un remoto, puedes usar como atajo para en otros comandos. | +| git fetch | `git fetch ` | Obtiene un específico del repositorio. Deja para obtener todas las referencias remotas. | +| git pull | `git pull ` | Obtiene la copia remota especificada de la rama actual e inmediatamente la fusiona con la copia local. | +| git push | `git push ` | Empuja la rama a , junto con los commits y objetos necesarios. Crea la rama con el nombre en el repositorio remoto si no existe. | ### Git Diff -| Command | Example | Description | -| ----------------- | ------------------- | ---------------------------------------------------------------------- | -| git diff HEAD | `git diff HEAD` | Show the difference between the working directory and the last commit. | -| git diff --cached | `git diff --cached` | Show difference between staged changes and last commit | +| Comando | Ejemplo | Descripción | +| ----------------- | ------------------- | ------------------------------------------------------------------------ | +| git diff HEAD | `git diff HEAD` | Muestra la diferencia entre el directorio de trabajo y el último commit. | +| git diff --cached | `git diff --cached` | Muestra la diferencia entre los cambios realizados y el último commit. | ### Git Config -| Command | Example | Description | -| ---------------------------------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | -| git config --global user.name | `git config --global user.name ` | Define the author name to be used for all commits by the current user. | -| git config --global user.email | `git config --global user.email ` | Define author email to be used for all commits by the current user. | -| git config --global alias | `git config --global alias ` | Create shortcut for a git command . | -| git config --system core.editor | `git config --system core.editor ` | Set the text editor to be used by commands for all users on the machine. arg should be the comamnd that launches the desired editor. | -| git config --global --edit | `git config --global --edit ` | Open the global configuration file in a text editor for manual editing. | +| Comando | Ejemplo | Descripción | +| ---------------------------------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- | +| git config --global user.name | `git config --global user.name ` | Define el nombre de autor que se usará para todos los commits del usuario actual. | +| git config --global user.email | `git config --global user.email ` | Define el email del autor que se usará para todas las confirmaciones del usuario actual. | +| git config --global alias | `git config --global alias ` | Crear un acceso directo para un comando git. | +| git config --system core.editor | `git config --system core.editor ` | Establece el editor de texto que usarán todos los usuarios de la máquina. arg debe ser el comando que lanza el editor deseado. | +| git config --global --edit | `git config --global --edit ` | Abrir el archivo de configuración global en un editor de texto para su edición manual. | ### Git Rebase -| Command | Example | Description | -| -------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| git rebase -i | `git rebase -i ` | Interactively rebase current branch onto . Launches editor to enter commands for how each commit will be transferred to the new base. | +| Comando | Ejemplo | Descripción | +| -------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | +| git rebase -i | `git rebase -i ` | Rebase interactivamente la rama actual en . Inicia el editor para introducir comandos sobre cómo se transferirá cada confirmación a la nueva base. | ### Git Pull -| Command | Example | Description | -| -------------------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | -| git pull --rebase | `git pull --rebase ` | Fetch the remote’s copy of current branch and rebases it into the local copy. Uses git rebase instead of the merge to integrate the branches. | +| Comando | Ejemplo | Descripción | +| -------------------------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| git pull --rebase | `git pull --rebase ` | Obtiene la copia remota de la rama actual y la vuelve a basar en la copia local. Utiliza git rebase en lugar de merge para integrar las ramas. | ### Git Reset -| Command | Example | Description | -| ------------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | -| git reset | `git reset ` | Reset the staging area to match the most recent commit but leave the working directory unchanged. | -| git reset --hard | `git reset --hard` | Reset staging area and working directory to match most recent commit and overwrites all changes in the working directory | -| git reset | `git reset ` | Move the current branch tip backwards to , reset the staging area to match, but leave the working directory alone | -| git reset --hard | `git reset --hard ` | Same as previous, but resets both the staging area & working directory to match. Deletes uncommitted changes, and all commits after . | +| Comando | Ejemplo | Descripción | +| ------------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| git reset | `git reset ` | Restablece el área de preparación para que coincida con la confirmación más reciente, pero deja el directorio de trabajo sin cambios. | +| git reset --hard | `git reset --hard` | Restablece el área de preparación y el directorio de trabajo para que coincidan con la confirmación más reciente y sobreescribe todos los cambios en el directorio de trabajo. | +| git reset | `git reset ` | Mueve la punta de la rama actual hacia atrás hasta , resetea el área de preparación para que coincida, pero deja el directorio de trabajo solo | +| git reset --hard | `git reset --hard ` | Igual que el anterior, pero reinicia tanto el área de preparación como el directorio de trabajo para que coincidan. Borra los cambios no comprometidos, y todos los commits posteriores a . | ### Git Push -| Command | Example | Description | -| ------------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -| git push --force | `git push --force` | Forces the git push even if it results in a non-fast-forward merge. Do not use the --force flag unless you’re sure you know what you’re doing. | -| git push --all | `git push --all` | Push all of your local branches to the specified remote. | -| git push --tags | `git push --tags` | Tags aren’t automatically pushed when you push a branch or use the --all flag. The --tags flag sends all of your local tags to the remote repo. | +| Comando | Ejemplo | Descripción | +| ------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| git push --force | `git push --force` | Fuerza el git push incluso si resulta en una fusión no rápida. No uses la opción --force a menos que estés seguro de lo que haces. | +| git push --all | `git push --all` | Envía todas tus ramas locales a la remota especificada. | +| git push --tags | `git push --tags` | Las etiquetas no se envían automáticamente cuando envías una rama o usas la opción --all. La opción --tags envía todas tus etiquetas locales al repositorio remoto. | -## Resources +## Recursos - [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) - [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) @@ -157,5 +164,13 @@ I have taken these from [atlassian](https://www.atlassian.com/git/tutorials/atla - [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) - [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) - [Git cheatsheet](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) +- [En español] [Comandos Git](https://gitea.vergaracarmona.es/man-linux/comandos-git) +- [En español][Apuntes Curso de Git](https://vergaracarmona.es/wp-content/uploads/2022/10/Curso-git_vergaracarmona.es_.pdf) de [Juan Carlos Rubio](https://www.linkedin.com/in/juan-carlos-rubio-pineda/Curso-git_vergaracarmona-es). +- [En español] En los [apuntes](https://vergaracarmona.es/apuntes/) del traductor: + - ["Instalar git en ubuntu"](https://vergaracarmona.es/instalar-git-en-ubuntu/) + - ["Comandos de git"](https://vergaracarmona.es/comandos-de-git/) + - ["Estrategias de fusión en git: Ship / Show / Ask"](https://vergaracarmona.es/estrategias-bifurcacion-git-ship-show-ask/) + - ["Resolver conflictos en Git. Merge, Squash, Rebase o Pull"](https://vergaracarmona.es/merge-squash-rebase-pull/) + - ["Borrar commits de git: reset, rebase y cherry-pick"](https://vergaracarmona.es/reset-rebase-cherry-pick/) -See you on [Day 38](day38.md) +Nos vemos en el [Día 38](day38.md) diff --git a/2022/es/Days/day38.md b/2022/es/Days/day38.md index 6627fbe..673a7ee 100644 --- a/2022/es/Days/day38.md +++ b/2022/es/Days/day38.md @@ -1,110 +1,110 @@ -## Staging & Changing +## Puesta en marcha (Staging) y cambios de git -We have already covered some of the basics but putting things into a walkthrough makes it better for me to learn and understand how and why we are doing it this way. Before we get into any git-based services such as GitHub, git has its powers that we can take advantage of on our local workstation. +Ya hemos cubierto algunos de los conceptos básicos, pero poner las cosas en un tutorial hace que sea mejor para aprender y entender cómo y por qué lo estamos haciendo de esta manera en concreto. Antes de entrar en cualquier servicio basado en git como GitHub, git tiene superpoderes para aprovechar en local. -We are going to take the project folder we created at the start of the git session and we are going to walk through some of the simple steps we can do with git. We created a folder on our local machine and we initialised it with the `git init` command +Vamos a verlos seleccionando la carpeta del proyecto que creamos al inicio de la sesión de git y veremos algunos de los sencillos y potentes pasos que podemos hacer con git. Creamos una carpeta en nuestra máquina local y la inicializamos con el comando `git init`. ![](Images/Day38_Git1.png) -We can also see now that we have initialised the folder we have a hidden folder in our directory. +También podemos ver que después de inicializar tenemos una carpeta oculta en nuestro directorio: `.git`. ![](Images/Day38_Git2.png) -This is where the details of the git repository are stored as well as the information regarding our branches and commits. +Aquí es donde se almacenan los detalles del repositorio git así como la información relativa a nuestras ramas y commits. ¡Donde habita toda la magía de git! -### Staging Files +### Ficheros Staging -We then start working on our empty folder and maybe we add some source code on the first days of work. We create our readme.mdfile and we can see that file in the directory, next we check our `git status` and it knows about the new readme.mdfile but we have not committed the file yet. +A continuación, empezamos a trabajar en nuestra carpeta vacía. Podemos añadir algo de código fuente de los primeros días de trabajo. Creamos nuestro fichero `readme.md` y comprobamos nuestro `git status`. Veremos el nuevo fichero `readme.md` pero sin confirmar todavía. ![](Images/Day38_Git3.png) -We can stage our readme.mdfile with the `git add README.md` command then we can see changes to be committed that we did not have before and a green new file. +Con el comando `git add README.md` podremos ver en `git status` que el fichero está en verde, esto indica que tenemos los cambios preparados para confirmar. ![](Images/Day38_Git4.png) -Next up we want to commit this, our first commit or our first snapshot of our project. We can do this by using the `git commit -m "Meaningful message"` command so that we can easily see what has changed for each commit. Also, notice the yellow cross changes now to a green tick. This is something I have within my terminal with the theme I use, something we covered in the Linux section. +A continuación vamos confirmar esto, que no quede pendiente, haremos nuestro primer commit o, visto de otra manera, la primera instantánea de nuestro proyecto. Esto lo hacemos con el comando `git commit -m ""` dejando un mensaje esclarecedor y conciso que describa los cambios que se incluyen a la rama. Además, observe que la cruz amarilla cambia ahora a una marca verde. Esto es algo que tengo dentro de mi terminal con el tema que uso, lo vimos en la sección de Linux. ![](Images/Day38_Git5.png) -### Committing Changes +### Confirmando cambios -We are going to most likely want to add more files or even change the files we have in our directory. We have already done our first commit above. But now we are going to add more details and more files. +O como maldecimos algunos en español "comiteando que es gerundio". Lo más probable es que queramos añadir más archivos o incluso cambiar los archivos que tenemos en nuestro directorio. Ya hemos hecho nuestro primer commit, pero ahora vamos a añadir más y más y más. -We could repeat our process from before, create or edit our file > `git add .` to add all files to the staging area then `git commit -m "meaningful message"` and this would work just fine. But to be able to offer a meaningful message on commit of what has changed you might not want to write something out like `git commit -m "Well, I changed some code because it did not work and when I fixed that I also added something new to the readme.mdto ensure everyone knew about the user experience and then I made a tea."` I mean this would work as well although probably make it descriptive but the preferred way here is to add this with a text editor. +Podríamos repetir nuestro proceso de antes, crear o editar nuestro archivo con `git add .` para añadir todos los archivos a la zona de preparación y luego `git commit -m "mensaje significativo"` y esto funcionaría sin problemas. Pero para ser capaz de ofrecer un mensaje significativo en el commit de lo que ha cambiado puede que no quieras escribir algo como `git commit -m "Bueno, he cambiado algo de código porque no funcionaba y cuando lo arreglé también añadí algo nuevo al readme.mdpara asegurarme de que todo el mundo conocía la experiencia de usuario y luego hice un té."` Quiero decir que esto funcionaría también aunque probablemente lo haría descriptivo pero la forma preferida aquí es añadir esto con un editor de texto. -If we run `git commit` after running `git add` it will open our default text editor which in my case here is nano. Here are the steps I took to add some changes to the file, ran `git status` to show what is and what is not staged. Then I used `git add` to add the file to the staging area, then ran `git commit` which opened nano. +Si ejecutamos `git commit` después de ejecutar `git add` se abrirá nuestro editor de texto por defecto que en mi caso es nano. Estos son los pasos que seguí para añadir algunos cambios al archivo, ejecuté `git status` para mostrar lo que está y lo que no está preparado. Luego usé `git add` para agregar el archivo al área de staging, luego ejecuté `git commit` que abrió nano. ![](Images/Day38_Git6.png) -When nano opens you can then add your short and long description and then save the file. +Cuando se abra nano puedes añadir tu descripción corta y larga y luego guardar el archivo. ![](Images/Day38_Git7.png) -### Committing Best Practices +### Mejores prácticas para el commit -There is a balance here between when to commit and commit often. We do not want to be waiting to be finished the project before committing, each commit should be meaningful and they also should not be coupled with non-relevant tasks with each other. If you have a bug fix and a typo make sure they are two separate commits as a best practice. +Hay un equilibrio entre confirmar empaquetando cambios relacionados y confirmar a menudo. No queremos esperar a terminar un proyecto para nuestro primer commit y cada confirmación debe ser significativa. Tampoco debe estar asociada con tareas no relevantes entre sí. Si tienes una corrección de errores y un error tipográfico la mejor práctica es asegurarse de incluirlos en dos commits distintos. Así puedes abreviar y darle significado al mensaje del commit. -Make the commit message mean something. +En términos de redacción, el equipo o tú mismo deberíais ceñiros a la misma redacción para cada confirmación. Por ejemplo, recomiendan que los mensajes comiencen con un verbo en infinitivo, como "añadir" o "eliminar". Esto ayuda a mantener la consistencia y a que los mensajes sean más fáciles de leer. En muchos proyectos se decide que sean en inglés. También se agradece la brevedad cuando repasas los logs de git 😅 -In terms of wording, the team or yourself should be sticking to the same wording for each commit. +### Saltarse la zona de preparación -### Skipping the Staging Area +¿Tenemos que preparar siempre nuestros cambios antes de confirmarlos? -Do we always have to stage our changes before committing them? +La respuesta es sí. Pero no lo veas como un handicap, es la manera de estar 100% seguro de que no vas a errar. Además, la práctica recomendada es evitar utilizar 'git add .' y en su lugar utilizar 'git add ' para añadir los cambios del archivo o archivos en concreto para ser más específico y asegurarte de que no estás añadiendo cambios que no quieres. ¿Conoces el dicho "Más vale prevenir que curar"? Pues eso. -The answer is yes but don't see this as a shortcut, you have to be sure 100% that you are not needing that snapshot to roll back to, it is a risky thing to do. +También hay una forma de saltarse la zona de preparación y confirmar directamente con el comando `git commit -a -m ""`. Es útil cuando tienes un cambio pequeño y no quieres tener que pasar por el proceso de preparación y confirmación. Pero cuidadito, si tienes muchos cambios y no los has preparado, esto podría añadirlos todos a la confirmación. ![](Images/Day38_Git8.png) -### Removing Files +### Eliminación de archivos -What about removing files from our project, maybe we have another file in our directory that we have committed but now the project no longer needs or using it, as a best practice we should remove it. +Qué pasa con la eliminación de archivos de nuestro proyecto, tal vez tenemos otro archivo en nuestro directorio que hemos confirmado, pero ahora el proyecto ya no lo necesita o utiliza, como una mejor práctica debemos eliminarlo. -Just because we remove the file from the directory, git is still aware of this file and we also need to remove it from the repository. You can see the workflow for this below. +Sólo porque eliminamos el archivo del directorio, git todavía es consciente de este archivo y también tenemos que eliminarlo del repositorio. Puedes ver el flujo de trabajo para esto a continuación. ![](Images/Day38_Git9.png) -That could be a bit of a pain to either remember or have to deal with if you have a large project which has many moving files and folders. We can do this with one command with `git rm oldcode.ps1` +Esto podría ser un poco molesto de recordar o tener que lidiar con ello si tienes un proyecto grande que tiene muchos archivos y carpetas en movimiento. Podemos hacer esto con un comando con `git rm oldcode.ps1`. ![](Images/Day38_Git10.png) -### Renaming or Moving Files +### Renombrar o Mover Archivos -Within our operating system, we can rename and move our files. We will no doubt need to do this from time to time with our projects. Similar to removing though there is a two-step process, we change our files on our OS and then we have to modify and make sure that the staging area or that the files are added correctly. Steps as follows: +Dentro de nuestro sistema operativo podemos renombrar y mover nuestros archivos. Sin duda necesitaremos hacer esto de vez en cuando con nuestros proyectos. Similar a eliminar aunque hay un proceso de dos pasos, cambiamos nuestros archivos en nuestro sistema operativo y luego tenemos que modificar y asegurarnos de que la zona de montaje o que los archivos se añaden correctamente. Los pasos son los siguientes: ![](Images/Day38_Git11.png) -However, like removing files from the operating system and then the git repository we can perform this rename using a git command too. +Sin embargo, al igual que eliminamos archivos del sistema operativo y luego del repositorio git podemos realizar este renombrado utilizando también un comando git. ![](Images/Day38_Git12.png) -### Ignoring Files +### Ignorando Archivos -We may have the requirement to ignore files or folders within our project that we might be using locally or that will be just wasted space if we were to share with the overall project, a good example of this could be logs. I also think using this for secrets that you do not want to be shared out in public or across teams. +Podemos tener la necesidad de ignorar los archivos o carpetas dentro de nuestro proyecto que podríamos estar utilizando a nivel local o que sólo sería un desperdicio de espacio si tuviéramos que compartir con el proyecto en general, un buen ejemplo de esto podría ser registros. También creo que el uso de este para los secretos que no quieren ser compartidos en público o entre los equipos. -We can ignore files by adding folders or files to the `.gitignore` file in our project directory. +Podemos ignorar archivos añadiendo carpetas o archivos al archivo `.gitignore` en el directorio de nuestro proyecto. ![](Images/Day38_Git13.png) -You can then open the `.gitignore` file and see that we have the logs/ directory present. But we could also add additional files and folders here to ignore. +Podemos abrir el archivo `.gitignore` y ver que tenemos el directorio logs/ presente. Pero también podríamos añadir aquí archivos y carpetas adicionales para ignorar. ![](Images/Day38_Git14.png) -We can then see `git status` and then see what has happened. +A continuación podemos ver `git status` y ver qué ha pasado. ![](Images/Day38_Git15.png) -There are also ways in which you might need to go back and ignore files and folders, maybe you did want to share the logs folder but then later realised that you didn't want to. You will have to use `git rm --cached ` to remove files and folders from the staging area if you have a previously tracked folder that you now want to ignore. +También hay formas en las que podrías necesitar volver atrás e ignorar archivos y carpetas, quizás querías compartir la carpeta de logs pero luego te diste cuenta de que no querías hacerlo. Tendrás que usar `git rm --cached ` para eliminar archivos y carpetas del área de preparación si tienes una carpeta previamente rastreada que ahora quieres ignorar. -### Short Status +### Estado breve -We have been using `git status` a lot to understand what we have in our staging area and what we do not, it's a very comprehensive command with lots of detail. Most of the time you will just want to know what has been modified or what is new? We can use `git status -s` for a short status of this detail. I would usually set an alias on my system to just use `git status -s` vs the more detailed command. +Hemos estado usando mucho `git status` para entender lo que tenemos en nuestra área de preparación y lo que no, es un comando muy completo con muchos detalles. La mayoría de las veces sólo querrás saber qué ha sido modificado o qué hay de nuevo. Podemos usar `git status -s` para un breve estado de este detalle. Yo normalmente establecería un alias en mi sistema para usar `git status -s` en lugar del comando más detallado. ![](Images/Day38_Git16.png) -In the post tomorrow we will continue to look through these short examples of these common git commands. +En el post de mañana seguiremos viendo estos breves ejemplos de estos comandos comunes de git. -## Resources +## Recursos - [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) - [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) @@ -113,5 +113,14 @@ In the post tomorrow we will continue to look through these short examples of th - [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) - [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) - [Git cheatsheet](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) +- [En español] [Comandos Git](https://gitea.vergaracarmona.es/man-linux/comandos-git) +- [En español][Apuntes Curso de Git](https://vergaracarmona.es/wp-content/uploads/2022/10/Curso-git_vergaracarmona.es_.pdf) de [Juan Carlos Rubio](https://www.linkedin.com/in/juan-carlos-rubio-pineda/Curso-git_vergaracarmona-es). +- [En español] En los [apuntes](https://vergaracarmona.es/apuntes/) del traductor: + - ["Instalar git en ubuntu"](https://vergaracarmona.es/instalar-git-en-ubuntu/) + - ["Comandos de git"](https://vergaracarmona.es/comandos-de-git/) + - ["Estrategias de fusión en git: Ship / Show / Ask"](https://vergaracarmona.es/estrategias-bifurcacion-git-ship-show-ask/) + - ["Resolver conflictos en Git. Merge, Squash, Rebase o Pull"](https://vergaracarmona.es/merge-squash-rebase-pull/) + - ["Borrar commits de git: reset, rebase y cherry-pick"](https://vergaracarmona.es/reset-rebase-cherry-pick/) +- [Ejemplos README.md para tus proyectos](https://gitea.vergaracarmona.es/manuelver/plantillas-README) -See you on [Day 39](day39.md) +Nos vemos en el [Día 39](day39.md). diff --git a/2022/es/Days/day39.md b/2022/es/Days/day39.md index f71d661..b7d20a3 100644 --- a/2022/es/Days/day39.md +++ b/2022/es/Days/day39.md @@ -1,194 +1,190 @@ -## Viewing, unstaging, discarding & restoring +## Visualización, desescalado, descarte y restauración -Continuing from where we finished yesterday around some of the commands that we have with git and how to leverage git with your projects. Remember we have not touched GitHub or any other git-based services yet this is all to help you keep control of your projects locally at the moment, but they will all become useful when we start to integrate into those tools. +Vamos a continuar donde lo dejamos ayer en torno a algunos de los comandos que tenemos con git y cómo aprovechar git con sus proyectos. Recuerde que no hemos tocado GitHub o cualquier otro servicio basado en git todavía, estamos viendo como mantener el control de los proyectos a nivel local por el momento, pero todos ellos serán útiles cuando empezamos a integrar esas herramientas. -### Viewing the Staged and Unstaged Changes +### Viendo los Cambios Staged y Unstaged -It is good practice to make sure you view the staged and unstaged code before committing. We can do this by running the `git diff --staged` command +Es una buena práctica asegurarse de ver el código preparado y no preparado antes de confirmar. Podemos hacerlo ejecutando el comando `git diff --staged` ![](Images/Day39_Git1.png) -This then shows us all the changes we have made and all new files we have added or deleted. +Esto nos muestra todos los cambios que hemos hecho y todos los archivos nuevos que hemos añadido o borrado. -changes in the modified files are indicated with `---` or `+++` you can see below that we just added +add some text below which means they are new lines. +Los cambios en los archivos modificados se indican con `---` o `+++` puedes ver abajo que acabamos de añadir +añadir algo de texto debajo lo que significa que son nuevas líneas. ![](Images/Day39_Git2.png) -We can also run `git diff` to compare our staging area with our working directory. If we make some changes to our newly added file code.txt and add some lines of text. +También podemos ejecutar `git diff` para comparar nuestra área de staging con nuestro directorio de trabajo. Si hacemos algunos cambios en nuestro archivo recién añadido code.txt y añadimos algunas líneas de texto. ![](Images/Day39_Git3.png) -If we then run `git diff` we compare and see the output below. +Si luego ejecutamos `git diff` comparamos y vemos la salida de abajo. ![](Images/Day39_Git4.png) -### Visual Diff Tools +### Herramientas visuales Diff -For me, the above is more confusing so I would much rather use a visual tool, - -To name a few visual diff tools: +Para mí, lo anterior es algo confuso, así que prefiero utilizar una herramienta visual. Por nombrar algunas de ellas: - KDiff3 - P4Merge -- WinMerge (Windows Only) +- WinMerge (Sólo Windows) - VSCode -To set this in git we run the following command `git config --global diff.tool vscode` +Para configurar esto en git ejecutamos el siguiente comando `git config --global diff.tool vscode`. -We are going to run the above and we are going to set some parameters when we launch VScode. +Vamos a ejecutar lo anterior y vamos a establecer algunos parámetros cuando lancemos VScode. ![](Images/Day39_Git5.png) -We can also check our configuration with `git config --global -e` +También podemos comprobar nuestra configuración con `git config --global -e`. ![](Images/Day39_Git6.png) -We can then use `git difftool` to now open our diff visual tool. +Podemos usar `git difftool` para abrir nuestra herramienta visual diff. ![](Images/Day39_Git7.png) -Which then opens our VScode editor on the diff page and compares the two, we have only modified one file from nothing to now adding a line of code on the right side. +Esto abre nuestro editor VScode en la página diff y compara los dos. Veremos que sólo hemos modificado un archivo añadiendo una línea de código en el lado derecho. ![](Images/Day39_Git8.png) -I find this method much easier to track changes and this is something similar to what we will see when we look into git-based services such as GitHub. +Encuentro este método mucho más fácil para rastrear cambios y es algo similar a lo que veremos cuando busquemos en servicios basados en git como GitHub. -We can also use `git difftool --staged` to compare stage with committed files. +También podemos usar `git difftool --staged` para comparar el stage con los archivos confirmados. ![](Images/Day39_Git9.png) -Then we can cycle through our changed files before we commit. +Entonces podemos ver el ciclo a través de nuestros archivos cambiados antes de confirmar. ![](Images/Day39_Git10.png) -I am using VScode as my IDE and like most IDEs they have this functionality built in it is very rare you would need to run these commands from the terminal, although helpful if you don't have an IDE installed for some reason. +Estoy usando VScode como mi IDE y como la mayoría de los IDEs tienen esta funcionalidad incorporada. Es muy raro que necesites ejecutar estos comandos desde la terminal, aunque es útil si no tienes un IDE instalado por alguna razón. -### Viewing the History +### Viendo el Historial -We previously touched on `git log` which will provide us with a comprehensive view of all commits we have made in our repository. +Anteriormente hemos tocado `git log` que nos proporcionará una visión completa de todos los commits que hemos hecho en nuestro repositorio. ![](Images/Day39_Git11.png) -Each commit has its hexadecimal string, unique to the repository. Here you can see which branch we are working on and then also the author, date and commit message. +Cada commit tiene su cadena hexadecimal, única para el repositorio. Aquí puedes ver en qué rama estamos trabajando y también el autor, la fecha y el mensaje de confirmación. -We also have `git log --oneline` and this gives us a much smaller version of the hexadecimal string which we can use in other `diff` commands. We also only have the one-line description or commit message. +También tenemos `git log --oneline` que nos devuelve una versión mucho más pequeña de la cadena hexadecimal que podemos usar en otros comandos `diff`. También tenemos sólo la descripción de una línea o el mensaje de commit. ![](Images/Day39_Git12.png) -We can reverse this into a start with the first commit by running `git log --oneline --reverse` and now we see our first commit at the top of our page. +Podemos revertir esto en un inicio con el primer commit ejecutando `git log --oneline --reverse` y ahora vemos nuestro primer commit en la parte superior de nuestra página. ![](Images/Day39_Git13.png) -### Viewing a Commit +### Ver un commit -Being able to look at the commit message is great if you have been conscious about following best practices and you have added a meaningful commit message, however, there is also `git show` command which allows us to inspect and view a commit. - -We can use `git log --oneline --reverse` to get a list of our commits. and then we can take those and run `git show ` +Ser capaz de mirar el mensaje de confirmación es genial si has sido consciente de seguir las mejores prácticas y has añadido un mensaje de confirmación significativo, sin embargo, también existe el comando `git show` si queremos inspeccionar un commit concreto. Podemos utilizar `git log --oneline --reverse` para obtener una lista de nuestros commits. y luego podemos tomarlos y ejecutar `git show `. ![](Images/Day39_Git14.png) -The output of that command will look like below with the detail of the commit, author and what changed. +La salida de ese comando se verá como abajo con el detalle del commit, autor y lo que cambió. ![](Images/Day39_Git15.png) -We can also use `git show HEAD~1` where 1 is how many steps back from the current version we want to get back to. +También podemos usar `git show HEAD~1` donde 1 es el número de pasos hacia atrás desde la versión actual a la que queremos volver. -This is great if you want some detail on your files, but if we want to list all the files in a tree for the whole snapshot directory. We can achieve this by using the `git ls-tree HEAD~1` command, again going back one snapshot from the last commit. We can see below we have two blobs, these indicate files whereas the tree would indicate a directory. You can also see commits and tags in this information. +Esto es genial si queremos algún detalle de nuestros archivos, pero si queremos listar todos los archivos de un árbol para todo el directorio de la instantánea. Podemos conseguirlo usando el comando `git ls-tree HEAD~1`, de nuevo retrocediendo una instantánea desde el último commit. Podemos ver abajo que tenemos dos blobs, estos indican archivos mientras que el árbol indicaría un directorio. También puedes ver commits y tags en esta información. ![](Images/Day39_Git16.png) -We can then use the above to drill in and see the contents of our file (blobs) using the `git show` command. +Podemos usar lo anterior para ver el contenido de nuestro archivo (blobs) usando el comando `git show`. ![](Images/Day39_Git17.png) -Then the contents of that specific version of the file will be shown. +Entonces se mostrará el contenido de esa versión específica del archivo. ![](Images/Day39_Git18.png) -### Unstaging Files +### Unstaging archivos -There will be a time when you have maybe used `git add .` but there are files you do not wish to commit to that snapshot just yet. In this example below I have added newfile.txt to my staging area but I am not ready to commit this file so I am going to use the `git restore --staged newfile.txt` to undo the `git add` step. +Habrá un momento en el que quizás haya usado `git add .` pero hay archivos que no desea confirmar en esa instantánea todavía. En este ejemplo he añadido newfile.txt a mi área de staging pero no estoy listo para confirmar este archivo así que voy a usar `git restore --staged newfile.txt` para deshacer el paso `git add`. ![](Images/Day39_Git19.png) -We can also do the same to modified files such as main.js and unstage the commit, see above we have a greem M for modified and then below we are unstaging those changes. +También podemos hacer lo mismo con archivos modificados como main.js y deshacer el commit, mira arriba tenemos una M en verde y abajo hemos deshecho esos cambios. ![](Images/Day39_Git20.png) -I have found this command quite useful during the 90DaysOfDevOps as I sometimes work ahead of the days where I feel I want to make notes for the following day but I don't want to commit and push to the public GitHub repository. +He encontrado este comando bastante útil durante los 90DaysOfDevOps ya que a veces trabajo antes de los días en los que siento que quiero hacer anotaciones para el día siguiente pero no quiero hacer commit y push al repositorio público de GitHub. -### Discarding Local Changes +### Descartando Cambios Locales -Sometimes we might make changes but we are not happy with those changes and we want to throw them away. We are going to use the `git restore` command again and we are going to be able to restore files from our snapshots or previous versions. We can run `git restore .` against our directory and we will restore everything from our snapshot but notice that our untracked file is still present. There is no previous file being tracked called newfile.txt. +A veces podemos hacer cambios pero no estamos contentos con esos cambios y queremos desecharlos. Vamos a utilizar el comando `git restore` de nuevo y vamos a poder restaurar archivos de nuestras snapshots o versiones anteriores. Podemos ejecutar `git restore .` contra nuestro directorio y restauraremos todo desde nuestra instantánea, pero observa que nuestro archivo no rastreado sigue presente. No hay ningún archivo anterior siendo rastreado llamado newfile.txt. ![](Images/Day39_Git21.png) -Now to remove newfile.txt or any untracked files. We can use `git clean` we will get a warning alone. +Ahora para eliminar newfile.txt o cualquier archivo no rastreado. Podemos usar `git clean` solo obtendremos una advertencia. ![](Images/Day39_Git22.png) -Or if we know the consequences then we might want to run `git clean -fd` to force and remove all directories. +O si conocemos las consecuencias podemos ejecutar `git clean -fd` para forzar y eliminar todos los directorios. ![](Images/Day39_Git23.png) -### Restoring a File to an Earlier Version +### Restaurar un archivo a una versión anterior -As we have alluded to throughout a big portion of what Git can help with is being able to restore copies of your files from your snapshots (this is not a backup but it is a very fast restore point) My advice is that you also save copies of your code in other locations using a backup solution for this. +Como hemos aludido, lo que Git nos puede ayudar es a restaurar copias de tus archivos desde tus instantáneas (esto no es una copia de seguridad, pero es un punto de restauración muy rápido). Es recomendable que también guardes copias de tu código en otros lugares utilizando una solución de copia de seguridad expresamente para esto. -As an example let's go and delete our most important file in our directory, notice we are using Unix-based commands to remove this from the directory, not git commands. +Como ejemplo vamos a borrar nuestro archivo más importante en nuestro directorio, pero utilizando comandos basados en Unix para eliminar el directorio, no comandos de git. ![](Images/Day39_Git24.png) -Now we have no readme.mdin our working directory. We could have used `git rm readme.md` and this would then be reflected in our git database. Let's also delete it from here to simulate it being removed completely. +Ahora no tenemos readme.md en nuestro directorio de trabajo. Podríamos haber usado `git rm readme.md` y esto se reflejaría en nuestra base de datos de git. Así que lo borramos también así para simular la eliminación por completo. ![](Images/Day39_Git25.png) -Let's now commit this with a message and prove that we no longer have anything in our working directory or staging area. +Ahora confirmemos esto con un mensaje y probemos que ya no tenemos nada en nuestro directorio de trabajo o área de preparación. ![](Images/Day39_Git26.png) -Mistakes were made and we now need this file back! +¡Se cometieron errores y ahora necesitamos recuperar ese archivo! 😱 -We could use the `git undo` command which will undo the last commit, but what if it was a while back? We can use our `git log` command to find our commits and then we find that our file is in the last commit but we don't all of those commits to be undone so we can then use this command `git restore --source=HEAD~1 README.md` to specifically find the file and restore it from our snapshot. +Podríamos usar el comando `git undo` que deshará el último commit, pero ¿qué pasa si fue hace tiempo? Podemos usar nuestro comando `git log` para encontrar el commit concreto pero no queremos que todos los commits que haya por el medio se deshagan, así que vamos a especificar el fichero con el comando `git restore --source=HEAD~1 README.md` y restaurarlo desde nuestro snapshot. -You can see using this process we now have the file back in our working directory. +Puedes ver que usando este proceso ahora tenemos el archivo de vuelta en nuestro directorio de trabajo 😅 ![](Images/Day39_Git27.png) -We now have a new untracked file and we can use our commands previously mentioned to track, stage and commit our files and changes. +Ahora tenemos un nuevo archivo no rastreado y podemos usar los comandos mencionados anteriormente para rastrear, preparar y comitear nuestros cambios. ### Rebase vs Merge -This seems to be the biggest headache when it comes to Git and when to use rebase vs using merge on your git repositories. +Este parece ser el mayor dolor de cabeza cuando se trata de Git, cuando usar rebase o merge en tus repositorios git. -The first thing to know is that both `git rebase` and `git merge` solve the same problem. Both are to integrate changes from one branch into another branch. However, they do this in different ways. +Lo primero que hay que saber es que tanto `git rebase` como `git merge` resuelven el mismo problema. Ambos sirven para integrar cambios de una rama en otra rama. Sin embargo, lo hacen de formas diferentes. -Let's start with a new feature in a new dedicated branch. The Main branch continues with new commits. +Empecemos con una nueva característica en una nueva rama dedicada. La rama principal continúa con nuevos commits. ![](Images/Day39_Git28.png) -The easy option here is to use `git merge feature main` which will merge the main branch into the feature branch. +La opción fácil es usar `git merge feature main` que fusionará la rama principal en la rama feature. ![](Images/Day39_Git29.png) -Merging is easy because it is non-destructive. The existing branches are not changed in any way. However, this also means that the feature branch will have an irrelevant merge commit every time you need to incorporate upstream changes. If the main is very busy or active this will or can pollute the feature branch history. +La fusión es fácil porque no es destructiva. Las ramas existentes no se modifican. Sin embargo, esto también significa que la rama principal tendrá un commit de fusión irrelevante cada vez que necesites incorporar cambios de la rama principal. Si la main está muy ocupada o activa esto podría contaminar el historial de la rama feature. -As an alternate option, we can rebase the feature branch onto the main branch using +Como opción alternativa, podemos volver a basar la rama de características en la rama principal utilizando: ``` git checkout feature git rebase main ``` -This moves the feature branch (the entire feature branch) effectively incorporating all of the new commits in the main. But, instead of using a merge commit, rebasing re-writes the project history by creating brand new commits for each commit in the original branch. +Esto mueve la rama feature (toda la rama feature) incorporando efectivamente todos los nuevos commits en la main. Pero, en lugar de usar un commit merge, rebasing reescribe la historia del proyecto creando nuevos commits para cada commit en la rama original. ![](Images/Day39_Git30.png) -The biggest benefit of rebasing is a much cleaner project history. It also eliminates unnecessary merge commits. and as you compare the last two images, you can follow arguably a much cleaner linear project history. +El mayor beneficio de rebase es un historial del proyecto mucho más limpio. También elimina commits de fusión innecesarios. Si comparas las dos últimas imágenes, puedes seguir una historia del proyecto lineal mucho más limpia. -Although it's still not a foregone conclusion, choosing the cleaner history also comes with tradeoffs, If you do not follow the [The Golden rule of rebasing](https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing) re-writing project history can be potentially catastrophic for your collaboration workflow. And, less importantly, rebasing loses the context provided by a merge commit—you can’t see when upstream changes were incorporated into the feature. +Aunque todavía no es una conclusión inevitable, la elección del historial más limpio también viene con desventajas, si no sigues [La regla de oro de rebasing](hhttps://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing) y vuelves a escribir el historial del proyecto puede ser potencialmente catastrófico para su flujo de trabajo de colaboración. Y por otro lado, con menos importancia pero también presente, al realizar rebase se pierde el contexto proporcionado por un commit de fusión: no puedes ver cuándo se incorporaron realmente los cambios de la línea ascendente en la feature. -## Resources +## Recursos - [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) - [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) @@ -198,5 +194,13 @@ Although it's still not a foregone conclusion, choosing the cleaner history also - [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) - [Git cheatsheet](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) - [Exploring the Git command line – A getting started guide](https://veducate.co.uk/exploring-the-git-command-line/) +- [En español] [Comandos Git](https://gitea.vergaracarmona.es/man-linux/comandos-git) +- [En español][Apuntes Curso de Git](https://vergaracarmona.es/wp-content/uploads/2022/10/Curso-git_vergaracarmona.es_.pdf) de [Juan Carlos Rubio](https://www.linkedin.com/in/juan-carlos-rubio-pineda/Curso-git_vergaracarmona-es). +- [En español] En los [apuntes](https://vergaracarmona.es/apuntes/) del traductor: + - ["Instalar git en ubuntu"](https://vergaracarmona.es/instalar-git-en-ubuntu/) + - ["Comandos de git"](https://vergaracarmona.es/comandos-de-git/) + - ["Estrategias de fusión en git: Ship / Show / Ask"](https://vergaracarmona.es/estrategias-bifurcacion-git-ship-show-ask/) + - ["Resolver conflictos en Git. Merge, Squash, Rebase o Pull"](https://vergaracarmona.es/merge-squash-rebase-pull/) + - ["Borrar commits de git: reset, rebase y cherry-pick"](https://vergaracarmona.es/reset-rebase-cherry-pick/) -See you on [Day40](day40.md) +Nos vemos en el [Día 40](day40.md) diff --git a/2022/es/Days/day40.md b/2022/es/Days/day40.md index 92f8e1a..bfa5f78 100644 --- a/2022/es/Days/day40.md +++ b/2022/es/Days/day40.md @@ -1,191 +1,195 @@ -## Social Network for code +## Red social para el código -Exploring GitHub | GitLab | BitBucket +Explorando GitHub | GitLab | BitBucket 🚀 -Today I want to cover some of the git-based services that we have likely all heard of and expect we also use daily. +Hoy veremos algunos de los servicios basados en git de los que probablemente hemos oído hablar. Utilizaremos algunos de nuestros conocimientos adquiridos para mover copias de nuestros datos a cada uno de los principales servicios. -We will then use some of our prior session knowledge to move copies of our data to each of the main services. - -I called this section "Social Network for Code" let me explain why? +He llamado a esta sección "Red Social para el Código", ya verás por qué... ### GitHub -Most common at least for me is GitHub, GitHub is a web-based hosting service for git. It is most commonly used by software developers to store their code. Source Code Management with the git version control features as well as a lot of additional features. It allows for teams or open contributors to easily communicate and provides a social aspect to coding. (hence the social networking title) Since 2018 GitHub is part of Microsoft. +El más común es GitHub, un servicio de alojamiento basado en web para git. Es muy utilizado por los desarrolladores de software para almacenar código. Tienes la gestión del código fuente centralizada en un repositorio remoto y distribuida gracias a las características de control de versiones git, así como un montón de características adicionales. Permite a los equipos y colaboradores comunicarse fácilmente y proporciona un aspecto social a la codificación. Desde 2018 GitHub forma parte de Microsoft (A golpe de talonario). -GitHub has been around for quite some time and was founded in 2007/2008. With Over 40 million users on the platform today. +GitHub fue fundada en 2007/2008. Con Más de 40 millones de usuarios en la plataforma a día de hoy. -GitHub Main Features +Características principales de GitHub -- Code Repository -- Pull Requests -- Project Management toolset - Issues -- CI / CD Pipeline - GitHub Actions +- Repositorio de código +- Solicitudes de Pull +- Herramientas de gestión de proyectos - Issues +- Canalización CI / CD - Acciones GitHub -In terms of pricing, GitHub has different levels of pricing for its users. More can be found on [Pricing](https://github.com/pricing) +En términos de precios, GitHub tiene diferentes niveles de precios para sus usuarios. Puedes encontrar más información en [Pricing](https://github.com/pricing) -For this, we will cover the free tier. +Aquí veremos tan solo el nivel gratuito. -I am going to be using my already created GitHub account during this walkthrough, if you do not have an account then on the opening GitHub page there is a sign-up option and some easy steps to get set up. +Voy a utilizar mi cuenta de GitHub ya creada durante este tutorial, si no tienes una cuenta, en la página de apertura de GitHub hay una opción de registro y algunos pasos sencillos para configurarla. -### GitHub opening page +### Página de inicio de GitHub -When you first log in to your GitHub account you get a page containing a lot of widgets giving you options of where and what you would like to see or do. First up we have the "All Activity" this is going to give you a look into what is happening with your repositories or activity in general associated with your organisation or account. +La primera vez que accedes a tu cuenta de GitHub aparece una página que contiene un montón de widgets que te dan opciones de dónde y qué te gustaría ver o hacer. En primer lugar tenemos "Toda la actividad", que te dará una visión de lo que está sucediendo con tus repositorios o actividad en general asociada a tu organización o cuenta. ![](Images/Day40_Git1.png) -Next, we have our Code Repositories, either our own or repositories that we have interacted with recently. We can also quickly create new repositories or search repositories. +A continuación, tenemos nuestros repositorios de código, ya sean propios o repositorios con los que hemos interactuado recientemente. También podemos crear rápidamente nuevos repositorios o buscar repositorios. ![](Images/Day40_Git2.png) -We then have our recent activity, these for me are issues and pull requests that I have created or contributed to recently. +Luego tenemos nuestra actividad reciente, que para mí son temas y pull requests que he creado o contribuido recientemente. ![](Images/Day40_Git3.png) -Over on the right side of the page, we have some referrals for repositories that we might be interested in, most likely based on your recent activity or own projects. +En la parte derecha tenemos algunas referencias de repositorios en los que podríamos estar interesados, probablemente basados en tu actividad reciente o en tus propios proyectos. ![](Images/Day40_Git4.png) -To be honest I am very rarely on my home page that we just saw and described, although I now see that the feed could be really useful to help interact with the community a little better on certain projects. +Para ser honesto no suelo entrar en mi propia página de inicio, veo que el feed podría ser realmente útil para ayudar a interactuar mejor con la comunidad en ciertos proyectos. -Next up if we want to head into our GitHub Profile we can navigate to the top right corner and on your image, there is a drop-down which allows you to navigate through your account. From here to access your Profile select "Your Profile" +A continuación, si queremos entrar en nuestro perfil de GitHub podemos navegar a la esquina superior derecha y en tu imagen, hay un desplegable que te permite navegar a través de tu cuenta. Desde aquí para acceder a tu Perfil selecciona "Tu Perfil" ![](Images/Day40_Git5.png) -Next, your profile page will appear, by default, unless you change your configuration you are not going to see what I have, I have added some functionality that shows my recent blog posts over on [vZilla](https://vzilla.co.uk) and then also my latest videos on my [YouTube](https://m.youtube.com/c/MichaelCade1) Channel. +A continuación, aparecerá tu página de perfil, por defecto, a menos que cambies tu configuración no vas a ver lo que yo tengo, he añadido alguna funcionalidad que muestra mis últimas entradas de blog en [vZilla](https://vzilla.co.uk) y también mis últimos vídeos en mi canal de [YouTube](https://m.youtube.com/c/MichaelCade1) Channel. -You are not going to be spending much time looking at your profile, but this is a good profile page to share around your network so they can see the cool projects you are working on. +No vas a pasar mucho tiempo mirando tu perfil, pero esta es una buena página de perfil para compartir en tu red para que puedan ver los proyectos interesantes en los que estás trabajando. + +Si quieres ver algunos ejemplos de páginas de inicio: +- Página del autor [Michael Cade](https://github.com/MichaelCade/MichaelCade) +- Página del traductor [manuelver](https://github.com/manuelver/manuelver) ![](Images/Day40_Git6.png) -We can then drill down into the building block of GitHub, the repositories. Here you are going to see your repositories and if you have private repositories they are also going to be shown in this long list. +A continuación, podemos profundizar en el bloque de construcción de GitHub, los repositorios. Aquí vas a ver tus repositorios y si tienes repositorios privados también se mostrarán en esta larga lista. ![](Images/Day40_Git7.png) -As the repository is so important to GitHub let me choose a pretty busy one of late and run through some of the core functionality that we can use here on top of everything I am already using when it comes to editing our "code" in git on my local system. +El repositorio es muy importante en GitHub, así que elijo uno bastante movido últimamente para ejecutar algunas de las funciones básicas que podemos utilizar. -First of all, from the previous window, I have selected the 90DaysOfDevOps repository and we get to see this view. You can see from this view we have a lot of information, we have our main code structure in the middle showing our files and folders that are stored in our repository. We have our readme. mdbeing displayed down at the bottom. Over to the right of the page, we have an about section where the repository has a description and purpose. Then we have a lot of information underneath this showing how many people have starred in the project, forked, and watched. +Desde la ventana anterior, he seleccionado el repositorio 90DaysOfDevOps. Se puede ver en esta vista que tenemos una gran cantidad de información, tenemos nuestra estructura de código principal en el centro mostrando nuestros archivos y carpetas que se almacenan en nuestro repositorio. Tenemos nuestro readme.md que se muestra en la parte inferior y le da más importancia al fichero, ya que es nuestra presentación del proyecto. A la derecha de la página, tenemos una sección con una descripción y propósito del proyecto. Luego tenemos un montón de información debajo de esto que muestra cuántas personas han destacado en el proyecto con una star, cuántas lo han visto y cuántas lo han bifurcado. ![](Images/Day40_Git8.png) -If we scroll down a little further you will also see that we have Released, these are from the golang part of the challenge. We do not have any packages in our project, we have our contributors listed here. (Thank you community for assisting in my spelling and fact checking) We then have languages used again these are from different sections in the challenge. +Si nos desplazamos un poco más abajo también veremos que tenemos Releases, estos son de la parte golang del desafío. No tenemos ningún paquete en nuestro proyecto en este momento, y también vemos a nuestros colaboradores listados. (Gracias comunidad por ayudar en mi ortografía y otras correcciones) Luego tenemos lenguajes utilizados. ![](Images/Day40_Git9.png) -A the top of the page you are going to see a list of tabs. These may vary and these can be modified to only show the ones you require. You will see here that I am not using all of these and I should remove them to make sure my whole repository is tidy. +En la parte superior de la página verás una lista de pestañas. Éstas pueden variar y pueden modificarse para mostrar sólo las que necesites. Aquí verás que no estoy usando todas y que debería quitarlas para asegurarme de que todo mi repositorio está ordenado y limpio. -First up we had the code tab which we just discussed but these tabs are always available when navigating through a repository which is super useful so we can jump between sections quickly and easily. Next, we have the issues tab. +En primer lugar tenemos la pestaña de código, de la que acabamos de hablar, pero estas pestañas están siempre disponibles cuando se navega a través de un repositorio, lo que es muy útil para que podamos saltar entre las secciones de forma rápida y sencilla. A continuación, tenemos la pestaña de problemas. -Issues let you track your work on GitHub, where development happens. In this specific repository you can see I have some issues focused on adding diagrams or typos but also we have an issue stating a need or requirement for a Chinese version of the repository. +Las incidencias te permiten hacer un seguimiento de tu trabajo en GitHub, donde tiene lugar el desarrollo. En este repositorio específico se puede ver que tengo algunas cuestiones centradas en la adición de diagramas o errores tipográficos, pero también tenemos una cuestión que indica una necesidad o requisito para una versión china del repositorio. -If this was a code repository then this is a great place to raise concerns or issues with the maintainers, but remember to be mindful and detailed about what you are reporting, and give as much detail as possible. +Si esto fuera un repositorio de código, entonces este es un gran lugar para plantear inquietudes o problemas con los mantenedores, pero recuerde que debe ser consciente y detallado acerca de lo que está informando, y dar tantos detalles como sea posible. ![](Images/Day40_Git10.png) -The next tab is Pull Requests, Pull requests let you tell others about changes you've pushed to a branch in a repository. This is where someone may have forked your repository, made changes such as bug fixes or feature enhancements or just typos in a lot of the cases in this repository. +La siguiente pestaña es Pull Requests. Permite informar a otros sobre los cambios que ha empujado a una rama en un repositorio. Aquí es donde alguien puede haber bifurcado el repositorio en otra rama, sea del mismo proyecto o de un fork, ha hecho cambios como correcciones de errores o mejoras de características o simplemente errores tipográficos, y luego ha solicitado que se fusionen esos cambios en la rama principal del proyecto. -We will cover forking later on. +Cubriremos el forking con más detalle más adelante. ![](Images/Day40_Git11.png) -I believe the next tab is quite new? But I thought for a project like #90DaysOfDevOps this could help guide the content journey but also help the community as they walk through their learning journey. I have created some discussion groups for each section of the challenge so people can jump in and discuss. +La siguiente pestaña es bastante nueva, pero se ha creado para #90DaysOfDevOps porque no solo puede ayudar a guiar en el viaje por el contenido, sino que también ayuda a la comunidad a medida que caminan a través de su aprendizaje. Dentro hay grupos de discusión para cada sección del desafío para que quien quiera pueda entrar y comentar, a modo de foro. ![](Images/Day40_Git12.png) -The Actions tab is going to enable you to build, test and deploy code and a lot more right from within GitHub. GitHub Actions will be something we cover in the CI/CD section of the challenge but this is where we can set some configuration here to automate steps for us. +La pestaña de Actions te permitirá construir, probar, desplegar código y mucho más. GitHub Actions lo veremos en la sección de CI/CD del desafío. Como info previa, es aquí donde podemos establecer automatizaciones de tareas repetitivas para que se hagan por si solas con un disparador. -On my main GitHub Profile, I am using GitHub Actions to fetch the latest blog posts and YouTube videos to keep things up to date on that home screen. +Por ejemplo, en mi perfil principal de GitHub utilizo las Actions para obtener las últimas entradas del blog y vídeos de YouTube y mantener al día mi página de perfil Github. ![](Images/Day40_Git13.png) -I mentioned above how GitHub is not just a source code repository but is also a project management tool, The Project tab enables us to build out project tables kanban type boards so that we can link issues and PRs to better collaborate on the project and have visibility of those tasks. +Ya he mencionado que GitHub no es sólo un repositorio de código fuente, sino también una herramienta de gestión de proyectos. La pestaña Projects nos permite crear tablas de proyecto tipo kanban para que podamos vincular las incidencias y PRs para colaborar mejor en el proyecto y tener visibilidad/transparencia de las tareas. ![](Images/Day40_Git14.png) -I know that issues to me seem like a good place to log feature requests and they are but the wiki page allows for a comprehensive roadmap for the project to be outlined with the current status and in general better document your project is it troubleshooting or how-to type content. +La página wiki permite una hoja de ruta completa para el proyecto que se describe con el estado actual y, en general, documentar mejor el proyecto. ![](Images/Day40_Git15.png) -Not so applicable to this project but the Security tab is there to make sure that contributors know how to deal with certain tasks, we can define a policy here but also code scanning add-ons to make sure your code for example does not contain secret environment variables. +No es tan aplicable a este proyecto, pero la pestaña de Security está ahí para asegurarse de que los contribuyentes saben cómo hacer frente a ciertas tareas, podemos definir una política aquí, pero también complementos de escaneo de código para asegurarse de que su código, por ejemplo, no contiene variables de entorno con contraseñas. ![](Images/Day40_Git16.png) -For me the insights tab is great, it provides so much information about the repository from how much activity has been going on down to commits and issues, but it also reports on traffic to the repository. You can see a list on the left side that allows you to go into great detail about metrics on the repository. +Para mí la pestaña de Insights es genial ya que proporciona mucha información sobre el repositorio. Desde cuantificar la actividad que ha habido hasta los commits e issues, pasando también por informes sobre el tráfico del repositorio. Puedes ver una lista en el lado izquierdo que te permite entrar en gran detalle sobre las métricas del repositorio. ![](Images/Day40_Git17.png) -Finally, we have the Settings tab, this is where we can get into the details of how we run our repository, I am currently the only maintainer of the repository but we could share this responsibility here. We can define integrations and other such tasks here. +Por último, tenemos la pestaña Configuración donde podemos entrar en los detalles de cómo personalizar nuestro repositorio. Actualmente soy el único mantenedor del repositorio pero podríamos compartir esta responsabilidad aquí. Podemos definir integraciones, políticas de ramas y otras tareas. ![](Images/Day40_Git18.png) -This was a super quick overview of GitHub, I think there are some other areas that I might have mentioned that need explaining in a little more detail. As mentioned GitHub houses millions of repositories mostly these are holding source code and these can be public or privately accessible. +Como se mencionó GitHub alberga millones de repositorios, en su mayoría son código fuente y estos pueden ser de acceso público o privado. + +Hemos echado un vistazo súper rápido de GitHub, creo que se podría detallar mucho más, pero por ahora no somos comerciales de la herramienta, así que vamos a la parte técnica. ### Forking -I am going to get more into Open-Source in the session tomorrow but a big part of any code repository is the ability to collaborate with the community. Let's think of the scenario I want a copy of a repository because I want to make some changes to it, maybe I want to fix a bug or maybe I want to change something to use it for a use case that I have that was maybe not the intended use case for the original maintainer of the code. This is what we would call forking a repository. A fork is a copy of a repository. Forking a repository allows you to freely experiment with changes without affecting the original project. +Voy a entrar más en Open-Source en la sesión de mañana, pero una gran parte de cualquier repositorio de código es la capacidad de colaborar con la comunidad. Pensemos en el escenario que quiero una copia de un repositorio porque quiero hacer algunos cambios en él, tal vez quiero corregir un error o tal vez quiero cambiar algo para utilizarlo para un caso de uso que tengo que tal vez no era el caso de uso previsto para el mantenedor original del código. Esto es lo que llamaríamos bifurcar un repositorio. Un fork es una copia de un repositorio. La bifurcación de un repositorio permite experimentar libremente con los cambios sin afectar al proyecto original. -Let me head back to the opening page after login and see one of those suggested repositories. +Permíteme volver a la página de inicio después de iniciar sesión y ver uno de esos repositorios sugeridos. ![](Images/Day40_Git19.png) -If we click on that repository we are going to get the same look as we have just walked through on the 90DaysOfDevOps repository. +Si hacemos click en ese repositorio vamos a obtener el mismo aspecto que acabamos de ver en el repositorio 90DaysOfDevOps. ![](Images/Day40_Git20.png) -If we notice below we have 3 options, we have watch, fork and star. +Si nos fijamos a continuación tenemos 3 opciones: -- Watch - Updates when things happen to the repository. -- Fork - a copy of a repository. -- Star - "I think your project is cool" +- Watch - Se actualiza con los visitante al repositorio. +- Fork - Las copias del repositorio. +- Star - "Creo que tu proyecto es genial". ![](Images/Day40_Git21.png) -Given our scenario of wanting a copy of this repository to work on we are going to hit the fork option. If you are a member of multiple organisations then you will have to choose where the fork will take place, I am going to choose my profile. +Vamos a darle a la opción fork para hacer una copia en la que trabajar. Si eres miembro de varias organizaciones entonces tendrás que elegir donde se realizará el fork, yo voy a elegir mi perfil. ![](Images/Day40_Git22.png) -Now we have our copy of the repository that we can freely work on and change as we see fit. This would be the start of the pull request process that we mentioned briefly before but we will cover it in more detail tomorrow. +Ahora ya tenemos nuestra copia del repositorio sobre la que podemos trabajar libremente y modificarla a nuestro antojo. Este sería el comienzo del proceso de pull request que mencionamos brevemente antes pero que cubriremos con más detalle mañana. ![](Images/Day40_Git23.png) -Ok, I hear you say, but how do I make changes to this repository and code if it's on a website, well you can go through and edit on the website but it's not going to be the same as using your favourite IDE on your local system with your favourite colour theme. For us to get a copy of this repository on our local machine we will perform a clone of the repository. This will allow us to work on things locally and then push our changes back into our forked copy of the repository. +Ok, te oigo decir, pero ¿cómo puedo hacer cambios en este repositorio y el código si está en un sitio web? Bueno, puedes editarlo directamente en el página Github, pero no va a ser lo mismo que usar tu IDE favorito en local. Para obtener una copia de este repositorio en local vamos a realizar un clon del repositorio. Esto nos permitirá trabajar localmente y luego empujar/pushear nuestros cambios de nuevo en nuestra copia bifurcada en el repositorio remoto. -We have several options when it comes to getting a copy of this code as you can see below. +Tenemos varias opciones cuando se trata de obtener una copia de este código como se puede ver a continuación. -There is a local version available of GitHub Desktop which gives you a visual desktop application to track changes and push and pull changes between local and GitHub. +Hay una versión local disponible de GitHub Desktop que le da una aplicación de escritorio visual para realizar un seguimiento de los cambios y empujar/pushear y tirar/pullear los cambios entre el local y GitHub. -For this little demo, I am going to use the HTTPS URL we see on there. +Para esta pequeña demostración, voy a utilizar la URL HTTPS. ![](Images/Day40_Git24.png) -Now on our local machine, I am going to navigate to a directory I am happy to download this repository to and then run `git clone url` +Ahora, en nuestra máquina local, voy a navegar al directorio donde quiero descargar el repositorio y luego ejecutar `git clone url`. ![](Images/Day40_Git25.png) -Now we could take it to VScode to make some changes to this. +Podemos llevarlo a VScode para hacer algunos cambios. ![](Images/Day40_Git26.png) -Let's now make some changes, I want to make a change to all those links and replace that with something else. +Vamos a hacer algunos cambios, quiero hacer un cambio en todos esos enlaces y sustituirlos por otra cosa. ![](Images/Day40_Git27.png) -Now if we check back on GitHub and we find our readme.mdin that repository, you should be able to see a few changes that I made to the file. +Si nos fijamos de nuevo en GitHub y encontramos nuestro readme.md, deberías ser capaz de ver algunos cambios que he hecho en el archivo. ![](Images/Day40_Git28.png) -At this stage, this might be complete and we might be happy with our change as we are the only people going to use our new change but maybe it was a bug change and if that is the case then we will want to contribute via a Pull Request to notify the original repository maintainers of our change and see if they accept our changes. +En esta etapa, esto podría estar completo y podríamos estar contentos con nuestro cambio, ya que somos las únicas personas que van a utilizar nuestro nuevo cambio, pero tal vez fue un cambio de error y si ese es el caso, entonces vamos a querer contribuir a través de un Pull Request para notificar a los mantenedores del repositorio original de nuestro cambio y ver si aceptan nuestros cambios. -We can do this by using the contribute button highlighted below. I will cover more on this tomorrow when we look into Open-Source workflows. +Podemos hacer esto utilizando el botón de contribución que se muestra a continuación. Mañana con los flujos de trabajo Open-Source veremos más sobre esto. ![](Images/Day40_Git29.png) -I have spent a long time looking through GitHub and I hear some of you cry but what about other options! +Me han dicho muchos: ¿qué pasa con las otras opciones de repositorios remotos? -Well, there are and I am going to find some resources that cover the basics for some of those as well. You are going to come across GitLab and BitBucket amongst others in your travels and whilst they are git-based services they have their differences. +Bueno, voy a dejar algunos recursos que cubren los conceptos básicos para el resto de opciones. En tus viajes te encontrarás con GitLab y BitBucket, entre otros, y aunque son servicios basados en Git, tienen sus diferencias. -You will also come across hosted options. Most commonly here I have seen GitLab as a hosted version vs GitHub Enterprise (Don't believe there is a free hosted GitHub?) +También encontrarás opciones alojadas, la más común es GitLab frente a GitHub Enterprise. El traductor recomienda la opcíon de código libre gitea.io. -## Resources +## Recursos - [Learn GitLab in 3 Hours | GitLab Complete Tutorial For Beginners](https://www.youtube.com/watch?v=8aV5AxJrHDg) - [BitBucket Tutorials Playlist](https://www.youtube.com/watch?v=OMLh-5O6Ub8&list=PLaD4FvsFdarSyyGl3ooAm-ZyAllgw_AM5) @@ -196,5 +200,14 @@ You will also come across hosted options. Most commonly here I have seen GitLab - [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) - [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) - [Git cheatsheet](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) +- [En español] [Comandos Git](https://gitea.vergaracarmona.es/man-linux/comandos-git) +- [En español][Apuntes Curso de Git](https://vergaracarmona.es/wp-content/uploads/2022/10/Curso-git_vergaracarmona.es_.pdf) de [Juan Carlos Rubio](https://www.linkedin.com/in/juan-carlos-rubio-pineda/Curso-git_vergaracarmona-es). +- [En español] En los [apuntes](https://vergaracarmona.es/apuntes/) del traductor: + - ["Instalar git en ubuntu"](https://vergaracarmona.es/instalar-git-en-ubuntu/) + - ["Comandos de git"](https://vergaracarmona.es/comandos-de-git/) + - ["Estrategias de fusión en git: Ship / Show / Ask"](https://vergaracarmona.es/estrategias-bifurcacion-git-ship-show-ask/) + - ["Resolver conflictos en Git. Merge, Squash, Rebase o Pull"](https://vergaracarmona.es/merge-squash-rebase-pull/) + - ["Borrar commits de git: reset, rebase y cherry-pick"](https://vergaracarmona.es/reset-rebase-cherry-pick/) +- [GitHub Profile README Generator](https://github.com/rahuldkjain/github-profile-readme-generator) -See you on [Day 41](day41.md) +Nos vemos en el [Día 41](day41.md) diff --git a/2022/es/Days/day41.md b/2022/es/Days/day41.md index f3a7dd7..0b83db9 100644 --- a/2022/es/Days/day41.md +++ b/2022/es/Days/day41.md @@ -1,118 +1,106 @@ ---- -title: '#90DaysOfDevOps - The Open Source Workflow - Day 41' -published: false -description: 90DaysOfDevOps - The Open Source Workflow -tags: 'DevOps, 90daysofdevops, learning' -cover_image: null -canonical_url: null -id: 1048806 ---- +## El flujo de trabajo del Open Source -## The Open Source Workflow +Esperemos que a través de las últimas 7 secciones de Git tengamos una mejor comprensión de lo que es git. También en GitHub cómo un servicio online que se integra con git para proporcionar un repositorio de código fuente, además de una forma en que la comunidad en general puede colaborar en el código y los proyectos abiertos. -Hopefully, through the last 7 sections of Git, we have a better understanding of what git is and then how a git-based service such as GitHub integrates with git to provide a source code repository but also a way in which the wider community can collaborate on code and projects together. +Cuando pasamos a través de los fundamentos de GitHub fuimos a través del proceso de bifurcación de un proyecto al azar y hacer un cambio en nuestro repositorio local. Aquí queremos ir un paso más allá y contribuir a un proyecto de código abierto. -When we went through the GitHub fundamentals we went through the process of forking a random project and making a change to our local repository. Here we want to go one step further and contribute to an open-source project. Remember that contributing doesn't need to be bug fixes or coding features but it could also be documentation. Every little helps and it also allows you to get hands-on with some of the git functionality we have covered. +Recuerda que contribuir no tiene por qué ser corregir errores o codificar características, sino que también puede ser documentación, traducción, propuestas de mejoras, etc. Todo ayuda a mejorar los proyectos comunitarios. Además permite ponerte manos a la obra con algunas de las funcionalidades de git que hemos cubierto o con las tecnologías que contienen los repositorios. -## Fork a Project +## Bifurcar un proyecto -The first thing we have to do is find a project we can contribute to. I have recently been presenting on the [Kanister Project](https://github.com/kanisterio/kanister) and I would like to share my presentations that are now on YouTube to the main readme.mdfile in the project. +Lo primero que tenemos que hacer es encontrar un proyecto en el que podamos contribuir. Recientemente he estado presentando en el [Proyecto Kanister](https://github.com/kanisterio/kanister) y me gustaría compartir mis presentaciones que ahora están en YouTube al fichero readme.md principal del proyecto. -First of all, we need to fork the project. Let's run through that process. I am going to navigate to the link shared above and fork the repository. +En primer lugar, tenemos que bifurcar el proyecto como vimos en el día de ayer. Voy a navegar hasta el enlace mencionado y hacer un fork del repositorio. ![](Images/Day41_Git1.png) -We now have our copy of the whole repository. +Ahora tenemos nuestra copia de todo el repositorio. ![](Images/Day41_Git2.png) -For reference on the Readme.mdfile the original Presentations listed are just these two so we need to fix this with our process. +En el archivo Readme.md las presentaciones originales listadas son solo estas dos por lo que vamos a aportar más. ![](Images/Day41_Git3.png) -## Clones to a local machine +## Clona a una máquina local -Now we have our fork we can bring that down to our local and we can then start making our edits to the files. Using the code button on our repo we can grab the URL and then use `git clone url` in a directory we wish to place the repository. +Ahora que tenemos nuestro fork podemos bajarlo a nuestra máquina local y empezar a editar los archivos. Usando el botón de código en nuestro repositorio podemos coger la URL y luego usar `git clone url` en un directorio en el que queramos colocar el repositorio. Personalmente, me gusta llamar al directorio con el mismo nombre del proyecto. ![](Images/Day41_Git4.png) -## Make our changes +## Realizamos nuestros cambios -We have our project local so we can open VSCode or an IDE or text editor of your choice to add your modifications. +Tenemos nuestro proyecto en local así que podemos abrir VSCode o un IDE o editor de texto de nuestra elección para añadir las modificaciones. ![](Images/Day41_Git5.png) -The readme.mdfile is written in markdown language and because I am modifying someone else's project I am going to follow the existing project formatting to add our content. +El archivo readme.md está escrito en lenguaje markdown y como estoy modificando el proyecto de otra persona voy a seguir el formato del proyecto existente para añadir nuestro contenido. Quiero decir con esto que es importante seguir la línea editorial de un proyecto y hacer cambios que encajen con el proyecto para no dificurtar su futura lectura y la comprobación de cambios por el autor. ![](Images/Day41_Git6.png) -## Test your changes +## Prueba tus cambios -We must as a best practice test our changes, this makes total sense if this was a code change to an application you would want to ensure that the application still functions after a code change, well we also must make sure that documentation is formatted and looks correct. +Como buena práctica debemos probar nuestros cambios, esto tiene sentido total si se tratara de un cambio de código a una aplicación que desea asegurarse de que la aplicación sigue funcionando después de un cambio de código, así que también debemos asegurarnos de que la documentación tiene el formato y el aspecto correcto. Ni se te ocurra pedir cambios en una pull request con errores porque no se te aceptará y puede que en muchos casos simplemente seas ignorado. -In vscode we can add a lot of plugins one of these is the ability to preview markdown pages. +En vscode podemos añadir un montón de plugins para previsualizar páginas markdown. ![](Images/Day41_Git7.png) -## Push changes back to our forked repository +Personalmente utilizo [markdown](https://marketplace.visualstudio.com/items?itemName=starkwang.markdown) y [markdown all in one](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one), que me permite previsualizar el archivo markdown y mucho más. -We do not have the authentication to push our changes directly back to the Kanister repository so we have to take this route. Now that I am happy with our changes we can run through some of those now well-known git commands. +## Enviar los cambios a nuestro repositorio fork + +No tenemos la autenticación para pushear cambios directamente al repositorio Kanister así que tenemos que tomar otra ruta. En el momento que estoy satisfecho con los cambios y lo he comprobado las veces necesarias para estar seguro que no tiene errores, podemos ejecutar los comandos git que ya tenemos en nuestro haber. ![](Images/Day41_Git8.png) -Now we go back to GitHub to check the changes once more and then contribute back to the master project. +Ahora volvemos a GitHub para comprobar los cambios una vez más, no dejes de comprobarlo, los errores no vendrán por hacer las cosas mal, eso es normal, los errores vendrán por no comprobar las suficientes veces. En este punto, ya podemos contribuir al proyecto original. -Looks good. +Tiene buena pinta. ![](Images/Day41_Git9.png) -Now we can go back to the top of our forked repository for Kanister and we can see that we are 1 commit ahead of the kanisterio:master branch. +Ahora podemos volver a la parte superior de nuestro repositorio bifurcado para Kanister y podemos ver que estamos 1 commit por delante de la rama kanisterio:master. ![](Images/Day41_Git10.png) -Next, we hit that contribute button highlighted above. We see the option to "Open Pull Request" +A continuación, pulsamos el botón de contribuir resaltado arriba, la opción "Open Pull Request". ![](Images/Day41_Git11.png) -## Open a pull request +## Abrir un pull request -There is quite a bit going on in this next image, top left you can now see we are in the original or the master repository. then you can see what we are comparing and that is the original master and our forked repository. We then have a create pull request button which we will come back to shortly. We have our single commit but if this was more changes you might have multiple commits here. then we have the changes we have made in the readme.mdfile. +Atento, en la siguiente imagen hay bastantes cosas sucediendo, arriba a la izquierda puedes ver que estamos en el repositorio original master. Luego puedes ver lo que estamos comparando y que es el repositorio original y nuestro repositorio bifurcado. A continuación, tenemos un botón de crear pull request al que vamos a volver en breve. Tenemos nuestra único commit, pero si se tratara de más cambios se podrían ver todos los commits aquí. Vemos los cambios realizados en readme.md. ![](Images/Day41_Git12.png) -We have reviewed the above changes and we are ready to create a pull request by hitting the green button. +Hemos revisado los cambios anteriores y estamos listos para crear un pull request dándole al botón verde. -Then depending on how the maintainer of a project has set out their Pull Request functionality on their repository you may or may not have a template that gives you pointers on what the maintainer wants to see. +Entonces, dependiendo de cómo el mantenedor de un proyecto ha establecido su funcionalidad Pull Request, puede o no tener una plantilla que le da indicaciones sobre lo que el mantenedor quiere ver. -This is again where you want to make a meaningful description of what you have done, clear and concise but with enough detail. You can see I have made a simple change overview and I have ticked documentation. +Aquí es donde puedes hacer una descripción significativa de lo que has hecho, clara y concisa, pero con suficiente detalle. Puedes ver que he hecho un simple resumen de cambios y he marcado documentación. ![](Images/Day41_Git13.png) -## Create a pull request +## Crear un pull request -We are now ready to create our pull request. After hitting the "Create Pull Request" at the top of the page you will get a summary of your pull request. +Ya estamos listos para crear nuestro pull request. Después de pulsar "Create Pull Request" en la parte superior de la página obtendrás un resumen de tu pull request. ![](Images/Day41_Git14.png) -Scrolling down you are likely to see some automation taking place, in this instance, we require a review and some checks are taking place. We can see that Travis CI is in progress and a build has started and this will check our update, making sure that before anything is merged we are not breaking things with our additions. +Desplazándote hacia abajo es probable que veas que sucede alguna automatización, en este caso, requerimos una revisión y algunas comprobaciones que se están llevando a cabo. Podemos ver que Travis CI está en progreso y una construcción ha comenzado y esto comprobará nuestra actualización, asegurándose de que no estamos rompiendo nada con nuestras adiciones antes de que se fusione. ![](Images/Day41_Git15.png) -Another thing to note here is that the red in the screenshot above, can look a little daunting and look as if you have made mistakes! Don't worry you have not broken anything, my biggest tip here is this process is there to help you and the maintainers of the project. If you have made a mistake at least from my experience the maintainer will contact and advise on what to do next. +Otra cosa a tener en cuenta aquí es que el rojo en la captura de pantalla anterior, puede parecer un poco desalentador, parece como si hubieras cometido errores. Nada más lejos, no te preocupes, no has roto nada, mi mayor consejo aquí es que este proceso está ahí para ayudarte a ti y a los mantenedores del proyecto. Si usted ha cometido un error, al menos desde mi experiencia, el mantenedor se pondrá en contacto y le aconsejará sobre qué hacer a continuación. -This pull request is now public for everyone to see [added Kanister presentation/resource #1237](https://github.com/kanisterio/kanister/pull/1237) +![](Images/Day41_Git16.png) -I am going to publish this before the merge and pull requests are accepted so maybe we can get a little prize for anyone that is still following along and can add a picture of the successful PR? +Este pull request es ahora público para que todo el mundo lo vea: [added Kanister presentation/resource #1237](https://github.com/kanisterio/kanister/pull/1237) -1. Fork this repository to your own GitHub account -2. Add your picture and possibly text -3. Push the changes to your forked repository -4. Create a PR that I will see and approve. -5. I will think of some sort of prize +Con esto terminamos nuestro repaso a Git y GitHub. A continuación nos sumergiremos en los contenedores, que comienza con una visión general de cómo y por qué contenedores y también una mirada a la virtualización y cómo hemos llegado hasta aquí. -This then wraps up our look into Git and GitHub, next we are diving into containers which starts with a big picture look into how, and why containers and also a look into virtualisation and how we got here. - -## Resources +## Recursos - [Learn GitLab in 3 Hours | GitLab Complete Tutorial For Beginners](https://www.youtube.com/watch?v=8aV5AxJrHDg) - [BitBucket Tutorials Playlist](https://www.youtube.com/watch?v=OMLh-5O6Ub8&list=PLaD4FvsFdarSyyGl3ooAm-ZyAllgw_AM5) @@ -123,5 +111,13 @@ This then wraps up our look into Git and GitHub, next we are diving into contain - [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) - [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) - [Git cheatsheet](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) +- [En español] [Comandos Git](https://gitea.vergaracarmona.es/man-linux/comandos-git) +- [En español][Apuntes Curso de Git](https://vergaracarmona.es/wp-content/uploads/2022/10/Curso-git_vergaracarmona.es_.pdf) de [Juan Carlos Rubio](https://www.linkedin.com/in/juan-carlos-rubio-pineda/Curso-git_vergaracarmona-es). +- [En español] En los [apuntes](https://vergaracarmona.es/apuntes/) del traductor: + - ["Instalar git en ubuntu"](https://vergaracarmona.es/instalar-git-en-ubuntu/) + - ["Comandos de git"](https://vergaracarmona.es/comandos-de-git/) + - ["Estrategias de fusión en git: Ship / Show / Ask"](https://vergaracarmona.es/estrategias-bifurcacion-git-ship-show-ask/) + - ["Resolver conflictos en Git. Merge, Squash, Rebase o Pull"](https://vergaracarmona.es/merge-squash-rebase-pull/) + - ["Borrar commits de git: reset, rebase y cherry-pick"](https://vergaracarmona.es/reset-rebase-cherry-pick/) -See you on [Day 42](day42.md) +Nos vemos en el [Día 42](day42.md) diff --git a/2022/es/Days/day42.md b/2022/es/Days/day42.md index 4fabc7e..898ae6f 100644 --- a/2022/es/Days/day42.md +++ b/2022/es/Days/day42.md @@ -1,128 +1,129 @@ -## The Big Picture: Containers +## El panorama: Contenedores -We are now starting the next section and this section is going to be focused on containers in particular we are going to be looking into Docker getting into some of the key areas to understand more about Containers. +Empezamos nueva sección en la que nos centraremos en los contenedores. En particular vamos a mirar Docker para entender algunas claves de los contenedores. -I will also be trying to get some hands-on here to create the container that we can use during this section but also in future sections later on in the challenge. +Pasaremos por un poco de práctica para crear el contenedor que utilizaremos durante esta sección y en futuras secciones del desafío. -As always this first post is going to be focused on the big picture of how we got here and what it all means. +Como siempre, este primer post se va a centrar en el panorama general de cómo hemos llegado hasta aquí y lo que todo esto significa. -#History of platforms and application development -#do we want to talk about Virtualisation & Containerisation +### ¿Por qué otra forma de ejecutar aplicaciones? -### Why another way to run applications? +Lo primero que tenemos que plantearnos es por qué necesitamos otra forma de ejecutar software o aplicaciones. La elección es grande, podemos ejecutar nuestras aplicaciones de muchas formas diferentes, por ejemplo, podríamos ver las aplicaciones desplegadas en hardware físico con un sistema operativo y una sola aplicación desplegada allí, y podríamos verlas en máquina virtual o instancias IaaS basadas en la nube ejecutando nuestra aplicación, que luego se integran en una base de datos de nuevo en una MV o como PaaS ofreciendo en la nube pública. O, como vamos a ver, podemos ver nuestras aplicaciones ejecutándose en contenedores. -The first thing we have to take a look at is why do we need another way to run our software or applications? Well it is just that choice is great, we can run our applications in many different forms, we might see applications deployed on physical hardware with an operating system and a single application deployed there, and we might see the virtual machine or cloud-based IaaS instances running our application which then integrate into a database again in a VM or as PaaS offering in the public cloud. Or we might see our applications running in containers. +Ninguna de las opciones anteriores es incorrecta o correcta, pero cada una tiene sus razones para escogerla y seguramente ninguna de ellas desaparecezca. He visto una gran cantidad de contenido sobre Contenedores vs Máquinas Virtuales y realmente no debería haber un argumento, ya que son como argumentos de manzanas vs peras en el que ambos son frutas (formas de ejecutar nuestras aplicaciones), pero no son lo mismo. -None of the above options is wrong or right, but they each have their reasons to exist and I also strongly believe that none of these is going away. I have seen a lot of content that walks into Containers vs Virtual Machines and there really should not be an argument as that is more like apples vs pears argument where they are both fruit (ways to run our applications) but they are not the same. +También diría que si estás empezando y estás desarrollando una aplicación deberías inclinarte hacia los contenedores, más adelante lo veremos en detalle pero en resumen se trata de eficiencia, velocidad y tamaño. Pero esto tiene un precio, si no tienes ni idea de contenedores va a ser una curva de aprendizaje demasiado inclinada, te obligará a entender el por qué y entrar en esta mentalidad. Si has desarrollado tus aplicaciones de una forma particular o no estás en un entorno totalmente nuevo, puede que tengas que enfrentarte a más problemas incluso antes de considerar los contenedores. -I would also say that if you were starting and you were developing an application you should lean towards containers simply because we will get into some of these areas later, but it's about efficiency, speed and size. But that also comes with a price, if you have no idea about containers then it's going to be a learning curve to force yourself to understand the why and get into that mindset. If you have developed your applications a particular way or you are not in a greenfield environment then you might have more pain points to deal with before even considering containers. - -We have many different choices then when it comes to downloading a given piece of software, there are a variety of different operating systems that we might be using. And specific instructions for what we need to do to install our applications. +Tenemos muchas opciones diferentes a la hora de descargar un determinado software, hay una variedad de sistemas operativos diferentes que podríamos utilizar. E instrucciones específicas sobre lo que tenemos que hacer para instalar nuestras aplicaciones. ![](Images/Day42_Containers1.png) -More and more recently I am finding that the applications we might have once needed a full server OS, A VM, Physical or cloud instance are now releasing container-based versions of their software. I find this interesting as this opens the world of containers and then Kubernetes to everyone and not just a focus on application developers. +Cada vez nos encontramos más que las aplicaciones que una vez podrían haber necesitado un sistema operativo de servidor completo (una MV, instancia física o en la nube), ahora están lanzando versiones su software basadas en contenedores. Es interesante ya que esto abre las posibilidades de los contenedores y de Kubernetes a todo el mundo, y no sólo un enfoque en los desarrolladores de aplicaciones. ![](Images/Day42_Containers2.png) -As you can probably tell as I have said before, I am not going to advocate that the answer is containers, what's the question! But I would like to discuss how this is another option for us to be aware of when we deploy our applications. +Podrás deducir por lo que se ha dicho antes que no se va defender los contenedores como el mejor sistema para desplegar aplicaciones, pero desde luego existe el espacio para el debate. ![](Images/Day42_Containers4.png) -We have had container technology for a long time, so why now over the last say 10 years has this become popular, I would say even more popular in the last 5. We have had containers for decades. It comes down to the challenge of containers or should I say images as well, to how we distribute our software, because if we just have container technology, then we still will have many of the same problems we've had with software management. +Hemos tenido la tecnología de contenedores durante mucho tiempo, así que ¿por qué en los últimos 10 años se ha hecho tan popular? Diría que incluso mucho más populares en los últimos 5. -If we think about Docker as a tool, the reason that it took off, is because of the ecosystem of images that are easy to find and use. Simple to get on your systems and get up and running. A major part of this is consistency across the entire space, of all these different challenges that we face with software. It doesn't matter if it's MongoDB or nodeJS, the process to get either of those up and running will be the same. The process to stop either of those is the same. All of these issues will still exist, but the nice thing is, when we bring good container and image technology together, we now have a single set of tools to help us tackle all of these different problems. Some of those issues are listed below: +Hemos tenido contenedores durante décadas. ¿Se reduce al desafío de los contenedores o debería decir imágenes también? Porque si sólo tenemos la tecnología de contenedores, entonces todavía tendremos muchos de los mismos problemas que hemos tenido con la gestión de software. -- We first have to find software on the internet. -- We then have to download this software. -- Do we trust the source? -- Do we then need a license? Which License? -- Is it compatible with different platforms? -- What is the package? binary? Executable? Package manager? -- How do we configure the software? -- Dependencies? Did the overall download have us covered or do we need them as well? -- Dependencies of Dependencies? -- How do we start the application? -- How do we stop the application? -- Will it auto-restart? -- Start on boot? -- Resource conflicts? -- Conflicting libraries? -- Port Conflicts -- Security for the software? -- Software updates? -- How can I remove the software? +Si pensamos en Docker como una herramienta, la razón por la que despegó es al ecosistema de imágenes que son fáciles de conseguir y de poner en marcha. Una parte importante de esto es la coherencia en todo el espacio, de todos estos diferentes desafíos que enfrentamos con el software. No importa si es MongoDB o nodeJS, el proceso para poner en marcha cualquiera de ellos será el mismo. El proceso para detener cualquiera de ellos es el mismo. Todos estos problemas seguirán existiendo, pero lo bueno es que, cuando unimos una buena tecnología de contenedores e imágenes conseguiremos un único conjunto de herramientas para ayudarnos a abordar todos estos problemas diferentes. Algunos de esos problemas son: -We can split the above into 3 areas of the complexity of the software that containers and images do help with these. +- Primero tenemos que encontrar software en Internet. +- Luego tenemos que descargarlo. +- ¿Confiamos en la fuente? +- ¿Necesitamos una licencia? ¿Qué licencia? +- ¿Es compatible con diferentes plataformas? +- ¿Cuál es el paquete? ¿Binario? ¿Ejecutable? ¿Gestor de paquetes? +- ¿Cómo se configura el software? +- ¿Dependencias? ¿La descarga general nos ha cubierto o también las necesitamos? +- ¿Dependencias de dependencias? +- ¿Cómo iniciamos la aplicación? +- ¿Cómo detenemos la aplicación? +- ¿Se reiniciará automáticamente? +- ¿Se iniciará al arrancar? +- ¿Conflictos de recursos? +- ¿Conflictos de librerías? +- Conflictos de puertos +- ¿Seguridad del software? +- ¿Actualizaciones del software? +- ¿Cómo puedo eliminar el software? -| Distribution | Installation | Operation | -| ------------ | ------------- | ------------------ | -| Find | Install | Start | -| Download | Configuration | Security | -| License | Uninstall | Ports | -| Package | Dependencies | Resource Conflicts | -| Trust | Platform | Auto-Restart | -| Find | Libraries | Updates | +Podemos dividir lo anterior en 3 áreas de la complejidad del software que los contenedores y las imágenes ayudan con estos. -Containers and images are going to help us remove some of these challenges that we have with possibly other software and applications. +| Distribución | Instalación | Funcionamiento | +| ------------ | -------------- | ------------------- | +| Buscar | Instalar | Iniciar | +| Descargar | Configuración | Seguridad | +| Licencia | Desinstalación | Puertos | +| Paquete | Dependencias | Conflictos Recursos | +| Confianza | Plataforma | Reinicio automático | +| Buscar | Bibliotecas | Actualizaciones | -At a high level we could move installation and operation into the same list, Images are going to help us from a distribution point of view and containers help with the installation and operations. +Los contenedores y las imágenes nos van a ayudar a eliminar algunos de estos retos que tenemos posiblemente con otro software y aplicaciones. -Ok, probably sounds great and exciting but we still need to understand what is a container and now I have mentioned images so let's cover those areas next. +En un alto nivel podríamos mover la instalación y el funcionamiento en la misma lista, las imágenes nos van a ayudar desde el punto de vista de la distribución y los contenedores ayudan con la instalación y las operaciones. -Another thing you might have seen a lot when we talk about Containers for software development is the analogy used alongside shipping containers, shipping containers are used to ship various goods across the seas using large vessels. +Ok, probablemente suena muy bien y emocionante, pero todavía tenemos que entender lo que es un contenedor y ahora he mencionado imágenes así que vamos a verlo a continuación. + +Otra cosa que habrás visto a menudo cuando hablamos de contenedores para el desarrollo de software es la analogía utilizada con los contenedores marítimos, los contenedores marítimos se utilizan para transportar diversas mercancías a través de los mares utilizando grandes buques. ![](Images/Day42_Containers5.png) -What does this have to do with our topic of containers? Think about the code that software developers write, how can we ship that particular code from one machine to another machine? +¿Qué tiene que ver con nuestro tema de los contenedores? Piensa en el código que escriben los desarrolladores de software, ¿cómo podemos enviar ese código concreto de una máquina a otra? -If we think about what we touched on before about software distribution, installation and operations but now we start to build this out into an environment visual. We have hardware and an operating system where you will run multiple applications. For example, nodejs has certain dependencies and needs certain libraries. If you then want to install MySQL then it needs its required libraries and dependencies. Each software application will have its library and dependency. We might be massively lucky and not have any conflicts between any of our applications where specific libraries and dependencies are clashing causing issues but the more applications the more chance or risk of conflicts. However, this is not about that one deployment when everything fixes your software applications are going to be updated and then we can also introduce these conflicts. +Si pensamos en lo que hemos tocado antes sobre la distribución de software, instalación y operaciones, pero ahora empezamos a construir esto en un entorno visual. Tenemos hardware y un sistema operativo donde se ejecutarán múltiples aplicaciones. Por ejemplo, nodejs tiene ciertas dependencias y necesita ciertas bibliotecas. Si a continuación, desea instalar MySQL entonces necesita sus bibliotecas y sus dependencias propias. Cada aplicación de software tendrá sus bibliotecas y dependencias. Podríamos tener mucha suerte y no tener ningún conflicto entre cualquiera de nuestras aplicaciones donde las bibliotecas y dependencias específicas están chocando causando problemas, pero cuantas más aplicaciones más posibilidades o riesgo de conflictos. Sin embargo, se trata de que un despliegue se producirá muchas veces, y no puede esperar a que todo este arreglado, porque en cada actualización se podrían introducir estos conflictos. ![](Images/Day42_Containers6.png) -Containers can help solve this problem. Containers help **build** your application, **ship** the application, **deploy** and **scale** these applications with ease independently. let's look at the architecture, you will have hardware and operating system then on top of it you will have a container engine like docker which we will cover later. The container engine software helps create containers that package the libraries and dependencies along with it so that you can move this container seamlessly from one machine to another machine without worrying about the libraries and dependencies since they come as a part of a package which is nothing but the container so you can have different containers this container can be moved across the systems without worrying about the underlying dependencies that the application -needs to run because everything the application needs to run is packaged as -a container that you can move. +Los contenedores pueden ayudar a resolver este problema. Los contenedores ayudan a **construir**, a **enviar**, a **desplegar** y a **escalar** estas aplicaciones con facilidad de forma independiente. echemos un vistazo a la arquitectura, tendrás hardware y sistema operativo y luego encima tendrás un motor de contenedores como docker que veremos en breve. El software de motor de contenedores ayuda a crear contenedores que empaquetan las bibliotecas y dependencias junto con él para que pueda mover este contenedor sin problemas de una máquina a otra sin preocuparse por las bibliotecas y dependencias, ya que vienen como parte de un paquete en el contenedor. Con lo cual, se puede mover a través de los sistemas sin preocuparse por las dependencias subyacentes que la aplicación necesita para funcionar. ![](Images/Day42_Containers7.png) -### The advantages of these containers +### Las ventajas de estos contenedores -- Containers help package all the dependencies within the container and - isolate it. +- Los contenedores ayudan a empaquetar todas las dependencias dentro del contenedor y aislarlas. -- It is easy to manage the containers +- Es fácil gestionar. -- The ability to move from one system to another. +- Se puede pasar de un sistema a otro. -- Containers help package the software and you can easily ship it without any duplicate efforts +- Los contenedores ayudan a empaquetar el software y se puede enviar fácilmente sin duplicar esfuerzos. -- Containers are easily scalable. +- Los contenedores son fácilmente escalables. -Using containers you can scale independent containers and use a load balancer -or a service which helps split the traffic and you can scale the applications horizontally. Containers offer a lot of flexibility and ease in how you manage your applications +Usando contenedores puedes escalar contenedores independientes y usar un equilibrador de carga +o un servicio que ayude a dividir el tráfico y puedas escalar las aplicaciones horizontalmente. Los contenedores ofrecen mucha flexibilidad y facilidad a la hora de gestionar las aplicaciones. -### What is a container? +### ¿Qué es un contenedor? -When we run applications on our computer, this could be the web browser or VScode that you are using to read this post. That application is running as a process or what is known as a process. On our laptops or systems, we tend to run multiple applications or as we said processes. When we open a new application or click on the application icon this is an application we would like to run, sometimes this application might be a service that we just want to run in the background, our operating system is full of services that are running in the background providing you with the user experience you get with your system. +Cuando ejecutamos aplicaciones en nuestro ordenador, podría ser en el navegador o en el VScode que quizá estés utilizando para leer este post, esa aplicación se ejecuta como un proceso. En nuestros portátiles o sistemas tendemos a ejecutar múltiples aplicaciones o, como hemos dicho, procesos. Cuando abrimos una nueva aplicación o hacemos clic en el icono de la aplicación, a veces podría ser un servicio que sólo queremos ejecutar en segundo plano, nuestro sistema operativo está lleno de servicios que se ejecutan en segundo plano y que proporcionan la experiencia de usuario final. -That application icon represents a link to an executable somewhere on your file system, the operating system then loads that executable into memory. Interestingly, that executable is sometimes referred to as an image when we're talking about a process. +Ese icono de aplicación representa un enlace a un ejecutable en algún lugar de tu sistema de archivos, el sistema operativo entonces carga ese ejecutable en la memoria. Curiosamente, a veces nos referimos a ese ejecutable como una imagen cuando hablamos de un proceso. -Containers are processes, A container is a standard unit of software that packages up code and all its dependencies so the application runs quickly and reliably from one computing environment to another. +Un contenedor es una unidad estándar de software que empaqueta el código y todas sus dependencias para que la aplicación se ejecute de forma rápida y fiable de un entorno informático a otro como lo hacen las aplicaciones. -Containerised software will always run the same, regardless of the infrastructure. Containers isolate software from its environment and ensure that it works uniformly despite differences for instance between development and staging. +El software en contenedores siempre se ejecutará igual, independientemente de la infraestructura. Los contenedores aíslan el software en su entorno mínimo viable y garantizan que funcione de manera uniforme a pesar de las diferencias, por ejemplo, entre el desarrollo y la puesta en escena. -I mentioned images in the last section when it comes to how and why containers and images combined made containers popular in our ecosystem. +He mencionado las imágenes en la última sección cuando se trata de cómo y por qué la combinación de contenedores e imágenes ha hecho que los contenedores sean populares en nuestro ecosistema. -### What is an Image? +### ¿Qué es una imagen? -A container image is a lightweight, standalone, executable package of software that includes everything needed to run an application: code, runtime, system tools, system libraries and settings. Container images become containers at runtime. +Una imagen de contenedor es un paquete de software ligero, independiente y ejecutable que incluye todo lo necesario para ejecutar una aplicación: código, tiempo de ejecución, herramientas del sistema, bibliotecas del sistema y configuraciones. Las imágenes de contenedor se convierten en contenedores en tiempo de ejecución. -## Resources +## Recursos - [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) - [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) - [Docker Tutorial for Beginners - What is Docker? Introduction to Containers](https://www.youtube.com/watch?v=17Bl31rlnRM&list=WL&index=128&t=61s) - [Introduction to Container By Red Hat](https://www.redhat.com/en/topics/containers) +- [En español] En los [apuntes](https://vergaracarmona.es/apuntes/) del traductor: + - [Preparación de entorno de pruebas local para docker](https://vergaracarmona.es/preparacion-de-entorno-de-pruebas-local-para-docker/) + - [Uso básico de docker](https://vergaracarmona.es/uso-basico-de-docker/) + - [Una breve historia sobre contenedores](https://vergaracarmona.es/breve-historia-de-contenedores/) + - [Desplegar con docker-compose los servicios Traefik y Portainer](https://vergaracarmona.es/desplegar-con-docker-compose-los-servicios-traefik-y-portainer/) -See you on [Day 43](day43.md) +Nos vemos en el [Día 43](day43.md) diff --git a/2022/es/Days/day43.md b/2022/es/Days/day43.md index 0e39fe7..70a141b 100644 --- a/2022/es/Days/day43.md +++ b/2022/es/Days/day43.md @@ -1,62 +1,67 @@ -## What is Docker & Getting installed +## Qué es Docker y cómo instalarlo -In the previous post, I mentioned Docker at least once and that is because Docker is innovative in making containers popular even though they have been around for such a long time. +En el post anterior, he mencionado Docker al menos una vez y eso es porque Docker es el culpable en gran parte de la popularización de los contenedores, a pesar de que han existido desde hace mucho tiempo. -We are going to be using and explaining docker here but we should also mention the [Open Container Initiative (OCI)](https://www.opencontainers.org/) which is an industry standards organization that encourages innovation while avoiding the danger of vendor lock-in. Thanks to the OCI, we have a choice when choosing a container toolchain, including Docker, [CRI-O](https://cri-o.io/), [Podman](http://podman.io/), [LXC](https://linuxcontainers.org/), and others. +Vamos a utilizar y explicar un poco Docker, pero también debemos mencionar la [Open Container Initiative (OCI)](https://www.opencontainers.org/), que es una organización de estándares de la industria que fomenta la innovación, evitando el peligro de la dependencia del proveedor. Gracias a la OCI, tenemos donde elegir entre las herramientas de contenedores, incluyendo Docker, [CRI-O](https://cri-o.io/), [Podman](http://podman.io/), [LXC](https://linuxcontainers.org/), entre otros. -Docker is a software framework for building, running, and managing containers. The term "docker" may refer to either the tools (the commands and a daemon) or the Dockerfile file format. +Docker es un framework de software para construir, ejecutar y gestionar contenedores. El término "docker" puede referirse tanto a las herramientas (los comandos y un daemon) como al formato de archivo Dockerfile. -We are going to be using Docker Personal here which is free (for education and learning). This includes all the essentials that we need to cover to get a good foundation of knowledge of containers and tooling. +Utilizaremos Docker Personal, que es gratuito (para la educación y el aprendizaje). Esto incluye todo lo esencial que necesitamos para obtener una buena base de conocimientos de los contenedores y herramientas. -It is probably worth breaking down some of the "docker" tools that we will be using and what they are used for. The term docker can be referring to the docker project overall, which is a platform for devs and admins to develop, ship and run applications. It might also be a reference to the docker daemon process running on the host which manages images and containers also called Docker Engine. +Probablemente vale la pena desglosar algunas de las herramientas "docker" para saber por qué se utilizan. El término docker puede referirse al proyecto docker en general, que es una plataforma para que los desarrolladores y administradores desarrollen, envíen y ejecuten aplicaciones. También puede ser una referencia al daemon Docker que se ejecuta en el host que gestiona las imágenes y contenedores también llamado Docker Engine. ### Docker Engine -Docker Engine is an open-source containerization technology for building and containerizing your applications. Docker Engine acts as a client-server application with: +Docker Engine es una tecnología de contenerización de código abierto para construir y contenerizar tus aplicaciones. Docker Engine actúa como una aplicación cliente-servidor con: -- A server with a long-running daemon process dockerd. -- APIs specify interfaces that programs can use to talk to and instruct the Docker daemon. -- A command line interface (CLI) client docker. +- Un servidor con un proceso demonio de larga ejecución dockerd. +- Las API especifican interfaces que los programas pueden utilizar para hablar con el demonio Docker y darle instrucciones. +- Una interfaz de línea de comandos (CLI) docker cliente. -The above was taken from the official Docker documentation and the specific [Docker Engine Overview](https://docs.docker.com/engine/) +Lo anterior fue tomado de la documentación oficial de Docker y el específico [Docker Engine Overview](https://docs.docker.com/engine/) ### Docker Desktop -We have a docker desktop for both Windows and macOS systems. An easy-to-install, lightweight docker development environment. A native OS application that leverages virtualisation capabilities on the host operating system. +Disponemos de un Docker Desktop para sistemas Windows y macOS. Un entorno de desarrollo docker ligero y fácil de instalar. Una aplicación nativa del sistema operativo que aprovecha las capacidades de virtualización en el sistema operativo anfitrión. Nadie lo utiliza, pero es una buena opción para comenzar. -It’s the best solution if you want to build, debug, test, package, and ship Dockerized applications on Windows or macOS. +Puedes construir, depurar, probar, empaquetar y enviar aplicaciones Dockerizadas en Windows o macOS. -On Windows, we can also take advantage of WSL2 and Microsoft Hyper-V. We will cover some of the WSL2 benefits as we go through. +En Windows, también podemos aprovechar WSL2 y Microsoft Hyper-V. Veremos algunas de las ventajas de WSL2 a medida que avancemos, ya que como Windows no llega lo mejor es utilizar las opciones Linux. -Because of the integration with hypervisor capabilities on the host operating system docker provides the ability to run your containers with Linux Operating systems. +Debido a la difícil integración con las capacidades del hipervisor en el sistema operativo anfitrión, docker proporciona la capacidad de ejecutar sus contenedores con sistemas operativos Linux que no dan tantos problemas. ### Docker Compose -Docker compose is a tool that allows you to run more complex apps over multiple containers. With the benefit of being able to use a single file and command to spin up your application. +Docker compose es una herramienta que te permite ejecutar aplicaciones más complejas sobre múltiples contenedores. Con la ventaja de ser capaz de utilizar un único archivo y comando para hacer girar su aplicación. Es el principio de la orquestación de contenedores, un concepto que tendremos que interiorizar para dejar de tratar a nuestras máquinas como mascotas y comenzar a verlas como ganado. ### Docker Hub -A centralised resource for working with Docker and its components. Most commonly known as a registry to host docker images. But there are a lot of additional services here which can be used in part with automation or integrated into GitHub as well as security scanning. +Un recurso centralizado para trabajar con Docker y sus componentes, un registro de imágenes que nos facilitará mucho la existencia. Hay un montón de servicios adicionales que pueden ser utilizados en parte con la automatización o integrados en GitHub, así como el escaneo de seguridad. ### Dockerfile -A dockerfile is a text file that contains commands you would normally execute manually to build a docker image. Docker can build images automatically by reading the instructions we have in our dockerfile. +Un dockerfile es un archivo de texto que contiene comandos que también se pueden ejecutar manualmente para construir una imagen docker. Docker puede construir imágenes automáticamente leyendo las instrucciones que tenemos en nuestro dockerfile gracias al lenguaje declarativo. -## Installing Docker Desktop +## Instalando Docker Desktop -The [docker documenation](https://docs.docker.com/engine/install/) is amazing and if you are only just diving in then you should take a look and have a read-through. We will be using Docker Desktop on Windows with WSL2. I had already run through the installation on the machine we are using here. +La [documenación de Docker](https://docs.docker.com/engine/install/) es asombrosa y si quieres aprender de verdad deberías echarle un vistazo y tenerla como referencia. Vamos a utilizar Docker Desktop en Windows con WSL2. Ya he ejecutado la instalación en la máquina que estamos utilizando. ![](Images/Day43_Containers1.png) -Take note before you go ahead and install at the system requirements, [Install Docker Desktop on Windows](https://docs.docker.com/desktop/windows/install/) if you are using macOS including the M1-based CPU architecture you can also take a look at [Install Docker Desktop on macOS](https://docs.docker.com/desktop/mac/install/) +Toma nota antes de seguir adelante en los requisitos del sistema antes de [Instalar Docker Desktop en Windows](https://docs.docker.com/desktop/windows/install/). Si estás usando macOS, inclusive para la arquitectura de CPU basada en M1, puedes echar un vistazo a [Instalar Docker Desktop en macOS](https://docs.docker.com/desktop/mac/install/). Linux también puede ejecutar Docker Desktop virtualizado: https://docs.docker.com/desktop/install/linux-install/ -I will run through the Docker Desktop installation for Windows on another Windows Machine and log the process down below. +Voy a ejecutar a través de la instalación de Docker Desktop para Windows en otra máquina Windows y registrar el proceso de abajo. -## Resources +## Recursos - [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) - [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) - [Docker Tutorial for Beginners - What is Docker? Introduction to Containers](https://www.youtube.com/watch?v=17Bl31rlnRM&list=WL&index=128&t=61s) - [WSL 2 with Docker getting started](https://www.youtube.com/watch?v=5RQbdMn04Oc) +- [En español] En los [apuntes](https://vergaracarmona.es/apuntes/) del traductor: + - [Preparación de entorno de pruebas local para docker](https://vergaracarmona.es/preparacion-de-entorno-de-pruebas-local-para-docker/) + - [Uso básico de docker](https://vergaracarmona.es/uso-basico-de-docker/) + - [Una breve historia sobre contenedores](https://vergaracarmona.es/breve-historia-de-contenedores/) + - [Desplegar con docker-compose los servicios Traefik y Portainer](https://vergaracarmona.es/desplegar-con-docker-compose-los-servicios-traefik-y-portainer/) -See you on [Day 44](day44.md) +Nos vemos en el [Día 44](day44.md) diff --git a/2022/es/Days/day44.md b/2022/es/Days/day44.md index aa71342..5c5cae1 100644 --- a/2022/es/Days/day44.md +++ b/2022/es/Days/day44.md @@ -1,132 +1,145 @@ -## Docker Images & Hands-On with Docker Desktop +## Imágenes Docker y Manos a la Obra con Docker Desktop -We now have Docker Desktop installed on our system. (If you are running Linux then you still have options but no GUI but docker does work on Linux.)[Install Docker Engine on Ubuntu](https://docs.docker.com/engine/install/ubuntu/) (Other distributions also available.) +Ahora tenemos Docker Desktop instalado en nuestro sistema. (Si estás ejecutando Linux, tienes más opciones pero no el GUI.)[Instalar Docker Engine en Ubuntu](https://docs.docker.com/engine/install/ubuntu/) (También está disponible para otras distribuciones.) -In this post, we are going to get started with deploying some images into our environment. A recap on what a Docker Image is - A Docker image is a file used to execute code in a Docker container. Docker images act as a set of instructions to build a Docker container, like a template. Docker images also act as the starting point when using Docker. +En este post, vamos a empezar con el despliegue de algunas imágenes en nuestro entorno. Una imagen Docker es un archivo utilizado para ejecutar código en un contenedor Docker. Las imágenes Docker actúan como un conjunto de instrucciones para construir un contenedor Docker, como una plantilla. Las imágenes Docker también actúan como el punto de partida cuando se utiliza Docker. -Now is a good time to go and create your account on [DockerHub](https://hub.docker.com/) +Ahora es un buen momento para crear tu cuenta en [DockerHub](https://hub.docker.com/) ![](Images/Day44_Containers1.png) -DockerHub is a centralised resource for working with Docker and its components. Most commonly known as a registry to host docker images. But there are a lot of additional services here which can be used in part with automation or integrated into GitHub as well as security scanning. +DockerHub es un recurso centralizado para trabajar con Docker y sus componentes. Más comúnmente conocido como un registro para alojar imágenes Docker. Pero hay un montón de servicios adicionales que se pueden utilizar en parte con la automatización o integración en GitHub, así como el escaneo de seguridad. -If you scroll down once logged in you are going to see a list of container images, You might see database images for MySQL, hello-world etc. Think of these as great baseline images or you might just need a database image and you are best to use the official one which means you don't need to create your own. +Desplazándote hacia abajo una vez logueado verás una lista de imágenes de contenedores, es posible que veas imágenes de bases de datos MySQL, hello-world, etc. Piensa en estas como las imágenes de referencia, puede que sólo necesites una imagen de BBDD MySQL y la mejor sea utilizar la oficial, lo que significa que no es necesario crear una propia personalizada. ![](Images/Day44_Containers2.png) -We can drill deeper into the view of available images and search across categories, operating systems and architectures. The one thing I highlight below is the Official Image, this should give you peace of mind about the origin of this container image. +Podemos profundizar en la vista de imágenes disponibles y buscar por categorías, sistemas operativos y arquitecturas. Hay que destacar la Imagen Oficial, porque esta debería darte tranquilidad sobre su origen. Para nada recomiendo utilizar imágenes no oficiales, sobretodo en producción. En caso de que lo hagas, asegúrate al menos de que son de un editor verificado. ![](Images/Day44_Containers3.png) -We can also search for a specific image, for example, WordPress might be a good base image that we want we can do that at the top and find all container images related to WordPress. Below are notices that we also have verified publisher. - -- Official Image - Docker Official images are a curated set of Docker open source and "drop-in" solution repositories. - -- Verified Publisher - High-quality Docker content from verified publishers. These products are published and maintained directly by a commercial entity. +Por otra parte, podemos buscar una imagen específica, por ejemplo, WordPress podría ser una buena imagen de base que incluye todas las imágenes de contenedores relacionados que necesite la aplicación. Ten en cuenta que existe diferencias entre imagen oficial y editor verificado. +- **Imagen Oficial** - Las imágenes Oficiales de Docker son un conjunto curado de código abierto de Docker y repositorios de soluciones "drop-in". +- **Editor verificado** - Contenido Docker de alta calidad de editores verificados. Estos productos son publicados y mantenidos directamente por una entidad comercial. ![](Images/Day44_Containers4.png) -### Exploring Docker Desktop +### Explorando Docker Desktop -We have Docker Desktop installed on our system and if you open this I expect unless you had this already installed you will see something similar to the image below. As you can see we have no containers running and our docker engine is running. +Tenemos Docker Desktop instalado en nuestro equipo windows. Si lo abres por primera vez verás algo similar a la imagen de abajo. Como puedes ver no tenemos ningún contenedor ejecutándose y nuestro motor docker está funcionando. ![](Images/Day44_Containers5.png) -Because this was not a fresh install for me, I do have some images already downloaded and available on my system. You will likely see nothing in here. +Debido a que esta no fue la primera instalación, tengo algunas imágenes ya descargadas y disponibles en mi sistema. Es probable que lo veas diferente. ![](Images/Day44_Containers6.png) -Under remote repositories, this is where you will find any container images you have stored in your docker hub. You can see from the below I do not have any images. +En los repositorios remotos es donde encontrarás cualquier imagen de contenedor que hayas almacenado en tu docker hub. Puedes ver en la imagen de abajo que no tengo ninguna imagen. ![](Images/Day44_Containers7.png) -We can also clarify this on our dockerhub site and confirm that we have no repositories there. +Hay que confirmarlo en nuestro sitio dockerhub y confirmar que no tenemos repositorios allí. ![](Images/Day44_Containers8.png) -Next, we have the Volumes tab, If you have containers that require persistence then this is where we can add these volumes to your local file system or a shared file system. +A continuación, tenemos la pestaña Volumes. Si tienes contenedores que requieren persistencia será aquí donde podemos añadir estos volúmenes al sistema de archivos local o a un sistema de archivos compartido. ![](Images/Day44_Containers9.png) -At the time of writing, there is also a Dev Environments tab, this is going to help you collaborate with your team instead of moving between different git branches. We won't be covering this. +En el momento de escribir esto, también hay una pestaña de Entornos de Desarrollo, esto va a ayudarte a colaborar con tu equipo en lugar de moverte entre diferentes ramas de git. No vamos a cubrir esto. ![](Images/Day44_Containers10.png) -Going back to the first tab you can see that there is a command we can run which is a getting started container. Let's run `docker run -d -p 80:80 docker/getting-started` in our terminal. +Volviendo a la primera pestaña puedes ver que hay un comando que podemos ejecutar para iniciar el contenedor. Ejecutamos en nuestro terminal: + +```shell +docker run -d -p 80:80 docker/getting-started +``` ![](Images/Day44_Containers11.png) -If we go and check our docker desktop window again, we are going to see that we have a running container. +Si comprobamos nuestro docker desktop veremos que ya tenemos un contenedor en ejecución. ![](Images/Day44_Containers12.png) -You might have noticed that I am using WSL2 and for you to be able to use that you will need to make sure this is enabled in the settings. +Te habrás dado cuenta de que estoy usando WSL2. Para usarlo tendrás que asegurarte de que está activado en la configuración. ![](Images/Day44_Containers13.png) -If we now go and check our Images tab again, you should now see an in-use image called docker/getting-started. +Si ahora comprobamos nuestra pestaña Imágenes deberías ver una imagen en uso llamada docker/getting-started. ![](Images/Day44_Containers14.png) -Back to the Containers/Apps tab, click on your running container. You are going to see the logs by default and along the top, you have some options to choose from, in our case I am pretty confident that this is going to be a web page running in this container so we are going to choose the open in the browser. +De vuelta a la pestaña Contenedores/Apps, haz click en tu contenedor en ejecución. Verás los registros por defecto y en la parte superior tiene algunas opciones para elegir. En nuestro caso no va a ser una web que se ejecute en este contenedor por lo que vamos a elegir la apertura en el navegador. ![](Images/Day44_Containers15.png) -When we hit that button above sure enough a web page should open hitting your localhost and display something similar to below. +Cuando pulsemos el botón de arriba, se abrirá una web que mostrará algo similar a lo que se muestra a continuación. -This container also has some more detail on our containers and images. +Este contenedor también tiene algunos detalles más sobre nuestros contenedores e imágenes. ![](Images/Day44_Containers16.png) -We have now run our first container. Nothing too scary just yet. What about if we wanted to pull one of the container images down from DockerHub? Maybe there is a `hello world` docker container we could use. +Ya hemos ejecutado nuestro primer contenedor. Nada demasiado aterrador todavía. ¿Y si quisiéramos bajar una de las imágenes de contenedor de DockerHub? Podemos usar un contenedor docker llamado `hello world` para comprobarlo. -I went ahead and stopped the getting started container not that it's taking up any mass amount of resources but for tidiness, as we walk through some more steps. +Me adelanté y detuve el contenedor de inicio, no es que esté ocupando una cantidad masiva de recursos, sino para mantener un orden mientras vemos algunos pasos más. -Back in our terminal let's go ahead and run `docker run hello-world` and see what happens. +De vuelta en nuestro terminal vamos a seguir adelante y ejecutar `docker run hello-world` y a ver qué pasa. -You can see we did not have the image locally so we pulled that down and then we got a message that is written into the container image with some information on what it did to get up and running and some links to reference points. +Puedes ver que no teníamos la imagen localmente así que la bajamos y entonces tenemos un mensaje que está escrito en la imagen del contenedor con alguna información sobre lo que hizo para ponerse en marcha y algunos enlaces a puntos de referencia. ![](Images/Day44_Containers17.png) -However, if we go and look in Docker Desktop now we have no running containers but we do have an exited container that used the hello-world message, meaning it came up, delivered the message and then is terminated. +Sin embargo, si vamos y miramos en Docker Desktop ahora no tenemos ningún contenedor en ejecución, pero sí tenemos un contenedor que utilizó el mensaje hola-mundo, lo que significa que apareció, entregó el mensaje y luego se terminó. ![](Images/Day44_Containers18.png) -And for the last time, let's just go and check the images tab and see that we have a new hello-world image locally on our system, meaning that if we run the `docker run hello-world` command again in our terminal we would not have to pull anything unless a version changes. +Y para terminar vamos a comprobar la pestaña images de nuevo en la que tendremos una nueva imagen hello-world localmente, lo que significa que si ejecutamos de nuevo el comando `docker run hello-world` en nuestro terminal no tendríamos que descargar nada a menos de que cambie la versión. ![](Images/Day44_Containers19.png) -The message from the hello-world container set down the challenge of running something a little more ambitious. +El mensaje del contenedor hello-world nos planteó el reto de ejecutar algo un poco más ambicioso. -Challenge Accepted! +¡Reto aceptado! ![](Images/Day44_Containers20.png) -In running `docker run -it ubuntu bash` in our terminal we are going to run a containerised version of Ubuntu well not a full copy of the Operating system. You can find out more about this particular image on [DockerHub](https://hub.docker.com/_/ubuntu) +Al ejecutar `docker run -it ubuntu bash` en nuestro terminal vamos a ejecutar una versión en un contenedor de Ubuntu, que no es una copia completa del sistema operativo. Puedes encontrar más información sobre esta imagen en particular en [DockerHub](https://hub.docker.com/_/ubuntu) -You can see below when we run the command we now have an interactive prompt (`-it`) and we have a bash shell into our container. +Puedes ver a continuación cuando ejecutamos el comando que ahora tenemos un símbolo del sistema interactivo (`-it`) y tenemos un shell bash en nuestro contenedor. ![](Images/Day44_Containers21.png) -We have a bash shell but we don't have much more which is why this container image is less than 30MB. +Tenemos una shell bash pero no tenemos mucho más, piensa que la imagen de este contenedor pesa menos de 30MB. ![](Images/Day44_Containers22.png) -But we can still use this image and we can still install software using our apt package manager, we can update our container image and upgrade also. +Pero con esta imagen podemos, por ejemplo: +- Instalar todo el software que necesitemos usando nuestro gestor de paquetes apt. +- Actualizar nuestra imagen de contenedor +- Crear un nuevo contenedor a partir de esta imagen +- Utilizar el contenedor interactivo para pruebas. + +Y todo lo que imaginemos. ![](Images/Day44_Containers23.png) -Or maybe we want to install some software into our container, I have chosen a really bad example here as pinta is an image editor and it's over 200MB but hopefully you get where I am going with this. This would increase the size of our container considerably but still, we are going to be in the MB and not in the GB. +He instalado algún software en el contenedor, he elegido un ejemplo muy malo aquí ya que `pinta` es un editor de imágenes de más de 200 MB, pero espero que entiendas a dónde voy con esto. Esto aumentaría el tamaño de nuestro contenedor considerablemente pero aún así, vamos a estar en unos MB sin llegar al GB. ![](Images/Day44_Containers24.png) -I wanted that to hopefully give you an overview of Docker Desktop and the not-so-scary world of containers when you break it down with simple use cases, we do need to cover some networking, security and other options we have vs just downloading container images and using them like this. By the end of the section, we want to have made something and uploaded it to our DockerHub repository and be able to deploy it. +Quería que esto te diera una visión general de Docker Desktop y el mundo no tan aterrador de los contenedores cuando lo desglosas con casos de uso simples. Ahora tenemos que ver algo de redes, de seguridad y otras opciones mínimas que necesitamos de base. -## Resources +## Recursos - [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) - [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) - [Docker Tutorial for Beginners - What is Docker? Introduction to Containers](https://www.youtube.com/watch?v=17Bl31rlnRM&list=WL&index=128&t=61s) - [WSL 2 with Docker getting started](https://www.youtube.com/watch?v=5RQbdMn04Oc) +- [En español] En los [apuntes](https://vergaracarmona.es/apuntes/) del traductor: + - [Preparación de entorno de pruebas local para docker](https://vergaracarmona.es/preparacion-de-entorno-de-pruebas-local-para-docker/) + - [Uso básico de docker](https://vergaracarmona.es/uso-basico-de-docker/) + - [Una breve historia sobre contenedores](https://vergaracarmona.es/breve-historia-de-contenedores/) + - [Desplegar con docker-compose los servicios Traefik y Portainer](https://vergaracarmona.es/desplegar-con-docker-compose-los-servicios-traefik-y-portainer/) -See you on [Day 45](day45.md) +Nos vemos en el [Día 45](day45.md) diff --git a/2022/es/Days/day45.md b/2022/es/Days/day45.md index fe3cfbb..46b2bfb 100644 --- a/2022/es/Days/day45.md +++ b/2022/es/Days/day45.md @@ -1,66 +1,67 @@ -## The anatomy of a Docker Image +## La anatomía de una imagen Docker -In the last session, we covered some basics of how we can use Docker Desktop combined with DockerHub to deploy and run some verified images. A recap on what an image is, you won't forget things if I keep mentioning them. +En la última sesión, vimos algunos aspectos básicos de cómo podemos utilizar Docker Desktop combinado con DockerHub para desplegar y ejecutar algunas imágenes verificadas. Una recapitulación sobre lo que es una imagen, no olvidarás cosas si sigo mencionándolas. -A Docker image is a read-only template that contains a set of instructions for creating a container that can run on the Docker platform. It provides a convenient way to package up applications and preconfigured server environments, which you can use for your private use or share publicly with other Docker users. Docker images are also the starting point for anyone using Docker for the first time. +Una imagen Docker es una plantilla de sólo lectura que contiene un conjunto de instrucciones para crear un contenedor que se puede ejecutar en la plataforma Docker. Proporciona una forma práctica de empaquetar aplicaciones y entornos de servidor preconfigurados, que puedes utilizar para tu uso privado o compartir públicamente con otros usuarios de Docker. Las imágenes Docker son también el punto de partida para cualquiera que utilice Docker por primera vez. -What happens if we want to create our own Docker image? For us to do this we would create a Dockerfile. You saw how we could take that Ubuntu container image and we could add our software and we would have our container image with the software that we wanted and everything is good, however, if that container is shut down or thrown away then all those software updates and installations go away there is no repeatable version of what we had done. So that is great for showing off the capabilities but it doesn't help with the transport of images across multiple environments with the same set of software installed each time the container is run. +¿Qué ocurre si queremos crear nuestra propia imagen Docker? Para ello crearíamos un Dockerfile. Ya viste cómo podríamos tomar esa imagen de contenedor Ubuntu y añadir nuestro software. Con lo que tendríamos nuestra imagen de contenedor con el software que queremos, sin embargo, si ese contenedor se apaga o se destruye todas esas actualizaciones de software y las instalaciones desaparecen, perdemos los cambios sin una versión repetible. Así que eso es genial para mostrar las capacidades, pero no ayuda con el transporte de imágenes a través de múltiples entornos con el mismo conjunto de software instalado cada vez que se ejecuta el contenedor, que es la potencia de docker. -### What is a Dockerfile +### ¿Qué es un Dockerfile? -A dockerfile is a text file that contains commands you would normally execute manually to build a docker image. Docker can build images automatically by reading the instructions we have in our dockerfile. +Un dockerfile es un archivo de texto que contiene comandos que normalmente ejecutarías manualmente para construir una imagen docker. Docker puede construir imágenes automáticamente leyendo las instrucciones que tenemos en nuestro dockerfile. -Each of the files that make up a docker image is known as a layer. these layers form a series of images, built on top of each other in stages. Each layer is dependent on the layer immediately below it. The order of your layers is key to the efficiency of the lifecycle management of your docker images. +Cada uno de los archivos que componen una imagen docker se conoce como una capa. Estas capas forman una serie de imágenes, construidas unas sobre otras por etapas. Cada capa depende de la capa inmediatamente inferior. El orden de tus capas es clave para la eficiencia de la gestión del ciclo de vida de tus imágenes docker. -We should organise our layers that change most often as high in the stack as possible, this is because when you make changes to a layer in your image, Docker not only rebuilds that particular layer but all layers built from it. Therefore a change to a layer at the top involves the least amount of work to rebuild the entire image. +Debemos organizar nuestras capas que cambian más a menudo lo más alto posible en la pila, esto se debe a que cuando se realizan cambios en una capa de la imagen, Docker no sólo reconstruye esa capa en particular, sino todas las capas construidas a partir de ella. Por lo tanto, un cambio en una capa en la parte superior implica la menor cantidad de trabajo para reconstruir toda la imagen. -Each time docker launches a container from an image (like we ran yesterday) it adds a writeable layer, known as the container layer. This stores all changes to the container throughout its runtime. This layer is the only difference between a live operational container and the source image itself. Any number of like-for-like containers can share access to the same underlying image while maintaining their state. +Cada vez que docker lanza un contenedor desde una imagen (como hicimos ayer) añade una capa escribible, conocida como la capa del contenedor. Esto almacena todos los cambios en el contenedor a lo largo de su tiempo de ejecución. Esta capa es la única diferencia entre un contenedor operativo en vivo y la propia imagen de origen. Cualquier número de contenedores similares pueden compartir el acceso a la misma imagen subyacente, manteniendo su estado. -Back to the example, we used yesterday with the Ubuntu image. We could run that same command multiple times and on the first container we could go and install pinta and on the second we could install figlet with two different applications, different purposes, different sizes etc. Each container that we deployed shares the same image but not the same state and then that state is then gone when we remove the container. +Volviendo al ejemplo que utilizamos ayer con la imagen de Ubuntu. Podríamos ejecutar ese mismo comando múltiples veces y en el primer contenedor podríamos instalar pinta y en el segundo podríamos instalar figlet con dos aplicaciones diferentes, diferentes propósitos, diferentes tamaños, etc. Cada contenedor que desplegamos comparte la misma imagen pero no el mismo estado y luego ese estado desaparece cuando eliminamos el contenedor. ![](Images/Day45_Containers1.png) -Following the example above with the Ubuntu image, but also many other ready-built container images available on DockerHub and other third-party repositories. These images are generally known as the parent image. It is the foundation upon which all other layers are built and provides the basic building blocks for our container environments. +Estas imágenes se conocen generalmente como la imagen padre. Es la base sobre la que se construyen todas las demás capas y proporciona los bloques de construcción básicos para nuestros entornos de contenedores. -Together with a set of individual layer files, a Docker image also includes an additional file known as a manifest. This is essentially a description of the image in JSON format and comprises information such as image tags, a digital signature, and details on how to configure the container for different types of host platforms. +Junto con un conjunto de archivos de capas individuales, una imagen Docker también incluye un archivo adicional conocido como manifiesto. Se trata básicamente de una descripción de la imagen en formato JSON y contiene información como las etiquetas de la imagen, una firma digital y detalles sobre cómo configurar el contenedor para distintos tipos de plataformas host. ![](Images/Day45_Containers2.png) -### How to create a docker image +### Cómo crear una imagen docker - There are two ways we can create a docker image. We can do it a little on the fly with the process that we started yesterday, we pick our base image spin up that container, and install all of the software and dependencies that we wish to have on our container. + Hay dos maneras en que podemos crear una imagen docker. Podemos hacerlo un poco sobre la marcha con el proceso que empezamos ayer, elegimos nuestra imagen base, giramos ese contenedor e instalamos todo el software y las dependencias que deseamos tener en nuestro contenedor. - Then we can use the `docker commit container name` then we have a local copy of this image under docker images and in our docker desktop images tab. + Luego podemos usar el `docker commit container name` entonces tenemos una copia local de esta imagen bajo docker images y en nuestra pestaña docker desktop images. - Super simple, I would not recommend this method unless you want to understand the process, it is going to be very difficult to manage lifecycle management this way and a lot of manual configuration/reconfiguration. But it is the quickest and most simple way to build a docker image. Great for testing, troubleshooting, validating dependencies etc. + Con este método no entenderás el proceso y será muy difícil manejar la gestión del ciclo de vida, además de tener un montón de configuraciones manuales/reconfiguraciones. Pero se entiende que es la forma más rápida y sencilla de construir una imagen docker. Aunque no sea recomendable puede resultar ideal para pruebas, resolución de problemas, validación de dependencias, etc. -The way we intend to build our image is through a dockerfile. Which gives us a clean, compact and repeatable way to create our images. Much easier lifecycle management and easy integration into Continous Integration and Continuous delivery processes. But as you might gather it is a little more difficult than the first mentioned process. +La mejor práctica de construir imágenes es a través de un dockerfile. Lo que nos da una forma limpia, compacta y repetible para crear nuestras imágenes con unas pocas líneas. La gestión del ciclo de vida es mucho más fácil, así como la integración en procesos de CI/CD. Pero como se puede deducir, implica un aprendizaje. El saber no ocupa lugar. -Using the dockerfile method is much more in tune with real-world, enterprise-grade container deployments. +El uso del método dockerfile está mucho más en sintonía con el mundo real, los despliegues de contenedores de nivel empresarial. -A dockerfile is a three-step process whereby you create the dockerfile and add the commands you need to assemble the image. +Un dockerfile es un proceso de tres pasos mediante el cual se crea el dockerfile y se añaden los comandos necesarios para montar la imagen. -The following table shows some of the dockerfile statements we will be using or that you will most likely be using. +La siguiente tabla muestra algunas de las sentencias dockerfile que utilizaremos o que probablemente necesitarás. -| Command | Purpose | -| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -| FROM | To specify the parent image. | -| WORKDIR | To set the working directory for any commands that follow in the Dockerfile. | -| RUN | To install any applications and packages required for your container. | -| COPY | To copy over files or directories from a specific location. | -| ADD | As COPY, but also able to handle remote URLs and unpack compressed files. | -| ENTRYPOINT | Command that will always be executed when the container starts. If not specified, the default is /bin/sh -c | -| CMD | Arguments passed to the entrypoint. If ENTRYPOINT is not set (defaults to /bin/sh -c), the CMD will be the commands the container executes. | -| EXPOSE | To define which port through which to access your container application. | -| LABEL | To add metadata to the image. | +| Comando | Propósito | +| ---------- | --------------------------------------------------------------------------------------------------------------------------- | +| FROM | Para especificar la imagen base. | +| WORKDIR | Para establecer el directorio de trabajo para cualquier comando que siga en el Dockerfile. | +| RUN | Para instalar las aplicaciones y paquetes necesarios para su contenedor. | +| COPY | Para copiar archivos o directorios desde una ubicación específica. | +| ADD | Como COPY, pero también capaz de manejar URLs remotas y desempaquetar archivos comprimidos. | +| ENTRYPOINT | Comando que se ejecutará siempre cuando se inicie el contenedor. Si no se especifica, el valor por defecto es `/bin/sh -c` | +| CMD | Argumentos pasados al punto de entrada. Si no se establece ENTRYPOINT, el CMD serán los comandos que ejecute el contenedor. | +| EXPOSE | Para definir el puerto a través del cual acceder a su aplicación contenedora. | +| LABEL | Para añadir metadatos a la imagen. | -Now we have the detail on how to build our first dockerfile we can create a working directory and create our dockerfile. I have created a working directory within this repository where you can see the files and folders I have to walk through. [Containers](Containers) +Con estos detalles ya podemos crear un directorio de trabajo para construir el primer dockerfile. En este repositorio puedes encontrar el directorio de trabajo con los archivos y carpetas que veremos: [Containers](Containers) -In this directory, I am going to create a .dockerignore file similar to the .gitignore we used in the last section. This file will list any files that would otherwise be created during the Docker build process, which you want to exclude from the final build. +En este directorio tendré el archivo `.dockerignore` que es similar al `.gitignore`, ¿Lo recuerdas?. Este archivo enumerará todos los archivos que se desean excluir en el proceso de construcción de Docker, para evitarlos en la construcción final. -Remember everything about containers is about being compact, as fast as possible with no bloat. +Recuerda, en la creación de los contenedores es importante ser compacto, tan rápido como sea posible sin bloat (código hinchado). + +Así que haremos un Dockerfile muy simple con el siguiente diseño: -I want to create a very simple Dockerfile with the below layout also can be found in the folder linked above. ``` # Use the official Ubuntu 18.04 as base @@ -71,33 +72,33 @@ RUN apt-get install -y nginx curl RUN rm -rf /var/lib/apt/lists/* ``` -Navigate to this directory in your terminal, and then run `docker build -t 90daysofdevops:0.1 .` we are using the `-t` and then setting an image name and tag. +Es importante que le fichero se llame `Dockerfile` para que docker lo pueda reconocer. Cuando lo tengas ejecuta `docker build -t 90daysofdevops:0.1 .`. Fíjate que usamos el punto para que busque el Dockerfile en el directorio donde estamos ubicados. Con el anterior comando estamos usando la `-t` y luego estableciendo un nombre de imagen y una etiqueta. ![](Images/Day45_Containers3.png) -Now we have created our image we can then go and run our image using Docker Desktop or we could use the docker command line. I have used Docker Desktop I have fired up a container and you can see that we have `curl` available to us in the cli of the container. +Ahora que hemos creado nuestra imagen podemos ir y ejecutar nuestra imagen utilizando Docker Desktop o podríamos utilizar la línea de comandos docker. He utilizado Docker Desktop, he lanzado un contenedor y puedes ver que tenemos `curl` disponible para nosotros en el cli del contenedor. ![](Images/Day45_Containers4.png) -Whilst in Docker Desktop there is also the ability to leverage the UI to do some more tasks with this new image. +Mientras que en Docker Desktop también existe la posibilidad de aprovechar la interfaz de usuario para hacer algunas tareas más con esta nueva imagen. ![](Images/Day45_Containers5.png) -We can inspect our image, in doing so you see very much of the dockerfile and the lines of code that we wanted to run within our container. +Podemos inspeccionar nuestra imagen, al hacerlo se ve gran parte del dockerfile y las líneas de código que queríamos ejecutar dentro de nuestro contenedor. ![](Images/Day45_Containers6.png) -We have a pull option, now this would fail for us because this image is not hosted anywhere so we would get that as an error. However, we do have a Push to hub which would enable us to push our image to DockerHub. +Tenemos una opción pull, ahora esto fallaría porque la imagen no está alojada en ningún lugar por lo que obtendríamos un error. Sin embargo, tenemos una opción Push al hub que nos permitiría enviar nuestra imagen a nuestro registro DockerHub. -If you are using the same `docker build` we ran earlier then this would not work either, you would need the build command to be `docker build -t {{username}}/{{imagename}}:{{version}}` +Si estás usando el mismo `docker build` que ejecutamos antes, esto tampoco funcionaría, necesitarías que el comando de compilación fuera `docker build -t {{username}}/{{imagename}}:{{version}}`. ![](Images/Day45_Containers7.png) -Then if we go and take a look in our DockerHub repository you can see that we just pushed a new image. Now in Docker Desktop, we would be able to use that pull tab. +A continuación, si echamos un vistazo a nuestro repositorio DockerHub se puede ver que acabamos de subir una nueva imagen. Ahora en Docker Desktop, seríamos capaces de utilizar la pestaña pull. ![](Images/Day45_Containers8.png) -## Resources +## Recursos - [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) - [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) @@ -105,5 +106,10 @@ Then if we go and take a look in our DockerHub repository you can see that we ju - [WSL 2 with Docker getting started](https://www.youtube.com/watch?v=5RQbdMn04Oc) - [Blog on gettng started building a docker image](https://stackify.com/docker-build-a-beginners-guide-to-building-docker-images/) - [Docker documentation for building an image](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) +- [En español] En los [apuntes](https://vergaracarmona.es/apuntes/) del traductor: + - [Preparación de entorno de pruebas local para docker](https://vergaracarmona.es/preparacion-de-entorno-de-pruebas-local-para-docker/) + - [Uso básico de docker](https://vergaracarmona.es/uso-basico-de-docker/) + - [Una breve historia sobre contenedores](https://vergaracarmona.es/breve-historia-de-contenedores/) + - [Desplegar con docker-compose los servicios Traefik y Portainer](https://vergaracarmona.es/desplegar-con-docker-compose-los-servicios-traefik-y-portainer/) -See you on [Day 46](day46.md) +Nos vemos en el [Día 46](day46.md) diff --git a/2022/es/Days/day46.md b/2022/es/Days/day46.md index 983c023..fec60f9 100644 --- a/2022/es/Days/day46.md +++ b/2022/es/Days/day46.md @@ -1,42 +1,40 @@ ## Docker Compose -The ability to run one container could be great if you have a self-contained image that has everything you need for your single use case, where things get interesting is when you are looking to build multiple applications between different container images. For example, if I had a website front end but required a backend database I could put everything in one container but better and more efficient would be to have its container for the database. +La capacidad de ejecutar un contenedor puede ser muy grande si tienes una imagen auto-contenida que tiene todo lo que necesita para su caso de uso único. Donde las cosas se ponen interesantes es cuando estás buscando construir múltiples aplicaciones entre diferentes imágenes de contenedores. Por ejemplo, si tuvieras un sitio web front-end, pero requiere una base de datos back-end podría poner todo en un contenedor, aunque lo más eficiente es tener un contenedor propio para la base de datos. -This is where Docker compose comes in which is a tool that allows you to run more complex apps over multiple containers. With the benefit of being able to use a single file and command to spin up your application. The example I am going to the walkthrough in this post is from the [Docker QuickStart sample apps (Quickstart: Compose and WordPress)](https://docs.docker.com/samples/wordpress/). +Aquí es donde entra en juego Docker compose, una herramienta que permite ejecutar aplicaciones más complejas en varios contenedores. Con el beneficio de ser capaz de utilizar un único archivo y comando para hacer girar su aplicación. El ejemplo que voy a mostrar en este día es de [Docker QuickStart sample apps (Quickstart: Compose and WordPress)](https://docs.docker.com/samples/wordpress/). -In this first example we are going to: +Veremos cómo: -- Use Docker compose to bring up WordPress and a separate MySQL instance. -- Use a YAML file which will be called `docker-compose.yml` -- Build the project -- Configure WordPress via a Browser -- Shutdown and Clean up +- Usar Docker Compose para traer WordPress y una instancia separada de MySQL. +- Utilizar un archivo YAML que se llamará `docker-compose.yml`. +- Construir el proyecto +- Configurar WordPress a través de un navegador +- Apagar y limpiar -### Install Docker Compose +### Instalar Docker Compose -As mentioned Docker Compose is a tool, If you are on macOS or Windows then compose is included in your Docker Desktop installation. However, you might be wanting to run your containers on a Windows server host or Linux server and in which case you can install using these instructions [Install Docker Compose](https://docs.docker.com/compose/install/) +Como se ha mencionado Docker Compose es una herramienta, si estás en macOS o Windows entonces compose está incluido en tu instalación de Docker Desktop, así como en las últimas versiones de docker para linux. Sin embargo, es posible que desees ejecutar tus contenedores con una versión de docker más antigua, en cuyo caso puedes instalarlo siguiendo estas instrucciones [Install Docker Compose](https://docs.docker.com/compose/install/) -To confirm we have `docker-compose` installed on our system we can open a terminal and simply type the above command. +Para confirmar que tenemos `docker-compose` instalado en nuestro sistema podemos abrir un terminal y simplemente escribir el comando anterior. En la últimas versiones se está dejando de usar el guión medio: `docker compose`. ![](Images/Day46_Containers1.png) ### Docker-Compose.yml (YAML) -The next thing to talk about is the docker-compose.yml which you can find in the container folder of the repository. But more importantly, we need to discuss YAML, in general, a little. +Lo siguiente de lo que hablar es de como construir el fichero docker-compose.yml, pero realmente es más importante de que hablemos un poco de YAML, en general. -YAML could almost have its session as you are going to find it in so many different places. But for the most part +YAML casi podría tener su propio día en #90DaysOfDevOps, ya que lo vas a encontrar en muchos lugares diferentes. Pero en general "YAML es un lenguaje de serialización de datos amigable para todos los lenguajes de programación", al igual que JSON o TOML. -"YAML is a human-friendly data serialization language for all programming languages." +Se utiliza habitualmente para archivos de configuración y en algunas aplicaciones en las que se almacenan o transmiten datos. Sin duda te habrás encontrado con archivos XML que suelen ofrecer ese mismo archivo de configuración. YAML proporciona una sintaxis mínima pero está orientado a esos mismos casos de uso. -It is commonly used for configuration files and in some applications where data is being stored or transmitted. You have no doubt come across XML files that tend to offer that same configuration file. YAML provides a minimal syntax but is aimed at those same use cases. +YAML no es un lenguaje de marcas, como se ha mencionado es un lenguaje de serialización y ha ido ganando popularidad en los últimos años. Las capacidades de serialización de objetos lo convierten en un sustituto viable de lenguajes como JSON. -YAML Ain't Markup Language (YAML) is a serialisation language that has steadily increased in popularity over the last few years. The object serialisation abilities make it a viable replacement for languages like JSON. +El acrónimo YAML era la abreviatura de Yet Another Markup Language. Pero los mantenedores lo renombraron a YAML Ain't Markup Language para poner más énfasis en sus características orientadas a los datos. -The YAML acronym was shorthand for Yet Another Markup Language. But the maintainers renamed it to YAML Ain't Markup Language to place more emphasis on its data-oriented features. +De todos modos, volvamos al archivo docker-compose.yml. Este es un archivo de configuración de lo que queremos hacer cuando se trata de múltiples contenedores que se despliegan en nuestro único sistema. -Anyway, back to the docker-compose.yml file. This is a configuration file of what we want to do when it comes to multiple containers being deployed on our single system. - -Straight from the tutorial linked above you can see the contents of the file looks like this: +Directamente desde el tutorial vinculado anteriormente se puede ver el contenido del archivo se parece a esto: ``` version: "3.9" @@ -72,95 +70,93 @@ volumes: wordpress_data: {} ``` -We declare a version and then a large part of this docker-compose.yml file is made up of our services, we have a DB service and a WordPress service. You can see each of those has an image defined with a version tag associated. We are now also introducing state into our configuration unlike our first walkthroughs, but now we are going to create volumes so we can store our databases there. +Declaramos una versión y luego una gran parte de este archivo docker-compose.yml se compone de nuestros servicios, tenemos un servicio DB y un servicio de WordPress. Puedes ver que cada uno de ellos tiene una imagen definida con una etiqueta de versión asociada. Ahora también estamos introduciendo el estado en nuestra configuración a diferencia de nuestros primeros paseos, pero ahora vamos a crear volúmenes para que podamos almacenar nuestras bases de datos allí. -We then have some environmental variables such as passwords and usernames. These files can get very complicated but the YAML configuration file simplifies what these look like overall. +Luego tenemos algunas variables de entorno como contraseñas y nombres de usuario. Estos archivos pueden llegar a ser muy complicados, pero el archivo de configuración YAML simplifica su aspecto general. -### Build the project +### Construir el proyecto -Next up we can head back into our terminal and we can use some commands with our docker-compose tool. Navigate to your directory, where your docker-compose.yml file is located. +A continuación podemos volver a nuestro terminal y podemos utilizar algunos comandos con nuestra herramienta docker-compose. Asegurate de estar ubicado en el directorio donde se encuentra el archivo docker-compose.yml. -From the terminal, we can simply run `docker-compose up -d` this will start the process of pulling those images and standing up your multi-container application. +Desde el terminal, podemos simplemente ejecutar `docker-compose up -d` esto iniciará el proceso de extracción de las imágenes y la puesta en marcha de su aplicación multi-contenedor. -The `-d` in this command means detached mode, which means that the Run command is or will be in the background. +La `-d` en este comando significa modo separado, lo que significa que el comando Run estará en segundo plano. ![](Images/Day46_Containers2.png) -If we now run the `docker ps` command, you can see we have 2 containers running, one being WordPress and the other being MySQL. +Si ahora ejecutamos el comando `docker ps`, podemos ver que tenemos 2 contenedores ejecutándose, uno es WordPress y el otro es MySQL. ![](Images/Day46_Containers3.png) -Next, we can validate that we have WordPress up and running by opening a browser and going to `http://localhost:8000` and you should see the WordPress set-up page. +A continuación, podemos verificar que tenemos WordPress funcionando abriendo un navegador y yendo a `http://localhost:8000`. Deberías ver la página de configuración de WordPress. ![](Images/Day46_Containers4.png) -We can run through the setup of WordPress, and then we can start building our website as we see fit in the console below. +Podemos ejecutar la configuración de WordPress, y luego podemos empezar a construir nuestro sitio web como mejor nos parezca en la consola de abajo. ![](Images/Day46_Containers5.png) -If we then open a new tab and navigate to that same address we did before `http://localhost:8000` we will now see a simple default theme with our site title "90DaysOfDevOps" and then a sample post. +Si a continuación abrimos una nueva pestaña y navegamos a la misma dirección que antes `http://localhost:8000` veremos ahora un sencillo tema por defecto con el título de nuestro sitio "90DaysOfDevOps" y a continuación un post de ejemplo. ![](Images/Day46_Containers6.png) -Before we make any changes, open Docker Desktop and navigate to the volumes tab and here you will see two volumes associated with our containers, one for WordPress and one for DB. +Antes de hacer ningún cambio, abre Docker Desktop y navega hasta la pestaña de volúmenes y aquí verás dos volúmenes asociados a nuestros contenedores, uno para WordPress y otro para DB. ![](Images/Day46_Containers7.png) -My Current wordpress theme is "Twenty Twenty-Two" and I want to change this to "Twenty Twenty" Back in the dashboard we can make those changes. +Mi tema actual de wordpress es "Twenty Twenty-Two" y quiero cambiarlo por "Twenty Twenty". De vuelta en el dashboard podemos hacer esos cambios. ![](Images/Day46_Containers8.png) -I am also going to add a new post to my site, and here below you see the latest version of our new site. +También voy a añadir un nuevo post a mi sitio, y aquí abajo se ve la última versión de nuestro nuevo sitio. ![](Images/Day46_Containers9.png) -### Clean Up or not +### Limpiar o no limpiar -If we were now to use the command `docker-compose down` this would bring down our containers. But will leave our volumes in place. +Si ahora usáramos el comando `docker-compose down` esto bajaría nuestros contenedores. Pero dejará nuestros volúmenes en su sitio. ![](Images/Day46_Containers10.png) -We can just confirm in Docker Desktop that our volumes are still there though. +Podemos confirmar en Docker Desktop que nuestros volúmenes siguen ahí. ![](Images/Day46_Containers11.png) -If we then want to bring things back up then we can issue the `docker up -d` command from within the same directory and we have our application back up and running. +Si luego queremos volver a poner las cosas en marcha, podemos ejecutar el comando `docker up -d` desde el mismo directorio y ya tenemos nuestra aplicación de nuevo en marcha. ![](Images/Day46_Containers12.png) -We then navigate in our browser to that same address of `http://localhost:8000` and notice that our new post and our theme change are all still in place. +A continuación, navegamos en nuestro navegador a la misma dirección de `http://localhost:8000` y observamos que nuestro nuevo post y nuestro cambio de tema siguen en su lugar. ![](Images/Day46_Containers13.png) -If we want to get rid of the containers and those volumes then issuing the `docker-compose down --volumes` will also destroy the volumes. +Si queremos deshacernos de los contenedores y de esos volúmenes, al ejecutar `docker-compose down --volumes` también destruiremos los volúmenes. ![](Images/Day46_Containers14.png) -Now when we use `docker-compose up -d` again we will be starting, however, the images will still be local on our system so you won't need to re-pull them from the DockerHub repository. +Ahora cuando usemos `docker-compose up -d` de nuevo estaremos arrancando, sin embargo, las imágenes seguirán siendo locales en nuestro sistema por lo que no será necesario volver a extraerlas del repositorio de DockerHub. -I know that when I started diving into docker-compose and its capabilities I was then confused as to where this sits alongside or with Container Orchestration tools such as Kubernetes, well everything we have done here in this short demo is focused on one host we have WordPress and DB running on the local desktop machine. We don't have multiple virtual machines or multiple physical machines, we also can't easily scale up and down the requirements of our application. +Sé que cuando empecé a bucear en docker-compose y sus capacidades estaba confundido en cuanto las diferencias con otras herramientas de orquestación de contenedores como Kubernetes. Por ahora lo que hemos hecho en esta breve demostración se centra en un host que tenemos WordPress y DB se ejecuta en la máquina de escritorio local. No tenemos múltiples máquinas virtuales o múltiples máquinas físicas, tampoco podemos escalar fácilmente hacia arriba y hacia abajo los requisitos de nuestra aplicación. -Our next section is going to cover Kubernetes but we have a few more days of Containers in general first. +En la sección de Kubernetes despejaremos algunas dudas, por ahora tenemos algunos días más de Contenedores en general. -This is also a great resource for samples of docker-compose applications with multiple integrations. [Awesome-Compose](https://github.com/docker/awesome-compose) +Este es también un gran recurso para muestras de aplicaciones docker-compose con múltiples integraciones. [Awesome-Compose](https://github.com/docker/awesome-compose) -In the above repository, there is a great example which will deploy an Elasticsearch, Logstash, and Kibana (ELK) in single-node. - -I have uploaded the files to the [Containers folder](2022/Days/Containers/elasticsearch-logstash-kibana/) When you have this folder locally, navigate there and you can simply use `docker-compose up -d` +En el repositorio hay un gran ejemplo que desplegará un Elasticsearch, Logstash, y Kibana (ELK) en single-node. Podrás encontrar los ficheros en la carpeta [Containers](2022/Days/Containers/elasticsearch-logstash-kibana/). Si tienes esta carpeta en local, tan solo navega hasta allí y usa `docker-compose up -d`. ![](Images/Day46_Containers15.png) -We can then check we have those running containers with `docker ps` +Podrás comprobar que tenemos esos contenedores en ejecución con `docker ps`. Estos mantendrán el mismo entorno que en mi pc. ![](Images/Day46_Containers16.png) -Now we can open a browser for each of the containers: +Ahora podemos abrir un navegador para cada uno de los contenedores: ![](Images/Day46_Containers17.png) -To remove everything we can use the `docker-compose down` command. +Como en la anterior práctica, para eliminar todo podemos usar el comando `docker-compose down`. -## Resources +## Recursos - [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) - [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) @@ -169,5 +165,11 @@ To remove everything we can use the `docker-compose down` command. - [Blog on getting started building a docker image](https://stackify.com/docker-build-a-beginners-guide-to-building-docker-images/) - [Docker documentation for building an image](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) - [YAML Tutorial: Everything You Need to Get Started in Minute](https://www.cloudbees.com/blog/yaml-tutorial-everything-you-need-get-started) +- [En español] En los [apuntes](https://vergaracarmona.es/apuntes/) del traductor: + - [Preparación de entorno de pruebas local para docker](https://vergaracarmona.es/preparacion-de-entorno-de-pruebas-local-para-docker/) + - [Uso básico de docker](https://vergaracarmona.es/uso-basico-de-docker/) + - [Una breve historia sobre contenedores](https://vergaracarmona.es/breve-historia-de-contenedores/) + - [Desplegar con docker-compose los servicios Traefik y Portainer](https://vergaracarmona.es/desplegar-con-docker-compose-los-servicios-traefik-y-portainer/) + - [Comparando TOML, JSON y YAML](https://vergaracarmona.es/comparando-toml-json-y-yaml/) -See you on [Day 47](day47.md) +Nos vemos en el [Día 47](day47.md) diff --git a/2022/es/Days/day47.md b/2022/es/Days/day47.md index 70a4a8a..b35f545 100644 --- a/2022/es/Days/day47.md +++ b/2022/es/Days/day47.md @@ -1,92 +1,92 @@ ## Docker Networking & Security -During this container session so far we have made things happen but we have not looked at how things have worked behind the scenes either from a networking point of view also we have not touched on security, that is the plan for this session. +Hasta ahora hemos visto como desplegar contenedores, pero no sabemos aún cómo funcionan las redes y cuál es la seguridad mínima que necesitan. Cómo bien anuncia el título, este es el plan de hoy. ### Docker Networking Basics -Open a terminal, and type the command `docker network` this is the main command for configuring and managing container networks. +Vamos al grano, abre un terminal y escribe el comando `docker network`. Este es el comando principal para configurar y gestionar redes de los contenedores. -From the below, you can see this is how we can use the command, and all of the sub-commands available. We can create new networks, list existing ones, and inspect and remove networks. +Puedes ver como podemos usar el comando y todos los sub-comandos disponibles. Podemos crear nuevas redes, listar las existentes, inspeccionarlas y eliminarlas. ![](Images/Day47_Containers1.png) -Let's take a look at the existing networks we have since our installation, so the out-of-box Docker networking looks like using the `docker network list` command. +Vamos a echar un vistazo a las redes existentes que tenemos desde nuestra instalación usando el comando `docker network list`. -Each network gets a unique ID and NAME. Each network is also associated with a single driver. Notice that the "bridge" network and the "host" network have the same name as their respective drivers. +Cada red tiene un ID y un NOMBRE únicos. Cada red también está asociada a un único controlador. Observa que la red "bridge" y la red "host" tienen el mismo nombre que sus respectivos controladores. ![](Images/Day47_Containers2.png) -Next, we can take a deeper look into our networks with the `docker network inspect` command. +A continuación, podemos echar un vistazo más profundo a nuestras redes con el comando `docker network inspect`. -With me running `docker network inspect bridge` I can get all the configuration details of that specific network name. This includes name, ID, drivers, connected containers and as you can see quite a lot more. +Si ejecuto `docker network inspect bridge` puedo obtener todos los detalles de configuración de ese nombre de red específico. Esto incluye nombre, ID, controladores, contenedores conectados y mucho más como puedes ver. ![](Images/Day47_Containers3.png) ### Docker: Bridge Networking -As you have seen above a standard installation of Docker Desktop gives us a pre-built network called `bridge` If you look back up to the `docker network list` command, you will see that the network called bridge is associated with the `bridge` driver. Just because they have the same name doesn't they are the same thing. Connected but not the same thing. +Como has visto arriba una instalación estándar de Docker Desktop nos da una red pre-construida llamada `bridge` Si vuelves a mirar el comando `docker network list`, verás que la red llamada bridge está asociada con el driver `bridge`. Que tengan el mismo nombre no quiere decir que sean la misma cosa. Están conectadas pero no son lo mismo. -The output above also shows that the bridge network is scoped locally. This means that the network only exists on this Docker host. This is true of all networks using the bridge driver - the bridge driver provides single-host networking. +La salida anterior también muestra que la red bridge tiene un ámbito local. Esto significa que la red sólo existe en este host Docker. Esto es cierto para todas las redes que utilizan el controlador bridge que proporciona la red de un solo host. -All networks created with the bridge driver are based on a Linux bridge (a.k.a. a virtual switch). +Todas las redes creadas con el controlador bridge se basan en un bridge Linux (también conocido como conmutador virtual). -### Connect a Container +### Conectar un Contenedor -By default the bridge network is assigned to new containers, meaning unless you specify a network all containers will be connected to the bridge network. +Por defecto la red bridge es asignada a los nuevos contenedores, lo que significa que a menos que especifiques una red todos los contenedores serán conectados a la red bridge. -Let's create a new container with the command `docker run -dt ubuntu sleep infinity` +Vamos a crear un nuevo contenedor con el comando `docker run -dt ubuntu sleep infinity`. -The sleep command above is just going to keep the container running in the background so we can mess around with it. +El comando sleep de arriba sólo va a mantener el contenedor funcionando en segundo plano para que podamos trastear con él. ![](Images/Day47_Containers4.png) -If we then check our bridge network with `docker network inspect bridge` you will see that we have a container matching what we have just deployed because we did not specify a network. +Si a continuación comprobamos nuestra red bridge con `docker network inspect bridge` veremos que tenemos un contenedor que coincide con lo que acabamos de desplegar porque no hemos especificado ninguna red. ![](Images/Day47_Containers5.png) -We can also dive into the container using `docker exec -it 3a99af449ca2 bash` you will have to use `docker ps` to get your container ID. +También podemos bucear en el contenedor usando `docker exec -it 3a99af449ca2 bash`, tendrás que usar `docker ps` para obtener el ID del contenedor que has creado. -From here our image doesn't have anything to ping so we need to run the following command.`apt-get update && apt-get install -y iputils-ping` then ping an external interfacing address. `ping -c5 www.90daysofdevops.com` +En principio, nuestra imagen no tiene nada con lo que hacer ping, así que tenemos que ejecutar el siguiente comando: `apt-get update && apt-get install -y iputils-ping`. Luego vamos a hacer ping a una dirección de interfaz externa, a ver que pasa: `ping -c5 www.90daysofdevops.com` ![](Images/Day47_Containers6.png) -To clear this up we can run `docker stop 3a99af449ca2` again and use `docker ps` to find your container ID but this will remove our container. +Ahora podemos parar el contenedor con `docker stop 3a99af449ca2` y utilizar `docker ps` para buscar su ID de contenedor, veremops que esto eliminará nuestro contenedor. -### Configure NAT for external connectivity +### Configurar NAT para conectividad externa -In this step, we'll start a new NGINX container and map port 8080 on the Docker host to port 80 inside of the container. This means that traffic that hits the Docker host on port 8080 will be passed on to port 80 inside the container. +En este paso, iniciaremos un nuevo contenedor NGINX y asignaremos el puerto 8080 en el host Docker al puerto 80 dentro del contenedor. Esto significa que el tráfico que llega al host Docker en el puerto 8080 pasará al puerto 80 dentro del contenedor. -Start a new container based on the official NGINX image by running `docker run --name web1 -d -p 8080:80 nginx` +Inicie un nuevo contenedor basado en la imagen oficial de NGINX ejecutando `docker run --name web1 -d -p 8080:80 nginx`. ![](Images/Day47_Containers7.png) -Review the container status and port mappings by running `docker ps` +Revise el estado del contenedor y las asignaciones de puertos ejecutando `docker ps`. ![](Images/Day47_Containers8.png) -The top line shows the new web1 container running NGINX. Take note of the command the container is running as well as the port mapping - `0.0.0.0:8080->80/tcp` maps port 8080 on all host interfaces to port 80 inside the web1 container. This port mapping is what effectively makes the container's web service accessible from external sources (via the Docker hosts IP address on port 8080). +La línea superior muestra el nuevo contenedor web1 ejecutando NGINX. Fíjate en el output del contenedor en la asignación de puertos - `0.0.0.0:8080->80/tcp`. Asigna el puerto 8080 en todas las interfaces del host al puerto 80 dentro del contenedor web1. Esta asignación de puertos es lo que hace que el servicio web del contenedor sea accesible desde fuentes externas (a través de la dirección IP de los hosts Docker en el puerto 8080). -Now we need our IP address for our actual host, we can do this by going into our WSL terminal and using the `IP addr` command. +Ahora necesitamos nuestra dirección IP para nuestro host anfitrión, podemos hacer esto yendo a nuestro terminal WSL y utilizando el comando `ip addr`. ![](Images/Day47_Containers9.png) -Then we can take this IP and open a browser and head to `http://172.25.218.154:8080/` Your IP might be different. This confirms that NGINX is accessible. +Entonces podemos tomar esta IP y abrir un navegador y dirigirnos a `http://172.25.218.154:8080/` (Ten en cuenta que tiene que se tu IP, seguramente sea diferente). Esto confirma que NGINX es accesible. ![](Images/Day47_Containers10.png) -I have taken these instructions from this site from way back in 2017 DockerCon but they are still relevant today. However, the rest of the walkthrough goes into Docker Swarm and I am not going to be looking into that here. [Docker Networking - DockerCon 2017](https://github.com/docker/labs/tree/master/dockercon-us-2017/docker-networking) +Estas instrucciones se han sacado de "Docker Networking - DockerCon 2017". Aun siendo de la DockerCon 2017 sigue estando vigente a día de hoy. En ese tutorial siguen explicando otros conceptos de redes incluyyendo Docker Swarm, pero no lo veremos aquí. No obstante, aquí tenéis el enlace por si queréis echarle un vistazo: [Docker Networking - DockerCon 2017](https://github.com/docker/labs/tree/master/dockercon-us-2017/docker-networking) -### Securing your containers +### Asegurando tus contenedores -Containers provide a secure environment for your workloads vs a full server configuration. They offer the ability to break up your applications into much smaller, loosely coupled components each isolated from one another which helps reduce the attack surface overall. +Los contenedores proporcionan un entorno seguro para las cargas de trabajo frente a una configuración de servidor completa. Ofrecen la capacidad de dividir aplicaciones en componentes mucho más pequeños y poco acoplados, cada uno aislado del otro, lo que ayuda a reducir la superficie de ataque en general. -But they are not immune from hackers that are looking to exploit systems. We still need to understand the security pitfalls of the technology and maintain best practices. +Pero no son inmunes a los hackers que buscan explotar los sistemas. Todavía tenemos que entender las trampas de seguridad de la tecnología y mantener las mejores prácticas. -### Move away from root permission +### Alejarse del permiso de root -All of the containers we have deployed have been using the root permission to the process within your containers. This means they have full administrative access to your container and host environments. Now to walk through we knew these systems were not going to be up and running for long. But you saw how easy it was to get up and running. +Todos los contenedores que hemos desplegado han estado utilizando el permiso root al proceso dentro de sus contenedores. Esto significa que tienen pleno acceso administrativo a su contenedor y entornos de acogida. Ahora a recorrer sabíamos que estos sistemas no iban a estar en funcionamiento por mucho tiempo. Pero ya has visto lo fácil que es ponerlo en marcha. -We can add a few steps to our process to enable non-root users to be our preferred best practice. When creating our dockerfile we can create user accounts. You can find this example also in the containers folder in the repository. +Podemos añadir algunos pasos a nuestro proceso para permitir que los usuarios no root sean quienes administren el contenedor, siguiendo así una buena práctica de seguridad. Al crear nuestro dockerfile podemos crear cuentas de usuario. Puedes encontrar este ejemplo también en la carpeta [containers](containers) del repositorio. ``` # Use the official Ubuntu 18.04 as base @@ -96,27 +96,27 @@ RUN groupadd -g 1000 basicuser && useradd -r -u 1000 -g basicuser basicuser USER basicuser ``` -We can also use `docker run --user 1009 ubuntu` the Docker run command overrides any user specified in your Dockerfile. Therefore, in the following example, your container will always run with the least privilege—provided user identifier 1009 also has the lowest permission level. +También podemos usar `docker run --user 1009 ubuntu` el comando Docker run anula cualquier usuario especificado en tu Dockerfile. Por lo tanto, en el siguiente ejemplo, su contenedor siempre se ejecutará con el identificador de usuario 1009 con menos privilegios, con un nivel de permisos más bajo. -However, this method doesn’t address the underlying security flaw of the image itself. Therefore it’s better to specify a non-root user in your Dockerfile so your containers always run securely. +Sin embargo, este método no aborda el fallo de seguridad subyacente de la propia imagen. Por lo tanto, es mejor especificar un usuario no root en tu Dockerfile para que tus contenedores siempre se ejecuten de forma segura. -### Private Registry +### Registro Privado -Another area we have used heavily in public registries in DockerHub, with a private registry of container images set up by your organisation means that you can host where you wish or there are managed services for this as well, but all in all, this gives you complete control of the images available for you and your team. +Hasta ahora hemos utilizado registros públicos en DockerHub. Con un registro privado de imágenes de contenedores establecido por la organización podremos evitar problemas de curiosos. Se puede alojar la imágen donde desees, existen registros OpenSources y también administrados por terceros. Esto da un control completo de las imágenes disponibles para el equipo de trabajo. -DockerHub is great to give you a baseline, but it's only going to be providing you with a basic service where you have to put a lot of trust into the image publisher. +DockerHub está muy bien para darte una base, pero sólo te va a proporcionar un servicio básico en el que tienes que confiar mucho en el editor de imágenes. -### Lean & Clean +### Liviano y limpio -Have mentioned this throughout, although not related to security. But the size of your container can also affect security in terms of attack surface if you have resources you do not use in your application then you do not need them in your container. +He mencionado esto en todo momento sin relacionarlo con la seguridad. Pero el tamaño del contenedor puede afectar a la seguridad en términos de superficie de ataque. Si tienes recursos que no usas en tu aplicación entonces no los necesitas en tu contenedor, los puedes eliminar. -This is also my major concern with pulling the `latest` images because that can bring a lot of bloat to your images as well. DockerHub does show the compressed size for each of the images in a repository. +Esta es mi mayor preocupación con la extracción de las imágenes `latest` porque eso puede traer un montón de bloat (hinchazón) a sus imágenes. DockerHub muestra el tamaño comprimido para cada una de las imágenes en un repositorio. -Checking `docker image` is a great command to see the size of your images. +En definitiva, busca siempre de que tus imágenes sean lo más pequeñas posibles. `docker image` es el comando para comprobar el tamaño de las imágenes en local. ![](Images/Day47_Containers11.png) -## Resources +## Recursos - [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) - [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) @@ -125,5 +125,10 @@ Checking `docker image` is a great command to see the size of your images. - [Blog on getting started building a docker image](https://stackify.com/docker-build-a-beginners-guide-to-building-docker-images/) - [Docker documentation for building an image](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) - [YAML Tutorial: Everything You Need to Get Started in Minute](https://www.cloudbees.com/blog/yaml-tutorial-everything-you-need-get-started) +- [En español] En los [apuntes](https://vergaracarmona.es/apuntes/) del traductor: + - [Preparación de entorno de pruebas local para docker](https://vergaracarmona.es/preparacion-de-entorno-de-pruebas-local-para-docker/) + - [Uso básico de docker](https://vergaracarmona.es/uso-basico-de-docker/) + - [Una breve historia sobre contenedores](https://vergaracarmona.es/breve-historia-de-contenedores/) + - [Desplegar con docker-compose los servicios Traefik y Portainer](https://vergaracarmona.es/desplegar-con-docker-compose-los-servicios-traefik-y-portainer/) -See you on [Day 48](day48.md) +Nos vemos en el [Día 48](day48.md) diff --git a/2022/es/Days/day48.md b/2022/es/Days/day48.md index 1d8ed54..c8c2942 100644 --- a/2022/es/Days/day48.md +++ b/2022/es/Days/day48.md @@ -1,96 +1,94 @@ -## Alternatives to Docker +## Alternativas a Docker -I did say at the very beginning of this section that we were going to be using Docker, simply because resource wise there is so much and the community is very big, but also this was really where the indents to making containers popular came from. I would encourage you to go and watch some of the history around Docker and how it came to be, I found it very useful. +Dije al principio de esta sección que íbamos a usar Docker, simplemente porque tiene muchos recursos ya que la comunidad es muy grande, pero también porque fue de aquí de donde vinieron los impulsos para popularizar los contenedores. Te animo a que veas algo de la [historia de los contenedores](https://vergaracarmona.es/breve-historia-de-contenedores/), me pareció muy útil para entender todos los conceptos que trae. -But as I have alluded to there are other alternatives to Docker. If we think about what Docker is and what we have covered. It is a platform for developing, testing, deploying, and managing applications. +Pero como he aludido existen alternativas a Docker si pensamos en lo que es Docker y de qué se ocupa: una plataforma para desarrollar, probar, desplegar y gestionar aplicaciones. -I want to highlight a few alternatives to Docker that you might or will in the future see out in the wild. +Quiero destacar algunas alternativas a Docker que podrías ver o verás en el futuro. ### Podman -What is Podman? Podman is a daemon-less container engine for developing, managing, and running OCI Containers on your Linux System. Containers can either be run as root or in rootless mode. +¿Qué es Podman? [Podman](https://podman.io/) es un motor de contenedores sin demonio para desarrollar, gestionar y ejecutar contenedores OCI en tu sistema Linux. Los contenedores se pueden ejecutar como root o en modo rootless. -I am going to be looking at this from a Windows point of view but know that like Docker there is no requirement for virtualisation there as it will use the underlying OS which is cannot do in the Windows world. +Al igual que Docker no hay ningún requisito para la virtualización, pero utilizará el sistema operativo subyacente y por eso no se puede ejecutar en Windows a pelo. Se puede ejecutar bajo WSL2 pero no es tan visual como la experiencia con Docker Desktop, que está hecho para quienes usan el ratón. -Podman can be run under WSL2 although not as sleek as the experience with Docker Desktop. There is also a Windows remote client where you can connect to a Linux VM where your containers will run. - -My Ubuntu on WSL2 is the 20.04 release. Following the next steps will enable you to install Podman on your WSL instance. +También hay un cliente remoto de Windows donde se puede conectar a una máquina virtual Linux donde se ejecutarán los contenedores. Con el Ubuntu en WSL2 de la versión 20.04, siguiendo los siguientes pasos podrás instalar Podman en tu instancia WSL. ```Shell echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_20.04/ /" | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list ``` -Add the GPG Key +Para añadir la clave GPG: ```Shell curl -L "https://download.opensuse.org/repositories/devel:/kubic:\ /libcontainers:/stable/xUbuntu_20.04/Release.key" | sudo apt-key add - ``` -Run a system update and upgrade with the `sudo apt-get update && sudo apt-get upgrade` command. Finally, we can install podman using `sudo apt install podman` +Ejecute una actualización del sistema con `sudo apt-get update && sudo apt-get upgrade`. Por último, podemos instalar podman usando `sudo apt install podman`. Espero que os déis cuenta de la incomodidad que es usar un sistema operativo que no sea Linux para trabajar con contenedores. Suele pasar con la mayoría de aplicaciones de Sistemas o desarrollo. Así como hemos visto la optimización de los contenedores, deberéis tener en cuenta que el sistema operativo anfitrión también es importante. -We can now use a lot of the same commands we have been using for docker, note that we do not have that nice docker desktop UI. You can see below I used `podman images` and I have nothing after installation then I used `podman pull ubuntu` to pull down the ubuntu container image. +Ahora podemos utilizar muchos de los mismos comandos que hemos estado utilizando para docker. Como puedes ver a continuación, he utilizado `podman images` y no tengo nada después de la instalación. Luego, he utilizado `podman pull ubuntu` para bajar la imagen del contenedor ubuntu. ![](Images/Day48_Containers1.png) -We can then run our Ubuntu image using `podman run -dit ubuntu` and `podman ps` to see our running image. +Podemos ejecutar nuestra imagen de Ubuntu usando `podman run -dit ubuntu` y `podman ps` para ver nuestra imagen en ejecución. ![](Images/Day48_Containers2.png) -To then get into that container we can run `podman attach dazzling_darwin` your container name will most likely be different. +Para entrar en ese contenedor podemos ejecutar `podman attach dazzling_darwin` el nombre de tu contenedor seguramente será diferente. ![](Images/Day48_Containers3.png) -If you are moving from docker to podman it is also common to change your config file to have `alias docker=podman` that way any command you run with docker will use podman. +Si te estás moviendo de docker a podman también es común cambiar el archivo de configuración para tener `alias docker=podman` de esa manera cualquier comando que ejecute con docker utilizará podman. ### LXC -LXC is a containerisation engine that enables users again to create multiple isolated Linux container environments. Unlike Docker, LXC acts as a hypervisor for creating multiple Linux machines with separate system files, and networking features. Was around before Docker and then made a short comeback due to Docker's shortcomings. +LXC es un motor de contenedorización que permite a los usuarios crear múltiples entornos de contenedores Linux aislados. A diferencia de Docker, LXC actúa como un hipervisor para crear múltiples máquinas Linux con archivos de sistema separados, y características de red. Existió antes que Docker y volvió a aparecer debido a las deficiencias de Docker. -LXC is as lightweight though as docker and easily deployed. +Sin embargo, LXC es tan ligero como Docker y fácil de desplegar. ### Containerd -A standalone container runtime. Containerd brings simplicity and robustness as well as of course portability. Containerd was formerly a tool that runs as part of Docker container services until Docker decided to graduate its components into standalone components. +Un runtime de contenedor independiente. Containerd aporta simplicidad y robustez, así como, por supuesto, portabilidad. Containerd era antes una herramienta que se ejecutaba como parte de los servicios de contenedores Docker hasta que Docker decidió graduar sus componentes en componentes independientes. -A project in the Cloud Native Computing Foundation, placing it in the same class as popular container tools like Kubernetes, Prometheus, and CoreDNS. +Es un proyecto de la Cloud Native Computing Foundation, lo que lo sitúa en la misma clase que herramientas de contenedores populares como Kubernetes, Prometheus y CoreDNS. De hecho, a partir de la versión 1.11, Kubernetes utiliza containerd como su runtime de contenedor predeterminado mientras que antes era Docker. -### Other Docker tooling +### Otras herramientas Docker -We could also mention toolings and options around Rancher, and VirtualBox but we can cover them in more detail another time. +También podríamos mencionar herramientas y opciones alrededor de Rancher, y VirtualBox pero podemos cubrirlas en más detalle en otra ocasión. [**Gradle**](https://gradle.org/) -- Build scans allow teams to collaboratively debug their scripts and track the history of all builds. -- Execution options give teams the ability to continuously build so that whenever changes are inputted, the task is automatically executed. -- The custom repository layout gives teams the ability to treat any file directory structure as an artefact repository. +- Las exploraciones de construcción permiten a los equipos depurar sus scripts de forma colaborativa y realizar un seguimiento del historial de todas las construcciones. +- Las opciones de ejecución dan a los equipos la capacidad de construir continuamente de modo que cada vez que se introducen cambios, la tarea se ejecuta automáticamente. +- El diseño personalizado del repositorio ofrece a los equipos la posibilidad de tratar cualquier estructura de directorios de archivos como un repositorio de artefactos. [**Packer**](https://packer.io/) -- Ability to create multiple machine images in parallel to save developer time and increase efficiency. -- Teams can easily debug builds using Packer’s debugger, which inspects failures and allows teams to try out solutions before restarting builds. -- Support with many platforms via plugins so teams can customize their builds. +- Posibilidad de crear varias imágenes de máquina en paralelo para ahorrar tiempo a los desarrolladores y aumentar la eficacia. +- Los equipos pueden depurar fácilmente las compilaciones mediante el depurador de Packer, que inspecciona los fallos y permite a los equipos probar soluciones antes de reiniciar las compilaciones. +- Compatibilidad con muchas plataformas mediante plugins para que los equipos puedan personalizar sus compilaciones. [**Logspout**](https://github.com/gliderlabs/logspout) -- Logging tool - The tool’s customizability allows teams to ship the same logs to multiple destinations. -- Teams can easily manage their files because the tool only requires access to the Docker socket. -- Completely open-sourced and easy to deploy. +- Herramienta de registro: la capacidad de personalización de la herramienta permite a los equipos enviar los mismos registros a varios destinos. +- Los equipos pueden gestionar fácilmente sus archivos porque la herramienta sólo requiere acceso al socket Docker. +- Completamente de código abierto y fácil de desplegar. [**Logstash**](https://www.elastic.co/products/logstash) -- Customize your pipeline using Logstash’s pluggable framework. -- Easily parse and transform your data for analysis and to deliver business value. -- Logstash’s variety of outputs lets you route your data where you want. +- Personaliza tu pipeline utilizando el marco de trabajo pluggable de Logstash. +- Analice y transforme fácilmente sus datos para el análisis y para ofrecer valor empresarial. +- La variedad de salidas de Logstash le permite dirigir sus datos hacia donde desee. [**Portainer**](https://www.portainer.io/) -- Utilise pre-made templates or create your own to deploy applications. -- Create teams and assign roles and permissions to team members. -- Know what is running in each environment using the tool’s dashboard. +- Utilice plantillas prediseñadas o cree las suyas propias para desplegar aplicaciones. +- Cree equipos y asigne funciones y permisos a sus miembros. +- Sepa qué se está ejecutando en cada entorno mediante el panel de control de la herramienta. -## Resources +## Recursos - [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) - [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) @@ -101,5 +99,10 @@ We could also mention toolings and options around Rancher, and VirtualBox but we - [YAML Tutorial: Everything You Need to Get Started in Minute](https://www.cloudbees.com/blog/yaml-tutorial-everything-you-need-get-started) - [Podman | Daemonless Docker | Getting Started with Podman](https://www.youtube.com/watch?v=Za2BqzeZjBk) - [LXC - Guide to building an LXC Lab](https://www.youtube.com/watch?v=cqOtksmsxfg) +- [En español] En los [apuntes](https://vergaracarmona.es/apuntes/) del traductor: + - [Preparación de entorno de pruebas local para docker](https://vergaracarmona.es/preparacion-de-entorno-de-pruebas-local-para-docker/) + - [Uso básico de docker](https://vergaracarmona.es/uso-basico-de-docker/) + - [Una breve historia sobre contenedores](https://vergaracarmona.es/breve-historia-de-contenedores/) + - [Desplegar con docker-compose los servicios Traefik y Portainer](https://vergaracarmona.es/desplegar-con-docker-compose-los-servicios-traefik-y-portainer/) -See you on [Day 49](day49.md) +Nos vemos en el [Día 49](day49.md) diff --git a/2022/es/Days/day49.md b/2022/es/Days/day49.md index 87468bf..7637c55 100644 --- a/2022/es/Days/day49.md +++ b/2022/es/Days/day49.md @@ -1,224 +1,199 @@ -## The Big Picture: Kubernetes +## El panorama: Kubernetes -In the last section we covered Containers, Containers fall short when it comes to scale and orchestration alone. The best we can do is use docker-compose to bring up multiple containers together. When it comes to Kubernetes which is a Container Orchestrator, this gives us the ability to scale up and down in an automated way or based on a load of your applications and services. +En la última sección vimos los Contenedores. Los contenedores se quedan cortos cuando se trata de escalar y de orquestación, no pueden por sí solos. Lo mejor que podemos hacer es utilizar docker-compose para reunir varios contenedores. Cuando se trata de Kubernetes, que es un orquestador de contenedores, esto nos da la capacidad de escalar hacia arriba y hacia abajo de manera automatizada o basada en una carga de sus aplicaciones y servicios. -As a platform Kubernetes offers the ability to orchestrate containers according to your requirements and desired state. We are going to cover Kubernetes in this section as it is growing rapidly as the next wave of infrastructure. I would also suggest that from a DevOps perspective Kubernetes is just one platform that you will need to have a basic understanding of, you will also need to understand bare metal, virtualisation and most likely cloud-based services as well. Kubernetes is just another option to run our applications. +Como plataforma, Kubernetes ofrece la capacidad de orquestar contenedores de acuerdo a sus necesidades y el estado deseado. Vamos a cubrir Kubernetes en esta sección, ya que está creciendo rápidamente como la próxima ola de infraestructura. También me gustaría sugerir que, desde una perspectiva DevOps, Kubernetes es sólo una plataforma de las que tendrás que tener al menos un conocimiento básico. También tendrá que entender el bare metal, la virtualización y muy probablemente también los servicios basados en cloud. Kubernetes es sólo otra opción para ejecutar nuestras aplicaciones y se puede aplicar en estás dos mencionadas. -### What is Container Orchestration? +### ¿Qué es la orquestación de contenedores? -I have mentioned Kubernetes and I have mentioned Container Orchestration, Kubernetes is the technology whereas container orchestration is the concept or the process behind the technology. Kubernetes is not the only Container Orchestration platform we also have Docker Swarm, HashiCorp Nomad and others. But Kubernetes is going from strength to strength so I want to cover Kubernetes but wanted to say that it is not the only one out there. +He mencionado Kubernetes y he mencionado orquestación de contenedores, Kubernetes es la tecnología mientras que la orquestación de contenedores es el concepto o el proceso detrás de esta tecnología. Kubernetes no es la única plataforma de orquestación de contenedores, también tenemos las mencionadas anteriormente docker compose y Docker Swarm, o otras como HashiCorp Nomad. Pero Kubernetes va viento en popa, es la más utilizada, así que nos centraremos en ella. -### What is Kubernetes? +### ¿Qué es Kubernetes? -The first thing you should read if you are new to Kubernetes is the official documentation, My experience of really deep diving into Kubernetes a little over a year ago was that this is going to be a steep learning curve. Coming from a virtualisation and storage background I was thinking about how daunting this felt. +Lo primero que debes leer si eres nuevo en Kubernetes es la documentación oficial, es el mejor tutorial para aprender y además la van utilizando con más ejemplos o nuevas implementaciones. Mi experiencia de buceo realmente profundo en Kubernetes fue una curva de aprendizaje empinada. Viniendo de un fondo de virtualización y almacenamiento pensaba en lo desalentador que esto se sentía, pero el camino se hace al andar. -But the community, free learning resources and documentation are amazing. [Kubernetes.io](https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/) +La comunidad, los recursos de aprendizaje gratuitos y la documentación son increíbles, no dejes de empaparte en ella: [Kubernetes.io](https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/) -_Kubernetes is a portable, extensible, open-source platform for managing containerized workloads and services, that facilitates both declarative configuration and automation. It has a large, rapidly growing ecosystem. Kubernetes services, support, and tools are widely available._ +Ahora al pastel. Kubernetes es una plataforma portátil, extensible y de código abierto para gestionar cargas de trabajo y servicios en contenedores. Facilita tanto la configuración declarativa como la automatización. Cuenta con un ecosistema amplio y de rápido crecimiento. Los servicios, el soporte y las herramientas de Kubernetes están ampliamente disponibles. -Important things to note from the above quote, Kubernetes is Open-Source with a rich history that goes back to Google who donated the project to the Cloud Native Computing Foundation (CNCF) and it has now been progressed by the open-source community as well as large enterprise vendors contributing to making Kubernetes what it is today. +Cosas importantes a tener en cuenta de la cita anterior, Kubernetes es de código abierto con una rica historia que se remonta a cuando Google donó el proyecto a la Cloud Native Computing Foundation (CNCF). Ahora está siendo desarrollado por la comunidad de código abierto, así como grandes proveedores empresariales que contribuyen a hacer Kubernetes lo que es hoy. -I mentioned above that containers are great and in the previous section, we spoke about how containers and container images have changed and accelerated the adoption of cloud-native systems. But containers alone are not going to give you the production-ready experience you need from your application. Kubernetes gives us the following: +Antes he mencionado que los contenedores son geniales y, en la sección anterior, hemos hablado de cómo los contenedores y las imágenes de contenedores han cambiado y acelerado la adopción de sistemas nativos de la nube. Pero los contenedores por sí solos no van a darte la experiencia lista para producción que necesitas de tu aplicación. Kubernetes nos proporciona estas soluciones: -- **Service discovery and load balancing** Kubernetes can expose a container using the DNS name or using their IP address. If traffic to a container is high, Kubernetes can load balance and distribute the network traffic so that the deployment is stable. +- **Descubrimiento de servicios y equilibrio de carga** - Kubernetes puede exponer un contenedor utilizando el nombre DNS o su dirección IP. Si el tráfico a un contenedor es alto, Kubernetes puede equilibrar la carga y distribuir el tráfico de red para que el despliegue sea estable. +- **Orquestación de almacenamiento** - Kubernetes permite montar automáticamente un sistema de almacenamiento de su elección, como almacenamiento local, proveedores de nubes públicas, etc. +- **Rollouts y rollbacks automatizados** - Puedes describir el estado deseado para los contenedores desplegados utilizando Kubernetes, y puedes cambiar el estado actual al estado deseado a un ritmo controlado. Por ejemplo, puedes automatizar Kubernetes para crear nuevos contenedores para su despliegue, eliminar los contenedores existentes y adoptar todos sus recursos al nuevo contenedor. +- **Empaquetado automático de contenedores** - Proporcionas a Kubernetes un clúster de nodos que pueda utilizar para ejecutar tareas en contenedores, indicas cuánta CPU y memoria (RAM) necesitas para cada contenedor y Kubernetes puede acomodar los contenedores en sus nodos para hacer el mejor uso de los recursos. +- **Auto-reparación** - Kubernetes reinicia los contenedores que fallan, reemplaza los contenedores, mata los contenedores que no responden a su chequeo de salud definido por el usuario y no los anuncia a los clientes hasta que estén listos para servir. +- **Gestión de secretos y configuración** - Kubernetes permite almacenar y gestionar información confidencial, como contraseñas, tokens OAuth y claves SSH. Puede desplegar y actualizar secretos y la configuración de la aplicación sin reconstruir sus imágenes de contenedor, y sin exponer secretos en la configuración de su pila. -- **Storage orchestration** Kubernetes allows you to automatically mount a storage system of your choice, such as local storage, public cloud providers, and more. +Kubernetes proporciona un marco para ejecutar sistemas distribuidos de forma resiliente. -- **Automated rollouts and rollbacks** You can describe the desired state for your deployed containers using Kubernetes, and it can change the actual state to the desired state at a controlled rate. For example, you can automate Kubernetes to create new containers for your deployment, remove existing containers and adopt all their resources to the new container. +La orquestación de contenedores gestiona el despliegue, la colocación y el ciclo de vida de los contenedores. -- **Automatic bin packing** You provide Kubernetes with a cluster of nodes that it can use to run containerized tasks. You tell Kubernetes how much CPU and memory (RAM) each container needs. Kubernetes can fit containers onto your nodes to make the best use of your resources. +También tiene muchas otras responsabilidades: -- **Self-healing** Kubernetes restarts containers that fail, replaces containers, kills containers that don't respond to your user-defined health check, and doesn't advertise them to clients until they are ready to serve. +- La gestión de clústeres federa hosts en un objetivo. +- La gestión de la programación distribuye los contenedores entre los nodos a través del programador. +- El descubrimiento de servicios sabe dónde se encuentran los contenedores y distribuye las solicitudes de los clientes entre ellos. +- La replicación garantiza la disponibilidad del número adecuado de nodos y contenedores para la carga de trabajo solicitada. +- La gestión de la salud detecta y reemplaza los contenedores y nodos no saludables. -- **Secret and configuration management** Kubernetes lets you store and manage sensitive information, such as passwords, OAuth tokens, and SSH keys. You can deploy and update secrets and application configuration without rebuilding your container images, and without exposing secrets in your stack configuration. +### Principales componentes de Kubernetes -Kubernetes provides you with a framework to run distributed systems resiliently. +Kubernetes es un orquestador de contenedores para aprovisionar, gestionar y escalar aplicaciones. Puede utilizarlo para gestionar el ciclo de vida de aplicaciones en contenedores en un clúster de nodos, que es una colección de máquinas de trabajo como VMs o máquinas físicas. -Container Orchestration manages the deployment, placement, and lifecycle of containers. +Es posible que sus aplicaciones necesiten muchos otros recursos para ejecutarse, como volúmenes, redes y secretos que pueden ayudarle a conectarse a bases de datos, comunicarse con back-ends con firewalls y proteger claves. Con Kubernetes, puede añadir estos recursos a su aplicación. Los recursos de infraestructura que sus aplicaciones necesitan que se gestionen de forma declarativa. -It also has many other responsibilities: +El paradigma clave de Kubernetes es su modelo declarativo. Usted proporciona el estado que desea y Kubernetes lo hace posible. Si necesita cinco instancias, no inicie cinco instancias separadas por su cuenta. En su lugar, le dice a Kubernetes que necesita cinco instancias, y Kubernetes reconcilia automáticamente el estado. Si algo sale mal con una de sus instancias y falla, Kubernetes aún conoce el estado que usted desea y crea instancias en un nodo disponible. -- Cluster management federates hosts into one target. - -- Schedule management distributes containers across nodes through the scheduler. -- Service discovery knows where containers are located and distributes client requests across them. - -- Replication ensures that the right number of nodes and containers are available for the requested workload. - -- Health management detects and replaces unhealthy containers and nodes. - -### Main Kubernetes Components - -Kubernetes is a container orchestrator to provision, manage, and scale apps. You can use it to manage the lifecycle of containerized apps in a cluster of nodes, which is a collection of worker machines such as VMs or physical machines. - -Your apps might need many other resources to run, such as volumes, networks, and secrets that can help you connect to databases, talk to firewalled back ends, and secure keys. With Kubernetes, you can add those resources to your app. Infrastructure resources that your apps need are managed declaratively. - -The key paradigm of Kubernetes is its declarative model. You provide the state that you want and Kubernetes makes it happen. If you need five instances, you don't start five separate instances on your own. Instead, you tell Kubernetes that you need five instances, and Kubernetes automatically reconciles the state. If something goes wrong with one of your instances and it fails, Kubernetes still knows the state that you want and creates instances on an available node. - -### Node +### Nodo #### Control Plane -Every Kubernetes cluster requires a Control Plane node, the control plane's components make global decisions about the cluster (for example, scheduling), as well as detecting and responding to cluster events. +Cada clúster Kubernetes requiere un nodo de Control Plane, los componentes del Control Plane toman decisiones globales sobre el clúster, por ejemplo la programación, así como la detección y respuesta a los eventos del clúster. ![](Images/Day49_Kubernetes1.png) #### Worker Node -A worker machine that runs Kubernetes workloads. It can be a physical (bare metal) machine or a virtual machine (VM). Each node can host one or more pods. Kubernetes nodes are managed by a control plane +Un Worker machine que ejecuta cargas de trabajo Kubernetes. Puede ser una máquina física (bare metal) o una máquina virtual (VM). Cada nodo puede alojar uno o más pods. Los nodos Kubernetes son gestionados por un plano de control. ![](Images/Day49_Kubernetes2.png) -There are other node types but I won't be covering them here. +Existen otros tipos de nodos pero no los trataré aquí. #### kubelet -An agent that runs on each node in the cluster. It makes sure that containers are running in a Pod. +Un agente que se ejecuta en cada nodo del clúster. Se asegura de que los contenedores se ejecutan en un Pod. -The kubelet takes a set of PodSpecs that are provided through various mechanisms and ensures that the containers described in those PodSpecs are running and healthy. The kubelet doesn't manage containers which were not created by Kubernetes. +El kubelet toma un conjunto de PodSpecs que se proporcionan a través de diversos mecanismos y se asegura de que los contenedores descritos en los PodSpecs se están ejecutando y en buen estado. El kubelet no gestiona contenedores que no hayan sido creados por Kubernetes. ![](Images/Day49_Kubernetes3.png) #### kube-proxy -kube-proxy is a network proxy that runs on each node in your cluster, implementing part of the Kubernetes Service concept. +kube-proxy es un proxy de red que se ejecuta en cada nodo de su clúster, implementando parte del concepto de Servicio Kubernetes. -kube-proxy maintains network rules on nodes. These network rules allow network communication to your Pods from network sessions inside or outside of your cluster. +kube-proxy mantiene reglas de red en los nodos. Estas reglas de red permiten la comunicación de red a sus Pods desde sesiones de red dentro o fuera de su cluster. -kube-proxy uses the operating system packet filtering layer if there is one and it's available. Otherwise, kube-proxy forwards the traffic itself. +kube-proxy utiliza la capa de filtrado de paquetes del sistema operativo si existe y está disponible. De lo contrario, kube-proxy reenvía el tráfico por sí mismo. ![](Images/Day49_Kubernetes4.png) #### Container runtime -The container runtime is the software that is responsible for running containers. +El container runtime es el software responsable de ejecutar los contenedores. -Kubernetes supports several container runtimes: Docker, containerd, CRI-O, and any implementation of the Kubernetes CRI (Container Runtime Interface). +Kubernetes soporta varios container runtime: Docker, containerd, CRI-O, y cualquier implementación del CRI (Container Runtime Interface) de Kubernetes. ![](Images/Day49_Kubernetes5.png) ### Cluster -A cluster is a group of nodes, where a node can be a physical machine or a virtual machine. Each of the nodes will have the container runtime (Docker) and will also be running a kubelet service, which is an agent that takes in the commands from the Master controller (more on that later) and a Proxy, that is used to proxy connections to the Pods from another component (Services, that we will see later). +Un cluster es un grupo de nodos, donde un nodo puede ser una máquina física o una máquina virtual. Cada uno de los nodos tendrá el tiempo de ejecución del contenedor (Docker) y también estará ejecutando un servicio kubelet, que es un agente que recibe los comandos del controlador Maestro (veremos más sobre esto más adelante) y un Proxy, que se utiliza para proxy conexiones a los Pods de otro componente (Servicios, que veremos más adelante). -Our control plane which can be made highly available will contain some unique roles compared to the worker nodes, the most important will be the kube API server, this is where any communication will take place to get information or push information to our Kubernetes cluster. +Nuestro control plane, que se puede hacer altamente disponible, contendrá algunos roles únicos en comparación con los nodos Workers, el más importante será el servidor API kube, aquí es donde cualquier comunicación se llevará a cabo para obtener información o enviar información a nuestro clúster Kubernetes. -#### Kube API-Server +#### Servidor API Kube -The Kubernetes API server validates and configures data for the API objects which include pods, services, replication controllers, and others. The API Server services REST operations and provide the frontend to the cluster's shared state through which all other components interact. +El servidor API de Kubernetes valida y configura los datos para los objetos API que incluyen pods, servicios, controladores de replicación y otros. El servidor API da servicio a las operaciones REST y proporciona el frontend al estado compartido del cluster a través del cual interactúan el resto de componentes. -#### Scheduler +#### Planificador (Scheduler) -The Kubernetes scheduler is a control plane process which assigns Pods to Nodes. The scheduler determines which Nodes are valid placements for each Pod in the scheduling queue according to constraints and available resources. The scheduler then ranks each valid Node and binds the Pod to a suitable Node. +El programador de Kubernetes es un proceso del control plane que asigna Pods a Nodos. El programador determina qué Nodos son válidos para cada Pod en la cola de programación de acuerdo con las restricciones y los recursos disponibles. A continuación, el planificador clasifica cada Nodo válido y vincula el Pod a un Nodo adecuado. -#### Controller Manager +#### Gestor de Controladores -The Kubernetes controller manager is a daemon that embeds the core control loops shipped with Kubernetes. In applications of robotics and automation, a control loop is a non-terminating loop that regulates the state of the system. In Kubernetes, a controller is a control loop that watches the shared state of the cluster through the apiserver and makes changes attempting to move the current state towards the desired state. +El gestor de controladores de Kubernetes es un demonio que incorpora los bucles de control centrales incluidos en Kubernetes. En aplicaciones de robótica y automatización, un bucle de control es un bucle no terminal que regula el estado del sistema. En Kubernetes, un controlador es un bucle de control que observa el estado compartido del cluster a través del apiserver y realiza cambios intentando mover el estado actual hacia el estado deseado. #### etcd -Consistent and highly-available key value store used as Kubernetes' backing store for all cluster data. +Almacén de valores clave consistente y de alta disponibilidad utilizado como almacén de respaldo de Kubernetes para todos los datos del clúster. ![](Images/Day49_Kubernetes6.png) #### kubectl -To manage this from a CLI point of view we have kubectl, kubectl interacts with the API server. +Para gestionar esto desde un punto de vista CLI tenemos kubectl, kubectl interactúa con el servidor API. -The Kubernetes command-line tool, kubectl, allows you to run commands against Kubernetes clusters. You can use kubectl to deploy applications, inspect and manage cluster resources, and view logs. +La herramienta de línea de comandos de Kubernetes, kubectl, le permite ejecutar comandos contra clústeres Kubernetes. Puede utilizar kubectl para desplegar aplicaciones, inspeccionar y gestionar recursos de clúster y ver registros. ![](Images/Day49_Kubernetes7.png) ### Pods -A Pod is a group of containers that form a logical application. E.g. If you have a web application that is running a NodeJS container and also a MySQL container, then both these containers will be located in a single Pod. A Pod can also share common data volumes and they also share the same networking namespace. Remember that Pods are ephemeral and they could be brought up and down by the Master Controller. Kubernetes uses a simple but effective means to identify the Pods via the concepts of Labels (name – values). +Un Pod es un grupo de contenedores que forman una aplicación lógica. Por ejemplo, si tienes una aplicación web que está ejecutando un contenedor NodeJS y también un contenedor MySQL, entonces ambos contenedores pueden estar ubicados en un único Pod, aunque no es lo aconsejable. Un Pod también puede compartir volúmenes de datos comunes y también comparten el mismo espacio de nombres de red. Recuerda que los Pods son efímeros y pueden ser subidos y bajados por el Controlador Maestro. Kubernetes utiliza un medio simple pero eficaz para identificar los Pods a través de los conceptos de Labels (nombre - valor). -- Pods handle Volumes, Secrets, and configuration for containers. - -- Pods are ephemeral. They are intended to be restarted automatically when they die. - -- Pods are replicated when the app is scaled horizontally by the ReplicationSet. Each Pod will run the same container code. - -- Pods live on Worker Nodes. +Algunas características importantes de los Pods: +- Los Pods son la unidad más pequeña de Kubernetes. +- Los Pods manejan Volúmenes, Secretos y configuración para los contenedores. +- Los Pods son efímeros. Están pensados para reiniciarse automáticamente cuando mueren. +- Los Pods se replican cuando la aplicación se escala horizontalmente mediante el ReplicationSet. Cada Pod ejecutará el mismo código de contenedor. +- Los Pods viven en Nodos Workers. +- Los Pods pueden comunicarse entre sí usando localhost. ![](Images/Day49_Kubernetes8.png) ### Deployments -- You can just decide to run Pods but when they die they die. +Puedes decidir ejecutar Pods pero cuando mueren, mueren. Los Deployments son una forma de ejecutar Pods de forma continua. Los Deployments también le permiten actualizar una aplicación en ejecución sin tiempo de inactividad. -- A Deployment will enable your pod to run continuously. - -- Deployments allow you to update a running app without downtime. - -- Deployments also specify a strategy to restart Pods when they die +- Un Deployment permitirá que tu pod se ejecute continuamente. +- Los Deployments le permiten actualizar una aplicación en ejecución sin tiempo de inactividad. +- Los Deployments también especifican una estrategia para reiniciar Pods cuando mueren. +- Los Deployments son la forma recomendada de administrar Pods en producción. +- Los Deployments son una abstracción de alto nivel que maneja la creación de Pods y ReplicaSets. +- Los Deployments son declarativos, como todo en Kubernetes, esto significa que describe el estado deseado en su clúster y Kubernetes se encarga de cambiar el estado real para que coincida con el estado deseado. ![](Images/Day49_Kubernetes9.png) ### ReplicaSets -- The Deployment can also create the ReplicaSet +Como se ha comentado, el Deployment también puede crear el ReplicaSet. Un ReplicaSet es un objeto que define un conjunto de Pods idénticos. Un ReplicaSet garantiza que un número especificado de réplicas de un Pod se estén ejecutando en todo momento. Si hay demasiados Pods, el ReplicaSet eliminará los Pods adicionales. Si hay muy pocos Pods, el ReplicaSet creará más. Los ReplicaSets son la forma recomendada de administrar Pods en producción. -- A ReplicaSet ensures your app has the desired number of Pods - -- ReplicaSets will create and scale Pods based on the Deployment - -- Deployments, ReplicaSets, and Pods are not exclusive but can be +- Un ReplicaSet asegura que su aplicación tiene el número deseado de Pods +- Los ReplicaSets crearán y escalarán Pods basándose en el Deployment +- Los Deployments, ReplicaSets y Pods no son excluyentes, pero pueden ser ### StatefulSets -- Does your App require you to keep information about its state? +¿Necesita tu App mantener información sobre su estado? Por ejemplo, una base de datos necesita estado. Los StatefulSets son la forma de ejecutar aplicaciones que necesitan mantener un estado. Los StatefulSets son similares a los Deployments, pero tienen algunas diferencias importantes: -- A database needs state - -- A StatefulSet’s Pods are not interchangeable. - -- Each pod has a unique, persistent identifier that the controller maintains over any rescheduling. +- Los Pods de un StatefulSet no son intercambiables. +- Cada pod tiene un identificador único y persistente que el controlador mantiene por encima de cualquier reprogramación. +- Los Pods de un StatefulSet se crean en orden secuencial, uno a la vez. +- Los Pods de un StatefulSet tienen un nombre DNS estable y predecible. Mantienen el mismo nombre a través de las reprogramaciones. +- Los volúmenes pueden ser persistentes. ![](Images/Day49_Kubernetes10.png) ### DaemonSets -- DaemonSets are for continuous process - -- They run one Pod per Node. - -- Each new node added to the cluster gets a pod started - -- Useful for background tasks such as monitoring and log collection - -- Each pod has a unique, persistent identifier that the controller maintains over any rescheduling. +- Los DaemonSets son para procesos continuos que se ejecutan en todos los nodos. Un Pod por Nodo. +- Cada nuevo nodo añadido al cluster hace que se inicie un pod. +- Útiles para tareas en segundo plano como monitorización y recogida de logs. +- Cada pod tiene un identificador único y persistente que el controlador mantiene por encima de cualquier reprogramación. ![](Images/Day49_Kubernetes11.png) -### Services +### Servicios -- A single endpoint to access Pods +Características de los Servicios: +- Un único punto final para acceder a los Pods +- Una forma unificada de dirigir el tráfico a un cluster y eventualmente a una lista de Pods. +- Usando un Servicio, los Pods pueden ser subidos y bajados sin afectar a nada. +- Los Servicios pueden ser expuestos interna o externamente. También pueden ser expuestos en diferentes puertos. -- a unified way to route traffic to a cluster and eventually to a list of Pods. - -- By using a Service, Pods can be brought up and down without affecting anything. - -This is just a quick overview and notes around the fundamental building blocks of Kubernetes, we can take this knowledge and add in some other areas around Storage and Ingress to enhance our applications but we then also have a lot of choices on where our Kubernetes cluster runs. The next session will focus on those options on where can I run a Kubernetes cluster, whilst also exploring some specifics around Storage. +Esto es sólo una visión general rápida y notas sobre los bloques de construcción fundamentales de Kubernetes, podemos tomar este conocimiento y añadir en algunas otras áreas alrededor de almacenamiento y de entrada para mejorar nuestras aplicaciones, pero entonces también tenemos un montón de opciones sobre dónde se ejecuta nuestro clúster Kubernetes. La siguiente sesión se centrará en esas opciones sobre dónde se puede ejecutar un clúster Kubernetes, mientras que también exploraremos algunos detalles sobre el almacenamiento. ![](Images/Day49_Kubernetes12.png) -### What we will cover in the series on Kubernetes - -- Kubernetes Architecture -- Kubectl Commands -- Kubernetes YAML -- Kubernetes Ingress -- Kubernetes Services -- Helm Package Manager -- Persistent Storage -- Stateful Apps - -## Resources +## Recursos - [Kubernetes Documentation](https://kubernetes.io/docs/home/) - [TechWorld with Nana - Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]](https://www.youtube.com/watch?v=X48VuDVv0do) - [TechWorld with Nana - Kubernetes Crash Course for Absolute Beginners](https://www.youtube.com/watch?v=s_o8dwzRlu4) - [Kunal Kushwaha - Kubernetes Tutorial for Beginners | What is Kubernetes? Architecture Simplified!](https://www.youtube.com/watch?v=KVBON1lA9N8) -See you on [Day 50](day50.md) +Nos vemos en el [Día 50](day50.md) diff --git a/2022/es/Days/day50.md b/2022/es/Days/day50.md index c8a6a9f..5b1a942 100644 --- a/2022/es/Days/day50.md +++ b/2022/es/Days/day50.md @@ -1,42 +1,46 @@ -## Choosing your Kubernetes platform +## Elegir tu plataforma Kubernetes -I wanted to use this session to break down some of the platforms or maybe distributions is a better term to use here, one thing that has been a challenge in the Kubernetes world is removing complexity. +En esta sesión se va a desglosar algunas de las plataformas o tal vez distribuciones es un mejor término a utilizar aquí. Una cosa que ha sido un reto en el mundo Kubernetes es eliminar la complejidad. -Kubernetes the hard way walks through how to build out from nothing to a full-blown functional Kubernetes cluster this is to the extreme but more and more at least the people I am speaking to are wanting to remove that complexity and run a managed Kubernetes cluster. The issue there is that it costs more money but the benefits could be if you use a managed service do you need to know the underpinning node architecture and what is happening from a Control Plane node point of view when generally you do not have access to this. +Kubernetes the hard way (el camino difícil) explica cómo construir desde la nada un clúster Kubernetes completamente funcional. Esto es extremo, pero cada vez más, al menos las personas con las que hablo, quieren eliminar esa complejidad y ejecutar un clúster Kubernetes gestionado. El problema es que cuesta más dinero, pero las ventajas podrían ser que, si se utiliza un servicio gestionado, es necesario conocer la arquitectura de los nodos y lo que ocurre desde el punto de vista del control plane, algo a lo que generalmente no se tiene acceso. -Then we have the local development distributions that enable us to use our systems and run a local version of Kubernetes so developers can have the full working environment to run their apps in the platform they are intended for. +Luego tenemos las distribuciones de desarrollo local que nos permiten utilizar nuestros sistemas y ejecutar una versión local de Kubernetes para que los desarrolladores puedan tener el entorno de trabajo completo para ejecutar sus aplicaciones en la plataforma para la que están destinadas. -The general basis of all of these concepts is that they are all a flavour of Kubernetes which means we should be able to freely migrate and move our workloads where we need them to suit our requirements. +La base general de todos estos conceptos es que todos son una variante de Kubernetes, lo que significa que deberíamos poder migrar y mover libremente nuestras cargas de trabajo donde las necesitemos para adaptarlas a nuestras necesidades. -A lot of our choice will also depend on what investments have been made. I mentioned the developer experience as well but some of those local Kubernetes environments that run our laptops are great for getting to grips with the technology without spending any money. +Gran parte de nuestra elección dependerá también de las inversiones realizadas. También he mencionado la experiencia de los desarrolladores, pero algunos de esos entornos locales de Kubernetes que ejecutan nuestros portátiles son estupendos para familiarizarse con la tecnología sin gastar dinero. -### Bare-Metal Clusters +### Clusters Bare-Metal -An option for many could be running your Linux OS straight onto several physical servers to create our cluster, it could also be Windows but I have not heard much about the adoption rate around Windows, Containers and Kubernetes. If you are a business and you have made a CAPEX decision to buy your physical servers then this might be how you go when building out your Kubernetes cluster, the management and admin side here means you are going to have to build yourself and manage everything from the ground up. +Una opción para muchos podría ser ejecutar su sistema operativo Linux directamente en varios servidores físicos para crear nuestro clúster, también podría ser Windows pero no he oído hablar mucho de la tasa de adopción en entornos Windows, puede ser anecdótica. -### Virtualisation +Si en tu empresa se ha tomado la decisión de CAPEX para comprar sus servidores físicos, entonces esto podría ser una forma en la que construir la arquitectura, un clúster Kubernetes. La gestión y administración de lado significa que la vas a tener que construir tu mismo y gestionarlo todo desde el principio. -Regardless of test and learning environments or enterprise-ready Kubernetes clusters virtualisation is a great way to go, typically the ability to spin up virtual machines to act as your nodes and then cluster those together. You have the underpinning architecture, efficiency and speed of virtualisation as well as leveraging that existing spend. VMware for example offers a great solution for both Virtual Machines and Kubernetes in various flavours. +### Virtualización -My first ever Kubernetes cluster was built based on Virtualisation using Microsoft Hyper-V on an old server that I had which was capable of running a few VMs as my nodes. +Independientemente de si se trata de entornos de prueba y aprendizaje o de clústeres Kubernetes listos para la funcionar, la virtualización es una gran opción, ya que permite crear máquinas virtuales que actúan como nodos y, a continuación, agruparlos en clústeres. Dispones de la arquitectura de apoyo, la eficiencia y la velocidad de la virtualización, además de aprovechar el gasto existente. VMware, por ejemplo, ofrece una gran solución tanto para máquinas virtuales como para Kubernetes en varias versiones. -### Local Desktop options +Mi primer clúster Kubernetes se construyó sobre la base de la virtualización utilizando Microsoft Hyper-V en un servidor antiguo que tenía que era capaz de ejecutar algunas máquinas virtuales como mis nodos. Esto me permitió construir un clúster Kubernetes y empezar a jugar con él. -There are several options when it comes to running a local Kubernetes cluster on your desktop or laptop. This as previously said gives developers the ability to see what their app will look like without having to have multiple costly or complex clusters. Personally, this has been one that I have used a lot and in particular, I have been using minikube. It has some great functionality and adds-ons which changes the way you get something up and running. +### Opciones de escritorio local -### Kubernetes Managed Services +Hay varias opciones cuando se trata de ejecutar un clúster local de Kubernetes en su ordenador de sobremesa o portátil. Esto, como se dijo anteriormente, ofrece a los desarrolladores la posibilidad de ver cómo se verá su aplicación sin tener que tener múltiples clústeres costosos o complejos. Personalmente, he utilizado mucho minikube. Tiene una gran funcionalidad y complementos que cambian la forma de poner algo en marcha. -I have mentioned virtualisation, and this can be achieved with hypervisors locally but we know from previous sections we could also leverage VMs in the public cloud to act as our nodes. What I am talking about here with Kubernetes managed services are the offerings we see from the large hyperscalers but also from MSPs removing layers of management and control away from the end user, this could be removing the control plane from the end user this is what happens with Amazon EKS, Microsoft AKS and Google Kubernetes Engine. (GKE) +### Servicios gestionados Kubernetes -### Overwhelming choice +He mencionado la virtualización, y esto se puede lograr con hipervisores a nivel local, pero sabemos por secciones anteriores que también podríamos aprovechar las máquinas virtuales en la nube pública para actuar como nuestros nodos. De lo que estoy hablando aquí con los servicios gestionados Kubernetes son las ofertas que vemos de los grandes hiperescaladores, pero también de los MSP eliminando capas de gestión y control lejos del usuario final, esto podría ser eliminar el plano de control del usuario final, esto es lo que sucede con Amazon EKS, Microsoft AKS y Google Kubernetes Engine. (GKE) -I mean the choice is great but there is a point where things become overwhelming and this is not a depth look into all options within each category listed above. On top of the above, we also have OpenShift which is from Red Hat and this option can be run across the options above in all the major cloud providers and probably today gives the best overall useability to the admins regardless of where clusters are deployed. +### Elección abrumadora -So where do you start from your learning perspective, as I said I started with the virtualisation route but that was because I had access to a physical server which I could use for the purpose, I appreciate and in fact, since then I no longer have this option. +Quiero decir que la elección es grande, pero hay un punto en el que las cosas se vuelven abrumadoras y esto no es una mirada en profundidad a todas las opciones dentro de cada categoría enumerada anteriormente. -My actual advice now would be to use Minikube as a first option or Kind (Kubernetes in Docker) but Minikube gives us some additional benefits which almost abstracts the complexity out as we can just use add-ons and get things built out quickly and we can then blow it away when we are finished, we can run multiple clusters, we can run it almost anywhere, cross-platform and hardware agnostic. +No podemos olvidar que además de lo anterior también tenemos OpenShift que es de Red Hat. Esta opción se puede ejecutar a través de las opciones anteriores en todos los principales proveedores de nube y, probablemente, hoy en día ofrece la mejor facilidad de uso general para los administradores, independientemente de donde se despliegan los clusters. -I have been through a bit of a journey with my learning around Kubernetes so I am going to leave the platform choice and specifics here to list out the options that I have tried to give me a better understanding of Kubernetes the platform and where it can run. What I might do with the below blog posts is take another look at these update them and bring them more into here vs them being linked to blog posts. +Por lo tanto, ¿por dónde empezar desde la perspectiva del aprendizaje? Como he dicho yo empecé por la ruta de la virtualización, pero eso fue porque tenía acceso a un servidor físico que podía utilizar para este fin, lo agradezco muchísimo. + +Mi consejo actual sería utilizar Minikube como primera opción o Kind (Kubernetes en Docker), pero Minikube nos da algunos beneficios adicionales que casi abstrae la complejidad, ya que sólo podemos utilizar complementos y hacer las cosas rápidamente y luego podemos volarlo cuando hayamos terminado, podemos ejecutar múltiples clusters, podemos ejecutarlo casi en cualquier lugar, multiplataforma y agnóstico de hardware. + +He estado a través de un poco de un viaje con mi aprendizaje en torno a Kubernetes así que voy a dejar la elección de la plataforma y los detalles aquí para enumerar las opciones que he probado para darme una mejor comprensión de Kubernetes la plataforma y donde se puede ejecutar. Lo que podría hacer con las siguientes entradas de blog es echar otro vistazo a estos actualizarlos y traerlos más aquí frente a ellos están vinculados a las entradas del blog. - [Kubernetes playground – How to choose your platform](https://vzilla.co.uk/vzilla-blog/building-the-home-lab-kubernetes-playground-part-1) - [Kubernetes playground – Setting up your cluster](https://vzilla.co.uk/vzilla-blog/building-the-home-lab-kubernetes-playground-part-2) @@ -48,22 +52,11 @@ I have been through a bit of a journey with my learning around Kubernetes so I a - [Getting started with CIVO Cloud](https://vzilla.co.uk/vzilla-blog/getting-started-with-civo-cloud) - [Minikube - Kubernetes Demo Environment For Everyone](https://vzilla.co.uk/vzilla-blog/project_pace-kasten-k10-demo-environment-for-everyone) -### What we will cover in the series on Kubernetes - -- Kubernetes Architecture -- Kubectl Commands -- Kubernetes YAML -- Kubernetes Ingress -- Kubernetes Services -- Helm Package Manager -- Persistent Storage -- Stateful Apps - -## Resources +## Recursos - [Kubernetes Documentation](https://kubernetes.io/docs/home/) - [TechWorld with Nana - Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]](https://www.youtube.com/watch?v=X48VuDVv0do) - [TechWorld with Nana - Kubernetes Crash Course for Absolute Beginners](https://www.youtube.com/watch?v=s_o8dwzRlu4) - [Kunal Kushwaha - Kubernetes Tutorial for Beginners | What is Kubernetes? Architecture Simplified!](https://www.youtube.com/watch?v=KVBON1lA9N8) -See you on [Day 51](day51.md) +Nos vemos en el [Día 51](day51.md) diff --git a/2022/ko/Days/day01.md b/2022/ko/Days/day01.md index 23c754e..cf6d6c0 100644 --- a/2022/ko/Days/day01.md +++ b/2022/ko/Days/day01.md @@ -23,11 +23,11 @@ date: '2022-04-17T10:12:40Z' 위의 블로그를 읽고 저의 학습 여정의 수준이 매우 높을 것이라고 짐작하시는 분들을 위해 말씀드리면, 저는 그 분야들에 대해 전문가는 아닙니다만 유료이건 무료이건 어떤 형태로든 자료를 공유하고 싶었습니다. 우리는 모두 서로 다른 환경에 있을 것이니 각자에게 맞는 선택을 하시길 바랍니다. -앞으로 90일간 저는 기본적인 영역들에 대해 다루고 자료들을 문서화 하려고 합니다. 커뮤니티의 적극적인 참여도 바라고 있습니다. 많은 분의 학습 여정과 자료의 공유를 통해 공개적으로 함께 도와가며 서로 배우길 바랍니다. +앞으로 90일간 저는 기본적인 영역들에 대해 다루고 자료들을 문서화하려고 합니다. 커뮤니티의 적극적인 참여도 바라고 있습니다. 많은 분의 학습 여정과 자료의 공유를 통해 공개적으로 함께 도와가며 서로 배우길 바랍니다. 프로젝트 리포지토리의 readme에 12주에 6일을 더한 분량의 섹션 별로 분할을 해두었습니다. 첫 6일간은 특정 영역에 뛰어들기 전에 데브옵스에 대한 전반적인 기본 지식들에 대해 학습할 것입니다. 반복해서 말씀드리면 저의 자료가 완벽하지 않습니다. 따라서 이 자료들이 유용하게 활용될 수 있도록 커뮤니티의 도움을 바랍니다. -지금 이 순간에 공유하고 싶은 자료가 하나 더 있습니다. 모두가 꼼꼼히 살펴야하고, 스스로에 대한, 자신의 관심과 현재 위치를 마인드맵으로 그려야할, 그것은 +지금 이 순간에 공유하고 싶은 자료가 하나 더 있습니다. 모두가 꼼꼼히 살펴야 하고, 스스로에 대한, 자신의 관심과 현재 위치를 마인드맵으로 그려야 할, 그것은 [DevOps Roadmap](https://roadmap.sh/devops) @@ -35,30 +35,31 @@ date: '2022-04-17T10:12:40Z' ## 첫 단계 - 데브옵스란? -소개드리고 싶은 유튜브 비디오나 블로그 글이 너무 많습니다. 하지만 우리는 90일의 도전을 시작했고 매일 한시간씩 새로운 것을 배우거나 데브옵스에 관해 배우기로 했으므로, "DevOps란 무엇인가"라는 높은 수준의 정보를 먼저 얻는 것이 좋다고 생각합니다. +소개드리고 싶은 유튜브 비디오나 블로그 글이 너무 많습니다. 하지만 우리는 90일의 도전을 시작했고 매일 한 시간씩 새로운 것을 배우거나 데브옵스에 관해 배우기로 했으므로, "DevOps란 무엇인가"라는 높은 수준의 정보를 먼저 얻는 것이 좋다고 생각합니다. 우선, 데브옵스는 도구가 아닙니다. 살 수 있는 것도 아니고, software SKU나 깃허브 레포지토리에서 다운로드 받을 수 있는 오픈 소스도 아닙니다. 또한 프로그래밍 언어도 아니고, 괴상한 흑마술도 아닙니다. 데브옵스란 소프트웨어 개발에서 좀 더 현명하게 일하는 방법을 말합니다. - 잠깐... 혹시 소프트웨어 개발자가 아니라면 이 학습 과정을 중단해야 할까요??? 아닙니다.. 데브옵스란 소프트웨어 개발과 운영의 통합을 의미하기 때문입니다. 위에서 언급했듯이 저는 일반적으로 운영에 속하는 VM(가상머신)과 관련된 쪽에 있었지만, 커뮤니티에는 다양한 배경을 가진 사람들이 있습니다. 그리고 개인, 개발자, 운영자 그리고 QA 엔지니어 모두는 DevOps를 더 잘 이해함으로써 모범사례에 관해 동등하게 배울 수 있습니다. -데브옵스는 이 목표를 달성하기 위한 일련의 관행입니다: 제품이 초기 아이디어 단계부터 최종 사용자, 내부 팀 또는 고객 등 모든 사용자에게 실제 운영 서비스로 전달되기 까지의 시간을 단축하는 것. +데브옵스는 이 목표를 달성하기 위한 일련의 관행입니다: 제품이 초기 아이디어 단계부터 최종 사용자, 내부 팀 또는 고객 등 모든 사용자에게 실제 운영 서비스로 전달되기까지의 시간을 단축하는 것. 첫 주에 다룰 또 다른 분야는 **애자일 방법론** 에 관한 것입니다. 애플리케이션을 지속적으로 전달(Continuous Delivery)하기 위해 데브옵스와 애자일은 주로 함께 다루어집니다. -개략적으로 말해 데브옵스적 사고방식이나 문화는 길고 몇년이 걸릴 수 있는 소프트웨어 배포 프로세스를 더 작고, 자주 배포하는 방식으로 시간을 단축시키는 것입니다. 추가로 이해해야할 또 다른 핵심 포인트는 위에 언급한 개발, 운영, QA 팀간의 사일로를 무너트리는 것은 데브옵스 엔지니어의 책임입니다. +개략적으로 말해 데브옵스적 사고방식이나 문화는 길고 몇 년이 걸릴 수 있는 소프트웨어 배포 프로세스를 더 작고, 자주 배포하는 방식으로 시간을 단축시키는 것입니다. 추가로 이해해야 할 또 다른 핵심 포인트는 위에 언급한 개발, 운영, QA 팀 간의 사일로를 무너트리는 것은 데브옵스 엔지니어의 책임입니다. -데브옵스의 관점에서 보면 **개발, 테스트, 배포**는 모두 데브옵스 팀과 함께 해야하기 때문입니다. +데브옵스의 관점에서 보면 **개발, 테스트, 배포**는 모두 데브옵스 팀과 함께해야 하기 때문입니다. 최종적으로 이런 것을 효과적이고 효율적으로 하기 위해서는 **자동화**를 최대한 활용해야 합니다. ## 자료 -이곳을 학습 도구로 활용하기 위해 이 readme 파일에 추가적으로 자료를 덪붙이는 것에 대해 항상 열려있습니다. +이곳을 학습 도구로 활용하기 위해 이 readme 파일에 추가적으로 자료를 덧붙이는 것에 대해 항상 열려있습니다. 그리고 아래 동영상들을 꼭 보시기 바랍니다. 또한 위에 설명드린 내용에서 많은 인사이트를 얻었으면 합니다. - [DevOps in 5 Minutes](https://www.youtube.com/watch?v=Xrgk023l4lI) - [What is DevOps? Easy Way](https://www.youtube.com/watch?v=_Gpe1Zn-1fE&t=43s) - [DevOps roadmap 2022 | Success Roadmap 2022](https://www.youtube.com/watch?v=7l_n97Mt0ko) +- [From Zero to DevOps Engineer - DevOps Roadmap for YOUR specific background](https://www.youtube.com/watch?v=G_nVMUtaqCk) 여기까지 읽었다면 나에게 필요한 내용인지 아닌지 알 수 있을 것입니다. [Day 2](day02.md) diff --git a/2022/ko/Days/day02.md b/2022/ko/Days/day02.md index 15c10b6..244e179 100644 --- a/2022/ko/Days/day02.md +++ b/2022/ko/Days/day02.md @@ -13,7 +13,7 @@ date: '2022-04-17T21:15:34Z' 부디, 여러분이 자료를 찾고 [Day1 of #90DaysOfDevOps](day01.md) 페이지에 글을 올리면서 함께 참여하기를 바랍니다. -첫 번째 글에서 짦게 다루었습니다만, 이제 더 깊이 있는 개념 그리고 애플리케이션을 만드는 것에는 두가지 주요 파트가 있다는 것에 대해 이해할 필요가 있습니다. 소프트웨어 개발자들이 애플리케이션을 작성하고 테스트하는 **개발** 파트와 애플리케이션을 서버에 배포하고 유지하는 **운영** 파트 입니다. +첫 번째 글에서 짧게 다루었습니다만, 이제 더 깊이 있는 개념 그리고 애플리케이션을 만드는 것에는 두 가지 주요 파트가 있다는 것에 대해 이해할 필요가 있습니다. 소프트웨어 개발자들이 애플리케이션을 작성하고 테스트하는 **개발** 파트와 애플리케이션을 서버에 배포하고 유지하는 **운영** 파트 입니다. ## 데브옵스는 그 둘을 연결합니다. @@ -39,27 +39,27 @@ To get to grips with DevOps or the tasks which a DevOps engineer would be carryi ## 이것도 알고, 저것도 알고 -네트워크 또는 인프라의 스페셜리스트가 될 필요는 없습니다. 서버를 올리고, 실행시키고 상호간 통신이 가능하도록 구성하는 방법에 대한 지식만 있으면됩니다. 마찬가지로 개발자가 될 필요는 없습니다. 프로그래밍 언어에 대한 기본적인 지식만 있으면 됩니다. 하지만 어느 한 분야의 전문가로써 데브옵스 업무에 참여할 수 있고, 이럴 경우 다른 분야에 적응하기 위한 매우 좋은 기반이 될 것입니다. +네트워크 또는 인프라의 스페셜리스트가 될 필요는 없습니다. 서버를 올리고, 실행시키고 상호 간 통신이 가능하도록 구성하는 방법에 대한 지식만 있으면 됩니다. 마찬가지로 개발자가 될 필요는 없습니다. 프로그래밍 언어에 대한 기본적인 지식만 있으면 됩니다. 하지만 어느 한 분야의 전문가로서 데브옵스 업무에 참여할 수 있고, 이럴 경우 다른 분야에 적응하기 위한 매우 좋은 기반이 될 것입니다. -또한 서버나 애플리케이션의 관리를 매일 인계받지 못할 수 도 있습니다. +또한 서버나 애플리케이션의 관리를 매일 인계받지 못할 수도 있습니다. -서버에 대해서만 이야기 했지만, 애플리케이션이 컨테이너로 실행되도록 개발해야 할 수 도 있습니다. 여전히 서버에서 실행하는 것이라곤 하나, 가상화, IaaS (클라우드 인프라 서비스)와 더불어 컨테이너화에 대한 이해도 필요합니다. +서버에 대해서만 이야기했지만, 애플리케이션이 컨테이너로 실행되도록 개발해야 할 수도 있습니다. 여전히 서버에서 실행하는 것이라곤 하나, 가상화, IaaS (클라우드 인프라 서비스)와 더불어 컨테이너화에 대한 이해도 필요합니다. ## 고차원적인 개요 -한쪽에서 우리 개발자들이 애플리케이션을 위핸 시 기능들을 (버그 수정과 더불어) 추가합니다. +한쪽에서 우리 개발자들이 애플리케이션을 위한 기능들을 (버그 수정과 더불어) 추가합니다. 다른 한쪽에서는 실제 애플리케이션이 실행되고 필요 서비스들과 통신하도록 구성 및 관리되고 있는 서버, 인프라 내지는 환경이 있습니다. 여기서 핵심은 버그 수정 및 새 기능이 추가된 버전을 운영 환경에 적용시켜 최종 사용자에게 제공하도록 하는 것입니다. -새 애플리케이션 버전을 어떻게 출시하는가? 이것이 데브옵스 엔지니어의 핵심 업무 입니다. 테스트를 포함한 효과적이고 자동화된 방식을 지속적으로 고민해야합니다. +새 애플리케이션 버전을 어떻게 출시하는가? 이것이 데브옵스 엔지니어의 핵심 업무입니다. 테스트를 포함한 효과적이고 자동화된 방식을 지속적으로 고민해야 합니다. 여기서 오늘 학습을 끝내도록 하겠습니다. 부디 유용했기를 바랍니다. 앞으로 DevOps의 다양한 영역들과, 다양한 도구 및 프로세스들의 사용 이점에 대해서 깊이 있게 다루도록 하겠습니다. ## 자료 -이곳을 학습 도구로 활용하기 위해 이 readme 파일에 추가적으로 자료를 덪붙이는 것에 대해 항상 열려있습니다. +이곳을 학습 도구로 활용하기 위해 이 readme 파일에 추가적으로 자료를 덧붙이는 것에 대해 항상 열려있습니다. 그리고 아래 동영상들을 꼭 보시기 바랍니다. 또한 위에 설명드린 내용에서 많은 인사이트를 얻었으면 합니다. diff --git a/2022/ko/Days/day03.md b/2022/ko/Days/day03.md new file mode 100644 index 0000000..88d45e2 --- /dev/null +++ b/2022/ko/Days/day03.md @@ -0,0 +1,97 @@ +--- +title: '#90DaysOfDevOps - Application Focused - Day 3' +published: false +description: 90DaysOfDevOps - Application Focused +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048825 +--- + +## 데브옵스 수명 주기 - 애플리케이션 중심 + +앞으로 몇 주 동안 계속 진행하면서 지속적 개발, 테스트, 배포, 모니터에 대해 100% 반복해서 접하게 될 것입니다. DevOps 엔지니어 역할로 향하고 있다면 반복성이 익숙해질 것이지만 매번 지속적으로 향상시키는 것도 흥미를 유지하는 또 다른 요소입니다. + +이번 시간에는 애플리케이션을 처음부터 끝까지 살펴본 다음 다시 반복하듯 되돌아보는 고차원의 시각으로 살펴보겠습니다. + +### Development (개발) + +애플리케이션의 새로운 예를 들어 보겠습니다. 먼저 아무것도 만들어지지 않은 상태에서 개발자는 고객 또는 최종 사용자와 요구 사항을 논의하고 애플리케이션에 대한 일종의 계획이나 요구 사항을 마련해야 합니다. 그런 다음 요구 사항을 바탕으로 새로운 애플리케이션을 만들어야 합니다. + +이 단계의 도구와 관련해서는 애플리케이션을 작성하는 데 사용할 IDE와 프로그래밍 언어를 선택하는 것 외에는 실제 요구 사항이 없습니다. + +데브옵스 엔지니어로서 이 계획을 만들거나 최종 사용자를 위해 애플리케이션을 코딩하는 것은 여러분이 아니라 숙련된 개발자가 할 일이라는 점을 기억하세요. + +그러나 애플리케이션에 대한 최상의 인프라 결정을 내릴 수 있도록 일부 코드를 읽을 수 있는 것도 나쁘지 않을 것입니다. + +앞서 이 애플리케이션은 어떤 언어로든 작성할 수 있다고 언급했습니다. 중요한 것은 버전 관리 시스템을 사용하여 유지 관리해야 한다는 것인데, 이 부분은 나중에 자세히 다룰 것이며 특히 **Git**에 대해 자세히 살펴볼 것입니다. + +또한 이 프로젝트에서 한 명의 개발자가 작업하는 것이 아닐 수도 있지만, 이 경우에도 모범 사례에서는 코드를 저장하고 협업하기 위한 코드 저장소가 필요하며, 이는 비공개 또는 공개일 수 있고 호스팅되거나 비공개로 배포될 수 있으며 일반적으로 **GitHub 또는 GitLab**과 같은 코드 저장소가 코드 저장소로 사용되는 것을 듣게 될 것입니다. 이에 대해서는 나중에 **Git** 섹션에서 다시 다루겠습니다. + +### Testing (테스팅) + +이 단계에서는 요구 사항이 있고 애플리케이션이 개발되고 있습니다. 하지만 우리가 사용할 수 있는 모든 다양한 환경, 특히 선택한 프로그래밍 언어에서 코드를 테스트하고 있는지 확인해야 합니다. + +이 단계에서 QA는 버그를 테스트할 수 있으며, 테스트 환경을 시뮬레이션하는 데 컨테이너를 사용하는 경우가 많아져 전반적으로 물리적 또는 클라우드 인프라의 비용 오버헤드를 개선할 수 있습니다. + +이 단계는 또한 다음 영역인 지속적 통합의 일부로 자동화될 가능성이 높습니다. + +이 테스트를 자동화할 수 있다는 것은 수십, 수백, 심지어 수천 명의 QA 엔지니어가 이 작업을 수동으로 수행해야 하는 것과 비교하면 그 자체로 의미가 있으며, 이러한 엔지니어는 스택 내에서 다른 작업에 집중하여 워터폴 방법론을 사용하는 대부분의 기존 소프트웨어 릴리스에서 지체되는 경향이 있는 버그 및 소프트웨어 테스트 대신 더 빠르게 움직이고 더 많은 기능을 개발할 수 있습니다. + +### Integration (통합) + +매우 중요한 것은 통합이 데브옵스 라이프사이클의 중간에 있다는 것입니다. 개발자가 소스 코드에 변경 사항을 더 자주 커밋해야 하는 practice(관행)입니다. 이는 매일 또는 매주 단위로 이루어질 수 있습니다. + +커밋할 때마다 애플리케이션은 자동화된 테스트 단계를 거치게 되며, 이를 통해 다음 단계로 넘어가기 전에 문제나 버그를 조기에 발견할 수 있습니다. + +이제 이 단계에서 "하지만 우리는 애플리케이션을 만들지 않고 소프트웨어 공급업체에서 기성품을 구입합니다."라고 말할 수 있습니다. 많은 회사가 이렇게 하고 있고 앞으로도 계속 그렇게 할 것이며 위의 3단계에 집중하는 것은 소프트웨어 공급업체가 될 것이므로 걱정하지 마세요. 하지만 마지막 단계를 채택하면 기성품 배포를 더 빠르고 효율적으로 배포할 수 있으므로 여전히 채택하고 싶을 수도 있습니다. + +오늘 당장 상용 소프트웨어를 구매할 수도 있지만 내일이나 또는... 다음 직장에서 사용할 수도 있기 때문에 위의 지식을 갖추는 것만으로도 매우 중요하다고 말씀드리고 싶습니다. + +### Deployment (배포) + +Ok so we have our application built and tested against the requirements of our end user and we now need to go ahead and deploy this application into production for our end users to consume. + +This is the stage where the code is deployed to the production servers, now this is where things get extremely interesting and it is where the rest of our 86 days dives deeper into these areas. Because different applications require different possibly hardware or configurations. This is where **Application Configuration Management** and **Infrastructure as Code** could play a key part in your DevOps lifecycle. It might be that your application is **Containerised** but also available to run on a virtual machine. This then also leads us onto platforms like **Kubernetes** which would be orchestrating those containers and making sure you have the desired state available to your end users. + +Of these bold topics, we will go into more detail over the next few weeks to get a better foundational knowledge of what they are and when to use them. + +이제 최종 사용자의 요구 사항에 따라 애플리케이션을 빌드하고 테스트를 마쳤으므로 이제 최종 사용자가 사용할 수 있도록 이 애플리케이션을 프로덕션에 배포해야 합니다. + +이 단계는 코드를 프로덕션 서버에 배포하는 단계로, 이제부터 매우 흥미로운 일이 벌어지며 나머지 86일 동안 이러한 영역에 대해 더 자세히 알아볼 것입니다. 애플리케이션마다 필요한 하드웨어나 구성이 다르기 때문입니다. 바로 이 부분에서 **Application Configuration Management(애플리케이션 구성 관리)**와 **Infrastructure as Code(코드형 인프라)**가 데브옵스 라이프사이클에서 중요한 역할을 할 수 있습니다. 애플리케이션이 **Containerised(컨테이너화)**되어 있지만 가상 머신에서 실행할 수 있는 경우도 있을 수 있습니다. 그런 다음 이러한 컨테이너를 오케스트레이션하고 최종 사용자가 원하는 상태를 사용할 수 있도록 하는 **Kubernetes**와 같은 플랫폼으로 이어집니다. + +이 대담한 주제 중 앞으로 몇 주에 걸쳐 더 자세히 살펴보면서 컨테이너가 무엇이고 언제 사용하는지에 대한 기초 지식을 쌓을 것입니다. + +### Monitoring (관제) + +새로운 기능으로 지속적으로 업데이트하고 있는 애플리케이션이 있으며, 테스트 과정에서 문제점이 발견되지 않는지 확인하고 있습니다. 필요한 구성과 성능을 지속적으로 유지할 수 있는 애플리케이션이 우리 환경에서 실행되고 있습니다. + +하지만 이제 최종 사용자가 필요한 경험을 얻고 있는지 확인해야 합니다. 이 단계에서는 애플리케이션 성능을 지속적으로 모니터링하여 개발자가 향후 릴리스에서 애플리케이션을 개선하여 최종 사용자에게 더 나은 서비스를 제공할 수 있도록 더 나은 결정을 내릴 수 있도록 해야 합니다. + +또한 이 섹션에서는 구현된 기능에 대한 피드백을 수집하고 최종 사용자가 어떻게 개선하기를 원하는지에 대한 피드백을 수집할 것입니다. + +안정성은 여기서도 핵심 요소이며, 결국에는 애플리케이션이 필요할 때 항상 사용할 수 있기를 원합니다. 이는 지속적으로 모니터링해야 하는 다른 **observability, security and data management(관찰 가능성, 보안 및 데이터 관리)** 영역으로 이어지며, 피드백을 통해 애플리케이션을 지속적으로 개선, 업데이트 및 릴리스하는 데 항상 사용할 수 있습니다. + +특히 [@\_ediri](https://twitter.com/_ediri) 커뮤니티의 일부 의견은 이러한 지속적인 프로세스의 일부로 FinOps 팀도 참여해야 한다고 언급했습니다. 앱과 데이터는 어딘가에서 실행되고 저장되므로 리소스 관점에서 상황이 변경될 경우 비용이 클라우드 요금에 큰 재정적 고통을 주지 않도록 지속적으로 모니터링해야 합니다. + +위에서 언급한 "DevOps 엔지니어"에 대해서도 언급할 때가 되었다고 생각합니다. 많은 사람들이 DevOps 엔지니어라는 직책을 가지고 있지만, 이것은 DevOps 프로세스를 포지셔닝하는 이상적인 방법은 아닙니다. 제 말은 커뮤니티의 다른 사람들과 이야기할 때 데브옵스 엔지니어라는 직책이 누구의 목표가 되어서는 안 된다는 것입니다. 실제로 어떤 직책이든 여기에서 설명한 데브옵스 프로세스와 문화를 채택해야 하기 때문입니다. 데브옵스는 클라우드 네이티브 엔지니어/아키텍트, 가상화 관리자, 클라우드 아키텍트/엔지니어, 인프라 관리자와 같은 다양한 직책에서 사용되어야 합니다. 몇 가지 예를 들었지만, 위에서 DevOps 엔지니어를 사용한 이유는 위의 모든 직책에서 사용하는 프로세스의 범위 등을 강조하기 위해서입니다. + +## Resources + +I am always open to adding additional resources to these readme files as it is here as a learning tool. + +My advice is to watch all of the below and hopefully you also picked something up from the text and explanations above. + +학습 도구로서 이 Readme 파일에 추가 리소스를 추가하는 것은 언제나 열려 있습니다. + +아래의 내용을 모두 보시고 위의 텍스트와 설명에서 많은 것들을 얻으셨으면 좋겠습니다. + +- [Continuous Development](https://www.youtube.com/watch?v=UnjwVYAN7Ns) I will also add that this is focused on manufacturing but the lean culture can be closely followed with DevOps. +- [Continuous Testing - IBM YouTube](https://www.youtube.com/watch?v=RYQbmjLgubM) +- [Continuous Integration - IBM YouTube](https://www.youtube.com/watch?v=1er2cjUq1UI) +- [Continuous Monitoring](https://www.youtube.com/watch?v=Zu53QQuYqJ0) +- [The Remote Flow](https://www.notion.so/The-Remote-Flow-d90982e77a144f4f990c135f115f41c6) +- [FinOps Foundation - What is FinOps](https://www.finops.org/introduction/what-is-finops/) +- [**NOT FREE** The Phoenix Project: A Novel About IT, DevOps, and Helping Your Business Win](https://www.amazon.com/Phoenix-Project-DevOps-Helping-Business/dp/1942788290/) + +여기까지 왔다면 이곳이 자신이 원하는 곳인지 아닌지 알 수 있을 것입니다. 다음에 뵙겠습니다. [Day 4](day04.md). diff --git a/2022/ko/Days/day04.md b/2022/ko/Days/day04.md new file mode 100644 index 0000000..8fdae78 --- /dev/null +++ b/2022/ko/Days/day04.md @@ -0,0 +1,99 @@ +--- +title: '#90DaysOfDevOps - DevOps & Agile - Day 4' +published: false +description: 90DaysOfDevOps - DevOps & Agile +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048700 +--- + +## DevOps & Agile (데브옵스 & 애자일) + +데브옵스와 애자일의 차이점을 알고 계신가요? 데브옵스와 애자일은 독립적인 개념으로 형성되었습니다. 하지만 이제 이 두 용어는 융합되고 있습니다. + +이 글에서는 애자일과 데브옵스의 중요한 차이점을 살펴보고 이 둘이 긴밀하게 연결되어 있는 이유를 알아보겠습니다. + +이 분야를 배우면서 제가 본 공통적인 관점, 즉 목표와 프로세스가 비슷하지만 데브옵스와 애자일에 대해 조금 더 이해하는 것이 시작하기에 좋은 출발점이라고 생각합니다. 이 섹션에서는 이에 대해 간략하게 정리해 보려고 합니다. + +정의부터 시작하겠습니다. + +### Agile Development + +애자일은 제품의 큰 결과물을 한 번에 출시하기보다는 작은 결과물을 더 빠르게 제공하는 데 중점을 두는 접근 방식으로, 소프트웨어는 반복적으로 개발됩니다. 팀은 매주 또는 매달 점진적인 업데이트를 통해 새 버전을 출시합니다. 애자일의 최종 목표는 최종 사용자에게 최적의 경험을 제공하는 것입니다. + +### DevOps + +지난 며칠 동안 데브옵스의 최종 목표를 설명하는 몇 가지 다른 방법으로 이 문제를 다뤄왔습니다. 데브옵스는 일반적으로 소프트웨어 개발자와 운영 전문가 간의 협력을 기반으로 +및 소프트웨어 개발자와 운영 전문가 간의 협력을 기반으로 하는 배포 관행을 설명합니다. 데브옵스의 주요 이점은 간소화된 개발 프로세스를 제공하고 잘못된 커뮤니케이션을 최소화하는 것입니다. + +## 애자일과 데브옵스의 차이점은 무엇인가? + +차이점은 주로 선입견에 있습니다. 애자일과 데브옵스는 서로 다른 선입견을 가지고 있지만 서로를 돕고 있습니다. 애자일은 짧은 반복을 원하는데, 이는 데브옵스가 제공하는 자동화를 통해서만 가능합니다. 애자일은 고객이 특정 버전을 사용해보고 신속하게 피드백을 주기를 원하는데, 이는 데브옵스가 새로운 환경을 쉽게 만들 수 있을 때만 가능합니다. + +### Different participants (서로 다른 참여자) + +애자일은 최종 사용자와 개발자 간의 커뮤니케이션을 최적화하는 데 중점을 두는 반면 데브옵스는 개발자와 운영, 팀원을 대상으로 합니다. 애자일은 고객을 향한 외부 지향적인 반면 데브옵스는 일련의 내부 관행이라고 할 수 있습니다. + +### 팀 + +애자일은 일반적으로 소프트웨어 개발자와 프로젝트 관리자에게 적용됩니다. 데브옵스 엔지니어의 역량은 제품 주기의 모든 단계에 관여하고 애자일 팀의 일원이므로 개발, QA(품질 보증) 및 운영이 교차하는 지점에 있습니다. + +### 적용된 프레임워크 + +애자일에는 유연성과 투명성을 달성하기 위한 다양한 관리 프레임워크가 있습니다: Scrum > Kanban > Lean > Extreme > Crystal > Dynamic > Feature-Driven. 데브옵스는 협업을 통한 개발 접근 방식에 중점을 두지만 구체적인 방법론을 제공하지는 않습니다. 그러나 데브옵스는 코드형 인프라, 코드형 아키텍처, 모니터링, 자가 치유, 엔드투엔드 테스트 자동화와 같은 관행을 장려합니다. 그러나 이것은 그 자체로 프레임워크가 아니라 관행입니다. + +### 피드백 + +애자일에서는 피드백의 주요 출처가 최종 사용자인 반면, 데브옵스에서는 이해관계자와 팀 자체의 피드백이 더 높은 우선순위를 갖습니다. + +### 대상 영역 + +애자일은 배포 및 유지 관리보다 소프트웨어 개발에 더 중점을 둡니다. 데브옵스는 소프트웨어 개발에도 중점을 두지만 그 가치와 도구는 모니터링, 고가용성, 보안 및 데이터 보호와 같은 배포 및 릴리스 후 단계에도 적용됩니다. + +### 문서 + +애자일은 문서화 및 모니터링보다 유연성과 당면한 작업에 우선순위를 둡니다. 반면 데브옵스는 프로젝트 문서를 필수 프로젝트 구성 요소 중 하나로 간주합니다. + +### 위험요소 + +애자일 리스크는 방법론의 유연성에서 비롯됩니다. 애자일 프로젝트는 우선순위와 요구사항이 계속 변하기 때문에 예측하거나 평가하기가 어렵습니다. + +데브옵스 위험은 용어에 대한 오해와 적절한 도구의 부재에서 비롯됩니다. 어떤 사람들은 데브옵스를 개발 프로세스의 기본 구조를 바꾸지 못하는 배포 및 지속적 통합을 위한 소프트웨어 모음으로 간주합니다. + +### 사용되는 툴들 + +애자일 도구는 경영진의 커뮤니케이션 협업, 메트릭 및 피드백 처리에 중점을 둡니다. 가장 인기 있는 애자일 도구로는 JIRA, Trello, Slack, Zoom, SurveyMonkey 등이 있습니다. + +데브옵스는 팀 커뮤니케이션, 소프트웨어 개발, 배포 및 통합을 위해 Jenkins, GitHub Actions, BitBucket 등과 같은 도구를 사용합니다. 애자일과 데브옵스는 초점과 범위가 약간 다르지만 핵심 가치는 거의 동일하므로 두 가지를 결합할 수 있습니다. + +## 모두 모아본다면... 좋은 선택일까요? 논의가 필요할까요? + +애자일과 데브옵스를 결합하면 다음과 같은 이점을 얻을 수 있습니다: + +- 유연한 관리와 강력한 기술. +- 애자일 관행은 데브옵스 팀이 우선순위를 보다 효율적으로 소통하는 데 도움이 됩니다. +- 데브옵스 관행을 위해 지불해야 하는 자동화 비용은 신속하고 자주 배포해야 하는 애자일 요구 사항에 따라 정당화됩니다. +- 애자일 방식을 채택하는 팀은 협업을 개선하고 팀의 동기를 높이며 직원 이직률을 낮출 수 있습니다. +- 결과적으로 제품 품질이 향상됩니다. + +애자일을 사용하면 이전 제품 개발 단계로 돌아가 오류를 수정하고 기술 부채의 누적을 방지할 수 있습니다. 애자일과 데브옵스를 동시에 도입하려면 +동시에 도입하려면 다음 7단계를 따르세요: + +1. 개발 팀과 운영 팀을 통합합니다. +2. 빌드 및 운영 팀을 만들고 모든 개발 및 운영 관련 문제를 전체 DevOps 팀에서 논의합니다. +3. 스프린트에 대한 접근 방식을 변경하고 우선순위를 지정하여 개발 작업과 동일한 가치를 지닌 DevOps 작업을 제공하세요. 개발 팀과 운영 팀이 다른 팀의 workflow와 발생 가능한 문제에 대해 의견을 교환하도록 장려하세요. +4. 모든 개발 단계에 QA를 포함하세요. +5. 올바른 도구를 선택하세요. +6. 가능한 모든 것을 자동화하세요. +7. 가시적인 수치 결과물을 사용하여 측정하고 제어하세요. + +어떻게 생각하시나요? 다른 견해가 있으신가요? 개발자, 운영, QA 또는 애자일 및 DevOps에 대해 더 잘 이해하고 이에 대한 의견과 피드백을 전달해 주실 수 있는 분들의 의견을 듣고 싶습니다. + +### Resources + +- [DevOps for Developers – Day in the Life: DevOps Engineer in 2021](https://www.youtube.com/watch?v=2JymM0YoqGA) +- [3 Things I wish I knew as a DevOps Engineer](https://www.youtube.com/watch?v=udRNM7YRdY4) +- [How to become a DevOps Engineer feat. Shawn Powers](https://www.youtube.com/watch?v=kDQMjAQNvY4) + +여기까지 왔다면 이곳이 자신이 원하는 곳인지 아닌지 알 수 있을 것입니다. 다음에 뵙겠습니다. [Day 5](day05.md). diff --git a/2022/ko/Days/day05.md b/2022/ko/Days/day05.md new file mode 100644 index 0000000..eadf533 --- /dev/null +++ b/2022/ko/Days/day05.md @@ -0,0 +1,86 @@ +--- +title: '#90DaysOfDevOps - Plan > Code > Build > Testing > Release > Deploy > Operate > Monitor > - Day 5' +published: false +description: 90DaysOfDevOps - Plan > Code > Build > Testing > Release > Deploy > Operate > Monitor > +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048830 +--- + +## 계획 > 코드 작성 > 빌드 > 테스트 > 릴리즈 > 배포 > 운영 > 모니터링 > + +오늘은 데브옵스 환경에서 애플리케이션의 시작부터 끝까지 개별 단계와 continuous cycle에 대해 집중적으로 살펴보겠습니다. + +![DevOps](/2022/Days/Images/Day5_DevOps8.png) + +### 계획 + +개발팀이 다음 스프린트에서 출시할 기능과 버그 수정을 결정하는 계획 프로세스는 데브옵스 엔지니어가 참여하여, 앞으로 어떤 일이 발생할지 파악하고 개발팀의 결정이나 경로에 영향을 미치고, 그들이 구축한 인프라로 작업하도록 돕거나 그들이 다른 경로를 따를 경우 더 나은 방향으로 안내할 수 있는 기회입니다. 중요한 점은 개발자나 소프트웨어 엔지니어링 팀이 데브옵스 엔지니어의 고객이 되므로, 고객이 나쁜 방향으로 가기 전에 고객과 협력할 수 있는 기회라는 것입니다. + +### 코드 작성 + +이제 계획 세션을 마치고 코드 작성 단계에 진입합니다. 이 단계에서 당신이 참여할 수 있는 역할 중 하나는 코드를 작성하는 동안 인프라에 대한 이해도를 높여서 어떤 서비스를 사용할 수 있는지, 그 서비스와 어떻게 상호작용할 수 있는지를 더 잘 이해할 수 있도록 돕는 것입니다. 또한, 코드 작성이 완료되면 해당 코드를 리포지토리에 병합하는 일도 중요한 역할입니다. + +### 빌드 + +여기에서는 자동화 프로세스의 첫 번째로, 코드를 가져와서 사용하는 언어에 따라 변환하거나 컴파일하거나 해당 코드에서 도커 이미지를 생성할 수 있기 때문에, CI 파이프라인을 사용하여 이러한 프로세스를 자동화할 것입니다. 이렇게 함으로써, 코드를 변경하거나 새 코드를 추가할 때마다 일일이 수동으로 작업하는 것이 아니라, 자동화된 프로세스를 통해 더욱 효율적이고 일관성 있는 작업을 수행할 수 있게 됩니다. + +## 테스트 + +빌드가 완료되면 몇 가지 테스트를 실행합니다. 개발 팀은 보통 어떤 테스트를 작성할지 제안할 수 있지만, 이를 실행해야 합니다. 테스트는 프로덕션에 문제가 발생하지 않도록 최소화하기 위한 시도입니다. 새로운 버그가 발생하지 않도록 보장하는 것은 불가능하지만, 최대한 이전에 작동하던 것이 깨지지 않도록 보장하기 위해 노력합니다. + +## 릴리즈 + +테스트가 모두 통과되면, 애플리케이션 유형에 따라 릴리스 프로세스가 수행됩니다. 하지만 이 단계는 작업 중인 애플리케이션에 따라 생략될 수도 있습니다. 일반적으로, GitHub 리포지토리나 git 리포지토리에서 가져온 코드나 빌드된 도커 이미지를 프로덕션 서버에 배포하기 위해 레지스트리나 리포지토리에 저장합니다. 이를 통해 배포 프로세스가 진행됩니다. + +## 배포 + +배포는 모든 개발과정의 최종 단계이기 때문에, 프로덕션 환경에 코드를 적용하는 과정입니다. 이 단계에서 비즈니스에서는 여러분과 소프트웨어 엔지니어링 팀이 지금까지 이 제품에 투자한 모든 시간과 노력의 가치를 실현할 수 있습니다. + +## 운영 + +한 번 배포가 완료되면, 해당 제품이 운영되기 시작하게 됩니다. 운영에는 고객이 사이트나 애플리케이션을 사용할 때 발생하는 문제를 파악하고, 이에 대한 대처 방안을 마련하는 것이 포함됩니다. 예를 들어, 사이트가 느리게 실행되는 문제가 발생하면, 운영팀은 이유를 파악하고 피크 기간 동안은 서버 수를 늘리고, 사용량이 적은 기간에는 서버 수를 줄이는 자동 확장 기능을 구축할 수 있습니다. 또한, 운영 유형 메트릭 처리와 같은 다양한 작업도 수행됩니다. 가능한 경우에는 이러한 작업을 자동화하는 것이 좋습니다. 그러나, 몇 가지 단계를 수행해야 하는 환경에서는 자동화가 어려울 수도 있습니다. 그런 경우에는 가능한 한 자동화를 시도하면서도, 일부 작업을 수동으로 처리해야 할 수도 있습니다. 그리고, 자동화 프로세스에서는 운영팀이 배포가 발생했음을 알 수 있도록 몇 가지 유형의 알림을 포함하는 것이 좋습니다. + +## 모니터링 + +위의 모든 부분이 마지막 단계로 이어지는데, 특히 운영 문제 자동 확장 문제 해결과 관련된 모니터링이 필요하기 때문입니다. +문제가 있다는 것을 알려주는 모니터링이 없다면 문제가 있는 것이므로 메모리 사용률 CPU 사용률 디스크 공간, API 엔드포인트, 응답 시간, 엔드포인트가 얼마나 빨리 응답하는지 등을 모니터링할 수 있으며, 이 중 큰 부분은 로그입니다. 개발자는 로그를 통해 프로덕션 시스템에 액세스하지 않고도 무슨 일이 일어나고 있는지 확인할 수 있습니다. + +## 다듬기 & 반복 + +여태까지 수행한 프로세스를 검토하고 개선할 부분을 찾습니다. 그리고 이를 바탕으로 다시 계획 단계로 돌아가 전체 과정을 재진행합니다. 이는 지속적인 개선과 반복적인 프로세스 개선을 위한 사이클을 형성하며, 더 나은 제품과 높은 품질의 서비스를 제공하기 위한 필수적인 단계입니다. + +## Continuous + +여러 도구들이 지속적인 프로세스를 달성하는 데 도움을 줍니다. 이 모든 코드와 클라우드 인프라 또는 모든 환경을 완전히 자동화하는 것이 궁극적인 목표이며, 이를 지속적 통합/지속적 배포/지속적 배포 또는 줄여서 "CI/CD"로 설명하기도 합니다. 이번에는 90일 후에 CI/CD에 대한 기본 사항을 예제와 함께 배울 수 있는 워크숍을 제공할 예정입니다. + +### Continuous Delivery + +Continuous Delivery = 계획 > 코드 작성 > 빌드 > 테스트 + +### Continuous Integration + +이는 위에서 설명한 지속적 배포 단계와 릴리스 단계의 결과를 합친 것입니다. 이 단계는 성공과 실패 모두에 해당하며, 지속적 배포를 통해 피드백을 받거나 지속적 배포로 진행될 수 있습니다. + +Continuous Integration = 계획 > 코드 > 빌드 > 테스트 > 릴리즈 + +### Continuous Deployment + +성공적인 CI 릴리스 후, CD 단계로 이동합니다. + +성공적인 CI 릴리즈 = Continuous Deployment = 배포 > 운영 > 모니터링 + +위의 세 가지 개념은 데브옵스 라이프사이클의 각 단계를 간단히 정리한 것으로 볼 수 있습니다. + +이전에 다룬 Day 3 를 약간 요약했었지만, 이제는 더 이해하기 쉬워진 것 같습니다. + +### 자료 + +- [DevOps for Developers – Software or DevOps Engineer?](https://www.youtube.com/watch?v=a0-uE3rOyeU) +- [Techworld with Nana -DevOps Roadmap 2022 - How to become a DevOps Engineer? What is DevOps?](https://www.youtube.com/watch?v=9pZ2xmsSDdo&t=125s) +- [How to become a DevOps Engineer in 2021 - DevOps Roadmap](https://www.youtube.com/watch?v=5pxbp6FyTfk) + +여기까지 왔다면 이 여정이 자신이 찾던 여정인지 아닌지를 판단할 수 있을 것입니다. + +[Day 6](day06.md)에서 봐요! diff --git a/2022/ko/Days/day06.md b/2022/ko/Days/day06.md new file mode 100644 index 0000000..dff2b35 --- /dev/null +++ b/2022/ko/Days/day06.md @@ -0,0 +1,75 @@ +--- +title: '#90DaysOfDevOps - DevOps - The real stories - Day 6' +published: false +description: 90DaysOfDevOps - DevOps - The real stories +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048855 +--- + +## 데브옵스 - 실제 사례 + +처음에는 넷플릭스나 포춘지 선정 500대 기업처럼 데브옵스를 실행하는 기업이 없었기 때문에 많은 사람들이 데브옵스를 쉽게 접하기 어려웠습니다. 그러나 현재는 많은 기업이 데브옵스를 도입하면서, 데브옵스가 점차 일상적인 개발 방법으로 자리 잡게 되었다고 생각합니다. + +뒤에 나올 예시를 통해 다양한 산업과 업종에서 DevOps를 적용하고 있으며, 이로 인해 비즈니스의 목표 달성에 큰 긍정적인 영향을 미치고 있다는 것을 알 수 있습니다. + +여기서 가장 중요한 이점은 데브옵스를 올바르게 수행하면, 비즈니스의 소프트웨어 개발 속도와 품질을 개선하는 데 큰 도움이 된다는 것입니다. + +저는 오늘 이 자리를 통해, 데브옵스를 성공적으로 도입한 기업들의 사례를 살펴보고 이와 관련된 몇 가지 리소스를 공유하고자 합니다. 이 자리는 여러분들이 함께 참여하여, 서로 도움을 주고받을 수 있는 좋은 기회가 될 것입니다. 여러분의 비즈니스에 데브옵스 문화를 도입하셨나요? 그렇다면, 성공적이었나요? + +앞서 언급한 넷플릭스는 매우 좋은 사례이며, 오늘날 우리가 일반적으로 볼 수 있는 것들과 비교하면 상당히 발전된 모델입니다. 그러나, 성공하고 있는 다른 대형 브랜드들에 대해서도 언급하고자 합니다. + +## Amazon + +2010년에 아마존은 물리적 서버 공간을 AWS(Amazon Web Services) 클라우드로 이전하여, 아주 작은 단위로 용량을 확장하거나 축소함으로써 리소스를 절약할 수 있게 되었습니다. 이를 통해 아마존은 리테일 지점을 운영하면서 뿐만 아니라, AWS 자체적으로도 높은 수익을 창출하게 되었다는 사실도 알려져 있습니다. + +아마존은 2011년에 (자료를 통해 확인할 수 있는 바와 같이) 지속적인 배포 프로세스를 채택하여, 개발자가 원할 때 필요한 서버에 코드를 배포할 수 있게 되었습니다. 이를 통해 아마존은 새로운 소프트웨어를 평균 11.6초 만에 프로덕션 서버에 배포할 수 있게 되었습니다! + +## Netflix + +넷플릭스를 사용하지 않는 사람이 있을까요? 그들은 고품질의 스트리밍 서비스를 제공하며, 개인적으로도 훌륭한 사용자 경험을 제공합니다. + +사용자 경험이 왜 그렇게 좋을까요? 글쎄요, 기억에 남는 결함 없이 서비스를 제공하려면 속도, 유연성, 품질에 대한 관심이 필요합니다. + +넷플릭스 개발자는 IT 운영에 의존하지 않고도 배포 가능한 웹 이미지로 코드를 자동으로 빌드할 수 있습니다. 이미지가 업데이트되면 맞춤형으로 구축된 웹 기반 플랫폼을 사용하여 넷플릭스 인프라에 통합됩니다. + +이미지 배포에 실패하면, 롤백 되어 이전 버전으로 트래픽이 다시 라우팅 되도록 지속적인 모니터링이 이루어집니다. + +Netflix 팀 내에서 수행해야 할 일과 수행하지 말아야 할 일에 대해 자세히 설명하는 훌륭한 강연이 뒤에 있습니다. + +## Etsy + +많은 회사에서는 배포가 느리고 고통스러워서 어려움을 겪는 경우가 많습니다. 이와 관련하여, 많은 팀이 사일로에 갇혀 협력하지 못하는 문제가 있습니다. + +Amazon과 Netflix에 관한 글을 읽으면서 알게 된 것 중 하나는, Etsy가 2009년 말에 이미 개발자가 코드를 배포할 수 있도록 해뒀을 가능성이 높다는 것입니다. 이는 다른 두 회사보다 훨씬 앞선 시기였습니다. (흥미로운 사실이죠!) + +더 흥미로운 점은, 개발자가 배포 책임감을 느낄 때 애플리케이션 성능, 가동 시간 및 기타 목표에 대한 책임감도 함께 갖게 된다는 것을 깨달았다는 것입니다. + +학습 문화는 데브옵스의 핵심적인 부분입니다. 실패를 통해 교훈을 얻는다면, 실패도 성공으로 이어질 수 있다는 내용은 인용된 것 같지만, 어느 정도 일리가 있는 것 같습니다! + +일부 대규모 기업에서는 데브옵스가 판도를 바꾼 다른 사례도 뒤에 추가했습니다. + +## 자료 + +- [How Netflix Thinks of DevOps](https://www.youtube.com/watch?v=UTKIT6STSVM) +- [16 Popular DevOps Use Cases & Real Life Applications [2021]](https://www.upgrad.com/blog/devops-use-cases-applications/) +- [DevOps: The Amazon Story](https://www.youtube.com/watch?v=ZzLa0YEbGIY) +- [How Etsy makes DevOps work](https://www.networkworld.com/article/2886672/how-etsy-makes-devops-work.html) +- [Adopting DevOps @ Scale Lessons learned at Hertz, Kaiser Permanente and lBM](https://www.youtube.com/watch?v=gm18-gcgXRY) +- [Interplanetary DevOps at NASA JPL](https://www.usenix.org/conference/lisa16/technical-sessions/presentation/isla) +- [Target CIO explains how DevOps took root inside the retail giant](https://enterprisersproject.com/article/2017/1/target-cio-explains-how-devops-took-root-inside-retail-giant) + +### 데브옵스에 대해 살펴본 첫 며칠의 요약 + +- 데브옵스는 전체 애플리케이션 개발 라이프사이클인 **개발**, **테스트**, **배포**, **운영**을 단일 팀이 관리할 수 있도록 하는 개발과 운영의 조합입니다. + +- 데브옵스의 주요 초점과 목표는 개발 라이프사이클을 단축하면서도 비즈니스 목표와 긴밀하게 연계하여 기능 및 수정 사항을 자주 제공하는 것입니다. + +- 데브옵스는 소프트웨어를 안정적이고 신속하게 배포하고 개발할 수 있는 소프트웨어 개발 접근 방식으로, 이를 **지속적인 개발, 테스트, 배포, 모니터링**이라고도 합니다. + +여기까지 왔다면 이 여정이 자신이 찾던 여정인지 아닌지를 판단할 수 있을 것입니다. [Day 7](day07.md)에 뵙겠습니다. + +Day 7 에서는 개발자가 되는 것이 목표가 아니라, 개발자들이 하는 일을 이해할 수 있도록 프로그래밍 언어에 대해 알아보게 됩니다. + +일주일 안에 모든 것을 배울 수는 없겠지만, 7일 또는 7시간 동안 무언가를 배운다면 처음 시작할 때보다 더 많은 것을 알게 될 것입니다. diff --git a/2022/ko/Days/day07.md b/2022/ko/Days/day07.md new file mode 100644 index 0000000..b901e8d --- /dev/null +++ b/2022/ko/Days/day07.md @@ -0,0 +1,71 @@ +--- +title: '#90DaysOfDevOps - The Big Picture: Learning a Programming Language - Day 7' +published: false +description: 90DaysOfDevOps - The Big Picture DevOps & Learning a Programming Language +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048856 +--- + +## 큰 그림: 데브옵스 및 프로그래밍 언어 학습 + +장기적으로 데브옵스 엔지니어로 성공하려면, 적어도 하나의 프로그래밍 언어를 기초 수준에서 이해하는 것이 매우 중요합니다. 이번 섹션에서는 이러한 중요성에 대해 자세히 알아보고, 이번 주나 섹션이 끝날 때까지 학습 계획을 수립하기 위해 왜, 어떻게, 무엇을 해야 하는지 더 잘 이해하도록 합니다. + +소셜 미디어에서 데브옵스 관련 직무를 수행하기 위해 프로그래밍 기술이 필요한지 묻는다면 대부분 '그렇다'고 대답할 것입니다. 하지만 이러한 역할을 위해 어떤 프로그래밍 언어를 배워야 하는지에 대한 질문은 대답하기 어렵습니다. 일반적으로 Python을 추천하지만, Go(Golang)를 추천하는 경우도 점점 늘어나고 있습니다. + +제 생각에는 데브옵스에서 성공하려면 프로그래밍 기술에 대한 탄탄한 기초를 갖추는 것이 중요합니다. 그러나 이러한 기술이 왜 필요한지 이해해야 목표를 달성하기 위한 적절한 길을 선택할 수 있습니다. + +## 프로그래밍 언어를 배워야 하는 이유를 이해합니다. + +데브옵스에서 사용되는 대부분의 도구가 Python 또는 Go로 작성되어 있기 때문에 데브옵스 엔지니어에게 Python과 Go를 자주 권장합니다. 이러한 도구를 만들거나 이러한 도구를 만드는 팀에 합류하는 데 관심이 있다면 데브옵스 도구를 만드는 데 사용되는 언어를 배우는 것이 좋습니다. Kubernetes나 컨테이너에 많이 관여하고 있다면 프로그래밍 언어로 Go를 배우는 것이 더 유리할 수 있습니다. 제 경우에는 클라우드 네이티브 에코시스템에 속해 있으며 Kubernetes의 데이터 관리에 중점을 두는 회사로, 모든 도구가 Go로 작성되어 있는 Kasten by Veeam에서 일하고 있습니다. + +아직 명확한 결정이 내려지지 않은 학생이나 경력 전환기의 경우, 진로를 선택하는 것이 쉽지 않을 수 있습니다. 이런 상황에서는 자신이 만들고 싶은 애플리케이션과 가장 잘 맞고 가장 공감할 수 있는 것을 선택하는 것이 가장 좋습니다. + +저는 소프트웨어 개발자가 되고자 하는 것이 아닙니다. 프로그래밍 언어에 대한 기본적인 이해를 바탕으로 다양한 도구의 기능을 이해하고 이를 개선할 수 있는 방법을 찾는 것이 목표입니다. + +Kasten K10이나 Terraform, HCL과 같은 데브옵스 도구와 상호 작용하는 방법을 이해하는 것이 중요합니다. 이는 일반적으로 YAML로 작성되는 구성 파일을 통해 이루어집니다. 이러한 파일을 통해 DevOps 도구로 작업을 수행할 수 있습니다. (이 섹션의 마지막 날에는 YAML에 대해 더 자세히 살펴보겠습니다.) + +## 제가 방금 프로그래밍 언어를 배우지 말라고 설득한 건가요? + +많은 경우, 데브옵스 엔지니어의 주된 책임은 엔지니어링 팀과 협력하여 데브옵스 관행을 workflow에 통합하는 것입니다. 여기에는 애플리케이션에 대한 광범위한 테스트와 workflow가 앞서 설명한 데브옵스 원칙을 준수하는지 확인하는 작업인 경우가 많습니다. 그러나 작업의 상당 부분에는 애플리케이션 성능 또는 기타 기술적 결함과 관련된 문제 해결도 포함될 수 있습니다. 따라서 작업 중인 애플리케이션에서 사용하는 프로그래밍 언어에 대한 전문 지식을 갖추는 것이 중요합니다. 예를 들어, 애플리케이션이 Node.js로 작성된 경우 Go나 Python을 알아도 별 도움이 되지 않습니다. + +## 왜 Go인가요? + +Go가 데브옵스를 위한 유망한 프로그래밍 언어인 이유. Go는 최근 몇 년 동안 상당한 인기를 얻었으며, 2021년 StackOverflow 설문조사에서 가장 선호하는 프로그래밍, 스크립팅 및 마크업 언어 중 하나로 4위에 올랐고, 1위는 Python이었습니다. 자세히 살펴보겠습니다. [StackOverflow 2021 Developer Survey – Most Wanted Link](https://insights.stackoverflow.com/survey/2021#section-most-loved-dreaded-and-wanted-programming-scripting-and-markup-languages) + +앞서 언급했듯이, Kubernetes, Docker, Grafana, Prometheus 등 가장 잘 알려진 데브옵스 도구 및 플랫폼 중 일부는 Go로 작성되었습니다. + +데브옵스 목적에 특히 적합한 Go의 주요 기능이나 특성은 무엇일까요? + +## Go 프로그램 구축 및 배포 + +데브옵스 역할에서 Python과 같은 언어를 사용하면 프로그램을 실행하기 전에 컴파일할 필요가 없다는 이점이 있습니다. 빌드 프로세스가 길어지면 불필요하게 프로세스 속도가 느려질 수 있으므로 소규모 자동화 작업에 특히 유용합니다. Go는 컴파일 언어이긴 하지만 **머신 코드로 직접 컴파일되며** 컴파일 시간이 빠른 것으로 알려져 있다는 점에 집중할 필요가 있습니다. + +## 데브옵스를 위한 Go vs Python + +Go 프로그램은 정적으로 링크됩니다. 즉, Go 프로그램을 컴파일할 때 모든 것이 단일 바이너리 실행 파일에 포함되며 원격 시스템에 외부 종속성을 설치할 필요가 없습니다. 따라서 외부 라이브러리에 의존하는 경우가 많은 Python 프로그램에 비해 Go 프로그램을 더 쉽게 배포할 수 있습니다. Python을 사용하면 프로그램을 실행하려는 원격 머신에 필요한 모든 라이브러리가 설치되어 있는지 확인해야 합니다. + +Go는 특정 플랫폼에 종속되지 않는 언어이기 때문에 Linux, Windows, macOS 등 \*다양한 운영 체제용 바이너리 실행 파일을 쉽게 만들 수 있습니다. 반면에 Python으로 특정 운영 체제용 바이너리 실행 파일을 생성하는 것은 더 어려울 수 있습니다. + +Go는 Python에 비해 컴파일 및 실행 시간이 빠르고 CPU와 메모리 측면에서 리소스 소비가 적은 매우 효율적인 프로그래밍 언어입니다. 이 언어에는 다양한 최적화가 구현되어 있어 뛰어난 성능을 제공합니다. (자세한 내용은 아래 리소스를 참조하세요.) + +특정 프로그래밍 작업을 위해 종종 서드파티 라이브러리에 의존하는 Python에 비해 Go에는 데브옵스에 필요한 대부분의 기능을 바로 사용할 수 있는 표준 라이브러리가 있습니다. 여기에는 파일 처리, HTTP 웹 서비스, JSON 처리, 동시성 및 병렬 처리를 위한 기본 지원, 심지어 테스트 기능까지 포함됩니다. + +제가 Go를 선택한 이유는 파이썬을 비판하기 위해서가 아니라는 점을 분명히 말씀드리고 싶습니다. 제가 근무하는 회사에서 Go로 소프트웨어를 개발하기 때문에 Go를 사용하는 것이 합리적입니다. + +프로그래밍 언어 하나를 배우면 다른 언어를 배우기가 더 쉬워진다는 말을 들었습니다. 어느 회사에서든 자바스크립트 및 Node.js 애플리케이션을 관리, 설계, 오케스트레이션, 디버깅하게 될 가능성이 있고, 지금 Go를 배워두면 도움이 될 것입니다. + +## 자료 + +- [StackOverflow 2021 Developer Survey](https://insights.stackoverflow.com/survey/2021) +- [Why we are choosing Golang to learn](https://www.youtube.com/watch?v=7pLqIIAqZD4&t=9s) +- [Jake Wright - Learn Go in 12 minutes](https://www.youtube.com/watch?v=C8LgvuEBraI&t=312s) +- [Techworld with Nana - Golang full course - 3 hours 24 mins](https://www.youtube.com/watch?v=yyUHQIec83I) +- [**NOT FREE** Nigel Poulton Pluralsight - Go Fundamentals - 3 hours 26 mins](https://www.pluralsight.com/courses/go-fundamentals) +- [FreeCodeCamp - Learn Go Programming - Golang Tutorial for Beginners](https://www.youtube.com/watch?v=YS4e4q9oBaU&t=1025s) +- [Hitesh Choudhary - Complete playlist](https://www.youtube.com/playlist?list=PLRAV69dS1uWSR89FRQGZ6q9BR2b44Tr9N) + +앞으로 6일 동안 위에서 언급한 자료를 공부하고 매일 진행 상황을 메모할 계획입니다. 전체 과정은 약 3시간 정도 걸리지만, 저는 이 학습에 하루 한 시간씩 할애할 예정입니다. 시간이 여유가 있으신 분들도 함께 하며 깊이 있게 공부하실 수 있도록 전체 리소스 목록을 공유해 드립니다. + +[Day 8](day08.md)에서 봐요! diff --git a/2022/ko/Days/day08.md b/2022/ko/Days/day08.md new file mode 100644 index 0000000..e9c9705 --- /dev/null +++ b/2022/ko/Days/day08.md @@ -0,0 +1,118 @@ +--- +title: '#90DaysOfDevOps - Setting up your DevOps environment for Go & Hello World - Day 8' +published: false +description: 90DaysOfDevOps - Setting up your DevOps environment for Go & Hello World +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048857 +--- + +## Go를 위한 데브옵스 환경 설정 및 Hello World + +Go 언어에 대한 몇 가지 기본 사항을 살펴보기 전에, 먼저 컴퓨터에 Go를 설치하고 모든 "learning programming 101" 모듈에서 가르치는 Hello World 앱을 만들어야 합니다. 이 문서에서는 컴퓨터에 Go를 설치하는 단계를 안내하며, 그림으로 문서화하여 사람들이 쉽게 따라 할 수 있도록 하겠습니다. + +먼저, [go.dev/dl](https://go.dev/dl/)로 이동하면 다운로드할 수 있는 몇 가지 옵션이 나타납니다. + +![](/2022/Days/Images/Day8_Go1.png) + +여기까지 오셨다면, 현재 사용 중인 컴퓨터의 운영 체제를 확인하고 해당하는 다운로드를 선택하여 설치를 시작하시면 됩니다. 제가 사용하는 운영 체제는 Windows입니다. 기본적으로 다음 화면부터는 모든 기본값을 그대로 두어도 됩니다. **(최신 버전이 나오면 스크린샷과 다르게 나올 수도 있으니 참고해주세요.)** + +![](/2022/Days/Images/Day8_Go2.png) + +만약 이전 버전의 Go가 설치되어 있다면, 먼저 해당 버전을 제거해야 합니다. Windows에서는 이를 위한 내장 제거 기능을 제공하며, 이를 통해 이전 버전을 제거하고 하나의 설치 프로그램으로 설치할 수 있습니다. + +작업을 완료한 후 명령 프롬프트/터미널을 열어서 Go가 설치되어 있는지 확인해야 합니다. 만약 아래와 같은 출력이 표시되지 않았다면, Go가 설치되지 않은 것이므로 단계를 되짚어봐야 합니다. + +`go version` + +![](/2022/Days/Images/Day8_Go3.png) + +다음으로 Go 환경변수를 확인하겠습니다. 작업 디렉토리가 올바르게 구성되었는지 항상 확인하는 것이 좋으므로, 아래 디렉토리가 시스템에 있는지 확인해야 합니다. + +![](/2022/Days/Images/Day8_Go4.png) + +확인하셨나요? 지금까지 잘 따라오고 있나요? 해당 디렉토리로 이동하면 아래와 같은 메시지가 나타납니다. + +![](/2022/Days/Images/Day8_Go5.png) + +그럼 PowerShell 터미널에서 mkdir 명령어를 사용하여 디렉토리를 만들어 보겠습니다. 또한, 아래에서 보이듯이 Go 폴더 내에 3개의 폴더를 생성해야 합니다. + +![](/2022/Days/Images/Day8_Go6.png) + +이제 Go를 설치하고 작업 디렉토리를 준비했습니다. 이제 통합 개발 환경(IDE)이 필요합니다. 사용 가능한 IDE는 여러 가지가 있지만, 가장 일반적이고 제가 사용하는 것은 VSCode(Visual Studio Code)입니다. IDE에 대한 자세한 내용은 [여기](https://www.youtube.com/watch?v=vUn5akOlFXQ)에서 확인할 수 있습니다. _(엄밀히 말하면 VSCode는 IDE가 아닌 코드 에디터입니다. - 옮긴이)_ + +만약 컴퓨터에 아직 VSCode를 다운로드하고 설치하지 않았다면, [여기](https://code.visualstudio.com/download)로 이동하여 설치할 수 있습니다. 아래에서 확인할 수 있는 것처럼, 다양한 운영체제를 제공됩니다. + +![](/2022/Days/Images/Day8_Go7.png) + +Go 설치와 마찬가지로, 기본값으로 다운로드하여 설치합니다. 설치가 완료되면, 파일 열기를 선택하고 Go 디렉토리를 만들었던 곳으로 이동하여 VSCode를 열 수 있습니다. + +![](/2022/Days/Images/Day8_Go8.png) + +신뢰에 관한 팝업이 표시될 수 있는데, 원한다면 이를 읽고 '예, 작성자를 신뢰합니다'를 누르세요. (나중에 신뢰하지 않는 파일을 열기 시작해도 저는 책임지지 않습니다!) + +이전에 만든 세 개의 폴더를 모두 볼 수 있습니다. 이제 `src` 폴더를 마우스 오른쪽 버튼으로 클릭하고 `Hello`라는 새 폴더를 생성하겠습니다. + +![](/2022/Days/Images/Day8_Go9.png) + +여기까지는 꽤 쉬운 내용이었죠? 이제 다음 단계에서는 아무것도 이해하지 못한 상태에서 첫 번째 Go 프로그램을 만들 것입니다. + +다음으로, `Hello` 폴더에 `main.go` 파일을 생성합니다. `main.go` 파일을 열고 Enter 키를 누르면 Go 확장 프로그램과 패키지를 설치할 것인지 묻는 메시지가 나타납니다. 이전에 만든 빈 `pkg` 폴더를 확인하면 이제 새로운 패키지가 추가된 것을 확인할 수 있습니다. + +![](/2022/Days/Images/Day8_Go10.png) + +이제 Hello World 앱을 실행하고 다음 코드를 새 `main.go` 파일에 복사하여 저장해 보겠습니다. + +```go +package main + +import "fmt" + +func main() { + fmt.Println("Hello #90DaysOfDevOps") +} +``` + +이해가 어려울 수도 있지만, 함수, 패키지 등에 대해 더 자세하게 다룰 예정입니다. 현재는 앱을 실행해보겠습니다. 터미널에서 `Hello` 폴더로 돌아가서 제대로 작동하는지 확인할 수 있습니다. 다음 명령을 사용하여 프로그램이 제대로 작동하는지 확인할 수 있습니다. + +``` +go run main.go +``` + +![](/2022/Days/Images/Day8_Go11.png) + +여기서 끝이 아닙니다. 다른 Windows 컴퓨터에서 이 프로그램을 실행하려면 어떻게 해야 할까요? 다음 명령을 사용하여 바이너리로 빌드하면 됩니다. + +``` +go build main.go +``` + +![](/2022/Days/Images/Day8_Go12.png) +_(Mac 운영체제의 경우 `main` 파일이 생성됩니다. - 옮긴이)_ + +이를 실행한다면 동일한 결과를 볼 수 있습니다: + +```bash +# Windows +$ ./main.exe +Hello #90DaysOfDevOps + +# Mac - 올긴이 +$ ./main +Hello #90DaysOfDevOps +``` + +## 자료 + +- [StackOverflow 2021 Developer Survey](https://insights.stackoverflow.com/survey/2021) +- [Why we are choosing Golang to learn](https://www.youtube.com/watch?v=7pLqIIAqZD4&t=9s) +- [Jake Wright - Learn Go in 12 minutes](https://www.youtube.com/watch?v=C8LgvuEBraI&t=312s) +- [Techworld with Nana - Golang full course - 3 hours 24 mins](https://www.youtube.com/watch?v=yyUHQIec83I) +- [**NOT FREE** Nigel Poulton Pluralsight - Go Fundamentals - 3 hours 26 mins](https://www.pluralsight.com/courses/go-fundamentals) +- [FreeCodeCamp - Learn Go Programming - Golang Tutorial for Beginners](https://www.youtube.com/watch?v=YS4e4q9oBaU&t=1025s) +- [Hitesh Choudhary - Complete playlist](https://www.youtube.com/playlist?list=PLRAV69dS1uWSR89FRQGZ6q9BR2b44Tr9N) + +[Day 9](day09.md)에서 봐요! + +![](/2022/Days/Images/Day8_Go13.png) diff --git a/2022/ko/Days/day09.md b/2022/ko/Days/day09.md new file mode 100644 index 0000000..798d0d8 --- /dev/null +++ b/2022/ko/Days/day09.md @@ -0,0 +1,82 @@ +--- +title: "#90DaysOfDevOps - Let's explain the Hello World code - Day 9" +published: false +description: 90DaysOfDevOps - Let's explain the Hello World code +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1099682 +--- + +## Hello World 코드를 설명해 보겠습니다. + +### Go 작동 방식 + +[Day 8](day08.md)에서는 컴퓨터에 Go를 설치하는 방법을 안내하고, 그 후 첫 번째 Go 애플리케이션을 만들었습니다. + +이 섹션에서는 코드를 더 자세히 살펴보고 Go 언어를 더 잘 이해해보겠습니다. + +### 컴파일이 무엇인가요? + +[Hello World 코드](/2022/Days/Go/hello.go)를 이해하기 전에 컴파일에 대한 이해가 필요합니다. + +파이썬, 자바, Go, C++ 등은 우리가 일반적으로 사용하는 고수준 프로그래밍 언어입니다. 이는 사람이 이해하기 쉽지만, 기계가 실행하기 위해서는 기계가 이해할 수 있는 형태로 변환되어야 합니다. 이러한 변환 작업을 컴파일이라고 합니다. 컴파일은 사람이 작성한 코드를 기계가 이해할 수 있는 코드로 변환하는 과정입니다. + +![](/2022/Days/Images/Day9_Go1.png) + +이전에 [Day 8](day08.md)에서 수행한 작업을 위 그림으로 확인할 수 있습니다. 우선 간단한 Hello World를 출력하는 main.go를 작성하고, 이를 `go build main.go` 명령을 사용하여 실행 파일로 컴파일했습니다. + +### 패키지가 무엇인가요? + +패키지는 같은 디렉토리에 있는 여러 개의 .go 확장자 파일의 모음으로 구성됩니다. 더 간단히 말하면, 패키지는 같은 디렉토리 내에서 함께 컴파일되는 소스 파일들입니다. 또한, 더 복잡한 Go 프로그램에서는 여러 패키지가 폴더1, 폴더2, 폴더3 등에 분산되어 있을 수 있으며, 각 패키지는 서로 다른 .go 파일들로 이루어질 수 있습니다. + +패키지를 사용하면 다른 사람들의 코드를 재사용하여 처음부터 모든 것을 새로 작성할 필요가 없어집니다. 만약 프로그램에서 계산기가 필요하다면, 기존에 Go 언어로 작성된 패키지에서 수학 함수를 가져와 코드에 적용시키면 장기적으로 많은 시간과 노력을 절약할 수 있습니다. + +Go 언어는 코드를 패키지로 구성하여 소스 코드의 재사용성과 유지 보수성을 쉽게 확보할 수 있도록 권장합니다. + +### Hello #90DaysOfDevOps 한 줄 한 줄 + +이제 Hello #90DaysOfDevOps main.go 파일을 살펴보겠습니다. + +![](/2022/Days/Images/Day9_Go2.png) + +Go 언어에서는 모든 .go 파일은 패키지에 속해야 하며, `package something`과 같이 첫 줄에 패키지 이름을 명시해야 합니다. 이때, `package main`은 이 파일이 main 함수를 포함하는 패키지임을 나타냅니다. + +패키지 이름은 원하는 대로 지정할 수 있습니다. 하지만 이 프로그램 시작점에서의 패키지는 `main`으로 지정해야 하며, 이는 규칙입니다. (이 규칙에 대해 추가적인 이해가 필요한가요?) + +![](/2022/Days/Images/Day9_Go3.png) + +코드를 컴파일하고 실행할 때, 시작해야 하는 위치를 컴퓨터에게 알려주어야 합니다. 이를 위해 'main'이라는 함수를 작성합니다. 컴퓨터는 프로그램의 시작점을 찾기 위해 'main' 함수를 찾습니다. + +함수는 특정 작업을 수행하는 코드 블록으로, 프로그램 전체에서 사용할 수 있습니다. + +`func`를 사용하여 함수를 어떤 이름으로든 선언할 수 있지만, 이 경우 코드가 시작되는 곳이므로 `main`이라는 이름을 지정해야 합니다. + +![](/2022/Days/Images/Day9_Go4.png) + +다음으로, 코드의 세 번째 줄인 'import'를 살펴보겠습니다. 이 줄은 메인 프로그램에 다른 패키지를 가져오고자 하는 것을 의미합니다. 'fmt'는 Go에서 제공하는 표준 패키지 중 하나이며, `Println()` 함수를 포함하고 있기 때문에, 이를 'import' 했으므로 여섯 번째 줄에서 이 함수를 사용할 수 있습니다. 프로그램에서 사용하거나 재사용할 수 있는 여러 표준 패키지가 있으므로, 처음부터 작성해야 하는 번거로움을 줄일 수 있습니다. [Go Standard Library](https://pkg.go.dev/std) + +![](/2022/Days/Images/Day9_Go5.png) + +여기에 있는 `Println()`은 실행 파일이 성공적으로 실행됐을 때 터미널에 STDOUT(standard output)을 출력하는 함수입니다. 괄호 안에는 원하는 메시지를 자유롭게 입력할 수 있습니다. + +![](/2022/Days/Images/Day9_Go6.png) + +### TLDR + +- **1행** = 이 파일은 `main` 패키지에 있으며, 프로그램의 진입점을 포함하고 있으므로 `main`으로 불러야 합니다. +- **3행** = `Println()`을 사용하려면 6행에서 'fmt' 패키지를 'import'하여야 합니다. +- **5행** = 프로그램의 실제 시작점은 `main` 함수입니다. +- **6행** = 이렇게 하면 시스템에 "Hello #90DaysOfDevOps"을 출력할 수 있습니다. + +## 자료 + +- [StackOverflow 2021 Developer Survey](https://insights.stackoverflow.com/survey/2021) +- [Why we are choosing Golang to learn](https://www.youtube.com/watch?v=7pLqIIAqZD4&t=9s) +- [Jake Wright - Learn Go in 12 minutes](https://www.youtube.com/watch?v=C8LgvuEBraI&t=312s) +- [Techworld with Nana - Golang full course - 3 hours 24 mins](https://www.youtube.com/watch?v=yyUHQIec83I) +- [**NOT FREE** Nigel Poulton Pluralsight - Go Fundamentals - 3 hours 26 mins](https://www.pluralsight.com/courses/go-fundamentals) +- [FreeCodeCamp - Learn Go Programming - Golang Tutorial for Beginners](https://www.youtube.com/watch?v=YS4e4q9oBaU&t=1025s) +- [Hitesh Choudhary - Complete playlist](https://www.youtube.com/playlist?list=PLRAV69dS1uWSR89FRQGZ6q9BR2b44Tr9N) + +[Day 10](day10.md)에서 봐요! diff --git a/2022/ko/Days/day10.md b/2022/ko/Days/day10.md new file mode 100644 index 0000000..6db4c02 --- /dev/null +++ b/2022/ko/Days/day10.md @@ -0,0 +1,99 @@ +--- +title: '#90DaysOfDevOps - The Go Workspace - Day 10' +published: false +description: 90DaysOfDevOps - The Go Workspace +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048701 +--- + +### Go 워크스페이스 + +[Day 8](day08.md)에서 Go 워크스페이스를 간략히 살펴보고 'Hello #90DaysOfDevOps'의 데모를 실행했습니다. 그러나 Go 워크스페이스에 대해 좀 더 자세히 설명해야 합니다. + +기본값을 선택한 다음 이미 정의된 GOPATH에 Go 폴더가 생성됐지만, 실제로는 이 GOPATH를 원하는 위치로 변경할 수 있습니다. + +다음 명령어를 실행하면 + +``` +echo $GOPATH +``` + +출력은 다음과 유사해야 합니다.(사용자 아이디가 다를 수 있습니다.) + +``` +/home/michael/projects/go +``` + +그런 다음 여기에 3개의 디렉토리를 생성했습니다. **src**, **pkg**, **bin**. + +![](/2022/Days/Images/Day10_Go1.png) + +**src**는 Go 프로그램과 프로젝트를 저장하는 곳으로, 모든 Go 리포지토리의 네임스페이스 패키지 관리를 담당합니다. 컴퓨터에서 Hello #90DaysOfDevOps 프로젝트를 위한 Hello 폴더를 확인할 수 있습니다. + +![](/2022/Days/Images/Day10_Go2.png) + +**pkg**는 프로그램에 설치되거나 설치되었던 패키지의 파일을 저장하는 곳입니다. 이것은 사용 중인 패키지가 수정되었는지 여부에 따라 컴파일 프로세스의 속도를 향상하는 데 도움이 됩니다. + +![](/2022/Days/Images/Day10_Go3.png) + +**bin**은 컴파일된 모든 바이너리가 저장되는 곳입니다. + +![](/2022/Days/Images/Day10_Go4.png) + +Hello #90DaysOfDevOps는 복잡한 프로그램이 아니기 때문에, 다른 훌륭한 리소스인 [GoChronicles](https://gochronicles.com/)에서 가져온 좀 더 복잡한 Go 프로그램의 예시를 소개해 드리겠습니다. + +![](/2022/Days/Images/Day10_Go5.png) + +이 페이지는 [GoChronicles](https://gochronicles.com/project-structure/)에 언급되지 않은 다른 폴더에 대한 자세한 설명과 함께, 레이아웃이 왜 이렇게 구성되었는지에 대해 자세히 설명합니다. + +### 코드 컴파일 및 실행 + +[Day 9](day09.md)에서도 코드 컴파일에 대한 간략한 소개를 다루었지만, 이번에는 더 자세히 살펴보겠습니다. + +코드를 실행하기 위해서는 먼저 코드를 **컴파일**해야 합니다. Go에서 컴파일하는 방법은 세 가지가 있습니다. + +- go build +- go install +- go run + +컴파일을 진행하기 전에 Go를 설치하면 무엇을 얻을 수 있는지 살펴봅시다. + +8일 차에 Go를 설치하는 동안 Go 소스 파일의 빌드 및 처리를 용이하게 하는 다양한 프로그램으로 구성된 Go 도구를 얻었습니다. 이러한 도구 중 하나가 `Go`입니다. + +표준 Go 설치에 포함되지 않은 추가 도구도 설치할 수 있다는 점에 유의하세요. + +Go가 제대로 설치되었는지 확인하려면 명령 프롬프트를 열고 `go`를 입력합니다. 아래 이미지와 비슷한 내용이 표시되고 그 뒤에 "Additional Help Topics"가 표시됩니다. 현재로서는 이것에 대해 생각할 필요는 없습니다. + +![](/2022/Days/Images/Day10_Go6.png) + +8일째인 지금까지 이미 이 도구 중 최소 두 가지를 사용했다는 사실을 기억하실 겁니다. + +![](/2022/Days/Images/Day10_Go7.png) + +자세히 알고 싶은 것은 "build", "install", 그리고 "run"입니다. + +![](/2022/Days/Images/Day10_Go8.png) + +- `go run` - 이 명령은 command line에 지정한 .go 파일로 구성된 기본 패키지를 컴파일하고 실행합니다. 이때, 컴파일된 실행 파일은 임시 폴더에 저장됩니다. +- `go build` - 현재 디렉토리에서 패키지와 종속성을 컴파일합니다. 만약 프로젝트에 `main` 패키지가 포함되어 있다면, 실행 파일이 현재 디렉토리에 생성됩니다. 그렇지 않은 경우, 실행 파일은 `pkg` 폴더에 생성되며, 이후 다른 Go 프로그램에서 가져와서 사용할 수 있습니다. 또한 `go build`를 사용하면 Go가 지원하는 모든 OS 플랫폼에 대해 실행 파일을 빌드할 수 있습니다. +- `go install` - go build와 비슷하지만, 실행 파일을 `bin` 폴더에 저장합니다. + +`go build`과 `go run`을 실행했지만, 원하는 경우 이곳에서 다시 실행할 수 있습니다. `go install`은 실행 파일을 bin 폴더에 넣는 것으로 설명한 대로 수행됩니다. + +![](/2022/Days/Images/Day10_Go9.png) + +이 글을 따라오면서 아래의 재생 목록이나 동영상 중 하나를 시청하시기 바랍니다. 제 목표는 여러분과 함께하는 7일 또는 7시간 동안의 여정에서 제가 발견한 흥미로운 정보들을 공유하는 것이기에 저는 이 모든 자료에서의 핵심 정보를 모아서 Go 언어의 기본 개념을 설명하고자 합니다. 아래 자료들은 여러분이 이해해야 할 필수적인 주제에 대한 이해에 도움을 줄 수 있습니다. + +## 자료 + +- [StackOverflow 2021 Developer Survey](https://insights.stackoverflow.com/survey/2021) +- [Why we are choosing Golang to learn](https://www.youtube.com/watch?v=7pLqIIAqZD4&t=9s) +- [Jake Wright - Learn Go in 12 minutes](https://www.youtube.com/watch?v=C8LgvuEBraI&t=312s) +- [Techworld with Nana - Golang full course - 3 hours 24 mins](https://www.youtube.com/watch?v=yyUHQIec83I) +- [**NOT FREE** Nigel Poulton Pluralsight - Go Fundamentals - 3 hours 26 mins](https://www.pluralsight.com/courses/go-fundamentals) +- [FreeCodeCamp - Learn Go Programming - Golang Tutorial for Beginners](https://www.youtube.com/watch?v=YS4e4q9oBaU&t=1025s) +- [Hitesh Choudhary - Complete playlist](https://www.youtube.com/playlist?list=PLRAV69dS1uWSR89FRQGZ6q9BR2b44Tr9N) + +[Day 11](day11.md)에서 봐요! diff --git a/2022/ko/Days/day11.md b/2022/ko/Days/day11.md new file mode 100644 index 0000000..2bfe879 --- /dev/null +++ b/2022/ko/Days/day11.md @@ -0,0 +1,176 @@ +--- +title: '#90DaysOfDevOps - Variables & Constants in Go - Day 11' +published: false +description: 90DaysOfDevOps - Variables & Constants in Go +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048862 +--- + +오늘의 주제에 들어가기 전에, [Techworld with Nana](https://www.youtube.com/watch?v=yyUHQIec83I)에서 다룬 Go의 기초에 대한 환상적이고 간결한 여정에 대해 큰 박수를 보내고 싶습니다. + +[Day 8](day08.md)에는 환경을 설정하였고, [Day 9](day09.md)에는 Hello #90DaysOfDevOps 코드를 검토하였으며, [Day 10](day10.md)에는 Go 워크스페이스를 살펴보고 코드를 컴파일한 후 실행하는 과정까지 자세히 학습했습니다. + +오늘은 새로운 프로그램을 만들어보면서 변수, 상수 그리고 데이터 타입에 대해 살펴볼 예정입니다. + +## Go의 변수 및 상수 + +우선, 애플리케이션을 계획하는 것으로 시작하겠습니다. #90DaysOfDevOps 챌린지가 얼마나 남았는지 알려주는 프로그램을 만드는 것이 좋을 것 같습니다. + +프로그램을 실행하기 전에 고려해야 할 사항은 앱을 빌드하고 참가자를 환영하며 완료한 일 수에 대한 피드백을 줄 때 "#90DaysOfDevOps"이란 용어를 여러 번 사용할 수 있다는 것입니다. 이것은 프로그램에서 #90DaysOfDevOps를 변수로 사용할 좋은 상황입니다. + +- 변수는 값을 저장하기 위해 사용됩니다. +- 저장된 정보나 값이 담긴 작은 상자와 같은 것입니다. +- 변수는 프로그램 전체에서 사용할 수 있으며, 챌린지나 변수가 변경되더라도 한 곳에서만 변경하면 되는 장점이 있습니다. 즉, 변수 하나만 변경하면 커뮤니티의 다른 챌린지에도 적용할 수 있습니다. + +Go 프로그램에서는 변수를 선언하고 값을 정의하기 위해 **키워드(var, const...)**를 사용합니다. 이러한 변수 선언은 `func main` 코드 블록 내에서 이루어집니다. `키워드`에 대한 자세한 내용은 [여기](https://go.dev/ref/spec#Keywords)에서 확인할 수 있습니다. + +변수 이름이 명시적인지 항상 확인하세요. 변수를 선언하면 반드시 사용해야 하며, 그렇지 않으면 오류가 발생합니다. 이는 사용되지 않는 코드(죽은 코드)를 방지할 수 있습니다. 사용되지 않는 패키지도 마찬가지입니다. + +```go +var challenge = "#90DaysOfDevOps" +``` + +다음 코드 스니펫에서 볼 수 있듯이 위와 같이 선언하면 변수를 사용할 수 있음을 알 수 있습니다. + +```go +package main + +import "fmt" + +func main() { + var challenge = "#90DaysOfDevOps" + fmt.Println("Welcome to", challenge, "") +} +``` + +위 코드 스니펫은 [day11_example1.go](/2022/Days/Go/day11_example1.go)에서 볼 수 있습니다. + +위 예제를 사용하여 코드를 빌드하면 아래와 같이 출력되는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day11_Go1.png) + +이번 챌린지의 기간은 90일이지만, 다음 챌린지에서는 100일이 될 수도 있으므로, 이번 챌린지에서 사용되는 변수가 다음 챌린지에서도 유용하게 사용될 수 있도록 정의하고 싶습니다. 하지만 우리 프로그램에서는 이 변수를 상수로 정의하고자 합니다. 상수는 값을 변경할 수 없지만, 변수와 유사합니다.(이 코드를 사용하여 새로운 앱을 만들 경우 상수를 변경할 수 있지만, 애플리케이션을 실행하는 동안에는 이 90이 변경되지 않습니다.) + +`const` 키워드를 코드에 추가하고, 출력을 위해 다른 코드 라인을 추가합니다. + +```go +package main + +import "fmt" + +func main() { + var challenge = "#90DaysOfDevOps" + const daystotal = 90 + + fmt.Println("Welcome to", challenge, "") + fmt.Println("This is a", daystotal, "challenge") +} +``` + +위 코드 스니펫은 [day11_example2.go](/2022/Days/Go/day11_example2.go)에서 볼 수 있습니다. + +`go build`를 다시 실행하면 아래와 같은 결과를 확인할 수 있습니다. + +![](/2022/Days/Images/Day11_Go2.png) + +이것이 우리 프로그램의 끝은 아니며 [Day 12](day12.md)에서 더 많은 기능을 추가할 예정입니다. 현재 완료한 일 수 외에도 다른 변수를 추가하려고 합니다. + +`dayscomplete` 변수를 추가하였고, 완료한 일 수도 함께 기록하였습니다. + +```go +package main + +import "fmt" + +func main() { + var challenge = "#90DaysOfDevOps" + const daystotal = 90 + var dayscomplete = 11 + + fmt.Println("Welcome to", challenge, "") + fmt.Println("This is a", daystotal, "challenge and you have completed", dayscomplete, "days") + fmt.Println("Great work") +} +``` + +위 코드 스니펫은 [day11_example3.go](/2022/Days/Go/day11_example3.go)에서 볼 수 있습니다. + +`go build`를 다시 실행하거나 `go run`을 실행할 수 있습니다. + +![](/2022/Days/Images/Day11_Go3.png) + +코드를 더 쉽게 읽고 편집하기 위해 몇 가지 다른 예제입니다. 이전에는 `Println`을 사용했지만, `Printf`를 사용하여 코드 줄 끝에 변수를 순서대로 정의하는 `%v`를 사용하면 코드를 간단히 만들 수 있습니다. 또한 줄 바꿈은 `\n`을 사용합니다. + +기본값을 사용하기 때문에 `%v`를 사용하고 있지만, 다른 옵션은 [fmt package documentation](https://pkg.go.dev/fmt)의 코드 예제 [day11_example4.go](/2022/Days/Go/day11_example4.go)에서 확인할 수 있습니다. + +변수를 정의하는 방법 중에는 '변수'와 '타입'을 명시하는 대신 더 간단한 형태로 정의하는 것도 있습니다. 이렇게 코딩하면 코드의 기능은 동일하지만, 더 깔끔하고 간결해집니다. 하지만 이 방법은 변수에만 적용되며 상수에는 적용되지 않습니다. + +```go +func main() { + challenge := "#90DaysOfDevOps" + const daystotal = 90 +``` + +## 데이터 타입 + +예제에서는 변수의 타입을 정의하지 않았습니다. 이는 값을 지정하고 Go가 해당 타입을 유추할 수 있을 만큼 똑똑하거나 저장한 값에 기반하여 타입을 결정할 수 있기 때문입니다. 그러나 사용자가 입력하도록 하려면 특정 타입을 명시해야 합니다. + +지금까지 코드에서는 문자열과 정수를 사용했습니다. 정수는 일 수를, 문자열은 챌린지 이름을 나타내는 데 사용했습니다. + +각 데이터 타입은 서로 다른 작업을 수행하며, 이에 따라 다르게 작동한다는 것을 유의해야 합니다. 예를 들어, 정수는 문자열과는 곱할 수 없습니다. + +총 네 가지 타입이 있습니다: + +- **Basic type**: 숫자, 문자열, 불리언 값이 해당 범주에 속합니다. +- **Aggregate type**: 배열과 구조체가 해당 범주에 속합니다. +- **Reference type**: 포인터, 슬라이스, 맵, 함수, 채널이 해당 범주에 속합니다. +- **Interface type** + +데이터 타입은 프로그래밍에서 매우 중요한 개념입니다. 이는 변수의 크기와 타입을 지정하는 데 사용됩니다. + +Go는 정적으로 타입이 지정되어 있어서 변수의 타입이 정의된 후에는 해당 타입의 데이터만 저장할 수 있습니다. + +Go 언어에는 다음과 같이 세 가지 기본 데이터 타입이 있습니다: + +- **bool**: 참(True) 또는 거짓(False) 값을 나타냅니다. +- **Numeric**: 정수형(integer), 부동 소수점 값(floating-point), 복소수형(complex)을 나타냅니다. +- **string**: 문자열 값을 나타냅니다. + +[Golang by example](https://golangbyexample.com/all-data-types-in-golang-with-examples/)에서 데이터 타입에 대해 매우 자세하게 설명되어 있습니다. + +[Techworld with Nana](https://www.youtube.com/watch?v=yyUHQIec83I&t=2023s)에서도 데이터 타입에 대해 자세히 다루고 있으니 추천해드립니다. + +변수의 타입을 정의해야 하는 경우 다음과 같이 정의할 수 있습니다: + +```go +var TwitterHandle string +var DaysCompleted uint +``` + +Go 언어에서 변수는 값이 할당되는 것을 의미합니다. 따라서 해당 값을 출력하려면 다음과 같이 할 수 있습니다: + +```go +fmt.Printf("challenge is %T, daystotal is %T, dayscomplete is %T\n", conference, daystotal, dayscomplete) +``` + +여러 종류의 정수 및 부동 소수점 타입이 있으며, 앞의 링크들에서 자세한 내용을 확인할 수 있습니다. + +- **int** = 정수 +- **unint** = 양의 정수 +- **floating point types** = 소수점이 있는 실수 + +## 자료 + +- [StackOverflow 2021 Developer Survey](https://insights.stackoverflow.com/survey/2021) +- [Why we are choosing Golang to learn](https://www.youtube.com/watch?v=7pLqIIAqZD4&t=9s) +- [Jake Wright - Learn Go in 12 minutes](https://www.youtube.com/watch?v=C8LgvuEBraI&t=312s) +- [Techworld with Nana - Golang full course - 3 hours 24 mins](https://www.youtube.com/watch?v=yyUHQIec83I) +- [**NOT FREE** Nigel Poulton Pluralsight - Go Fundamentals - 3 hours 26 mins](https://www.pluralsight.com/courses/go-fundamentals) +- [FreeCodeCamp - Learn Go Programming - Golang Tutorial for Beginners](https://www.youtube.com/watch?v=YS4e4q9oBaU&t=1025s) +- [Hitesh Choudhary - Complete playlist](https://www.youtube.com/playlist?list=PLRAV69dS1uWSR89FRQGZ6q9BR2b44Tr9N) + +이제부터는 프로그램에 몇 가지 사용자 입력 기능을 추가해서 완료된 일수를 입력받도록 하겠습니다. + +[Day 12](day12.md)에서 봐요! diff --git a/2022/ko/Days/day12.md b/2022/ko/Days/day12.md new file mode 100644 index 0000000..72f7380 --- /dev/null +++ b/2022/ko/Days/day12.md @@ -0,0 +1,85 @@ +--- +title: '#90DaysOfDevOps - Getting user input with Pointers and a finished program - Day 12' +published: false +description: 90DaysOfDevOps - Getting user input with Pointers and a finished program +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048864 +--- + +## 포인터를 이용하여 사용자 입력을 받아 프로그램 완성하기 + +어제([Day 11](day11.md)) 독립적인 첫 번째 Go 프로그램을 만들 때, 코드 내에서 사용자 입력을 받기 위한 변수를 생성하고 값을 할당했습니다. 이제 사용자에게 입력을 요청하여 최종 메시지 값을 변수에 할당하려고 합니다. + +## 사용자 입력 받기 + +사용자 입력을 받기 전에 애플리케이션을 다시 살펴보고 변수를 점검해보겠습니다. + +어제 우리는 [day11_example4.go](/2022/Days/Go/day11_example4.go) 코드에서 `challenge, daystotal, dayscomplete`를 변수와 상수로 정의했습니다. + +이제 새로운 변수 `TwitterName`을 추가하겠습니다. 이 변수는 [day12_example1.go](/2022/Days/Go/day12_example1.go) 코드에서 찾을 수 있습니다. 코드를 실행하면 아래와 같이 출력됩니다. + +![](/2022/Days/Images/Day12_Go1.png) + +현재 12일째인데, 코드가 하드코딩되어 있다면 매일 `dayscomplete`를 수정하고 매일 코드를 컴파일해야 하기 때문에 효율적이지 않습니다. + +사용자로부터 이름과 수행한 일수를 입력받아야 합니다. 이를 위해서는 `fmt` 패키지 내의 다른 함수를 사용할 수 있습니다. + +`fmt` 패키지는 포맷된 입력 및 출력(I/O)을 위한 다양한 기능을 제공합니다. 이 패키지에 대한 요약은 다음과 같습니다. + +- 메시지 출력 +- 사용자 입력 수집 +- 파일에 쓰기 + +이 방법은 변수에 값을 할당하는 대신 사용자로부터 입력을 요청하는 방식입니다. + +```go +fmt.Scan(&TwitterName) +``` + +변수 앞에 `&`를 사용하는 것도 주목해 주세요. 이것은 포인터라 불리며, 다음 섹션에서 다룰 예정입니다. + +[day12_example2.go](/2022/Days/Go/day12_example2.go) 코드에서는 사용자로부터 `TwitterName`과 `DaysCompleted`라는 두 변수를 입력받고 있습니다. + +프로그램을 실행하면 위의 두 변수 모두에 대한 입력을 받는 걸 볼 수 있습니다. + +![](/2022/Days/Images/Day12_Go2.png) + +사용자 의견을 반영하여 메시지를 출력하는 기능도 좋지만, 챌린지 종료까지 남은 일수를 알려주는 기능도 추가하는 것이 어떨까요? + +이를 위해 `remainingDays`라는 변수를 만들고, `90`이라는 값을 할당하겠습니다. 그리고 `DaysCompleted`로 사용자 입력을 받으면 남은 날짜를 계산하여 `remainingDays`의 값을 변경하겠습니다. 다음과 같이 간단하게 변수를 변경하면 됩니다. + +```go +remainingDays = remainingDays - DaysCompleted +``` + +[day12_example2.go](/2022/Days/Go/day12_example3.go) 코드에서 완성된 프로그램의 모습을 확인할 수 있습니다. + +프로그램을 실행하면, 사용자 입력을 기반으로 `remainingDays` 값을 계산하는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day12_Go3.png) + +## 포인터가 무엇인가요?(특수 변수) + +포인터는 다른 변수의 메모리 주소를 가리키는 (특수)변수입니다. + +이에 대한 자세한 설명은 [geeksforgeeks](https://www.geeksforgeeks.org/pointers-in-golang/)에서 확인할 수 있습니다. + +출력 명령에 `&`를 사용할 때와 사용하지 않은 코드 예시를 통해 포인터의 메모리 주소를 확인해 볼 수 있습니다. [day12_example4.go](/2022/Days/Go/day12_example4.go)에 코드 예제를 추가했습니다. + +아래는 이 코드를 실행한 모습입니다. + +![](/2022/Days/Images/Day12_Go4.png) + +## 자료 + +- [StackOverflow 2021 Developer Survey](https://insights.stackoverflow.com/survey/2021) +- [Why we are choosing Golang to learn](https://www.youtube.com/watch?v=7pLqIIAqZD4&t=9s) +- [Jake Wright - Learn Go in 12 minutes](https://www.youtube.com/watch?v=C8LgvuEBraI&t=312s) +- [Techworld with Nana - Golang full course - 3 hours 24 mins](https://www.youtube.com/watch?v=yyUHQIec83I) +- [**NOT FREE** Nigel Poulton Pluralsight - Go Fundamentals - 3 hours 26 mins](https://www.pluralsight.com/courses/go-fundamentals) +- [FreeCodeCamp - Learn Go Programming - Golang Tutorial for Beginners](https://www.youtube.com/watch?v=YS4e4q9oBaU&t=1025s) +- [Hitesh Choudhary - Complete playlist](https://www.youtube.com/playlist?list=PLRAV69dS1uWSR89FRQGZ6q9BR2b44Tr9N) + +[Day 13](day13.md)에서 봐요! diff --git a/2022/ko/Days/day13.md b/2022/ko/Days/day13.md new file mode 100644 index 0000000..adb7bd4 --- /dev/null +++ b/2022/ko/Days/day13.md @@ -0,0 +1,322 @@ +--- +title: '#90DaysOfDevOps - Tweet your progress with our new App - Day 13' +published: false +description: 90DaysOfDevOps - Tweet your progress with our new App +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048865 +--- + +## 새로운 앱으로 진행 상황을 트윗하세요 + +프로그래밍 언어를 살펴본 마지막 날입니다. 우리는 프로그래밍 언어의 겉 부분만 살짝 살펴봤을 뿐이고 앞으로는 더 큰 흥미와 관심을 가지고 더욱 깊이 파고들어야 합니다. + +최근 며칠간 애플리케이션에 작은 아이디어를 추가하면서 기능을 개선했습니다. 이번 세션에서는 앞서 언급한 패키지를 활용하여 화면에 진행 상황을 업데이트하는 것뿐만 아니라, 챌린지의 세부 정보와 상태를 트윗할 수 있는 기능을 만들어보려고 합니다. + +## 진행 상황을 트윗하는 기능 추가 + +이 기능을 사용하려면 먼저 트위터에서 개발자 API 접근을 설정해야 합니다. + +[Twitter Developer Platform](https://developer.twitter.com)으로 이동하여 내 트위터로 계정으로 로그인하면, 이미 만든 앱이 없는 경우 아래와 같은 화면이 표시됩니다. + +![](/2022/Days/Images/Day13_Go1.png) + +여기에서 Elevated 등급 계정을 요청할 수 있습니다. 시간이 조금 걸릴 수 있지만, 제 경우에는 빠르게 승인이 됐습니다. + +다음으로, 프로젝트 및 앱을 선택하여 앱을 생성합니다. 보유한 계정 액세스 권한에 따라 제한이 있으며, Essential 계정은 하나의 앱과 하나의 프로젝트만, Elevated 계정은 3개의 앱만 만들 수 있습니다. + +![](/2022/Days/Images/Day13_Go2.png) + +애플리케이션의 이름을 지정합니다. + +![](/2022/Days/Images/Day13_Go3.png) + +API token이 제공됩니다. 이를 안전한 장소에 저장해야 합니다.(저는 이후 앱을 삭제했습니다.) 나중에 Go 애플리케이션에서 이 토큰이 필요할 것입니다. + +![](/2022/Days/Images/Day13_Go4.png) + +이제 앱이 생성되었습니다.(스크린샷에 보이는 앱 이름은 이미 생성된 것이기 때문에, 고유해야 하므로 앱 이름을 변경해야 했습니다.) + +![](/2022/Days/Images/Day13_Go5.png) + +"consumer keys"는 이전에 생성한 key를 의미하며, access token과 비밀번호도 필요합니다. 이 정보는 "Keys & Tokens" 탭에서 확인할 수 있습니다. + +![](/2022/Days/Images/Day13_Go6.png) + +트위터 개발자 포털에서 필요한 모든 작업을 마쳤습니다. 나중에 필요하실 수 있으니 key를 안전한 곳에 보관해주세요. + +## Go 트위터 봇 + +애플리케이션을 시작했던 코드인 [day13_example1](/2022/Days/Go/day13_example1.go)를 기억해주세요. 하지만 먼저 올바른 코드로 트윗을 생성할 수 있는지 확인해야 합니다. + +트위터에 메시지나 출력을 트윗 형태로 전달하기 위한 코드를 생각해봐야 합니다. 이를 위해 [go-twitter](https://github.com/dghubble/go-twitter) 라이브러리를 사용할 것입니다. 이 라이브러리는 Go 언어로 작성된 트위터 API 클라이언트 라이브러리입니다. + +메인 애플리케이션에 적용하기 전에 `src` 폴더에 'go-twitter-bot'이라는 새 디렉토리를 만들고, 해당 폴더에서 `go mod init github.com/michaelcade/go-Twitter-bot` 명령을 실행하여 `go.mod` 파일을 생성한 후, 새로운 'main.go' 파일을 작성하여 테스트해 보았습니다. + +트위터 개발자 포털에서 생성한 key, token 및 비밀번호가 필요하며, 이를 환경 변수로 설정해야 합니다. 하지만 이는 실행 중인 운영 체제에 따라 다를 수 있습니다. + +환경 변수와 관련하여 몇 가지 질문이 있어, 블로그 게시물을 소개해드립니다. 해당 게시물은 환경 변수 설정 방법을 더 자세히 설명하고 있습니다. [How To Set Environment Variables](https://www.twilio.com/blog/2017/01/how-to-set-environment-variables.html)를 통해 확인해보세요. + +Windows + +``` +set CONSUMER_KEY +set CONSUMER_SECRET +set ACCESS_TOKEN +set ACCESS_TOKEN_SECRET +``` + +Linux / MacOS + +``` +export CONSUMER_KEY +export CONSUMER_SECRET +export ACCESS_TOKEN +export ACCESS_TOKEN_SECRET +``` + +이 단계에서는 [day13_example2](/2022/Days/Go/day13_example2.go) 코드를 살펴볼 수 있습니다. 이 코드에서는 구조체를 사용하여 key, secret, token을 정의합니다. + +Credentials를 분석하고 트위터 API에 연결하는 `func`가 있습니다. + +이후 성공 여부에 따라 트윗을 전송합니다. + +```go +package main + +import ( + // ... + "fmt" + "log" + "os" + + "github.com/dghubble/go-twitter/twitter" + "github.com/dghubble/oauth1" +) + +// Credentials는 트위터 REST API에 대한 인증에 필요한 +// 모든 access/consumer token과 secret key를 저장합니다. +type Credentials struct { + ConsumerKey string + ConsumerSecret string + AccessToken string + AccessTokenSecret string +} + +// getClient는 인증에 필요한 모든 것을 포함하며, +// 트위터 클라이언트 또는 오류에 대한 포인터를 반환하는 +// Credentials 구조체에 대한 포인터를 받아 나중에 트윗을 보내거나 +// 새 트윗을 스트리밍하는 데 사용할 수 있는 헬퍼 함수입니다. +func getClient(creds *Credentials) (*twitter.Client, error) { + // consumer key(API key)와 consumer secret(API secret)을 전달합니다. + config := oauth1.NewConfig(creds.ConsumerKey, creds.ConsumerSecret) + // access token과 access token secret을 전달합니다. + token := oauth1.NewToken(creds.AccessToken, creds.AccessTokenSecret) + + httpClient := config.Client(oauth1.NoContext, token) + client := twitter.NewClient(httpClient) + + // Credentials 확인 + verifyParams := &twitter.AccountVerifyParams{ + SkipStatus: twitter.Bool(true), + IncludeEmail: twitter.Bool(true), + } + + // 사용자를 검색하고 Credentials가 올바른지 확인할 수 있고, + // 성공적으로 로그인할 수 있는지 확인할 수 있습니다! + user, _, err := client.Accounts.VerifyCredentials(verifyParams) + if err != nil { + return nil, err + } + + log.Printf("User's ACCOUNT:\n%+v\n", user) + return client, nil +} +func main() { + fmt.Println("Go-Twitter Bot v0.01") + creds := Credentials{ + AccessToken: os.Getenv("ACCESS_TOKEN"), + AccessTokenSecret: os.Getenv("ACCESS_TOKEN_SECRET"), + ConsumerKey: os.Getenv("CONSUMER_KEY"), + ConsumerSecret: os.Getenv("CONSUMER_SECRET"), + } + + client, err := getClient(&creds) + if err != nil { + log.Println("Error getting Twitter Client") + log.Println(err) + } + + tweet, resp, err := client.Statuses.Update("A Test Tweet from the future, testing a #90DaysOfDevOps Program that tweets, tweet tweet", nil) + if err != nil { + log.Println(err) + } + log.Printf("%+v\n", resp) + log.Printf("%+v\n", tweet) +} + +``` + +위와 같이 작성하면 상황에 따라 오류가 발생하거나 성공하여 코드에 적힌 메시지가 포함된 트윗이 전송됩니다. + +## 두 가지의 결합 - Go-Twitter-Bot + 우리의 앱 + +이제 이 두 가지를 `main.go`에서 병합해야 합니다. 이 작업을 수행하는 더 좋은 방법이 있을 것이며, 프로젝트에 둘 이상의 `.go` 파일을 가질 수 있으므로 이에 대해 의견을 제시해 주시기 바랍니다. + +[day13_example3](/2022/Days/Go/day13_example3.go)에서 병합된 코드를 볼 수 있지만 아래에서도 보여드리겠습니다. + +```go +package main + +import ( + // ... + "fmt" + "log" + "os" + + "github.com/dghubble/go-twitter/twitter" + "github.com/dghubble/oauth1" +) + +// Credentials는 트위터 REST API에 대한 인증에 필요한 +// 모든 access/consumer token과 secret key를 저장합니다. +Credentials REST API에 대한 인증에 필요한 모든 액세스/소비자 토큰과 비밀 키를 저장합니다. +type Credentials struct { + ConsumerKey string + ConsumerSecret string + AccessToken string + AccessTokenSecret string +} + +// getClient는 인증에 필요한 모든 것을 포함하며, +// 트위터 클라이언트 또는 오류에 대한 포인터를 반환하는 +// Credentials 구조체에 대한 포인터를 받아 나중에 트윗을 보내거나 +// 새 트윗을 스트리밍하는 데 사용할 수 있는 헬퍼 함수입니다. +func getClient(creds *Credentials) (*twitter.Client, error) { + // consumer key(API key)와 consumer secret(API secret)을 전달합니다. + config := oauth1.NewConfig(creds.ConsumerKey, creds.ConsumerSecret) + // access token과 access token secret을 전달합니다. + token := oauth1.NewToken(creds.AccessToken, creds.AccessTokenSecret) + + httpClient := config.Client(oauth1.NoContext, token) + client := twitter.NewClient(httpClient) + + // Verify Credentials + verifyParams := &twitter.AccountVerifyParams{ + SkipStatus: twitter.Bool(true), + IncludeEmail: twitter.Bool(true), + } + + // we can retrieve the user and verify if the credentials + // we have used successfully allow us to log in! + user, _, err := client.Accounts.VerifyCredentials(verifyParams) + if err != nil { + return nil, err + } + + log.Printf("User's ACCOUNT:\n%+v\n", user) + return client, nil +} + +func main() { + creds := Credentials{ + AccessToken: os.Getenv("ACCESS_TOKEN"), + AccessTokenSecret: os.Getenv("ACCESS_TOKEN_SECRET"), + ConsumerKey: os.Getenv("CONSUMER_KEY"), + ConsumerSecret: os.Getenv("CONSUMER_SECRET"), + } + { + const DaysTotal int = 90 + var remainingDays uint = 90 + challenge := "#90DaysOfDevOps" + + fmt.Printf("Welcome to the %v challenge.\nThis challenge consists of %v days\n", challenge, DaysTotal) + + var TwitterName string + var DaysCompleted uint + + // asking for user input + fmt.Println("Enter Your Twitter Handle: ") + fmt.Scanln(&TwitterName) + + fmt.Println("How many days have you completed?: ") + fmt.Scanln(&DaysCompleted) + + // Credentials 확인 + remainingDays = remainingDays - DaysCompleted + + //fmt.Printf("Thank you %v for taking part and completing %v days.\n", TwitterName, DaysCompleted) + //fmt.Printf("You have %v days remaining for the %v challenge\n", remainingDays, challenge) + //fmt.Println("Good luck") + + client, err := getClient(&creds) + if err != nil { + log.Println("Error getting Twitter Client, this is expected if you did not supply your Twitter API tokens") + log.Println(err) + } + + message := fmt.Sprintf("Hey I am %v I have been doing the %v for %v days and I have %v Days left", TwitterName, challenge, DaysCompleted, remainingDays) + tweet, resp, err := client.Statuses.Update(message, nil) + if err != nil { + log.Println(err) + } + log.Printf("%+v\n", resp) + log.Printf("%+v\n", tweet) + } +} +``` + +결과는 트윗으로 표시되어야 하지만, 환경 변수가 제공되지 않은 경우 아래와 같은 오류가 발생해야 합니다. + +![](/2022/Days/Images/Day13_Go7.png) + +만약 이 문제를 해결하거나 트위터 인증을 사용하지 않기로 선택했다면, 어제 작성한 코드를 사용할 수 있습니다. 성공한 경우 터미널 출력은 다음과 유사하게 표시됩니다: + +![](/2022/Days/Images/Day13_Go8.png) + +결과 트윗은 아래와 같이 표시되어야 합니다: + +![](/2022/Days/Images/Day13_Go9.png) + +## 여러 OS에 맞게 컴파일하는 방법 + +"여러 운영체제에서 컴파일하려면 어떻게 해야 할까요?"라는 질문에 대해 다루고자 합니다. Go의 가장 장점 중 하나는 다양한 운영체제에 대해 쉽게 컴파일할 수 있다는 점입니다. 아래 명령어를 실행하면 모든 운영체제 목록을 확인할 수 있습니다: + +``` +go tool dist list +``` + +지금까지 `go build` 명령을 사용하여 HM(host machine)과 빌드 대상을 환경 변수 `GOOS`와 `GOARCH`를 이용하여 결정할 수 있었습니다. 그러나 아래 예제와 같이 다른 바이너리를 생성할 수도 있습니다. + +``` +GOARCH=amd64 GOOS=darwin go build -o ${BINARY_NAME}_0.1_darwin main.go +GOARCH=amd64 GOOS=linux go build -o ${BINARY_NAME}_0.1_linux main.go +GOARCH=amd64 GOOS=windows go build -o ${BINARY_NAME}_0.1_windows main.go +GOARCH=arm64 GOOS=linux go build -o ${BINARY_NAME}_0.1_linux_arm64 main.go +GOARCH=arm64 GOOS=darwin go build -o ${BINARY_NAME}_0.1_darwin_arm64 main.go +``` + +위의 모든 플랫폼에 대한 바이너리가 디렉토리에 생성됩니다. 이후 코드에 새로운 기능을 추가할 때마다, 바이너리로 빌드하기 위해 [makefile](/2022/Days/Go/makefile)을 사용할 수도 있습니다. + +지금 리포지토리에서 볼 수 있는 릴리스를 만드는 데 사용한 [repository](https://github.com/MichaelCade/90DaysOfDevOps/releases)입니다. + +## 자료 + +- [StackOverflow 2021 Developer Survey](https://insights.stackoverflow.com/survey/2021) +- [Why we are choosing Golang to learn](https://www.youtube.com/watch?v=7pLqIIAqZD4&t=9s) +- [Jake Wright - Learn Go in 12 minutes](https://www.youtube.com/watch?v=C8LgvuEBraI&t=312s) +- [Techworld with Nana - Golang full course - 3 hours 24 mins](https://www.youtube.com/watch?v=yyUHQIec83I) +- [**NOT FREE** Nigel Poulton Pluralsight - Go Fundamentals - 3 hours 26 mins](https://www.pluralsight.com/courses/go-fundamentals) +- [FreeCodeCamp - Learn Go Programming - Golang Tutorial for Beginners](https://www.youtube.com/watch?v=YS4e4q9oBaU&t=1025s) +- [Hitesh Choudhary - Complete playlist](https://www.youtube.com/playlist?list=PLRAV69dS1uWSR89FRQGZ6q9BR2b44Tr9N) +- [A great repo full of all things DevOps & exercises](https://github.com/bregman-arie/devops-exercises) +- [GoByExample - Example based learning](https://gobyexample.com/) +- [go.dev/tour/list](https://go.dev/tour/list) +- [go.dev/learn](https://go.dev/learn/) + +7일간의 프로그래밍 언어 학습을 마무리합니다. 앞으로도 더 많은 내용을 다룰 예정이며, 이번 학습을 통해 Go 프로그래밍 언어의 다른 측면도 이해할 수 있었기를 바랍니다. + +다음으로, Linux와 Linux에서 알아야 할 몇 가지 기본 사항에 대해 살펴보겠습니다. + +[Day 14](day14.md)에서 봐요! diff --git a/2022/ko/Days/day14.md b/2022/ko/Days/day14.md new file mode 100644 index 0000000..b5df11b --- /dev/null +++ b/2022/ko/Days/day14.md @@ -0,0 +1,116 @@ +--- +title: '#90DaysOfDevOps - The Big Picture: DevOps and Linux - Day 14' +published: false +description: 90DaysOfDevOps - The Big Picture DevOps and Linux +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049033 +--- + +## 큰 그림: 데브옵스와 Linux + +Linux와 데브옵스는 유사한 문화와 관점을 공유하며, 둘 다 커스터마이징과 확장성에 중점을 둡니다. 이 두 가지 측면은 특히 데브옵스에서 중요한 역할을 합니다. + +특히 소프트웨어 개발이나 인프라 관리와 관련 기술들이 Linux에서 개발되었습니다. + +또한 많은 오픈 소스 프로젝트, 특히 DevOps 도구는 Linux에서 바로 실행되도록 설계되었습니다. + +DevOps나 운영 역할 관점에서는 대부분 Linux를 다룰 가능성이 높습니다. WinOps를 다루는 일도 있지만, 보통은 Linux 서버를 관리하고 배포하는 일이 많을 것입니다. + +저는 몇 년 동안 Linux를 사용해왔지만, 메인 데스크탑 컴퓨터는 주로 macOS나 Windows였습니다. 하지만 클라우드 네이티브 역할로 전환한 후에는 노트북에서 Linux를 기본 운영 체제로 사용하기로 결정했습니다. 일부 오디오 및 비디오 장비는 Linux와 호환되지 않기 때문에 업무 관련 애플리케이션은 여전히 Windows가 필요하지만, 앞으로 7일간은 개념을 더 잘 이해하기 위해 데스크탑에서 Linux를 사용하겠습니다. + +## 시작하기 + +더 쉬운 방법이 있기 때문에 여러분도 저와 똑같이 하라고 권하고 싶지는 않지만, 저처럼 단계를 밟으면 Linux를 더 빨리 배울 수 있다는 걸 알려드리고 싶습니다. + +이번 7일 동안, 저는 Windows에서 VirtualBox를 사용해 가상 머신을 띄울 계획입니다. 데스크탑 버전의 Linux 배포판도 함께 사용할 예정이지만, 여러분이 관리하게 될 대부분의 Linux 서버는 GUI가 없이 shell 기반으로 운영될 것입니다. 하지만, 앞서 90일 동안 학습한 많은 도구들이 Linux에서 시작되었다는 것을 언급했듯이, Linux 데스크탑을 실행해 보는 것도 강력히 추천합니다. + +이 글의 나머지 부분에서는 Virtual Box 환경에서 우분투 데스크탑 가상 머신 실행에 초점을 맞출 것입니다. [Virtual Box](https://www.virtualbox.org/)를 다운로드하고 링크된 사이트에서 최신 [Ubuntu ISO](https://ubuntu.com/download)를 가져와서 데스크탑 환경을 구축할 수도 있지만, 그렇게 하는 것은 데브옵스답지 않겠죠? + +Linux 배포판을 선택한 또 다른 이유는 대부분 무료이며 오픈 소스이기 때문입니다. 또한, 모바일 디바이스와 엔터프라이즈 RedHat Enterprise 서버를 제외하고 가장 널리 배포된 배포판인 우분투를 선택했습니다. 제가 틀렸을 수도 있지만 CentOS의 역사를 살펴보면 우분투가 목록에서 높은 순위에 있으며 매우 간단한 편이라고 생각합니다. + +## HashiCorp Vagrant 소개 + +Vagrant는 CLI 유틸리티로 가상 머신의 수명 주기를 관리합니다. vSphere, Hyper-v, Virtual Box, Docker 등 다양한 플랫폼에서 Vagrant를 사용하여 가상 머신을 생성하고 제거할 수 있습니다. 다른 대안도 있지만, 저는 Virtual Box를 사용할 것입니다. + +먼저 해야 할 일은 Vagrant를 컴퓨터에 설치하는 것입니다. [HashiCorp Vagrant](https://www.vagrantup.com/downloads) 다운로드 페이지에서는 사용 가능한 모든 운영 체제를 볼 수 있습니다. 저는 Windows를 사용 중이기 때문에 시스템용 바이너리를 다운로드하여 설치하였습니다. + +다음으로 [Virtual Box](https://www.virtualbox.org/wiki/Downloads)를 설치해야 합니다. 이 프로그램은 다양한 운영체제에서 실행할 수 있으며, 윈도우, 맥 OS, 또는 리눅스를 실행할 경우 필요합니다. + +두 설치 모두 매우 간단하며, 훌륭한 커뮤니티도 있어서 문제가 발생하면 언제든지 연락하시면 도움을 드릴 수 있습니다. + +## 첫 번째 VAGRANTFILE + +VAGRANTFILE은 배포하려는 가상 머신의 유형을 정의하고, 해당 머신의 구성과 프로비저닝을 설정합니다. + +VAGRANTFILE을 저장하고 정리할 때, 저는 워크스페이스의 폴더에 파일을 저장합니다. 제 시스템에서의 예시를 아래에서 확인하실 수 있습니다. 이 방법을 따라 하면 다른 시스템으로 쉽게 전환할 수 있으며, Linux 데스크탑을 "distro hopping"_(리눅스 사용자들이 사용하는 운영체제를 자주 바꾸는 행위 - 옮긴이)_ 하는 "rabbit hole"_(위험을 대비한 대안을 여러 개 준비하는 행위 - 옮긴이)_ 에도 적합합니다. + +![](/2022/Days/Images/Day14_Linux1.png) + +VAGRANTFILE을 살펴보고 우리가 현재 만들고 있는 것을 확인해 봅시다. + +``` +Vagrant.configure("2") do |config| + + config.vm.box = "chenhan/ubuntu-desktop-20.04" + + config.vm.provider :virtualbox do |v| + + v.memory = 8096 + + v.cpus = 4 + + v.customize ["modifyvm", :id, "--vram", "128"] + +end + +end +``` + +이건 매우 간단한 VAGRANTFILE입니다. 특정 "box"를 원한다는 뜻이며, 이 box는 여러분이 찾고 있는 시스템의 공개 이미지 또는 비공개 빌드일 가능성이 높습니다. 공개적으로 사용 가능한 "box"들의 목록은 [public catalogue of Vagrant boxes](https://app.vagrantup.com/boxes/search)에서 찾을 수 있습니다. + +다음 줄에서는 `VirtualBox`라는 특정한 공급자를 사용하고자 합니다. 또한 컴퓨터의 메모리를 `8GB`로, CPU 수를 `4`로 정의합니다. 제 경험상, 디스플레이 문제가 발생하면 비디오 메모리를 추가하는 것이 좋습니다. 이렇게 하면 비디오 메모리를 `128MB`까지 늘릴 수 있지만 시스템에 따라 다를 수 있습니다. + +``` +v.customize ["modifyvm", :id, "--vram", ""] +``` + +이 vagrant 파일은 [Linux Folder](/2022/Days/Linux/VAGRANTFILE)에서 확인할 수 있습니다. + +## Linux 데스크탑 프로비저닝 + +제 첫 번째 Linux 데스크탑을 시작하고 실행할 준비가 된 상태입니다. 저는 Windows 운영체제에서 PowerShell을 사용하고 있습니다. 프로젝트 폴더로 이동하여 VAGRANTFILE이 위치한 경로로 이동해주세요. 그곳에서 `vagrant up` 명령어를 입력하면 아래와 같은 내용이 표시됩니다. + +![](/2022/Days/Images/Day14_Linux2.png) + +추가해야 할 사항은 이 가상 머신에서 네트워크가 `NAT`로 설정된다는 것입니다. 현재 단계에서는 NAT에 대해 알 필요가 없으며, 네트워킹 세션에서 이에 대해 자세히 설명할 계획입니다. 가상 머신을 홈 네트워크에 연결하는 가장 간단한 방법이기도 하며, Virtual Box의 기본 네트워킹 모드입니다. 추가적인 정보는 [Virtual Box documentation](https://www.virtualbox.org/manual/ch06.html#network_nat)에서 확인할 수 있습니다. + +`vagrant up`이 완료되면 `vagrant ssh`를 사용하여 새 VM의 터미널로 바로 이동할 수 있습니다. + +![](/2022/Days/Images/Day14_Linux3.png) + +앞으로 며칠 동안 이곳에서 대부분의 작업을 진행할 예정입니다. 또한 개발자 워크스테이션에 몇 가지 사용자 지정 기능을 추가하여 일상적인 작업을 훨씬 더 간편하게 만들 계획입니다. 비표준 터미널이 없다면, 스스로를 DevOps 전문가로 여길 수 있을까요? + +확인을 위해 가상 머신을 선택하면 로그인 프롬프트가 표시되어야 합니다. + +![](/2022/Days/Images/Day14_Linux4.png) + +여기까지 읽으셨는데 "Username과 Password가 무엇인가요?"라는 질문이 계속 나오신다면? + +- Username = vagrant + +- Password = vagrant + +내일은 터미널에서의 몇 가지 명령어와 그 명령어들이 하는 일에 대해 알아보도록 하겠습니다. + +## 자료 + +- [Learn the Linux Fundamentals - Part 1](https://www.youtube.com/watch?v=kPylihJRG70) +- [Linux for hackers (don't worry you don't need to be a hacker!)](https://www.youtube.com/watch?v=VbEx7B_PTOE) + +앞으로 더 많은 자원을 확보할 예정이며, Go 언어 자료와 마찬가지로 일반적으로 무료 콘텐츠를 제공하여 모두가 참여하고 배울 수 있도록 할 것입니다. + +다음 글에서는 자주 사용할 수 있는 Linux 환경의 명령어에 대해 살펴볼 것입니다. + +[Day 15](day15.md)에서 봐요! diff --git a/2022/ko/Days/day15.md b/2022/ko/Days/day15.md new file mode 100644 index 0000000..6666d50 --- /dev/null +++ b/2022/ko/Days/day15.md @@ -0,0 +1,195 @@ +--- +title: '#90DaysOfDevOps - Linux Commands for DevOps (Actually everyone) - Day 15' +published: false +description: 90DaysOfDevOps - Linux Commands for DevOps (Actually everyone) +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048834 +--- + +## 데브옵스(실제로는 모든 사용자)를 위한 Linux 명령 + +[어제](day14.md) 터미널에서 몇 가지 명령을 사용하여 작업을 수행하는 데 많은 시간을 할애하게 될 것이라고 언급했습니다. + +또한 vagrant 프로비저닝된 VM을 사용하면 `vagrant ssh`를 사용하여 box에 액세스할 수 있다고도 언급했습니다. 프로비저닝한 디렉토리와 동일한 디렉토리에 있어야 합니다. + +SSH의 경우 username과 password는 필요하지 않으며, 가상 box 콘솔에 로그인하려는 경우에만 필요합니다. + +아래는 우리가 원하는 위치입니다: + +![](/2022/Days/Images/Day15_Linux1.png) + +## 명령어들 + +여기서 다루지 않은 명령어도 있습니다. 이러한 명령어를 다루는 문서 페이지가 있지만, 특정 명령에 대한 옵션을 이해해야 할 때는 `man` 페이지를 사용할 수 있습니다. `man` 페이지를 사용하면 이 글에서 다루는 각 명령어에 대한 더 많은 옵션을 찾을 수 있습니다. `man man`을 실행하면 `man` 페이지에 대한 도움말을 볼 수 있습니다. `Q`를 눌러 매뉴얼 페이지를 종료할 수 있습니다. + +![](/2022/Days/Images/Day15_Linux2.png) +![](/2022/Days/Images/Day15_Linux3.png) + +Windows에서 `관리자 권한으로 실행`을 마우스 오른쪽 버튼으로 클릭으로 하는 것에 익숙하다면, `sudo` 명령어를 비슷하게 생각할 수 있습니다. 이 명령어를 사용하면 명령을 `root` 권한으로 실행하며, 명령 실행 전에 암호를 입력해야 하는 메시지가 표시됩니다. + +![](/2022/Days/Images/Day15_Linux4.png) + +일회성 작업이 아니라 여러 작업을 수행하며 일시적으로 `sudo` 권한을 유지하려면 어떻게 해야 할까요? `sudo su`를 사용하면 `sudo`와 동일한 권한을 가질 수 있습니다. 그러나 이 방법은 보안상 위험할 수 있습니다. `root` 권한을 오랜 시간 동안 유지하는 것은 위험하기 때문입니다. 테스트 VM에서는 문제가 되지 않을 수 있지만 실제 서버에서는 위험할 수 있습니다. 따라서 작업을 마치면 `exit`를 입력하여 `root` 권한을 해제해야 합니다. + +![](/2022/Days/Images/Day15_Linux5.png) + +저는 항상 `clear` 명령어를 사용합니다. 이 명령어는 이전 명령의 출력 화면을 모두 지우고 깔끔한 작업 공간을 제공하기 때문에 프롬프트를 맨 위에 위치시키는 것과 같은 효과를 가집니다. 윈도우 운영체제에서는 이 명령어를 `cls`로 사용할 수 있습니다. + +![](/2022/Days/Images/Day15_Linux6.png) + +이제 시스템 내에서 무언가를 생성한 후에 터미널에서 시각화할 수 있는 몇 가지 명령어를 살펴보겠습니다. 먼저 `mkdir` 명령어를 사용하여 시스템에 폴더를 생성할 수 있습니다. 예를 들어, 홈 디렉토리에 Day15라는 폴더를 생성하려면 `mkdir Day15` 명령어를 사용하면 됩니다. + +![](/2022/Days/Images/Day15_Linux7.png) + +`cd`를 사용하면 디렉토리를 변경할 수 있으므로, 새로운 디렉토리로 이동하려면 `cd D`에서 탭을 사용하여 `cd Day15` 같이 가능한 디렉토리를 자동 완성할 수 있습니다. 시작 위치로 돌아가려면 `cd ..`을 사용하면 됩니다. + +![](/2022/Days/Images/Day15_Linux8.png) + +`rmdir` 명령어를 사용하면 디렉토리를 삭제할 수 있습니다. 예를 들어, `rmdir Day15` 명령어를 실행하면 폴더가 삭제됩니다.(단, 해당 폴더가 비어있을 경우에만 작동합니다.) + +![](/2022/Days/Images/Day15_Linux9.png) + +가끔 파일 시스템의 깊은 곳에서 디렉토리를 찾았지만, 그 위치를 모르는 경우가 있습니다. `pwd` 명령어는 작업 디렉토리의 경로를 출력해주는데, 비밀번호처럼 보이지만 실제로는 "print working directory"의 약자입니다. + +![](/2022/Days/Images/Day15_Linux10.png) + +폴더와 디렉토리를 만드는 방법은 알고 있지만, 파일을 만드는 방법은 어떨까요? 파일을 생성하는 방법 중 하나는 `touch` 명령을 사용하는 것입니다. 예를 들어, `touch Day15` 명령을 실행하면 파일이 생성됩니다. `mkdir` 명령은 이후에 살펴볼 예정이므로, 지금은 무시하셔도 됩니다. + +![](/2022/Days/Images/Day15_Linux11.png) + +현재 디렉토리 내 모든 파일과 폴더를 나열하려면 `ls` 명령을 반복해서 사용해야 할 것입니다. 해당 명령어로 방금 생성한 파일이 있는지 확인해보겠습니다. + +![](/2022/Days/Images/Day15_Linux12.png) + +우리는 리눅스 시스템에서 어떻게 파일을 찾을 수 있을까요? `locate` 명령어를 사용하면 파일 시스템을 검색할 수 있습니다. 만약 `locate Day15`와 같이 입력하면 해당 파일의 위치를 알려줍니다. 또한, 파일이 존재하는데 검색 결과가 없다면 `sudo updatedb` 명령어를 실행하여 파일 시스템의 모든 파일을 인덱싱한 후 다시 `locate` 명령어를 실행하세요. 만약 `locate` 명령어가 없다면 `sudo apt install mlocate` 명령어를 사용하여 설치할 수 있습니다. + +![](/2022/Days/Images/Day15_Linux13.png) + +리눅스 시스템에서 파일을 찾으려면 어떻게 해야 할까요? `mv` 명령어를 사용하면 파일을 이동할 수 있습니다. 예를 들어, `mv Day15 90DaysOfDevOps` 명령어는 Day15 파일을 90DaysOfDevOps 폴더로 이동시킵니다. + +![](/2022/Days/Images/Day15_Linux14.png) + +파일을 옮겼는데, 이름을 변경하고 싶다면 어떻게 해야 할까요? 이름을 변경하려면 `mv` 명령어를 다시 사용하면 됩니다. 예를 들어, 대소문자를 변경하려면 `mv Day15 day15`와 같이 입력하고, 파일 이름을 완전히 바꾸려면 `mv day15 AnotherDay`와 같이 입력하면 됩니다. 변경 후에는 `ls` 명령어를 사용하여 파일이 정상적으로 변경되었는지 확인할 수 있습니다. + +![](/2022/Days/Images/Day15_Linux15.png) + +이제 파일과 디렉토리가 생성되면 디렉토리를 삭제해 보겠습니다. 파일을 삭제하려면 간단히 `rm AnotherDay` 명령어를 사용할 수 있습니다. 폴더를 재귀적으로(하위 폴더까지) 삭제하려면 `rm -R` 명령어를 사용하는 것이 일반적입니다. 또한, `rm -R -f` 명령어를 사용하여 해당 파일을 강제로 삭제할 수도 있습니다. 시스템과 영원한 작별 인사를 하고 싶다면 `sudo rm -R -f /`를 입력하면 됩니다._(주의: 이 명령어는 시스템을 완전히 삭제합니다. - 옮긴이)_ + +![](/2022/Days/Images/Day15_Linux16.png) + +파일 이동에 대해 살펴봤는데, 한 폴더에서 다른 폴더로 파일을 복사하고 싶을 때는 `mv` 명령어 대신 `cp` 명령어를 사용해야 합니다. 이제 `cp Day15 Desktop`으로 파일을 복사할 수 있습니다. + +![](/2022/Days/Images/Day15_Linux17.png) + +폴더와 파일을 만들었지만, 폴더에는 아직 내용이 없습니다. 내용을 추가하는 몇 가지 방법이 있지만, 가장 쉬운 방법은 `echo`를 사용하는 것입니다. `echo`를 사용하면 터미널에서 많은 내용을 출력할 수 있습니다. 저는 시스템 변수가 설정되어 있는지를 확인하기 위해 시스템 변수를 출력할 때 echo를 자주 사용합니다. 파일에 내용을 추가하려면 `echo "Hello #90DaysOfDevOps" > Day15`를 사용할 수 있습니다. 또는 `echo "Commands are fun!" >> Day15`를 사용할 수도 있습니다. + +![](/2022/Days/Images/Day15_Linux18.png) + +`cat`은 매우 자주 사용하는 명령어 중 하나입니다. `cat`은 "concatenate(연결)"의 약어로, `cat Day15` 명령어를 사용하여 파일 내용을 확인할 수 있습니다. 이 명령어는 구성 파일을 빠르게 읽을 때 유용합니다. + +![](/2022/Days/Images/Day15_Linux19.png) + +복잡한 구성 파일에서 모든 줄을 읽는 대신에, 특정한 단어를 찾고 싶거나 찾아야 하는 경우 `grep`을 사용할 수 있습니다. 예를 들면 `cat Day15 | grep "#90DaysOfDevOps"`를 입력하여 파일에서 원하는 단어를 검색할 수 있습니다. 이렇게 하면 빠르게 결과를 얻을 수 있습니다. + +![](/2022/Days/Images/Day15_Linux20.png) + +제가 `clear` 명령을 자주 사용하여 이전에 실행한 일부 명령을 놓칠 수 있기 때문에, `history` 명령을 사용하여 이전에 실행한 모든 명령을 찾을 수 있습니다. `history -c` 명령은 기록을 제거합니다. + +`history`를 실행하고 특정 명령을 선택하려는 경우 `!3`을 사용하여 목록에서 세 번째 명령을 선택할 수 있습니다. + +또한 `history | grep "Command"`를 사용하여 특정 명령을 검색할 수도 있습니다. + +서버에서 명령이 언제 실행되었는지 추적하려면 히스토리 파일의 각 명령에 날짜와 시간을 추가할 수도 있습니다. + +다음 시스템 변수가 이 동작을 제어합니다: + +``` +HISTTIMEFORMAT="%d-%m-%Y %T " +``` + +bash_profile에 쉽게 추가할 수 있습니다: + +```bash +echo 'export HISTTIMEFORMAT="%d-%m-%Y %T "' >> ~/.bash_profile +``` + +히스토리 파일을 더 크게 만들 수도 있습니다: + +```bash +echo 'export HISTSIZE=100000' >> ~/.bash_profile +echo 'export HISTFILESIZE=10000000' >> ~/.bash_profile +``` + +![](/2022/Days/Images/Day15_Linux21.png) + +비밀번호를 변경해야 하나요? `passwd` 명령어를 사용하여 비밀번호를 변경할 수 있습니다. 비밀번호가 숨겨져 있을 때는 이 명령어를 실행해도 `history`에 표시되지 않지만, 명령에 `-p PASSWORD`가 포함되면 `history`에 표시됩니다. + +![](/2022/Days/Images/Day15_Linux22.png) + +새로운 사용자를 시스템에 추가하고 싶을 경우 `sudo` 명령어를 사용하여 `sudo useradd NewUser`를 입력해야 합니다. + +![](/2022/Days/Images/Day15_Linux23.png) + +그룹을 재생성하려면 `sudo` 권한이 필요합니다. `sudo groupadd DevOps` 명령을 사용하여 새로운 사용자를 해당 그룹에 추가하려면 `sudo usermod -a -G DevOps` 명령을 실행하세요. `-a`는 추가를, `-G`는 그룹 이름을 나타냅니다. + +![](/2022/Days/Images/Day15_Linux24.png) + +`sudo` 그룹에 새로운 사용자를 추가하는 것은 드물기는 하지만, 이를 위해서는 `usermod -a -G sudo NewUser` 명령어를 입력하면 됩니다. + +### 권한 + +읽기, 쓰기, 실행 권한은 Linux 시스템의 모든 파일과 폴더에 대한 권한입니다. + +전체 목록입니다: + +- 0 = 없음 `---` +- 1 = 실행만 `--X` +- 2 = 쓰기만 `-W-` +- 3 = 쓰기 및 실행 `-WX` +- 4 = 읽기 전용 `R--` +- 5 = 읽기 & 실행 `R-X` +- 6 = 읽기 및 쓰기 `RW-` +- 7 = 읽기, 쓰기 및 실행 `RWX` + +또한 `777` 또는 `775`로도 표시되며 이는 위 목록과 동일한 숫자를 나타내지만 각각 **User - Group - Everyone**을 나타냅니다. + +파일을 살펴봅시다. `ls -al Day15`를 실행하면 위에서 언급한 3개의 그룹을 볼 수 있으며, 사용자와 그룹은 읽기 및 쓰기 권한을 가지고 있지만 모두 읽기 권한만 있습니다. + +![](/2022/Days/Images/Day15_Linux25.png) + +시스템에서 많은 양의 바이너리를 생성하고 실행할 수 있는 기능을 제공해야 한다면, `chmod`를 사용하여 해당 바이너리에 대한 권한을 변경할 수 있습니다. 예를 들어, `chmod 750 Day15` 명령어를 실행하면 Day15 파일에 대한 권한을 설정할 수 있으며, `ls -al Day15` 명령어로 권한이 설정되었는지 확인할 수 있습니다. 전체 폴더에 대해 이 작업을 실행하려면 `-R` 옵션을 사용하여 재귀적으로(하위 폴더까지) 설정할 수 있습니다. + +![](/2022/Days/Images/Day15_Linux26.png) + +파일 소유자를 변경하는 것은 어떨까요? 이 작업에는 `chown`을 사용할 수 있습니다. `Day15`의 소유권을 사용자 `vagrant`에서 `NewUser`로 변경하려면 `sudo chown NewUser Day15`를 다시 `-R`로 실행할 수 있습니다. + +![](/2022/Days/Images/Day15_Linux27.png) + +특정 데이터만 필요한 출력을 얻을 때, 실제로 사용되는 명령어는 `awk`입니다. 예를 들어, `who`를 실행하면 정보가 포함된 줄을 얻을 수 있지만, 이름만 필요한 경우도 있습니다. 이때는 `who | awk '{print $1}'`를 실행하여 첫 번째 열에 해당하는 이름 목록만 가져올 수 있습니다. + +![](/2022/Days/Images/Day15_Linux28.png) + +데이터 스트림을 표준 입력에서 읽으려면 커맨드라인을 생성하고 실행해야 합니다. 이렇게 하면 명령의 출력을 가져와 다른 명령의 인수로 전달할 수 있습니다. 이러한 사용 사례에 유용한 도구로 `xargs`가 있습니다. 예를 들어, 실행 가능한 시스템에서 모든 Linux 사용자 계정의 목록을 가져오고 싶다면, `cut -d: -f1 < /etc/passwd`를 실행하면 아래와 같은 긴 목록이 생성됩니다. + +![](/2022/Days/Images/Day15_Linux29.png) + +이 목록을 압축하려면 `cut -d: -f1 < /etc/passwd | sort | xargs`와 같은 명령을 사용하면 됩니다. `xargs`를 추가로 사용합니다. + +![](/2022/Days/Images/Day15_Linux30.png) + +이미 언급된 것은 아니지만, `cut` 명령어는 파일에서 각 줄의 섹션을 제거하는 데 사용할 수 있습니다. 이 명령어는 바이트 위치, 문자 또는 필드 단위로 줄의 일부를 잘라내는 데 사용됩니다. 예를 들어, `cut -d " " -f 2 list.txt` 명령어를 사용하면 첫 글자를 제거하고 숫자만 표시할 수 있습니다. 많은 조합이 있기 때문에 수동으로 데이터를 추출하는 것보다 이 명령어를 사용하는 것이 더 빠를 수 있습니다. + +![](/2022/Days/Images/Day15_Linux31.png) + +명령을 입력을 멈추고 때는 컨트롤 + C를 누르면 해당 줄이 취소되고 새로 시작됩니다. + +## 자료 + +- [Learn the Linux Fundamentals - Part 1](https://www.youtube.com/watch?v=kPylihJRG70) +- [Linux for hackers (don't worry you don't need to be a hacker!)](https://www.youtube.com/watch?v=VbEx7B_PTOE) + +[Day 16](day16.md)에서 봐요! + +목록이 꽤 길지만, 리눅스 서버를 관리하거나 리눅스 데스크톱에서 작업하는 등 일상에서 이 명령어를 모두 활용한다고 자신 있게 말할 수 있습니다. Windows나 macOS에서는 UI를 탐색하는 것이 간단하지만, 터미널을 통해 모든 것이 이루어지는 Linux 서버에서는 그렇지 않습니다. diff --git a/2022/ko/Days/day16.md b/2022/ko/Days/day16.md new file mode 100644 index 0000000..a3357f4 --- /dev/null +++ b/2022/ko/Days/day16.md @@ -0,0 +1,166 @@ +--- +title: '#90DaysOfDevOps - Managing your Linux System, Filesystem & Storage - Day 16' +published: false +description: '90DaysOfDevOps - Managing your Linux System, Filesystem & Storage' +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048702 +--- + +## Linux 시스템, 파일 시스템 및 스토리지 관리 + +지금까지 우리는 리눅스와 데브옵스에 대한 간략한 개요를 살펴보았고, [Day 14](day14.md)에서는 실습 환경을 설정하였으며, [Day 15](day15.md)에서는 터미널에서 작업을 수행할 때 자주 사용되는 명령어들을 살펴보았습니다. + +여기서는 업데이트, 소프트웨어 설치, 시스템 폴더의 용도와 스토리지에 대해 살펴보겠습니다. 이는 이해해야 할 핵심 영역 세 가지입니다. + +## 우분투 및 소프트웨어 관리 + +가장 먼저 살펴볼 사항은 운영체제 업데이트 방법입니다. 대부분의 사용자는 Windows OS와 macOS에서 이 프로세스에 익숙할 것이며, Linux 데스크톱과 서버에서는 조금 다릅니다. + +업데이트 및 소프트웨어 설치를 위해 Ubuntu VM에서 사용할 apt 패키지 관리자를 살펴볼 것입니다. + +일반적으로, 개발 워크스테이션에서 소프트웨어를 설치하기 전에 중앙 리포지토리에서 사용 가능한 최신 업데이트가 있는지 확인하기 위해 이 명령을 실행하는 것이 좋습니다. + +`sudo apt-get update` + +![](/2022/Days/Images/Day16_Linux1.png) + +이제 최신 OS 업데이트가 설치된 업데이트된 우분투 가상 머신이 생겼습니다. 이제 여기에 몇 가지 소프트웨어를 설치하려고 합니다. + +텍스트 배너를 생성하는 프로그램인 `figlet`을 선택해 보겠습니다. + +터미널에 `figlet`을 입력하면 시스템에 이 프로그램이 설치되어 있지 않다는 것을 알 수 있습니다. + +![](/2022/Days/Images/Day16_Linux2.png) + +위의 내용을 보면 시도해 볼 수 있는 몇 가지 `apt` 설치 옵션이 제공된다는 것을 알 수 있습니다. 기본 리포지토리에는 figlet이라는 프로그램이 있기 때문입니다. `sudo apt install figlet`을 시도해 보겠습니다. + +![](/2022/Days/Images/Day16_Linux3.png) + +이제 아래에서 볼 수 있듯이 `figlet` 앱을 사용할 수 있습니다. + +![](/2022/Days/Images/Day16_Linux4.png) + +`apt` 패키지 관리자를 사용하여 해당 소프트웨어나 다른 소프트웨어를 제거할 수도 있습니다. + +`sudo apt remove figlet` + +![](/2022/Days/Images/Day16_Linux5.png) + +시스템에 추가할 수 있는 타사 리포지토리도 있는데, 바로 액세스할 수 있는 리포지토리는 Ubuntu 기본 리포지토리입니다. + +Ubuntu 가상 머신에 Vagrant를 설치하려면 현재로서는 불가능합니다. 이를 확인하려면 아래의 첫 번째 명령어를 실행하면 됩니다. 그다음에는 HashiCorp 리포지토리를 신뢰하는 키를 추가하고, 리포지토리를 시스템에 추가해야 합니다. + +![](/2022/Days/Images/Day16_Linux6.png) + +HashiCorp 리포지토리를 추가했으면 이제 `sudo apt install vagrant`를 실행하여 시스템에 vagrant를 설치할 수 있습니다. + +![](/2022/Days/Images/Day16_Linux7.png) + +우분투에는 소프트웨어 설치와 관련하여 내장된 패키지 관리자를 사용할 수 있는 다양한 옵션이 있으며, 스냅을 이용한 소프트웨어 설치도 가능합니다. + +이 글을 통해 Linux에서 OS 및 소프트웨어 설치를 관리하는 방법에 대한 감을 잡으셨기를 바랍니다. + +## 파일 시스템 설명 + +Linux는 구성 파일들로 이루어져 있으며, 변경하고자 하는 내용이 있다면 해당 구성 파일을 수정하면 됩니다. + +Windows 운영체제에서는 C 드라이브가 루트 디렉토리입니다. 반면 Linux 운영체제에서는 `/` 디렉토리가 중요한 위치로, 시스템 내의 여러 폴더를 찾을 수 있는 기본적인 디렉토리입니다. + +![](/2022/Days/Images/Day16_Linux8.png) + +- `/bin` - 바이너리의 줄임말로, 시스템에서 필요한 실행 파일, 도구 및 바이너리가 있는 폴더입니다. + +![](/2022/Days/Images/Day16_Linux9.png) + +- `/boot` - 시스템 부팅에 필요한 모든 파일이 위치합니다. 부팅 방법과 부팅할 드라이브를 찾을 수 있습니다. + +![](/2022/Days/Images/Day16_Linux10.png) + +- `/dev` - 이 폴더에서는 장치 정보를 찾을 수 있으며, 디스크 드라이브에 대한 포인터를 찾을 수 있습니다. 일반적으로 `sda`는 기본 OS 디스크입니다. + +![](/2022/Days/Images/Day16_Linux11.png) + +- `/etc` - 리눅스 시스템에서 가장 중요한 폴더로, 대부분의 구성 파일이 있는 곳입니다. + +![](/2022/Days/Images/Day16_Linux12.png) + +- `/home` - 사용자 폴더와 파일이 위치하는 곳입니다. 이 폴더에는 vagrant 사용자 폴더뿐만 아니라 명령어 섹션에서 작업한 `Document` 및 `Desktop` 폴더 있습니다. + +![](/2022/Days/Images/Day16_Linux13.png) + +- `/lib` - `/bin` 폴더가 바이너리 및 실행 파일을 가지고 있다면, 이 폴더는 이러한 파일들에 대한 공유 라이브러리를 가지고 있는 곳입니다. + +![](/2022/Days/Images/Day16_Linux14.png) + +- `/media` - 이동식 디바이스를 찾을 수 있는 곳입니다. + +![](/2022/Days/Images/Day16_Linux15.png) + +- `/mnt` - 임시 마운트 지점입니다. 스토리지 섹션에서 자세히 다루겠습니다. + +![](/2022/Days/Images/Day16_Linux16.png) + +- `/opt` - 옵션 소프트웨어 패키지가 위치하는 폴더입니다. 이 폴더에는 몇 가지 vagrant 및 가상 머신 패키지가 저장되어 있습니다. + +![](/2022/Days/Images/Day16_Linux17.png) + +- `/proc` - 커널 및 프로세스 정보를 찾을 수 있는 곳으로, `/dev`와 유사합니다. + +![](/2022/Days/Images/Day16_Linux18.png) + +- `/root` - 액세스 권한을 얻으려면 sudo를 사용해야 하는 루트의 홈 폴더입니다. + +![](/2022/Days/Images/Day16_Linux19.png) + +- `/run` - 애플리케이션 상태를 위한 자리 표시자입니다. + +![](/2022/Days/Images/Day16_Linux20.png) + +- `/sbin` - `bin` 폴더와 유사하지만 시스템에서 슈퍼유저 권한이 필요한 도구들이 위치합니다. 즉, `sudo bin`입니다. + +![](/2022/Days/Images/Day16_Linux21.png) + +- `/tmp` - 임시 파일이 위치하는 폴더입니다. + +![](/2022/Days/Images/Day16_Linux22.png) + +- `/usr` - 일반 사용자가 소프트웨어 패키지를 설치한 경우, 일반적으로 `/usr/bin` 위치에 설치됩니다. + +![](/2022/Days/Images/Day16_Linux23.png) + +- `/var` - 애플리케이션은 `bin` 폴더에 설치됩니다. 모든 로그 파일을 저장할 위치가 필요한데, 이 위치가 바로 `/var`입니다. + +![](/2022/Days/Images/Day16_Linux24.png) + +## 스토리지 + +Linux 시스템이나 다른 시스템에서도 사용 가능한 디스크와 해당 디스크의 여유 공간을 확인하는 것은 유용합니다. 아래의 명령어 몇 가지는 스토리지를 식별하고 사용 및 관리하는 데 도움이 됩니다. + +- `lblk`는 블록 장치를 나열합니다. `sda`는 물리적 디스크이고 `sda1, sda2, sda3`는 해당 디스크의 파티션입니다. + +![](/2022/Days/Images/Day16_Linux25.png) + +- `df` 명령어는 파티션 정보, 전체 사용량 및 사용 가능한 용량에 대한 더 자세한 정보를 제공합니다. 다른 플래그를 사용하여 구문 분석할 수 있습니다. 일반적으로 `df -h` 명령어를 사용하여 인간이 읽기 쉬운 출력을 생성합니다. + +![](/2022/Days/Images/Day16_Linux26.png) + +새로운 디스크를 시스템에 추가할 경우, Windows에서와 마찬가지로 디스크 관리에서 디스크를 포맷해야 합니다. 그러나 Linux 터미널에서는 추가된 새 디스크와 관련된 sdb와 함께 `sudo mkfs -t ext4 /dev/sdb` 명령어를 사용하여 포맷할 수 있습니다. + +새로 포맷한 디스크를 사용하기 위해서는 `/mnt` 폴더에서 `sudo mkdir NewDisk` 명령어로 디렉토리를 생성한 후, `sudo mount /dev/sdb NewDisk`를 사용하여 해당 위치에 디스크를 마운트해야 합니다. + +시스템에서 스토리지를 안전하게 마운트 해제해야 할 때도 있고, 구성에서 그냥 가져와야 할 때도 있습니다. 이 작업은 `sudo umount /dev/sdb` 명령어로 수행할 수 있습니다. + +만약에 당신이 해당 디스크를 마운트 해제하고 싶지 않고, 이 디스크를 데이터베이스나 지속적으로 사용할 다른 용도로 사용하려는 경우, 시스템을 재부팅 할 때 그 디스크가 있어야 합니다. 이를 위해, 이 디스크를 `/etc/fstab` 구성 파일에 추가하여 지속성을 유지해야 합니다. 그렇지 않으면 기계가 재부팅될 때 사용할 수 없으며 수동으로 위의 프로세스를 진행해야 합니다. 데이터는 여전히 디스크에 남아 있지만, 이 파일에 구성을 추가하지 않으면 자동으로 마운트되지 않습니다. + +`fstab` 구성 파일을 편집한 후 `sudo mount -a` 명령을 실행하여 작동을 확인할 수 있습니다. 오류가 없다면, 이제 변경 사항이 재시작 시에도 지속됩니다. + +텍스트 편집기를 사용하여 파일을 편집하는 방법은 다음 세션에서 다루겠습니다. + +## 자료 + +- [Learn the Linux Fundamentals - Part 1](https://www.youtube.com/watch?v=kPylihJRG70) +- [Linux for hackers (don't worry you don't need to be a hacker!)](https://www.youtube.com/watch?v=VbEx7B_PTOE) + +[Day 17](day17.md)에서 봐요! diff --git a/2022/ko/Days/day17.md b/2022/ko/Days/day17.md new file mode 100644 index 0000000..50a07f2 --- /dev/null +++ b/2022/ko/Days/day17.md @@ -0,0 +1,86 @@ +--- +title: '#90DaysOfDevOps - Text Editors - nano vs vim - Day 17' +published: false +description: 90DaysOfDevOps - Text Editors - nano vs vim +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048703 +--- + +## 텍스트 편집기 - nano vs vim + +대부분의 Linux 시스템은 서버로 사용되며, 이러한 시스템에는 GUI가 없습니다. 또한 이전 세션에서 언급했듯이, Linux 시스템은 대부분 구성 파일로 구성되어 있어 변경하려면 이러한 구성 파일을 편집하여 시스템의 모든 것을 변경해야 합니다. + +다양한 옵션이 있지만, 가장 일반적으로 사용되는 두 가지 터미널 텍스트 편집기를 소개하고자 합니다. 제 경험상, 빠른 수정 작업에는 `nano`가 더 편리하지만, `vim`은 다양한 기능을 제공하여 더 복잡한 편집 작업을 수행할 수 있습니다. + +### nano + +- 모든 시스템에서 사용할 수 있는 것은 아닙니다. +- 처음 시작할 때 좋습니다. + +`nano 90DaysOfDevOps.txt`를 실행하면 아무 내용도 없는 새 파일이 생성되며, 이 파일에 텍스트를 추가할 수 있습니다. 하단에 도움말 메뉴가 있습니다. + +![](/2022/Days/Images/Day17_Linux1.png) + +이제 `Ctrl X + enter`를 입력한 다음 `ls`를 실행하면 새 텍스트 파일을 볼 수 있습니다. + +![](/2022/Days/Images/Day17_Linux2.png) + +이제 해당 파일을 읽기 위해 `cat` 명령어를 실행할 수 있습니다. 그리고 `nano 90DaysOfDevOps.txt` 명령어를 사용하여 파일에 추가 텍스트를 입력하거나 수정할 수 있습니다. + +제게 있어서 nano는 구성 파일에 작은 변경 사항을 적용하기 매우 편리한 편집기입니다. + +### vim + +1976년에 출시된 UNIX 텍스트 편집기인 vi의 형제 버전인 vim은 다양한 기능을 제공하여 가장 일반적인 텍스트 편집기 중 하나일까요? + +- 대부분의 Linux 배포판에서 지원됩니다. +- vim만 다루는 7시간짜리 강좌를 찾을 수 있다는 것은 매우 놀랍습니다! + +`vim` 명령어를 사용하여 vim 에디터로 이동하거나 새 텍스트 파일을 편집하려면 `vim 90DaysOfDevOps.txt`와 같은 명령어를 실행할 수 있습니다. 그러나 이 경우 하단에 도움말 메뉴가 없음을 확인할 수 있습니다. + +첫 번째 질문은 "vim을 어떻게 종료할까요?"일 수 있습니다. 종료 방법으로는 `ESC` 키가 있으며, 변경 사항이 없다면 `:q`를 입력하면 됩니다. + +![](/2022/Days/Images/Day17_Linux3.png) + +기본적으로 `normal` 모드에서 시작하고 `command, normal, visual, insert` 모드도 있습니다. 텍스트를 추가하려면 `i`를 눌러 `normal` 모드에서 `insert` 모드로 전환해야 합니다. 변경 사항을 저장하고 텍스트를 추가한 후에는 `ESC` 키를 누르고 `:wq`를 입력하면 됩니다. + +![](/2022/Days/Images/Day17_Linux4.png) + +![](/2022/Days/Images/Day17_Linux5.png) + +`cat` 명령으로 변경 사항을 저장했는지 확인할 수 있습니다. + +vim은 단축키만 알고 있다면 작은 작업도 매우 빠르게 수행할 수 있는 멋진 기능이 있습니다. 예를 들어, 반복되는 단어 목록을 추가한 후 이를 변경해야 한다고 가정해 봅시다. 구성 파일에서 네트워크 이름이 반복되는 경우, 이를 빠르게 변경하고 싶을 수 있습니다. 이 예시에서는 'day'라는 단어를 사용하고 있습니다. + +![](/2022/Days/Images/Day17_Linux6.png) + +'day'를 '90DaysOfDevOps'로 변경하려면, `ESC` 키를 누르고 `:%s/Day/90DaysOfDevOps`를 입력하면 됩니다. + +![](/2022/Days/Images/Day17_Linux7.png) + +이제 Enter 키를 누르면 'day'라는 단어가 '90DaysOfDevOps로' 바뀝니다. + +![](/2022/Days/Images/Day17_Linux8.png) + +복사 및 붙여넣기는 저에게 정말 큰 도움이 됐습니다. normal 모드에서는 키보드의 `yy`를 사용하여 복사할 수 있으며, 같은 줄에 `p`를 사용하여 붙여넣기하거나, 새 줄에 `P`를 사용하여 붙여넣기할 수 있습니다. + +특정 줄을 삭제하려면 삭제할 줄 수를 선택한 후 `dd`를 입력하면 됩니다. + +때로는 파일을 검색해야 할 필요가 있습니다. 이전 세션에서 언급한 것처럼 `grep`을 사용할 수 있지만, `/word`를 사용하면 첫 번째 일치 항목을 찾을 수 있으며, `n` 키를 사용하여 다음 항목으로 이동할 수 있습니다. + +제가 드릴 수 있는 가장 큰 조언은 가능한 한 직접 사용해 보라는 것입니다. + +일반적으로 면접에서 물어보는 질문 중 하나는, "Linux에서 가장 좋아하는 텍스트 편집기는 무엇인가요?" 입니다. 이 질문에 대답하려면 적어도 두 가지 이상의 텍스트 편집기를 알고 있어야 하며, nano에 대한 대답도 괜찮습니다. 이 질문에 대답하는 것은 적어도 텍스트 편집기가 무엇인지 이해했음을 보여주는 것입니다. 하지만 더욱 능숙하게 사용하려면 직접 사용해 보는 것이 좋습니다. + +vim에서 방향키로 사용할 수 있는 키는 화살표 키뿐만 아니라 `H,J,K,L`도 사용할 수 있습니다. + +## 자료 + +- [Vim in 100 Seconds](https://www.youtube.com/watch?v=-txKSRn0qeA) +- [Vim tutorial](https://www.youtube.com/watch?v=IiwGbcd8S7I) +- [Learn the Linux Fundamentals - Part 1](https://www.youtube.com/watch?v=kPylihJRG70) +- [Linux for hackers (don't worry you don't need to be a hacker!)](https://www.youtube.com/watch?v=VbEx7B_PTOE) + +[Day 18](day18.md)에서 봐요! diff --git a/2022/ko/Days/day18.md b/2022/ko/Days/day18.md new file mode 100644 index 0000000..d277581 --- /dev/null +++ b/2022/ko/Days/day18.md @@ -0,0 +1,213 @@ +--- +title: '#90DaysOfDevOps - SSH & Web Server - Day 18' +published: false +description: 90DaysOfDevOps - SSH & Web Server +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048733 +--- + +## SSH 및 웹 서버 + +앞서 언급한 바와 같이, 여러분은 다수의 원격 Linux 서버를 관리할 가능성이 높습니다. 그러므로 이러한 원격 서버와의 연결이 안전한지 확인하는 것이 중요합니다. 본 섹션에서는 원격 시스템과의 보안 터널 구축을 돕기 위해, 모든 사용자가 알아야 할 SSH의 주요 기본 개념들을 살펴볼 것입니다. + +- SSH로 연결 설정하기 +- 파일 전송하기 +- 개인 키 만들기 + +### SSH 소개 + +- 보안 shell +- 네트워킹 프로토콜 +- 보안 통신 허용 +- 모든 네트워크 서비스를 보호 +- 일반적으로 원격 command line 액세스에 사용 + +사실 우린 이미 vagrant 구성과 자동화를 통해 SSH를 사용하고 있었습니다. `vagrant ssh`만 실행해도 원격 가상 머신에 접근할 수 있었습니다. + +원격 머신이 워크스테이션과 동일한 시스템이 아니라 원격 위치, 클라우드 기반 시스템이거나 인터넷을 통해서만 접근할 수 있는 데이터 센터에서 실행될 경우, 시스템을 안전하게 관리하기 위한 접근 방법이 필요합니다. + +SSH는 클라이언트와 서버 간의 보안 터널을 제공하여 공격자가 정보를 가로챌 수 없게 합니다. + +![](/2022/Days/Images/Day18_Linux1.png) + +서버에는 항상 특정한 TCP 포트(22)에서 실행되어 대기 중인 서버 측 SSH 서비스가 존재합니다. + +올바른 자격증명이나 SSH 키를 가진 클라이언트를 사용하면 해당 서버에 접근할 수 있습니다. + +### 시스템에 브리지 네트워크 어댑터 추가하기 + +현재의 virtual box VM과 함께 사용하려면, 우리 시스템에 브리지 네트워크 어댑터를 추가해야 합니다. + +가상 머신을 종료한 다음, Virtual Box 내의 머신을 마우스 우클릭 후 Settings를 선택합니다. 새 창에서 Network를 선택하세요. + +![](/2022/Days/Images/Day18_Linux2.png) + +이제 가상 머신을 다시 시작하면 로컬 머신에서 IP 주소를 갖게 됩니다. `IP addr` 명령어로 확인할 수 있습니다. + +### SSH 서버 실행 확인 + +우리는 vagrant를 사용해왔기 때문에 SSH가 우리 머신에 이미 설정되어 있다는 것을 알고 있지만, 다음 명령어를 실행하여 확인할 수도 있습니다. + +`sudo systemctl status ssh` + +![](/2022/Days/Images/Day18_Linux3.png) + +시스템에 SSH 서버가 없으면 `sudo apt install OpenSSH-server` 명령어를 사용하여 설치할 수 있습니다. + +방화벽이 실행 중인 경우 SSH가 허용되도록 하려면 `sudo ufw allow ssh`를 사용할 수 있습니다. 하지만 vagrant 프로비저닝을 사용하여 자동화했으므로 이 작업은 필요하지 않습니다. + +### 원격 접속 - SSH password + +이제 SSH 서버가 포트 22에서 들어오는 연결 요청을 수신하도록 설정했고 브리지 네트워킹을 추가했으므로, 로컬 머신의 putty 또는 SSH 클라이언트를 사용하여 SSH로 시스템에 연결할 수 있습니다. + +[# PuTTy installation Guide](https://www.cuit.columbia.edu/putty) + +![](/2022/Days/Images/Day18_Linux4.png) + +Open을 클릭하세요. 이 IP 주소를 통해 처음으로 이 시스템에 연결하는 경우 경고가 표시됩니다. 이 시스템이 우리 것임을 알고 있으므로 Yes를 선택할 수 있습니다. + +![](/2022/Days/Images/Day18_Linux5.png) + +username(vagrant)과 password(기본 - vagrant)를 입력하라는 메시지가 표시됩니다. 아래에서 SSH 클라이언트(PuTTY)를 사용하여 username과 password로 머신에 연결하는 것을 확인할 수 있습니다. + +![](/2022/Days/Images/Day18_Linux6.png) + +이제부터 우리의 원격 클라이언트는 VM에 연결되어 있으며, 시스템에서 명령어를 실행할 수 있습니다. + +### 원격 접속 - SSH 키 + +앞서 설명한 방법으로 시스템에 쉽게 액세스할 수 있지만, username과 password에 의존하고 있습니다. 악의적인 사용자가 이 정보와 시스템의 공용 주소 또는 IP를 알게 되면 쉽게 침입할 수 있습니다. 이 때문에 SSH 키가 선호됩니다. + +SSH 키를 사용하면, 클라이언트와 서버 모두 이 장치가 신뢰할 수 있는 것임을 알 수 있는 키 쌍을 제공합니다. + +키를 생성하는 것은 쉽습니다. 로컬 머신(Windows)에서 다음 명령어를 실행하면 됩니다. 시스템에 SSH 클라이언트가 설치되어 있다면 이 명령어가 작동할 것입니다. + +`ssh-keygen -t ed25519` + +여기에서 `ed25519`가 무엇인지에 대해 자세히 설명하지는 않겠지만, 암호학에 관심이 있다면 [cryptography](https://en.wikipedia.org/wiki/EdDSA#Ed25519)를 참고해보세요. + +![](/2022/Days/Images/Day18_Linux7.png) + +생성된 SSH 키는 `C:\Users\micha/.ssh/`에 저장되어 있습니다. + +하지만 이 키로 Linux VM에 연결하려면 키를 복사해야 합니다. `ssh-copy-id vagrant@192.168.169.135`를 사용하여 이 작업을 수행할 수 있습니다. + +Windows 클라이언트에서 Powershell을 사용하여 키를 생성했지만, Windows에는 `ssh-copy-id`를 실행할 수 없습니다. Windows에서 이 작업을 수행하는 방법이 있으며, 온라인에서 간단한 검색을 통해 대체 방법을 찾을 수 있습니다. 여기서는 Windows 머신에서 git bash를 사용하여 복사하는 것을 보여 드리겠습니다. + +![](/2022/Days/Images/Day18_Linux8.png) + +이제 Powershell로 돌아와 password 없이 SSH 키로 연결이 작동하는지 테스트할 수 있습니다. + +`ssh vagrant@192.168.169.135` + +![](/2022/Days/Images/Day18_Linux9.png) + +필요한 경우 passphrase를 사용하여 더욱 안전하게 만들 수 있습니다. 또한 password 없이 키 쌍만을 사용하여 SSH를 허용하도록 설정할 수 있습니다. 이렇게 하려면 다음 설정 파일에서 수정하면 됩니다. + +`sudo nano /etc/ssh/sshd_config` + +여기에 `#` 주석 처리가 되어있는 `PasswordAuthentication yes`라는 줄이 있고, 이를 주석 처리 해제하고 yes를 no로 변경해야 합니다. 그런 다음 `sudo systemctl reload sshd`를 실행해서 SSH 서비스를 다시 로드해야 합니다. + +## 웹 서버 설정하기 + +위에서 설명한 SSH와는 별개로, 이번에는 웹 서버를 구축하는 방법을 다루고자 합니다. 처음에는 조금 어려워 보일 수 있지만, 실제로는 그렇지 않습니다. + +리눅스 가상 머신을 이미 구축해 두었다고 가정하고, 이 가상 머신에 apache 웹 서버를 추가하여 내부 네트워크에서 접근할 수 있는 간단한 웹 사이트를 호스팅하려고 합니다. 인터넷에서 접근할 수 있는 웹 사이트는 아니며, 그에 대한 내용은 여기서 다루지 않습니다. + +이 과정은 LAMP 스택이라고도 불립니다. + +- **L**inux 운영 체제 +- **A**pache 웹 서버 +- **M**ySQL 데이터베이스 +- **P**HP + +### Apache2 + +Apache2는 오픈 소스 HTTP 서버입니다. 아래 명령어를 사용하여 Apache2를 설치할 수 있습니다. + +`sudo apt-get install apache2` + +Apache2가 정상적으로 설치되었는지 확인하려면 `sudo service apache2 restart`를 실행합니다. + +SSH 통합 네트워크 주소를 사용하여 브라우저에서 해당 주소로 이동합니다. 예를 들면 `http://192.168.169.135/`와 같습니다. + +![](/2022/Days/Images/Day18_Linux10.png) + +### MySQL + +MySQL은 웹 사이트의 데이터를 저장하는 데이터베이스입니다. `sudo apt-get install mysql-server` 명령어를 사용하여 MySQL을 설치합니다. + +### PHP + +PHP는 서버 측 스크립팅 언어로, MySQL 데이터베이스와 상호 작용하기 위해 사용합니다. PHP 및 종속성을 설치하려면 `sudo apt-get install php libapache2-mod-php php-mysql`을 사용합니다. + +기본적으로 Apache는 index.html을 사용하지만, 대신 index.php를 사용하도록 설정하려고 합니다. + +`sudo nano /etc/apache2/mods-enabled/dir.conf`를 사용하여 index.php를 목록의 첫 번째 항목으로 이동시킵니다. + +![](/2022/Days/Images/Day18_Linux11.png) + +Apache2 서비스를 다시 시작합니다. `sudo systemctl restart apache2` + +이제 PHP가 올바르게 구성되었는지 확인해 보겠습니다. 다음 명령어를 사용하여 새 파일을 생성합니다. + +`sudo nano /var/www/html/90Days.php` + +아래 내용을 복사한 후 Ctrl + X를 눌러 종료하고 파일을 저장합니다. + +```php + +``` + +다음 URL로 이동하여 PHP가 올바르게 구성되었는지 확인합니다. `http://192.168.169.135/90Days.php` 이 주소로 이동하면 PHP가 올바르게 설정되었음을 확인할 수 있는 화면이 표시됩니다. + +![](/2022/Days/Images/Day18_Linux12.png) + +### 워드프레스 설치 + +LAMP 스택에 워드프레스를 설치하기 위해 [How to install WordPress on Ubuntu with LAMP](https://blog.ssdnodes.com/blog/how-to-install-wordpress-on-ubuntu-18-04-with-lamp-tutorial/)을 참고하였습니다. 이 글에 나와 있는 명령어들은 아래와 같습니다. + +`sudo mysql -u root -p` + +`CREATE DATABASE wordpressdb;` + +`CREATE USER 'admin-user'@'localhost' IDENTIFIED BY 'password';` + +`GRANT ALL PRIVILEGES ON wordpressdb.* TO 'admin-user'@'localhost';` + +`FLUSH PRIVILEGES;` + +`EXIT;` + +`sudo apt install php-curl php-gd php-mbstring php-xml php-xmlrpc php-soap php-intl php-zip` + +`sudo systemctl restart apache2` + +`cd /var/www` + +`sudo curl -O https://wordpress.org/latest.tar.gz` + +`sudo tar -xvf latest.tar.gz` + +`sudo rm latest.tar.gz` + +위 링크의 Step 4에 도달했습니다. 워드프레스 디렉토리에 대한 모든 권한이 올바르게 설정되어 있는지 확인해야 합니다. + +내부 네트워크 전용이므로 이 단계에서 "generate security keys"를 할 필요가 없습니다. apache 구성을 워드프레스로 변경하는 Step 5로 이동합니다. + +모든 설정이 올바르게 구성되어 있다면, 내부 네트워크 주소를 통해 워드프레스 설치를 진행할 수 있습니다. + +## 자료 + +- [Client SSH GUI - Remmina](https://remmina.org/) +- [The Beginner's guide to SSH](https://www.youtube.com/watch?v=2QXkrLVsRmk) +- [Vim in 100 Seconds](https://www.youtube.com/watch?v=-txKSRn0qeA) +- [Vim tutorial](https://www.youtube.com/watch?v=IiwGbcd8S7I) +- [Learn the Linux Fundamentals - Part 1](https://www.youtube.com/watch?v=kPylihJRG70) +- [Linux for hackers (don't worry you don't need to be a hacker!)](https://www.youtube.com/watch?v=VbEx7B_PTOE) + +[Day 19](day19.md)에서 봐요! diff --git a/2022/ko/Days/day19.md b/2022/ko/Days/day19.md new file mode 100644 index 0000000..4ceb99a --- /dev/null +++ b/2022/ko/Days/day19.md @@ -0,0 +1,310 @@ +--- +title: '#90DaysOfDevOps - Automate tasks with bash scripts - Day 19' +published: false +description: 90DaysOfDevOps - Automate tasks with bash scripts +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048774 +--- + +## bash 스크립팅을 이용한 작업 자동화 + +오늘 사용할 shell은 bash이지만, 내일 ZSH에 대해 다룰 때 다른 shell도 다룰 예정입니다. + +BASH - **B**ourne **A**gain **Sh**ell + +프로그래밍 언어처럼 shell 스크립팅에도 거의 일주일 동안의 섹션을 쓸 수 있습니다. bash는 다른 자동화 도구와 함께 작업하는 기능을 제공합니다. + +여전히 많은 사람들이 복잡한 shell 스크립트를 만들어 무언가를 실행하게 하고, 비즈니스에서 가장 중요한 부분을 이 스크립트에 의존하고 있다고 합니다. 하지만 이런 이유로 shell/bash 스크립팅을 이해해야 한다고 말하는 것은 아닙니다. 자동화 도구와 함께 사용하고 ad-hoc(특별한) 작업을 위해 shell/bash 스크립팅을 배워야 합니다. + +이 섹션에서 사용한 예로, 매주 월요일 아침에 리눅스 VM을 새로 생성하고, 해당 리눅스 기계에 필요한 모든 소프트웨어 스택을 추가하는 등의 작업을 할 수 있는 간단한 bash 스크립트로 VAGRANTFILE을 감쌀 수 있습니다. + +면접에서 스크립팅 경험 관련 질문이 점점 더 많아지고 있다는 소식도 종종 듣고 있습니다. + +### 시작하기 + +이 90일 동안 다루는 많은 것들과 마찬가지로, 진정한 배움은 경험을 통해 알게 됩니다. 실제로 경험을 통해 배우면 기억에 오래 남습니다. + +우선, 텍스트 에디터가 필요합니다. [Day 17](day17.md)에 가장 일반적인 텍스트 에디터 두 가지와 그것들을 어떻게 사용하는지에 대해 다뤘습니다. + +첫 번째 shell 스크립트를 생성해봅시다. + +`touch 90DaysOfDevOps.sh` + +그다음 `nano 90DaysOfDevOps.sh`를 입력하면 nano에서 새로운 빈 shell 스크립트가 열립니다. 여기서 원하는 텍스트 에디터를 선택할 수 있습니다. + +모든 bash 스크립트의 첫 줄은 다음과 같아야 합니다: `#!/usr/bin/bash`(bash 바이너리의 경로입니다.) + +터미널에서 `which bash`를 실행하여 이를 확인해야 합니다. Ubuntu를 사용하지 않는 경우 터미널에서는 `whereis bash`도 시도해 볼 수 있습니다. + +그러나 이미 생성된 shell 스크립트는 다른 경로들이 있을 수도 있습니다: + +- `#!/bin/bash` +- `#!/usr/bin/env bash` + +스크립트의 다음 줄에는 주석을 추가하여 스크립트의 목적이나 스크립트에 대한 정보를 제공합니다. `#`을 사용하면 코드의 특정 줄에 주석을 달고 다가올 명령어가 무엇을 할 것인지 설명할 수 있습니다. 주석을 많이 남길수록 사용자 경험이 향상된다고 생각합니다. 특히 공유할 때 그렇습니다. + +리눅스 섹션에서 설치한 figlet 프로그램을 사용하여 스크립트에서 asci 아트를 만들 때도 있습니다. + +![](/2022/Days/Images/Day19_Linux1.png) + +이 리눅스 섹션에서 앞서 다룬 모든 명령어들([Day 15](day15.md))은 스크립트를 테스트하는 간단한 명령어로 사용할 수 있습니다. + +스크립트에 간단한 코드 블록을 추가해 봅시다. + +```bash +mkdir 90DaysOfDevOps +cd 90DaysOfDevOps +touch Day19 +ls +``` + +텍스트 에디터를 저장하고 종료한 후, `./90DaysOfDevOps.sh`를 실행하면 권한이 거부되었다는 메시지가 표시됩니다. `ls -al` 명령을 사용하여 이 파일의 권한을 확인할 수 있는데 이 파일에 실행 권한이 없음을 확인할 수 있습니다. + +![](/2022/Days/Images/Day19_Linux2.png) + +`chmod +x 90DaysOfDevOps.sh`를 사용하여 이를 변경한 다음 `x`인 것을 봤을 때 스크립트를 실행할 수 있음을 확인할 수 있습니다. + +![](/2022/Days/Images/Day19_Linux3.png) + +`./90DaysOfDevOps.sh`를 사용하여 스크립트를 다시 실행할 수 있습니다. 스크립트를 실행한 후 새 디렉토리가 생성되고 해당 디렉토리로 이동한 다음 새 파일이 생성됩니다. + +![](/2022/Days/Images/Day19_Linux4.png) + +기본적인 것들이지만, 다른 도구를 호출하여 일상적인 작업을 쉽게 만들고 자동화하는 데 사용할 수 있다는 것을 알 수 있습니다. + +### 변수, 조건문 + +이 섹션의 대부분은 Golang을 배울 때 다룬 것과 중복되지만, 여기에서 다시 살펴볼 가치가 있다고 생각합니다. + +- ### 변수 + +변수를 사용하면 스크립트 내에서 반복되는 특정 용어를 한 번만 정의할 수 있습니다. + +스크립트에 변수를 추가하려면 다음과 같이 새로운 줄에 입력하면 됩니다. + +`challenge="90DaysOfDevOps"` + +이렇게 하면 코드에서 `$challenge`를 사용할 때 변수가 변경되면 전체에 반영됩니다. + +![](/2022/Days/Images/Day19_Linux5.png) + +이제 `sh` 스크립트를 실행하면 스크립트에 추가된 출력이 표시됩니다. + +![](/2022/Days/Images/Day19_Linux6.png) + +또한 다음과 같이 사용자 입력을 요청하여 변수를 설정할 수도 있습니다: + +```bash +echo "Enter your name" +read name +``` + +이렇게 하면 입력이 변수 `$name`으로 정의됩니다. 이후에 이를 사용할 수 있습니다. + +- ### 조건문 + +우리는 도전 과제에 참여한 사람과 그들이 완료한 날짜 수를 알아보고 싶을 수도 있습니다. 이를 `if`, `if-else`, `else-if` 조건문을 사용해 정의할 수 있습니다. 아래 스크립트에 이를 정의한 것을 확인할 수 있습니다. + +```bash +#!/bin/bash +# ___ ___ ____ ___ __ ____ ___ +# / _ \ / _ \| _ \ __ _ _ _ ___ / _ \ / _| _ \ _____ __/ _ \ _ __ ___ +#| (_) | | | | | | |/ _` | | | / __| | | | |_| | | |/ _ \ \ / / | | | '_ \/ __| +# \__, | |_| | |_| | (_| | |_| \__ \ |_| | _| |_| | __/\ V /| |_| | |_) \__ \ +# /_/ \___/|____/ \__,_|\__, |___/\___/|_| |____/ \___| \_/ \___/| .__/|___/ +# |___/ |_| +# +# 이 스크립트는 bash 스크립팅을 시연하기 위한 것입니다! + +# 정의할 변수 + +ChallengeName=#90DaysOfDevOps +TotalDays=90 + +# 사용자 입력 + +echo "Enter Your Name" +read name +echo "Welcome $name to $ChallengeName" +echo "How Many Days of the $ChallengeName challenge have you completed?" +read DaysCompleted + +if [ $DaysCompleted -eq 90 ] +then + echo "You have finished, well done" +elif [ $DaysCompleted -lt 90 ] +then + echo "Keep going you are doing great" +else + echo "You have entered the wrong amount of days" +fi +``` + +다음 단계로 이동하기 위해 값을 비교하거나 확인하는 과정을 위에서 볼 수 있습니다. 여기서 주목할 만한 다양한 옵션이 있습니다. + +- `eq` - 두 값이 같으면 TRUE 반환 +- `ne` - 두 값이 같지 않으면 TRUE 반환 +- `gt` - 첫 번째 값이 두 번째 값보다 크면 TRUE 반환 +- `ge` - 첫 번째 값이 두 번째 값보다 크거나 같으면 TRUE 반환 +- `lt` - 첫 번째 값이 두 번째 값보다 작으면 TRUE 반환 +- `le` - 첫 번째 값이 두 번째 값보다 작거나 같으면 TRUE 반환 + +파일 및 폴더에 대한 정보를 결정하기 위해 bash 스크립팅을 사용할 수도 있습니다. 이를 파일 조건이라고 합니다. + +- `-d file` 파일이 디렉토리인 경우 True +- `-e file` 파일이 존재하는 경우 True +- `-f file` 제공된 문자열이 파일인 경우 True +- `-g file` 파일에 그룹 ID가 설정된 경우 True +- `-r file` 파일이 읽을 수 있는 경우 True +- `-s file` 파일의 크기가 0이 아닌 경우 True + +```bash +FILE="90DaysOfDevOps.txt" +if [ -f "$FILE" ] +then + echo "$FILE is a file" +else + echo "$FILE is not a file" +fi +``` + +![](/2022/Days/Images/Day19_Linux7.png) + +디렉토리에 파일이 아직 있다면 첫 번째 echo를 반환해야 합니다. 그러나 파일을 제거하면 두 번째 echo를 반환하게 됩니다. + +![](/2022/Days/Images/Day19_Linux8.png) + +특정 항목을 시스템에서 검색할 때 시간을 절약하는 데 사용할 수 있는 방법을 확인하실 수 있습니다. + +GitHub에서 놀라운 저장소를 발견했습니다. 많은 스크립트를 가진 것 같습니다. [DevOps Bash Tools](https://github.com/HariSekhon/DevOps-Bash-tools/blob/master/README.md) + +### 예제 + +**시나리오**: 우리 회사는 "90DaysOfDevOps"라는 이름을 가지고 있으며, 이제 확장할 때가 왔습니다. 1인 팀에서 다음 몇 주 동안 더 많은 사람으로 늘리려고 합니다. 지금까지 나만이 온보딩 과정을 알고 있으므로, 이러한 작업 중 일부를 자동화하여 병목 현상을 줄이고자 합니다. + +**요구 사항**: + +- 사용자 이름이 커맨드 라인 인수로 전달될 수 있습니다. +- 커맨드 라인 인수의 이름으로 사용자가 생성됩니다. +- password가 커맨드 라인 인수로 전달될 수 있습니다. +- 사용자의 password가 설정됩니다. +- 계정 생성이 성공적으로 이루어졌음을 나타내는 메시지가 표시됩니다. + +먼저 `touch create_user.sh`를 사용하여 shell 스크립트를 생성합시다. + +계속 진행하기 전에, `chmod +x create_user.sh`를 사용하여 이를 실행 가능하게 만들어줍시다. + +그런 다음 `nano create_user.sh`를 사용하여 설정한 시나리오에 대한 스크립트 편집을 시작하겠습니다. + +첫 번째 요구 사항인 "사용자 이름이 커맨드 라인 인수로 전달될 수 있습니다."는 다음과 같이 사용할 수 있습니다. + +```bash +#! /usr/bin/bash + +# 사용자 이름이 커맨드 라인 인수로 전달될 수 있습니다. +echo "$1" +``` + +![](/2022/Days/Images/Day19_Linux9.png) + +이를 실행하려면 `./create_user.sh Michael`을 사용하십시오. Michael 대신에 당신의 이름을 사용하세요. + +![](/2022/Days/Images/Day19_Linux10.png) + +다음으로 두 번째 요구 사항인 "커맨드 라인 인수의 이름으로 사용자가 생성됩니다."를 처리할 수 있습니다. 이는 `useradd` 명령어를 사용하여 수행할 수 있습니다. `-m` 옵션은 사용자 홈 디렉토리를 /home/username으로 생성하기 위한 것입니다. + +```bash +#! /usr/bin/bash + +# 사용자 이름이 커맨드 라인 인수로 전달될 수 있습니다. +echo "$1 user account being created." + +# 커맨드 라인 인수의 이름으로 사용자가 생성됩니다. +sudo useradd -m "$1" +``` + +경고: 사용자 계정 이름을 제공하지 않으면 `$1` 변수가 채워지지 않아 오류가 발생합니다. + +계정이 생성되었는지 확인하려면 `awk -F: '{ print $1}' /etc/passwd` 명령을 사용합니다. + +![](/2022/Days/Images/Day19_Linux11.png) + +다음 요구 사항은 "password가 커맨드 라인 인수로 전달될 수 있습니다."입니다. 먼저, 이는 실제 환경에서는 절대 사용하지 않는 것이 좋습니다. 이는 단지 연습을 위한 것이며, 이를 통해 요구 사항을 이해할 수 있습니다. + +```bash +#! /usr/bin/bash + +# 사용자 이름이 커맨드 라인 인수로 전달될 수 있습니다. +echo "$1 user account being created." + +# 커맨드 라인 인수의 이름으로 사용자가 생성됩니다. +sudo useradd -m "$1" + +# password가 커맨드 라인 인수로 전달될 수 있습니다. +sudo chpasswd <<< "$1":"$2" +``` + +두 개의 파라미터로 이 스크립트를 실행하려면 `./create_user.sh 90DaysOfDevOps password`를 사용하세요. + +아래 이미지에서 스크립트를 실행하여 사용자와 password를 생성한 다음, 수동으로 해당 사용자로 전환하고 `whoami` 명령으로 확인했다는 것을 알 수 있습니다. + +![](/2022/Days/Images/Day19_Linux12.png) + +마지막 요구 사항은 "계정 생성이 성공적으로 이루어졌음을 나타내는 메시지가 표시됩니다."입니다. 우리는 이미 코드의 첫 번째 줄에 이를 포함하고 있으며, 위의 스크린샷에서 `90DaysOfDevOps user account being created`라는 메시지가 표시되는 것을 볼 수 있습니다. 이는 `$1` 매개변수로 테스트할 때 남겨진 것입니다. + +이제 이 스크립트를 사용하여 리눅스 시스템에 새 사용자를 빠르게 온보딩하고 설정할 수 있습니다. 하지만 기존 사용자 중 몇 명이 이 과정을 거쳐 다른 사람들에게 새 사용자 이름이나 password를 알려주는 대신 앞서 다룬 사용자 입력을 추가하여 변수를 수집할 수 있습니다. + +```bash +#! /usr/bin/bash + +echo "What is your intended username?" +read username +echo "What is your password" +read password + +# 사용자 이름이 커맨드 라인 인수로 전달될 수 있습니다. +echo "$username user account being created." + +# 커맨드 라인 인수의 이름으로 사용자가 생성됩니다. +sudo useradd -m $username + +# password가 커맨드 라인 인수로 전달될 수 있습니다. +sudo chpasswd <<< $username:$password +``` + +단계를 더욱 인터랙티브하게 만들면 + +![](/2022/Days/Images/Day19_Linux14.png) + +마무리하기 위해, 새 사용자 계정이 생성되었다는 성공적인 출력을 원할 수도 있습니다. + +![](/2022/Days/Images/Day19_Linux15.png) + +한 가지 눈에 띄는 점은 입력 시 비밀번호가 표시된다는 점인데, 코드 `read -s password`에서의 `-s` 플래그를 사용하여 이를 숨길 수 있습니다. + +![](/2022/Days/Images/Day19_Linux16.png) + +실험 목적으로 생성한 사용자를 삭제하려면 `sudo userdel test_user`를 사용할 수 있습니다. + +[예제 스크립트](/2022/Days/Linux/create-user.sh) + +한 번 더 강조하고 싶은 바는, 이것은 shell 스크립팅이 유연하게 활용될 수 있는 다양한 용도를 갖는다는 것을 강조하기 위해 만들어진 것이라는 것입니다. + +매일, 매주, 매월 반복되는 작업이 어떤 것이 있는지 생각해보고, 그것을 어떻게 더 잘 자동화할 수 있을지 생각해보세요. 첫 번째 옵션은 주로 bash 스크립트를 사용하는 것이며, 그 이후에는 더 복잡한 영역으로 이동할 수 있습니다. + +저는 제 로컬 머신에서 minikube를 사용하여 쿠버네티스 클러스터를 빠르게 생성하고 데이터 서비스 및 Kasten K10을 사용하여 데이터 관리에 대한 요구 사항과 필요성을 보여주기 위한 매우 간단한 [bash 파일](https://github.com/MichaelCade/project_pace/blob/main/singlecluster_demo.sh)을 생성했습니다만, 아직 쿠버네티스를 다루지 않았기 때문에 여기서 다루는 것이 적절하지 않다고 생각합니다. + +## 자료 + +- [Bash in 100 seconds](https://www.youtube.com/watch?v=I4EWvMFj37g) +- [Bash script with practical examples - Full Course](https://www.youtube.com/watch?v=TPRSJbtfK4M) +- [Client SSH GUI - Remmina](https://remmina.org/) +- [The Beginner's guide to SSH](https://www.youtube.com/watch?v=2QXkrLVsRmk) +- [Vim in 100 Seconds](https://www.youtube.com/watch?v=-txKSRn0qeA) +- [Vim tutorial](https://www.youtube.com/watch?v=IiwGbcd8S7I) +- [Learn the Linux Fundamentals - Part 1](https://www.youtube.com/watch?v=kPylihJRG70) +- [Linux for hackers (don't worry you don't need to be a hacker!)](https://www.youtube.com/watch?v=VbEx7B_PTOE) + +[Day 20](day20.md)에서 봐요! diff --git a/2022/ko/Days/day20.md b/2022/ko/Days/day20.md new file mode 100644 index 0000000..8bd14e8 --- /dev/null +++ b/2022/ko/Days/day20.md @@ -0,0 +1,166 @@ +--- +title: '#90DaysOfDevOps - Dev workstation setup - All the pretty things - Day 20' +published: false +description: 90DaysOfDevOps - Dev workstation setup - All the pretty things +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048734 +--- + +## 개발 워크스테이션 설정 - 예쁜 모든 것들 + +이 내용은 Linux 서버를 설정하는 것과 혼동되지 않도록 주의해야 하며, Linux 데스크톱의 선택성 및 유연성을 보여주고자 합니다. + +저는 거의 일 년 동안 Linux 데스크톱을 사용해 왔고, 외관과 느낌 측면에서 원하는 대로 구성했습니다. Ubuntu VM과 Virtual Box를 이용하여 사용자 지정 맞춤 구성을 해봅시다. + +더 쉽게 따라 할 수 있는 분들을 위해 설명 외의 부분에 대한 YouTube 동영상을 준비했습니다. + +[![Click to access YouTube Video](/2022/Days/Images/Day20_YouTube.png)](https://youtu.be/jeEslAtHfKc) + +기본적으로 시스템은 아래와 같이 표시됩니다. + +![](/2022/Days/Images/Day20_Linux1.png) + +기본 bash shell은 아래에서 볼 수 있습니다. + +![](/2022/Days/Images/Day20_Linux2.png) + +이 중 많은 부분이 dotfiles와 관련이 있으며, 이 시리즈의 마지막 Linux 세션에서 다루게 됐습니다. + +### dotfiles + +먼저 dotfiles에 대해 알아보고 싶습니다. 리눅스가 구성 파일로 구성되어 있다고 이전에 언급했습니다. 이 dotfiles는 리눅스 시스템과 응용 프로그램의 구성 파일입니다. + +또한 dotfiles는 데스크톱을 꾸미고 예쁘게 만드는 데 사용되는 것뿐만 아니라 생산성을 돕는 구성 변경 및 설정이 있다고 덧붙입니다. + +앞서 언급했듯이 많은 소프트웨어 프로그램들이 이 dotfiles에 구성을 저장합니다. 이 dotfiles는 기능 관리를 돕습니다. + +각 dotfile은 `.`으로 시작합니다. 이름이 어떻게 지어졌는지 짐작할 수 있을 것입니다. + +지금까지 우리는 shell로서 bash를 사용해 왔으므로 홈 폴더에 .bashrc와 .bash_profile이 있을 것입니다. 아래에서 시스템에 있는 몇 가지 dotfiles를 볼 수 있습니다. + +![](/2022/Days/Images/Day20_Linux3.png) + +우리는 shell을 변경할 것이므로, 나중에 새로운 `.zshrc` dotfile을 볼 수 있습니다. + +dotfiles은 구성 파일임을 알 수 있습니다. 우리는 이것들을 사용하여 명령 프롬프트에 별칭을 추가하거나 다른 위치로 경로를 추가할 수 있습니다. 일부 사람들은 자신의 dotfiles를 공개적으로 사용할 수 있도록 게시합니다. 제 dotfiles는 [MichaelCade/dotfiles](https://github.com/MichaelCade/dotfiles)에서 찾을 수 있습니다. 여기에는 저의 맞춤형 `.zshrc` 파일, 제가 선택한 터미널인 terminator의 구성 파일이 폴더에 있고, 그리고 일부 배경 옵션이 있습니다. + +### ZSH + +앞에서 언급했듯이, 지금까지의 상호 작용에서 우리는 기본 shell인 Ubuntu와 함께 제공되는 bash shell을 사용했습니다. ZSH는 매우 유사하지만, bash보다 몇 가지 이점이 있습니다. + +Zsh에는 대화형 탭 완성, 자동 파일 검색, 정규식 통합, 명령 범위를 정의하는 고급 단축어 및 풍부한 테마 엔진과 같은 기능이 있습니다. + +우리는 `apt` 패키지 관리자를 사용하여 시스템에 zsh를 설치할 수 있습니다. bash 터미널에서 `sudo apt install zsh`를 실행해 봅시다. 이 작업은 VM 콘솔 내에서 수행할 예정이며 SSH를 통해 연결하는 대신에 진행합니다. + +설치 명령이 완료되면 터미널 내에서 `zsh`를 실행할 수 있으며, 이렇게 하면 shell 구성 스크립트가 시작됩니다. + +![](/2022/Days/Images/Day20_Linux4.png) + +위 질문에 대해 `1`을 선택했고, 이제 더 많은 옵션을 볼 수 있습니다. + +![](/2022/Days/Images/Day20_Linux5.png) + +이 메뉴에서 몇 가지 기본 제공 편집을 통해 필요에 따라 ZSH를 구성할 수 있음을 알 수 있습니다. + +`0`으로 종료한 다음 `ls -al | grep .zshrc`를 사용하면 새로운 구성 파일이 있는 것을 확인할 수 있습니다. + +이제 우리는 터미널을 열 때마다 zsh를 기본 shell로 사용하려고 합니다. 이를 위해 shell을 변경하는 `chsh -s $(which zsh)` 명령을 실행할 수 있습니다. 그런 다음 로그아웃하고 다시 로그인하여 변경 사항이 적용되도록 해야 합니다. + +로그인 후 터미널을 열면 아래와 같이 보일 것입니다. 또한 `which $SHELL`을 실행하여 shell이 변경되었음을 확인할 수 있습니다. + +![](/2022/Days/Images/Day20_Linux6.png) + +일반적으로 저는 각 Ubuntu 데스크톱에서 이 단계를 수행하며, 이 외에도 zsh shell이 bash보다 약간 빠르다고 느낍니다. + +### OhMyZSH + +다음으로 터미널 내에서 조금 더 나은 모습과 추가 기능을 제공하고자 합니다. + +OhMyZSH는 zsh 구성을 관리하기 위한 무료 오픈 소스 프레임워크입니다. 플러그인, 테마 등 많은 것들이 있어 zsh shell과 상호 작용하는 것이 훨씬 재밌습니다. + +[ohmyzsh](https://ohmyz.sh/)에 대한 자세한 정보를 확인해보세요. + +Oh My ZSH를 설치합시다. `curl`, `wget` 또는 `fetch` 중에서 선택할 수 있는데, 첫 번째 두 가지는 시스템에서 사용 가능하지만, `curl`로 시작하겠습니다. + +`sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"` + +위 명령을 실행하면 아래와 같은 출력을 볼 수 있습니다. + +![](/2022/Days/Images/Day20_Linux7.png) + +이제 우리의 경험을 위한 테마를 시작할 수 있습니다. Oh My ZSH에는 100개 이상의 테마가 포함되어 있지만, 저의 모든 애플리케이션과 모든 것에 대한 기본값은 Dracula 테마입니다. + +또한 Oh My ZSH를 사용할 때 다음 두 가지 플러그인을 반드시 사용해야 한다고 강조하고 싶습니다. + +`git clone https://github.com/zsh-users/zsh-autosuggestions.git $ZSH_CUSTOM/plugins/zsh-autosuggestions` + +`git clone https://github.com/zsh-users/zsh-syntax-highlighting.git $ZSH_CUSTOM/plugins/zsh-syntax-highlighting` + +`nano ~/.zshrc` + +플러그인을 편집하여 이제 `plugins=(git zsh-autosuggestions zsh-syntax-highlighting)`를 포함하도록 합니다. + +### Gnome Extensions + +저는 Gnome Extensions도 사용하며, 특히 아래 목록을 사용합니다. + +[Gnome extensions](https://extensions.gnome.org) + + - Caffeine + - CPU Power Manager + - Dash to Dock + - Desktop Icons + - User Themes + +## 소프트웨어 설치 + +`apt`를 사용하여 제 컴퓨터에 설치한 프로그램 목록입니다. + + - VSCode + - azure-cli + - containerd.io + - docker + - docker-ce + - google-cloud-sdk + - insomnia + - packer + - terminator + - terraform + - vagrant + +### Dracula 테마 + +[Dracula Theme](https://draculatheme.com/)는 제가 유일하게 사용하는 테마입니다. 깔끔하고 명확한 모습이며 모든 것이 훌륭해 보입니다. 이 사이트에서는 컴퓨터에서 사용하는 다양한 프로그램을 지원합니다. + +위 링크에서 zsh를 검색하면 최소 두 가지 옵션을 찾을 수 있습니다. + +수동 설치 또는 git을 사용하여 설치할 수 있는 지침을 따릅니다. 그런 다음 아래와 같이 `.zshrc` 구성 파일을 편집해야 합니다. + +![](/2022/Days/Images/Day20_Linux8.png) + +다음으로 [Gnome Terminal Dracula theme](https://draculatheme.com/gnome-terminal)를 원하게 될 텐데, 여기에 모든 지침이 나와 있습니다. + +모든 단계를 문서화하는 데 오랜 시간이 걸릴 것이므로, 저는 과정을 동영상으로 제공했습니다.(아래 이미지를 클릭하세요) + +[![](/2022/Days/Images/Day20_YouTube.png)](https://youtu.be/jeEslAtHfKc) + +여기까지 왔다면, 이제 #90DaysOfDevOps의 Linux 섹션을 완료했습니다. 다시 한번, 피드백과 추가 자료에 대해서는 언제든지 환영입니다. + +여기에 적는 것보다 동영상을 통해 많은 단계를 보여드리는 것이 더 쉬울거라고 생각했는데, 이에 대해 어떻게 생각하시나요? 저는 이 글을 다시 읽어보고 가능하면 동영상 연습을 만들어서 우리가 다룬 내용들을 더 잘 설명하고 보여줄 수 있도록 하고자 합니다. 어떻게 생각하시나요? + +## 자료 + +- [Bash in 100 seconds](https://www.youtube.com/watch?v=I4EWvMFj37g) +- [Bash script with practical examples - Full Course](https://www.youtube.com/watch?v=TPRSJbtfK4M) +- [Client SSH GUI - Remmina](https://remmina.org/) +- [The Beginner's guide to SSH](https://www.youtube.com/watch?v=2QXkrLVsRmk) +- [Vim in 100 Seconds](https://www.youtube.com/watch?v=-txKSRn0qeA) +- [Vim tutorial](https://www.youtube.com/watch?v=IiwGbcd8S7I) +- [Learn the Linux Fundamentals - Part 1](https://www.youtube.com/watch?v=kPylihJRG70) +- [Linux for hackers (don't worry you don't need to be a hacker!)](https://www.youtube.com/watch?v=VbEx7B_PTOE) + +내일부터 7일간 네트워킹에 대해 알아보는 시간을 가지며, 데브옵스와 관련된 네트워킹에 대한 기초적인 지식과 이해를 쌓을 것입니다. + +[Day 21](day21.md)에서 봐요! diff --git a/2022/ko/Days/day21.md b/2022/ko/Days/day21.md new file mode 100644 index 0000000..180b1f9 --- /dev/null +++ b/2022/ko/Days/day21.md @@ -0,0 +1,115 @@ +--- +title: '#90DaysOfDevOps - The Big Picture: DevOps and Networking - Day 21' +published: false +description: 90DaysOfDevOps - The Big Picture DevOps and Networking +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048761 +--- + +## 큰 그림: 데브옵스와 네트워킹 + +모든 섹션과 마찬가지로 공개 및 무료 교육 자료를 사용하고 있으며 많은 콘텐츠가 다른 사람의 저작물일 수 있습니다. 네트워킹 섹션의 경우, 표시된 콘텐츠의 대부분은 [Practical Networking](https://www.practicalnetworking.net/)의 무료 [Networking Fundamentals series](https://www.youtube.com/playlist?list=PLIFyRwBY_4bRLmKfP1KnZA6rZbRHtxmXi)에서 가져온 것입니다. 리소스에도 링크와 함께 언급되어 있지만 커뮤니티의 관점에서 특정 기술 분야에 대한 이해를 돕기 위해 이 과정을 활용했기 때문에 이 점을 강조하는 것이 적절합니다. 이 저장소는 제 메모를 저장하고 커뮤니티가 이 과정과 나열된 리소스로부터 혜택을 받을 수 있도록 하는 저장소입니다. + +21일 차에 오신 것을 환영합니다! 앞으로 7일 동안 네트워킹과 데브옵스가 가장 중요한 주제이지만, 네트워킹의 기본에 대해서도 살펴볼 필요가 있을 것입니다. + +궁극적으로 앞서 말씀드렸듯이 데브옵스는 조직 내 문화와 프로세스 변화에 관한 것으로, 앞서 논의한 것처럼 가상 머신, 컨테이너 또는 Kubernetes가 될 수도 있지만 네트워크가 될 수도 있습니다. 데브옵스 관점에서 네트워크를 더 많이 포함해야 하는 인프라에 이러한 데브옵스 원칙을 사용한다면 사용 가능한 다양한 Topology 및 네트워킹 도구와 스택에서와 같이 네트워크에 대해서도 알아야 합니다. + +저는 코드로 인프라스트럭처의 네트워킹 디바이스를 구성하고 가상 머신처럼 모든 것을 자동화해야 한다고 주장하지만, 그렇게 하려면 무엇을 자동화할지 잘 이해해야 합니다. + +### 넷데브옵스 | 네트워크 데브옵스란 무엇인가요? + +네트워크 데브옵스 또는 넷데브옵스라는 용어를 들어보셨을 수도 있습니다. 이미 네트워크 엔지니어이고 인프라 내의 네트워크 구성 요소를 잘 파악하고 있다면 DHCP, DNS, NAT 등과 같은 네트워킹에 사용되는 요소를 이해하고 있을 것입니다. 또한 하드웨어 또는 소프트웨어 정의 네트워킹 옵션, 스위치, 라우터 등에 대해서도 잘 이해하고 있을 것입니다. + +하지만 네트워크 엔지니어가 아니라면 네트워크 데브옵스의 최종 목표를 이해하려면 이러한 영역 중 일부에 대한 전반적인 기초 지식이 필요할 수 있습니다. + +그러나 이러한 용어와 관련하여 NetDevOps 또는 네트워크 데브옵스를 네트워크에 데브옵스 원칙과 관행을 적용하고 버전 제어 및 자동화 도구를 네트워크 생성, 테스트, 모니터링 및 배포에 적용하는 것으로 생각할 수 있습니다. + +네트워크 데브옵스를 자동화가 필요한 것으로 생각한다면, 앞서 데브옵스가 팀 간의 사일로를 허무는 것에 대해 언급했습니다. 네트워킹 팀이 유사한 모델과 프로세스로 변경하지 않으면 병목 현상이 발생하거나 전체적으로 장애가 발생할 수 있습니다. + +프로비저닝, 구성, 테스트, 버전 제어 및 배포와 관련된 자동화 원칙을 사용하는 것이 좋은 출발점입니다. 자동화는 전반적으로 배포 속도, 네트워킹 인프라의 안정성, 지속적인 개선을 가능하게 할 뿐만 아니라 테스트가 완료되면 여러 환경에서 프로세스를 공유할 수 있습니다. 예를 들어 한 환경에서 완전히 테스트 된 네트워크 정책은 이전에는 수동으로 작성된 프로세스와 달리 코드로 되어 있기 때문에 다른 위치에서도 빠르게 사용할 수 있습니다. +이러한 사고에 대한 좋은 관점과 개요는 여기에서 찾을 수 있습니다. [Network DevOps](https://www.thousandeyes.com/learning/techtorials/network-devops) + +## 네트워킹 기본 사항 + +여기서는 데브옵스 측면은 잠시 접어두고 이제 네트워킹의 기본 사항에 대해 간략히 살펴보겠습니다. + +### 네트워크 장치 + +이 콘텐츠를 동영상으로 보고 싶으시다면 Practical Networking에서 다음 동영상을 확인하세요: + +- [Network Devices - Hosts, IP Addresses, Networks - Networking Fundamentals - Lesson 1a](https://www.youtube.com/watch?v=bj-Yfakjllc&list=PLIFyRwBY_4bRLmKfP1KnZA6rZbRHtxmXi&index=1) +- [Network Devices - Hub, Bridge, Switch, Router - Networking Fundamentals - Lesson 1b](https://www.youtube.com/watch?v=H7-NR3Q3BeI&list=PLIFyRwBY_4bRLmKfP1KnZA6rZbRHtxmXi&index=2) + +**호스트**는 트래픽을 보내거나 받는 모든 장치입니다. + +![](/2022/Days/Images/Day21_Networking1.png) + +**IP 주소**는 각 호스트의 신원입니다. + +![](/2022/Days/Images/Day21_Networking2.png) + +**네트워크**는 호스트 간에 트래픽을 전송하는 역할을 합니다. 네트워크가 없다면 데이터를 수동으로 많이 이동해야 할 것입니다! + +비슷한 연결이 필요한 호스트의 논리적 그룹입니다. + +![](/2022/Days/Images/Day21_Networking3.png) + +**스위치**는 네트워크 내에서 통신을 촉진합니다. 스위치는 호스트 간에 데이터 패킷을 전달합니다. 스위치는 호스트에 직접 패킷을 보냅니다. + +- 네트워크: 유사한 연결이 필요한 호스트들의 그룹. +- 네트워크의 호스트는 동일한 IP 주소 공간을 공유합니다. + +![](/2022/Days/Images/Day21_Networking4.png) + +**라우터**는 네트워크 간의 통신을 용이하게 합니다. 앞서 스위치가 네트워크 내의 통신을 관리한다고 말했듯이 라우터는 이러한 네트워크를 함께 연결하거나 최소한 허용되는 경우 서로에 대한 액세스 권한을 부여할 수 있게 해줍니다. + +라우터는 트래픽 제어 지점(보안, 필터링, 리디렉션)을 제공할 수 있습니다. 최근에는 이러한 기능 중 일부를 제공하는 스위치도 점점 더 많아지고 있습니다. + +라우터는 자신이 연결된 네트워크를 학습합니다. 이를 라우트라고 하며 라우팅 테이블은 라우터가 알고 있는 모든 네트워크입니다. + +라우터는 연결된 네트워크에 IP 주소를 가지고 있습니다. 이 IP는 게이트웨이라고도 하는 각 호스트가 로컬 네트워크에서 나가는 통로가 되기도 합니다. + +라우터는 또한 앞서 언급한 네트워크에서 계층 구조를 생성합니다. + +![](/2022/Days/Images/Day21_Networking5.png) + +## 스위치 대 라우터 + +**라우팅**은 네트워크 간에 데이터를 이동하는 프로세스입니다. + +- 라우터는 라우팅을 주요 목적으로 하는 장치입니다. + +**스위칭**은 네트워크 내에서 데이터를 이동하는 프로세스입니다. + +- 스위치는 스위칭을 주목적으로 하는 장치입니다. + +다음과 같이 다양한 네트워크 장치가 있다는 것을 알고 있으므로 이는 장치에 대한 기본적인 개요입니다: + +- 액세스 포인트 +- 방화벽 +- 로드 밸런서 +- 레이어 3 스위치 +- IDS/IPS +- 프록시 +- 가상 스위치 +- 가상 라우터 + +이러한 모든 장치는 라우팅 및/또는 스위칭을 수행합니다. + +앞으로 며칠 동안 이 목록에 대해 조금 더 자세히 알아보도록 하겠습니다. + +- OSI 모델 +- 네트워크 프로토콜 +- DNS(도메인 이름 시스템) +- NAT +- DHCP +- 서브넷 + +## 자료 + +- [Networking Fundamentals](https://www.youtube.com/playlist?list=PLIFyRwBY_4bRLmKfP1KnZA6rZbRHtxmXi) +- [Computer Networking full course](https://www.youtube.com/watch?v=IPvYjXCsTg8) + +[Day 22](day22.md)에서 봐요! diff --git a/2022/ko/Days/day22.md b/2022/ko/Days/day22.md new file mode 100644 index 0000000..7814c7d --- /dev/null +++ b/2022/ko/Days/day22.md @@ -0,0 +1,111 @@ +--- +title: '#90DaysOfDevOps - The OSI Model - The 7 Layers - Day 22' +published: false +description: 90DaysOfDevOps - The OSI Model - The 7 Layers +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049037 +--- + +아래 콘텐츠는 대부분 실용적인 네트워킹의 [Networking Fundamentals series](https://www.youtube.com/playlist?list=PLIFyRwBY_4bRLmKfP1KnZA6rZbRHtxmXi)에서 가져온 것입니다. 이 콘텐츠를 동영상으로 보고 싶으시다면 다음 두 동영상을 확인해 보세요: + +- [The OSI Model: A Practical Perspective - Layers 1 / 2 / 3](https://www.youtube.com/watch?v=LkolbURrtTs&list=PLIFyRwBY_4bRLmKfP1KnZA6rZbRHtxmXi&index=3) +- [The OSI Model: A Practical Perspective - Layers 4 / 5+](https://www.youtube.com/watch?v=0aGqGKrRE0g&list=PLIFyRwBY_4bRLmKfP1KnZA6rZbRHtxmXi&index=4) + +## OSI 모델 - 7개의 Layers + +산업으로서 네트워킹의 전반적인 목적은 두 호스트가 데이터를 공유할 수 있도록 하는 것입니다. 네트워킹 이전에는 이 호스트에서 이 호스트로 데이터를 가져오려면 이 호스트에 무언가를 꽂고 다른 호스트에 가서 다른 호스트에 꽂아야 했습니다. + +네트워킹을 사용하면 호스트가 유선을 통해 데이터를 자동으로 공유할 수 있으므로 이 작업을 자동화할 수 있으며, 이 작업을 수행하려면 호스트가 일련의 규칙을 따라야 합니다. + +이는 모든 언어와 다르지 않습니다. 영어에는 두 명의 영어 사용자가 따라야 하는 일련의 규칙이 있습니다. 스페인어에도 고유한 규칙이 있습니다. 프랑스어에는 고유한 규칙이 있으며, 네트워킹에도 고유한 규칙이 있습니다. + +네트워킹에 대한 규칙은 7가지 계층으로 나뉘며, 이러한 계층을 OSI 모델이라고 합니다. + +### OSI 모델 소개 + +OSI 모델(개방형 시스템 상호 연결 모델)은 네트워킹 시스템의 기능을 설명하는 데 사용되는 프레임워크입니다. OSI 모델은 서로 다른 제품과 소프트웨어 간의 상호 운용성을 지원하기 위해 컴퓨팅 기능을 보편적인 규칙과 요구 사항으로 특성화합니다. OSI 참조 모델에서 컴퓨팅 시스템 간의 통신은 7가지 추상화 계층으로 나뉩니다: **물리적, 데이터 링크, 네트워크, 전송, 세션, 프레젠테이션 및 애플리케이션**. + +![](/2022/Days/Images/Day22_Networking1.png) + +### 물리적 + +OSI 모델에서 Layer 1은 물리적이라고 하며, 물리적 케이블 등 수단을 통해 한 호스트에서 다른 호스트로 데이터를 전송할 수 있다는 전제하에 이 Layer에서도 Wi-Fi를 고려할 수 있습니다. 또한 한 호스트에서 다른 호스트로 데이터를 전송하기 위해 허브와 중계기 주변에서 더 많은 레거시 하드웨어를 볼 수 있습니다. + +![](/2022/Days/Images/Day22_Networking2.png) + +### 데이터 링크 + +Layer 2의 데이터 링크는 데이터가 프레임으로 패키지화되는 노드 간 전송을 가능하게 합니다. 또한 물리 계층에서 발생했을 수 있는 오류를 수정하는 수준도 있습니다. 또한 이 단계에서 MAC 주소가 도입되거나 처음 등장합니다. + +네트워킹 첫날인 [Day 21](day21.md) +에서 다룬 스위치에 대한 첫 번째 언급도 여기에서 볼 수 있습니다. + +![](/2022/Days/Images/Day22_Networking3.png) + +### 네트워크 + +Layer 3 스위치 또는 Layer 2 스위치라는 용어를 들어보셨을 것입니다. OSI 모델인 Layer 3에서 네트워크는 End to End 전송을 목표로 하며, 첫날 개요에서 언급한 IP 주소가 있는 곳입니다. + +라우터와 호스트는 Layer 3에 존재하며, 라우터는 여러 네트워크 간에 라우팅하는 기능이라는 점을 기억하세요. IP가 있는 모든 것은 Layer 3으로 간주할 수 있습니다. + +![](/2022/Days/Images/Day22_Networking4.png) + +그렇다면 왜 Layer 2와 3 모두에 주소 체계가 필요할까요? (MAC 주소와 IP 주소) + +한 호스트에서 다른 호스트로 데이터를 전송하는 것을 생각해 보면, 각 호스트에는 IP 주소가 있지만 그사이에는 여러 개의 스위치와 라우터가 있습니다. 각 장치에는 Layer 2 MAC 주소가 있습니다. + +Layer 2 MAC 주소는 호스트에서 스위치/라우터로만 이동하며 hop에 중점을 두는 반면, Layer 3 IP 주소는 데이터 패킷이 최종 호스트에 도달할 때까지 해당 패킷을 유지합니다. (End to End) + +IP 주소 - Layer 3 = End to End 전송 + +MAC 주소 - Layer 2 = Hop to Hop 전송 + +이제 Layer3와 Layer2 주소를 연결하는 ARP(주소 확인 프로토콜)라는 네트워크 프로토콜이 있지만 오늘은 다루지 않겠습니다. + +### 전송 + +서비스 간 전송, Layer 4는 데이터 스트림을 구분하기 위해 존재합니다. Layer 3과 Layer 2에 주소 체계가 있는 것과 마찬가지로 Layer 4에는 포트가 있습니다. + +![](/2022/Days/Images/Day22_Networking5.png) + +### 세션, 프레젠테이션, 애플리케이션 + +Layers 5,6,7의 구분이 다소 모호해졌습니다. + +보다 최근의 이해를 돕기 위해 [TCP IP Model](https://www.geeksforgeeks.org/tcp-ip-model/)을 살펴보는 것이 좋습니다. + +이제 이 네트워킹 스택을 사용하여 호스트가 서로 통신할 때 어떤 일이 일어나는지 설명해 보겠습니다. 이 호스트에는 다른 호스트로 전송할 데이터를 생성하는 애플리케이션이 있습니다. + +소스 호스트는 캡슐화 프로세스라고 하는 과정을 거치게 됩니다. 이 데이터는 먼저 Layer 4로 전송됩니다. + +Layer 4는 해당 데이터에 헤더를 추가하여 서비스 간 전송이라는 Layer 4의 목표를 용이하게 할 수 있습니다. 이 헤더는 TCP 또는 UDP를 사용하는 포트가 될 것입니다. 또한 소스 포트와 대상 포트도 포함됩니다. + +이를 세그먼트(데이터 및 포트)라고도 합니다. + +이 세그먼트는 OSI 스택을 통해 네트워크 계층인 Layer 3으로 전달되고, 네트워크 계층은 이 데이터에 또 다른 헤더를 추가합니다. +이 헤더는 End to End 전송이라는 Layer 3의 목표를 달성하기 위한 것으로, 이 헤더에는 소스 IP 주소와 대상 IP가 있으며, 헤더와 데이터를 합쳐 패킷이라고도 합니다. + +그러면 Layer 3이 해당 패킷을 받아 Layer 2로 전달하고, Layer 2는 다시 한번 해당 데이터에 또 다른 헤더를 추가하여 Layer 2의 목표인 Hop to Hop 전송을 달성하게 되는데, 이 헤더에는 소스 및 대상 맥 주소가 포함됩니다. +Layer 2 헤더와 데이터가 있을 때 이를 프레임이라고 합니다. + +그런 다음 이 프레임은 1과 0으로 변환되어 Layer 1 물리적 케이블 또는 Wi-Fi를 통해 전송됩니다. + +![](/2022/Days/Images/Day22_Networking6.png) + +위에서 헤더와 데이터의 각 Layer에 대한 네이밍에 대해 언급했지만, 이것도 그려보기로 했습니다. + +![](/2022/Days/Images/Day22_Networking7.png) + +데이터를 전송하는 애플리케이션은 어딘가로 데이터를 전송하고 있으므로 수신은 스택을 거슬러 올라가 수신 호스트에 전달하기 위해 다소 역방향으로 이루어집니다. + +![](/2022/Days/Images/Day22_Networking8.png) + +## 자료 + +- [Networking Fundamentals](https://www.youtube.com/playlist?list=PLIFyRwBY_4bRLmKfP1KnZA6rZbRHtxmXi) + +* [Computer Networking full course](https://www.youtube.com/watch?v=IPvYjXCsTg8) + +[Day 23](day23.md)에서 봐요! diff --git a/2022/ko/Days/day23.md b/2022/ko/Days/day23.md new file mode 100644 index 0000000..dea0573 --- /dev/null +++ b/2022/ko/Days/day23.md @@ -0,0 +1,122 @@ +--- +title: '#90DaysOfDevOps - Network Protocols - Day 23' +published: false +description: 90DaysOfDevOps - Network Protocols +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048704 +--- + +아래 콘텐츠는 대부분 실용적인 네트워킹의 [Networking Fundamentals series](https://www.youtube.com/playlist?list=PLIFyRwBY_4bRLmKfP1KnZA6rZbRHtxmXi)에서 가져온 것입니다. 이 콘텐츠를 동영상으로 보고 싶으시다면 이 동영상을 확인해보세요: + +- [Network Protocols - ARP, FTP, SMTP, HTTP, SSL, TLS, HTTPS, DNS, DHCP](https://www.youtube.com/watch?v=E5bSumTAHZE&list=PLIFyRwBY_4bRLmKfP1KnZA6rZbRHtxmXi&index=12) + +## 네트워크 프로토콜 + +인터넷 표준을 구성하는 일련의 규칙과 메시지입니다. + +- ARP - 주소 확인 프로토콜 + +ARP에 대해 자세히 알고 싶으시다면 여기에서 인터넷 표준을 읽어보세요. [RFC 826](https://datatracker.ietf.org/doc/html/rfc826) + +Layer 2 네트워크에서 IP 주소를 고정된 물리적 컴퓨터 주소(MAC 주소라고도 함)에 연결합니다. + +![](/2022/Days/Images/Day23_Networking1.png) + +- FTP - 파일 전송 프로토콜 + +소스에서 대상으로 파일을 전송할 수 있습니다. 일반적으로 이 프로세스는 인증되지만, 익명 액세스를 사용하도록 구성한 경우 사용할 수 있습니다. 이제 더 나은 보안을 위해 클라이언트에서 FTP 서버로 SSL/TLS 연결을 제공하는 FTPS를 더 자주 보게 될 것입니다. 이 프로토콜은 OSI 모델의 애플리케이션 계층에서 찾을 수 있습니다. + +![](/2022/Days/Images/Day23_Networking2.png) + +- SMTP - 단순 메일 전송 프로토콜 + +전자 메일 전송에 사용되는 메일 서버는 SMTP를 사용하여 메일 메시지를 보내고 받습니다. Microsoft 365를 사용하더라도 SMTP 프로토콜이 동일한 용도로 사용된다는 것을 알 수 있습니다. + +![](/2022/Days/Images/Day23_Networking3.png) + +- HTTP - 하이퍼 텍스트 전송 프로토콜 + +HTTP는 인터넷과 콘텐츠 탐색의 기초입니다. 우리가 즐겨 찾는 웹사이트에 쉽게 액세스할 수 있게 해줍니다. HTTP는 여전히 많이 사용되고 있지만, 대부분의 즐겨 찾는 사이트에서는 HTTPS가 더 많이 사용되고 있거나 사용되어야 합니다. + +![](/2022/Days/Images/Day23_Networking4.png) + +- SSL - 보안 소켓 계층 | TLS - 전송 계층 보안 + +SSL의 뒤를 이어 등장한 TLS는 네트워크를 통해 안전한 통신을 제공하는 **암호화 프로토콜**입니다. 메일, 인스턴트 메시징 및 기타 애플리케이션에서 찾을 수 있지만 가장 일반적으로 HTTPS를 보호하는 데 사용됩니다. + +![](/2022/Days/Images/Day23_Networking5.png) + +- HTTPS - SSL/TLS로 보호되는 HTTP + +네트워크를 통한 보안 통신에 사용되는 HTTP의 확장인 HTTPS는 위에서 언급한 것처럼 TLS로 암호화됩니다. 호스트 간에 데이터가 교환되는 동안 인증, 개인 정보 보호 및 무결성을 제공하는 데 중점을 두었습니다. + +![](/2022/Days/Images/Day23_Networking6.png) + +- DNS - 도메인 이름 시스템 + +DNS는 인간 친화적인 도메인 이름을 매핑하는 데 사용됩니다. 예를 들어 우리가 모두 알고 있는 [google.com](https://google.com)은 브라우저를 열고 [8.8.8.8](https://8.8.8.8)을 입력하면 우리가 거의 알고 있는 Google이 표시됩니다. 하지만 모든 웹사이트의 IP 주소를 모두 기억하기란 쉽지 않으며, 일부 웹사이트는 정보를 찾기 위해 구글을 사용하기도 합니다. + +호스트, 서비스 및 기타 리소스에 연결할 수 있도록 하는 DNS의 역할이 바로 여기에 있습니다. + +모든 호스트에서 인터넷 연결이 필요한 경우 해당 도메인 이름을 확인할 수 있도록 DNS가 있어야 합니다. DNS는 며칠 또는 몇 년을 투자하여 학습할 수 있는 영역입니다. 또한 경험상 네트워킹과 관련된 모든 오류의 일반적인 원인은 대부분 DNS라고 말하고 싶습니다. 하지만 네트워크 엔지니어가 동의할지는 모르겠습니다. + +![](/2022/Days/Images/Day23_Networking7.png) + +- DHCP - 동적 호스트 구성 프로토콜 + +인터넷에 액세스하거나 서로 간에 파일을 전송하는 등 호스트가 작동하는 데 필요한 프로토콜에 대해 많이 논의했습니다. + +이 두 가지 작업을 모두 수행하기 위해 모든 호스트에 필요한 4가지 사항이 있습니다. + +- IP 주소 +- 서브넷 마스크 +- 기본 게이트웨이 +- DNS + +IP 주소는 호스트가 위치한 네트워크에서 호스트의 고유 주소로, 집 번호라고 생각하시면 됩니다. + +서브넷 마스크는 곧 다루겠지만 우편번호나 우편번호로 생각하시면 됩니다. + +기본 게이트웨이는 일반적으로 네트워크에서 Layer 3 연결을 제공하는 라우터의 IP입니다. 이를 우리 동네를 빠져나갈 수 있는 하나의 도로라고 생각할 수 있습니다. + +그리고 방금 설명한 DNS는 복잡한 공인 IP 주소를 보다 적합하고 기억하기 쉬운 도메인 이름으로 변환하는 데 도움을 줍니다. 어쩌면 이것을 올바른 게시물을 얻기 위한 거대한 분류 사무실이라고 생각할 수 있습니다. + +각 호스트마다 이 네 가지가 필요하다고 말씀드렸듯이 호스트가 1,000개 또는 10,000개라면 이 네 가지를 개별적으로 결정하는 데 매우 오랜 시간이 걸릴 것입니다. 이때 DHCP가 등장하여 네트워크의 범위를 결정하면 이 프로토콜이 네트워크에서 사용 가능한 모든 호스트에 배포됩니다. + +또 다른 예로 커피숍에 가서 커피를 마시고 노트북이나 휴대폰을 들고 앉았다고 가정해 봅시다. 호스트를 커피숍 와이파이에 연결하면 인터넷에 접속할 수 있고, 메시지와 메일이 핑을 받기 시작하며, 웹 페이지와 소셜 미디어를 탐색할 수 있습니다. 커피숍 와이파이에 연결했을 때 컴퓨터는 전용 DHCP 서버 또는 DHCP를 처리하는 라우터에서 DHCP 주소를 선택했을 것입니다. + +![](/2022/Days/Images/Day23_Networking8.png) + +### 서브넷 + +서브넷은 IP 네트워크의 논리적 세분화입니다. + +서브넷은 대규모 네트워크를 더 효율적으로 실행할 수 있는 더 작고 관리하기 쉬운 네트워크로 나눕니다. + +각 서브넷은 더 큰 네트워크의 논리적 세분화입니다. 충분한 서브넷을 가진 연결된 장치는 공통 IP 주소 식별자를 공유하여 서로 통신할 수 있습니다. + +라우터는 서브넷 간의 통신을 관리합니다. + +서브넷의 크기는 연결 요구 사항과 사용되는 네트워크 기술에 따라 달라집니다. + +조직은 사용 가능한 주소 공간의 한도 내에서 서브넷의 수와 크기를 결정할 책임이 있습니다. +사용 가능한 주소 공간의 한도 내에서 서브넷의 수와 크기를 결정할 책임이 있으며, 세부 사항은 해당 조직에 로컬로 유지됩니다. 서브넷은 지점 간 링크 또는 몇 개의 디바이스를 지원하는 서브네트워크와 같이 더 작은 서브넷으로 세분화할 수도 있습니다. + +무엇보다도 대규모 네트워크를 서브넷으로 세분화하면 +네트워크를 서브넷으로 분할하면 IP 주소 +재할당을 가능하게 하고 네트워크 혼잡, 간소화, 네트워크 통신 및 효율성을 완화합니다. + +서브넷은 네트워크 보안도 향상시킬 수 있습니다. +네트워크의 한 섹션이 손상되면 해당 섹션을 격리하여 악의적인 공격자가 더 큰 네트워크에서 이동하기 어렵게 만들 수 있습니다. + +![](/2022/Days/Images/Day23_Networking9.png) + +## 자료 + +- [Networking Fundamentals](https://www.youtube.com/playlist?list=PLIFyRwBY_4bRLmKfP1KnZA6rZbRHtxmXi) +- [Subnetting Mastery](https://www.youtube.com/playlist?list=PLIFyRwBY_4bQUE4IB5c4VPRyDoLgOdExE) +- [Computer Networking full course](https://www.youtube.com/watch?v=IPvYjXCsTg8) + +[Day 24](day24.md)에서 봐요! diff --git a/2022/ko/Days/day24.md b/2022/ko/Days/day24.md new file mode 100644 index 0000000..094a6dc --- /dev/null +++ b/2022/ko/Days/day24.md @@ -0,0 +1,147 @@ +--- +title: '#90DaysOfDevOps - Network Automation - Day 24' +published: false +description: 90DaysOfDevOps - Network Automation +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048805 +--- + +## 네트워크 자동화 + +### 네트워크 자동화의 기본 사항 + +네트워크 자동화의 주요 동인 + +- 민첩성 달성 +- 비용 절감 +- 오류 제거 +- 규정 준수 보장 +- 중앙 집중식 관리 + +자동화 도입 프로세스는 각 비즈니스에 따라 다릅니다. 자동화를 배포하는 데 있어 모든 것에 적합한 방법은 없으며, 조직에 가장 적합한 접근 방식을 파악하고 수용하는 능력은 보다 민첩한 환경을 유지하거나 만드는 데 매우 중요하며, 항상 비즈니스 가치와 최종 사용자 경험에 초점을 맞춰야 합니다. (처음에 DevOps 전체와 문화 변화 및 이로 인한 자동화된 프로세스와 관련하여 비슷한 내용을 말씀드렸습니다.) + +이를 세분화하려면 자동화하려는 작업이나 프로세스가 최종 사용자 경험 또는 비즈니스 가치를 어떻게 달성하고 개선할 수 있는지 파악하고 단계별 체계적인 접근 방식을 따라야 합니다. + +"어디로 가는지 모르면 어떤 길이라도 그곳에 도달할 수 있습니다." + +달성하고자 하는 프레임워크 또는 설계 구조를 통해 최종 목표가 무엇인지 파악한 다음, 비즈니스 결과를 기반으로 다양한 단계에서 자동화 성공 여부를 측정하면서 목표 달성을 위해 단계적으로 작업하세요. + +기존 애플리케이션을 중심으로 모델링된 개념 구축 자동화는 애플리케이션, 서비스, 인프라에 적용해야 하기 때문에 거창하게 개념을 설계할 필요가 없으므로 기존 인프라, 즉 기존 애플리케이션을 중심으로 모델링하여 개념을 구축하기 시작하세요. + +### 네트워킹 자동화에 대한 접근 방식 + +작업을 식별하고 네트워크 변경 요청에 대한 검색을 수행하여 솔루션을 자동화할 가장 일반적인 이슈와 문제를 파악해야 합니다. + +- 현재 수동으로 처리하고 있는 모든 변경 요청과 workflow의 목록을 작성합니다. +- 가장 일반적이고 시간이 오래 걸리며 오류가 발생하기 쉬운 활동을 파악하세요. +- 비즈니스 중심 접근 방식을 취하여 요청의 우선순위를 정하세요. +- 이는 자동화 프로세스를 구축하기 위한 프레임워크이며, 자동화해야 하는 작업과 자동화하지 않아야 하는 작업을 구분합니다. + +그런 다음 작업을 나누고 서로 다른 네트워크 기능이 어떻게 작동하고 상호 작용하는지 분석해야 합니다. + +- 인프라/네트워크 팀은 애플리케이션을 배포하기 위해 여러 계층에서 변경 티켓을 받습니다. +- 네트워크 서비스를 기반으로 여러 영역으로 나누고 서로 어떻게 상호 작용하는지 이해합니다. + - 애플리케이션 최적화 + - ADC(애플리케이션 전송 컨트롤러) + - 방화벽 + - DDI(DNS, DHCP, IPAM 등) + - 라우팅 + - 기타 +- 다양한 종속성을 파악하여 비즈니스 및 문화적 차이를 해결하고 팀 간 협업을 유도하세요. + +재사용 가능한 정책, 재사용 가능한 서비스 작업, 프로세스 및 입출력을 정의하고 단순화하세요. + +- 다양한 서비스, 프로세스 및 입출력을 위한 오퍼링을 정의하세요. +- 배포 프로세스를 간소화하면 신규 워크로드와 기존 워크로드 모두의 시장 출시 시간을 단축할 수 있습니다. +- 표준 프로세스가 마련되면, 멀티스레드 접근 방식과 제공을 위해 개별 요청에 따라 프로세스를 순서화 및 조정할 수 있습니다. + +정책을 비즈니스별 활동과 결합하세요. 이 정책을 구현하면 비즈니스에 어떤 도움이 되나요? 시간이 절약되나요? 비용이 절감되나요? 더 나은 비즈니스 결과를 제공하나요? + +- 서비스 작업이 상호 운용 가능한지 확인하세요. +- 증분 서비스 작업을 연결하여 비즈니스 서비스를 만들 수 있도록 정렬하세요. +- 필요에 따라 서비스 작업을 연결하고 다시 연결할 수 있는 유연성을 제공하세요. +- 셀프 서비스 기능을 배포하고 운영 효율성을 개선할 수 있는 기반을 마련하세요. +- 감독 및 규정 준수에 지속적으로 기여할 수 있도록 다양한 기술 스킬셋을 허용합니다. + +가용성과 서비스를 유지하면서 정책과 프로세스를 **반복**하여 추가하고 개선하세요. + +- 기존 작업을 자동화하여 작게 시작하세요. +- 자동화 프로세스에 익숙해져서 자동화를 통해 이점을 얻을 수 있는 다른 영역을 식별할 수 있습니다. +- 자동화 이니셔티브를 반복하여 필요한 가용성을 유지하면서 민첩성을 점진적으로 추가합니다. +- 점진적인 접근 방식을 취하면 성공의 길을 열 수 있습니다! + +네트워크 서비스를 오케스트레이션하세요! + +- 애플리케이션을 신속하게 제공하려면 배포 프로세스의 자동화가 필요합니다. +- 민첩한 서비스 환경을 구축하려면 기술 전반에 걸쳐 관리해야 할 다양한 요소가 필요합니다. +- 자동화와 배포 순서를 제어할 수 있는 End To End 오케스트레이션을 준비하세요. + +## 네트워크 자동화 도구 + +여기서 좋은 소식은 대부분의 경우 네트워크 자동화에 사용하는 도구는 다른 자동화 영역에 사용하거나 지금까지 이미 다룬 내용 또는 향후 세션에서 다룰 내용과 동일하다는 것입니다. + +운영 체제 - 이번 챌린지 내내 그랬듯이 저는 대부분의 학습을 Linux OS로 하는 데 집중하고 있으며, 그 이유는 Linux 섹션에서 설명했지만, 크로스 OS 플랫폼이긴 하지만 오늘 다룰 거의 모든 도구는 처음부터 모두 Linux 기반 애플리케이션 또는 도구로 시작되었습니다. + +통합 개발 환경(IDE) - 다양한 언어에서 사용할 수 있는 광범위한 플러그인을 기반으로 Visual Studio Code를 IDE로 추천한다는 것 외에는 여기서 더 이상 설명할 것이 없습니다. + +구성 관리 - 아직 구성 관리 섹션은 다루지 않았지만, 이 영역에서 구성 관리 및 자동화를 위해 Ansible이 가장 선호되는 것은 분명합니다. Ansible은 Python으로 작성되었지만, Python을 알 필요는 없습니다. + +- 에이전트리스 +- SSH만 필요 +- 대규모 지원 커뮤니티 +- 다양한 네트워크 모듈 +- 푸시 전용 모델 +- YAML로 구성 +- 오픈 소스! + +[Link to Ansible Network Modules](https://docs.ansible.com/ansible/2.9/modules/list_of_network_modules.html) + +구성 관리 섹션에서 **Ansible Tower**에 대해서도 다룰 예정이며, 이를 Ansible의 GUI로 보시면 됩니다. + +CI/CD - 이와 관련된 개념과 도구에 대해서는 다시 다룰 예정이지만, 네트워킹뿐만 아니라 서비스 및 플랫폼의 모든 프로비저닝에 걸쳐 있기 때문에 최소한 여기서 언급하는 것이 중요합니다. + +특히 Jenkins는 네트워크 자동화를 위한 인기 있는 도구를 제공하거나 제공하는 것으로 보입니다. + +- 변경사항이 있는지 git 리포지토리를 모니터링한 다음 변경을 시작합니다. + +버전 관리 - 이 역시 나중에 자세히 살펴볼 내용입니다. + +- Git은 로컬 디바이스에서 코드의 버전 제어를 제공합니다 - 크로스 플랫폼 +- GitHub, GitLab, BitBucket 등은 리포지토리를 정의하고 코드를 업로드할 수 있는 온라인 웹사이트입니다. + +언어 | 스크립팅 - 우리가 아직 다루지 않은 Python입니다. 상황에 따라 프로그래밍 언어로 Go를 사용하기로 결정했는데, Golang과 Python이 박빙의 승부를 펼쳤으며 네트워크 자동화에는 Python이 승자가 된 것 같습니다. + +- 여기서 언급해야 할 것이 바로 파이썬으로 작성된 자동화 프레임워크인 Nornir입니다. 이것은 Ansible의 역할을 하는 것으로 보이지만 특히 네트워크 자동화를 중심으로 합니다. [Nornir documentation](https://nornir.readthedocs.io/en/latest/) + +API 분석 - Postman은 RESTful API를 분석하기 위한 훌륭한 도구입니다. API를 빌드, 테스트 및 수정하는 데 도움이 됩니다. + +- POST >>> 리소스 객체를 생성합니다. +- GET >>> 리소스를 검색합니다. +- PUT >>> 리소스를 생성하거나 교체합니다. +- PATCH >>> 리소스 오브젝트를 생성하거나 업데이트합니다. +- DELETE >>> 리소스를 삭제합니다. + +[Postman tool Download](https://www.postman.com/downloads/) + +### 기타 언급할 도구 + +[Cisco NSO (Network Services Orchestrator)](https://www.cisco.com/c/en/us/products/cloud-systems-management/network-services-orchestrator/index.html) + +[NetYCE - Simplify Network Automation](https://netyce.com/) + +[Network Test Automation](https://pubhub.devnetcloud.com/media/genie-feature-browser/docs/#/) + +앞으로 3일 동안은 지금까지 다룬 내용 중 몇 가지를 좀 더 실습해보고 Python과 네트워크 자동화에 관한 작업을 해볼 계획입니다. + +지금까지 네트워킹 주제를 모두 다루지는 못했지만, 아래에 추가하는 리소스를 통해 계속 학습하면서 따라갈 수 있을 정도로 폭넓게 다루고자 합니다. + +## 자료 + +- [3 Necessary Skills for Network Automation](https://www.youtube.com/watch?v=KhiJ7Fu9kKA&list=WL&index=122&t=89s) +- [Computer Networking full course](https://www.youtube.com/watch?v=IPvYjXCsTg8) +- [Practical Networking](http://www.practicalnetworking.net/) +- [Python Network Automation](https://www.youtube.com/watch?v=xKPzLplPECU&list=WL&index=126) + +[Day 25](day25.md)에서 봐요! diff --git a/2022/ko/Days/day25.md b/2022/ko/Days/day25.md new file mode 100644 index 0000000..ec612c7 --- /dev/null +++ b/2022/ko/Days/day25.md @@ -0,0 +1,175 @@ +--- +title: '#90DaysOfDevOps - Python for Network Automation - Day 25' +published: false +description: 90DaysOfDevOps - Python for Network Automation +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049038 +--- + +## 네트워크 자동화를 위한 Python + +Python은 자동화된 네트워크 운영에 사용되는 표준 언어입니다. + +네트워크 자동화뿐만 아니라 리소스를 찾을 때 어디에나 있는 것 같고, 앞서 언급했듯이 파이썬이 아니라면 일반적으로 파이썬으로도 작성된 Ansible입니다. + +이미 언급한 것 같지만 '프로그래밍 언어 배우기' 섹션에서 제가 파이썬 대신 Go를 선택한 이유는 회사에서 Go로 개발 중이어서 배울 수 있는 좋은 이유였지만, 그렇지 않았다면 파이썬을 배우는 데 시간이 더 걸렸을 것입니다. + +- 가독성 및 사용 편의성 - 파이썬은 그냥 말이 되는 것 같습니다. 코드에서 블록을 시작하고 끝내기 위해 `{}`에 대한 요구 사항이 없는 것 같습니다. 여기에 VS Code와 같은 강력한 IDE를 결합하면 파이썬 코드를 실행할 때 매우 쉽게 시작할 수 있습니다. + +여기서 언급할 만한 또 다른 IDE는 Pycharm일 수 있습니다. + +- 라이브러리 - 파이썬의 확장성은 네트워크 자동화뿐만 아니라 실제로 모든 종류의 장치와 구성을 위한 라이브러리가 많이 있다는 점을 앞서 언급했습니다. 여기에서 방대한 양을 확인할 수 있습니다. [PyPi](https://pypi.python.org/pypi) + +라이브러리를 워크스테이션에 다운로드하려면 `pip`라는 도구를 사용하여 PyPI에 연결하고 로컬로 다운로드하면 됩니다. Cisco, 주니퍼, 아리스타와 같은 네트워크 벤더는 자사 디바이스에 쉽게 액세스할 수 있도록 라이브러리를 개발했습니다. + +- 강력하고 효율적 - Go 파트에서 "Hello World" 시나리오를 진행하면서 6줄 정도의 코드를 작성했던 것을 기억하시나요? Python에서는 + +```python +print('hello world') +``` + +위의 모든 사항을 종합하면 자동화 작업 시 파이썬이 언급되는 이유를 쉽게 알 수 있을 것입니다. + +몇 년 전에도 네트워크 장치와 상호 작용하여 구성 백업을 자동화하거나 장치에 대한 로그 및 기타 인사이트를 수집하는 스크립트가 있었을 가능성이 있다는 점에 유의하는 것이 중요하다고 생각합니다. 여기서 말하는 자동화는 조금 다른데, 이는 전반적인 네트워킹 환경이 이러한 사고방식에 더 잘 맞도록 변화하여 더 많은 자동화를 가능하게 했기 때문입니다. + +- 소프트웨어 정의 네트워크 - SDN 컨트롤러는 네트워크의 모든 디바이스에 컨트롤 플레인 구성을 제공하는 책임을 지므로 네트워크 변경에 대한 단일 접점만 있으면 더 이상 모든 디바이스에 텔넷 또는 SSH로 접속할 필요가 없으며, 사람이 이 작업을 수행해야 하므로 실패 또는 구성 오류의 가능성이 반복적으로 발생할 수 있습니다. + +- 높은 수준의 오케스트레이션 - 이러한 SDN 컨트롤러에서 한 단계 더 올라가면 서비스 수준을 오케스트레이션 할 수 있으며, 이 오케스트레이션 계층을 원하는 플랫폼(VMware, Kubernetes, 퍼블릭 클라우드 등)에 통합할 수 있습니다. + +- 정책 기반 관리 - 무엇을 원하시나요? 원하는 상태는 무엇인가요? 이를 설명하면 시스템에서 원하는 상태가 되기 위한 모든 세부 사항을 파악합니다. + +## 실습 환경 설정하기 + +모든 사람이 실제 라우터, 스위치 및 기타 네트워킹 장치에 액세스할 수 있는 것은 아닙니다. + +저는 앞서 언급한 몇 가지 도구를 살펴보면서 네트워크 구성을 자동화하는 방법을 직접 실습하고 배울 수 있도록 하고 싶었습니다. + +옵션에 관해서는 몇 가지를 선택할 수 있습니다. + +- [GNS3 VM](https://www.gns3.com/software/download-vm) +- [Eve-ng](https://www.eve-ng.net/) +- [Unimus](https://unimus.net/) 실험실 환경은 아니지만 흥미로운 개념입니다. + +앞서 언급했듯이 [Eve-ng](https://www.eve-ng.net/)를 사용하여 랩을 구축할 예정입니다. 가상 환경은 다양한 시나리오를 테스트할 수 있는 샌드박스 환경을 가질 수 있다는 것을 의미하며, 다양한 디바이스와 Topology로 실행 수 있다는 점도 흥미로울 수 있습니다. + +저희는 커뮤니티 에디션을 통해 EVE-NG의 모든 것을 보여드리려고 합니다. + +### 시작하기 + +[커뮤니티 에디션](https://www.eve-ng.net/index.php/download/)은 ISO 및 OVF 형식으로 제공됩니다. + +저희는 OVF 다운로드를 사용할 예정이지만, ISO를 사용하면 하이퍼바이저 없이 베어메탈 서버에서 빌드할 수 있습니다. + +![](/2022/Days/Images/Day25_Networking1.png) + +여기서는 vExpert를 통해 라이선스가 있는 VMware Workstation을 사용하지만, [documentation](https://www.eve-ng.net/index.php/documentation/installation/system-requirement/)에 언급된 다른 옵션이나 VMware Player도 동일하게 사용할 수 있습니다. 안타깝게도 이전에 사용하던 가상 박스는 사용할 수 없습니다! + +가상 박스가 지원되기는 하지만 GNS3에서 문제가 발생했던 부분이기도 합니다. + +[Download VMware Workstation Player - FREE](https://www.vmware.com/uk/products/workstation-player.html) + +[VMware Workstation PRO](https://www.vmware.com/uk/products/workstation-pro.html) 역시 무료 평가판 기간이 있다고 합니다! + +### VM웨어 워크스테이션 프로에 설치하기 + +이제 하이퍼바이저 소프트웨어 다운로드 및 설치가 완료되었고, EVE-NG OVF가 다운로드되었습니다. VMware Player를 사용 중이시라면 이 과정이 동일한지 알려주시기 바랍니다. + +이제 구성할 준비가 되었습니다. + +VMware 워크스테이션을 열고 `file`과 `open`를 선택합니다. + +![](/2022/Days/Images/Day25_Networking2.png) + +EVE-NG OVF 이미지를 다운로드하면 압축 파일 안에 들어 있습니다. 해당 폴더에 내용을 압축을 풀면 다음과 같은 모양이 됩니다. + +![](/2022/Days/Images/Day25_Networking3.png) + +EVE-NG OVF 이미지를 다운로드한 위치로 이동하여 가져오기를 시작합니다. + +알아볼 수 있는 이름을 지정하고 시스템 어딘가에 가상 머신을 저장합니다. + +![](/2022/Days/Images/Day25_Networking4.png) + +가져오기가 완료되면 프로세서 수를 4개로 늘리고 할당된 메모리를 8GB로 늘립니다. (최신 버전으로 가져온 후 그렇지 않은 경우 VM 설정을 편집해야 합니다.) + +또한 Intel VT-x/EPT 또는 AMD-V/RVI 가상화 확인란이 활성화되어 있는지 확인합니다. 이 옵션은 VMware 워크스테이션이 가상화 플래그를 게스트 OS에 전달하도록 지시합니다(중첩 가상화). CPU가 이를 허용함에도 불구하고 가상 박스가 있는 GNS3에서 이 문제가 발생했습니다. + +![](/2022/Days/Images/Day25_Networking5.png) + +### 전원 켜기 및 액세스 + +사이드노트 & Rabbit hole: 가상박스에서는 작동하지 않는다고 말씀드린 것을 기억하세요! 네, VM웨어 워크스테이션과 EVE-NG에서도 같은 문제가 발생했지만, 가상화 플랫폼의 잘못은 아니었습니다! + +Windows 머신에서 WSL2를 실행 중이며 이로 인해 환경 내부에 중첩된 모든 것을 실행할 수 있는 기능이 제거된 것 같습니다. WSL2를 사용할 때 CPU의 인텔 VT-d 가상화 측면이 제거되는 것처럼 보이는데 왜 우분투 VM이 실행되는지 혼란스럽습니다. + +이 문제를 해결하려면 Windows 시스템에서 다음 명령을 실행하고 시스템을 재부팅 할 수 있으며, 이 명령이 꺼져 있는 동안에는 WSL2를 사용할 수 없다는 점에 유의하세요. + +`bcdedit /set hypervisorlaunchtype off` + +다시 돌아가서 WSL2를 사용하려면 이 명령을 실행하고 재부팅 해야 합니다. + +`bcdedit /set hypervisorlaunchtype auto` + +이 두 명령은 모두 관리자 권한으로 실행해야 합니다! + +다시 돌아와서, 이제 VMware Workstation에 전원이 켜진 머신이 있어야 하며 다음과 유사한 프롬프트가 표시되어야 합니다. + +![](/2022/Days/Images/Day25_Networking6.png) + +위의 프롬프트에서 다음을 사용할 수 있습니다: + +username = root +password = eve + +그러면 루트 password를 다시 입력하라는 메시지가 표시되며, 이 password는 나중에 호스트에 SSH할 때 사용됩니다. + +그런 다음 호스트 이름을 변경할 수 있습니다. + +![](/2022/Days/Images/Day25_Networking7.png) + +다음으로 DNS 도메인 이름을 정의합니다. 저는 아래 이름을 사용했지만, 나중에 변경해야 할지는 아직 모르겠습니다. + +![](/2022/Days/Images/Day25_Networking8.png) + +그런 다음 네트워킹을 구성하고, 재부팅 후에도 주어진 IP 주소가 영구적으로 유지되도록 정적을 선택합니다. + +![](/2022/Days/Images/Day25_Networking9.png) + +마지막 단계로 워크스테이션에서 연결할 수 있는 네트워크의 고정 IP 주소를 제공합니다. + +![](/2022/Days/Images/Day25_Networking10.png) + +여기에는 네트워크, 기본 게이트웨이 및 DNS에 대한 서브넷 마스크를 제공해야 하는 몇 가지 추가 단계가 있습니다. + +완료되면 재부팅되고 백업이 완료되면 고정 IP 주소를 가져와 브라우저에 입력할 수 있습니다. + +![](/2022/Days/Images/Day25_Networking11.png) + +GUI의 기본 username은 `admin`이고 password는 `eve`이며, SSH의 기본 username은 `root`이고 password는 `eve`이지만 설정 중에 변경한 경우 변경되었을 수 있습니다. + +![](/2022/Days/Images/Day25_Networking12.png) + +다른 콘솔을 탐색할 때 브라우저에 새 탭이 열리므로 콘솔과 네이티브에 대해 HTML5를 선택했습니다. + +다음 단계는 다음과 같습니다: + +- EVE-NG 클라이언트 팩 설치 +- 일부 네트워크 이미지를 EVE-NG에 로드합니다. +- 네트워크 Topology 빌드 +- 노드 추가하기 +- 노드 연결하기 +- 파이썬 스크립트 빌드 시작 +- telnetlib, Netmiko, Paramiko, Pexpect 살펴보기 + +## 자료 + +- [Free Course: Introduction to EVE-NG](https://www.youtube.com/watch?v=g6B0f_E0NMg) +- [EVE-NG - Creating your first lab](https://www.youtube.com/watch?v=9dPWARirtK8) +- [3 Necessary Skills for Network Automation](https://www.youtube.com/watch?v=KhiJ7Fu9kKA&list=WL&index=122&t=89s) +- [Computer Networking full course](https://www.youtube.com/watch?v=IPvYjXCsTg8) +- [Practical Networking](http://www.practicalnetworking.net/) +- [Python Network Automation](https://www.youtube.com/watch?v=xKPzLplPECU&list=WL&index=126) + +[Day 26](day26.md)에서 봐요! diff --git a/2022/ko/Days/day26.md b/2022/ko/Days/day26.md new file mode 100644 index 0000000..5835e85 --- /dev/null +++ b/2022/ko/Days/day26.md @@ -0,0 +1,121 @@ +--- +title: '#90DaysOfDevOps - Building our Lab - Day 26' +published: false +description: 90DaysOfDevOps - Building our Lab +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048762 +--- + +## 실험실 구축 + +EVE-NG를 사용하여 에뮬레이트된 네트워크를 계속 설정한 다음 몇 가지 디바이스를 배포하고 이러한 디바이스의 구성을 자동화할 수 있는 방법에 대해 생각해 보겠습니다. [Day 25](day25.md)에서는 VMware Workstation을 사용하여 머신에 EVE-NG를 설치하는 방법을 다루었습니다. + +### EVE-NG 클라이언트 설치하기 + +장치에 SSH를 할 때 사용할 애플리케이션을 선택할 수 있는 클라이언트 팩도 있습니다. 또한 링크 간 패킷 캡처를 위해 Wireshark를 설정합니다. 사용 중인 OS(윈도우, 맥OS, 리눅스)에 맞는 클라이언트 팩을 다운로드할 수 있습니다. + +[EVE-NG Client Download](https://www.eve-ng.net/index.php/download/) + +![](/2022/Days/Images/Day26_Networking1.png) + +빠른 팁: Linux를 클라이언트로 사용하는 경우 이 [client pack](https://github.com/SmartFinn/eve-ng-integration)이 있습니다. + +설치는 간단하며, 기본값을 그대로 두는 것이 좋습니다. + +### 네트워크 Images 가져오기 + +이 단계는 어려웠습니다. 마지막에 링크할 몇 가지 동영상을 통해 라우터 및 스위치 이미지를 업로드하는 방법과 위치를 알려주면서 몇 가지 리소스와 다운로드 링크를 제공합니다. + +저는 모든 것을 교육 목적으로 사용한다는 점에 유의하는 것이 중요합니다. 네트워크 공급업체에서 공식 이미지를 다운로드하는 것이 좋습니다. + +[Blog & Links to YouTube videos](https://loopedback.com/2019/11/15/setting-up-eve-ng-for-ccna-ccnp-ccie-level-studies-includes-multiple-vendor-node-support-an-absolutely-amazing-study-tool-to-check-out-asap/) + +[How To Add Cisco VIRL vIOS image to Eve-ng](https://networkhunt.com/how-to-add-cisco-virl-vios-image-to-eve-ng/) + +전반적으로 단계가 조금 복잡하고 훨씬 더 쉬울 수도 있지만 위의 블로그와 동영상은 EVE-NG 박스에 이미지를 추가하는 과정을 안내합니다. + +저는 FileZilla를 사용하여 SFTP를 통해 qcow2를 VM으로 전송했습니다. + +실습에는 Cisco vIOS L2(스위치)와 Cisco vIOS(라우터)가 필요합니다. + +### 실습 만들기 + +EVE-NG 웹 인터페이스 내에서 새로운 네트워크 Topology를 생성하겠습니다. 외부 네트워크에 대한 게이트웨이 역할을 할 스위치 4개와 라우터 1개가 있습니다. + +| Node | IP Address | +| ------- | ------------ | +| Router | 10.10.88.110 | +| Switch1 | 10.10.88.111 | +| Switch2 | 10.10.88.112 | +| Switch3 | 10.10.88.113 | +| Switch4 | 10.10.88.114 | + +#### EVE-NG에 노드 추가하기 + +EVE-NG에 처음 로그인하면 아래와 같은 화면이 표시되며, 첫 번째 랩을 생성하는 것부터 시작하겠습니다. + +![](/2022/Days/Images/Day26_Networking2.png) + +랩 이름을 지정하고 다른 필드는 선택 사항입니다. + +![](/2022/Days/Images/Day26_Networking3.png) + +그러면 네트워크 생성을 시작할 수 있는 빈 캔버스가 표시됩니다. 캔버스를 마우스 오른쪽 버튼으로 클릭하고 노드 추가를 선택합니다. + +여기에서 긴 노드 옵션 목록이 표시되며, 위의 과정을 따라 했다면 아래 표시된 파란색 두 개가 선택되어 있고 나머지는 회색으로 표시되어 선택할 수 없습니다. + +![](/2022/Days/Images/Day26_Networking4.png) + +실습에 다음을 추가하려고 합니다: + +- Cisco vIOS 라우터 1대 +- Cisco vIOS 스위치 4개 + +간단한 마법사를 실행하여 실습에 추가하면 다음과 같은 화면이 나타납니다. + +![](/2022/Days/Images/Day26_Networking5.png) + +#### 노드 연결하기 + +이제 라우터와 스위치 사이에 연결을 추가해야 합니다. 장치 위로 마우스를 가져가면 아래와 같이 연결 아이콘이 표시되고 이를 연결하려는 장치에 연결하면 아주 쉽게 연결할 수 있습니다. + +![](/2022/Days/Images/Day26_Networking6.png) + +환경 연결이 완료되면 마우스 오른쪽 클릭 메뉴에서 찾을 수 있는 상자나 원을 사용하여 물리적 경계나 위치를 정의하는 방법을 추가할 수도 있습니다. 실험실의 이름이나 IP 주소를 정의하고 싶을 때 유용한 텍스트를 추가할 수도 있습니다. + +저는 아래와 같이 실험실을 만들었습니다. + +![](/2022/Days/Images/Day26_Networking7.png) + +위의 실습은 모두 전원이 꺼져 있으며, 모든 것을 선택하고 마우스 오른쪽 버튼을 클릭한 후 선택된 시작을 선택하면 실습을 시작할 수 있습니다. + +![](/2022/Days/Images/Day26_Networking8.png) + +실습을 시작하고 실행하면 각 장치에 콘솔을 연결할 수 있으며, 이 단계에서는 아무 구성도 하지 않은 상태로 매우 멍청한 상태임을 알 수 있습니다. 각 터미널에서 직접 복사하거나 생성하여 각 노드에 구성을 추가할 수 있습니다. + +참조를 위해 리포지토리의 네트워킹 폴더에 구성을 남겨두겠습니다. + +| Node | Configuration | +| ------- | -------------------------------- | +| Router | [R1](/2022/Days/Networking/R1) | +| Switch1 | [SW1](/2022/Days/Networking/SW1) | +| Switch2 | [SW2](/2022/Days/Networking/SW2) | +| Switch3 | [SW3](/2022/Days/Networking/SW3) | +| Switch4 | [SW4](/2022/Days/Networking/SW4) | + +## 자료 + +- [Free Course: Introduction to EVE-NG](https://www.youtube.com/watch?v=g6B0f_E0NMg) +- [EVE-NG - Creating your first lab](https://www.youtube.com/watch?v=9dPWARirtK8) +- [3 Necessary Skills for Network Automation](https://www.youtube.com/watch?v=KhiJ7Fu9kKA&list=WL&index=122&t=89s) +- [Computer Networking full course](https://www.youtube.com/watch?v=IPvYjXCsTg8) +- [Practical Networking](http://www.practicalnetworking.net/) +- [Python Network Automation](https://www.youtube.com/watch?v=xKPzLplPECU&list=WL&index=126) + +저는 네트워크 엔지니어가 아니기 때문에 여기서 사용하는 대부분의 예제는 무료는 아니지만 네트워크 자동화를 이해하는 데 도움이 되는 시나리오 중 일부를 이 방대한 책에서 가져온 것입니다. + +- [Hands-On Enterprise Automation with Python (Book)](https://www.packtpub.com/product/hands-on-enterprise-automation-with-python/9781788998512) + +[Day 27](day27.md)에서 봐요! diff --git a/2022/ko/Days/day27.md b/2022/ko/Days/day27.md new file mode 100644 index 0000000..ae79ffe --- /dev/null +++ b/2022/ko/Days/day27.md @@ -0,0 +1,139 @@ +--- +title: '#90DaysOfDevOps - Getting Hands-On with Python & Network - Day 27' +published: false +description: 90DaysOfDevOps - Getting Hands-On with Python & Network +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048735 +--- + +## 파이썬 및 네트워크 실습하기 + +네트워킹 기초의 마지막 섹션에서는 [Day 26](day26.md)에 만든 실습 환경으로 몇 가지 자동화 작업과 도구를 다뤄보겠습니다. + +클라이언트 vs telnet에서 장치에 연결하기 위해 SSH 터널을 사용할 것입니다. 클라이언트와 기기 사이에 생성된 SSH 터널은 암호화됩니다. [Day 18](day18.md)의 Linux 섹션에서도 SSH에 대해 다루었습니다. + +## 가상 에뮬레이트 환경에 액세스하기 + +스위치와 상호 작용하려면 EVE-NG 네트워크 내부에 워크스테이션이 필요하거나 Python이 설치된 Linux 박스를 배포하여 자동화를 수행할 수 있습니다([Resource for setting up Linux inside EVE-NG](https://www.youtube.com/watch?v=3Qstk3zngrY)) 또는 저처럼 워크스테이션에서 액세스할 수 있는 클라우드를 정의할 수 있습니다. + +![](/2022/Days/Images/Day27_Networking3.png) + +이를 위해 캔버스를 마우스 오른쪽 버튼으로 클릭하고 네트워크를 선택한 다음 "Management(Cloud0)"를 선택하면 홈 네트워크에 연결됩니다. + +![](/2022/Days/Images/Day27_Networking4.png) + +하지만 이 네트워크 내부에는 아무것도 없으므로 새 네트워크에서 각 장치로 연결을 추가해야 합니다. (제 네트워킹 지식이 더 필요한데, 다음 단계로 최상위 라우터에 이 작업을 수행한 다음, 이 하나의 케이블을 통해 나머지 네트워크에 연결할 수 있을 것 같나요?) + +그런 다음 각 장치에 로그온하고 클라우드가 들어오는 위치에 적용되는 인터페이스에 대해 다음 명령을 실행했습니다. + +``` +enable +config t +int gi0/0 +IP add DHCP +no sh +exit +exit +sh ip int br +``` + +마지막 단계에서는 홈 네트워크의 DHCP 주소를 제공합니다. 내 장치 네트워크 목록은 다음과 같습니다: + +| Node | IP Address | Home Network IP | +| ------- | ------------ | --------------- | +| Router | 10.10.88.110 | 192.168.169.115 | +| Switch1 | 10.10.88.111 | 192.168.169.178 | +| Switch2 | 10.10.88.112 | 192.168.169.193 | +| Switch3 | 10.10.88.113 | 192.168.169.125 | +| Switch4 | 10.10.88.114 | 192.168.169.197 | + +### 네트워크 장치에 SSH + +위의 설정이 완료되었으므로 이제 워크스테이션을 사용하여 홈 네트워크의 장치에 연결할 수 있습니다. 저는 Putty를 사용하고 있지만 장치에 SSH를 할 수 있는 git bash와 같은 다른 터미널에도 액세스할 수 있습니다. + +아래에서 라우터 장치에 대한 SSH 연결을 확인할 수 있습니다. (R1) + +![](/2022/Days/Images/Day27_Networking5.png) + +### 파이썬을 사용하여 장치에서 정보 수집하기 + +Python을 활용하는 첫 번째 예는 모든 장치에서 정보를 수집하는 것이며, 특히 각 장치에 연결하여 간단한 명령을 실행하여 인터페이스 구성 및 설정을 제공할 수 있기를 원합니다. 이 스크립트를 여기에 저장해 두었습니다. [netmiko_con_multi.py](/2022/Days/Networking/netmiko_con_multi.py) + +이제 이 스크립트를 실행하면 모든 장치에서 각 포트 구성을 볼 수 있습니다. + +![](/2022/Days/Images/Day27_Networking6.png) + +다양한 장치를 많이 사용하는 경우 이 스크립트를 작성하면 한 곳에서 모든 구성을 중앙에서 빠르게 제어하고 이해할 수 있어 편리합니다. + +### Python을 사용하여 디바이스 구성하기 + +위의 내용은 유용하지만 Python을 사용하여 장치를 구성하는 것은 어떻습니까? 시나리오에서 `SW1`과 `SW2` 사이에 트렁크 포트가 있습니다. 이 작업을 여러 개의 동일한 스위치에서 자동화하고 각 스위치에 수동으로 연결하여 구성을 변경할 필요가 없다고 다시 상상해 보겠습니다. + +이를 위해 [netmiko_sendchange.py](/2022/Days/Networking/netmiko_sendchange.py)를 사용할 수 있습니다. 이렇게 하면 SSH를 통해 연결되고 `SW1`에서 해당 변경을 수행하여 `SW2`로 변경됩니다. + +![](/2022/Days/Images/Day27_Networking7.png) + +이제 코드를 보면 `sending configuration to device`이라는 메시지가, 이것이 발생했는지 확인되지 않은 경우 스크립트에 추가 코드를 추가하여 스위치에서 해당 확인 및 유효성 검사를 수행하거나 이전에 스크립트를 수정하여 이를 표시할 수 있습니다. [netmiko_con_multi_vlan.py](/2022/Days/Networking/netmiko_con_multi_vlan.py) + +![](/2022/Days/Images/Day27_Networking8.png) + +### 디바이스 구성 백업하기 + +또 다른 사용 사례는 네트워크 구성을 캡처하여 백업하는 것이지만, 네트워크에 있는 모든 장치에 연결하고 싶지는 않으므로 [backup.py](/2022/Days/Networking/backup.py)를 사용하여 이 작업을 자동화할 수도 있습니다. 또한 백업하려는 IP 주소로 [backup.txt](/2022/Days/Networking/backup.txt)를 채워야 합니다. + +스크립트를 실행하면 아래와 같은 내용이 표시됩니다. + +![](/2022/Days/Images/Day27_Networking9.png) + +파이썬으로 간단한 인쇄 스크립트를 작성했기 때문에 백업 파일도 함께 보여드릴 수 있습니다. + +![](/2022/Days/Images/Day27_Networking10.png) + +### Paramiko + +SSH를 위해 널리 사용되는 Python 모듈입니다. 자세한 내용은 [공식 GitHub 링크](https://github.com/paramiko/paramiko)에서 확인할 수 있습니다. + +이 모듈은 `pip install paramiko` 명령어를 사용하여 설치할 수 있습니다. + +![](/2022/Days/Images/Day27_Networking1.png) + +파이썬 셸에 들어가서 Paramiko 모듈을 가져와서 설치가 완료되었는지 확인할 수 있습니다. + +![](/2022/Days/Images/Day27_Networking2.png) + +### Netmiko + +Netmiko 모듈은 네트워크 디바이스만을 대상으로 하지만, Paramiko는 SSH 연결 전반을 처리하는 더 광범위한 도구입니다. + +위에서 Paramiko와 함께 사용한 Netmiko는 `pip install netmiko`를 사용하여 설치할 수 있습니다. + +Netmiko는 다양한 네트워크 벤더와 디바이스를 지원하며, 지원 디바이스 목록은 [GitHub Page](https://github.com/ktbyers/netmiko#supports)에서 확인할 수 있습니다. + +### 기타 모듈 + +우리가 살펴볼 기회가 없었지만, 네트워크 자동화와 관련하여 훨씬 더 많은 기능을 제공하는 몇 가지 다른 모듈도 언급할 가치가 있습니다. + +`netaddr`은 IP 주소 작업 및 조작에 사용되며, 설치는 `pip install netaddr`로 간단합니다. + +스위치 구성을 엑셀 스프레드시트에 많이 저장하고 싶을 때, `xlrd`를 사용하면 스크립트가 엑셀 통합 문서를 읽고 행과 열을 행렬로 변환할 수 있습니다. `pip install xlrd`를 실행하면 모듈을 설치할 수 있습니다. + +제가 미처 살펴보지 못한 네트워크 자동화를 사용할 수 있는 더 많은 사용 사례는 [여기](https://github.com/ktbyers/pynet/tree/master/presentations/dfwcug/examples)에서 확인할 수 있습니다. + +네트워킹은 제가 한동안 다루지 않았던 분야이고 다뤄야 할 내용이 훨씬 더 많지만, 제가 작성한 노트와 이 글에서 공유한 리소스가 누군가에게 도움이 되기를 바랍니다. + +## 자료 + +- [Free Course: Introduction to EVE-NG](https://www.youtube.com/watch?v=g6B0f_E0NMg) +- [EVE-NG - Creating your first lab](https://www.youtube.com/watch?v=9dPWARirtK8) +- [3 Necessary Skills for Network Automation](https://www.youtube.com/watch?v=KhiJ7Fu9kKA&list=WL&index=122&t=89s) +- [Computer Networking full course](https://www.youtube.com/watch?v=IPvYjXCsTg8) +- [Practical Networking](http://www.practicalnetworking.net/) +- [Python Network Automation](https://www.youtube.com/watch?v=xKPzLplPECU&list=WL&index=126) + +저는 네트워크 엔지니어가 아니기 때문에 여기서 사용하는 대부분의 예제는 무료는 아니지만 네트워크 자동화를 이해하는 데 도움이 되는 시나리오 중 일부를 이 방대한 책에서 가져온 것입니다. + +- [Hands-On Enterprise Automation with Python (Book)](https://www.packtpub.com/product/hands-on-enterprise-automation-with-python/9781788998512) + +클라우드 컴퓨팅에 대해 알아보고 주제에 대한 이해와 기초 지식을 쌓을 수 있는 [Day 28](day28.md)에서 봐요! diff --git a/2022/ko/Days/day28.md b/2022/ko/Days/day28.md new file mode 100644 index 0000000..41dcf99 --- /dev/null +++ b/2022/ko/Days/day28.md @@ -0,0 +1,105 @@ +--- +title: '#90DaysOfDevOps - The Big Picture: DevOps & The Cloud - Day 28' +published: false +description: 90DaysOfDevOps - The Big Picture DevOps & The Cloud +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048737 +--- + +## 큰 그림: 데브옵스와 클라우드 + +클라우드 컴퓨팅과 제공되는 서비스는 데브옵스 정신 및 프로세스와 매우 잘 어울립니다. 클라우드 컴퓨팅은 기술과 서비스를 제공하는 것으로 생각할 수 있지만, 앞서 여러 번 언급했듯이 데브옵스는 프로세스와 프로세스 개선에 관한 것입니다. + +그러나 클라우드 학습 여정은 가파른 여정이며 모든 요소를 알고 이해하거나 적절한 가격대에 가장 적합한 서비스를 선택하는 것은 혼란스러운 일입니다. + +![](/2022/Days/Images/Day28_Cloud1.png) + +퍼블릭 클라우드에 데브옵스 마인드셋이 필요한가요? 제 대답은 '아니다'이지만, 클라우드 컴퓨팅을 제대로 활용하고 많은 사람이 겪었던 막대한 클라우드 비용을 피하려면 클라우드 컴퓨팅과 데브옵스를 함께 생각하는 것이 중요합니다. + +퍼블릭 클라우드의 의미를 40,000피트 상공에서 보면, 관리형 서비스에 대한 책임을 일부 제거하여 여러분과 여러분의 팀이 애플리케이션과 최종 사용자라는 더 중요한 측면에 집중할 수 있도록 하는 것입니다. 결국 퍼블릭 클라우드는 다른 사람의 컴퓨터일 뿐입니다. + +![](/2022/Days/Images/Day28_Cloud2.png) + +이 첫 번째 섹션에서는 퍼블릭 클라우드가 무엇인지, 그리고 전체적으로 퍼블릭 클라우드라고 불리는 몇 가지 구성 요소에 대해 조금 더 자세히 설명하고자 합니다. + +### SaaS + +첫 번째로 다룰 영역은 서비스로서의 소프트웨어로, 이 서비스는 온-프레미스에서 실행하던 서비스의 거의 모든 관리 오버헤드를 제거합니다. 이메일용 Microsoft Exchange를 예로 들어 보겠습니다. 예전에는 데이터 센터나 계단 아래 찬장에 있는 물리적 상자였습니다. 이 서버에 먹이를 주고 물을 주어야 했습니다. 즉, 서버 하드웨어를 구입하고, 운영 체제를 설치하고, 필요한 애플리케이션을 설치한 다음 패치를 유지해야 하며, 문제가 발생하면 문제를 해결하고 다시 실행해야 합니다. + +또한 데이터를 백업하고 있는지 확인해야 하지만, 대부분의 경우 SaaS를 사용한다고 해서 달라지지는 않습니다. + +SaaS의 기능, 특히 Microsoft 365의 경우 앞서 Exchange를 언급했듯이 관리 오버헤드를 없애고 메일을 통해 Exchange 기능뿐만 아니라 다른 많은 생산성(Office 365) 및 저장소 옵션(OneDrive)을 제공하는 서비스를 제공하여 전반적으로 최종 사용자에게 훌륭한 경험을 제공합니다. + +Salesforce, SAP, Oracle, Google, Apple과 같은 다른 SaaS 애플리케이션도 널리 채택되고 있습니다. 모두 더 많은 스택을 관리해야 하는 부담을 덜어줍니다. + +DevOps와 SaaS 기반 애플리케이션에 대한 이야기가 있을 거라고 확신하지만, 그 내용을 파악하는 데 어려움을 겪고 있습니다. Azure DevOps에 Microsoft 365와의 훌륭한 통합 기능이 있다는 것을 알고 있으므로 살펴보고 다시 보고할 수 있습니다. + +![](/2022/Days/Images/Day28_Cloud3.png) + +### 퍼블릭 클라우드 + +다음은 퍼블릭 클라우드입니다. 대부분의 사람들은 퍼블릭 클라우드를 몇 가지 다른 방식으로 생각할 수 있으며, 일부는 Microsoft Azure, Google Cloud Platform 및 AWS와 같은 하이퍼 스케일러로만 볼 수 있습니다. + +![](/2022/Days/Images/Day28_Cloud4.png) + +또한 퍼블릭 클라우드를 이러한 하이퍼 스케일러뿐만 아니라 전 세계 수천 개의 MSP를 포함하는 훨씬 더 광범위한 서비스로 보는 사람도 있을 것입니다. 이 글에서는 하이퍼 스케일러와 MSP를 포함한 퍼블릭 클라우드를 고려할 예정이지만, 나중에 하이퍼 스케일러 중 하나 이상을 구체적으로 살펴봄으로써 기초적인 지식을 얻도록 하겠습니다. + +![](/2022/Days/Images/Day28_Cloud5.png) +_수천 개의 더 많은 회사가 이 서비스를 이용할 수 있지만, 저는 제가 함께 일했고 알고 있는 로컬, 지역, 통신사 및 글로벌 브랜드 중에서 골랐을 뿐입니다_. + +앞서 SaaS 섹션에서 클라우드가 시스템의 일부를 관리해야 하는 책임이나 부담을 덜어준다고 언급했습니다. SaaS의 경우 물리적 시스템, 네트워크, 스토리지, 운영 체제, 애플리케이션 등 많은 추상화 계층이 어느 정도 제거되었습니다. 클라우드의 경우 요구 사항에 따라 제거하거나 유지할 수 있는 추상화 수준이 다양합니다. + +이미 SaaS에 대해 언급했지만, 퍼블릭 클라우드와 관련하여 최소 두 가지를 더 언급할 수 있습니다. + +IaaS(Infrastructure as a Service) - 이 계층을 가상 머신으로 생각할 수 있지만, 온프레미스에서는 클라우드의 물리적 계층을 관리해야 하는 반면, 클라우드에서는 물리적 계층은 클라우드 제공업체의 책임이며 운영 체제, 데이터, 실행하려는 애플리케이션을 관리 및 운영하게 됩니다. + +PaaS(Platform as a Service) - 계층의 책임이 계속 제거되며, 사용자가 데이터와 애플리케이션을 제어하지만, 기반이 되는 하드웨어나 운영 체제에 대해 걱정할 필요가 없습니다. + +다른 많은 aaS 제품이 있지만, 이 두 가지가 기본입니다. 스토리지 계층을 제공하지만, 그 밑에 있는 하드웨어에 대해 걱정할 필요가 없는 StaaS(Storage as a service) 관련 제품을 볼 수 있습니다. 또는 컨테이너를 위한 CaaS에 대해 들어보셨을 수도 있고, 앞으로 7일 동안 다룰 또 다른 aaS는 시스템을 항상 가동할 필요가 없고 필요할 때만 함수를 실행하기를 원하는 경우에 사용할 수 있는 FaaS(Functions as a Service입니다. + +퍼블릭 클라우드는 사용자가 원하는 제어 계층의 추상화 계층을 제공하고 비용을 지불할 수 있는 여러 가지 방법이 있습니다. + +![](/2022/Days/Images/Day28_Cloud6.png) + +### 프라이빗 클라우드 + +자체 데이터 센터를 보유하는 것은 과거의 일이 아닙니다. 퍼블릭 클라우드를 사용하는 것만으로는 기술뿐만 아니라 운영 비용 모델을 관리하기 어렵다는 것을 알게 된 많은 기업들 사이에서 다시 부상하고 있다고 생각합니다. + +여기서 주목해야 할 중요한 점은 퍼블릭 클라우드는 이제 기업의 책임이 될 가능성이 높으며, 온프레미스 환경이 될 것이라는 점입니다. + +가상화 시대와 온프레미스 인프라 환경을 지배했던 VMware뿐만 아니라 이 분야에서도 흥미로운 일들이 일어나고 있습니다. 퍼블릭 클라우드의 온프레미스 버전을 제공하는 하이퍼 스케일러도 있습니다. + +![](/2022/Days/Images/Day28_Cloud7.png) + +### 하이브리드 클라우드 + +앞서 언급한 퍼블릭 클라우드와 프라이빗 클라우드에 이어서, 퍼블릭 클라우드에서 제공되는 서비스를 활용하면서 온프레미스 환경의 기능을 활용하거나 규제에 따라 데이터를 로컬에 저장해야 하는 경우 두 환경 간에 유연성을 제공할 수 있는 하이브리드 클라우드도 있습니다. + +![](/2022/Days/Images/Day28_Cloud8.png) + +이 모든 것을 종합하면 워크로드를 저장하고 실행하는 위치에 대한 선택의 폭이 넓어집니다. + +![](/2022/Days/Images/Day28_Cloud9.png) + +구체적인 하이퍼스케일에 들어가기 전에 트위터의 힘에 우리가 어디로 가야 할지를 물어봤습니다. + +![](/2022/Days/Images/Day28_Cloud10.png) + +[트위터 설문조사 링크](https://twitter.com/MichaelCade1/status/1486814904510259208?s=20&t=x2n6QhyOXSUs7Pq0itdIIQ) + +어느 쪽이 가장 높은 비율을 얻든 제품에 대해 더 자세히 살펴볼 것이지만, 중요한 것은 모든 서비스의 서비스가 상당히 유사하다는 점이며, 제가 하나부터 시작하라고 말하는 이유는 하나의 기초와 가상 머신 생성, 네트워킹 설정 방법 등을 알기 때문이라고 생각하기 때문입니다. 다른 서비스로 이동하여 해당 영역에서 빠르게 성장할 수 있었습니다. + +어느 쪽이든, 저는 세 가지 하이퍼 스케일러를 모두 다루는 훌륭한 **무료** 리소스를 공유하려고 합니다. + +또한 다른 섹션에서 그랬던 것처럼 시나리오를 작성하여 며칠 동안 진행하면서 무언가를 구축 할 수 있습니다. + +## 자료 + +- [Hybrid Cloud and MultiCloud](https://www.youtube.com/watch?v=qkj5W98Xdvw) +- [Microsoft Azure Fundamentals](https://www.youtube.com/watch?v=NKEFWyqJ5XA&list=WL&index=130&t=12s) +- [Google Cloud Digital Leader Certification Course](https://www.youtube.com/watch?v=UGRDM86MBIQ&list=WL&index=131&t=10s) +- [AWS Basics for Beginners - Full Course](https://www.youtube.com/watch?v=ulprqHHWlng&t=5352s) + +[Day 29](day29.md)에서 봐요! diff --git a/2022/ko/Days/day29.md b/2022/ko/Days/day29.md new file mode 100644 index 0000000..527b151 --- /dev/null +++ b/2022/ko/Days/day29.md @@ -0,0 +1,141 @@ +--- +title: '#90DaysOfDevOps - Microsoft Azure Fundamentals - Day 29' +published: false +description: 90DaysOfDevOps - Microsoft Azure Fundamentals +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048705 +--- + +## Microsoft Azure 기초 + +시작하기 전에 트위터 투표의 승자는 Microsoft Azure였으며, 따라서 페이지의 제목도 그렇게 정해졌습니다. 박빙의 승부가 펼쳐졌고 24시간 동안의 결과가 꽤 흥미로웠습니다. + +![](/2022/Days/Images/Day29_Cloud1.png) + +이 주제를 다루면서 Microsoft Azure에서 사용할 수 있는 서비스에 대해 더 잘 이해하고 업데이트할 수 있다는 측면에서 저는 오늘 하루는 Amazon AWS에 기대고 있습니다. 하지만 세 가지 주요 클라우드 제공업체 모두에 대해 준비해 둔 리소스를 남겨 두었습니다. + +설문조사에는 이 세 가지 서비스만 포함되었고 특히 오라클 클라우드에 대한 의견도 몇 개 있었습니다. 실제 사용 중인 다른 클라우드 제공업체에 대한 의견을 더 듣고 싶습니다. + +### 기본 사항 + +- 퍼블릭 클라우드 서비스 제공 +- 지리적으로 분산되어 있음(전 세계 60개 이상의 지역) +- 인터넷 및/또는 개인 연결을 통해 액세스 +- 멀티 테넌트 모델 +- 사용량 기반 청구 - (종량제 및 사용량 증가에 따른 과금) +- 다양한 요구 사항에 맞는 다양한 서비스 유형 및 제품. + +- [Microsoft Azure 글로벌 인프라](https://infrastructuremap.microsoft.com/explore) + +SaaS 및 하이브리드 클라우드에 대해 많이 이야기했지만 여기서는 해당 주제를 다루지 않을 계획입니다. + +시작하고 따라 하는 가장 좋은 방법은 링크를 클릭하여 [Microsoft Azure 무료 계정](https://azure.microsoft.com/en-gb/free/)을 생성하는 것입니다. + +### 지역 + +위의 인터랙티브 지도를 링크했는데, 아래 이미지에서 전 세계 Microsoft Azure 플랫폼에서 제공되는 다양한 지역을 확인할 수 있습니다. + +![](/2022/Days/Images/Day29_Cloud2.png) +[Microsoft 문서](https://docs.microsoft.com/en-us/azure/networking/microsoft-global-network)에서 가져온 이미지 - _01/05/2021_ + +또한 다른 지역과 연결되지 않거나 다른 지역과 대화할 수 없음을 의미하는 여러 "sovereign" 클라우드를 볼 수 있는데, 예를 들어 `AzureUSGovernment`, `AzureChinaCloud` 등과 같은 정부와 관련된 클라우드가 있습니다. + +Microsoft Azure 내에서 서비스를 배포할 때 거의 모든 것에 대해 지역을 선택합니다. 하지만 모든 지역에서 모든 서비스를 이용할 수 있는 것은 아니라는 점에 유의해야 합니다. 이 글을 쓰는 시점에 [지역별 사용 가능한 제품](https://azure.microsoft.com/en-us/global-infrastructure/services/?products=all)을 보면 미국 중서부 지역에서는 Azure Databricks을 사용할 수 없다는 것을 알 수 있습니다. + +또한 위에서 "거의 모든 것"이라고 언급했는데, Azure Bot Services, Bing Speech, Azure Virtual Desktop, Static Web Apps 등과 같이 지역과 연결된 특정 서비스가 있습니다. + +이면에서는 region이 둘 이상의 데이터 센터로 구성될 수 있습니다. 이를 가용 영역이라고 합니다. + +아래 이미지에서 볼 수 있듯이 이 이미지는 Microsoft 공식 문서에서 가져온 것으로, region이란 무엇이며 region이 가용 영역으로 어떻게 구성되는지 설명합니다. 그러나 모든 지역에 가용 영역이 여러 개 있는 것은 아닙니다. + +![](/2022/Days/Images/Day29_Cloud3.png) + +Microsoft 설명서는 매우 훌륭하며 [여기](https://docs.microsoft.com/en-us/azure/availability-zones/az-overview)에서 지역 및 가용 영역에 대한 자세한 내용을 읽을 수 있습니다. + +### 구독 + +Microsoft Azure는 모든 주요 클라우드 공급자가 이 모델을 따르는 소비 모델 클라우드라고 언급했음을 기억하세요. + +엔터프라이즈인 경우 회사에서 이러한 Azure 서비스를 사용할 수 있도록 Microsoft와 엔터프라이즈 계약을 원하거나 이미 설정했을 수 있습니다. + +저와 같이 교육용으로 Microsoft Azure를 사용하는 경우 몇 가지 다른 옵션이 있습니다. + +일반적으로 일정 기간 동안 Azure에서 사용할 수 있는 몇 가지 무료 클라우드 크레딧을 제공하는 [Microsoft Azure 무료 계정](https://azure.microsoft.com/en-gb/free/)이 있습니다. + +또한 Visual Studio 연간 구독과 함께 매달 몇 가지 무료 크레딧을 제공하는 [Visual Studio](https://azure.microsoft.com/en-us/pricing/member-offers/credit-for-visual-studio-subscribers/) 구독을 사용할 수도 있습니다(몇 년 전에는 일반적으로 MSDN으로 알려짐). + +마지막으로 신용카드를 건네고 [종량제](https://azure.microsoft.com/en-us/pricing/purchase-options/pay-as-you-go/) 모델을 사용하는 방법이 있습니다. + +구독은 잠재적으로 비용 중심이지만 완전히 다른 환경을 가진 서로 다른 구독 간의 경계로 볼 수 있습니다. 구독은 리소스가 생성되는 곳입니다. + +### 관리 그룹 + +관리 그룹을 사용하면 Azure AD(Active Directory) 또는 테넌트 환경 전반에서 제어를 분리할 수 있습니다. 관리 그룹을 통해 정책, RBAC(역할 기반 액세스 제어) 및 예산을 제어할 수 있습니다. + +구독은 이러한 관리 그룹에 속하므로 Azure AD 테넌트에 많은 구독을 보유할 수 있으며, 이러한 구독은 정책, RBAC 및 예산도 제어할 수 있습니다. + +### 리소스 관리자 및 리소스 그룹 + +#### Azure 리소스 관리자 + +- 리소스 공급자를 기반으로 구축된 JSON 기반 API입니다. +- 리소스는 리소스 그룹에 속하며 공통 수명 주기를 공유합니다. +- 병렬 처리 +- JSON 기반 배포는 선언적이고 비독립적이며 리소스 간의 종속성을 이해하여 생성 및 순서를 관리합니다. + +#### 리소스 그룹 + +- 모든 Azure Resource Manager 리소스는 하나의 리소스 그룹에만 존재합니다! +- 리소스 그룹은 지역 외부의 리소스를 포함할 수 있는 지역에서 만들어집니다. +- 리소스 그룹 간에 리소스 이동 가능 +- 리소스 그룹은 다른 리소스 그룹과 차단되지 않으며, 리소스 그룹 간에 통신할 수 있습니다. +- 리소스 그룹은 정책, RBAC 및 예산도 제어할 수 있습니다. + +### 실습 + +이제 연결하여 **Subscription**을 사용할 수 있는지 확인해 보겠습니다. 기본 제공되는 간단한 **Management Group**을 확인한 다음, 원하는 **Region**에 새로운 전용 **Resource Group**을 만들 수 있습니다. + +[Azure 포털](https://portal.azure.com/#home)에 처음 로그인하면 상단에 리소스, 서비스 및 문서를 검색할 수 있는 기능이 표시됩니다. + +![](/2022/Days/Images/Day29_Cloud4.png) + +먼저 구독을 살펴보겠습니다. 여기에서는 매달 무료 크레딧을 제공하는 Visual Studio Professional 구독을 사용하고 있음을 알 수 있습니다. + +![](/2022/Days/Images/Day29_Cloud5.png) + +더 넓은 화면으로 이동하여 구독으로 어떤 일이 일어나고 있는지 또는 무엇을 할 수 있는지 살펴보면 왼쪽에 IAM 액세스 제어를 정의할 수 있는 제어 기능과 함께 청구 정보를 볼 수 있으며 더 아래로 내려가면 더 많은 리소스를 사용할 수 있습니다. + +![](/2022/Days/Images/Day29_Cloud6.png) + +여러 개의 구독이 있고 이를 모두 하나의 구독으로 관리하려는 시나리오가 있을 수 있는데, 이때 관리 그룹을 사용하여 책임 그룹을 분리할 수 있습니다. 아래 제 경우에는 구독이 있는 테넌트 루트 그룹만 있는 것을 볼 수 있습니다. + +또한 이전 이미지에서 상위 관리 그룹이 테넌트 루트 그룹에 사용된 아이디와 동일한 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day29_Cloud7.png) + +다음으로 리소스 그룹이 있는데, 여기에서 리소스를 결합하여 한 곳에서 쉽게 관리할 수 있습니다. 저는 다른 여러 프로젝트를 위해 몇 개를 만들었습니다. + +![](/2022/Days/Images/Day29_Cloud8.png) + +앞으로 며칠 동안 할 작업을 위해 리소스 그룹을 만들고 싶습니다. 이 콘솔에서 이전 이미지의 생성 옵션을 누르면 쉽게 할 수 있습니다. + +![](/2022/Days/Images/Day29_Cloud9.png) + +유효성 검사 단계가 수행된 후 생성한 내용을 검토한 다음 생성할 수 있습니다. 또한 하단에 "Download a template for automation"가 표시되는데, 이를 통해 JSON 형식을 가져와서 나중에 원할 경우, 이 간단한 작업을 자동화 방식으로 수행할 수 있으며, 이에 대해서도 나중에 다룰 것입니다. + +![](/2022/Days/Images/Day29_Cloud10.png) + +생성 버튼을 누르면 리소스 그룹 목록에 다음 세션에서 수행할 작업을 위한 "90DaysOfDevOps" 그룹이 준비됩니다. + +![](/2022/Days/Images/Day29_Cloud11.png) + +## 자료 + +- [Hybrid Cloud and MultiCloud](https://www.youtube.com/watch?v=qkj5W98Xdvw) +- [Microsoft Azure Fundamentals](https://www.youtube.com/watch?v=NKEFWyqJ5XA&list=WL&index=130&t=12s) +- [Google Cloud Digital Leader Certification Course](https://www.youtube.com/watch?v=UGRDM86MBIQ&list=WL&index=131&t=10s) +- [AWS Basics for Beginners - Full Course](https://www.youtube.com/watch?v=ulprqHHWlng&t=5352s) + +[Day 30](day30.md)에서 봐요! diff --git a/2022/ko/Days/day30.md b/2022/ko/Days/day30.md new file mode 100644 index 0000000..0eeab29 --- /dev/null +++ b/2022/ko/Days/day30.md @@ -0,0 +1,175 @@ +--- +title: '#90DaysOfDevOps - Microsoft Azure Security Models - Day 30' +published: false +description: 90DaysOfDevOps - Microsoft Azure Security Models +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049039 +--- + +## Microsoft Azure 보안 모델 + +Microsoft Azure 개요에 이어서 Azure 보안부터 시작하여 일상적인 업무에 어떤 도움이 될 수 있는지 살펴보겠습니다. 대부분의 경우 기본 제공 역할로도 충분하지만, 다양한 인증 및 구성 영역을 만들고 작업할 수 있다는 것을 알게 되었습니다. 다른 퍼블릭 클라우드에 비해 Microsoft Azure의 Active Directory 배경이 상당히 발전되어 있다는 것을 알았습니다. + +Microsoft Azure가 다른 퍼블릭 클라우드 공급자와 다르게 작동하는 것처럼 보이는 영역 중 하나는 Azure에는 항상 Azure AD가 있다는 것입니다. + +### 디렉토리 서비스 + +- Azure Active Directory는 Microsoft Azure 및 기타 Microsoft 클라우드 서비스에서 사용하는 보안 원칙을 호스팅합니다. +- 인증은 SAML, WS-Federation, OpenID Connect 및 OAuth2와 같은 프로토콜을 통해 수행됩니다. +- 쿼리는 Microsoft Graph API라는 REST API를 통해 수행됩니다. +- 테넌트는 tenant.onmicrosoft.com을 기본 이름으로 사용하지만 사용자 지정 도메인 이름을 사용할 수도 있습니다. +- 구독은 Azure Active Directory 테넌트와 연결됩니다. + +AWS와 비교하기 위해 AWS를 생각해보면 여전히 매우 다르지만, AWS IAM(ID 및 액세스 관리)이 동등한 오퍼링이 될 것입니다. + +Azure AD Connect는 AD에서 Azure AD로 계정을 복제하는 기능을 제공합니다. 여기에는 그룹과 때로는 개체가 포함될 수도 있습니다. 이는 세분화 및 필터링할 수 있습니다. 여러 포리스트 및 도메인을 지원합니다. + +Microsoft Azure AD(Active Directory)에서 클라우드 계정을 만들 수 있지만 대부분의 조직은 이미 온-프레미스에 있는 자체 Active Directory에서 사용자를 계정화하고 있습니다. + +Azure AD Connect를 사용하면 Windows AD 서버뿐만 아니라 다른 Azure AD, Google 및 기타 서버도 볼 수 있습니다. 또한 외부 사람 및 조직과 공동 작업할 수 있는 기능을 제공하는데, 이를 Azure B2B라고 합니다. + +액티브 디렉토리 도메인 서비스와 Microsoft Azure 액티브 디렉토리 간의 인증 옵션은 암호 해시와 ID 동기화를 통해 모두 가능합니다. + +![](/2022/Days/Images/Day30_Cloud1.png) + +암호 해시 전달은 선택 사항이며, 암호 해시를 사용하지 않는 경우 통과 인증이 필요합니다. + +아래에 링크된 비디오에서 패스스루 인증에 대해 자세히 설명합니다. + +[Azure Active Directory 패스스루 인증을 사용한 사용자 로그인](https://docs.microsoft.com/en-us/azure/active-directory/hybrid/how-to-connect-pta) + +![](/2022/Days/Images/Day30_Cloud2.png) + +### 페더레이션 + +Microsoft 365, Microsoft Dynamics 및 온-프레미스 Active Directory를 사용하는 경우 페더레이션을 위해 Azure AD를 이해하고 통합하는 것은 매우 쉽습니다. 하지만 Microsoft 에코시스템 외부의 다른 서비스를 사용하고 있을 수도 있습니다. + +Azure AD는 이러한 다른 타사 앱 및 기타 디렉토리 서비스에 대한 페더레이션 브로커 역할을 할 수 있습니다. + +이는 Azure 포털에서 다양한 옵션이 있는 엔터프라이즈 애플리케이션으로 표시됩니다. + +![](/2022/Days/Images/Day30_Cloud3.png) + +엔터프라이즈 애플리케이션 페이지에서 아래로 스크롤 하면 추천 애플리케이션의 긴 목록을 볼 수 있습니다. + +![](/2022/Days/Images/Day30_Cloud4.png) + +이 옵션을 사용하면 개발 중인 애플리케이션이나 갤러리 이외의 애플리케이션을 "직접 가져와서" 통합할 수도 있습니다. + +이전에 이 기능을 살펴본 적은 없지만 다른 클라우드 제공업체 및 기능과 비교할 때 상당한 기능 집합이라는 것을 알 수 있습니다. + +### 역할 기반 액세스 제어 + +여기서 다룰 범위는 이미 [Day 29](day29.md)에서 다뤘으며, 이러한 영역 중 하나에 따라 역할 기반 액세스 제어를 설정할 수 있습니다. + +- 구독 +- 관리 그룹 +- 리소스 그룹 +- 리소스 + +역할은 세 가지로 나눌 수 있으며, Microsoft Azure에는 많은 기본 제공 역할이 있습니다. 이 세 가지 역할은 다음과 같습니다: + +- 소유자 +- 기여자 +- 리더 + +소유자와 기여자는 범위가 매우 유사하지만, 소유자가 권한을 변경할 수 있습니다. + +다른 역할은 특정 유형의 Azure 리소스 및 사용자 지정 역할에 따라 다릅니다. + +그룹과 사용자에 대한 사용 권한 할당에 중점을 두어야 합니다. + +사용 권한은 상속됩니다. + +다시 돌아가서 우리가 만든 "90DaysOfDevOps" 리소스 그룹을 살펴보고 그 안의 액세스 제어(IAM)를 확인하면 기여자 목록과 고객 사용자 액세스 관리자 목록이 있고 소유자 목록이 있는 것을 볼 수 있습니다(하지만 이 목록은 표시할 수 없습니다). + +![](/2022/Days/Images/Day30_Cloud5.png) + +또한 여기에서 할당된 역할이 빌트인 역할인지 여부와 해당 역할이 어떤 카테고리에 속하는지 확인할 수 있습니다. + +![](/2022/Days/Images/Day30_Cloud6.png) + +이 리소스 그룹에 대해 계정을 확인하고 해당 액세스 권한을 갖고자 하는 계정에 올바른 권한이 있는지 확인하거나 사용자가 너무 많은 액세스 권한을 갖고 있는지 확인하려는 경우 액세스 확인 탭을 사용할 수도 있습니다. + +![](/2022/Days/Images/Day30_Cloud7.png) + +### 클라우드용 Microsoft Defender + +- 클라우드용 Microsoft Defender(이전의 Azure Security Center)는 전체 Azure 환경의 보안에 대한 인사이트를 제공합니다. + +- 단일 대시보드를 통해 모든 Azure 및 비 Azure 리소스의 전반적인 보안 상태를 파악할 수 있으며(Azure Arc를 통해) 보안 강화 지침을 제공합니다. + +- 프리티어에는 지속적인 평가 및 보안 권장 사항이 포함됩니다. + +- 보호되는 리소스 유형(예: Servers, AppService, SQL, Storage, Containers, KeyVault)에 대한 유료 플랜. + +다른 구독으로 전환하여 Azure 보안 센터를 확인했으며, 여기에서 몇 가지 리소스를 기반으로 한 곳에서 몇 가지 권장 사항을 확인할 수 있습니다. + +![](/2022/Days/Images/Day30_Cloud8.png) + +### Azure 정책 + +- Azure Policy는 조직 표준을 적용하고 대규모로 규정 준수를 평가하는 데 도움이 되는 Azure 기본 서비스입니다. + +- 클라우드용 Microsoft Defender에 통합됩니다. Azure Policy는 규정을 준수하지 않는 리소스를 감사하고 수정 사항을 적용합니다. + +- 리소스 일관성, 규정 준수, 보안, 비용 및 관리 표준을 관리하는 데 일반적으로 사용됩니다. + +- JSON 형식을 사용하여 평가 로직을 저장하고 리소스의 규정 준수 여부와 규정 미준수 시 취할 조치(예: 감사, AuditIfNotExists, 거부, 수정, DeployIfNotExists)를 결정합니다. + +- 무료로 사용할 수 있습니다. 단, Azure 정책 게스트 구성 사용량에 대해 서버/월당 청구되는 Azure Arc 연결 리소스는 예외입니다. + +### 실습 + +www.90DaysOfDevOps.com 도메인을 구입했는데 이 도메인을 내 Azure Active Directory 포털에 추가하고 싶습니다. [Azure Active Directory 포털을 사용하여 사용자 지정 도메인 이름 추가](https://docs.microsoft.com/en-us/azure/active-directory/fundamentals/add-custom-domain) + +![](/2022/Days/Images/Day30_Cloud9.png) + +이제 새 Active Directory 도메인에 새 사용자를 만들 수 있습니다. + +![](/2022/Days/Images/Day30_Cloud10.png) + +이제 모든 새로운 90DaysOfDevOps 사용자를 하나의 그룹으로 묶는 그룹을 만들고 싶습니다. 아래와 같이 그룹을 만들 수 있으며, Azure AD가 사용자 계정을 쿼리하여 동적으로 추가하는 "Dynamic User"와 수동으로 사용자를 그룹에 추가하는 "Assigned"를 사용하고 있음을 알 수 있습니다. + +![](/2022/Days/Images/Day30_Cloud11.png) + +쿼리를 작성할 때 많은 옵션이 있지만, 저는 단순히 대표 이름을 찾아 이름에 @90DaysOfDevOps.com이 포함되어 있는지 확인하려고 합니다. + +![](/2022/Days/Images/Day30_Cloud12.png) + +이제 michael.cade@90DaysOfDevOps.com 에 대한 사용자 계정을 이미 만들었으므로 규칙이 작동하는지 확인할 수 있습니다. 비교를 위해 다른 도메인에 연결한 다른 계정도 여기에 추가했는데, 이 규칙으로 인해 사용자가 이 그룹에 속하지 않는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day30_Cloud13.png) + +그 후 user1@90DaysOfDevOps.com 을 새로 추가했고 그룹을 확인하면 회원을 볼 수 있습니다. + +![](/2022/Days/Images/Day30_Cloud14.png) + +이 요구 사항이 많아진다면, 콘솔에서 이 모든 작업을 수행하지 않고 대량 옵션을 사용하여 사용자를 만들고, 초대하고, 삭제하거나 PowerShell을 사용하여 자동화된 확장 방식을 사용하고 싶을 것입니다. + +이제 리소스 그룹으로 이동하여 90DaysOfDevOps 리소스 그룹에서 소유자가 방금 만든 그룹이 되도록 지정할 수 있습니다. + +![](/2022/Days/Images/Day30_Cloud15.png) + +마찬가지로 여기로 이동하여 리소스 그룹에 대한 할당 액세스를 거부할 수도 있습니다. + +이제 새 사용자 계정으로 Azure Portal에 로그인하면 액세스 권한이 없기 때문에 이전 그림에서 볼 수 있는 다른 리소스 그룹에는 액세스 권한이 없고 90DaysOfDevOps 리소스 그룹에만 액세스 권한이 있는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day30_Cloud16.png) + +모든 사용자가 포털을 알고 있을 필요는 없지만, 액세스 권한을 확인하기 위해 [앱 포털](https://myapps.microsoft.com/)을 사용하여 테스트할 수 있는 싱글 사인온 포털입니다. + +![](/2022/Days/Images/Day30_Cloud17.png) + +이 포털을 브랜딩으로 사용자 지정할 수 있으며, 이 부분은 나중에 다시 다룰 수 있습니다. + +## 자료 + +- [Hybrid Cloud and MultiCloud](https://www.youtube.com/watch?v=qkj5W98Xdvw) +- [Microsoft Azure Fundamentals](https://www.youtube.com/watch?v=NKEFWyqJ5XA&list=WL&index=130&t=12s) +- [Google Cloud Digital Leader Certification Course](https://www.youtube.com/watch?v=UGRDM86MBIQ&list=WL&index=131&t=10s) +- [AWS Basics for Beginners - Full Course](https://www.youtube.com/watch?v=ulprqHHWlng&t=5352s) + +[Day 31](day31.md)에서 봐요! diff --git a/2022/ko/Days/day31.md b/2022/ko/Days/day31.md new file mode 100644 index 0000000..f7b1e1b --- /dev/null +++ b/2022/ko/Days/day31.md @@ -0,0 +1,114 @@ +--- +title: '#90DaysOfDevOps - Microsoft Azure Compute Models - Day 31' +published: false +description: 90DaysOfDevOps - Microsoft Azure Compute Models +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049040 +--- + +## Microsoft Azure 컴퓨팅 모델 + +어제 Microsoft Azure의 보안 모델에 대한 기본 사항을 다룬 데 이어 오늘은 Azure에서 사용할 수 있는 다양한 컴퓨팅 서비스에 대해 살펴보겠습니다. + +### 서비스 가용성 옵션 + +이 섹션은 데이터 관리에서 제 역할을 고려할 때 제 마음에 와닿는 부분입니다. 온-프레미스와 마찬가지로 서비스의 가용성을 보장하는 것이 중요합니다. + +- 고가용성(지역 내 보호) +- 재해 복구(지역 간 보호) +- 백업(특정 시점으로부터의 복구) + +Microsoft는 지정학적 경계 내에 여러 지역을 배포합니다. + +서비스 가용성을 위한 Azure의 두 가지 개념엔 Sets와 영역이 있습니다. + +가용성 Sets - 데이터 센터 내에서 복원력 제공 + +가용성 영역 - 지역 내 데이터 센터 간에 복원력을 제공합니다. + +### 가상 머신 + +퍼블릭 클라우드의 시작점일 가능성이 높습니다. + +- 다양한 기능을 갖춘 다양한 계열 및 [크기](https://docs.microsoft.com/en-us/azure/virtual-machines/sizes)의 가상 머신을 제공합니다(때로는 압도적일 수 있음). +- 고성능, 짧은 지연 시간, 높은 메모리 옵션의 VM에 이르기까지 다양한 옵션과 초점이 있는 VM을 제공합니다. +- 또한 B-Series에서 찾을 수 있는 burstable VM 유형도 있습니다. 이는 대부분의 경우 CPU 요구 사항이 낮지만, 한 달에 한 번 정도 성능 급증이 필요한 워크로드에 적합합니다. +- 가상 머신은 모든 네트워크에 연결을 제공할 수 있는 가상 네트워크에 배치됩니다. +- Windows 및 Linux 게스트 OS 지원. +- 특정 Linux 배포판의 경우 [Azure 튜닝된 커널](https://docs.microsoft.com/en-us/azure/virtual-machines/linux/endorsed-distros#azure-tuned-kernels)도 있습니다. + +### 템플릿 + +앞서 마이크로소프트 애저의 이면이나 밑에 있는 모든 것이 JSON이라고 언급했습니다. + +리소스를 생성하는 데 사용할 수 있는 여러 가지 관리 포털과 콘솔이 있지만, 가장 선호하는 경로는 JSON 템플릿을 통한 것입니다. + +증분 또는 전체 모드, 즉 반복 가능한 원하는 상태의 무동력 배포. + +배포된 리소스 정의를 내보낼 수 있는 다양한 템플릿이 있습니다. 저는 이 템플릿 기능을 AWS CloudFormation과 같은 것에 적용하거나 멀티클라우드 옵션을 위한 Terraform이 될 수 있다고 생각하고 있습니다. Terraform에 대해서는 IaC 섹션에서 자세히 다루겠습니다. + +### 스케일링 + +자동 확장은 사용하지 않는 리소스를 스핀다운 하거나 필요할 때 스핀업할 수 있는 퍼블릭 클라우드의 큰 기능입니다. + +Azure에는 IaaS용 VMSS(Virtual Machine Scale Sets)라는 것이 있습니다. 이를 통해 일정 및 메트릭을 기반으로 골드 스탠다드 이미지를 자동으로 생성하고 확장할 수 있습니다. + +이는 윈도우를 업데이트하는 데 이상적이므로 이미지를 업데이트하고 최소한의 영향을 미치면서 배포할 수 있습니다. + +Azure 앱 서비스와 같은 다른 서비스에는 자동 확장 기능이 내장되어 있습니다. + +### 컨테이너 + +컨테이너를 사용 사례로 다루지 않았고 DevOps 학습 여정에서 컨테이너가 필요한 이유와 방법을 다루지 않았지만, Azure에는 몇 가지 특정 컨테이너 중심 서비스가 있다는 점을 언급할 필요가 있습니다. + +Azure Kubernetes Service(AKS) - 기반 클러스터 관리의 control plane이나 관리에 대해 걱정할 필요가 없는 관리형 Kubernetes 솔루션을 제공합니다. 나중에 Kubernetes에 대해 자세히 알아보세요. + +Azure Container Instances - 초당 과금 방식의 서비스형 컨테이너. 컨테이너 오케스트레이션이 필요 없이 이미지를 실행하고 가상 네트워크와 통합할 수 있습니다. + +Service Fabric - 많은 기능을 제공하지만, 컨테이너 인스턴스에 대한 오케스트레이션이 포함되어 있습니다. + +Azure에는 Docker 이미지, Helm 차트, OCI 아티팩트 및 이미지에 대한 비공개 레지스트리를 제공하는 컨테이너 레지스트리도 있습니다. 이에 대해서는 컨테이너 섹션에서 다시 자세히 설명하겠습니다. + +또한 많은 컨테이너 서비스가 실제로 컨테이너를 내부적으로 활용할 수도 있지만 이는 관리 요구 사항에서 추상화되어 있다는 점도 언급해야 합니다. + +앞서 언급한 컨테이너 중심 서비스는 다른 모든 퍼블릭 클라우드에서도 비슷한 서비스를 찾을 수 있습니다. + +### 애플리케이션 서비스 + +- Azure Application Services는 서비스를 쉽게 설정할 수 있는 애플리케이션 호스팅 솔루션을 제공합니다. +- 자동 배포 및 확장. +- Windows 및 Linux 기반 솔루션을 지원합니다. +- 서비스는 유형과 크기가 지정된 앱 서비스 플랜에서 실행됩니다. +- 웹 앱, API 앱, 모바일 앱 등 다양한 서비스를 지원합니다. +- 안정적인 테스트 및 홍보를 위한 배포 슬롯 지원. + +### 서버리스 컴퓨팅 + +저에게 서버리스는 더 배우고 싶은 흥미진진한 다음 단계입니다. + +서버리스의 목표는 함수의 런타임에 대해서만 비용을 지불하고 가상 머신이나 PaaS 애플리케이션을 항상 실행할 필요가 없다는 것입니다. 필요할 때 함수를 실행하기만 하면 사라집니다. + +Azure Functions - 서버리스 코드를 제공합니다. 퍼블릭 클라우드에 대해 처음 살펴본 것을 기억한다면 관리의 추상화 계층을 기억할 수 있는데, 서버리스 함수를 사용하면 코드만 관리하게 됩니다. + +대규모의 이벤트 기반은 나중에 실습을 하게 되면 무언가를 구축할 계획이 있습니다. + +많은 Azure 및 타사 서비스에 대한 입력 및 출력 바인딩을 제공합니다. + +다양한 프로그래밍 언어를 지원합니다. (C#, NodeJS, Python, PHP, batch, bash, Golang 및 Rust. 또는 모든 실행 파일) + +Azure Event Grid를 사용하면 서비스 및 이벤트에서 로직을 트리거할 수 있습니다. + +Azure Logic App은 그래픽 기반 workflow 및 통합을 제공합니다. + +또한 일관된 관리 및 예약을 통해 Windows 및 Linux 노드 모두에서 대규모 작업을 실행할 수 있는 Azure Batch도 살펴볼 수 있습니다. + +## 자료 + +- [Hybrid Cloud and MultiCloud](https://www.youtube.com/watch?v=qkj5W98Xdvw) +- [Microsoft Azure Fundamentals](https://www.youtube.com/watch?v=NKEFWyqJ5XA&list=WL&index=130&t=12s) +- [Google Cloud Digital Leader Certification Course](https://www.youtube.com/watch?v=UGRDM86MBIQ&list=WL&index=131&t=10s) +- [AWS Basics for Beginners - Full Course](https://www.youtube.com/watch?v=ulprqHHWlng&t=5352s) + +[Day 32](day32.md)에서 봐요! diff --git a/2022/ko/Days/day32.md b/2022/ko/Days/day32.md new file mode 100644 index 0000000..8d3f91d --- /dev/null +++ b/2022/ko/Days/day32.md @@ -0,0 +1,191 @@ +--- +title: '#90DaysOfDevOps - Microsoft Azure Storage Models - Day 32' +published: false +description: 90DaysOfDevOps - Microsoft Azure Storage Models +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048775 +--- + +## Microsoft Azure 스토리지 모델 + +### 스토리지 서비스 + +- Azure 스토리지 서비스는 스토리지 계정으로 제공됩니다. +- 스토리지 계정은 주로 REST API를 통해 액세스합니다. +- 스토리지 계정은 DNS 이름(`.core.windows.net`)의 일부인 고유한 이름을 가져야 합니다. +- 다양한 복제 및 암호화 옵션. +- 리소스 그룹 내에 위치 + +Azure Portal 상단의 검색 창에서 저장소 그룹을 검색하여 저장소 그룹을 만들 수 있습니다. + +![](/2022/Days/Images/Day32_Cloud1.png) + +그런 다음 이 이름은 고유해야 하며 공백 없이 모두 소문자이어야 하지만 숫자를 포함할 수 있다는 점을 기억하고 스토리지 계정을 만들기 위한 단계를 실행할 수 있습니다. + +![](/2022/Days/Images/Day32_Cloud2.png) + +또한 스토리지 계정과 여기에 저장하는 모든 항목에 대해 원하는 중복성 수준을 선택할 수 있습니다. 목록에서 아래로 내려갈수록 옵션은 더 비싸지만, 데이터는 더 많이 분산됩니다. + +기본 중복 옵션조차도 데이터의 사본 3개를 제공합니다. + +[Azure 스토리지 이중화](https://docs.microsoft.com/en-us/azure/storage/common/storage-redundancy) + +위 링크의 요약은 아래와 같습니다: + +- **Locally-redundant storage** - 기본 지역의 단일 데이터 센터 내에서 데이터를 세 번 복제합니다. +- **Geo-redundant storage** - LRS를 사용하여 기본 지역의 단일 물리적 위치 내에서 데이터를 세 번 동기식으로 복사합니다. +- **Zone-redundant storage** - 기본 지역의 Azure 가용성 영역 3개에 걸쳐 Azure 스토리지 데이터를 동기식으로 복제합니다. +- **Geo-zone-redundant storage** - 가용성 영역 간 중복으로 제공되는 고가용성과 지리적 복제를 통해 제공되는 지역 중단으로부터의 보호를 결합합니다. GZRS 스토리지 계정의 데이터는 기본 지역의 Azure 가용 영역 3개에 복사되며, 지역 재해로부터 보호하기 위해 두 번째 지리적 영역에도 복제됩니다. + +![](/2022/Days/Images/Day32_Cloud3.png) + +다시 성능 옵션으로 이동합니다. 스탠다드와 프리미엄 중에서 선택할 수 있습니다. 여기서는 스탠다드를 선택했지만, 프리미엄은 몇 가지 구체적인 옵션을 제공합니다. + +![](/2022/Days/Images/Day32_Cloud4.png) + +드롭다운에서 다음 세 가지 옵션 중에서 선택할 수 있습니다. + +![](/2022/Days/Images/Day32_Cloud5.png) + +스토리지 계정에 사용할 수 있는 고급 옵션은 훨씬 더 많지만, 지금은 이러한 영역에 대해 자세히 설명할 필요가 없습니다. 이러한 옵션은 암호화와 데이터 보호에 관한 것입니다. + +### 관리 디스크 + +몇 가지 방법으로 스토리지에 액세스할 수 있습니다. + +인증된 액세스를 통한 액세스: + +- 전체 제어를 위한 공유키. +- 위임된 세분화된 액세스를 위한 공유 액세스 서명. +- Azure Active Directory(사용 가능한 경우) + +공용 액세스: + +- 공용 액세스를 부여하여 HTTP를 통한 익명 액세스를 활성화할 수도 있습니다. +- 예를 들어 기본 콘텐츠와 파일을 블록 블롭에 호스팅하여 브라우저가 이 데이터를 보고 다운로드할 수 있도록 할 수 있습니다. + +다른 Azure 서비스에서 스토리지에 액세스하는 경우 트래픽은 Azure 내에 유지됩니다. + +스토리지 성능에는 두 가지 유형이 있습니다: + +- **Standard** - 최대 IOPS 수 +- **Premium** - 보장된 IOPS 수 + +IOPS => 초당 입/출력 작업 수. + +작업에 적합한 스토리지를 선택할 때 고려해야 할 비관리형 디스크와 관리형 디스크의 차이점도 있습니다. + +### 가상 머신 스토리지 + +- 가상 머신 OS 디스크는 일반적으로 persistent 스토리지에 저장됩니다. +- 일부 상태 비저장 워크로드에는 persistent 스토리지가 필요하지 않으며 레이턴시 감소가 더 큰 이점이 됩니다. +- 노드-로컬 스토리지에 생성되는 임시 OS 관리 디스크를 지원하는 VM이 있습니다. + - 이러한 디스크는 VM 스케일 세트와 함께 사용할 수도 있습니다. + +관리 디스크는 Azure Virtual 머신과 함께 사용할 수 있는 내구성 있는 블록 스토리지입니다. Ultra Disk Storage, Premium SSD, Standard SSD 또은 Standard HDD를 사용할 수 있습니다. 또한 몇 가지 특징이 있습니다. + +- 스냅샷 및 이미지 지원 +- SKU 간 간단한 이동 +- 가용성 세트와 결합하여 가용성 향상 +- 사용한 스토리지가 아닌 디스크 크기를 기준으로 요금이 청구됩니다. + +## 아카이브 스토리지 + +- **Cool Tier** - 블롭을 차단하고 추가할 수 있는 쿨 티어 스토리지를 사용할 수 있습니다. + - 스토리지 비용 절감 + - 트랜잭션 비용이 더 높습니다. +- **Archive Tier** - 블록 블롭에 아카이브 스토리지를 사용할 수 있습니다. + - 이것은 블롭 단위로 구성됩니다. + - 더 저렴한 비용, 더 긴 데이터 검색 대기 시간. + - 일반 Azure 스토리지와 동일한 데이터 내구성. + - 필요에 따라 사용자 지정 데이터 계층화를 사용하도록 설정할 수 있습니다. + +### 파일 공유 + +위에서 스토리지 계정을 만들었으므로 이제 파일 공유를 만들 수 있습니다. + +![](/2022/Days/Images/Day32_Cloud6.png) + +이렇게 하면 Azure에서 SMB2.1 및 3.0 파일 공유가 제공됩니다. + +Azure 내부에서 사용할 수 있으며 인터넷에 연결된 SMB3 및 포트 445를 통해 외부에서도 사용할 수 있습니다. + +Azure에서 공유 파일 스토리지를 제공합니다. + +REST API 외에 표준 SMB 클라이언트를 사용하여 매핑할 수 있습니다. + +[Azure NetApp Files](https://vzilla.co.uk/vzilla-blog/azure-netapp-files-how)(SMB 및 NFS)도 참조하세요. + +### 캐싱 및 미디어 서비스 + +Azure 콘텐츠 전송 네트워크는 전 세계에 위치한 정적 웹 콘텐츠의 캐시를 제공합니다. + +Azure 미디어 서비스는 재생 서비스 외에 미디어 트랜스코딩 기술을 제공합니다. + +## Microsoft Azure 데이터베이스 모델 + +지난 [Day 28](day28.md)에서 다양한 서비스 옵션에 대해 다뤘습니다. 그중 하나는 많은 양의 인프라와 운영 체제를 추상화하고 애플리케이션 또는 이 경우 데이터베이스 모델만 제어할 수 있는 PaaS(서비스형 플랫폼)였습니다. + +### 관계형 데이터베이스 + +Azure SQL 데이터베이스는 Microsoft SQL Server를 기반으로 하는 서비스로서의 관계형 데이터베이스를 제공합니다. + +이는 특정 기능 버전이 필요한 경우 데이터베이스 호환성 수준을 사용할 수 있는 최신 SQL 브랜치를 실행하는 SQL입니다. + +이를 구성하는 방법에는 몇 가지 옵션이 있는데, 인스턴스에서 하나의 데이터베이스를 제공하는 단일 데이터베이스를 제공할 수 있으며, 탄력적 풀을 사용하면 용량 풀을 공유하고 집합적으로 확장하는 여러 데이터베이스를 사용할 수 있습니다. + +이러한 데이터베이스 인스턴스는 일반 SQL 인스턴스처럼 액세스할 수 있습니다. + +MySQL, PostgreSQL 및 MariaDB를 위한 추가 관리형 제품. + +![](/2022/Days/Images/Day32_Cloud7.png) + +### NoSQL 솔루션 + +Azure Cosmos DB는 스키마에 구애받지 않는 NoSQL 구현입니다. + +99.99% SLA + +자동 유도를 통해 전 세계 어디서나 99번째 백분위수에서 한 자릿수 지연 시간을 제공하는 전 세계에 분산된 데이터베이스입니다. + +데이터의 partitioning/sharding/distribution에 파티션 키를 활용합니다. + +다양한 데이터 모델 지원(documents, key-value, graph, column-friendly) + +다양한 API 지원(DocumentDB SQL, MongoDB, Azure Table Storage, Gremlin) + +![](/2022/Days/Images/Day32_Cloud9.png) + +[CAP 정리](https://en.wikipedia.org/wiki/CAP_theorem)를 기반으로 다양한 정합성 모델을 제공합니다. + +![](/2022/Days/Images/Day32_Cloud8.png) + +### 캐싱 + +Redis와 같은 캐싱 시스템에 대한 자세한 설명은 생략하고 Microsoft Azure에는 Azure Cache for Redis라는 서비스가 있다는 점을 말씀드리고 싶었습니다. + +Azure Cache for Redis는 Redis 소프트웨어를 기반으로 하는 인메모리 데이터 저장소를 제공합니다. + +- 이 서비스는 오픈 소스 Redis Cache를 구현한 것입니다. + - 호스팅된 보안 Redis 캐시 인스턴스입니다. + - 다양한 티어를 사용할 수 있습니다. + - 캐시를 활용하려면 애플리케이션을 업데이트해야 합니다. + - 쓰기에 비해 읽기 요구 사항이 높은 애플리케이션을 대상으로 합니다. + - 키-값 저장소 기반. + +![](/2022/Days/Images/Day32_Cloud10.png) + +지난 며칠 동안 Microsoft Azure에 대해 많은 메모를 하고 이론을 공부했지만, 이러한 구성 요소가 어떻게 결합되고 작동하는지에 대한 실무적인 측면으로 들어가기 전에 기본 구성 요소를 다루고 싶었습니다. + +시나리오 기반 서비스 배포를 시작하고 실행하기 전에 네트워킹과 관련된 이론이 한 가지 더 남아 있습니다. 또한 지금까지 사용하던 포털을 사용할 때와 Microsoft Azure와 상호 작용할 수 있는 몇 가지 다른 방법도 살펴보고자 합니다. + +## 자료 + +- [Hybrid Cloud and MultiCloud](https://www.youtube.com/watch?v=qkj5W98Xdvw) +- [Microsoft Azure Fundamentals](https://www.youtube.com/watch?v=NKEFWyqJ5XA&list=WL&index=130&t=12s) +- [Google Cloud Digital Leader Certification Course](https://www.youtube.com/watch?v=UGRDM86MBIQ&list=WL&index=131&t=10s) +- [AWS Basics for Beginners - Full Course](https://www.youtube.com/watch?v=ulprqHHWlng&t=5352s) + +[Day 33](day33.md)에서 봐요! diff --git a/2022/ko/Days/day33.md b/2022/ko/Days/day33.md new file mode 100644 index 0000000..6be0712 --- /dev/null +++ b/2022/ko/Days/day33.md @@ -0,0 +1,190 @@ +--- +title: '#90DaysOfDevOps - Microsoft Azure Networking Models + Azure Management - Day 33' +published: false +description: 90DaysOfDevOps - Microsoft Azure Networking Models + Azure Management +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048706 +--- + +## Microsoft Azure 네트워킹 모델 + Azure 관리 + +오늘이 Microsoft Azure의 12번째 생일을 기념하는 날인 것 같습니다! (2022년 2월 1일) 아무튼, 이번 포스팅에서는 Microsoft Azure 내의 네트워킹 모델과 Azure 관리 옵션에 대해 알아보려고 합니다. 지금까지는 Azure 포털만 사용했지만, 플랫폼 내에서 리소스를 구동하고 생성하는 데 사용할 수 있는 다른 영역에 대해서도 언급했습니다. + +## Azure 네트워크 모델 + +### 가상 네트워크 + +- 가상 네트워크는 Azure에서 생성된 구조입니다. +- 가상 네트워크에는 하나 이상의 IP 범위가 할당됩니다. +- 가상 네트워크는 지역 내 구독 내에 존재합니다. +- 가상 서브넷은 네트워크 범위를 분할하기 위해 가상 네트워크에 생성됩니다. +- 가상 머신은 가상 서브넷에 배치됩니다. +- 가상 네트워크 내의 모든 가상 머신은 통신할 수 있습니다. +- 가상 네트워크당 65,536개의 프라이빗 IP. +- 리전으로부터의 송신 트래픽에 대해서만 비용을 지불합니다. (리전을 벗어나는 데이터) +- IPv4 및 IPv6 지원. + - 퍼블릭 대면 및 가상 네트워크 내 IPv6. + +Azure 가상 네트워크는 AWS VPC에 비유할 수 있습니다. 하지만 몇 가지 주의해야 할 차이점이 있습니다: + +- AWS에서는 기본 VNet이 생성되지만 Microsoft Azure에서는 그렇지 않으므로 요구 사항에 맞게 첫 번째 가상 네트워크를 생성해야 합니다. +- Azure의 모든 가상 머신은 기본적으로 인터넷에 대한 NAT 액세스 권한을 갖습니다. AWS에 따른 NAT 게이트웨이가 없습니다. +- Microsoft Azure에는 사설 또는 공용 서브넷의 개념이 없습니다. +- 공용 IP는 vNIC 또는 로드 밸런서에 할당할 수 있는 리소스입니다. +- 가상 네트워크와 서브넷에는 서브넷 수준 위임을 가능하게 하는 자체 ACL이 있습니다. +- AWS에서는 가용 영역별로 서브넷이 있는 반면, 가상 네트워크에서는 가용 영역 전체에 걸쳐 서브넷이 있습니다. + +또한 가상 네트워크 피어링도 있습니다. 이를 통해 테넌트 및 리전 전반의 가상 네트워크를 Azure 백본을 사용하여 연결할 수 있습니다. 전이되지는 않지만, 허브 가상 네트워크의 Azure 방화벽을 통해 활성화할 수 있습니다. 게이트웨이 트랜짓을 사용하면 피어링된 가상 네트워크가 연결된 네트워크에 연결할 수 있으며, 그 예로 ExpressRoute to On-Premises를 들 수 있습니다. + +### 액세스 제어 + +- Azure는 네트워크 보안 그룹을 활용하며, 이는 stateful합니다. +- 규칙을 만든 다음 네트워크 보안 그룹에 할당할 수 있습니다. +- 네트워크 보안 그룹은 서브넷 또는 VM에 적용됩니다. +- 서브넷에 적용되는 경우에도 가상 머신 NIC에서는 여전히 "Edge" 디바이스가 아닌 것으로 적용됩니다. + +![](/2022/Days/Images/Day33_Cloud1.png) + +- 규칙은 네트워크 보안 그룹에 결합됩니다. +- 우선순위에 따라 유연한 구성이 가능합니다. +- 우선순위 숫자가 낮을수록 우선순위가 높습니다. +- 대부분의 로직은 IP 주소로 구축되지만, 일부 태그와 레이블도 사용할 수 있습니다. + +| Description | Priority | Source Address | Source Port | Destination Address | Destination Port | Action | +| ---------------- | -------- | ------------------ | ----------- | ------------------- | ---------------- | ------ | +| Inbound 443 | 1005 | \* | \* | \* | 443 | Allow | +| ILB | 1010 | Azure LoadBalancer | \* | \* | 10000 | Allow | +| Deny All Inbound | 4000 | \* | \* | \* | \* | DENY | + +또한 애플리케이션 보안 그룹(ASG)도 있습니다. + +- NSG가 성장하는 환경에서 유지 관리가 어려울 수 있는 IP 주소 범위에 초점을 맞추는 경우. +- ASG를 사용하면 다양한 애플리케이션 역할(웹서버, DB 서버, WebApp1 등)에 대한 실제 이름(Monikers)을 정의할 수 있습니다. +- 가상 머신 NIC는 하나 이상의 ASG의 멤버가 됩니다. + +그런 다음 ASG는 네트워크 보안 그룹의 일부인 규칙에서 통신 흐름을 제어하는 데 사용할 수 있으며 서비스 태그와 같은 NSG 기능을 계속 사용할 수 있습니다. + +| Action | Name | Source | Destination | Port | +| ------ | ------------------ | ---------- | ----------- | ------------ | +| Allow | AllowInternettoWeb | Internet | WebServers | 443(HTTPS) | +| Allow | AllowWebToApp | WebServers | AppServers | 443(HTTPS) | +| Allow | AllowAppToDB | AppServers | DbServers | 1443 (MSSQL) | +| Deny | DenyAllinbound | Any | Any | Any | + +### 로드 밸런싱 + +Microsoft Azure에는 두 가지 로드 밸런싱 솔루션이 있습니다. (퍼스트 파티, Azure 마켓플레이스에서 사용할 수 있는 타사도 있습니다.) 두 솔루션 모두 외부 또는 내부 엔드포인트에서 작동할 수 있습니다. + +- Load Balancer (Layer 4)는 해시 기반 배포 및 포트 포워딩을 지원합니다. +- App Gateway (Layer 7)는 SSL offload, 쿠키 기반 세션 선호도, URL 기반 콘텐츠 라우팅과 같은 기능을 지원합니다. + +또한 앱 게이트웨이를 사용하면 선택적으로 웹 애플리케이션 방화벽 구성 요소를 사용할 수 있습니다. + +## Azure 관리 도구 + +대부분의 이론 시간을 Azure 포털을 살펴보는 데 할애했는데, 데브옵스 문화를 따르고 이러한 작업, 특히 프로비저닝과 관련된 많은 작업을 처리할 때 API 또는 커맨드라인 도구를 통해 수행한다고 제안하고 싶습니다. Azure 환경의 프로비저닝을 자동화할 때 이를 알아야 하므로 사용할 수 있는 다른 관리 도구 몇 가지를 언급하고 싶었습니다. + +### Azure 포털 + +Microsoft Azure Portal은 커맨드라인 도구의 대안을 제공하는 웹 기반 콘솔입니다. Azure 포털에서 구독을 관리할 수 있습니다. 간단한 웹 앱부터 복잡한 클라우드 배포까지 모든 것을 빌드, 관리 및 모니터링할 수 있습니다. 포털 내에서 찾을 수 있는 또 다른 것은 이러한 이동 경로이며, 앞서 언급했듯이 JSON은 모든 Azure 리소스의 기반이며, 포털에서 시작하여 기능, 서비스 및 기능을 이해한 다음 나중에 자동화된 workflow에 통합하기 위해 그 아래에 있는 JSON을 이해할 수 있습니다. + +![](/2022/Days/Images/Day33_Cloud2.png) + +Azure Preview Portal도 있으며, 이 포털을 사용하여 새로운 서비스 및 향후 개선 사항을 보고 테스트할 수 있습니다. + +![](/2022/Days/Images/Day33_Cloud3.png) + +### PowerShell + +Azure PowerShell을 살펴보기 전에 PowerShell에 대해 먼저 소개할 필요가 있습니다. PowerShell은 작업 자동화 및 구성 관리 프레임워크, 커맨드라인 셸 및 스크립팅 언어입니다. Linux 섹션에서 셸 스크립팅에 대해 다룬 것과 비슷하다고 감히 말할 수 있습니다. PowerShell은 Windows OS에서 처음 발견되었지만, 이제는 크로스 플랫폼입니다. + +Azure PowerShell은 PowerShell 커맨드라인에서 직접 Azure 리소스를 관리하기 위한 cmdlets의 집합입니다. + +아래에서 PowerShell 명령 `Connect-AzAccount`를 사용하여 구독에 연결할 수 있음을 확인할 수 있습니다. + +![](/2022/Days/Images/Day33_Cloud4.png) + +그런 다음 Azure VM과 관련된 특정 명령을 찾으려면 다음 명령을 실행하면 됩니다. 이 PowerShell 프로그래밍 언어에 대해 더 많이 배우고 이해하는 데 몇 시간을 투자할 수 있습니다. + +![](/2022/Days/Images/Day33_Cloud5.png) + +[여기](https://docs.microsoft.com/en-us/powershell/azure/get-started-azureps?view=azps-7.1.0)에서 PowerShell에서 서비스를 시작하고 프로비저닝하는 방법에 대한 Microsoft의 훌륭한 빠른 시작 가이드를 확인하세요. + +### Visual Studio Code + +많은 분들께서 보셨듯이 제가 자주 사용하는 IDE는 Visual Studio Code입니다. + +Visual Studio Code는 Microsoft에서 Windows, Linux 및 macOS용으로 만든 무료 소스 코드 편집기입니다. + +아래에서 Visual Studio Code에 내장된 많은 통합 및 도구를 사용하여 Microsoft Azure 및 그 안의 서비스와 상호 작용할 수 있음을 확인할 수 있습니다. + +![](/2022/Days/Images/Day33_Cloud6.png) + +### Cloud Shell + +Azure Cloud Shell은 Azure 리소스를 관리하기 위한 대화형, 인증된 브라우저 액세스 가능 셸입니다. 작업 방식에 가장 적합한 셸 환경을 선택할 수 있는 유연성을 제공합니다. + +![](/2022/Days/Images/Day33_Cloud7.png) + +아래에서 볼 수 있듯이 포털 내에서 Cloud Shell을 처음 실행하면 Bash와 PowerShell 중에서 선택할 수 있습니다. + +![](/2022/Days/Images/Day33_Cloud8.png) + +Cloud Shell을 사용하려면 구독에 약간의 저장 공간을 제공해야 합니다. + +Cloud Shell을 사용하도록 선택하면 머신이 스핀업되며, 이러한 머신은 일시적이지만 파일은 디스크 이미지와 마운트된 파일 공유를 통해 두 가지 방식으로 유지됩니다. + +![](/2022/Days/Images/Day33_Cloud9.png) + +- Cloud Shell은 세션별, 사용자별로 제공되는 임시 호스트에서 실행됩니다. +- 대화형 활동이 없으면 20분 후에 Cloud Shell이 시간 초과됨 +- Cloud Shell을 사용하려면 Azure 파일 공유를 마운트해야 함 +- Cloud Shell은 Bash와 PowerShell 모두에 동일한 Azure 파일 공유를 사용합니다. +- Cloud Shell은 사용자 계정당 하나의 머신이 할당됨 +- Cloud Shell은 파일 공유에 보관된 5GB 이미지를 사용하여 $HOME을 유지합니다. +- 권한은 Bash에서 일반 Linux 사용자로 설정됨 + +위 내용은 [Cloud Shell 개요](https://docs.microsoft.com/en-us/azure/cloud-shell/overview)에서 복사한 것입니다. + +### Azure CLI + +마지막으로 Azure CLI에 대해 알아보겠습니다. Azure CLI는 윈도우, 리눅스, 맥OS에서 설치할 수 있습니다. 설치가 완료되면 `az`를 입력한 후 다른 명령어를 입력해 Azure 리소스를 생성, 업데이트, 삭제, 조회할 수 있습니다. + +처음 Azure 학습에 들어갔을 때 Azure PowerShell과 Azure CLI가 있어서 약간 혼란스러웠습니다. + +이에 대한 커뮤니티의 피드백이 있으면 좋겠습니다. 하지만 제가 알기로 Azure PowerShell은 Windows PowerShell 또는 PowerShell Core에 추가된 모듈(다른 OS에서도 사용 가능하지만 전부는 아님)인 반면, Azure CLI는 Azure에 연결하여 해당 명령을 실행하는 크로스 플랫폼 커맨드라인 프로그램이라고 알고 있습니다. + +이 두 옵션 모두 구문은 다르지만, 제가 보기에는 매우 유사한 작업을 수행할 수 있습니다. + +예를 들어 PowerShell에서 가상 머신을 만들려면 `New-AzVM` cmdlet을 사용하는 반면, Azure CLI는 `az VM create`를 사용합니다. + +앞서 시스템에 Azure PowerShell 모듈이 설치되어 있고 Windows 컴퓨터에서 PowerShell을 통해 호출할 수 있는 Azure CLI도 설치되어 있는 것을 보았습니다. + +![](/2022/Days/Images/Day33_Cloud10.png) + +이미 언급했듯이 여기서 중요한 점은 올바른 도구를 선택하는 것입니다. Azure는 자동화를 기반으로 실행됩니다. 포털 내에서 수행하는 모든 작업은 리소스를 읽거나, 만들거나, 수정하거나, 삭제하기 위해 실행되는 코드로 변환됩니다. + +Azure CLI + +- Windows, macOS, Linux에 설치할 수 있는 크로스 플랫폼 커맨드라인 인터페이스 +- Windows PowerShell, Cmd, Bash 및 기타 Unix 셸에서 실행됩니다. + +Azure PowerShell + +- 크로스 플랫폼 PowerShell 모듈, Windows, macOS, Linux에서 실행됨 +- Windows PowerShell 또는 PowerShell 필요 + +사용 중인 환경에서 PowerShell을 사용할 수 없지만 .mdor bash를 사용할 수 있는 경우 Azure CLI를 선택하는 것이 좋습니다. + +다음으로 지금까지 살펴본 모든 이론을 바탕으로 몇 가지 시나리오를 만들어 Azure에서 실습해 보겠습니다. + +## 자료 + +- [Hybrid Cloud and MultiCloud](https://www.youtube.com/watch?v=qkj5W98Xdvw) +- [Microsoft Azure Fundamentals](https://www.youtube.com/watch?v=NKEFWyqJ5XA&list=WL&index=130&t=12s) +- [Google Cloud Digital Leader Certification Course](https://www.youtube.com/watch?v=UGRDM86MBIQ&list=WL&index=131&t=10s) +- [AWS Basics for Beginners - Full Course](https://www.youtube.com/watch?v=ulprqHHWlng&t=5352s) + +[Day 34](day34.md)에서 봐요! diff --git a/2022/ko/Days/day34.md b/2022/ko/Days/day34.md new file mode 100644 index 0000000..6a5fac5 --- /dev/null +++ b/2022/ko/Days/day34.md @@ -0,0 +1,197 @@ +--- +title: '#90DaysOfDevOps - Microsoft Azure Hands-On Scenarios - Day 34' +published: false +description: 90DaysOfDevOps - Microsoft Azure Hands-On Scenarios +tags: 'DevOps, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048763 +--- + +## Microsoft Azure 실습 시나리오 + +지난 6일 동안 Microsoft Azure와 퍼블릭 클라우드 전반에 대해 집중적으로 살펴봤는데요, Azure의 빌딩 블록을 이해하기 위해서는 많은 이론이 필요했지만, 다른 주요 클라우드 제공업체에도 잘 적용될 수 있을 것입니다. + +처음에 퍼블릭 클라우드에 대한 기초 지식을 얻고 최소한 한 공급자를 선택하는 것에 대해 언급했는데, 여러 클라우드를 얕게 다룰 경우 길을 잃기 쉽지만, 한 공급자를 선택한 후 기본 사항을 이해하면 다른 클라우드로 이동하여 학습을 가속화하는 것이 매우 쉽다고 생각됩니다. + +이번 마지막 세션에서는 Microsoft에서 만든 참고 자료로 [AZ-104 Microsoft Azure Administrator](https://microsoftlearning.github.io/AZ-104-MicrosoftAzureAdministrator/) 시험 준비에 사용되는 이 페이지에서 실습 시나리오를 골라보겠습니다. + +여기에는 컨테이너와 쿠버네티스와 같이 아직 자세히 다루지 않은 내용도 있으므로 아직은 여기에 뛰어들지 않겠습니다. + +이전 포스팅에서 Module 1,2,3의 대부분을 만들었습니다. + +### 가상 네트워킹 + +[Module 04](https://microsoftlearning.github.io/AZ-104-MicrosoftAzureAdministrator/Instructions/Labs/LAB_04-Implement_Virtual_Networking.html) 따라 하기: + +위의 내용을 살펴보고 #90DaysOfDevOps의 이름을 몇 가지 변경했습니다. 또한 클라우드 셸을 사용하는 대신 Windows 머신에서 Azure CLI를 사용하여 전날 생성한 새 사용자로 로그인했습니다. + +브라우저를 열고 계정에 인증할 수 있는 `az login`을 사용하여 이 작업을 수행할 수 있습니다. + +그런 다음 아래 작업 중 일부를 빌드하는 데 사용할 PowerShell 스크립트와 Module에서 몇 가지 참조를 만들었습니다. 관련 파일은 이 폴더에서 찾을 수 있습니다. +(/2022/Days/Cloud/01VirtualNetworking) + +스크립트의 파일 위치를 사용자 환경에 맞게 변경해야 합니다. + +첫 번째 단계에서는 환경에 가상 네트워크나 가상 머신이 생성되어 있지 않고 리소스 그룹에 클라우드 셸 스토리지 위치만 구성되어 있습니다. + +먼저 [PowerShell 스크립트](/2022/Days/Cloud/01VirtualNetworking/Module4_90DaysOfDevOps.ps1)를 실행합니다. + +![](/2022/Days/Images/Day34_Cloud1.png) + +- Task 1: 가상 네트워크 생성 및 구성 + +![](/2022/Days/Images/Day34_Cloud2.png) + +- Task 2: 가상 네트워크에 가상 머신 배포 + +![](/2022/Days/Images/Day34_Cloud3.png) + +- Task 3: Azure VM의 프라이빗 및 퍼블릭 IP 주소 구성 + +![](/2022/Days/Images/Day34_Cloud4.png) + +- Task 4: 네트워크 보안 그룹 구성 + +![](/2022/Days/Images/Day34_Cloud5.png) +![](/2022/Days/Images/Day34_Cloud6.png) + +- Task 5: 내부 이름 확인을 위한 Azure DNS 구성 + +![](/2022/Days/Images/Day34_Cloud7.png) +![](/2022/Days/Images/Day34_Cloud8.png) + +### 네트워크 트래픽 관리 + +[Module 06](https://microsoftlearning.github.io/AZ-104-MicrosoftAzureAdministrator/Instructions/Labs/LAB_06-Implement_Network_Traffic_Management.html)에 이어서 + +다음 단계에서는 지난번 리소스 그룹으로 이동하여 리소스를 삭제했는데, 저처럼 사용자 계정을 해당 리소스 그룹에만 접근하도록 설정하지 않았다면 Module 이름을 '90Days\*'로 변경하여 모든 리소스와 리소스 그룹을 삭제할 수 있습니다. 이것이 다음 실습 각각에 대한 제 프로세스입니다. + +이 실습에서는 아래 작업 중 일부를 구축하는 데 사용할 Module의 일부 참조와 PowerShell 스크립트도 만들었습니다. 관련 파일은 이 폴더에서 찾을 수 있습니다. +(/2022/Days/Cloud/02TrafficManagement) + +- Task 1: 실습 환경 프로비저닝 + +먼저 [PowerShell 스크립트](/2022/Days/Cloud/02TrafficManagement/Mod06_90DaysOfDevOps.ps1)를 실행합니다. + +![](/2022/Days/Images/Day34_Cloud9.png) + +- Task 2: 허브 및 스포크 네트워크 Topology 구성 + +![](/2022/Days/Images/Day34_Cloud10.png) + +- Task 3: 가상 네트워크 피어링의 전이성 테스트 + +이 작업의 경우 90DaysOfDevOps 그룹은 권한 때문에 네트워크 감시자에 액세스할 수 없었는데, 이는 네트워크 감시자가 리소스 그룹에 묶여 있지 않은 리소스 중 하나이기 때문인 것으로 예상됩니다(이 사용자에 대해 RBAC이 적용된 곳). 미국 동부 네트워크 감시자 기여자 역할을 90DaysOfDevOps 그룹에 추가했습니다. + +![](/2022/Days/Images/Day34_Cloud11.png) +![](/2022/Days/Images/Day34_Cloud12.png) +![](/2022/Days/Images/Day34_Cloud13.png) + +두 개의 스포크 가상 네트워크가 서로 피어링되지 않기 때문에 예상되는 현상입니다(가상 네트워크 피어링은 전이적이지 않음). + +- Task 4: 허브 및 스포크 Topology에서 라우팅 구성하기 + +여기서 제 계정이 90DaysOfDevOps 그룹 내에서 제 사용자로 스크립트를 실행할 수 없는 또 다른 문제가 있었는데, 잘 모르겠으므로 다시 기본 관리자 계정으로 이동했습니다. 90DaysOfDevOps 그룹은 90DaysOfDevOps 리소스 그룹의 모든 소유자이므로 VM 내에서 명령을 실행할 수 없는 이유를 알고 싶습니다. + +![](/2022/Days/Images/Day34_Cloud14.png) +![](/2022/Days/Images/Day34_Cloud15.png) + +그런 다음 michael.cade@90DaysOfDevOps.com 계정으로 돌아가서 이 섹션을 계속할 수 있었습니다. 여기서 동일한 테스트를 다시 실행하고 있지만 이제 결과에 도달할 수 있습니다. + +![](/2022/Days/Images/Day34_Cloud16.png) + +- Task 5: Azure 로드밸런싱 장치 구현하기 + +![](/2022/Days/Images/Day34_Cloud17.png) +![](/2022/Days/Images/Day34_Cloud18.png) + +- Task 6: Azure 애플리케이션 게이트웨이 구현 + +![](/2022/Days/Images/Day34_Cloud19.png) +![](/2022/Days/Images/Day34_Cloud20.png) + +### Azure 스토리지 + +[Module 07](https://microsoftlearning.github.io/AZ-104-MicrosoftAzureAdministrator/Instructions/Labs/LAB_07-Manage_Azure_Storage.html)에 이어서 진행합니다: + +이 실습에서는 아래 작업 중 일부를 빌드하는 데 사용할 PowerShell 스크립트와 Module의 일부 참조도 만들었습니다. 관련 파일은 이 폴더에서 찾을 수 있습니다. +(/2022/Days/Cloud/03Storage) + +- Task 1: 실습 환경 프로비저닝 + +먼저 [PowerShell 스크립트](/2022/Days/Cloud/03Storage/Mod07_90DaysOfDeveOps.ps1)를 실행합니다. + +![](/2022/Days/Images/Day34_Cloud21.png) + +- Task 2: Azure Storage 계정 만들기 및 구성 + +![](/2022/Days/Images/Day34_Cloud22.png) + +- Task 3: 블롭 스토리지 관리 + +![](/2022/Days/Images/Day34_Cloud23.png) + +- Task 4: Azure 스토리지에 대한 인증 및 권한 부여 관리 + +![](/2022/Days/Images/Day34_Cloud24.png) +![](/2022/Days/Images/Day34_Cloud25.png) + +이 기능이 허용되기를 기다리는 동안 조금 조바심이 났지만 결국 작동했습니다. + +![](/2022/Days/Images/Day34_Cloud26.png) + +- Task 5: Azure 파일 공유 만들기 및 구성하기 + +실행 명령에서 michael.cade@90DaysOfDevOps.com 에서는 작동하지 않아서 승격된 계정을 사용했습니다. + +![](/2022/Days/Images/Day34_Cloud27.png) +![](/2022/Days/Images/Day34_Cloud28.png) +![](/2022/Days/Images/Day34_Cloud29.png) + +- Task 6: Azure 스토리지에 대한 네트워크 액세스 관리 + +![](/2022/Days/Images/Day34_Cloud30.png) + +### 서버리스(웹 앱 구현) + +[Module 09a](https://microsoftlearning.github.io/AZ-104-MicrosoftAzureAdministrator/Instructions/Labs/LAB_09a-Implement_Web_Apps.html)를 따릅니다: + +- Task 1: Azure 웹 앱 만들기 + +![](/2022/Days/Images/Day34_Cloud31.png) + +- Task 2: 스테이징 배포 슬롯 만들기 + +![](/2022/Days/Images/Day34_Cloud34.png) + +- Task 3: 웹 앱 배포 설정 구성 + +![](/2022/Days/Images/Day34_Cloud33.png) + +- Task 4: 스테이징 배포 슬롯에 코드 배포 + +![](/2022/Days/Images/Day34_Cloud32.png) + +- Task 5: 스테이징 슬롯 교체 + +![](/2022/Days/Images/Day34_Cloud35.png) + +- Task 6: Azure 웹 앱의 자동 확장 구성 및 테스트 + +제가 사용하는 이 스크립트는 (/2022/Days/Cloud/04Serverless)에서 찾을 수 있습니다. + +![](/2022/Days/Images/Day34_Cloud36.png) + +이것으로 Microsoft Azure와 퍼블릭 클라우드 전반에 대한 섹션을 마무리합니다. 이 시나리오를 작업하는 것이 매우 즐거웠다고 말씀드리고 싶습니다. + +## 자료 + +- [Hybrid Cloud and MultiCloud](https://www.youtube.com/watch?v=qkj5W98Xdvw) +- [Microsoft Azure Fundamentals](https://www.youtube.com/watch?v=NKEFWyqJ5XA&list=WL&index=130&t=12s) +- [Google Cloud Digital Leader Certification Course](https://www.youtube.com/watch?v=UGRDM86MBIQ&list=WL&index=131&t=10s) +- [AWS Basics for Beginners - Full Course](https://www.youtube.com/watch?v=ulprqHHWlng&t=5352s) + +다음으로 버전 관리 시스템, 특히 git과 코드 저장소 개요에 대해 살펴볼 것이며, 제가 선호하는 옵션인 GitHub를 선택하겠습니다. + +[Day 35](day35.md)에서 봐요! diff --git a/2022/ko/Days/day35.md b/2022/ko/Days/day35.md new file mode 100644 index 0000000..e06fd8c --- /dev/null +++ b/2022/ko/Days/day35.md @@ -0,0 +1,140 @@ +--- +title: '#90DaysOfDevOps - The Big Picture: Git - Version Control - Day 35' +published: false +description: 90DaysOfDevOps - The Big Picture Git - Version Control +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049041 +--- + +## 큰 그림: Git - 버전 관리 + +Git을 시작하기 전에 버전 관리가 무엇이며 왜 필요한지 이해해야 하나요? 이번 Git 시작 단계에서는 버전 관리가 무엇인지, 그리고 Git의 기본 사항에 대해 살펴보겠습니다. + +### 버전 제어란 무엇인가요? + +Git이 유일한 버전 관리 시스템은 아니므로 여기서는 버전 관리와 관련하여 어떤 옵션과 방법론을 사용할 수 있는지 살펴보고자 합니다. + +버전 관리의 가장 분명하고 큰 장점은 프로젝트의 이력을 추적할 수 있다는 것입니다. 우리는 `git log`를 사용하여 이 리포지토리를 되돌아보고 많은 커밋과 많은 코멘트가 있으며 프로젝트에서 지금까지 무슨 일이 일어났는지 확인할 수 있습니다. 명령어에 대해서는 나중에 설명할 테니 걱정하지 마세요. 이제 이것이 소스 코드로 가득 찬 실제 소프트웨어 프로젝트이고 여러 사람이 서로 다른 시간에 소프트웨어에 커밋하고, 다른 작성자와 검토자가 모두 여기에 기록되어 무슨 일이 언제, 누가, 누가 검토했는지 알 수 있다고 생각해보세요. + +![](/2022/Days/Images/Day35_Git1.png) + +과거 버전 제어는 변경을 하기 전에 수동으로 버전 복사본을 만드는 것과 같은 방식이었을 것입니다. 또한 혹시 모른다는 생각으로 쓸모없는 오래된 코드를 주석 처리했을 수도 있습니다. + +![](/2022/Days/Images/Day35_Git2.png) + +저는 소스 코드뿐만 아니라 거의 모든 프로젝트에 버전 관리를 사용하기 시작했고, 이와 같은 프로젝트에 대해 이야기합니다(90DaysOfDevOps). 진행된 모든 것을 롤백하고 기록하는 기능을 받아들이는 것은 어떨까요? + +그러나 **버전 제어는 백업이 아닙니다!** + +버전 관리의 또 다른 이점은 프로젝트의 여러 버전을 관리할 수 있다는 점입니다. 예를 들어 모든 운영 체제에서 사용할 수 있는 무료 앱이 있고 모든 운영 체제에서 사용할 수 있는 유료 앱이 있다고 가정해 봅시다. 대부분의 코드는 두 애플리케이션 간에 공유됩니다. 각 앱에 코드를 복사하여 붙여 넣을 수도 있지만, 개발 인원이 한 명 이상으로 늘어나면 매우 지저분해지고 실수도 발생할 수 있습니다. + +프리미엄 앱에는 추가 기능을 프리미엄 커밋이라고 부르고 무료 버전에는 일반 커밋만 포함할 수 있습니다. + +버전 관리에서 이를 달성하는 방법은 branch를 사용하는 것입니다. + +![](/2022/Days/Images/Day35_Git3.png) + +branch를 사용하면 위에서 설명한 것처럼 동일한 앱에 대해 두 개의 코드 스트림을 사용할 수 있습니다. 하지만 소스 코드가 없는 버전에 포함된 새로운 기능이 프리미엄 버전에 포함되기를 원하며, 이를 위해 Merge라는 기능을 사용합니다. + +![](/2022/Days/Images/Day35_Git4.png) + +무료 버전에서 작업하는 팀과 프리미엄 유료 버전에서 작업하는 팀이 있을 수 있고, 둘 다 전체 코드의 일부에 영향을 주는 코드를 변경하면 어떻게 될지 모르기 때문에 merge는 복잡할 수 있습니다. 변수가 업데이트되어 무언가를 망가뜨릴 수도 있습니다. 그러면 기능 중 하나가 중단되는 충돌이 발생합니다. 버전 관리로는 이러한 충돌을 해결할 수 없습니다. 하지만 버전 제어를 사용하면 이를 쉽게 관리할 수 있습니다. + +지금까지 버전 관리를 선택하지 않았다면 일반적으로 가장 큰 이유는 공동 작업 기능입니다. 개발자 간에 코드를 공유할 수 있는 기능, 그리고 앞서 말씀드린 대로 코드라고 하면 동료와 함께 작업하는 공동 프레젠테이션이나 프로젝트 전반에 걸쳐 커뮤니티가 수정 및 업데이트를 제공하는 90DaysOfDevOps 챌린지 등 다른 이유로 소스 제어를 사용하는 사례가 점점 더 많아지고 있습니다. + +버전 관리가 없다면 소프트웨어 개발자 팀은 어떻게 이런 일을 처리할 수 있을까요? 저는 프로젝트를 진행하면서 상황을 추적하는 것만으로도 충분히 힘들다는 것을 느낍니다. 저는 그들이 코드를 각 기능 모듈로 분리할 것이라고 예상합니다. 아마도 퍼즐 조각을 한데 모은 다음 릴리스하기 전에 문제와 이슈를 파악했을 것입니다. + +버전 관리를 통해 우리는 단일 소스를 확보할 수 있습니다. 여전히 서로 다른 모듈에서 작업할 수 있지만 협업이 더 잘 이루어질 수 있습니다. + +![](/2022/Days/Images/Day35_Git5.png) + +여기서 한 가지 더 언급할 것은 버전 관리의 이점을 누릴 수 있는 것은 개발자뿐만 아니라 모든 팀원이 가시성을 확보할 수 있을 뿐만 아니라 프로젝트 관리 도구도 여기에 연결하여 작업을 추적할 수 있다는 것입니다. 다른 모듈에서 다룰 Jenkins와 같은 빌드 머신도 있을 수 있습니다. 시스템을 빌드하고 패키징하여 배포 테스트와 메트릭을 자동화하는 도구입니다. + +### Git이란 무엇인가요? + +Git은 소스 코드 또는 모든 파일의 변경 사항을 추적하는 도구이며, 오픈소스 분산 버전 관리 시스템이라고도 할 수 있습니다. + +시스템에서 Git을 사용할 수 있는 방법은 여러 가지가 있는데, 가장 일반적으로는 커맨드라인에서 사용하는 것이 가장 일반적이지만, GUI와 Visual Studio Code와 같은 도구에서도 Git을 인식하는 작업을 활용할 수 있습니다. + +이제 로컬 머신에 Git을 설치하기 전에 개략적인 개요를 살펴보겠습니다. + +앞서 만든 폴더를 살펴보겠습니다. + +![](/2022/Days/Images/Day35_Git2.png) + +이 폴더를 버전 제어에 사용하려면 먼저 `git init` 명령을 사용하여 이 디렉토리를 초기화해야 합니다. 지금은 이 명령이 디렉토리를 컴퓨터 어딘가에 있는 데이터베이스의 리포지토리로 저장한다고 생각하면 됩니다. + +![](/2022/Days/Images/Day35_Git6.png) + +이제 몇 가지 파일과 폴더를 만들 수 있으며 소스 코드가 시작될 수도 있고 이미 여기에 무언가가 있을 수도 있습니다. 우리는 `git add .` 명령을 사용하여 디렉토리의 모든 파일과 폴더를 스냅샷에 넣을 수 있지만 아직 해당 데이터베이스에 아무것도 커밋하지 않았습니다. 우리는 단지 `.`가 있는 모든 파일을 추가할 준비가 되었다고 말하는 것입니다. + +![](/2022/Days/Images/Day35_Git7.png) + +이제 파일을 커밋하고 싶으면 `git commit -m "My First Commit"` 명령으로 이 작업을 수행합니다. 커밋에 대한 설명을 할 수 있으며 각 커밋에 대해 무슨 일이 일어났는지 알 수 있도록 도와줍니다. + +![](/2022/Days/Images/Day35_Git8.png) + +이제 프로젝트의 히스토리에서 어떤 일이 일어났는지 확인할 수 있습니다. `git log` 명령어를 사용합니다. + +![](/2022/Days/Images/Day35_Git9.png) + +`samplecode.ps1`라는 파일을 추가로 생성하면 상태가 달라집니다. 또한 `git status`를 사용하여 리포지토리의 상태를 확인할 수 있는데, 커밋할 항목이 없음을 보여주며 samplecode.ps1이라는 새 파일을 추가할 수 있습니다. 그런 다음 동일한 `git status`를 실행하면 커밋할 파일이 있는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day35_Git10.png) + +`git add samplecode.ps1`명령을 사용하여 새 파일을 추가한 다음`git status`를 다시 실행하면 파일이 커밋될 준비가 된 것을 확인할 수 있습니다. + +![](/2022/Days/Images/Day35_Git11.png) + +그런 다음 `git commit -m "My Second Commit"` 명령을 실행합니다. + +![](/2022/Days/Images/Day35_Git12.png) + +`git status`를 한 번 더 입력하면, 모든 것이 다시 깨끗해졌음을 확인할 수 있습니다. + +![](/2022/Days/Images/Day35_Git13.png) + +이제 최신 변경 사항과 첫 번째 커밋을 보여주는 `git log` 명령을 사용할 수 있습니다. + +![](/2022/Days/Images/Day35_Git14.png) + +커밋 사이의 변경 사항, 즉 어떤 파일이 추가되거나 수정되었는지 확인하려면 `git diff b8f8 709a`를 사용하면 됩니다. + +![](/2022/Days/Images/Day35_Git15.png) + +그러면 새 파일을 추가한 경우 변경된 내용이 표시됩니다. + +![](/2022/Days/Images/Day35_Git16.png) + +나중에 더 자세히 설명하겠지만 커밋을 이동하면서 시간 여행을 할 수 있습니다! 커밋 번호를 사용하면 `git checkout 709a` 명령을 사용하여 새 파일을 잃지 않고 시간을 거슬러 올라갈 수 있습니다. + +![](/2022/Days/Images/Day35_Git17.png) + +마찬가지로 커밋 번호와 같은 방법으로 앞으로 이동하고 싶을 수도 있고, 여기서 `git switch -` 명령을 사용하여 작업을 취소할 수도 있습니다. + +![](/2022/Days/Images/Day35_Git18.png) + +TLDR; + +- 프로젝트 히스토리 추적하기 +- 프로젝트의 여러 버전 관리 +- 개발자 및 더 넓은 범위의 팀과 도구 간에 코드 공유 +- 팀워크 조정 +- 아, 그리고 시간 여행! + +너무 많은 내용을 설명한 것 같지만, 어떤 명령어를 사용하는지 몰라도 버전 관리의 큰 그림을 이해할 수 있기를 바랍니다. + +다음에는 로컬 머신에 Git을 설치 및 설정하고 Git을 통해 얻을 수 있는 다른 사용 사례와 명령어에 대해 좀 더 자세히 살펴보겠습니다. + +## 자료 + +- [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) +- [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) +- [Git Tutorial for Beginners](https://www.youtube.com/watch?v=8JJ101D3knE&t=52s) +- [Git for Professionals Tutorial](https://www.youtube.com/watch?v=Uszj_k0DGsg) +- [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) +- [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) + +[Day 36](day36.md)에서 봐요! diff --git a/2022/ko/Days/day36.md b/2022/ko/Days/day36.md new file mode 100644 index 0000000..39ba8fd --- /dev/null +++ b/2022/ko/Days/day36.md @@ -0,0 +1,154 @@ +--- +title: '#90DaysOfDevOps - Installing & Configuring Git - Day 36' +published: false +description: 90DaysOfDevOps - Installing & Configuring Git +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048738 +--- + +## Git 설치 및 구성 + +Git은 버전 관리를 위한 오픈 소스 크로스 플랫폼 도구입니다. 저처럼 우분투 또는 대부분의 Linux 환경을 사용하는 경우 이미 Git이 설치되어 있을 수 있지만 설치 및 구성 과정을 살펴보겠습니다. + +시스템에 이미 git이 설치되어 있더라도 최신 버전인지 확인하는 것도 좋은 방법입니다. + +### Git 설치하기 + +이미 언급했듯이 Git은 크로스 플랫폼이므로 Windows와 Linux를 통해 실행할 것이지만 [여기](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)에서 macOS도 찾을 수 있습니다. + +[Windows](https://git-scm.com/download/win)의 경우 공식 사이트에서 설치할 수 있습니다. + +Windows 컴퓨터에서 `winget`을 사용할 수도 있는데, 이것을 Windows 애플리케이션 패키지 관리자라고 생각하면 됩니다. + +설치하기 전에 Windows 머신에 어떤 버전이 있는지 확인해 보겠습니다. PowerShell 창을 열고 `git --version`을 실행합니다. + +![](/2022/Days/Images/Day36_Git1.png) + +WSL 우분투 버전의 Git도 확인할 수 있습니다. + +![](/2022/Days/Images/Day36_Git2.png) + +이 글을 쓰는 시점에 최신 Windows 릴리스는 `2.35.1`이므로 업데이트해야 할 사항이 몇 가지 있는데 이를 살펴보겠습니다. 리눅스도 마찬가지일 것으로 예상합니다. + +저는 최신 설치 프로그램을 다운로드하고 마법사를 실행했으며 여기에 이를 문서화할 것입니다. 주의해야 할 중요한 점은 최신 버전을 설치하기 전에 git이 이전 버전을 제거한다는 것입니다. + +즉, 아래에 표시된 프로세스도 대부분 git을 사용하지 않고 설치하는 것과 동일한 프로세스입니다. + +매우 간단한 설치입니다. 다운로드가 완료되면 두 번 클릭하고 시작하세요. GNU 라이선스 계약을 읽어보세요. 하지만 이 소프트웨어는 무료 오픈소스 소프트웨어라는 점을 기억하세요. + +![](/2022/Days/Images/Day36_Git3.png) + +이제 추가로 설치할 컴포넌트를 선택해 git과 연결할 수 있습니다. 저는 Windows에서 bash 스크립트를 실행할 수 있는 Git Bash를 항상 설치합니다. + +![](/2022/Days/Images/Day36_Git4.png) + +그런 다음 사용할 SSH 실행 파일을 선택할 수 있습니다. 리눅스 섹션에서 보셨을 번들 OpenSSH를 그대로 두겠습니다. + +![](/2022/Days/Images/Day36_Git5.png) + +그다음에는 실험적인 기능을 활성화할 수 있는데, 저는 필요하지 않으므로 활성화하지 않고 나중에 설치를 통해 돌아와서 언제든지 활성화할 수 있습니다. + +![](/2022/Days/Images/Day36_Git6.png) + +설치가 완료되었으므로 이제 Git Bash 및 최신 릴리스 노트를 열도록 선택할 수 있습니다. + +![](/2022/Days/Images/Day36_Git7.png) + +마지막 확인은 PowerShell 창에서 현재 어떤 버전의 git이 있는지 살펴보는 것입니다. + +![](/2022/Days/Images/Day36_Git8.png) + +매우 간단하며 이제 최신 버전을 사용하고 있습니다. 리눅스 머신에서는 업데이트가 조금 늦은 것 같아서 업데이트 과정을 안내해 드리겠습니다. + +`sudo apt-get install git` 명령을 실행하기만 하면 됩니다. + +![](/2022/Days/Images/Day36_Git9.png) + +다음을 실행하여 소프트웨어 설치를 위한 git 저장소를 추가할 수도 있습니다. + +``` +sudo add-apt-repository ppa:git-core/ppa -y +sudo apt-get update +sudo apt-get install git -y +git --version +``` + +### Git 구성하기 + +처음 git을 사용할 때는 몇 가지 설정을 정의해야 합니다, + +- Name +- Email +- 기본 에디터 +- Line Ending + +이 설정은 세 가지 수준에서 수행할 수 있습니다. + +- System = 모든 사용자 +- Global = 현재 사용자의 모든 리포지토리 +- Local = 현재 리포지토리 + +예제 +`git config --global user.name "Michael Cade"` +`git config --global user.email Michael.Cade@90DaysOfDevOPs.com"` +운영 체제에 따라 기본 텍스트 편집기가 결정됩니다. 다음 명령을 설정하지 않은 제 우분투 머신에서는 Nano를 사용하고 있습니다. 아래 명령은 이를 비주얼 스튜디오 코드로 변경합니다. + +`git config --global core.editor "code --wait"` + +이제 모든 git 구성을 보려면 다음 명령을 사용하면 됩니다. + +`git config --global -e` + +![](/2022/Days/Images/Day36_Git10.png) + +어떤 머신에서든 이 파일의 이름은 `.gitconfig`입니다. 제 Windows 머신에서는 사용자 계정 디렉토리에서 이 파일을 찾을 수 있습니다. + +![](/2022/Days/Images/Day36_Git11.png) + +### Git 이론 + +어제 포스트에서 다른 버전 관리 유형이 있으며 이를 두 가지 유형으로 나눌 수 있다고 언급했습니다. 하나는 "클라이언트-서버"이고 다른 하나는 "분산"입니다. + +### 클라이언트-서버 버전 제어 + +git이 등장하기 전에는 클라이언트-서버가 버전 관리를 위한 사실상 유일한 방법이었다. 그 예로 2000년에 설립된 오픈소스 버전 관리 시스템인 [Apache Subversion](https://subversion.apache.org/)을 들 수 있습니다. + +이 클라이언트-서버 버전 제어 모델에서는 개발자가 서버에서 소스 코드와 실제 파일을 다운로드하는 것이 첫 번째 단계입니다. 이렇게 한다고 해서 충돌이 예방되는 것은 아니지만 충돌의 복잡성과 해결 방법이 예방됩니다. + +![](/2022/Days/Images/Day36_Git12.png) + +예를 들어 두 명의 개발자가 같은 파일을 작업하고 있는데 한 개발자가 새로운 변경 사항을 먼저 커밋하거나 서버에 파일을 다시 업로드한다고 가정해 보겠습니다. 두 번째 개발자가 업데이트를 하려고 할 때 충돌이 발생합니다. + +![](/2022/Days/Images/Day36_Git13.png) + +이때, 첫 번째 개발자의 코드 변경 사항을 가져와서 자신의 작업과 충돌하는 부분을 모두 처리한 다음, 커밋해야 합니다. + +![](/2022/Days/Images/Day36_Git15.png) + +### 분산 버전 제어 + +Git이 유일한 분산 버전 제어 시스템은 아닙니다. 하지만 사실상 거의 유일한 시스템입니다. + +Git의 주요 이점은 다음과 같습니다: + +- 빠름 +- 스마트 +- 유연함 +- 안전 및 보안 + +클라이언트-서버 버전 제어 모델과 달리 각 개발자는 커밋 히스토리, 모든 branch 등을 의미하는 소스 리포지토리를 다운로드합니다. + +![](/2022/Days/Images/Day36_Git16.png) + +## 자료 + +- [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) +- [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) +- [Git Tutorial for Beginners](https://www.youtube.com/watch?v=8JJ101D3knE&t=52s) +- [Git for Professionals Tutorial](https://www.youtube.com/watch?v=Uszj_k0DGsg) +- [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) +- [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) + +[Day 37](day37.md)에서 봐요! diff --git a/2022/ko/Days/day37.md b/2022/ko/Days/day37.md new file mode 100644 index 0000000..c5965f6 --- /dev/null +++ b/2022/ko/Days/day37.md @@ -0,0 +1,170 @@ +--- +title: '#90DaysOfDevOps - Gitting to know Git - Day 37' +published: false +description: 90DaysOfDevOps - Gitting to know Git +tags: 'DevOps, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048707 +--- + +## Gitting to know Git(Git에 대해 알아보기) + +제목과 글 전체에 끔찍한 말장난이 들어가서 죄송합니다. Git을 아재 개그로 바꾼 사람이 제가 처음은 아닐 겁니다! + +지난 두 번의 포스팅에서 버전 관리 시스템과 버전 관리 시스템으로서의 Git의 기본적인 workflow에 대해 배웠고, [Day 35](day35.md)에서는 시스템에 Git을 설치하고 업데이트와 구성을 했습니다. 또한 클라이언트-서버 버전 관리 시스템과 분산 버전 관리 시스템인 Git [Day 36](day36.md) 사이의 이론에 대해 조금 더 자세히 알아보았습니다. + +이제 Git에서 흔히 볼 수 있는 몇 가지 명령어와 사용 사례를 살펴보겠습니다. + +### git은 어디에서 도움을 받을 수 있나요? + +git으로 작업을 완료하는 데 필요한 명령이 기억나지 않거나 모를 때가 있을 것입니다. 도움이 필요할 것입니다. + +Google이나 검색 엔진이 도움을 찾을 때 가장 먼저 찾을 수 있는 곳일 것입니다. + +두 번째는 공식 git 사이트와 문서입니다. [git-scm.com/docs](http://git-scm.com/docs) 여기에서 사용 가능한 모든 명령어에 대한 확실한 정보뿐만 아니라 다양한 리소스를 찾을 수 있습니다. + +![](/2022/Days/Images/Day37_Git1.png) + +터미널에 연결할 수 없는 경우에도 동일한 문서에 액세스할 수 있어 매우 유용합니다. 예를 들어 `git add` 명령어를 선택했다면 `git add --help`를 실행하면 아래에 설명서가 표시됩니다. + +![](/2022/Days/Images/Day37_Git2.png) + +셸에서 `git add -h`를 사용하면 사용 가능한 옵션에 대한 요약을 볼 수 있습니다. + +![](/2022/Days/Images/Day37_Git3.png) + +### Git을 둘러싼 오해 + +"Git에는 액세스 제어 기능이 없다." - 리더에게 소스 코드를 유지 관리할 수 있는 권한을 부여할 수 있습니다. + +"Git은 너무 무겁다." - Git은 대규모 프로젝트의 경우 기록을 줄여주는 얕은(shallow) 저장소를 제공할 수 있습니다. + +### 실제 단점 + +바이너리 파일에는 적합하지 않습니다. 소스 코드에는 적합하지만 실행 파일이나 동영상 등에는 적합하지 않습니다. + +도구의 명령어와 기능에 대해 설명하는 데 시간을 할애해야 한다는 점이 사용자 친화적이지 않다는 것을 보여주는 대표적인 예입니다. + +하지만 전반적으로 Git은 배우기는 어렵지만 사용하기는 쉽습니다. + +### git 생태계 + +여기서는 git과 관련된 생태계를 간략하게 다루되 일부 영역에 대해 깊이 있게 다루지는 않겠지만 개략적인 수준에서 알아두는 것이 중요하다고 생각합니다. + +거의 모든 최신 개발 도구는 Git을 지원합니다. + +- 개발자 도구 - 이미 비주얼 스튜디오 코드에 대해 언급했지만, 서브블룸 텍스트 및 기타 텍스트 편집기 및 IDE에 대한 git 플러그인 및 통합을 찾을 수 있습니다. +- 팀 도구 - CI/CD 관점에서의 Jenkins, 메시징 프레임워크의 Slack, 프로젝트 관리 및 이슈 추적을 위한 Jira와 같은 도구에 대해서도 언급했습니다. +- 클라우드 제공업체 - 모든 대형 클라우드 제공업체는 git, Microsoft Azure, Amazon AWS 및 Google Cloud Platform을 지원합니다. +- Git 기반 서비스 - 나중에 더 자세히 다룰 GitHub, GitLab 및 BitBucket이 있습니다. 이러한 서비스는 코드를 위한 소셜 네트워크입니다! + +### Git 치트시트 + +대부분의 명령어를 다루지는 않았지만, 온라인에서 제공되는 몇 가지 치트 시트를 살펴본 후 몇 가지 git 명령어와 그 용도를 문서화하고 싶었습니다. 이 명령어들을 모두 기억할 필요는 없으며, 더 많은 실습과 사용을 통해 최소한 git 기본 명령어 정도는 익힐 수 있을 것입니다. + +[Atlassian](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet)에서 가져온 것이지만, 적어두고 설명을 읽어보면 명령이 무엇인지 알 수 있을 뿐만 아니라 일상적인 작업에서 실습을 해볼 수 있는 좋은 방법입니다. + +### Git 기본 사항 + +| Command | Example | Description | +| ------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| git init | `git init ` | 지정한 디렉토리에 빈 git 리포지토리를 만듭니다. | +| git clone | `git clone ` | \에 있는 리포지토리를 로컬 머신에 복제합니다. | +| git config | `git config user.name` | 현재 리포지토리 `system`, `global`, `local` 플래그의 모든 commit에 사용할 작성자 이름을 정의하여 구성 옵션을 설정합니다. | +| git add | `git add ` | 다음 commit을 위해 \의 모든 변경 사항을 스테이징합니다. 모든 항목에 대해 \와 \<.>을 추가할 수도 있습니다. | +| git commit -m | `git commit -m ""` | 스테이징된 스냅샷을 commit하고, \를 사용하여 commit되는 내용을 자세히 설명합니다. | +| git status | `git status` | 스테이징된 파일, 스테이징되지 않은 파일 및 추적되지 않은 파일을 나열합니다. | +| git log | `git log` | 기본 형식을 사용하여 모든 commit 기록을 표시합니다. 이 명령에는 추가 옵션이 있습니다. | +| git diff | `git diff` | 인덱스와 작업 디렉토리 사이의 스테이징되지 않은 변경 내용을 표시합니다. | + +### Git 변경사항 되돌리기 + +| Command | Example | Description | +| ---------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| git revert | `git revert ` | \의 모든 변경 사항을 취소하는 새 commit을 만든 다음 현재 branch에 적용합니다. | +| git reset | `git reset ` | 스테이징 영역에서 \을 제거하지만 작업 디렉토리는 변경하지 않고 그대로 둡니다. 이렇게 하면 변경 내용을 덮어쓰지 않고 파일을 스테이징 해제할 수 있습니다. | +| git clean | `git clean -n` | 작업 디렉토리에서 어떤 파일을 제거할지 표시합니다. clean을 실행하려면 `-n` 대신 `-f`를 사용해야 합니다. | + +### Git 수정 기록 + +| Command | Example | Description | +| ---------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| git commit | `git commit --amend` | 마지막 commit을 단계적 변경 사항과 마지막 commit을 결합한 것으로 바꿉니다. 아무것도 준비하지 않은 상태에서 사용하면 마지막 commit의 메시지를 편집할 수 있습니다. | +| git rebase | `git rebase ` | 현재 branch를 \로 rebase합니다. \는 commit ID, branch 이름, 태그 또는 HEAD에 대한 레퍼런스가 될 수 있습니다. | +| git reflog | `git reflog` | 로컬 리포지토리의 HEAD에 대한 변경 로그를 표시합니다. 날짜 정보를 표시하려면 --relative-date 플래그를 추가해야 하고, 모든 레퍼런스를 표시하려면 --all을 추가해야 합니다. | + +### Git Branchs + +| Command | Example | Description | +| ------------ | -------------------------- | ---------------------------------------------------------------------------------------------------------------- | +| git branch | `git branch` | 리포지토리에 있는 모든 branch를 나열합니다. \ 인수를 추가하여 \라는 이름의 새 branch를 만듭니다. | +| git checkout | `git checkout -b ` | \라는 이름의 새 branch를 생성하고 checkout합니다. 기존 branch를 checkout하려면 -b 플래그를 지웁니다. | +| git merge | `git merge ` | \를 현재 branch에 merge합니다. | + +### Git 원격 리포지토리 + +| Command | Example | Description | +| -------------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| git remote add | `git remote add ` | 원격 리포지토리에 대한 새 연결을 생성합니다. 리모트를 추가한 후 \을 다른 명령에서 \에 대한 바로 가기로 사용할 수 있습니다. | +| git fetch | `git fetch ` | 리포지토리에서 특정 \를 가져옵니다. 모든 원격 레퍼런스를 가져오려면 \를 생략하세요. | +| git pull | `git pull ` | 지정된 리모트의 현재 branch 복사본을 가져와서 로컬 복사본에 즉시 merge합니다. | +| git push | `git push ` | branch를 필요한 commit 및 오브젝트와 함께 \로 push합니다. 원격 리포지토리에 이름이 지정된 branch가 없는 경우 branch를 생성합니다. | + +### Git Diff + +| Command | Example | Description | +| ----------------- | ------------------- | ----------------------------------------------------- | +| git diff HEAD | `git diff HEAD` | 작업 디렉토리와 마지막 commit의 diff를 표시합니다. | +| git diff --cached | `git diff --cached` | 단계적 변경 사항과 마지막 commit의 diff를 표시합니다. | + +### Git Config + +| Command | Example | Description | +| ------------------------------------------------------ | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| git config --global user.name \ | `git config --global user.name ` | 현재 사용자가 모든 commit에 사용할 작성자 이름을 정의합니다. | +| git config --global user.email \ | `git config --global user.email ` | 현재 사용자가 모든 commit에 사용할 작성자 이메일을 정의합니다. | +| git config --global alias \ \ | `git config --global 별칭 ` | git 명령에 대한 단축어를 만듭니다. | +| git config --system core.editor \ | `git config --system core.editor ` | 컴퓨터의 모든 사용자에 대한 명령에서 사용할 텍스트 편집기를 설정합니다. \ 인수는 원하는 편집기를 실행하는 명령이어야 합니다. | +| git config --global --edit | `git config --global --edit ` | 수동 편집을 위해 텍스트 편집기에서 전역 구성 파일을 엽니다. | + +### Git Rebase + +| Command | Example | Description | +| --------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------- | +| git rebase -i \ | `git rebase -i ` | 현재 branch를 \로 rebase합니다. 편집기를 사용하여 각 commit을 새 저장소로 옮기는 방법에 대한 명령을 입력해야 합니다. | + +### Git Pull + +| Command | Example | Description | +| --------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | +| git pull --rebase \ | `git pull --rebase ` | 현재 branch의 리모트 복사본을 가져와서 로컬 복사본으로 rebase합니다. branch를 통합하기 위해 merge 대신 git rebase를 사용합니다. | + +### Git Reset + +| Command | Example | Description | +| -------------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| git reset | `git reset` | 스테이징 영역을 가장 최근 commit과 일치하도록 reset하되 작업 디렉토리는 변경하지 않습니다. | +| git reset --hard | `git reset --hard` | 스테이징 영역과 작업 디렉토리를 가장 최근 commit과 일치하도록 reset하고 작업 디렉토리의 모든 변경 내용을 덮어씁니다. | +| git reset \ | `git reset ` | 현재 branch 끝을 \ 뒤로 이동하고 스테이징 영역을 일치하도록 reset하되 작업 디렉토리는 그대로 둡니다 | +| git reset --hard \ | `git reset --hard ` | 이전과 동일하지만 스테이징 영역과 작업 디렉토리를 모두 일치하도록 reset합니다. commit되지 않은 변경 사항과 \ 이후의 모든 commit을 삭제합니다. | + +### Git Push + +| Command | Example | Description | +| -------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- | +| git push \ --force | `git push --force` | non-fast-forward merge가 아닌 경우에도 git push를 강제로 수행합니다. 자신이 무엇을 하고 있는지 확실하지 않으면 --force 플래그를 사용하지 말아야 합니다. | +| git push \ --all | `git push --all` | 모든 로컬 branch를 지정한 리모트로 push 합니다. | +| git push \ --tags | `git push --tags` | branch를 push하거나 --all 플래그를 사용하면 태그가 자동으로 push되지 않습니다. tags 플래그는 모든 로컬 태그를 원격 리포지토리에 보냅니다. | + +## 자료 + +- [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) +- [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) +- [Git Tutorial for Beginners](https://www.youtube.com/watch?v=8JJ101D3knE&t=52s) +- [Git for Professionals Tutorial](https://www.youtube.com/watch?v=Uszj_k0DGsg) +- [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) +- [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) +- [Git cheatsheet](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) + +[Day 38](day38.md)에서 봐요! diff --git a/2022/ko/Days/day38.md b/2022/ko/Days/day38.md new file mode 100644 index 0000000..a1a8289 --- /dev/null +++ b/2022/ko/Days/day38.md @@ -0,0 +1,127 @@ +--- +title: '#90DaysOfDevOps - Staging & Changing - Day 38' +published: false +description: 90DaysOfDevOps - Staging & Changing +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049042 +--- + +## 스테이징 및 변경 + +이미 몇 가지 기본 사항을 다뤘지만, 이렇게 연습을 해보면 어떻게 그리고 왜 이런 방식으로 작업하는지 더 잘 이해하고 배울 수 있습니다. GitHub와 같은 git 기반 서비스에 들어가기 전에 로컬 워크스테이션에서 활용할 수 있는 git의 강력한 기능을 살펴봅시다. + +git 세션을 시작할 때 만든 프로젝트 폴더를 가지고 git으로 할 수 있는 몇 가지 간단한 예제를 보여드리겠습니다. 로컬 머신에 폴더를 생성하고 `git init` 명령으로 초기화했습니다. + +![](/2022/Days/Images/Day38_Git1.png) + +이제 폴더를 초기화했으므로 디렉토리에 숨겨진 폴더가 있는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day38_Git2.png) + +이 폴더에는 branch 및 커밋에 관한 정보뿐만 아니라 git 저장소의 세부 정보가 저장됩니다. + +### 스테이징 파일 + +그런 다음 빈 폴더에서 작업을 시작하고 작업 첫날에 소스 코드를 추가할 수 있습니다. README.md 파일을 생성하면 디렉토리에서 해당 파일을 볼 수 있고, 다음으로 `git status`를 확인하면 새 README.md 파일이 보이지만, 아직 그 파일을 커밋하지는 않은 상태입니다. + +![](/2022/Days/Images/Day38_Git3.png) + +이제 `git add README.md` 명령으로 README.md 파일을 스테이징하면 이전에 없던 변경 사항과 초록색으로 표시되는 새 파일을 커밋할 수 있는 상태가 됩니다. + +![](/2022/Days/Images/Day38_Git4.png) + +다음으로 프로젝트의 첫 번째 커밋 또는 첫 번째 스냅샷인 이 파일을 커밋하고 싶습니다. 각 커밋에 대해 변경된 내용을 쉽게 확인할 수 있도록 `git commit -m "의미 있는 메시지"` 명령을 사용하여 이 작업을 수행할 수 있습니다. 또한 노란색 십자가가 이제 녹색 체크 표시로 바뀐 것을 확인할 수 있습니다. 이것은 제가 터미널에서 사용하는 테마로, 리눅스 섹션에서 다룬 내용입니다. + +![](/2022/Days/Images/Day38_Git5.png) + +### 변경 사항 커밋 + +파일을 더 추가하거나 디렉토리에 있는 파일을 변경하고 싶을 때가 많습니다. 위에서 이미 첫 번째 커밋을 했습니다. 하지만 이제 더 많은 세부 사항으로 더 많은 파일을 추가하겠습니다. + +이전 프로세스를 반복하여 파일을 만들거나 수정한 다음 `git add .`를 실행하여 모든 파일을 스테이징 영역에 추가한 다음 `git commit -m "의미 있는 메시지"`를 실행하면 정상적으로 작동할 수 있습니다. 그러나 커밋에 변경된 내용에 대한 의미 있는 메시지를 제공하려면 `git commit -m "음, 일부 코드가 작동하지 않아서 변경했으며, 이를 수정할 때 모든 사람이 사용자 경험에 대해 알 수 있도록 README.md에 새로운 내용을 추가했습니다."`와 같이 설명적인 내용을 작성하는 것도 가능하지만 여기서는 텍스트 편집기를 사용하여 추가하는 것이 더 바람직할 수 있습니다. + +`git add`를 실행한 후 `git commit`을 실행하면 기본 텍스트 편집기(여기서는 nano)가 열립니다. 다음은 파일에 몇 가지 변경 사항을 추가하기 위해 수행한 단계이며, `git status`를 실행하여 스테이징된 항목과 스테이징되지 않은 항목을 표시합니다. 그런 다음 `git add`를 사용하여 파일을 스테이징 영역에 추가한 다음 `git commit`을 실행하여 nano를 열었습니다. + +![](/2022/Days/Images/Day38_Git6.png) + +Nano가 열리면 설명을 추가한 다음 파일을 저장할 수 있습니다. + +![](/2022/Days/Images/Day38_Git7.png) + +### 커밋 모범 사례 + +커밋 시기와 커밋 횟수 사이에는 균형이 필요합니다. 프로젝트가 끝날 때까지 기다렸다가 커밋하는 것은 바람직하지 않으며, 각 커밋은 의미가 있어야 하고 서로 관련 없는 작업들은 함께 커밋해서는 안 됩니다. 버그 수정과 오타를 해결한 경우, 두 가지 커밋을 분리하여 커밋하는 것이 좋습니다. + +커밋 메시지에 의미를 부여하세요. + +문구 측면에서, 팀이나 본인이 각 커밋에 대해 동일한 문구를 사용해야 합니다. + +### 스테이징 영역 건너뛰기 + +변경 사항을 커밋하기 전에 항상 스테이징해야 할까요? + +정답은 '예'이지만, 롤백할 스냅샷이 필요하지 않다는 것을 100% 확신해야 하며, 이는 위험할 수 있습니다. + +![](/2022/Days/Images/Day38_Git8.png) + +### 파일 제거 + +프로젝트에서 파일을 제거하는 것은 어떨까요? 디렉토리에 커밋했지만 이제 프로젝트에 더 이상 필요하지 않거나 사용하지 않는 다른 파일이 있는 경우, 파일을 제거해야 합니다. + +디렉토리에서 파일을 제거해도 git은 여전히 이 파일을 인식하므로 리포지토리에서도 파일을 제거해야 합니다. 아래에서 이를 위한 workflow를 확인할 수 있습니다. + +![](/2022/Days/Images/Day38_Git9.png) + +이동하는 파일과 폴더가 많은 대규모 프로젝트의 경우 기억하거나 처리하는 것이 다소 번거로울 수 있습니다. 이 작업은 `git rm oldcode.ps1` 명령 하나로 수행할 수 있습니다. + +![](/2022/Days/Images/Day38_Git10.png) + +### 파일 이름 바꾸기 또는 이동 + +운영 체제 내에서 파일 이름을 바꾸고 이동할 수 있습니다. 프로젝트에서 때때로 이 작업을 해야 할 때가 있을 것입니다. 2단계 프로세스가 있지만 제거와 유사하게, OS에서 파일을 변경한 다음 스테이징 영역이나 파일이 올바르게 추가되었는지 수정하고 확인해야 합니다. 단계는 다음과 같습니다: + +![](/2022/Days/Images/Day38_Git11.png) + +그러나 운영 체제에서 파일을 제거한 다음 git 리포지토리에서 파일을 제거하는 것과 마찬가지로 git 명령을 사용하여 이름 변경을 할 수 있습니다. + +![](/2022/Days/Images/Day38_Git12.png) + +### 파일 무시하기 + +프로젝트 내 로컬에서만 사용 중이거나 전체 프로젝트에 공유되면 공간 낭비일 수 있는 파일이나 폴더를 무시해야 하는 경우가 있는데, 그 좋은 예로 로그를 들 수 있습니다. 또한 공개적으로 또는 팀 간에 공유하고 싶지 않은 비밀에 대해서도 이 기능을 사용할 수 있다고 생각합니다. + +프로젝트 디렉토리의 `.gitignore` 파일에 폴더나 파일을 추가하여 파일을 무시할 수 있습니다. + +![](/2022/Days/Images/Day38_Git13.png) + +`.gitignore` 파일을 열면 logs/ 디렉토리가 있는 것을 확인할 수 있습니다. 여기에 무시할 파일과 폴더를 추가할 수도 있습니다. + +![](/2022/Days/Images/Day38_Git14.png) + +이제 `git status`를 보고 어떤 일이 일어났는지 확인할 수 있습니다. + +![](/2022/Days/Images/Day38_Git15.png) + +로그 폴더를 이미 공유했지만, 나중에 공유하면 안 된다는 것을 깨달았을 때 파일과 폴더를 무시해야 하는 경우도 있습니다. 이전에 추적한 폴더가 있지만 이제 무시하고 싶은 경우 `git rm --cached`를 사용하여 스테이징 영역에서 파일과 폴더를 제거해야 합니다. + +### 간략한 status + +준비 영역에 무엇이 있고 무엇이 없는지 파악하기 위해 `git status`를 많이 사용해왔는데, 이 명령은 매우 포괄적이고 세부적인 내용을 담고 있습니다. 대부분의 경우 무엇이 수정되었는지 또는 무엇이 새로운 것인지 알고 싶을 것입니다. 이 세부 사항에 대한 간단한 상태를 확인하려면 `git status -s`를 사용할 수 있습니다. 저는 보통 시스템에서 단축어로 설정하여 더 자세한 명령 대신 `git status -s`만 사용하도록 합니다. + +![](/2022/Days/Images/Day38_Git16.png) + +내일 포스트에서는 이러한 일반적인 git 명령에 대한 간략한 예제를 계속 살펴보겠습니다. + +## 자료 + +- [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) +- [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) +- [Git Tutorial for Beginners](https://www.youtube.com/watch?v=8JJ101D3knE&t=52s) +- [Git for Professionals Tutorial](https://www.youtube.com/watch?v=Uszj_k0DGsg) +- [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) +- [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) +- [Git cheatsheet](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) + +[Day 39](day39.md)에서 봐요! diff --git a/2022/ko/Days/day39.md b/2022/ko/Days/day39.md new file mode 100644 index 0000000..8f8234d --- /dev/null +++ b/2022/ko/Days/day39.md @@ -0,0 +1,212 @@ +--- +title: '#90DaysOfDevOps - Viewing, unstaging, discarding & restoring - Day 39' +published: false +description: '90DaysOfDevOps - Viewing, unstaging, discarding & restoring' +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048827 +--- + +## 보기, 스테이징 해제, 삭제 및 복원 + +어제에 이어서 git에서 사용할 수 있는 몇 가지 명령어와 프로젝트에서 git을 활용하는 방법에 대해 알아보겠습니다. 아직 GitHub나 다른 git 기반 서비스에 대해서는 다루지 않았지만, 지금은 로컬에서 프로젝트를 제어하는 데 도움이 되는 내용이며, 향후 해당 도구에 통합되기 시작하면 모두 유용하게 사용할 수 있을 것입니다. + +### 스테이징된 변경 사항과 스테이징되지 않은 변경 사항 보기 + +commit하기 전에 스테이징된 코드와 스테이징되지 않은 코드를 확인하는 것이 좋습니다. 다음 `git diff --staged` 명령을 실행하면 됩니다. + +![](/2022/Days/Images/Day39_Git1.png) + +그러면 우리가 수행한 모든 변경 사항과 추가하거나 삭제한 모든 새 파일이 표시됩니다. + +수정한 파일의 변경 사항은 `---` 또는 `+++`로 표시되며, 아래에서 방금 + 추가한 텍스트는 새로운 줄임을 의미합니다. + +![](/2022/Days/Images/Day39_Git2.png) + +또한 `git diff`를 실행하여 스테이징 영역과 작업 디렉토리를 비교할 수 있습니다. 새로 추가한 code.txt 파일을 변경하고 몇 줄의 텍스트를 추가하면 다음과 같습니다. + +![](/2022/Days/Images/Day39_Git3.png) + +그런 다음 `git diff`를 실행하면 아래와 같은 출력을 비교하여 확인할 수 있습니다. + +![](/2022/Days/Images/Day39_Git4.png) + +### 시각적 Diff 도구 + +저는 위의 방법이 혼란스럽다고 생각하기 때문에 시각적 도구를 사용하는 편이 낫습니다, + +몇 가지 시각적 Diff 도구를 소개합니다: + +- KDiff3 +- P4Merge +- WinMerge (Windows 전용) +- VSCode + +git에서 설정하려면 다음 명령 `git config --global diff.tool vscode`를 실행합니다. + +위의 명령어를 실행하고 VScode를 시작할 때 몇 가지 매개 변수를 설정하겠습니다. + +![](/2022/Days/Images/Day39_Git5.png) + +또한 `git config --global -e`로 설정을 확인할 수 있습니다. + +![](/2022/Days/Images/Day39_Git6.png) + +이제 `git difftool`을 사용하여 Diff 시각화 도구를 열 수 있습니다. + +![](/2022/Days/Images/Day39_Git7.png) + +이제 Diff 페이지에서 VScode 에디터를 열고 두 파일을 비교하면, 아무것도 없는 상태에서 오른쪽에 코드 한 줄을 추가한 파일 하나만 수정했습니다. + +![](/2022/Days/Images/Day39_Git8.png) + +이 방법은 변경 사항을 추적하기가 훨씬 쉬우며, GitHub와 같은 Git 기반 서비스를 살펴볼 때 보게 될 것과 비슷한 방식입니다. + +또한 `git difftool --staged`를 사용하여 commit된 파일과 스테이지를 비교할 수 있습니다. + +![](/2022/Days/Images/Day39_Git9.png) + +그러면 commit하기 전에 변경된 파일들을 확인할 수 있게 됩니다. + +![](/2022/Days/Images/Day39_Git10.png) + +저는 IDE로 VScode를 사용하고 있으며 대부분의 IDE와 마찬가지로 이미 내장되어 있는 명령어이므로 터미널에서 직접 실행해야 하는 경우는 매우 드물지만, 어떤 이유로 IDE가 설치되어 있지 않은 경우 유용합니다. + +### 히스토리 보기 + +앞서 리포지토리에서 수행한 모든 commit을 종합적으로 볼 수 있는 `git log`에 대해 살펴봤습니다. + +![](/2022/Days/Images/Day39_Git11.png) + +각 commit에는 리포지토리에 고유한 16진수 문자열이 있습니다. 여기에서 작업 중인 branch와 작성자, 날짜, commit 메시지를 확인할 수 있습니다. + +또한 `git log --oneline`을 사용하면 다른 `diff` 명령에서 사용할 수 있는 훨씬 더 작은 버전의 16진수 문자열을 얻을 수 있습니다. 또한 한 줄 설명 또는 commit 메시지만 있습니다. + +![](/2022/Days/Images/Day39_Git12.png) + +`git log --oneline --reverse`를 실행하면 페이지 상단에 첫 번째 commit이 표시됩니다. + +![](/2022/Days/Images/Day39_Git13.png) + +### commit 보기 + +commit 메시지를 볼 수 있는 것은 모범 사례를 따르고 의미 있는 commit 메시지를 추가한 경우 매우 유용하지만, commit을 검사하고 볼 수 있는 `git show` 명령도 있습니다. + +우리는 `git log --oneline --reverse`를 사용하여 commit 목록을 가져올 수 있습니다. 그런 다음 이를 가져와서 `git show `를 실행할 수 있습니다. + +![](/2022/Days/Images/Day39_Git14.png) + +이 명령의 출력은 commit, 작성자 및 변경된 내용에 대한 세부 정보와 함께 아래와 같이 표시됩니다. + +![](/2022/Days/Images/Day39_Git15.png) + +`git show HEAD~1`을 사용할 수도 있습니다. 여기서 1은 현재 버전에서 몇 단계 뒤로 돌아가려는지 나타냅니다. + +이 방법은 파일에 대한 세부 정보를 원하지만, 전체 스냅샷 디렉토리에 대한 트리의 모든 파일을 나열하려는 경우에 유용합니다. 마지막 commit에서 다시 한 스냅샷을 거슬러 올라가는 `git ls-tree HEAD~1` 명령을 사용하면 이 작업을 수행할 수 있습니다. 아래에서 두 개의 blob이 있는 것을 볼 수 있는데, blob은 파일을 나타내고 트리는 디렉토리를 나타냅니다. 이 정보에서 commit과 태그도 볼 수 있습니다. + +![](/2022/Days/Images/Day39_Git16.png) + +이제 위의 내용을 사용하여 `git show` 명령을 사용하여 파일(blob)의 내용을 자세히 확인할 수 있습니다. + +![](/2022/Days/Images/Day39_Git17.png) + +그러면 특정 버전의 파일 내용이 표시됩니다. + +![](/2022/Days/Images/Day39_Git18.png) + +### 파일 스테이징 해제 + +`git add .`를 사용했지만 아직 해당 스냅샷에 commit하고 싶지 않은 파일이 있는 경우가 있을 수 있습니다. 아래 예제에서는 스테이징 영역에 newfile.txt를 추가했지만, 이 파일을 commit할 준비가 되지 않았으므로 `git restore --staged newfile.txt`를 사용하여 `git add` 단계를 실행 취소하겠습니다. + +![](/2022/Days/Images/Day39_Git19.png) + +위 그림에서 수정된 파일(예: main.js)에 대해서도 동일한 작업을 수행하여 commit의 스테이징을 해제할 수 있습니다. + +![](/2022/Days/Images/Day39_Git20.png) + +저는 이 명령어가 90DaysOfDevOps 기간 동안 매우 유용하다는 것을 알았습니다. 다음 날을 위한 메모를 작성하고 싶지만, 공개 GitHub 리포지토리에 commit하고 push하고 싶지 않은 날을 앞두고 작업하는 경우가 종종 있기 때문입니다. + +### 로컬 변경 사항 삭제하기 + +때때로 우리는 변경을 했지만, 그 변경이 마음에 들지 않아서 버리고 싶을 때가 있습니다. 다시 `git restore` 명령을 사용하여 스냅샷 또는 이전 버전에서 파일을 복원할 수 있습니다. 디렉토리에 대해 `git restore .`를 실행하면 스냅샷에서 모든 것을 복원할 수 있지만 추적되지 않은 파일이 여전히 존재한다는 것을 알 수 있습니다. 추적 중인 이전 파일은 newfile.txt라는 파일이 없습니다. + +![](/2022/Days/Images/Day39_Git21.png) + +이제 새로운 파일 txt 또는 추적되지 않은 파일을 제거합니다. 우리는 `git clean`을 사용하면 경고만 받을 수 있습니다. + +![](/2022/Days/Images/Day39_Git22.png) + +또는 결과를 알고 있다면 `git clean -fd`를 실행하여 모든 디렉토리를 강제로 제거할 수 있습니다. + +![](/2022/Days/Images/Day39_Git23.png) + +### 파일을 이전 버전으로 복원하기 + +앞서 언급했듯이 Git의 큰 장점 중 하나는 스냅샷에서 파일 사본을 복원할 수 있다는 점입니다(백업은 아니지만 매우 빠른 복원 방법입니다). 백업 솔루션을 사용하여 코드 사본을 다른 위치에도 저장하는 것을 추천드립니다. + +예시로 디렉토리에서 가장 중요한 파일을 삭제해 보겠습니다. 디렉토리에서 이 파일을 제거하기 위해 git 명령이 아닌 Unix 기반 명령을 사용하고 있음을 알 수 있습니다. + +![](/2022/Days/Images/Day39_Git24.png) + +이제 작업 디렉토리에 readme.md가 없습니다. `git rm readme.md`를 사용하면 git 데이터베이스에 반영될 수 있습니다. 완전히 제거된 것을 시뮬레이션하기 위해 여기서도 삭제해 보겠습니다. + +![](/2022/Days/Images/Day39_Git25.png) + +이제 이 내용을 메시지와 함께 commit하고 작업 디렉토리 또는 스테이징 영역에 더 이상 아무것도 없음을 증명해 보겠습니다. + +![](/2022/Days/Images/Day39_Git26.png) + +실수가 있었으니 이제 이 파일을 되돌릴 필요가 있습니다! + +`git undo` 명령을 사용하여 마지막 commit을 취소할 수 있지만, 오래된 commit이라면 어떻게 해야 할까요? `git log` 명령을 사용하여 commit 기록을 찾을 수 있습니다. 파일이 마지막 commit에 포함되어 있다는 것을 확인했지만, 모든 commit을 취소하고 싶지는 않습니다. 이 경우 `git restore --source=HEAD~1 README.md` 명령을 사용하여 특정 파일을 찾고 스냅샷에서 복원할 수 있습니다. + +이 프로세스를 통해 파일을 작업 디렉토리에 다시 가져온 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day39_Git27.png) + +이제 추적되지 않은 새 파일이 생겼으며 앞서 언급한 명령을 사용하여 파일과 변경 사항을 추적, 스테이징 및 commit할 수 있습니다. + +### Rebase와 Merge + +git 리포지토리에서 언제 rebase를 사용해야 하는지, 언제 merge를 사용해야 하는지가 가장 골치 아픈 문제인 것 같습니다. + +가장 먼저 알아야 할 것은 `git rebase`와 `git merge`이 모두 같은 문제를 해결한다는 것입니다. 둘 다 한 branch의 변경 내용을 다른 branch에 통합하는 것입니다. 하지만 다른 방식으로 이 작업을 수행합니다. + +새로운 feature branch로 새로운 기능을 만들어보겠습니다. main branch는 새로운 commit이 계속 추가되고 있습니다. + +![](/2022/Days/Images/Day39_Git28.png) + +여기서 쉬운 옵션은 `git merge feature main`을 사용하여 main branch를 feature branch에 merge하는 것입니다. + +![](/2022/Days/Images/Day39_Git29.png) + +merge는 비파괴적이기 때문에 간단합니다. 기존 branch는 어떤 방식으로도 변경되지 않습니다. 하지만 feature branch에 업스트림 변경 사항을 통합해야 할 때마다 관련 없는 merge commit이 발생하게 됩니다. main branch가 매우 바쁘거나 활성 상태인 경우 feature branch 히스토리를 오염시킬 수도 있습니다. + +다른 옵션으로, feature branch를 main branch에 rebase하는 방법도 있습니다. + +``` +git checkout feature +git rebase main +``` + +이렇게 하면 feature branch(전체 feature branch)가 main branch에 모든 새 commit을 효과적으로 통합합니다. 그러나 merge commit을 사용하는 대신 rebase는 원래 branch에 있는 각 commit에 대해 새로운 commit을 생성하여 프로젝트 기록을 다시 작성하게 됩니다. + +![](/2022/Days/Images/Day39_Git30.png) + +rebase의 가장 큰 장점은 프로젝트 히스토리가 훨씬 깔끔해진다는 것입니다. 또한 불필요한 merge commit을 제거하며, 마지막 두 이미지를 비교하면 훨씬 더 깔끔한 선형 프로젝트 히스토리를 따라갈 수 있습니다. + +아직 확실한 결론은 아니지만, 더 깔끔한 히스토리를 선택하는 것도 장단점이 있는데, [rebase의 황금률](https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing)을 따르지 않는다면 프로젝트 히스토리를 다시 작성하는 것은 협업 workflow에 치명적일 수 있습니다. 그리고 더 중요한 것은 rebase를 하면 merge commit이 제공하는 컨텍스트가 사라져 업스트림 변경 사항이 언제 feature에 통합되었는지 알 수 없다는 것입니다. + +## 자료 + +- [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) +- [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) +- [Git Tutorial for Beginners](https://www.youtube.com/watch?v=8JJ101D3knE&t=52s) +- [Git for Professionals Tutorial](https://www.youtube.com/watch?v=Uszj_k0DGsg) +- [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) +- [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) +- [Git cheatsheet](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) +- [Exploring the Git command line – A getting started guide](https://veducate.co.uk/exploring-the-git-command-line/) + +[Day 40](day40.md)에서 봐요! diff --git a/2022/ko/Days/day40.md b/2022/ko/Days/day40.md new file mode 100644 index 0000000..d031db5 --- /dev/null +++ b/2022/ko/Days/day40.md @@ -0,0 +1,210 @@ +--- +title: '#90DaysOfDevOps - Social Network for code - Day 40' +published: false +description: 90DaysOfDevOps - Social Network for code +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049044 +--- + +## 코드를 위한 소셜 네트워크 + +GitHub 살펴보기 | GitLab | BitBucket + +오늘은 우리 모두가 들어봤을 법한, 그리고 우리도 매일 사용할 것으로 예상되는 몇 가지 git 기반 서비스를 다루고자 합니다. + +그런 다음 이전 세션에서 배운 지식을 사용하여 데이터의 사본을 각 주요 서비스로 이동해 보겠습니다. + +이 섹션을 "코드를 위한 소셜 네트워크"라고 부른 이유를 설명해드릴까요? + +### GitHub + +적어도 저에게 가장 일반적인 것은 GitHub입니다. GitHub는 Git을 위한 웹 기반 호스팅 서비스입니다. 소프트웨어 개발자가 코드를 저장하는 데 가장 일반적으로 사용합니다. git 버전 관리 기능뿐만 아니라 다양한 추가 기능을 통해 소스 코드를 관리할 수 있습니다. 팀이나 오픈 컨트리뷰터가 쉽게 소통할 수 있으며 코딩에 소셜 측면을 제공합니다. (따라서 소셜 네트워킹이라는 제목을 붙였습니다.) 2018년부터 GitHub는 Microsoft의 일부가 되었습니다. + +GitHub는 2007/2008년에 설립되어 꽤 오래전부터 존재해 왔습니다. 현재 4천만 명 이상의 사용자가 이 플랫폼을 사용하고 있습니다. + +GitHub 주요 기능 + +- 코드 리포지토리 +- Pull Requests +- 프로젝트 관리 도구 세트 - Issues +- CI/CD 파이프라인 - GitHub Actions + +가격 측면에서 GitHub는 사용자에 따라 다양한 수준의 가격을 책정합니다. 자세한 내용은 [가격](https://github.com/pricing)에서 확인할 수 있습니다. + +여기서는 프리티어를 다루겠습니다. + +이 안내에서는 이미 생성한 GitHub 계정을 사용할 예정이므로 계정이 없는 경우, GitHub 시작 페이지에서 가입 옵션과 몇 가지 간단한 단계를 통해 설정할 수 있습니다. + +### GitHub 시작 페이지 + +GitHub 계정에 처음 로그인하면 다양한 위젯이 포함된 페이지가 표시되어 어디에서 무엇을 보고 싶고 무엇을 할 것인지에 대한 옵션을 제공합니다. 먼저 "All Activity"를 통해 리포지토리에서 어떤 일이 일어나고 있는지 또는 조직이나 계정과 관련된 일반적인 활동을 살펴볼 수 있습니다. + +![](/2022/Days/Images/Day40_Git1.png) + +다음으로, 자체 리포지토리 또는 최근에 상호 작용한 리포지토리가 있는 코드 리포지토리가 있습니다. 새 리포지토리나 검색 리포지토리를 빠르게 생성할 수도 있습니다. + +![](/2022/Days/Images/Day40_Git2.png) + +최근 활동은 제가 최근에 만들었거나 기여한 issues와 pull requests입니다. + +![](/2022/Days/Images/Day40_Git3.png) + +페이지 오른쪽에는 최근 활동 또는 자체 프로젝트를 기반으로 관심을 가질 만한 리포지토리에 대한 추천이 있습니다. + +![](/2022/Days/Images/Day40_Git4.png) + +솔직히 저는 방금 보고 설명한 홈페이지에 거의 들어가지 않지만, 특정 프로젝트에서 커뮤니티와 좀 더 잘 소통하는 데 이 피드가 정말 유용할 수 있다는 것을 깨달았습니다. + +다음으로 GitHub 프로필로 이동하려면 오른쪽 상단 모서리로 이동하면 이미지에 계정을 탐색할 수 있는 드롭다운이 있습니다. 여기에서 프로필에 액세스하려면 "Your Profile"을 선택합니다. + +![](/2022/Days/Images/Day40_Git5.png) + +다음으로 프로필 페이지가 표시되는데, 기본적으로 설정을 변경하지 않는 한 내가 가진 것을 볼 수 없으며, [vZilla](https://vzilla.co.uk)의 최근 블로그 게시물과 내 [YouTube](https://m.youtube.com/c/MichaelCade1) 채널의 최신 동영상을 보여주는 기능을 추가했습니다. + +프로필을 보는 데 많은 시간을 할애하지는 않겠지만, 현재 진행 중인 멋진 프로젝트를 볼 수 있도록 네트워크에 공유하기에 좋은 프로필 페이지입니다. + +![](/2022/Days/Images/Day40_Git6.png) + +이제 GitHub의 빌딩 블록인 리포지토리를 자세히 살펴볼 수 있습니다. 여기에서 리포지토리를 볼 수 있으며 비공개 리포지토리가 있는 경우 이 긴 목록에 해당 리포지토리도 표시됩니다. + +![](/2022/Days/Images/Day40_Git7.png) + +리포지토리는 GitHub에서 매우 중요하기 때문에 최근에 많이 사용된 리포지토리를 선택하여 로컬 시스템에서 git으로 "코드"를 편집할 때 이미 사용하고 있는 모든 기능 외에 여기서 사용할 수 있는 핵심 기능 몇 가지를 살펴보겠습니다. + +우선, 이전 창에서 90DaysOfDevOps 리포지토리를 선택했더니 다음과 같은 보기가 표시됩니다. 이 보기에서 많은 정보를 볼 수 있으며, 리포지토리에 저장된 파일과 폴더를 보여주는 기본 코드 구조가 있습니다. 맨 아래에는 README.md이 표시됩니다. 페이지 오른쪽에는 리포지토리에 대한 설명과 목적이 있는 정보 섹션이 있습니다. 그리고 그 아래에는 얼마나 많은 사람들이 프로젝트에 참여하고, folk하고, 봤는지 보여주는 많은 정보가 있습니다. + +![](/2022/Days/Images/Day40_Git8.png) + +조금 더 아래로 스크롤하면 릴리즈가 있는 것을 볼 수 있는데, 이는 챌린지의 Go 언어 부분에서 나온 것입니다. 우리 프로젝트에는 패키지가 없으며 여기에 기여자가 나열되어 있습니다. (오타와 사실 확인에 도움을 주신 커뮤니티에 감사드립니다.) 그런 다음 챌린지의 다른 섹션에서 다시 사용된 언어가 있습니다. + +![](/2022/Days/Images/Day40_Git9.png) + +페이지 상단에 탭 목록이 표시됩니다. 탭은 다양할 수 있으며 필요한 탭만 표시하도록 수정할 수 있습니다. 이 탭들을 모두 사용하지 않으므로 전체 리포지토리를 깔끔하게 정리하려면 이 탭들을 제거해야 한다는 것을 알 수 있습니다. + +먼저 방금 설명한 코드 탭이 있는데, 이 탭은 리포지토리를 탐색할 때 항상 사용할 수 있으므로 섹션 사이를 빠르고 쉽게 이동할 수 있어 매우 유용합니다. 다음으로 issues 탭이 있습니다. + +issues를 사용하면 개발이 이루어지는 GitHub에서 작업을 추적할 수 있습니다. 이 특정 리포지토리에는 다이어그램이나 오타를 추가하는 데 중점을 둔 몇 가지 issues가 있지만 중국어 버전의 리포지토리에 대한 필요성 또는 요구 사항을 명시하는 issues도 있음을 알 수 있습니다. + +이 리포지토리가 코드 리포지토리라면 유지 관리자에게 우려 사항이나 문제를 제기하기에 좋은 곳이지만, 보고하는 내용을 염두에 두고 가능한 한 자세하게 설명해야 함을 잊지 마세요. + +![](/2022/Days/Images/Day40_Git10.png) + +다음 탭은 pull requests이며, pull requests를 사용하면 리포지토리의 branch에 push한 변경 사항을 다른 사람에게 알릴 수 있습니다. 누군가 리포지토리를 folk하여 버그 수정이나 기능 개선 등의 변경을 하거나 이 리포지토리의 많은 경우, 오타를 수정했을 수 있습니다. + +folk에 대해서는 나중에 다루겠습니다. + +![](/2022/Days/Images/Day40_Git11.png) + +다음 탭은 꽤 새로운 탭이라고 생각되죠? #90DaysOfDevOps와 같은 프로젝트에서는 이 탭이 콘텐츠 여정을 안내하는 데 도움이 될 뿐만 아니라 커뮤니티가 학습 여정을 걸어가는 데도 도움이 될 수 있다고 생각했습니다. 챌린지의 각 섹션에 대한 토론 그룹을 만들어 사람들이 참여하여 토론할 수 있도록 했습니다. + +![](/2022/Days/Images/Day40_Git12.png) + +Actions 탭을 사용하면 GitHub 내에서 바로 코드를 빌드, 테스트 및 배포하는 등 다양한 작업을 수행할 수 있습니다. GitHub 작업은 챌린지의 CI/CD 섹션에서 다루겠지만, 여기에서 몇 가지 구성을 설정하여 단계를 자동화할 수 있습니다. + +제 기본 GitHub 프로필에서는 GitHub Actions를 사용하여 최신 블로그 게시물과 YouTube 동영상을 가져와 홈 화면에 최신 정보를 표시하고 있습니다. + +![](/2022/Days/Images/Day40_Git13.png) + +위에서 GitHub가 단순한 소스 코드 리포지토리가 아니라 프로젝트 관리 도구라고 말씀드렸는데, Projects 탭에서는 프로젝트 테이블을 칸반 형식의 보드로 구성하여 issues와 PR을 연결하여 프로젝트에 대한 협업을 개선하고 해당 작업에 대한 가시성을 확보할 수 있습니다. + +![](/2022/Days/Images/Day40_Git14.png) + +issues가 기능 요청을 기록하기에 좋은 곳인 것 같고 실제로도 그렇지만 Wiki 페이지를 사용하면 프로젝트에 대한 포괄적인 로드맵을 현재 상태와 함께 설명할 수 있고 일반적으로 문제 해결 또는 방법 유형 콘텐츠 등 프로젝트에 대한 문서화를 더 잘 할 수 있습니다. + +![](/2022/Days/Images/Day40_Git15.png) + +이 프로젝트에는 해당되지 않지만, Security 탭은 기여자가 특정 작업을 처리하는 방법을 알 수 있도록 하기 위한 탭으로, 여기에서 정책을 정의할 수 있을 뿐만 아니라 코드 검사 애드온을 사용하여 코드에 비밀 환경 변수가 포함되어 있지 않은지 확인할 수도 있습니다. + +![](/2022/Days/Images/Day40_Git16.png) + +Insight 탭은 리포지토리의 활동량부터 commit 및 issues에 이르기까지 리포지토리에 대한 많은 정보를 제공할 뿐만 아니라 리포지토리에 대한 트래픽도 보고해줘서 매우 유용합니다. 왼쪽에 리포지토리의 메트릭에 대해 자세히 살펴볼 수 있는 목록이 표시됩니다. + +![](/2022/Days/Images/Day40_Git17.png) + +마지막으로 Settings 탭이 있는데, 여기서 리포지토리를 실행하는 방법에 대한 세부 정보를 확인할 수 있으며, 현재 리포지토리의 유일한 관리자는 저이지만, 여기서 다른 사람에게 권한을 부여할 수 있습니다. 여기에서 통합 및 기타 작업을 정의할 수 있습니다. + +![](/2022/Days/Images/Day40_Git18.png) + +지금까지 GitHub에 대한 간략한 개요를 살펴봤는데, 좀 더 자세히 설명해야 할 부분이 몇 가지 더 있을 것 같습니다. 앞서 언급했듯이 GitHub에는 수백만 개의 리포지토리가 있으며, 대부분 소스 코드가 저장되어 있고 공개 또는 비공개로 액세스할 수 있습니다. + +### Folk + +내일 세션에서 오픈소스에 대해 더 자세히 다룰 예정이지만, 코드 리포지토리의 가장 큰 장점은 커뮤니티와 협업할 수 있다는 점입니다. 리포지토리에 몇 가지 변경을 하고 싶어서, 버그를 수정하고 싶어서, 또는 원래 코드 관리자가 의도한 사용 사례가 아닌 다른 사용 사례에 사용하기 위해 무언가를 변경하고 싶어서 리포지토리의 복사본을 원하는 시나리오를 생각해 봅시다. 이를 리포지토리 folk라고 합니다. folk는 리포지토리의 복사본입니다. 리포지토리를 folk하면 원래 프로젝트에 영향을 주지 않고 자유롭게 변경 사항을 실험할 수 있습니다. + +로그인 후 시작 페이지로 돌아가서 추천 리포지토리 중 하나를 살펴보겠습니다. + +![](/2022/Days/Images/Day40_Git19.png) + +해당 리포지토리를 클릭하면 방금 살펴본 90DaysOfDevOps 리포지토리와 동일한 모습을 볼 수 있습니다. + +![](/2022/Days/Images/Day40_Git20.png) + +아래에서 3가지 옵션이 있음을 알 수 있습니다. Watch, Folk, Star가 있습니다. + +- Watch - 리포지토리에 어떤 일이 발생하면 업데이트합니다. +- Folk - 리포지토리의 복사본. +- Star - "프로젝트가 멋진 것 같아요" + +![](/2022/Days/Images/Day40_Git21.png) + +이 리포지토리의 복사본을 작업하고 싶다는 시나리오를 고려할 때, folk 옵션을 사용하겠습니다. 여러 조직의 구성원인 경우, folk가 발생할 위치를 선택해야 하는데, 저는 제 프로필을 선택하겠습니다. + +![](/2022/Days/Images/Day40_Git22.png) + +이제 우리는 자유롭게 작업하고 필요에 따라 변경할 수 있는 리포지토리 사본을 갖게 되었습니다. 이것이 앞서 잠깐 언급했던 pull requests 프로세스의 시작이지만 내일 더 자세히 다루겠습니다. + +![](/2022/Days/Images/Day40_Git23.png) + +이 리포지토리와 코드가 웹사이트에 있는 경우, 웹사이트에 가서 편집할 수는 있지만 로컬 시스템에서 좋아하는 색상 테마로 좋아하는 IDE를 사용하는 것과는 다를 것입니다. 로컬 시스템에서 이 리포지토리의 복사본을 얻으려면 리포지토리의 복제를 수행합니다. 이렇게 하면 로컬에서 작업한 다음 변경 사항을 folk된 리포지토리 사본에 다시 push할 수 있습니다. + +아래에서 볼 수 있듯이 이 코드의 복사본을 얻는 데는 몇 가지 옵션이 있습니다. + +변경 사항을 추적하고 로컬과 GitHub 간에 변경 사항을 push 및 pull할 수 있는 시각적 데스크톱 애플리케이션을 제공하는 GitHub Desktop의 로컬 버전이 있습니다. + +이 작은 데모에서는 여기에 표시된 HTTPS URL을 사용하겠습니다. + +![](/2022/Days/Images/Day40_Git24.png) + +이제 로컬 컴퓨터에서 이 리포지토리를 다운로드할 디렉토리로 이동한 다음 `git clone url`을 실행하겠습니다. + +![](/2022/Days/Images/Day40_Git25.png) + +이제 VScode로 가져가서 몇 가지 변경을 할 수 있습니다. + +![](/2022/Days/Images/Day40_Git26.png) + +이제 몇 가지 변경을 해보겠습니다. 모든 링크를 변경하고 다른 것으로 바꾸고 싶습니다. + +![](/2022/Days/Images/Day40_Git27.png) + +이제 GitHub를 다시 확인하고 해당 리포지토리에서 README.md을 찾으면 파일에 몇 가지 변경한 내용을 볼 수 있을 것입니다. + +![](/2022/Days/Images/Day40_Git28.png) + +이 단계에서는 이 작업이 완료되고 우리만 새로운 변경 사항을 사용할 것이므로 변경 사항에 만족할 수도 있지만, 버그 변경일 수도 있으며 이 경우, pull requests를 통해 기여하여 원래 리포지토리 관리자에게 변경 사항을 알리고 변경 사항을 수락하는지 확인하고 싶을 것입니다. + +아래 강조 표시된 기여 버튼을 사용하여 이 작업을 수행할 수 있습니다. 내일 오픈소스 workflow를 살펴보면서 이에 대해 더 자세히 다루겠습니다. + +![](/2022/Days/Images/Day40_Git29.png) + +오랜 시간 동안 GitHub를 살펴봤는데 다른 옵션은 없는지 궁금해하시는 분들도 계실 것 같습니다! + +글쎄요, 그런 옵션도 있고 그중 일부에 대한 기본 사항을 다루는 몇 가지 리소스를 찾아보려고 합니다. 앞으로 GitLab과 BitBucket을 만나게 될 텐데, 이 두 서비스는 git 기반 서비스이긴 하지만 차이점이 있습니다. + +또한 호스팅 옵션도 있습니다. 호스팅 버전인 GitLab과 무료 호스팅 GitHub도 있을 거라고 생각하지 않으신가요? + +## 자료 + +- [Learn GitLab in 3 Hours | GitLab Complete Tutorial For Beginners](https://www.youtube.com/watch?v=8aV5AxJrHDg) +- [BitBucket Tutorials Playlist](https://www.youtube.com/watch?v=OMLh-5O6Ub8&list=PLaD4FvsFdarSyyGl3ooAm-ZyAllgw_AM5) +- [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) +- [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) +- [Git Tutorial for Beginners](https://www.youtube.com/watch?v=8JJ101D3knE&t=52s) +- [Git for Professionals Tutorial](https://www.youtube.com/watch?v=Uszj_k0DGsg) +- [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) +- [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) +- [Git cheatsheet](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) + +[Day 41](day41.md)에서 봐요! diff --git a/2022/ko/Days/day41.md b/2022/ko/Days/day41.md new file mode 100644 index 0000000..bdcba09 --- /dev/null +++ b/2022/ko/Days/day41.md @@ -0,0 +1,127 @@ +--- +title: '#90DaysOfDevOps - The Open Source Workflow - Day 41' +published: false +description: 90DaysOfDevOps - The Open Source Workflow +tags: 'DevOps, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048806 +--- + +## 오픈 소스 workflow + +지난 7회에 걸친 Git 섹션을 통해 Git이 무엇인지, 그리고 GitHub와 같은 Git 기반 서비스가 어떻게 소스 코드 저장소를 제공할 뿐만 아니라 더 많은 커뮤니티가 함께 코드와 프로젝트를 협업할 수 있는 방법을 제공하는지 더 잘 이해하셨기를 바랍니다. + +GitHub의 기본 사항을 살펴볼 때 임의의 프로젝트를 fork하고 로컬 리포지토리를 변경하는 과정을 거쳤습니다. 여기서는 한 단계 더 나아가 오픈소스 프로젝트에 기여하고자 합니다. 기여는 반드시 버그 수정이나 코딩 기능일 필요는 없으며 문서화일 수도 있다는 점을 기억하세요. 작은 도움이라도 모두 의미 있으며, 지금까지 다룬 몇 가지 git 기능을 직접 사용해 볼 수 있습니다. + +## 프로젝트 fork하기 + +가장 먼저 해야 할 일은 우리가 기여할 수 있는 프로젝트를 찾는 것입니다. 저는 최근 [Kanister 프로젝트](https://github.com/kanisterio/kanister)에서 발표를 하고 있는데, 현재 유튜브에 올라와 있는 프레젠테이션을 프로젝트의 메인 README.md 파일에 공유하고자 합니다. + +우선 프로젝트를 fork해야 합니다. 그 과정을 살펴보겠습니다. 위에서 공유한 링크로 이동하여 리포지토리를 fork하겠습니다. + +![](/2022/Days/Images/Day41_Git1.png) + +이제 전체 리포지토리의 복사본을 얻었습니다. + +![](/2022/Days/Images/Day41_Git2.png) + +참고로 README.md 파일에 나열된 원본 프레젠테이션은 이 두 개뿐이므로 프로세스를 통해 이 문제를 해결해야 합니다. + +![](/2022/Days/Images/Day41_Git3.png) + +## 로컬 머신에 복제 + +이제 fork를 로컬로 가져와서 파일에 대한 편집을 시작할 수 있습니다. 리포지토리의 코드 버튼을 사용하여 URL을 가져온 다음 리포지토리를 배치하려는 디렉토리에 `git clone url`을 사용하면 됩니다. + +![](/2022/Days/Images/Day41_Git4.png) + +## 변경하기 + +프로젝트가 로컬에 있으므로 VSCode 또는 원하는 IDE 또는 텍스트 편집기를 열어 수정 사항을 추가할 수 있습니다. + +![](/2022/Days/Images/Day41_Git5.png) + +READEME.md 파일은 마크다운 언어로 작성되었으며, 다른 사람의 프로젝트를 수정하고 있으므로 기존 프로젝트 형식을 따라 콘텐츠를 추가하겠습니다. + +![](/2022/Days/Images/Day41_Git6.png) + +## 변경 사항 테스트하기 + +코드 변경 후에도 애플리케이션이 계속 작동하는지 확인하려면 변경 사항을 테스트하는 것이 가장 좋은 방법이며, 문서 형식이 올바르게 지정되어 있는지 확인해야 합니다. + +VSCode에서는 많은 플러그인을 추가할 수 있는데, 그중 하나가 마크다운 페이지를 미리 볼 수 있는 기능입니다. + +![](/2022/Days/Images/Day41_Git7.png) + +## 변경 사항을 fork된 리포지토리로 push하기 + +변경 사항을 Kanister 리포지토리로 직접 push할 수 있는 권한이 없으므로 이 경로를 사용해야 합니다. 이제 변경 사항에 만족하므로 이제 잘 알려진 몇 가지 git 명령을 실행할 수 있습니다. + +![](/2022/Days/Images/Day41_Git8.png) + +이제 GitHub로 돌아가서 변경 사항을 다시 한번 확인한 다음 마스터 프로젝트에 다시 기여합니다. + +좋아 보이네요. + +![](/2022/Days/Images/Day41_Git9.png) + +이제 Kanister의 fork된 리포지토리 상단으로 돌아가서 kanisterio:master branch보다 commit이 1개 앞선 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day41_Git10.png) + +다음으로 위에 강조 표시된 기여 버튼을 누릅니다. "Open Pull Request" 옵션이 표시됩니다. + +![](/2022/Days/Images/Day41_Git11.png) + +## Open Pull Request + +다음 이미지에서 꽤 많은 일이 진행되고 있습니다. 왼쪽 위에는 이제 원본 또는 마스터 리포지토리에 있는 것을 볼 수 있습니다. 그리고 비교 대상인 원본 마스터 리포지토리와 fork된 리포지토리를 볼 수 있습니다. 이제 Create Pull Request 버튼이 있는데, 곧 다시 설명하겠습니다. 단일 commit이 있지만 변경 사항이 더 많으면 여기에 여러 개의 commit이 있을 수 있습니다. 그러면 README.md 파일에 변경 사항이 있습니다. + +![](/2022/Days/Images/Day41_Git12.png) + +위의 변경 사항을 검토했으며 녹색 버튼을 눌러 pull requests를 생성할 준비가 되었습니다. + +그런 다음 프로젝트 관리자가 리포지토리에 pull requests 기능을 어떻게 설정했는지에 따라 관리자가 보고자 하는 내용을 알려주는 템플릿이 있을 수도 있고 없을 수도 있습니다. + +여기서도 자신이 한 일에 대해 명확하고 간결하면서도 충분히 상세하게 의미 있는 설명을 작성해야 합니다. 간단한 변경 개요를 작성하고 문서화를 체크한 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day41_Git13.png) + +## Create Pull Request + +이제 pull requests를 만들 준비가 되었습니다. 페이지 상단의 "Create Pull Request"를 누르면 pull requests에 대한 요약이 표시됩니다. + +![](/2022/Days/Images/Day41_Git14.png) + +아래로 스크롤하면 일부 자동화가 진행 중인 것을 볼 수 있는데, 이 경우 검토가 필요하며 몇 가지 확인이 진행 중입니다. Travis CI가 진행 중이고 빌드가 시작되었음을 알 수 있으며, 업데이트를 확인하여 merge하기 전에 추가한 내용이 손상되지 않았는지 확인합니다. + +![](/2022/Days/Images/Day41_Git15.png) + +위 스크린샷에서 보이는 빨간색은 약간 위협적으로 보일 수 있으며, 마치 실수를 저질렀다고 생각할 수 있습니다. 걱정하지 마세요, 아무것도 망가뜨린 것이 없습니다. 여기서 가장 중요한 팁은 이 과정이 당신과 프로젝트 관리자를 돕기 위한 것이라는 것입니다. 혹시 실수를 저질렀다면 제 경험에 따르면 관리자가 연락하여 다음에 무엇을 해야 할지 조언해줄 것입니다. + +이 pull requests는 이제 모든 사람이 볼 수 있도록 공개되었습니다 [added Kanister presentation/resource #1237](https://github.com/kanisterio/kanister/pull/1237). + +merge 및 pull requests가 수락되기 전에 이 글을 게시하려고 합니다. 따라서 여전히 관심을 가지고 있는 사람들에게 성공적인 PR의 사진을 추가할 수 있는 작은 보상을 제공할 수 있을 것입니다. + +1. 이 저장소를 귀하의 GitHub 계정으로 folk하세요. +2. 사진과 함께 텍스트를 추가해 주세요. +3. 변경 사항을 folk된 저장소에 push하세요. +4. 제가 볼 수 있고 승인할 수 있는 PR을 생성하세요. +5. 일종의 보상을 생각해 볼게요. + +이것으로 Git과 GitHub에 대해 살펴본 내용을 마무리하고, 다음에는 컨테이너를 어떻게, 왜 사용하는지에 대한 큰 그림부터 시작하여 가상화에 대해 살펴보고 여기까지 오게 된 과정을 살펴볼 것입니다. + +## 자료 + +- [Learn GitLab in 3 Hours | GitLab Complete Tutorial For Beginners](https://www.youtube.com/watch?v=8aV5AxJrHDg) +- [BitBucket Tutorials Playlist](https://www.youtube.com/watch?v=OMLh-5O6Ub8&list=PLaD4FvsFdarSyyGl3ooAm-ZyAllgw_AM5) +- [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) +- [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) +- [Git Tutorial for Beginners](https://www.youtube.com/watch?v=8JJ101D3knE&t=52s) +- [Git for Professionals Tutorial](https://www.youtube.com/watch?v=Uszj_k0DGsg) +- [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) +- [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) +- [Git cheatsheet](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) + +[Day 42](day42.md)에서 봐요! diff --git a/2022/ko/Days/day42.md b/2022/ko/Days/day42.md new file mode 100644 index 0000000..17a9ed9 --- /dev/null +++ b/2022/ko/Days/day42.md @@ -0,0 +1,136 @@ +--- +title: '#90DaysOfDevOps - The Big Picture: Containers - Day 42' +published: false +description: 90DaysOfDevOps - The Big Picture Containers +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048826 +--- + +## 큰 그림: 컨테이너 + +이제 다음 섹션을 시작하겠습니다. 이번 섹션에서는 컨테이너, 특히 컨테이너에 대해 더 많이 이해하기 위해 몇 가지 핵심 영역에 대해 살펴보는 Docker를 중점적으로 다룰 것입니다. + +또한 이 섹션뿐만 아니라 챌린지 후반부의 다음 섹션에서도 사용할 수 있는 컨테이너를 만들기 위한 실습도 해보려고 합니다. + +언제나 그렇듯이 이번 첫 번째 포스팅에서는 우리가 어떻게 여기까지 왔는지, 그리고 이 모든 것이 무엇을 의미하는지에 대한 큰 그림에 초점을 맞출 것입니다. + +플랫폼 및 애플리케이션 개발의 역사 가상화 및 컨테이너화에 대해 이야기하고 싶습니다. + +### 왜 애플리케이션을 실행하는 다른 방법일까요? + +가장 먼저 살펴봐야 할 것은 소프트웨어나 애플리케이션을 실행하는 다른 방법이 필요한 이유입니다. 다양한 형태로 애플리케이션을 실행할 수 있기 때문입니다. 물리적 하드웨어에 운영 체제와 단일 애플리케이션이 배포된 애플리케이션을 볼 수도 있고, 가상 머신 또는 클라우드 기반 IaaS 인스턴스가 애플리케이션을 실행한 다음 다시 가상 머신의 데이터베이스에 통합되거나 퍼블릭 클라우드의 PaaS 제품으로 통합되는 것을 볼 수도 있습니다. 또는 애플리케이션이 컨테이너에서 실행되는 것을 볼 수도 있습니다. + +위의 옵션 중 어느 것도 틀린 것도, 옳은 것도 아니지만 각 옵션이 존재해야 하는 이유가 있으며, 저는 이 중 어느 것도 사라지지 않을 것이라고 굳게 믿습니다. 컨테이너와 가상 머신을 비교하는 콘텐츠를 많이 봤는데, 이는 사과와 배를 비교하는 것과 같이 둘 다 과일(애플리케이션을 실행하는 방법)이지만 같은 과일이 아니기 때문에 논쟁을 해서는 안 됩니다. + +또한 애플리케이션을 개발 중이라면 나중에 이러한 영역 중 일부를 다루겠지만 효율성, 속도 및 크기에 관한 것이므로 컨테이너에 기대야 한다고 말씀드리고 싶습니다. 하지만 여기에는 대가가 따르는데, 컨테이너에 대해 전혀 모른다면 그 이유를 이해하고 그 사고방식에 익숙해지려면 학습 곡선을 밟아야 할 것입니다. 애플리케이션을 특정 방식으로 개발했거나 그린필드 환경이 아니라면 컨테이너를 고려하기 전에 해결해야 할 문제가 더 많을 수 있습니다. + +특정 소프트웨어를 다운로드할 때 사용할 수 있는 운영 체제가 다양하기 때문에 선택의 폭이 넓어집니다. 그리고 애플리케이션을 설치하기 위해 수행해야 하는 작업에 대한 구체적인 지침도 있습니다. + +![](/2022/Days/Images/Day42_Containers1.png) + +최근에는 예전에는 전체 서버 OS, 가상 머신, 물리적 또는 클라우드 인스턴스가 필요했던 애플리케이션이 이제 컨테이너 기반 버전의 소프트웨어를 출시하는 경우가 점점 더 많아지고 있습니다. 이는 애플리케이션 개발자에게만 초점을 맞추는 것이 아니라 모든 사람에게 컨테이너와 쿠버네티스의 세계를 열어준다는 점에서 흥미롭습니다. + +![](/2022/Days/Images/Day42_Containers2.png) + +앞서 말씀드렸듯이, 저는 컨테이너가 정답이라고 주장하지는 않겠습니다. 하지만 애플리케이션을 배포할 때 고려해야 할 또 다른 옵션이 컨테이너라는 점을 말씀드리고 싶습니다. + +![](/2022/Days/Images/Day42_Containers4.png) + +최근 10년 동안, 특히 지난 5년간 컨테이너 기술이 인기를 얻은 이유는 무엇일까요? 이미 수십 년 동안 컨테이너 기술이 존재해 왔습니다. 이 문제는 컨테이너와 이미지라는 용어를 두고, 소프트웨어 배포 방식의 도전 과제로 귀결됩니다. 만약 단순히 컨테이너 기술만을 가지고 있다면, 여전히 소프트웨어 관리에 있어서 겪었던 여러 문제들이 계속 발생할 것입니다. + +docker를 도구로 생각하면, docker가 성공할 수 있었던 이유는 쉽게 찾고 사용할 수 있는 이미지 에코시스템 때문입니다. 시스템에 설치하고 실행하는 것이 간단합니다. 그중 가장 중요한 부분은 소프트웨어에서 직면하는 다양한 과제에 대한 전체 공간의 일관성입니다. MongoDB든 nodeJS든 상관없이 두 가지를 모두 실행하는 프로세스는 동일합니다. 중단하는 과정도 마찬가지입니다. 이러한 모든 문제는 여전히 존재하겠지만, 좋은 점은 좋은 컨테이너와 이미지 기술을 함께 사용하면 이러한 다양한 문제를 모두 해결하는 데 도움이 되는 단일 도구 세트를 갖게 된다는 것입니다. 이러한 문제 중 일부는 다음과 같습니다: + +- 먼저 인터넷에서 소프트웨어를 찾아야 합니다. +- 그런 다음, 이 소프트웨어를 다운로드해야 합니다. +- 소스를 신뢰할 수 있는가? +- 라이선스가 필요한가요? 어떤 라이선스가 필요한가요? +- 다른 플랫폼과 호환되는가? +- 패키지는 무엇인가요? 바이너리인가요? 실행 파일인가요? 패키지 관리자? +- 소프트웨어를 어떻게 구성하나요? +- 종속성은 무엇인가요? 전체 다운로드에 포함되어 있나요, 아니면 추가로 필요한가요? +- 종속성의 종속성? +- 애플리케이션을 어떻게 시작하나요? +- 애플리케이션을 어떻게 중지하나요? +- 자동으로 다시 시작되나요? +- 부팅 시 시작되나요? +- 리소스 충돌? +- 충돌하는 라이브러리? +- 포트 충돌 +- 소프트웨어 보안? +- 소프트웨어 업데이트? +- 소프트웨어를 제거하려면 어떻게 해야 하나요? + +위의 내용을 소프트웨어의 복잡성 중 컨테이너와 이미지가 도움이 되는 세 가지 영역으로 나눌 수 있습니다. + +| Distribution | Installation | Operation | +| ------------ | ------------- | ------------------ | +| Find | Install | Start | +| Download | Configuration | Security | +| License | Uninstall | Ports | +| Package | Dependencies | Resource Conflicts | +| Trust | Platform | Auto-Restart | +| Find | Libraries | Updates | + +컨테이너와 이미지는 다른 소프트웨어와 애플리케이션에서 겪을 수 있는 이러한 문제 중 일부를 제거하는 데 도움이 될 것입니다. + +높은 수준에서 설치와 운영을 동일한 목록으로 옮길 수 있으며, 이미지는 배포 관점에서, 컨테이너는 설치와 운영에 도움이 될 것입니다. + +좋아요, 멋지고 흥미진진하게 들리겠지만 컨테이너가 무엇인지 이해할 필요가 있고 이제 이미지를 언급했으니 다음에는 그 부분을 다루겠습니다. + +소프트웨어 개발용 컨테이너에 대해 이야기할 때 많이 보셨을 또 다른 것은 선적 컨테이너와 함께 사용되는 비유입니다. 선적 컨테이너는 대형 선박을 사용하여 바다를 가로질러 다양한 물품을 운송하는 데 사용됩니다. + +![](/2022/Days/Images/Day42_Containers5.png) + +이것이 컨테이너라는 주제와 어떤 관련이 있을까요? 소프트웨어 개발자가 작성하는 코드를 생각해 보세요. 특정 코드를 한 컴퓨터에서 다른 컴퓨터로 어떻게 전송할 수 있을까요? + +앞서 소프트웨어 배포, 설치 및 운영에 대해 다룬 내용을 이제 환경 비주얼로 구축하기 시작하면 다음과 같습니다. 여러 애플리케이션을 실행할 하드웨어와 운영 체제가 있습니다. 예를 들어 nodejs에는 특정 종속성이 있고 특정 라이브러리가 필요합니다. 그런 다음 MySQL을 설치하려면 필요한 라이브러리와 종속성이 필요합니다. 각 소프트웨어 애플리케이션에는 해당 라이브러리와 종속성이 있습니다. 운이 좋아서 특정 라이브러리와 종속성이 충돌하여 문제를 일으키는 애플리케이션 간에 충돌이 발생하지 않을 수도 있지만, 애플리케이션이 많을수록 충돌의 가능성이나 위험은 높아집니다. 그러나 소프트웨어 애플리케이션을 모두 수정한 후 업데이트하면 이러한 충돌이 발생할 수도 있습니다. + +![](/2022/Days/Images/Day42_Containers6.png) + +컨테이너는 이 문제를 해결하는 데 도움이 될 수 있습니다. 컨테이너는 애플리케이션을 **구축**하고, 애플리케이션을 **배송**하고, 이러한 애플리케이션을 독립적으로 쉽게 **배포**하고 **확장**할 수 있도록 도와줍니다. 아키텍처를 살펴보면 하드웨어와 운영체제가 있고 그 위에 나중에 다룰 docker(docker)와 같은 컨테이너 엔진이 있습니다. 컨테이너 엔진 소프트웨어는 라이브러리와 종속성을 함께 패키징하는 컨테이너를 생성하는 데 도움이 되므로 라이브러리와 종속성이 컨테이너 패키지의 일부로 제공되므로 라이브러리와 종속성에 대한 걱정 없이 이 컨테이너를 한 시스템에서 다른 시스템으로 원활하게 이동할 수 있으므로 이 컨테이너는 애플리케이션이 실행하는 데 필요한 기본 종속성에 대한 걱정 없이 시스템 간에 이동이 가능합니다. +애플리케이션이 실행하는 데 필요한 모든 것이 컨테이너로 패키징되어 있기 때문에 +컨테이너로 패키징되어 있기 때문입니다. + +![](/2022/Days/Images/Day42_Containers7.png) + +### 컨테이너의 장점 + +- 컨테이너는 컨테이너 내의 모든 종속성을 패키징하고 격리할 수 있습니다. + +- 컨테이너를 쉽게 관리할 수 있습니다. + +- 한 시스템에서 다른 시스템으로 이동할 수 있습니다. + +- 컨테이너는 소프트웨어를 패키징하는 데 도움이 되며 중복 작업 없이 쉽게 배포할 수 있습니다. + +- 컨테이너는 쉽게 확장할 수 있습니다. + +컨테이너를 사용하면 독립적인 컨테이너를 확장하고 로드 밸런서를 사용할 수 있습니다. +또는 트래픽을 분할하는 데 도움이 되는 서비스를 사용하여 애플리케이션을 수평적으로 확장할 수 있습니다. 컨테이너는 애플리케이션 관리 방식에 있어 많은 유연성과 편의성을 제공합니다. + +### 컨테이너란 무엇인가요? + +컴퓨터에서 애플리케이션을 실행할 때 이 글을 읽는 데 사용하고 있는 웹 브라우저나 VScode가 컨테이너일 수 있습니다. 해당 애플리케이션은 프로세스로 실행되거나 프로세스라고 하는 것으로 알려져 있습니다. 노트북이나 시스템에서는 여러 개의 애플리케이션 또는 프로세스를 실행하는 경향이 있습니다. 새 애플리케이션을 열거나 애플리케이션 아이콘을 클릭하면 이 애플리케이션은 우리가 실행하려는 애플리케이션이며, 때로는 이 애플리케이션이 백그라운드에서 실행하려는 서비스일 수도 있으며, 운영 체제는 백그라운드에서 실행되는 서비스로 가득 차 있어 시스템에서 얻을 수 있는 사용자 경험을 제공합니다. + +이 애플리케이션 아이콘은 파일 시스템 어딘가에 있는 실행 파일에 대한 링크를 나타내며, 운영 체제는 해당 실행 파일을 메모리에 로드합니다. 흥미롭게도 프로세스에 대해 이야기할 때 이 실행 파일을 이미지라고 부르기도 합니다. + +컨테이너는 프로세스로, 컨테이너는 코드와 모든 종속성을 패키징하여 애플리케이션이 한 컴퓨팅 환경에서 다른 컴퓨팅 환경으로 빠르고 안정적으로 실행되도록 하는 소프트웨어의 표준 단위입니다. + +컨테이너화된 소프트웨어는 인프라에 관계없이 항상 동일하게 실행됩니다. 컨테이너는 소프트웨어를 환경으로부터 분리하여 개발 환경과 스테이징 환경 간의 차이에도 불구하고 소프트웨어가 균일하게 작동하도록 보장합니다. + +지난 섹션에서 컨테이너와 이미지의 결합이 어떻게 그리고 왜 우리 에코시스템에서 컨테이너가 인기를 얻게 되었는지에 관해 이미지를 언급했습니다. + +### 이미지란 무엇인가요? + +컨테이너 이미지는 경량의 독립형 실행형 소프트웨어 패키지입니다. + +## 자료 + +- [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) +- [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) +- [Docker Tutorial for Beginners - What is Docker? Introduction to Containers](https://www.youtube.com/watch?v=17Bl31rlnRM&list=WL&index=128&t=61s) +- [Introduction to Container By Red Hat](https://www.redhat.com/en/topics/containers) + +[Day 43](day43.md)에서 봐요! diff --git a/2022/ko/Days/day43.md b/2022/ko/Days/day43.md new file mode 100644 index 0000000..ae51ab3 --- /dev/null +++ b/2022/ko/Days/day43.md @@ -0,0 +1,88 @@ +--- +title: '#90DaysOfDevOps - What is Docker & Getting installed - Day 43' +published: false +description: 90DaysOfDevOps - What is Docker & Getting installed +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048739 +--- + +## Docker를 알아보고 설치하기 + +이전 포스팅에서 docker에 대해 한 번쯤은 언급했는데, 그 이유는 docker가 컨테이너가 오래전부터 사용되어 왔음에도 불구하고 대중화될 수 있었던 혁신적인 기술이기 때문입니다. + +여기서는 docker를 사용하고 설명할 예정이지만, 벤더 종속의 위험을 피하면서 혁신을 장려하는 산업 표준 조직인 [Open Container Initiative(OCI)](https://www.opencontainers.org/)에 대해서도 언급해야 합니다. OCI 덕분에 컨테이너 툴체인을 선택할 때 Docker, [CRI-O](https://cri-o.io/), [Podman](http://podman.io/), [LXC](https://linuxcontainers.org/) 등을 선택할 수 있게 되었습니다. + +docker는 컨테이너를 빌드, 실행 및 관리하기 위한 소프트웨어 프레임워크입니다. "docker"라는 용어는 도구(명령어 및 데몬) 또는 Dockerfile 파일 형식을 지칭할 수 있습니다. + +여기서는 (교육 및 학습용으로) 무료인 Docker Personal을 사용하겠습니다. 여기에는 컨테이너와 도구에 대한 지식의 기초를 다지기 위해 다루어야 할 모든 필수 사항이 포함됩니다. + +우리가 사용할 몇 가지 "docker" 도구와 그 용도를 세분화해 볼 가치가 있을 것입니다. docker라는 용어는 개발자와 관리자가 애플리케이션을 개발, 배포 및 실행하기 위한 플랫폼인 docker 프로젝트 전반을 지칭할 수 있습니다. 또한 이미지와 컨테이너를 관리하는 호스트에서 실행되는 docker 데몬 프로세스를 지칭할 수도 있으며, Docker Engine이라고도 합니다. + +### Docker Engine + +Docker Engine은 애플리케이션을 빌드하고 컨테이너화하기 위한 오픈소스 컨테이너화 기술입니다. Docker Engine은 클라이언트-서버 애플리케이션으로 작동합니다: + +- 장기 실행 데몬 프로세스인 dockerd가 있는 서버. +- API는 프로그램이 Docker 데몬과 대화하고 지시하는 데 사용할 수 있는 인터페이스를 지정합니다. +- 커맨드라인 인터페이스(CLI) 클라이언트 docker입니다. + +위의 내용은 공식 docker 문서와 특정 [Docker Engine 개요](https://docs.docker.com/engine/)에서 발췌한 것입니다. + +### Docker Desktop + +저희는 Windows와 macOS 시스템 모두를 위한 Docker Desktop을 제공합니다. 설치하기 쉬운 경량 docker 개발 환경입니다. 호스트 운영 체제의 가상화 기능을 활용하는 네이티브 OS 애플리케이션입니다. + +Windows 또는 macOS에서 docker화된 애플리케이션을 빌드, 디버그, 테스트, 패키징 및 출시하려는 경우 가장 적합한 솔루션입니다. + +Windows에서는 WSL2와 Microsoft Hyper-V도 활용할 수 있습니다. WSL2의 몇 가지 이점은 차근차근 살펴보도록 하겠습니다. + +호스트 운영 체제의 하이퍼바이저 기능과 통합되어 있기 때문에 docker는 리눅스 운영 체제에서 컨테이너를 실행할 수 있는 기능을 제공합니다. + +### Docker Compose + +Docker Compose는 여러 컨테이너에서 더 복잡한 앱을 실행할 수 있는 도구입니다. 단일 파일과 명령을 사용하여 애플리케이션을 스핀업할 수 있다는 이점이 있습니다. + +### DockerHub + +docker와 그 구성 요소로 작업하기 위한 중앙 집중식 리소스입니다. 가장 일반적으로는 docker 이미지를 호스팅하는 레지스트리로 알려져 있습니다. 그러나 여기에는 부분적으로 자동화와 함께 사용하거나 보안 검사뿐만 아니라 GitHub에 통합할 수 있는 많은 추가 서비스가 있습니다. + +### Dockerfile + +Dockerfile은 일반적으로 docker 이미지를 빌드하기 위해 수동으로 실행하는 명령이 포함된 텍스트 파일입니다. docker는 Dockerfile에 있는 지침을 읽어 이미지를 자동으로 빌드할 수 있습니다. + +## Docker Desktop 설치 + +[Docker 문서](https://docs.docker.com/engine/install/)는 매우 훌륭하며, 이제 막 docker에 입문하는 분이라면 꼭 한 번 읽어보시기 바랍니다. 여기서는 WSL2가 설치된 Windows에서 Docker Desktop을 사용하겠습니다. 여기서 사용하는 머신에 이미 설치를 완료했습니다. + +![](/2022/Days/Images/Day43_Containers1.png) + +설치를 진행하기 전에 시스템 요구 사항을 참고하시기 바라며, [윈도우에 Docker Desktop 설치하기](https://docs.docker.com/desktop/windows/install/)를 참고하시고, M1 기반 CPU 아키텍처를 포함한 맥OS를 사용하시는 경우 [맥OS에 docker Desktop 설치하기](https://docs.docker.com/desktop/mac/install/)도 참고하시면 됩니다. + +다른 윈도우 머신에서 윈도우용 docker Desktop 설치를 실행하고 그 과정을 아래에 기록해 보겠습니다. + +### Windows + +- 장치의 운영 체제로 Windows를 선택합니다. + + +- 인스톨러를 저장할 폴더로 이동하여 저장합니다. + +- 인스톨러를 실행하고 몇 초간 기다린 후 WSL에 대한 액세스 권한을 부여합니다. + + +- 확인을 클릭하면 설치가 시작됩니다. + + +- Docker Desktop이 장치에 성공적으로 설치되었습니다. 이제 터미널에서 "docker" 명령을 실행하여 설치가 성공적으로 완료되었는지 확인할 수 있습니다. + + +## 자료 + +- [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) +- [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) +- [Docker Tutorial for Beginners - What is Docker? Introduction to Containers](https://www.youtube.com/watch?v=17Bl31rlnRM&list=WL&index=128&t=61s) +- [WSL 2 with Docker getting started](https://www.youtube.com/watch?v=5RQbdMn04Oc) + +[Day 44](day44.md)에서 봐요! diff --git a/2022/ko/Days/day44.md b/2022/ko/Days/day44.md new file mode 100644 index 0000000..37350ed --- /dev/null +++ b/2022/ko/Days/day44.md @@ -0,0 +1,141 @@ +--- +title: '#90DaysOfDevOps - Docker Images & Hands-On with Docker Desktop - Day 44' +published: false +description: 90DaysOfDevOps - Docker Images & Hands-On with Docker Desktop +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048708 +--- + +## Docker 이미지 및 Docker Desktop 실습하기 + +이제 시스템에 Docker Desktop을 설치했습니다. (Linux를 실행하는 경우 여전히 옵션은 있지만 GUI는 없지만 Docker는 Linux에서 작동합니다.)[우분투에 Docker Engine 설치](https://docs.docker.com/engine/install/ubuntu/) (다른 배포판도 사용할 수 있습니다.) + +이 글에서는 몇 가지 이미지를 우리 환경에 배포하는 작업을 시작하겠습니다. Docker 이미지에 대한 요약 - Docker 이미지는 Docker 컨테이너에서 코드를 실행하는 데 사용되는 파일입니다. Docker 이미지는 템플릿처럼 Docker 컨테이너를 빌드하기 위한 일련의 지침 역할을 합니다. 또한 Docker 이미지는 Docker를 사용할 때 시작점 역할을 하기도 합니다. + +지금 바로 [DockerHub](https://hub.docker.com/)에서 계정을 생성하세요. + +![](/2022/Days/Images/Day44_Containers1.png) + +DockerHub는 Docker 및 그 구성 요소로 작업하기 위한 중앙 집중식 리소스입니다. 가장 일반적으로는 docker 이미지를 호스팅하는 레지스트리로 알려져 있습니다. 그러나 여기에는 부분적으로 자동화와 함께 사용하거나 보안 검사뿐만 아니라 GitHub에 통합할 수 있는 많은 추가 서비스가 있습니다. + +로그인한 후 아래로 스크롤하면 컨테이너 이미지 목록이 표시되며, MySQL, hello-world 등의 데이터베이스 이미지가 표시될 수 있습니다. 데이터베이스 이미지가 필요하거나 직접 만들 필요가 없는 경우 공식 이미지를 사용하는 것이 가장 좋습니다. + +![](/2022/Days/Images/Day44_Containers2.png) + +사용 가능한 이미지 보기를 더 자세히 살펴보고 카테고리, 운영 체제 및 아키텍처에 따라 검색할 수 있습니다. 아래에서 강조 표시한 것은 공식 이미지로, 이 컨테이너 이미지의 출처에 대해 안심할 수 있습니다. + +![](/2022/Days/Images/Day44_Containers3.png) + +특정 이미지를 검색할 수도 있습니다. 예를 들어 워드프레스가 좋은 기본 이미지가 될 수 있으므로 상단에 있는 이미지를 검색하여 워드프레스와 관련된 모든 컨테이너 이미지를 찾을 수 있습니다. 아래는 확인된 퍼블리셔에 대한 공지사항입니다. + +- 공식 이미지 - Docker 공식 이미지는 엄선된 Docker 오픈 소스 및 "drop-in" 솔루션 리포지토리 집합입니다. + +- 검증된 퍼블리셔 - 검증된 퍼블리셔의 고품질 Docker 콘텐츠입니다. 이러한 제품은 상업적 주체가 직접 게시하고 유지 관리합니다. + +![](/2022/Days/Images/Day44_Containers4.png) + +### Docker Desktop 살펴보기 + +저희 시스템에는 Docker Desktop이 설치되어 있으며, 이 파일을 열면 이미 설치되어 있지 않다면 아래 이미지와 비슷한 것을 볼 수 있을 것입니다. 보시다시피 컨테이너가 실행되고 있지 않고 Docker Engine이 실행되고 있습니다. + +![](/2022/Days/Images/Day44_Containers5.png) + +새로 설치한 것이 아니기 때문에 이미 다운로드하여 시스템에 사용할 수 있는 이미지가 몇 개 있습니다. 여기에는 아무것도 표시되지 않을 것입니다. + +![](/2022/Days/Images/Day44_Containers6.png) + +원격 리포지토리 아래에서 DockerHub에 저장한 컨테이너 이미지를 찾을 수 있습니다. 아래에서 볼 수 있듯이 이미지가 없습니다. + +![](/2022/Days/Images/Day44_Containers7.png) + +DockerHub 사이트에서도 리포지토리가 없음을 확인할 수 있습니다. + +![](/2022/Days/Images/Day44_Containers8.png) + +다음으로 Volumes 탭이 있는데, 지속성이 필요한 컨테이너가 있는 경우 여기에서 로컬 파일 시스템이나 공유 파일 시스템에 이러한 Volumes를 추가할 수 있습니다. + +![](/2022/Days/Images/Day44_Containers9.png) + +이 글을 쓰는 시점에 Environments 탭도 있는데, 이 탭은 다른 git branch 사이를 이동하지 않고 팀과 협업하는 데 도움이 될 것입니다. 여기서는 다루지 않겠습니다. + +![](/2022/Days/Images/Day44_Containers10.png) + +첫 번째 탭으로 돌아가면 시작 컨테이너를 실행할 수 있는 명령이 있음을 알 수 있습니다. 터미널에서 `docker run -d -p 80:80 docker/getting-started`를 실행해 보겠습니다. + +![](/2022/Days/Images/Day44_Containers11.png) + +Docker Desktop 창을 다시 확인하면 컨테이너가 실행 중인 것을 확인할 수 있습니다. + +![](/2022/Days/Images/Day44_Containers12.png) + +WSL2를 사용하고 있다는 것을 눈치채셨을 텐데요, 이를 사용하려면 설정에서 이 기능이 활성화되어 있는지 확인해야 합니다. + +![](/2022/Days/Images/Day44_Containers13.png) + +이제 Images 탭으로 다시 이동하여 확인하면 이제 사용 중인 이미지인 docker/getting-started를 볼 수 있습니다. + +![](/2022/Days/Images/Day44_Containers14.png) + +Containers/Apps 탭으로 돌아가서 실행 중인 컨테이너를 클릭합니다. 기본적으로 로그가 표시되고 상단에 선택할 수 있는 몇 가지 옵션이 있는데, 이 컨테이너에서 실행 중인 웹 페이지가 될 것이 확실하므로 브라우저에서 열기를 선택하겠습니다. + +![](/2022/Days/Images/Day44_Containers15.png) + +위의 버튼을 누르면 로컬호스트로 연결되는 웹 페이지가 열리고 아래와 비슷한 내용이 표시됩니다. + +이 컨테이너에는 컨테이너와 이미지에 대한 자세한 내용도 있습니다. + +![](/2022/Days/Images/Day44_Containers16.png) +이제 첫 번째 컨테이너를 실행했습니다. 아직은 쉽습니다. 컨테이너 이미지 중 하나를 DockerHub에서 가져오고 싶다면 어떻게 해야 할까요? 아마도 우리가 사용할 수 있는 `hello world` docker 컨테이너가 있을 것입니다. + +시작 컨테이너는 리소스를 많이 차지하기 때문이 아니라 몇 가지 단계를 더 진행하면서 깔끔하게 정리하기 위해 중단했습니다. + +터미널로 돌아와서 `docker run hello-world`를 실행하고 어떤 일이 일어나는지 살펴봅시다. + +로컬에 이미지가 없었기 때문에 이미지를 끌어내렸고, 컨테이너 이미지에 시작 및 실행에 대한 몇 가지 정보와 참조 지점에 대한 링크가 포함된 메시지가 표시되는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day44_Containers17.png) + +그러나 이제 Docker Desktop을 살펴보면 실행 중인 컨테이너는 없지만, hello-world 메시지를 사용한 종료된 컨테이너, 즉 시작되어 메시지를 전달한 후 종료된 컨테이너는 있습니다. + +![](/2022/Days/Images/Day44_Containers18.png) + +마지막으로 Images 탭을 확인해보면 시스템에 로컬로 새로운 hello-world 이미지가 있는 것을 확인할 수 있습니다. 즉, 터미널에서 `docker run hello-world` 명령을 다시 실행해도 버전이 변경되지 않는 한 아무것도 가져올 필요가 없습니다. + +![](/2022/Days/Images/Day44_Containers19.png) + +'hello-world' 컨테이너에서 온 메시지로 인해 조금 더 야심찬 도전을 하고 싶어졌습니다. + +도전! + +![](/2022/Days/Images/Day44_Containers20.png) + +터미널에서 `docker run -it ubuntu bash`를 실행할 때 우리는 운영 체제의 전체 복사본이 아닌 우분투의 컨테이너화된 버전을 실행할 것입니다. 이 특정 이미지에 대한 자세한 내용은 [DockerHub](https://hub.docker.com/_/ubuntu)에서 확인할 수 있습니다. + +아래 명령어를 실행하면 대화형 프롬프트(`-it`)가 나타나고 컨테이너에 bash 셸이 생성되는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day44_Containers21.png) + +bash 셸이 있지만 그 이상은 없기 때문에 이 컨테이너 이미지는 30MB 미만입니다. + +![](/2022/Days/Images/Day44_Containers22.png) + +하지만 여전히 이 이미지를 사용할 수 있고, apt package manager를 사용하여 소프트웨어를 설치할 수 있으며, 컨테이너 이미지를 업데이트하고 업그레이드할 수도 있습니다. + +![](/2022/Days/Images/Day44_Containers23.png) + +또는 컨테이너에 일부 소프트웨어를 설치하고 싶을 수도 있습니다. pinta는 이미지 편집기이고 200MB가 넘기 때문에 여기서는 정말 나쁜 예를 선택했지만 제가 이걸로 무엇을 하려는지 이해하시길 바랍니다. 이렇게 하면 컨테이너의 크기가 상당히 커지지만, 여전히 GB가 아닌 MB 단위로 사용할 것입니다. + +![](/2022/Days/Images/Day44_Containers24.png) + +이 글에서는 사용 사례를 통해 Docker Desktop과 컨테이너의 세계에 대한 개요를 간단하고 접근하기 쉬운 방식으로 제공하고자 합니다. 그러나 컨테이너 이미지를 다운로드하고 사용하는 것 외에도 네트워킹, 보안 및 기타 사용 가능한 옵션에 대해서도 다뤄야 합니다. 이 섹션의 궁극적인 목표는 무언가를 만들어서 DockerHub 리포지토리에 업로드하고 배포하는 것입니다. + +## 자료 + +- [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) +- [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) +- [Docker Tutorial for Beginners - What is Docker? Introduction to Containers](https://www.youtube.com/watch?v=17Bl31rlnRM&list=WL&index=128&t=61s) +- [WSL 2 with Docker getting started](https://www.youtube.com/watch?v=5RQbdMn04Oc) + +[Day 45](day45.md)에서 봐요! diff --git a/2022/ko/Days/day45.md b/2022/ko/Days/day45.md new file mode 100644 index 0000000..ff1359b --- /dev/null +++ b/2022/ko/Days/day45.md @@ -0,0 +1,119 @@ +--- +title: '#90DaysOfDevOps - The anatomy of a Docker Image - Day 45' +published: false +description: 90DaysOfDevOps - The anatomy of a Docker Image +tags: 'DevOps, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048777 +--- + +## Docker 이미지의 구조 + +지난 세션에서는 DockerHub와 결합된 Docker Desktop을 사용하여 몇 가지 검증된 이미지를 배포하고 실행하는 방법에 대한 몇 가지 기본 사항을 다루었습니다. 이미지가 무엇인지에 대한 요약을 계속 언급하면 잊어버리지 않을 것입니다. + +Docker 이미지는 Docker 플랫폼에서 실행할 수 있는 컨테이너를 만들기 위한 일련의 지침이 포함된 읽기 전용 템플릿입니다. 애플리케이션과 사전 구성된 서버 환경을 패키징하여 개인적으로 사용하거나 다른 Docker 사용자와 공개적으로 공유할 수 있는 편리한 방법을 제공합니다. 또한 Docker 이미지는 Docker를 처음 사용하는 모든 사용자에게 시작점이 됩니다. + +자체 Docker 이미지를 만들려면 어떻게 해야 하나요? 이를 위해서는 Dockerfile을 생성해야 합니다. 우분투 컨테이너 이미지를 가져와서 소프트웨어를 추가하면 원하는 소프트웨어가 포함된 컨테이너 이미지를 갖게 되고 모든 것이 좋지만, 컨테이너가 종료되거나 폐기되면 모든 소프트웨어 업데이트와 설치가 사라져 반복할 수 있는 버전이 없습니다. 따라서 컨테이너를 실행할 때마다 동일한 소프트웨어 세트가 설치된 여러 환경에 걸쳐 이미지를 전송하는 데는 도움이 되지 않습니다. + +### Dockerfile이란? + +Dockerfile은 일반적으로 docker 이미지를 빌드하기 위해 수동으로 실행하는 명령이 포함된 텍스트 파일입니다. docker는 Dockerfile에 있는 지침을 읽어 이미지를 자동으로 빌드할 수 있습니다. + +docker 이미지를 구성하는 각 파일을 레이어라고 하며, 이러한 레이어는 단계적으로 서로 위에 빌드되는 일련의 이미지를 형성합니다. 각 레이어는 바로 아래 레이어에 종속됩니다. 레이어의 순서는 docker 이미지의 라이프사이클 관리 효율성의 핵심입니다. + +가장 자주 변경되는 레이어는 가능한 한 스택에서 가장 높은 곳에 구성해야 하는데, 이는 이미지의 레이어를 변경하면 Docker가 해당 레이어뿐만 아니라 해당 레이어에서 빌드된 모든 레이어를 다시 빌드하기 때문입니다. 따라서 맨 위에 있는 레이어를 변경하면 전체 이미지를 다시 빌드하는 데 필요한 작업량이 가장 적습니다. + +docker가 이미지로부터 컨테이너를 실행할 때마다 (어제 실행한 것처럼), 컨테이너 레이어라고 하는 쓰기 가능한 레이어가 추가됩니다. 이 레이어는 컨테이너가 실행되는 동안 모든 변경 사항을 저장합니다. 이 레이어는 실제 운영 중인 컨테이너와 소스 이미지 자체 사이의 유일한 차이점입니다. 같은 이미지에 기반한 동일한 컨테이너들이 상태를 유지하면서 액세스를 공유할 수 있습니다. + +예제로 돌아가서, 어제 우분투 이미지를 사용했습니다. 동일한 명령을 여러 번 실행하여 첫 번째 컨테이너에는 pinta를 설치하고 두 번째 컨테이너에는 두 개의 다른 애플리케이션, 다른 목적, 다른 크기 등을 가진 figlet을 설치할 수 있습니다. 배포한 각 컨테이너는 동일한 이미지를 공유하지만, 동일한 상태는 아니며, 컨테이너를 제거하면 해당 상태는 사라집니다. + +![](/2022/Days/Images/Day45_Containers1.png) + +위의 예제에서 우분투 이미지뿐만 아니라 DockerHub 및 기타 서드파티 리포지토리에서 사용할 수 있는 다른 많은 기성 컨테이너 이미지도 마찬가지입니다. 이러한 이미지를 일반적으로 부모 이미지라고 합니다. 이 이미지는 다른 모든 레이어가 구축되는 기반이 되며 컨테이너 환경의 기본 구성 요소를 제공합니다. + +개별 레이어 파일 세트와 함께 Docker 이미지에는 manifest라는 추가 파일도 포함됩니다. 이 파일은 기본적으로 이미지에 대한 JSON 형식의 설명이며 이미지 태그, 전자 서명, 다양한 유형의 호스트 플랫폼에 맞게 컨테이너를 구성하는 방법에 대한 세부 정보와 같은 정보로 구성됩니다. + +![](/2022/Days/Images/Day45_Containers2.png) + +### Docker 이미지를 생성하는 방법 + +docker 이미지를 생성하는 방법에는 두 가지가 있습니다. 어제 시작한 프로세스로 즉석에서 만들 수 있습니다. 기본 이미지를 선택하여 해당 컨테이너를 스핀업하고 컨테이너에 원하는 모든 소프트웨어와 종속성을 설치합니다. + +그런 다음 `docker commit container name`을 사용하면 이 이미지의 로컬 복사본이 docker 이미지와 Docker Desktop 이미지 탭 아래에 있습니다. + +매우 간단하지만, 프로세스를 이해하고 싶은 게 아니라면, 이 방법을 권장하지 않습니다. 이 방법은 라이프사이클 관리를 관리하기가 매우 어렵고 수동 구성/재구성이 많이 필요합니다. 하지만 docker 이미지를 빌드하는 가장 빠르고 간단한 방법입니다. 테스트, 문제 해결, 종속성 검증 등에 적합합니다. + +우리가 이미지를 생성하려는 방법은 Dockerfile을 통한 방법입니다. 이는 이미지를 만드는 깔끔하고 간결하며 반복 가능한 방법을 제공합니다. 더 쉬운 라이프사이클 관리와 지속적인 통합 및 지속적인 배포 프로세스에 쉽게 통합할 수 있습니다. 하지만 처음 언급된 방법보다 조금 더 어려울 수 있습니다. + +Dockerfile 방법을 사용하는 것이 실제 엔터프라이즈급 컨테이너 배포에 훨씬 더 잘 맞습니다. + +Dockerfile은 3단계 프로세스를 통해 Dockerfile을 만들고 이미지를 조립하는 데 필요한 명령을 추가합니다. + +다음 표는 사용자가 가장 많이 사용할 가능성이 높은 몇 가지 Dockerfile 설정을 보여줍니다. + +| Command | Purpose | +| ---------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| FROM | 상위 이미지를 지정합니다. | +| WORKDIR | Dockerfile에서 다음에 나오는 명령의 작업 디렉터리를 설정합니다. | +| RUN | 컨테이너에 필요한 애플리케이션과 패키지를 설치합니다. | +| COPY | 특정 위치에서 파일 또는 디렉터리를 복사합니다. | +| ADD | 복사뿐만 아니라 원격 URL을 처리하고 압축 파일의 압축을 풀 수도 있습니다. | +| ENTRYPOINT | 컨테이너가 시작될 때 항상 실행되는 명령입니다. 지정하지 않으면 기본값은 "/bin/sh -c"입니다. | +| CMD | 엔트리포인트로 전달된 인자입니다. 엔트리포인트가 설정되지 않은 경우(기본값은 "/bin/sh -c"), 컨테이너가 실행하는 명령은 CMD가 됩니다. | +| EXPOSE | 컨테이너 애플리케이션에 액세스할 포트를 정의합니다. | +| LABEL | 이미지에 메타데이터를 추가합니다. | + +이제 첫 번째 Dockerfile을 빌드하는 방법에 대한 세부 정보를 얻었으므로 작업 디렉터리를 생성하고 Dockerfile을 만들 수 있습니다. 이 리포지토리 내에 작업 디렉터리를 만들었는데, [여기서](/2022/Days/Containers/) 제가 살펴봐야 할 파일과 폴더를 볼 수 있습니다. + +이 디렉터리에는 지난 섹션에서 사용한 .gitignore와 유사한 .dockerignore 파일을 만들겠습니다. 이 파일에는 최종 빌드에서 제외하려는 Docker 빌드 프로세스 중에 생성되는 모든 파일이 나열됩니다. + +컨테이너는 부피가 커지지 않고 가능한 한 빠르게 컴팩트하게 만들어야 함을 기억하세요. + +위에 링크된 폴더에서 아래 레이아웃으로 매우 간단한 Dockerfile을 만들고 싶습니다. + +```dockerfile +# 공식 우분투 18.04를 기본으로 사용하세요. +FROM ubuntu:18.04 +# nginx 및 curl 설치 +RUN apt-get update && apt-get upgrade -y +RUN apt-get install -y nginx curl +RUN rm -rf /var/lib/apt/lists/* +``` + +터미널에서 이 디렉토리로 이동한 다음 `docker build -t 90daysofdevops:0.1 .`를 실행합니다. `-t`를 사용한 다에는 이미지 이름과 태그를 설정할 수 있습니다. + +![](/2022/Days/Images/Day45_Containers3.png) + +이제 이미지를 만들었으므로 Docker Desktop을 사용하여 이미지를 실행하거나 docker 커맨드라인을 사용할 수 있습니다. 저의 경우에는 Docker Desktop을 사용하여 컨테이너를 실행하고, 컨테이너의 cli에서 `curl`을 사용한 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day45_Containers4.png) + +Docker Desktop에서는 UI를 활용하여 이 새로운 이미지로 몇 가지 작업을 더 수행할 수 있습니다. + +![](/2022/Days/Images/Day45_Containers5.png) + +이미지를 검사하면 컨테이너 내에서 실행하려고 하는 Dockerfile과 코드들을 매우 많이 볼 수 있습니다. + +![](/2022/Days/Images/Day45_Containers6.png) + +pull 옵션이 있지만, 이 이미지는 어디에도 호스팅되지 않기 때문에 이 옵션은 실패할 것이고 오류로 표시됩니다. 하지만 Push to hub 옵션이 있어 이미지를 DockerHub로 push할 수 있습니다. + +앞서 실행한 것과 동일한 `docker build`를 사용하는 경우에도 이 방법이 작동하지 않으므로 빌드 명령을 `docker build -t {{username}}/{{imagename}}:{{version}}`로 해야 합니다. + +![](/2022/Days/Images/Day45_Containers7.png) + +이제 DockerHub 리포지토리로 이동하여 살펴보면 방금 새 이미지를 push한 것을 확인할 수 있습니다. 이제 Docker Desktop에서 해당 pull 탭을 사용할 수 있습니다. + +![](/2022/Days/Images/Day45_Containers8.png) + +## 자료 + +- [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) +- [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) +- [Docker Tutorial for Beginners - What is Docker? Introduction to Containers](https://www.youtube.com/watch?v=17Bl31rlnRM&list=WL&index=128&t=61s) +- [WSL 2 with Docker getting started](https://www.youtube.com/watch?v=5RQbdMn04Oc) +- [Blog on gettng started building a docker image](https://stackify.com/docker-build-a-beginners-guide-to-building-docker-/2022/Days/images/) +- [Docker documentation for building an image](https://docs.docker.com/develop/develop-/2022/Days/images/dockerfile_best-practices/) + +[Day 46](day46.md)에서 봐요! diff --git a/2022/ko/Days/day46.md b/2022/ko/Days/day46.md new file mode 100644 index 0000000..bf81ef0 --- /dev/null +++ b/2022/ko/Days/day46.md @@ -0,0 +1,183 @@ +--- +title: '#90DaysOfDevOps - Docker Compose - Day 46' +published: false +description: 90DaysOfDevOps - Docker Compose +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048740 +--- + +## Docker Compose + +하나의 컨테이너를 실행할 수 있는 기능은 단일 사용 사례에 필요한 모든 것을 갖춘 독립적인 이미지가 있는 경우 유용할 수 있지만, 서로 다른 컨테이너 이미지 간에 여러 애플리케이션을 빌드하려는 경우 흥미로운 문제가 발생할 수 있습니다. 예를 들어, 웹사이트 프론트엔드가 있지만 백엔드 데이터베이스가 필요한 경우 모든 것을 하나의 컨테이너에 넣을 수 있지만 데이터베이스용 컨테이너를 사용하는 것이 더 효율적이고 좋을 것입니다. + +이때 여러 컨테이너에서 더 복잡한 앱을 실행할 수 있는 도구인 Docker Compose가 등장합니다. 단일 파일과 명령을 사용하여 애플리케이션을 스핀업할 수 있다는 이점이 있습니다. 이 글에서 안내하는 예제는 [Docker 빠른 시작 샘플 앱(빠른 시작: 작성 및 워드프레스)](https://docs.docker.com/samples/wordpress/)에서 가져온 것입니다. + +이 첫 번째 예제에서는 + +- Docker Compose를 사용하여 WordPress와 별도의 MySQL 인스턴스를 불러옵니다. +- 'docker-compose.yml'이라는 YAML 파일을 사용합니다. +- 프로젝트 빌드 +- 브라우저를 통해 워드프레스 구성 +- 종료 및 정리 + +### Docker Compose 설치 + +앞서 언급했듯이 docker compose는 도구이며, 맥OS나 윈도우를 사용하는 경우 Docker Desktop 설치에 compose가 포함되어 있습니다. 하지만, 윈도우 서버 호스트나 리눅스 서버에서 컨테이너를 실행하고 싶을 수 있으며, 이 경우 다음 [docker compose 설치](https://docs.docker.com/compose/install/) 지침을 사용하여 설치할 수 있습니다. + +터미널을 열고 위의 명령어를 입력하면 시스템에 `docker-compose`가 설치되었는지 확인할 수 있습니다. + +![](/2022/Days/Images/Day46_Containers1.png) + +### Docker-Compose.yml(YAML) + +다음에 이야기할 것은 리포지토리의 컨테이너 폴더에서 찾을 수 있는 docker-compose.yml입니다. 그 전에, YAML에 대해 조금 설명하겠습니다. + +거의 모든 프로그래밍 언어에서 사용할 수 있는 YAML은 다양한 곳에서 사용될 수 있습니다. + +"YAML은 모든 프로그래밍 언어에 대한 인간 친화적인 데이터 직렬화 언어입니다." + +일반적으로 구성 파일과 데이터를 저장하거나 전송하는 일부 애플리케이션에서 사용됩니다. 동일한 구성 파일을 제공하는 경향이 있는 XML 파일을 접한 적이 있을 것입니다. YAML은 최소한의 구문을 제공하지만, 동일한 사용 사례를 목표로 합니다. + +YAML(YAML Ain't Markup Language)은 지난 몇 년 동안 꾸준히 인기가 높아진 직렬화 언어입니다. 객체 직렬화 기능 덕분에 JSON과 같은 언어를 대체할 수 있습니다. + +YAML의 약어는 Yet Another Markup Language의 약자였습니다. 그러나 유지 관리자는 데이터 지향적 기능을 더 강조하기 위해 YAML Ain't Markup Language로 이름을 변경했습니다. + +어쨌든, 다시 docker-compose.yml 파일로 돌아가겠습니다. 이 파일은 단일 시스템에 여러 개의 컨테이너를 배포할 때 수행하고자 하는 작업의 구성 파일입니다. + +위에 링크된 튜토리얼에서 바로 파일의 내용을 보면 다음과 같이 보입니다: + +```yaml +version: '3.9' + +services: + DB: + image: mysql:5.7 + volumes: + - db_data:/var/lib/mysql + restart: always + environment: + MYSQL_ROOT_PASSWORD: somewordpress + MYSQL_DATABASE: wordpress + MYSQL_USER: wordpress + MYSQL_PASSWORD: wordpress + + wordpress: + depends_on: + - db + image: wordpress:latest + volumes: + - wordpress_data:/var/www/html + ports: + - '8000:80' + restart: always + environment: + WORDPRESS_DB_HOST: db + WORDPRESS_DB_USER: wordpress + WORDPRESS_DB_PASSWORD: wordpress + WORDPRESS_DB_NAME: wordpress +volumes: + db_data: {} + wordpress_data: {} +``` + +버전을 선언한 다음, 이 docker-compose.yml 파일의 대부분은 서비스로 구성되어 있으며, DB 서비스와 워드프레스 서비스가 있습니다. 각 서비스에는 버전 태그가 연결된 이미지가 정의되어 있는 것을 볼 수 있습니다. 이제 첫 번째 연습과 달리 구성에 상태도 도입하고 있는데, 데이터베이스를 저장할 수 있도록 볼륨을 생성하겠습니다. + +그런 다음 비밀번호 및 사용자 이름과 같은 몇 가지 환경 변수가 있습니다. 이러한 파일은 매우 복잡해질 수 있지만 YAML 구성 파일을 사용하면 전체적으로 단순화할 수 있습니다. + +### 프로젝트 빌드 + +이제 터미널로 돌아가서 docker-compose 도구로 몇 가지 명령을 사용할 수 있습니다. 디렉토리로 이동하여 docker-compose.yml 파일이 있는 디렉터리로 이동합니다. + +터미널에서 `docker-compose up -d`를 실행하면 해당 이미지를 가져와 멀티 컨테이너 애플리케이션을 세우는 프로세스가 시작됩니다. + +이 명령의 `-d`는 분리 모드를 의미하며, 이는 실행 명령이 백그라운드에서 실행 중이거나 실행될 것임을 의미합니다. + +![](/2022/Days/Images/Day46_Containers2.png) + +이제 `docker ps` 명령을 실행하면 2개의 컨테이너가 실행 중이며 하나는 WordPress이고 다른 하나는 MySQL인 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day46_Containers3.png) + +다음으로 브라우저를 열고 `http://localhost:8000`으로 이동하면 WordPress가 실행 중인지 확인할 수 있으며, WordPress 설정 페이지가 표시됩니다. + +![](/2022/Days/Images/Day46_Containers4.png) + +워드프레스 설정을 완료한 다음 아래 콘솔에서 원하는 대로 웹사이트 구축을 시작할 수 있습니다. + +![](/2022/Days/Images/Day46_Containers5.png) + +이제 새 탭을 열고 `http://localhost:8000` 이전과 동일한 주소로 이동하면 사이트 제목이 "90DaysOfDevOps"인 간단한 기본 테마가 표시되고 샘플 게시물이 표시됩니다. + +![](/2022/Days/Images/Day46_Containers6.png) + +변경하기 전에 Docker Desktop을 열고 볼륨 탭으로 이동하면 컨테이너와 연결된 두 개의 볼륨(하나는 워드프레스용, 다른 하나는 DB용)을 볼 수 있습니다. + +![](/2022/Days/Images/Day46_Containers7.png) + +현재 워드프레스 테마는 "Twenty Twenty-Two"이며 이를 "Twenty Twenty"로 변경하고 싶습니다. 대시보드로 돌아와서 변경할 수 있습니다. + +![](/2022/Days/Images/Day46_Containers8.png) + +또한 사이트에 새 게시물을 추가하려고 하는데, 아래에서 새 사이트의 최신 버전을 볼 수 있습니다. + +![](/2022/Days/Images/Day46_Containers9.png) + +### 정리 여부 + +이제 `docker-compose down` 명령을 사용하면 컨테이너가 삭제됩니다. 하지만 볼륨은 그대로 유지됩니다. + +![](/2022/Days/Images/Day46_Containers10.png) + +Docker Desktop에서 볼륨이 여전히 존재한다는 것을 확인할 수 있습니다. + +![](/2022/Days/Images/Day46_Containers11.png) + +그런 다음 다시 백업하려면 동일한 디렉토리 내에서 `docker up -d` 명령을 실행하면 애플리케이션을 다시 백업하고 실행할 수 있습니다. + +![](/2022/Days/Images/Day46_Containers12.png) + +그런 다음 브라우저에서 동일한 주소인 `http://localhost:8000`으로 이동하면 새 글과 테마 변경 사항이 모두 그대로 유지되는 것을 확인할 수 있습니다. + +![](/2022/Days/Images/Day46_Containers13.png) + +컨테이너와 해당 볼륨을 제거하려면 `docker-compose down --volumes`를 실행하면 볼륨도 제거됩니다. + +![](/2022/Days/Images/Day46_Containers14.png) + +이제 `docker-compose up -d`를 다시 사용하면 시작하지만, 이미지는 여전히 우리 시스템의 로컬에 있으므로 DockerHub 리포지토리에서 다시 가져올 필요가 없습니다. + +docker-compose와 그 기능에 대해 알아보기 시작했을 때 이것이 Kubernetes와 같은 컨테이너 오케스트레이션 도구와 어디에 위치하는지 혼란스러웠는데, 이 짧은 데모에서 우리가 한 모든 작업은 로컬 데스크톱 머신에서 실행 중인 WordPress와 DB가 있는 호스트 하나에 초점을 맞추고 있습니다. 여러 가상 머신이나 여러 물리적 머신이 없으며 애플리케이션의 요구 사항을 쉽게 확장 및 축소할 수도 없습니다. + +다음 섹션에서는 Kubernetes를 다룰 예정이지만, 먼저 컨테이너에 대한 전반적인 내용을 며칠 더 살펴보겠습니다. + +[Awesome-Compose](https://github.com/docker/awesome-compose)는 여러 통합이 있는 docker-compose 애플리케이션의 샘플을 위한 훌륭한 리소스입니다. + +위의 리포지토리에는 단일 노드에 Elasticsearch, Logstash, Kibana(ELK)를 배포하는 훌륭한 예제가 있습니다. + +[Containers 폴더](/2022/Days/Containers/elasticsearch-logstash-kibana/)에 파일을 업로드했습니다. 이 폴더가 로컬에 있으면 해당 폴더로 이동하여 `docker-compose up -d`를 사용하면 간단하게 설치할 수 있습니다. + +![](/2022/Days/Images/Day46_Containers15.png) + +그런 다음 `docker ps`로 실행 중인 컨테이너가 있는지 확인할 수 있습니다. + +![](/2022/Days/Images/Day46_Containers16.png) + +이제 각 컨테이너에 대한 브라우저를 열 수 있습니다: + +![](/2022/Days/Images/Day46_Containers17.png) + +모든 것을 제거하려면 `docker-compose down` 명령을 사용할 수 있습니다. + +## 자료 + +- [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) +- [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) +- [Docker Tutorial for Beginners - What is Docker? Introduction to Containers](https://www.youtube.com/watch?v=17Bl31rlnRM&list=WL&index=128&t=61s) +- [WSL 2 with Docker getting started](https://www.youtube.com/watch?v=5RQbdMn04Oc) +- [Blog on getting started building a docker image](https://stackify.com/docker-build-a-beginners-guide-to-building-docker-/2022/Days/images/) +- [Docker documentation for building an image](https://docs.docker.com/develop/develop-/2022/Days/images/dockerfile_best-practices/) +- [YAML Tutorial: Everything You Need to Get Started in Minute](https://www.cloudbees.com/blog/yaml-tutorial-everything-you-need-get-started) + +[Day 47](day47.md)에서 봐요! diff --git a/2022/ko/Days/day47.md b/2022/ko/Days/day47.md new file mode 100644 index 0000000..e779b7e --- /dev/null +++ b/2022/ko/Days/day47.md @@ -0,0 +1,139 @@ +--- +title: '#90DaysOfDevOps - Docker Networking & Security - Day 47' +published: false +description: 90DaysOfDevOps - Docker Networking & Security +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049078 +--- + +## Docker 네트워킹 및 보안 + +지금까지 컨테이너 세션에서 우리는 작업을 수행했지만, 네트워킹 관점에서 작업이 어떻게 작동했는지 살펴보지 않았으며 보안에 대해서도 다루지 않았습니다. + +### Docker 네트워킹 기본 사항 + +터미널을 열고, 컨테이너 네트워크를 구성하고 관리하기 위한 기본 명령어인 `docker network` 명령을 입력합니다. + +아래에서 이 명령어를 사용하는 방법과 사용 가능한 모든 하위 명령을 확인할 수 있습니다. 새로운 네트워크를 생성하고, 기존 네트워크를 나열하고, 네트워크를 검사 및 제거할 수 있습니다. + +![](/2022/Days/Images/Day47_Containers1.png) + +설치 이후 우리가 가지고 있는 기존 네트워크를 살펴보기 위해 `docker network list` 명령을 사용하는 기본 Docker 네트워킹의 모습을 살펴봅시다. + +각 네트워크는 고유한 ID와 이름을 갖습니다. 각 네트워크는 또한 단일 드라이버와 연결됩니다. "bridge" 네트워크와 "host" 네트워크는 각각의 드라이버와 이름이 동일합니다. + +![](/2022/Days/Images/Day47_Containers2.png) + +다음으로 `docker network inspect` 명령으로 네트워크를 더 자세히 살펴볼 수 있습니다. + +`docker network inspect bridge`를 실행하면 특정 네트워크 이름에 대한 모든 구성 세부 정보를 얻을 수 있습니다. 여기에는 이름, ID, 드라이버, 연결된 컨테이너 등이 포함되며 보시다시피 훨씬 더 많은 정보를 확인할 수 있습니다. + +![](/2022/Days/Images/Day47_Containers3.png) + +### Docker: bridge 네트워킹 + +위에서 보았듯이 Docker Desktop을 표준 설치하면 `bridge`라는 사전 구축된 네트워크가 제공됩니다. `docker network list` 명령을 다시 실행하면 bridge라는 네트워크가 `bridge` 드라이버와 연결되어 있는 것을 볼 수 있습니다. 이름이 같다고 해서 같은 것은 아닙니다. 연결되었지만 같은 것은 아닙니다. + +위의 출력은 또한 bridge 네트워크가 로컬로 범위가 지정되었음을 보여줍니다. 이는 네트워크가 이 Docker host에만 존재한다는 것을 의미합니다. 이는 bridge 드라이버를 사용하는 모든 네트워크에 해당되며, bridge 드라이버는 단일 host 네트워킹을 제공합니다. + +bridge 드라이버로 생성된 모든 네트워크는 Linux bridge(virtual switch라고도 함)를 기반으로 합니다. + +### 컨테이너 연결 + +기본적으로 bridge 네트워크는 새 컨테이너에 할당되므로 네트워크를 지정하지 않으면 모든 컨테이너가 bridge 네트워크에 연결됩니다. + +`docker run -dt ubuntu sleep infinity` 명령으로 새 컨테이너를 생성해 보겠습니다. + +위의 sleep 명령은 컨테이너를 백그라운드에서 계속 실행시켜서 컨테이너를 마음대로 다룰 수 있도록 합니다. + +![](/2022/Days/Images/Day47_Containers4.png) + +이제 `docker network inspect bridge`로 bridge 네트워크를 확인하면 네트워크를 지정하지 않았기 때문에 방금 배포한 것과 일치하는 컨테이너가 있는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day47_Containers5.png) + +`docker exec -it 3a99af449ca2 bash`를 사용하여 컨테이너를 자세히 살펴볼 수도 있습니다. 컨테이너 ID를 얻으려면 `docker ps`를 사용해야 합니다. + +여기에서 이미지에는 핑할 항목이 없으므로, `apt-get update && apt-get install -y iputils-ping`을 실행한 다음 외부 인터페이스 주소를 핑합니다. `ping -c5 www.90daysofdevops.com` + +![](/2022/Days/Images/Day47_Containers6.png) + +이 문제를 해결하기 위해 `docker stop 3a99af449ca2`를 다시 실행하고 `docker ps`를 사용하여 컨테이너 ID를 찾을 수 있지만, 이렇게 하면 컨테이너가 제거됩니다. + +### 외부 연결을 위한 NAT 구성하기 + +이 단계에서는 새 NGINX 컨테이너를 시작하고 Docker host의 포트 8080을 컨테이너 내부의 포트 80으로 매핑합니다. 즉, 포트 8080의 Docker host에 도달하는 트래픽은 컨테이너 내부의 포트 80으로 전달됩니다. + +`docker run --name web1 -d -p 8080:80 nginx`를 실행하여 공식 NGINX 이미지를 기반으로 새 컨테이너를 시작합니다. + +![](/2022/Days/Images/Day47_Containers7.png) + +`docker ps`를 실행하여 컨테이너 상태와 포트 매핑을 검토합니다. + +![](/2022/Days/Images/Day47_Containers8.png) + +맨 위 줄은 NGINX를 실행하는 새 web1 컨테이너를 보여줍니다. 컨테이너가 실행 중인 명령과 포트 매핑에 주목하세요. - `0.0.0.0:8080->80/tcp`는 모든 host 인터페이스의 8080 포트를 web1 컨테이너 내부의 80 포트에 매핑합니다. 이 포트 매핑을 통해 외부 소스에서 컨테이너의 웹 서비스에 효과적으로 액세스할 수 있습니다(포트 8080의 Docker host IP 주소를 통해). + +이제 실제 host에 대한 IP 주소가 필요하며, WSL 터미널로 이동하여 `IP addr` 명령을 사용하여 이를 수행할 수 있습니다. + +![](/2022/Days/Images/Day47_Containers9.png) + +그런 다음, 이 IP를 가지고 브라우저를 열어 `http://172.25.218.154:8080/`로 이동하면 IP가 다를 수 있습니다. 이렇게 하면 NGINX에 액세스할 수 있음을 확인할 수 있습니다. + +![](/2022/Days/Images/Day47_Containers10.png) + +이 사이트의 이 지침은 2017년 DockerCon에서 가져온 것이지만 오늘날에도 여전히 유효합니다. 그러나 나머지 연습은 Docker Swarm에 대한 것이므로 여기서는 다루지 않겠습니다. [Docker 네트워킹 - DockerCon 2017](https://github.com/docker/labs/tree/master/dockercon-us-2017/docker-networking) + +### 컨테이너 보안 + +컨테이너는 전체 서버 구성에 비해 워크로드에 안전한 환경을 제공합니다. 컨테이너는 애플리케이션을 서로 격리된 훨씬 더 작고 느슨하게 결합된 구성 요소로 분할할 수 있는 기능을 제공하므로 전체적으로 공격 표면을 줄이는 데 도움이 됩니다. + +하지만 시스템의 취약점을 공격하려는 해커로부터 자유롭지는 않습니다. 우리는 여전히 이 기술의 보안 결함을 이해하고 모범 사례를 유지해야 합니다. + +### 루트 권한에서 벗어나기 + +지금까지 배포한 모든 컨테이너는 컨테이너 내 프로세스에 대한 루트 권한을 사용해 왔습니다. 즉, 컨테이너와 host 환경에 대한 모든 관리 액세스 권한이 있다는 뜻입니다. 이제 이러한 시스템이 오래 가동되지 않을 것이라는 것을 알고 있었습니다. 하지만 시작하고 실행하는 것이 얼마나 쉬운지 보셨을 것입니다. + +프로세스에 몇 단계를 추가하여 루트 사용자가 아닌 사용자가 선호하는 모범 사례를 사용할 수 있도록 할 수 있습니다. dockerfile을 만들 때 사용자 계정을 만들 수 있습니다. 이 예제는 리포지토리의 컨테이너 폴더에서도 찾을 수 있습니다. + +```dockerfile +# 공식 Ubuntu 18.04를 기본으로 사용하세요. +FROM ubuntu:18.04 +RUN apt-get update && apt-get upgrade -y +RUN groupadd -g 1000 basicuser && useradd -r -u 1000 -g basicuser basicuser +USER basicuser +``` + +`docker run --user 1009 ubuntu` 명령은 dockerfile에 지정된 모든 사용자를 재정의합니다. 따라서 다음 예제에서는 컨테이너가 항상 권한이 가장 낮은 사용자 식별자 1009로 실행되며 권한 수준도 가장 낮습니다. + +그러나 이 방법은 이미지 자체의 근본적인 보안 결함을 해결하지 못합니다. 따라서 컨테이너가 항상 안전하게 실행되도록 dockerfile에 루트 사용자가 아닌 사용자를 지정하는 것이 좋습니다. + +### 비공개 레지스트리 + +조직에서 컨테이너 이미지의 비공개 레지스트리를 설정하면 원하는 곳에서 호스팅할 수 있거나 이를 위한 관리형 서비스도 있지만, 대체로 사용자와 팀이 사용할 수 있는 이미지를 완벽하게 제어할 수 있습니다. + +DockerHub는 기준선을 제시하는 데는 훌륭하지만, 이미지 게시자를 많이 신뢰해야 하는 기본적인 서비스만 제공합니다. + +### 린 & 클린 + +보안과 관련되지는 않았지만, 전체적으로 언급했습니다. 그러나 애플리케이션에서 사용하지 않는 리소스가 컨테이너에 필요하지 않은 경우 컨테이너의 크기는 공격 표면 측면에서 보안에 영향을 미칠 수 있습니다. + +또한 `latest` 이미지를 가져올 때 이미지에 많은 부풀림을 가져올 수 있기 때문에 이것이 저의 주요 관심사입니다. DockerHub는 리포지토리에 있는 각 이미지의 압축 크기를 표시합니다. + +`docker image`를 확인하면 이미지의 크기를 확인할 수 있는 좋은 명령어입니다. + +![](/2022/Days/Images/Day47_Containers11.png) + +## 자료 + +- [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) +- [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) +- [Docker Tutorial for Beginners - What is Docker? Introduction to Containers](https://www.youtube.com/watch?v=17Bl31rlnRM&list=WL&index=128&t=61s) +- [WSL 2 with Docker getting started](https://www.youtube.com/watch?v=5RQbdMn04Oc) +- [Blog on getting started building a docker image](https://stackify.com/docker-build-a-beginners-guide-to-building-docker-/2022/Days/images/) +- [Docker documentation for building an image](https://docs.docker.com/develop/develop-/2022/Days/images/dockerfile_best-practices/) +- [YAML Tutorial: Everything You Need to Get Started in Minute](https://www.cloudbees.com/blog/yaml-tutorial-everything-you-need-get-started) + +[Day 48](day48.md)에서 봐요! diff --git a/2022/ko/Days/day48.md b/2022/ko/Days/day48.md new file mode 100644 index 0000000..9d8ac00 --- /dev/null +++ b/2022/ko/Days/day48.md @@ -0,0 +1,115 @@ +--- +title: '#90DaysOfDevOps - Alternatives to Docker - Day 48' +published: false +description: 90DaysOfDevOps - Alternatives to Docker +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048807 +--- + +## Docker의 대안 + +이 섹션의 맨 처음에 Docker를 사용할 것이라고 말씀드린 이유는 단순히 리소스 측면에서 매우 많고 커뮤니티가 매우 크기 때문이기도 하지만, 컨테이너를 대중화하기 위한 시도가 바로 여기에서 시작되었기 때문입니다. Docker의 역사와 그 탄생 과정을 살펴보는 것이 매우 유용하다고 생각합니다. + +하지만 앞서 언급했듯이 Docker를 대체할 수 있는 다른 대안이 있습니다. Docker가 무엇이고 무엇을 다루었는지 생각해 보면 다음과 같습니다. 애플리케이션을 개발, 테스트, 배포 및 관리하기 위한 플랫폼입니다. + +앞으로 실제로 사용할 수 있거나 앞으로 사용할 수 있는 Docker의 몇 가지 대안을 강조하고 싶습니다. + +### Podman + +Podman이란? Podman은 리눅스 시스템에서 OCI 컨테이너를 개발, 관리, 실행하기 위한 데몬이 없는 컨테이너 엔진입니다. 컨테이너는 루트로 실행하거나 루트리스 모드로 실행할 수 있습니다. + +여기서는 Windows 관점에서 살펴볼 것이지만, Docker와 마찬가지로 Windows에서는 할 수 없는 기본 OS를 사용하기 때문에 가상화가 필요하지 않습니다. + +Podman은 WSL2에서도 실행할 수 있지만, Docker Desktop의 경험만큼 매끄럽지는 않습니다. 컨테이너가 실행될 Linux VM에 연결할 수 있는 Windows 원격 클라이언트도 있습니다. + +제가 사용하는 WSL2의 우분투는 20.04 릴리스입니다. 다음 단계에 따라 WSL 인스턴스에 Podman을 설치할 수 있습니다. + +```Shell +echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_20.04/ /" | +sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list +``` + +GPG 키를 추가합니다. + +```Shell +curl -L "https://download.opensuse.org/repositories/devel:/kubic:\ +/libcontainers:/stable/xUbuntu_20.04/Release.key" | sudo apt-key add - +``` + +`sudo apt-get update && sudo apt-get upgrade`명령으로 시스템 업데이트 및 업그레이드를 실행합니다. 마지막으로`sudo apt install podman`을 사용하여 podman을 설치할 수 있습니다. + +이제 docker에 사용하던 것과 동일한 명령을 많이 사용할 수 있습니다. 다만 멋진 docker 데스크톱 UI가 없다는 점에 유의하세요. 아래에서 볼 수 있듯이 `podman images`를 사용했고 설치 후 아무것도 없으므로 `podman pull ubuntu`를 사용하여 우분투 컨테이너 이미지를 끌어 내렸습니다. + +![](/2022/Days/Images/Day48_Containers1.png) + +그런 다음 `podman run -dit ubuntu`와 `podman ps`를 사용하여 우분투 이미지를 실행하여 실행 중인 이미지를 확인할 수 있습니다. + +![](/2022/Days/Images/Day48_Containers2.png) + +그런 다음 해당 컨테이너에 들어가기 위해 `podman attach dazzling_darwin`을 실행하면 컨테이너 이름이 달라질 수 있습니다. + +![](/2022/Days/Images/Day48_Containers3.png) + +docker에서 podman으로 이동하는 경우, 설정 파일에 `alias docker=podman`으로 변경하여 docker로 실행하는 모든 명령이 podman을 사용하도록 하는 것도 일반적입니다. + +### LXC + +LXC는 사용자가 다시 여러 개의 격리된 리눅스 컨테이너 환경을 생성할 수 있게 해주는 컨테이너화 엔진입니다. Docker와 달리, LXC는 별도의 시스템 파일과 네트워킹 기능을 갖춘 여러 리눅스 머신을 생성하기 위한 하이퍼바이저 역할을 합니다. docker보다 먼저 등장했다가 docker의 단점으로 인해 잠시 사용되었습니다. + +LXC는 docker만큼 가볍고 쉽게 배포할 수 있습니다. + +### Containerd + +독립형 컨테이너 런타임. Containerd는 단순성과 견고성은 물론 이식성까지 제공합니다. 이전에는 Docker 컨테이너 서비스의 일부로 실행되는 도구로 사용되다가 Docker가 구성 요소를 독립형 구성 요소로 분리하기로 결정하기 전까지 Containerd가 사용되었습니다. + +클라우드 네이티브 컴퓨팅 재단의 프로젝트로, Kubernetes, Prometheus, CoreDNS와 같은 인기 컨테이너 도구와 같은 부류에 속합니다. + +### 기타 Docker 도구 + +Rancher와 VirtualBox와 관련된 도구와 옵션도 언급할 수 있지만 다음 기회에 더 자세히 다루겠습니다. + +[**Gradle**](https://gradle.org/) + +- 빌드 스캔을 통해 팀은 공동으로 스크립트를 디버깅하고 모든 빌드의 이력을 추적할 수 있습니다. +- 실행 옵션을 통해 팀은 변경 사항이 입력될 때마다 작업이 자동으로 실행되도록 지속적으로 빌드할 수 있습니다. +- 사용자 지정 리포지토리 레이아웃을 통해 팀은 모든 파일 디렉토리 구조를 아티팩트 리포지토리로 취급할 수 있습니다. + +[**Packer**](https://packer.io/) + +- 여러 머신 이미지를 병렬로 생성하여 개발자의 시간을 절약하고 효율성을 높일 수 있습니다. +- 패커의 디버거를 사용하여 빌드를 쉽게 디버깅할 수 있어 실패를 검사하고 빌드를 다시 시작하기 전에 솔루션을 시험해 볼 수 있습니다. +- 플러그인을 통해 다양한 플랫폼을 지원하므로 팀이 빌드를 커스터마이징할 수 있습니다. + +[**Logspout**](https://github.com/gliderlabs/logspout) + +- 로깅 도구 - 이 도구의 사용자 지정 기능을 통해 팀은 동일한 로그를 여러 대상에 전송할 수 있습니다. +- 이 도구는 Docker 소켓에 액세스하기만 하면 되기 때문에 팀에서 파일을 쉽게 관리할 수 있습니다. +- 완전히 오픈 소스이며 배포가 쉽습니다. + +[**Logstash**](https://www.elastic.co/products/logstash) + +- Logstash의 플러그형 프레임워크를 사용해 파이프라인을 사용자 정의하세요. +- 분석을 위해 데이터를 쉽게 구문 분석하고 변환하여 비즈니스 가치를 제공할 수 있습니다. +- Logstash의 다양한 출력을 통해 원하는 곳으로 데이터를 라우팅할 수 있습니다. + +[**Portainer**](https://www.portainer.io/) + +- 미리 만들어진 템플릿을 활용하거나 직접 템플릿을 만들어 애플리케이션을 배포하세요. +- 팀을 생성하고 팀원에게 역할과 권한을 할당하세요. +- 도구의 대시보드를 사용하여 각 환경에서 무엇이 실행되고 있는지 파악하세요. + +## 자료 + +- [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) +- [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) +- [Docker Tutorial for Beginners - What is Docker? Introduction to Containers](https://www.youtube.com/watch?v=17Bl31rlnRM&list=WL&index=128&t=61s) +- [WSL 2 with Docker getting started](https://www.youtube.com/watch?v=5RQbdMn04Oc) +- [Blog on getting started building a docker image](https://stackify.com/docker-build-a-beginners-guide-to-building-docker-images/) +- [Docker documentation for building an image](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) +- [YAML Tutorial: Everything You Need to Get Started in Minute](https://www.cloudbees.com/blog/yaml-tutorial-everything-you-need-get-started) +- [Podman | Daemonless Docker | Getting Started with Podman](https://www.youtube.com/watch?v=Za2BqzeZjBk) +- [LXC - Guide to building an LXC Lab](https://www.youtube.com/watch?v=cqOtksmsxfg) + +[Day 49](day49.md)에서 봐요! diff --git a/2022/ko/Days/day49.md b/2022/ko/Days/day49.md new file mode 100644 index 0000000..2afaa6f --- /dev/null +++ b/2022/ko/Days/day49.md @@ -0,0 +1,235 @@ +--- +title: '#90DaysOfDevOps - The Big Picture: Kubernetes - Day 49' +published: false +description: 90DaysOfDevOps - The Big Picture Kubernetes +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049049 +--- + +## 큰 그림: Kubernetes + +지난 섹션에서 컨테이너에 대해 살펴보았는데, 컨테이너는 scale과 오케스트레이션만으로는 부족합니다. 우리가 할 수 있는 최선은 docker-compose를 사용하여 여러 컨테이너를 함께 불러오는 것입니다. 컨테이너 오케스트레이터인 Kubernetes를 사용하면 애플리케이션과 서비스의 부하에 따라 자동화된 방식으로 확장 및 축소할 수 있습니다. + +플랫폼으로서 Kubernetes는 요구사항과 원하는 상태에 따라 컨테이너를 오케스트레이션할 수 있는 기능을 제공합니다. 이 섹션에서는 차세대 인프라로 빠르게 성장하고 있는 Kubernetes에 대해 다룰 예정입니다. 또한 데브옵스 관점에서 볼 때 Kubernetes는 기본적인 이해가 필요한 하나의 플랫폼일 뿐이며, 베어메탈, 가상화 및 대부분의 클라우드 기반 서비스도 이해해야 합니다. Kubernetes는 애플리케이션을 실행하기 위한 또 다른 옵션일 뿐입니다. + +### 컨테이너 오케스트레이션이란 무엇인가요? + +앞서 Kubernetes와 컨테이너 오케스트레이션에 대해 언급했는데, Kubernetes는 기술인 반면 컨테이너 오케스트레이션은 기술 이면의 개념 또는 프로세스입니다. 컨테이너 오케스트레이션 플랫폼은 Kubernetes뿐만 아니라 Docker Swarm, HashiCorp Nomad 등도 있습니다. 하지만 Kubernetes가 점점 더 강세를 보이고 있기 때문에 Kubernetes를 다루고 싶지만, Kubernetes만이 유일한 것은 아니라는 점을 말씀드리고 싶었습니다. + +### Kubernetes란 무엇인가요? + +Kubernetes를 처음 접하는 경우 가장 먼저 읽어야 할 것은 공식 문서입니다. 1년 조금 전에 Kubernetes에 대해 깊이 파고든 제 경험에 따르면 학습 곡선이 가파르게 진행될 것입니다. 가상화 및 스토리지에 대한 배경지식이 있는 저는 이것이 얼마나 벅차게 느껴질지 생각했습니다. + +하지만 커뮤니티, 무료 학습 리소스 및 문서는 놀랍습니다. [Kubernetes.io](https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/) + +Kubernetes는 컨테이너화된 워크로드와 서비스를 관리하기 위한 이식 가능하고 확장 가능한 오픈소스 플랫폼으로, 선언적 구성과 자동화를 모두 용이하게 합니다. 빠르게 성장하는 대규모 에코시스템이 있습니다. Kubernetes 서비스, 지원, 도구는 널리 이용 가능합니다. + +위의 인용문에서 주목해야 할 중요한 점은 Kubernetes는 클라우드 네이티브 컴퓨팅 재단(CNCF)에 프로젝트를 기부한 Google로 거슬러 올라가는 풍부한 역사를 가진 오픈소스이며, 현재 오픈소스 커뮤니티와 대기업 벤더가 오늘날의 Kubernetes를 만드는 데 기여하면서 발전해 왔다는 점입니다. + +위에서 컨테이너가 훌륭하다고 말씀드렸고 이전 섹션에서는 컨테이너와 컨테이너 이미지가 어떻게 클라우드 네이티브 시스템의 채택을 변화시키고 가속화했는지에 대해 이야기했습니다. 하지만 컨테이너만으로는 애플리케이션에 필요한 프로덕션 지원 환경을 제공할 수 없습니다. Kubernetes는 다음과 같은 이점을 제공합니다: + +- **Services discovery 및 로드 밸런싱** Kubernetes는 DNS 이름 또는 IP 주소를 사용하여 컨테이너를 노출할 수 있습니다. 컨테이너에 대한 트래픽이 많을 경우, Kubernetes는 네트워크 트래픽을 로드 밸런싱하고 분산하여 배포가 안정적으로 이루어지도록 할 수 있습니다. + +- **스토리지 오케스트레이션** Kubernetes를 사용하면 로컬 스토리지, 퍼블릭 클라우드 제공자 등 원하는 스토리지 시스템을 자동으로 마운트할 수 있습니다. + +- **자동화된 롤아웃 및 롤백** 배포된 컨테이너에 대해 원하는 상태를 설명할 수 있으며, 제어된 속도로 실제 상태를 원하는 상태로 변경할 수 있습니다. 예를 들어, 배포를 위한 새 컨테이너를 생성하고, 기존 컨테이너를 제거하고, 모든 리소스를 새 컨테이너에 적용하도록 Kubernetes를 자동화할 수 있습니다. + +- **자동 bin 패킹** 컨테이너화된 작업을 실행하는 데 사용할 수 있는 노드 클러스터를 Kubernetes에 제공하고, 각 컨테이너에 필요한 CPU와 메모리(RAM)의 양을 Kubernetes에 알려줍니다. Kubernetes는 리소스를 최대한 활용하기 위해 컨테이너를 노드에 맞출 수 있습니다. + +- **자가 복구** Kubernetes는 장애가 발생한 컨테이너를 다시 시작하고, 컨테이너를 교체하고, 사용자 정의 상태 확인에 응답하지 않는 컨테이너를 죽이고, 제공할 준비가 될 때까지 클라이언트에게 알리지 않습니다. + +- **비밀 및 구성 관리** Kubernetes를 사용하면 비밀번호, OAuth 토큰, SSH 키와 같은 민감한 정보를 저장하고 관리할 수 있습니다. 컨테이너 이미지를 다시 빌드하거나 스택 구성에 시크릿을 노출하지 않고도 시크릿 및 애플리케이션 구성을 배포하고 업데이트할 수 있습니다. + +Kubernetes는 분산 시스템을 탄력적으로 실행할 수 있는 프레임워크를 제공합니다. + +컨테이너 오케스트레이션은 컨테이너의 배포, 배치 및 라이프사이클을 관리합니다. + +또한 다른 많은 책임도 있습니다: + +- 클러스터 관리는 호스트를 하나의 대상으로 묶습니다. + +- 스케줄 관리는 스케줄러를 통해 컨테이너를 노드 간에 배포합니다. + +- Services discovery은 컨테이너의 위치를 파악하고 클라이언트 요청을 컨테이너에 분산합니다. + +- 복제는 요청된 워크로드에 적합한 수의 노드와 컨테이너를 사용할 수 있도록 보장합니다. + +- 상태 관리는 건강하지 않은 컨테이너와 노드를 감지하고 교체합니다. + +### 주요 Kubernetes 구성 요소 + +Kubernetes는 애플리케이션을 프로비저닝, 관리 및 확장하기 위한 컨테이너 오케스트레이터입니다. 이를 사용하여 VM 또는 물리적 머신과 같은 워커 머신의 모음인 노드 클러스터에서 컨테이너화된 앱의 라이프사이클을 관리할 수 있습니다. + +앱을 실행하려면 데이터베이스 연결, 방화벽 백엔드와의 통신, 키 보안에 도움이 되는 볼륨, 네트워크, 시크릿 등 다른 많은 리소스가 필요할 수 있습니다. Kubernetes를 사용하면 이러한 리소스를 앱에 추가할 수 있습니다. 앱에 필요한 인프라 리소스는 선언적으로 관리됩니다. + +Kubernetes의 핵심 패러다임은 선언적 모델입니다. 사용자가 원하는 상태를 제공하면 Kubernetes가 이를 실현합니다. 인스턴스 다섯 개가 필요한 경우, 사용자가 직접 다섯 개의 인스턴스를 시작하지 않습니다. 대신 인스턴스 5개가 필요하다고 Kubernetes에 알려주면 Kubernetes가 자동으로 상태를 조정합니다. 인스턴스 중 하나에 문제가 발생하여 실패하더라도 Kubernetes는 여전히 사용자가 원하는 상태를 파악하고 사용 가능한 노드에 인스턴스를 생성합니다. + +### 노드 + +#### 컨트롤 플레인 + +모든 Kubernetes 클러스터에는 컨트롤 플레인 노드가 필요하며, 컨트롤 플레인의 구성 요소는 클러스터에 대한 전역 결정(예: 스케줄링)을 내리고 클러스터 이벤트를 감지 및 응답합니다. + +![](/2022/Days/Images/Day49_Kubernetes1.png) + +#### 워커 노드 + +Kubernetes 워크로드를 실행하는 워커 머신입니다. 물리적(베어메탈) 머신이거나 가상 머신(VM)일 수 있습니다. 각 노드는 하나 이상의 pod를 호스트할 수 있습니다. Kubernetes 노드는 컨트롤 플레인에 의해 관리됩니다. + +![](/2022/Days/Images/Day49_Kubernetes2.png) + +다른 노드 유형이 있지만 여기서는 다루지 않겠습니다. + +#### kubelet + +클러스터의 각 노드에서 실행되는 에이전트입니다. 컨테이너가 pod에서 실행되고 있는지 확인합니다. + +kubelet은 다양한 메커니즘을 통해 제공되는 일련의 PodSpec을 가져와서 해당 PodSpec에 설명된 컨테이너가 실행 중이고 정상인지 확인합니다. kubelet은 Kubernetes가 생성하지 않은 컨테이너는 관리하지 않습니다. + +![](/2022/Days/Images/Day49_Kubernetes3.png) + +#### kube-proxy + +kube-proxy는 클러스터의 각 노드에서 실행되는 네트워크 프록시로, Kubernetes Services 개념의 일부를 구현합니다. + +kube-proxy는 노드에서 네트워크 규칙을 유지 관리합니다. 이러한 네트워크 규칙은 클러스터 내부 또는 외부의 네트워크 세션에서 pod로의 네트워크 통신을 허용합니다. + +운영 체제 패킷 필터링 계층이 있고 사용 가능한 경우, kube-proxy는 이를 사용합니다. 그렇지 않으면, kube-proxy는 트래픽 자체를 전달합니다. + +![](/2022/Days/Images/Day49_Kubernetes4.png) + +#### 컨테이너 런타임 + +컨테이너 런타임은 컨테이너 실행을 담당하는 소프트웨어입니다. + +Kubernetes는 여러 컨테이너 런타임을 지원합니다: docker, containerd, CRI-O 그리고 Kubernetes CRI(Container Runtime Interface)의 모든 구현 + +![](/2022/Days/Images/Day49_Kubernetes5.png) + +### 클러스터 + +클러스터는 노드의 그룹으로, 노드는 물리적 머신 또는 가상 머신이 될 수 있습니다. 각 노드에는 컨테이너 런타임(Docker)이 있으며 마스터 컨트롤러(나중에 자세히 설명)의 명령을 받는 에이전트인 kubelet 서비스와 다른 구성 요소(나중에 자세히 설명)에서 pod에 대한 연결을 프록시하는 데 사용되는 프록시도 실행됩니다. + +고가용성으로 만들 수 있는 컨트롤 플레인에는 워커 노드와 비교하여 몇 가지 고유한 역할이 포함되며, 가장 중요한 것은 정보를 가져오거나 Kubernetes 클러스터로 정보를 푸시하기 위한 모든 통신이 이루어지는 곳인 kube API 서버입니다. + +#### Kube API 서버 + +Kubernetes API 서버는 pod, 서비스, 응답 컨트롤러 등을 포함하는 API 오브젝트에 대한 데이터의 유효성을 검사하고 구성합니다. API 서버는 REST 작업을 수행하고 다른 모든 구성 요소가 상호 작용하는 클러스터의 공유 상태에 대한 프론트엔드를 제공합니다. + +#### 스케줄러 + +Kubernetes 스케줄러는 노드에 pod를 할당하는 컨트롤 플레인 프로세스입니다. 스케줄러는 제약 조건과 사용 가능한 리소스에 따라 스케줄링 대기열에서 각 pod에 대해 유효한 배치가 되는 노드를 결정합니다. 그런 다음 스케줄러는 각 유효한 노드의 순위를 매기고 pod를 적합한 노드에 바인딩합니다. + +#### 컨트롤러 매니저 + +Kubernetes 컨트롤러 매니저는 Kubernetes와 함께 제공되는 핵심 제어 루프를 임베드하는 daemon입니다. 로보틱스 및 자동화 애플리케이션에서 제어 루프는 시스템 상태를 조절하는 비종료 루프입니다. Kubernetes에서 컨트롤러는 API 서버를 통해 클러스터의 공유 상태를 감시하고 현재 상태를 원하는 상태로 이동시키기 위해 변경을 시도하는 제어 루프입니다. + +#### etcd + +모든 클러스터 데이터에 대한 Kubernetes의 백업 저장소로 사용되는 일관되고 가용성이 높은 키 값 저장소입니다. + +![](/2022/Days/Images/Day49_Kubernetes6.png) + +#### kubectl + +CLI 관점에서 이를 관리하기 위해 kubectl이 있으며, kubectl은 API 서버와 상호 작용합니다. + +Kubernetes 커맨드-라인 도구인 kubectl을 사용하면 Kubernetes 클러스터에 대해 명령을 실행할 수 있습니다. kubectl을 사용하여 애플리케이션을 배포하고, 클러스터 리소스를 검사 및 관리하고, 로그를 볼 수 있습니다. + +![](/2022/Days/Images/Day49_Kubernetes7.png) + +### Pods + +pod는 논리적 애플리케이션을 구성하는 컨테이너 그룹입니다. 예를 들어, NodeJS 컨테이너와 MySQL 컨테이너를 실행하는 웹 애플리케이션이 있는 경우, 이 두 컨테이너는 모두 단일 pod에 위치하게 됩니다. 또한 pod는 공통 데이터 볼륨을 공유할 수 있으며 동일한 네트워킹 네임스페이스도 공유합니다. pod는 임시적이며 마스터 컨트롤러에 의해 위아래로 이동될 수 있다는 것을 기억합시다. Kubernetes는 레이블(이름-값) 개념을 통해 pod를 식별하는 간단하지만, 효과적인 수단을 사용합니다. + +- pod는 컨테이너의 볼륨, 시크릿 및 구성을 처리합니다. + +- pod는 임시적입니다. 죽으면 자동으로 재시작되도록 설계되었습니다. + +- pod는 ReplicationSet에 의해 앱이 수평으로 스케일 될 때 복사됩니다. 각 pod는 동일한 컨테이너 코드를 실행합니다. + +- pod는 워커 노드에서 실행됩니다. + +![](/2022/Days/Images/Day49_Kubernetes8.png) + +### Deployments + +- pod를 실행하기로 결정할 수 있지만 죽으면 끝입니다. + +- Deployments를 사용하면 pod가 지속적으로 실행될 수 있습니다. + +- Deployments를 사용하면 다운타임 없이 실행 중인 앱을 업데이트할 수 있습니다. + +- 또한, Deployments는 pod가 죽었을 때 재시작하는 전략을 지정합니다. + +![](/2022/Days/Images/Day49_Kubernetes9.png) + +### ReplicaSets + +- Deployments는 ReplicaSets을 생성할 수도 있습니다. + +- ReplicaSets은 앱이 원하는 수의 pod를 갖도록 보장합니다. + +- ReplicaSets은 Deployments에 따라 pod를 생성하고 확장합니다. + +- Deployments, ReplicaSets, pod는 배타적이지는 않지만 그렇게 될 수 있습니다. + +### StatefulSets + +- 앱의 상태에 대한 정보를 유지해야 하나요? + +- 데이터베이스에는 상태가 필요합니다. + +- StatefulSets의 pod는 서로 호환되지 않습니다. + +- 각 pod에는 컨트롤러가 모든 스케줄링에 대해 유지하는 고유하고 영구적인 식별자가 있습니다. + +![](/2022/Days/Images/Day49_Kubernetes10.png) + +### DaemonSets + +- DaemonSets은 연속 프로세스를 위한 것입니다. + +- 노드당 하나의 pod를 실행합니다. + +- 클러스터에 새로운 노드가 추가될 때마다 pod가 시작됩니다. + +- 모니터링 및 로그 수집과 같은 백그라운드 작업에 유용합니다. + +- 각 pod에는 컨트롤러가 모든 스케줄링에 대해 유지하는 고유하고 영구적인 식별자가 있습니다. + +![](/2022/Days/Images/Day49_Kubernetes11.png) + +### Services + +- pod에 액세스하기 위한 단일 엔드포인트입니다. + +- 클러스터와 최종적으로 pod 목록으로 트래픽을 라우팅하는 통합된 방법입니다. + +- Services를 사용하면 아무 영향 없이 pod를 올리고 내릴 수 있습니다. + +이것은 Kubernetes의 기본 구성 요소에 대한 간략한 개요와 참고 사항일 뿐이며, 이 지식을 바탕으로 스토리지와 Ingress 관련 몇 가지 다른 영역을 추가하여 애플리케이션을 개선할 수 있지만, Kubernetes 클러스터가 실행되는 위치에 대한 선택의 폭도 넓어집니다. 다음 세션에서는 스토리지와 관련된 몇 가지 세부 사항을 살펴보면서 Kubernetes 클러스터를 실행할 수 있는 위치에 대한 이러한 옵션에 중점을 두겠습니다. + +![](/2022/Days/Images/Day49_Kubernetes12.png) + +### Kubernetes 시리즈에서 다룰 내용 + +- Kubernetes 아키텍처 +- Kubectl 커맨드 +- Kubernetes YAML +- Kubernetes Ingress +- Kubernetes Services +- Helm 패키지 관리자 +- 영속성 스토리지 +- stateful 앱 + +## 자료 + +- [Kubernetes Documentation](https://kubernetes.io/docs/home/) +- [TechWorld with Nana - Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]](https://www.youtube.com/watch?v=X48VuDVv0do) +- [TechWorld with Nana - Kubernetes Crash Course for Absolute Beginners](https://www.youtube.com/watch?v=s_o8dwzRlu4) +- [Kunal Kushwaha - Kubernetes Tutorial for Beginners | What is Kubernetes? Architecture Simplified!](https://www.youtube.com/watch?v=KVBON1lA9N8) + +[Day 50](day50.md)에서 봐요! diff --git a/2022/ko/Days/day50.md b/2022/ko/Days/day50.md new file mode 100644 index 0000000..ffd3c00 --- /dev/null +++ b/2022/ko/Days/day50.md @@ -0,0 +1,79 @@ +--- +title: '#90DaysOfDevOps - Choosing your Kubernetes platform - Day 50' +published: false +description: 90DaysOfDevOps - Choosing your Kubernetes platform +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049046 +--- + +## Kubernetes 플랫폼 선택하기 + +이 세션을 통해 몇 가지 플랫폼 또는 배포판이라는 용어를 사용하는 것이 더 적합할 수도 있는데, Kubernetes 세계에서 도전 과제 중 하나는 복잡성을 제거하는 것입니다. + +Kubernetes 어려운 길은 아무것도 없는 상태에서 완전한 기능을 갖춘 Kubernetes 클러스터로 구축하는 방법을 안내하지만, 적어도 제가 이야기하는 사람들은 점점 더 많은 사람들이 이러한 복잡성을 제거하고 관리형 Kubernetes 클러스터를 실행하기를 원하고 있습니다. 문제는 비용이 더 많이 들지만, 관리형 서비스를 사용하면 기본 노드 아키텍처와 컨트롤 플레인 노드 관점에서 무슨 일이 일어나고 있는지 알아야 하지만 일반적으로 이에 액세스할 수 없는 경우 이점을 누릴 수 있다는 것입니다. + +그런 다음 시스템을 사용할 수 있는 로컬 개발 배포판이 있고, 개발자가 의도한 플랫폼에서 앱을 실행할 수 있는 완전한 작업 환경을 갖출 수 있도록 로컬 버전의 Kubernetes를 실행할 수 있습니다. + +이 모든 개념의 일반적인 기본은 모두 Kubernetes의 한 종류이므로 요구 사항에 맞게 워크로드를 필요한 곳으로 자유롭게 마이그레이션하고 이동할 수 있어야 한다는 것입니다. + +또한 어떤 투자가 이루어졌는지에 따라 많은 선택이 달라질 것입니다. 개발자 경험에 대해서도 언급했지만, 노트북에서 실행되는 로컬 Kubernetes 환경 중 일부는 비용을 들이지 않고도 기술을 익힐 수 있는 훌륭한 환경입니다. + +### 베어 메탈 클러스터 + +많은 사람들이 클러스터를 생성하기 위해 여러 대의 물리적 서버에서 바로 Linux OS를 실행하는 옵션을 선택할 수 있으며, Windows일 수도 있지만 Windows, 컨테이너 및 Kubernetes와 관련된 채택률에 대해서는 많이 듣지 못했습니다. 만약 여러분이 기업이고 물리적 서버를 구매하기로 CAPEX 결정을 내렸다면, Kubernetes 클러스터를 구축할 때 이 방법을 사용할 수 있지만, 관리 및 관리자 측면에서는 여러분이 직접 구축하고 모든 것을 처음부터 관리해야 한다는 것을 의미합니다. + +### 가상화 + +테스트 및 학습 환경이나 엔터프라이즈급 Kubernetes 클러스터에 관계없이 가상화는 일반적으로 가상 머신을 스핀업하여 노드 역할을 하도록 한 다음 함께 클러스터링할 수 있는 훌륭한 방법입니다. 가상화의 기본 아키텍처, 효율성 및 속도를 활용할 수 있을 뿐만 아니라 기존 지출을 활용할 수 있습니다. 예를 들어 VMware는 가상 머신과 Kubernetes 모두를 위한 훌륭한 솔루션을 다양한 형태로 제공합니다. + +제가 처음으로 구축한 Kubernetes 클러스터는 몇 개의 VM을 노드로 실행할 수 있는 오래된 서버에서 Microsoft Hyper-V를 사용한 가상화를 기반으로 구축되었습니다. + +### 로컬 데스크톱 옵션 + +데스크톱이나 노트북에서 로컬 Kubernetes 클러스터를 실행하는 데는 몇 가지 옵션이 있습니다. 앞서 말했듯이 개발자는 비용이 많이 들거나 복잡한 클러스터를 여러 개 보유하지 않고도 앱이 어떻게 보일지 확인할 수 있습니다. 개인적으로 저는 이 클러스터를 많이 사용해 왔으며 특히 Minikube를 사용해 왔습니다. 여기에는 무언가를 시작하고 실행하는 방식을 바꾸는 몇 가지 훌륭한 기능과 애드온이 있습니다. + +### Kubernetes Managed Services + +가상화에 대해 언급했는데, 이는 로컬에서 하이퍼바이저를 통해 달성할 수 있지만 이전 섹션에서 퍼블릭 클라우드의 가상 머신을 활용하여 노드 역할을 할 수도 있다는 것을 알고 있습니다. 여기서 말하는 Kubernetes 관리형 서비스란 대규모 하이퍼스케일러뿐만 아니라 최종 사용자로부터 관리 및 제어 계층을 제거하여 최종 사용자로부터 제어 플레인을 제거하는 MSP에서 제공하는 서비스를 말하며, 이는 Amazon EKS, Microsoft AKS 및 Google Kubernetes Engine에서 일어나는 일입니다. (GKE) + +### 압도적인 선택 + +선택의 폭이 넓다는 것은 좋지만, 위에 나열된 각 카테고리의 모든 옵션에 대해 자세히 살펴본 것은 아닙니다. 위의 옵션 외에도 Red Hat의 OpenShift가 있으며, 이 옵션은 위의 모든 주요 클라우드 제공업체에서 실행할 수 있으며 클러스터가 배포된 위치에 관계없이 관리자에게 최고의 전반적인 사용성을 제공할 수 있습니다. + +제가 가상화 경로로 시작했다고 말씀드렸지만, 이는 제가 목적에 맞게 사용할 수 있는 물리적 서버에 액세스할 수 있었기 때문에 감사하게도 그 이후로는 더 이상 이 옵션을 사용할 수 없었습니다. + +지금 제가 드리고 싶은 조언은 Minikube를 첫 번째 옵션으로 사용하거나 Kind(Docker의 Kubernetes)를 사용하라는 것이지만, Minikube는 애드온을 사용하고 빠르게 구축한 다음 완료되면 날려버릴 수 있고, 여러 클러스터를 실행할 수 있으며, 거의 모든 곳에서 실행할 수 있고, 크로스 플랫폼 및 하드웨어에 구애받지 않기 때문에 복잡성을 거의 추상화할 수 있는 몇 가지 추가적인 이점을 제공합니다. + +저는 Kubernetes에 대해 배우면서 약간의 여정을 거쳤기 때문에 플랫폼 선택과 구체적인 내용은 여기서는 플랫폼인 Kubernetes와 실행 가능한 위치에 대한 이해를 돕기 위해 시도했던 옵션들을 나열해 보겠습니다. 아래 블로그 포스팅을 다시 한번 살펴보고 블로그 게시물에 링크되어 있는 것보다 여기에 더 많이 소개할 수 있도록 하겠습니다. + +- [Kubernetes playground – How to choose your platform](https://vzilla.co.uk/vzilla-blog/building-the-home-lab-kubernetes-playground-part-1) +- [Kubernetes playground – Setting up your cluster](https://vzilla.co.uk/vzilla-blog/building-the-home-lab-kubernetes-playground-part-2) +- [Getting started with Amazon Elastic Kubernetes Service (Amazon EKS)](https://vzilla.co.uk/vzilla-blog/getting-started-with-amazon-elastic-kubernetes-service-amazon-eks) +- [Getting started with Microsoft Azure Kubernetes Service (AKS)](https://vzilla.co.uk/vzilla-blog/getting-started-with-microsoft-azure-kubernetes-service-aks) +- [Getting Started with Microsoft AKS – Azure PowerShell Edition](https://vzilla.co.uk/vzilla-blog/getting-started-with-microsoft-aks-azure-powershell-edition) +- [Getting started with Google Kubernetes Service (GKE)](https://vzilla.co.uk/vzilla-blog/getting-started-with-google-kubernetes-service-gke) +- [Kubernetes, How to – AWS Bottlerocket + Amazon EKS](https://vzilla.co.uk/vzilla-blog/kubernetes-how-to-aws-bottlerocket-amazon-eks) +- [Getting started with CIVO Cloud](https://vzilla.co.uk/vzilla-blog/getting-started-with-civo-cloud) +- [Minikube - Kubernetes Demo Environment For Everyone](https://vzilla.co.uk/vzilla-blog/project_pace-kasten-k10-demo-environment-for-everyone) + +### Kubernetes 시리즈에서 다룰 내용 + +- Kubernetes 아키텍처 +- Kubectl 커맨드 +- Kubernetes YAML +- Kubernetes Ingress +- Kubernetes Services +- Helm 패키지 관리자 +- 영속성 스토리지 +- stateful 앱 + +## 자료 + +- [Kubernetes Documentation](https://kubernetes.io/docs/home/) +- [TechWorld with Nana - Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]](https://www.youtube.com/watch?v=X48VuDVv0do) +- [TechWorld with Nana - Kubernetes Crash Course for Absolute Beginners](https://www.youtube.com/watch?v=s_o8dwzRlu4) +- [Kunal Kushwaha - Kubernetes Tutorial for Beginners | What is Kubernetes? Architecture Simplified!](https://www.youtube.com/watch?v=KVBON1lA9N8) + +[Day 51](day51.md)에서 봐요! diff --git a/2022/ko/Days/day51.md b/2022/ko/Days/day51.md new file mode 100644 index 0000000..a5da888 --- /dev/null +++ b/2022/ko/Days/day51.md @@ -0,0 +1,178 @@ +--- +title: '#90DaysOfDevOps - Deploying your first Kubernetes Cluster - Day 51' +published: false +description: 90DaysOfDevOps - Deploying your first Kubernetes Cluster +tags: 'DevOps, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048778 +--- + +## 첫 번째 Kubernetes 클러스터 배포하기 + +이 글에서는 Minikube를 사용하여 로컬 머신에서 Kubernetes 클러스터를 시작하고 실행해 보겠습니다. 이렇게 하면 나머지 Kubernetes 섹션을 위한 기본 Kubernetes 클러스터가 제공되지만, 나중에 VirtualBox에서도 Kubernetes 클러스터를 배포하는 방법을 살펴볼 것입니다. 퍼블릭 클라우드에서 관리형 Kubernetes 클러스터를 스핀업하는 대신 이 방법을 선택한 이유는 무료 티어를 사용하더라도 비용이 들기 때문이며, 이전 섹션 [Day 50](day50.md)에서 해당 환경을 스핀업하려는 경우 몇 가지 블로그를 공유한 바 있습니다. + +### Minikube란? + +> "Minikube는 macOS, Linux, Windows에서 로컬 Kubernetes 클러스터를 빠르게 설정합니다. 우리는 애플리케이션 개발자와 새로운 Kubernetes 사용자를 돕는 데 주력하고 있습니다." + +위에 해당되지 않을 수도 있지만, 저는 Minikube가 Kubernetes 방식으로 무언가를 테스트하고 싶을 때 앱을 쉽게 배포할 수 있고 몇 가지 놀라운 애드온이 있다는 것을 알게 되었으며, 이 글에서도 다룰 것입니다. + +우선, 워크스테이션 OS에 관계없이 Minikube를 실행할 수 있습니다. 먼저 [프로젝트 페이지](https://minikube.sigs.k8s.io/docs/start/)로 이동합니다. 첫 번째 옵션은 설치 방법을 선택하는 것입니다. 저는 이 방법을 사용하지 않았지만, 여러분은 제가 사용하는 방법과 다른 방법을 선택할 수 있습니다(곧 소개할 예정입니다). + +아래에 언급된 "Container or virtual machine managers, such as Docker, Hyper kit, Hyper-V, KVM, Parallels, Podman, VirtualBox, or VMware"가 있어야 한다고 명시되어 있는데, 이것이 Minikube가 실행되는 곳이고 쉬운 옵션이며 저장소에 명시되어 있지 않은 한 저는 Docker를 사용하고 있습니다. 그리고 [여기](https://docs.docker.com/get-docker/)에서 시스템에 Docker를 설치할 수 있습니다. + +![](/2022/Days/Images/Day51_Kubernetes1.png) + +### Minikube 및 기타 전제조건을 설치하는 방법... + +저는 한동안 arkade를 사용하여 모든 Kubernetes 도구와 CLI를 설치해왔는데, arkade를 시작하기 위한 설치 단계는 이 [github 저장소](https://github.com/alexellis/arkade)에서 확인할 수 있습니다. 설치가 필요한 다른 블로그 게시물에서도 언급했습니다. arkade get을 누른 다음 툴이나 CLI를 사용할 수 있는지 확인하는 것만으로도 간단합니다. 리눅스 섹션에서 패키지 관리자와 소프트웨어를 얻는 프로세스에 대해 이야기했는데, arkade는 모든 앱과 Kubernetes용 CLI를 위한 마켓플레이스라고 생각하시면 됩니다. 시스템에서 사용할 수 있는 매우 편리한 작은 도구로, GO로 작성되어 크로스 플랫폼을 지원합니다. + +![](/2022/Days/Images/Day51_Kubernetes2.png) + +arkade 내에서 사용 가능한 긴 앱 목록의 일부로 Minikube도 그중 하나이므로 간단한 `arkade get minikube` 명령으로 바이너리를 다운로드하고 이제 바로 사용할 수 있습니다. + +![](/2022/Days/Images/Day51_Kubernetes3.png) + +또한 도구의 일부로 kubectl이 필요하므로 arkade를 통해서도 얻을 수 있으며, 위에서 언급한 curl 명령의 일부로 Minikube 문서에 나와 있다고 생각합니다. 이 포스트의 뒷부분에서 kubectl에 대해 더 자세히 다루겠습니다. + +### Kubernetes 클러스터 시작 및 실행하기 + +이 특정 섹션에서는 로컬 머신에서 Kubernetes 클러스터를 시작하고 실행할 때 사용할 수 있는 옵션에 대해 다루고자 합니다. 다음 명령을 실행하기만 하면 사용할 수 있는 클러스터가 스핀업됩니다. + +커맨드라인에 minikube가 사용되며, 모든 설치가 완료되면 `minikube start`를 실행하여 첫 번째 Kubernetes 클러스터를 배포할 수 있습니다. 아래에서 중첩된 가상화 노드를 실행할 위치에 대한 기본값이 Docker 드라이버인 것을 확인할 수 있습니다. 게시물의 시작 부분에서 사용 가능한 다른 옵션에 대해 언급했는데, 다른 옵션은 이 로컬 Kubernetes 클러스터의 모양을 확장하고자 할 때 도움이 됩니다. + +이 인스턴스에서는 단일 Minikube 클러스터가 단일 docker 컨테이너로 구성되며, 이 컨테이너에는 컨트롤 플레인 노드와 워커 노드가 하나의 인스턴스에 포함됩니다. 일반적으로는 이러한 노드를 분리합니다. 다음 섹션에서는 아직 홈 랩 유형의 Kubernetes 환경이지만 프로덕션 아키텍처에 조금 더 가까운 환경을 살펴볼 것입니다. + +![](/2022/Days/Images/Day51_Kubernetes4.png) + +지금까지 몇 번 언급했지만, 저는 사용 가능한 애드온 때문에 Minikube를 좋아하는데, 처음부터 필요한 모든 애드온을 포함한 간단한 명령으로 클러스터를 배포할 수 있기 때문에 매번 동일한 설정을 배포하는 데 도움이 됩니다. + +아래에서 이러한 애드온 목록을 볼 수 있는데, 저는 일반적으로 `CSI-host path-driver`와 `volumesnapshots` 애드온을 사용하지만, 아래에서 긴 목록을 볼 수 있습니다. 물론 이러한 애드온은 나중에 Kubernetes 섹션에서 다루겠지만 일반적으로 Helm을 사용하여 배포할 수 있지만 훨씬 더 간단해진다. + +![](/2022/Days/Images/Day51_Kubernetes5.png) + +또한 프로젝트에서 몇 가지 추가 구성을 정의하고 있는데, apiserver는 임의의 API 포트 대신 6433으로 설정하고 container runtime도 containerd로 정의하고 있지만 기본값은 docker이고 CRI-O도 사용할 수 있습니다. 또한 특정 Kubernetes 버전도 설정하고 있습니다. + +![](/2022/Days/Images/Day51_Kubernetes6.png) + +이제 Minikube를 사용하여 첫 번째 Kubernetes 클러스터를 배포할 준비가 되었습니다. 클러스터와 상호 작용하려면 `kubectl`도 필요하다고 앞서 언급했습니다. arkade를 사용하여 `arkade get kubectl` 명령으로 kubectl을 설치할 수 있습니다. + +![](/2022/Days/Images/Day51_Kubernetes7.png) + +또는 다음에서 크로스 플랫폼으로 다운로드할 수 있습니다. + +- [리눅스](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux) +- [macOS](https://kubernetes.io/docs/tasks/tools/install-kubectl-macos) +- [윈도우](https://kubernetes.io/docs/tasks/tools/install-kubectl-windows) + +kubectl을 설치했으면 `kubectl get nodes`와 같은 간단한 명령으로 클러스터와 상호 작용할 수 있습니다. + +![](/2022/Days/Images/Day51_Kubernetes8.png) + +### kubectl이란? + +이제 Minikube와 Kubernetes 클러스터를 모두 설치하고 실행 중이며, Minikube에 대해서는 최소한 Minikube가 무엇을 하는지에 대해 설명했지만, kubectl이 무엇이고 어떤 역할을 하는지에 대해서는 설명하지 않았습니다. + +kubectl은 Kubernetes 클러스터와 상호 작용하는 데 사용되거나 상호 작용할 수 있게 해주는 클리어로, 여기서는 Minikube 클러스터와 상호 작용하는 데 사용하고 있지만 퍼블릭 클라우드 전반의 엔터프라이즈 클러스터와 상호 작용하는 데도 kubectl을 사용할 수 있습니다. + +우리는 애플리케이션을 배포하고 클러스터 리소스를 검사 및 관리하기 위해 kubectl을 사용합니다. 훨씬 더 자세한 개요는 Kubernetes [공식 문서](https://kubernetes.io/docs/reference/kubectl/overview/)에서 확인할 수 있습니다. + +kubectl은 이전 포스트에서 간략하게 다룬 컨트롤 플레인 노드에 있는 API 서버와 상호작용합니다. + +### kubectl 치트 시트 + +공식 문서와 함께, 필자는 kubectl 명령어를 찾을 때 [이 페이지](https://unofficial-kubernetes.readthedocs.io/en/latest/)를 항상 열어두는 것을 추천합니다. + +| Listing Resources | | +| ------------------------ | ------------------------------------------ | +| kubectl get nodes | 클러스터의 모든 노드 나열 | +| kubectl get namespaces | 클러스터의 모든 네임스페이스 나열 | +| kubectl get pods | 기본 네임스페이스 클러스터에 모든 pod 나열 | +| kubectl get pods -n name | "이름" 네임스페이스에 모든 pod를 나열 | + +| Creating Resources | | +| ----------------------------- | ------------------------------------------ | +| kubectl create namespace name | "name"이라는 네임스페이스를 생성 | +| kubectl create -f [filename] | JSON 또는 YAML 파일에서 리소스를 다시 생성 | + +| Editing Resources | | +| ---------------------------- | ------------- | +| kubectl edit svc/servicename | 서비스를 편집 | + +| More detail on Resources | | +| ------------------------ | ------------------------------------- | +| kubectl describe nodes | 원하는 수의 리소스 상태를 자세히 표시 | + +| Delete Resources | | +| ------------------ | --------------------------------------------------------- | +| kubectl delete pod | 리소스를 제거할 수 있으며, 이는 stdin 또는 파일에서 제거. | + +예를 들어 `-n`은 `namespace`의 줄임말로, 명령을 입력하기 쉬울 뿐만 아니라 스크립트를 작성할 때 훨씬 더 깔끔한 코드를 만들 수 있습니다. + +| Short name | Full name | +| ---------- | -------------------------- | +| csr | certificatesigningrequests | +| cs | componentstatuses | +| cm | configmaps | +| ds | daemonsets | +| deploy | deployments | +| ep | endpoints | +| ev | events | +| hpa | horizontalpodautoscalers | +| ing | ingresses | +| limits | limitranges | +| ns | namespaces | +| no | nodes | +| pvc | persistentvolumeclaims | +| pv | persistentvolumes | +| po | pods | +| pdb | poddisruptionbudgets | +| psp | podsecuritypolicies | +| rs | replicasets | +| rc | replicationcontrollers | +| quota | resourcequotas | +| sa | serviceaccounts | +| svc | services | + +마지막으로 추가하고 싶은 것은 데이터 서비스를 표시하기 위해 데모 환경을 빠르게 스핀업하고 Kasten K10으로 이러한 워크로드를 보호하기 위해 Minikube와 관련된 또 다른 프로젝트를 만들었습니다. [Project Pace](https://github.com/MichaelCade/project_pace)는 여기에서 찾을 수 있으며 여러분의 피드백이나 상호 작용을 원하며 Minikube 클러스터를 배포하고 다양한 데이터 서비스 애플리케이션을 만드는 몇 가지 자동화된 방법을 표시하거나 포함합니다. + +다음에는 VirtualBox를 사용하여 여러 노드를 가상 머신에 배포하는 방법을 살펴보겠지만, Linux 섹션에서 vagrant를 사용하여 머신을 빠르게 스핀업하고 원하는 방식으로 소프트웨어를 배포했던 것처럼 여기에서도 쉽게 진행할 것입니다. + +어제 포스트에 배포 중인 다양한 Kubernetes 클러스터에 대해 제가 수행한 워크스루 블로그인 이 목록을 추가했습니다. + +- [Kubernetes playground – How to choose your platform](https://vzilla.co.uk/vzilla-blog/building-the-home-lab-kubernetes-playground-part-1) +- [Kubernetes playground – Setting up your cluster](https://vzilla.co.uk/vzilla-blog/building-the-home-lab-kubernetes-playground-part-2) +- [Getting started with Amazon Elastic Kubernetes Service (Amazon EKS)](https://vzilla.co.uk/vzilla-blog/getting-started-with-amazon-elastic-kubernetes-service-amazon-eks) +- [Getting started with Microsoft Azure Kubernetes Service (AKS)](https://vzilla.co.uk/vzilla-blog/getting-started-with-microsoft-azure-kubernetes-service-aks) +- [Getting Started with Microsoft AKS – Azure PowerShell Edition](https://vzilla.co.uk/vzilla-blog/getting-started-with-microsoft-aks-azure-powershell-edition) +- [Getting started with Google Kubernetes Service (GKE)](https://vzilla.co.uk/vzilla-blog/getting-started-with-google-kubernetes-service-gke) +- [Kubernetes, How to – AWS Bottlerocket + Amazon EKS](https://vzilla.co.uk/vzilla-blog/kubernetes-how-to-aws-bottlerocket-amazon-eks) +- [Getting started with CIVO Cloud](https://vzilla.co.uk/vzilla-blog/getting-started-with-civo-cloud) +- [Minikube - Kubernetes Demo Environment For Everyone](https://vzilla.co.uk/vzilla-blog/project_pace-kasten-k10-demo-environment-for-everyone) +- [Minikube - Deploy Minikube Using Vagrant and Ansible on VirtualBox](https://medium.com/techbeatly/deploy-minikube-using-vagrant-and-ansible-on-virtualbox-infrastructure-as-code-2baf98188847) + +### Kubernetes 시리즈에서 다룰 내용 + +아래에 언급된 내용 중 일부를 다루기 시작했지만, 내일 두 번째 클러스터 배포를 통해 더 많은 실습을 한 후 클러스터에 애플리케이션 배포를 시작할 수 있습니다. + +- Kubernetes 아키텍처 +- Kubectl 커맨드 +- Kubernetes YAML +- Kubernetes Ingress +- Kubernetes Services +- Helm 패키지 관리자 +- 영속성 스토리지 +- stateful 앱 + +## 자료 + +사용하신 무료 리소스가 있다면 리포지토리에 PR을 통해 여기에 추가해 주시면 기꺼이 포함시켜드리겠습니다. + +- [Kubernetes Documentation](https://kubernetes.io/docs/home/) +- [TechWorld with Nana - Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]](https://www.youtube.com/watch?v=X48VuDVv0do) +- [TechWorld with Nana - Kubernetes Crash Course for Absolute Beginners](https://www.youtube.com/watch?v=s_o8dwzRlu4) +- [Kunal Kushwaha - Kubernetes Tutorial for Beginners | What is Kubernetes? Architecture Simplified!](https://www.youtube.com/watch?v=KVBON1lA9N8) +- [Techbeatly - Deploy Minikube Using Vagrant and Ansible on VirtualBox](https://www.youtube.com/watch?v=xPLQqHbp9BM&t=371s) + +[Day 52](day52.md)에서 봐요! diff --git a/2022/ko/Days/day52.md b/2022/ko/Days/day52.md new file mode 100644 index 0000000..29e2c9a --- /dev/null +++ b/2022/ko/Days/day52.md @@ -0,0 +1,182 @@ +--- +title: '#90DaysOfDevOps - Setting up a multinode Kubernetes Cluster - Day 52' +published: false +description: 90DaysOfDevOps - Setting up a multinode Kubernetes Cluster +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049050 +--- + +## 멀티노드 Kubernetes 클러스터 설정하기 + +이 제목을 "Vagrant로 멀티노드 Kubernetes 클러스터 설정하기"로 하고 싶었지만, 너무 길 것 같았습니다! + +어제 세션에서는 멋진 프로젝트를 사용하여 첫 번째 Kubernetes 클러스터를 배포하고 Kubernetes를 사용할 때 접하게 될 가장 중요한 CLI 도구(kubectl)를 조금 실습해 보았습니다. + +여기서는 VirtualBox를 기본으로 사용하지만, 지난번 리눅스 섹션에서 Vagrant에 대해 이야기할 때 언급했듯이 지원되는 모든 하이퍼바이저 또는 가상화 도구를 사용할 수 있습니다. 리눅스 섹션에서 우분투 머신을 배포한 것은 [Day 14](day14.md)였습니다. + +### Vagrant에 대한 간략한 요약 + +Vagrant는 가상 머신의 라이프사이클을 관리하는 CLI 유틸리티입니다. vSphere, Hyper-v, Virtual Box, Docker 등 다양한 플랫폼에서 가상 머신을 스핀업 및 스핀다운하는 데 Vagrant를 사용할 수 있습니다. 다른 공급업체도 있지만 여기서는 Virtual Box를 사용하고 있으므로 계속 사용하겠습니다. + +이 [블로그 및 리포지토리](https://devopscube.com/kubernetes-cluster-vagrant/)를 기준으로 하여 구성을 안내해 드리겠습니다. 하지만 Kubernetes 클러스터를 처음 배포하는 경우라면 수동으로 이 작업을 수행하는 방법도 살펴보고 최소한 어떤 모습인지 알고 계실 것을 권해드리고 싶습니다. Kubernetes는 릴리스될 때마다 더욱 효율적으로 개선되고 있다고 말씀드리고 싶습니다. 저는 이것을 VMware와 ESX 시절에 비유하자면, ESX 서버 3대를 배포하는 데 적어도 하루는 필요했지만, 지금은 한 시간 안에 이를 실행할 수 있습니다. 저희는 Kubernetes와 관련해서는 그 방향으로 나아가고 있습니다. + +### Kubernetes 랩 환경 + +환경을 구축하는 데 사용할 vagrantfile을 [Kubernetes 폴더](/2022/Days/Kubernetes)에 업로드했습니다. 이 파일을 잡고 터미널에서 이 디렉토리로 이동합니다. 저는 다시 Windows를 사용하므로 PowerShell을 사용하여 vagrant로 워크스테이션 명령을 수행하겠습니다. vagrant가 없는 경우 어제 Minikube 및 기타 도구를 설치할 때 다룬 arkade를 사용할 수 있습니다. 간단한 명령어인 `arkade get vagrant`를 실행하면 최신 버전의 vagrant를 다운로드하여 설치할 수 있습니다. + +디렉토리에 들어가면 `vagrant up`을 실행하고 모든 것이 올바르게 구성되었다면 터미널에 다음과 같은 킥오프가 표시됩니다. + +![](/2022/Days/Images/Day52_Kubernetes1.png) + +터미널에서 몇 가지 단계가 진행되는 것을 볼 수 있지만, 그동안 우리가 여기서 무엇을 빌드하고 있는지 살펴봅시다. + +![](/2022/Days/Images/Day52_Kubernetes2.png) + +위에서 보면 3개의 가상 머신을 빌드하고 컨트롤 플레인 노드와 두 개의 워커 노드가 있다는 것을 알 수 있습니다. [Day 49](day49.md)로 돌아가면 이미지에서 볼 수 있는 이러한 영역에 대한 설명이 더 있습니다. + +또한 이미지에서는 클러스터 외부에서 kubectl 액세스가 발생하여 해당 kube apiserver에 도달하는 것으로 표시되어 있지만, 실제로는 vagrant 프로비저닝의 일부로 각 노드 내에서 클러스터에 액세스할 수 있도록 각 노드에 kubectl을 배포하고 있습니다. + +이 실습을 구축하는 과정은 설정에 따라 5분에서 30분 정도 걸릴 수 있습니다. + +곧 스크립트에 대해서도 다룰 예정이지만, 배포의 일부로 3개의 스크립트를 호출하는 vagrant 파일을 보면 클러스터가 실제로 생성되는 곳이라는 것을 알 수 있습니다. Vagrant boxes를 사용하여 가상 머신과 OS 설치를 배포하는 것이 얼마나 쉬운지 살펴보았지만, 배포 프로세스의 일부로 셸 스크립트를 실행할 수 있는 기능이 있다는 것은 이러한 실습 빌드 아웃 자동화와 관련하여 매우 흥미로운 부분입니다. + +완료되면 터미널에서 노드 중 하나에 `vagrant ssh master`로 접속하면 액세스할 수 있으며, 기본 사용자 이름과 비밀번호는 `vagrant/vagrant`입니다. + +원하는 경우 `vagrant ssh node01` 및 `vagrant ssh node02`를 사용하여 작업자 노드에 액세스할 수도 있습니다. + +![](/2022/Days/Images/Day52_Kubernetes3.png) + +이제 새 클러스터의 위 노드 중 하나에서 `kubectl get nodes`를 실행하여 3노드 클러스터와 그 상태를 확인할 수 있습니다. + +![](/2022/Days/Images/Day52_Kubernetes4.png) + +이 시점에서, 컨트롤 플레인 노드 1개와 워커 노드 2개로 구성된 3노드 클러스터가 실행되고 있습니다. + +### Vagrant 파일 및 셸 스크립트 연습 + +vagrantfile을 살펴보면 여러 작업자 노드, VirtualBox 내의 브리지 네트워크에 대한 네트워킹 IP 주소, 그리고 일부 이름 지정을 정의하고 있음을 알 수 있습니다. 또한 특정 호스트에서 실행하려는 일부 스크립트를 호출하고 있음을 알 수 있습니다. + +```shell +NUM_WORKER_NODES=2 +IP_NW="10.0.0." +IP_START=10 + +Vagrant.configure("2") do |config| + config.vm.provision "shell", inline: <<-SHELL + apt-get update -y + echo "$IP_NW$((IP_START)) master-node" >> /etc/hosts + echo "$IP_NW$((IP_START+1)) worker-node01" >> /etc/hosts + echo "$IP_NW$((IP_START+2)) worker-node02" >> /etc/hosts + SHELL + config.vm.box = "bento/ubuntu-21.10" + config.vm.box_check_update = true + + config.vm.define "master" do |master| + master.vm.hostname = "master-node" + master.vm.network "private_network", ip: IP_NW + "#{IP_START}" + master.vm.provider "virtualbox" do |vb| + vb.memory = 4048 + vb.cpus = 2 + vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] + end + master.vm.provision "shell", path: "scripts/common.sh" + master.vm.provision "shell", path: "scripts/master.sh" + end + + (1..NUM_WORKER_NODES).each do |i| + config.vm.define "node0#{i}" do |node| + node.vm.hostname = "worker-node0#{i}" + node.vm.network "private_network", ip: IP_NW + "#{IP_START + i}" + node.vm.provider "virtualbox" do |vb| + vb.memory = 2048 + vb.cpus = 1 + vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] + end + node.vm.provision "shell", path: "scripts/common.sh" + node.vm.provision "shell", path: "scripts/node.sh" + end + end + end +``` + +실행 중인 스크립트를 분석해 보겠습니다. 특정 노드에서 실행할 세 개의 스크립트가 위의 VAGRANTFILE에 나열되어 있습니다. + +`master.vm.provision "shell", path: "scripts/common.sh"` + +위의 스크립트는 노드를 준비하는 데 초점을 맞출 것이며, 3개의 노드 모두에서 실행될 것이며, 기존의 모든 Docker 구성 요소를 제거하고 Docker와 ContainerD는 물론 kubeadm, kubelet 및 kubectl을 다시 설치합니다. 이 스크립트는 또한 시스템의 기존 소프트웨어 패키지도 업데이트합니다. + +`master.vm.provision "shell", path: "scripts/master.sh"` + +master.sh 스크립트는 컨트롤 플레인 노드에서만 실행되며, 이 스크립트는 kubeadm 커맨드를 사용하여 Kubernetes 클러스터를 생성합니다. 또한 이 클러스터에 대한 액세스를 위한 구성 컨텍스트도 준비할 것이며, 이는 다음에 다룰 것입니다. + +`node.vm.provision "shell", path: "scripts/node.sh"` + +이것은 단순히 마스터가 생성한 구성을 가져와서 우리 노드를 Kubernetes 클러스터에 추가하는 것이며, 이 추가 프로세스는 다시 kubeadm과 config 폴더에서 찾을 수 있는 다른 스크립트를 사용합니다. + +### Kubernetes 클러스터에 액세스하기 + +이제 두 개의 클러스터가 배포되었습니다. 이전 섹션에서 배포한 Minikube 클러스터와 방금 VirtualBox에 배포한 새로운 3노드 클러스터가 있습니다. + +또한 vagrant를 실행한 머신에서도 액세스할 수 있는 구성 파일에는 워크스테이션에서 클러스터에 액세스하는 방법이 포함되어 있습니다. + +이를 보여드리기 전에 컨텍스트에 대해 말씀드리겠습니다. + +![](/2022/Days/Images/Day52_Kubernetes5.png) + +컨텍스트가 중요하며, 데스크톱이나 노트북에서 Kubernetes 클러스터에 액세스할 수 있는 기능이 필요합니다. 다양한 옵션이 존재하며 사람들은 각기 다른 운영 체제를 일상적으로 사용합니다. + +기본적으로, Kubernetes CLI 클라이언트(kubectl)는 엔드포인트 및 자격 증명과 같은 Kubernetes 클러스터 세부 정보를 저장하기 위해 C:\Users\username.kube\config를 사용합니다. 클러스터를 배포한 경우 해당 위치에서 이 파일을 볼 수 있습니다. 하지만 지금까지 마스터 노드에서 SSH 또는 다른 방법을 통해 모든 kubectl 명령을 실행했다면 이 포스팅이 워크스테이션과 연결할 수 있는 방법을 이해하는 데 도움이 되길 바랍니다. + +그런 다음 클러스터에서 kubeconfig 파일을 가져오거나 배포된 구성 파일에서 가져올 수도 있고, SCP를 통해 이 파일의 내용을 가져오거나 마스터 노드에 콘솔 세션을 열고 로컬 윈도우 머신에 복사할 수도 있습니다. + +![](/2022/Days/Images/Day52_Kubernetes6.png) + +그런 다음 해당 구성 파일의 복사본을 가져와서 `$HOME/.kube/config` 위치로 이동합니다. + +![](/2022/Days/Images/Day52_Kubernetes7.png) + +이제 로컬 워크스테이션에서 `kubectl cluster-info`와 `kubectl get nodes`를 실행하여 클러스터에 액세스할 수 있는지 확인할 수 있습니다. + +![](/2022/Days/Images/Day52_Kubernetes8.png) + +이렇게 하면 윈도우 머신에서 연결 및 제어가 가능할 뿐만 아니라 윈도우 머신에서 특정 서비스에 액세스하기 위해 포트 포워딩을 수행할 수 있습니다. + +워크스테이션에서 여러 클러스터를 관리하는 방법에 관심이 있으시다면 [여기](https://vzilla.co.uk/vzilla-blog/building-the-home-lab-kubernetes-playground-part-6)에 더 자세한 안내가 있습니다. + +이 목록은 제가 배포 중인 다양한 Kubernetes 클러스터에 대해 수행한 워크스루 블로그입니다. + +- [Kubernetes playground – How to choose your platform](https://vzilla.co.uk/vzilla-blog/building-the-home-lab-kubernetes-playground-part-1) +- [Kubernetes playground – Setting up your cluster](https://vzilla.co.uk/vzilla-blog/building-the-home-lab-kubernetes-playground-part-2) +- [Getting started with Amazon Elastic Kubernetes Service (Amazon EKS)](https://vzilla.co.uk/vzilla-blog/getting-started-with-amazon-elastic-kubernetes-service-amazon-eks) +- [Getting started with Microsoft Azure Kubernetes Service (AKS)](https://vzilla.co.uk/vzilla-blog/getting-started-with-microsoft-azure-kubernetes-service-aks) +- [Getting Started with Microsoft AKS – Azure PowerShell Edition](https://vzilla.co.uk/vzilla-blog/getting-started-with-microsoft-aks-azure-powershell-edition) +- [Getting started with Google Kubernetes Service (GKE)](https://vzilla.co.uk/vzilla-blog/getting-started-with-google-kubernetes-service-gke) +- [Kubernetes, How to – AWS Bottlerocket + Amazon EKS](https://vzilla.co.uk/vzilla-blog/kubernetes-how-to-aws-bottlerocket-amazon-eks) +- [Getting started with CIVO Cloud](https://vzilla.co.uk/vzilla-blog/getting-started-with-civo-cloud) +- [Minikube - Kubernetes Demo Environment For Everyone](https://vzilla.co.uk/vzilla-blog/project_pace-kasten-k10-demo-environment-for-everyone) + +### Kubernetes 시리즈에서 다룰 내용 + +아래에 언급된 내용 중 일부를 다루기 시작했지만, 내일 두 번째 클러스터 배포를 통해 더 많은 실습을 한 다음 클러스터에 애플리케이션 배포를 시작할 수 있습니다. + +- Kubernetes 아키텍처 +- Kubectl 커맨드 +- Kubernetes YAML +- Kubernetes Ingress +- Kubernetes Services +- Helm 패키지 관리자 +- 영속성 스토리지 +- stateful 앱 + +## 자료 + +사용하신 무료 리소스가 있으시면 리포지토리에 PR을 통해 여기에 추가해 주시면 기꺼이 포함시켜 드리겠습니다. + +- [Kubernetes Documentation](https://kubernetes.io/docs/home/) +- [TechWorld with Nana - Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]](https://www.youtube.com/watch?v=X48VuDVv0do) +- [TechWorld with Nana - Kubernetes Crash Course for Absolute Beginners](https://www.youtube.com/watch?v=s_o8dwzRlu4) +- [Kunal Kushwaha - Kubernetes Tutorial for Beginners | What is Kubernetes? Architecture Simplified!](https://www.youtube.com/watch?v=KVBON1lA9N8) + +[Day 53](day53.md)에서 봐요! diff --git a/2022/ko/Days/day53.md b/2022/ko/Days/day53.md new file mode 100644 index 0000000..e648020 --- /dev/null +++ b/2022/ko/Days/day53.md @@ -0,0 +1,129 @@ +--- +title: '#90DaysOfDevOps - Rancher Overview - Hands On - Day 53' +published: false +description: 90DaysOfDevOps - Rancher Overview - Hands On +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048742 +--- + +## Rancher 개요 - 핸즈온 + +이 섹션에서는 Rancher에 대해 살펴볼 것인데, 지금까지는 클러스터 관리에 대한 좋은 가시성을 운영팀에 제공하는 몇 가지 좋은 UI와 멀티클러스터 관리 도구가 있지만, 지금까지 한 모든 작업은 cli와 kubectl을 사용했습니다. + +Rancher는 [사이트](https://rancher.com/)에 따르면 + +> Rancher는 컨테이너를 도입하는 팀을 위한 완벽한 소프트웨어 스택입니다. 이 스택은 모든 인프라에서 여러 개의 Kubernetes 클러스터를 관리할 때 발생하는 운영 및 보안 문제를 해결하는 동시에 데브옵스 팀에 컨테이너화된 워크로드를 실행하기 위한 통합 도구를 제공합니다. + +Rancher를 사용하면 거의 모든 위치에서 프로덕션급 Kubernetes 클러스터를 배포할 수 있으며 중앙 집중식 인증, 액세스 제어 및 통합 가시성을 제공합니다. 이전 섹션에서 Kubernetes와 관련하여 거의 압도적인 선택의 폭이 있으며, 어디에서 실행해야 하는지 또는 실행할 수 있는지에 대해 언급했지만, Rancher를 사용하면 어디에 있든 상관없습니다. + +### Rancher 배포 + +가장 먼저 해야 할 일은 로컬 워크스테이션에 Rancher를 배포하는 것입니다. 이 단계를 진행하기 위해 선택할 수 있는 몇 가지 방법과 위치가 있는데, 저는 로컬 워크스테이션을 사용하고 Rancher를 docker 컨테이너로 실행하고 싶습니다. 아래 명령을 실행하면 컨테이너 이미지를 가져온 다음 Rancher UI에 액세스할 수 있습니다. + +다른 Rancher 배포 방법은 [Rancher 빠른 시작 가이드](https://rancher.com/docs/rancher/v2.6/en/quick-start-guide/deployment/)에서 확인할 수 있습니다. + +`sudo docker run -d --restart=unless-stopped -p 80:80 -p 443:443 --privileged rancher/rancher` + +docker 데스크톱에서 볼 수 있듯이 실행 중인 Rancher 컨테이너가 있습니다. + +![](/2022/Days/Images/Day53_Kubernetes1.png) + +### Rancher UI 액세스 + +위의 컨테이너가 실행 중이면 웹 페이지를 통해 컨테이너로 이동할 수 있어야 합니다. `https://localhost`를 입력하면 아래와 같이 로그인 페이지가 나타납니다. + +![](/2022/Days/Images/Day53_Kubernetes2.png) + +아래 안내에 따라 필요한 비밀번호를 입력합니다. 저는 Windows를 사용하고, grep 명령이 필요하기 때문에 Windows용 bash를 사용하기로 했습니다. + +![](/2022/Days/Images/Day53_Kubernetes3.png) + +이제 위의 비밀번호를 사용하여 로그인하면 다음 페이지에서 새 비밀번호를 정의할 수 있습니다. + +![](/2022/Days/Images/Day53_Kubernetes4.png) + +위의 작업을 완료하면 로그인이 완료되고 시작 화면을 볼 수 있습니다. Rancher 배포의 일부로 로컬 K3 클러스터가 프로비저닝된 것도 볼 수 있습니다. + +![](/2022/Days/Images/Day53_Kubernetes5.png) + +### Rancher에 대한 간략한 둘러보기 + +가장 먼저 살펴볼 것은 로컬로 배포된 K3S 클러스터입니다. 아래에서 클러스터 내부에서 어떤 일이 일어나고 있는지 잘 볼 수 있습니다. 이것은 기본 배포이며 아직 이 클러스터에 아무것도 배포하지 않았습니다. 1개의 노드로 구성되어 있고 5개의 배포가 있는 것을 볼 수 있습니다. 그리고 pod, 코어, 메모리에 대한 몇 가지 통계가 있는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day53_Kubernetes6.png) + +왼쪽 메뉴에는 앱 및 마켓플레이스 탭도 있는데, 이 탭을 통해 클러스터에서 실행할 애플리케이션을 선택할 수 있습니다. 앞서 언급했듯이 Rancher는 여러 개의 다른 클러스터를 실행하거나 관리할 수 있는 기능을 제공합니다. 마켓플레이스를 사용하면 애플리케이션을 매우 쉽게 배포할 수 있습니다. + +![](/2022/Days/Images/Day53_Kubernetes7.png) + +또 한 가지 언급할 것은 오른쪽 상단에 있는 Rancher에서 관리 중인 클러스터에 액세스해야 하는 경우 선택한 클러스터에 대한 kubectl 셸을 열 수 있다는 것입니다. + +![](/2022/Days/Images/Day53_Kubernetes8.png) + +### 새 클러스터 생성 + +지난 두 세션에 걸쳐 로컬에서 Minikube 클러스터를 생성하고 가상박스와 함께 Vagrant를 사용하여 3노드 Kubernetes 클러스터를 생성했으며, Rancher를 사용하여 클러스터를 생성할 수도 있습니다. [Rancher 폴더](/2022/Days/Kubernetes/Rancher)에는 동일한 3개의 노드를 구축할 수 있는 추가 vagrant 파일이 있지만 Kubernetes 클러스터를 생성하는 단계가 없습니다(Rancher가 이 작업을 대신 수행하기를 원합니다). + +그러나 각 노드에서 `common.sh` 스크립트가 계속 실행되는 것을 볼 수 있도록 docker가 설치되고 OS가 업데이트되기를 원합니다. 이것은 또한 Kubeadm, Kubectl 등을 설치합니다. 그러나 노드를 클러스터로 생성하고 조인하기 위한 Kubeadm 명령은 실행되지 않습니다. + +vagrant 폴더 위치로 이동하여 `vagrant up`을 실행하기만 하면 가상 박스에서 3개의 가상 머신을 생성하는 프로세스가 시작됩니다. + +![](/2022/Days/Images/Day53_Kubernetes9.png) + +이제 노드 또는 VM이 제자리에 배치되고 준비되었으므로 Rancher를 사용하여 새로운 Kubernetes 클러스터를 생성할 수 있습니다. 클러스터를 생성하는 첫 번째 화면에서는 클러스터가 어디에 있는지, 즉 퍼블릭 클라우드 관리형 Kubernetes 서비스를 사용 중인지, vSphere 또는 다른 것을 사용 중인지에 대한 몇 가지 옵션을 제공합니다. + +![](/2022/Days/Images/Day53_Kubernetes10.png) + +통합 플랫폼 중 하나를 사용하지 않으므로 "custom"을 선택하겠습니다. 시작 페이지는 클러스터 이름을 정의하는 곳입니다(아래에 로컬이라고 되어 있지만 로컬을 사용할 수 없습니다. 저희 클러스터는 vagrant라고 합니다.) 여기에서 Kubernetes 버전, 네트워크 공급자 및 기타 구성 옵션을 정의하여 Kubernetes 클러스터를 시작하고 실행할 수 있습니다. + +![](/2022/Days/Images/Day53_Kubernetes11.png) + +다음 페이지에서는 활성화할 적절한 서비스와 함께 각 노드에서 실행해야 하는 등록 코드(etcd, 컨트롤 플레인 및 워커)를 제공합니다. 마스터 노드의 경우, etcd와 컨트롤 플레인이 필요하므로 명령은 아래와 같습니다. + +![](/2022/Days/Images/Day53_Kubernetes12.png) + +``` +sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run rancher/rancher-agent:v2.6.3 --server https://10. 0.0.1 --token mpq8cbjjwrj88z4xmf7blqxcfmwdsmq92bmwjpphdkklfckk5hfwc2 --ca-checksum a81944423cbfeeb92be0784edebba1af799735ebc30ba8cbe5cc5f996094f30b --etcd --controlplane +``` + +네트워킹이 올바르게 구성되었다면, 이제 첫 번째 마스터 노드가 등록되고 클러스터가 생성되고 있음을 나타내는 Rancher 대시보드에 다음과 같이 빠르게 표시되어야 합니다. + +![](/2022/Days/Images/Day53_Kubernetes13.png) + +그런 다음 다음 명령으로 각 워커 노드에 대한 등록 프로세스를 반복하면 얼마 후 마켓플레이스를 활용하여 애플리케이션을 배포할 수 있는 클러스터를 실행할 수 있게 됩니다. + +``` +sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run rancher/rancher-agent:v2.6.3 --server https://10. 0.0.1 --token mpq8cbjjwrj88z4xmf7blqxcfmwdsmq92bmwjpphdkklfckk5hfwc2 --ca-checksum a81944423cbfeeb92be0784edebba1af799735ebc30ba8cbe5cc5f996094f30b --worker +``` + +![](/2022/Days/Images/Day53_Kubernetes14.png) + +지난 세 세션 동안, 우리는 몇 가지 다른 방법으로 Kubernetes 클러스터를 시작하고 실행하는 방법을 사용했으며, 남은 날에는 플랫폼에서 가장 중요한 애플리케이션 측면을 살펴볼 것입니다. 서비스 프로비저닝과 Kubernetes에서 서비스를 프로비저닝하고 사용할 수 있는 방법에 대해 살펴보겠습니다. + +부트스트랩 Rancher 노드에 대한 요구사항에 따라 해당 VM에 4GB 램이 있어야 하며 그렇지 않으면 크래시 루프가 발생한다고 들었는데, 이후 워커 노드에 2GB가 있는 것으로 업데이트했습니다. + +### Kubernetes 시리즈에서 다룰 내용 + +아래에 언급된 내용 중 일부를 다루기 시작했지만, 내일 두 번째 클러스터 배포를 통해 더 많은 실습을 한 다음 클러스터에 애플리케이션 배포를 시작할 수 있습니다. + +- Kubernetes 아키텍처 +- Kubectl 커맨드 +- Kubernetes YAML +- Kubernetes Ingress +- Kubernetes Services +- Helm 패키지 관리자 +- 영속성 스토리지 +- stateful 앱 + +## 자료 + +사용하신 무료 리소스가 있으시면 리포지토리에 PR을 통해 여기에 추가해 주시면 기꺼이 포함시켜 드리겠습니다. + +- [Kubernetes Documentation](https://kubernetes.io/docs/home/) +- [TechWorld with Nana - Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]](https://www.youtube.com/watch?v=X48VuDVv0do) +- [TechWorld with Nana - Kubernetes Crash Course for Absolute Beginners](https://www.youtube.com/watch?v=s_o8dwzRlu4) +- [Kunal Kushwaha - Kubernetes Tutorial for Beginners | What is Kubernetes? Architecture Simplified!](https://www.youtube.com/watch?v=KVBON1lA9N8) + +[Day 54](day54.md)에서 봐요! diff --git a/2022/ko/Days/day54.md b/2022/ko/Days/day54.md new file mode 100644 index 0000000..4c7b91b --- /dev/null +++ b/2022/ko/Days/day54.md @@ -0,0 +1,223 @@ +--- +title: '#90DaysOfDevOps - Kubernetes Application Deployment - Day 54' +published: false +description: 90DaysOfDevOps - Kubernetes Application Deployment +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048764 +--- + +## Kubernetes 애플리케이션 배포 + +이제 드디어 일부 애플리케이션을 클러스터에 배포하게 되었는데, 일부 사람들은 이것이 바로 애플리케이션 배포를 위해 Kubernetes가 존재하는 이유라고 말할 수 있습니다. + +여기서 아이디어는 컨테이너 이미지를 가져와서 이제 컨테이너 오케스트레이터로서 Kubernetes를 활용하기 위해 컨테이너 이미지를 Kubernetes 클러스터에 pod로 배포할 수 있다는 것입니다. + +### Kubernetes에 앱 배포하기 + +애플리케이션을 Kubernetes 클러스터에 배포하는 방법에는 여러 가지가 있지만, 가장 일반적인 두 가지 접근 방식인 YAML 파일과 Helm 차트를 다뤄보겠습니다. + +이러한 애플리케이션 배포에는 Minikube 클러스터를 사용할 것입니다. 앞서 언급한 Kubernetes의 구성 요소 또는 빌딩 블록 중 일부를 살펴볼 것입니다. + +이 섹션과 컨테이너 섹션을 통해 이미지와 Kubernetes의 장점, 그리고 이 플랫폼에서 확장을 매우 쉽게 처리할 수 있는 방법에 대해 논의했습니다. + +이 첫 번째 단계에서는 Minikube 클러스터 내에 상태 비저장 애플리케이션을 간단히 생성해 보겠습니다. 사실상의 표준 상태 비저장 애플리케이션인 `nginx`를 사용하여 첫 번째 데모에서 배포를 구성하여 pod를 제공한 다음 nginx pod에서 호스팅하는 간단한 웹 서버로 이동할 수 있는 서비스도 생성할 것입니다. 이 모든 것이 네임스페이스에 포함될 것입니다. + +![](/2022/Days/Images/Day54_Kubernetes1.png) + +### YAML 생성 + +첫 번째 데모에서는 YAML로 수행하는 모든 작업을 정의하고자 합니다. YAML에 대한 전체 섹션이 있을 수 있지만, 여기서는 간략히 살펴보고 마지막에 YAML을 더 자세히 다룰 몇 가지 리소스를 남겨두려고 합니다. + +다음을 하나의 YAML 파일로 만들 수도 있고, 애플리케이션의 각 측면별로 나눌 수도 있습니다. 즉, 네임스페이스, 배포 및 서비스 생성을 위한 별도의 파일일 수 있지만 이 파일에서는 아래에서 `---`를 사용하여 하나의 파일로 구분했습니다. 이 파일은 [여기](/2022/Days/Kubernetes)에서 찾을 수 있습니다(파일명:- nginx-stateless-demo.YAML). + +```Yaml +apiVersion: v1 +kind: Namespace +metadata: + name: nginx + "labels": { + "name": "nginx" + } +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment + namespace: nginx +spec: + selector: + matchLabels: + app: nginx + replicas: 1 + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx + ports: + - containerPort: 80 +--- +apiVersion: v1 +kind: Service +metadata: + name: nginx-service + namespace: nginx +spec: + selector: + app: nginx-deployment + ports: + - protocol: TCP + port: 80 + targetPort: 80 +``` + +### 클러스터 확인 + +배포하기 전에 `nginx`라는 네임스페이스가 없는지 확인해야 하는데, `kubectl get namespace` 명령을 실행하여 확인할 수 있으며, 아래에서 볼 수 있듯이 `nginx`라는 네임스페이스가 없습니다. + +![](/2022/Days/Images/Day54_Kubernetes2.png) + +### 앱을 배포할 시간 + +이제 Minikube 클러스터에 애플리케이션을 배포할 준비가 되었으며, 이 프로세스는 다른 모든 Kubernetes 클러스터에서도 동일하게 작동합니다. + +YAML 파일 위치로 이동한 다음 `kubectl create -f nginx-stateless-demo.yaml`을 실행하면 3개의 오브젝트가 생성되고 네임스페이스, 배포 및 서비스가 생성된 것을 확인할 수 있습니다. + +![](/2022/Days/Images/Day54_Kubernetes3.png) + +클러스터에서 사용 가능한 네임스페이스를 확인하기 위해 `kubectl get namespace` 명령을 다시 실행하면 이제 새 네임스페이스가 있는 것을 확인할 수 있습니다. + +![](/2022/Days/Images/Day54_Kubernetes5.png) + +이제 `kubectl get pods -n nginx`를 사용하여 네임스페이스에 pod가 있는지 확인하면 준비 및 실행 상태의 pod 1개가 있는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day54_Kubernetes4.png) + +또한 `kubectl get service -n nginx`를 실행하여 서비스가 생성되었는지 확인할 수 있습니다. + +![](/2022/Days/Images/Day54_Kubernetes6.png) + +마지막으로, 배포를 확인하여 원하는 구성을 어디에 어떻게 유지하는지 확인할 수 있습니다. + +![](/2022/Days/Images/Day54_Kubernetes7.png) + +위는 몇 가지 알아두면 좋은 명령어를 사용했지만, `kubectl get all -n nginx`를 사용하여 하나의 YAML 파일로 배포한 모든 것을 볼 수도 있습니다. + +![](/2022/Days/Images/Day54_Kubernetes8.png) + +위 그림에서 replicaset가 있는 것을 볼 수 있는데, 배포에서 배포할 이미지의 레플리카 개수를 정의합니다. 처음에는 1로 설정되었지만, 애플리케이션을 빠르게 확장하려면 여러 가지 방법으로 확장할 수 있습니다. + +터미널 내에서 텍스트 편집기를 열고 배포를 수정할 수 있는 `kubectl edit deployment nginx-deployment -n nginx`를 사용하여 파일을 편집할 수 있습니다. + +![](/2022/Days/Images/Day54_Kubernetes9.png) + +터미널 내의 텍스트 편집기에서 위의 내용을 저장했을 때 문제가 없고 올바른 서식이 사용되었다면 네임스페이스에 추가로 배포된 것을 볼 수 있을 것입니다. + +![](/2022/Days/Images/Day54_Kubernetes10.png) + +또한 kubectl과 `kubectl scale deployment nginx-deployment --replicas=10 -n nginx`를 사용하여 레플리카 수를 변경할 수 있습니다. + +![](/2022/Days/Images/Day54_Kubernetes11.png) + +두 방법 중 하나를 사용하려는 경우 이 방법을 사용하여 애플리케이션을 다시 1로 축소할 수 있습니다. 저는 편집 옵션을 사용했지만, 위의 스케일 명령을 사용할 수도 있습니다. + +![](/2022/Days/Images/Day54_Kubernetes12.png) + +여기서 사용 사례를 통해 매우 빠르게 스핀업 및 스핀다운할 수 있을 뿐만 아니라 애플리케이션을 빠르게 확장 및 축소할 수 있다는 것을 알 수 있기를 바랍니다. 이것이 웹 서버라면 부하가 많을 때는 확장하고 부하가 적을 때는 축소할 수 있습니다. + +### 앱 노출하기 + +그렇다면 어떻게 웹 서버에 접속할 수 있을까요? + +위에서 저희 서비스를 보면 사용 가능한 외부 IP가 없으므로 웹 브라우저를 열고 마술처럼 접속할 수는 없습니다. 접속을 위해 몇 가지 옵션이 있습니다. + +**ClusterIP** - 표시되는 IP는 클러스터 내부 네트워크에 있는 클러스터IP입니다. 클러스터 내의 사물만 이 IP에 연결할 수 있습니다. + +**NodePort** - NAT를 사용하여 클러스터에서 선택한 각 노드의 동일한 포트에 서비스를 노출합니다. + +**로드 밸런서** - 현재 클라우드에 외부 로드 밸런서를 생성합니다. 저희는 Minikube를 사용하고 있지만, VirtualBox에서 했던 것과 같이 자체 Kubernetes 클러스터를 구축한 경우 이 기능을 제공하려면 metallb와 같은 로드밸런서를 클러스터에 배포해야 합니다. + +**포트 포워드** - 로컬 호스트에서 내부 Kubernetes 클러스터 프로세스에 액세스하고 상호 작용할 수 있는 포트 포워드 기능도 있습니다. 이 옵션은 테스트 및 결함 발견에만 사용됩니다. + +이제 선택할 수 있는 몇 가지 옵션이 생겼습니다. Minikube에는 본격적인 Kubernetes 클러스터와 비교했을 때 몇 가지 제한 사항이나 차이점이 있습니다. + +다음 명령을 실행하여 로컬 워크스테이션을 사용하여 액세스를 포트 포워딩할 수 있습니다. + +`kubectl port-forward deployment/nginx-deployment -n nginx 8090:80` + +![](/2022/Days/Images/Day54_Kubernetes13.png) + +위 명령을 실행하면 로컬 머신과 포트에 대한 포트 포워딩 역할을 하므로 이 터미널을 사용할 수 없게 됩니다. + +![](/2022/Days/Images/Day54_Kubernetes14.png) + +이제 Minikube를 통해 애플리케이션을 노출하는 방법을 구체적으로 살펴보겠습니다. Minikube를 사용하여 서비스에 연결하기 위한 URL을 생성할 수도 있습니다. [자세한 내용](https://minikube.sigs.k8s.io/docs/commands/service/) + +먼저, `kubectl delete service nginx-service -n nginx`를 사용하여 서비스를 삭제합니다. + +다음으로 `kubectl expose deployment nginx-deployment --name nginx-service --namespace nginx --port=80 --type=NodePort`를 사용하여 새 서비스를 생성합니다. 여기서 expose를 사용하고 유형을 NodePort로 변경한다는 점에 유의하세요. + +![](/2022/Days/Images/Day54_Kubernetes15.png) + +마지막으로 새 터미널에서 `minikube --profile='mc-demo' service nginx-service --url -n nginx`를 실행하여 서비스에 대한 터널을 생성합니다. + +![](/2022/Days/Images/Day54_Kubernetes16.png) + +브라우저 또는 제어를 열고 터미널에서 링크를 클릭합니다. + +![](/2022/Days/Images/Day54_Kubernetes17.png) + +### Helm + +Helm은 애플리케이션을 배포할 수 있는 또 다른 방법입니다. "Kubernetes를 위한 패키지 관리자"로 알려진 Helm에 대한 자세한 내용은 [여기](https://helm.sh/)에서 확인할 수 있습니다. + +Helm은 Kubernetes를 위한 패키지 매니저입니다. Helm은 Kubernetes에서 yum이나 apt에 해당하는 것으로 간주할 수 있습니다. Helm은 패키지 애플리케이션처럼 생각할 수 있는 차트를 배포하는데, 이는 미리 구성된 애플리케이션 리소스를 사용하기 쉬운 하나의 차트로 배포할 수 있는 청사진입니다. 그런 다음 다른 구성 세트로 차트의 다른 버전을 배포할 수 있습니다. + +사용 가능한 모든 Helm 차트를 찾아볼 수 있는 사이트가 있으며 물론 직접 만들 수도 있습니다. 문서도 명확하고 간결하며 이 분야의 다른 모든 신조어들 사이에서 Helm이라는 용어를 처음 들었을 때처럼 어렵지 않습니다. + +Helm을 시작하고 실행하거나 설치하는 것은 매우 간단합니다. 간단합니다. RaspberryPi arm64 장치를 포함한 거의 모든 배포판에 대한 바이너리와 다운로드 링크는 여기에서 찾을 수 있습니다. + +또는 설치 스크립트를 사용할 수도 있는데, 이 경우 최신 버전의 Helm이 다운로드되어 설치된다는 이점이 있습니다. + +```Shell +curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 + +chmod 700 get_helm.sh + +./get_helm.sh +``` + +마지막으로, 애플리케이션 관리자를 위한 패키지 관리자, 맥용 homebrew, 윈도우용 chocolatey, Ubuntu/Debian용 apt, snap 및 pkg도 사용할 수 있습니다. + +지금까지는 Helm이 클러스터에 다양한 테스트 애플리케이션을 다운로드하고 설치하는 데 가장 적합한 방법인 것 같습니다. + +여기에 링크할 수 있는 좋은 리소스로는 Kubernetes 패키지를 찾고, 설치하고, 게시할 수 있는 리소스인 [ArtifactHUB](https://artifacthub.io/)를 들 수 있습니다. 또한 Helm 차트를 표시하는 UI인 [KubeApps](https://kubeapps.com/)에 대해서도 언급하겠습니다. + +### Kubernetes에서 다룰 내용 + +아래에 언급된 내용 중 일부를 다루기 시작했지만, 내일 두 번째 클러스터 배포를 통해 더 많은 실습을 한 후 클러스터에 애플리케이션 배포를 시작할 수 있습니다. + +- Kubernetes 아키텍처 +- Kubectl 커맨드 +- Kubernetes YAML +- Kubernetes Ingress +- Kubernetes Services +- Helm 패키지 관리자 +- 영속성 스토리지 +- stateful 앱 + +## 자료 + +사용하신 무료 리소스가 있으시면 리포지토리에 PR을 통해 여기에 추가해 주시면 기꺼이 포함시켜 드리겠습니다. + +- [Kubernetes Documentation](https://kubernetes.io/docs/home/) +- [TechWorld with Nana - Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]](https://www.youtube.com/watch?v=X48VuDVv0do) +- [TechWorld with Nana - Kubernetes Crash Course for Absolute Beginners](https://www.youtube.com/watch?v=s_o8dwzRlu4) +- [Kunal Kushwaha - Kubernetes Tutorial for Beginners | What is Kubernetes? Architecture Simplified!](https://www.youtube.com/watch?v=KVBON1lA9N8) + +[Day 55](day55.md)에서 봐요! diff --git a/2022/ko/Days/day55.md b/2022/ko/Days/day55.md new file mode 100644 index 0000000..e8f7c85 --- /dev/null +++ b/2022/ko/Days/day55.md @@ -0,0 +1,239 @@ +--- +title: '#90DaysOfDevOps - State and Ingress in Kubernetes - Day 55' +published: false +description: 90DaysOfDevOps - State and Ingress in Kubernetes +tags: 'DevOps, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048779 +--- + +## Kubernetes의 State와 Ingress + +이번 Kubernetes 마지막 섹션에서는 State와 Ingress에 대해 살펴보겠습니다. + +지금까지 설명한 모든 것은 상태 비저장에 관한 것이며, 상태 비저장은 실제로 애플리케이션이 어떤 네트워크를 사용하든 상관하지 않고 영구적인 저장소가 필요하지 않은 경우입니다. 예를 들어 Stateful 애플리케이션과 데이터베이스가 제대로 작동하려면, 호스트 이름, IP 등 변경되지 않는 고유 ID를 통해 pod가 서로 연결될 수 있도록 해야 합니다. Stateful 애플리케이션의 예로는 MySQL 클러스터, Redis, Kafka, MongoDB 등이 있습니다. 기본적으로 데이터를 저장하는 모든 애플리케이션을 통해 가능합니다. + +### Stateful 애플리케이션 + +StatefulSet은 Kubernetes가 스케줄링 위치에 관계없이 유지 관리하는 고유하고 영구적인 ID와 안정적인 호스트 이름을 가진 pod의 집합을 나타냅니다. 특정 StatefulSet pod의 상태 정보 및 기타 복원력 있는 데이터는 StatefulSet과 연결된 영속성 디스크 스토리지에 유지됩니다. + +### Deployment vs StatefulSet + +- Stateful 애플리케이션을 복제하는 것은 더 어렵다. +- 배포(Stateless 애플리케이션)에서 pod를 복제하는 것은 동일하며 상호 교환이 가능하다. +- 임의의 해시를 사용하여 임의의 순서로 pod를 생성한다. +- 모든 pod에 로드 밸런싱하는 하나의 서비스이다. + +StatefulSet 또는 Stateful 애플리케이션의 경우 위의 내용이 더 어렵습니다. + +- 동시에 생성하거나 삭제할 수 없다. +- 임의로 주소를 지정할 수 없다. +- 레플리카 pod는 동일하지 않다. + +곧 데모에서 보게 될 것은 각 pod가 고유한 식별자를 가지고 있다는 것입니다. 상태 비저장 애플리케이션을 사용하면 임의의 이름을 볼 수 있습니다. 예를 들어 `app-7469bbb6d7-9mhxd`인 반면, 상태 저장 애플리케이션은 `mongo-0`에 더 가깝고 확장 시 `mongo-1`이라는 새 pod를 생성합니다. + +이러한 pod는 동일한 사양으로 생성되지만 상호 교환할 수는 없습니다. 각 StatefulSet pod는 모든 스케줄링에 걸쳐 영구 식별자를 가지고 있습니다. 이는 데이터베이스에 쓰고 읽어야 하는 데이터베이스와 같은 Stateful 워크로드가 필요할 때, 데이터 불일치를 초래할 수 있기 때문에 두 개의 pod가 인식 없이 동시에 쓰게 할 수 없기 때문에 필요합니다. 주어진 시간에 데이터베이스에 하나의 pod만 쓰도록 해야 하지만 여러 개의 pod가 해당 데이터를 읽을 수 있습니다. + +StatefulSet의 각 pod는 영구 볼륨과 데이터베이스의 복제본에 액세스하여 읽을 수 있으며, 이는 마스터로부터 지속적으로 업데이트됩니다. 또한 각 pod는 이 영속성 볼륨에 pod 상태도 저장하는데, 만약 `mongo-0`이 죽으면 새 pod가 프로비저닝될 때 스토리지에 저장된 pod 상태를 이어받게 된다는 점도 흥미롭습니다. + +TLDR; StatefulSet vs Deployment + +- 예측 가능한 pod 이름 = `mongo-0` +- 고정된 개별 DNS 이름 +- pod 아이덴티티 - 상태 유지, 역할 유지 +- Stateful 앱 복제는 복잡함 + - 해야 할 일이 많음: + - 복제 및 데이터 동기화를 구성 + - 원격 공유 스토리지를 사용할 수 있도록 설정 + - 관리 및 백업 + +### 영속성 볼륨 | Claims | StorageClass + +Kubernetes에서 데이터를 어떻게 지속하나요? + +위에서 상태 저장 애플리케이션이 있을 때 상태를 어딘가에 저장해야 한다고 언급했는데, 바로 이 부분에서 볼륨의 필요성이 대두되는데, Kubernetes는 기본적으로 지속성을 제공하지 않습니다. + +pod 라이프사이클에 의존하지 않는 스토리지 계층이 필요합니다. 이 스토리지는 모든 Kubernetes 노드에서 사용할 수 있고 액세스할 수 있어야 합니다. 또한 이 스토리지는 Kubernetes 클러스터가 충돌하더라도 생존할 수 있도록 Kubernetes 클러스터 외부에 있어야 합니다. + +### 영속성 볼륨 + +- 데이터를 저장하기 위한 클러스터 리소스(예: CPU 및 RAM) +- YAML 파일을 통해 생성 +- 실제 물리적 스토리지(NAS)가 필요 +- Kubernetes 클러스터에 대한 외부 통합 +- 스토리지에 다양한 유형의 스토리지를 사용 +- PV는 네임스페이스가 없음 +- 로컬 스토리지를 사용할 수 있지만 클러스터의 한 노드에 한정 +- 데이터베이스 지속성은 원격 스토리지(NAS)를 사용 + +### 영구 볼륨 Claims + +위의 영구 볼륨만 있어도 사용할 수 있지만 애플리케이션에서 Claims하지 않으면 사용되지 않습니다. + +- YAML 파일을 통해 생성 +- 영속성 볼륨 Claims은 pod 구성(볼륨 어트리뷰트)에서 사용 +- PVC는 pod와 동일한 네임스페이스에 존재 +- 볼륨이 pod에 마운트됨 +- pod는 여러 가지 볼륨 유형(ConfigMaps, Secrets, PVC)을 사용 + +PV와 PVC를 생각하는 또 다른 방법은 다음과 같습니다. + +PV는 Kubernetes 어드민에 의해 생성됩니다. +PVC는 사용자 또는 애플리케이션 개발자가 생성합니다. + +또한 자세히 설명하지는 않겠지만 언급할 가치가 있는 두 가지 다른 유형의 볼륨이 있습니다: + +### ConfigMaps | Secrets + +- pod의 구성 파일 +- pod의 인증서 파일 + +### StorageClass + +- YAML 파일을 통해 생성 +- PVC가 영속성 볼륨을 Claims할 때 동적으로 프로비저닝 +- 각 스토리지 백엔드에는 프로비저너가 있음 +- 스토리지 백엔드는 (프로비저너 속성을 통해) YAML에 정의됨 +- 기본 스토리지 공급자 추상화 +- 해당 스토리지에 대한 파라미터 정의 + +### 연습 시간 + +어제 세션에서는 상태 비저장 애플리케이션을 생성하는 방법을 살펴봤는데, 여기서는 동일한 작업을 수행하되 Minikube 클러스터를 사용하여 상태 저장 워크로드를 배포하고자 합니다. + +지속성을 사용하는 기능과 애드온을 갖기 위해 사용하는 Minikube 명령에 대한 요약은 `minikube start --addons volumesnapshots,csi-hostpath-driver --apiserver-port=6443 --container-runtime=containerd -p mc-demo --kubernetes-version=1.21.2`입니다. + +이 명령은 나중에 보여드리는 스토리지 클래스를 제공하는 CSI-hostpath-driver를 사용합니다. + +애플리케이션의 빌드 아웃은 아래와 같습니다: + +![](/2022/Days/Images/Day55_Kubernetes1.png) + +이 애플리케이션의 YAML 구성 파일은 여기에서 찾을 수 있습니다. [pacman-stateful-demo.yaml](/2022/Days/Kubernetes) + +### StorageClass 구성 + +애플리케이션 배포를 시작하기 전에 실행해야 하는 한 단계가 더 있는데, 그것은 StorageClass(CSI-hostpath-sc)가 기본 StorageClass인지 확인하는 것입니다. 먼저 `kubectl get storageclass` 명령을 실행하여 확인할 수 있지만, 기본적으로 Minikube 클러스터는 표준 스토리지 클래스를 기본값으로 표시하므로 다음 명령으로 변경해야 합니다. + +이 첫 번째 명령은 CSI-hostpath-sc 스토리지 클래스를 기본값으로 설정합니다. + +`kubectl patch storageclass csi-hostpath-sc -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'` + +이 명령은 표준 StorageClass에서 기본 어노테이션을 제거합니다. + +`kubectl patch storageclass standard -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'` + +![](/2022/Days/Images/Day55_Kubernetes2.png) + +클러스터에 Pacman 네임스페이스가 없는 상태에서 시작합니다. `kubectl get namespace` + +![](/2022/Days/Images/Day55_Kubernetes3.png) + +그런 다음 YAML 파일을 배포합니다. `kubectl create -f pacman-stateful-demo.yaml` 이 명령에서 우리는 Kubernetes 클러스터 내에 여러 개의 오브젝트를 생성하고 있음을 볼 수 있습니다. + +![](/2022/Days/Images/Day55_Kubernetes4.png) + +이제 새로 생성된 네임스페이스가 생겼습니다. + +![](/2022/Days/Images/Day55_Kubernetes5.png) + +다음 이미지와 `kubectl get all -n pacman` 명령에서 네임스페이스 내부에서 여러 가지 일이 일어나고 있음을 확인할 수 있습니다. 우리는 NodeJS 웹 프론트엔드를 실행하는 pod를 가지고 있고, 백엔드 데이터베이스를 실행하는 mongo를 가지고 있습니다. Pacman과 mongo 모두 해당 pod에 액세스하기 위한 서비스가 있습니다. Pacman을 위한 배포와 mongo를 위한 StatefulSet이 있습니다. + +![](/2022/Days/Images/Day55_Kubernetes6.png) + +또한 영속성 볼륨과 영속성 볼륨 Claims도 가지고 있는데, `kubectl get pv`를 실행하면 네임스페이스가 없는 영속성 볼륨을 얻을 수 있고, `kubectl get pvc -n pacman`을 실행하면 네임스페이스가 있는 영속성 볼륨 Claims을 얻을 수 있습니다. + +![](/2022/Days/Images/Day55_Kubernetes7.png) + +### 게임 플레이하기 | 미션 크리티컬 애플리케이션에 액세스하기 + +앞서 언급한 바와 같이 상태 비저장 애플리케이션에서 Minikube를 사용하고 있기 때문에 애플리케이션에 액세스하는 데 있어 몇 가지 장애물이 있지만, 클러스터 내에서 Ingress 또는 로드 밸런서에 액세스하여 외부에서 액세스하기 위해 자동으로 IP를 받도록 설정되어 있습니다. (위의 Pacman 네임스페이스의 모든 구성 요소 이미지에서 이를 확인할 수 있습니다). + +이 데모에서는 포트 포워드 방법을 사용하여 애플리케이션에 액세스하겠습니다. 새 터미널을 열고 다음 `kubectl port-forward svc/pacman 9090:80 -n pacman` 명령을 실행하고 브라우저를 열면 이제 애플리케이션에 액세스할 수 있습니다. AWS 또는 특정 위치에서 실행하는 경우, 위의 스크린샷에서 이 pod 이름을 다시 한번 확인하면 클라우드와 영역은 물론 Kubernetes 내의 pod와 동일한 호스트에 대해서도 보고됩니다. + +![](/2022/Days/Images/Day55_Kubernetes8.png) + +이제 데이터베이스에 저장할 높은 점수를 생성할 수 있습니다. + +![](/2022/Days/Images/Day55_Kubernetes9.png) + +좋아요, 이제 높은 점수를 얻었지만 `mongo-0` pod를 삭제하면 어떻게 되나요? `kubectl delete pod mongo-0 -n pacman`을 실행하면 삭제할 수 있으며, 아직 앱에 있는 경우 적어도 몇 초 동안은 높은 점수를 사용할 수 없는 것을 볼 수 있을 것입니다. + +![](/2022/Days/Images/Day55_Kubernetes10.png) + +이제 게임으로 돌아가서 새 게임을 만들면 제 높은 점수를 확인할 수 있습니다. 하지만 제 말을 진정으로 믿을 수 있는 유일한 방법은 직접 시도해보고 소셜 미디어에 최고 점수를 공유하는 것입니다! + +![](/2022/Days/Images/Day55_Kubernetes11.png) + +배포를 통해 이전 세션에서 다룬 커맨드를 사용하여 확장할 수 있지만, 특히 대규모 Pacman 파티를 주최하려는 경우 `kubectl scale deployment pacman --replicas=10 -n pacman`을 사용하여 확장할 수 있습니다. + +![](/2022/Days/Images/Day55_Kubernetes12.png) + +### Ingress 설명 + +Kubernetes에 대해 마무리하기 전에 Kubernetes의 중요한 측면인 Ingress에 대해서도 다루고 싶었습니다. + +### Ingress란 무엇인가요? + +지금까지 예제에서는 포트 포워드를 사용하거나 Minikube 내에서 특정 명령을 사용하여 애플리케이션에 액세스했지만, 프로덕션 환경에서는 이 방법이 작동하지 않습니다. 여러 사용자가 대규모로 애플리케이션에 액세스할 수 있는 더 나은 방법이 필요할 것입니다. + +또한 NodePort가 옵션이라고 말씀드렸지만, 이 역시 테스트 목적으로만 사용해야 합니다. + +Ingress는 애플리케이션을 노출하는 더 나은 방법을 제공하며, 이를 통해 Kubernetes 클러스터 내에서 라우팅 규칙을 정의할 수 있습니다. + +Ingress의 경우, 애플리케이션의 내부 서비스에 대한 포워드 요청을 생성합니다. + +### 언제 Ingress가 필요한가요? + +클라우드 제공자를 사용하는 경우, 관리형 Kubernetes 제품에는 클러스터에 대한 Ingress 옵션이 있거나 로드 밸런서 옵션이 제공될 가능성이 높습니다. 이를 직접 구현할 필요가 없다는 것이 관리형 Kubernetes의 장점 중 하나입니다. + +클러스터를 실행하는 경우 엔트리포인트를 구성해야 합니다. + +### Minikube에서 Ingress 구성하기 + +제가 실행 중인 mc-demo라는 특정 클러스터에서 다음 명령을 실행하여 클러스터에서 Ingress를 활성화할 수 있습니다. + +`minikube --profile='mc-demo' addons enable ingress` + +![](/2022/Days/Images/Day55_Kubernetes13.png) + +이제 네임스페이스를 확인하면 새로운 ingress-nginx 네임스페이스가 있는 것을 볼 수 있습니다. `kubectl get ns` + +![](/2022/Days/Images/Day55_Kubernetes14.png) + +이제 Pacman 서비스를 실행하기 위해 Ingress YAML 구성을 생성해야 합니다. 이 파일을 리포지토리 [pacman-ingress.yaml](/2022/Days/Kubernetes)에 추가했습니다. + +그런 다음 `kubectl create -f pacman-ingress.yaml`을 사용하여 Ingress 네임스페이스에 이 파일을 생성할 수 있습니다. + +![](/2022/Days/Images/Day55_Kubernetes15.png) + +그런 다음 `kubectl get ingress -n pacman`을 실행하면 다음과 같이 출력됩니다. + +![](/2022/Days/Images/Day55_Kubernetes16.png) + +그러면 윈도우에서 WSL2에서 실행되는 Minikube를 사용하고 있기 때문에 `minikube tunnel --profile=mc-demo`를 사용하여 Minikube 터널을 생성해야 한다는 메시지가 표시됩니다. + +하지만 여전히 192.168.49.2에 액세스하여 Pacman 게임을 플레이할 수 없습니다. + +누구든지 Windows 및 WSL에서 이 기능을 사용할 수 있거나 사용할 수 있다면 피드백을 보내 주시면 감사하겠습니다. 리포지토리에 이 문제를 제기하고 시간과 수정 사항이 생기면 다시 돌아오겠습니다. + +업데이트: 이 블로그가 WSL에서 작동하지 않는 원인을 파악하는 데 도움이 될 것 같습니다 [Docker 런타임을 사용하여 WSL2에서 Minikube를 실행하도록 Ingress 구성하기](https://hellokube.dev/posts/configure-minikube-ingress-on-wsl2/). + +## 자료 + +사용하신 무료 리소스가 있으시면 리포지토리에 PR을 통해 여기에 추가해 주시면 기꺼이 포함시켜 드리겠습니다. + +- [Kubernetes StatefulSet simply explained](https://www.youtube.com/watch?v=pPQKAR1pA9U) +- [Kubernetes Volumes explained](https://www.youtube.com/watch?v=0swOh5C3OVM) +- [Kubernetes Ingress Tutorial for Beginners](https://www.youtube.com/watch?v=80Ew_fsV4rM) +- [Kubernetes Documentation](https://kubernetes.io/docs/home/) +- [TechWorld with Nana - Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]](https://www.youtube.com/watch?v=X48VuDVv0do) +- [TechWorld with Nana - Kubernetes Crash Course for Absolute Beginners](https://www.youtube.com/watch?v=s_o8dwzRlu4) +- [Kunal Kushwaha - Kubernetes Tutorial for Beginners | What is Kubernetes? Architecture Simplified!](https://www.youtube.com/watch?v=KVBON1lA9N8) + +이것으로 Kubernetes 섹션을 마무리합니다. Kubernetes에 대해 다룰 수 있는 추가 콘텐츠는 매우 많으며 7일 동안 기초적인 지식을 얻을 수 있지만, 사람들은 [100DaysOfKubernetes](https://100daysofkubernetes.io/overview.html)를 통해 심도 있게 살펴볼 수 있습니다. + +다음 시간에는 IaC(Infrastructure as Code)와 이것이 데브옵스 관점에서 수행하는 중요한 역할에 대해 살펴보겠습니다. + +[Day 56](day56.md)에서 봐요! diff --git a/2022/ko/Days/day56.md b/2022/ko/Days/day56.md new file mode 100644 index 0000000..343cc55 --- /dev/null +++ b/2022/ko/Days/day56.md @@ -0,0 +1,133 @@ +--- +title: '#90DaysOfDevOps - The Big Picture: IaC - Day 56' +published: false +description: 90DaysOfDevOps - The Big Picture IaC +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048709 +--- + +## 큰 그림: IaC + +인간은 실수를 합니다! 자동화를 도입해야 합니다! + +현재 시스템을 어떻게 구축하고 계신가요? + +오늘 물리 머신, 가상 머신, 클라우드 VM, 클라우드 PaaS 등 모든 것을 잃게 된다면 어떤 계획을 세우시겠습니까? + +모든 것을 교체하는 데 얼마나 걸리나요? + +IaC는 이를 테스트할 수 있는 동시에 이를 수행할 수 있는 솔루션을 제공하며, 이를 백업 및 복구와 혼동해서는 안 되지만 인프라와 환경, 플랫폼 측면에서 이를 스핀업하여 가축과 반려동물로 취급할 수 있어야 합니다. + +결론은 코드를 사용하여 전체 환경을 재구축할 수 있다는 것입니다. + +처음부터 데브옵스에 대해 일반적으로 장벽을 허물어 시스템을 안전하고 신속하게 프로덕션에 배포하는 방법이라고 말씀드린 것을 기억하세요. + +IaC는 시스템을 제공하는 데 도움이 되며, 우리는 많은 프로세스와 도구에 대해 이야기했습니다. IaC는 프로세스의 이 부분을 구현하기 위해 익숙한 더 많은 도구를 제공합니다. + +이 섹션에서는 IaC에 대해 집중적으로 살펴보겠습니다. 이를 코드의 인프라 또는 코드로서의 구성이라고도 합니다. 가장 잘 알려진 용어는 아마도 IaC가 아닐까 생각합니다. + +### 반려동물 대 가축 + +데브옵스 이전을 살펴보면, 새로운 애플리케이션을 빌드해야 하는 경우 대부분의 경우 서버를 수동으로 준비해야 합니다. + +- 가상 머신 배포 | 물리적 서버 및 운영 체제 설치 +- 네트워킹 구성 +- 라우팅 테이블 생성 +- 소프트웨어 및 업데이트 설치 +- 소프트웨어 구성 +- 데이터베이스 설치 + +이는 시스템 관리자가 수동으로 수행하는 프로세스입니다. 애플리케이션의 규모가 클수록 더 많은 리소스와 서버가 필요하며, 이러한 시스템을 가동하는 데 더 많은 수작업이 필요합니다. 이 작업에는 엄청난 인력과 시간이 소요될 뿐만 아니라 기업 입장에서도 이러한 환경을 구축하기 위해 리소스에 대한 비용을 지불해야 합니다. "인간은 실수를 합니다! 자동화를 도입해야 합니다!"로 섹션을 시작한 이유입니다. + +위의 초기 설정 단계에 이어서 이러한 서버를 유지 관리해야 합니다. + +- 버전 업데이트 +- 새 릴리스 배포 +- 데이터 관리 +- 애플리케이션 복구 +- 서버 추가, 제거 및 확장 +- 네트워크 구성 + +여러 테스트 및 개발 환경의 복잡성을 추가하세요. + +위에서 언급한 서버를 마치 반려동물처럼 돌보던 시절에는 서버에 애칭을 붙이거나 적어도 한동안 '가족'의 일원이 되기를 바라며 이름을 지어주기도 했습니다. + +IaC를 사용하면 이러한 모든 작업을 처음부터 끝까지 자동화할 수 있습니다. IaC는 인프라를 자동으로 프로비저닝하는 개념으로, 일부 툴은 서버에 문제가 발생하면 서버를 폐기하고 새 서버를 스핀업하는 작업을 수행합니다. 이 프로세스는 자동화되어 있으며 서버는 코드에 정의된 대로 정확하게 작동합니다. 이 시점에서는 장애가 발생하거나 애플리케이션의 일부 또는 전부를 업데이트하여 더 이상 현장에 존재하지 않고 이를 대체할 다른 서버가 있을 때까지는 서버의 명칭이 무엇이든 상관없습니다. + +이는 거의 모든 플랫폼, 가상화, 클라우드 기반 워크로드, 그리고 Kubernetes 및 컨테이너와 같은 클라우드 네이티브 인프라에서 사용할 수 있습니다. + +### 인프라 프로비저닝 + +이 섹션에서 사용할 도구는 아래의 처음 두 가지 영역만 다루고 있습니다. Terraform은 우리가 다룰 도구이며, 이를 통해 무에서 시작하여 인프라의 모양을 코드로 정의한 다음 배포할 수 있으며, 인프라를 관리하고 애플리케이션을 처음 배포할 수도 있지만 그 시점에서는 애플리케이션을 추적할 수 없게 되므로 다음 섹션에서 구성 관리 도구로서 Ansible과 같은 것이 이 부분에서 더 잘 작동할 수 있습니다. + +너무 앞서 나가지 않고 초기 애플리케이션 설정을 처리한 다음 해당 애플리케이션과 그 구성을 관리하는 데는 chef, puppet 및 ansible과 같은 도구가 가장 적합합니다. + +소프트웨어의 초기 설치 및 구성 + +- 새 서버 스핀업 +- 네트워크 구성 +- 로드 밸런서 생성 +- 인프라 수준에서 구성 + +### 프로비저닝된 인프라 구성 + +- 서버에 애플리케이션 설치 +- 애플리케이션을 배포할 서버를 준비합니다. + +### 애플리케이션 배포 + +- 애플리케이션 배포 및 관리 +- 유지 관리 단계 +- 소프트웨어 업데이트 +- 재구성 + +### IaC 도구의 차이점 + +선언적 방식과 절차적 방식 + +절차적 + +- 단계별 지침 +- 서버 생성 > 서버 추가 > 이 변경하기 + +선언적 + +- 결과 선언 +- 서버 2개 + +변경 가능(반려동물) vs 변경 불가(가축) + +변경 가능 + +- 대체 대신 변경 +- 일반적으로 수명이 길다 + +변경 불가 + +- 변경 대신 교체 +- 수명이 짧을 수 있음 + +이것이 바로 IaC를 위한 다양한 옵션이 있는 이유입니다. 모든 것을 지배하는 하나의 도구가 없기 때문입니다. + +저희는 주로 Terraform을 사용하며 직접 실습해볼 예정인데, 이것이 IaC가 실제로 작동할 때 그 이점을 확인할 수 있는 가장 좋은 방법이기 때문입니다. 실습은 코드 작성에 필요한 기술을 익힐 수 있는 가장 좋은 방법이기도 합니다. + +다음에는 직접 사용해 보기 전에 101을 통해 Terraform에 대해 살펴보겠습니다. + +## 자료 + +아래에 많은 리소스를 나열했으며 이 주제는 이미 여러 번 다루어졌다고 생각합니다. 추가 리소스가 있는 경우 리소스와 함께 PR을 올리면 기꺼이 검토하여 목록에 추가해 드리겠습니다. + +- [What is Infrastructure as Code? Difference of Infrastructure as Code Tools](https://www.youtube.com/watch?v=POPP2WTJ8es) +- [Terraform Tutorial | Terraform Course Overview 2021](https://www.youtube.com/watch?v=m3cKkYXl-8o) +- [Terraform explained in 15 mins | Terraform Tutorial for Beginners](https://www.youtube.com/watch?v=l5k1ai_GBDE) +- [Terraform Course - From BEGINNER to PRO!](https://www.youtube.com/watch?v=7xngnjfIlK4&list=WL&index=141&t=16s) +- [HashiCorp Terraform Associate Certification Course](https://www.youtube.com/watch?v=V4waklkBC38&list=WL&index=55&t=111s) +- [Terraform Full Course for Beginners](https://www.youtube.com/watch?v=EJ3N-hhiWv0&list=WL&index=39&t=27s) +- [KodeKloud - Terraform for DevOps Beginners + Labs: Complete Step by Step Guide!](https://www.youtube.com/watch?v=YcJ9IeukJL8&list=WL&index=16&t=11s) +- [Terraform Simple Projects](https://terraform.joshuajebaraj.com/) +- [Terraform Tutorial - The Best Project Ideas](https://www.youtube.com/watch?v=oA-pPa0vfks) +- [Awesome Terraform](https://github.com/shuaibiyy/awesome-terraform) + +[Day 57](day57.md)에서 봐요! diff --git a/2022/ko/Days/day57.md b/2022/ko/Days/day57.md new file mode 100644 index 0000000..0e1208e --- /dev/null +++ b/2022/ko/Days/day57.md @@ -0,0 +1,98 @@ +--- +title: '#90DaysOfDevOps - An intro to Terraform - Day 57' +published: false +description: 90DaysOfDevOps - An intro to Terraform +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048710 +--- + +## Terraform 소개 + +"Terraform은 인프라를 안전하고 효율적으로 구축, 변경, 버전 관리할 수 있는 도구입니다." + +위의 인용문은 Terraform의 개발사인 HashiCorp에서 인용한 것입니다. + +"Terraform은 수백 개의 클라우드 서비스를 관리하기 위한 일관된 CLI workflow를 제공하는 코드 소프트웨어 도구로서 오픈 소스 인프라입니다. Terraform은 클라우드 API를 선언적 구성 파일로 코드화합니다." + +해시코프는 [HashiCorp 배우기](https://learn.hashicorp.com/terraform?utm_source=terraform_io&utm_content=terraform_io_hero)에서 모든 제품을 다루는 훌륭한 리소스를 제공하고 있으며, IaC로 무언가를 달성하려고 할 때 유용한 데모를 제공합니다. + +모든 클라우드 제공업체와 온프레미스 플랫폼은 일반적으로 UI를 통해 리소스를 생성할 수 있는 관리 콘솔에 대한 액세스를 제공하며, 일반적으로 이러한 플랫폼은 동일한 리소스를 생성할 수 있는 CLI 또는 API 액세스도 제공하지만, API를 사용하면 빠르게 프로비저닝할 수 있습니다.형 + +IaC를 사용하면 이러한 API에 연결하여 원하는 상태로 리소스를 배포할 수 있습니다. + +아래에 배타적이거나 완전한 도구가 아닌 다른 도구가 있습니다. 다른 도구가 있다면 PR을 통해 공유해 주세요. + +| Cloud Specific | Cloud Agnostic | +| ------------------------------- | -------------- | +| AWS CloudFormation | Terraform | +| Azure Resource Manager | Pulumi | +| Google Cloud Deployment Manager | | + +데모뿐만 아니라 일반적으로 사용하고자 하는 클라우드와 플랫폼에 구애받지 않으려는 것이 바로 우리가 Terraform을 사용하는 또 다른 이유입니다. + +## Terraform 개요 + +Terraform은 프로비저닝에 중점을 둔 도구로, 복잡한 인프라 환경을 프로비저닝할 수 있는 기능을 제공하는 CLI입니다. 로컬 또는 원격(클라우드)에 존재하는 복잡한 인프라 요구 사항을 정의할 수 있습니다. Terraform을 사용하면 처음에 구축할 수 있을 뿐만 아니라 해당 리소스의 수명 기간 동안 유지 관리 및 업데이트할 수 있습니다. + +여기서는 개략적인 내용만 다루겠지만, 더 자세한 내용과 다양한 리소스를 보려면 [terraform.io](https://www.terraform.io/)를 방문하세요. + +### 쓰기 + +Terraform을 사용하면 환경을 구축할 선언적 구성 파일을 만들 수 있습니다. 이 파일은 블록, 인수, 표현식을 사용하여 리소스를 간결하게 설명할 수 있는 해시코프 구성 언어(HCL)를 사용하여 작성됩니다. 물론 가상 머신, 컨테이너를 배포할 때와 쿠버네티스 내에서 이를 자세히 살펴볼 것입니다. + +### 계획 + +위의 구성 파일들이 우리가 보고자 하는 것을 배포할 것인지 확인하기 위해 Terraform cli의 특정 기능을 사용하여 배포하거나 변경하기 전에 해당 계획을 테스트할 수 있는 기능입니다. Terraform은 인프라를 위한 지속적인 도구이므로 인프라의 측면을 변경하려면 코드에서 모두 캡처되도록 Terraform을 통해 변경해야 한다는 점을 기억하세요. + +### 적용 + +만족스러우면 계속해서 이 구성을 Terraform 내에서 사용할 수 있는 많은 제공업체에 적용할 수 있습니다. [여기](https://registry.terraform.io/browse/providers)에서 사용 가능한 수많은 제공자를 확인할 수 있습니다. + +또 한 가지 언급할 것은 사용 가능한 모듈도 있다는 것인데, 이러한 모듈은 공개적으로 생성 및 공유되어 있으므로 특정 인프라 리소스를 모든 곳에 동일한 방식으로 배포하는 모범 사례를 반복해서 생성할 필요가 없다는 점에서 컨테이너 이미지와 유사합니다. 사용 가능한 모듈은 [여기](https://registry.terraform.io/browse/modules)에서 찾을 수 있습니다. + +Terraform workflow는 다음과 같습니다. (_Terraform 사이트에서 가져옴_) + +![](/2022/Days/Images/Day57_IAC3.png) + +### Terraform vs Vagrant + +이번 챌린지에서는 개발 환경에 집중하는 또 다른 해시코프 오픈소스 도구인 Vagrant를 사용했습니다. + +- Vagrant는 개발 환경 관리에 중점을 둔 도구입니다. + +- Terraform은 인프라 구축을 위한 도구입니다. + +두 도구에 대한 자세한 비교는 공식 [HashiCorp 사이트](https://www.vagrantup.com/intro/vs/terraform)에서 확인할 수 있습니다. + +## Terraform 설치 + +Terraform을 설치하는 데에는 많은 것이 필요하지 않습니다. + +Terraform은 크로스 플랫폼이며, 제 리눅스 머신에서 아래에서 CLI를 다운로드하고 설치하는 몇 가지 옵션을 볼 수 있습니다. + +![](/2022/Days/Images/Day57_IAC2.png) + +`arkade`를 사용하여 Terraform을 설치하면, 아케이드는 필요한 도구, 앱, 클리스를 시스템에 설치할 수 있는 편리한 작은 도구입니다. 간단한 `arkade get terraform`으로 Terraform을 업데이트할 수 있으며, Terraform이 있다면 같은 명령으로 Terraform CLI도 설치할 수 있습니다. + +![](/2022/Days/Images/Day57_IAC1.png) + +앞으로 HCL에 대해 좀 더 자세히 살펴본 다음 다양한 플랫폼에서 인프라 리소스를 생성하는 데 Terraform을 사용해 보도록 하겠습니다. + +## 자료 + +아래에 많은 리소스를 나열했으며 이 주제는 이미 여러 번 다루어졌다고 생각합니다. 추가 리소스가 있는 경우 리소스와 함께 PR을 올리면 기꺼이 검토하여 목록에 추가해 드리겠습니다. + +- [What is Infrastructure as Code? Difference of Infrastructure as Code Tools](https://www.youtube.com/watch?v=POPP2WTJ8es) +- [Terraform Tutorial | Terraform Course Overview 2021](https://www.youtube.com/watch?v=m3cKkYXl-8o) +- [Terraform explained in 15 mins | Terraform Tutorial for Beginners](https://www.youtube.com/watch?v=l5k1ai_GBDE) +- [Terraform Course - From BEGINNER to PRO!](https://www.youtube.com/watch?v=7xngnjfIlK4&list=WL&index=141&t=16s) +- [HashiCorp Terraform Associate Certification Course](https://www.youtube.com/watch?v=V4waklkBC38&list=WL&index=55&t=111s) +- [Terraform Full Course for Beginners](https://www.youtube.com/watch?v=EJ3N-hhiWv0&list=WL&index=39&t=27s) +- [KodeKloud - Terraform for DevOps Beginners + Labs: Complete Step by Step Guide!](https://www.youtube.com/watch?v=YcJ9IeukJL8&list=WL&index=16&t=11s) +- [Terraform Simple Projects](https://terraform.joshuajebaraj.com/) +- [Terraform Tutorial - The Best Project Ideas](https://www.youtube.com/watch?v=oA-pPa0vfks) +- [Awesome Terraform](https://github.com/shuaibiyy/awesome-terraform) + +[Day 58](day58.md)에서 봐요! diff --git a/2022/ko/Days/day58.md b/2022/ko/Days/day58.md new file mode 100644 index 0000000..abbd732 --- /dev/null +++ b/2022/ko/Days/day58.md @@ -0,0 +1,234 @@ +--- +title: '#90DaysOfDevOps - HashiCorp Configuration Language (HCL) - Day 58' +published: false +description: 90DaysOfDevOps - HashiCorp Configuration Language (HCL) +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048741 +--- + +## HashiCorp 구성 언어(HCL) + +Terraform으로 무언가를 만들기 시작하기 전에 HashiCorp 구성 언어(HCL)에 대해 조금 알아볼 필요가 있습니다. 지금까지 챌린지를 진행하면서 몇 가지 다른 스크립팅 및 프로그래밍 언어를 살펴봤는데, 여기에 또 다른 언어가 있습니다. [Go 프로그래밍 언어](day07.md)에 이어 [bash 스크립트](day19.md)를 다루었고, [네트워크 자동화](day27.md)와 관련해서는 파이썬도 조금 다뤄봤습니다. + +이제 HashiCorp 구성 언어(HCL)를 다뤄야 하는데, 이 언어를 처음 접하는 분들에게는 다소 어렵게 느껴질 수 있지만 매우 간단하고 강력한 언어입니다. + +이 섹션을 진행하면서 어떤 OS를 사용하든 시스템에서 로컬로 실행할 수 있는 예제를 사용할 것이며, 일반적으로 Terraform에서 사용하는 인프라 플랫폼은 아니지만 VirtualBox를 사용할 것입니다. 그러나 로컬에서 실행하는 것은 무료이며 이 게시물에서 원하는 것을 달성할 수 있습니다. 이 포스팅의 개념을 도커나 쿠버네티스로 확장할 수도 있습니다. + +하지만 일반적으로는 퍼블릭 클라우드(AWS, Google, Microsoft Azure)뿐만 아니라 가상화 환경(VMware, Microsoft Hyper-V, Nutanix AHV)에도 인프라를 배포하는 데 Terraform을 사용하거나 사용해야 합니다. 퍼블릭 클라우드에서 Terraform을 사용하면 가상 머신 자동 배포뿐 아니라 PaaS 워크로드와 같은 모든 필수 인프라와 VPC 및 보안 그룹과 같은 모든 네트워킹 필수 자산을 생성할 수 있습니다. + +Terraform에는 두 가지 중요한 측면이 있는데, 이 포스팅에서 다룰 code와 state입니다. 이 두 가지를 함께 Terraform의 핵심이라고 부를 수 있습니다. 그런 다음 우리가 대화하고 배포하고자 하는 환경이 있는데, 이는 지난 세션에서 간략히 언급했지만, AWS 공급자, Azure 공급자 등을 사용하여 실행되는 Terraform 공급자를 사용하여 실행됩니다. 수백 개가 있습니다. + +### 기본 Terraform 사용법 + +Terraform `.tf` 파일이 어떻게 구성되는지 살펴보겠습니다. 첫 번째로 살펴볼 예제는 AWS에 리소스를 배포하는 코드이며, 이를 위해서는 시스템에 AWS CLI를 설치하고 계정에 맞게 구성해야 합니다. + +### 공급자 + +더 복잡하게 만들 때까지는 일반적으로 `main.tf`라고 부르는 `.tf` 파일 구조의 맨 위에 있습니다. 여기서는 앞서 언급했던 공급자를 정의합니다. 보시다시피 AWS 공급자의 소스는 `hashicorp/aws`이며, 이는 공급자가 HashiCorp에서 직접 유지 관리하거나 게시했음을 의미합니다. 기본적으로 [Terraform 레지스트리](https://registry.terraform.io/)에서 사용할 수 있는 제공자를 참조하게 되며, 제공자를 작성하여 로컬에서 사용하거나 Terraform 레지스트리에 자체 게시할 수도 있습니다. + +``` +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 3.0" + } + } +} +``` + +프로비저닝할 AWS 리전을 결정하기 위해 여기에 리전을 추가할 수도 있는데, 이를 위해 다음을 추가할 수 있습니다: + +``` +provider "aws" { + region = "ap-southeast-1" //리소스를 배포해야 하는 지역 +} +``` + +### Terraform 리소스 + +- EC2, 로드 밸런서, VPC 등과 같은 하나 이상의 인프라 개체를 설명하는 Terraform 구성 파일의 또 다른 중요한 구성 요소입니다. + +- 리소스 블록은 지정된 유형("aws_instance")의 리소스를 지정된 로컬 이름("90daysofdevops")으로 선언합니다. + +- 리소스 유형과 이름은 함께 지정된 리소스의 식별자 역할을 합니다. + +``` +resource "aws_instance" "90daysofdevops" { + ami = data.aws_ami.instance_id.id + instance_type = "t2.micro" + availability_zone = "us-west-2a" + security_groups = [aws_security_group.allow_web.name] + user_data = <<-EOF + #! /bin/bash + sudo yum update + sudo yum install -y httpd + sudo systemctl start httpd + sudo systemctl enable httpd + echo " +

Deployed via Terraform

+ +" | sudo tee /var/www/html/index.html + EOF + tags = { + Name = "Created by Terraform" + } +} +``` + +위에서 `yum` 업데이트를 실행하고 ec2 인스턴스에 `httpd`를 설치하는 것을 볼 수 있습니다. + +이제 전체 main.tf 파일을 보면 다음과 같이 보일 수 있습니다. + +``` +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 3.27" + } + } + + required_version = ">= 0.14.9" +} + +provider "aws" { + profile = "default" + region = "us-west-2" +} + +resource "aws_instance" "90daysofdevops" { + ami = "ami-830c94e3" + instance_type = "t2.micro" + availability_zone = "us-west-2a" + user_data = <<-EOF + #! /bin/bash + sudo yum update + sudo yum install -y httpd + sudo systemctl start httpd + sudo systemctl enable httpd + echo " +

Deployed via Terraform

+ +" | sudo tee /var/www/html/index.html + EOF + tags = { + Name = "Created by Terraform" + + tags = { + Name = "ExampleAppServerInstance" + } +} +``` + +위의 코드는 AWS에서 매우 간단한 웹 서버를 ec2 인스턴스로 배포합니다. 이 코드와 이와 같은 다른 구성의 가장 큰 장점은 이 작업을 반복할 수 있고 매번 동일한 출력을 얻을 수 있다는 것입니다. 제가 코드를 엉망으로 만들었을 가능성을 제외하고는 위와 같이 사람이 개입할 여지가 없습니다. + +한 번도 사용하지 않을 것 같은 아주 간단한 예제를 살펴볼 수 있지만, 어쨌든 유머러스하게 만들어 보겠습니다. 모든 훌륭한 스크립팅 및 프로그래밍 언어가 그렇듯, Hello World부터 시작해야 합니다. + +``` +terraform { + # 이 모듈은 현재 Terraform 0.13.x에서만 테스트 중입니다. 그러나 더 쉽게 업그레이드할 수 있도록 다음과 같이 설정하고 있습니다. + # 0.12.26을 최소 버전으로 설정했는데, 이 버전은 소스 URL이 있는 required_providers에 대한 지원이 추가되었기 때문입니다. + # 0.13.x 코드와 호환됩니다. + required_version = ">= 0.12.26" +} + +# website::tag::1:: 가장 간단한 Terraform 모듈: "Hello, World!"를 출력하기만 하면 됩니다. +output "hello_world" { + value = "Hello, 90DaysOfDevOps from Terraform" +} +``` + +이 파일은 IaC 폴더 안의 Hello-world 폴더에서 찾을 수 있지만, Terraform 코드를 사용하기 위해 실행해야 하는 몇 가지 명령이 있기 때문에 바로 작동하지는 않습니다. + +터미널에서 main.tf가 생성된 폴더로 이동합니다. 이 저장소에서 가져올 수도 있고 위의 코드를 사용하여 새 저장소를 생성할 수도 있습니다. + +해당 폴더에서 `terraform init`을 실행합니다. + +Terraform 코드가 있는 모든 디렉토리에서 또는 Terraform 코드를 실행하기 전에 이 작업을 수행해야 합니다. 구성 디렉터리를 초기화하면 구성에 정의된 공급자를 다운로드하여 설치합니다. 이 경우에는 공급자가 없지만 위의 예제에서는 이 구성에 대한 AWS 공급자를 다운로드합니다. + +![](/2022/Days/Images/Day58_IAC1.png) + +다음 명령은 `terraform plan`입니다. + +`terraform plan` 명령은 실행 계획을 생성하여 Terraform이 인프라에 적용하려는 변경 사항을 미리 볼 수 있게 해줍니다. + +hello-world 예제를 통해 아래에서 간단히 볼 수 있듯이, 이것이 AWS ec2 인스턴스였다면 생성할 모든 단계가 출력되는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day58_IAC2.png) + +이 시점에서 리포지토리를 초기화했고 필요한 경우 제공자를 다운로드했으며, 테스트 워크스루를 실행하여 원하는 대로 표시되는지 확인했으므로 이제 코드를 실행하고 배포할 수 있습니다. + +`terraform apply`를 사용하면 이 작업을 수행할 수 있으며, 이 명령에는 안전 조치가 내장되어 있어 앞으로 일어날 일에 대한 계획 보기가 다시 제공되므로 계속할 것인지에 대한 응답을 보장합니다. + +![](/2022/Days/Images/Day58_IAC3.png) + +값을 입력하기 위해 yes를 입력하면 코드가 배포됩니다. 그다지 흥미롭지는 않지만, 코드에서 정의한 출력이 나오는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day58_IAC4.png) + +이제 우리는 아무것도 배포하지 않았고, 아무것도 추가, 변경 또는 삭제하지 않았지만, 만약 배포했다면 위와 같이 표시된 것을 볼 수 있을 것입니다. 그러나 무언가를 배포한 후 배포한 모든 것을 제거하려면 `terraform destroy` 명령을 사용할 수 있습니다. 이 경우에도 `apply` 및 `delete` 명령 끝에 `--auto-approve`을 사용하여 수동 개입을 우회할 수 있지만 예라고 입력해야 하는 안전성이 있습니다. 하지만 이 단축키는 학습 및 테스트 시에만 사용하는 것이 좋으며, 때로는 모든 것이 빌드된 것보다 빨리 사라질 수 있습니다. + +지금까지 Terraform CLI에서 다룬 명령어는 총 4가지입니다. + +- `terraform init` = 프로바이더로 프로젝트 폴더 준비하기 +- `terraform plan` = 코드를 기반으로 다음 명령 중에 생성 및 변경될 내용을 표시합니다. +- `terraform apply`= 코드에 정의된 리소스를 배포합니다. +- `terraform destroy` = 프로젝트에서 생성한 리소스를 파괴합니다. + +코드 파일에서 두 가지 중요한 측면도 다루었습니다. + +- providers = API를 통해 Terraform이 최종 플랫폼과 대화하는 방법 +- resources = 우리가 코드로 배포하고자 하는 것 + +또 한 가지 주의해야 할 점은 `terraform init`을 실행할 때 폴더의 트리를 전후로 살펴보고 어떤 일이 발생하고 제공자와 모듈을 어디에 저장하는지 확인하는 것입니다. + +### Terraform state + +또한 디렉터리 내부에 생성되는 state 파일도 알아야 하는데, 이 hello-world 예제에서 state 파일은 간단합니다. 이것은 Terraform에 따라 세계를 표현하는 JSON 파일입니다. 상태는 민감한 데이터를 기꺼이 보여줄 수 있으므로 주의해야 하며, 모범 사례로 GitHub에 업로드하기 전에 `.tfstate` 파일을 `.gitignore` 폴더에 넣는 것이 좋습니다. + +기본적으로 상태 파일은 프로젝트 코드와 같은 디렉터리에 있지만 옵션으로 원격으로 저장할 수도 있습니다. 프로덕션 환경에서는 S3 버킷과 같은 공유 위치가 될 가능성이 높습니다. + +또 다른 옵션으로는 유료 관리형 서비스인 Terraform Cloud가 있습니다. (최대 5명의 사용자까지 무료) + +원격 위치에 상태를 저장할 때 얻을 수 있는 장점은 다음과 같습니다: + +- 민감한 데이터 암호화 +- 협업 +- 자동화 +- 그러나 복잡성이 증가할 수 있습니다. + +```JSON +{ + "version": 4, + "terraform_version": "1.1.6", + "serial": 1, + "lineage": "a74296e7-670d-0cbb-a048-f332696ca850", + "outputs": { + "hello_world": { + "value": "Hello, 90DaysOfDevOps from Terraform", + "type": "string" + } + }, + "resources": [] +} +``` + +## 자료 + +아래에 많은 리소스를 나열했으며 이 주제는 이미 여러 번 다루어졌다고 생각합니다. 추가 리소스가 있는 경우 리소스와 함께 PR을 올리면 기꺼이 검토하여 목록에 추가해 드리겠습니다. + +- [What is Infrastructure as Code? Difference of Infrastructure as Code Tools](https://www.youtube.com/watch?v=POPP2WTJ8es) +- [Terraform Tutorial | Terraform Course Overview 2021](https://www.youtube.com/watch?v=m3cKkYXl-8o) +- [Terraform explained in 15 mins | Terraform Tutorial for Beginners](https://www.youtube.com/watch?v=l5k1ai_GBDE) +- [Terraform Course - From BEGINNER to PRO!](https://www.youtube.com/watch?v=7xngnjfIlK4&list=WL&index=141&t=16s) +- [HashiCorp Terraform Associate Certification Course](https://www.youtube.com/watch?v=V4waklkBC38&list=WL&index=55&t=111s) +- [Terraform Full Course for Beginners](https://www.youtube.com/watch?v=EJ3N-hhiWv0&list=WL&index=39&t=27s) +- [KodeKloud - Terraform for DevOps Beginners + Labs: Complete Step by Step Guide!](https://www.youtube.com/watch?v=YcJ9IeukJL8&list=WL&index=16&t=11s) +- [Terraform Simple Projects](https://terraform.joshuajebaraj.com/) +- [Terraform Tutorial - The Best Project Ideas](https://www.youtube.com/watch?v=oA-pPa0vfks) +- [Awesome Terraform](https://github.com/shuaibiyy/awesome-terraform) + +[Day 59](day59.md)에서 봐요! diff --git a/2022/ko/Days/day59.md b/2022/ko/Days/day59.md new file mode 100644 index 0000000..5f9554c --- /dev/null +++ b/2022/ko/Days/day59.md @@ -0,0 +1,130 @@ +--- +title: '#90DaysOfDevOps - Create a VM with Terraform & Variables - Day 59' +published: false +description: 90DaysOfDevOps - Create a VM with Terraform & Variables +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049051 +--- + +## Terraform 및 변수를 사용하여 VM 생성하기 + +이 세션에서는 VirtualBox 내에서 Terraform을 사용하여 VM을 한두 개 생성해 보겠습니다. VirtualBox는 워크스테이션 가상화 옵션이므로 Terraform의 사용 사례는 아니지만, 저는 현재 36,000피트 상공에 있으며 이 정도 높이의 클라우드에 퍼블릭 클라우드 리소스를 배포한 만큼 노트북에서 로컬로 이 작업을 수행하는 것이 훨씬 더 빠릅니다. + +순전히 데모 목적이지만 개념은 동일합니다. 원하는 상태 구성 코드를 만든 다음 VirtualBox 공급자에 대해 실행할 것입니다. 과거에는 여기서는 vagrant를 사용했으며 이 섹션의 시작 부분에서 vagrant와 Terraform의 차이점에 대해 다루었습니다. + +### VirtualBox에서 가상 머신 생성하기 + +가장 먼저 할 일은 VirtualBox라는 새 폴더를 생성한 다음 VirtualBox.tf 파일을 생성하고 여기에서 리소스를 정의하는 것입니다. VirtualBox 폴더에서 VirtualBox.tf로 찾을 수 있는 아래 코드는 Virtualbox에 2개의 VM을 생성합니다. + +커뮤니티 VirtualBox 제공업체에 대한 자세한 내용은 [여기](https://registry.terraform.io/providers/terra-farm/virtualbox/latest/docs/resources/vm)에서 확인할 수 있습니다. + +``` +terraform { + required_providers { + virtualbox = { + source = "terra-farm/virtualbox" + version = "0.2.2-alpha.1" + } + } +} + +# 현재 공급자 자체에 대한 구성 옵션이 없습니다. + +resource "virtualbox_vm" "node" { + count = 2 + name = format("node-%02d", count.index + 1) + image = "https://app.vagrantup.com/ubuntu/boxes/bionic64/versions/20180903.0.0/providers/virtualbox.box" + cpus = 2 + memory = "512 mib" + + network_adapter { + type = "hostonly" + host_interface = "vboxnet1" + } +} + +output "IPAddr" { + value = element(virtualbox_vm.node.*.network_adapter.0.ipv4_address, 1) +} + +output "IPAddr_2" { + value = element(virtualbox_vm.node.*.network_adapter.0.ipv4_address, 2) +} + +``` + +이제 코드가 정의되었으므로 이제 폴더에서 `terraform init`을 수행하여 Virtualbox용 공급자를 다운로드할 수 있습니다. + +![](/2022/Days/Images/Day59_IAC1.png) + +또한 시스템에도 VirtualBox가 설치되어 있어야 합니다. 그런 다음 `terraform plan`을 실행하여 코드가 무엇을 생성하는지 확인할 수 있습니다. 이어서 `terraform apply`를 실행하면 아래 이미지에 완성된 프로세스가 표시됩니다. + +![](/2022/Days/Images/Day59_IAC2.png) + +이제 Virtualbox에서 2개의 가상 머신을 볼 수 있습니다. + +![](/2022/Days/Images/Day59_IAC3.png) + +### 구성 변경 + +배포에 다른 노드를 추가해 보겠습니다. 카운트 라인을 변경하여 원하는 새로운 노드 수를 표시하면 됩니다. `terraform apply`를 실행하면 아래와 같이 표시됩니다. + +![](/2022/Days/Images/Day59_IAC4.png) + +VirtualBox에서 완료되면 이제 3개의 노드가 실행되고 있는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day59_IAC5.png) + +완료되면 `terraform destroy`를 사용하여 이를 지우면 머신이 제거됩니다. + +![](/2022/Days/Images/Day59_IAC6.png) + +### 변수 및 출력 + +지난 세션에서 hello-world 예제를 실행할 때 출력을 언급했습니다. 여기서 더 자세히 살펴볼 수 있습니다. + +하지만 여기에도 사용할 수 있는 다른 많은 변수가 있으며, 변수를 정의하는 몇 가지 다른 방법도 있습니다. + +- `terraform plan` 또는 `terraform apply` 명령을 사용하여 변수를 수동으로 입력할 수 있습니다. + +- 블록 내의 .tf 파일에 변수를 정의할 수 있습니다. + +- `TF_VAR_NAME` 형식을 사용하여 시스템 내에서 환경 변수를 사용할 수 있습니다. + +- 저는 프로젝트 폴더에 terraform.tfvars 파일을 사용하는 것을 선호합니다. + +- \*auto.tfvars 파일 옵션이 있습니다. + +- 또는 `-var` 또는 `-var-file`을 사용하여 `terraform plan` 또는 `terraform apply`을 실행할 때를 정의할 수 있습니다. + +아래에서 위로 올라가는 것이 변수를 정의하는 순서입니다. + +또한 상태 파일에 민감한 정보가 포함될 것이라고 언급했습니다. 민감한 정보를 변수로 정의하고 이를 민감한 정보로 정의할 수 있습니다. + +``` +variable "some resource" { + description = "something important" + type= string + sensitive = true + +} +``` + +## 자료 + +아래에 많은 리소스를 나열했으며 이 주제는 이미 여러 번 다루어졌다고 생각합니다. 추가 리소스가 있는 경우 리소스와 함께 PR을 올리면 기꺼이 검토하여 목록에 추가해 드리겠습니다. + +- [What is Infrastructure as Code? Difference of Infrastructure as Code Tools](https://www.youtube.com/watch?v=POPP2WTJ8es) +- [Terraform Tutorial | Terraform Course Overview 2021](https://www.youtube.com/watch?v=m3cKkYXl-8o) +- [Terraform explained in 15 mins | Terraform Tutorial for Beginners](https://www.youtube.com/watch?v=l5k1ai_GBDE) +- [Terraform Course - From BEGINNER to PRO!](https://www.youtube.com/watch?v=7xngnjfIlK4&list=WL&index=141&t=16s) +- [HashiCorp Terraform Associate Certification Course](https://www.youtube.com/watch?v=V4waklkBC38&list=WL&index=55&t=111s) +- [Terraform Full Course for Beginners](https://www.youtube.com/watch?v=EJ3N-hhiWv0&list=WL&index=39&t=27s) +- [KodeKloud - Terraform for DevOps Beginners + Labs: Complete Step by Step Guide!](https://www.youtube.com/watch?v=YcJ9IeukJL8&list=WL&index=16&t=11s) +- [Terraform Simple Projects](https://terraform.joshuajebaraj.com/) +- [Terraform Tutorial - The Best Project Ideas](https://www.youtube.com/watch?v=oA-pPa0vfks) +- [Awesome Terraform](https://github.com/shuaibiyy/awesome-terraform) + +[Day 60](day60.md)에서 봐요! diff --git a/2022/ko/Days/day60.md b/2022/ko/Days/day60.md new file mode 100644 index 0000000..7722f1b --- /dev/null +++ b/2022/ko/Days/day60.md @@ -0,0 +1,194 @@ +--- +title: '#90DaysOfDevOps - Docker Containers, Provisioners & Modules - Day 60' +published: false +description: '90DaysOfDevOps - Docker Containers, Provisioners & Modules' +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049052 +--- + +## Docker 컨테이너, Provisioners 및 모듈 + +[Day 59](day59.md)에는 Terraform을 사용하여 로컬 무료 VirtualBox 환경에 가상 머신을 프로비저닝했습니다. 이 섹션에서는 몇 가지 구성이 포함된 Docker 컨테이너를 로컬 Docker 환경에 배포해 보겠습니다. + +### Docker 데모 + +먼저 아래 코드 블록을 사용하여 간단한 웹 앱을 Docker에 배포하고 이를 게시하여 네트워크에서 사용할 수 있도록 하겠습니다. nginx를 사용할 것이며 로컬 호스트와 포트 8000을 통해 노트북에서 외부에서 사용할 수 있도록 할 것입니다. 커뮤니티에서 제공하는 Docker 공급자를 사용하고 있으며 구성에서도 사용 중인 Docker 이미지를 확인할 수 있습니다. + +``` +terraform { + required_providers { + docker = { + source = "kreuzwerker/docker" + version = "2.16.0" + } + } +} + +provider "docker" {} + +resource "docker_image" "nginx" { + name = "nginx:latest" + keep_locally = false +} + +resource "docker_container" "nginx" { + image = docker_image.nginx.latest + name = "tutorial" + ports { + internal = 80 + external = 8000 + } +} +``` + +첫 번째 작업은 `terraform init` 명령을 사용하여 로컬 머신에 프로바이더를 다운로드하는 것입니다. + +![](/2022/Days/Images/Day60_IAC1.png) + +그런 다음 `terraform apply`를 실행한 다음 `docker ps`를 실행하면 컨테이너가 실행되는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day60_IAC2.png) + +이제 브라우저를 열어 `http://localhost:8000/`으로 이동하면 NGINX 컨테이너에 액세스할 수 있는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day60_IAC3.png) + +자세한 내용은 [Docker Provider](https://registry.terraform.io/providers/kreuzwerker/docker/latest/docs/resources/container)에서 확인할 수 있습니다. + +위는 Terraform과 Docker로 무엇을 할 수 있는지, 그리고 Terraform 상태에서 어떻게 관리할 수 있는지에 대한 아주 간단한 데모입니다. 컨테이너 섹션에서 docker-compose에 대해 다뤘고, 이것과 IaC, 그리고 Kubernetes 사이에는 약간의 교차점이 있습니다. + +이를 보여드리고 Terraform이 어떻게 좀 더 복잡한 것을 처리할 수 있는지 보여드리기 위해, 우리가 docker-compose로 만든 워드프레스와 MySQL용 docker-compose 파일을 가져와서 이것을 Terraform에 넣도록 하겠습니다. [docker-wordpress.tf](2022/Days/IaC/Docker-WordPress/docker-WordPress.tf)를 찾을 수 있습니다. + +``` +terraform { + required_providers { + docker = { + source = "kreuzwerker/docker" + version = "2.16.0" + } + } +} + +provider "docker" {} + +variable wordpress_port { + default = "8080" +} + +resource "docker_volume" "db_data" { + name = "db_data" +} + +resource "docker_network" "wordpress_net" { + name = "wordpress_net" +} + +resource "docker_container" "db" { + name = "db" + image = "mysql:5.7" + restart = "always" + network_mode = "wordpress_net" + env = [ + "MYSQL_ROOT_PASSWORD=wordpress", + "MYSQL_PASSWORD=wordpress", + "MYSQL_USER=wordpress", + "MYSQL_DATABASE=wordpress" + ] + mounts { + type = "volume" + target = "/var/lib/mysql" + source = "db_data" + } +} + +resource "docker_container" "wordpress" { + name = "wordpress" + image = "wordpress:latest" + restart = "always" + network_mode = "wordpress_net" + env = [ + "WORDPRESS_DB_HOST=db:3306", + "WORDPRESS_DB_USER=wordpress", + "WORDPRESS_DB_NAME=wordpress", + "WORDPRESS_DB_PASSWORD=wordpress" + ] + ports { + internal = "80" + external = "${var.wordpress_port}" + } +} +``` + +이 파일을 다시 새 폴더에 넣은 다음 `terraform init` 명령을 실행하여 필요한 Provisioners를 내려놓습니다. + +![](/2022/Days/Images/Day60_IAC4.png) + +그런 다음 `terraform apply` 명령을 실행한 다음 `docker ps` 출력을 살펴보면 새로 생성된 컨테이너를 볼 수 있습니다. + +![](/2022/Days/Images/Day60_IAC5.png) + +이제 WordPress 프론트엔드로 이동할 수도 있습니다. 컨테이너 섹션에서 docker-compose로 이 과정을 거쳤을 때와 마찬가지로 이제 설정을 실행할 수 있으며 WordPress 게시물이 MySQL 데이터베이스에 저장됩니다. + +![](/2022/Days/Images/Day60_IAC6.png) + +이제 컨테이너와 Kubernetes에 대해 자세히 살펴봤는데요, 테스트용으로는 괜찮지만, 실제 웹사이트를 운영할 계획이라면 컨테이너만으로는 이 작업을 수행하지 않고 Kubernetes를 사용하여 이를 달성할 것입니다. 다음에는 Terraform과 Kubernetes를 사용하여 살펴보도록 하겠습니다. + +### Provisioners + +Provisioners는 어떤 것이 선언적일 수 없는 경우 이를 배포에 파싱할 수 있는 방법을 제공하기 위해 존재합니다. + +다른 대안이 없고 코드에 이러한 복잡성을 추가해야 하는 경우 다음 코드 블록과 유사한 것을 실행하여 이를 수행할 수 있습니다. + +``` +resource "docker_container" "db" { + # ... + + provisioner "local-exec" { + command = "echo The server's IP address is ${self.private_ip}" + } +} + +``` + +원격 실행 Provisioners는 원격 리소스가 생성된 후 원격 리소스에서 스크립트를 호출합니다. 이 스크립트는 OS에 따라 다르거나 구성 관리 도구에서 래핑하는 데 사용될 수 있습니다. 이 중 일부는 Provisioners에서 다루고 있습니다. + +[Provisioners에 대한 자세한 내용](https://www.terraform.io/language/resources/provisioners/syntax) + +- file +- local-exec +- remote-exec +- vendor + - ansible + - chef + - puppet + +### 모듈 + +모듈은 함께 사용되는 여러 리소스를 위한 컨테이너입니다. 모듈은 동일한 디렉터리에 있는 .tf 파일 모음으로 구성됩니다. + +모듈은 인프라 리소스를 분리할 수 있는 좋은 방법일 뿐만 아니라 이미 만들어진 타사 모듈을 가져올 수 있으므로 처음부터 다시 만들 필요가 없습니다. + +예를 들어, 동일한 프로젝트를 사용하여 일부 VM, VPC, 보안 그룹을 구축한 다음 Kubernetes 클러스터도 구축하려는 경우 리소스를 모듈로 분할하여 리소스와 그룹화 위치를 더 잘 정의하고 싶을 것입니다. + +모듈의 또 다른 장점은 이러한 모듈을 가져와 다른 프로젝트에 사용하거나 커뮤니티를 돕기 위해 공개적으로 공유할 수 있다는 것입니다. + +저희는 인프라를 구성 요소로 나누고 있으며, 여기서 구성 요소는 모듈로 알려져 있습니다. + +## 자료 + +아래에 많은 리소스를 나열했으며 이 주제는 이미 여러 번 다루어졌다고 생각합니다. 추가 리소스가 있는 경우 리소스와 함께 PR을 올리면 기꺼이 검토하여 목록에 추가해 드리겠습니다. + +- [What is Infrastructure as Code? Difference of Infrastructure as Code Tools](https://www.youtube.com/watch?v=POPP2WTJ8es) +- [Terraform Tutorial | Terraform Course Overview 2021](https://www.youtube.com/watch?v=m3cKkYXl-8o) +- [Terraform explained in 15 mins | Terraform Tutorial for Beginners](https://www.youtube.com/watch?v=l5k1ai_GBDE) +- [Terraform Course - From BEGINNER to PRO!](https://www.youtube.com/watch?v=7xngnjfIlK4&list=WL&index=141&t=16s) +- [HashiCorp Terraform Associate Certification Course](https://www.youtube.com/watch?v=V4waklkBC38&list=WL&index=55&t=111s) +- [Terraform Full Course for Beginners](https://www.youtube.com/watch?v=EJ3N-hhiWv0&list=WL&index=39&t=27s) +- [KodeKloud - Terraform for DevOps Beginners + Labs: Complete Step by Step Guide!](https://www.youtube.com/watch?v=YcJ9IeukJL8&list=WL&index=16&t=11s) +- [Terraform Simple Projects](https://terraform.joshuajebaraj.com/) +- [Terraform Tutorial - The Best Project Ideas](https://www.youtube.com/watch?v=oA-pPa0vfks) +- [Awesome Terraform](https://github.com/shuaibiyy/awesome-terraform) + +[Day 61](day61.md)에서 봐요! diff --git a/2022/ko/Days/day61.md b/2022/ko/Days/day61.md new file mode 100644 index 0000000..a9ce538 --- /dev/null +++ b/2022/ko/Days/day61.md @@ -0,0 +1,172 @@ +--- +title: '#90DaysOfDevOps - Kubernetes & Multiple Environments - Day 61' +published: false +description: 90DaysOfDevOps - Kubernetes & Multiple Environments +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048743 +--- + +## Kubernetes 및 다중 환경 + +지금까지 IaC에 대한 이 섹션에서는 가상 머신을 배포하는 방법을 살펴보았지만, 가상 머신의 모양을 코드에서 정의한 다음 배포한다는 전제는 실제로 동일합니다. Docker 컨테이너도 마찬가지이며, 이 세션에서는 Terraform을 사용하여 Kubernetes에서 지원하는 리소스와 상호 작용하는 방법을 살펴보겠습니다. + +저는 데모 목적으로 3개의 주요 클라우드 제공업체에 Terraform을 사용하여 Kubernetes 클러스터를 배포해 왔으며, 리포지토리 [tf_k8deploy](https://github.com/MichaelCade/tf_k8deploy)를 찾을 수 있습니다. + +그러나 Terraform을 사용하여 Kubernetes 클러스터 내의 객체와 상호 작용할 수도 있는데, 이는 [Kubernetes 공급자](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs)를 사용하거나 [Helm 공급자](https://registry.terraform.io/providers/hashicorp/helm/latest)를 사용하여 차트 배포를 관리할 수 있습니다. + +이제 이전 섹션에서 살펴본 것처럼 `kubectl`을 사용할 수 있습니다. 하지만 Kubernetes 환경에서 Terraform을 사용하면 몇 가지 이점이 있습니다. + +- 통합 workflow - 클러스터 배포에 Terraform을 사용했다면, 동일한 workflow와 도구를 사용하여 Kubernetes 클러스터 내에 배포할 수 있습니다. + +- 라이프사이클 관리 - Terraform은 단순한 프로비저닝 도구가 아니라 변경, 업데이트, 삭제를 가능하게 합니다. + +### 간단한 Kubernetes 데모 + +지난 세션에서 만든 데모와 마찬가지로 이제 Kubernetes 클러스터에 nginx를 배포할 수 있습니다. 여기서는 데모 목적으로 Minikube를 다시 사용하겠습니다. Kubernetes.tf 파일을 생성하고 [여기](2022/Days/IaC/Kubernetes/Kubernetes.tf)에서 이 파일을 찾을 수 있습니다. + +이 파일에서 Kubernetes 공급자를 정의하고, kubeconfig 파일을 가리키고, nginx라는 네임스페이스를 생성한 다음, 2개의 복제본과 마지막으로 서비스를 포함하는 배포를 생성하겠습니다. + +``` +terraform { + required_providers { + kubernetes = { + source = "hashicorp/kubernetes" + version = ">= 2.0.0" + } + } +} +provider "kubernetes" { + config_path = "~/.kube/config" +} +resource "kubernetes_namespace" "test" { + metadata { + name = "nginx" + } +} +resource "kubernetes_deployment" "test" { + metadata { + name = "nginx" + namespace = kubernetes_namespace.test.metadata.0.name + } + spec { + replicas = 2 + selector { + match_labels = { + app = "MyTestApp" + } + } + template { + metadata { + labels = { + app = "MyTestApp" + } + } + spec { + container { + image = "nginx" + name = "nginx-container" + port { + container_port = 80 + } + } + } + } + } +} +resource "kubernetes_service" "test" { + metadata { + name = "nginx" + namespace = kubernetes_namespace.test.metadata.0.name + } + spec { + selector = { + app = kubernetes_deployment.test.spec.0.template.0.metadata.0.labels.app + } + type = "NodePort" + port { + node_port = 30201 + port = 80 + target_port = 80 + } + } +} +``` + +새 프로젝트 폴더에서 가장 먼저 해야 할 일은 `terraform init` 명령을 실행하는 것입니다. + +![](/2022/Days/Images/Day61_IAC1.png) + +그리고 `terraform apply` 명령을 실행하기 전에 네임스페이스가 없다는 것을 보여드리겠습니다. + +![](/2022/Days/Images/Day61_IAC2.png) + +apply 명령을 실행하면 Kubernetes 클러스터 내에 3개의 새로운 리소스, 네임스페이스, 배포 및 서비스가 생성됩니다. + +![](/2022/Days/Images/Day61_IAC3.png) + +이제 클러스터 내에 배포된 리소스를 살펴볼 수 있습니다. + +![](/2022/Days/Images/Day61_IAC4.png) + +이전 섹션에서 보셨듯이 Minikube를 사용하고 있기 때문에 도커 네트워킹으로 인그레스를 시도할 때 한계가 있습니다. 하지만 `kubectl port-forward -n nginx svc/nginx 30201:80` 명령을 실행하고 `http://localhost:30201/`으로 브라우저를 열면 NGINX 페이지를 볼 수 있습니다. + +![](/2022/Days/Images/Day61_IAC5.png) + +Terraform과 Kubernetes에 대해 더 자세한 데모를 해보고 싶으시다면 [HashiCorp 학습 사이트](https://learn.hashicorp.com/tutorials/terraform/kubernetes-provider)를 방문해 보시기 바랍니다. + +### 여러 환경 + +우리가 실행한 데모를 이제 특정 프로덕션, 스테이징 및 개발 환경이 동일하게 보이고 이 코드를 활용하기를 원한다면 Terraform을 사용하여 이를 달성하는 두 가지 접근 방식이 있습니다. + +- `terraform workspaces` - 단일 백엔드 내의 여러 개의 명명된 섹션 + +- 파일 구조 - 디렉토리 레이아웃은 분리를 제공하고, 모듈은 재사용을 제공합니다. + +하지만 위의 각 방법에는 장단점이 있습니다. + +### Terraform workspaces + +장점 + +- 쉬운 시작 +- 편리한 terraform.workspace 표현식 +- 코드 중복 최소화 + +단점 + +- 인적 오류가 발생하기 쉬움(TF를 사용하여 이를 제거하려고 노력 중임) +- 동일한 백엔드 내에 저장된 상태 +- 코드베이스가 배포 구성을 명확하게 보여주지 않음. + +### 파일 구조 + +장점 + +- 백엔드 격리 + - 보안 향상 + - 인적 오류 가능성 감소 +- 배포된 상태를 완벽하게 나타내는 코드베이스 + +단점 + +- 프로비저닝 환경에 여러 Terraform 적용 필요 +- 코드 중복이 더 많지만, 모듈을 사용하여 최소화할 수 있습니다. + +## 자료 + +아래에 많은 리소스를 나열했으며 이 주제는 이미 여러 번 다루어졌다고 생각합니다. 추가 리소스가 있는 경우 리소스와 함께 PR을 올리면 기꺼이 검토하여 목록에 추가해 드리겠습니다. + +- [What is Infrastructure as Code? Difference of Infrastructure as Code Tools](https://www.youtube.com/watch?v=POPP2WTJ8es) +- [Terraform Tutorial | Terraform Course Overview 2021](https://www.youtube.com/watch?v=m3cKkYXl-8o) +- [Terraform explained in 15 mins | Terraform Tutorial for Beginners](https://www.youtube.com/watch?v=l5k1ai_GBDE) +- [Terraform Course - From BEGINNER to PRO!](https://www.youtube.com/watch?v=7xngnjfIlK4&list=WL&index=141&t=16s) +- [HashiCorp Terraform Associate Certification Course](https://www.youtube.com/watch?v=V4waklkBC38&list=WL&index=55&t=111s) +- [Terraform Full Course for Beginners](https://www.youtube.com/watch?v=EJ3N-hhiWv0&list=WL&index=39&t=27s) +- [KodeKloud - Terraform for DevOps Beginners + Labs: Complete Step by Step Guide!](https://www.youtube.com/watch?v=YcJ9IeukJL8&list=WL&index=16&t=11s) +- [Terraform Simple Projects](https://terraform.joshuajebaraj.com/) +- [Terraform Tutorial - The Best Project Ideas](https://www.youtube.com/watch?v=oA-pPa0vfks) +- [Awesome Terraform](https://github.com/shuaibiyy/awesome-terraform) + +[Day 62](day62.md)에서 봐요! diff --git a/2022/ko/Days/day62.md b/2022/ko/Days/day62.md new file mode 100644 index 0000000..b233684 --- /dev/null +++ b/2022/ko/Days/day62.md @@ -0,0 +1,135 @@ +--- +title: '#90DaysOfDevOps - Testing, Tools & Alternatives - Day 62' +published: false +description: '90DaysOfDevOps - Testing, Tools & Alternatives' +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049053 +--- + +## 테스트, 도구 및 대안 + +IaC에 대한 이 섹션을 마무리하면서 코드 테스트, 사용 가능한 다양한 도구, 그리고 이를 달성하기 위한 Terraform의 몇 가지 대안에 대해 언급하지 않을 수 없습니다. 이 섹션의 시작 부분에서 말씀드렸듯이 제가 Terraform에 초점을 맞춘 이유는 첫째로 무료이며 오픈 소스이고 둘째로 크로스 플랫폼이며 환경에 구애받지 않기 때문입니다. 하지만 고려해야 할 다른 대안도 있지만, 전반적인 목표는 이것이 인프라를 배포하는 방법이라는 것을 사람들에게 알리는 것입니다. + +### Code Rot + +이 세션에서 다루고자 하는 첫 번째 영역은 Code Rot으로, 애플리케이션 코드와 달리 코드로서의 인프라는 한 번 사용되었다가 오랫동안 사용하지 않을 수도 있습니다. Terraform을 사용하여 AWS에 VM 환경을 배포하려고 하는데, 처음에 완벽하게 작동하고 환경이 갖춰졌지만, 이 환경이 자주 변경되지 않아 코드가 중앙 위치에 저장되기를 바라지만 코드가 변경되지 않는 상태를 그대로 유지한다고 가정해 보겠습니다. + +인프라에 변화가 생기면 어떻게 될까요? 하지만 대역 외에서 수행되거나 다른 환경이 변경되는 경우가 있습니다. + +- 대역 외 변경 사항 +- 고정되지 않은 버전 +- 더 이상 사용되지 않는 종속성 +- 적용되지 않은 변경 사항 + +### 테스트 + +코드 썩음과 일반적으로 뒤따르는 또 다른 큰 영역은 IaC를 테스트하고 모든 영역이 정상적으로 작동하는지 확인하는 기능입니다. + +먼저 살펴볼 수 있는 몇 가지 기본 제공 테스트 명령어가 있습니다: + +| Command | Description | +| -------------------- | ------------------------------------------------------------------------ | +| `terraform fmt` | Terraform 구성 파일을 표준 형식과 스타일로 다시 작성합니다. | +| `terraform validate` | 디렉터리에 있는 구성 파일의 유효성을 검사하여 구성만 참조합니다. | +| `terraform plan` | 실행 계획을 생성하여 Terraform이 계획한 변경 사항을 미리 볼 수 있습니다. | +| Custom validation | 입력 변수가 예상과 일치하는지 확인하기 위한 입력 변수 유효성 검사 | + +Terraform 외부에서 사용할 수 있는 몇 가지 테스트 도구도 있습니다: + +- [tflint](https://github.com/terraform-linters/tflint) + + - 가능한 오류를 찾습니다. + - 더 이상 사용되지 않는 구문과 사용되지 않는 선언에 대해 경고합니다. + - 모범 사례와 명명 규칙을 적용합니다. + +검사 도구 + +- [checkov](https://www.checkov.io/) - 클라우드 인프라 구성을 스캔하여 배포하기 전에 잘못된 구성을 찾습니다. +- [tfsec](https://aquasecurity.github.io/tfsec/v1.4.2/) - Terraform 코드에 대한 정적 분석 보안 스캐너입니다. +- [terrascan](https://github.com/accurics/terrascan) - IaC를 위한 정적 코드 분석기입니다. +- [terraform-compliance](https://terraform-compliance.com/) - IaC에 대한 네거티브 테스트 기능을 지원하는 Terraform에 대한 경량의 보안 및 규정 준수 중심 테스트 프레임워크입니다. +- [snyk](https://docs.snyk.io/products/snyk-infrastructure-as-code/scan-terraform-files/scan-and-fix-security-issues-in-terraform-files) - Terraform 코드에서 잘못된 구성과 보안 문제를 스캔합니다. + +관리형 클라우드 제품 + +- [Terraform Sentinel](https://www.terraform.io/cloud-docs/sentinel) - HashCorp 엔터프라이즈 제품과 통합된 임베디드 정책 기반 프레임워크로 세분화된 로직 기반 정책 결정을 가능하게 하며, 외부 소스의 정보를 사용하도록 확장할 수 있습니다. + +### 자동화된 테스트 + +- [Terratest](https://terratest.gruntwork.io/) - Terratest는 인프라 테스트를 위한 패턴과 도우미 함수를 제공하는 Go 라이브러리입니다. +- Terratest는 인프라 코드에 대한 자동화된 테스트 작성을 용이하게 합니다. 일반적인 인프라 테스트를 위한 다양한 도우미 함수와 패턴을 제공합니다. +- 코드는 2022/Days/IaC/Terratest에서 찾을 수 있습니다. +- 이 애플리케이션을 실행하려면 + - git clone #repo_url#
+ - cd test
+ - go mod init ""
+ **MODULE_NAME은 github.com//이 됩니다.**
+ - go mod init github.com/
+ - go run + +--- + +go mod init ""은 테스트 폴더에 go.mod 파일을 생성합니다.
+ +- go.mod 파일은 GoLang에서 의존성 관리의 기초입니다. +- 프로젝트에서 필요하거나 사용할 모든 모듈이 go.mod 파일에 유지됩니다. +- 프로젝트에서 사용하거나 가져올 모든 패키지의 항목을 생성합니다. +- 수동으로 각 종속성을 가져오는 노력을 줄입니다. + +처음 **go test**를 실행하면 go.sum 파일이 생성됩니다.
+ +- **go test** 또는 **go build**가 처음 실행될 때 go.sum 파일이 생성됩니다. +- 특정 버전(최신)으로 모든 패키지를 설치합니다. +- 우린 파일을 편집하거나 수정할 필요가 없습니다. + +추가로 언급할 만한 것들 + +- [Terraform 클라우드](https://cloud.hashicorp.com/products/terraform) - Terraform 클라우드는 HashCorp의 관리형 서비스 제품입니다. 실무자, 팀 및 조직이 프로덕션에서 Terraform을 사용하기 위해 불필요한 도구와 문서가 필요하지 않습니다. + +- [Terragrunt](https://terragrunt.gruntwork.io/) - Terragrunt는 구성을 건조하게 유지하고, 여러 Terraform 모듈로 작업하고, 원격 상태를 관리하기 위한 추가 도구를 제공하는 얇은 래퍼입니다. + +- [Atlantis](https://www.runatlantis.io/) - Terraform 풀 리퀘스트 자동화 + +### 대안 + +이 섹션을 시작할 때 57일째에 몇 가지 대안이 있다고 언급했으며, 이번 챌린지에서도 이에 대해 계속 살펴볼 계획입니다. + +| Cloud Specific | Cloud Agnostic | +| ------------------------------- | -------------- | +| AWS CloudFormation | Terraform | +| Azure Resource Manager | Pulumi | +| Google Cloud Deployment Manager | | + +저는 위의 목록 중 AWS CloudFormation을 가장 많이 사용했으며 AWS에서 기본으로 제공하지만, Terraform 이외의 다른 제품은 사용해 본 적이 없습니다. 클라우드별 버전은 특정 클라우드에서는 매우 훌륭하지만, 여러 클라우드 환경이 있는 경우 이러한 구성을 마이그레이션하는 데 어려움을 겪거나 IaC 작업을 위해 여러 관리 플레인을 사용해야 할 것입니다. + +흥미로운 다음 단계는 시간을 내서 [Pulumi](https://www.pulumi.com/)에 대해 자세히 알아보는 것입니다. + +Pulumi 사이트의 비교 부분에서 + +> "Terraform과 Pulumi 모두 코드가 원하는 인프라 상태를 나타내는 코드 모델로 원하는 상태 인프라를 제공하며, 배포 엔진은 이 원하는 상태를 스택의 현재 상태와 비교하여 어떤 리소스를 생성, 업데이트 또는 삭제해야 하는지를 결정합니다." + +제가 볼 수 있는 가장 큰 차이점은 HCL(HashCorp 구성 언어)과 달리 Pulumi는 Python, TypeScript, JavaScript, Go, .NET과 같은 범용 언어를 허용한다는 점입니다. + +간략한 개요 [Pulumi 소개: 코드형 최신 인프라](https://www.youtube.com/watch?v=QfJTJs24-JM) 저는 선택의 폭이 넓다는 점이 마음에 들어서 좀 더 자세히 알아보고 싶었습니다. + +이것으로 IaC 섹션을 마무리하고, 다음에는 구성 관리와 약간 겹치는 부분, 특히 일부 작업 및 데모에 Ansible을 사용할 구성 관리의 큰 그림을 살펴볼 것입니다. + +## 리소스 + +아래에 많은 리소스를 나열했으며 이 주제는 이미 여러 번 다루어졌다고 생각합니다. 추가 리소스가 있는 경우 리소스와 함께 PR을 올리면 기꺼이 검토하여 목록에 추가해 드리겠습니다. + +- [What is Infrastructure as Code? Difference of Infrastructure as Code Tools](https://www.youtube.com/watch?v=POPP2WTJ8es) +- [Terraform Tutorial | Terraform Course Overview 2021](https://www.youtube.com/watch?v=m3cKkYXl-8o) +- [Terraform explained in 15 mins | Terraform Tutorial for Beginners](https://www.youtube.com/watch?v=l5k1ai_GBDE) +- [Terraform Course - From BEGINNER to PRO!](https://www.youtube.com/watch?v=7xngnjfIlK4&list=WL&index=141&t=16s) +- [HashiCorp Terraform Associate Certification Course](https://www.youtube.com/watch?v=V4waklkBC38&list=WL&index=55&t=111s) +- [Terraform Full Course for Beginners](https://www.youtube.com/watch?v=EJ3N-hhiWv0&list=WL&index=39&t=27s) +- [KodeKloud - Terraform for DevOps Beginners + Labs: Complete Step by Step Guide!](https://www.youtube.com/watch?v=YcJ9IeukJL8&list=WL&index=16&t=11s) +- [Terraform Simple Projects](https://terraform.joshuajebaraj.com/) +- [Terraform Tutorial - The Best Project Ideas](https://www.youtube.com/watch?v=oA-pPa0vfks) +- [Awesome Terraform](https://github.com/shuaibiyy/awesome-terraform) +- [Pulumi - IaC in your favorite programming language!](https://www.youtube.com/watch?v=vIjeiDcsR3Q&t=51s) + +[Day 63](day63.md)에서 봐요! diff --git a/2022/ko/Days/day63.md b/2022/ko/Days/day63.md new file mode 100644 index 0000000..93ddcfe --- /dev/null +++ b/2022/ko/Days/day63.md @@ -0,0 +1,101 @@ +--- +title: '#90DaysOfDevOps - The Big Picture: Configuration Management - Day 63' +published: false +description: 90DaysOfDevOps - The Big Picture Configuration Management +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048711 +--- + +## 큰 그림: 구성 관리 + +IaC를 다루는 섹션의 뒷부분에서 바로 이어서 구성 관리 또는 애플리케이션 구성 관리에 대해 이야기할 때 약간의 교차점이 있을 것입니다. + +구성 관리는 애플리케이션, 시스템, 서버를 원하는 상태로 유지하는 프로세스입니다. 인프라스트럭처와 겹치는 부분은 IaC가 인프라가 원하는 상태에 있는지 확인하지만, 그 이후에는 특히 Terraform이 OS 설정이나 애플리케이션의 원하는 상태를 관리하지 않기 때문에 구성 관리 도구가 필요하다는 점입니다. Deane에서 변경 사항이 발생할 때 시스템과 애플리케이션이 예상대로 작동하는지 확인합니다. + +구성 관리는 문서화되지 않은 크고 작은 변경을 방지합니다. + +### 시나리오: 구성 관리를 사용하려는 이유 + +구성 관리를 사용하고자 하는 시나리오나 이유를 알기 위해 철수를 만나보세요. 철수는 우리의 시스템 관리자이며, 환경 내의 모든 시스템에서 열심히 일하며 만족하는 사람입니다. + +시스템에 장애가 발생하거나 화재가 발생하거나 서버가 다운되면 어떻게 될까요? 철수는 화재가 발생하면 어떻게 해야 하는지 정확히 알고 있기 때문에 쉽게 해결할 수 있지만, 특히 대규모로 확장하는 환경에서 여러 서버가 장애를 일으키기 시작하면 철수에게 구성 관리 도구가 필요한 이유가 바로 여기에 있습니다. 구성 관리 도구는 철수가 각 서버를 빠르고 효과적으로 대규모로 설정하는 방법에 대한 지침을 푸시할 수 있는 올바른 코드를 구성하기만 하면 되는 록스타처럼 보이도록 도와줄 수 있습니다. + +### 구성 관리 도구 + +다양한 구성 관리 도구를 사용할 수 있으며, 각 도구에는 특정 상황에 더 적합한 특정 기능이 있습니다. + +![](/2022/Days/Images/Day63_config1.png) + +이 단계에서는 위 그림의 옵션을 간략히 살펴본 후 어떤 도구를 사용할지, 왜 사용할지 결정하겠습니다. + +- **Chef** + - Chef는 인프라 자동화를 통해 모든 환경, 모든 규모에서 구성이 일관되게 적용되도록 보장합니다. + - Chef는 Ruby와 Erlang으로 작성된 OpsCode에서 개발한 오픈 소스 도구입니다. + - Chef는 이기종 인프라를 보유하고 있으며 성숙한 솔루션을 찾고 있는 조직에 가장 적합합니다. + - Recipes와 Cookbooks은 시스템의 구성 코드를 결정합니다. + - 프로 - 방대한 Recipes 컬렉션을 사용할 수 있습니다. + - 장점 - 강력한 버전 제어를 제공하는 Git과 잘 통합됩니다. + - 단점 - 학습 곡선이 가파르며 상당한 시간이 필요합니다 + - 단점 - 메인 서버에서 제어할 수 있는 권한이 많지 않습니다. + - 아키텍처 - 서버/클라이언트 + - 설정 용이성 - 보통 + - 언어 - 절차적 - 작업 수행 방법 지정 +- **Puppet** + - Puppet은 자동 배포를 지원하는 구성 관리 도구입니다. + - Puppet은 Ruby로 빌드되며 매니페스트 작성에 DSL을 사용합니다. + - Puppet은 확장성에 중점을 둔 이기종 인프라에서도 잘 작동합니다. + - 장점 - 지원을 위한 대규모 커뮤니티가 있습니다. + - 장점 - 잘 발달된 보고 메커니즘입니다. + - 단점 - 고급 작업을 수행하려면 Ruby 언어에 대한 지식이 필요합니다. + - 단점 - 메인 서버에 대한 제어 권한이 많지 않습니다. + - 아키텍처 - 서버/클라이언트 + - 설정 용이성 - 보통 + - 언어 - 선언적 - 수행할 작업만 지정 가능 +- **Ansible** + - Ansible은 구성 관리, 클라우드 프로비저닝, 배포 및 오케스트레이션을 자동화하는 IT 자동화 도구입니다. + - Ansible Playbook의 핵심은 YAML로 작성되어 있습니다. (몇 번 본 적이 있으므로 YAML에 대한 섹션을 만들어야 합니다.) + - Ansible은 빠르게 시작하고 실행하는 데 중점을 두는 환경이 있을 때 잘 작동합니다. + - 서버에 지침을 제공하는 Playbook에서 작동합니다. + - 장점 - 원격 노드에 에이전트가 필요하지 않습니다. + - 장점 - YAML은 배우기 쉽습니다. + - 단점 - 성능 속도가 다른 도구보다 느린 경우가 많습니다.(철수가 직접 수동으로 수행하는 것보다 빠름) + - 단점 - YAML은 Ruby만큼 강력하지는 않지만 학습 곡선이 적습니다. + - 아키텍처 - 클라이언트 전용 + - 설정 용이성 - 매우 쉬움 + - 언어 - 절차적 - 작업 수행 방법 지정 +- **SaltStack** + - SaltStack은 구성 관리와 원격 실행을 자동화하는 CLI 기반 도구입니다. + - SaltStack은 Python 기반이며, 명령어는 YAML 또는 해당 DSL로 작성됩니다. + - 확장성과 복원력을 최우선으로 고려하는 환경에 적합합니다. + - 장점 - 가동 및 실행 시 사용이 간편합니다. + - 장점 - 우수한 보고 메커니즘입니다. + - 단점 - 설정 단계가 까다롭습니다. + - 단점 - 다른 서비스보다 훨씬 덜 개발된 새로운 웹 UI가 있습니다. + - 아키텍처 - 서버/클라이언트 + - 설정 용이성 - 보통 + - 언어 - 선언적 - 수행할 작업만 지정함 + +### Ansible과 Terraform 비교 + +이 섹션에서 사용할 도구는 Ansible입니다. (사용하기 쉽고 언어에 지식이 약간만 필요합니다.) + +도구를 좀 더 자세히 살펴보기 전에 Ansible과 Terraform의 몇 가지 차이점을 살펴보는 것이 중요하다고 생각합니다. + +| | Ansible | Terraform | +| ----------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | +| 유형 | Ansible은 구성 관리 도구입니다. | Terraform은 오케스트레이션 도구입니다. | +| 인프라 | Ansible은 변경 가능한 인프라를 지원하며, Terraform은 변경 불가능한 인프라를 지원합니다. | +| 언어 | Ansible은 절차적 언어를 따르고, Terraform은 선언적 언어를 따릅니다. | +| 프로비저닝 | 부분 프로비저닝(VM, 네트워크, 스토리지) 제공합니다. | Terraform은 광범위한 프로비저닝(VM, 네트워크, 스토리지) 제공합니다. | +| 패키징 | 패키징 및 템플릿에 대한 완벽한 지원 제공합니다. | 패키징 및 템플릿에 대한 부분 지원 제공합니다. | +| 라이프사이클 관리 | Ansible에는 라이프사이클 관리 기능이 없습니다. | Terraform은 라이프사이클 및 상태 관리에 크게 의존합니다. | + +## 자료 + +- [What is Ansible](https://www.youtube.com/watch?v=1id6ERvfozo) +- [Ansible 101 - Episode 1 - Introduction to Ansible](https://www.youtube.com/watch?v=goclfp6a2IQ) +- [NetworkChuck - You need to learn Ansible right now!](https://www.youtube.com/watch?v=5hycyr-8EKs&t=955s) + +[Day 64](day64.md)에서 봐요! diff --git a/2022/ko/Days/day64.md b/2022/ko/Days/day64.md new file mode 100644 index 0000000..fc5d2ec --- /dev/null +++ b/2022/ko/Days/day64.md @@ -0,0 +1,87 @@ +--- +title: '#90DaysOfDevOps - Ansible: Getting Started - Day 64' +published: false +description: '90DaysOfDevOps - Ansible: Getting Started' +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048765 +--- + +## Ansible: 시작하기 + +어제 [Day 63](day63.md)에서 Ansible이 무엇인지에 대해 조금 다루었지만 여기서는 이에 대해 조금 더 자세히 알아보겠습니다. 먼저 Ansible은 RedHat에서 제공합니다. 둘째, 에이전트가 없으며 SSH를 통해 연결하고 명령을 실행합니다. 셋째, 크로스 플랫폼(Linux 및 macOS, WSL2) 및 오픈 소스(엔터프라이즈용 유료 옵션도 있음)이며 다른 모델에 비해 Ansible은 구성을 push합니다. + +### Ansible 설치 + +여러분이 상상할 수 있듯이, RedHat과 Ansible 팀은 Ansible을 문서화하는 데 환상적인 작업을 해왔습니다. 이는 일반적으로 [여기](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html)에서 찾을 수 있는 설치 단계부터 시작됩니다. Ansible은 에이전트가 없는 자동화 도구이며, 이 도구는 "Control Node"라고 하는 시스템에 배포되고 이 Control Node에서 SSH를 통해 머신 및 기타 장치(네트워크일 수 있음)를 관리한다고 말씀드린 것을 기억하세요. + +위에 링크된 문서에는 Windows OS를 Control Node로 사용할 수 없다고 명시되어 있습니다. + +Control Node 및 적어도 이 데모에서는 [Linux 섹션](day20.md)에서 만든 Linux VM을 Control Node로 사용하겠습니다. + +이 시스템은 우분투를 실행 중이며 설치 단계는 다음 명령만 있으면 됩니다. + +```Shell +sudo apt update +sudo apt install software-properties-common +sudo add-apt-repository --yes --update ppa:ansible/ansible +sudo apt install ansible +``` + +이제 Control Node에 ansible이 설치되어 있어야 하며, `ansible --version`을 실행하여 확인할 수 있으며 아래와 비슷한 내용이 표시됩니다. + +![](/2022/Days/Images/Day64_config1.png) + +이제 환경의 다른 Node를 제어하는 방법을 살펴보기 전에 로컬 머신에 대해 `ansible localhost -m ping` 명령을 실행하여 ansible의 기능을 확인할 수도 있습니다. 이 명령은 [Ansible 모듈](https://docs.ansible.com/ansible/2.9/user_guide/modules_intro.html)을 사용하며, 여러 시스템에서 하나의 작업을 빠르게 수행할 수 있는 방법이기도 합니다. 로컬 호스트만으로는 그다지 재미있지 않지만, 무언가를 얻거나 모든 시스템이 가동 중이고 1000개 이상의 서버와 디바이스가 있다고 상상해 보세요. + +![](/2022/Days/Images/Day64_config2.png) + +또는 실제 모듈의 실제 사용법은 `ansible webservers -m service -a "name=httpd state=started"`와 같이 모든 웹서버에 httpd 서비스가 실행 중인지 여부를 알려주는 것일 수 있습니다. 이 명령에 사용된 웹서버 용어에 대해 간략히 설명했습니다. + +### 호스트 + +위에서 localhost를 사용하여 시스템에 대한 간단한 핑 모듈을 실행하는 방법으로는 네트워크에 다른 컴퓨터를 지정할 수 없습니다. 예를 들어 VirtualBox가 실행 중인 Windows 호스트에는 IP 10.0.0.1의 네트워크 어댑터가 있지만 아래에서 볼 수 있듯이 핑으로 연결할 수 있지만 ansible을 사용하여 해당 작업을 수행할 수 없습니다. + +![](/2022/Days/Images/Day64_config3.png) + +이러한 작업으로 자동화할 호스트 또는 Node를 지정하려면 이를 정의해야 합니다. 시스템의 /etc/ansible 디렉토리로 이동하여 정의할 수 있습니다. + +![](/2022/Days/Images/Day64_config4.png) + +편집하려는 파일은 호스트 파일이며, 텍스트 편집기를 사용하여 호스트를 정의할 수 있습니다. 호스트 파일에는 파일을 사용하고 수정하는 방법에 대한 많은 훌륭한 지침이 포함되어 있습니다. 아래로 스크롤하여 [windows]라는 새 그룹을 만들고 해당 호스트에 대한 `10.0.0.1` IP 주소를 추가하겠습니다. 파일을 저장합니다. + +![](/2022/Days/Images/Day64_config5.png) + +그러나 Ansible이 시스템에 연결하려면 SSH를 사용할 수 있어야 한다고 말씀드린 것을 기억하세요. 아래에서 볼 수 있듯이 `ansible windows -m ping`을 실행하면 SSH를 통한 연결에 실패하여 연결할 수 없다는 메시지가 표시됩니다. + +![](/2022/Days/Images/Day64_config6.png) + +이제 인벤토리에 호스트를 추가하기 시작했는데, 모든 장치를 정의하는 곳이기 때문에 이 파일의 다른 이름인 네트워크 장치, 스위치 및 라우터도 여기에 추가하고 그룹화할 수 있습니다. 하지만 호스트 파일에는 Linux 시스템 그룹에 액세스하기 위한 자격 증명도 추가했습니다. + +![](/2022/Days/Images/Day64_config7.png) + +이제 `ansible Linux -m ping`을 실행하면 아래와 같이 성공합니다. + +![](/2022/Days/Images/Day64_config8.png) + +이제 구성을 자동화하려는 대상 시스템인 Node 요구 사항이 있습니다. 이 시스템에는 Ansible을 위한 어떤 것도 설치하지 않습니다(소프트웨어를 설치할 수는 있지만 필요한 Ansible의 클라이언트는 없습니다). Ansible은 SSH를 통해 연결하고 SFTP를 통해 모든 것을 전송합니다. (원하는 경우 SSH를 구성한 경우 SCP 대 SFTP를 사용할 수 있습니다.) + +### Ansible 명령 + +리눅스 머신에 대해 `ansible Linux -m ping`을 실행하고 응답을 얻을 수 있는 것을 보셨겠지만, 기본적으로 Ansible을 사용하면 많은 adhoc 명령을 실행할 수 있습니다. 하지만 이 명령을 시스템 그룹에 대해 실행하여 해당 정보를 다시 가져올 수 있습니다. [adhoc 명령](https://docs.ansible.com/ansible/latest/user_guide/intro_adhoc.html) + +명령을 반복하거나 이러한 명령을 실행하기 위해 개별 시스템에 로그인해야 하는 경우 Ansible이 도움이 될 수 있습니다. 예를 들어, 아래의 간단한 명령은 Linux 그룹에 추가하는 모든 시스템에 대한 모든 운영 체제 세부 정보를 출력합니다. +`ansible linux -a "cat /etc/os-release"` + +다른 사용 사례로는 시스템 재부팅, 파일 복사, 패커 및 사용자 관리 등이 있습니다. adhoc 명령과 Ansible 모듈을 결합할 수도 있습니다. + +adhoc 명령은 선언적 모델을 사용하여 지정된 최종 상태에 도달하는 데 필요한 작업을 계산하고 실행합니다. adhoc 명령은 시작하기 전에 현재 상태를 확인하고 현재 상태가 지정된 최종 상태와 다르지 않으면 아무 작업도 수행하지 않음으로써 일종의 무임승차를 하는 셈입니다. + +## 자료 + +- [What is Ansible](https://www.youtube.com/watch?v=1id6ERvfozo) +- [Ansible 101 - Episode 1 - Introduction to Ansible](https://www.youtube.com/watch?v=goclfp6a2IQ) +- [NetworkChuck - You need to learn Ansible right now!](https://www.youtube.com/watch?v=5hycyr-8EKs&t=955s) + +[Day 65](day65.md)에서 봐요! diff --git a/2022/ko/Days/day65.md b/2022/ko/Days/day65.md new file mode 100644 index 0000000..b768a82 --- /dev/null +++ b/2022/ko/Days/day65.md @@ -0,0 +1,278 @@ +--- +title: '#90DaysOfDevOps - Ansible Playbooks - Day 65' +published: false +description: 90DaysOfDevOps - Ansible Playbooks +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049054 +--- + +### Ansible Playbook + +이 섹션에서는 적어도 Ansible의 경우 하나의 명령으로 여러 서버를 실행하여 긴 서버 목록을 재부팅하는 것과 같은 간단한 명령을 수행하고 각 서버에 개별적으로 연결해야 하는 번거로움을 줄일 수 있다는 점이 가장 큰 장점이라고 할 수 있습니다. + +하지만 실제로 베어 운영 체제를 가져와서 해당 시스템에서 실행할 소프트웨어와 서비스를 선언하고 모두 원하는 상태로 실행되도록 하는 것은 어떨까요? + +이것이 바로 Ansible Playbook이 필요한 이유입니다. Playbook을 사용하면 서버 그룹을 가져와서 해당 그룹에 대해 구성 및 설치 작업을 수행할 수 있습니다. + +### Playbook 형식 + +Playbook > Play > Task + +스포츠에 관심이 있는 분이라면 Playbook이라는 용어를 들어보셨을 텐데요, Playbook은 다양한 Play와 Task로 구성된 Play 방법을 팀에게 알려주는 것으로, Play를 스포츠나 게임의 세트 피스라고 생각하면 각 Play에 Task가 연관되어 있고, Play를 구성하는 여러 Task가 있을 수 있으며, Playbook에는 여러 가지 다른 Play가 있을 수 있습니다. + +이러한 Playbook은 YAML(YAML은 마크업 언어가 아님)로 작성되어 있으며, 지금까지 다룬 많은 섹션, 특히 컨테이너와 Kubernetes에서 YAML 형식의 구성 파일을 찾을 수 있습니다. + +playbook.yml이라는 간단한 Playbook을 살펴보겠습니다. + +```Yaml +- name: Simple Play + hosts: localhost + connection: local + tasks: + - name: Ping me + ping: + - name: print os + debug: + msg: "{{ ansible_os_family }}" +``` + +위의 파일 [simple_play](/2022/Days/Configmgmt/simple_play.yml)을 찾을 수 있습니다. 그런 다음 `ansible-playbook simple_play.yml` 명령을 사용하면 다음 단계를 수행합니다. + +![](/2022/Days/Images/Day65_config1.png) + +'gathering facts'라는 첫 번째 Task가 발생한 것을 볼 수 있지만, 우리가 트리거하거나 요청하지 않았나요? 이 모듈은 원격 호스트에 대한 유용한 변수를 수집하기 위해 Playbook에서 자동으로 호출됩니다. [ansible.builtin.setup](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/setup_module.html) + +두 번째 Task는 Ping을 설정하는 것이었는데, 이것은 ICMP Ping이 아니라 원격 또는 로컬 호스트에 대한 연결 성공 시 `pong`을 반환하는 파이썬 스크립트입니다. [ansible.builtin.ping](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/ping_module.html) + +그런 다음 첫 번째 Task로 정의한 세 번째 또는 두 번째 Task는 OS를 알려주는 메시지 인쇄를 비활성화하지 않는 한 실행됩니다. 이 Task에서는 조건문을 사용하고 있으므로 모든 유형의 운영 체제에 대해 이 Playbook을 실행할 수 있으며, 그러면 OS 이름이 반환됩니다. 편의상 이 출력은 단순히 메시지를 출력하고 있지만 다음과 같이 말하는 Task를 추가할 수 있습니다: + +```Yaml +tasks: + - name: "shut down Debian flavoured systems" + command: /sbin/shutdown -t now + when: ansible_os_family == "Debian" +``` + +### Vagrant로 환경 설정하기 + +Vagrant를 사용하여 Node 환경을 설정할 것입니다. 저는 이것을 합리적인 4 Node로 유지하려고 하지만 300 Node 또는 3000 Node가 될 수 있으며 이것이 서버를 구성할 수 있는 Ansible 및 기타 구성 관리 도구의 힘이라는 것을 알 수 있기를 바랍니다. + +이 파일은 [여기](/2022/Days/Configmgmt/Vagrantfile)에서 찾을 수 있습니다. + +```Vagrant +Vagrant.configure("2") do |config| + servers=[ + { + :hostname => "db01", + :box => "bento/ubuntu-21.10", + :ip => "192.168.169.130", + :ssh_port => '2210' + }, + { + :hostname => "web01", + :box => "bento/ubuntu-21.10", + :ip => "192.168.169.131", + :ssh_port => '2211' + }, + { + :hostname => "web02", + :box => "bento/ubuntu-21.10", + :ip => "192.168.169.132", + :ssh_port => '2212' + }, + { + :hostname => "loadbalancer", + :box => "bento/ubuntu-21.10", + :ip => "192.168.169.134", + :ssh_port => '2213' + } + + ] + +config.vm.base_address = 600 + + servers.each do |machine| + + config.vm.define machine[:hostname] do |node| + node.vm.box = machine[:box] + node.vm.hostname = machine[:hostname] + + node.vm.network :public_network, bridge: "Intel(R) Ethernet Connection (7) I219-V", ip: machine[:ip] + node.vm.network "forwarded_port", guest: 22, host: machine[:ssh_port], id: "ssh" + + node.vm.provider :virtualbox do |v| + v.customize ["modifyvm", :id, "--memory", 2048] + v.customize ["modifyvm", :id, "--name", machine[:hostname]] + end + end + end + +end +``` + +`vagrant up` 명령을 사용하여 VirtualBox에서 이러한 머신을 스핀업하면 메모리를 더 추가할 수 있고 각 머신에 대해 다른 private_network 주소를 정의할 수도 있지만 제 환경에서는 이 방법이 작동합니다. 컨트롤 박스는 리눅스 섹션에서 배포한 우분투 데스크톱이라는 점을 기억하세요. + +리소스가 제한되어 있는 경우 `vagrant up web01 web02`를 실행하여 여기서 사용 중인 웹서버만 불러올 수도 있습니다. + +### Ansible 호스트 구성 + +이제 환경이 준비되었으므로 Ansible을 확인할 수 있으며, 이를 위해 우분투 데스크톱(이 데스크톱을 사용할 수도 있지만 아래 네트워크에 액세스하는 네트워크에 있는 모든 Linux 기반 머신을 동일하게 사용할 수 있음)을 컨트롤로 사용하고, ansible 호스트 파일에서 새 Node를 그룹에 추가해 보겠습니다, 이 파일을 인벤토리로 생각할 수 있으며, 이에 대한 대안으로 `-i filename`을 사용하여 ansible 명령의 일부로 호출되는 또 다른 인벤토리 파일을 사용할 수 있습니다. 이는 프로덕션, 테스트 및 스테이징 환경마다 다른 파일을 가질 수 있으므로 호스트 파일을 사용하는 것보다 유용할 수 있습니다. 기본 호스트 파일을 사용하고 있으므로 이 파일을 기본으로 사용하므로 지정할 필요가 없습니다. + +기본 호스트 파일에 다음을 추가했습니다. + +```Text +[control] +ansible-control + +[proxy] +loadbalancer + +[webservers] +web01 +web02 + +[database] +db01 + +``` + +![](/2022/Days/Images/Day65_config2.png) + +계속 진행하기 전에 Node에 대해 명령을 실행할 수 있는지 확인하기 위해 `ansible nodes -m command -a hostname`을 실행해 보겠습니다. 이 간단한 명령은 연결이 있는지 테스트하고 호스트 이름을 다시 보고합니다. + +또한, 연결을 보장하기 위해 /etc/hosts 파일 내의 Ubuntu 제어 Node에 이러한 Node와 IP를 추가했습니다. 우분투 상자에서 각 Node에 대해 SSH 구성을 수행해야 할 수도 있습니다. + +```Text +192.168.169.140 ansible-control +192.168.169.130 db01 +192.168.169.131 web01 +192.168.169.132 web02 +192.168.169.133 loadbalancer +``` + +![](/2022/Days/Images/Day65_config3.png) + +이 단계에서는 제어 Node와 서버 Node 사이에 SSH 키를 설정하는 과정을 진행하겠습니다. 다음 단계에서는 호스트의 파일에 변수를 추가하여 사용자 이름과 비밀번호를 제공하는 방법을 사용할 수 있습니다. 이 방법은 결코 모범 사례가 될 수 없으므로 권장하지 않습니다. + +SSH를 설정하고 Node 간에 공유하려면 아래 단계를 따르세요. 비밀번호(`vagrant`)를 묻는 메시지가 표시되면 `y`를 몇 번 눌러야 수락할 수 있습니다. + +`ssh-keygen` + +![](/2022/Days/Images/Day65_config5.png) + +`ssh-copy-id localhost` + +![](/2022/Days/Images/Day65_config6.png) + +이제 모든 VM이 켜져 있다면 `ssh-copy-id web01 && ssh-copy-id web02 && ssh-copy-id loadbalancer && ssh-copy-id db01`을 실행하면 비밀번호를 입력하라는 메시지가 표시됩니다(이 경우 비밀번호는 `vagrant`입니다). + +모든 VM을 실행하지 않고 웹서버만 실행하고 있으므로 `ssh-copy-id web01 && ssh-copy-id web02`를 발급했습니다. + +![](/2022/Days/Images/Day65_config7.png) + +Playbook을 실행하기 전에 그룹과 간단하게 연결되었는지 확인하고 싶어서 `ansible webservers -m ping`을 실행하여 연결을 테스트했습니다. + +![](/2022/Days/Images/Day65_config4.png) + +### 첫 번째 "진짜" Ansible Playbook + +첫 번째 Ansible Playbook은 웹 서버를 구성하는 것으로, 호스트 파일에서 [webservers] 그룹 아래에 웹 서버를 그룹화했습니다. + +Playbook을 실행하기 전에 web01과 web02에 apache가 설치되어 있지 않은 것을 확인할 수 있습니다. 아래 스크린샷 상단은 이 Playbook을 실행하기 위해 ansible 컨트롤 내에서 생성한 폴더 및 파일 레이아웃을 보여줍니다. `playbook1.yml`이 있고, template 폴더에는 `index.html.j2`와 `ports.conf.j2` 파일이 있습니다. 이 파일은 위에 나열된 리포지토리 폴더에서 찾을 수 있습니다. + +그런 다음 web01에 SSH로 접속하여 apache가 설치되어 있는지 확인합니다. + +![](/2022/Days/Images/Day65_config8.png) + +위에서 web01에 apache가 설치되어 있지 않다는 것을 알 수 있으므로 아래 Playbook을 실행하여 이 문제를 해결할 수 있습니다. + +```Yaml +- hosts: webservers + become: yes + vars: + http_port: 8000 + https_port: 4443 + html_welcome_msg: "Hello 90DaysOfDevOps" + tasks: + - name: ensure apache is at the latest version + apt: + name: apache2 + state: latest + + - name: write the apache2 ports.conf config file + template: + src: templates/ports.conf.j2 + dest: /etc/apache2/ports.conf + notify: + - restart apache + + - name: write a basic index.html file + template: + src: templates/index.html.j2 + dest: /var/www/html/index.html + notify: + - restart apache + + - name: ensure apache is running + service: + name: apache2 + state: started + + handlers: + - name: restart apache + service: + name: apache2 + state: restarted +``` + +위의 Playbook을 분석합니다: + +- `host: webserver`는 이 Playbook을 실행할 그룹이 웹서버라는 그룹이라는 것을 의미합니다. +- `become: yes`는 Playbook을 실행하는 사용자가 원격 시스템에서 루트가 된다는 의미입니다. 루트 비밀번호를 입력하라는 메시지가 표시됩니다. +- 그런 다음 `vars`가 있는데, 이는 웹서버 전체에서 원하는 몇 가지 환경 변수를 정의합니다. + +그런 다음 Task를 시작합니다, + +- Task 1은 apache가 최신 버전을 실행 중인지 확인하는 것입니다. +- Task 2는 template 폴더에 있는 소스에서 ports.conf 파일을 작성하는 것입니다. +- Task 3은 기본 index.html 파일을 생성하는 것입니다. +- Task 4는 apache가 실행 중인지 확인하는 것입니다. + +마지막으로 Handler 섹션인 [Handler: 변경에 대한 Task 실행](https://docs.ansible.com/ansible/latest/user_guide/playbooks_handlers.html)이 있습니다. + +"때로는 컴퓨터에서 변경이 이루어질 때만 Task가 실행되기를 원할 때가 있습니다. 예를 들어, 태스크가 해당 서비스의 구성을 업데이트하지만, 구성이 변경되지 않은 경우 서비스를 다시 시작하고 싶을 수 있습니다. Ansible은 이 사용 사례를 해결하기 위해 Handler를 사용합니다. Handler는 알림을 받을 때만 실행되는 태스크입니다. 각 Handler는 전 세계적으로 고유한 이름을 가져야 합니다." + +이 단계에서는 5개의 VM을 배포했다고 생각할 수 있습니다(Ansible 컨트롤 역할을 하는 Ubuntu 데스크톱 머신 포함). 다른 시스템은 이 섹션의 나머지 부분에서 다루게 될 것입니다. + +### Playbook 실행 + +이제 Node에 대해 Playbook을 실행할 준비가 되었습니다. Playbook을 실행하려면 `ansible-playbook playbook1.yml`을 사용하면 됩니다. Playbook 내에서 Playbook이 실행될 호스트를 정의했으며, 정의한 Task를 안내합니다. + +명령이 완료되면 Play와 Task를 보여주는 출력이 표시되며, 아래 이미지에서 원하는 상태를 설치하는 데 시간이 걸리는 것을 확인할 수 있습니다. + +![](/2022/Days/Images/Day65_config9.png) + +그런 다음 Node로 이동하여 Node에 소프트웨어가 설치되었는지 확인하여 이를 다시 확인할 수 있습니다. + +![](/2022/Days/Images/Day65_config10.png) + +위와 같이 두 개의 독립형 웹서버를 배포했으므로 이제 정의한 각각의 IP로 이동하여 새 웹 사이트를 가져올 수 있습니다. + +![](/2022/Days/Images/Day65_config11.png) + +이 섹션의 나머지 부분을 진행하면서 이 Playbook을 기반으로 구축할 것입니다. 또한 Ubuntu 데스크톱을 가져와서 Ansible을 사용하여 애플리케이션과 구성을 부트스트랩할 수 있는지 살펴보고 싶어서 이 부분도 다뤄볼 수 있을 것 같습니다. 예를 들어 명령에서 로컬 호스트를 사용하여 로컬 호스트에 대해 Playbook을 실행할 수 있다는 것을 보셨습니다. + +여기에 추가해야 할 또 다른 사항은 우리는 실제로 Ubuntu VM으로만 작업하고 있지만 Ansible은 대상 시스템에 구애받지 않는다는 것입니다. 시스템을 관리하기 위해 이전에 언급했던 대안은 서버별로 서버를 관리할 수 있습니다(서버 수가 많을 경우 확장성이 떨어지고 Node가 3개일 때도 문제가 있음) Linux 섹션에서 다시 다룬 셸 스크립팅을 사용할 수도 있지만 이러한 Node는 잠재적으로 다를 수 있으므로 가능하지만 누군가 스크립트를 유지 및 관리해야 합니다. Ansible은 무료이며 전문화된 스크립트가 필요 없는 대신 간편한 버튼을 누릅니다. + +## 자료 + +- [What is Ansible](https://www.youtube.com/watch?v=1id6ERvfozo) +- [Ansible 101 - Episode 1 - Introduction to Ansible](https://www.youtube.com/watch?v=goclfp6a2IQ) +- [NetworkChuck - You need to learn Ansible right now!](https://www.youtube.com/watch?v=5hycyr-8EKs&t=955s) +- [Your complete guide to Ansible](https://www.youtube.com/playlist?list=PLnFWJCugpwfzTlIJ-JtuATD2MBBD7_m3u) + +위에 나열된 마지막 재생 목록은 이 섹션의 많은 코드와 아이디어가 나온 곳이며, 동영상 형식의 훌륭한 리소스이자 워크스루입니다. + +[Day 66](day66.md)에서 봐요! diff --git a/2022/ko/Days/day66.md b/2022/ko/Days/day66.md new file mode 100644 index 0000000..797916e --- /dev/null +++ b/2022/ko/Days/day66.md @@ -0,0 +1,130 @@ +--- +title: '#90DaysOfDevOps - Ansible Playbooks Continued... - Day 66' +published: false +description: 90DaysOfDevOps - Ansible Playbooks Continued... +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048712 +--- + +## Ansible Playbook (계속) + +지난 섹션에서는 vagrant 파일을 사용하여 4대의 머신을 배포하는 작은 실험실을 만드는 것으로 시작했고, 이 섹션에서 만든 Linux 머신을 Ansible 제어 시스템으로 사용했습니다. + +또한 Playbook의 몇 가지 시나리오를 실행했고 마지막에는 web01과 web02를 개별 웹 서버로 만드는 Playbook을 만들었습니다. + +![](/2022/Days/Images/Day66_config1.png) + +### 깔끔하게 정리하기 + +추가 자동화 및 배포를 시작하기 전에 Playbook을 간결하고 깔끔하게 유지하는 기능과 작업과 Handler를 하위 폴더로 분리하는 방법에 대해 다뤄야 합니다. + +작업을 폴더 내의 해당 파일에 복사하겠습니다. + +```Yaml +- name: ensure apache is at the latest version + apt: name=apache2 state=latest + +- name: write the apache2 ports.conf config file + template: + src=templates/ports.conf.j2 + dest=/etc/apache2/ports.conf + notify: restart apache + +- name: write a basic index.html file + template: + src: templates/index.html.j2 + dest: /var/www/html/index.html + notify: + - restart apache + +- name: ensure apache is running + service: + name: apache2 + state: started +``` + +Handler도 마찬가지입니다. + +```Yaml +- name: restart apache + service: + name: apache2 + state: restarted +``` + +Playbook의 이름을 `playbook2.yml`로 지정한 다음, 이 파일을 가리킵니다. 이 모든 파일은 [ansible-scenario2](/2022/Days/Configmgmt/ansible-scenario2/)에서 찾을 수 있습니다. + +제어 머신에서 테스트할 수 있습니다. 리포지토리에서 파일을 복사한 경우 "write a basic index.html file"에서 변경된 사항을 발견했을 것입니다. + +![](/2022/Days/Images/Day66_config2.png) + +`curl web01:8000`을 사용하여 어떤 간단한 변경이 있었는지 알아봅시다. + +![](/2022/Days/Images/Day66_config3.png) + +방금 Playbook을 정리하고 규모에 따라 Playbook을 매우 압도적으로 만들 수 있는 영역을 분리하기 시작했습니다. + +### Role과 Ansible Galaxy + +현재 4개의 VM을 배포했으며 이 중 2개의 VM을 웹 서버로 구성했지만 데이터베이스 서버와 로드 밸런서 또는 프록시 등 좀 더 구체적인 기능이 있습니다. 이 작업을 수행하고 리포지토리를 정리하기 위해 Ansible 내에서 Role을 사용할 수 있습니다. + +이를 위해 공유 리포지토리에서 Ansible Role을 관리하기 위해 존재하는 `ansible-galaxy` 명령을 사용합니다. + +![](/2022/Days/Images/Day66_config4.png) + +우리는 `ansible-galaxy`를 사용하여 웹서버에 대한 세부 정보를 넣을 apache2의 Role을 생성할 것입니다. + +![](/2022/Days/Images/Day66_config5.png) + +위의 명령 `ansible-galaxy init roles/apache2`는 위에 표시된 폴더 구조를 생성합니다. 다음 단계는 기존 작업과 template을 새 구조의 관련 폴더로 이동하는 것입니다. + +![](/2022/Days/Images/Day66_config6.png) + +복사하여 붙여넣으면 파일을 쉽게 옮길 수 있지만, tasks/main.yml을 변경하여 이 파일이 apache2_install.yml을 가리키도록 해야 합니다. + +또한 새로운 Role을 참조하도록 Playbook을 변경해야 합니다. playbook1.yml과 playbook2.yml에서 작업과 Handler를 두 버전 간에 변경하면서 다른 방식으로 결정합니다. 아래와 같이 이 Role을 사용하도록 Playbook을 변경해야 합니다: + +```Yaml +- hosts: webservers + become: yes + vars: + http_port: 8000 + https_port: 4443 + html_welcome_msg: "Hello 90DaysOfDevOps - Welcome to Day 66!" + roles: + - apache2 +``` + +![](/2022/Days/Images/Day66_config7.png) + +이제 새 Playbook 이름인 `ansible-playbook playbook3.yml`로 Playbook을 다시 실행하면 deprecated가 발생한 것을 확인할 수 있으며, 다음에 수정할 수 있습니다. + +![](/2022/Days/Images/Day66_config8.png) + +Playbook이 실행되었지만, deprecated가 발생했으므로 이제 방법을 수정해야 합니다. 이를 위해 tasks/main.yml의 include 옵션을 아래와 같이 import_tasks로 변경했습니다. + +![](/2022/Days/Images/Day66_config9.png) + +이 파일은 [ansible-scenario3](/2022/Days/Configmgmt/ansible-scenario3)에서 찾을 수 있습니다. + +또한 우리가 만들 `ansible-galaxy`를 사용하면서 몇 가지 Role을 더 만들 것입니다: + +- common = 모든 서버용(`ansible-galaxy init roles/common`) +- nginx = 로드밸런서용(`ansible-galaxy init roles/nginx`) + +![](/2022/Days/Images/Day66_config10.png) + +여기서는 여기까지만 하고 다음 세션에서는 배포했지만, 아직 아무것도 하지 않은 다른 Node에 대한 작업을 시작하겠습니다. + +## 자료 + +- [What is Ansible](https://www.youtube.com/watch?v=1id6ERvfozo) +- [Ansible 101 - Episode 1 - Introduction to Ansible](https://www.youtube.com/watch?v=goclfp6a2IQ) +- [NetworkChuck - You need to learn Ansible right now!](https://www.youtube.com/watch?v=5hycyr-8EKs&t=955s) +- [Your complete guide to Ansible](https://www.youtube.com/playlist?list=PLnFWJCugpwfzTlIJ-JtuATD2MBBD7_m3u) + +위에 나열된 마지막 재생 목록은 이 섹션의 많은 코드와 아이디어가 나온 곳이며, 동영상 형식의 훌륭한 리소스이자 워크스루입니다. + +[Day 67](day67.md)에서 봐요! diff --git a/2022/ko/Days/day67.md b/2022/ko/Days/day67.md new file mode 100644 index 0000000..a1cc13f --- /dev/null +++ b/2022/ko/Days/day67.md @@ -0,0 +1,122 @@ +--- +title: '#90DaysOfDevOps - Using Roles & Deploying a Loadbalancer - Day 67' +published: false +description: '90DaysOfDevOps - Using Roles & Deploying a Loadbalancer' +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048713 +--- + +## Role 사용 및 로드밸런서 배포하기 + +지난 세션에서는 Role에 대해 다루고 `ansible-galaxy` 명령을 사용하여 앞으로 사용할 몇 가지 Role에 대한 폴더 구조를 만들었습니다. 모든 것이 Role 폴더에 숨겨져 있기 때문에 구성 코드의 작업 저장소가 훨씬 더 깔끔해졌습니다. + +하지만 지금까지는 apache2 Role만 사용했고 웹서버를 처리하기 위해 작동하는 playbook3.yaml이 있습니다. + +이 시점에서 `vagrant up web01 web02`만 사용했다면 이제 `vagrant up loadbalancer`를 실행하면 로드 밸런서/프록시로 사용할 다른 Ubuntu 시스템이 나타납니다. + +호스트 파일에 이 새 시스템을 이미 정의했지만, 사용할 수 있을 때까지 ssh 키가 구성되지 않았으므로 시스템이 가동되고 준비되면 `ssh-copy-id loadbalancer`도 실행해야 합니다. + +### Common Role + +어제 세션 마지막에 `common` Role을 만들었는데, Common은 모든 서버에서 사용되는 반면 다른 Role은 사용 사례에 따라 다르지만 이제 설치하려는 애플리케이션은 가짜처럼 일반적이며 이것이 왜 그런지 많은 이유를 알 수는 없지만 그 목적을 보여줍니다. Common Role 폴더 구조에서 작업 폴더로 이동하면 main.yml이 있습니다. 이 YAML에서 이 파일을 install_tools.yml 파일로 가리켜야 하며, `- import_tasks: install_tools.yml` 줄을 추가하여 이를 수행합니다. 이전에는 `include`였으나 곧 사용되지 않을 예정이므로 import_tasks를 사용합니다. + +```Yaml +- name: "Install Common packages" + apt: name={{ item }} state=latest + with_items: + - neofetch + - tree + - figlet +``` + +그런 다음 playbook에서 각 호스트 블록에 대한 Common Role을 추가합니다. + +```Yaml +- hosts: webservers + become: yes + vars: + http_port: 8000 + https_port: 4443 + html_welcome_msg: "Hello 90DaysOfDevOps - Welcome to Day 66!" + roles: + - common + - apache2 +``` + +### Nginx + +다음 단계는 로드밸런서 VM에 nginx를 설치하고 구성하는 것입니다. 일반적인 폴더 구조와 마찬가지로, 마지막 세션을 기반으로 nginx를 구성합니다. + +먼저 playbook에 호스트 블록을 추가하겠습니다. 이 블록에는 Common Role과 새로운 nginx Role이 포함됩니다. + +playbook은 여기에서 찾을 수 있습니다. [playbook4.yml](/2022/Days/Configmgmt/ansible-scenario4/playbook4.yml) + +```Yaml +- hosts: webservers + become: yes + vars: + http_port: 8000 + https_port: 4443 + html_welcome_msg: "Hello 90DaysOfDevOps - Welcome to Day 66!" + roles: + - common + - apache2 + +- hosts: proxy + become: yes + roles: + - common + - nginx +``` + +이것이 의미가 있으려면 실행할 작업을 정의해야 하며, 같은 방식으로 이번에는 설치용 파일과 구성용 파일 두 개를 가리키도록 작업의 main.yml을 수정하겠습니다. + +원하는 결과에 따라 수정한 다른 파일이 몇 개 더 있는데, [ansible-scenario4](/2022/Days/Configmgmt/ansible-scenario4) 폴더에서 변경된 모든 파일을 살펴보세요. nginx 폴더의 작업, Handler 및 template 폴더를 확인하면 추가 변경 사항과 파일을 찾을 수 있습니다. + +### 업데이트된 playbook 실행 + +어제부터 시스템에 일부 패키지를 설치하는 Common Role을 추가한 데 이어 설치 및 구성을 포함하는 nginx Role도 추가했습니다. + +`anible-playbook playbook4.yml`을 사용하여 playbook4.yml을 실행해 보겠습니다. + +![](/2022/Days/Images/Day67_config1.png) + +이제 웹 서버와 로드밸런서가 구성되었으므로 이제 로드밸런서의 IP 주소인 http://192.168.169.134/ 로 이동할 수 있어야 합니다. + +![](/2022/Days/Images/Day67_config2.png) + +이 과정을 따르고 있는데도 이 상태가 나타나지 않는다면 사용 중인 환경의 서버 IP 주소 때문일 수 있습니다. 이 파일은 `templates\mysite.j2`에서 찾을 수 있으며 아래와 유사하게 보입니다: 웹 서버 IP 주소로 업데이트해야 합니다. + +```J2 + upstream webservers { + server 192.168.169.131:8000; + server 192.168.169.132:8000; + } + + server { + listen 80; + + location / { + proxy_pass http://webservers; + } + } +``` + +우리가 설치한 것이 모두 정상이라고 확신하지만, ansible을 사용하여 임시 명령을 사용하여 이러한 일반적인 도구 설치를 확인해 보겠습니다. + +`ansible loadbalancer -m command -a neofetch` + +![](/2022/Days/Images/Day67_config3.png) + +## 자료 + +- [What is Ansible](https://www.youtube.com/watch?v=1id6ERvfozo) +- [Ansible 101 - Episode 1 - Introduction to Ansible](https://www.youtube.com/watch?v=goclfp6a2IQ) +- [NetworkChuck - You need to learn Ansible right now!](https://www.youtube.com/watch?v=5hycyr-8EKs&t=955s) +- [Your complete guide to Ansible](https://www.youtube.com/playlist?list=PLnFWJCugpwfzTlIJ-JtuATD2MBBD7_m3u) + +위에 나열된 마지막 재생 목록은 이 섹션의 많은 코드와 아이디어가 나온 곳이며, 동영상 형식의 훌륭한 리소스이자 워크스루입니다. + +[Day 68](day68.md)에서 봐요! diff --git a/2022/ko/Days/day68.md b/2022/ko/Days/day68.md new file mode 100644 index 0000000..bfba1de --- /dev/null +++ b/2022/ko/Days/day68.md @@ -0,0 +1,353 @@ +--- +title: '#90DaysOfDevOps - Tags, Variables, Inventory & Database Server config - Day 68' +published: false +description: '90DaysOfDevOps - Tags, Variables, Inventory & Database Server config' +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048780 +--- + +## Tag, Variable, Inventory 및 Database 서버 구성 + +### Tag + +어제 세션에 playbook을 남겨두었으므로 모든 작업을 실행하고 해당 playbook 내에서 play해야 합니다. 즉, 웹서버와 로드밸런서 play 및 작업을 모두 실행해야 완료할 수 있습니다. + +하지만 Tag를 사용하면 원하는 경우 이러한 작업을 분리할 수 있습니다. 이는 환경에 매우 크고 긴 playbook이 있는 경우 효율적인 방법이 될 수 있습니다. + +이 경우 playbook 파일에서는 [ansible-scenario5](/2022/Days/Configmgmt/ansible-scenario5/playbook5.yml)를 사용하고 있습니다. + +```Yaml +- hosts: webservers + become: yes + vars: + http_port: 8000 + https_port: 4443 + html_welcome_msg: "Hello 90DaysOfDevOps - Welcome to Day 66!" + roles: + - common + - apache2 + tags: web + +- hosts: proxy + become: yes + roles: + - common + - nginx + tags: proxy +``` + +그런 다음 `ansible-playbook playbook5.yml --list-tags`를 사용하여 이를 확인할 수 있으며, list Tag는 우리가 playbook에서 정의한 Tag의 윤곽을 나타냅니다. + +![](/2022/Days/Images/Day68_config1.png) + +이제 프록시만 타깃팅하려면 `ansible-playbook playbook5.yml --tags proxy`를 실행하면 아래에서 볼 수 있듯이 프록시에 대해서만 playbook을 실행할 수 있습니다. + +![](/2022/Days/Images/Day68_config2.png) + +Tag는 작업 수준에서도 추가할 수 있으므로 원하는 위치와 작업을 세분화할 수 있습니다. 예를 들어 애플리케이션 중심 Tag가 될 수도 있고, 작업을 살펴보고 설치, 구성 또는 제거에 따라 작업에 Tag를 지정할 수도 있습니다. 사용할 수 있는 또 다른 매우 유용한 Tag는 다음과 같습니다. + +`tag: always` 이것은 명령에 어떤 --tags를 사용하든 상관없이 항상 값으로 Tag가 지정된 항목이 있으면 ansible-playbook 명령을 실행할 때 항상 실행되도록 보장합니다. + +Tag를 사용하여 여러 Tag를 함께 묶을 수도 있으며, `ansible-playbook playbook5.yml --tags proxy,web`을 실행하도록 선택하면 해당 Tag가 있는 모든 항목이 실행됩니다. 물론 이 예제에서는 playbook을 실행하는 것과 같은 의미이지만, 다른 play가 여러 개 있는 경우에는 이 방법이 의미가 있을 것입니다. + +둘 이상의 Tag를 정의할 수도 있습니다. + +### Variable + +Ansible에는 크게 두 가지 유형의 Variable이 있습니다. + +- User created +- Ansible Facts + +### Ansible Facts + +playbook을 실행할 때마다 "Gathering facts"라는 정의되지 않은 작업이 있었는데, 이러한 Variable 또는 fact를 사용하여 자동화 작업을 수행할 수 있습니다. + +![](/2022/Days/Images/Day68_config3.png) + +다음 `ansible proxy -m setup` 명령을 실행하면 JSON 형식의 많은 출력을 볼 수 있습니다. 이를 사용하려면 터미널에 많은 정보가 있어야 하므로 `ansible proxy -m setup >> facts.json`을 사용하여 파일로 출력하고 싶습니다. [여기](/2022/Days/Configmgmt/ansible-scenario5/facts.json)에서 이 파일을 볼 수 있습니다. + +![](/2022/Days/Images/Day68_config4.png) + +이 파일을 열면 명령에 대한 모든 종류의 정보를 볼 수 있습니다. IP 주소, 아키텍처, 바이오스 버전을 확인할 수 있습니다. 이 정보를 활용하여 playbook에 사용하려는 경우 유용한 정보가 많이 있습니다. + +한 가지 아이디어는 웹서버의 IP 주소를 하드코딩한 nginx template mysite.j2 내에서 이러한 Variable 중 하나를 잠재적으로 사용하는 것입니다. mysite.j2에 for 루프를 생성하면 [webservers] 그룹을 순환하여 2개 이상의 웹서버를 자동으로 동적으로 생성하거나 이 로드 밸런서 구성에 추가할 수 있습니다. + +``` +#Dynamic Config for server {{ ansible_facts['nodename'] }} + upstream webservers { + {% for host in groups['webservers'] %} + server {{ hostvars[host]['ansible_facts']['nodename'] }}:8000; + {% endfor %} + } + + server { + listen 80; + + location / { + proxy_pass http://webservers; + } + } +``` + +위의 결과는 지금과 동일하게 보이지만 웹 서버를 더 추가하거나 제거하면 프록시 구성이 동적으로 변경됩니다. 이 기능을 사용하려면 이름 확인을 구성해야 합니다. + +### User created + +User created Variable은 우리가 직접 만든 Variable입니다. playbook을 살펴보면 `vars:`가 있고 거기에 3개의 Variable 목록이 있는 것을 볼 수 있습니다. + +```Yaml +- hosts: webservers + become: yes + vars: + http_port: 8000 + https_port: 4443 + html_welcome_msg: "Hello 90DaysOfDevOps - Welcome to Day 68!" + roles: + - common + - apache2 + tags: web + +- hosts: proxy + become: yes + roles: + - common + - nginx + tags: proxy +``` + +그러나 Variable을 해당 파일로 이동하여 playbook에 Variable이 없도록 할 수 있습니다. 이 작업을 수행하되, [ansible-scenario6](/2022/Days/Configmgmt/ansible-scenario6) 폴더로 이동하겠습니다. 해당 폴더의 루트에 group_vars 폴더를 만들겠습니다. 그런 다음 all이라는 또 다른 폴더를 만듭니다(모든 그룹이 이 Variable을 가져옵니다). 이 폴더에 `common_variables.yml`이라는 파일을 만들고 playbook의 Variable을 이 파일에 복사합니다. Variable과 함께 playbook에서 Variable을 제거합니다. + +```Yaml +http_port: 8000 +https_port: 4443 +html_welcome_msg: "Hello 90DaysOfDevOps - Welcome to Day 68!" +``` + +이 Variable을 전역 Variable로 연결하기 때문에 여기에 NTP 및 DNS 서버도 추가할 수 있습니다. Variable은 우리가 만든 폴더 구조에서 설정됩니다. 이제 playbook이 얼마나 깔끔해졌는지 아래에서 확인할 수 있습니다. + +```Yaml +- hosts: webservers + become: yes + roles: + - common + - apache2 + tags: web + +- hosts: proxy + become: yes + roles: + - common + - nginx + tags: proxy +``` + +그 Variable 중 하나는 http_port로, 아래와 같이 mysite.j2 내의 for 루프에서 이 Variable을 다시 사용할 수 있습니다: + +```J2 +#Dynamic Config for server {{ ansible_facts['nodename'] }} + upstream webservers { + {% for host in groups['webservers'] %} + server {{ hostvars[host]['ansible_facts']['nodename'] }}:{{ http_port }}; + {% endfor %} + } + + server { + listen 80; + + location / { + proxy_pass http://webservers; + } + } +``` + +또한, 어떤 웹서버를 사용하고 있는지 파악할 수 있도록 roles/apache2/templates/index.HTML.j2 파일에 분석 가능한 사실을 정의할 수도 있습니다. + +```J2 + + +

{{ html_welcome_msg }}! I'm webserver {{ ansible_facts['nodename'] }}

+ + +``` + +Variable을 변경하여 `ansible-playbook playbook6.yml` 명령을 실행한 결과, 로드밸런서에 도달하면 그룹에 있는 웹서버 중 하나에 도달한 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day68_config5.png) + +또한 host_vars라는 폴더를 추가하고 web01.yml을 생성하여 원하는 경우 특정 메시지를 표시하거나 호스트별로 표시되는 내용을 변경할 수 있습니다. + +### Inventory 파일 + +지금까지 호스트를 결정하기 위해 /etc/ansible 폴더에 있는 기본 호스트 파일을 사용했습니다. 그러나 프로덕션 및 스테이징과 같이 환경마다 다른 파일을 사용할 수 있습니다. 더 많은 환경을 만들지는 않겠습니다. 하지만 호스트 파일은 만들 수 있습니다. + +서버와 노드의 다양한 Inventory에 대해 여러 개의 파일을 만들 수 있습니다. 우리는 `ansible-playbook -i dev playbook.yml`을 사용하여 이를 호출합니다. 호스트 파일 내에 Variable을 정의한 다음 이를 출력하거나 playbook의 다른 곳에서 해당 Variable을 활용할 수도 있습니다. 예를 들어 아래 예제 및 교육 과정에서는 호스트 파일에서 생성된 환경 Variable을 로드밸런서 웹 페이지 template에 추가하여 웹 페이지 메시지의 일부로 환경을 표시했습니다. + +### Database 서버 배포 + +아직 전원을 켜고 구성하지 않은 머신이 하나 더 있습니다. vagrant 파일이 있는 곳에서 `vagrant up db01`을 사용하여 이 작업을 수행할 수 있습니다. 전원이 켜지고 액세스할 수 있게 되면 `ssh-copy-id db01`을 사용하여 SSH 키를 복사하여 액세스할 수 있도록 해야 합니다. + +여기서는 [ansible-scenario7](/2022/Days/Configmgmt/ansible-scenario7) 폴더에서 작업할 것입니다. + +그런 다음 `ansible-galaxy init roles/mysql`을 사용하여 "MySQL"이라는 새 Role에 대한 새 폴더 구조를 만들어 보겠습니다. + +playbook에서 Database 구성을 위한 새로운 play 블록을 추가하겠습니다. /etc/ansible/hosts 파일에 그룹 Database가 정의되어 있습니다. 그런 다음 Database 그룹에 공통 Role과 이전 단계에서 생성한 MySQL이라는 새 Role을 갖도록 지시합니다. 또한 Database 그룹에 Database Tag를 지정하고 있는데, 이는 앞서 설명한 것처럼 원하는 경우 이러한 Tag에 대해서만 실행하도록 선택할 수 있음을 의미합니다. + +```Yaml +- hosts: webservers + become: yes + roles: + - common + - apache2 + tags: + web + +- hosts: proxy + become: yes + roles: + - common + - nginx + tags: + proxy + +- hosts: database + become: yes + roles: + - common + - mysql + tags: database +``` + +이제 Role 폴더 구조 내에서 트리가 자동으로 생성되었으므로 다음을 채워야 합니다: + +Handlers - main.yml + +```Yaml +# handlers file for roles/mysql +- name: restart mysql + service: + name: mysql + state: restarted +``` + +Tasks - install_mysql.yml, main.yml & setup_mysql.yml + +install_mysql.yml - 이 작업은 MySQL을 설치하고 서비스가 실행 중인지 확인하기 위해 수행됩니다. + +```Yaml +- name: "Install Common packages" + apt: name={{ item }} state=latest + with_items: + - python3-pip + - mysql-client + - python3-mysqldb + - libmysqlclient-dev + +- name: Ensure mysql-server is installed latest version + apt: name=mysql-server state=latest + +- name: Installing python module MySQL-python + pip: + name: PyMySQL + +- name: Ensure mysql-server is running + service: + name: mysql + state: started +``` + +main.yml은 이러한 파일에서 작업을 가져오도록 제안하는 포인터 파일입니다. + +```Yaml +# tasks file for roles/mysql +- import_tasks: install_mysql.yml +- import_tasks: setup_mysql.yml +``` + +setup_mysql.yml - 이 작업은 Database와 Database 사용자를 생성합니다. + +```Yaml +- name: Create my.cnf configuration file + template: src=templates/my.cnf.j2 dest=/etc/mysql/conf.d/mysql.cnf + notify: restart mysql + +- name: Create database user with name 'devops' and password 'DevOps90' with all database privileges + community.mysql.mysql_user: + login_unix_socket: /var/run/mysqld/mysqld.sock + login_user: "{{ mysql_user_name }}" + login_password: "{{ mysql_user_password }}" + name: "{{db_user}}" + password: "{{db_pass}}" + priv: '*.*:ALL' + host: '%' + state: present + +- name: Create a new database with name '90daysofdevops' + mysql_db: + login_user: "{{ mysql_user_name }}" + login_password: "{{ mysql_user_password }}" + name: "{{ db_name }}" + state: present +``` + +위에서 비밀번호, 사용자 이름 및 Database와 같은 일부 구성을 결정하기 위해 몇 가지 Variable을 사용하고 있음을 알 수 있으며, 이 Variable은 모두 group_vars/all/common_variables.yml 파일에 저장되어 있습니다. + +```Yaml +http_port: 8000 +https_port: 4443 +html_welcome_msg: "Hello 90DaysOfDevOps - Welcome to Day 68!" + +mysql_user_name: root +mysql_user_password: "vagrant" +db_user: devops +db_pass: DevOps90 +db_name: 90DaysOfDevOps +``` + +또한 template 폴더에 아래와 같은 my.cnf.j2 파일이 있습니다: + +```J2 +[mysql] +bind-address = 0.0.0.0 +``` + +### playbook 실행 + +이제 VM이 실행 중이고 구성 파일이 준비되었으므로 이제 playbook을 실행할 준비가 되었습니다. 다음 `ansible-playbook playbook7.yml`을 실행하면 이전에 수행한 모든 작업이 포함된 playbook을 실행할 수 있고, `ansible-playbook playbook7.yml --tags database` 명령으로 Database 그룹에 배포하여 새 구성 파일만 실행하도록 선택할 수도 있습니다. + +Database Tag에 대해서만 실행했지만, 오류가 발생했습니다. 이 오류는 pip3(파이썬)가 설치되어 있지 않다는 것을 알려줍니다. 이 오류는 일반 작업에 추가하여 해결할 수 있습니다. + +![](/2022/Days/Images/Day68_config6.png) + +위의 문제를 수정하고 playbook을 다시 실행했더니 성공적으로 변경되었습니다. + +![](/2022/Days/Images/Day68_config7.png) + +이제 새로 구성한 db01 서버에서 모든 것이 우리가 원하는 대로 작동하는지 확인해야 합니다. Control Node에서 `ssh db01` 명령을 사용하여 이 작업을 수행할 수 있습니다. + +MySQL에 연결하기 위해 `sudo /usr/bin/mysql -u root -p`를 사용하고 프롬프트에서 root에 대한 vagrant 암호를 제공했습니다. + +연결이 완료되면 먼저 DevOps라는 사용자가 생성되었는지 확인합니다. `select user, host from mysql.user;` + +![](/2022/Days/Images/Day68_config8.png) + +이제 `SHOW DATABASES;` 명령을 실행하여 생성된 새 Database를 확인할 수 있습니다. + +![](/2022/Days/Images/Day68_config9.png) + +루트를 사용하여 연결했지만 이제 `sudo /usr/bin/MySQL -u devops -p`를 사용하여 동일한 방법으로 DevOps 계정으로 로그인할 수도 있지만 여기서 암호는 DevOps90입니다. + +제가 발견한 한 가지는 `setup_mysql.yml`에 `login_unix_socket: /var/run/mysqld/mysqld.sock` 줄을 추가해야 db01 MySQL 인스턴스에 성공적으로 연결할 수 있었고 이제 이 작업을 실행할 때마다 사용자를 만들 때 변경 사항을 보고하므로 어떤 제안이라도 대단히 감사하겠습니다. + +## 자료 + +- [What is Ansible](https://www.youtube.com/watch?v=1id6ERvfozo) +- [Ansible 101 - Episode 1 - Introduction to Ansible](https://www.youtube.com/watch?v=goclfp6a2IQ) +- [NetworkChuck - You need to learn Ansible right now!](https://www.youtube.com/watch?v=5hycyr-8EKs&t=955s) +- [Your complete guide to Ansible](https://www.youtube.com/playlist?list=PLnFWJCugpwfzTlIJ-JtuATD2MBBD7_m3u) + +위에 나열된 마지막 재생 목록은 이 섹션의 많은 코드와 아이디어가 나온 곳이며, 동영상 형식의 훌륭한 리소스이자 워크스루입니다. + +[Day 69](day69.md)에서 봐요! diff --git a/2022/ko/Days/day69.md b/2022/ko/Days/day69.md new file mode 100644 index 0000000..fd197fc --- /dev/null +++ b/2022/ko/Days/day69.md @@ -0,0 +1,143 @@ +--- +title: '#90DaysOfDevOps - All other things Ansible - Automation Controller (Tower), AWX, Vault - Day 69' +published: false +description: '90DaysOfDevOps - All other things Ansible - Automation Controller (Tower), AWX, Vault' +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048714 +--- + +## 기타 모든 Ansible - 자동화 컨트롤러(타워), AWX, Vault + +구성 관리에 대한 섹션을 마무리하면서 Ansible을 다룰 때 접할 수 있는 다른 영역에 대해 살펴보고 싶었습니다. + +Ansible 자동화 플랫폼을 구성하는 많은 제품이 있습니다. + +Red Hat Ansible Automation Platform은 조직 전반에서 자동화를 구축하고 운영하기 위한 기반입니다. 이 플랫폼에는 전사적인 자동화를 구현하는 데 필요한 모든 도구가 포함되어 있습니다. + +![](/2022/Days/Images/Day69_config1.png) + +이 글에서는 이 중 일부를 다루려고 합니다. 하지만 더 자세한 내용은 공식 Red Hat Ansible 사이트에서 더 많은 정보를 확인할 수 있습니다. [Ansible.com](https://www.ansible.com/?hsLang=en-us) + +### Ansible 자동화 컨트롤러 | AWX + +자동화 컨트롤러와 AWX는 제공하는 기능이 매우 유사하기 때문에 이 두 가지를 함께 묶었습니다. + +AWX 프로젝트 또는 줄여서 AWX는 Red Hat이 후원하는 오픈 소스 커뮤니티 프로젝트로, 사용자 환경 내에서 Ansible 프로젝트를 더 잘 제어할 수 있도록 지원합니다. AWX는 자동화 컨트롤러 구성 요소가 파생된 업스트림 프로젝트입니다. + +엔터프라이즈 솔루션을 찾고 계신다면 자동화 컨트롤러를 찾으시거나 이전에 Ansible Tower라고 들어보셨을 것입니다. Ansible 자동화 컨트롤러는 Ansible 자동화 플랫폼의 컨트롤 플레인입니다. + +AWX와 자동화 컨트롤러는 지금까지 이 섹션에서 다룬 다른 모든 기능 위에 다음과 같은 기능을 제공합니다. + +- 사용자 인터페이스 +- 역할 기반 액세스 제어 +- workflow +- CI/CD 통합 + +자동화 컨트롤러는 지원 비용을 지불하는 엔터프라이즈 제품입니다. + +Minikube kubernetes 환경 내에서 AWX를 배포하는 방법을 살펴보겠습니다. + +### Ansible AWX 배포하기 + +AWX를 kubernetes 클러스터에 배포할 필요는 없으며, [github](https://github.com/ansible/awx)에서 AWX에 대한 자세한 내용을 확인할 수 있습니다. 그러나 버전 18.0부터는 AWX 오퍼레이터를 사용하여 AWX를 설치하는 것이 선호됩니다. + +우선 Minikube 클러스터가 필요합니다. kubernetes 섹션에서 `minikube start --cpus=4 --memory=6g --addons=ingress` 명령으로 새 Minikube 클러스터를 생성하는 방법을 따라 했다면 이 작업을 수행할 수 있습니다. + +![](/2022/Days/Images/Day69_config2.png) + +공식 [Ansible AWX 오퍼레이터](https://github.com/ansible/awx-operator)는 여기에서 확인할 수 있습니다. 설치 지침에 명시된 대로 이 리포지토리를 복제한 다음 배포를 실행해야 합니다. + +위의 리포지토리를 folk한 다음 `git clone https://github.com/MichaelCade/awx-operator.git`을 실행했는데, 여러분도 똑같이 하시고 제가 만든 리포지토리는 변경되거나 존재하지 않을 수 있으므로 사용하지 않는 것이 좋습니다. + +복제된 리포지토리에서 아래와 같이 `NodePort`를 `ClusterIP`로 변경해야 하는 awx-demo.yml 파일을 찾을 수 있습니다: + +```Yaml +--- +apiVersion: awx.ansible.com/v1beta1 +kind: AWX +metadata: + name: awx-demo +spec: + service_type: ClusterIP +``` + +다음 단계는 awx 연산자를 배포할 네임스페이스를 정의하는 것으로, `export NAMESPACE=awx` 명령을 사용한 다음 `make deploy`로 배포를 시작합니다. + +![](/2022/Days/Images/Day69_config3.png) + +확인을 통해 새 네임스페이스가 있고 네임스페이스에서 awx-operator-controller pod가 실행되고 있음을 확인합니다. `kubectl get pods -n awx` + +![](/2022/Days/Images/Day69_config4.png) + +복제된 리포지토리 내에서 awx-demo.yml이라는 파일을 찾을 수 있으며, 이제 이 파일을 Kubernetes 클러스터와 awx 네임스페이스에 배포하려고 합니다. `kubectl create -f awx-demo.yml -n awx` + +![](/2022/Days/Images/Day69_config5.png) + +`kubectl get pods -n awx -w`로 진행 상황을 계속 주시할 수 있습니다. + +모든 것이 실행되면 아래와 같은 이미지와 비슷한 것이 보일 것입니다. + +![](/2022/Days/Images/Day69_config6.png) + +이제 새 터미널에서 `minikube service awx-demo-service --url -n $NAMESPACE`를 실행하여 Minikube 인그레스를 통해 이를 노출한 후 awx 배포에 액세스할 수 있어야 합니다. + +![](/2022/Days/Images/Day69_config7.png) + +그런 다음 해당 주소 []로 브라우저를 열면 사용자 이름과 비밀번호를 입력하라는 메시지가 표시되는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day69_config8.png) + +기본적으로 사용자 이름은 admin이며, 비밀번호를 얻으려면 다음 명령어를 실행하여 `kubectl get secret awx-demo-admin-password -o jsonpath="{.data.password}" -n awx| base64 --decode`를 얻을 수 있습니다. + +![](/2022/Days/Images/Day69_config9.png) + +이렇게 하면 중앙 집중화된 위치에서 playbook 및 구성 관리 작업을 관리할 수 있는 UI가 제공되며, 지금까지 하나의 Ansible 제어 스테이션에서 실행하던 것과 달리 팀원들이 함께 작업할 수 있습니다. + +이 영역은 이 도구의 기능을 살펴보는 데 더 많은 시간을 할애할 수 있는 또 다른 영역 중 하나입니다. + +Ansible AWX 사용에 대해 더 자세히 설명하는 Jeff Geerling의 훌륭한 리소스를 소개해 드리겠습니다. [Ansible 101 - 에피소드 10 - Ansible 타워 및 AWX](https://www.youtube.com/watch?v=iKmY4jEiy_A&t=752s) + +이 비디오에서 그는 자동화 컨트롤러(이전 Ansible Tower)와 Ansible AWX(무료 및 오픈 소스)의 차이점에 대해서도 자세히 설명합니다. + +### Ansible Vault + +`ansible-vault`를 사용하면 Ansible 데이터 파일을 암호화하고 해독할 수 있습니다. 이 섹션에서는 일부 민감한 정보를 건너뛰고 일반 텍스트로 표시했습니다. + +Ansible 바이너리에는 이 민감한 정보를 마스킹할 수 있는 `ansible-vault`가 내장되어 있습니다. + +![](/2022/Days/Images/Day69_config10.png) + +비밀 관리는 점차 HashiCorp Vault나 AWS 키 관리 서비스와 같은 도구와 함께 더 많은 시간을 할애해야 하는 또 다른 영역이 되었습니다. 이 부분은 더 자세히 살펴볼 영역으로 표시하겠습니다. + +Jeff Geerling의 훌륭한 리소스와 데모를 다시 한번 링크해드리겠습니다 [Ansible 101 - 에피소드 6 - Ansible Vault와 역할](https://www.youtube.com/watch?v=JFweg2dUvqM). + +### Ansible Galaxy(문서) + +이제 데모 프로젝트의 일부 역할과 파일 구조를 생성하기 위해 이미 `ansible-galaxy`를 사용했습니다. 하지만 [Ansible Galaxy 문서](https://galaxy.ansible.com/docs/)도 있습니다. + +"Galaxy는 Ansible 콘텐츠를 찾고 공유하기 위한 허브입니다." + +### Ansible 테스트 + +- [Ansible Molecule](https://molecule.readthedocs.io/en/latest/) - Molecule 프로젝트는 Ansible 역할의 개발 및 테스트를 지원하도록 설계되었습니다. + +- [Ansible Lint](https://ansible-lint.readthedocs.io/en/latest/) - playbook, 역할 및 컬렉션을 Lint하기 위한 CLI 도구입니다. + +### 기타 리소스 + +- [Ansible 문서](https://docs.ansible.com/ansible/latest/index.html) + +## 자료 + +- [What is Ansible](https://www.youtube.com/watch?v=1id6ERvfozo) +- [Ansible 101 - Episode 1 - Introduction to Ansible](https://www.youtube.com/watch?v=goclfp6a2IQ) +- [NetworkChuck - You need to learn Ansible right now!](https://www.youtube.com/watch?v=5hycyr-8EKs&t=955s) +- [Your complete guide to Ansible](https://www.youtube.com/playlist?list=PLnFWJCugpwfzTlIJ-JtuATD2MBBD7_m3u) + +위에 나열된 마지막 재생 목록은 이 섹션의 많은 코드와 아이디어가 나온 곳이며, 동영상 형식의 훌륭한 리소스이자 연습입니다. + +이 포스팅에서는 구성 관리에 대해 살펴본 내용을 마무리하고, 다음에는 CI/CD 파이프라인과 애플리케이션 개발 및 릴리스에 이러한 workflow를 달성하기 위해 사용할 수 있는 몇 가지 도구 및 프로세스에 대해 살펴봅니다. + +[Day 70](day70.md)에서 봐요! diff --git a/2022/ko/Days/day70.md b/2022/ko/Days/day70.md new file mode 100644 index 0000000..2e16fc3 --- /dev/null +++ b/2022/ko/Days/day70.md @@ -0,0 +1,123 @@ +--- +title: '#90DaysOfDevOps - The Big Picture: CI/CD Pipelines - Day 70' +published: false +description: 90DaysOfDevOps - The Big Picture CI/CD Pipelines +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048836 +--- + +## 큰 그림: CI/CD 파이프라인 + +CI/CD(지속적 통합/지속적 배포) 파이프라인 구현은 최신 DevOps 환경의 중추입니다. + +파이프라인은 애플리케이션의 빌드, 테스트 및 배포를 자동화하여 개발과 운영 간의 격차를 해소합니다. + +챌린지의 첫 번째 섹션에서 이 중요한 요소에 대해 많이 다루었습니다. 하지만 다시 한번 말씀드리자면: + +지속적 통합(CI)은 점진적인 코드 변경을 더 자주 그리고 안정적으로 수행하는 보다 현대적인 소프트웨어 개발 관행입니다. 지속적 통합에 의해 트리거되는 자동화된 빌드 및 테스트 Workflow Step은 리포지토리에 병합되는 코드 변경 사항을 신뢰할 수 있도록 보장합니다. + +그런 다음 해당 코드/애플리케이션은 지속적 배포 프로세스의 일부로 신속하고 원활하게 제공됩니다. + +### CI/CD의 중요성은? + +- 소프트웨어를 빠르고 효율적으로 배포 +- 애플리케이션을 최대한 빠르게 시장에 출시하기 위한 효과적인 프로세스를 촉진합니다. +- 버전 릴리스를 위해 몇 달 또는 몇 년을 기다릴 필요 없이 버그 수정 및 새로운 기능을 지속적으로 제공할 수 있습니다. + +개발자가 영향력 있는 작은 변경을 정기적으로 수행할 수 있으므로 더 빠른 수정과 더 많은 기능을 더 빨리 얻을 수 있습니다. + +### 자, 이게 무슨 뜻인가요? + +[Day 5](day05.md)에서 데브옵스에 대한 많은 이론을 다뤘으며, 이미 여기에서 CI/CD 파이프라인이 최신 데브옵스 환경의 핵심이라고 언급했듯이, 이 파이프라인은 최신 데브옵스 환경의 기본입니다. + +![데브옵스](/2022/Days/Images/Day5_DevOps8.png) + +이제 데브옵스의 기본을 배우는 여정에 조금 더 들어섰으므로 위 이미지의 몇 가지 핵심 사항을 다시 한번 강조하고 싶습니다. + +소프트웨어 개발 수명 주기(SDLC)를 언급하고 있습니다. + +이 주기는 영원히 반복되는 주기이기 때문에 일반적으로 무한 루프 내에 단계가 기록됩니다. + +개발자가 **코드**를 작성하면 **빌드**되거나 모두 컴파일되고, 버그가 있는지 **테스트**되고, 최종 사용자나 고객이 사용하는 프로덕션에 **배포**되고(**운영**), **모니터링** 및 피드백을 수집하고, 마지막으로 해당 피드백을 중심으로 개선 사항을 **계획**하고 반복하는 것이 이 주기의 단계입니다. + +### CI/CD에 대해 좀 더 자세히 알아봅시다. + +### CI + +CI는 개발자가 하루에 여러 번 공유 리포지토리에 코드를 통합해야 하는 개발 관행입니다. + +코드가 작성되어 Github 또는 GitLab과 같은 리포지토리에 push되면 마법이 시작됩니다. + +![](/2022/Days/Images/Day70_CICD1.png) + +자동화된 빌드를 통해 코드가 검증되므로 팀이나 프로젝트 소유자가 문제를 조기에 발견할 수 있습니다. + +![](/2022/Days/Images/Day70_CICD2.png) + +여기에서 코드를 분석하고 일련의 자동화된 테스트를 수행하는데, 세 가지 예는 다음과 같습니다. + +- 단위 테스트는 소스 코드의 개별 단위를 테스트합니다. +- 유효성 검사 테스트는 소프트웨어가 의도된 용도를 충족하거나 적합한지 확인합니다. +- 형식 테스트는 구문 및 기타 형식 지정 오류를 확인합니다. + +이러한 테스트는 workflow로 생성된 다음 마스터 브랜치로 push할 때마다 실행되므로 거의 모든 주요 개발팀에는 일종의 CI/CD workflow가 있으며, 개발팀에서는 하루 종일 전 세계의 여러 팀에서 다양한 프로젝트를 진행하는 개발자로부터 새로운 코드가 들어올 수 있으므로 코드가 승인되기 전에 모든 사람이 같은 페이지에 있는지 확인하는 테스트의 자동화된 workflow를 구축하는 것이 더 효율적입니다. 사람이 매번 이 작업을 수행하려면 훨씬 더 오랜 시간이 걸립니다. + +![](/2022/Days/Images/Day70_CICD3.png) + +테스트가 완료되고 성공하면 컴파일하여 리포지토리로 보낼 수 있습니다. 예를 들어, 저는 DockerHub를 사용하고 있지만 파이프라인의 CD 측면에 활용되는 모든 곳이 될 수 있습니다. + +![](/2022/Days/Images/Day70_CICD4.png) + +따라서 이 프로세스는 소프트웨어 개발 프로세스와 매우 유사하며, 애플리케이션을 만들고, 버그를 추가하고, 수정한 다음 소스 제어를 업데이트하고, 테스트하면서 버전도 관리합니다. + +다음 단계로 넘어가면 CD 요소인데, 일반적으로 상용 소프트웨어에서 볼 수 있는 CD 요소는 점점 더 많아지고 있으며, 오라클이나 Microsoft와 같은 공급업체로부터 소프트웨어를 받으면 DockerHub 유형 리포지토리에서 이를 소비한 다음 CD 파이프라인을 사용하여 환경에 배포하는 추세를 보게 될 것이라고 주장하고 싶습니다. + +### CD + +이제 테스트된 버전의 코드를 배포할 준비가 되었습니다. 소프트웨어 공급업체가 이 단계를 진행하겠지만, 저는 이것이 앞으로 우리 모두가 필요한 상용 소프트웨어를 배포하는 방식이 될 것이라고 굳게 믿습니다. + +이제 코드를 환경에 배포할 차례입니다. 여기에는 프로덕션 환경뿐만 아니라 스테이징과 같은 다른 환경도 포함될 것입니다. + +![](/2022/Days/Images/Day70_CICD5.png) + +소프트웨어 배포 1일차에서 다음 단계는 올바른 코드 베이스를 올바른 환경으로 가져오고 있는지 확인하는 것입니다. 소프트웨어 리포지토리(DockerHub)에서 요소를 가져올 수도 있지만, 다른 코드 리포지토리에서 추가 구성, 예를 들어 애플리케이션에 대한 구성을 가져올 수도 있습니다. 아래 다이어그램에서는 DockerHub에서 소프트웨어의 최신 릴리스를 가져온 다음 이를 환경에 릴리스하는 동시에 Git 리포지토리에서 구성을 가져올 수 있습니다. CD 도구가 이 작업을 수행하여 모든 것을 환경에 push합니다. + +이 작업은 동시에 수행되지 않을 가능성이 높습니다. 즉, 구성이 올바른지 확인하기 위해 스테이징 환경으로 이동하여 이 구성에 대해 실행한 후 테스트를 위한 수동 단계일 수도 있고, 이 코드를 프로덕션에 배포하기 전에 다시 자동화할 수도 있습니다(자동화로 가겠습니다). + +![](/2022/Days/Images/Day70_CICD6.png) + +그런 다음 애플리케이션의 v2가 나오면 이번에는 단계를 반복하여 애플리케이션 + 구성이 스테이징에 배포되어 모든 것이 정상인지 확인한 다음 프로덕션에 배포합니다. + +### CI/CD를 사용하는 이유는 무엇인가요? + +이미 여러 번 이점에 대해 설명했지만, 수동으로 수행해야 하는 작업을 자동화하여 작은 문제가 메인 코드 베이스에 들어가기 전에 발견하기 때문입니다. 고객에게 잘못된 코드를 push하면 큰 문제가 발생할 수 있다는 것을 상상할 수 있을 것입니다! + +또한 메인 코드 리포지토리는 시간이 지남에 따라 지속적으로 구축되기 때문에 첫날에 수행한 지름길 수정이 몇 년 후 기하급수적으로 더 많은 비용이 드는 수정이 될 수 있다는 생각인 기술 부채를 방지하는 데 도움이 됩니다. + +### 도구 + +다른 섹션과 마찬가지로 CI/CD 파이프라인 프로세스를 달성하는 몇 가지 도구에 대해 실습해 보겠습니다. + +모든 도구가 CI와 CD를 모두 수행해야 하는 것은 아니며, 소프트웨어를 Kubernetes 클러스터에 배포하는 데 있어 CD 요소에 능숙한 ArgoCD를 살펴볼 것입니다. 하지만 Jenkins와 같은 것은 다양한 플랫폼에서 작동할 수도 있습니다. + +저는 다음을 살펴볼 계획입니다: + +- Jenkins +- ArgoCD +- GitHub Actions + +## 자료 + +- [Jenkins is the way to build, test, deploy](https://youtu.be/_MXtbjwsz3A) +- [Introduction to Jenkins](https://www.edx.org/course/introduction-to-jenkins) +- [Jenkins.io](https://www.jenkins.io/) +- [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) +- [ArgoCD Tutorial for Beginners](https://www.youtube.com/watch?v=MeU5_k9ssrs) +- [What is Jenkins?](https://www.youtube.com/watch?v=LFDrDnKPOTg) +- [Complete Jenkins Tutorial](https://www.youtube.com/watch?v=nCKxl7Q_20I&t=3s) +- [GitHub Actions](https://www.youtube.com/watch?v=R8_veQiYBjI) +- [GitHub Actions CI/CD](https://www.youtube.com/watch?v=mFFXuXjVgkU) + +[Day 71](day71.md)에서 봐요! diff --git a/2022/ko/Days/day71.md b/2022/ko/Days/day71.md new file mode 100644 index 0000000..a821ca3 --- /dev/null +++ b/2022/ko/Days/day71.md @@ -0,0 +1,105 @@ +--- +title: '#90DaysOfDevOps - What is Jenkins? - Day 71' +published: false +description: 90DaysOfDevOps - What is Jenkins? +tags: 'DevOps, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048745 +--- + +## Jenkins란 무엇인가요? + +Jenkins는 새로 만든 코드를 지속적으로 개발, 테스트 및 배포할 수 있는 지속적 통합 도구입니다. + +야간 빌드 또는 지속적 개발을 통해 이를 달성할 수 있는 방법에는 두 가지가 있습니다. 첫 번째 옵션은 개발자가 하루 종일 작업을 개발하다가 정해진 하루가 끝나면 변경 사항을 소스 코드 저장소에 push하는 것입니다. 그런 다음 밤에는 단위 테스트를 실행하고 소프트웨어를 빌드합니다. 이것이 모든 코드를 통합하는 오래된 방식이라고 할 수 있습니다. + +![](/2022/Days/Images/Day71_CICD1.png) + +다른 옵션이자 선호되는 방식은 개발자가 소스 코드에 변경 사항을 커밋하고 해당 코드 커밋이 완료되면 빌드 프로세스가 지속적으로 시작되는 방식입니다. + +![](/2022/Days/Images/Day71_CICD2.png) + +위의 방법을 사용하면 전 세계에 분산된 개발자가 있는 경우 매일 정해진 시간에 코드 변경 사항 커밋을 중단할 수 없습니다. 이러한 테스트와 빌드 프로세스를 제어하기 위해 CI 서버 역할을 하는 것이 바로 Jenkins입니다. + +![](/2022/Days/Images/Day71_CICD3.png) + +여기서는 Jenkins에 대해 이야기하고 있지만 나중에 몇 가지를 더 추가하여 Jenkins가 전반적으로 가장 인기 있는 것으로 보이는 이유와 그 이유, 그리고 다른 도구가 Jenkins보다 무엇을 할 수 있는지에 대해 알아보고자 합니다. + +- TravisCI - GitHub에서 호스팅되는 소프트웨어 프로젝트를 빌드하고 테스트하는 데 사용되는 호스팅된 분산형 지속적 통합 서비스입니다. +- Bamboo - 빠른 컴파일을 위해 여러 빌드를 병렬로 실행할 수 있으며, 리포지토리와 연결할 수 있는 기능이 내장되어 있고 Ant 및 Maven용 빌드 작업이 있습니다. +- Buildbot - 소프트웨어 빌드, 테스트 및 릴리스 프로세스를 자동화하기 위한 오픈 소스 프레임워크입니다. Python으로 작성되었으며 여러 플랫폼에서 작업의 분산 병렬 실행을 지원합니다. +- Apache Gump - 매일 밤 Java 프로젝트를 빌드하고 테스트하도록 설계된 Java 프로젝트 전용으로, 모든 프로젝트가 API 및 기능 수준 모두에서 호환되도록 보장합니다. + +이제부터는 Jenkins에 초점을 맞추겠습니다. Jenkins는 위의 모든 도구와 마찬가지로 오픈 소스이며 Java로 작성된 자동화 서버입니다. 지속적인 통합을 통해 소프트웨어 개발 프로세스를 자동화하고 지속적인 배포를 용이하게 하는 데 사용됩니다. + +### Jenkins의 특징 + +예상할 수 있듯이 Jenkins는 다양한 영역에 걸쳐 많은 기능을 가지고 있습니다. + +**간편한 설치** - Jenkins는 Windows, macOS 및 Linux 운영 체제용 패키지와 함께 실행할 준비가 된 독립형 자바 기반 프로그램입니다. + +**간편한 구성** - 오류 확인 및 기본 제공 도움말이 포함된 웹 인터페이스를 통해 쉽게 설정 및 구성할 수 있습니다. + +**플러그인** - 업데이트 센터에서 다양한 플러그인을 사용할 수 있으며 CI/CD 툴체인의 여러 도구와 통합됩니다. + +**확장 가능** - 사용 가능한 플러그인 외에도 플러그인 아키텍처를 통해 Jenkins를 확장할 수 있어 거의 무한한 용도로 사용할 수 있는 옵션을 제공합니다. + +**분산** - Jenkins는 여러 머신에 작업을 쉽게 분산하여 여러 플랫폼에서 빌드, 테스트 및 배포 속도를 높일 수 있도록 지원합니다. + +### Jenkins 파이프라인 + +이 파이프라인을 보셨겠지만, 훨씬 광범위하게 사용되며 특정 도구에 대해서는 언급하지 않았습니다. + +Jenkins에 코드를 커밋하면 모든 자동화된 테스트를 통해 애플리케이션을 빌드한 다음 각 단계가 완료되면 해당 코드를 릴리스 및 배포합니다. 이 프로세스를 자동화할 수 있는 것이 바로 Jenkins입니다. + +![](/2022/Days/Images/Day71_CICD4.png) + +### Jenkins 아키텍처 + +먼저, 바퀴를 재발명하고 싶지 않기 때문에 항상 [Jenkins 문서](https://www.jenkins.io/doc/developer/architecture/)에서 시작하는 것이 가장 좋지만, 여기에도 제가 메모하고 배운 내용을 적어 두려고 합니다. + +Jenkins는 윈도우, 리눅스, 맥OS 등 다양한 운영체제에 설치할 수 있을 뿐만 아니라 Docker 컨테이너로 배포하거나 Kubernetes 내에서 배포할 수 있는 기능도 있습니다. [Jenkins 설치하기](https://www.jenkins.io/doc/book/installing/) + +이번 글에서는 Minikube 클러스터 내에 Jenkins를 설치하여 Kubernetes에 배포하는 과정을 시뮬레이션해 보겠습니다. 하지만 이는 이 섹션의 나머지 부분에서 구성한 시나리오에 따라 달라집니다. + +이제 아래 이미지를 분석해 보겠습니다. + +1단계 - 개발자가 소스 코드 리포지토리에 변경 사항을 커밋합니다. + +2단계 - Jenkins가 정기적으로 리포지토리를 확인하여 새 코드를 가져옵니다. + +3단계 - 빌드 서버가 코드를 실행 파일로 빌드하며, 이 예에서는 잘 알려진 빌드 서버로 maven을 사용하고 있습니다. 다루어야 할 또 다른 영역입니다. + +4단계 - 빌드에 실패하면 개발자에게 피드백이 다시 전송됩니다. + +5단계 - 그런 다음 Jenkins는 빌드된 앱을 테스트 서버에 배포합니다. 이 예에서는 잘 알려진 테스트 서버로 selenium을 사용하고 있습니다. 또 다른 영역입니다. + +6단계 - 테스트가 실패하면 개발자에게 피드백이 전달됩니다. + +7단계 - 테스트가 성공하면 프로덕션에 릴리스할 수 있습니다. + +이 주기는 연속적이기 때문에 애플리케이션을 몇 시간, 며칠, 몇 달, 몇 년이 아닌 몇 분 만에 업데이트할 수 있습니다! + +![](/2022/Days/Images/Day71_CICD5.png) + +필요한 경우 master가 slave Jenkins 환경에 작업을 배포할 수 있는 master-slave 기능이 있는 등 Jenkins의 아키텍처에는 훨씬 더 많은 기능이 있습니다. + +참고로 Jenkins는 오픈 소스이므로 지원을 필요로 하는 많은 기업이 있을 것이며, CloudBees는 유료 엔터프라이즈 고객을 위한 지원 및 기타 기능을 제공하는 엔터프라이즈 버전의 Jenkins입니다. + +고객 중 한 예로 Bosch를 들 수 있는데, Bosch 사례 연구는 [여기](https://assets.ctfassets.net/vtn4rfaw6n2j/case-study-boschpdf/40a0b23c61992ed3ee414ae0a55b6777/case-study-bosch.pdf)에서 확인할 수 있습니다. + +내일은 애플리케이션의 단계별 예시를 통해 Jenkins를 사용하는 방법을 살펴본 다음 다른 도구와 함께 사용할 수 있도록 하겠습니다. + +## 자료 + +- [Jenkins is the way to build, test, deploy](https://youtu.be/_MXtbjwsz3A) +- [Jenkins.io](https://www.jenkins.io/) +- [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) +- [ArgoCD Tutorial for Beginners](https://www.youtube.com/watch?v=MeU5_k9ssrs) +- [What is Jenkins?](https://www.youtube.com/watch?v=LFDrDnKPOTg) +- [Complete Jenkins Tutorial](https://www.youtube.com/watch?v=nCKxl7Q_20I&t=3s) +- [GitHub Actions](https://www.youtube.com/watch?v=R8_veQiYBjI) +- [GitHub Actions CI/CD](https://www.youtube.com/watch?v=mFFXuXjVgkU) + +[Day 72](day72.md)에서 봐요!킨 diff --git a/2022/ko/Days/day72.md b/2022/ko/Days/day72.md new file mode 100644 index 0000000..b82d989 --- /dev/null +++ b/2022/ko/Days/day72.md @@ -0,0 +1,162 @@ +--- +title: '#90DaysOfDevOps - Getting hands-on with Jenkins - Day 72' +published: false +description: 90DaysOfDevOps - Getting hands-on with Jenkins +tags: 'DevOps, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048829 +--- + +## Jenkins 실습하기 + +오늘 계획은 Jenkins를 직접 사용해 보고 CI 파이프라인의 일부로 사용할 수 있는 몇 가지 예제 코드 베이스를 살펴보면서 무언가를 만들어 보는 것입니다. + +### 파이프라인이란 무엇인가요? + +시작하기 전에 CI와 관련하여 파이프라인이 무엇인지 알아야 하는데, 어제 세션에서 이미 다음 이미지와 함께 이 내용을 다루었습니다. + +![](/2022/Days/Images/Day71_CICD4.png) + +위의 프로세스 또는 단계를 자동화하여 최종적으로 배포된 애플리케이션을 고객, 최종 사용자 등에게 제공할 수 있는 결과물을 얻고자 합니다. + +이 자동화된 프로세스를 통해 사용자와 고객에 대한 버전 관리를 수행할 수 있습니다. 모든 변경 사항, 기능 향상, 버그 수정 등은 이 자동화된 프로세스를 거쳐 코드가 양호한지 확인하기 위해 많은 수동 개입 없이 모든 것이 정상인지 확인합니다. + +이 프로세스에는 안정적이고 반복 가능한 방식으로 소프트웨어를 빌드하고, 여러 단계의 테스트 및 배포를 통해 빌드된 소프트웨어('build'라고 함)를 발전시키는 작업이 포함됩니다. + +Jenkins 파이프라인은 Jenkins파일이라는 텍스트 파일로 작성됩니다. 이 파일은 소스 제어 리포지토리에 커밋되어야 합니다. 이를 코드형 파이프라인이라고도 하며, 몇 주 전에 다룬 IaC에 매우 유사하게 비유할 수도 있습니다. + +[Jenkins 파이프라인 정의](https://www.jenkins.io/doc/book/pipeline/#ji-toolbar) + +### Jenkins 배포하기 + +Jenkins 배포를 재미있게 해봤는데요, [문서](https://www.jenkins.io/doc/book/installing/)를 보면 Jenkins를 설치할 수 있는 위치에 대한 옵션이 많다는 것을 알 수 있습니다. + +저는 Minikube를 가지고 있고 이를 여러 번 사용했기 때문에 이 작업에도 Minikube를 사용하고 싶었습니다. (또한 무료입니다!) [Kubernetes 설치](https://www.jenkins.io/doc/book/installing/kubernetes/)에 나와 있는 단계는 벽에 부딪혀서 실행하지 못했지만, 여기에 단계를 문서화하면 두 가지를 비교할 수 있습니다. + +첫 번째 단계는 Minikube 클러스터를 시작하고 실행하는 것으로, `minikube start` 명령으로 간단히 할 수 있습니다. + +![](/2022/Days/Images/Day72_CICD1.png) + +여기에서 찾을 수 있는 모든 YAML 구성과 값이 있는 폴더를 [여기](/2022/Days/CICD/Jenkins) 추가했습니다.이제 클러스터가 생겼으므로 다음을 실행하여 jenkins 네임스페이스를 생성할 수 있습니다. `kubectl create -f jenkins-namespace.yml` + +![](/2022/Days/Images/Day72_CICD2.png) + +클러스터에 Jenkins를 배포하기 위해 Helm을 사용할 것이며, Helm은 Kubernetes 섹션에서 다루었습니다. 먼저 jenkinsci Helm 리포지토리 `helm repo add jenkinsci https://charts.jenkins.io`를 추가한 다음 `helm repo update` chart를 업데이트해야 합니다. + +![](/2022/Days/Images/Day72_CICD3.png) + +Jenkins의 기본 개념은 파이프라인의 상태를 저장하는 것으로, 위의 Helm 설치를 지속성 없이 실행할 수 있지만 해당 pod가 재부팅, 변경 또는 수정되면 생성한 파이프라인이나 구성이 손실됩니다. `kubectl apply -f jenkins-volume.yml` 명령으로 jenkins-volume.yml 파일을 사용하여 지속성을 위한 volume을 생성합니다. + +![](/2022/Days/Images/Day72_CICD4.png) + +또한 이 YAML 파일과 명령어를 사용하여 생성할 수 있는 서비스 계정이 필요합니다. `kubectl apply -f jenkins-sa.yml` + +![](/2022/Days/Images/Day72_CICD5.png) +이 단계에서는 Helm chart를 사용하여 배포하는 것이 좋으며, 먼저 `chart=jenkinsci/jenkins`를 사용하여 chart를 정의한 다음, 이 명령을 사용하여 배포할 것이며, 여기에는 이전에 클러스터에 배포한 지속성 및 서비스 계정이 포함된 jenkins-values.yml이 포함됩니다. `helm install jenkins -n jenkins -f jenkins-values.yml $chart` + +![](/2022/Days/Images/Day72_CICD6.png) + +이 단계에서는 pod가 이미지를 가져올 것이지만 pod가 스토리지에 액세스할 수 없으므로 Jenkins를 시작하고 실행하기 위한 구성을 시작할 수 없습니다. + +이 단계에서는 문서가 무슨 일이 일어나야 하는지 이해하는 데 큰 도움이 되지 않았습니다. 하지만 Jenkins 설치를 시작할 수 있는 권한이 없다는 것을 알 수 있습니다. + +![](/2022/Days/Images/Day72_CICD7.png) + +위의 문제를 수정하거나 해결하려면, 우리가 제안한 이 위치에 Jenkins pod가 쓸 수 있도록 액세스 권한 또는 올바른 권한을 제공해야 합니다. 이를 위해 `minikube ssh`를 사용하여 실행 중인 Minikube Docker 컨테이너에 들어간 다음 `sudo chown -R 1000:1000 /data/jenkins-volume`을 사용하여 데이터 volume에 대한 권한이 설정되어 있는지 확인할 수 있습니다. + +![](/2022/Days/Images/Day72_CICD8.png) + +위의 프로세스로 pod가 수정되어야 하지만, 그렇지 않은 경우 `kubectl delete pod jenkins-0 -n jenkins` 명령으로 pod를 강제로 새로 고칠 수 있습니다. 이 시점에서, 2/2의 실행 중인 pod인 jenkins-0이 있어야 합니다. + +![](/2022/Days/Images/Day72_CICD9.png) + +이제 관리자 비밀번호가 필요하며 다음 명령어를 사용하여 비밀번호를 입력할 수 있습니다. `kubectl exec --namespace jenkins -it svc/jenkins -c jenkins -- /bin/cat /run/secrets/chart-admin-password && echo` + +![](/2022/Days/Images/Day72_CICD10.png) + +이제 워크스테이션에서 접근할 수 있도록 `port-forward` 명령을 사용할 것이므로 새 터미널을 엽니다. `kubectl --namespace jenkins port-forward svc/jenkins 8080:8080` + +![](/2022/Days/Images/Day72_CICD11.png) + +이제 브라우저를 열고 `http://localhost:8080`에 로그인하여 이전 단계에서 수집한 username: admin과 password로 인증할 수 있어야 합니다. + +![](/2022/Days/Images/Day72_CICD12.png) + +인증이 완료되면 Jenkins 시작 페이지는 다음과 같이 표시되어야 합니다: + +![](/2022/Days/Images/Day72_CICD13.png) + +여기에서 "Manage Jenkins"로 이동하면 사용 가능한 몇 가지 업데이트가 있는 "Manage Plugins"가 표시됩니다. 해당 플러그인을 모두 선택하고 "Download now and install after restart"를 선택합니다. + +![](/2022/Days/Images/Day72_CICD14.png) + +더 나아가 shell 스크립트를 사용하여 Jenkins 배포를 자동화하고 싶다면 트위터에서 저와 공유한 이 훌륭한 리포지토리를 참고하세요 [mehyedes/nodejs-k8s](https://github.com/mehyedes/nodejs-k8s/blob/main/docs/automated-setup.md). + +### Jenkinsfile + +이제 Kubernetes 클러스터에 Jenkins가 배포되었으므로 이제 돌아가서 이 Jenkinsfile에 대해 생각해 볼 수 있습니다. + +모든 Jenkinsfile은 이렇게 시작될 가능성이 높습니다. 먼저 파이프라인의 단계를 정의하는 곳이며, 이 경우에는 빌드 > 테스트 > 배포가 있습니다. 하지만 여기서는 특정 단계를 호출하기 위해 `echo` 명령을 사용하는 것 외에는 아무것도 하지 않습니다. + +``` +Jenkinsfile (Declarative Pipeline) + +pipeline { + agent any + + stages { + stage('Build') { + steps { + echo 'Building..' + } + } + stage('Test') { + steps { + echo 'Testing..' + } + } + stage('Deploy') { + steps { + echo 'Deploying....' + } + } + } +} + +``` + +Jenkins 대시보드에서 "New Item"을 선택하고 항목에 이름을 지정합니다. 저는 "echo1"이라고 하고 이것이 파이프라인이라고 해보겠습니다. + +![](/2022/Days/Images/Day72_CICD15.png) + +확인을 누르면 파이프라인에만 관심이 있는 간단한 테스트를 위한 탭(일반, 빌드 트리거, 고급 프로젝트 옵션 및 파이프라인)이 표시됩니다. 파이프라인에서 스크립트를 추가할 수 있으며, 위의 스크립트를 복사하여 상자에 붙여 넣을 수 있습니다. + +위에서 말했듯이 이것은 많은 작업을 수행하지는 않지만 빌드 > 테스트 > 배포의 단계를 보여줍니다. + +![](/2022/Days/Images/Day72_CICD16.png) + +저장을 클릭하면 이제 아래에 강조 표시된 "build now"를 사용하여 빌드를 실행할 수 있습니다. + +![](/2022/Days/Images/Day72_CICD17.png) + +또한 터미널을 열고 `kubectl get pods -n jenkins`를 실행하여 어떤 일이 발생하는지 확인해야 합니다. + +![](/2022/Days/Images/Day72_CICD18.png) + +자, 아주 간단하지만 이제 Jenkins 배포와 설치가 올바르게 작동하고 있으며 여기에서 CI 파이프라인의 구성 요소를 볼 수 있습니다. + +다음 섹션에서는 Jenkins 파이프라인을 구축하겠습니다. + +## 자료 + +- [Jenkins is the way to build, test, deploy](https://youtu.be/_MXtbjwsz3A) +- [Jenkins.io](https://www.jenkins.io/) +- [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) +- [ArgoCD Tutorial for Beginners](https://www.youtube.com/watch?v=MeU5_k9ssrs) +- [What is Jenkins?](https://www.youtube.com/watch?v=LFDrDnKPOTg) +- [Complete Jenkins Tutorial](https://www.youtube.com/watch?v=nCKxl7Q_20I&t=3s) +- [GitHub Actions](https://www.youtube.com/watch?v=R8_veQiYBjI) +- [GitHub Actions CI/CD](https://www.youtube.com/watch?v=mFFXuXjVgkU) + +[Day 73](day73.md)에서 봐요! diff --git a/2022/ko/Days/day73.md b/2022/ko/Days/day73.md new file mode 100644 index 0000000..f29851c --- /dev/null +++ b/2022/ko/Days/day73.md @@ -0,0 +1,226 @@ +--- +title: '#90DaysOfDevOps - Building a Jenkins Pipeline - Day 73' +published: false +description: 90DaysOfDevOps - Building a Jenkins Pipeline +tags: 'DevOps, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048766 +--- + +## Jenkins 파이프라인 구축하기 + +지난 섹션에서는 Minikube 클러스터에 Jenkins를 배포하고 파이프라인의 단계를 echo하는 것 외에는 별다른 기능을 하지 않는 매우 기본적인 Jenkins 파이프라인을 설정했습니다. + +또한 Jenkins Pipeline 생성에서 실행할 수 있는 몇 가지 예제 스크립트가 있다는 것을 보셨을 것입니다. + +![](/2022/Days/Images/Day73_CICD1.png) + +첫 번째 데모 스크립트는 "Declarative (Kubernetes)"이며 아래 단계를 볼 수 있습니다. + +```Yaml +// Uses Declarative syntax to run commands inside a container. +pipeline { + agent { + kubernetes { + // Rather than inline YAML, in a multibranch Pipeline you could use: yamlFile 'jenkins-pod.yaml' + // Or, to avoid YAML: + // containerTemplate { + // name 'shell' + // image 'ubuntu' + // command 'sleep' + // args 'infinity' + // } + yaml ''' +apiVersion: v1 +kind: Pod +spec: + containers: + - name: shell + image: ubuntu + command: + - sleep + args: + - infinity +''' + // Can also wrap individual steps: + // container('shell') { + // sh 'hostname' + // } + defaultContainer 'shell' + } + } + stages { + stage('Main') { + steps { + sh 'hostname' + } + } + } +} +``` + +이 파이프라인을 실행하면 어떤 결과가 발생하는지 아래에서 확인할 수 있습니다. + +![](/2022/Days/Images/Day73_CICD2.png) + +### Job 만들기 + +#### 목표 + +- 간단한 앱을 만들어 GitHub 공용 리포지토리에 저장 [https://github.com/scriptcamp/kubernetes-kaniko.git](https://github.com/scriptcamp/kubernetes-kaniko.git) + +- Jenkins를 사용하여 Docker 컨테이너 이미지를 빌드하고 DockerHub에 push합니다. (이를 위해 비공개 리포지토리를 사용합니다.) + +Minikube에서 실행 중이거나 Minikube를 사용하는 Kubernetes 클러스터에서 이 작업을 수행하려면 [Kaniko](https://github.com/GoogleContainerTools/kaniko#running-kaniko-in-a-kubernetes-cluster)라는 것을 사용해야 하지만, 실제 Kubernetes 클러스터에서 Jenkins를 사용하거나 서버에서 실행하는 경우 에이전트를 지정하여 Docker 빌드 명령을 수행하고 이를 DockerHub에 업로드할 수 있는 기능을 제공하는 것이 일반적입니다. + +위의 내용을 염두에 두고 GitHub credentials로 Kubernetes에 시크릿을 배포해 보겠습니다. + +```Shell +kubectl create secret docker-registry dockercred \ + --docker-server=https://index.docker.io/v1/ \ + --docker-username= \ + --docker-password=\ + --docker-email= +``` + +여기서 다룰 내용 대부분을 관통하는 [DevOpsCube.com](https://devopscube.com/build-docker-image-kubernetes-pod/)의 또 다른 훌륭한 리소스를 공유하고자 합니다. + +### Jenkins에 credentials 추가하기 + +하지만 저희와 다른 Jenkins 시스템을 사용 중이라면 Jenkins 내에서 credentials를 정의한 다음 파이프라인 및 구성 내에서 여러 번 사용하고 싶을 것입니다. 생성 시 결정한 ID를 사용하여 파이프라인에서 이러한 credentials를 참조할 수 있습니다. 계속해서 단계를 진행하여 DockerHub 및 GitHub에 대한 사용자 항목을 만들었습니다. + +먼저 "Manage Jenkins"를 선택한 다음 "Manage Credentials"를 선택합니다. + +![](/2022/Days/Images/Day73_CICD3.png) + +페이지 중앙에 Jenkins로 범위가 설정된 Stores가 표시되면 여기에서 Jenkins를 클릭합니다. + +![](/2022/Days/Images/Day73_CICD4.png) + +이제 Global Credentials (Unrestricted)를 선택합니다. + +![](/2022/Days/Images/Day73_CICD5.png) + +그런 다음 왼쪽 상단에 Add Credentials가 있습니다. + +![](/2022/Days/Images/Day73_CICD6.png) + +계정에 대한 세부 정보를 입력한 다음 확인을 선택하고, 이 credentials를 호출할 때 참조할 ID를 기억하세요. 여기서도 비밀번호 대신 특정 토큰 액세스를 사용하는 것이 좋습니다. + +![](/2022/Days/Images/Day73_CICD7.png) + +GitHub의 경우 [Personal Access Token](https://vzilla.co.uk/vzilla-blog/creating-updating-your-github-personal-access-token)을 사용해야 합니다. + +저는 이 계정을 생성하는 과정이 직관적이지 않아서 사용하지는 않지만, UI에서 명확하지 않아서 그 과정을 공유하고 싶었습니다. + +### 파이프라인 구축 + +Kubernetes 클러스터에 비밀로 배포된 DockerHub credentials를 가지고 있으며, 이 credentials를 파이프라인의 DockerHub 단계에 배포하기 위해 호출할 것입니다. + +파이프라인 스크립트는 아래에서 볼 수 있는 것과 같으며, 파이프라인의 프로젝트 가져오기 단계에서도 볼 수 있는 GitHub 리포지토리에 있는 Jenkinsfile이 될 수 있습니다. + +```Yaml +podTemplate(yaml: ''' + apiVersion: v1 + kind: Pod + spec: + containers: + - name: maven + image: maven + command: + - sleep + args: + - 99d + - name: kaniko + image: gcr.io/kaniko-project/executor:debug + command: + - sleep + args: + - 9999999 + volumeMounts: + - name: kaniko-secret + mountPath: /kaniko/.docker + restartPolicy: Never + volumes: + - name: kaniko-secret + secret: + secretName: dockercred + items: + - key: .dockerconfigjson + path: config.json +''') { + node(POD_LABEL) { + stage('Get the project') { + git url: 'https://github.com/scriptcamp/kubernetes-kaniko.git', branch: 'main' + container('maven') { + stage('Test the project') { + sh ''' + echo pwd + ''' + } + } + } + + stage('Build & Test the Docker Image') { + container('kaniko') { + stage('Deploy to DockerHub') { + sh ''' + /kaniko/executor --context `pwd` --destination me1e/helloword + ''' + } + } + } + + } +} +``` + +Jenkins 대시보드에서 항목을 시작하려면 "New Item"을 선택해야 합니다. + +![](/2022/Days/Images/Day73_CICD8.png) + +그런 다음 항목에 이름을 지정하고 파이프라인을 선택한 다음 확인을 누릅니다. + +![](/2022/Days/Images/Day73_CICD9.png) + +일반 트리거나 빌드 트리거는 선택하지 않겠지만 흥미로운 일정과 기타 구성이 있을 수 있으므로 이 트리거를 사용해 보겠습니다. + +![](/2022/Days/Images/Day73_CICD10.png) + +마지막에 있는 Pipeline 탭에만 관심이 있습니다. + +![](/2022/Days/Images/Day73_CICD11.png) + +파이프라인 정의에서 위에 있는 파이프라인 스크립트를 스크립트 섹션에 복사하여 붙여 넣고 저장을 누릅니다. + +![](/2022/Days/Images/Day73_CICD12.png) + +다음으로 페이지 왼쪽에서 "Build Now" 옵션을 선택합니다. + +![](/2022/Days/Images/Day73_CICD13.png) + +이제 1분 미만의 짧은 시간을 기다려야 합니다. Status 아래에 위에서 스크립트에서 정의한 단계가 표시됩니다. + +![](/2022/Days/Images/Day73_CICD14.png) + +더 중요한 것은 이제 DockerHub로 이동하여 새 빌드가 있는지 확인하는 것입니다. + +![](/2022/Days/Images/Day73_CICD15.png) + +전체적으로 파악하는 데 시간이 좀 걸렸지만, Minikube와 GitHub 및 DockerHub에 대한 액세스를 사용하여 누구나 실행할 수 있는 시나리오를 실습하고 작업하기 위해 계속 진행하려고 했습니다. + +이 데모에 사용한 DockerHub 리포지토리는 비공개 리포지토리였습니다. 하지만 다음 섹션에서는 이러한 단계 중 일부를 발전시켜 단순히 `pwd`를 출력하고 몇 가지 테스트 및 빌드 단계를 실행하는 대신 무언가를 수행하도록 하고 싶습니다. + +## 자료 + +- [Jenkins is the way to build, test, deploy](https://youtu.be/_MXtbjwsz3A) +- [Jenkins.io](https://www.jenkins.io/) +- [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) +- [ArgoCD Tutorial for Beginners](https://www.youtube.com/watch?v=MeU5_k9ssrs) +- [What is Jenkins?](https://www.youtube.com/watch?v=LFDrDnKPOTg) +- [Complete Jenkins Tutorial](https://www.youtube.com/watch?v=nCKxl7Q_20I&t=3s) +- [GitHub Actions](https://www.youtube.com/watch?v=R8_veQiYBjI) +- [GitHub Actions CI/CD](https://www.youtube.com/watch?v=mFFXuXjVgkU) + +[Day 74](day74.md)에서 봐요! diff --git a/2022/ko/Days/day74.md b/2022/ko/Days/day74.md new file mode 100644 index 0000000..dcf4168 --- /dev/null +++ b/2022/ko/Days/day74.md @@ -0,0 +1,96 @@ +--- +title: '#90DaysOfDevOps - Hello World - Jenkinsfile App Pipeline - Day 74' +published: false +description: 90DaysOfDevOps - Hello World - Jenkinsfile App Pipeline +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048744 +--- + +## Hello World - Jenkinsfile 앱 파이프라인 + +지난 섹션에서는 공개 GitHub 리포지토리에 있는 dockerfile에서 비공개 Dockerhub 리포지토리로 docker 이미지를 push하는 간단한 Jenkins 파이프라인을 구축했습니다. + +이 섹션에서는 한 단계 더 나아가 간단한 애플리케이션을 통해 다음을 달성하고자 합니다. + +### 목표 + +- Dockerfile (Hello World) +- Jenkinsfile +- GitHub 리포지토리가 업데이트될 때 트리거할 Jenkins 파이프라인 +- GitHub 리포지토리를 소스로 사용 +- Run - 리포지토리 복제/가져오기, 빌드, 테스트, 배포 단계 +- 점진적인 버전 번호로 DockerHub에 배포 +- Kubernetes 클러스터에 배포하는(여기에는 GitHub credentials를 사용하는 다른 job 및 매니페스트 리포지토리가 포함됨) Stretch Goal + +### 1단계 + +[GitHub 리포지토리](https://github.com/MichaelCade/Jenkins-HelloWorld)가 있습니다. 여기에는 현재 Dockerfile과 index.html이 있습니다. + +![](/2022/Days/Images/Day74_CICD1.png) + +위에서 파이프라인에서 소스로 사용하던 것을 이제 해당 Jenkins 파이프라인 스크립트를 GitHub 리포지토리에도 추가하려고 합니다. + +![](/2022/Days/Images/Day74_CICD2.png) + +이제 Jenkins 대시보드로 돌아가서 새 파이프라인을 만들되, 스크립트를 붙여 넣는 대신 "Pipeline script from SCM"를 사용하고 아래의 구성 옵션을 사용하겠습니다. + +참고로 리포지토리 URL은 `https://github.com/MichaelCade/Jenkins-HelloWorld.git`을 사용하겠습니다. + +![](/2022/Days/Images/Day74_CICD3.png) + +이 시점에서 저장 및 적용을 누르면 수동으로 파이프라인을 실행하여 DockerHub 리포지토리에 업로드된 새 Docker 이미지를 빌드할 수 있습니다. + +하지만 리포지토리 또는 소스 코드가 변경될 때마다 빌드를 트리거하도록 일정을 설정하고 싶습니다. webhooks를 사용하거나 예약 pull을 사용할 수 있습니다. + +파이프라인을 유지하기 위해 값비싼 클라우드 리소스를 사용하고 있고 코드 저장소에 변경 사항이 많다면 많은 비용이 발생할 수 있으므로 이 점을 크게 고려해야 합니다. 이것이 데모 환경이라는 것을 알고 있기 때문에 "poll scm" 옵션을 사용하고 있습니다. (또한 Minikube를 사용하면 webhooks를 사용할 수 있는 기능이 부족하다고 생각합니다.) + +![](/2022/Days/Images/Day74_CICD4.png) + +어제 세션 이후 변경한 한 가지는 이제 이미지를 공개 저장소(이 경우 michaelcade1\90DaysOfDevOps)에 업로드하고 싶다는 것인데, 제 Jenkinsfile에는 이미 이 변경 사항이 있습니다. 그리고 이전 섹션에서 기존 데모 컨테이너 이미지를 모두 제거했습니다. + +![](/2022/Days/Images/Day74_CICD5.png) + +여기서 거꾸로 돌아가서 파이프라인을 생성한 다음 이전에 표시된 대로 구성을 추가했습니다. + +![](/2022/Days/Images/Day74_CICD6.png) + +이 단계에서는 파이프라인이 실행되지 않았으며 스테이지 뷰는 다음과 같이 표시됩니다. + +![](/2022/Days/Images/Day74_CICD7.png) + +이제 "Build Now" 버튼을 트리거해 보겠습니다. 그러면 스테이지 뷰에 스테이지가 표시됩니다. + +![](/2022/Days/Images/Day74_CICD8.png) + +이제 DockerHub 리포지토리로 이동하면 2개의 새 Docker 이미지가 있어야 합니다. 빌드 ID는 1이고 최신 빌드가 있어야 하는데, 이는 "Upload to DockerHub"를 기반으로 생성하는 모든 빌드에 대해 Jenkins Build_ID 환경 변수를 사용하여 버전을 전송하고 최신 빌드도 발행하기 때문입니다. + +![](/2022/Days/Images/Day74_CICD9.png) + +이제 아래와 같이 깃허브 리포지토리에 index.html 파일을 업데이트해 보겠습니다. + +![](/2022/Days/Images/Day74_CICD10.png) + +Jenkins로 돌아가서 "Build Now"를 다시 선택하면 됩니다. 2번 빌드가 성공했는지 확인해 보겠습니다. + +![](/2022/Days/Images/Day74_CICD11.png) + +그런 다음 DockerHub를 간단히 살펴보면 태그가 버전 2와 최신 태그가 있는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day74_CICD12.png) + +여기서 한 가지 주목할 점은, 제가 Kubernetes 클러스터에 액세스 및 인증을 통해 DockerHub로 도커 빌드를 push할 수 있는 시크릿을 추가했다는 것입니다. 이 과정을 따라하는 경우 계정에 대해 이 과정을 반복하고 내 리포지토리 및 계정과 연결된 Jenkins파일도 변경해야 합니다. + +## 자료 + +- [Jenkins is the way to build, test, deploy](https://youtu.be/_MXtbjwsz3A) +- [Jenkins.io](https://www.jenkins.io/) +- [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) +- [ArgoCD Tutorial for Beginners](https://www.youtube.com/watch?v=MeU5_k9ssrs) +- [What is Jenkins?](https://www.youtube.com/watch?v=LFDrDnKPOTg) +- [Complete Jenkins Tutorial](https://www.youtube.com/watch?v=nCKxl7Q_20I&t=3s) +- [GitHub Actions](https://www.youtube.com/watch?v=R8_veQiYBjI) +- [GitHub Actions CI/CD](https://www.youtube.com/watch?v=mFFXuXjVgkU) + +[Day 75](day75.md)에서 봐요! diff --git a/2022/ko/Days/day75.md b/2022/ko/Days/day75.md new file mode 100644 index 0000000..ac41675 --- /dev/null +++ b/2022/ko/Days/day75.md @@ -0,0 +1,188 @@ +--- +title: '#90DaysOfDevOps - GitHub Actions Overview - Day 75' +published: false +description: 90DaysOfDevOps - GitHub Actions Overview +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049070 +--- + +## GitHub Actions 개요 + +이 섹션에서는 방금 시간을 할애한 것과는 다른 접근 방식을 살펴보고자 합니다. 이 세션에서 집중적으로 다룰 내용은 GitHub Actions입니다. + +GitHub Actions는 파이프라인의 다른 작업들 사이에서 빌드, 테스트 및 배포할 수 있는 CI/CD 플랫폼입니다. 이 플랫폼은 GitHub 리포지토리를 대상으로 빌드하고 테스트하는 Wolkflow의 개념을 가지고 있습니다. 또한 GitHub Actions를 사용하여 리포지토리 내에서 발생하는 Event를 기반으로 다른 Wolkflow를 구동할 수도 있습니다. + +### Wolkflow + +전반적으로 GitHub Actions에서는 작업을 **Wolkflow**라고 부릅니다. + +- **Wolkflow**는 구성 가능한 자동화된 프로세스입니다. +- YAML 파일로 정의됩니다. +- 하나 이상의 **Job**을 포함하고 실행합니다. +- 리포지토리의 **Event**에 의해 트리거될 때 실행되거나 수동으로 실행할 수 있습니다. +- 리포지토리당 여러 Wolkflow를 사용할 수 있습니다. +- **Wolkflow**에는 **Job**과 해당 **Job**을 달성하기 위한 **Step**이 포함됩니다. +- **Wolkflow** 내에는 **Wolkflow**가 실행되는 **Runner**도 있습니다. + +예를 들어 PR을 빌드하고 테스트하는 **Wolkflow**, 릴리스가 만들어질 때마다 애플리케이션을 배포하는 **Wolkflow**, 누군가 새 issue를 열 때마다 레이블을 추가하는 또 다른 **Wolkflow**가 있을 수 있습니다. + +### Event + +Event는 Wolkflow를 실행하도록 트리거하는 리포지토리의 특정 이벤트입니다. + +### Job + +Job은 Runner에서 실행되는 Wolkflow의 Step 집합입니다. + +### Step + +Job 내의 각 Ste은 실행되는 shell 스크립트 또는 Action이 될 수 있습니다. Step은 순서대로 실행되며 서로 종속됩니다. + +### Action + +자주 반복되는 작업에는 반복 가능한 사용자 지정 애플리케이션이 사용됩니다. + +### Runner + +Runner는 Wolkflow를 실행하는 서버로, 각 Runner는 한 번에 하나의 작업을 실행합니다. GitHub Actions는 Ubuntu Linux, Microsoft Windows 및 macOS Runner를 실행할 수 있는 기능을 제공합니다. 특정 OS 또는 하드웨어에서 직접 호스팅할 수도 있습니다. + +아래에서 Wolkflow를 트리거하는 Event > Wolkflow가 두 개의 Job으로 구성 > 작업 내에 단계와 액션이 있는 모습을 볼 수 있습니다. + +아래에서 Wolkflow를 트리거하는 Event가 있고 > Wolkflow가 두 개의 Job으로 구성되어 있으며 > Job 내에 Step가 있고 > Action이 있는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day75_CICD1.png) + +### YAML + +실제 사용 사례를 살펴보기 전에 위의 이미지를 예제 YAML 파일 형태로 간단히 살펴봅시다. + +주석을 추가하여 YAML Wolkflow의 구성 요소를 찾을 수 있도록 했습니다. + +```Yaml +#Workflow +name: 90DaysOfDevOps +#Event +on: [push] +#Jobs +jobs: + check-bats-version: + #Runner + runs-on: ubuntu-latest + #Steps + steps: + #Actions + - uses: actions/checkout@v2 + - uses: actions/setup-node@v2 + with: + node-version: '14' + - run: npm install -g bats + - run: bats -v +``` + +### GitHub Actions 실습하기 + +코드 빌드, 테스트, 배포 및 그 이후의 지속적인 단계와 관련하여 CI/CD 요구 사항을 충족할 수 있는 GitHub Actions에는 많은 옵션이 있다고 생각합니다. + +GitHub Actions를 사용할 수 있는 많은 옵션과 기타 자동화된 작업을 볼 수 있습니다. + +### 코드 lint에 GitHub 액션 사용하기 + +한 가지 옵션은 리포지토리 내에서 코드를 깨끗하고 깔끔하게 정리하는 것입니다. 이것이 첫 번째 예제 데모가 될 것입니다. + +이 섹션의 리소스 중 하나에 링크된 몇 가지 예제 코드를 사용하여 `GitHub/super-linter`를 사용하여 코드를 확인하겠습니다. + +```Yaml +name: Super-Linter + +on: push + +jobs: + super-lint: + name: Lint code base + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Run Super-Linter + uses: github/super-linter@v3 + env: + DEFAULT_BRANCH: main + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +``` + +**github/super-linter** +위에서 단계 중 하나에 GitHub/super-linter라는 Action이 있으며 이는 커뮤니티에서 이미 작성된 Step을 참조하고 있음을 알 수 있습니다. 이에 대한 자세한 내용은 [Super-Linter](https://github.com/github/super-linter)에서 확인할 수 있습니다. + +"이 리포지토리는 super-linter를 실행하기 위한 Github Actions를 위한 저장소입니다. 소스 코드의 유효성을 검사하는 데 도움이 되도록 bash로 작성된 다양한 linter의 간단한 조합입니다." + +또한 위의 코드 스니펫에 GITHUB_TOKEN이 언급되어 있어서 이것이 왜 필요한지, 어떤 용도로 사용되는지 궁금했습니다. + +"참고: Wolkflow에서 환경 변수 `GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}`을 전달하면 GitHub Super-Linter가 PR의 Checks 섹션에 각 linter 실행 상태를 표시합니다. 이 기능이 없으면 전체 실행의 전체 상태만 볼 수 있습니다. **GitHub Secret은 GitHub에서 자동으로 설정하므로 설정할 필요가 없으며, Action으로 전달하기만 하면 됩니다.**" + +굵은 텍스트는 이 단계에서 주목해야 할 중요한 부분입니다. 우리는 이 기능을 사용하지만, 리포지토리 내에서 환경 변수를 설정할 필요는 없습니다. + +테스트할 리포지토리는 Jenkins 데모에서 사용한 리포지토리를 사용하겠습니다. [Jenkins-HelloWorld](https://github.com/MichaelCade/Jenkins-HelloWorld). + +다음은 Jenkins 세션에 남겨둔 저장소입니다. + +![](/2022/Days/Images/Day75_CICD2.png) + +이 기능을 활용하려면 위의 Actions 탭을 사용하여 곧 다룰 마켓플레이스에서 선택하거나 위의 super-linter 코드를 사용하여 파일을 생성할 수 있는데, 직접 생성하려면 리포지토리에 이 위치에 새 파일을 만들어야 합니다. `.github/workflows/workflow_name`은 분명히 여러분이 알아볼 수 있는 유용한 이름이어야 하며, 여기에는 리포지토리에 대해 다양한 작업과 작업을 수행하는 다양한 Wolkflow가 있을 수 있습니다. + +`.github/workflows/super-linter.yml`을 생성하겠습니다. + +![](/2022/Days/Images/Day75_CICD3.png) + +이제 코드를 붙여 넣고 리포지토리에 코드를 커밋한 다음 Actions 탭으로 이동하면 아래와 같은 super-linter Wolkflow가 표시됩니다. + +![](/2022/Days/Images/Day75_CICD4.png) + +코드에서 리포지토리에 무언가를 push할 때 이 Wolkflow가 실행되도록 정의했기 때문에, super-linter.yml을 리포지토리에 push할 때 Wolkflow가 트리거되었습니다. + +![](/2022/Days/Images/Day75_CICD5.png) + +위에서 보시다시피 해킹 능력과 코딩 능력에 따라 몇 가지 오류가 발생했습니다. + +적어도 아직은 제 코드는 아니었지만, 이 코드를 실행하고 오류가 발생했을 때 이 [문제](https://github.com/github/super-linter/issues/2255)를 발견했습니다. + +2번 super-linter의 버전을 버전 3에서 4로 변경하고 작업을 다시 실행했습니다. + +![](/2022/Days/Images/Day75_CICD6.png) + +예상대로 해커 코딩에서 몇 가지 문제가 발생했으며 여기 [Wolkflow](https://github.com/MichaelCade/Jenkins-HelloWorld/runs/5600278515?check_suite_focus=true)에서 확인할 수 있습니다. + +Wolkflow 내에서 무언가가 실패하거나 오류를 보고했을 때 리포지토리에 표시되는 모습을 지금 보여주고 싶었습니다. + +![](/2022/Days/Images/Day75_CICD7.png) + +이제 제 코드에서 문제를 해결하고 변경 사항을 적용하면 Wolkflow가 다시 실행됩니다(이미지에서 'bugs'를 해결하는 데 시간이 걸린 것을 볼 수 있습니다.) 파일을 삭제하는 것은 권장되지 않지만, 문제가 해결되었음을 보여주는 매우 빠른 방법입니다. + +![](/2022/Days/Images/Day75_CICD8.png) + +위에 강조 표시된 new Wolkflow 버튼을 누르면 수많은 작업의 문이 열립니다. 이번 챌린지를 진행하면서 눈치채셨겠지만, 저희는 거인의 어깨 위에 서서 코드, 자동화 및 기술을 널리 공유하여 삶을 더 편하게 만들고자 하는 것이 아닙니다. + +![](/2022/Days/Images/Day75_CICD9.png) + +Wolkflow가 성공했을 때 리포지토리의 녹색 체크 표시를 보여드리지 못했네요. + +![](/2022/Days/Images/Day75_CICD10.png) + +지금까지는 GitHub Actions의 기본적인 관점에 대해 설명했지만, 저와 같은 분이라면 GitHub Actions를 사용하여 많은 작업을 자동화할 수 있는 다른 방법을 알고 계실 것입니다. + +다음에는 CD의 또 다른 영역인 애플리케이션을 환경에 배포하기 위해 ArgoCD를 살펴볼 것입니다. + +## 자료 + +- [Jenkins is the way to build, test, deploy](https://youtu.be/_MXtbjwsz3A) +- [Jenkins.io](https://www.jenkins.io/) +- [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) +- [ArgoCD Tutorial for Beginners](https://www.youtube.com/watch?v=MeU5_k9ssrs) +- [What is Jenkins?](https://www.youtube.com/watch?v=LFDrDnKPOTg) +- [Complete Jenkins Tutorial](https://www.youtube.com/watch?v=nCKxl7Q_20I&t=3s) +- [GitHub Actions](https://www.youtube.com/watch?v=R8_veQiYBjI) +- [GitHub Actions CI/CD](https://www.youtube.com/watch?v=mFFXuXjVgkU) + +[Day 76](day76.md)에서 봐요! diff --git a/2022/ko/Days/day76.md b/2022/ko/Days/day76.md new file mode 100644 index 0000000..33df75d --- /dev/null +++ b/2022/ko/Days/day76.md @@ -0,0 +1,83 @@ +--- +title: '#90DaysOfDevOps - ArgoCD Overview - Day 76' +published: false +description: 90DaysOfDevOps - ArgoCD Overview +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048809 +--- + +## ArgoCD 개요 + +"Argo CD는 Kubernetes를 위한 선언적 GitOps 지속적 배포 도구입니다." + +버전 제어가 핵심입니다. 환경을 즉석에서 변경했는데 그 변경 사항을 기억하지 못하고 불이 켜져 있고 모든 것이 초록색이기 때문에 계속 진행했던 적이 있으신가요? 변경을 시도했다가 모든 것 또는 일부가 망가진 적이 있나요? 변경한 사실을 알았다면 잘못된 스크립트나 맞춤법 오류를 빠르게 되돌릴 수 있을 것입니다. 하지만 대규모로 변경을 진행하다 보니 본인도 몰랐을 수도 있고, 바로 발견하지 못해 비즈니스가 어려움을 겪고 있을 수도 있습니다. 따라서 버전 관리가 중요합니다. 뿐만 아니라 "애플리케이션 정의, 구성 및 환경은 선언적이어야 하며 버전 관리가 이루어져야 합니다." 이 외에도 "애플리케이션 배포 및 수명 주기 관리는 자동화되고, 감시 가능하며, 이해하기 쉬워야 한다"고 언급합니다. + +운영 배경을 가지고 있지만 IaC로 사용하는 데 많은 경험을 쌓은 저로서는 지속적인 배포/제공 워크플로우를 통해 이 모든 좋은 것들을 처리할 수 있는 다음 단계라고 생각합니다. + +[ArgoCD란](https://argo-cd.readthedocs.io/en/stable/) + +### ArgoCD 배포 + +이번 배포에서는 신뢰할 수 있는 Minikube Kubernetes 클러스터를 다시 로컬로 사용할 것입니다. + +```Shell +kubectl create namespace argocd +kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml +``` + +![](/2022/Days/Images/Day76_CICD1.png) + +`kubectl get pods -n argocd`로 모든 ArgoCD pod가 실행되고 있는지 확인합니다. + +![](/2022/Days/Images/Day76_CICD2.png) + +또한, `kubectl get all -n argocd`로 네임스페이스에 배포한 모든 것을 확인해봅시다. + +![](/2022/Days/Images/Day76_CICD3.png) + +위의 내용이 정상적으로 보이면 포트 포워드를 통해 접근하는 것을 고려해야 합니다. 새 터미널에서 `kubectl port-forward svc/argocd-server -n argocd 8080:443` 명령을 사용합니다. + +그런 다음 새 웹 브라우저를 열고 `https://localhost:8080`로 이동합니다. + +![](/2022/Days/Images/Day76_CICD4.png) + +로그인하려면 관리자 사용자 이름이 필요하며, 생성한 암호를 비밀번호로 사용하려면 `kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d && echo`를 사용합니다. + +![](/2022/Days/Images/Day76_CICD5.png) + +로그인하면 비어있는 CD 캔버스가 표시됩니다. + +![](/2022/Days/Images/Day76_CICD6.png) + +### 애플리케이션 배포 + +이제 ArgoCD를 실행하고 실행 중이므로 이제 Helm뿐만 아니라 Git 리포지토리에서 애플리케이션을 배포하는 데 사용할 수 있습니다. + +제가 배포하고자 하는 애플리케이션은 Pac-Man입니다. 네, Pac-Man은 유명한 게임이자 데이터 관리와 관련하여 많은 데모에서 사용하는 게임이며, 우리가 Pac-Man을 보는 것은 이번이 마지막이 아닐 것입니다. + +[Pac-Man](https://github.com/MichaelCade/pacman-tanzu.git)의 리포지토리는 여기에서 찾을 수 있습니다. + +스크린샷을 사용하여 각 단계를 설명하는 대신, 이 특정 애플리케이션 배포를 위해 수행한 단계를 다루는 연습 동영상을 만드는 것이 더 쉬울 것이라고 생각했습니다. + +[ArgoCD 데모 - 90일간의 개발 운영](https://www.youtube.com/watch?v=w6J413_j0hA) + +참고 - 영상 중 앱 상태가 정상인데도 만족스럽지 않은 서비스가 있는데, 이는 Pac-Man 서비스에 대해 설정된 로드밸런서 유형이 보류 중이고, Minikube에는 로드밸런서가 구성되지 않았기 때문입니다. 이 문제를 테스트하고 싶으시다면 서비스에 대한 YAML을 ClusterIP로 변경하고 포트 포워딩을 사용하여 게임을 플레이할 수 있습니다. + +이것으로 CICD 파이프라인 섹션을 마칩니다. 현재 업계에서 이 영역에 많은 관심이 집중되고 있으며, 일반적으로 CICD 내에서 사용되는 방법론과 관련된 GitOps 관련 용어도 듣게 될 것입니다. + +다음 섹션에서는 새로운 개념은 아니지만 환경을 다르게 바라보면서 점점 더 중요해지고 있는 또 다른 개념 또는 영역인 Observability에 대해 살펴봅니다. + +## 자료 + +- [Jenkins is the way to build, test, deploy](https://youtu.be/_MXtbjwsz3A) +- [Jenkins.io](https://www.jenkins.io/) +- [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) +- [ArgoCD Tutorial for Beginners](https://www.youtube.com/watch?v=MeU5_k9ssrs) +- [What is Jenkins?](https://www.youtube.com/watch?v=LFDrDnKPOTg) +- [Complete Jenkins Tutorial](https://www.youtube.com/watch?v=nCKxl7Q_20I&t=3s) +- [GitHub Actions](https://www.youtube.com/watch?v=R8_veQiYBjI) +- [GitHub Actions CI/CD](https://www.youtube.com/watch?v=mFFXuXjVgkU) + +[Day 77](day77.md)에서 봐요! diff --git a/2022/ko/Days/day77.md b/2022/ko/Days/day77.md new file mode 100644 index 0000000..1f4bfd4 --- /dev/null +++ b/2022/ko/Days/day77.md @@ -0,0 +1,83 @@ +--- +title: '#90DaysOfDevOps - The Big Picture: Monitoring - Day 77' +published: false +description: 90DaysOfDevOps - The Big Picture Monitoring +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048715 +--- + +## 큰 그림: 모니터링 + +이 섹션에서는 모니터링이란 무엇이며 왜 필요한지에 대해 설명합니다. + +### 모니터링이란 무엇인가요? + +모니터링은 전체 인프라를 면밀히 주시하는 프로세스입니다. + +### 모니터링이란 무엇이며 왜 필요한가요?1 + +애플리케이션 서버, 데이터베이스 서버, 웹 서버와 같은 다양한 특수 서버를 포함하여 수천 대의 서버를 관리한다고 가정해 봅시다. 또한 퍼블릭 클라우드 서비스 및 Kubernetes를 비롯한 추가 서비스와 다양한 플랫폼으로 인해 이 문제는 더욱 복잡해질 수 있습니다. + +![](/2022/Days/Images/Day77_Monitoring1.png) + +우리는 서버의 모든 서비스, 애플리케이션, 리소스가 정상적으로 실행되고 있는지 확인할 책임이 있습니다. + +![](/2022/Days/Images/Day77_Monitoring2.png) + +어떻게 하나요? 세 가지 방법이 있습니다: + +- 모든 서버에 수동으로 로그인하여 서비스 프로세스 및 리소스에 대한 모든 데이터를 확인합니다. +- 우리를 대신하여 서버에 로그인하고 데이터를 확인하는 스크립트를 작성합니다. + +이 두 가지 옵션 모두 상당한 양의 작업이 필요합니다, + +세 번째 옵션은 더 쉬운 방법으로, 시중에 나와 있는 모니터링 솔루션을 사용할 수 있습니다. + +Nagios와 Zabbix는 쉽게 사용할 수 있는 솔루션으로, 원하는 만큼 서버를 포함하도록 모니터링 인프라를 확장할 수 있습니다. + +### Nagios + +Nagios는 같은 이름의 회사에서 만든 인프라 모니터링 도구입니다. 이 도구의 오픈 소스 버전은 Nagios core라고 하며 상용 버전은 Nagios XI라고 합니다. [Nagios 웹사이트](https://www.nagios.org/) + +이 도구를 사용하면 서버를 모니터링하고 서버가 충분히 활용되고 있는지 또는 해결해야 할 장애 작업이 있는지 확인할 수 있습니다. + +![](/2022/Days/Images/Day77_Monitoring3.png) + +기본적으로 모니터링을 통해 서버와 서비스의 상태를 확인하고 인프라의 상태를 파악하는 두 가지 목표를 달성할 수 있으며, 전체 인프라에 대한 40,000피트 뷰를 제공하여 서버가 제대로 작동하고 있는지, 애플리케이션이 제대로 작동하는지, 웹 서버에 연결할 수 있는지 여부를 확인할 수 있습니다. + +특정 서버에서 지난 10주 동안 디스크가 10%씩 증가하고 있으며, 향후 4~5일 이내에 완전히 소진될 것이고 곧 응답하지 못할 것임을 알려줍니다. 디스크 또는 서버가 위험한 상태에 있을 때 경고하여 서비스 중단을 피하기 위한 적절한 조치를 취할 수 있도록 알려줍니다. + +이 경우 일부 디스크 공간을 확보하여 서버에 장애가 발생하지 않고 사용자에게 영향을 미치지 않도록 할 수 있습니다. + +대부분의 모니터링 엔지니어에게 어려운 질문은 무엇을 모니터링할 것인가, 또는 무엇을 모니터링하지 않을 것인가입니다. + +모든 시스템에는 여러 리소스가 있는데, 이 중 어떤 리소스를 주시해야 하고 어떤 리소스를 간과할 수 있는지, 예를 들어 CPU 사용량을 모니터링해야 하는지에 대한 대답은 분명히 '예'이지만 그럼에도 불구하고 여전히 결정해야 할 사항은 시스템의 열린 포트 수를 모니터링해야 하는지 여부입니다. 범용 서버인 경우 상황에 따라 필요하지 않을 수도 있지만 웹 서버인 경우 다시 모니터링해야 할 수도 있습니다. + +### 지속적인 모니터링 + +모니터링은 새로운 항목이 아니며 지속적인 모니터링도 많은 기업이 수년 동안 채택해 온 이상입니다. + +모니터링과 관련하여 세 가지 주요 영역에 중점을 둡니다. + +- 인프라 모니터링 +- 애플리케이션 모니터링 +- 네트워크 모니터링 + +이 세션에서 두 가지 일반적인 시스템과 도구에 대해 언급했지만, 사용 가능한 도구는 매우 많다는 점에 유의해야 합니다. 모니터링 솔루션의 진정한 이점은 무엇을 모니터링해야 하고 무엇을 모니터링하지 않아야 하는지에 대한 질문에 답하는 데 시간을 할애했을 때 나타납니다. + +어떤 플랫폼에서든 모니터링 솔루션을 켜면 정보를 수집하기 시작하지만, 그 정보가 너무 많으면 솔루션의 이점을 제대로 활용하기 어렵기 때문에 시간을 들여 구성해야 합니다. + +다음 세션에서는 모니터링 도구를 직접 사용해 보고 무엇을 모니터링할 수 있는지 살펴보겠습니다. + +## 자료 + +- [The Importance of Monitoring in DevOps](https://www.devopsonline.co.uk/the-importance-of-monitoring-in-devops/) +- [Understanding Continuous Monitoring in DevOps?](https://medium.com/devopscurry/understanding-continuous-monitoring-in-devops-f6695b004e3b) +- [DevOps Monitoring Tools](https://www.youtube.com/watch?v=Zu53QQuYqJ0) +- [Top 5 - DevOps Monitoring Tools](https://www.youtube.com/watch?v=4t71iv_9t_4) +- [How Prometheus Monitoring works](https://www.youtube.com/watch?v=h4Sl21AKiDg) +- [Introduction to Prometheus monitoring](https://www.youtube.com/watch?v=5o37CGlNLr8) + +[Day 78](day78.md)에서 봐요! diff --git a/2022/ko/Days/day78.md b/2022/ko/Days/day78.md new file mode 100644 index 0000000..4519376 --- /dev/null +++ b/2022/ko/Days/day78.md @@ -0,0 +1,98 @@ +--- +title: '#90DaysOfDevOps - Hands-On Monitoring Tools - Day 78' +published: false +description: 90DaysOfDevOps - Hands-On Monitoring Tools +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049056 +--- + +## 실습용 모니터링 도구 + +지난 세션에서 모니터링의 큰 그림에 대해 이야기하면서 Nagios를 살펴본 이유는 두 가지였습니다. 첫 번째는 수년 동안 많이 들어본 소프트웨어이기 때문에 그 기능에 대해 조금 더 알고 싶었기 때문입니다. + +오늘은 Prometheus에 대해 살펴보려고 하는데요, 클라우드 네이티브 환경에서 점점 더 많이 사용되고 있지만 Kubernetes 등 외부에서도 이러한 물리적 리소스를 관리하는 데 사용할 수 있습니다. + +### Prometheus - 거의 모든 것을 모니터링합니다. + +우선, Prometheus는 컨테이너와 마이크로서비스 기반 시스템뿐만 아니라 물리적, 가상 및 기타 서비스를 모니터링하는 데 도움이 되는 오픈 소스입니다. Prometheus 뒤에는 대규모 커뮤니티가 있습니다. + +Prometheus에는 다양한 [통합 및 exporter](https://prometheus.io/docs/instrumenting/exporters/)가 있습니다. 핵심은 기존 메트릭을 Prometheus 메트릭으로 내보내는 것입니다. 또한 여러 프로그래밍 언어도 지원합니다. + +pull 접근 방식 - 수천 개의 마이크로서비스 또는 시스템 및 서비스와 대화하는 경우 push 방식은 일반적으로 서비스가 모니터링 시스템으로 push되는 것을 볼 수 있는 곳입니다. 이 경우 네트워크 과부하, 높은 CPU 사용량, 단일 장애 지점 등의 문제가 발생합니다. pull 방식은 모든 서비스의 메트릭 엔드포인트에서 Prometheus가 끌어오는 훨씬 더 나은 경험을 제공합니다. + +다시 한번 Prometheus의 구성을 위한 YAML을 살펴봅니다. + +![](/2022/Days/Images/Day78_Monitoring7.png) + +나중에 이것이 Kubernetes에 배포되었을 때 어떻게 보이는지, 특히 작업/exporter로부터 메트릭을 가져오는 **PushGateway**가 있는 것을 보게 될 것입니다. + +알림을 push하는 **AlertManager**가 있으며, 여기에서 이메일, 슬랙 및 기타 도구와 같은 외부 서비스와 통합할 수 있습니다. + +그런 다음 PushGateway에서 이러한 pull 메트릭의 검색을 관리하고 push 알림을 AlertManager로 전송하는 Prometheus Server가 있습니다. Prometheus Server는 또한 로컬 디스크에 데이터를 저장합니다. 원격 스토리지 솔루션을 활용할 수도 있습니다. + +또한 메트릭과 상호 작용하는 데 사용되는 언어인 PromQL도 있는데, 이는 나중에 Prometheus 웹 UI에서 볼 수 있지만, 이 섹션의 뒷부분에서 Grafana와 같은 데이터 시각화 도구에서도 어떻게 사용되는지 볼 수 있습니다. + +### Prometheus 배포 방법 + +Prometheus 설치 방법은 [다운로드 섹션](https://prometheus.io/download/) 도커 이미지에서도 다양하게 확인할 수 있습니다. + +`docker run --name prometheus -d -p 127.0.0.1:9090:9090 prom/prometheus` + +하지만 여기서는 Kubernetes에 배포하는 데 집중하겠습니다. 여기에도 몇 가지 옵션이 있습니다. + +- 구성 YAML 파일 생성 +- 오퍼레이터 사용(모든 Prometheus 구성 요소의 관리자) +- Helm 차트를 사용하여 오퍼레이터 배포 + +### Kubernetes에 배포하기 + +이 빠르고 간단한 설치를 위해 다시 로컬에서 Minikube 클러스터를 사용하겠습니다. Minikube와의 이전 접점과 마찬가지로, Helm을 사용하여 Prometheus Helm 차트를 배포할 것입니다. + +`helm repo add prometheus-community https://prometheus-community.github.io/helm-charts` + +![](/2022/Days/Images/Day78_Monitoring1.png) + +위에서 볼 수 있듯이 Helm 리포지토리 업데이트도 실행했으므로, 이제 `helm install stable prometheus-community/prometheus` 명령을 사용하여 Minikube 환경에 Prometheus를 배포할 준비가 되었습니다. + +![](/2022/Days/Images/Day78_Monitoring2.png) + +몇 분 후, 몇 개의 새로운 pod가 나타나는데, 이 데모에서는 기본 네임스페이스에 배포했으며, 일반적으로는 이 pod를 해당 네임스페이스에 push합니다. + +![](/2022/Days/Images/Day78_Monitoring3.png) + +모든 pod가 실행되고 나면 Prometheus의 배포된 모든 측면도 살펴볼 수 있습니다. + +![](/2022/Days/Images/Day78_Monitoring4.png) + +이제 Prometheus Server UI에 액세스하기 위해 다음 명령어를 사용하여 포팅 포워드할 수 있습니다. + +```Shell +export POD_NAME=$(kubectl get pods --namespace default -l "app=prometheus,component=server" -o jsonpath="{.items[0].metadata.name}") + kubectl --namespace default port-forward $POD_NAME 9090 +``` + +브라우저를 `http://localhost:9090`으로 처음 열면 다음과 같이 빈 화면이 표시됩니다. + +![](/2022/Days/Images/Day78_Monitoring5.png) + +Kubernetes 클러스터에 배포했기 때문에 Kubernetes API에서 자동으로 메트릭을 가져올 것이므로 일부 PromQL을 사용하여 최소한 `container_cpu_usage_seconds_total` 메트릭을 캡처하고 있는지 확인할 수 있습니다. + +![](/2022/Days/Images/Day78_Monitoring6.png) + +앞서 말씀드린 것처럼 메트릭을 확보하는 것도 좋지만 모니터링도 중요하지만, 모니터링 대상과 그 이유, 모니터링하지 않는 대상과 그 이유를 알아야 한다는 점에서 PromQL을 배우고 이를 실제로 적용하는 것은 매우 중요합니다! + +다시 Prometheus로 돌아오고 싶지만, 지금은 로그 관리와 데이터 시각화에 대해 생각해 보고 나중에 다시 Prometheus로 돌아올 수 있도록 해야 할 것 같습니다. + +## 자료 + +- [The Importance of Monitoring in DevOps](https://www.devopsonline.co.uk/the-importance-of-monitoring-in-devops/) +- [Understanding Continuous Monitoring in DevOps?](https://medium.com/devopscurry/understanding-continuous-monitoring-in-devops-f6695b004e3b) +- [DevOps Monitoring Tools](https://www.youtube.com/watch?v=Zu53QQuYqJ0) +- [Top 5 - DevOps Monitoring Tools](https://www.youtube.com/watch?v=4t71iv_9t_4) +- [How Prometheus Monitoring works](https://www.youtube.com/watch?v=h4Sl21AKiDg) +- [Introduction to Prometheus monitoring](https://www.youtube.com/watch?v=5o37CGlNLr8) +- [Promql cheat sheet with examples](https://www.containiq.com/post/promql-cheat-sheet-with-examples) + +[Day 79](day79.md)에서 봐요! diff --git a/2022/ko/Days/day79.md b/2022/ko/Days/day79.md new file mode 100644 index 0000000..8bc2fca --- /dev/null +++ b/2022/ko/Days/day79.md @@ -0,0 +1,81 @@ +--- +title: '#90DaysOfDevOps - The Big Picture: Log Management - Day 79' +published: false +description: 90DaysOfDevOps - The Big Picture Log Management +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049057 +--- + +## 큰 그림: 로그 관리 + +인프라 모니터링 과제와 솔루션의 연속선상에 있는 로그 관리는 전체 통합 가시성 퍼즐의 또 다른 퍼즐 조각입니다. + +### 로그 관리 및 집계 + +두 가지 핵심 개념에 대해 이야기해 보겠습니다. 첫 번째는 로그 집계로, 다양한 서비스에서 애플리케이션 로그를 수집하고 태그를 지정하여 쉽게 검색할 수 있는 단일 대시보드에 저장하는 방법입니다. + +애플리케이션 성능 관리 시스템에서 가장 먼저 구축해야 하는 시스템 중 하나는 로그 집계입니다. 애플리케이션 성능 관리는 애플리케이션이 빌드 및 배포된 후에도 지속적으로 작동하는지 확인하여 리소스가 충분히 할당되고 사용자에게 오류가 표시되지 않도록 해야 하는 데브옵스 라이프사이클의 일부입니다. 대부분의 프로덕션 배포에서 많은 관련 이벤트가 Google의 여러 서비스에서 로그를 생성합니다. 하나의 검색이 사용자에게 반환되기 전에 10개의 다른 서비스에 도달할 수 있으며, 10개의 서비스 중 하나에 논리 문제가 있을 수 있는 예기치 않은 검색 결과가 표시되는 경우 로그 집계는 Google과 같은 회사가 프로덕션에서 문제를 진단하는 데 도움이 되며, 모든 요청을 고유 ID에 매핑할 수 있는 단일 대시보드를 구축하여 검색하면 검색에 고유 ID가 부여되고 검색이 다른 서비스를 통과할 때마다 해당 서비스가 현재 수행 중인 작업과 해당 ID가 연결되도록 합니다. + +이것이 바로 로그를 생성하는 모든 곳에서 로그를 효율적으로 수집하고 장애가 다시 발생할 경우 쉽게 검색할 수 있도록 하는 좋은 로그 수집 플랫폼의 핵심입니다. + +### 예제 앱 + +예제 애플리케이션은 웹 앱으로, 일반적인 프론트엔드와 백엔드가 중요한 데이터를 MongoDB 데이터베이스에 저장하고 있습니다. + +사용자가 페이지가 모두 하얗게 변하고 오류 메시지가 인쇄되었다고 말하면 현재 스택의 문제를 진단하기 위해 사용자가 수동으로 오류를 보내야 하고 다른 세 가지 서비스의 관련 로그와 일치시켜야 합니다. + +### Elk + +예제 앱과 동일한 환경에 설치한 경우 세 가지 구성 요소인 Elasticsearch, Logstash, Kibana의 이름을 딴 인기 있는 오픈 소스 로그 집계 스택인 Elk에 대해 살펴보겠습니다. + +웹 애플리케이션은 프론트엔드에 연결되고, 프론트엔드는 백엔드에 연결되며, 백엔드는 Logstash로 로그를 전송하고, 이 세 가지 구성 요소가 작동하는 방식은 다음과 같습니다. + +### Elk의 구성 요소 + +Elasticsearch, Logstash, Kibana의 구성 요소는 모든 서비스가 Logstash로 로그를 전송하고, Logstash는 애플리케이션이 방출하는 텍스트인 이 로그를 가져온다는 것입니다. 예를 들어, 웹 애플리케이션에서 사용자가 웹 페이지를 방문할 때 웹 페이지는 이 방문자가 현재 이 페이지에 액세스한 것을 기록할 수 있으며, 이것이 로그 메시지의 예입니다. + +그러면 Logstash는 이 로그 메시지에서 사용자가 **시간**에 **무엇**을 했다는 내용을 추출합니다. 시간을 추출하고 메시지를 추출하고 사용자를 추출하고 그것들을 모두 태그로 포함시켜서 메시지가 태그와 메시지의 객체가 되어 특정 사용자의 모든 요청을 쉽게 검색할 수 있도록 하지만 Logstash는 자체적으로 저장하는 것이 아니라 텍스트 쿼리를 위한 효율적인 데이터베이스인 Elasticsearch에 저장하고 Elasticsearch는 Kibana로 결과를 노출하고 Kibana는 Elasticsearch에 연결하는 웹 서버로서 개발자나 팀의 다른 사람들이 관리자를 허용합니다, 대기 중인 엔지니어가 주요 장애가 발생할 때마다 프로덕션에서 로그를 볼 수 있습니다. 관리자는 Kibana에 연결하고, Kibana는 사용자가 원하는 것과 일치하는 로그를 찾기 위해 Elasticsearch를 쿼리합니다. + +검색 창에 "오류를 찾고 싶어요"라고 말하면, Kibana는 문자열 오류가 포함된 메시지를 찾으라고 말하고, 그러면 Elasticsearch는 Logstash가 채운 결과를 반환합니다. Logstash는 다른 모든 서비스에서 이러한 결과를 전송받았을 것입니다. + +### Elk를 사용해 프로덕션 문제를 진단하는 방법 + +한 사용자가 Elk 설정으로 이 작업을 수행하려고 할 때 오류 코드 1234567을 보았다고 말합니다. 검색 창에 1234567을 입력하고 엔터를 누르면 그에 해당하는 로그가 표시되고 로그 중 하나에서 내부 서버 오류가 1234567을 반환한다고 표시될 수 있으며, 그 로그를 생성한 서비스가 로그를 생성한 서비스가 백엔드임을 알 수 있고, 해당 로그가 생성된 시간을 확인할 수 있으므로 해당 로그의 시간으로 이동하여 백엔드에서 그 위와 아래의 메시지를 보면 사용자의 요청에 대해 어떤 일이 발생했는지 더 잘 파악할 수 있으며, 이 과정을 다른 서비스에서도 반복하여 사용자에게 문제가 발생한 원인을 찾을 때까지 반복할 수 있습니다. + +### 보안 및 로그 액세스 + +퍼즐의 중요한 조각은 로그가 관리자(또는 액세스 권한이 필요한 사용자 및 그룹)에게만 표시되도록 하는 것입니다. 로그에는 인증된 사용자만 액세스해야 하는 토큰과 같은 민감한 정보가 포함될 수 있으며, 인증 방법 없이 Kibana를 인터넷에 노출하고 싶지 않을 것입니다. + +### 로그 관리 도구의 예 + +로그 관리 플랫폼의 예는 다음과 같습니다. + +- Elasticsearch +- Logstash +- Kibana +- Fluentd - 인기 있는 오픈 소스 선택 +- Datadog - 대기업에서 일반적으로 사용되는 호스팅 제품, +- LogDNA - 호스트형 제품 +- Splunk + +클라우드 제공업체는 AWS CloudWatch Logs, Microsoft Azure Monitor, Google Cloud Logging과 같은 로깅도 제공합니다. + +로그 관리는 프로덕션 환경의 문제를 진단하기 위한 애플리케이션 및 인프라 환경의 전반적인 통합 가시성의 핵심 요소입니다. Elk 또는 CloudWatch와 같은 즌비된 솔루션을 설치하는 것은 비교적 간단하며 프로덕션 환경의 문제를 진단하고 분류하는 것이 훨씬 쉬워집니다. + +## 자료 + +- [The Importance of Monitoring in DevOps](https://www.devopsonline.co.uk/the-importance-of-monitoring-in-devops/) +- [Understanding Continuous Monitoring in DevOps?](https://medium.com/devopscurry/understanding-continuous-monitoring-in-devops-f6695b004e3b) +- [DevOps Monitoring Tools](https://www.youtube.com/watch?v=Zu53QQuYqJ0) +- [Top 5 - DevOps Monitoring Tools](https://www.youtube.com/watch?v=4t71iv_9t_4) +- [How Prometheus Monitoring works](https://www.youtube.com/watch?v=h4Sl21AKiDg) +- [Introduction to Prometheus monitoring](https://www.youtube.com/watch?v=5o37CGlNLr8) +- [Promql cheat sheet with examples](https://www.containiq.com/post/promql-cheat-sheet-with-examples) +- [Log Management for DevOps | Manage application, server, and cloud logs with Site24x7](https://www.youtube.com/watch?v=J0csO_Shsj0) +- [Log Management what DevOps need to know](https://devops.com/log-management-what-devops-teams-need-to-know/) +- [What is Elk Stack?](https://www.youtube.com/watch?v=4X0WLg05ASw) +- [Fluentd simply explained](https://www.youtube.com/watch?v=5ofsNyHZwWE&t=14s) + +[Day 80](day80.md)에서 봐요! diff --git a/2022/ko/Days/day80.md b/2022/ko/Days/day80.md new file mode 100644 index 0000000..8495a8c --- /dev/null +++ b/2022/ko/Days/day80.md @@ -0,0 +1,106 @@ +--- +title: '#90DaysOfDevOps - ELK Stack - Day 80' +published: false +description: 90DaysOfDevOps - ELK Stack +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048746 +--- + +## ELK 스택 + +이 세션에서는 앞서 언급한 몇 가지 옵션에 대해 조금 더 실습해 보겠습니다. + +ELK Stack은 세 가지 개별 도구의 조합입니다: + +- [Elasticsearch](https://www.elastic.co/what-is/elasticsearch)는 텍스트, 숫자, 위치 기반 정보, 정형, 비정형 등 모든 유형의 데이터를 위한 분산형 무료 개방형 검색 및 분석 엔진입니다. + +- [Logstash](https://www.elastic.co/logstash/)는 다양한 소스에서 데이터를 수집하고 변환한 다음 원하는 "stash(저장소)"로 전송하는 무료 개방형 서버 측 데이터 처리 파이프라인입니다. + +- [Kibana](https://www.elastic.co/kibana/)는 무료 개방형 사용자 인터페이스로, Elasticsearch 데이터를 시각화하고 Elastic Stack을 탐색할 수 있게 해줍니다. 쿼리 로드 추적부터 앱에서 요청이 흐르는 방식 이해까지 무엇이든 할 수 있습니다. + +ELK 스택을 사용하면 모든 소스에서 모든 형식의 데이터를 안정적이고 안전하게 가져온 다음 실시간으로 검색, 분석 및 시각화할 수 있습니다. + +위에서 언급한 구성 요소 외에도 스택으로 전달하기 위해 다양한 유형의 데이터를 수집하기 위해 엣지 호스트에 설치되는 경량 에이전트인 Beats도 볼 수 있습니다. + +- Log: 분석해야 하는 서버 로그가 식별됩니다. + +- Logstash: 로그와 이벤트 데이터를 수집합니다. 심지어 데이터를 구문 분석하고 변환합니다. + +- ElasticSearch: Logstash에서 변환된 데이터는 저장, 검색 및 색인됩니다. + +- Kibana는 Elasticsearch DB를 사용해 탐색, 시각화, 공유합니다. + +![](/2022/Days/Images/Day80_Monitoring8.png) + +[Guru99에서 가져온 사진](https://www.guru99.com/elk-stack-tutorial.html) + +이를 설명하는 좋은 리소스는 [ELK 스택에 대한 완전한 가이드](https://logz.io/learn/complete-guide-elk-stack/)입니다. + +Beats가 추가되면서 ELK Stack은 이제 Elastic Stack이라고도 불립니다. + +실습 시나리오에서는 Elastic Stack을 배포할 수 있는 많은 위치가 있지만, 여기서는 시스템에 로컬로 배포하기 위해 docker-compose를 사용하겠습니다. + +[Docker Compose로 Elastic Stack 시작하기](https://www.elastic.co/guide/en/elastic-stack-get-started/current/get-started-stack-docker.html#get-started-docker-tls) + +![](/2022/Days/Images/Day80_Monitoring1.png) + +여기에서 제가 사용한 원본 파일과 연습을 찾을 수 있습니다. [deviantony/docker-elk](https://github.com/deviantony/docker-elk) + +이제 `docker-compose up -d`를 실행할 수 있는데, 처음 실행할 때는 이미지를 가져와야 합니다. + +![](/2022/Days/Images/Day80_Monitoring2.png) + +이 리포지토리 또는 제가 사용한 리포지토리를 팔로우하면 "changeme"의 비밀번호를 갖게 되거나 제 리포지토리에서 "90DaysOfDevOps"의 비밀번호를 갖게 됩니다. 사용자 이름은 "elastic"입니다. + +몇 분 후, Kibana server / Docker 컨테이너인 `http://localhost:5601/`로 이동할 수 있습니다. + +![](/2022/Days/Images/Day80_Monitoring3.png) + +초기 홈 화면은 다음과 같이 표시될 것입니다. + +![](/2022/Days/Images/Day80_Monitoring4.png) + +"Get started by adding integrations"라는 제목의 섹션 아래에 "Try sample data"가 있으며, 이를 클릭하면 아래 표시된 것 중 하나를 추가할 수 있습니다. + +![](/2022/Days/Images/Day80_Monitoring5.png) + +저는 "Sample web logs"를 선택하려고 하는데, 이것은 실제로 ELK 스택에 어떤 데이터 세트를 가져올 수 있는지 살펴보기 위한 것입니다. + +"Add Data"를 선택하면 일부 데이터를 채우는 데 시간이 걸리고 "View Data" 옵션과 드롭다운에 해당 데이터를 볼 수 있는 사용 가능한 방법의 목록이 표시됩니다. + +![](/2022/Days/Images/Day80_Monitoring6.png) + +대시보드 보기에 명시된 대로: + +**샘플 로그 데이터** + +> 이 대시보드에는 사용해 볼 수 있는 샘플 데이터가 포함되어 있습니다. 이 데이터를 보고, 검색하고, 시각화와 상호 작용할 수 있습니다. Kibana에 대한 자세한 내용은 문서를 참조하세요. + +![](/2022/Days/Images/Day80_Monitoring7.png) + +이것은 Kibana를 사용하여 Logstash를 통해 ElasticSearch에 추가된 데이터를 시각화하는 것입니다. 이것이 유일한 옵션은 아니지만, 저는 이것을 배포하고 살펴보고 싶었습니다. + +언젠가는 Grafana에 대해서도 다룰 예정이며, 이 둘 사이의 데이터 시각화 유사점을 보게 될 것이고, Prometheus도 보셨을 것입니다. + +제가 Elastic Stack과 Prometheus + Grafana를 비교하면서 느낀 핵심은 Elastic Stack 또는 ELK Stack은 로그에 초점을 맞추고 있고 Prometheus는 메트릭에 초점을 맞추고 있다는 것입니다. + +저는 서로 다른 제품에 대해 더 잘 이해하기 위해 MetricFire의 이 기사 [Prometheus vs. ELK](https://www.metricfire.com/blog/prometheus-vs-elk/)를 읽었습니다. + +## 자료 + +- [Understanding Logging: Containers & Microservices](https://www.youtube.com/watch?v=MMVdkzeQ848) +- [The Importance of Monitoring in DevOps](https://www.devopsonline.co.uk/the-importance-of-monitoring-in-devops/) +- [Understanding Continuous Monitoring in DevOps?](https://medium.com/devopscurry/understanding-continuous-monitoring-in-devops-f6695b004e3b) +- [DevOps Monitoring Tools](https://www.youtube.com/watch?v=Zu53QQuYqJ0) +- [Top 5 - DevOps Monitoring Tools](https://www.youtube.com/watch?v=4t71iv_9t_4) +- [How Prometheus Monitoring works](https://www.youtube.com/watch?v=h4Sl21AKiDg) +- [Introduction to Prometheus monitoring](https://www.youtube.com/watch?v=5o37CGlNLr8) +- [Promql cheat sheet with examples](https://www.containiq.com/post/promql-cheat-sheet-with-examples) +- [Log Management for DevOps | Manage application, server, and cloud logs with Site24x7](https://www.youtube.com/watch?v=J0csO_Shsj0) +- [Log Management what DevOps need to know](https://devops.com/log-management-what-devops-teams-need-to-know/) +- [What is ELK Stack?](https://www.youtube.com/watch?v=4X0WLg05ASw) +- [Fluentd simply explained](https://www.youtube.com/watch?v=5ofsNyHZwWE&t=14s) + +[Day 81](day81.md)에서 봐요! diff --git a/2022/ko/Days/day81.md b/2022/ko/Days/day81.md new file mode 100644 index 0000000..6054668 --- /dev/null +++ b/2022/ko/Days/day81.md @@ -0,0 +1,166 @@ +--- +title: '#90DaysOfDevOps - Fluentd & FluentBit - Day 81' +published: false +description: 90DaysOfDevOps - Fluentd & FluentBit +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048716 +--- + +## Fluentd & FluentBit + +이 통합 observability 섹션의 일부로 살펴보고 싶었던 또 다른 데이터 수집기는 [Fluentd](https://docs.fluentd.org/)였습니다. 오픈소스 통합 로깅 레이어입니다. + +Fluentd는 깨끗하고 안정적인 로깅 파이프라인을 구축하는 데 적합한 네 가지 주요 기능을 갖추고 있습니다: + +JSON을 사용한 통합 로깅: Fluentd는 가능한 한 데이터를 JSON으로 구조화하려고 노력합니다. 이를 통해 여러 소스와 대상에 걸쳐 로그를 수집, 필터링, 버퍼링, 출력하는 등 로그 데이터 처리의 모든 측면을 통합할 수 있습니다. 엄격한 스키마를 강요하지 않고도 액세스할 수 있는 충분한 구조를 가지고 있기 때문에 JSON을 사용하면 다운스트림 데이터 처리가 훨씬 쉬워집니다. + +플러그 가능한 아키텍처: Fluentd는 커뮤니티가 기능을 확장할 수 있는 유연한 플러그인 시스템을 갖추고 있습니다. 300개 이상의 커뮤니티 기여 플러그인이 수십 개의 데이터 소스를 수십 개의 데이터 출력에 연결하여 필요에 따라 데이터를 조작합니다. 플러그인을 사용하면 로그를 즉시 더 효과적으로 활용할 수 있습니다. + +최소한의 리소스 필요: 데이터 수집기는 바쁜 컴퓨터에서도 편안하게 실행될 수 있도록 가벼워야 합니다. Fluentd는 C와 Ruby의 조합으로 작성되어 최소한의 시스템 리소스를 필요로 합니다. 바닐라 인스턴스는 30~40MB의 메모리에서 실행되며 초당 13,000개의 이벤트를 처리할 수 있습니다. + +내장된 안정성: 데이터 손실은 절대 일어나지 않습니다. Fluentd는 메모리 및 파일 기반 버퍼링을 지원하여 노드 간 데이터 손실을 방지합니다. 또한, 강력한 페일오버를 지원하며 고가용성을 위해 설정할 수 있습니다. + +[Fluentd 설치하기](https://docs.fluentd.org/quickstart#step-1-installing-fluentd) + +### 앱은 데이터를 어떻게 기록하나요? + +- 파일에 기록합니다. `.log` 파일(도구 없이는 대규모로 분석하기 어려움) +- 데이터베이스에 직접 기록(각 애플리케이션이 올바른 형식으로 구성되어 있어야 함) +- 타사 애플리케이션(NodeJS, NGINX, PostgreSQL) + +이것이 바로 통합 로깅 레이어가 필요한 이유입니다. + +FluentD는 위에 표시된 3가지 로깅 데이터 유형을 허용하고 이를 수집, 처리하여 대상(예: Elastic, MongoDB 또는 Kafka 데이터베이스)으로 로그를 전송할 수 있는 기능을 제공합니다. + +모든 데이터, 모든 데이터 소스를 FluentD로 전송할 수 있으며, 이를 모든 대상으로 전송할 수 있습니다. FluentD는 특정 소스나 대상에 종속되지 않습니다. + +Fluentd를 조사하는 과정에서 또 다른 옵션으로 Fluent bit를 계속 발견하게 되었는데, 서버뿐만 아니라 컨테이너에도 배포할 수 있지만 로깅 도구를 Kubernetes 환경에 배포하려는 경우 FluentBit가 해당 기능을 제공할 수 있을 것 같았습니다. + +[Fluentd & FluentBit](https://docs.fluentbit.io/manual/about/fluentd-and-fluent-bit) + +Fluentd와 FluentBit는 입력 플러그인을 사용하여 데이터를 FluentBit 형식으로 변환한 다음, 출력 플러그인을 사용하여 엘라스틱서치와 같은 출력 대상이 무엇이든 출력할 수 있습니다. + +또한 구성 간에 태그와 일치를 사용할 수도 있습니다. + +일부 아키텍처에서는 함께 사용할 수 있지만, FluentBit를 사용해야 할 좋은 이유를 찾을 수 없으며, FluentBit가 시작하기에 가장 좋은 방법인 것 같습니다. + +### Kubernetes의 FluentBit + +Kubernetes의 FluentBit는 데몬셋으로 배포되며, 이는 클러스터의 각 노드에서 실행된다는 것을 의미합니다. 그러면 각 노드의 각 Fluent Bit pod는 해당 노드의 각 컨테이너를 읽고 사용 가능한 모든 로그를 수집합니다. 또한 Kubernetes API 서버에서 메타데이터를 수집합니다. + +Kubernetes 어노테이션은 애플리케이션의 구성 YAML 내에서 사용할 수 있습니다. + +우선, Fluent Helm 리포지토리에서 배포할 수 있습니다. Helm 리포지토리에서 `helm repo add fluent https://fluent.github.io/helm-charts`를 실행한 다음 `helm install fluent-bit fluent/fluent-bit` 명령어를 사용하여 설치합니다. + +![](/2022/Days/Images/Day81_Monitoring1.png) + +내 클러스터에서는 (테스트 목적으로) 기본 네임스페이스에서 Prometheus를 실행 중이므로 fluent-bit pod가 실행 중인지 확인해야 합니다. `kubectl get all | grep fluent`를 사용하면 앞서 언급한 실행 중인 pod, 서비스 및 데몬셋을 확인할 수 있습니다. + +![](/2022/Days/Images/Day81_Monitoring2.png) + +FluentBit이 로그를 어디에서 가져올지 알 수 있도록 구성 파일이 있으며, 이 FluentBit의 Kubernetes 배포에는 구성 파일과 유사한 configmap이 있습니다. + +![](/2022/Days/Images/Day81_Monitoring3.png) + +이 configmap은 다음과 같이 보일 것입니다: + +``` +Name: fluent-bit +Namespace: default +Labels: app.kubernetes.io/instance=fluent-bit + app.kubernetes.io/managed-by=Helm + app.kubernetes.io/name=fluent-bit + app.kubernetes.io/version=1.8.14 + helm.sh/chart=fluent-bit-0.19.21 +Annotations: meta.helm.sh/release-name: fluent-bit + meta.helm.sh/release-namespace: default + +Data +==== +custom_parsers.conf: +---- +[PARSER] + Name docker_no_time + Format json + Time_Keep Off + Time_Key time + Time_Format %Y-%m-%dT%H:%M:%S.%L + +fluent-bit.conf: +---- +[SERVICE] + Daemon Off + Flush 1 + Log_Level info + Parsers_File parsers.conf + Parsers_File custom_parsers.conf + HTTP_Server On + HTTP_Listen 0.0.0.0 + HTTP_Port 2020 + Health_Check On + +[INPUT] + Name tail + Path /var/log/containers/*.log + multiline.parser docker, cri + Tag kube.* + Mem_Buf_Limit 5MB + Skip_Long_Lines On + +[INPUT] + Name systemd + Tag host.* + Systemd_Filter _SYSTEMD_UNIT=kubelet.service + Read_From_Tail On + +[FILTER] + Name Kubernetes + Match kube.* + Merge_Log On + Keep_Log Off + K8S-Logging.Parser On + K8S-Logging.Exclude On + +[OUTPUT] + Name es + Match kube.* + Host elasticsearch-master + Logstash_Format On + Retry_Limit False + +[OUTPUT] + Name es + Match host.* + Host elasticsearch-master + Logstash_Format On + Logstash_Prefix node + Retry_Limit False + +Events: +``` + +이제 pod를 로컬호스트로 포트 포워딩하여 연결성을 확보할 수 있습니다. 먼저 `kubectl get pods | grep fluent`로 pod의 이름을 가져온 다음 `kubectl port-forward fluent-bit-8kvl4 2020:2020`을 사용하여 `http://localhost:2020/`으로 웹 브라우저를 엽니다. + +![](/2022/Days/Images/Day81_Monitoring4.png) + +[FluentBit](https://medium.com/kubernetes-tutorials/exporting-kubernetes-logs-to-elasticsearch-using-fluent-bit-758e8de606af)에 대한 자세한 내용을 다루는 이 훌륭한 매체 기사도 발견했습니다. + +## 자료 + +- [Understanding Logging: Containers & Microservices](https://www.youtube.com/watch?v=MMVdkzeQ848) +- [The Importance of Monitoring in DevOps](https://www.devopsonline.co.uk/the-importance-of-monitoring-in-devops/) +- [Understanding Continuous Monitoring in DevOps?](https://medium.com/devopscurry/understanding-continuous-monitoring-in-devops-f6695b004e3b) +- [DevOps Monitoring Tools](https://www.youtube.com/watch?v=Zu53QQuYqJ0) +- [Top 5 - DevOps Monitoring Tools](https://www.youtube.com/watch?v=4t71iv_9t_4) +- [How Prometheus Monitoring works](https://www.youtube.com/watch?v=h4Sl21AKiDg) +- [Introduction to Prometheus monitoring](https://www.youtube.com/watch?v=5o37CGlNLr8) +- [Promql cheat sheet with examples](https://www.containiq.com/post/promql-cheat-sheet-with-examples) +- [Log Management for DevOps | Manage application, server, and cloud logs with Site24x7](https://www.youtube.com/watch?v=J0csO_Shsj0) +- [Log Management what DevOps need to know](https://devops.com/log-management-what-devops-teams-need-to-know/) +- [What is ELK Stack?](https://www.youtube.com/watch?v=4X0WLg05ASw) +- [Fluentd simply explained](https://www.youtube.com/watch?v=5ofsNyHZwWE&t=14s) +- [Fluent Bit explained | Fluent Bit vs Fluentd](https://www.youtube.com/watch?v=B2IS-XS-cc0) + +[Day 82](day82.md)에서 봐요! diff --git a/2022/ko/Days/day82.md b/2022/ko/Days/day82.md new file mode 100644 index 0000000..09548b3 --- /dev/null +++ b/2022/ko/Days/day82.md @@ -0,0 +1,112 @@ +--- +title: '#90DaysOfDevOps - EFK Stack - Day 82' +published: false +description: 90DaysOfDevOps - EFK Stack +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049059 +--- + +### EFK 스택 + +이전 섹션에서는 스택의 로그 수집기로 Logstash를 사용하는 ELK 스택에 대해 이야기했지만, EFK 스택에서는 이를 FluentD 또는 FluentBit으로 대체합니다. + +이 섹션에서 우리의 임무는 EFK를 사용하여 Kubernetes 로그를 모니터링하는 것입니다. + +### EFK 개요 + +우리는 다음을 Kubernetes 클러스터에 배포할 것입니다. + +![](/2022/Days/Images/Day82_Monitoring1.png) + +EFK 스택은 다음과 같은 3가지 소프트웨어가 함께 번들로 제공되는 모음입니다: + +- Elasticsearch: NoSQL 데이터베이스는 데이터를 저장하는 데 사용되며 검색 및 로그 쿼리를 위한 인터페이스를 제공합니다. + +- Fluentd: Fluentd는 통합 로깅 계층을 위한 오픈 소스 데이터 수집기입니다. Fluentd를 사용하면 데이터 수집과 소비를 통합하여 데이터를 더 잘 사용하고 이해할 수 있습니다. + +- Kibana: 로그 관리 및 통계를 위한 인터페이스. elasticsearch에서 정보를 읽는 역할을 담당합니다. + +### Minikube에 EFK 배포하기 + +우리는 신뢰할 수 있는 Minikube 클러스터를 사용해 EFK 스택을 배포할 것입니다. 우리 시스템에서 `minikube start`를 사용하여 클러스터를 시작하겠습니다. WSL2가 활성화된 Windows OS를 사용하고 있습니다. + +![](/2022/Days/Images/Day82_Monitoring2.png) + +EFK 스택을 클러스터에 배포하는 데 필요한 모든 것을 포함하는 [efk-stack.yaml](/2022/Days/Monitoring/EFK%20Stack/efk-stack.yaml)을 생성했으며, `kubectl create -f efk-stack.yaml` 명령을 사용하여 배포되는 모든 것을 확인할 수 있습니다. + +![](/2022/Days/Images/Day82_Monitoring3.png) + +시스템에 따라 다르지만, 이미 이 작업을 실행하여 이미지를 가져온 경우 다음 명령으로 진행 상황을 확인할 수 있습니다. `kubectl get pods -n kube-logging -w` 몇 분 정도 걸릴 수 있습니다. + +![](/2022/Days/Images/Day82_Monitoring4.png) + +위의 명령으로 상황을 계속 주시할 수 있지만, 모든 pod가 이제 실행 중인지 확인하기 위해 다음 `kubectl get pods -n kube-logging` 명령을 실행하여 모든 것이 정상임을 명확히 하고 싶습니다. + +![](/2022/Days/Images/Day82_Monitoring5.png) + +모든 pod가 실행되고 실행 중이고 이 단계에서는 다음을 볼 수 있어야 합니다. + +- ElasticSearch와 연결된 3개의 pod +- Fluentd와 연결된 pod 1개 +- Kibana와 연결된 pod 1개 + +또한 `kubectl get all -n kube-logging`을 사용하여 네임스페이스에 모두 표시할 수 있으며, 앞서 설명한 대로 fluentd는 데몬셋으로 배포되고, kibana는 deployment로, Elasticsearch는 statefulset으로 배포됩니다. + +![](/2022/Days/Images/Day82_Monitoring6.png) + +이제 모든 pod가 실행되고 실행 중이므로 이제 새 터미널에서 포트 포워드 명령을 실행하여 kibana 대시보드에 액세스할 수 있습니다. pod 이름은 여기에 표시된 명령과 다를 것입니다. `kubectl port-forward kibana-84cf7f59c-v2l8v 5601:5601 -n kube-logging` + +![](/2022/Days/Images/Day82_Monitoring7.png) + +이제 브라우저를 열고 `http://localhost:5601` 주소로 이동하면 아래와 같은 화면이 표시되거나 실제로 샘플 데이터 화면이 표시되거나 계속 진행하여 직접 구성할 수 있습니다. 어느 쪽이든 이전 세션에서 ELK 스택을 살펴볼 때 다루었던 테스트 데이터를 꼭 살펴보시기 바랍니다. + +![](/2022/Days/Images/Day82_Monitoring8.png) + +다음으로, 왼쪽 메뉴의 "discover" 탭을 누르고 인덱스 패턴에 "\*"를 추가해야 합니다. "Next step"를 눌러 다음 단계로 계속 진행합니다. + +![](/2022/Days/Images/Day82_Monitoring9.png) + +2단계 2번에서는 시간별로 데이터를 필터링하기 위해 드롭다운에서 @timestamp 옵션을 사용하겠습니다. 패턴 만들기를 누르면 완료하는 데 몇 초 정도 걸릴 수 있습니다. + +![](/2022/Days/Images/Day82_Monitoring10.png) + +이제 몇 초 후에 "discover" 탭으로 돌아가면 Kubernetes 클러스터에서 데이터가 들어오는 것을 볼 수 있을 것입니다. + +![](/2022/Days/Images/Day82_Monitoring11.png) + +이제 EFK 스택이 실행 중이고 Fluentd를 통해 Kubernetes 클러스터에서 로그를 수집하고 있으므로 왼쪽 상단의 Kibana 로고를 눌러 홈 화면으로 이동하면 처음 로그인할 때 보았던 것과 동일한 페이지가 표시됩니다. + +다른 플러그인이나 소스로부터 APM, 로그 데이터, 메트릭 데이터, 보안 이벤트를 추가할 수 있습니다. + +![](/2022/Days/Images/Day82_Monitoring12.png) + +"Add log data"를 선택하면 아래에서 로그를 가져올 위치에 대한 많은 선택 사항이 있음을 알 수 있으며, ELK 스택의 일부인 Logstash가 언급되어 있는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day82_Monitoring13.png) + +메트릭 데이터 아래에서 Prometheus 및 기타 여러 서비스에 대한 소스를 추가할 수 있음을 알 수 있습니다. + +### APM(Application Performance Monitoring) + +애플리케이션 내부에서 심층적인 성능 메트릭과 오류를 수집하는 APM(Application Performance Monitoring)을 수집하는 옵션도 있습니다. 이를 통해 수천 개의 애플리케이션의 성능을 실시간으로 모니터링할 수 있습니다. + +여기서는 APM에 대해 자세히 설명하지 않겠지만, [Elastic 사이트](https://www.elastic.co/observability/application-performance-monitoring)에서 자세한 내용을 확인할 수 있습니다. + +## 자료 + +- [Understanding Logging: Containers & Microservices](https://www.youtube.com/watch?v=MMVdkzeQ848) +- [The Importance of Monitoring in DevOps](https://www.devopsonline.co.uk/the-importance-of-monitoring-in-devops/) +- [Understanding Continuous Monitoring in DevOps?](https://medium.com/devopscurry/understanding-continuous-monitoring-in-devops-f6695b004e3b) +- [DevOps Monitoring Tools](https://www.youtube.com/watch?v=Zu53QQuYqJ0) +- [Top 5 - DevOps Monitoring Tools](https://www.youtube.com/watch?v=4t71iv_9t_4) +- [How Prometheus Monitoring works](https://www.youtube.com/watch?v=h4Sl21AKiDg) +- [Introduction to Prometheus monitoring](https://www.youtube.com/watch?v=5o37CGlNLr8) +- [Promql cheat sheet with examples](https://www.containiq.com/post/promql-cheat-sheet-with-examples) +- [Log Management for DevOps | Manage application, server, and cloud logs with Site24x7](https://www.youtube.com/watch?v=J0csO_Shsj0) +- [Log Management what DevOps need to know](https://devops.com/log-management-what-devops-teams-need-to-know/) +- [What is ELK Stack?](https://www.youtube.com/watch?v=4X0WLg05ASw) +- [Fluentd simply explained](https://www.youtube.com/watch?v=5ofsNyHZwWE&t=14s) + +[Day 83](day83.md)에서 봐요! diff --git a/2022/ko/Days/day83.md b/2022/ko/Days/day83.md new file mode 100644 index 0000000..e2361c3 --- /dev/null +++ b/2022/ko/Days/day83.md @@ -0,0 +1,153 @@ +--- +title: '#90DaysOfDevOps - Data Visualisation - Grafana - Day 83' +published: false +description: 90DaysOfDevOps - Data Visualisation - Grafana +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048767 +--- + +## 데이터 시각화 - Grafana + +이 섹션에서는 통합 observability과 관련하여 많은 Kibana를 살펴봤습니다. 하지만 시간을 내어 Grafana에 대해서도 다뤄야 합니다. 하지만 이 둘은 동일하지도 않고 서로 완전히 경쟁하는 것도 아닙니다. + +Kibana의 핵심 기능은 데이터 쿼리 및 분석입니다. 사용자는 다양한 방법을 사용해 근본 원인 분석과 진단을 위해 데이터 내에서 특정 이벤트나 문자열에 대해 Elasticsearch에서 색인된 데이터를 검색할 수 있습니다. 이러한 쿼리를 기반으로 사용자는 차트, 표, 지리적 지도 및 기타 유형의 시각화를 사용하여 다양한 방식으로 데이터를 시각화할 수 있는 Kibana의 시각화 기능을 사용할 수 있습니다. + +Grafana는 Kibana의 folk로 시작되었으며, 당시 Kibana가 제공하지 않았던 메트릭, 즉 모니터링에 대한 지원을 제공하는 것이 목표였습니다. + +Grafana는 무료 오픈 소스 데이터 시각화 도구입니다. 현장에서는 일반적으로 Prometheus와 Grafana를 함께 사용하는 것을 볼 수 있지만, Elasticsearch 및 Graphite와 함께 사용하는 경우도 있습니다. + +두 도구의 주요 차이점은 로깅과 모니터링입니다. 이 섹션에서는 Nagios로 모니터링을 다루기 시작해 Prometheus를 살펴본 다음 로깅으로 이동해 ELK 및 EFK 스택을 다루었습니다. + +Grafana는 시스템 CPU, 메모리, 디스크 및 I/O 사용률과 같은 메트릭을 분석하고 시각화하는 데 적합합니다. 이 플랫폼은 전체 텍스트 데이터 쿼리를 허용하지 않습니다. Kibana는 Elasticsearch 위에서 실행되며 주로 로그 메시지 분석에 사용됩니다. + +Kibana는 배포가 매우 쉬울 뿐만 아니라 배포 위치를 선택할 수 있다는 것을 이미 확인했듯이, Grafana도 마찬가지입니다. + +둘 다 Linux, Mac, Windows, Docker에 설치하거나 소스에서 빌드하는 것을 지원합니다. + +의심할 여지 없이 다른 도구도 있지만, Grafana는 가상, 클라우드 및 클라우드 네이티브 플랫폼에 걸쳐서 제가 본 도구이므로 이 섹션에서 다루고 싶었습니다. + +### Prometheus Operator + Grafana Deployment + +이 섹션에서 이미 Prometheus에 대해 다루었지만, 이 두 가지를 함께 사용하는 경우가 너무 많아서 최소한 시각화에서 어떤 메트릭을 표시할 수 있는지 확인할 수 있는 환경을 만들어 보고 싶었습니다. 환경을 모니터링하는 것이 중요하다는 것은 알고 있지만, Prometheus나 다른 메트릭 도구에서 이러한 메트릭만 살펴보는 것은 번거롭고 확장성이 떨어집니다. 바로 이 지점에서 Grafana가 등장하여 Prometheus 데이터베이스에 수집 및 저장된 메트릭의 대화형 시각화를 제공합니다. + +이 시각화를 통해 환경에 맞는 사용자 정의 차트, 그래프 및 알림을 만들 수 있습니다. 이 연습에서는 Minikube 클러스터를 사용하겠습니다. + +먼저 이것을 로컬 시스템에 복제하는 것으로 시작하겠습니다. `git clone https://github.com/prometheus-operator/kube-prometheus.git` 및 `cd kube-prometheus`를 입력하세요. + +![](/2022/Days/Images/Day83_Monitoring1.png) + +첫 번째 작업은 Minikube 클러스터 내에서 네임스페이스를 생성하는 것입니다. `kubectl create -f manifests/setup` 이전 섹션에서 따라하지 않은 경우 `minikube start`를 사용하여 여기에 새 클러스터를 불러올 수 있습니다. + +![](/2022/Days/Images/Day83_Monitoring2.png) + +다음으로, `kubectl create -f manifests/` 명령을 사용하여 데모에 필요한 모든 것을 배포할 것인데, 보시다시피 클러스터 내에 다양한 리소스가 배포될 것입니다. + +![](/2022/Days/Images/Day83_Monitoring3.png) + +이제 pod가 실행될 때까지 기다려야 하며, 실행 상태가 되면 `kubectl get pods -n monitoring -w` 명령어를 사용하여 pod를 계속 감시할 수 있습니다. + +![](/2022/Days/Images/Day83_Monitoring4.png) + +모든 것이 실행 중이면 `kubectl get pods -n monitoring` 명령으로 모든 pod가 실행 중이고 정상 상태인지 확인할 수 있습니다. + +![](/2022/Days/Images/Day83_Monitoring5.png) + +배포와 함께 데모 후반부에서 사용할 몇 가지 서비스를 배포했으며, `kubectl get svc -n monitoring` 명령으로 확인할 수 있습니다. + +![](/2022/Days/Images/Day83_Monitoring6.png) + +마지막으로 `kubectl get all -n monitoring` 명령으로 새 모니터링 네임스페이스에 배포된 모든 리소스를 확인해 봅시다. + +![](/2022/Days/Images/Day83_Monitoring7.png) + +새 터미널을 열면 이제 Grafana 도구에 액세스하여 몇 가지 메트릭을 수집하고 시각화할 준비가 되었으며, 사용할 명령은 `kubectl --namespace monitoring port-forward svc/grafana 3000`입니다. + +![](/2022/Days/Images/Day83_Monitoring8.png) + +브라우저를 열고 http://localhost:3000 로 이동하면 사용자 이름과 비밀번호를 입력하라는 메시지가 표시됩니다. + +![](/2022/Days/Images/Day83_Monitoring9.png) +액세스하기 위한 기본 사용자 이름과 비밀번호는 다음과 같습니다. + +``` +Username: admin +Password: admin +``` + +하지만 처음 로그인할 때 새 비밀번호를 입력하라는 메시지가 표시됩니다. 초기 화면 또는 홈페이지에는 탐색할 수 있는 몇 가지 영역과 Grafana와 그 기능을 익히는 데 유용한 몇 가지 리소스가 표시됩니다. 나중에 사용하게 될 "Add your first data source" 및 "create your first dashboard" 위젯을 주목하세요. + +![](/2022/Days/Images/Day83_Monitoring10.png) + +Grafana 데이터 소스에 이미 prometheus 데이터 소스가 추가되어 있는 것을 볼 수 있지만, Minikube를 사용하고 있기 때문에 로컬 호스트에서 사용할 수 있도록 prometheus도 포팅해야 하므로 새 터미널을 열고 다음 명령을 실행할 수 있습니다. `kubectl --namespace monitoring port-forward svc/prometheus-k8s 9090` 이제 Grafana의 홈페이지에서 "Add your first data source"라는 위젯에 들어가서 여기에서 Prometheus를 선택합니다. + +![](/2022/Days/Images/Day83_Monitoring11.png) + +새 데이터 소스의 경우 http://localhost:9090 주소를 사용할 수 있으며, 아래에 강조 표시된 대로 드롭다운을 브라우저로 변경해야 합니다. + +![](/2022/Days/Images/Day83_Monitoring12.png) + +이제 페이지 하단에서 저장 및 테스트를 누르면 됩니다. 그러면 아래와 같이 Prometheus의 포트 포워딩이 작동하는 결과를 확인할 수 있습니다. + +![](/2022/Days/Images/Day83_Monitoring13.png) + +홈페이지로 돌아가서 "Create your first dashboard" 옵션을 찾아 "Add a new panel"를 선택합니다. + +![](/2022/Days/Images/Day83_Monitoring14.png) + +아래에서 이미 Grafana 데이터 원본에서 수집하고 있는 것을 볼 수 있지만, Prometheus 데이터 원본에서 메트릭을 수집하려면 데이터 원본 드롭다운을 선택하고 새로 만든 "Prometheus-1"을 선택합니다. + +![](/2022/Days/Images/Day83_Monitoring15.png) + +그런 다음 메트릭 브라우저를 선택하면 Minikube 클러스터와 관련된 Prometheus에서 수집되는 메트릭의 긴 목록이 표시됩니다. + +![](/2022/Days/Images/Day83_Monitoring16.png) + +데모에서는 시스템 리소스에 대한 몇 가지 출력을 제공하는 메트릭을 찾아보겠습니다. `cluster:node_cpu:ratio{}`는 클러스터의 노드에 대한 세부 정보를 제공하고 이 통합이 작동하고 있음을 증명합니다. + +![](/2022/Days/Images/Day83_Monitoring17.png) + +이 시각화가 마음에 들면 오른쪽 상단의 적용 버튼을 누르면 이 그래프를 대시보드에 추가할 수 있습니다. 계속해서 그래프와 다른 차트를 추가하여 필요한 시각화를 제공할 수 있습니다. + +![](/2022/Days/Images/Day83_Monitoring18.png) + +그러나 이전에 만든 수천 개의 대시보드를 활용할 수 있으므로 새로 만들 필요가 없습니다. + +![](/2022/Days/Images/Day83_Monitoring19.png) + +Kubernetes를 검색하면 선택할 수 있는 미리 빌드된 대시보드의 긴 목록을 볼 수 있습니다. + +![](/2022/Days/Images/Day83_Monitoring20.png) + +Kubernetes API 서버 대시보드를 선택하고 새로 추가된 Prometheus-1 데이터 소스에 맞게 데이터 소스를 변경하면 아래에 표시되는 몇 가지 메트릭을 볼 수 있습니다. + +![](/2022/Days/Images/Day83_Monitoring21.png) + +### 알림 + +또한 배포한 알림 관리자를 활용하여 슬랙이나 다른 통합으로 알림을 보낼 수도 있는데, 이렇게 하려면 아래 세부 정보를 사용하여 알림 관리자 서비스를 포트로 포워드해야 합니다. + +`kubectl --namespace monitoring port-forward svc/alertmanager-main 9093` +`http://localhost:9093` + +이것으로 통합 observability에 대한 모든 것에 대한 섹션을 마쳤습니다. 개인적으로 이 섹션은 이 주제가 얼마나 광범위한 주제인지 강조했지만, 마찬가지로 이것이 우리의 역할에 얼마나 중요한지, 특히 다른 섹션에서 이미 다룬 모든 자동화를 통해 매우 극적으로 변화할 수 있는 경우 메트릭, 로깅 또는 추적이든 앞으로 광범위한 환경에서 무슨 일이 일어나고 있는지 잘 파악해야 한다는 것을 알 수 있었습니다. + +다음 섹션에서는 데이터 관리와 데이터 관리와 관련하여 데브옵스 원칙을 어떻게 고려해야 하는지에 대해 살펴보겠습니다. + +## 자료 + +- [Understanding Logging: Containers & Microservices](https://www.youtube.com/watch?v=MMVdkzeQ848) +- [The Importance of Monitoring in DevOps](https://www.devopsonline.co.uk/the-importance-of-monitoring-in-devops/) +- [Understanding Continuous Monitoring in DevOps?](https://medium.com/devopscurry/understanding-continuous-monitoring-in-devops-f6695b004e3b) +- [DevOps Monitoring Tools](https://www.youtube.com/watch?v=Zu53QQuYqJ0) +- [Top 5 - DevOps Monitoring Tools](https://www.youtube.com/watch?v=4t71iv_9t_4) +- [How Prometheus Monitoring works](https://www.youtube.com/watch?v=h4Sl21AKiDg) +- [Introduction to Prometheus monitoring](https://www.youtube.com/watch?v=5o37CGlNLr8) +- [Promql cheat sheet with examples](https://www.containiq.com/post/promql-cheat-sheet-with-examples) +- [Log Management for DevOps | Manage application, server, and cloud logs with Site24x7](https://www.youtube.com/watch?v=J0csO_Shsj0) +- [Log Management what DevOps need to know](https://devops.com/log-management-what-devops-teams-need-to-know/) +- [What is ELK Stack?](https://www.youtube.com/watch?v=4X0WLg05ASw) +- [Fluentd simply explained](https://www.youtube.com/watch?v=5ofsNyHZwWE&t=14s) + +[Day 84](day84.md)에서 봐요! diff --git a/2022/ko/Days/day84.md b/2022/ko/Days/day84.md new file mode 100644 index 0000000..451c6a1 --- /dev/null +++ b/2022/ko/Days/day84.md @@ -0,0 +1,73 @@ +--- +title: '#90DaysOfDevOps - The Big Picture: Data Management - Day 84' +published: false +description: 90DaysOfDevOps - The Big Picture Data Management +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048747 +--- + +## 큰 그림: 데이터 관리 + +![](/2022/Days/Images/Day84_Data1.png) + +데이터가 몇 년 전보다 더 중요해졌다는 것은 알고 있지만, 데이터 관리는 결코 넘어야 할 새로운 벽이 아닙니다. 가치 있고 끊임없이 변화하는 데이터는 자동화와 빈번한 소프트웨어 릴리스의 지속적인 통합, 테스트 및 배포에 대해 이야기할 때 엄청난 악몽이 될 수도 있습니다. 영구 데이터와 기본 데이터 서비스는 종종 문제가 발생할 때 주범이 되기도 합니다. + +하지만 클라우드 네이티브 데이터 관리에 들어가기 전에 한 단계 더 올라가야 합니다. 이번 챌린지를 통해 다양한 플랫폼을 다루었습니다. 물리, 가상, 클라우드 또는 클라우드 네이티브(Kubernetes 포함) 등 어떤 플랫폼이든 데이터 관리에 대한 요구 사항을 충족하지 않는 플랫폼은 없습니다. + +비즈니스에서 가장 미션 크리티컬한 시스템을 위한 것이든, 아니면 적어도 일부 톱니바퀴가 시스템의 일부 수준에 영구 데이터를 저장하고 있든, 환경 어딘가에 숨어 있는 데이터베이스를 찾을 가능성이 높습니다. + +### 데브옵스와 데이터 + +데브옵스 원칙에 대해 이야기했던 이 시리즈의 맨 처음과 마찬가지로, 데이터와 관련하여 더 나은 프로세스를 위해서는 적절한 인력을 포함시켜야 합니다. 여기에는 DBA가 포함될 수도 있지만, 마찬가지로 데이터 서비스의 백업에 관심이 있는 사람들도 포함될 것입니다. + +둘째, 데이터와 관련된 다양한 데이터 유형, 도메인 및 경계를 식별해야 합니다. 이렇게 하면 데이터베이스 관리자, 스토리지 엔지니어 또는 백업에 집중하는 엔지니어 사이에서만 사일로 방식으로 처리되는 것이 아닙니다. 이렇게 하면 전체 팀이 더 넓은 비즈니스를 위한 애플리케이션을 개발하고 호스팅하는 데 있어 최선의 조치 경로를 결정하고 데이터 아키텍처에 집중할지, 아니면 나중에 고려할지 결정할 수 있습니다. + +이제 데이터 라이프사이클의 다양한 영역에 걸쳐 데이터 수집에 대해 이야기할 수 있습니다. 서비스나 애플리케이션에 데이터를 어디서 어떻게 수집할 것인가? 서비스, 애플리케이션 또는 사용자는 이 데이터에 어떻게 액세스할까요? 또한 데이터를 어떻게 보호할 것인지, 그리고 그 데이터를 어떻게 보호할 것인지에 대해서도 이해해야 합니다. + +### 데이터 관리 101 + +[데이터 관리 지식 체계](https://www.dama.org/cpages/body-of-knowledge)에 따르면 데이터 관리는 "데이터 및 정보 자산의 가치를 제어, 보호, 제공 및 향상시키는 계획, 정책, 프로그램 및 관행을 개발, 실행 및 감독하는 것"입니다. + +- 데이터는 비즈니스의 가장 중요한 측면입니다 - 데이터는 전체 비즈니스의 한 부분일 뿐입니다. "데이터는 비즈니스의 생명선"이라는 표현을 본 적이 있는데, 대부분 사실일 것입니다. 혈액이 신체에 매우 중요하지만, 혈액만으로는 혈액을 액체로 만드는 데 필요한 신체적 측면이 부족하다는 생각이 들었습니다. + +- 데이터 품질은 그 어느 때보다 중요합니다. 데이터를 비즈니스 자산으로 취급해야 하며, 이는 자동화 및 DevOps 원칙에 따라 데이터에 필요한 고려 사항을 제공해야 한다는 것을 의미합니다. + +- 적시에 데이터에 액세스해야 합니다. - 효과적인 의사 결정을 내리기 위해 적시에 적절한 데이터에 액세스하지 못하는 것을 참을 수 있는 사람은 아무도 없습니다. 데이터는 프레젠테이션에 관계없이 간소화된 방식으로 적시에 사용할 수 있어야 합니다. + +- 데이터 관리는 DevOps의 조력자가 되어야 합니다 - 앞서 간소화에 대해 언급했지만, 데이터 관리 요구 사항을 주기에 포함시켜 데이터의 가용성뿐만 아니라 데이터 포인트에 대한 다른 중요한 정책 기반 보호와 함께 완전히 테스트된 복구 모델도 포함시켜야 합니다. + +### 데이터옵스 + +데이터옵스와 데브옵스 모두 기술 개발 및 운영의 모범 사례를 적용하여 품질을 개선하고, 속도를 높이고, 보안 위협을 줄이고, 고객을 만족시키고, 숙련된 전문가에게 의미 있고 도전적인 업무를 제공합니다. DevOps와 DataOps는 가능한 한 많은 프로세스 단계를 자동화하여 제품 제공을 가속화한다는 목표를 공유합니다. 데이터옵스의 목표는 탄력적인 데이터 파이프라인과 데이터 분석을 통한 신뢰할 수 있는 인사이트입니다. + +데이터옵스에 중점을 두는 가장 일반적인 상위 영역은 머신 러닝, 빅 데이터, 인공 지능을 포함한 데이터 분석이 될 것입니다. + +### 데이터 관리는 정보 관리입니다. + +이 섹션에서는 머신 러닝이나 인공 지능을 다루지 않고 데이터 보호 관점에서 데이터를 보호하는 데 초점을 맞출 것이며, 이 하위 섹션의 제목은 "데이터 관리는 정보의 관리"이며 정보 = 데이터라고 연관 지을 수 있습니다. + +데이터와 관련된 여정에서 고려해야 할 세 가지 핵심 영역은 다음과 같습니다: + +- 정확성 - 프로덕션 데이터가 정확한지 확인하는 것과 마찬가지로 백업 형태의 데이터도 작동하는지 확인하고 복구에 대해 테스트하여 장애나 사유가 발생할 경우 가능한 한 빨리 다시 가동할 수 있도록 해야 합니다. + +- 일관성 - 데이터 서비스가 여러 위치에 걸쳐 있는 경우 프로덕션의 경우 모든 데이터 위치에서 일관성을 유지하여 정확한 데이터를 얻을 수 있도록 해야 하며, 이는 이러한 데이터 서비스를 보호하는 데 있어서도 마찬가지입니다. 특히 데이터 서비스는 백업, 복제본 등을 위해 해당 데이터의 깨끗한 사본을 생성할 수 있도록 다양한 수준에서 일관성을 보장해야 합니다. + +- 보안 - 액세스 제어와 마찬가지로 일반적으로 데이터를 보관하는 것은 현재 전 세계적으로 화두가 되고 있는 주제입니다. 적절한 사람만 데이터에 액세스할 수 있도록 하는 것이 가장 중요하며, 이는 다시 데이터 보호로 이어져 필요한 사람만 백업에 액세스하고 백업에서 복원할 수 있으며 다른 버전의 비즈니스 데이터를 복제하여 제공할 수 있도록 해야 합니다. + +더 나은 데이터 = 더 나은 의사 결정 + +### 데이터 관리의 Days + +앞으로 6회에 걸쳐 데이터베이스, 백업 및 복구, 재해 복구, 애플리케이션 모빌리티에 대해 자세히 살펴보면서 데모와 실습을 병행할 예정입니다. + +## 자료 + +- [Kubernetes Backup and Restore made easy!](https://www.youtube.com/watch?v=01qcYSck1c4&t=217s) +- [Kubernetes Backups, Upgrades, Migrations - with Velero](https://www.youtube.com/watch?v=zybLTQER0yY) +- [7 Database Paradigms](https://www.youtube.com/watch?v=W2Z7fbCLSTw&t=520s) +- [Disaster Recovery vs. Backup: What's the difference?](https://www.youtube.com/watch?v=07EHsPuKXc0) +- [Veeam Portability & Cloud Mobility](https://www.youtube.com/watch?v=hDBlTdzE6Us&t=3s) + +[Day 85](day85.md)에서 봐요! diff --git a/2022/ko/Days/day85.md b/2022/ko/Days/day85.md new file mode 100644 index 0000000..c63dee9 --- /dev/null +++ b/2022/ko/Days/day85.md @@ -0,0 +1,152 @@ +--- +title: '#90DaysOfDevOps - Data Services - Day 85' +published: false +description: 90DaysOfDevOps - Data Services +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048781 +--- + +## 데이터 서비스 + +데이터베이스는 우리 환경에서 가장 흔히 접하는 데이터 서비스가 될 것입니다. 이번 세션에서는 다양한 유형의 데이터베이스와 각 데이터베이스의 사용 사례에 대해 살펴보고자 합니다. 이번 챌린지를 통해 우리가 사용하고 본 몇 가지 사례를 살펴보겠습니다. + +애플리케이션 개발 관점에서 올바른 데이터 서비스 또는 데이터베이스를 선택하는 것은 애플리케이션의 성능과 확장성 측면에서 매우 중요한 결정이 될 것입니다. + +https://www.youtube.com/watch?v=W2Z7fbCLSTw + +### Key-value + +Key-value 데이터베이스는 간단한 Key-value 방식을 사용하여 데이터를 저장하는 비관계형 데이터베이스의 한 유형입니다. Key-value 데이터베이스는 키가 고유 식별자 역할을 하는 Key-value 쌍의 모음으로 데이터를 저장합니다. 키와 값은 단순한 객체부터 복잡한 복합 객체에 이르기까지 무엇이든 될 수 있습니다. Key-value 데이터베이스는 고도로 파티셔닝이 가능하며 다른 유형의 데이터베이스에서는 달성할 수 없는 규모로 수평 확장이 가능합니다. + +Key-value 데이터베이스의 예로는 Redis가 있습니다. + +_Redis는 인메모리 데이터 구조 저장소로, 분산형 인메모리 Key-value 데이터베이스, 캐시 및 메시지 브로커로 사용되며 내구성을 옵션으로 선택할 수 있습니다. Redis는 문자열, 목록, 맵, 집합, 정렬된 집합, HyperLogLogs, 비트맵, 스트림, 공간 인덱스 등 다양한 종류의 추상 데이터 구조를 지원합니다._ + +![](/2022/Days/Images/Day85_Data1.png) + +Redis에 대한 설명에서 알 수 있듯이 이것은 데이터베이스가 빠르다는 것을 의미하지만, 그 대가로 공간에 제한이 있다는 것을 의미합니다. 또한 쿼리나 조인이 없으므로 데이터 모델링 옵션이 매우 제한적입니다. + +Best for: + +- 캐싱 +- Pub/Sub +- 리더보드 +- 쇼핑 카트 + +일반적으로 다른 영구 데이터 레이어 위에 캐시로 사용됩니다. + +### Wide-column + +Wide-column 데이터베이스는 데이터 저장소를 여러 서버 또는 데이터베이스 노드에 분산할 수 있는 유연한 컬럼으로 구성하고, 다차원 매핑을 사용하여 컬럼, 행, 타임스탬프로 데이터를 참조하는 NoSQL 데이터베이스입니다. + +_Cassandra는 무료 오픈소스, 분산형, 광역 열 저장소, NoSQL 데이터베이스 관리 시스템으로, 여러 상품 서버에서 대량의 데이터를 처리하도록 설계되어 단일 장애 지점 없이 고가용성을 제공합니다._ + +![](/2022/Days/Images/Day85_Data2.png) + +스키마가 없어 비정형 데이터를 처리할 수 없지만 일부 워크로드에는 이점으로 작용할 수 있습니다. + +Best for: + +- 시계열 +- 과거 기록 +- 많은 쓰기, 적은 읽기 + +### 문서 + +문서 데이터베이스(문서 지향 데이터베이스 또는 문서 저장소라고도 함)는 문서에 정보를 저장하는 데이터베이스입니다. + +_MongoDB는 소스 사용이 가능한 크로스 플랫폼 문서 지향 데이터베이스 프로그램입니다. NoSQL 데이터베이스 프로그램으로 분류되는 MongoDB는 선택적 스키마와 함께 JSON과 유사한 문서를 사용합니다. MongoDB는 MongoDB Inc.에서 개발했으며 서버 사이드 퍼블릭 라이선스에 따라 라이선스가 부여됩니다._ + +![](/2022/Days/Images/Day85_Data3.png) + +NoSQL 문서 데이터베이스를 사용하면 복잡한 SQL 코드를 사용하지 않고도 간단한 데이터를 저장할 수 있습니다. 안정성 저하 없이 빠르게 저장할 수 있습니다. + +Best for: + +- 대부분의 애플리케이션 +- 게임 +- 사물 인터넷 + +### 관계형 + +데이터베이스를 처음 사용하시지만 데이터베이스에 대해 알고 계신다면 관계형 데이터베이스를 접해 보셨을 것입니다. + +관계형 데이터베이스는 1970년 E. F. Codd가 제안한 데이터의 관계형 모델에 기반한 디지털 데이터베이스입니다. 관계형 데이터베이스를 유지 관리하는 데 사용되는 시스템은 관계형 데이터베이스 관리 시스템입니다. 많은 관계형 데이터베이스 시스템에는 데이터베이스를 쿼리하고 유지 관리하기 위해 SQL을 사용할 수 있는 옵션이 있습니다. + +_MySQL은 오픈소스 관계형 데이터베이스 관리 시스템입니다. 이 이름은 공동 창립자 Michael Widenius의 딸 이름인 'My'와 구조화된 쿼리 언어의 약자인 'SQL'을 조합한 것입니다._ + +MySQL은 관계형 데이터베이스의 한 예이며 다른 많은 옵션이 있습니다. + +![](/2022/Days/Images/Day85_Data4.png) + +관계형 데이터베이스를 연구하는 동안 **ACID**라는 용어 또는 약어가 많이 언급되었는데, (원자성, 일관성, 격리성, 내구성)은 오류, 정전 및 기타 사고에도 불구하고 데이터 유효성을 보장하기 위한 데이터베이스 트랜잭션의 일련의 속성입니다. 데이터베이스의 맥락에서 ACID 속성을 충족하는 일련의 데이터베이스 작업(데이터에 대한 단일 논리적 작업으로 인식될 수 있음)을 트랜잭션이라고 합니다. 예를 들어, 한 은행 계좌에서 다른 은행 계좌로 자금을 이체하는 경우, 한 계좌에서 인출하고 다른 계좌에 입금하는 등 여러 가지 변경 사항이 포함되더라도 이는 단일 트랜잭션에 해당합니다. + +Best for: + +- 대부분의 애플리케이션(수년 동안 사용되어 왔지만, 최고라는 의미는 아님) + +비정형 데이터에는 적합하지 않으며, 특정 워크로드에 대해 더 나은 확장 기능을 제공하는 다른 NoSQL이 언급되는 경우 확장 기능이 이상적이지 않습니다. + +### 그래프 + +그래프 데이터베이스는 테이블이나 문서 대신 노드와 관계를 저장합니다. 화이트보드에 아이디어를 스케치하는 것처럼 데이터가 저장됩니다. 데이터는 사전 정의된 모델에 제한되지 않고 저장되므로 매우 유연한 방식으로 데이터를 사고하고 사용할 수 있습니다. + +_Neo4j는 Neo4j, Inc.에서 개발한 그래프 데이터베이스 관리 시스템입니다. 개발자는 네이티브 그래프 저장 및 처리 기능을 갖춘 ACID 호환 트랜잭션 데이터베이스라고 설명합니다._ + +Best for: + +- 그래프 +- 지식 그래프 +- 추천 엔진 + +### 검색 엔진 + +지난 섹션에서는 Elasticsearch 방식으로 검색 엔진 데이터베이스를 사용했습니다. + +검색 엔진 데이터베이스는 데이터 콘텐츠 검색 전용으로 사용되는 비관계형 데이터베이스의 한 유형입니다. 검색 엔진 데이터베이스는 인덱스를 사용해 데이터 간에 유사한 특성을 분류하고 검색 기능을 용이하게 합니다. + +_Elasticsearch는 Lucene 라이브러리를 기반으로 하는 검색 엔진입니다. HTTP 웹 인터페이스와 스키마가 없는 JSON 문서를 갖춘 분산형 멀티테넌트 지원 전체 텍스트 검색 엔진을 제공합니다._ + +Best for: + +- 검색 엔진 +- Typeahead +- 로그 검색 + +### Multi-model + +Multi-model 데이터베이스는 단일 통합 백엔드에 대해 여러 데이터 모델을 지원하도록 설계된 데이터베이스 관리 시스템입니다. 반면, 대부분의 데이터베이스 관리 시스템은 데이터를 구성, 저장 및 조작하는 방법을 결정하는 단일 데이터 모델을 중심으로 구성됩니다. 문서, 그래프, 관계형, Key-value 모델은 Multi-model 데이터베이스에서 지원할 수 있는 데이터 모델의 예입니다. + +_Fauna는 네이티브 GraphQL을 통해 안전하고 확장 가능한 클라우드 API로 제공되는 유연하고 개발자 친화적인 트랜잭션 데이터베이스입니다._ + +Best for: + +- 데이터 모델 선택에 얽매이지 않는 경우 +- ACID 준수 +- 빠름 +- 프로비저닝 오버헤드 없음 +- 데이터를 어떻게 소비하고 클라우드에 무거운 작업을 맡기고 싶으신가요? + +어떤 산업에 종사하든 데이터베이스의 한 영역을 접하게 될 것이므로, 이것으로 데이터베이스 개요 세션을 마무리하겠습니다. 그런 다음 이 섹션의 뒷부분에서 몇 가지 예를 들어 데이터 관리, 특히 이러한 데이터 서비스의 보호 및 저장에 대해 살펴볼 것입니다. + +아래에 링크한 수많은 리소스를 통해 모든 데이터베이스 유형과 이에 수반되는 모든 것을 심도 있게 살펴보는 데 90년이 걸릴 수도 있습니다. + +## 자료 + +- [Redis Crash Course - the What, Why and How to use Redis as your primary database](https://www.youtube.com/watch?v=OqCK95AS-YE) +- [Redis: How to setup a cluster - for beginners](https://www.youtube.com/watch?v=GEg7s3i6Jak) +- [Redis on Kubernetes for beginners](https://www.youtube.com/watch?v=JmCn7k0PlV4) +- [Intro to Cassandra - Cassandra Fundamentals](https://www.youtube.com/watch?v=YjYWsN1vek8) +- [MongoDB Crash Course](https://www.youtube.com/watch?v=ofme2o29ngU) +- [MongoDB in 100 Seconds](https://www.youtube.com/watch?v=-bt_y4Loofg) +- [What is a Relational Database?](https://www.youtube.com/watch?v=OqjJjpjDRLc) +- [Learn PostgreSQL Tutorial - Full Course for Beginners](https://www.youtube.com/watch?v=qw--VYLpxG4) +- [MySQL Tutorial for Beginners [Full Course]](https://www.youtube.com/watch?v=7S_tz1z_5bA) +- [What is a graph database? (in 10 minutes)](https://www.youtube.com/watch?v=REVkXVxvMQE) +- [What is Elasticsearch?](https://www.youtube.com/watch?v=ZP0NmfyfsoM) +- [FaunaDB Basics - The Database of your Dreams](https://www.youtube.com/watch?v=2CipVwISumA) +- [Fauna Crash Course - Covering the Basics](https://www.youtube.com/watch?v=ihaB7CqJju0) + +[Day 86](day86.md)에서 봐요! diff --git a/2022/ko/Days/day86.md b/2022/ko/Days/day86.md new file mode 100644 index 0000000..dbe7f7f --- /dev/null +++ b/2022/ko/Days/day86.md @@ -0,0 +1,181 @@ +--- +title: '#90DaysOfDevOps - Backup all the platforms - Day 86' +published: false +description: 90DaysOfDevOps - Backup all the platforms +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049058 +--- + +## 모든 플랫폼 백업 + +이번 챌린지를 진행하는 동안 다양한 플랫폼과 환경에 대해 논의했습니다. 이 모든 플랫폼과 환경의 공통점은 모두 어느 정도의 데이터 보호가 필요하다는 사실입니다! + +데이터 보호는 수년 전부터 존재해 왔지만, 오늘날의 풍부한 데이터와 이러한 데이터가 가져다주는 가치는 여러 노드와 애플리케이션 전반의 고가용성을 통해 인프라 장애에 대한 복원력을 확보해야 할 뿐만 아니라 장애 시나리오가 발생할 경우 안전하고 안전한 위치에 중요한 데이터의 사본이 필요하다는 점을 고려해야 한다는 것을 의미합니다. + +요즘 사이버 범죄와 랜섬웨어에 대한 이야기를 많이 듣는데, 이는 엄청난 위협이며 랜섬웨어의 공격을 받을 수 있다는 사실에 대해 오해하지 마세요. 랜섬웨어는 시기의 문제가 아닙니다. 따라서 그 시기가 닥쳤을 때를 대비해 데이터를 안전하게 보호해야 하는 이유는 더욱 커집니다. 그러나 데이터 손실의 가장 흔한 원인은 랜섬웨어나 사이버 범죄가 아니라 실수로 인한 삭제입니다! + +우리 모두는 실수로 삭제하지 말았어야 할 파일을 삭제하고 순간적으로 후회한 경험이 있을 것입니다. + +챌린지 기간 동안 논의한 모든 기술과 자동화를 통해 상태 저장 데이터 또는 복잡한 stateless 구성을 보호해야 하는 요구 사항은 플랫폼에 관계없이 여전히 존재합니다. + +![](/2022/Days/Images/Day86_Data1.png) + +하지만 자동화를 염두에 두고 데이터 보호를 수행할 수 있어야 하며 워크플로우에 통합할 수 있어야 합니다. + +백업이 무엇인지 살펴보면 + +_정보 기술에서 백업 또는 데이터 백업은 데이터 손실이 발생한 후 원본을 복원하는 데 사용할 수 있도록 컴퓨터 데이터의 복사본을 다른 곳에 저장하는 것입니다. 이러한 과정을 나타내는 동사 형태는 "back up"이고, 명사 및 형용사 형태는 "백업"입니다._ + +이를 가장 간단한 형태로 분류하면 백업은 데이터를 복사하여 새 위치에 붙여 넣는 것입니다. 간단히 말해, 지금 당장 C: 드라이브에 있는 파일을 D: 드라이브로 복사하여 백업을 만들면 C: 드라이브에 문제가 발생하거나 파일 내에서 잘못 편집된 부분이 있을 때를 대비해 복사본을 확보할 수 있습니다. D: 드라이브에 있는 사본으로 되돌릴 수 있습니다. 이제 C 드라이브와 D 드라이브가 모두 있는 곳에서 컴퓨터가 죽으면 보호되지 않으므로 시스템 외부의 솔루션이나 집에 있는 NAS 드라이브에 데이터 사본을 저장하는 방법을 고려해야 하나요? 하지만 집에 무슨 일이 생기면 다른 위치의 다른 시스템에 저장하는 것을 고려해야 할 수도 있고, 클라우드가 옵션이 될 수도 있습니다. 장애 위험을 줄이기 위해 중요한 파일의 사본을 여러 위치에 저장할 수 있을까요? + +### 3-2-1 백업 방법론 + +이제 3-2-1 규칙 또는 백업 방법론에 대해 이야기하기에 좋은 시기인 것 같습니다. 이 주제를 다룬 [라이트닝 토크](https://www.youtube.com/watch?v=5wRt1bJfKBw)를 진행한 적이 있습니다. + +데이터를 보호해야 하는 이유에 대해서는 이미 몇 가지 극단적인 예를 들었지만, 아래에 몇 가지를 더 말씀드리겠습니다: + +![](/2022/Days/Images/Day86_Data2.png) + +이제 3-2-1 방법론에 대해 말씀드리겠습니다. 데이터의 첫 번째 복사본 또는 백업은 가능한 한 프로덕션 시스템에 가깝게 저장해야 하는데, 그 이유는 복구 속도를 고려한 것이며, 다시 실수로 삭제하는 경우가 가장 흔한 복구 이유가 될 것이라는 원래의 이야기로 돌아가겠습니다. 하지만 원본 또는 프로덕션 시스템 외부의 적절한 보조 미디어에 저장하고 싶습니다. + +그런 다음 다른 집, 건물, 데이터 센터 또는 퍼블릭 클라우드 등 두 번째 위치로 데이터 사본을 외부 또는 오프사이트로 전송하고 싶습니다. + +![](/2022/Days/Images/Day86_Data3.png) + +### 백업 책임 + +백업을 하지 않아도 된다는 속설에 대해 "모든 것이 stateless 상태"라는 말을 들어보셨을 것입니다. 모든 것이 stateless 상태라면 비즈니스는 무엇일까요? 데이터베이스도 없고, 워드 문서도 없나요? 비즈니스 내의 모든 개인이 데이터를 보호해야 할 책임이 있지만, 미션 크리티컬 애플리케이션과 데이터에 대한 백업 프로세스를 제공하는 것은 대부분 운영 팀에서 담당하게 될 것입니다. + +데이터베이스에 실수를 해서 클러스터의 모든 노드에 복제되거나 화재, 홍수, 피의 시나리오로 인해 클러스터를 더 이상 사용할 수 없게 되어 중요한 데이터가 손실되는 경우를 제외하고는 "고가용성은 내 백업이고, 클러스터에 여러 노드를 구축했으니 절대 다운될 일은 없습니다!"라고 생각하는 것도 좋은 생각일 수 있습니다. 고집을 부리는 것이 아니라 데이터와 서비스를 인식하는 것이 중요하며, 모든 사람이 아키텍처에 고가용성 및 내결함성을 고려해야 하지만 이것이 백업의 필요성을 대체할 수는 없습니다! + +복제는 데이터의 오프사이트 복사본을 제공하는 것처럼 보일 수 있으며, 위에서 언급한 클러스터가 여러 위치에 분산되어 있을 수도 있지만 첫 번째 실수는 여전히 그곳에 복제될 것입니다. 하지만 백업 요구사항은 환경 내에서 애플리케이션 복제 또는 시스템 복제와 함께 고려해야 합니다. + +이제 이 모든 것을 말했듯이 다른 쪽에서도 극단적으로 나아가 너무 많은 위치에 데이터 사본을 전송할 수 있으며, 이는 비용뿐만 아니라 표면 영역이 크게 확장되어 공격받을 위험이 높아집니다. + +어쨌든 백업은 누가 관리하나요? 각 비즈니스마다 다르겠지만 누군가는 백업 요구 사항을 이해해야 합니다. 그리고 복구 계획도 이해해야 합니다! + +### 모두가 신경 쓸 때까지 아무도 신경 쓰지 않습니다. + +백업은 대표적인 예로, 무언가를 복원해야 할 때까지 아무도 백업에 대해 신경 쓰지 않습니다. 데이터를 백업해야 한다는 요구 사항과 함께 복원 방법도 고려해야 합니다! + +텍스트 문서의 예에서는 아주 작은 파일에 대해 이야기하고 있으므로 앞뒤로 복사하는 기능이 쉽고 빠릅니다. 하지만 100GB 이상의 파일에 대해 이야기하는 경우에는 시간이 오래 걸립니다. 또한 가상 머신을 예로 들면 복구해야 하는 수준도 고려해야 합니다. + +전체 가상 머신이 있고 운영 체제, 애플리케이션이 설치되어 있으며 데이터베이스 서버인 경우 일부 데이터베이스 파일도 있습니다. 실수로 데이터베이스에 잘못된 코드 줄을 삽입한 경우 전체 가상 머신을 복원할 필요는 없으며, 복구 대상만 세분화하여 복구하고 싶습니다. + +### 백업 시나리오 + +이제 일부 데이터를 보호하는 시나리오를 구축해 보겠습니다. 특히, 로컬 컴퓨터(이 경우에는 Windows이지만 제가 사용할 도구는 무료 오픈 소스일 뿐만 아니라 크로스 플랫폼도 지원합니다)에서 일부 파일을 보호하고 싶습니다. 집에 로컬로 있는 NAS 장치뿐만 아니라 클라우드의 Object Storage 버킷에도 보호되도록 하고 싶습니다. + +이 중요한 데이터를 백업하고 싶은데, 마침 90DaysOfDevOps의 저장소이기도 하고, 지금 이 글을 읽고 있는 GitHub로도 전송되고 있는데, 만약 내 컴퓨터가 죽고 GitHub가 다운되면 어떻게 될까요? 다른 사람이 어떻게 콘텐츠를 읽을 수 있을 뿐만 아니라 해당 데이터를 다른 서비스로 어떻게 복원할 수 있을까요? + +![](/2022/Days/Images/Day86_Data5.png) + +이를 달성하는 데 도움이 되는 많은 도구가 있지만, 저는 백업을 암호화, 중복 제거 및 압축하는 동시에 여러 위치로 백업을 보낼 수 있는 오픈 소스 백업 도구인 [Kopia](https://kopia.io/)라는 도구를 사용하려고 합니다. + +[여기](https://github.com/kopia/kopia/releases)에서 릴리스를 다운로드할 수 있으며, 이 글을 쓰는 시점에서는 v0.10.6을 사용할 것입니다. + +### Kopia 설치하기 + +Kopia CLI와 GUI가 있는데, 여기서는 GUI를 사용하겠지만 GUI를 제공하지 않는 리눅스 서버의 경우 CLI 버전도 사용할 수 있다는 것을 알고 있습니다. + +저는 `KopiaUI-Setup-0.10.6.exe`를 사용하겠습니다. + +다음번 설치는 매우 빠르게 진행되며, 애플리케이션을 열면 백업 저장소로 사용할 스토리지 유형을 선택할 수 있는 선택 항목이 표시됩니다. + +![](/2022/Days/Images/Day86_Data6.png) + +### 리포지토리 설정하기 + +먼저 로컬 NAS 장치를 사용하여 리포지토리를 설정하고 SMB를 사용하여 이 작업을 수행하려고 하지만 NFS를 사용할 수도 있습니다. + +![](/2022/Days/Images/Day86_Data7.png) + +다음 화면에서는 비밀번호를 정의할 것이며, 이 비밀번호는 리포지토리 콘텐츠를 암호화하는 데 사용됩니다. + +![](/2022/Days/Images/Day86_Data8.png) + +이제 리포지토리가 구성되었으므로 임시 스냅샷을 트리거하여 리포지토리에 데이터 쓰기를 시작할 수 있습니다. + +![](/2022/Days/Images/Day86_Data9.png) + +먼저 스냅샷할 대상의 경로를 입력해야 하며, 여기서는 `90DaysOfDevOps` 폴더의 복사본을 만들고자 합니다. 곧 스케줄링 측면으로 돌아가겠습니다. + +![](/2022/Days/Images/Day86_Data10.png) + +스냅샷 보존을 정의할 수 있습니다. + +![](/2022/Days/Images/Day86_Data11.png) + +제외하려는 파일이나 파일 형식이 있을 수 있습니다. + +![](/2022/Days/Images/Day86_Data12.png) + +일정을 정의하려면 이다음 화면에서 할 수 있으며, 이 스냅샷을 처음 생성할 때 이 페이지가 정의할 첫 페이지입니다. + +![](/2022/Days/Images/Day86_Data13.png) + +그리고 여기에서 처리할 수 있는 몇 가지 다른 설정이 표시됩니다. + +![](/2022/Days/Images/Day86_Data14.png) + +지금 스냅샷을 선택하면 데이터가 리포지토리에 기록됩니다. + +![](/2022/Days/Images/Day86_Data15.png) + +### S3로 오프사이트 백업 + +Kopia에서는 UI를 통해 한 번에 하나의 리포지토리만 구성할 수 있는 것처럼 보입니다. 그러나 UI를 통해 창의력을 발휘하여 여러 리포지토리 구성 파일을 선택하여 로컬 및 오프사이트에 복사본을 오브젝트 스토리지에 저장하려는 목표를 달성할 수 있습니다. + +제가 데이터를 전송하기 위해 선택한 오브젝트 스토리지는 Google 클라우드 스토리지입니다. 먼저 Google 클라우드 플랫폼 계정에 로그인하고 스토리지 버킷을 생성했습니다. 시스템에 이미 구글 클라우드 SDK가 설치되어 있었지만 `gcloud auth application-default login`을 실행하면 계정으로 인증되었습니다. + +![](/2022/Days/Images/Day86_Data16.png) + +그런 다음 Kopia의 CLI를 사용하여 이전 단계에서 SMB 리포지토리를 추가한 후 리포지토리의 현재 상태를 표시했습니다. `C:\Program Files\KopiaUI\resources\server\kopia.exe" --config-file=C:\Users\micha\AppData\Roaming\kopia\repository.config repository status` 명령을 사용하여 이 작업을 수행했습니다. + +![](/2022/Days/Images/Day86_Data17.png) + +이제 데모를 위해 리포지토리에 대한 구성을 교체할 준비가 되었습니다. 이 두 리포지토리에 모두 적용하는 장기적인 솔루션을 원한다면 `smb.config` 파일과 `object.config` 파일을 생성하고 이 두 명령을 실행하여 데이터 사본을 각 위치로 전송할 수 있어야 할 것입니다. 리포지토리를 추가하기 위해 `"C:\Program Files\KopiaUI\resources\server\kopia.exe" --config-file=C:\Users\micha\AppData\Roaming\kopia\repository.config repository create gcs --bucket 90daysofdevops`를 실행합니다. + +위의 명령은 우리가 생성한 구글 클라우드 스토리지 버킷의 이름이 `90daysofdevops`라는 것을 고려합니다. + +![](/2022/Days/Images/Day86_Data18.png) + +이제 새 리포지토리를 생성했으므로 `"C:\Program Files\KopiaUI\resources\server\kopia.exe" --config-file=C:\Users\micha\AppData\Roaming\kopia\repository.config repository status` 명령을 다시 실행하면 이제 GCS 리포지토리 구성이 표시됩니다. + +![](/2022/Days/Images/Day86_Data19.png) + +다음으로 해야 할 일은 스냅샷을 생성하여 새로 생성한 리포지토리로 전송하는 것입니다. `"C:\Program Files\KopiaUI\resources\server\kopia.exe" --config-file=C:\Users\micha\AppData\Roaming\kopia\repository.config kopia snapshot create "C:\Users\micha\demo\90DaysOfDevOps"` 명령을 사용하여 이 프로세스를 시작할 수 있습니다. 아래 브라우저에서 이제 Google 클라우드 스토리지 버킷에 백업에 기반한 kopia 파일이 있는 것을 확인할 수 있습니다. + +![](/2022/Days/Images/Day86_Data20.png) + +위의 프로세스를 통해 중요한 데이터를 두 개의 다른 위치로 전송해야 하는 요구 사항을 해결할 수 있으며, 그중 하나는 Google Cloud Storage의 오프사이트에 있고 물론 다른 미디어 유형에 데이터의 프로덕션 사본이 여전히 있습니다. + +### 복원 + +복원은 또 다른 고려 사항이며 매우 중요한 기능으로, Kopia는 기존 위치뿐만 아니라 새로운 위치로도 복원할 수 있는 기능을 제공합니다. + +`"C:\Program Files\KopiaUI\resources\server\kopia.exe" --config-file=C:\Users\micha\AppData\Roaming\kopia\repository.config snapshot list` 명령을 실행하면 현재 구성된 리포지토리(GCS)에 있는 스냅샷이 나열됩니다. + +![](/2022/Days/Images/Day86_Data21.png) + +그런 다음 `"C:\Program Files\KopiaUI\resources\server\kopia.exe" --config-file=C:\Users\micha\AppData\Roaming\kopia\repository.config mount all Z:` 명령을 사용하여 GCS에서 직접 해당 스냅샷을 마운트할 수 있습니다. + +![](/2022/Days/Images/Day86_Data22.png) + +또한 `kopia snapshot restore kdbd9dff738996cfe7bcf99b45314e193`을 사용하여 스냅샷 내용을 복원할 수도 있습니다. + +위의 명령어가 매우 긴데, 이는 실습 상단에 설명한 대로 KopiaUI 버전의 kopia.exe를 사용했기 때문이며, kopia.exe를 다운로드하여 경로에 넣으면 `kopia` 명령어만 사용하면 됩니다. + +다음 세션에서는 Kubernetes 내에서 워크로드를 보호하는 데 중점을 두겠습니다. + +## 자료 + +- [Kubernetes Backup and Restore made easy!](https://www.youtube.com/watch?v=01qcYSck1c4&t=217s) +- [Kubernetes Backups, Upgrades, Migrations - with Velero](https://www.youtube.com/watch?v=zybLTQER0yY) +- [7 Database Paradigms](https://www.youtube.com/watch?v=W2Z7fbCLSTw&t=520s) +- [Disaster Recovery vs. Backup: What's the difference?](https://www.youtube.com/watch?v=07EHsPuKXc0) +- [Veeam Portability & Cloud Mobility](https://www.youtube.com/watch?v=hDBlTdzE6Us&t=3s) + +[Day 87](day87.md)에서 봐요! diff --git a/2022/ko/Days/day87.md b/2022/ko/Days/day87.md new file mode 100644 index 0000000..a3f8dc3 --- /dev/null +++ b/2022/ko/Days/day87.md @@ -0,0 +1,190 @@ +--- +title: '#90DaysOfDevOps - Hands-On Backup & Recovery - Day 87' +published: false +description: 90DaysOfDevOps - Hands-On Backup & Recovery +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048717 +--- + +## 백업 및 복구 실습 + +지난 세션에서는 로컬 NAS와 클라우드 기반 오브젝트 스토리지에 중요한 데이터를 백업하는 데 사용한 오픈소스 백업 도구인 [Kopia](https://kopia.io/)에 대해 살펴봤습니다. + +이번 섹션에서는 Kubernetes 백업의 세계로 들어가 보겠습니다. 이 플랫폼은 챌린지 초반에 [큰 그림: Kubernetes](/2022/Days/Days/day49.md)에서 다뤘던 플랫폼입니다. + +이번에도 Minikube 클러스터를 사용하지만, 이번에는 사용 가능한 몇 가지 애드온을 활용하겠습니다. + +### Kubernetes 클러스터 설정 + +Minikube 클러스터를 설정하기 위해 `minikube start --addons volumesnapshots,csi-hostpath-driver --apiserver-port=6443 --container-runtime=containerd -p 90daysofdevops --kubernetes-version=1.21.2`를 실행하면 백업을 수행할 때 이를 최대한 활용하기 위해 `volumesnapshots` 및 `csi-hostpath-driver`를 사용하고 있는 것을 알 수 있습니다. + +이 시점에서는 아직 Kasten K10을 배포하지 않았지만, 클러스터가 가동되면 다음 명령을 실행하여 Kasten K10이 이를 사용할 수 있도록 volumesnapshotclass에 주석을 달려고 합니다. + +```Shell +kubectl annotate volumesnapshotclass csi-hostpath-snapclass \ + k10.kasten.io/is-snapshot-class=true +``` + +또한 다음을 사용하여 기본 저장소 클래스를 표준 기본 저장소 클래스에서 csi-hostpath 저장소 클래스로 변경할 것입니다. + +```Shell +kubectl patch storageclass csi-hostpath-sc -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' + +kubectl patch storageclass standard -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}' +``` + +![](/2022/Days/Images/Day87_Data1.png) + +### Kasten K10 배포하기 + +Kasten Helm 리포지토리를 추가합니다. + +`helm repo add kasten https://charts.kasten.io/` + +여기에서도 `arkade kasten install k10`을 사용할 수 있지만 데모를 위해 다음 단계를 진행하겠습니다. [자세한 내용](https://blog.kasten.io/kasten-k10-goes-to-the-arkade) + +네임스페이스를 생성하고 K10을 배포합니다.(약 5분 정도 소요됨) + +`helm install k10 kasten/k10 --namespace=kasten-io --set auth.tokenAuth.enabled=true --set injectKanisterSidecar.enabled=true --set-string injectKanisterSidecar.namespaceSelector.matchLabels.k10/injectKanisterSidecar=true --create-namespace` + +![](/2022/Days/Images/Day87_Data1.png) + +다음 명령어를 실행하여 pod가 생성되는 것을 확인할 수 있습니다. + +`kubectl get pods -n kasten-io -w` + +![](/2022/Days/Images/Day87_Data3.png) + +포트 포워딩을 통해 K10 대시보드에 접속하고, 새 터미널을 열어 아래 명령을 실행합니다. + +`kubectl --namespace kasten-io port-forward service/gateway 8080:8000` + +Kasten 대시보드는 `http://127.0.0.1:8080/k10/#/`에서 사용할 수 있습니다. + +![](/2022/Days/Images/Day87_Data4.png) + +이제 대시보드로 인증하려면 다음 명령어로 얻을 수 있는 토큰이 필요합니다. + +```Shell +TOKEN_NAME=$(kubectl get secret --namespace kasten-io|grep k10-k10-token | cut -d " " -f 1) +TOKEN=$(kubectl get secret --namespace kasten-io $TOKEN_NAME -o jsonpath="{.data.token}" | base64 --decode) + +echo "Token value: " +echo $TOKEN +``` + +![](/2022/Days/Images/Day87_Data5.png) + +이제 이 토큰을 가져와 브라우저에 입력하면 이메일과 회사 이름을 입력하라는 메시지가 표시됩니다. + +![](/2022/Days/Images/Day87_Data6.png) + +그러면 Kasten K10 대시보드에 액세스할 수 있습니다. + +![](/2022/Days/Images/Day87_Data7.png) + +### stateful 애플리케이션 배포 + +Kubernetes 섹션에서 사용한 stateful 애플리케이션을 사용합니다. + +![](/2022/Days/Images/Day55_Kubernetes1.png) + +이 애플리케이션의 YAML 구성 파일은 여기에서 찾을 수 있습니다. -> [pacman-stateful-demo.yaml](/2022/Days/Kubernetes/pacman-stateful-demo.yaml) + +![](/2022/Days/Images/Day87_Data8.png) + +`kubectl get all -n pacman`을 사용하여 다가오는 pod를 확인할 수 있습니다. + +![](/2022/Days/Images/Day87_Data9.png) + +그런 다음 새 터미널에서 pacman 프론트엔드를 포트 포워드할 수 있습니다. `kubectl port-forward svc/pacman 9090:80 -n pacman`을 실행합니다. + +브라우저에서 다른 탭을 열어 http://localhost:9090/ 에접속합니다. + +![](/2022/Days/Images/Day87_Data10.png) + +시간을 내어 백엔드 MongoDB 데이터베이스에서 높은 점수를 기록하세요. + +![](/2022/Days/Images/Day87_Data11.png) + +### 높은 점수 보호 + +이제 데이터베이스에 미션 크리티컬한 데이터가 있으며 이를 잃고 싶지 않습니다. 이 전체 애플리케이션을 보호하기 위해 Kasten K10을 사용할 수 있습니다. + +Kasten K10 대시보드 탭으로 돌아가면 Kubernetes 클러스터에 pacman 애플리케이션이 추가되어 애플리케이션 수가 1개에서 2개로 늘어난 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day87_Data12.png) + +애플리케이션 카드를 클릭하면 클러스터에서 자동으로 검색된 애플리케이션을 볼 수 있습니다. + +![](/2022/Days/Images/Day87_Data13.png) + +Kasten K10을 사용하면 스토리지 기반 스냅샷을 활용할 수 있을 뿐만 아니라 사본을 오브젝트 스토리지 옵션으로 내보낼 수도 있습니다. + +데모에서는 클러스터에 수동 스토리지 스냅샷을 생성한 다음, 고득점 데이터에 불량 데이터를 추가하여 실수로 실수하는 상황을 시뮬레이션해 보겠습니다. + +먼저 아래의 수동 스냅샷 옵션을 사용할 수 있습니다. + +![](/2022/Days/Images/Day87_Data14.png) + +데모에서는 모든 것을 기본값으로 두겠습니다. + +![](/2022/Days/Images/Day87_Data15.png) + +대시보드로 돌아가면 실행 중인 작업에 대한 상태 보고서가 표시되며, 완료되면 이와 같이 성공적으로 표시됩니다. + +![](/2022/Days/Images/Day87_Data16.png) + +### 실패 시나리오 + +이제 애플리케이션에 규범적인 잘못된 변경을 추가하기만 하면 미션 크리티컬 데이터에 치명적인 변경을 수행할 수 있습니다. + +아래에서 볼 수 있듯이, 프로덕션 미션 크리티컬 데이터베이스에는 원하지 않는 두 가지 입력이 있습니다. + +![](/2022/Days/Images/Day87_Data17.png) + +### 데이터 복원 + +이것은 간단한 데모이며 현실적이지 않은 방식이지만 데이터베이스를 삭제하는 것이 얼마나 쉬운지 보셨나요? + +이제 고득점 목록을 실수하기 전의 상태로 조금 더 깔끔하게 정리해 보겠습니다. + +애플리케이션 카드와 pacman 탭으로 돌아가면 이제 복원할 수 있는 복원 지점이 하나 생겼습니다. + +![](/2022/Days/Images/Day87_Data18.png) + +복원을 선택하면 해당 애플리케이션에 연결된 모든 스냅샷과 내보내기를 볼 수 있습니다. + +![](/2022/Days/Images/Day87_Data19.png) + +복원을 선택하면 사이드 창이 나타나며, 기본 설정을 유지하고 복원을 누릅니다. + +![](/2022/Days/Images/Day87_Data20.png) + +복원할 것인지 확인합니다. + +![](/2022/Days/Images/Day87_Data21.png) + +그런 다음 대시보드로 돌아가서 복원 진행 상황을 확인할 수 있습니다. 다음과 같은 화면이 표시됩니다. + +![](/2022/Days/Images/Day87_Data22.png) + +하지만 더 중요한 것은 미션 크리티컬 애플리케이션에서 고점수 목록이 어떻게 보이는지입니다. 앞서 다룬 대로 pacman으로 포트 포워딩을 다시 시작해야 합니다. + +![](/2022/Days/Images/Day87_Data23.png) + +매우 간단한 데모이며, 백업과 관련하여 Kasten K10이 달성할 수 있는 것의 표면적인 부분만 다루었습니다. 앞으로 이러한 영역 중 일부에 대해 좀 더 심층적인 비디오 콘텐츠를 제작할 예정입니다. 또한 재해 복구 및 데이터의 이동성과 관련하여 데이터 관리와 관련된 몇 가지 다른 주요 영역을 강조하기 위해 Kasten K10을 사용할 것입니다. + +다음에는 애플리케이션 일관성에 대해 살펴보겠습니다. + +## 자료 + +- [Kubernetes Backup and Restore made easy!](https://www.youtube.com/watch?v=01qcYSck1c4&t=217s) +- [Kubernetes Backups, Upgrades, Migrations - with Velero](https://www.youtube.com/watch?v=zybLTQER0yY) +- [7 Database Paradigms](https://www.youtube.com/watch?v=W2Z7fbCLSTw&t=520s) +- [Disaster Recovery vs. Backup: What's the difference?](https://www.youtube.com/watch?v=07EHsPuKXc0) +- [Veeam Portability & Cloud Mobility](https://www.youtube.com/watch?v=hDBlTdzE6Us&t=3s) + +[Day 88](day88.md)에서 봐요! diff --git a/2022/ko/Days/day88.md b/2022/ko/Days/day88.md new file mode 100644 index 0000000..d9ce6df --- /dev/null +++ b/2022/ko/Days/day88.md @@ -0,0 +1,296 @@ +--- +title: '#90DaysOfDevOps - Application Focused Backup - Day 88' +published: false +description: 90DaysOfDevOps - Application Focused Backups +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048749 +--- + +## 애플리케이션 중심 백업 + +데이터 서비스 또는 데이터베이스와 같은 데이터 집약적인 애플리케이션에 대해서는 이미 [day 85](day85.md)에서 설명한 바 있습니다. 이러한 데이터 서비스의 경우 특히 애플리케이션 일관성과 관련하여 일관성을 관리하는 방법을 고려해야 합니다. + +이 글에서는 애플리케이션 데이터를 일관되게 보호하는 것과 관련된 요구 사항을 자세히 살펴보겠습니다. + +이를 위해 우리가 선택한 도구는 [Kanister](https://kanister.io/)입니다. + +![](/2022/Days/Images/Day88_Data1.png) + +### Kanister 소개 + +Kanister는 Kasten이 만든 오픈소스 프로젝트로, Kubernetes에서 애플리케이션 데이터를 관리(백업 및 복원)할 수 있게 해줍니다. Kanister를 Helm 애플리케이션으로 Kubernetes 클러스터에 배포할 수 있습니다. + +Kanister는 Kubernetes 커스텀 리소스를 사용하며, Kanister를 배포할 때 설치되는 주요 커스텀 리소스는 다음과 같습니다. + +- `Profile` - 백업을 저장하고 복구할 대상 위치입니다. 가장 일반적으로는 오브젝트 스토리지입니다. +- `Blueprint` - 데이터베이스를 백업 및 복구하기 위해 수행해야 하는 단계가 Blueprint에 유지되어야 합니다. +- `ActionSet` - 대상 백업을 Profile로 이동하고 복원 작업을 수행하는 동작입니다. + +### 실행 연습 + +실습에 들어가기 전에 Kanister가 애플리케이션 데이터를 보호하기 위해 취하는 워크플로우를 살펴보겠습니다. 먼저 컨트롤러를 Helm을 사용하여 Kubernetes 클러스터에 배포하고, Kanister는 해당 네임스페이스 내에 위치합니다. 커뮤니티에서 지원하는 많은 Blueprint를 사용할 수 있으며, 이에 대해서는 곧 자세히 다루겠습니다. 그런 다음 데이터베이스 워크로드가 있습니다. + +![](/2022/Days/Images/Day88_Data2.png) + +이제 ActionSet을 생성합니다. + +![](/2022/Days/Images/Day88_Data3.png) + +ActionSet을 사용하면 특정 데이터 서비스에 대해 Blueprint에 정의된 액션을 실행할 수 있습니다. + +![](/2022/Days/Images/Day88_Data4.png) + +ActionSet은 차례로 Kanister 함수(KubeExec, KubeTask, 리소스 라이프사이클)를 사용하여 백업을 대상 리포지토리(Profile)로 push합니다. + +![](/2022/Days/Images/Day88_Data5.png) + +해당 작업이 완료/실패하면 해당 상태가 ActionSet에서 업데이트됩니다. + +![](/2022/Days/Images/Day88_Data6.png) + +### Kanister 배포 + +이번에도 Minikube 클러스터를 사용하여 애플리케이션 백업을 수행합니다. 이전 세션에서 계속 실행 중이라면 이 클러스터를 계속 사용할 수 있습니다. + +이 글을 쓰는 시점에, 우리는 다음 Helm 명령으로 이미지 버전 `0.75.0`을 사용하여 Kubernetes 클러스터에 kanister를 설치합니다. + +`helm install kanister --namespace kanister kanister/kanister-operator --set image.tag=0.75.0 --create-namespace` + +![](/2022/Days/Images/Day88_Data7.png) + +`kubectl get pods -n kanister`를 사용하여 pod가 실행 중인지 확인한 다음 사용자 정의 리소스 정의가 사용 가능한지 확인할 수 있습니다.(Kanister만 설치한 경우 강조 표시된 3이 표시됩니다.) + +![](/2022/Days/Images/Day88_Data8.png) + +### 데이터베이스 배포하기 + +Helm을 통해 MySQL을 배포합니다: + +```Shell +APP_NAME=my-production-app +kubectl create ns ${APP_NAME} +helm repo add bitnami https://charts.bitnami.com/bitnami +helm install mysql-store bitnami/mysql --set primary.persistence.size=1Gi,volumePermissions.enabled=true --namespace=${APP_NAME} +kubectl get pods -n ${APP_NAME} -w +``` + +![](/2022/Days/Images/Day88_Data9.png) + +초기 데이터로 MySQL 데이터베이스를 채우고 다음을 실행합니다: + +```Shell +MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace ${APP_NAME} mysql-store -o jsonpath="{.data.mysql-root-password}" | base64 --decode) +MYSQL_HOST=mysql-store.${APP_NAME}.svc.cluster.local +MYSQL_EXEC="mysql -h ${MYSQL_HOST} -u root --password=${MYSQL_ROOT_PASSWORD} -DmyImportantData -t" +echo MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} +``` + +### MySQL 클라이언트 생성하기 + +클라이언트 역할을 할 다른 컨테이너 이미지를 실행합니다. + +```Shell +APP_NAME=my-production-app +kubectl run mysql-client --rm --env APP_NS=${APP_NAME} --env MYSQL_EXEC="${MYSQL_EXEC}" --env MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} --env MYSQL_HOST=${MYSQL_HOST} --namespace ${APP_NAME} --tty -i --restart='Never' --image docker.io/bitnami/mysql:latest --command -- bash +``` + +```Shell +참고: 이미 기존 MySQL 클라이언트 pod가 실행 중인 경우 다음 명령으로 삭제하세요. + +kubectl delete pod -n ${APP_NAME} mysql-client +``` + +### MySQL에 데이터 추가하기 + +```Shell +echo "create database myImportantData;" | mysql -h ${MYSQL_HOST} -u root --password=${MYSQL_ROOT_PASSWORD} +MYSQL_EXEC="mysql -h ${MYSQL_HOST} -u root --password=${MYSQL_ROOT_PASSWORD} -DmyImportantData -t" +echo "drop table Accounts" | ${MYSQL_EXEC} +echo "create table if not exists Accounts(name text, balance integer); insert into Accounts values('nick', 0);" | ${MYSQL_EXEC} +echo "insert into Accounts values('albert', 112);" | ${MYSQL_EXEC} +echo "insert into Accounts values('alfred', 358);" | ${MYSQL_EXEC} +echo "insert into Accounts values('beatrice', 1321);" | ${MYSQL_EXEC} +echo "insert into Accounts values('bartholomew', 34);" | ${MYSQL_EXEC} +echo "insert into Accounts values('edward', 5589);" | ${MYSQL_EXEC} +echo "insert into Accounts values('edwin', 144);" | ${MYSQL_EXEC} +echo "insert into Accounts values('edwina', 233);" | ${MYSQL_EXEC} +echo "insert into Accounts values('rastapopoulos', 377);" | ${MYSQL_EXEC} +echo "select * from Accounts;" | ${MYSQL_EXEC} +exit +``` + +아래와 같은 데이터를 볼 수 있을 것입니다. + +![](/2022/Days/Images/Day88_Data10.png) + +### Kanister Profile 생성 + +Kanister는 Blueprint와 이 두 유틸리티를 통해 오브젝트 스토리지 공급자와 상호작용할 수 있는 CLI인 `kanctl`과 또 다른 유틸리티인 `kando`를 제공합니다. + +[CLI 다운로드](https://docs.kanister.io/tooling.html#tooling) + +이제 Profile 대상과 복원 위치로 사용할 AWS S3 버킷을 생성했습니다. 환경 변수를 사용하여 `kanctl`로 실행하는 명령을 계속 보여드릴 수 있도록 환경 변수를 사용하여 kanister Profile을 생성하겠습니다. + +`kanctl create profile s3compliant --access-key $ACCESS_KEY --secret-key $SECRET_KEY --bucket $BUCKET --region eu-west-2 --namespace my-production-app` + +![](/2022/Days/Images/Day88_Data11.png) + +### Blueprint 시간 + +[Kanister 예제](https://github.com/kanisterio/kanister/tree/master/examples)에 나열되어 있지 않은 데이터 서비스가 아니라면 처음부터 만들 필요는 없지만, 커뮤니티 기여를 통해 이 프로젝트의 인지도를 높일 수 있습니다. + +우리가 사용할 Blueprint는 아래와 같습니다. + +```Shell +apiVersion: cr.kanister.io/v1alpha1 +kind: Blueprint +metadata: + name: mysql-blueprint +actions: + backup: + outputArtifacts: + mysqlCloudDump: + keyValue: + s3path: "{{ .Phases.dumpToObjectStore.Output.s3path }}" + phases: + - func: KubeTask + name: dumpToObjectStore + objects: + mysqlSecret: + kind: Secret + name: '{{ index .Object.metadata.labels "app.kubernetes.io/instance" }}' + namespace: '{{ .StatefulSet.Namespace }}' + args: + image: ghcr.io/kanisterio/mysql-sidecar:0.75.0 + namespace: "{{ .StatefulSet.Namespace }}" + command: + - bash + - -o + - errexit + - -o + - pipefail + - -c + - | + s3_path="/mysql-backups/{{ .StatefulSet.Namespace }}/{{ index .Object.metadata.labels "app.kubernetes.io/instance" }}/{{ toDate "2006-01-02T15:04:05.999999999Z07:00" .Time | date "2006-01-02T15-04-05" }}/dump.sql.gz" + root_password="{{ index .Phases.dumpToObjectStore.Secrets.mysqlSecret.Data "mysql-root-password" | toString }}" + mysqldump --column-statistics=0 -u root --password=${root_password} -h {{ index .Object.metadata.labels "app.kubernetes.io/instance" }} --single-transaction --all-databases | gzip - | kando location push --profile '{{ toJson .Profile }}' --path ${s3_path} - + kando output s3path ${s3_path} + restore: + inputArtifactNames: + - mysqlCloudDump + phases: + - func: KubeTask + name: restoreFromBlobStore + objects: + mysqlSecret: + kind: Secret + name: '{{ index .Object.metadata.labels "app.kubernetes.io/instance" }}' + namespace: '{{ .StatefulSet.Namespace }}' + args: + image: ghcr.io/kanisterio/mysql-sidecar:0.75.0 + namespace: "{{ .StatefulSet.Namespace }}" + command: + - bash + - -o + - errexit + - -o + - pipefail + - -c + - | + s3_path="{{ .ArtifactsIn.mysqlCloudDump.KeyValue.s3path }}" + root_password="{{ index .Phases.restoreFromBlobStore.Secrets.mysqlSecret.Data "mysql-root-password" | toString }}" + kando location pull --profile '{{ toJson .Profile }}' --path ${s3_path} - | gunzip | mysql -u root --password=${root_password} -h {{ index .Object.metadata.labels "app.kubernetes.io/instance" }} + delete: + inputArtifactNames: + - mysqlCloudDump + phases: + - func: KubeTask + name: deleteFromBlobStore + args: + image: ghcr.io/kanisterio/mysql-sidecar:0.75.0 + namespace: "{{ .Namespace.Name }}" + command: + - bash + - -o + - errexit + - -o + - pipefail + - -c + - | + s3_path="{{ .ArtifactsIn.mysqlCloudDump.KeyValue.s3path }}" + kando location delete --profile '{{ toJson .Profile }}' --path ${s3_path} +``` + +이를 추가하기 위해 `kubectl create -f mysql-blueprint.yml -n kanister` 명령을 사용합니다. + +![](/2022/Days/Images/Day88_Data12.png) + +### ActionSet을 생성하고 애플리케이션 보호하기 + +이제 이 애플리케이션에 대한 백업을 정의하는 ActionSet을 사용하여 MySQL 데이터의 백업을 수행하겠습니다. 컨트롤러와 동일한 네임스페이스에 ActionSet을 생성합니다. + +`kubectl get profiles.cr.kanister.io -n my-production-app` 명령은 이전에 생성한 Profile을 표시하며, 여기에 여러 Profile을 구성할 수 있으므로 다른 ActionSet에 특정 Profile을 사용할 수 있습니다. + +그런 다음 `kanctl`을 사용하여 다음 명령으로 ActionSet을 생성합니다. + +`kanctl create actionset --action backup --namespace kanister --blueprint mysql-blueprint --statefulset my-production-app/mysql-store --profile my-production-app/s3-profile-dc5zm --secrets mysql=my-production-app/mysql-store` + +위의 명령에서 네임스페이스에 추가한 Blueprint, `my-production-app` 네임스페이스의 statefulset, 그리고 MySQL 애플리케이션에 들어가기 위한 시크릿을 정의하고 있음을 알 수 있습니다. + +![](/2022/Days/Images/Day88_Data13.png) + +ActionSet 이름을 가져와서 다음 명령 `kubectl --namespace kanister describe actionset backup-qpnqv`를 사용하여 ActionSet의 상태를 확인합니다. + +마지막으로, 이제 AWS S3 버킷에 데이터가 있는지 확인할 수 있습니다. + +![](/2022/Days/Images/Day88_Data14.png) + +### 복원 + +복원하기 전에 약간의 손상을 입혀야 합니다. 테이블을 drop할 수도 있고, 실수일 수도 있고 그렇지 않을 수도 있습니다. + +MySQL pod에 연결합니다. + +```Shell +APP_NAME=my-production-app +kubectl run mysql-client --rm --env APP_NS=${APP_NAME} --env MYSQL_EXEC="${MYSQL_EXEC}" --env MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} --env MYSQL_HOST=${MYSQL_HOST} --namespace ${APP_NAME} --tty -i --restart='Never' --image docker.io/bitnami/mysql:latest --command -- bash +``` + +중요 데이터 DB는 `echo "SHOW DATABASES;" | ${mysql_exec}`로 확인할 수 있습니다. + +그런 다음 drop하기 위해 `echo "DROP DATABASE myImportantData;" | ${mysql_exec}`를 실행했습니다. + +그리고 데이터베이스를 보여주기 위해 몇 번의 시도를 통해 이것이 사라진 것을 확인했습니다. + +![](/2022/Days/Images/Day88_Data15.png) + +이제 Kanister를 사용하여 `kubectl get actionset -n kanister`를 사용하여 앞서 가져 온 ActionSet 이름을 찾아 중요한 데이터를 다시 가져올 수 있습니다. 그런 다음 `kanctl create actionset -n kanister --action restore --from "backup-qpnqv"`를 사용하여 데이터를 복원하기 위한 복원 ActionSet을 생성합니다. + +![](/2022/Days/Images/Day88_Data16.png) + +아래 명령어를 사용하여 데이터베이스에 연결하면 데이터가 복구되었는지 확인할 수 있습니다. + +```Shell +APP_NAME=my-production-app +kubectl run mysql-client --rm --env APP_NS=${APP_NAME} --env MYSQL_EXEC="${MYSQL_EXEC}" --env MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD} --env MYSQL_HOST=${MYSQL_HOST} --namespace ${APP_NAME} --tty -i --restart='Never' --image docker.io/bitnami/mysql:latest --command -- bash +``` + +이제 MySQL 클라이언트에 들어가서 `echo "SHOW DATABASES;" | ${MYSQL_EXEC}`를 실행하면 데이터베이스가 다시 돌아온 것을 확인할 수 있습니다. 또한 `"select * from Accounts;" | ${MYSQL_EXEC}`를 실행하여 데이터베이스의 내용을 확인할 수 있으며 중요한 데이터가 복원되었습니다. + +![](/2022/Days/Images/Day88_Data17.png) + +다음 포스트에서는 Kubernetes 내의 재해 복구에 대해 살펴보겠습니다. + +## 자료 + +- [Kanister Overview - An extensible open-source framework for app-lvl data management on Kubernetes](https://www.youtube.com/watch?v=wFD42Zpbfts) +- [Application Level Data Operations on Kubernetes](https://community.cncf.io/events/details/cncf-cncf-online-programs-presents-cncf-live-webinar-kanister-application-level-data-operations-on-kubernetes/) +- [Kubernetes Backup and Restore made easy!](https://www.youtube.com/watch?v=01qcYSck1c4&t=217s) +- [Kubernetes Backups, Upgrades, Migrations - with Velero](https://www.youtube.com/watch?v=zybLTQER0yY) +- [7 Database Paradigms](https://www.youtube.com/watch?v=W2Z7fbCLSTw&t=520s) +- [Disaster Recovery vs. Backup: What's the difference?](https://www.youtube.com/watch?v=07EHsPuKXc0) +- [Veeam Portability & Cloud Mobility](https://www.youtube.com/watch?v=hDBlTdzE6Us&t=3s) + +[Day 89](day89.md)에서 봐요! diff --git a/2022/ko/Days/day89.md b/2022/ko/Days/day89.md new file mode 100644 index 0000000..87e0328 --- /dev/null +++ b/2022/ko/Days/day89.md @@ -0,0 +1,221 @@ +--- +title: '#90DaysOfDevOps - Disaster Recovery - Day 89' +published: false +description: 90DaysOfDevOps - Disaster Recovery +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048718 +--- + +## 재해 복구 + +장애 시나리오에 따라 복구 요구 사항이 어떻게 달라지는지 이미 언급했습니다. 화재, 홍수, 피의 시나리오의 경우 대부분 재해 상황으로, 워크로드를 완전히 다른 위치에서 가능한 한 빨리 가동하거나 최소한 복구 시간 목표(RTO)를 거의 0에 가깝게 설정해야 할 수 있습니다. + +이는 전체 애플리케이션 스택을 standby 환경으로 복제하는 작업을 자동화할 때만 대규모로 달성할 수 있습니다. + +이를 통해 클라우드 리전, 클라우드 제공업체 간 또는 온프레미스와 클라우드 인프라 간에 빠른 페일오버를 수행할 수 있습니다. + +지금까지의 주제에 따라 몇 세션 전에 배포하고 구성한 Minikube 클러스터를 사용하여 Kasten K10을 사용하여 이를 달성하는 방법에 대해 집중적으로 살펴보겠습니다. + +그런 다음 이론상 어느 위치에서나 standby 클러스터 역할을 할 수 있는 또 다른 Minikube 클러스터를 Kasten K10을 설치하여 생성할 것입니다. + +Kasten K10은 또한 실행 중인 Kubernetes 클러스터에 문제가 발생할 경우 카탈로그 데이터를 복제하여 새 클러스터에서 사용할 수 있도록 하는 기능을 내장하고 있습니다. [K10 재해 복구](https://docs.kasten.io/latest/operating/dr.html). + +### K10에 오브젝트 스토리지 추가 + +가장 먼저 해야 할 일은 백업을 위한 대상 위치로 오브젝트 스토리지 버킷을 추가하는 것입니다. 이것은 오프사이트 위치 역할을 할 뿐만 아니라 복구할 재해 복구 소스 데이터로도 활용할 수 있습니다. + +지난 세션에서 Kanister 데모를 위해 생성한 S3 버킷을 정리했습니다. + +![](/2022/Days/Images/Day89_Data1.png) + +포트 포워딩을 통해 K10 대시보드에 접속하고 새 터미널을 열어 아래 명령을 실행합니다: + +`kubectl --namespace kasten-io port-forward service/gateway 8080:8000` + +Kasten 대시보드는 `http://127.0.0.1:8080/k10/#/`에서 확인할 수 있습니다. + +![](/2022/Days/Images/Day87_Data4.png) + +대시보드로 인증하려면 이제 다음 명령으로 얻을 수 있는 토큰이 필요합니다. + +```Shell +TOKEN_NAME=$(kubectl get secret --namespace kasten-io|grep k10-k10-token | cut -d " " -f 1) +TOKEN=$(kubectl get secret --namespace kasten-io $TOKEN_NAME -o jsonpath="{.data.token}" | base64 --decode) + +echo "Token value: " +echo $TOKEN +``` + +![](/2022/Days/Images/Day87_Data5.png) + +이제 이 토큰을 가져와 브라우저에 입력하면 이메일과 회사 이름을 입력하라는 메시지가 표시됩니다. + +![](/2022/Days/Images/Day87_Data6.png) + +그러면 Kasten K10 대시보드에 액세스할 수 있습니다. + +![](/2022/Days/Images/Day87_Data7.png) + +이제 Kasten K10 대시보드로 돌아왔으므로 location profile을 추가하고 페이지 상단의 "Settings"와 "New Profile"을 선택합니다. + +![](/2022/Days/Images/Day89_Data2.png) + +아래 이미지에서 이 location profile의 위치를 선택할 수 있는 것을 볼 수 있으며, Amazon S3를 선택하고 민감한 액세스 자격 증명, 지역 및 버킷 이름을 추가할 것입니다. + +![](/2022/Days/Images/Day89_Data3.png) + +새 프로필 생성 창을 아래로 스크롤하면 S3 Object Lock API를 활용하는 변경 불가능한 백업도 활성화할 수 있다는 것을 알 수 있습니다. 이 데모에서는 이 기능을 사용하지 않겠습니다. + +![](/2022/Days/Images/Day89_Data4.png) + +"Save Profile"을 누르면 아래와 같이 새로 생성되거나 추가된 location profile을 볼 수 있습니다. + +![](/2022/Days/Images/Day89_Data5.png) + +### pacman 앱을 오브젝트 스토리지에 보호하는 정책 만들기 + +이전 세션에서는 pacman 애플리케이션의 임시 스냅샷만 만들었으므로 애플리케이션 백업을 새로 생성한 오브젝트 스토리지 위치로 전송하는 백업 정책을 만들어야 합니다. + +대시보드로 돌아가서 정책 카드를 선택하면 아래와 같은 화면이 표시됩니다. "Create New Policy"를 선택합니다. + +![](/2022/Days/Images/Day89_Data6.png) + +먼저 정책에 유용한 이름과 설명을 지정할 수 있습니다. 또한 on-demand로 사용하는 데모 용도로 백업 빈도를 정의할 수도 있습니다. + +![](/2022/Days/Images/Day89_Data7.png) + +다음으로 스냅샷 내보내기를 통해 백업을 활성화하여 데이터를 location profile로 내보내려고 합니다. location profile이 여러 개 있는 경우 백업을 전송할 위치를 선택할 수 있습니다. + +![](/2022/Days/Images/Day89_Data8.png) + +다음으로 이름 또는 레이블로 애플리케이션을 선택하는데, 저는 이름과 모든 리소스를 기준으로 선택하겠습니다. + +![](/2022/Days/Images/Day89_Data9.png) + +고급 설정에서는 이 중 어떤 것도 사용하지 않을 것이지만, 어제 작성한 [Kanister 사용법](https://github.com/MichaelCade/90DaysOfDevOps/blob/main/Days/day88.md)에 따라 Kasten K10의 일부로 Kanister를 활용하여 데이터의 애플리케이션 일관된 사본을 가져올 수 있습니다. + +![](/2022/Days/Images/Day89_Data10.png) + +마지막으로 "Create Policy"을 선택하면 이제 정책 창에서 정책을 볼 수 있습니다. + +![](/2022/Days/Images/Day89_Data11.png) + +생성된 정책의 맨 아래에는 "Show import details"가 있는데, standby 클러스터로 import하기 위해서는 이 문자열이 필요합니다. 지금은 안전한 곳에 복사하세요. + +![](/2022/Days/Images/Day89_Data12.png) + +계속 진행하기 전에 "run once"을 선택하여 개체 스토리지 버킷으로 백업을 전송하기만 하면 됩니다. + +![](/2022/Days/Images/Day89_Data13.png) + +아래 스크린샷은 데이터 백업 및 내보내기가 성공적으로 완료된 것을 보여드리기 위한 것입니다. + +![](/2022/Days/Images/Day89_Data14.png) + +### 새 MiniKube 클러스터 생성 및 K10 배포 + +그런 다음 두 번째 Kubernetes 클러스터를 배포해야 하며, OpenShift를 포함하여 지원되는 모든 버전의 Kubernetes가 될 수 있지만 교육용으로는 다른 이름의 무료 버전의 MiniKube를 사용하겠습니다. + +`minikube start --addons volumesnapshots,csi-hostpath-driver --apiserver-port=6443 --container-runtime=containerd -p standby --kubernetes-version=1.21.2`를 사용하여 새 클러스터를 생성할 수 있습니다. + +![](/2022/Days/Images/Day89_Data15.png) + +그리고 다음을 사용하여 이 클러스터에 Kasten K10을 배포할 수 있습니다: + +`helm install k10 kasten/k10 --namespace=kasten-io --set auth.tokenAuth.enabled=true --set injectKanisterSidecar.enabled=true --set-string injectKanisterSidecar.namespaceSelector.matchLabels.k10/injectKanisterSidecar=true --create-namespace` + +이 작업에는 시간이 걸리겠지만, 그동안 `kubectl get pods -n kasten-io -w`를 사용하여 pod가 실행 상태가 되는 진행 상황을 확인할 수 있습니다. + +Minikube를 사용하고 있기 때문에 import 정책을 실행할 때 애플리케이션이 실행되며, 이 standby 클러스터에서 스토리지 클래스가 동일하다는 점에 주목할 필요가 있습니다. 그러나 마지막 세션에서 다룰 내용은 이동성과 변환입니다. + +pod가 가동되고 실행되면 다른 클러스터에서 이전 단계에서 수행한 단계를 따를 수 있습니다. + +포트 포워딩을 통해 K10 대시보드에 액세스하고 새 터미널을 열어 아래 명령을 실행합니다. + +`kubectl --namespace kasten-io port-forward service/gateway 8080:8000` + +Kasten 대시보드는 `http://127.0.0.1:8080/k10/#/`에서 확인할 수 있습니다. + +![](/2022/Days/Images/Day87_Data4.png) + +대시보드로 인증하려면 이제 다음 명령으로 얻을 수 있는 토큰이 필요합니다. + +```Shell +TOKEN_NAME=$(kubectl get secret --namespace kasten-io|grep k10-k10-token | cut -d " " -f 1) +TOKEN=$(kubectl get secret --namespace kasten-io $TOKEN_NAME -o jsonpath="{.data.token}" | base64 --decode) + +echo "Token value: " +echo $TOKEN +``` + +![](/2022/Days/Images/Day87_Data5.png) + +이제 이 토큰을 가져와 브라우저에 입력하면 이메일과 회사 이름을 입력하라는 메시지가 표시됩니다. + +![](/2022/Days/Images/Day87_Data6.png) + +그러면 Kasten K10 대시보드에 액세스할 수 있습니다. + +![](/2022/Days/Images/Day87_Data7.png) + +### pacman을 새로운 Minikube 클러스터로 import + +이제 해당 standby 클러스터에서 import 정책을 생성하고 개체 스토리지 백업에 연결하여 어떤 모양과 방식으로 가져올지 결정할 수 있습니다. + +먼저, 앞서 다른 클러스터에서 살펴본 location profile을 추가하고, 여기에 다크 모드를 표시하여 프로덕션 시스템과 DR standby location의 차이를 보여줍니다. + +![](/2022/Days/Images/Day89_Data16.png) + +이제 대시보드로 돌아가서 정책 탭으로 이동하여 새 정책을 생성합니다. + +![](/2022/Days/Images/Day89_Data17.png) + +아래 이미지에 따라 import 정책을 만듭니다. 완료되면 정책을 만들 수 있습니다. 여기에는 import 후 복원하는 옵션이 있으며, 일부 사용자는 이 옵션을 원할 수 있으며, 이 옵션은 완료되면 standby 클러스터로 복원됩니다. 또한 복원할 때 애플리케이션의 구성을 변경할 수 있으며, 이는 [day 90](day90.md)에 문서화한 내용입니다. + +![](/2022/Days/Images/Day89_Data18.png) + +on demeand import를 선택했지만 언제 import를 수행할지 일정을 설정할 수 있습니다. 이 때문에 한 번 실행하겠습니다. + +![](/2022/Days/Images/Day89_Data19.png) + +아래에서 성공적인 import 정책 작업을 확인할 수 있습니다. + +![](/2022/Days/Images/Day89_Data20.png) + +이제 대시보드로 돌아가서 애플리케이션 카드로 이동하면 아래에 "Removed" 아래에 표시되는 드롭다운을 선택하면 여기에 애플리케이션이 표시됩니다. 복원을 선택합니다. + +![](/2022/Days/Images/Day89_Data21.png) + +여기에서 사용 가능한 복원 지점을 확인할 수 있습니다. 이것은 기본 클러스터에서 pacman 애플리케이션에 대해 실행한 백업 작업입니다. + +![](/2022/Days/Images/Day89_Data22.png) + +다음 세션에서 더 자세히 다루고자 하므로 기본값은 변경하지 않겠습니다. + +![](/2022/Days/Images/Day89_Data23.png) + +"Restore"을 누르면 확인 메시지가 표시됩니다. + +![](/2022/Days/Images/Day89_데이터24.png) + +아래에서 standby 클러스터에 있는 것을 확인할 수 있으며, pod를 확인하면 실행 중인 애플리케이션이 있는 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day89_Data25.png) + +이제 포트 포워딩을 할 수 있습니다.(real-life/프로덕션 환경에서는 애플리케이션에 액세스하기 위해 이 단계가 필요하지 않으며, ingress를 사용할 것입니다). + +![](/2022/Days/Images/Day89_Data26.png) + +다음으로 애플리케이션 이동성 및 변환에 대해 살펴보겠습니다. + +## 자료 + +- [Kubernetes Backup and Restore made easy!](https://www.youtube.com/watch?v=01qcYSck1c4&t=217s) +- [Kubernetes Backups, Upgrades, Migrations - with Velero](https://www.youtube.com/watch?v=zybLTQER0yY) +- [7 Database Paradigms](https://www.youtube.com/watch?v=W2Z7fbCLSTw&t=520s) +- [Disaster Recovery vs. Backup: What's the difference?](https://www.youtube.com/watch?v=07EHsPuKXc0) +- [Veeam Portability & Cloud Mobility](https://www.youtube.com/watch?v=hDBlTdzE6Us&t=3s) + +[Day 90](day90.md)에서 봐요! diff --git a/2022/ko/Days/day90.md b/2022/ko/Days/day90.md new file mode 100644 index 0000000..ec21917 --- /dev/null +++ b/2022/ko/Days/day90.md @@ -0,0 +1,127 @@ +--- +title: '#90DaysOfDevOps - Data & Application Mobility - Day 90' +published: false +description: 90DaysOfDevOps - Data & Application Mobility +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048748 +--- + +## 데이터 및 애플리케이션 이동성 + +90DaysOfDevOps 챌린지 90일 차! 이번 마지막 세션에서는 데이터와 애플리케이션의 이동성에 대해 다뤄보겠습니다. 특히 Kubernetes에 초점을 맞출 예정이지만, 플랫폼 간 및 플랫폼 전반의 요구사항은 계속 증가하는 요구사항이며 현장에서 볼 수 있는 것입니다. + +"워크로드, 애플리케이션 및 데이터를 한 위치에서 다른 위치로 이동하고 싶다"는 사용 사례는 비용, 위험 또는 비즈니스에 더 나은 서비스를 제공하기 위한 것 등 여러 가지 이유가 있을 수 있습니다. + +이 세션에서는 워크로드를 가지고 한 클러스터에서 다른 클러스터로 Kubernetes 워크로드를 이동하는 방법을 살펴보되, 이 과정에서 대상 위치에서 애플리케이션이 있는 방식을 변경할 것입니다. + +여기에는 [재해 복구](day89.md)에서 겪었던 많은 특징이 사용됩니다. + +### **요구 사항** + +현재 Kubernetes 클러스터로는 수요를 감당할 수 없고 비용이 천정부지로 치솟고 있기 때문에 프로덕션 Kubernetes 클러스터를 다른 퍼블릭 클라우드에 위치한 재해 복구 위치로 이전하여 확장 기능을 제공하면서도 더 저렴한 요금으로 운영하고자 하는 비즈니스 결정이 내려졌습니다. 또한 대상 클라우드에서 사용할 수 있는 일부 기본 클라우드 서비스를 활용할 수도 있습니다. + +현재 미션 크리티컬 애플리케이션(Pac-Man)에 데이터베이스(MongoDB)가 있고 느린 스토리지에서 실행되고 있는데, 더 빠른 새로운 스토리지 계층으로 옮기고 싶습니다. + +현재 Pac-Man(NodeJS) 프론트엔드는 확장이 잘되지 않으며, 새로운 위치에서 사용 가능한 pod의 수를 늘리고 싶습니다. + +### IT팀에 문의하기 + +간략하게 설명했지만, 실제로는 이미 재해 복구 Kubernetes 클러스터에 임포트한 상태입니다. + +가장 먼저 해야 할 일은 재해 복구 테스트를 위해 89일에 수행한 복원 작업을 제거하는 것입니다. + +"standby" Minikube 클러스터에서 `kubectl delete ns pacman`을 사용하여 이 작업을 수행할 수 있습니다. + +![](/2022/Days/Images/Day90_Data1.png) + +시작하려면 Kasten K10 대시보드로 이동하여 애플리케이션 카드를 선택합니다. 드롭다운에서 "Removed"을 선택합니다. + +![](/2022/Days/Images/Day90_Data2.png) + +그러면 사용 가능한 복원 지점 목록이 표시됩니다. 여기에는 미션 크리티컬 데이터가 포함되어 있으므로 사용 가능한 지점을 선택합니다. (이 예에서는 복원 지점이 하나만 있습니다.) + +![](/2022/Days/Images/Day90_Data3.png) + +재해 복구 프로세스를 작업할 때는 모든 것을 기본값으로 두었습니다. 그러나 애플리케이션을 변환해야 하는 재해 복구 프로세스가 있는 경우 이러한 추가 복원 옵션을 사용할 수 있습니다. 이 경우 스토리지와 복제본 수를 변경해야 합니다. + +![](/2022/Days/Images/Day90_Data4.png) + +"Apply transforms to restored resources" 옵션을 선택합니다. + +![](/2022/Days/Images/Day90_Data5.png) + +수행하려는 변환에 대한 두 가지 기본 제공 예제가 요구 사항에 필요한 것입니다. + +![](/2022/Days/Images/Day90_Data6.png) + +첫 번째 요구 사항은 기본 클러스터에서는 `csi-hostpath-sc`라는 스토리지 클래스를 사용했지만, 새 클러스터에서는 `standard`를 사용하고자 하는 것이므로 여기서 변경을 수행할 수 있습니다. + +![](/2022/Days/Images/Day90_Data7.png) + +이제 하단의 변형 만들기 버튼을 누르세요. + +![](/2022/Days/Images/Day90_Data8.png) + +다음 요구 사항은 pacman 프론트엔드 배포를 "5"로 확장하는 것입니다. + +![](/2022/Days/Images/Day90_Data9.png) + +이 과정을 잘 따라가셨다면 아래와 같이 두 가지 transform을 모두 보실 수 있을 것입니다. + +![](/2022/Days/Images/Day90_Data10.png) + +이제 아래 이미지에서 아래 나열된 모든 아티팩트를 복원할 것임을 알 수 있으며, 원한다면 복원하려는 대상을 더 세분화할 수도 있습니다. "Restore" 버튼을 누릅니다. + +![](/2022/Days/Images/Day90_Data11.png) + +다시 한번 작업을 확인하라는 메시지가 표시됩니다. + +![](/2022/Days/Images/Day90_Data12.png) + +마지막으로 터미널로 돌아가서 클러스터를 살펴보면, 이제 pacman pod에 대해 5개의 pod가 있고 스토리지 클래스가 표준 대 csi-hostpath-sc로 설정된 것을 볼 수 있습니다. + +![](/2022/Days/Images/Day90_Data13.png) + +변환을 통해 다양한 옵션을 얻을 수 있습니다. 마이그레이션뿐만 아니라 재해 복구, 테스트 및 개발 유형 시나리오 등에도 적용할 수 있습니다. + +### API 및 자동화 + +API를 활용하여 이러한 작업 중 일부를 자동화하는 기능에 대해서는 언급하지 않았지만, 이러한 옵션은 존재하며 UI 전체에 걸쳐 일부 이동 경로가 자동화 작업에 API를 활용할 수 있는 명령 집합을 제공합니다. + +Kasten K10에서 주목해야 할 중요한 점은 배포 시 Kubernetes 클러스터 내부에 배포된 다음 Kubernetes API를 통해 호출할 수 있다는 것입니다. + +이것으로 데이터 저장 및 보호에 관한 섹션을 마무리하겠습니다. + +## 자료 + +- [쿠버네티스 백업과 복원이 쉬워졌다!](https://www.youtube.com/watch?v=01qcYSck1c4&t=217s) +- [Kubernetes 백업, 업그레이드, 마이그레이션 - Velero와 함께](https://www.youtube.com/watch?v=zybLTQER0yY) +- [7가지 데이터베이스 패러다임](https://www.youtube.com/watch?v=W2Z7fbCLSTw&t=520s) +- [재해 복구와 백업: 차이점은 무엇인가요?](https://www.youtube.com/watch?v=07EHsPuKXc0) +- [Veeam 이동성 및 클라우드 이동성](https://www.youtube.com/watch?v=hDBlTdzE6Us&t=3s) + +### **Closing** + +이 챌린지를 마무리하면서, 정보가 항상 관련성이 있는지 확인하기 위해 계속해서 피드백을 요청하고 싶습니다. + +또한 데브옵스 주제와 관련하여 미처 다루지 못했거나 더 깊이 파고들지 못한 많은 주제가 있다는 점에 감사드립니다. + +이는 내년에 이 챌린지를 다시 시도하여 90일 분량의 콘텐츠와 워크스루를 다시 만들 수 있다는 것을 의미합니다. + +### 다음은 무엇인가요? + +우선, 잠시 글쓰기를 쉬면서 2022년 1월 1일에 이 챌린지를 시작해서 2022년 3월 31일 19시 50분(BST)에 마쳤습니다! 슬로건이었죠. 하지만 제가 오랫동안 말하고 말했듯이이 콘텐츠가 한 사람에게 도움이 된다면 항상 공개적으로 배울 가치가 있습니다! + +앞으로 이 콘텐츠를 어디로 가져갈지에 대한 몇 가지 아이디어가 있는데, 이 콘텐츠가 깃허브 저장소 외에 다른 곳에서 활용될 수 있기를 바라며 전자책이나 실제 책으로도 제작하는 것을 검토해 볼 수 있기를 바랍니다. + +그런 일이 일어나기 전에 각 게시물을 다시 살펴보고 모든 것이 문법적으로 올바른지 확인해야 한다는 것도 알고 있습니다. 마크다운을 인쇄물이나 전자책으로 만드는 방법에 대해 알고 계신 분이 있다면 피드백을 주시면 감사하겠습니다. + +언제나 그렇듯이 이슈와 홍보를 계속 보내주시기 바랍니다. + +Thanks! +@MichaelCade1 + +- [GitHub](https://github.com/MichaelCade) +- [Twitter](https://twitter.com/MichaelCade1) diff --git a/2022/vi/Days/day03.md b/2022/vi/Days/day03.md index 253fda1..4a9cc11 100644 --- a/2022/vi/Days/day03.md +++ b/2022/vi/Days/day03.md @@ -56,7 +56,7 @@ Cuối cùng thì chúng ta cũng đã xây dựng xong ứng dụng, kiểm th Các ứng dụng khác nhau đòi hỏi các yêu cầu khác nhau về phần cứng và cấu hình. Đó là khi quản lý cấu hình ứng dụng (Application Configuration Management) và cơ sở hạ tầng ứng dụng dưới dạng mã (Infrastructure as Code) đóng vai trò then chốt trong vòng đời DevOps. Các ứng dụng có thể được đóng gói và chạy trong các containers hoặc chạy trên các máy ảo (VM). Điều này khiến chúng ta cần sử dụng các nền tảng như Kubernetes để điều phối các containers và đảm bảo ứng dụng ở trong trạng thái mong muốn nhằm phục vụ người dùng cuối. -Chúng ta sẽ tìm hiểu chi tiết về các chủ đề quan trọng này trong vài tuần tới để có kiến thức nền tẳng tốt hơn về chúng và khi nào thì nên sử dụng. +Chúng ta sẽ tìm hiểu chi tiết về các chủ đề quan trọng này trong vài tuần tới để có kiến thức nền tảng tốt hơn về chúng và khi nào thì nên sử dụng. ## Giám sát diff --git a/2022/vi/Days/day16.md b/2022/vi/Days/day16.md index e83f0d8..6658e78 100644 --- a/2022/vi/Days/day16.md +++ b/2022/vi/Days/day16.md @@ -138,7 +138,7 @@ Trên Windows, bạn có ổ C: và đó là thứ mà chúng ta coi là gốc. Khi đề cập tới một hệ thống Linux hoặc bất kỳ hệ thống nào, chúng ta có thể muốn biết các ổ đĩa có sẵn và chúng tôi có bao nhiêu dung lượng trống trên các đĩa đó. Một vài lệnh sau đây giúp xác định và sử dụng cũng như quản lý bộ lưu trữ. -- `lsblk` Liệt kê các thiết bị chặn(List Block devices). `sda` là đĩa vật lý của chúng ta và sau đó `sda1, sda2, sda3` là các phân vùng của chúng ta trên đĩa đó. +- `lsblk` Liệt kê các thiết bị khối (List Block devices). `sda` là đĩa vật lý của chúng ta và sau đó `sda1, sda2, sda3` là các phân vùng của chúng ta trên đĩa đó. ![](../../Days/Images/Day16_Linux25.png) diff --git a/2022/vi/Days/day35.md b/2022/vi/Days/day35.md new file mode 100644 index 0000000..0748325 --- /dev/null +++ b/2022/vi/Days/day35.md @@ -0,0 +1,140 @@ +--- +title: '#90DaysOfDevOps - Bức tranh toàn cảnh: Git - Quản lý phiên bản - Ngày 35' +published: false +description: 90DaysOfDevOps - Bức tranh toàn cảnh Git - Quản lý phiên bản +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049041 +--- + +## Bức tranh toàn cảnh: Git - Quản lý phiên bản + +Trước khi bắt đầu tìm hiểu về git, chúng ta cần hiểu quản lý phiên bản là gì và tại sao chúng ta cần làm vậy? Trong bài mở đầu về git này, chúng ta sẽ đi qua khái niệm quản lý phiên bản và kiếm thức cơ bản về git. + +### Quản lý phiên bản là gì? + +Git không phải là hệ thống quản lý phên bản duy nhất, vì vậy ở đây chúng ta sẽ đề cập đến những lựa chọn và phương pháp có sẵn cho việc quản lý phiên bản. + +Lợi ích rõ ràng nhất và lớn nhất của quản lý phiên bản là khả năng theo dõi lịch sử của dự án. Chúng ta có thể xem lại kho lưu trữ (repository) bằng cách sử dụng `git log` và xem lại toàn bộ các commit cũng như comments cũng như những gì đã diễn ra trong toàn bộ dự án. Đừng lo, chúng ta sẽ đi vào cách lệnh ở phần sau. Bây giờ, hãy tưởng tượng đây là một dự án phần mềm thực tế với rất nhiều mã nguồn và có nhiều người đang làm việc chung để phát triển sản phẩn tại các thời điểm khác nhau, tất cả các kỹ sư đã đóng góp code, và tất cả những người review code đều được ghi lại ở đây để cho chúng ta biết điều gì đã xảy ra, khi nào, bởi ai và ai đã review. + +![](../../Days/Images/Day35_Git1.png) + +Quản lý phiên bản trước đây sẽ giống như việc tạo một bản sao phiên bản code của bạn theo cách thủ công trước khi bạn thực hiện các thay đổi. CÓ thể bạn cũng không cần sử dụng những phiên bản cũ nữa nhưng nó được tạo ra để bạn có thể yên tâm hơn, nhỡ đâu... + +![](../../Days/Images/Day35_Git2.png) + +Tôi đã bắt đầu áp dụng quản lý phiên bản không chỉ đối với mã nguồn mà hầu hết mọi thứ, ví dụ như dự án này (90DaysOfDevOps). Tại sao lại không sử dụng các tính năng như khôi phục, ghi lại mọi thứ đã diễn ra. + +Tuy nhiên, để tránh hiểu lầm **Quản lý phiên bản không hoạt động như một bản sao lưu** + +Một lợi ích khác của quản lý phiên bản là khả năng quản lý nhiều phiên bản của một dự án. Lấy ví dụ như chúng ta có một ứng dụng miễn phí và sau đó là ứng dụng trả phí có sẵn trên tất cả các hệ điều hành. Phần lớn mã được chia sẽ giữa hai ứng dụng. Chúng tôi có thể sao chép và dán mã của mình cho từng commit vào từng ứng dụng, nhưng điều đó sẽ rất lộn xộn, đặc biệt là khi bạn mở rộng quy mô phát triển với nhiều nhân sự, cũng sẽ rất dễ mắc lỗi. + +Ứng dụng trả phí là nơi chúng ta có các chứ năng bổ sung, hãy gọi chúng là các commit trả phí, bản miễn phí sẽ chỉ chứa các commit bình thường. + +Cách chúng ta có thể làm được điều này trong quản lý phiên bản là thông qua phân nhánh (branching) + +![](../../Days/Images/Day35_Git3.png) + +Phân nhánh cho phép hai luồng mã cùng tồn tại cho một ứng dụng như chúng ta đã nói ở trên. Nhưng chúng ta vẫn muốn các tính năm mới có trong phiên bản miễn phí có trong phiên bản trả phí, để làm được điều này, chúng ta có một thứ gọi là merge. + +![](../../Days/Images/Day35_Git4.png) + +Bây giờ, điều này có vẻ dễ dàng nhưng việc merge có thể phức tạp vì bạn có thể có một nhóm làm việc trên phiên bản miễn phí và một nhóm khác làm việc với phiên bản trả phí và điều gì sẽ xảy ra nếu cả hai cùng thay đổi đến cấu trúc tổng thể của mã. CÓ thể một biến được cập nhật và làm hỏng phần nào đó. Sau đó, bạn có các conflict làm một chức năng không chạy được. Quản lý phiên bản không thể khắc phục được các conflict do bạn tạo ra. Nhưng quản lý phiên bản cho phép điều này được quản lý một cách dễ dàng. + +Nói chung, lý do chính nếu bạn chưa sử dụng quản lý phiên bản cho tới thởi điểm này có thể là bạn chưa cộng tác bao giờ. Sẽ có ngày càng nhiều trường hợp mà chúng ta cần tới khả năng chia sẽ mã giữa các nhà phát triển. Có thể là một bài trình bày chung mà bạn đang làm việc với đồng nghiệp hoặc thử thách 90DaysOfDevOps, nơi bạn có cộng đồng và các chỉnh sửa, cập nhật sẽ được cộng đồng đóng góp trong suốt dự án. + +Nếu không có quản lý phiên bản, làm thể nào các nhóm phát triển phần mềm có thể giải quyết vấn đề này? Tôi thấy thật khó khăn khi để theo dõi tất cả mọi thứ khi tôi đang thực hiện các dự án của mình. Tôi hi vọng họ sẽ chia nhỏ mã theo từng module chức năng một, có thể sẽ là từng miếng ghép nhỏ cho một bức tranh lớn để giải quyết các vấn đề trước khi tất cả được release. + +Với quản lý phiên bản, chúng ta có một nguồn sự thật duy nhất (single source of truth). Chúng ta có thể làm việc trên các module khác nhau nhưng nó cho phép chúng ta cộng tác tốt hơn. + +![](../../Days/Images/Day35_Git5.png) + +Một việc khác cần đề cập tới là không chỉ các nhà phát triển có thể hưởng lợi từ quản lý phiên bản, tất cả các thành viên và các công cụ có thể nhìn rõ dự án và tận dụng, các công cụ quản lý dự án có thể được liên kết và theo dõi tiến độ công việc. Chúng ta cũng có thể có một máy build, chẳng hạn như là một Jenkins server mà chúng ta sẽ nói trong phần sau. Một công cụ xây dựng mà nguồn và đóng gói hệ thống, tự động hoá quá trình kiểm thử và các metrics liên quan tới mã nguồn. + +### Git là gì? + +Git là một công cụ theo dõi các thay đổi đối với mã nguồn hoặc bất kỳ tệp nào hoặc cũng có thể nói Git là một hệt thống quản lý phiên bản phân tán mã nguồn mở. + +Có nhiều cách à git có thể được sử dụng trên các hệ thống của chúng ta, phổ biến nhất hoặc ít nhất là đối với tôi, tôi đã sử dụng dòng lệnh (command line), nhưng chúng ta cũng có các công cụ và giao diện người dùng đồng hoạ như Visual Studio Code, các công cụ này có các chức năng của git mà chúng ta có thể tận dụng. + +Bây giờ chúng ta sẽ xem qua một cách tổng quát trước khi cài đặt git trên máy của mình. + +Hãy sử dụng thư mục mà chúng ta đã tạo trước đó. + +![](../../Days/Images/Day35_Git2.png) + +Để sử dụng thư mục này với quản lý phiên bản, trước tiên chúng ta cần khởi tạo thư mục nào bằng lệnh `git init`. Hiện tại, chỉ cần nghĩ rằng lệnh này đặt thư mục của chúng ta làm kho lưu trữ trong cơ sở dữ liệu ở đâu đó trên máy tính của chúng ta. + +![](../../Days/Images/Day35_Git6.png) + +Bây giờ chúng ta có thể tạo một số tệp và thư mục cho mã nguồn hoặc cũng có thể đã có sẵn từ trước đó. Sử dụng lệnh `git add .` sẽ đặt tất cả cá tệp và thư mục trong thư mục của chúng ta vào một chiếc hộp nhưng chúng ta chưa commit bất cứ thứ gì vào cơ sở dữ liệu đó. Thao tác này chỉ có nghĩ là tất cả các tệp có `.` đã sẵn sàng để được thêm vào. + +![](../../Days/Images/Day35_Git7.png) + +Sau đó, chúng ta có thể muốn tiếp tục và commit các tệp của mình, việc này có thể thực hiện bằng lệnh `git commit -m "My First Commit"`. Chúng ta có thể đưa ra lý do cho commit của mình, điều này được khuyến khích để chúng ta có thể biết điều gì xảy ra trong mỗi commit. + +![](../../Days/Images/Day35_Git8.png) + +Bây giờ chúng ta có thể thấy những gì xảy ra trong lịch sử của dự án. Sử dụng lệnh `git log` + +![](../../Days/Images/Day35_Git9.png) + +Nếu chugns ta tạo một tệp bổ sung có tên là `samplecode.ps1`, thì trạng thái sẽ bị thay đổi. Chúng ta cũng có thể kiểm tra trạng thái của kho lưu trữ của mình bằng cách sử dụng `git status`, lệnh này cho chúng ta thấy không có gì để commit và chúng ta có thể thêm một tệp mới có thên samplecode.ps1. Sau đó, nếu chạy lại lệnh `git status` một lần nữa bạn sẽ thấy file mà chúng ta có thể commit. + +![](../../Days/Images/Day35_Git10.png) + +Thêm tệp mới của chúng ta bằng lệnh `git add samplecode.ps1` và sau đó chạy lại lệnh `git status` một lần nữa và thấy tệp này đã được sẵn sàng để commit. + +![](../../Days/Images/Day35_Git11.png) + +Sau đó dùng lệnh `git commit -m "My Second Commit"`. + +![](../../Days/Images/Day35_Git12.png) + +`git status` bây giờ cũng thể hiện rằng chúng ta đã dọn dẹp mọi thứ. + +![](../../Days/Images/Day35_Git13.png) + +Sau đó, chúng ta có thể sử dụng lệnh `git log` để hiện thị các commit mới nhất và commit đầu tiên. + +![](../../Days/Images/Day35_Git14.png) + +Nếu chúng ta muốn xem các thay đổi giữa các lần commit của mình, tức là những tệp nào đã được thêm hoặc sửa đổi, chúng ta có thể sử dụng `git diff b8f8 709a` + +![](../../Days/Images/Day35_Git15.png) + +Nó sẽ hiển thị những gì đã thay đổi, trong trường hợp của chúng ta, một tệp mới đã được thêm vào. + +![](../../Days/Images/Day35_Git16.png) + +Chúng ta sẽ đi sâu hơn vào vấn đề này sau nhưng chúng ta có thể nhảy giữa các commit của mình, đại loại là chúng ta có thể du hành thời gian! Bằng cách sử dụng hash của commit, có thể sử dụng lệnh `git checkout 709a` để nhảy ngược thời gian mà không làm mất tệp mới của chúng ta. + +![](../../Days/Images/Day35_Git17.png) + +Nhưng sau đó, chúng ta cũng sẽ muốn tiếp tục và có thể thực hiện điều này theo cách tương tự với hash của commit hoặc bạn có thể thấy như ở đây chúng ta sử dụng `git switch -` câu lệnh hoàn tác thao tác trước đó. + +![](../../Days/Images/Day35_Git18.png) + +TLDR: + +- Theo dõi lịch sử của một dự án +- Quản lý nhiều phiên bản khác nhau của một dự án +- Chia sẽ mã giữa các kỹ sư phát triển và mở rộng phạm vi các nhóm và công cụ sử dụng +- Phối hợp làm việc giữa các nhóm +- Ồ, và có thể du hành thời gian! + +Điều này giống như một bước nhảy mới nhưng hy vọng rằng bạn có thể thấy bức tranh toàn cảnh đằng sau quản lý phiên bản mà không thực sự biết các câu lệnh cụ thể và sức mạnh của chúng. + +Tiếp theo, chugsn ta sẽ cài đặt và thiết lập git trên máy cục bộ của bạn, đồng thời tìm hiểu sâu hơn một chút về một số trường hợp sử dụng và các câu lệnh trong Git. + +## Tài liệu tham khảo + +- [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) +- [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) +- [Git Tutorial for Beginners](https://www.youtube.com/watch?v=8JJ101D3knE&t=52s) +- [Git for Professionals Tutorial](https://www.youtube.com/watch?v=Uszj_k0DGsg) +- [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) +- [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) + +Hẹn gặp lại vào [ngày 36](day36.md) diff --git a/2022/vi/Days/day36.md b/2022/vi/Days/day36.md new file mode 100644 index 0000000..60fb987 --- /dev/null +++ b/2022/vi/Days/day36.md @@ -0,0 +1,154 @@ +--- +title: '#90DaysOfDevOps - Cài đặt & Cấu hình Git - Ngày 36' +published: false +description: 90DaysOfDevOps - Cài đặt & Cấu hình Git +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048738 +--- + +## Cài đặt & Cấu hình Git + +GIt là một công cụ quản lý phiên bản ã nguồn mở, đa nền tảng. Nếu bạn giống tôi, sử dụng Ubuntu hoặc các hệ điều hành Linux khác, bạn có thể thấy rằng git đã được cài đặt sẵn, tuy nhiên chúng ta vẫn sẽ đi qua việc cài đặt và cấu hình nó. + +Ngay cả khi bạn đã cài đặt git trên hệ thống của mình, bạn cũng nên đảm bảo rằng chúng ta luôn có bản cập nhật mới nhất. + +### Cài đặt Git + +Như đã đề cập, Git là công cụ đa nền tảng, chúng ta sẽ nhắc tới Windows và Linux và bạn cũng có thể tìm thấy hướng dẫn cho macOS tại [đây](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) + +Đối với [Windows](https://git-scm.com/download/win), chúng ta có thể download trình cài đặt từ trang web chính thức. + +Bạn cũng có thể sử dụng `winget` trên máy tính Windows của mình, và sử dụng nó như trình quản lý gói ứng dụng trên máy của bạn. + +Trước khi chúng ta cài đặt bất cứ thứ gì, hãy kiểm tra phiên bản hiện tại trên máy của bạn. Mởi cửa sổ PowerShell và chạy `git --version` + +![](../../Days/Images/Day36_Git1.png) + +Chúng ta cũng có thể kiểm tra phiên bản Git trên WSL Ubuntu của mình. + +![](../../Days/Images/Day36_Git2.png) + +Tại thời điểm viết bài, bản phát hành mới nhất trên Windows là `2.35.1`, vì vậy tôi sẽ hướng dẫn việc update một vài thứ. Linux cũng có thể tương tự như vậy. + +Sau khi tải xuống trình cài đặt phiên bản mới nhất và chạy qua trình hướng dẫn và ghi lại những điều đó tại đây. Lưu ý quan trọng là git sẽ gỡ cài đặt các phiên bản trước đó rồi mới cài đặt phiên bản mới nhất. + +Có nghĩ là quy trình bên dưới cũng là quy trình mà chúng ta phải trải qua đối với việc bạn cài git lần đầu tiên. + +Đây là một cài đặt khá đơn giản. Sau khi tài xuống, click đúp và bắt đầu. Đọc qua thoả thuận về giấy phép GNU. Nhưng hãy nhớ đây là phần mềm mã nguồn mở và miễn phí. + +![](../../Days/Images/Day36_Git3.png) + +Bây giờ chúng ta có thể chọn các thành phần bổ sung mà chúng ta muốn cài đặt cũng như liên kết với git. Trên Windows, tôi luôn đảm bảo rằng mình đã cài đặt Git Bash vì điều này cho phép chúng ta chạy các lệnh bash trên Windows. + +![](../../Days/Images/Day36_Git4.png) + +Sau đó, chúng ta có thể chọn phần mềm SSH mà chúng ta muốn sử dụng. Tôi chọn OpenSSH như bản có thể thấy trong phần tìm hiểu về Linux. + +![](../../Days/Images/Day36_Git5.png) + +Chúng ta cũng có thể bật các tính năng thử nghiệm, đối với tôi, tôi không cần chúng nên đã không bật chúng, bạn luôn có thể quay lại việc cài đặt để bật các tính năng này. + +![](../../Days/Images/Day36_Git6.png) + +Cài đặt hoàn tất, bây giờ chúng ta có thể chọn mở Git Bash hoặc đọc bản ghi chú cho bản phát hành mới nhất. + +![](../../Days/Images/Day36_Git7.png) + +Bước kiểm tra cuối cùng là mở PowerShell và thử lại câu lệnh kiểm tra phiên bản git. + +![](../../Days/Images/Day36_Git8.png) + +Sau các bước siêu đơn giản ở trên, chúng ta sẽ có phiên bản mới nhất của git. Đối với Linux, quá trình có thể sẽ mất thời gian hơn một chúng nhưng tôi cũng muốn nói qua về nó. + +Tôi chỉ cần chạy lệnh `sudo apt-get install git`. + +![](../../Days/Images/Day36_Git9.png) + +Bạn cũng có thể chạy các câu lệnh dưới dây để add thêm git repository cho các cài đặt phần mềm. + +``` +sudo add-apt-repository ppa:git-core/ppa -y +sudo apt-get update +sudo apt-get install git -y +git --version +``` + +### Cấu hình Git + +Khi lần đầu tiên sử dụng git, chúng ta phải xác định một số cài đặt sau. + +- Tên +- Email +- Editor mặc định +- Ký tự kết thúc dòng + +Điều này có thể thực hiện ở ba cấp độ. + +- Hệ thống = tất cả người dùng +- Global = tất cả repositories của người dùng hiện tại +- Local = repository hiện tại + +Ví dụ: +`git config --global user.name "Michael Cade"` +`git config --global user.email Michael.Cade@90DaysOfDevOPs.com"` +Tuỳ thuộc vào hệ điều hành của bạn, text editor mặc định sẽ được tự xác định. Với Ubuntu của tôi, câu lệnh tiếp theo sẽ sử dụng nano. Lệnh dưới đây sẽ thay đổi editor thành Visual Studio Code. + +`git config --global core.editor "code --wait"` + +bây giờ, nếu chúng ta muốn kiểm tra tất cả các cầu hình git thì có thể sử dụng lệnh sau + +`git config --global -e` + +![](../../Days/Images/Day36_Git10.png) + +Trên tất cả các máy, tệp này sẽ được đặt tên là `.gitconfig`. Trên máy Windows của tôi, bạn sẽ tìm thấy tệp này trong thư mục người dùng của mình. + +![](../../Days/Images/Day36_Git11.png) + +### Lý thuyết Git + +Tôi đã đề cập trong bài đăng ngày hôm qua rằng có các loại quản lý phiên bản khác nhau và chúng ta có thể chia thành hai loại chính. Một là Client-Server và loại còn lại là hệ phân tán. + +### Quản lý phiên bản Client-Server + +Trước khi git xuất hiện, Client-Server là phương thức chính để quản lý phiên bản. Ví dụ cho điều này sẽ là [Apache Subversion](https://subversion.apache.org/) là một một hệ thống kiểm soát phiên bản mã nguồn mở được ra mắt vào năm 2000. + +Trong mô hình quản lý phiên bản Client-Server này, bước đầu tiên nhà phát triểu cần làm là tải xuống mã nguồn và các tệp từ máy chủ. Điều này không giải quyết các xung đột nhưng nó loại bỏ sự phức tạp của các xung đột và cách giải quyết chúng. + +![](../../Days/Images/Day36_Git12.png) + +Bây giờ, giả sử chúng ta có hai nhà phát triển làm việc trên cùng một tệp và một người xong trước, upload file của họ lên server trước với những thay đổi của họ. Khi người thứ hai cập nhật file đó, xung đột sẽ xảy ra. + +![](../../Days/Images/Day36_Git13.png) + +Vì vậy, bây giờ người thứ hai cần kéo thay đổi mã của người đầu tiên xuống và giải quyết các xung đột trong mã nguồn rồi sau đó mới commit lên máy chủ. + +![](../../Days/Images/Day36_Git15.png) + +### Distributed Version Control + +Git không phải là hệ thống quản lý phiên bản phân tán duy nhất. Nhưng nó rất thông dụng. + +Một số lợi ích chính của Git là: + +- Nhanh +- Thông minh +- Linh hoạt +- An toàn & Bảo mật + +Khác với mô hình kiểm soát phiên bản Client-Server, mỗi nhà phát triển tải xuống một repository thì nó sẽ bao gồm tất cả mọi thứ. Lịch sử các commit, tất cả các nhánh,... + +![](../../Days/Images/Day36_Git16.png) + +## Tài liệu tham khảo + +- [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) +- [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) +- [Git Tutorial for Beginners](https://www.youtube.com/watch?v=8JJ101D3knE&t=52s) +- [Git for Professionals Tutorial](https://www.youtube.com/watch?v=Uszj_k0DGsg) +- [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) +- [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) + +Hẹn gặp lại vào [ngày 37](day37.md) diff --git a/2022/vi/Days/day37.md b/2022/vi/Days/day37.md new file mode 100644 index 0000000..b62ea53 --- /dev/null +++ b/2022/vi/Days/day37.md @@ -0,0 +1,169 @@ +--- +title: '#90DaysOfDevOps - Giới thiệu về Git - Ngày 37' +published: false +description: 90DaysOfDevOps - Giới thiệu về Git +tags: 'DevOps, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048707 +--- + +## Giới thiệu về git + +Trong hai bàì đăng trước, chúng ta đã tìm hiệu về quản lý phiên bản và một số quy trình, workflow của git với tư cách là một hệ thống quản lý phiên bản vào [ngày 35](day35.md) Sau đó chúng ta đã cài đặt git trên hệ thống, cập nhật và cấu hình. Chúng ta cũng đã đi sâu hơn một chút và điểm khác nhau cơ bản trong hệ thống quản lý phiên bản Client-Server và hệ thống quản lý phiên bản phân tán ví dụ như Git vào [ngày 36](day36.md). + +Bây giờ, chúng ta sẽ tìm hiểu các câu lệnh cơ bản và trường hợp sử dụng chúng với git. + +### Trợ giúp với git + +Sẽ có lúc bạn không thể nhớ hoặc không biết lệnh cần sử dụng để hoàn thành công việc với git. Bạn sẽ cần giúp đỡ. + +Google hoặc bất kỳ công cụ tìm kiểm nào có thể là điểm đến đầu tiên khi bạn tìm kiếm sự trờ giúp. + +Tiếp sau đó có thể là trang chính thức của git và tài liệu. [git-scm.com/docs](http://git-scm.com/docs) Tại đây, bạn sẽ không những chỉ tìm thấy tài liệu tham khảo tốt cho tất cả các câu lệnh, mà còn có rất nhiều các tài nguyên khác. + +![](../../Days/Images/Day37_Git1.png) + +Chúng ta cũng có thể truy cập tài liệu tương tự sau, điều này cực kỳ hữu ích nếu bạn không có kết nối nào từ terminal. Ví dụ: nếu chúng ta sử dụng lệnh `git add`, chúng ta có thể chạy `git add --help` và đọc hướng dẫn dưới đây. + +![](../../Days/Images/Day37_Git2.png) + +Chúng ta cũng có thể dụng `git add -h` để cung cấp tống hợp các tuỳ chọn có sẵn mà chúng ta có thể sử dụng. + +![](../../Days/Images/Day37_Git3.png) + +### Những câu chuyện xung quanh Git + +"Git không có quyền kiểm soát truy cập" - bạn có thể trao quyền cho một leader để duy trì mã nguồn. + +"Git quá nặng" - Git có thể cung cấp các kho lưu trữ nông (shallow repositories), có nghĩa là lịch sử git sẽ được cắt giảm nếu bạn có một project lớn. + +### Những thiếu sót thực tế + +Không phải là phương pháp lý tưởng cho các tệp nhị phân. Tuyệt vời cho mã nguồn nhưng không tuyệt vời cho các tệp thực thi hoặc video chẳng hạn. + +Git không thân thiện với người dùng, việc chúng ta phải dành thời gian để nói và tìm hiểu các lệnh và chứng năng của công cụ có lẽ là minh chứng rõ ràng nhất cho việc đó. + +Nhìn chung, git khó học nhưng dễ sử dụng. + +### Hệ sinh thái git + +Tôi muốn trình bày ngắn gọn về hệ sinh thái xung quanh git nhưng không đi quá sâu và việc đó. Điều quan trọng là phải nhắc đến ở góc độ high-level. + +Hầu như tất cả các công cụ phát triển hiện đại đều hỗ trợ git. + +- Công cụ phát triển - chúng ta đã đề cập tới Visual Studio Code, bạn sẽ tìm thấy các plugin và các tích hợp của git trong Sublime text và các trình soạn thảo văn bản và IDE khác. +- Công cụ nhóm - Cũng được đề cập trong các công cụ như Jenkins theo góc nhìn CI/CD, Slack từ góc độ dịch vụ nhắn tin và Jira từ góc độ quản lý dự án và theo dõi vấn đề. + +- Cloud providers - Tất cả các nhà cung cấp điện toán đám mây lớn đều hỗ trợ git, Microsoft Azure, Amazon AWS và Google Cloud Platform. +- Các dịch vụ dựa trên Git - Sau đó, chúng ta có GitHub, GitLab và BitBucket mà chúng tôi sẽ đề cập rõ hơn ở phần sau. Các dịch vụ này có thể coi như là một mạng xã hội dành cho mã nguồn. + +### Git Cheatsheet + +Chúng ta chưa đề cập đến hầu hết các lệnh này nhưng sau khi xem xét một số cheatsheet có sẵ, tôi cũng muốn ghi lại một số câu lệnh git và mục đích sử dụng của chúng. Chúng ta không cần phải nhớ tất cả những câu lệnh này, với việc thực hành và sử dụng nhiều hơn, bạn sẽ học được một số điều cơ bản về git. + +Tôi đã lấy những câu lệnh từ [atlassian](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) nhưng viết lại chúng và đọc mô tả là một cách hay để biết các lệnh làm gì cũng như bắt đầu thực hành trong công việc hàng ngày. + +### Cơ bản về Git + +| Lệnh | Ví dụ | Mô tả | +| ------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| git init | `git init ` | Tạo một git repository tron thư mục được chỉ định | +| git clone | `git clone ` | Sao chép repository tại vào máy local | +| git config | `git config user.name` | Khai báo tên người sử dụng cho tất cả các commit ở repository hiện tại, có các flag `system`, `global`, `local` để tuỳ chọn. | +| git add | `git add ` | Stage tất cả các thay đổi trong để chuẩn bị cho commit tiếp theo. Chúng ta có thể thêm và <.> cho tất cả mọi thứ. | +| git commit -m | `git commit -m ""` | Commit các file đã được staged, sử dụng để làm rõ thay đổi được commit là gì. | +| git status | `git status` | Liệt kê các tệp được staged, unstaged và untracked. | +| git log | `git log` | Hiển thị tất cả lịch sử commit bằng định dạng mặc định. Có các tuỳ chọn bổ sung với lệnh này. +| git diff | `git diff` | Hiển thị các thay đổi của các thay đổi chưa được stage. | + +### Git Hoàn tác thay đổi + +| Lệnh | Ví dụ | Mô tả | +| ---------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| git revert | `git revert ` | Tạo một commit mới hoàn tác lại tất cả các thay đổi trong trên branch hiện tại. | +| git reset | `git reset ` | Xoá khỏi stage, nhưng không thay đổi thư mục làm việc. Điều này unstaged một tệp nhưng không ghi đè bất cứ thay đổi nào. | +| git clean | `git clean -n` | Hiển thị tệp nào sẽ bị xoá khỏi thư mục làm việc. Sử dụng `-f` thay cho `-n` để thực hiện việc xoá. | + +### Git viết lại lịch sử + +| Lệnh | Ví dụ | Mô tả | +| ---------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | +| git commit | `git commit --amend` | Thay thế commit gần nhất bằng các thay đỏi đã được staged và ghép nó với commit cuối cùng. Sử dụng trong trường hợp chưa có gì được stage để thay đổi nội dung commit. | +| git rebase | `git rebase ` | Rebase nhanh hiện tại và trong . có thể là một commit ID, tên branch, tag hoặc một tham chiếu tương đối đến HEAD. | +| git reflog | `git reflog` | Hiện thị log của các thay đổi với HEAD của kho lưu trữ cục bộ (local repository). Thêm --relative-date hiển thị ngày tháng và --all để hiện thị tất cả các refs. | + +### Git Phân nhánh (Branch) + +| Lệnh | Ví dụ | Mô tả | +| ------------ | -------------------------- | ------------------------------------------------------------------------------------------------------------- | +| git branch | `git branch` | Liệt kê tất cả các branch trong repo của bạn. Thêm đối số để tạo một branch với với tên . | +| git checkout | `git checkout -b ` | Tạo và checkout sang một branch mới tên . Bỏ -b flag để checkout sang một branch đã có sẵn. | +| git merge | `git merge ` | Merge và branch hiện tại. | + +### Git Remote Repositories + +| Lệnh | Ví dụ | Mô tả | +| -------------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | +| git remote add | `git remote add ` | Tạo một kết nối mới đến một remote repo. Sau khi thêm một remote, bạn có thể dùng thay cho trong các lệnh của bạn. | +| git fetch | `git fetch ` | Kéo một nhánh cụ thể có tên , từ repo. Bỏ để kéo tất cả các remote refs. | +| git pull | `git pull ` | Kéo một bản sau của nhánh hiện tại từ remote repo và ngay lập tức merge nó vào bản sao local. | +| git push | `git push ` | Đẩy nhánh tới , cùng với các commits và objects. Tạo nhánh có thên trong remote repo nếu nó không tồn tại. | + +### Git Diff + +| Lệnh | Ví dụ | Mô tả | +| ----------------- | ------------------- | ---------------------------------------------------------------------- | +| git diff HEAD | `git diff HEAD` | Hiển thị sự khác biệt giữa thư mục làm việc và commit cuối cùng. | +| git diff --cached | `git diff --cached` | Hiện thị sự khác biệt giữa các thay đổi đã được staged và commit cuối cùng | + +### Git Config + +| Lệnh | Ví dụ | Mô tả | +| ---------------------------------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- | +| git config --global user.name | `git config --global user.name ` | Khai báo tên người dùng sẽ được sử dụng cho tất cả các commit ủa người dùng hiện tại. | +| git config --global user.email | `git config --global user.email ` | Khai báo email sẽ được sử dụng cho tất cả các commit của người dùng hiện tại. | +| git config --global alias | `git config --global alias ` | Tạo một phím tắt cho lệnh git . | +| git config --system core.editor | `git config --system core.editor ` | Cài đặt trình soạn thảo văn bản sẽ được sử dụng cho tất cả người dùng trên máy. phải là lệnh khởi chạy trình chỉnh sửa mong muốn | +| git config --global --edit | `git config --global --edit ` | Mở tệp cấu hình chung trong trình soạn thảo văn bản để chỉnh sửa thủ công. | + +### Git Rebase + +| Command | Example | Description | +| -------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| git rebase -i | `git rebase -i ` | Rebase nhánh hiện tại vào . Khởi chạy trình chỉnh sửa cho phép chỉnh sửa các commit khi chuyển qua base mới. | + +### Git Pull + +| Lệnh | Ví dụ | Mô tả | +| -------------------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| git pull --rebase | `git pull --rebase ` | Kéo các bản sao của nhánh hiện tại trên remote và rebasse vào bản sao tại local. Sử dụng git rebase thay cho merge để gộp các nhánh. | + +### Git Reset + +| Lệnh | Ví dụ | Mô tả | +| ------------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| git reset | `git reset ` | Reset khu vực staging về commit gần nhất nhưng giữ nguyên thư mục làm việc. | +| git reset --hard | `git reset --hard` | Reset khu vực staging về commit gần nhất và ghi đè lên tất cả các thay đổi trong thư mục làm việc. | +| git reset | `git reset ` | Di chuyển branch hiện tại về , reset khu vực staging reset về commit đó nhưng giữ nguyên khu vực làm việc. | +| git reset --hard | `git reset --hard ` | Giống với lệnh trước đó nhưng reset cả khu vực staging, thư mục làm việc. Xoá bỏ các thay đổi chưa được commit và tất cả các commit phía sau . | + +### Git Push + +| Lệnh | Ví dụ | Mô tả | +| ------------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | +| git push --force | `git push --force` | Ép buộc git đảy lên ngay cả khi kết quả không phải là một non-fast-forward merge. Không sử dụng --force trừ khi bạn biết chắc chắn mình đang làm gì. | +| git push --all | `git push --all` | Đẩy tất cả các nhánh ở local đến một remote xác định. | +| git push --tags | `git push --tags` | Tage không được tự động đẩy lên khi bạn đẩy một nhánh hay sử dụng --all. --tags sẽ gửi tất cả những local tags lên remote repo. | + +## Tài liệu tham khảo + +- [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) +- [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) +- [Git Tutorial for Beginners](https://www.youtube.com/watch?v=8JJ101D3knE&t=52s) +- [Git for Professionals Tutorial](https://www.youtube.com/watch?v=Uszj_k0DGsg) +- [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) +- [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) +- [Git cheatsheet](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) + +Hẹn gặp lại vào [ngày 38](day38.md) diff --git a/2022/vi/Days/day38.md b/2022/vi/Days/day38.md new file mode 100644 index 0000000..3190d54 --- /dev/null +++ b/2022/vi/Days/day38.md @@ -0,0 +1,127 @@ +--- +title: '#90DaysOfDevOps - Staging & Changing - Ngày 38' +published: false +description: 90DaysOfDevOps - Staging & Changing +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049042 +--- + +## Staging & Changing + +Chúng ta đã đề cập đến một số điều cơ bản nhưng việc đưa mọi thứ vào một kịch bản hoàn chỉnh giúp tôi học và hiểu cách thức, lý do chúng ta thực hiện theo cách này tốt hơn. Trước khi chúng ta sử dụng bất kỳ dịch vụ dựa trên git nào như GitHub, git có các chức năng mà bạn có thể tận dụng trên máy của mình. + +Chúng ta sẽ lấy thư mục dự án mà chúng ta đã tạo ở bài dầu tiên về git và đi qua lần lượt các bước với git. Chúng ta tạo một thư mục trên máy của mình và khởi tạo git với lệnh `git init`. + +![](../../Days/Images/Day38_Git1.png) + +Chúng ta cũng có thể thấy rằng thư mục đã được khởi tạo có một thư mục ẩn. + +![](../../Days/Images/Day38_Git2.png) + +Đây là nơi lưu trữ thông tin chi tết về git repository cũng như thông tin liên quan đến các nhánh và commit của chúng ta. + +### Stage các tệp + +Chúng ta bắt đầu làm việc với thư mục rỗng hoặc có thể chúng ta có một số mã nguồn vào những ngày làm việc trước đó. Đầu tiên, chúng ta tạo tệp readme.md và có thể thấy tệp đó trong thư mục, tiếp theo chúng ta kiểm tra với `git status` và git đã biết về tệp readme.md nhưng chúng ta chưa commit tệp đó. + +![](../../Days/Images/Day38_Git3.png) + +Chúng ta có thể stage tệp readme.md với lệnh `git add README.md` và có thể thấy thay đổi có thể được commit mà trước đó cũng ta không có và một tệp mới màu xanh lá cây. + +![](../../Days/Images/Day38_Git4.png) + +Tiếp theo chúng ta sẽ commit tệp này với commit đầu tiên của chúng ta. Chúng ta có thể làm điều này với lệnh `git commit -m "Meaningful message"` để có thể dễ dàng hiểu rằng mỗi commit đã thay đổi điều gì. Ngoài ra, hãy chú ý rằng chữ thập màu vàng bây giờ đã thay đổi thành dấu tính màu xanh lá cây. Đây là thứ tôi có trong terminal của mình với theme mà tôi sử dụng, thứ mà chúng ta đã đề cập trong phần nói về Linux. + +![](../../Days/Images/Day38_Git5.png) + +### Commit các thay đổi + +Chúng ta rất có thể muốn thêm nhiều tệp hơn hoặc thậm chí thay đổi các tệp chúng ta có trong thư mục của mình. Chúng tôi đã thực hiện commit đầu tiên của mình ở trên. Nhưng bây giờ, chúng ta sẽ thêm nhiều chi tiết và nhiều tệp hơn. + +Chúng ta có thể lặp lại các quy trình của mình như trước đó, tạo hoặc chỉnh sửa tệp của mình > `git add .` để thêm tất cả các file vào khu vực staging sau đó sử dụng `git commit -m "meaningful message"`. Nhưng để đưa ra một thông điệp có ý nghĩa cho thay đổi trong commit của mình, bạn có lẽ không nên viết ra những thứ như `git commit -m "Chà, tôi đã thay đổi một số mã vì nó không hoạt động và khi tôi sửa mã đó, tôi cũng đã thêm một số thứ mới trong readme.md để đảm bảo rằng mọi người đều biết về trải nghiệm của người dùng và sau đó tôi pha một ấm trà."` Ý tôi là điều này cũng có thể sẽ hiệu quả mặc dù hơi dài dòng nhưng các tốt hơn ở đây là nên thêm thông điệp bằng một trình soạn thảo văn bản. + +Nếu chúng ta chạy `git commit` sau khi chạy `git add`, git sẽ mở trình soạn thảo văn bản mặc định của chúng ta, trong trường hợp của tôi là nano. Dưới đây là các bước tôi đã thực hiện để thêm một số thay đổi vào tệp, chạy `git status` để thấy những thứ đã được staged và chưa được staged. Sau đó, tôi đã sử dụng `git add` để thêm tệp vào khu vực staging, cuối cùng là lệnh `git commit` để mở nano. + +![](../../Days/Images/Day38_Git6.png) + +Khi nano mở ra, bạn có thể thêm mô tả ngắn hoặc dài của mình rồi lưu lại tệp. + +![](../../Days/Images/Day38_Git7.png) + +### Best Practices khi Commit + +Ở đây có sự cân bằng giữa việc commit khi nào và commit thường xuyên. Chúng ta không muốn đợi đến cuối dự án trước khi commit, mỗi commit phải có ý nghĩa và chúng cũng không được kết hợp các nhiệm vụ không liên quan tới nhau. Nếu bạn có một bản sửa lỗi và một lỗi đánh máy, hãy chắc chắn rằng chúng là hai commit riêng biệt như một best practice. + +Làm cho thông điệp commit có ý nghĩa. + +Về cách diễn đạt, nhóm hoặc bạn nên tuân theo một cách diễn đạt cho mỗi lần commit. + +### Bỏ qua khu vực staging + +Có phải chúng ta luôn phải stage các thay đổi của mình trước khi commit chúng? + +Câu trả lời là có nhưng đừng coi đây là một lối tắt, bạn phải chắc chắn 100% rằng bạn không cần một snapshot để quay lại, đó là một việc làm mạo hiểm. + +![](../../Days/Images/Day38_Git8.png) + +### Xoá tệp + +Còn việc xoá tệp khỏi dự án của chúng tôi thì sao, có thể chúng ta có một tệp khác trong thư mục mà chúng ta đã cam kết nhưng hiện tại dự án không còn cần hoặc sử dụng tệp đó nữa, các tốt nhất là chúng ta nên xoá tệp đó. + +Chỉ vì chúng ta xoá tệp đó khỏi thư mục, git vẫn biết tệp này và chúng ta cũng cần xoá tệp khỏi repository. Bạn có thể thấy workflow như bên dưới. + +![](../../Days/Images/Day38_Git9.png) + +Nó có thể hơi khó nhớ hoặc khó thực hiện nếu bạn có một dự án lớn với nhiều tệp và thư mục cần xoá. Chúng ta có thể làm điều này với một lệnh duy nhất `git rm oldcode.ps1`. + +![](../../Days/Images/Day38_Git10.png) + +### Đổi tên hoặc Di chuyển tệp + +Trong hệ điều hành của chúng ta, chúng ta có thể đổi tên và di chuyển các tệp của mình. Chúng ta chắc chắn sẽ cần phải làm điều này rất nhiều lần trong dự án của chúng ta. Tương tự như xoá, quy trình sẽ gồn 2 bước, chúng ta thay đổi các tệp trên hệ điều hành của mình, sau đó sửa đổi và đảm bảo rằng khu vực staging hoặc các tệp được thêm vào một các chính xác. Các bước như sau: + +![](../../Days/Images/Day38_Git11.png) + +Tuy nhiên, giống như xoá các tệp khỏi hệ điều hành và sau đó là git repository, chúng ta có thể thực hiện việc đổi tên này bằng cách sử dụng lệnh git. + +![](../../Days/Images/Day38_Git12.png) + +### Bỏ qua tệp (ignore files) + +Chugns ta có thể có yêu cầu bỏ qua các tệp hoặc thư mục trong dự án của mình, thứ mà chúng ta chỉ sử dụng ở local hoặc nó sẽ tốn không gian nếu chia sẻ với toàn bộ dự án, một ví dụ tốt có thể là các logs. Tôi cũng nghĩ nên sử dụng điều này cho các file bí mật (secrets) mà bạn không muốn chia sẻ công khai hoặc giữa các nhóm. + +Chúng ta có thể bỏ qua các tệp bằng cách thêm các thư mục hoặc tệp vào tệp `.gitignore` trong thư mục dự án của chúng ta. + +![](../../Days/Images/Day38_Git13.png) + +Bạn có thể mở tệp `.gitignore` và thấy rằng chúng ta có thư mục log/. Nhưng chúng ta vẫn có thể thêm các tệp và thư mục tại đây để chúng được bỏ qua. + +![](../../Days/Images/Day38_Git14.png) + +Sau đó chúng ta có thể kiểm tra `git status` và xem điều gì đã xảy ra. + +![](../../Days/Images/Day38_Git15.png) + +Cũng có những ách mà bạn có thể cần quay lại và bỏ qua các tệp và thư mục, có thể bạn muốn chia sẻ thư mục logs nhưng sau đó nhận ra bạn không muốn. Bạn sẽ phải dùng lệnh `git rm --cached ` để xoá tệp và thư mục khỏi khu vực staging nếu bạn có một thư mục đã theo dõi trước đó mà bây giờ bạn muốn bỏ qua. + +### Trạng thái ngắn + +Chúng ta đã sử dụng `git status` rất nhiều để hiểu những gì chúng ta có trong khu vực staging của mình và những gì chúng ta không có, đây là một lệnh rất toàn diện với nhiều thông tin chi tiết. Dần dần, hầu hết những gì bạn muốn biết là cái gì đã được sửa đổi hoặc có gì mới. Chúng ta có thể sử dụng `git status -s` cho một bản tóm tắt ngắn của các chi tiết này. Tôi thường đặt một phím tắt trên hệ thống của mình để chỉ sử dụng `git status -s` so với lệnh chi tiết đầy đủ + +![](../../Days/Images/Day38_Git16.png) + +Trong bài đăng ngài mai, chúng ta sẽ tiếp tục xem qua các ví dụ ngắn về các lệnh git phổ biến. + +## Tài liệu tham khảo + +- [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) +- [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) +- [Git Tutorial for Beginners](https://www.youtube.com/watch?v=8JJ101D3knE&t=52s) +- [Git for Professionals Tutorial](https://www.youtube.com/watch?v=Uszj_k0DGsg) +- [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) +- [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) +- [Git cheatsheet](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) + +Hẹn gặp lại vào [ngày 39](day39.md) diff --git a/2022/vi/Days/day39.md b/2022/vi/Days/day39.md new file mode 100644 index 0000000..a0e1903 --- /dev/null +++ b/2022/vi/Days/day39.md @@ -0,0 +1,212 @@ +--- +title: '#90DaysOfDevOps - Xem, unstaging, loại bỏ & khôi phục - Ngày 39' +published: false +description: '90DaysOfDevOps - Xem, unstaging, loại bỏ & khôi phục' +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048827 +--- + +## Xem, unstaging, loại bỏ & khôi phục + +Tiếp tục với ngày hôm qua sau khi đã thực hành một số lệnh của git và thực hành với dự án mới của bạn. Hãy nhớ rằng, chúng ta chưa nhắc tới GitHub hoặc bất kỳ dịch vụ nào dựa trên git. Tất cả những điều được nhắc tới cho đến bây giờ giúp bản kiểm soát cục bộ các dự án của mình tại thời điển này nhưng chúng sẽ trở nên hữu ích khi bạn tích hợp với các công cụ được nhắc đến ở trên. + +### Xem các thay đổi được staged và chưa được staged + +Bạn nên xem các đoạn mã đã đước staged và chưa được staged trước khi commit. Chúng ta có thể làm điều này với lệnh `git diff --staged` + +![](../../Days/Images/Day39_Git1.png) + +Điều này sau đó cho chúng ta thấyt tất cả những thay đổi chúng ta đã thực hiện và tất cả các tệp mới mà chúng ta đã thêm hoặc xoá. + +Các thay đổi trong các tệp được biểu thị bằng `---` hoặc `+++` bạn có thể thấy như dưới dây, chúng ta vừa thêm dòng mới "+add some text". + +![](../../Days/Images/Day39_Git2.png) + +Chúng ta cũng có thể chạy `git diff` để so sánh khu vực staging với thư mục làm việc của chúng ta. Nếu như thực hiện một số thay đổi với tệp code.txt mới được thêm vào và thêm một số dòng. + +![](../../Days/Images/Day39_Git3.png) + +Nếu sau đó chúng ta chạy lệnh `git diff`, chúng ta sẽ so sánh và có kết quả như dưới đây. + +![](../../Days/Images/Day39_Git4.png) + +### Công cụ Diff trực quan + +Đối với tôi, những hiển thị ở trên rất khó hiểu nên tôi muốn sử dụng một công cụ trực quan hơn, dưới đây là một vài công cụ trực quan để xem được diff: + +- KDiff3 +- P4Merge +- WinMerge (chỉ cho Windows) +- VSCode + +Để thiết lập điều này với git, bạn chạy lệnh sau `git config --global diff.tool vscode` + +Chúng ta sẽ chạy phần trên và sẽ đặt một số tham số khi khởi chạy VScode. + +![](../../Days/Images/Day39_Git5.png) + +Chúng ta cũng có thể kiểm tra cấu hình của mình với `git config --global -e` + +![](../../Days/Images/Day39_Git6.png) + +Sau đó, chúng ta có thể sử dụng `git difftool` để mở công cụ trực quan. + +![](../../Days/Images/Day39_Git7.png) + +Sau đó, mở trang diff trên VSCode và so sánh 2 trang, chúng ta chỉ sửa đổi một tệp từ không có gì thành thêm một dòng mã như ở màn hình bên phải. + +![](../../Days/Images/Day39_Git8.png) + +Tôi thấy phương pháp này dễ dàng hơn nhiều để theo dõi các thay đổi và đây là phương pháp tương tự như những gì chúng ta sẽ thấy khi sử dụng các dịch vụ dựa trên git như GitHub. + +Chúng ta cũng có thể sử dụng `git difftool --staged` để so sánh stage với các tệp đã được commit. + +![](../../Days/Images/Day39_Git9.png) + +Sau đó, chúng ta có thể duyệt qua các tệp đã thay đổi của mình trước khi commit. + +![](../../Days/Images/Day39_Git10.png) + +Tôi đang sử dụng VSCode làm IDE của mình và giống như hầu hết các IDE khác, chúng có chức năng này được tích hợp sẵn, rất hiếm khi bạn cần chạy các lệnh này từ terminal, mặc dù nó rất hữu ích nếu bạn không có sẵn IDE bởi một lý do nào đó. + +### Xem lại lịch sử + +Trước đây chúng ta đã đề cập đến `git log` sẽ cung cấp một cái nhìn toàn diện về tất cả các commit mà chúng ta đã thực hiện trong kho lưu trữ của mình. + +![](../../Days/Images/Day39_Git11.png) + +Mỗi commit có chuỗi thập lục phân, duy nhất cho kho lưu trữ. Tại đây, bạn có thể xem chúng ta đang làm việc trên nhánh nào và sau đó là tác giả, ngày tháng và nội dung commit. + +Chúng ta cũng có `git log --oneline` và điều này mang lại một phiên bản ngắn gọn hơn nhiều của chuỗi thập lục phân mà chúng ta có thể sử dụng trong các lệnh `diff`. Chúng ta cũng chỉ có một dòng mô tả cho các commit. + +![](../../Days/Images/Day39_Git12.png) + +Chúng ta có thể đảo ngược điều này và bắt đầu với commit hận đầu tiên bằng cách chạy `git log --oneline --reverse`, chúng ta thấy commit đầu tiên của mình ở đầu trang. + +![](../../Days/Images/Day39_Git13.png) + +### Xem một commit + +Việc có thể xem nội dung commit là một điều tuyệt vời nếu bạn có ý thức tuân theo các best practices và có những nội dung commit có ý nghĩa. Tuy nhiên, cũng có lệnh `git show` cho phép chúng tôi kiểm tra và xem một commit. + +Chúng ta có thể sử dụng `git log --oneline --reverse` để lấy danh sách các commit của mình rồi lấy chúng và chạy `git show ` + +![](../../Days/Images/Day39_Git14.png) + +Đầu ra của lệnh đó sẽ giống như bên dưới với chi tiết về commit, tác giả và những gì đã thay đổi. + +![](../../Days/Images/Day39_Git15.png) + +Chúng ta cũng có thể sử dụng `git show HEAD~1` trong đó 1 là số bước quay lại từ phiên bản hiện tại. + +Điều này rất hữu ích nếu bạn muốn biết một số chi tiết về tệp của mình, nhưng nếu chúng ta muốn liệt kê tất cả các tệp trong một cây cho toàn bộ snapshot của thư mục. Chúng ta có thể sử dụng lệnh `git ls-tree HEAD~1`, một lần nữa quay lại một snapshot từ commit cuối cùng. Chúng ta có thể thấy có hai blobs, những blobs này biểu thị các tệp trong khi cây biểu thị một thư mục. Bạn cũng có thể thấy các commit và tags. + +![](../../Days/Images/Day39_Git16.png) + +Sau đó, chúng ta có thể sử dụng phần trên để đi sâu vào và xem nội dung của tệp (blobs) bằng cách sử dụng lệnh `git show`. + +![](../../Days/Images/Day39_Git17.png) + +Sau đó, nội dung của phiên bản cụ thể của tệp sẽ được hiển thị. + +![](../../Days/Images/Day39_Git18.png) + +### Unstage tệp + +Sẽ có lúc bạn có thể đã sử dụng `git add .` nhưng có những tệp bạn chưa muốn commit với snapshot đó. Trong ví dụ dưới đây, tôi đã thêm newfile.txt vào khu vực staging của mình nhưng tôi chưa sẵn sàng commit tệp này nên tôi sẽ sử dụng `git restore --staged newfile.txt` để hoàn tác bước `git add`. + +![](../../Days/Images/Day39_Git19.png) + +Chúng ta cũng có thể thực hiện tương tự với các tệp đã sửa đổi, chẳng hạn như main.js và hủy thực hiện commit, như ở trên chúng tôi có chữ M màu xanh lá cây để sửa đổi và sau đó bên dưới chúng ta sẽ hủy thực hiện những thay đổi đó. + +![](../../Days/Images/Day39_Git20.png) + +Tôi nhận thấy lệnh này khá hữu ích với 90DaysOfDevOps vì đôi khi tôi chuẩn bị cho nhiều ngày trước và cảm thấy muốn ghi chú lại nhưng tôi không muốn commit và đẩy lên kho lưu trữ GitHub công khai. + +### Loại bỏ các thay đổi cục bộ + +Đôi khi chúng ta có thể thực hiện các thay đổi nhưng chúng ta không hài lòng với những thay đổi đó và muốn loại bỏ chúng. Chúng ta sẽ sử dụng lại lệnh `git restore` và chúng ta sẽ có thể khôi phục các tệp từ snapshot hoặc các phiên bản trước đó. Chúng ta có thể chạy `git restore .` đối với thư mục của mình và nó sẽ khôi phục mọi thứ từ snapshot của mình, lưu ý rằng tệp chưa được theo dõi của chúng ta vẫn còn. Không có tệp có tên là newfile.txt được theo dõi trước đó. + +![](../../Days/Images/Day39_Git21.png) + +Bây giờ để xóa newfile.txt hoặc bất kỳ tệp nào chưa được theo dõi. Chúng ta có thể sử dụng `git clean`. + +![](../../Days/Images/Day39_Git22.png) + +Hoặc nếu chugns ta biết hậu quả, có thể muốn chạy `git clean -fd` để buộc và xóa tất cả các thư mục. + +![](../../Days/Images/Day39_Git23.png) + +### Khôi phục tệp về một phiên bản cũ + +Như chúng ta đã đề cập trong suốt phần lớn những gì Git có thể giúp là khôi phục các bản sao tệp của bạn từ các snapshot (đây không phải là bản sao lưu nhưng nó là một điểm khôi phục nhanh) Lời khuyên của tôi là bạn cũng nên lưu các bản sao mã của bạn ở các vị trí khác bằng giải pháp dự phòng cho việc này. + +Ví dụ: hãy xóa tệp quan trọng nhất trong thư mục của chúng ta, lưu ý rằng chúng ta đang sử dụng các lệnh dựa trên Unix để xóa tệp này khỏi thư mục, không phải lệnh git. + +![](../../Days/Images/Day39_Git24.png) + +Bây giờ, không còn readme.md trong thư mục làm việc của chúng tôi. Chúng ta có thể đã sử dụng `git rm readme.md` và nó sẽ được phản ánh trong cơ sở dữ liệu git. Chúng ta cũng hãy xóa nó khỏi đây để mô phỏng việc nó bị xóa hoàn toàn. + +![](../../Days/Images/Day39_Git25.png) + +Let's now commit this with a message and prove that we no longer have anything in our working directory or staging area. + +Bây giờ chúng ta hãy commit điều này và chứng minh rằng chúng ta không còn bất kỳ thứ gì trong thư mục làm việc hoặc khu vực tổ chức của mình. + +![](../../Days/Images/Day39_Git26.png) + +Chúng ta đã sai lầm và giờ cần tệp đó trở lại! + +Chúng ta có thể sử dụng lệnh `git undo` để hoàn tác commit cuối cùng, nhưng nếu đó diễn ra trước đó thì sao? Chúng ta có thể sử dụng lệnh `git log` để tìm các commit của mình và sau đó thấy rằng tệp nằm trong commit cuối cùng nhưng chúng ta không hoàn tác toàn bộ commit đó, vì vậy có thể sử dụng lệnh `git restore --source =HEAD~1 README.md` để tìm cụ thể tệp và khôi phục tệp từ snapshot của chúng ta. + +Bạn có thể thấy bằng cách sử dụng quy trình này, giờ đây chúng ta có tệp trở lại trong thư mục làm việc. + +![](../../Days/Images/Day39_Git27.png) + +We now have a new untracked file and we can use our commands previously mentioned to track, stage and commit our files and changes. +Bây giờ chúng ta có một tệp chưa được theo dõi mới và có thể sử dụng các lệnh đã đề cập trước đó để theo dõi, stage và commit các tệp và thay đổi của chúng ta. + +### Rebase vs Merge + +Đây dường như là vấn đề đau đầu nhất khi nói đến Git và khi nào nên sử dụng rebase hoặc merge trên kho git của bạn. + +Điều đầu tiên cần biết là cả `git rebase` và `git merge` đều giải quyết cùng một vấn đề. Cả hai đều để tích hợp các thay đổi từ nhánh này sang nhánh khác. Tuy nhiên, chúng làm điều này theo những cách khác nhau. + +Hãy bắt đầu với một tính năng mới trong một nhánh mới. Nhánh chính tiếp tục với các commit mới. + +![](../../Days/Images/Day39_Git28.png) + +Lựa chọn dễ dàng ở đây là sử dụng `git merge feature main` sẽ hợp nhất nhánh main vào nhánh feature. + +![](../../Days/Images/Day39_Git29.png) + +Merge rất dễ dàng vì nó không có tính phá hủy. Các nhánh hiện tại không bị thay đổi theo bất kỳ cách nào. Tuy nhiên, điều này cũng có nghĩa là nhánh tính năng sẽ có một merge commit không liên quan mỗi khi bạn cần kết hợp các thay đổi với upstream. Nếu main được commit liên tục và nhiều, điều này sẽ hoặc có thể làm bẩn lịch sử commit của nhánh feature. + +Là một tùy chọn thay thế, chúng ta có thể đặt lại nhánh feature lên nhánh main bằng cách sử dụng +``` +git checkout feature +git rebase main +``` + +Điều này chuyển nhánh feature (toàn bộ nhánh feature) kết hợp hiện quả với tất cả các commit mới trong nhánh main. Tuy nhiên, thay vì sử dụng một merge commit, việc rebase sẽ viết lại lịch sử commit bằng cách tạo các commit hoàn toàn mới cho mỗi commit trong nhánh ban đầu. + +![](../../Days/Images/Day39_Git30.png) + +Lợi ích lớn nhất của việc rebase là lịch sử dự án rõ ràng hơn nhiều. Nó cũng loại bỏ các merge commit không cần thiết. Và khi bạn so sánh hai hình ảnh cuối cùng, bạn có thể theo dõi lịch sử dự án tuyến tính rõ ràng hơn nhiều. + +Mặc dù đó vẫn không phải là một kết luận có thể bỏ qua, nhưng việc chọn lịch sử sạch hơn cũng đi kèm với sự đánh đổi. Nếu bạn không tuân theo [Quy tắc vàng của rebase](https://www.atlassian.com/git/tutorials/merging-vs-rebasing#the-golden-rule-of-rebasing) việc viết lại lịch sử dự án có thể là thảm họa đối với quy trình cộng tác của bạn. Và ít quan trọng hơn, việc rebase lại làm mất context được cung cấp bởi một merge commit — bạn không thể biết khi nào các thay đổi upstream được tích hợp vào feature. + +## Tài liệu tham khảo + +- [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) +- [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) +- [Git Tutorial for Beginners](https://www.youtube.com/watch?v=8JJ101D3knE&t=52s) +- [Git for Professionals Tutorial](https://www.youtube.com/watch?v=Uszj_k0DGsg) +- [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) +- [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) +- [Git cheatsheet](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) +- [Exploring the Git command line – A getting started guide](https://veducate.co.uk/exploring-the-git-command-line/) + +Hẹn gặp lại vào [ngày 40](day40.md) diff --git a/2022/vi/Days/day40.md b/2022/vi/Days/day40.md new file mode 100644 index 0000000..3dec6f7 --- /dev/null +++ b/2022/vi/Days/day40.md @@ -0,0 +1,211 @@ +--- +title: '#90DaysOfDevOps - Mạng xã hội dành cho code - Ngày 40' +published: false +description: 90DaysOfDevOps - Mạng xã hội dành cho code +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049044 +--- + +## Mạng xã hội dành cho code + +Khám phá GitHub | GitLab | BitBucket + +Hôm nay tôi muốn đề cập đến một số dịch vụ dựa trên git mà có lẽ tất cả chúng ta đều đã nghe nói đến và có thể đang sử dụng hàng ngày. + +Sau đó, chúng ta sẽ sử dụng một số kiến thức trong buổi trước của mình để. + +Tôi gọi phần này là "Mạng xã hội cho mã" và hãy để tôi giải thích tại sao? + +### GitHub + +Phổ biến nhất ít nhất đối với tôi là GitHub, GitHub là dịch vụ lưu trữ dựa trên web dành cho git. Nó được các nhà phát triển phần mềm sử dụng nhiều nhất để lưu trữ mã của họ. Quản lý mã nguồn với các tính năng quản lý phiên bản git và rất nhiều tính năng bổ sung. Nó cho phép các nhóm hoặc cộng tác viên dễ dàng giao tiếp và xã hội hoá việc viết mã. (do đó có tiêu đề là mạng xã hội) Kể từ năm 2018, GitHub là một phần của Microsoft. + +GitHub đã xuất hiện khá lâu và được thành lập vào năm 2007/2008. Với hơn 40 triệu người dùng trên nền tảng ngày nay. + +Các tính năng chính của GitHub + +- Code Repository +- Pull Requests +- Công cụ quản lý dự án - Issues +- CI / CD Pipeline - GitHub Actions + +Về giá cả, GitHub có các mức giá khác nhau cho người dùng. Bạn có thể tìm thêm thông tin về [Pricing](https://github.com/pricing) + +Lần này, chúng ta sẽ tìm hiểu với cấp miễn phí. + +Tôi sẽ sử dụng tài khoản GitHub đã tạo của mình trong hướng dẫn này, nếu bạn chưa có tài khoản thì trên trang GitHub mở sẽ có tùy chọn đăng ký và các bước dễ dàng để cấu hình. + +### Trang đầu tiên của Github + +Khi bạn đăng nhập lần đầu vào tài khoản GitHub của mình, bạn sẽ nhận được một trang chứa rất nhiều tiện ích cung cấp cho bạn các tùy chọn về địa điểm và nội dung bạn muốn xem hoặc làm. Đầu tiên, chúng ta có mục "All Activity", điều này sẽ cung cấp cho bạn cái nhìn về những gì đang xảy ra với kho lưu trữ hoặc hoạt động được liên kết với tổ chức hoặc tài khoản của bạn. + +![](../../Days/Images/Day40_Git1.png) + +Tiếp theo, chúng ta có Kho lưu trữ mã, kho lưu trữ của riêng chúng ta hoặc kho lưu trữ mà chúng ta đã tương tác gần đây. Chúng ta cũng có thể nhanh chóng tạo các kho mới hoặc tìm kiếm các kho mã. + +![](../../Days/Images/Day40_Git2.png) + +Sau đó, chúng ta có hoạt động gần đây của chúng ta, những điều này đối với tôi là issues và pull requests mà tôi đã tạo hoặc đóng góp gần đây. + +![](../../Days/Images/Day40_Git3.png) + +Ở phía bên phải của trang, chúng ta có một số giới thiệu về các kho mã mà chúng ta có thể quan tâm, rất có thể dựa trên hoạt động gần đây của bạn hoặc các dự án của riêng bạn. + +![](../../Days/Images/Day40_Git4.png) + +Thành thật mà nói, tôi rất hiếm khi vào trang chủ của mình, mặc dù bây giờ tôi thấy rằng việc xem qua nó có thể thực sự hữu ích để giúp tương tác với cộng đồng tốt hơn một chút trong một số dự án nhất định. + +Tiếp theo, nếu chúng ta muốn truy cập Hồ sơ GitHub của mình, chúng ta có thể điều hướng đến góc trên cùng bên phải và trên hình ảnh của bạn, có một drop-down cho phép bạn qua tài khoản của mình. Từ đây để truy cập Hồ sơ của bạn, chọn "Your Profile" + +![](../../Days/Images/Day40_Git5.png) + +Tiếp theo, trang hồ sơ của bạn sẽ xuất hiện theo mặc định, trừ khi bạn thay đổi cấu hình của mình, bạn sẽ không thấy những gì tôi có, tôi đã thêm một số chức năng hiển thị các bài đăng blog gần đây của tôi trên [vZilla](https://vzilla.co.uk) và sau đó là các video mới nhất của tôi trên Kênh [YouTube](https://m.youtube.com/c/MichaelCade1) của mình. + +Bạn sẽ không mất nhiều thời gian để xem hồ sơ của mình, nhưng đây là một nơi rất tốt để chia sẻ với mạng lưới của bạn để họ có thể thấy các dự án thú vị mà bạn đang thực hiện. + +![](../../Days/Images/Day40_Git6.png) + +Sau đó, chúng ta có thể đi sâu vào khối xây dựng của GitHub, các kho lưu trữ. Ở đây bạn sẽ thấy các kho lưu trữ của mình và nếu bạn có các kho lưu trữ private thì chúng cũng sẽ được hiển thị trong danh sách dài này. + +![](../../Days/Images/Day40_Git7.png) + +Vì kho lưu trữ rất quan trọng đối với GitHub, hãy để tôi chọn một kho lưu trữ khá hot trong thời gian gần đây và thực hiện một số chức năng chính có thể sử dụng ở đây khi tôi chỉnh sửa "mã" của chúng ta bằng git trên thống cục bộ của tôi. + +Trước hết, từ cửa sổ trước, tôi đã chọn kho lưu trữ 90DaysOfDevOps và chúng ta có thể thấy mành hình này. Bạn có thể thấy từ đây, chúng ta có rất nhiều thông tin, có cấu trúc mã chính ở giữa hiển thị các tệp và thư mục được lưu trữ trong kho lưu trữ, có readme.md hiển thị ở dưới cùng. Ở bên phải của trang, chúng ta có phần giới thiệu, có mô tả và mục đích của kho lưu trữ. Sau đó, chúng ta có rất nhiều thông tin bên dưới điều này cho thấy có bao nhiêu người đã thả sao cho dự án, số lần được fork và số người theo dõi. + +![](../../Days/Images/Day40_Git8.png) + +Nếu cuộn xuống thêm một chút, bạn cũng sẽ thấy rằng chúng ta có Released, đó là từ phần golang trong thử thách này. Chúng ta không có bất kỳ gói nào trong dự án của mình, và có người đóng góp được liệt kê ở đây. (Cảm ơn cộng đồng đã hỗ trợ tôi kiểm tra chính tả và tính xác thực của thông tin). Sau đó, chúng ta có các ngôn ngữ, đây là những ngôn ngữ được sử dụng trong thử thách. + +![](../../Days/Images/Day40_Git9.png) + +Ở đầu trang, bạn sẽ thấy một danh sách các tab. Chúng có thể khác nhau và chúng có thể được tuỳ biến để chỉ hiển thị những thứ bạn yêu cầu. Bạn sẽ thấy ở đây tôi không sử dụng tất cả những thứ này và nên loại bỏ chúng để đảm bảo toàn bộ kho lưu trữ gọn gàng. + +Đầu tiên, chúng ta có tab code mà chúng ta vừa thảo luận nhưng các tab này sẽ giúp điều hướng qua trong kho lưu trữ, điều này cực kỳ hữu ích để chúng ta có thể chuyển đổi giữa các phần một cách nhanh chóng và dễ dàng. Tiếp theo, chúng ta có tab Issues. + +Issues cho phép bạn theo dõi công việc của mình trên GitHub, nơi quá trình phát triển diễn ra. Trong kho lưu trữ cụ thể này, bạn có thể thấy tôi có một số issue tập trung vào việc thêm sơ đồ hoặc lỗi chính tả nhưng chúng ta cũng có yêu cầu có phiên bản tiếng Trung cho kho lưu trữ. + +Nếu đây là một kho lưu trữ mã thì đây là nơi tuyệt vời để nêu lên các vấn đề với những người bảo trì, nhưng hãy nhớ chú ý và cụ thể về những gì bạn đang báo cáo và cung cấp càng nhiều thông tin càng tốt. + +![](../../Days/Images/Day40_Git10.png) + +Tab tiếp theo là Pull Requests, Pull Requests cho phép bạn thông báo cho người khác về những thay đổi mà bạn đã đẩy tới một nhánh trong kho lưu trữ. Đây là nơi ai đó có thể đã phân nhánh kho lưu trữ của bạn, thực hiện các thay đổi như sửa lỗi hoặc cải tiến tính năng hoặc chỉ lỗi đánh máy. + +Chúng ta sẽ đề cập đến fork sau. + +![](../../Days/Images/Day40_Git11.png) + +Tôi tin rằng tab tiếp theo khá mới? Tab Discussion (Thảo luận). Nhưng tôi nghĩ đối với một dự án như #90DaysOfDevOps, điều này có thể giúp hướng dẫn cho các nội dung mới nhưng cũng giúp ích cho cộng đồng và qua hành trình học tập của mình. Tôi đã tạo một số nhóm thảo luận cho từng phần của thử thách để mọi người có thể tham gia và bình luận. + +![](../../Days/Images/Day40_Git12.png) + +Tab Actions sẽ cho phép bạn build, kiểm thử và triển khai mã,... với GitHub. GitHub Actions sẽ là nội dung chúng ta đề cập trong phần CI/CD của thử thách, đây là nơi chúng ta có thể đặt một số cấu hình để tự động hóa các bước. + +Trên Hồ sơ GitHub chính của mình, tôi đang sử dụng GitHub Actions để tìm các bài đăng trên blog và video YouTube mới nhất để cập nhật màn hình chính đó. + +![](../../Days/Images/Day40_Git13.png) + +Tôi đã đề cập ở trên về cách GitHub không chỉ là kho lưu trữ mã nguồn mà còn là một công cụ quản lý dự án, tab Project cho phép chúng ta xây dựng các bảng kanban cho dự án để chúng ta có thể liên kết các Issues và PR nhằm cộng tác tốt hơn và có thểm theo dõi tiến độ của các tasks. + +![](../../Days/Images/Day40_Git14.png) + +Tôi biết rằng issues có vẻ là một nơi tốt để ghi lại các yêu cầu tính năng và chúng đúng là để làm như vậy nhưng trang wiki cho phép phác thảo một lộ trình toàn diện cho dự án với trạng thái hiện tại và giúp các tài liệu hoàn thiện hơn cho dự án của bạn, ví dụ như hướng dẫn khắc phục sự cố các nội dụng dạng how-to. + +![](../../Days/Images/Day40_Git15.png) + +Không có trong dự án này nhưng có tab Security để đảm bảo rằng những contributors biết cách xử lý một số tác vụ nhất định, chúng ta có thể xác định một policy tại đây cũng như các tiện ích quét mã để đảm bảo mã của bạn không chứa các biến môi trường bí mật. + +![](../../Days/Images/Day40_Git16.png) + +Đối với tôi, tab insights rất tuyệt, nó cung cấp rất nhiều thông tin về kho lưu trữ, từ bao nhiêu hoạt động đang diễn ra cho đến các commits và issues, nhưng nó cũng báo cáo về lượng truy cập vào kho lưu trữ. Bạn có thể thấy một danh sách ở phía bên trái cho phép bạn xem chi tiết về các số liệu trên kho lưu trữ. + +![](../../Days/Images/Day40_Git17.png) + +Cuối cùng, chúng ta có tab Settings, đây là nơi chúng ta có thể xem chi tiết cách chúng ta chạy kho lưu trữ của mình, tôi hiện là người bảo trì duy nhất của kho lưu trữ nhưng chúng ta có thể chia sẻ trách nhiệm này tại đây. Chúng ta có thể định nghĩa tích hợp và các tác vụ khác tương tự như vậy tại đây. + +![](../../Days/Images/Day40_Git18.png) + +This was a super quick overview of GitHub, I think there are some other areas that I might have mentioned that need explaining in a little more detail. As mentioned GitHub houses millions of repositories mostly these are holding source code and these can be public or privately accessible. + +Đây là tổng quan siêu nhanh về GitHub, tôi nghĩ rằng có một số lĩnh vực khác mà tôi có thể đã đề cập cần được giải thích chi tiết hơn một chút. Như đã đề cập, GitHub chứa hàng triệu kho lưu trữ, hầu hết những kho lưu trữ này đang chứa mã nguồn và chúng có thể được truy cập công khai hoặc riêng tư. + +### Forking + +Ta sẽ tìm hiểu thêm về Nguồn mở trong buổi ngày mai nhưng một phần quan trọng của bất kỳ kho lưu trữ mã nào là khả năng cộng tác với cộng đồng. Hãy nghĩ về kịch bản sau: tôi muốn có một bản sao của kho lưu trữ vì tôi muốn thực hiện một số thay đổi, có thể tôi muốn sửa lỗi hoặc có thể tôi muốn thay đổi thứ gì đó để sử dụng nó cho trường hợp sử dụng mà tôi có thể không trường hợp sử dụng dự định cho người bảo trì ban đầu của mã. Đây là những gì chúng ta gọi là forking một kho lưu trữ. Một fork là một bản sao của một kho lưu trữ. Forking một kho lưu trữ cho phép bạn tự do thử nghiệm các thay đổi mà không ảnh hưởng đến dự án ban đầu. + +Hãy quay lại trang mở đầu sau khi đăng nhập và xem một trong những kho lưu trữ được đề xuất đó. + +![](../../Days/Images/Day40_Git19.png) + +Nếu chúng ta nhấp vào kho lưu trữ đó, chúng ta sẽ có giao diện giống như kho lưu trữ 90DaysOfDevOps. + +![](../../Days/Images/Day40_Git20.png) + +Nếu để ý bên dưới, chúng ta có 3 tùy chọn, chúng ta có watch, fork và star. + +- Watch - Cập nhật các thay đổi của kho lưu trữ. +- Fork - một bản sao của một kho lưu trữ. +- Star - "Tôi nghĩ dự án của bạn rất tuyệt" + +![](../../Days/Images/Day40_Git21.png) + +Với kịch bản của chúng ta là muốn một bản sao của kho lưu trữ để làm việc với nó, chúng ta sẽ nhấn tùy chọn fork. Nếu bạn là thành viên của nhiều tổ chức thì bạn sẽ phải chọn nơi để fork, tôi sẽ chọn profile của mình. + +![](../../Days/Images/Day40_Git22.png) + +Bây giờ chúng ta có bản sao của kho lưu trữ để có thể tự do làm việc và thay đổi phù hợp. Đây sẽ là bước khởi đầu của quy trình pull request mà chúng ta đã đề cập ngắn gọn trước đây, nó sẽ được đề cập chi tiết hơn vào ngày mai. + +![](../../Days/Images/Day40_Git23.png) + +Ok, nhưng làm cách nào để thay đổi kho lưu trữ và mã này nếu nó ở trên một trang web, bạn có thể xem qua và chỉnh sửa trực tiếp trên đó nhưng bạn không thể sử dụng IDE yêu thích của bạn trên máy cá nhân với theme màu yêu thích của bạn. Để chúng ta có được một bản sao của kho lưu trữ này trên máy của mình, chúng ta sẽ clone kho lưu trữ đó. Điều này sẽ cho phép chúng ta làm việc trên môi trường cục bộ và sau đó đẩy (push) các thay đổi trở lại bản sao được fork từ kho lưu trữ gốc. + +Chúng ta có một số tùy chọn khi nhận được một bản sao của mã này như bạn có thể thấy bên dưới. + +Có một phiên bản của GitHub Desktop cung cấp cho bạn một ứng dụng máy tính t để theo dõi các thay đổi cũng như push và pull các thay đổi giữa môi trường local và GitHub. + +Đối với demo nhỏ này, tôi sẽ sử dụng URL HTTPS mà chúng ta thấy trên đó. + +![](../../Days/Images/Day40_Git24.png) + +Bây giờ trên máy cục bộ của chúng ta, tôi sẽ điều hướng đến một thư mục mà tôi muốn tải xuống kho lưu trữ này và sau đó chạy `git clone url` + +![](../../Days/Images/Day40_Git25.png) + +Bây giờ chúng ta có thể mở nó bằng VSCode và thay đổi một số thứ. + +![](../../Days/Images/Day40_Git26.png) + +Hãy thực hiện một số thay đổi, tôi muốn thay đổi các liên kết đó và thay thế nó bằng thứ gì khác. + +![](../../Days/Images/Day40_Git27.png) + +Bây giờ, nếu chúng ta kiểm tra lại GitHub và tìm tệp Readme.md trong kho lưu trữ đó, bạn có thể thấy một vài thay đổi mà tôi đã thực hiện đối với tệp đó. + +![](../../Days/Images/Day40_Git28.png) + +Ở thời điểm này, quá trình này có thể đã hoàn tất và chúng ta có thể hài lòng với thay đổi của mình vì chúng ta là những người duy nhất sẽ sử dụng thay đổi mới đó. Nhưng rất có thể sẽ có lúc thay đổi của chúng ta là để sửa một bug và thông qua một Pull request, chúng ta sẽ thông báo cho những người bảo trì kho lưu trữ đó về thay đổi của chúng ta và xem liệu họ có chấp nhận những thay đổi đó hay không. + +Chúng ta có thể làm điều này bằng cách sử dụng nút Contribute được làm rõ ở dưới đây. Tôi sẽ đề cập nhiều hơn về vấn đề này vào ngày mai khi chúng ta xem xét quy trình làm việc với các phần mềm mã nguồn mở. + +![](../../Days/Images/Day40_Git29.png) + +Tôi đã dành một thời gian dài để hướng dẫn về Github và tôi nghe thấy một số yêu cầu vê những lựa chọn khác. + +Và tôi cũng sẽ tìm một số tài nguyên cơ bản cho những vấn đề đó. Bạn sẽ thấy GitLab và BitBucket trong số những lựa chọn khi bạn sử dụng các dịch vụ quản lý phiên bản, tuy chúng là những dịch vụ dựa trên git nhưng chúng cũng có một số khác biệt nhất dịnh. + +Bạn cũng sẽ bắt gặp các tuỳ chọn tự host. Phổ biến nhất ở đây tôi có thể thấy là GitLab và GitHub Enterprise (Tôi không nghĩ rằng có dịch vụ tự host miễn phí của Github?) +## Tài liệu tham khảo + +- [Learn GitLab in 3 Hours | GitLab Complete Tutorial For Beginners](https://www.youtube.com/watch?v=8aV5AxJrHDg) +- [BitBucket Tutorials Playlist](https://www.youtube.com/watch?v=OMLh-5O6Ub8&list=PLaD4FvsFdarSyyGl3ooAm-ZyAllgw_AM5) +- [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) +- [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) +- [Git Tutorial for Beginners](https://www.youtube.com/watch?v=8JJ101D3knE&t=52s) +- [Git for Professionals Tutorial](https://www.youtube.com/watch?v=Uszj_k0DGsg) +- [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) +- [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) +- [Git cheatsheet](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) + +Hẹn gặp lại vào [ngày 41](day41.md) diff --git a/2022/vi/Days/day41.md b/2022/vi/Days/day41.md new file mode 100644 index 0000000..fcf1da6 --- /dev/null +++ b/2022/vi/Days/day41.md @@ -0,0 +1,129 @@ +--- +title: '#90DaysOfDevOps - Quy trình làm việc với mã nguồn mở - Ngày 41' +published: false +description: 90DaysOfDevOps -Quy trình làm việc với mã nguồn mở +tags: 'DevOps, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048806 +--- + +## Quy trình làm việc với mã nguồn mở + +Hi vọng rằng qua 7 bài viết vừa rồi với Git, chúng ta đã hiểu rõ hơn về git là gì và sau đó là cách một dịch vụ sử dụng git như Github tích hợp với git để cung cấp kho lưu trữ mã nguồn và cũng là cách cộng đồng có thể cộng tác trên mã và các dự án khác nhau. + +Khi chúng ta xem xét các kiến thức cơ bản về GitHub, chúng ta đã trải qua quá trình fork một dự án bất kỳ và thực hiện thay đổi đó với kho lưu trữ cục bộ của chúng ta. Bây giờ, chúng ta sẽ tiến thêm một bước và thực hiện đóng góp cho một dự án mã nguồn mở. Hãy nhớ rằng việc đóng góp không nhất thiết phải là các bản sửa lỗi hoặc các tính năng cần viết mã, nó cũng có thể là tài liệu, sửa lỗi chính tả. Tất cả thứ dù là nhỏ nhất đều hữu ích và nó cũng cho phép bạn thực hành với một số chức năng git mà chúng ta đã đề cập trong những ngày qua. + +## Fork một project + +Điều đầu tiên chúng ta phải làm là tìm một dự án mà chúng ta có thể đóng góp. Gần đây, tôi đã thuyết trình về dự án [Kanister Project](https://github.com/kanisterio/kanister) và tôi muốn chia sẻ các bài thuyết trình của mình đã được đăng tải trên Youtube tới tệp Readme.md trong project đó. + +Trước hết, chúng ta cần fork project đó. Hãy cùng thử quy trình đó. Tôi sẽ tới liên kết đã ở trên và fork kho lưu trữ của project. + +![](../../Days/Images/Day41_Git1.png) + +Bây giờ, chúng ta đã có bản sao của toàn bộ kho lưu trữ. + +![](../../Days/Images/Day41_Git2.png) + +Để tham khảo trên tệp Readme.md, các bài trình bài ban đầu được liệt kê chỉ gồm 2 bài này, vì vậy chúng ta sẽ sửa với quy trình của chúng ta. + +![](../../Days/Images/Day41_Git3.png) + +## Clone vào máy cục bộ + +Sau khi có bản fork của kho lưu trữ, chúng ta có thể mang nó xuống máy cục bộ của mình và bắt đầu thực hiện chỉnh sửa của mình đối với các tệp. Sử dụng nút `code` trong repo của chúng ta để có thể lấy URL của kho lưu trữ rồi sử dụng lệnh `git clone ` trong thư mục mà chúng ta muốn đặt kho lưu trữ. + +![](../../Days/Images/Day41_Git4.png) + +## Thực hiện các thay đổi + +Sau khi có project ở máy của mình, chúng ta có thể mở VSCode hoặc IDE, text editor tuỳ chọn của mình để thực hiện thay đổi của mình. + +![](../../Days/Images/Day41_Git5.png) + +Tệp Readme.md được viết dưới cú pháp markdown và vì chúng ta đang chỉnh sửa một project của người khác nên sẽ thêm nội dung của mình với format của dự án hiện tại. + +![](../../Days/Images/Day41_Git6.png) + +## Kiểm tra thay đổi của bạn + + +Chúng ta phải kiểm tra các thay đổi của mình theo cách tốt nhất, điều này rất hợp lý nếu đây là thay đổi mã nguồn đối với một ứng dụng mà bạn muốn đảm bảo rằng ứng dụng vẫn hoạt động sau khi thay đổi được thêm vào, chúng ta cũng phải đảm bảo rằng tài liệu được định dạnh và trông một cách chuẩn xác. + +Với VSCode, chúng ta có thể thêm nhiều plugin, một trong số đá là khả năng xem trước các trang markdown. + +![](../../Days/Images/Day41_Git7.png) + +## Push các thay đổi trở lại kho lưu trữ của chúng ta + +Chúng ta không có quyền để đẩy trực tiếp các thay đổi trở lại kho lưu trữ của Kanister, vì vậy chúng ta phải đi theo con đường này. Bây giờ sau khi chúng ta hài lòng với những thay đổi cùa mình, chúng ta có thể chạy quả một số lệnh phổ biến của git. + +![](../../Days/Images/Day41_Git8.png) + +Bây giờ, chúng ta quay trở lại Github để kiểm tra các thay đổi một lần nữa và sau đó đóng góp cho dự án chính. + +Trong có vẻ ổn. + +![](../../Days/Images/Day41_Git9.png) + +Bây giờ chúng ta có thể quay trở lại kho lưu trữ được forked của Kanistẻ và thấy rằng mình đang ở trước một commit so với nhánh kanisterio:master. + +![](../../Days/Images/Day41_Git10.png) + +Tiếp theo, chúng ta nhấn nút `contribute` được đánh dấu ở trên. Chúng ta thấy có lựa chọn "Open Pull Request". + +![](../../Days/Images/Day41_Git11.png) + +## Mở một pull request + +Có khá nhiều thứ trong hình ảnh sau đây, trên cùng bên trái, bạn có thấy chúng ta đang ở kho lưu trữ gốc hoặc kho lưu trữ chính. Một nút tạo Pull request mà chúng ta sẽ nhắc tới sau đây. Chúng ta có một commit duy nhất nhưng nếu chúng ta sửa nhiều hơn thì có thể thấy được nhiều commits hơn ở đây. Sau đó là thay đổi trong tệp Readme.md của mà chúng ta đã thêm vào. + +![](../../Days/Images/Day41_Git12.png) + + +Sau khi xem xét các thay đổi ở trên và sẵn sàng tạo pull request, chúng ta có thể click nút màu xanh lá cây. + +Sau đó, tuỳ thuộc vào cách người bảo trì dự án thiết lập chứng năng Pull Request trong kho lưu trữ của họ, bạn có thể cần hoặc không cung cấp những thông tin về Pull request theo một template mà người bảo trì đã chuẩn bị. + +Đây là nơi bạn muốn mô tả về những gì bạn đã làm, rõ ràng và ngắn gọn nhưng đầy đủ chi tiết. Bạn có thể thấy tôi đã thực hiện một tổng quan về thay đổi đơn giản và tôi đã đánh dấu vào các đầu mục. + +![](../../Days/Images/Day41_Git13.png) + +## Tạo một pull request + +Bây giờ chúng ta đã sẵn sàng tạo một pull request. Sau khi nhấn "Create Pull Request" ở đầu trang, bạn sẽ nhận được bản tóm tắt về pull request của mình. + +![](../../Days/Images/Day41_Git14.png) + +Kéo xuống dưới, bạn có thể thấy một số quá trình tự động hoá đang diễn ra, trong trường hợp này, chúng ta yêu cầu một review cho pull request của mình. Chúng ta có thể thấy Travis CI đang được tiên shanfh và quá trình build đã được bắt đầu và nó sẽ kiểm tra bản cập nhật của chúng ta, đảm bảo bổ sung mới không phá vỡ bất cứ điều gì. + +![](../../Days/Images/Day41_Git15.png) + +Một điều khác cần lưu ý ở đây là màu đỏ trong ảnh chụp màn hình ở trên, có thể trông hơi khó chịu và có vẻ như bạn đã mặc một lỗi gì đó. Đừng lo lắng, bạn không làm hỏng bất cứ thứ gì, quy trình này là để giúp bạn và người bảo trì của dự án. Theo kinh nghiệm của tôi, nếu bạn mặc mỗi lỗi, người bảo trì sẽ liên hệ và tư vấn về những việc cần làm tiếp theo. + +Pull request này hiện đã được công khai cho mọi người xem [added Kanister presentation/resource #1237](https://github.com/kanisterio/kanister/pull/1237) + +Tôi sẽ publish tất cả những điều này trước khi pull request của tôi được chấp nhận, có lẽ sẽ có một phần thưởng cho ai thêm một hình ảnh của một PR thành công? + +1. Fork kho lưu trữ này về GitHub account của bạn +2. Thêm hình ảnh và có thể là một chút văn bản +3. Đẩy các thay đổi vào kho lưu trữ đã được forked của bạn +4. Tạo PR để tôi xem xét và duyệt +5. Tôi sẽ nghĩ một số giải thưởng + +Phần này kết thúc quá trình tìm hiểu về Git và GitHub của chúng ta, tiếp theo, chúng ta sẽ đi sâu vào containers, bắt đầu bằng một bức tranh toàn cảnh, xem xét cách thức và lý do tại sao các chúng ta sử dụng containers cũng như tìm hiểu thêm về ảo hoá. + +## Tài liệu tham khảo + +- [Learn GitLab in 3 Hours | GitLab Complete Tutorial For Beginners](https://www.youtube.com/watch?v=8aV5AxJrHDg) +- [BitBucket Tutorials Playlist](https://www.youtube.com/watch?v=OMLh-5O6Ub8&list=PLaD4FvsFdarSyyGl3ooAm-ZyAllgw_AM5) +- [What is Version Control?](https://www.youtube.com/watch?v=Yc8sCSeMhi4) +- [Types of Version Control System](https://www.youtube.com/watch?v=kr62e_n6QuQ) +- [Git Tutorial for Beginners](https://www.youtube.com/watch?v=8JJ101D3knE&t=52s) +- [Git for Professionals Tutorial](https://www.youtube.com/watch?v=Uszj_k0DGsg) +- [Git and GitHub for Beginners - Crash Course](https://www.youtube.com/watch?v=RGOj5yH7evk&t=8s) +- [Complete Git and GitHub Tutorial](https://www.youtube.com/watch?v=apGV9Kg7ics) +- [Git cheatsheet](https://www.atlassian.com/git/tutorials/atlassian-git-cheatsheet) + +Hẹn gặp lại vào [ngày 42](day42.md) diff --git a/2022/vi/Days/day42.md b/2022/vi/Days/day42.md new file mode 100644 index 0000000..690d148 --- /dev/null +++ b/2022/vi/Days/day42.md @@ -0,0 +1,135 @@ +--- +title: '#90DaysOfDevOps - Bức tranh toàn cảnh: Containers - Day 42' +published: false +description: 90DaysOfDevOps - Bức tranh toàn cảnh Containers +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048826 +--- + +## Bức tranh toàn cảnh: Containers + +Bây giờ, chúng ta bắt đầu với phần tiếp theo và phần này sẽ tập trung vào các containers, cụ thể là chúng ta sẽ nói tới Docker, một vài phần chính để hiểu thêm về các containers. + +Tôi cũng sẽ cố gắng thực hành nhiều trong phần này để tại một số container sử dụng trong phần này và các phần sau của thử thách. + +Như mọi khi, bài đăng đầu tiên này sẽ tập trung vào bức tranh toàn cảnh cách chúng ta đi được tới đây và ý nghĩa của những điều đó. + +- Lịch sử của các phát triển platforms và các ứng dụng +- Chúng ta cũng sẽ nói về ảo hoá và container hoá + +### Tại sao chạy ứng dụng bằng một cách khác? + +Điều đầu tiên chúng ta phải xem xét là tại sao chúng ta cần một cách khác để chạy phần mềm hoặc ứng dụng của mình? Chà, lựa chọn đó thật tuyệt, chúng ta có thể chạy các ứng dụng của mình ở nhiều dạng khác nhau, chúng ta có thể thấy các ứng dụng được triển khai trên phần cứng vật lý có hệ điều hành và một ứng dụng duy nhất được triển khai tại đó. Cũng có thể thấy máy ảo hoặc các phiên bản IaaS sử dụng điện toán đám mây chạy ứng dụng của chúng ta, sau đó tích hợp lại vào cơ sở dữ liệu trong máy ảo hoặc dưới dạng cung cấp PaaS trong đám mây công cộng. Hoặc cũng có thể thấy ứng dụng chạy trong các containers. + +Không có lựa chọn nào ở trên là đúng hay sai, nhưng chúng đều có lý do để tồn tại và tôi cũng tin tưởng rằng không có lựa chọn nào trong số này sẽ biến mất trong tương lai gần. Tôi đã thấy rất nhiều nội dung liên quan đến việc so sánh container và VMs và thực sự điều đó không nên được tranh luận, nó giống như tranh luận táo với lê quả nào ngon hơn dù cả hai đều là trái cây (=cách chạy ứng dụng của chúng ta) và chúng không giống nhau. + +Tôi cũng muốn nói rằng nếu bạn mới bắt đầu và đang phát triển một ứng dụng, bạn nên hướng tới các container đơn gỉan khi xét về tính hiệu quả, tốc độ và kích thước. Nhưng điều đó cũng đi kèm với một cái giá, nếu bạn không biết gì về container thì đó sẽ là một quá trình học tập để buộc bản thân bạn phải hiểu lý do tại sao chúng ta sử dụng và xây dựng một mindset mới. Nếu bạn đã phát triển các ứng dụng của mình theo một cách cụ thể hoặc chưa từng sử dụng containers thì bạn có thể có nhiều vấn đề khó giải quyết hơn trước cả khi xem xét đến việc sử dụng chúng. + +Chúng tôi có nhiều sự lựa chọn khác nhau khi tải xuống một phần mềm nhất định, có rất nhiều hệ điều hành khác nhau mà chúng ta có thể đang sử dụng và hướng dẫn cụ thể về những gì chúng ta cần làm để cài đặt ứng dụng của mình. + +![](../../Days/Images/Day42_Containers1.png) + +Gần đây, tôi nhận thấy rằng các ứng dụng mà chúng tôi có thể đã từng cần một hệ điều hành máy chủ đầy đủ, một máy ảo, một instance vật lý hoặc điện toán đám mây hiện đang phát hành các phiên bản phần mềm trên container của chúng. Tôi thấy điều này khá thú vị vì nó đứa thế giới của container và sau đó là Kubernetes tới mọi người chứ không chỉ tập trung vào các nhà phát triển ứng dụng. + +![](../../Days/Images/Day42_Containers2.png) + +Như bạn có thể thấy như tôi đã nói trước đây, tôi sẽ không cố thuyết phục rằng câu trả lời cho việc chạy các ứng dụng là việc sử dụng các containers! Tôi nói răng đây là một tùy chọn khác mà chúng ta cần lưu ý khi triển khai các ứng dụng của mình. + +![](../../Days/Images/Day42_Containers4.png) + +Chúng ta đã có công nghệ container trong một thời gian dài, vậy tại sao trong 10 năm qua, điều này đã trở nên phổ biến, tôi có thể nói rằng thậm chí nó còn phổ biến hơn trong 5 năm qua. Chúng ta đã có container trong nhiều thập kỷ. Nó liên quan đến các thách thức của containers hay thậm chí các images, về cách chúng ta phân phối phần mềm của mình, bởi vì nếu chúng ta chỉ có công nghệ container, thì chúng ta vẫn sẽ gặp các vấn đề giống như chúng ta đã gặp phải với quản lý phần mềm. + +Nếu chúng ta coi Docker như một công cụ, thì lý do khiến nó thành công là do hệ sinh thái images dễ tìm kiếm và sử dụng. Việc tích hợp vào hệ thống của bạn và thiết lập và chạy trở nên rất đơn giản. Một phần quan trọng của điều này là tính nhất quán, một trong những thách thức mà chúng ta phải đối mặt với việc triển phai, phát triển phần mềm. Không quan trọng đó là MongoDB hay nodeJS, quá trình thiết lập và chạy hai phần mềm này sẽ giống nhau. Việc tắt các ứng dụng trên cũng giống nhau. Tất cả những vấn đề vẫn sẽ tồn tại, nhưng điều tuyệt vời là khi chúng tôi kết hợp công nghệ images và containers với nhau, giờ đây chúng tôi có một bộ công cụ duy nhất giúp chúng tôi giải quyết tất cả các vấn đề được liệt kê dưới đây: + +- Đầu tiên chúng ta phải tìm phần mềm trên internet. +- Sau đó chúng ta phải tải phần mềm này về. +- Chúng ta có tin nguồn mà chúng ta tải về không? +- Vậy chúng ta có cần giấy phép không? License nào là phù hợp? +- Có tương thích với các nền tảng khác nhau không? +- Package đó là gì? mã nhị phân? tệp thực thi? Trình quản lý gói? +- Làm thế nào để chúng ta cấu hình phần mềm? +- Các dependencies? Toàn bộ quá trình tải xuống bao gồm chúng hay chúng ta cũng cần cài đặt, cấu hình chúng? +- Dependencies của dependencies? +- Làm thế nào để bắt đầu ứng dụng? +- Làm thế nào để dừng ứng dụng? +- Nó có tự động khởi động lại không? +- Khởi động khi boot? +- Xung đột tài nguyên? +- Xung đột thư viện? +- Xung đột cổng +- Bảo mật cho phần mềm? +- Nâng cấp phần mềm? +- Làm cách nào để gỡ bỏ phần mềm? + +Chúng ta có thể chia những điều trên thành 3 lĩnh vực rất phức tạp của phần mềm mà các containers và images giúp chúng ta giải quyết. + +| Phân phối | Cài đặt | Vận hành | +| ------------ | ------------- | ------------------ | +| Find | Install | Start | +| Download | Configuration | Security | +| License | Uninstall | Ports | +| Package | Dependencies | Resource Conflicts | +| Trust | Platform | Auto-Restart | +| Find | Libraries | Updates | + + +Containers và images sẽ giúp chúng ta loại bỏ một số thách thức mà chúng ta gặp phải với các phần mềm và ứng dụng khác. + +Ở high-level, chúng ta có thể gộp cài đặt và vận hành vào cùng một danh sách, images sẽ giúp chúng ta từ quan điểm phân phối và containers giúp cài đặt và vận hành. + +Ok, nghe có vẻ hay và thú vị nhưng chúng ta vẫn cần hiểu containers là gì và như tôi đã đề cập đến images nên tiếp theo chúng ta hãy đề cập đến phần đó. + +Một điều khác mà bạn có thể đã thấy rất nhiều khi chúng ta nói về Container để phát triển phần mềm là sự giống nhau của chúng với các công-te-nơ (container) vận chuyển, container vận chuyển được sử dụng để vận chuyển nhiều loại hàng hóa trên biển bằng tàu lớn. + +![](../../Days/Images/Day42_Containers5.png) + +Vậy thì những điều này có liên quan gì tới chủ đề container của chúng ta? Hãy nghĩ về mã nguồn mà các nhà phát triển phần mềm đã viết, làm thế nào chúng ta có thể triển kahi mã đó từ máy này sang một máy khác? + +Nếu chúng ta nghĩ về những gì đã được biết tới phân phối phần mềm, cài đặt và vận hành nhưng bây giờ chúng ta sẽ xây dựng chúng tành một hình ảnh môi trường. Chúng ta có phần cứng và hệ điều hành nơi bạn sẽ chạy nhiều ứng dụng. Ví dụ: NodeJS có một số dependencies nhất định và cần một số thư viện nhất định. Nếu sau đó bạn muốn cài đặt MySQL thì nó cần các thư viện và dependencies cần thiết. Mỗi ứng dụng phần mềm sẽ có thư viện và dependencies của nó. Chúng ta có thể rất may mắn và không có bất kỳ xung đột nào giữa bất kỳ các ứng dụng nào của chúng ta bởi sự xung đột giữa các thư viện và dependencies. Tuy nhiên, càng nhiều ứng dụng thì sẽ có càng nhiều cơ hội hoặc rủi ro xảy ra do các xung đột đó. Các ứng dụng sẽ được cập nhật và những xung đột này. Rất có thể với một lần triển khai sửa chữa các phần mềm của bản bằng việc update chúng sẽ tạo ra các xung đột khác. + +![](../../Days/Images/Day42_Containers6.png) + +Containers có thể giúp giải quyết vấn đề này. Containers giúp **xây dựng** ứng dụng của bạn, **vận chuyển** ứng dụng đó, **triển khai** và **mở rộng quy mô các ứng dụng này một cách dễ dàng và độc lập với nhau. Hãy nhìn vào kiến trúc, bạn sẽ có phần cứng và hệ điều hành, sau đó, bạn sẽ có một container engine như docker (chúng ta sẽ nhắc tới sau). Phần mềm container engine sẽ giúp tạo các container đóng gói các thư viện và các dependencies cùng với nó để bạn có thể di chuyển container này từ máy này sang máy khác mà không phải lo lắng về các thư viện và dependencies vì chúng là một phần của container. Container này có thể được di chuyển qua các hệ thống mà không phải lo lắng về các dependencies mà ứng dụng cần để chạy vì mọi thứ mà ứng dụng cần đều được đóng gói thành một container. + +![](../../Days/Images/Day42_Containers7.png) + +### Ưu điểm của containers + +- Container giúp đóng gói tất cả các dependencies bên trong và cô lập nó. + +- Dễ dàng quản lý các containers + +- Khả năng di chuyển từ hệ thống này qua hệ thống khác + +- Container giúp đóng gói phần mềm và bạn có thể dễ dàng vận chuyển nó mà không cần nhiều nỗ lực + +- Container có khả năng mở rộng dễ dàng + +Sử dụng các container, bạn có thể mở rộng các container và sử dụng bộ cân bằng tải hoặc một service để phân chia lưu lượng và có thể mở rộng ứng dụng theo chiều ngang. Container cung cấp tính linh hoạt và dễ dàng trong việc quản lý các ứng dụng của mình. + +### Container là gì? + +Khi chúng ta chạy các ứng dụng trên máy tính, đây có thể là VSCode hoặc trình duyệt web mà bạn đang sử dụng để đọc bài viết này. Ứng dụng đó đang chạy dưới dạng một process hoặc một thứ gì đó coi là một process. Trên máy tính xách tay hoặc hệ thống của chúng ta, chúng ta có xu hướng chạy nhiều ứng dụng hoặc như chúng tôi đã nói là các process. Khi chúng ta mở một ứng dụng mới hoặc click vào biểu tượng ứng dụng, đây là ứng dụng chúng ta muốn chạy, đôi khi ứng dụng này có thể là một dịch vụ mà chúng tôi chỉ muốn chạy nền, hệ điều hành của chúng ta có rất nhiều các dịch vụ chạy nền cung cấp cho bạn trải nghiệm người dùng mà bạn có đang có với hệ thống. + +Biểu tượng ứng dụng đó đại diện cho một liên kết đến một tệp thực thi ở đâu đó trên hệ thống tệp của bạn, sau đó hệ điều hành sẽ tải tệp thực thi đó vào bộ nhớ. Thật thú vị, tệp thực thi đó đôi khi được nhắc tới như là một hình ảnh khi chúng ta đang nói về một process. + +Containers là các processes, một container là một đơn vị phần mềm tiêu chuẩn đóng gói mã và tất cả các dependencies của nó để ứng dụng chạy nhanh và đáng tin cậy từ môi trường điện toán này sang môi trường điện toán khác. + +Phần mềm được đóng gói trong container sẽ luôn chạy giống nhau, bất kể trên cơ sở hạ tầng nào. Các container cách ly phần mềm khỏi môi trường của nó và đảm bảo rằng nó hoạt động đồng nhất bất chấp sự khác biệt chẳng hạn giữa môi trường phát triển và staging. + +Tôi đã đề cập đến image trong phần trước khi đề cập đến cách thức và lý do tại sao các container và image được kết hợp với nhau khiến các container trở nên phổ biến trong hệ sinh thái của chúng ta. + +### Image là gì? + +Container image là một gói phần mềm nhẹ, độc lập, có thể thực thi, bao gồm mọi thứ cần thiết để chạy một ứng dụng: mã, runtime, công cụ hệ thống, thư viện hệ thống và cài đặt. Container image trở thành container khi chạy. + +## Tài liệu tham khảo + +- [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) +- [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) +- [Docker Tutorial for Beginners - What is Docker? Introduction to Containers](https://www.youtube.com/watch?v=17Bl31rlnRM&list=WL&index=128&t=61s) +- [Introduction to Container By Red Hat](https://www.redhat.com/en/topics/containers) + +Hẹn gặp lại vào [ngày 43](day43.md) diff --git a/2022/vi/Days/day43.md b/2022/vi/Days/day43.md new file mode 100644 index 0000000..0b759ff --- /dev/null +++ b/2022/vi/Days/day43.md @@ -0,0 +1,94 @@ +--- +title: '#90DaysOfDevOps - Docker là gì & Cài đặt - Ngày 43' +published: false +description: 90DaysOfDevOps - Docker là gì & Cài đặt +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048739 +--- + +## Docker là gì & Cài đặt + +Trong bài viết trước, tôi đã đề cập đến Docker ít nhất một lần và lý do là Docker đá đóng góp công lớn trong việc làm cho container trở nên phổ biến mặc dù chúng đã xuất hiện từ lâu. + +Chúng ta sẽ sử dụng và giải thích về docker nhưng cũng sẽ đề cập tới [Open Container Initiative (OCI)](https://www.opencontainers.org/) là một tổ chức tiêu chuẩn công nghiệp khuyến khích đổi mới đồng thời giảm thiểu nguy cơ các dịch vụ bị khoá với các nhà cung cấp. Nhờ có OCI, khi chúng ta chọn chuỗi các công cụ container, chúng ta có thể chọn Docker, [CRI-O](https://cri-o.io/), [Podman](http://podman.io/), [LXC](https://linuxcontainers.org/), và các công cụ khác. + +Docker là một khung phần mềm để xây dựng, chạy, quản lý các vùng chứa. Thuật ngữ "docker" có thể đề cập đến các công cụ (các lệnh và deamon) + hoặc định dạng tệp Dockerfile. + +Chúng ta sẽ sử dụng Docker Personal trong tuần này, nó sẽ được miễn phí cho mục đích học tập. Tất cả những chức năng cần thiết mà chúng ta cần trang bị để có kiến thức nền tảng tốt về container và công cụ xung quanh đều có trong Docker Personal. + +Có lẽ đáng để chia nhỏ một số công cụ "docker" mà chúng ta sẽ sử dụng và cách chúng được sử dụng. Thuật ngữ docker có thể đề cập đến dự án docker nói chung, đây là một nền tảng dành cho các nhà phát triển và quản trị viên để phát triển, vận chuyển và chạy các ứng dụng. Nó cũng có thể nhắn tới process docker daemon chạy trên máy chủ quản lý image và container, hay còn được gọi là Docker Engine. + +### Docker Engine + +Docker Engine là một công nghệ container mã nguồn mở để xây dựng và đóng gói các ứng dụng của bạn. Docker Engine hoạt động như một ứng dụng client-server với: + +- Một máy chủ có tiến trình daemon dockerd. +- API với các giao diện mà các chương trình có thể sử dụng để giao tiếp và đưa ra chỉ thị với daemon Docker. +- Giao diện dòng lệnh (CLI) của docker. + +Phần trên được lấy từ tài liệu chính thức của Docker và [Tổng quan về Docker Engine cụ thể](https://docs.docker.com/engine/) + +### Docker Desktop + +Chúng ta có docker desktop cho cả Windows và macOS. Nó là một môi trường phát triển docker nhẹ, dễ cài đặt. Một ứng dụng native với khả năng tận dụng khả năng ảo hóa trên hệ điều hành máy chủ. + +Đây là giải pháp tốt nhất nếu bạn muốn xây dựng, gỡ lỗi, thử nghiệm, đóng gói và vận chuyển các ứng dụng Dockerized trên Windows hoặc macOS. + +Trên Windows, chúng ta cũng có thể tận dụng WSL2 và Microsoft Hyper-V. Chúng ta sẽ đề cập đến một số lợi ích của WSL2 trong các phần tiếp theo. + +Do tích hợp với các khả năng của trình ảo hóa trên hệ điều hành máy chủ, docker cung cấp khả năng chạy các vùng chứa của bạn với Hệ điều hành Linux. + +### Docker Compose + +Docker compose là một công cụ cho phép bạn chạy các ứng dụng phức tạp hơn trên nhiều containers. Với lợi ích là có thể sử dụng một tệp và lệnh duy nhất để khởi động ứng dụng của bạn. + +### Docker Hub + +Một tài nguyên tập trung để làm việc với Docker và các thành phần của nó. Thường được gọi là một registry để lưu trữ các docker images. Nhưng có rất nhiều dịch vụ bổ sung ở đây có thể được sử dụng để tự động hóa, tích hợp vào GitHub hoặc quét bảo mật. + +### Dockerfile + +Dockerfile là một tệp văn bản chứa các lệnh mà bạn thường thực hiện thủ công để tạo docker image. Docker có thể tự động tạo image bằng cách đọc các chỉ dẫn chúng ta có trong dockerfile của mình. + +## Cài đặt Docker Desktop + +[Tài liệu của Docker](https://docs.docker.com/engine/install/) rất tốt cho các bạn mới tìm hiểu về docker. Chúng ta sẽ sử dụng Docker Desktop trên Windows với WSL2. Tôi đã cài đặt cho máy tính mà chúng ta sẽ sử dụng ở trong phần này. + +![](../../Days/Images/Day43_Containers1.png) + +Lưu ý trước khi bạn tiếp tục và + +Take note before you go ahead and install at the system requirements, [Install Docker Desktop on Windows](https://docs.docker.com/desktop/windows/install/) if you are using macOS including the M1-based CPU architecture you can also take a look at [Install Docker Desktop on macOS](https://docs.docker.com/desktop/mac/install/) + +Tôi sẽ cặt đặt Docker Desktop cho Windows trên một máy Windows khác và ghi lại quá trình bên dưới. + +### Windows + +- Chọn windows làm hệ điều hành cho thiết bị của bạn. + +![](../../Days/Images/Day43_operatingSystem.png) + +- Điều hướng đến thư mục mà bạn muốn lưu bộ cài đặt và lưu lại. + +- Chạy bộ cài và đợi vài giây rồi cấp quyền truy cập cho WSL. + +![](../../Days/Images/Day43_EnableWSL.png) + +- Nhấn ok và quá trình cài đặt sẽ bắt đầu. +![](../../Days/Images/Day43_install.png) + +- Docker Desktop đã được cài đặt thành công trên thiết bị của bạn. Bây giờ bạn có thể chạy lệnh "docker" trên terminal để kiểm tra xem cài đặt có thành công hay không. + +![](../../Days/Images/Day43_check.png) + +## Tài liệu tham khảo + +- [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) +- [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) +- [Docker Tutorial for Beginners - What is Docker? Introduction to Containers](https://www.youtube.com/watch?v=17Bl31rlnRM&list=WL&index=128&t=61s) +- [WSL 2 with Docker getting started](https://www.youtube.com/watch?v=5RQbdMn04Oc) + +Hẹn gặp lại vào [ngày 44](day44.md) diff --git a/2022/vi/Days/day44.md b/2022/vi/Days/day44.md new file mode 100644 index 0000000..db8af7d --- /dev/null +++ b/2022/vi/Days/day44.md @@ -0,0 +1,142 @@ +--- +title: '#90DaysOfDevOps - Docker Images & Thực hành với Docker Desktop - Ngày 44' +published: false +description: 90DaysOfDevOps - Docker Images & Thực hành với Docker Desktop +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048708 +--- + +## Docker Images & Thực hành với Docker Desktop + +Bây giờ chúng ta đã cài đặt Docker Desktop trên hệ thống của mình. (Nếu bạn đang chạy Linux thì bạn vẫn còn có các tuỳ chọn nhưng không có GUI, dù sao thì docker có hoạt động trên Linux.) [Cài đặt Docker Engine trên Ubuntu](https://docs.docker.com/engine/install/ubuntu/) (Các bản phân phối khác cũng có sẵn.) + +Trong bài đăng này, chúng ta sẽ bắt đầu triển khai một số images và môi trường của chúng ta. Nhắc lại về Docker image - Docker image là một tệp được sử dụng để thực thi mã trong Docker container. Docker image hoạt động như một bộ chỉ dẫn để xây dựng Docker container, giống như một template. Docker images cũng đóng vai trò là điểm bắt đầu khi sử dụng Docker. + +Bây giờ là thời điểm tốt để tạo tài khoản cảu bạn trên [DockerHub](https://hub.docker.com/) + +![](../../Days/Images/Day44_Containers1.png) + +DockerHub là một tài nguyên tập trung để làm việc với Docker và các thành phần khác của nó. Thường được gọi là một registry để lưu trữ các docker images. Nhưng có rất nhiều dịch vụ bổ sung ở đây có thể được sử dụng để tự động hóa, tích hợp vào GitHub hoặc quét bảo mật. + +Nếu bạn kéo xuống sau khi đăng nhập, bạn sẽ thấy danh sách các container image. Bạn có thể thấy các image cho cơ sở dữ liệu sử dụng MySQL, hello-world, v.v. Hãy coi đây là những image cơ sở tốt, bạn có thể chỉ cần một image cho cơ sở dữ liệu ở đây và trong phần lớn trường hợp, tốt nhất là bạn nên sử dụng image chính thức (với dấu tích xanh) thay vì việc tạo riêng image của mình. + +![](../../Days/Images/Day44_Containers2.png) + +Chúng ta có thể đi sâu hơn vào chế độ xem các image có sẵn và tìm kiếm trên các danh mục, hệ điều hành và kiến ​​trúc. Một điều tôi nhấn mạnh bên dưới là image chính thức, điều này sẽ giúp bạn yên tâm hơn về nguồn gốc của nó. + +![](../../Days/Images/Day44_Containers3.png) + +Chúng ta cũng có thể tìm kiếm một image cụ thể, ví dụ: WordPress có thể là một image cơ sở tốt mà chúng ta muốn, chúng ta có thể làm điều đó ở trên cùng và tìm tất cả các container image liên quan đến WordPress. Dưới đây là chú ý cho việc chúng ta cũng có Verified Publisher. + +- Image chính thức (Official Image) - Docker Official images là một tập hợp các kho lưu trữ giải pháp mã nguồn mở Docker được tuyển chọn. + +- Verified Publisher - Nội dung Docker chất lượng cao từ các tổ chức đã được xác minh. Các sản phẩm này được công khai và duy trì bởi một công ty/tổ chức thương mại. + +![](../../Days/Images/Day44_Containers4.png) + +### Khám phá Docker Desktop + +Chúng ta đã cài đặt Docker Desktop trên hệ thống của mình và nnếu bạn mở ứng dụng này, bạn sẽ thấy một cái gì đó tương tự như hình bên dưới. Như bạn có thể thấy, chúng ta không có container nào đang chạy và docker engine của chúng ta đang chạy. + +![](../../Days/Images/Day44_Containers5.png) + +Vì đây không phải là bản cài đặt mới đối với tôi nên tôi có một số image đã được tải xuống và có sẵn trên hệ thống của mình. Bạn có thể sẽ không thấy gì ở đây. + +![](../../Days/Images/Day44_Containers6.png) + +Bạn sẽ thấy các container images mà bạn đã lưu trữ trong docker hub của mình trong mục remote repositories. Bạn có thể thấy như bên dưới, tôi không có bất kỳ image nào. + +![](../../Days/Images/Day44_Containers7.png) + +Chúng ta cũng có thể xác nhận này trên trang dockerhub của mình và xác nhận rằng chúng ta không có gì ở đó. + +![](../../Days/Images/Day44_Containers8.png) + +Tiếp theo, chúng ta có tab Volumes, nếu bạn có các containers yêu cầu tính bền vững thì đây là nơi chúng ta có thể thêm các volumes vào hệ thống tệp trên máy của bạn hoặc hệ thống tệp được chia sẻ. + +![](../../Days/Images/Day44_Containers9.png) + +Tại thời điểm viết bài, cũng có một tab "Dev Environments", đây là nơi giúp bạn cộng tác với nhóm của mình thay vì sử dụng các nhánh của khác nhau trên git. Tuy nhiên, chúng ta sẽ không nói về phần này. + +![](../../Days/Images/Day44_Containers10.png) + +Quay trở lại tab đầu tiên, bạn có thể thấy rằng có một lệnh mà chúng ta có thể chạy, đó là container getting-started. Hãy chạy `docker run -d -p 80:80 docker/getting-started` trong terminal của chúng ta. + +![](../../Days/Images/Day44_Containers11.png) + +Nếu chúng ta kiểm tra lại cửa sổ docker desktop, chúng ta sẽ thấy rằng chúng ta có một container đang chạy. + +![](../../Days/Images/Day44_Containers12.png) + +Bạn có thể nhận thấy rằng tôi đang sử dụng WSL2 và để có thể sử dụng, bạn cần đảm bảo rằng tính năng này được bật trong cài đặt. + +![](../../Days/Images/Day44_Containers13.png) + +Nếu bây giờ chúng ta kiểm tra lại tab Images của mình, bạn sẽ thấy một image đang được sử dụng có tên là `docker/getting-started`. + +![](../../Days/Images/Day44_Containers14.png) + +Quay lại tab Containers/Apps, nhấp vào container đang chạy của bạn. Bạn sẽ mặc định thấy được logs và trên thanh ở phía trên, bạn có một số tùy chọn để chọn, trong trường hợp của chúng ta, tôi khá tự tin rằng một trang web chạy trong container này, vì vậy chúng ta sẽ chọn mở trong trình duyệt. + +![](../../Days/Images/Day44_Containers15.png) + +Khi chúng tôi nhấn vào nút đó ở trên, chắc chắn rằng một trang web sẽ được mở ra và hiển thị nội dung tương tự như bên dưới. + +Container này cũng có thêm một số chi tiết về container và image của chúng ta. + +![](../../Days/Images/Day44_Containers16.png) + +Bây giờ chúng ta đã có container đầu tiên. Chưa có gì quá đáng sợ. Còn nếu chúng ta muốn pull một container image từ DockerHub thì sao? Có thể sẽ có một `hello world` container chúng ta có thể sử dụng. + +Tôi dừng container `getting started` không phải để tiết kiệm tài nguyên mà để những bước sau được nhìn rõ hơn. + +Quay trở lại terminal, chạy `docker run hello-world` và xem điều gì xảy ra. + +Bạn có thể thấy rằng chúng ta không có image ở local, vì vậy chúng ta đã kéo nó xuống từ dockerhub. Sau đó chúng ta nhận được một thông báo trong container image với một số thông tin về những gì nó đã làm để thiết lập và chạy cũng như một số liên kết đến các tài liệu tham khảo. + +![](../../Days/Images/Day44_Containers17.png) + +Nếu bây giờ chúng ta vào Docker Desktop, chúng ta không thấy có container đang chạy nhưng có một container đã exited gửi thông báo hello-world message, nghĩa là nó xuất hiện, gửi thông báo và sau đó bị chấm dứt. + +![](../../Days/Images/Day44_Containers18.png) + +Và cuối cùng, chúng ta hãy kiểm tra tab Images và thấy rằng chúng ta có một image hello-world mới trên hệ thống của mình, nghĩa là nếu chúng ta chạy lại lệnh `docker run hello-world` trong terminal, chúng ta sẽ không phải kéo bất cứ thứ gì trừ khi phiên bản thay đổi. + +![](../../Days/Images/Day44_Containers19.png) + +Thông điệp từ container hello-world đặt ra một thử thách làm một điều gì đó khó hơn một chút. + +Thử thách được chấp nhận! + +![](../../Days/Images/Day44_Containers20.png) + +Khi chạy `docker run -it ubuntu bash` trong thiết bị đầu cuối của chúng ta, chúng ta sẽ chạy phiên bản Ubuntu được đóng gói chứ không phải bản sao đầy đủ của Hệ điều hành. Bạn có thể tìm hiểu thêm về image cụ thể này trên [DockerHub](https://hub.docker.com/_/ubuntu) + +Bạn có thể thấy bên dưới khi chúng ta chạy lệnh, giờ đây chúng ta có một dấu nhắc tương tác (`-it`) và chúng ta có một trình shell bằng bash trong container của mình. + +![](../../Days/Images/Day44_Containers21.png) + +Chúng tôi có bash shell nhưng chúng ta không có gì khác, đó là lý do tại sao container image này nhỏ hơn 30 MB. + +![](../../Days/Images/Day44_Containers22.png) + +Nhưng chúng ta vẫn có thể sử dụng image này và có thể cài đặt phần mềm bằng trình quản lý gói apt của mình, chúng ta cũng có thể cập nhật container image và nâng cấp. + +![](../../Days/Images/Day44_Containers23.png) + +Hoặc có thể chúng ta muốn cài đặt một số phần mềm vào container của mình, tôi đã chọn một ví dụ thực sự tệ ở đây vì pinta là một trình chỉnh sửa image và nó có dung lượng hơn 200 MB nhưng hy vọng bạn sẽ hiểu được những gì tôi đang làm ở đây. Điều này sẽ làm tăng đáng kể kích thước container của chúng ta nhưng dù sao thì chúng ta vẫn đang ở MB chứ không phải GB. + +![](../../Days/Images/Day44_Containers24.png) + +Tôi hy vọng đã cung cấp cho bạn cái nhìn tổng quan về Docker Desktop và thế giới container không quá đáng sợ khi bạn chia nhỏ nó với các trường hợp sử dụng đơn giản. Chúng ta cần đề cập đến kết nối mạng, bảo mật và các tùy chọn khác mà chúng ta có so với việc chỉ tải xuống container image và sử dụng chúng như thế này. Đến cuối phần này, chúng ta sẽ tạo một cái gì đó, tải nó lên kho lưu trữ DockerHub và có thể triển khai nó. + +## Tài liệu tham khảo + +- [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) +- [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) +- [Docker Tutorial for Beginners - What is Docker? Introduction to Containers](https://www.youtube.com/watch?v=17Bl31rlnRM&list=WL&index=128&t=61s) +- [WSL 2 with Docker getting started](https://www.youtube.com/watch?v=5RQbdMn04Oc) + +Hẹn gặp lại vào [ngày 45](day45.md) diff --git a/2022/vi/Days/day45.md b/2022/vi/Days/day45.md new file mode 100644 index 0000000..a8197d7 --- /dev/null +++ b/2022/vi/Days/day45.md @@ -0,0 +1,119 @@ +--- +title: '#90DaysOfDevOps - Phân tích một Docker Image - Ngày 45' +published: false +description: 90DaysOfDevOps - Phân tích một Docker Image +tags: 'DevOps, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048777 +--- +## Phân tích một Docker Image + +Trong phần trước, chúng ta đã đề cập đến một số điều cơ bản về cách sử dụng Docker Desktop kết hợp với DockerHub để triển khai và chạy một số image đã được xác nhận. Ôn lại về image, chắc hẳn bạn sẽ không quên mọi thứ nếu tôi liên tục đề cập đến chúng. + +Docker image là một template chỉ có thể đọc chứa một bộ chỉ dẫn để tạo container có thể chạy được trên nền tảng Docker. Nó cũng câp một giải pháp thuận tiện để đóng gói các ứng dụng và môi trường được cấu hình trước mà bạn có thể sử dụng cho mục đích cá nhân hoặc chia sẻ công khai với những người dùng Docker khác. Docker image cũng là điểm khởi đầu với bất kỳ ai lần đầu tiên sử dụng Docker. + + +Điều gì sẽ xảy ra nếu chúng ta muốn tạo Docker image của riêng mình? Để làm được điều này, đầu tiên bạn cần tạo một Dockerfile. Bạn đã thấy cách chúng ta có thể lấy container image của Ubuntu và thêm các phần mềm cần thiết và mọi thứ hoạt động rất ổnm tuy nhiên, nếu container đó bị dừng lại hoặc loại bỏ thì tất cả các cập nhật phần mềm cũng như quá trình cài đặt sẽ biến mất, không có phiên bản nào lặp lại cho quá trình chúng ta đã thực hiện. Vì vậy, việc đó có thể tốt nếu chúng ta cần thể hiện các chức năng của Docker image nhưng không giúp ích gì cho việc truyền hình ảnh qua nhiều môi trường khác nhau với các phần mềm được cài đặt sẵn cho mỗi container khi khởi tạo/chạy. + +### Dockerfile là gì? + +Dockerfile là một tệp dữ liệu text có chứa các câu lệnh mà bạn sẽ thực hiện thủ công để xây dựng một docker image. Docker có thể xây dựng các hình ảnh một cách tự động bằng việc đọc các chỉ dẫn của chúng ta trong các dockerfile. + +Mỗi một tệp tạo ra một docker image được biết tới như một layer (lớp). Các layers này đến từ các images, được tạo trên các image khác trong nhiều stages. Mỗi một layer độc lập với layer nằm trực tiếp phía dưới của nó. Thứ tự của các layer đóng vai trò then chốt trong việc quản lý vòng đời docker image của bạn môt cách hiệu quả. + +Chúng ta nên tổ chức các layers theo thứ tự của việc hay thay đổi nhất. Các layer hay bị thay đổi nên nằm càng cao càng tốt trong stack của chúng ta, lý do vì khi bạn thay đổi một layer trong image của bạn, Docker không chỉ xây dựng lại layer đó mà toàn bộ các layer nằm phía sau/dựa vào layer đó. Do đó, một thay đổi với layer ở phía trên sẽ giúp tiết kiệm thời gian cho việc xây dựng lại toàn bộ image. + +Mỗi lần docker tạo một container từ một image (như chúng ta đã làm ngày hôm qua), chúng thêm vào một layer có thể được chỉnh sửa, hay còn biết đến như container layer. Nó sẽ ghi lại toàn bộ các thay đổi của container trong runtime. Layer này là thứ duy nhất khác biệt giữa một container đang hoạt động và image gốc. Bất kỳ số lượng container tương tự nào cũng có thể chia sẻ quyền truy cập vào cùng một base image trong khi vẫn duy trì trạng thái của chúng. + +Quay trở lại ví dụ chúng ta sử dụng ngày hôm qua với Ubuntu image. Chúng ta có thể chạy cùng một lệnh đó nhiều lần và trên container đầu tiên, chúng ta có thể cài đặt pinta và trên container thứ hai, chúng ta có thể cài đặt figlet với hai ứng dụng khác nhau, mục đích khác nhau, kích thước khác nhau, v.v. Mỗi container mà chúng ta triển khai chia sẻ cùng một image nhưng không cùng một trạng thái và sau đó trạng thái đó sẽ biến mất khi chúng ta xoá container. + +![](../../Days/Images/Day45_Containers1.png) + +Theo ví dụ trên với Ubuntu image, nhưng cũng có nhiều container image dựng sẵn khác có sẵn trên DockerHub và các kho lưu trữ của bên thứ ba. Những image này thường được gọi là image gốc - base image. Nó là nền tảng để xây dựng tất cả các layer khác và cung cấp các khối xây dựng cơ bản cho môi trường container của chúng ta. + +Cùng với một tập hợp các tệp layers riêng lẻ, Docker image cũng bao gồm một tệp bổ sung được gọi là manifest. Đây thực chất là phần mô tả image ở định dạng JSON và bao gồm các thông tin như image tag, chữ ký điện tử và chi tiết về cách định cấu hình container cho các loại nền tảng khác nhau. + +![](../../Days/Images/Day45_Containers2.png) + +### Làm thế nào để tạo một docker image + +Có hai cách chúng ta có thể tạo một docker image. Chúng ta có thể thực hiện nhanh chóng với quy trình mà chúng ta đã bắt đầu ngày hôm qua, chúng ta chọn base image của mình khởi động container đó và cài đặt tất cả phần mềm cũng như các dependencies (phụ thuộc) mà chúng ta muốn có trên container của mình. + +Sau đó, chúng ta có thể sử dụng `docker commit container name` để có một bản sao cục bộ của image này như một docker image và nó sẽ xuất hiện trong tab images của docker desktop của bạn. + +Cực kỳ đơn giản, tôi không đề xuất phương pháp này trừ khi bạn muốn hiểu quy trình, sẽ rất khó để quản lý vòng đời theo cách này và cần rất nhiều cấu hình thủ công. Nhưng đó là cách nhanh nhất và đơn giản nhất để xây dựng docker image. Nó rất tốt cho việc thử nghiệm, khắc phục sự cố, xác thực các dependencies, v.v. + +Cách chúng ta dự định xây dựng image của mình là thông qua một dockerfile. Điều này giúp chúng ta có một cách rõ ràng, nhanh gọn và có thể lặp lại để tạo một image. Quản lý vòng đời cũng sẽ dễ dàng hơn nhiều ngoài ra cũng dễ dàng tích hợp vào các quy trình Phân phối liên tục và Tích hợp liên tục (CI/CD). Nhưng như bạn có thể thấy, nó khó hơn một chút so với quy trình được đề cập đầu tiên. + +Việc sử dụng phương pháp dockerfile phù hợp hơn nhiều với việc triển container của doanh nghiệp trong thế giới thực. + +Dockerfile là một quy trình gồm ba bước, theo đó bạn tạo dockerfile và thêm các lệnh bạn cần để tạo nên một image. + +Bảng sau đây chứa một số câu lệnh dockerfile mà chúng tôi sẽ sử dụng và rất có thể bạn cũng sẽ sử dụng. + +| Lệnh | Mục đích | +| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------- | +| FROM | Để chỉ định hình ảnh gốc. | +| WORKDIR | Để đặt thư mục làm việc cho bất kỳ lệnh nào phía sau trong Dockerfile. | +| RUN | Để chạy các câu lệnh giúp cài đặt bất kỳ ứng dụng và package nào cần thiết cho container của bạn. | +| COPY | Để sao chép các tệp hoặc thư mục từ một vị trí cụ thể. | +| ADD | Là COPY, nhưng cũng có thể xử lý các URL và giải nén các tệp nén. | +| ENTRYPOINT | Lệnh sẽ luôn được thực thi khi container khởi động. Nếu không được chỉ định, giá trị mặc định là /bin/sh -c | +| CMD | Các đối số được chuyển đến điểm vào. Nếu ENTRYPOINT không được cấu hình (mặc định là /bin/sh -c), CMD sẽ là các lệnh mà container thực thi. | +| EXPOSE | Để xác định cổng nào để truy cập ứng dụng container của bạn. | +| LABEL | Để thêm metadata vào image. | + +Bây giờ chúng ta có chi tiết về cách xây dựng dockerfile đầu tiên, chúng ta có thể tạo một thư mục làm việc và tạo dockerfile. Tôi đã tạo một thư mục làm việc trong repository này, nơi bạn có thể xem các tệp và thư mục mà tôi thực hành. [Container](../../../2022/Days/Containers/) + +Trong thư mục này, tôi sẽ tạo một tệp .dockerignore tương tự như .gitignore mà chúng ta đã sử dụng trong phần trước. Tệp này sẽ liệt kê bất kỳ tệp nào sẽ được tạo trong quá trình xây dựng Docker mà bạn muốn loại bỏ khỏi bản dựng cuối cùng. + +Hãy nhớ rằng mọi thứ về container đều phải nhỏ gọn, nhanh nhất có thể và không bị cồng kềnh. + +Tôi muốn tạo một Dockerfile đơn giản với bố cục bên dưới, nó cũng có thể được tìm thấy trong thư mục được liên kết ở trên. + +``` +# Use the official Ubuntu 18.04 as base +FROM ubuntu:18.04 +# Install nginx and curl +RUN apt-get update && apt-get upgrade -y +RUN apt-get install -y nginx curl +RUN rm -rf /var/lib/apt/lists/* +``` + +Điều hướng đến thư mục này trong terminal của bạn, sau đó chạy `docker build -t 90daysofdevops:0.1 .` chúng ta đang sử dụng `-t`, sau đó đặt tên và thẻ cho image. + +![](../../Days/Images/Day45_Containers3.png) + +Bây giờ chúng ta đã tạo image của mình, sau đó chúng ta có thể chạy image của mình bằng Docker Desktop hoặc có thể sử dụng câu lệnh với docker. Tôi đã sử dụng Docker Desktop. Tôi đã kích hoạt một container và bạn có thể thấy rằng chúng ta có sẵn gói `curl` trong cli của container. + +![](../../Days/Images/Day45_Containers4.png) + +Trong khi Docker Desktop cũng có khả năng tận dụng giao diện người dùng để thực hiện thêm một số tác vụ với image mới này. + +![](../../Days/Images/Day45_Containers5.png) + +Chúng ta có thể kiểm tra hình ảnh của mình, khi làm như vậy, bạn sẽ thấy rất nhiều dockerfile và các dòng mã mà chúng ta muốn chạy trong container của mình. + +![](../../Days/Images/Day45_Containers6.png) + +Chúng ta có pull option, nếu thử thì chúng ta sẽ thất bại vì image này không được lưu trữ ở bất kỳ đâu nên sẽ gặp lỗi. Tuy nhiên, chúng ta có một tuỳ chọn "Push to Hub" cho phép chúng ta đẩy hình ảnh của mình lên DockerHub. + +Nếu bạn đang sử dụng cùng một lệnh `docker build` mà chúng ta đã chạy trước đó thì nó cũng sẽ không hoạt động, bạn sẽ cần lệnh build là `docker build -t {{username}}/{{imagename}}:{{version}} ` + +![](../../Days/Images/Day45_Containers7.png) + +Sau đó, nếu xem qua kho lưu trữ DockerHub của chúng ta, bạn có thể thấy rằng chúng ta vừa đẩy một hình ảnh mới. Bây giờ trong Docker Desktop, chúng ta có thể sử dụng pull tab đó. + +![](../../Days/Images/Day45_Containers8.png) + +## Tài liệu tham khảo + +- [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) +- [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) +- [Docker Tutorial for Beginners - What is Docker? Introduction to Containers](https://www.youtube.com/watch?v=17Bl31rlnRM&list=WL&index=128&t=61s) +- [WSL 2 with Docker getting started](https://www.youtube.com/watch?v=5RQbdMn04Oc) +- [Blog on gettng started building a docker image](https://stackify.com/docker-build-a-beginners-guide-to-building-docker-images/) +- [Docker documentation for building an image](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) + +Hẹn gặp lại vào [ngày 46](day46.md) diff --git a/2022/vi/Days/day46.md b/2022/vi/Days/day46.md new file mode 100644 index 0000000..fa5b11e --- /dev/null +++ b/2022/vi/Days/day46.md @@ -0,0 +1,182 @@ +--- +title: '#90DaysOfDevOps - Docker Compose - Day 46' +published: false +description: 90DaysOfDevOps - Docker Compose +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048740 +--- + +## Docker Compose + +Khả năng chạy một container sẽ rất tuyệt vời nếu bạn có một image độc lập có mọi thứ bạn cần cho trường hợp sử dụng của mình, những mọi thứ trở nên thú vị hơn khi bạn đang tìm cách xây dựng nhiều ứng dụng với các container image khác nhau. Ví dụ: nếu tôi có giao diện người dùng của trang web nhưng yêu cầu có một cơ sở dữ liệu ở phía backend, tôi có thể đặt cả hai vào một container chúng nhưng tốt hơn và hiệu quả hơn là có container cơ sở dữ liệu của riêng ứng dụng đó. + +Đây là nơi Docker compose xuất hiện, đây là một công cụ cho phép bạn chạy các ứng dụng phức tạp hơn trên nhiều container. Với lợi ích là có thể sử dụng một tệp và lệnh duy nhất để khởi động ứng dụng của bạn. Ví dụ tôi sẽ hướng dẫn trong bài đăng này là từ [Ứng dụng mẫu Docker QuickStart (Quickstart: Compose and WordPress)](https://docs.docker.com/samples/wordpress/). + +Trong ví dụ đầu tiên này, chúng ta sẽ: + +- Sử dụng Docker Compose để triển khai WordPress và một MySQL instance riêng. +- Sử dụng tệp YAML sẽ được gọi là `docker-compose.yml` +- Xây dựng dự án +- Định cấu hình WordPress qua trình duyệt web +- Dọn dẹp + +### Cài đặt Docker Compose + +Như đã đề cập Docker Compose là một công cụ. Nếu bạn đang sử dụng macOS hoặc Windows thì compose có sẵn trong bản cài đặt Docker Desktop của bạn. Tuy nhiên, bạn có thể muốn chạy container của mình trên máy chủ Windows hoặc máy chủ Linux và trong trường hợp đó, bạn có thể cài đặt bằng cách sử dụng hướng dẫn sau [Cài đặt Docker Compose](https://docs.docker.com/compose/install/) + +Để xác nhận rằng chúng ta đã cài đặt `docker-compose` trên hệ thống của mình, chúng ta có thể mở một terminal và gõ lệnh trên. + +![](../../Days/Images/Day46_Containers1.png) + +### Docker-Compose.yml (YAML) + +Điều tiếp theo mà chúng ta đề cập đến là docker-compose.yml, bạn có thể tìm thấy trong [thư mục Container của kho lưu trữ](../../Days/Containers/my_wordpress/docker-compose.yaml). Nhưng quan trọng hơn, chúng ta cần thảo luận về YAML một chút. + +Gần như có thể có một bài riêng về YAML vì bạn sẽ gặp nó ở rất nhiều nơi khác nhau. Nhưng khái quát lại thì: + +"YAML là ngôn ngữ tuần tự hóa dữ liệu (data serialization language) thân thiện với con người sử dụng với tất cả các ngôn ngữ lập trình." + +Nó thường được sử dụng cho các tệp cấu hình và trong một số ứng dụng nhằm lưu trữ hoặc truyền dữ liệu. Chắc chắn bạn đã bắt gặp các tệp XML được dùng để cung cấp cùng một tệp cấu hình đó. YAML cung cấp một cú pháp tối thiểu nhưng nhằm vào các trường hợp sử dụng tương tự. + +YAML Ain't Markup Language (YAML) là ngôn ngữ tuần tự hóa đã phổ biến dần trong vài năm qua. Các khả năng tuần tự hóa đối tượng giúp nó trở thành một sự thay thế khả thi cho các ngôn ngữ như JSON. + +Từ viết tắt YAML là viết tắt của Yet Another Markup Language. Nhưng những người bảo trì đã đổi tên nó thành YAML Ain't Markup Language để nhấn mạnh hơn vào các tính năng hướng dữ liệu của nó. + +Dù sao, hãy quay lại tệp docker-compose.yml. Đây là tệp cấu hình về những gì chúng ta muốn thực hiện khi có nhiều container đang được triển khai trên một hệ thống duy nhất của chúng ta. + +Ngay từ hướng dẫn được liên kết ở trên, bạn có thể thấy nội dung của tệp trông như thế này: +``` +version: "3.9" + +services: + DB: + image: mysql:5.7 + volumes: + - db_data:/var/lib/mysql + restart: always + environment: + MYSQL_ROOT_PASSWORD: somewordpress + MYSQL_DATABASE: wordpress + MYSQL_USER: wordpress + MYSQL_PASSWORD: wordpress + + wordpress: + depends_on: + - db + image: wordpress:latest + volumes: + - wordpress_data:/var/www/html + ports: + - "8000:80" + restart: always + environment: + WORDPRESS_DB_HOST: db + WORDPRESS_DB_USER: wordpress + WORDPRESS_DB_PASSWORD: wordpress + WORDPRESS_DB_NAME: wordpress +volumes: + db_data: {} + wordpress_data: {} +``` + +Chúng ta khai báo một phiên bản và sau đó một phần lớn của tệp docker-compose.yml này được tạo thành từ các services, chúng tôi có service DB và service WordPress. Bạn có thể thấy mỗi trong số đó có một image được xác định bằng version tag. Bây giờ chúng ta sẽ tạo các volumes để có thể lưu trữ cơ sở dữ liệu của mình ở đó. + +Sau đó, chúng tôi có một số biến môi trường (environment) như mật khẩu và tên người dùng. Các tệp này có thể trở nên rất phức tạp nhưng tệp cấu hình YAML đơn giản hóa giao diện tổng thể của chúng. + +### Xây dựng dự án + +Tiếp theo, chúng ta quay trở lại terminal của mình và sử dụng một số lệnh với công cụ docker-compose. Điều hướng đến thư mục của bạn, nơi chứa tệp docker-compose.yml. + +Từ terminal, chúng ta chỉ cần chạy `docker-compose up -d`, thao tác này sẽ bắt đầu quá trình pull những image và dựng ứng dụng có nhiều containers của bạn. + +`-d` trong lệnh này có nghĩa là chế độ tách rời (detached mode), có nghĩa là lệnh Run đang hoặc sẽ chạy ở chế độ nền. + +![](../../Days/Images/Day46_Containers2.png) + +Nếu bây giờ chúng ta chạy lệnh `docker ps`, bạn có thể thấy chúng ta có 2 containers đang chạy, một là WordPress và một là MySQL. + +![](../../Days/Images/Day46_Containers3.png) + +Tiếp theo, chúng ta có thể xác thực việc đã thiết lập và chạy WordPress bằng cách mở trình duyệt và truy cập `http://localhost:8000`, bạn sẽ thấy trang thiết lập WordPress. + +![](../../Days/Images/Day46_Containers4.png) + +Chúng tôi có thể trải qua quá trình thiết lập WordPress và sau đó có thể bắt đầu xây dựng trang web của mình với bảng điều khiển bên dưới. + +![](../../Days/Images/Day46_Containers5.png) + +Sau đó, nếu chúng ta mở một tab mới và điều hướng đến cùng một địa chỉ mà chúng ta đã làm trước đó `http://localhost:8000` thì sẽ thấy một theme mặc định đơn giản với tiêu đề trang web là "90DaysOfDevOps" và một bài đăng mẫu. + +![](../../Days/Images/Day46_Containers6.png) + +Trước khi chúng ta thực hiện bất kỳ thay đổi nào, hãy mở Docker Desktop và điều hướng đến tab Volumes, ở đây bạn sẽ thấy hai volumes được liên kết với containers của chúng ta, một cho wordpress và một cho db. + +![](../../Days/Images/Day46_Containers7.png) + +Theme wordpress hiện tại của tôi là "Twenty Twenty-Two" và tôi muốn thay đổi nó thành "Twenty Twenty", chúng ta có thể thực hiện những thay đổi đó trong bảng điều khiển. + +![](../../Days/Images/Day46_Containers8.png) + +Tôi cũng sẽ thêm một bài đăng mới vào trang web của mình và bạn có thể thấy phiên bản mới nhất của trang web của chúng ta. + +![](../../Days/Images/Day46_Containers9.png) + +### Dọn dẹp hay không + +Nếu bây giờ chúng ta sử dụng lệnh `docker-compose down` thì lệnh này sẽ xoá bỏ những containers của chúng ta nhưng sẽ để lại và giữ nguyên các volumes. + +![](../../Days/Images/Day46_Containers10.png) + +Chúng ta có thể xác nhận trong Docker Desktop rằng volumes của chúng ta vẫn còn đó. + +![](../../Days/Images/Day46_Containers11.png) + +Sau đó, nếu chúng ta muốn đem mọi thứ trở lại thì có thể sử dụng lệnh `docker up -d` từ trong cùng thư mục và chúng ta có các ứng dụng của mình khởi động và chạy bình thường trở lại. + +![](../../Days/Images/Day46_Containers12.png) + +Sau đó, chúng ta truy cập tới cùng một địa chỉ `http://localhost:8000` và nhận thấy rằng bài đăng mới và thay đổi về theme vẫn còn nguyên. + +![](../../Days/Images/Day46_Containers13.png) + +Nếu chúng ta muốn loại bỏ các containers và các volumes đó thì việc sử dụng lệnh `docker-compose down --volumes` cũng sẽ xoá bỏ các volumes. + +![](../../Days/Images/Day46_Containers14.png) + +Bây giờ, khi chúng ta sử dụng lại `docker-compose up -d`, các ứng dụng sẽ khởi động lại, tuy nhiên, các image đã có sẵn hệ thống của chúng ta nên sẽ không cần phải pull lại chúng từ kho lưu trữ DockerHub. + +Thú thật rằng khi tôi bắt đầu tìm hiểu về docker-compose và các khả năng của nó, tôi đã bối rối không biết nó nằm ở đâu bên cạnh hoặc với các công cụ Điều phối containers (Container Orchestration) như Kubernetes, mọi thứ chúng ta đã làm ở đây trong bản demo ngắn này đều tập trung vào một máy chủ khi chạy WordPress và DB trên máy tính để bàn cục bộ. Chúng ta không có nhiều máy ảo hoặc nhiều máy chủ vật lý, chúng ta cũng không thể dễ dàng mở rộng và thu nhỏ các yêu cầu của ứng dụng của mình. + +Phần tiếp theo của chúng tôi sẽ đề cập đến Kubernetes nhưng trước tiên chúng tôi có một vài ngày nữa về Container nói chung. + +Đây cũng là một nguồn tài nguyên tuyệt vời cho các mẫu ứng dụng docker-compose với nhiều tích hợp khác nhau. [Awesome-Compose](https://github.com/docker/awesome-compose) + +Trong kho lưu trữ ở trên, có một ví dụ tuyệt vời sẽ triển khai Elaticsearch, Logstash và Kibana (ELK) cho một node. + +Tôi đã tải các tệp lên [Thư mục vùng chứa](../Days/Containers/elasticsearch-logstash-kibana/) Khi bạn có thư mục này ở máy tính của bạn, hãy điều hướng đến đó và bạn chỉ cần sử dụng `docker-compose up -d` + +![](../../Days/Images/Day46_Containers15.png) + +Sau đó, chúng ta có thể kiểm tra các containers đang chạy với câu lệnh `docker ps` + +![](../../Days/Images/Day46_Containers16.png) + +Bây giờ chúng ta có thể mở trình duyệt cho từng vùng chứa: + +![](../../Days/Images/Day46_Containers17.png) + +Để xóa mọi thứ, chúng ta có thể sử dụng lệnh `docker-compose down`. + +## Tài liệu tham khảo + +- [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) +- [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) +- [Docker Tutorial for Beginners - What is Docker? Introduction to Containers](https://www.youtube.com/watch?v=17Bl31rlnRM&list=WL&index=128&t=61s) +- [WSL 2 with Docker getting started](https://www.youtube.com/watch?v=5RQbdMn04Oc) +- [Blog on getting started building a docker image](https://stackify.com/docker-build-a-beginners-guide-to-building-docker-images/) +- [Docker documentation for building an image](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) +- [YAML Tutorial: Everything You Need to Get Started in Minute](https://www.cloudbees.com/blog/yaml-tutorial-everything-you-need-get-started) + +Hẹn gặp bạn vào [ngày 47](day47.md) diff --git a/2022/vi/Days/day47.md b/2022/vi/Days/day47.md new file mode 100644 index 0000000..2b874ac --- /dev/null +++ b/2022/vi/Days/day47.md @@ -0,0 +1,144 @@ +--- +title: '#90DaysOfDevOps - Docker Networking & Security - Ngày 47' +published: false +description: 90DaysOfDevOps - Docker Networking & Security +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049078 +--- + +## Docker Networking & Security + +Trong loạt bài viết về container chúng ta đã xem xét qua mọi thứ nhưng chưa xem xét cách mọi thứ hoạt động ở phía sau từ góc độ network và cũng chưa đề cập tới bảo mật, nó sẽ được đề cập trong bài viết này. + +### Khái niệm cơ bản về Docker networking + +Mở một terminal và gõ lệnh `docker network`, đây là câu lệnh chính để định cấu hình và quản lý mạng container. + +Theo như bên dưới, bạn có thể thấy đây là cách chúng ta có thể sử dụng lệnh và các lệnh phụ có sẵn. Chúng ta có thể tạo các mạng mới, liệt kê cách mạng hiện có, kiểm tra và xoá các mạng. + +![](../../Days/Images/Day47_Containers1.png) + +Hãy xem qua các mạng hiện có mà chúng ta có kể từ khi cài đặt, mạng Docker có sẵn dùng trông giống như sử dụng lệnh `docker network list`. + +Mỗi mạng có một NAME và ID duy nhất. Mỗi mạng cũng được liên kết với một driver duy nhất. Lưu ý rằng mạng "bridge" và mạng "host" có cùng tên với driver tương ứng của chúng. + +![](../../Days/Images/Day47_Containers2.png) + +Tiếp theo, chúng ta có thể xem xét kỹ hơn các mạng của mình bằng lệnh `docker network inspect`. + +Khi tôi chạy lệnh `docker network inspect bridge`, tôi có thể nhận được tất cả các chi tiết cấu hình của mạng cụ thể đó. Điều này bao gồm tên, ID, driver, container được liên kết và như bạn thấy, có rất nhiều thông tin khác. + +![](../../Days/Images/Day47_Containers3.png) + +### Docker: Bridge Networking + +Như bạn đã thấy ở trên, bản cài đặt tiêu chuẩn của Docker Desktop cung cấp cho chúng ta một mạng dựng sẵn có tên là `bridge`. Nếu bạn xem lại lệnh `docker network list`, bạn có thể thấy rằng mạng được gọi là bridge được liên kết với driver `bridge`. Chỉ vì chúng có cùng tên không có nghĩa chúng giống nhau. Được liên kết nhưng không giống nhau. + +Đầu ra ở trên cũng cho thấy rằng mạng bridge có phạm vi cục bộ. Điều này có nghãi là mạng chỉ tồn tại trên máy chủ Docker này. Điều này đúng với tất cả các mạng sử dụng driver bridge - bridge driver cung cấp mạng cho single-host. + +Tất cả các mạng được tạo bằng bridge driver đều dựa trên cấu hình Linux bridge (còn gọi là virtual switch) + +### Kết nối tới một container + +Theo mặc định, bridge network được gán cho các container mới, nghĩa là trừ khi bạn chỉ định một mạng cụ thể, tất các các container sẽ được kết nối với mạng bridge. + +Hãy tạo một container mới với câu lệnh `docker run -dt ubuntu sleep infinity` + + +Lệnh sleep ở trên chỉ để giữ cho container chạy ở chế độ nền để chúng ta có thể thực hành với nó. + +![](../../Days/Images/Day47_Containers4.png) + +Sau đó, nếu chúng ta kiểm tra mạng bridge của mình với lệnh `docker network inspect bridge`, bạn sẽ thấy rằng chúng ta có một container khớp với những gì chúng ta vừa triển khai vì chúng ta đã không chỉ định một mạng nào cho nó. + +![](../../Days/Images/Day47_Containers5.png) + +Bạn cũng có thể đi sâu vào container bằng cách sử dụng `docker exec -it 3a99af449ca2 bash`, bạn sẽ phải sử dụng `docker ps` để lấy container id của bạn. + +Từ đây, image của chúng ta không có gì để ping nên chúng ta cần chạy thêm lệnh sau `apt-get update && apt-get install -y iputils-ping` sau đó ping một địa chỉ bên ngoài. `ping -c5 www.90daysofdevops.com` + +![](../../Days/Images/Day47_Containers6.png) + +Để xoá bỏ container, chúng ta có thể chạy lại lệnh `docker stop 3a99af449ca2` và sử dụng lệnh `docker ps` để kiểm tra. + +### Cấu hình NAT cho kết nối bên ngoài + +Trong bước này, chúng ta sẽ bắt đầu một NGINX container mới và map port 8080 trên máy chủ Docker tới cổng 80 bên trong container. Điều này có nghĩa là các truy cập vào máy chủ Docker trên cổng 8080 sẽ được chuyển sang cổng 80 bên trong container. + +Bắt đầu một container mới dựa trên NGINX image chính thức bằng cách chạy `docker run --name web1 -d -p 8080:80 nginx` + +![](../../Days/Images/Day47_Containers7.png) + +Xem lại trạng thái của container và port mapping bằng cách chạy `docker ps` + +![](../../Days/Images/Day47_Containers8.png) + +Dòng trên cùng hiển thị container web1 mới đang chạy NGINX. Lưu ý lệnh mà container đang chạy cũng như port mapping - `0.0.0.0:8080->80/tcp` ánh xạ cổng 8080 trên tất cả các interfaces của máy chủ tới cổng 80 bên trong container web1. Port mapping này là yếu tố làm cho dịch vụ web của container có thể truy cập hiệu quả từ bên ngoài (thông qua địa chỉ IP máy chủ Docker trên cổng 8080). + +Bây giờ chúng ta cần địa chỉ IP cho máy chủ thực tế của mình, có thể thực hiện việc này bằng cách vào WSL terminal của mình và sử dụng lệnh `IP addr`. + +![](../../Days/Images/Day47_Containers9.png) + +Sau đó, chúng tôi có thể lấy IP này, mở trình duyệt và truy cập `http://172.25.218.154:8080/` IP của bạn có thể khác. Điều này xác nhận rằng có thể truy cập được NGINX. + +![](../../Days/Images/Day47_Containers10.png) + +Tôi đã thực hiện các hướng dẫn của trang web này từ DockerCon 2017 nhưng chúng vẫn còn phù hợp cho đến ngày nay. Tuy nhiên, phần còn lại của hướng dẫn đi sâu vào Docker Swarm và chúng ta sẽ không xem xét điều đó ở đây. [Mạng Docker - DockerCon 2017](https://github.com/docker/labs/tree/master/dockercon-us-2017/docker-networking) + +### Bảo vệ container của bạn + +Container cung cấp môi trường an toàn cho workloads của bạn so với cấu hình một máy chủ đầy đủ. Chúng cung cấp khả năng chia nhỏ các ứng dụng của bạn thành nhiều thành phần nhỏ hơn, được liên kết lỏng lẻo, mỗi thành phần được tách biệt với nhau, giúp giảm tổng thể bề mặt cho các cuộc tấn công. + +Nhưng chúng không tránh khỏi các tin tặc đang tìm cách khai thác hệ thống. Chúng ta vẫn cần hiểu những nguy cơ bảo mật của công nghệ và tuân thủ, áp dụng các thực hành tốt nhất. + +### Di chuyển khỏi quyền root + +Tất cả các container mà chúng ta đã triển khai đều đang sử dụng quyền root đối với process trong container của bạn. Điều này có nghĩa là họ có toàn quyền truy cập của admin vào môi trường máy chủ và vùng chứa của bạn. Chúng ta đều đã biết rằng những hệ thống này sẽ không hoạt động lâu dài. Nhưng bạn cũng đã thấy rằng để khởi động và chạy chúng dễ dàng như thế nào. + +Chúng ta có thể thêm một vài bước vào quy trình của chúng ta để sử dụng người dùng không phải root như một thực hành tốt nhất mà chúng ta ưu tiên. Khi tạo các tệp dockerfile, chúng ta có thể tạo tài khoản người dùng. Bạn cũng có thể tìm thấy ví dụ này trong [thư mục container](../../Days/Containers/Dockerfile) + +``` +# Use the official Ubuntu 18.04 as base +FROM ubuntu:18.04 +RUN apt-get update && apt-get upgrade -y +RUN groupadd -g 1000 basicuser && useradd -r -u 1000 -g basicuser basicuser +USER basicuser +``` + +We can also use `docker run --user 1009 ubuntu` the Docker run command overrides any user specified in your Dockerfile. Therefore, in the following example, your container will always run with the least privilege—provided user identifier 1009 also has the lowest permission level. + +However, this method doesn’t address the underlying security flaw of the image itself. Therefore it’s better to specify a non-root user in your Dockerfile so your containers always run securely. + +Chúng ta cũng có thể sử dụng `docker run --user 1009 ubuntu` lệnh Docker run sẽ ghi đè bất kỳ người dùng nào được chỉ định trong Dockerfile. Do đó, trong ví dụ sau, container của bạn sẽ luôn chạy với ít đặc quyền nhất và mã định danh người dùng 1009 cũng có mức cấp phép thấp nhất. + +Tuy nhiên, phương pháp này không giải quyết được lỗ hổng bảo mật tiềm ẩn của chính image đó. Do đó, tốt hơn là chỉ định người dùng không phải root trong Dockerfile của bạn để vùng chứa của bạn luôn chạy an toàn. + +### Private Registry + +Một điều khác mà chúng ta đã sử dụng nhiều là các registry công khai như DockerHub. Thay vào đó, sử dụng một private registry chứa các container image do tổ chức của bạn có nghĩa là bạn có thể lưu trữ ở nơi bạn muốn hoặc cũng có các dịch vụ được quản lý sẵn cho việc này, nhưng nhìn chung, điều này mang lại cho bạn quyền kiểm soát hoàn toàn các image cho bạn và nhóm của bạn. + +DockerHub cung cấp cho bạn một điểm bắt đầu rất tốt, nhưng nó chỉ cung cấp cho bạn một dịch vụ cơ bản mà bạn phải đặt nhiều niềm tin vào các image publisher. + +### Tinh gọn và sạch sẽ + +Tôi đã đề cập đến việc này trong suốt các bài viết về container, mặc dù nó không liên quan tới bảo mật. Nhưng kích thước container của bạn có thể ảnh hưởng đến bảo mặt trên khía cạnh về bề mặt tấn công. Nếu bạn có tài nguyên mà bạn không sử dụng trong ứng dụng của mình thì bạn không cần nó trong container của mình. + +Đây cũng là mối quan tâm chính của tôi với việc lấy các hình ảnh `latest` bởi vì điều đó cũng có thể làm cho image của bạn lớn lên rất nhiều. DockerHub cũng hỗ trợ hiển thị kích thước sau khi nén cho từng hình ảnh ở trong kho lưu trữ. + +`docker image` là một câu lệnh tốt để kiểm tra kích thước các image của bạn. + +![](../../Days/Images/Day47_Containers11.png) + +## Resources + +- [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) +- [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) +- [Docker Tutorial for Beginners - What is Docker? Introduction to Containers](https://www.youtube.com/watch?v=17Bl31rlnRM&list=WL&index=128&t=61s) +- [WSL 2 with Docker getting started](https://www.youtube.com/watch?v=5RQbdMn04Oc) +- [Blog on getting started building a docker image](https://stackify.com/docker-build-a-beginners-guide-to-building-docker-images/) +- [Docker documentation for building an image](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) +- [YAML Tutorial: Everything You Need to Get Started in Minute](https://www.cloudbees.com/blog/yaml-tutorial-everything-you-need-get-started) + +Hẹn gặp lại vào [ngày 48](day48.md) diff --git a/2022/vi/Days/day48.md b/2022/vi/Days/day48.md new file mode 100644 index 0000000..ac74339 --- /dev/null +++ b/2022/vi/Days/day48.md @@ -0,0 +1,115 @@ +--- +title: '#90DaysOfDevOps - Các lựa chọn thay thế cho Docker - Ngày 48' +published: false +description: 90DaysOfDevOps - Các lựa chọn thay thế cho Docker +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048807 +--- + +## Các lựa chọn thay thế cho Docker + +Tôi đã nói ngay từ đầu rằng chúng ta sẽ sử dụng Docker cho loạt bài viết về Container, đơn giản vì có rất nhiều tài nguyên và cộng động sử dụng rất lớn, ngoài ra nó cũng là lý do khiến container trở nên phổ biến. Tôi nghĩ chúng ta nên tìm hiểu về lịch sử hình thành và phát triển của Docker, tôi thấy nó rất hữu ích. + +Nhưng như tôi đã đề cập, chúng ta có những lựa chọn khác thay thế cho Docker. Nếu chúng ta nghĩ Docker là gì và nó giúp gì cho chúng ta thì nó là một nền tảng để phát triển, kiểm thử, triển khai và quản lý các ứng dụng. + +Tôi muốn làm nổi bật một vài lựa chọn thay thế cho Docker mà bạn có thể hoặc sẽ thấy trong tương lai. + +### Podman + +Podman là gì? Podman là một container engine không sử dụng deamon nhằm phát triển, quản lý và chạy các bộ OCI containers trên hệ thống Linux. Các containers có thể được chạy với quyền root và non-root. + +Tôi sẽ xem xét điều này từ quan điểm của Windows nhưng biết rằng giống như Docker, không có yêu cầu ảo hoá ở đó vì nó sẽ sử dụng Hệ điều hành cơ bản, điều không thể thực hiện được với Windows. + +Podman có thể chạy trên WSL2 mặc dù không có một trải nghiệm mượt mà như với Docker Desktop. Ngoài ra còn có thể sử dụng Windows client để kết nối tới một Linux VM nơi mà containers của bạn sẽ chạy. + +Ubuntu của tôi trên WSL2 là phiên bản 20.04. Làm theo các bước tiếp theo sẽ cho phép bạn cài đặt Podman trên phiên bản WSL của mình + +```Shell +echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_20.04/ /" | +sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list +``` +Thêm khoá GPG + +```Shell +curl -L "https://download.opensuse.org/repositories/devel:/kubic:\ +/libcontainers:/stable/xUbuntu_20.04/Release.key" | sudo apt-key add - +``` + +Chạy bản cập nhật và nâng cấp hệ thống bằng lệnh `sudo apt-get update && sudo apt-get upgrade`. Cuối cùng, chúng ta có thể cài đặt podman bằng `sudo apt install podman` + +Bây giờ chúng ta có thể sử dụng rất nhiều lệnh tương tự với docker, lưu ý rằng chúng ta không có giao diện người dùng đẹp mắt giống docker. Bạn có thể thấy bên dưới tôi đã sử dụng `podman images` và không có gì sau khi cài đặt, sau đó tôi đã sử dụng `podman pull ubuntu` để kéo container image của ubuntu xuống. + +![](../../Days/Images/Day48_Containers1.png) + +Sau đó, chúng tôi có thể chạy hình ảnh Ubuntu của mình bằng cách sử dụng `podman run -dit ubuntu` và `podman ps` để xem hình ảnh đang chạy của chúng ta. + +![](../../Days/Images/Day48_Containers2.png) + +Sau đó, để truy cập vào container đó, chúng ta có thể chạy `podman attach dazzling_darwin` tên container của bạn rất có thể sẽ khác. + +![](../../Days/Images/Day48_Containers3.png) + +Nếu bạn đang chuyển từ docker sang podman, bạn cũng nên thay đổi tệp cấu hình của mình thành `alias docker=podman` theo cách đó, bất kỳ lệnh nào bạn chạy với docker cũng sẽ sử dụng podman. + +### LXC + +LXC là một container engine cho phép người dùng tạo nhiều Linux container được cô lập. Không giống như Docker, LXC hoạt động như một trình ảo hóa để tạo nhiều máy Linux với các tệp hệ thống riêng biệt và các tính năng, cấu hình mạng. Xuất hiện trước Docker và sau đó quay trở lại trong thời gian ngắn do những thiếu sót của Docker. + +LXC nhẹ như docker và dễ dàng triển khai. + +### Containerd + +Một standalone container runtime. Containerd mang lại sự đơn giản và mạnh mẽ cũng như tính di động. Containerd trước đây là một công cụ trong các dịch vụ container của Docker cho đến khi Docker quyết định tách nó ra thành một thành phần độc lập. + +Một dự án trong Cloud Native Computing Foundation, nó được đặt cùng với các công cụ vùng chứa phổ biến như Kubernetes, Prometheus và CoreDNS. + +### Các công cụ Docker khác + +Chúng ta cũng có thể đề cập đến các công cụ và tùy chọn xung quanh Rancher và VirtualBox nhưng có thể sẽ trình bày chi tiết hơn vào một bài viết khác. + +[**Gradle**](https://gradle.org/) + +- Quét bản dựng cho phép các nhóm cộng tác gỡ lỗi và theo dõi lịch sử của tất cả các bản dựng. +- Các tùy chọn thực thi cung cấp cho các nhóm khả năng xây dựng liên tục để bất cứ khi nào có thay đổi, nhiệm vụ sẽ tự động được thực thi. +- Bố cục kho lưu trữ tùy chỉnh cung cấp cho các nhóm khả năng xử lý bất kỳ cấu trúc thư mục tệp nào dưới dạng kho lưu trữ cho artifact. + +[**Packer**](https://packer.io/) + +- Khả năng tạo song song nhiều hình ảnh máy để tiết kiệm thời gian của nhà phát triển và tăng hiệu quả. +- Các nhóm có thể dễ dàng gỡ lỗi các bản dựng bằng trình gỡ lỗi của Packer, công cụ này sẽ kiểm tra các lỗi và cho phép các nhóm thử các giải pháp trước khi bắt đầu lại các bản dựng. +- Hỗ trợ nhiều nền tảng thông qua plugin để các nhóm có thể tùy chỉnh bản dựng của mình. + + +[**Logspout**](https://github.com/gliderlabs/logspout) + +- Công cụ ghi log - Khả năng tùy chỉnh của công cụ này cho phép các nhóm gửi cùng một nhật ký đến nhiều điểm đến. +- Các nhóm có thể dễ dàng quản lý các tệp của họ vì công cụ này chỉ yêu cầu quyền truy cập vào Docker socket. +- Mã nguồn mở và dễ triển khai. + +[**Logstash**](https://www.elastic.co/products/logstash) + +- Tùy chỉnh quy trình của bạn và dễ dàng tích hợp với Logstash pluggable framework. +- Dễ dàng phân tích cú pháp và chuyển đổi dữ liệu của bạn để phân tích và mang lại giá trị kinh doanh. +- Nhiều đầu ra khác nhau của Logstash cho phép bạn định tuyến dữ liệu của mình đến nơi bạn muốn. + +[**Portainer**](https://www.portainer.io/) + +- Sử dụng các mẫu được tạo sẵn hoặc tạo mẫu của riêng bạn để triển khai các ứng dụng. +- Tạo nhóm và gán vai trò và quyền cho các thành viên trong nhóm. +- Biết những gì đang chạy trong từng môi trường bằng bảng điều khiển của công cụ. + +## Tài nguyên tham khảo + +- [TechWorld with Nana - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=3c-iBn73dDE) +- [Programming with Mosh - Docker Tutorial for Beginners](https://www.youtube.com/watch?v=pTFZFxd4hOI) +- [Docker Tutorial for Beginners - What is Docker? Introduction to Containers](https://www.youtube.com/watch?v=17Bl31rlnRM&list=WL&index=128&t=61s) +- [WSL 2 with Docker getting started](https://www.youtube.com/watch?v=5RQbdMn04Oc) +- [Blog on getting started building a docker image](https://stackify.com/docker-build-a-beginners-guide-to-building-docker-images/) +- [Docker documentation for building an image](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/) +- [YAML Tutorial: Everything You Need to Get Started in Minute](https://www.cloudbees.com/blog/yaml-tutorial-everything-you-need-get-started) +- [Podman | Daemonless Docker | Getting Started with Podman](https://www.youtube.com/watch?v=Za2BqzeZjBk) +- [LXC - Guide to building an LXC Lab](https://www.youtube.com/watch?v=cqOtksmsxfg) + +Hẹn gặp lại vào [ngày 49](day49.md) diff --git a/2022/vi/Days/day49.md b/2022/vi/Days/day49.md new file mode 100644 index 0000000..05727e6 --- /dev/null +++ b/2022/vi/Days/day49.md @@ -0,0 +1,215 @@ +--- +title: '#90DaysOfDevOps - Bức tranh toàn cảnh: Kubernetes - Ngày 49' +published: false +description: 90DaysOfDevOps - Bức tranh toàn cảnh: Kubernetes +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049049 +--- + +## Bức tranh toàn cảnh: Kubernetes + +Trong phần trước, chúng ta đã đề cập đến Containers, container chưa đạt yêu cầu khi xem xét khía cạnh điều chỉnh quy mô (scaling) và điều phối (orchestration). Thứ tốt nhất chúng ta có thể làm là docker-compose để tạo một ứng dụng với nhiều container. Khi nói đến Kubernetes, một Container Orchestrator, nó mang lại chúng ta khả năng tăng và giảm quy mô một cách tự động hoặc dựa trên tải ứng dụng và dịch vụ của bạn. + +Là một nền tảng, Kubernetes cung cấp khả năng sắp xếp các container theo yêu cầu và trạng thái mong muốn của bạn. Chúng ta sẽ đề cập đến Kubernetes trong phần này vì nó đang nổi lên là một cách để triển khai cơ sở hạ tầng tiếp theo. Tôi cũng đề xuất rằng, từ góc độ DevOps, Kubernetes chỉ là một nền tảng mà bạn cần có hiểu biết cơ bản, cũng như về bare metal, ảo hoá và rất có thể là các dịch vụ dựa trên điện toán đám mây. Kubernetes chỉ là một tuỳ chọn khác để chạy các ứng dụng của bạn. + +### Container Orchestration (Điều phối container) là gì? + +Tôi đã đề cập tới Kubernetes và tôi đã đề cập tới Container Orchestration, Kubernetes là công nghệ trong khi điều phối container là khái niệm, quy trình phía sau công nghệ đó. Kubernetes không phải là nền tảng Điều phối container duy nhất mà chúng ta còn có Docker Swarm, HashiCorp Nomad và các nền tảng khác. Nhưng Kubernetes đang phát triển ngày càng mạnh mẽ, vì vậy tôi muốn đề cập đến Kubernetes nhưng muốn nói rằng nó không phải công nghệ duy nhất ngoài kia. + +### Kubernetes là gì? + +Điều đầu tiên bạn nên đọc nếu bạn chưa quen với Kubernetes là tài liệu chính thức. Kinh nghiệm của tôi khi thực sự tìm hiểu sâu về Kubernetes hơn một năm trước là đó sẽ là một quá trình học tập đòi hỏi nhiều thời gian. Xuất phát từ nền tảng ảo hoá và lưu trữ, tôi đã nghĩ nó sẽ rất khó khăn. + +Nhưng cộng động và tài nguyên học tập miễn phí và các tư liệu cực kỳ tốt. [Kubernetes.io](https://kubernetes.io/docs/concepts/overview/what-is-kubernetes/) + +_Kubernetes là một nền tảng mã nguồn mở, di động, có thể mở rộng để quản lý khối lượng công việc và dịch vụ được chạy trên container, hỗ trợ cả cấu hình khai báo và tự động hóa. Nó có một hệ sinh thái lớn, phát triển nhanh chóng. Các dịch vụ, hỗ trợ và công cụ Kubernetes được phổ biến rộng rãi._ + +Những điều quan trọng cần lưu ý trong câu trích dẫn trên, Kubernetes là dự án mã nguồn mở với lịch sử bắt nguồn từ Google, người đã trao tặng dự án cho tổ chức Cloud Native Computing Foundation (CNCF) và nó hiện cũng đang được phát triển bởi cộng đồng mã nguồn mở và các doanh nghiệp lớn góp phần tạo nên Kubernetes như ngày nay. + +Tôi đã đề cập ở trên về việc các container tốt như thế nào và trong phần trước, chúng ta đã nói về cách container và các container image đã thay đổi và đẩy nhanh việc áp dụng các hệ thống cloud-native. Nhưng chỉ riêng container sẽ không cung cấp trải nghiệm sẵn sàng cho môi trường sản xuất của các ứng dụng của bạn. Kubernetes cung cấp cho chúng ta những điều sau: + +- **Phát hiện dịch vụ (Service discovery) và cân bằng tải (load balancing)** Kubernetes có thể expose một container bằng cách sử dụng DNS hoặc địa chỉ IP của chúng. Nếu lưu lượng truy cập vào container cao, Kubernetes có thể cân bằng tải và điều phối lưu lượng mạng để quá trình triển khai được ổn định. + +- **Điều phối lưu trữ (Storage orchestration)** Kubernetes cho phép bạn tự động gắn hệ thống lưu trữ mà bạn chọn, chẳng hạn như lưu trữ cục bộ (local storage) hoặc các dịch vụ lưu trữ sử dụng điện toán đám mây công cộng,... + +- **Tự động triển khai và khôi phục (Automated rollouts and rollbacks)** Bạn có thể mô tả trạng thái mong muốn cho các containers đã triển khai của mình bằng Kubernetes và nó có thể thay đổi trạng thái mong muốn với tốc độ được kiểm soát. Ví dụ: bạn có thể tự động hoá Kubernetes để tạo container mới cho quá trình triển khai của mình, xoá container hiện có và sử dụng tất cả các tài nguyên của chúng ta cho container mới được tạo. + + +- **Đóng gói tự động** Bạn cung cấp cho Kubernetes một cluster gồm nhiều nodes mà nó có thể sử dụng để chạy các tác vụ được đóng gói trong các containers. Bạn cho Kubernetes biết lượng CPU và bộ nhớ (RAM) mà mỗi container cần. Kubernetes có thể sắp xếp các containers và các nodes của bạn để có thể tận dụng các tài nguyên một cách tốt nhất. + +- **Tự phục hồi** Kubernetes khởi động lại các container bị lỗi, thay thế các container, xoá bỏ các container không phản hồi các health-check do người dùng quy định và không sử dụng các container cho các yêu cầu từ người dùng cho đến khi chúng ở trạng thái sẵn sàng. + + +- **Quản lý cấu hình và bí mật (Secret and configuration management)** Kubernetes cho phép bạn lưu trữ và quản lý thông tin nhạy cảm, chẳng hạn như mật khẩu, OAuth tokens, hoặc SSH keys. Bạn có thể triển khai và cập nhật các giá trị bí mật cũng như cấu hình ứng dụng mà không cần xây dựng lại container image cũng như không để lộ các giá trị đó trong cấu hình hệ thống của bạn. + +Kubernetes cung cấp cho bạn một framework để chạy các hệ thống phân tán một cách linh hoạt. + +Container Orchestration quản lý việc triển khai, sắp xếp và vòng đời của các containers. + +Nó cũng có các nhiệm vụ khác: + +- Quản lý, liên kết các máy chủ thành một cluster. +- Quản lý lập lịch, sắp xếp các containers trên các nodes thông qua scheduler. +- Khám phá dịch vụ (service discovery) biết vị trí của các containers trong các nodes thông qua scheduler. +- Đảm bảo đủ số lượng nodes và containers cho khối lượng công việc được yêu cầu thông qua replication. +- Quản lý sức khoẻ, phát hiện và thay thế các nodes, containers. + +### Các thành phần chính của Kubernetes + +Kubernetes là một công cụ điều phối containers cho phép cung cấp, quản lý và mở rộng quy mô ứng dụng. Bạn có thể sử dụng nó để quản lý vòng đời của các ứng dụng được container hoá trong các nodes của một cluster - là một tập hợp các máy worker như các máy ảo hoặc các máy vật lý. + +Ứng dụng của bạn có thể cần nhiều tài nguyên khác để chạy, chẳng hạn như ổ đĩa, mạng và các giá trị bí mật giúp bạn kết nối với cơ sở dữ liệu, nói chuyện với các hệ thống được bảo vệ bởi tường lửa và khóa bảo mật. Với Kubernetes, bạn có thể thêm các tài nguyên đó vào ứng dụng của mình. Tài nguyên cơ sở hạ tầng mà ứng dụng của bạn cần sẽ được quản lý quản lý theo dạng khai báo. + +Hình mẫu chính (key paradigm) của Kubernetes là mô hình khai báo của nó. Bạn cung cấp trạng thái mà bạn muốn và Kubernetes sẽ biến nó thành hiện thực. Nếu bạn cần năm instances, thì bạn không tự mình khởi động năm instances riêng biệt. Thay vào đó, bạn nói với Kubernetes rằng bạn cần năm instances và Kubernetes sẽ tự động điều chỉnh trạng thái. Nếu xảy ra sự cố với một trong các instances của bạn, Kubernetes vẫn biết trạng thái mà bạn muốn và tạo các instances trên một node có sẵn. + +### Node + +#### Control Plane + +Mỗi Kubernetes cluster yêu cầu một Control plane node, các thành phần của control plane đưa ra các quyết định chung về cluster đó (ví dụ: lập lịch), cũng như phát hiện và phản hồi các sự kiện của cluster. + +![](../../Days/Images/Day49_Kubernetes1.png) + +#### Worker Node + +Một máy worker chạy khối lượng công vuệc của Kubernetes. Nó có thể là một máy vật lý (bare metal) hoặc máy ảo (VM). Mỗi node có thể lưu trữ một hoặc nhiều pods. Các nodes của Kubernetes được quản lý bởi một control plane. + +![](../../Days/Images/Day49_Kubernetes2.png) + +Có nhiều loại node khác nữa nhưng tôi sẽ không đề cập tại đây. + +#### kubelet + +Một agent chạy trên mọi node trong cluster. Nó đảm bảo rằng các containers đang được chạy trong pod. + +Kubelet nhận một bộ PodSpecs được cung cấp thông qua các cơ chế khác nhau và đảm bảo rằng các vùng chứa được mô tả trong các PodSpec đó đang chạy và khoẻ mạnh. Kubelet không quản lý các containers không được tạo bởi Kubernetes. + +![](../../Days/Images/Day49_Kubernetes3.png) + +#### kube-proxy + + +kube-proxy là một proxy mạng chạy trên mỗi node trong cluster của bạn, triển khai một phần của khái niệm Kubernetes Service. + +kube-proxy duy trì các quy tắc mạng trên các nodes. Các quy tắc mạng này cho phép giao tiếp mạng với các Pods của bạn từ các sessions mạnh bên trong hoặc bên ngoài cluster của bạn. + +kube-proxy sử dụng lớp lọc gói tin (packet filtering layer) của hệ điều hành nếu có thể. Nếu không, kube-proxy tự chuyển tiếp traffic. + +![](../../Days/Images/Day49_Kubernetes4.png) + +#### Container runtime + +The container runtime là phần mềm chịu trách nhiệm chạy các containers. + +Kubernetes hỗ trợ một số container runtimes: Docker, containerd, CRI-O, và mọi các triển khai của Kubernetes CRI (Container Runtime Interface). + +![](../../Days/Images/Day49_Kubernetes5.png) + +### Cluster + +Cluster là một nhóm các nodes, trong đó một node có thể là một máy vật lý hoặc một máy ảo. Mỗi node sẽ có container runtime (Docker) và cũng sẽ chạy một kubelet service, là agent nhận các lệnh từ Master controller (sẽ nói thêm sau) và một Proxy được sử dụng để kết nối proxy tới các Pods khác từ một thành phần khác (Services, thứ mà chúng ta sẽ đề cập sau). + +Control plane của chúng ta có thể được triển khai với độ sẵn sàng cao (HA) sẽ chứa một số vai trò khác biệt với các worker nodes, quan trọng nhất sẽ là máy chủ kube API, đây là nơi sẽ diễn ra mọi giao tiếp để lấy thông tin hoặc đẩy thông tin đến Kubernetes cluster của chúng ta. + +#### Máy chủ Kube API + +Máy chủ Kubernetes API xác thực và định cấu hình dữ liệu cho các đối tượng API bao gồm pods, services, replication controllers, và các đối tượng khác. Máy chủ API phụ vụ các tác vụ REST và cung cấp giao diện người dùng cho các trạng thái được chia sẻ của cluster qua đó tất cả các thành phần khác có thể tương tác. + +#### Scheduler + +Kubernetes scheduler (bộ lập lịch) là một quy trình của control plane lập lịch các Pods cho các Nodes. Scheduler xác định node nào là vị trí thích hợp cho từ pod trong hàng đợi lập lịch theo các ràng buộc và tài nguyên sẵn có. Sau đó, Scheduler sẽ xếp hạng từng node hợp lệ gắn pod vào một node thích hợp. + +#### Controller Manager + +Kubernetes controller manager là một trình chạy nền có các vòng điều khiển lõi được cài đặt cùng với Kubernetes. Trong các ứng dụng của người máy hoặc tự động hoá, vòng điểu khiển là một vòng lặp không kết thúc để điều chỉnh trạng thái của hệ thống. Trong Kubernetes, bộ điều khiển là một vòng điều khiển theo dõi trạng thái được chia sẽ của cluster thông qua máy chủ api và thực hiện các thay đổi nhằm chuyển trạng thái hiện tại sang trạng thái mong muốn. + +#### etcd + +Kho lưu trữ dạng key-value có tính nhất quán và độ sẵn sàng cao được sử dụng để lưu trữ toàn bộ cấu hình, trạng thái của Kubernetes cluster. + +![](../../Days/Images/Day49_Kubernetes6.png) + +#### kubectl + +Để quản lý Kubernetes cluster bằng CLI, chúng ta có kubectl, kubectl tương tác với API server. + +Công cụ dòng lệnh của Kubernetes, kubectl cho phép bạn chạy các lệnh tương tác với Kubernetes cluster. Bạn có thể sử dụng kubectl để triển khai ứng dụng, kiểm tra và quản lý tài nguyên của cluster cũng như xem log. + +![](../../Days/Images/Day49_Kubernetes7.png) + +### Pods + +Pod là một nhóm các container tạo thành một ứng dụng logic. Ví dụ: Nếu bạn có một ứng dụng web đang chạy nodejs container và một MySQL container thì cả hai containers này có thể được đặt trong một pod duy nhất. Một pod cũng có thể chia sẻ các volumes dữ liệu chung và chúng cũng chia sẻ một networking namespace. Hãy nhớ rằng các pod là tạm thời và chúng có thể được bật hoặc tắt bởi Master Controller. Kubernetes sử dụng một phương tiện đơn giản nhưng hiệu quả để xác định các pod thông qua khái niệm Labels (nhãn: key - values). + +- Pods sử lý Volumes, Secrets, và cấu hình cho containers. +- Pod mang tính tạm thời (ephemeral). Chúng sẽ tự khởi động lại khi chúng gặp lỗi. +- Pod được replicated khi ứng dụng mở rộng quy mô theo chiều ngang bởi ReplicaSet. Mỗi pod sẽ chạy cùng một container code. +- Pods chạy trên các Worker nodes. + +![](../../Days/Images/Day49_Kubernetes8.png) + +### Deployments + +- Bạn chỉ có thể quyết định chạy Pods, nhưng khi chúng gặp lỗi chúng sẽ biến mất. +- Một Deployment sẽ cho phép pod của bạn chạy liên tục. +- Deployment cho phép bạn cập nhật ứng dụng đang chạy mà không có đowntime. +- Deployment cũng xác định một chiến lược khởi động lại pod khi chúng chết. + +![](../../Days/Images/Day49_Kubernetes9.png) + +### ReplicaSets + +- Deployment cũng có thể tạo ReplicaSet. +- Một ReplicaSet đảm bảo ứng dụng của bạn có số lượng pod mong muốn. +- Replicate sẽ tạo vả mở rộng các nhóm dựa trên Deployment + +### StatefulSets + +- Ứng dụng của bạn có yêu cầu bạn lưu giữ thông tin về trạng thái của nó không? +- Một cơ sở dữ liệu cần trạng thái +- Các Pod của StatefulSet không thể hoán đổi cho nhau. +- Mỗi nhóm có một mã định danh duy nhất, cố định mà controller duy trì trong mọi lần lập lịch lại. + +![](../../Days/Images/Day49_Kubernetes10.png) + +### DaemonSets + +- DeamonSets được sử dụng cho các tiến trình liên tục. +- Chạy trên một pod trong mỗi node. +- Mỗi node mới được thêm vào cluster sẽ bắt đầu một pod mới +- Hữu ích cho các tác vụ nên như monitoring hay thu thập log +- Mỗi pod có một mã định danh duy nhất và cố định mà controller duy trì trong mọi lần lập lịch lại. + +![](../../Days/Images/Day49_Kubernetes11.png) + +### Services + +- Một endpoint duy nhất để truy cập các pods. +- Một cách thống nhất để định tuyến lưu lượng truy cập đến một cluster và cuối cùng là các pods. +- Bằng cách sử dụng Services, các pods có thể được khởi động và tắt mà không ảnh hưởng đến bất cứ thứ gì. + +Đây chỉ là khái quát nhanh và ghi chú về các khối xây dựng cơ bản của Kubernetes, chúng ta có thể sử dụng kiến thức này và thêm vào một số kiến thức khác xung quanh Storage và Ingress để cải thiện ứng dụng của mình nhưng cũng có nhiều lựa chọn về nơi mà bạn muốn chạy Kubernetes cluster của mình. Phần tiếp theo sẽ tập trung vào các tuỳ chọn về nơi chạy cluster Kubernetes, đồng thời tìm hiểu thêm một số kiến thức cụ thể về Storage. + +![](../../Days/Images/Day49_Kubernetes12.png) + +### Những gì chúng ta sẽ đề cập trong loạt bài về Kubernetes + +- Kiến trúc Kubernetes +- Các câu lệnh kubectl +- Kubernetes YAML +- Kubernetes Ingress +- Kubernetes Services +- Helm Package Manager +- Lưu trữ liên tục - Persistent Storage +- Ứng dụng có trạng thái - Stateful Apps + +## Tài liệu tham khảo + +- [Kubernetes Documentation](https://kubernetes.io/docs/home/) +- [TechWorld with Nana - Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]](https://www.youtube.com/watch?v=X48VuDVv0do) +- [TechWorld with Nana - Kubernetes Crash Course for Absolute Beginners](https://www.youtube.com/watch?v=s_o8dwzRlu4) +- [Kunal Kushwaha - Kubernetes Tutorial for Beginners | What is Kubernetes? Architecture Simplified!](https://www.youtube.com/watch?v=KVBON1lA9N8) + +Hẹn gặp lại vào [ngày 50](day50.md) diff --git a/2022/vi/Days/day50.md b/2022/vi/Days/day50.md new file mode 100644 index 0000000..8fa49ba --- /dev/null +++ b/2022/vi/Days/day50.md @@ -0,0 +1,79 @@ +--- +title: '#90DaysOfDevOps - Chọn nền tảng chạy Kubernetes - Ngày 50' +published: false +description: 90DaysOfDevOps - Chọn nền tảng chạy Kubernetes +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049046 +--- + +## Chọn nền tảng chạy Kubernetes + +Tôi muốn sử dụng phần này để chia nhỏ một số nền tảng, một thách thức với thế giới Kubernetes là loại bỏ, giảm bớt sự phức tạp. + +Kubernetes đã trải qua một chặng đường khó khăn về cách xây dựng từ con số không thành một Kubernetes cluster đầy đủ chức năng, điều này cực quan trọng nhưng ngày càng nhiều, ít nhất những người mà tôi đang nói chuyện đang muốn loại bỏ sự phức tạp đó và chạy Kubernetes cluster được quản lý. Vấn đề là nó tốn nhiều tiền hơn nhưng lợi ích đem lại nếu bạn sử dụng dịch vụ được quản lý, bạn có cần biết kiến thức node nền tảng và điều gì đang xảy ra trong Control Plan node khi nhìn chung bạn không có quyền truy cập vào nó. + +Sau đó, chúng ta có các bản phân phối phát triển cục bộ cho phép chúng ta sử dụng hệ thống của mình và chạy phiên bản Kubernetes cục bộ để các nhà phát triển có thể có môi trường làm việc đầy đủ để chạy ứng dụng của họ trong nên tảng mà họ dự định sử dụng. + +Cơ sở chung của tất cả các khái niệm này là chúng đều là một loại của Kubernetes, nghĩa là chúng ta có thể tự do migrate và di chuyển workloads của mình đến nơi chúng ta cần để phù hợp với yêu cầu của mình. + +Rất nhiều khi lựa chọn của chúng ta cũng sẽ phụ thuộc vào những khoản đầu tư đã được thực hiện. Tôi cũng đã đề cập đến trải nghiệm của nhà phát triển nhưng một số môi trường Kubernetes cục bộ chạy trên máy tính xách tay của chúng ta cũng đã rất tuyệt vời để nắm bắt công nghệ mà không tốn bất kỳ khoản tiền nào. + +### Bare-Metal Clusters + +Một lựa chọn cho nhiều người có thể là chạy hệ điều hành Linux của bạn trực tiếp trên một số máy chủ vật lý để tạo cluster của chúng ta, đó cũng có thể là Windows nhưng tôi chưa nghe nhiều tỷ lệ tương thích của Windows, Containers và Kubernetes. Nếu chúng ta là một doanh nghiệp và quyết định một khoản đầu tư vào các máy chủ vật lý thì đây có thể là lựa chọn của bạn cho việc chạy Kubernetes cluster, tuy nhiên bạn sẽ phải tự xây dựng và quản lý mọi thứ từ đầu. + +### Ảo hoá (Virtualisation) + +Bất kể môi trường ảo hoá bao gồm thử nghiệm hay học tập hay sẵn sàng cho các enterprise của Kubernetes cluster đều là một cách tốt để bạn bắt đầu, điển hình là việc tạo ra các máy ảo để hoạt động như các node của bạn sau đó nhóm chúng lại với nhau cũng như tận dụng khoản tiền đã chi. Ví dụ như VMware cung cấp một giải pháp tuyệt vời cho cả máy ảo và Kubernetes với nhiều tuỳ chọn khác nhau. + +Kubernetes cluster của tôi được xây dựng dựa trên ảo hoá bằng Microsoft Hyper-V trên một máy chủ cũ mà tôi có. Máy chủ này có khả năng chạy một số máy ảo làm node của tôi. + +### Các tuỳ chọn trên máy tính để bàn + +Có một số lựa chọn khi chạy Kubernetes cluster cục bộ trên máy tính để bàn hoặc máy tính xách tay của bạn. Như đã nói ở trên, điều này mang lại cho các nhà phát triển khả năng kiểm tra ứng dụng của họ mà không cần phải có nhiều cluster phức tạp hoặc tốn kém. Cá nhân tôi nghĩ rằng đây là một trong những thứ mà tôi đã sử dụng rất nhiều và cụ thể là tôi đã dùng minikube. Nó có một số chức năng và tiện ích bổ sung rất tốt giúp thay đổi cách bạn thiết lập và chạy một thứ gì đó. + +### Dịch vụ Kubernetes được quản lý + +Tôi đã đề cập đến ảo hoá và điều này có thể thực hiện được với các trình ảo hoá cục bộ, chúng ta đã biết từ các phần trước rằng chúng ta cũng có thể tận dụng các máy ảo trong dịch vụ điện toán đám mây công cộng để hoạt động như các nodes của chúng ta. Điều tôi đang muốn nhắc tới ở đây khi nói tới các dịch vụ được quản lý của Kubernetes là các dịch vụ mà chúng ta thấy từ các công ty điện toán đám mây cũng như từ các MSP (Managed service provider - Bên cung cấp dịch vụ quản lý) loại bỏ các tác vụ quản lý và kiểm soát khỏi người dùng cuối, điều này có thể loại bỏ quyền kiểm soát control plane khỏi người dùng cuối, đây là điều sẽ xảy ra với Amazon EKS, Microsoft AKS và Google Kubernetes Engine (GKE). + +### Quá nhiều chọn lựa + +Ý tôi là được lựa chọn là điều tuyệt vời nhưng có một điểm khiến chúng ta bị ngập trong các chọn lựa và bài viết này không đề cập một cách sâu sắc về tất cả các tuỳ chọn trong mỗi danh mục được liệt kê ở trên. Ngoài những điều được nhắc tới ở trên, chúng ta cũng có OpenShift của RedHat và lựa chọn này có thể được chạy trên các lựa chọn ở trên với tất cả các nhà cung cấp điện toán đám mây lớn và có lẽ sẽ mang lại khả năng sử dụng tổng thể tốt nhất cho các quản trị viên bất kể cluster được triển khai ở đâu. + +Vậy bạn bắt đầu từ đâu trong hành trình học tập của mình, như tôi đã nói, tôi bắt đầu với lộ trình ảo hoá nhưng đó là vì tôi có quyền truy cập vào một máy chủ vậy lý mà tôi có thể sử dụng cho mục đích này, tôi rất biết ơn vì điều đó và trên thực tế, kể từ đó tôi không còn được truy cập vào lựa chọn này. + +Lời khuyên thực tế của tôi bây giờ là sử dụng Minikube làm tuỳ chọn đầu tiên hoặc Kind (Kubernetes in Docker) nhưng Minikube mang lại cho chúng ta một số tiện ích bổ sung và gần như trừu tượng hoá sự phức tạp vì chúng ta có thể sử dụng các add-ón và xây dựng mọi thứ một cách nhanh chóng, sau đó xoá tất cả khi chúng ta hoàn thành, chúng ta cũng có thể chạy nhiều clusters, chạy nó ở hầu hết tất cả mọi nơi, đa nền tảng và không phụ thuộc và phần cứng. + +Tôi đã trài qua hành trình tìm hiểu về Kubernetes, vì vậy tôi sẽ để lại lựa chọn nền tảng và các chi tiết cụ thể ở đây để liệt kê các tuỳ chọn mà tôi đã thử để giúp tôi hiểu rõ hơn về nền tàng Kubernetes và nơi nó có thể chạy. Bạn có thể tham khảo những bài viết dưới đây để đưa ra lựa chọn của mình. + +- [Kubernetes playground – How to choose your platform](https://vzilla.co.uk/vzilla-blog/building-the-home-lab-kubernetes-playground-part-1) +- [Kubernetes playground – Setting up your cluster](https://vzilla.co.uk/vzilla-blog/building-the-home-lab-kubernetes-playground-part-2) +- [Getting started with Amazon Elastic Kubernetes Service (Amazon EKS)](https://vzilla.co.uk/vzilla-blog/getting-started-with-amazon-elastic-kubernetes-service-amazon-eks) +- [Getting started with Microsoft Azure Kubernetes Service (AKS)](https://vzilla.co.uk/vzilla-blog/getting-started-with-microsoft-azure-kubernetes-service-aks) +- [Getting Started with Microsoft AKS – Azure PowerShell Edition](https://vzilla.co.uk/vzilla-blog/getting-started-with-microsoft-aks-azure-powershell-edition) +- [Getting started with Google Kubernetes Service (GKE)](https://vzilla.co.uk/vzilla-blog/getting-started-with-google-kubernetes-service-gke) +- [Kubernetes, How to – AWS Bottlerocket + Amazon EKS](https://vzilla.co.uk/vzilla-blog/kubernetes-how-to-aws-bottlerocket-amazon-eks) +- [Getting started with CIVO Cloud](https://vzilla.co.uk/vzilla-blog/getting-started-with-civo-cloud) +- [Minikube - Kubernetes Demo Environment For Everyone](https://vzilla.co.uk/vzilla-blog/project_pace-kasten-k10-demo-environment-for-everyone) + +### Những gì chúng ta sẽ đề cập trong loạt bài về Kubernetes + +- Kiến trúc Kubernetes +- Các câu lệnh kubectl +- Kubernetes YAML +- Kubernetes Ingress +- Kubernetes Services +- Helm Package Manager +- Lưu trữ liên tục - Persistent Storage +- Ứng dụng có trạng thái - Stateful Apps + +## Tài liệu tham khảo + +- [Kubernetes Documentation](https://kubernetes.io/docs/home/) +- [TechWorld with Nana - Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]](https://www.youtube.com/watch?v=X48VuDVv0do) +- [TechWorld with Nana - Kubernetes Crash Course for Absolute Beginners](https://www.youtube.com/watch?v=s_o8dwzRlu4) +- [Kunal Kushwaha - Kubernetes Tutorial for Beginners | What is Kubernetes? Architecture Simplified!](https://www.youtube.com/watch?v=KVBON1lA9N8) + +Hẹn gặp lại vào [ngày 51](day51.md) diff --git a/2022/vi/Days/day51.md b/2022/vi/Days/day51.md new file mode 100644 index 0000000..c1b8b16 --- /dev/null +++ b/2022/vi/Days/day51.md @@ -0,0 +1,175 @@ +--- +title: '#90DaysOfDevOps - Triển khai cluster Kubernetes đầu tiên - Ngày 51' +published: false +description: 90DaysOfDevOps - Triển khai cluster Kubernetes đầu tiên +tags: 'DevOps, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048778 +--- + +## Triển khai cluster Kubernetes đầu tiên + +Trong bài viết này, chúng ta sẽ thiết lập và chạy một Kubernetes cluster trên máy tính cá nhân sử dụng minikube, điều này sẽ cung cấp cho chúng ta một cluster cơ bản cho phần còn lại của tuần nói về Kubernetes. Mặc dù chúng ta cũng sẽ xem xét tới việc triển khai một Kubernetes cluster với Virtual Box trong phần sau. Lý do chọn phương pháp này so với sử dụng dịch vụ được quản lý bởi các nhà cung cấp điện toán đám mây công cộng là vì nó sẽ khiến bạn tốn tiền ngay cả với bậc miễn phí, tôi đã chia sẻ một số blog nếu bạn muốn thực hiện điều đó vào [ngày 50](day50.md). + +### Minikube là gì? + +> "minikube nhanh chóng thiết lập một Kubernetes cluster cục bộ trên macOS, Linux và Windows. Chúng tôi tập trung vào việc trợ giúp các nhà phát triển ứng dụng và những người dùng mới của Kubernetes" + +Bạn có thể không phải là đối tượng được nhắc tới ở trên nhưng tôi nhận thấy minikube là một công cụ tuyệt vời nếu bạn chỉ muốn thực nghiệm thứ gì đó với Kubernetes, bạn có thể dễ dàng triển khai một ứng dụng và chúng cũng có một số add-ons rất tốt sẽ được giới thiệu ngay sau đây. + +Để bắt đầu, bất kể hệ điều hành nào cũng có thể chạy minikube. Trước tiên, hãy truy cập vào [trang web chính thức của dự án tại đây](https://minikube.sigs.k8s.io/docs/start/) để chọn phương pháp cài đặt. Tôi không sử dụng cách này nhưng bạn có thể chọn cách của tôi ở dưới dây. + +Được đề cập ở dưới, bạn cần phải có "Trình quản lý container hoặc máy ảo, ví dụ như Docker, Hyper kit, Hyper-V, KVM, Parallels, Podman, VirtualBox, hoặc VMware", đó sẽ là nơi Minikube chạy một cách dễ dàng nhất. Bạn có thể cài đặt Docker trên hệ thống của mình bằng cách sử dụng [hướng dẫn sau](https://docs.docker.com/get-docker/). + +![](../../Days/Images/Day51_Kubernetes1.png) + +### Các cài đặt minikube và các phần mềm khác của tôi + +Tôi đã sử dụng Arkade được một thời gian để tải tất cả các công cụ liên quan tới Kubernetes và CLIs, bạn có thể xem hướng dẫn cài đặt trên [github repository này](https://github.com/alexellis/arkade) để bắt đầu với Arkade. Tôi cũng đã đề cập đến điều này trong các bài đăng khác khi tôi muốn cài đặt thứ gì đó. Sự đơn giản của việc chỉ cần nhập arkade get và sau đó xem liệu công cụ hoặc cli của bạn có hay không sẽ giúp ích rất nhiều cho bạn. Trong tuần về Linux, chúng ta đã nói về trình quản lý gói và quy trình cài đặt các phần mềm, bạn có thể nghĩ rằng Arkade là một marketplace cho tất cả các ứng dụng và CLI cho Kubernetes. Một công cụ hữu ích và nhỏ gọn cho hệ thống của bạn, viết bằng Golang và có thể dùng với mọi platform. + +![](../../Days/Images/Day51_Kubernetes2.png) + +Là một phần của danh sách dài các ứng dụng có sẵn trong arkade, minikube có thể được tải xuống và cài đặt một cách đơn giản với câu lệnh `arkade get minikube`. + +![](../../Days/Images/Day51_Kubernetes3.png) + +Chúng tôi cũng sẽ cần kubectl như một phần của các công cụ, vì vậy bạn cũng có thể cài đặt nó thông qua arkade hoặc tôi tin rằng theo như tài liệu của minikube, nó cũng được cài đặt thông qua câu lệnh curl ở bên trên. Chúng ta sẽ nói về kubectl ở phần sau của bài viết. + +### Bắt đầu và chạy Kubernetes cluster + +Đối với phần này, tôi muốn đề cập đến các lựa chọn có sẵn cho chúng ta khi thiết lập và chạy một Kubernetes cluster trên máy tính cá nhân của bạn. Chúng ta có thể chỉ cần chạy lệnh sau và một cluster sẽ được tạo cho bạn sử dụng. + +minikube được sử dụng trên dòng lệnh và khi mọi thứ được cài đặt, bạn chỉ cần lệnh `minikube start` để triển khai Kubernetes cluster đầu tiên của mình. Bạn sẽ thấy bên dưới Docker Driver sẽ là lựa chọn mặc định cho nơi mà chúng ta sẽ chạy các node ảo hoá của mình. Tôi đã đề cập ở phần đầu của bài viết về các tuỳ chọn khác có sẵn, chúng sẽ hữu ích khi bạn muốn mở rộng Kubernetes cluster cục bộ này. + +Một minikube cluster sẽ bao gồm một docker container trong instance đó và sẽ có control plane node và worker node chạy trong cùng một instance trong khi thông thường, bạn sẽ tách riêng các node đó. Chúng ta sẽ đề cập đến điều đó trong phần tiếp theo, nơi chúng ta sẽ xem qua các môi trường Kubernetes trên máy tính cá nhân nhưng gần hơn một chút với kiến ​​trúc của môi trường sản xuất. + +![](../../Days/Images/Day51_Kubernetes4.png) + +Tôi đã đề cập tới vấn đề này một vài lần, tôi thích minikube vì chúng có các add-ons sẵn có, khả năng triển khai một cluster bằng một lệnh đơn giản bao gồm tất cả các add-ons cần thiết ngay từ đầu giúp tôi triển khai cùng một thiết lập mọi lúc. + +Bạn có thể thấy danh sách các add-ons ở dưới đây, tôi thường sử dụng add-on `CSI-host path-driver` và `volumesnapshots` nhưng bạn có thể xem danh sách đầy đủ ở dưới. Chắc chắn rằng các addon này thường có thể được triển khai bằng cách sử dụng Helm, thứ mà chúng ta sẽ đề cập sau trong phần Kubernetes, nó gíup mọi thứ đơn giản hơn nhiều. + +![](../../Days/Images/Day51_Kubernetes5.png) + +Tôi cũng đang xác định trong dự án của mình một số cấu hình bổ sung, apiserver được cấu hình trên port 6433 thay vì một port API ngẫu nhiên, và tôi sẽ cấu hình container runtime sử dụng containerd dù docker là lựa chọn mặc định và CRI-O cũng có thể được lựa chọn. Tôi cũng cài đặt một phiên bản Kubernetes cụ thể. + +![](../../Days/Images/Day51_Kubernetes6.png) + +Bây giờ, chúng ta đã sẵn sàng để triển khai Kubernetes cluster với minikube. Tôi đã đề cập trước đây rằng bạn sẽ cần `kubectl` để tương tác với cluster của bạn. Bạn có thể cài đặt nó với arkade bằng câu lệnh `arkade get kubectl` + +![](../../Days/Images/Day51_Kubernetes7.png) + +hoặc bạn có thể tải xuống từ trang web chính thức cho các nền tảng + +- [Linux](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux) +- [macOS](https://kubernetes.io/docs/tasks/tools/install-kubectl-macos) +- [Windows](https://kubernetes.io/docs/tasks/tools/install-kubectl-windows) + +Khi bạn đã có kubectl, chúng ta có thể tương tác với cluster sử dụng câu lệnh đơn giản `kubectl get nodes` + +![](../../Days/Images/Day51_Kubernetes8.png) + +### kubectl là gì? + +kubectl là một CLI (Command line interface - giao diện dòng lệnh) giúp bạn tương tác với Kubernetes clusters, chúng ta đang sử dụng nó ở đây để tương tác với minikube cluster của mình nhưng chúng ta cũng có thể sử dụng kubectl để tương tác với các cluster của doanh nghiệp chạy trên các đám mây công cộng. + +Chúng ta sử dụng kubectl để triển khai các ứng dụng cũng như kiểm tra và quản lý các tài nguyên của cluster. Bạn có thể đọc về [Tổng quan kubectl](https://kubernetes.io/docs/reference/kubectl/overview/) trên trang web chính thức của Kubernetes. + +kubectl tương tác với máy chủ API được chạy trên control plan node đã được chúng ta đề cập ở bài viết trước. + +### kubectl cheat sheet + +Cùng với tài liệu chính thức, tôi cũng hay sử dụng trang web này để tìm kiếm các câu lệnh của [Unofficial Kubernetes](https://unofficial-kubernetes.readthedocs.io/en/latest/) + +| Liệt kê các tài nguyên | | +| ------------------------ | ------------------------------------------ | +| kubectl get nodes | Liệt kê tất cả các nodes trong cluster | +| kubectl get namespaces | Liệt kê tất cả các namespaces trong cluster | +| kubectl get pods | Liệt kê tất cả các pods trong namespace mặc định của cluster | +| kubectl get pods -n name | Liệt kê tất cả các pods trong namespace "name" | + +| Tạo các tài nguyên | | +| ----------------------------- | ------------------------------------------- | +| kubectl create namespace name | Tạo một namespace với tên "name" | +| kubectl create -f [filename] | Tạo một tài nguyên từ tệp JSON hoặc YAML: | + +| Điều chỉnh các tài nguyên | | +| ---------------------------- | ----------------- | +| kubectl edit svc/servicename | Điều chỉnh một service | + +| Thông tin chi tiết hơn về tài nguyên | | +| ------------------------ | ------------------------------------------------------- | +| kubectl describe nodes | hiển thị chi tết trạng thái của các nodes | + +| Xoá tài nguyên | | +| ------------------ | ------------------------------------------------ | +| kubectl delete pod | Xoá các tài nguyên, có thể tử stdin hoặc tệp | + +Bạn có thể muốn biết các tên viết tắt của một số tài nguyên trên kubectl, ví dụ `-n` là tên viết tắt của `namespace` giúp bạn dễ dàng thao tác hơn và làm code của bạn trông gọn gàng hơn. + +| Tên rút gọn | Tên đầy đủ | +| ---------- | -------------------------- | +| csr | certificatesigningrequests | +| cs | componentstatuses | +| cm | configmaps | +| ds | daemonsets | +| deploy | deployments | +| ep | endpoints | +| ev | events | +| hpa | horizontalpodautoscalers | +| ing | ingresses | +| limits | limitranges | +| ns | namespaces | +| no | nodes | +| pvc | persistentvolumeclaims | +| pv | persistentvolumes | +| po | pods | +| pdb | poddisruptionbudgets | +| psp | podsecuritypolicies | +| rs | replicasets | +| rc | replicationcontrollers | +| quota | resourcequotas | +| sa | serviceaccounts | +| svc | services | + +Điều cuối cùng cần bổ sung ở đây là tôi đã tạo một dự án khác xung quanh minikube để giúp tôi nhanh chóng tạo ra các môi trường demo để hiển thị các dịch vụ dữ liệu và bảo vệ các workload đó với Kasten K10, [Project Pace](https://github.com/MichaelCade/project_pace) có thể được tìm thấy ở đó và tôi luôn chào đón phản hồi và tương tác của bạn, nó cũng có bao gồm một số các tự động để triển khai các minikube cluster của bạn và tạo các ứng dụng dịch vụ dữ liệu khác nhau. + +Tiếp theo, chúng ta sẽ triển kahi nhiều node vào các máy ảo bằng VirtualBox nhưng chúng ta sẽ chọn cách dễ hơn như các chúng ta đã làm trong tuần về Linux, sử dụng vagrant để tạo các máy ảo và triển khai các phần mềm theo cách chúng ta mong muốn. + +Tôi đã thêm danh sách này vào bài viết ngày hôm qua, đó là các blog hướng dẫn mà tôi đã thực hành với các Kubernetes cluster đã được triển khai. + +- [Kubernetes playground – How to choose your platform](https://vzilla.co.uk/vzilla-blog/building-the-home-lab-kubernetes-playground-part-1) +- [Kubernetes playground – Setting up your cluster](https://vzilla.co.uk/vzilla-blog/building-the-home-lab-kubernetes-playground-part-2) +- [Getting started with Amazon Elastic Kubernetes Service (Amazon EKS)](https://vzilla.co.uk/vzilla-blog/getting-started-with-amazon-elastic-kubernetes-service-amazon-eks) +- [Getting started with Microsoft Azure Kubernetes Service (AKS)](https://vzilla.co.uk/vzilla-blog/getting-started-with-microsoft-azure-kubernetes-service-aks) +- [Getting Started with Microsoft AKS – Azure PowerShell Edition](https://vzilla.co.uk/vzilla-blog/getting-started-with-microsoft-aks-azure-powershell-edition) +- [Getting started with Google Kubernetes Service (GKE)](https://vzilla.co.uk/vzilla-blog/getting-started-with-google-kubernetes-service-gke) +- [Kubernetes, How to – AWS Bottlerocket + Amazon EKS](https://vzilla.co.uk/vzilla-blog/kubernetes-how-to-aws-bottlerocket-amazon-eks) +- [Getting started with CIVO Cloud](https://vzilla.co.uk/vzilla-blog/getting-started-with-civo-cloud) +- [Minikube - Kubernetes Demo Environment For Everyone](https://vzilla.co.uk/vzilla-blog/project_pace-kasten-k10-demo-environment-for-everyone) +- [Minikube - Deploy Minikube Using Vagrant and Ansible on VirtualBox](https://medium.com/techbeatly/deploy-minikube-using-vagrant-and-ansible-on-virtualbox-infrastructure-as-code-2baf98188847) + + +### Những gì chúng ta sẽ đề cập trong loạt bài về Kubernetes + +Chúng ta đã đề cập tới một số vấn đề ở dưới và sẽ thực hành nhiều hơn vào ngày mai với cluster thứ 2, nơi mà chúng ta sẽ triển khai ứng dụng của mình. + +- Kiến trúc Kubernetes +- Các câu lệnh kubectl +- Kubernetes YAML +- Kubernetes Ingress +- Kubernetes Services +- Helm Package Manager +- Lưu trữ liên tục - Persistent Storage +- Ứng dụng có trạng thái - Stateful Apps + +## Tài liệu tham khảo + +- [Kubernetes Documentation](https://kubernetes.io/docs/home/) +- [TechWorld with Nana - Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]](https://www.youtube.com/watch?v=X48VuDVv0do) +- [TechWorld with Nana - Kubernetes Crash Course for Absolute Beginners](https://www.youtube.com/watch?v=s_o8dwzRlu4) +- [Kunal Kushwaha - Kubernetes Tutorial for Beginners | What is Kubernetes? Architecture Simplified!](https://www.youtube.com/watch?v=KVBON1lA9N8) +- [Techbeatly - Deploy Minikube Using Vagrant and Ansible on VirtualBox](https://www.youtube.com/watch?v=xPLQqHbp9BM&t=371s) + +Hẹn gặp lại vào [ngày 52](day52.md) diff --git a/2022/vi/Days/day52.md b/2022/vi/Days/day52.md new file mode 100644 index 0000000..12a3482 --- /dev/null +++ b/2022/vi/Days/day52.md @@ -0,0 +1,178 @@ +--- +title: '#90DaysOfDevOps - Thiết lập Kubernetes cluster đa node - Ngày 52' +published: false +description: 90DaysOfDevOps - Thiết lập Kubernetes cluster đa node +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1049050 +--- + +## Thiết lập Kubernetes cluster đa node + +Lúc đầu tôi đã tính để title của bài viết này là "Thiết lập Kubernetes cluster đa node với Vagrant" nhưng có thể nó hơi dài! + +Trong bài viết ngày hôm qua, chúng ta đã sử dụng một dự án thú vị để triển khai Kubernetes cluster đầu tiên của mình và thực hành chúng với công cụ CLI quan trọng nhất mà bạn sẽ gặp khi sử dụng Kubernetes (kubectl) + +Trong bài ngày hôm nay, chúng ta sẽ sử dụng VirtualBox làm cơ sở nhưng như đã đề cập ở lần trước khi chúng ta nói về Vagrant trong phần về Linux, chúng ta có thể sử dụng bất kỳ công cụ ảo hoá nào được hỗ trợ. Đó là [ngày 14](day14.md) khi chúng ta xem xét và triển khai máy chủ Ubuntu. + +### Tóm tắt nhanh về Vagrant + +Vagrant là một tiện ích CLI giúp quản lý vòng đời các máy ảo của bạn. Chúng ta có thể sử dụng vagrant để tạo, xoá các máy ảo trên nhiều nền tảng khác nhau bao gồm vSphere, Virtual Box và cả Docker. Nó có các nhà cung cấp khác nhưng chúng ta sẽ chọn Virtual Box ở đây. + +Tôi sẽ sử dụng [bài viết và repository này](https://devopscube.com/kubernetes-cluster-vagrant/) để cấu hình hệ hống. Tuy nhiên, tôi khuyên rằng nếu đây là lần đầu tiên bạn triển khai một Kubernetes cluster thì bạn cũng có thể xem xét thực hiện điều này một cách thủ công để sau đó ít nhất thì bạn cũng biết nó trông như thế nào. Phải công nhận sau mỗi bản phát hành của Kubernetes, các tác vụ để setup ngày càng được tinh gọn và hiệu quả hơn. Tôi nhớ thời của VMware và ESX và cách bạn mấy 1 ngày để triển khai 3 ESX server, bây giờ chúng ta có thể làm trong 1 giờ. Chúng ta sẽ đi theo hướng đó khi nói đến Kubernetes. + +### Môi trường Lab Kubernetes + +Tôi đã tải lên trong [Kubernetes folder](../../Days/Kubernetes/) vagrantfile mà chúng ta sẽ sử dụng để xây dựng môi trường. Lấy tệp này và điều hướng đến thư mục trong terminal của bạn. Tôi đang sử dụng Windows nên Powershell là lựa chọn để thực hiện các lệnh trên máy trạm của mình với vagrant. Nếu bạn chưa có vagrant thì bạn có thể sử dụng arkade, hôm qua chúng ta đã đề cập đến nó khi cài đặt minikube và các công cụ khác. Chỉ sử dụng lệnh `arkade get vagrant` và bạn sẽ tải xuống và cài đặt phiên bản vagrant mới nhất. + +Khi bạn đang ở trong thư mục của mình, chạy `vagrant up` và nếu tất cả được cấu hình chính xác thì bạn sẽ thấy phần khởi động sau trong terminal của mình. + +![](../../Days/Images/Day52_Kubernetes1.png) + +Trong terminal, bạn sẽ thấy một số bước đang diễn ra, nhưng trong thời gian chờ đợi, hãy xem những gì chúng ta đang chuẩn bị ở đây. + +![](../../Days/Images/Day52_Kubernetes2.png) + +Từ những điều trên, bạn có thể thấy rằng chúng ta sẽ xây dựng 3 máy ảo, chúng ta sẽ có một sẽ có một control plane node và 2 worker nodes. Nếu bạn qua lại [ngày 49](day49.md), bạn có thể đọc lại về những phần trong hình ảnh trên. + +Cũng trong hình ảnh đó, chúng ta thấy truy cập kubectl sẽ đến từ bên ngoài cluster tới kube apiserver trong khi thực tế như một phần của việc triển khai vagrant, chúng ta sẽ có kubectl trên mỗi node để có thể truy cập cluster từ trong tất cả các nodes. + +Quá trình thực hiện bài lab này có thể kéo dài từ 5 cho tới 30 phút phụ thuộc vào thiếp lập của bạn. + +Tôi cũng sẽ sớm đề cập tới các tệp nhưng bạn sẽ nhận thấy nếu bạn xem qua vagrantfile bạn sẽ thấy 3 phần của triển khai và đó chính là nơi cluster được tạo ra. Chúng ta thấy việc sử dụng vagrant để triển khai các máy ảo và cài đặt hệ điều hành của mình dễ dàng như thế nào với các vagrant boxes cũng như khả năng chạy tập lệnh shell như một phần của quy trình triển khai là điều khá thú vị nếu chúng ta tự động hoá các bản dựng của các bài lab. + +Sau khi hoàn tất, chúng ta có thể ssh tới một trong các node của mình `vagrant ssh master` từ terinal, username và password mặc định là `vagrant/vagrant` + +Bạn cũng có thể sử dụng `vagrant ssh node01` và `vagrant ssh node02` để truy cập các worker nodes nếu bạn muốn. + +![](../../Days/Images/Day52_Kubernetes3.png) + +Bây giờ chúng ta đang ở một trong các node trong cluster mới của chúng ta, có thể sử dụng `kubectl get nodes` để hiển thị 3 node cluster và trạng thái của chúng. + +![](../../Days/Images/Day52_Kubernetes4.png) + +Tại thời điểm này, chúng ta có một cluster với 3 nodes đang chạy, với 1 control plane node và 2 worker nodes. + +### Hướng dẫn về Vagrantfile và Shell Script + +Nếu chúng ta xem tệp vagrantfile của mình, bạn sẽ thấy rằng chúng ta đang xác định một vài worker node, địa chỉ IP mạng cho mạng bắc cầu trong VirtualBox và sau đó là một số tên đặt. Một điều khác mà bạn cũng sẽ thấy là chúng ta đang gọi một số tập lệnh mà chúng ta muốn chạy trên các máy chủ cụ thể. + +``` +NUM_WORKER_NODES=2 +IP_NW="10.0.0." +IP_START=10 + +Vagrant.configure("2") do |config| + config.vm.provision "shell", inline: <<-SHELL + apt-get update -y + echo "$IP_NW$((IP_START)) master-node" >> /etc/hosts + echo "$IP_NW$((IP_START+1)) worker-node01" >> /etc/hosts + echo "$IP_NW$((IP_START+2)) worker-node02" >> /etc/hosts + SHELL + config.vm.box = "bento/ubuntu-21.10" + config.vm.box_check_update = true + + config.vm.define "master" do |master| + master.vm.hostname = "master-node" + master.vm.network "private_network", ip: IP_NW + "#{IP_START}" + master.vm.provider "virtualbox" do |vb| + vb.memory = 4048 + vb.cpus = 2 + vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] + end + master.vm.provision "shell", path: "scripts/common.sh" + master.vm.provision "shell", path: "scripts/master.sh" + end + + (1..NUM_WORKER_NODES).each do |i| + config.vm.define "node0#{i}" do |node| + node.vm.hostname = "worker-node0#{i}" + node.vm.network "private_network", ip: IP_NW + "#{IP_START + i}" + node.vm.provider "virtualbox" do |vb| + vb.memory = 2048 + vb.cpus = 1 + vb.customize ["modifyvm", :id, "--natdnshostresolver1", "on"] + end + node.vm.provision "shell", path: "scripts/common.sh" + node.vm.provision "shell", path: "scripts/node.sh" + end + end + end +``` + +Hãy chia nhỏ những tập lệnh đang được chạy. Chúng ta có ba tập lệnh được liệt kê trong VAGRANTFILE để chạy trên các node cụ thể. + +`master.vm.provision "shell", path: "scripts/common.sh"` + +Tập lệnh trên sẽ tập trung vào việc chuẩn bị cho các nodes sẵn sàng, nó sẽ chạy trên 3 nodes của chúng ta và nó sẽ xoá tất cả các thành phần của Docker đang có và cài đặt lại Docker và ContainerD cũng như kubeadm, kubelet và kubectl. Tập lệnh này cũng sẽ cập nhật các gói phần mềm hiện có trên hệ thống. + +`master.vm.provision "shell", path: "scripts/master.sh"` + +Tập lệnh `master.sh` sẽ chỉ chạy trên control plane node, tập lệnh này sẽ tạo Kubernetes cluster sử dụng các lệnh kubeadm. Nó cũng sẽ chuẩn bị config context để truy cập vào cluster này, chúng ta sẽ nói đến sau đây. + +`node.vm.provision "shell", path: "scripts/node.sh"` + +Tập lệnh này chỉ đơn giản là lấy cấu hình do master tạo và kết nối các nodes của chúng ta vào Kubernetes cluster, quá trình kết nối này lại sử dụng kubeadmn và một tập lệnh khác có thể tìm thấy trong thư mục config. + +### Truy cập vào Kubernetes cluster + +Bây giờ chúng ta đã có hai cluster được triển khai, chúng ta có minikube cluster đã triển khai trong phần trước và có cluster 3 nodes mới mà chúng ta vừa triển khai trên VirtualBox. + +Ngoài ra, tệp cấu hình cũng giúp bạn có quyền truy cập trên máy của bạn, bạn đã chạy vagrant bao gồm cách chúng ta có thể truy cập vào cluster từ máy trạm của mình. + +Trước khi chúng ta nói đến điều đó, hãy nói qua về context. + +![](../../Days/Images/Day52_Kubernetes5.png) + +Context rất quan trọng, khả năng truy cập Kubernetes cluster từ máy tính để bàn hoặc máy tính xách tay của bạn là cần thiết. Có rất nhiều lựa chọn khác nhau và mọi người sử dụng các hệ điều hành khác nhau được mọi người sử dụng hàng ngày. + +Theo mặc định, ứng dụng Kubernetes CLI (kubectl) sử dụng C:\Users\username\.kube\config để lưu trữ các thông tin quan trọng của Kubernetes cluster, chẳng hạn như các endpoints và thông tin đăng nhập. Nếu bạn đã triển khai một cluster, bạn có thể thấy tệp này ở vị trí đó. Nhưng có thể bạn đang sử dụng node chính để chạy các lệnh kubectl của mình thông qua ssh hoặc các phương thức khác thì hi vọng bài viết này sẽ giúp bạn có thể kết nối từ máy trạm của mình. + +Sau đó, chúng ta cần lấy tệp kubeconfig từ cluster hoặc chúng ta cũng có thể lấy tệp này từ tệp cấu hình của mình sau khi triển khai, lấy nội dung của tệp này qua SCP hoặc chỉ cần mở một console session tới node chúng của bạn và sao chép xuống máy windows cục bộ. + +![](../../Days/Images/Day52_Kubernetes6.png) + +Sau đó, chúng ta sẽ lấy một bản sao của tệp cấu hình đó và chuyển nó đến vị trí `$HOME/.kube/config`. + +![](../../Days/Images/Day52_Kubernetes7.png) + +Bây giờ, từ máy trạm cục bộ của bạn, bạn có thể chạy `kubectl cluster-info` và `kubectl get nodes` để kiểm tra rằng bạn có quyền truy cập vào cluster của mình. + +![](../../Days/Images/Day52_Kubernetes8.png) + +Điều này không chỉ cho phép kết nối và điểu khiển từ máy windows của bạn mà còn cho phép chúng ta thực hiện một số chuyển tiếp cổng để truy cập các dịch vụ nhất định từ máy tính windows của chúng ta. + +Nếu bạn quan tâm đến cách quản lý nhiều cluster trên máy trạm của mình thì tôi có hướng dẫn chi tiết hơn [tại đây](https://vzilla.co.uk/vzilla-blog/building-the-home-lab-kubernetes-playground-part-6). + +Tôi đã thêm danh sách các bài blog hướng dẫn mà tôi đã thực hiện với các Kubernetes cluster khác nhau đang được triển khai. + +- [Kubernetes playground – How to choose your platform](https://vzilla.co.uk/vzilla-blog/building-the-home-lab-kubernetes-playground-part-1) +- [Kubernetes playground – Setting up your cluster](https://vzilla.co.uk/vzilla-blog/building-the-home-lab-kubernetes-playground-part-2) +- [Getting started with Amazon Elastic Kubernetes Service (Amazon EKS)](https://vzilla.co.uk/vzilla-blog/getting-started-with-amazon-elastic-kubernetes-service-amazon-eks) +- [Getting started with Microsoft Azure Kubernetes Service (AKS)](https://vzilla.co.uk/vzilla-blog/getting-started-with-microsoft-azure-kubernetes-service-aks) +- [Getting Started with Microsoft AKS – Azure PowerShell Edition](https://vzilla.co.uk/vzilla-blog/getting-started-with-microsoft-aks-azure-powershell-edition) +- [Getting started with Google Kubernetes Service (GKE)](https://vzilla.co.uk/vzilla-blog/getting-started-with-google-kubernetes-service-gke) +- [Kubernetes, How to – AWS Bottlerocket + Amazon EKS](https://vzilla.co.uk/vzilla-blog/kubernetes-how-to-aws-bottlerocket-amazon-eks) +- [Getting started with CIVO Cloud](https://vzilla.co.uk/vzilla-blog/getting-started-with-civo-cloud) +- [Minikube - Kubernetes Demo Environment For Everyone](https://vzilla.co.uk/vzilla-blog/project_pace-kasten-k10-demo-environment-for-everyone) + +### Những gì chúng ta sẽ đề cập trong loạt bài về Kubernetes + +- Kiến trúc Kubernetes +- Các câu lệnh kubectl +- Kubernetes YAML +- Kubernetes Ingress +- Kubernetes Services +- Helm Package Manager +- Lưu trữ liên tục - Persistent Storage +- Ứng dụng có trạng thái - Stateful Apps + +## Tài liệu tham khảo + +- [Kubernetes Documentation](https://kubernetes.io/docs/home/) +- [TechWorld with Nana - Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]](https://www.youtube.com/watch?v=X48VuDVv0do) +- [TechWorld with Nana - Kubernetes Crash Course for Absolute Beginners](https://www.youtube.com/watch?v=s_o8dwzRlu4) +- [Kunal Kushwaha - Kubernetes Tutorial for Beginners | What is Kubernetes? Architecture Simplified!](https://www.youtube.com/watch?v=KVBON1lA9N8) + +Hẹn gặp lại vào [ngày 53](day53.md) diff --git a/2022/vi/Days/day53.md b/2022/vi/Days/day53.md new file mode 100644 index 0000000..9ce5281 --- /dev/null +++ b/2022/vi/Days/day53.md @@ -0,0 +1,125 @@ +--- +title: '#90DaysOfDevOps - Tổng quan về Rancher - Thực hành - Ngày 53' +published: false +description: 90DaysOfDevOps - Tổng quan về Rancher - Thực hành +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048742 +--- + +## Tổng quan về Rancher - Thực hành + +Trong bài viết này, chúng ta sẽ đề cập tới Rancher, cho đến giờ, mọi thứ chúng ta làm đều dưới giao diện dòng lệnh sử dụng kubectl nhưng chứng ta có một số công cụ quản lý cluster với giao diện người dùng để các nhóm vận hành có thể quản lý các cluster một cách tốt hơn. + +Rancher theo như [trang web của họ](https://rancher.com/) + +> Rancher là phần mềm hoàn chỉnh dành cho các nhóm sử dụng containers. Nó giải quyết các vấn đề về vận hành và bảo mật trong việc quản lý các Kubernetes cluster trên bất kỳ cơ sở hạ tầng nào đồng thời cung cấp cho các nhóm DevOps các công cụ tích hợp để chạy các containerized workloads. + +Rancher cho phép chúng ta triển khai các cụm Kubernetes theo tiêu chuẩn của môi trường production và sau đó cung cấp xác thực tập trung, kiểm soát truy cập và khả năng quan sát. Tôi đã đề cập trong phần trước rằng có rất nhiều lựa chọn khi nói đến Kubernetes và nơi bạn nên hoặc có thể chạy chúng, khi sử dụng Rancher, việc chạy chúng ở đâu không quan trọng. + +### Triển khai Rancher + +Điều đầu tiên chúng ta cần làm là triển khai Rancher trên máy trạm cục bộ của mình, có một số cách và vị trí bạn có thể chọn để làm điều này. Đối với tôi, tôi muốn sử dụng máy tính cá nhân của mình và chạy Rancher bằng một docker container. Bằng cách chạy lệnh bên dưới, chúng ta sẽ kéo container image và sau đó có quyền truy cập vào giao diện người dùng của Rancher. + +Các phương pháp triển khai Rancher khác có tại [Rancher Quick-Start-Guide](https://rancher.com/docs/rancher/v2.6/en/quick-start-guide/deployment/) + +`sudo docker run -d --restart=unless-stopped -p 80:80 -p 443:443 --privileged rancher/rancher` + +Như bạn có thể thấy trong Docker Desktop của chúng ta, có một Rancher container đang chạy. + +![](../../Days/Images/Day53_Kubernetes1.png) + +### Truy cập Rancher UI + +Với container ở trên đang chạy, chúng ta có thể điều hướng tới nó thông qua một trang web. `https://localhost` sẽ hiển thị trang đăng nhập như ở dưới. + +![](../../Days/Images/Day53_Kubernetes2.png) + +Thực hiện theo các hướng dẫn dưới đây để có được mật khẩu cần thiết. Vì tôi đang sử dụng Windows nên tôi đã chọn bash vì chúng ta cần lệnh grep. + +![](../../Days/Images/Day53_Kubernetes3.png) + +Sau đó, chúng ta có thể lấy mật khẩu ở trên và đăng nhập, trang tiếp theo là nơi chúng ta có thể xác định mật khẩu mới. + +![](../../Days/Images/Day53_Kubernetes4.png) + +Khi chúng ta đã làm những điều trên, chúng ta sẽ đăng nhập và có thể thấy màn hình sau. Là một phần của triển khai Rancher, chúng ta cũng thấy một K3s cluster được tạo. + +![](../../Days/Images/Day53_Kubernetes5.png) + +### Sử dụng rancher + +Điều đầu tiên để chúng ta xem xét là K3S cluster được triển khai. Bạn có thể thấy như bên dưới để chúng ta có thể có được cái nhìn rõ ràng về những gì đang xảy ra bên trong cluster của chúng ta. Đây là triển khai mặc định và chúng ta chưa triển khai bất cứ thứ gì cho cluster này. Bạn có thể thấy nó được tạo thành từ 1 node và có 5 deployments. Sau đó, bạn cũng có thể thấy rằng có một số thông số về pods, cores và memory. + +![](../../Days/Images/Day53_Kubernetes6.png) + +Trên menu bên trái, chúng ta cũng có tab "Apps & Marketplace", điều này cho phép chúng ta chọn các ứng dụng mà chúng ta muốn chạy trên các cluster của mình, như đã đề cập, Rancher cung cấp cho chúng ta khả năng chạy hoặc quản lý các clusters khác nhau. Với marketplace, chúng ta có thể triển khai các ứng dụng của mình rất dễ dàng. + +![](../../Days/Images/Day53_Kubernetes7.png) + +Một điều khác cần đề cập tới là nếu bạn cần có quyền truy cập vào bất cứ cluster nào do Rancher quản lý, ở trên cùng bên phải, bạo có thể mở một kubectl shell tới cluster mà bạn chọn. + +![](../../Days/Images/Day53_Kubernetes8.png) + +### Tạo một cluster mới + +Trong hai ngày vừa qua, chúng ta đã tạo một minikube cluster và đã sử dụng Vagrant với VirtualBox để tạo một Kubernetes cluster gồm 3 nodes. Với Rancher, chúng ta cũng có thể tạo cluster. Trong [thư mục Rancher](../../../2022/Days/Kubernetes/Rancher/) bạn sẽ thấy các tệp vagrant tạo ra 3 nodes giống nhau nhưng không có các bước tạo Kubernetes cluster của chúng ta (chúng ta muốn Rancher làm điều này cho chúng ta) + +Tuy nhiên, chúng ta muốn cài đặt docker và cập nhật hệ điều hành nên bạn vẫn sẽ thấy `common.sh` chạy trên các nodes của chúng ta. Nó cũng sẽ căif đặt Kubeadm, Kubectl,... Nhưng nó sẽ không chạy các lệnh Kubeadm để tạo và nối các nodes của chúng ta thành một cluster. + +Chúng ta có thể điều hướng đến vị trì thư mục vagrant và chỉ cần chạy `vagrant up` và điều này sẽ bắt đầu quá trình tạo 3 máy ảo của chúng ta trong VirtualBox. + +![](../../Days/Images/Day53_Kubernetes9.png) + +Bây giờ chúng ta đã có các nodes hoặc máy ảo sẵn sàng, sau đó chúng ta có thể sử dụng Rancher để tạo Kubernetes cluster mới của mình. Màn hình đầu tiên để tạo cluster của bạn cung cấp cho bạn một số tuỳ chọn về vị trí của cluster, ví dụ như các dịch vụ Kubernetes được quản lý trên đám mây công cộng, vSphere hoặc lựa chọn khác. + +![](../../Days/Images/Day53_Kubernetes10.png) + +Chúng tôi sẽ chọn "custom" vì chúng ta không sử dụng một trong các nền tảng được tích hợp. Trang mở đầu là nơi bạn xác định tên cluster của mình (có ghi local ở dưới nhưng bạn không thể sử dụng local, cluster của chúng ta là vagrant). Bạn có thể xác định các phiên bản Kubernetes tại đây, nhà cung cấp mạng và một số tuỳ chọn cấu hình khác để khởi động và chạy cụm Kubernetes của bạn. + +![](../../Days/Images/Day53_Kubernetes11.png) + +Trang tiếp theo sẽ cung cấp cho bạn mã đăng ký cần được chạy trên từng node của bạn với các dịch vụ phù hợp để được kích hoạt. etcd, control-plane và worker. Đối với master node, chúng ta muốn có etcd và control-plan nên có thể nhìn lệnh bên dưới. + +![](../../Days/Images/Day53_Kubernetes12.png) + +``` +sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run rancher/rancher-agent:v2.6.3 --server https://10.0.0.1 --token mpq8cbjjwrj88z4xmf7blqxcfmwdsmq92bmwjpphdkklfckk5hfwc2 --ca-checksum a81944423cbfeeb92be0784edebba1af799735ebc30ba8cbe5cc5f996094f30b --etcd --controlplane +``` + +Nếu mạng được định cấu hình chính xác thì bạn sẽ nhanh chóng thấy thông tin sau trong bảng điều khiển rancher của ình, cho biết rằng master node đầu tiên hiện đang được đăng ký và cluster đang được tạo. + +![](../../Days/Images/Day53_Kubernetes13.png) + +Sau đó, chúng ta có thể lặp lại quy trình này với các worker nodes bằng lệnh sau và sau một lúc, bạn sẽ thiết lập và chạy các ứng dụng của mình và có khả năng tận dụng marketplace để triển khai các ứng dụng của mình. + +``` +sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run rancher/rancher-agent:v2.6.3 --server https://10.0.0.1 --token mpq8cbjjwrj88z4xmf7blqxcfmwdsmq92bmwjpphdkklfckk5hfwc2 --ca-checksum a81944423cbfeeb92be0784edebba1af799735ebc30ba8cbe5cc5f996094f30b --worker +``` + +![](../../Days/Images/Day53_Kubernetes14.png) + +Trong 3 ngày vừa qua, chúng ta đã sử dụng một số cách khác nhau để thiết lập và chạy với Kubernetes cluster, trong những ngày còn lại, chúng tôi sẽ xem xét khía cạnh ứng dụng của nền tảng và nó được cho là phần quan trọng nhất. Chúng ta sẽ xem xét các dịch vụ và khả năng cung cấp cũng như sử dụng dịch vụ của chúng ta trong Kubernetes. + +Tôi đã được nói rằng các yêu cầu xung quanh việc khởi động các rancher node yêu cầu các máy ảo phải có 4GB ram nếu không chúng sẽ gặp sự cố, tôi đã cập nhật vì các worker nodes của chúng ta chỉ có 2GB. + +### Những gì chúng ta sẽ đề cập trong loạt bài về Kubernetes + +- Kiến trúc Kubernetes +- Các câu lệnh kubectl +- Kubernetes YAML +- Kubernetes Ingress +- Kubernetes Services +- Helm Package Manager +- Lưu trữ liên tục - Persistent Storage +- Ứng dụng có trạng thái - Stateful Apps + +## Tài liệu tham khảo + +- [Kubernetes Documentation](https://kubernetes.io/docs/home/) +- [TechWorld with Nana - Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]](https://www.youtube.com/watch?v=X48VuDVv0do) +- [TechWorld with Nana - Kubernetes Crash Course for Absolute Beginners](https://www.youtube.com/watch?v=s_o8dwzRlu4) +- [Kunal Kushwaha - Kubernetes Tutorial for Beginners | What is Kubernetes? Architecture Simplified!](https://www.youtube.com/watch?v=KVBON1lA9N8) + +Hẹn gặp lại vào [ngày 54](day54.md) diff --git a/2022/vi/Days/day54.md b/2022/vi/Days/day54.md new file mode 100644 index 0000000..785f098 --- /dev/null +++ b/2022/vi/Days/day54.md @@ -0,0 +1,220 @@ +--- +title: '#90DaysOfDevOps - Triển khai ứng dụng Kubernetes - Ngày 54' +published: false +description: 90DaysOfDevOps - Triển khai ứng dụng Kubernetes +tags: 'devops, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048764 +--- + +## Triển khai ứng dụng Kubernetes + +Bây giờ, chúng ta cuối cùng cũng có thể triển khai một số ứng dụng vào trên các cluster của mình, một số người sẽ nói rằng đây là lý do Kubernetes tồn tại, để phân phối ứng dụng. + +Ý tưởng ở đây là chúng ta có thể lấy các container images của mình và triển khai chúng dưới dạng các pods trên Kubernetes cluster của chúng ta để tận dùng Kubernetes như một bộ điều phối container. + +### Trển khai ứng dụng trên Kubernetes + +Có một số cách để chúng ta có thể triển khai các ứng dụng của mình trên Kubernetes cluster, chúng ta sẽ đề cập đến hai trong số các cách tiếp cận phổ biến nhất là tệp YAML mà Heml charts. + +Chúng ta sẽ sử dụng minikube cluster cho các triển khai ứng dụng này. Chúng ta sẽ nhắc lại một số thành phần hoặc khối xây dựng đã đề cập tới trước đó của Kubernetes. + +Xuyên suốt tuần này và trong tuần về Container, chúng ta đã thảo luận về images và lợi ích của Kubernetes cũng như cách chúng ta có thể xử lý việc mở rộng quy mô khác dễ dàng bằng nền tảng này. + + +Trong bước đầu tiên này, chúng ta sẽ tạo một ứng dụng không trạng thái trong minikube cluster của mình. Chúng ta sẽ sử dụng một ứng dụng không trạng thái theo quy chẩn trong demo đầu tiên với Deployment của `nginx` sử dụng các pods của chúng ta, sau đó chúng ta cũng sẽ tạo một service cho phép chúng ta sử dụng một máy chủ web được phục vụ bởi nginx pod. Tất cả chúng sẽ nằm trong một namespace. + +![](../../Days/Images/Day54_Kubernetes1.png) + +### Tạo tệp YAML + +Trong demo đầu tiên, chúng ta muốn xác định mọi thứ chứng ta muốn làm bằng YAML, chúng ta có thể có nguyên một bài nói về YAML nhưng tôi sẽ lướt qua phần này và để lại một số tài nguyên ở cuối bài trình bày chi tiết về YAML. + +Chúng ta có thể tạo các tệp sau dưới dạng một tệp YAML hoặc chúng ta có thể chia nhỏ tệp này cho từng phần của ứng dụng của mình, ví dụ: đây có thể là các tệp riêng biệt dành cho namespace, deployement và service nhưng trong file này, như bên dưới, chúng ta sử dụng `---` đề tách các phần trong một tệp. Bạn có thể tìm thấy tệp này ở [đây](../../../2022/Days/Kubernetes/nginx-stateless-demo.yaml) + +```Yaml +apiVersion: v1 +kind: Namespace +metadata: + name: nginx + "labels": { + "name": "nginx" + } +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment + namespace: nginx +spec: + selector: + matchLabels: + app: nginx + replicas: 1 + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx + ports: + - containerPort: 80 +--- +apiVersion: v1 +kind: Service +metadata: + name: nginx-service + namespace: nginx +spec: + selector: + app: nginx-deployment + ports: + - protocol: TCP + port: 80 + targetPort: 80 +``` + +### Kiểm tra cluster của chúng ta + +Trước khi chúng ta triển khai bất cứ thứ gì, chúng ta chỉ cần đảm bảo rằng chúng ta không có một namespace nào là `nginx`. Có thể xác nhận việc này bằng cách chạy lệnh `kubectl get namespace` và như bạn có thể thấy dưới đây, chúng ta không có namespace nào là `nginx`. + +![](../../Days/Images/Day54_Kubernetes2.png) + +### Triển khai ứng dụng của chúng ta + +Bây giờ chúng ta đã sẵn sàng triển khai ứng dụng của mình lên minikube cluster, quy trình tương tự như thế này sẽ hoạt động trên bất kỳ Kubernetes cluster nào khác. + +Chúng ta cần điều hướng tới vị trị tệp YAML của mình và chạy lệnh `kubectl create -f nginx-stateless-demo.yaml`, sau đó bạn có thể thấy 3 đối tượng đã được tạo và chúng ta có một namespace, deployment và service. + +![](../../Days/Images/Day54_Kubernetes3.png) + +Hãy chạy lại lệnh để xem các namespaces có sẵn trong cluster của chúng ta `kubectl get namespace` và giờ bạn có thể thấy rằng chúng ta có namespace mới. + +![](../../Days/Images/Day54_Kubernetes5.png) + +Sau đó, nếu chúng ta kiểm tra các pods cho namespace sử dụng lệnh `kubectl get pods -n nginx` bạn sẽ thấy rằng chúng ta có 1 pod sẵn sàng và đang trong trạng thái chạy. + +![](../../Days/Images/Day54_Kubernetes4.png) + +Chúng ta cũng có thể kiểm tra service đã được tạo bằng câu lệnh `kubectl get service -n nginx` + +![](../../Days/Images/Day54_Kubernetes6.png) + +Cuối cùng, chúng ta có thể kiểm tra xem deployment ở đâu và làm thể nào chúng ta giữ được cấu hình mong muốn của mình. + +![](../../Days/Images/Day54_Kubernetes7.png) + +Ở trên có vài lệnh chúng ta cần biết nhưng cũng có thể sử dụng lệnh `kubectl get all -n nginx` để xem mọi thứ chúng ta đã triển khai với tệp YAML đó. + +![](../../Days/Images/Day54_Kubernetes8.png) + +Bạn có thể nhận thấy như ở trên rằng chúng ta cũng có một replicaset, trong deployment của mình, chúng ta cấu hình số replicas của image mà chúng ta muốn triển khai. Ban đầu nó được đặt là 1, nhưng nếu muốn nhanh chóng mở rộng quy mô ứng dụng của mình thì chúng ta có thể làm theo những cách sau. + +Chúng ta có thể chỉnh sửa tệp của mình sử dụng `kubectl edit deployment nginx-deployment -n nginx` sẽ mở trình soạn thảo văn bản trong terminal của bạn và cho phép bạn chỉnh sửa deployment của mình. + +![](../../Days/Images/Day54_Kubernetes9.png) + +Khi lưu thay đổi bằng trình soạn thảo của bạn trong terrminal, nếu không có sự cố nào và cú pháp chính xác đã được sửu dụng thì bạn sẽ thấy một số tài nguyên được triển khai trong namespace. + +![](../../Days/Images/Day54_Kubernetes10.png) + +Bạn cũng có thể thay đổi số lượng replicas sử dụng kubectl với câu lệnh `kubectl scale deployment nginx-deployment --replicas=10 -n nginx` + +![](../../Days/Images/Day54_Kubernetes11.png) + +Chúng ta có thể sử dụng phương pháp này để giảm quy mô ứng dụng của mình xuống 1 bằng cả 2 phương pháp. Tôi đã sử dụng lựa chọn chỉnh sửa nhưng bạn cũng có thể sử dụng lệnh `scale` như trên. + +![](../../Days/Images/Day54_Kubernetes12.png) + +Hy vọng rằng, bạn có thể thấy ở đây không chỉ việc triển khai ứng dụng siêu nhanh mà còn có khả năng tăng và giảm quy mô ứng dụng một cách nhanh chóng. Nếu đây là một máy chủ web, chúng ta có thể mở rộng quy mô khi có nhiều người sử dụng và giảm xuống khi tải được giảm. + +### Truy cập ứng dụng của chúng ta + +Nhưng làm thế nào để chúng ta có thể truy cập vào máy chủ web của mình? + +Nếu bạn nhìn vào service của chúng ta ở trên, bạn sẽ thấy không có sẵn IP nào ở bên ngoài để chúng ta có thể mở trình duyệt web và truy cập nó. Để truy cập được, chúng ta có một số lựa chọn. + +**ClusterIP** - IP mà bạn thấy là ClusterIP, IP này nằm trên mạng nội bộ của cluster, chỉ những thứ trong cluster mới có thể truy cập tới IP này. + +**NodePort** - Expose dịch vụ trên cùng một cổng của các nodes được chọn trong cluster sử dụng NAT. + +**LoadBalancer** -Tạo một bộ cân bằng tải bên ngoài trên đám mây hiện tại, chúng ta đang sử dụng minikube nhưng ví dụ nếu bạn đã xây dựng Kubernetes cluster của riêng mình trên VirtualBox, bạn cần triển khai một LoadBalancer chẳng hạn như metallb vào cluster của mình để có chức năng này. + +**Port-Forward** - Chúng ta cũng có khả năng chuyển tiếp cổng, cho phép bạn truy cập và tương tác với các process của Kubernetes cluster từ localhost. Lựa chọn này chỉ dành cho kiểm thử và tìm lỗi. + +Bây giờ chúng ta có một số lựa chọn dể chọn và Minikube có vài hạn chế hoặc khác biết so với một Kubernetes cluster thực tế. + +Chúng ta có thể chỉ cần chạy lệnh sau để chuyển tiếp cổng để truy cập ứng dụng từ máy trạm cục bộ của mình. + +`kubectl port-forward deployment/nginx-deployment -n nginx 8090:80` + +![](../../Days/Images/Day54_Kubernetes13.png) + +Lưu ý rằng khi bạn chạy lệnh trên, terminal đó sẽ không sử dụng được vì nó sẽ thực hiện việc chuyển tiếp cổng tới máy và cổng cục bộ của bạn. + +![](../../Days/Images/Day54_Kubernetes14.png) + +Bây giờ chúng ta sẽ xem xét cụ thể với Minikube về cách chúng ta có thể expose ứng dụng của mình. Chúng ta cũng có thể sử dụng minikube để tạo URL kết nối tới dịch vụ, [chi tiết cụ thể](https://minikube.sigs.k8s.io/docs/commands/service/) + +Trước hết, chúng ta xoá service của mình bằng cách sử dụng `kubectl delete service nginx-service -n nginx` + +Tiếp theo, chúng ta sẽ tạo một service mới sử dụng `kubectl expose deployment nginx-deployment --name nginx-service --namespace nginx --port=80 --type=NodePort` lưu ý ở đây rằng chúng ta sẽ sử dụng Expose và thay đổi type thành NodePort. + +![](../../Days/Images/Day54_Kubernetes15.png) + +Cuối cùng trong terminal mới chạy `minikube --profile='mc-demo' service nginx-service --URL -n nginx` để tạo một tunnel cho service của chúng ta. + +![](../../Days/Images/Day54_Kubernetes16.png) + +Mở trình duyệt và click vài liên kết trong terminal. + +![](../../Days/Images/Day54_Kubernetes17.png) + +### Helm + +Helm là một cách khác để chúng ta có thể triển khai các ứng dụng của mình. Được gọi là "Trình quản lý gói cho Kubernetes". Bạn có thể tìm hiểu thêm tại [đây](https://helm.sh/) + +Helm là trình quản lý gói cho Kubernetes. Helm có thể được coi như yum hoặc apt cho Kubernetes. Heml triển khai các charts mà bạn có thể coi như một ứng dụng được đóng gói. Đây là một blueprint cho các tài nguyên ứng dụng được định cấu hình trước của bạn. Các charts này có thể được triển khai dưới dạng một easy-to-use chart. Sau đó, bạn có thể triển khai một phiên bản khác của chart với một bộ cấu hình khác. + +Họ có một trang mà bạn có thể tham khảo tất cả các Heml charts có sẵ và đương nhiên, bạn có thể tạo biểu đồ của riêng mình. Tài liệu rất rõ ràng và ngắn gọn và không gây khó khăn như khi tôi bắt đầu nghe đến Helm. + +Việc thiết lập và cài đặt Heml cực kỳ đơn giản. Bạn có thể tìm thấy các tệp nhị phân và liên kết tải xuống tại đây cho hầu hết các hệ điều hành, bao gồm cả các thiết bị RaspberryPi arm64. + +Hoặc bạn có thể sử dụng tập lệnh cài đặt và có phiên bản mới nhất của Heml được tải xuống và cài đặt. + +```Shell +curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 + +chmod 700 get_helm.sh + +./get_helm.sh +``` + +Cuối cùng, cũng có tuỳ trọng sử dụng trình quản lý gói của hệ điều hành,homebrew cho mac, chocolatey cho windows, apt với Ubuntu/Debian, hoặc snap hay pkg. + +Cho tới nay, Helm dường như là cách tốt nhất để tải xuống và cài đặt các ứng dụng thử nghiệm khác nhau trong cluster của bạn. + +Một tài nguyên tốt ở đây là [ArtifactHUB](https://artifacthub.io/) giúp tìm, cài đặt và công khai các gói Kubernetes. Cũng xin nhắc tới [KubeApps](https://kubeapps.com/) với giao diện người dùng để hiển thị các helm charts. + +### Những gì chúng ta sẽ đề cập trong loạt bài về Kubernetes + +- Kiến trúc Kubernetes +- Các câu lệnh kubectl +- Kubernetes YAML +- Kubernetes Ingress +- Kubernetes Services +- Helm Package Manager +- Lưu trữ liên tục - Persistent Storage +- Ứng dụng có trạng thái - Stateful Apps + +## Tài liệu tham khảo + +- [Kubernetes Documentation](https://kubernetes.io/docs/home/) +- [TechWorld with Nana - Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]](https://www.youtube.com/watch?v=X48VuDVv0do) +- [TechWorld with Nana - Kubernetes Crash Course for Absolute Beginners](https://www.youtube.com/watch?v=s_o8dwzRlu4) +- [Kunal Kushwaha - Kubernetes Tutorial for Beginners | What is Kubernetes? Architecture Simplified!](https://www.youtube.com/watch?v=KVBON1lA9N8) + +Hẹn gặp lại vào [ngày 55](day55.md) diff --git a/2022/vi/Days/day55.md b/2022/vi/Days/day55.md new file mode 100644 index 0000000..a287b7b --- /dev/null +++ b/2022/vi/Days/day55.md @@ -0,0 +1,237 @@ +--- +title: '#90DaysOfDevOps - State và Ingress trong Kubernetes - Ngày 55' +published: false +description: 90DaysOfDevOps - State và Ingress trong Kubernetes +tags: 'DevOps, 90daysofdevops, learning' +cover_image: null +canonical_url: null +id: 1048779 +--- + +## State và Ingress trong Kubernetes + +Trong bài viết cuối cùng của Kubernetes, chúng ta sẽ xem xét State và Ingress. + +Mọi thứ chúng ta đã nói cho tới nay là về phi trạng thái (stateless), phi trạng thái có nghĩa rằng các ứng dụng của chúng ta không quan tâm tới mạng nào đang được sử dụng và không cần bất cứ bộ lưu trữ vĩnh viễn nào. Trong khi các ứng dụng có trạng thái ví dụ như cơ sở dữ liệu, để các ứng dụng như vậy hoạt động chính xác, bạn sẽ cần đảm bảo rằng các pods có thể liên lạc với nhau thông qua một định danh duy nhất không thay đổi (hostnames, IPs,...) Ví dụ về các ứng dụng có trạng thái bao gồm các MySQL clusters, Redis, Kafka, MongoDB và các ứng dụng khác. Về cơ bản, bất kỳ ứng dụng nào lưu trữ dữ liệu. + +### Ứng dụng có trạng thái + +StatefulSets đại diện cho một tập hợp các pods có định danh duy nhất, không đổ và hostnames ổn định mà Kubernetes sẽ duy trì bất kể chúng được lập lịch chạy ở đâu. Thông tin trạng thái và dữ liệu có khả năng phục hồi khác cho bất kỳ Stateful Set Pod cụ thể nào được duy trì trong persistent disk storage (bộ lưu trữ đĩa) được liên kết với StatefulSet. + +### Deployment với StatefulSet + +- Việc tạo ra các bản sao của ứng dụng có trạng thái khó khăn hơn. +- Việc tạo ra các bản sau của các pods trong một deployment (ứng dụng phi trạng thái) là giống hệt nhau và có thể hoán đổi. +- Tạo ra các pods theo thứ tự ngẫu nhiên với các giá trị băm ngẫu nhiên. +- Một Service cân bằng tải cho bất kỳ pod nào. + +Khi nói đến StatefulSets hoặc ứng dụng có trạng thái, những điều trên trở nên khó khăn hơn. + +- Không thể tạo hoặc xoá cùng một lúc. +- Không thể được truy cập một cách ngẫu nhiên. +- Các bản sao của pods không giống hệt nhau. + +Bạn có thể thấy một số thứ trong demo của chúng ta ngay sau đây về việc mỗi pods có một định danh riêng. Với ứng dụng phi trạng thái, bạn sẽ thấy các tên ngẫu nhiên, ví dụ: `app-7469bbb6d7-9mhxd` trong khi ứng dụng có trạng thái sẽ được sắp xếp nghiêm chỉnh hơn với `mongo-0` và khi được mở rộng quy mô, nó sẽ ạo một pod mới có tên là `mongo-1`. + +Các pods này được tạo từ cùng một cấu hình, nhưng chúng không thể hoán đổi cho nhau. Mỗi nhóm StatefulSet có một mã định danh cố định trong mọi lần lập lịch lại. Điều này là cần thiết bởi vì khi chúng ta yêu cầu các workloads có trạng thái ví dụ như cơ sở dữ liệu nơi chúng ta có các yêu cầu ghi và đọc, chúng ta không thể có hai pods cùng ghi một lúc mà không biết về việc này vì chúng sẽ khiến dữ liệu mất đi tính nhất quán. Chúng ta cần đảm bảo rằng chỉ một trong số các pods của chúng ta ghi vào cơ sở dữ liệu tại bất kỳ thời điểm nào, tuy nhiên, chúng tôi có thể có nhiều pods đọc dữ liệu đó. + +Mỗi pod trong StatefulSet sẽ có quyền truy cập vào persistent volume và một bản sao của cơ sở dữ liệu để đọc từ đó, và nó sẽ được cập nhật liên tự từ bản gốc. Một điều thú vị khác cần lưu ý là mỗi pod cũng sẽ lưu trữ trạng thái pod của nó trong persistent volume này, nếu sau đó `mongo-0` bị chết thì một pod mới sẽ được cung cấp và nó sẽ tiếp quản trạng thái pod được lưu trong bộ lưu trữ. + +TLDR; StatefulSets vs Deployments + +- Tên nhóm có thể được dự đoán = `mongo-0` +- DNS cố định +- Định danh pod - giữ nguyên State, giữ nguyên Role +- Tạo ra các bản sao của các ứng dụng có trạng thái rất phức tạp + - Có rất nhiều việc bạn phải làm: + - Định cấu hình cho các bản sao và đồng bộ hoá dữ liệu + - Tạo các bộ nhớ được chia sẻ + - Quản lý & sao lưu + +### Persistant Volumes | Claims | StorageClass + +Làm cách nào để duy trì dữ liệu trong Kubernetes? + +Chúng ta đã đề cập ở trên nhắc tới ứng dụng có trạng thái, chúng ta phải lưu trữ trạng thái ở đâu đó và đây là lúc cần có volume (một ổ đĩa), Kubernetes không cup cấp tính bền vững. + +Chúng ta yêu cầu lớp lưu trữ không phụ thuộc vào vòng đời của pod. Bộ lưu trữ này phải luôn có sẵn và truy cập được từ tất cả các Kubernetes nodes. Bộ lưu trữ cũng phải nằm ngoài Kubernetes cluster để có thể tồn tại độc lập ngay cả khi Kubernetes cluster gặp sự cố. + +### Persistent Volume + +- Một tài nguyên của cluster (như CPU và RAM) để lưu trữ dữ liệu +- Được tạo thông qua một tệp YAML +- Cần lưu trữ vật lý thực tế (Network-attached storage - NAS) +- Tích hợp từ bên ngoài vào Kubernetes cluster của bạn +- Bạn có thể có nhiều loại lưu trữ khi sử dụng các kho lưu trữ của mình +- PVs không được chia theo các namespaces +- Local storage khả dụng nhưng sẽ rành riêng cho một node trong cluster +- Cơ sở dữ liệu yêu cầu tính bền vững nên sử dụng lưu trữ từ xa (NAS) + +### Persistent Volume Claim + +Một persistent volume có thể sẵn có và đảm bảo tính sẵn sàng nhưng nếu nó không được claim bởi một ứng dụng, nó sẽ không được sử dụng. + +- Được tạo thông qua một tệp YAML +- Persistent Volume Claim được sử dụng trong cấu hình pod (thuộc tính volumes) +- PVCs ở trong cùng một namespace với pod +- Volume được mount vào pod +- Pods có thể có nhiều kiểu volume type khác nhau (ConfigMap, Secret, PVC) + +Một cách khác để nghĩ về PVs và PVCs như sau: +PVs được tạo bởi Kubernetes Admin +PVCs được tạo bởi người dùng hoặc nhà phát triển ứng dụng + +Cũng có 2 loại volumes khác mà chúng ta sẽ không đi vào chi tiết nhưng có được đề cập đến: + +### ConfigMaps | Secrets + +- Tệp cấu hình cho pod của bạn. +- Tệp certificate cho pod của bạn. + +### StorageClass + +- Được tạo thông qua tệp YAML +- Cung cấp Persistent Volumes một cách linh hoạt khi PVC yêu cầu nó +- Mỗi storage backend có provisioner của nó +- Storage bacned được định nghĩa bằng YAML (thông qua thuộc tính provisioner) +- Trìu tượng hoá các nhà cung cấp lưu trữ ở dưới +- Xác định các thông số cho lưu trữ đó + +### Tổng kết + +Trong bài viết ngày hôm qua, chúng ta đã được hướng dẫn cách tạo ứng dụng phi trạng thái, ở đây chúng ta sẽ làm điều tương tự nhưng sẽ triển khai workload có trạng thái sử dụng minikube cluster của mình. + +Một bản tóm tắt về các lệnh minikube mà chúng ta sẽ sử dụng để có các chứ năng và các addons để sử dụng tính bền bỉ là `minikube start --addons volumesnapshots,csi-hostpath-driver --apiserver-port=6443 --container-runtime=containerd -p mc-demo --Kubernetes-version=1.21.2` + +Lệnh này sử dụng CSI-hostpath-driver, thứ cung cấp cho chúng ta storageclass, thứ mà tôi sẽ trình bày sau. + +Ứng dụng được xây dựng xong sẽ trông như sau: + +![](../../Days/Images/Day55_Kubernetes1.png) + +Bạn có thể tìm thấy tệp cấu hình YAML cho ứng dụng này tại [pacman-stateful-demo.yaml](../../Days/Kubernetes/pacman-stateful-demo.yaml) + +### Cấu hình StorageClass + +Tuy nhiên, còn một bước nữa mà chúng ta nên chạy trước khi bắt đầu triển khai ứng dụng của mình và đó là đảm bảo storageclass của chúng ta (CSI-hostpath-sc) là lưu trữ mặc định của chúng ta. Trước tiên, chúng ta có thể kiểm tra điều này bằng cách chạy lệnh `kubectl get storageclass` nhưng minikube cluster sẽ hiển thị standard storageclass là mặc định, vì vậy chúng ta phải thay đổi điều đó bằng các lệnh dưới đây. + +Lệnh đầu tiên này sẽ đặt CSI-hostpath-sc storageclass là mặc định. + +`kubectl patch storageclass csi-hostpath-sc -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'` + +Lệnh này sẽ xoá chú thích mặc định khỏi standard StorageClass. + +`kubectl patch storageclass standard -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'` + +![](../../Days/Images/Day55_Kubernetes2.png) + +Chúng ta bắt đầu không có Pacman namespace trong cluster của mình `kubectl get namespace` + +![](../../Days/Images/Day55_Kubernetes3.png) + +Chúng ta sau đó triểu khai tệp YAML của mình. `kubectl create -f pacman-stateful-demo.yaml` bạn có thể thấy từ lệnh này, chúng ta đã tạo một số đối tượng trong Kubernetes cluster. + +![](../../Days/Images/Day55_Kubernetes4.png) + +Giờ đây chúng ta đã có namespace mới được tạo. + +![](../../Days/Images/Day55_Kubernetes5.png) + +Sao đó, như bạn có thể thấy trong ảnh tiếp theo và lệnh `kubectl get all -n pacman` sẽ cho thấy có một số điều đang xảy ra trong namespace của mình. Chúng ta có các pods chạy frontend với NodeJS, chúng ta có mongo chạy backend cơ sở dữ liệu. Có các service cho Pacman và mongo truy cập vào. Chúng ta có một deployment cho Pacman và một statefulset cho mongo. + +![](../../Days/Images/Day55_Kubernetes6.png) + +Chúng ta cũng có persistent volume và persistent volume claim, lệnh `kubectl get pv` sẽ cung cấp cho chúng ta persistent volumes trong mọi namespaces và lệnh `kubectl get pvc -n pacman` sẽ cung cấp cho chúng ta các persistent volume claims trong namespace pacman. + +![](../../Days/Images/Day55_Kubernetes7.png) + +### Chơi game | Ý tôi là truy cập vào ứng dụng siêu quan trọng của chúng ta + +Vì chúng ta đang sử dụng Minikube và như đã đề cập trong ứng dụng phi trạng thái, chúng ta có một số trở ngại cần vượt qua khi truy cập ứng dụng của mình. Tuy nhiên, chúng ta có quyền truy cập vào ingress hoặc load balancer trong cluster của mình, service được thiết lập để tự động nhận IP từ đó có thể truy cập từ bên ngoài (bạn có thể thấy điều này ở trên trong hình ảnh chụp các thành phần trong Pacman namespace). + +Đối với demo này, chúng ta sẽ sử dụng phương thức chuyển tiếp cổng để truy cập ứng dụng của mình. Bằng cách mở một terminal và chạy lệnh `kubectl port-forward svc/pacman 9090:80 -n pacman`. Mở trình duyệt và giờ đây, chúng ta sẽ có quyền truy cập vào ứng dụng của mình. Nếu bạn đang chạy ứng dụng này trên AWS thì nó cũng sẽ báo vị trí trên đám mây cũng như máy chủ chạy pod của bạn trong Kubernetes, một lần nữa bạn có thể nhìn lại và thấy tên pod này trên những ảnh chụp màn hình của chúng ta ở trên. + +![](../../Days/Images/Day55_Kubernetes8.png) + +Bây giờ chúng ta có thể chơi và ghi điểm số, sau đó nó sẽ được lưu trong cơ sở dữ liệu của chúng ta. + +![](../../Days/Images/Day55_Kubernetes9.png) + +OK, thât tuyệt nếu chúng ta có thể có một điểm số cao nhưng điều gì sẽ xảy ra nếu chúng ta xoá pod `mongo-0`? Bằng lệnh ``kubectl delete pod mongo-0 -n pacman` tôi có thể xoá nó và nếu bạn vẫn ở trong ứng dụng, bạn sẽ thấy điểm số sẽ không khả dụng ít nhất trong vài giây. + +![](../../Days/Images/Day55_Kubernetes10.png) + +Bây giờ, nếu tôi quay trở lại trò chơi của mình, tôi có thể tạo một trò chơi mới và xem điểm số cao nhất của mình. Tuy nhiên, cách duy nhất mà bạn có thể thực sự tin tôi là hãy tự mình thử và chia sẻ lên mạng xã hội về điểm số của mình! + +![](../../Days/Images/Day55_Kubernetes11.png) + +Với việc triển khai, chúng ta có thể mở rộng quy mô ứng dụng này bằng cách sử dụng các lệnh trong phần trước nhưng nếu bạn muốn tổ chức một bữa tiệc Pacman siêu to khổng lồ, bạn có thể mở rộng quy mô bằng cách sử dụng lệnh `kubectl scale deployment pacman --replicas=10 -n pacman` + +![](../../Days/Images/Day55_Kubernetes12.png) + +### Tìm hiểu về Ingress + +Trước khi chúng ta kết thúc phần về Kubernetes, tôi cũng muốn đề cập đến một phần kiến thức lớn của Kubernetes, đó là ingress. + +### Ingress là gì? + +Cho tới nay, với các ví dụ của chúng ta, chúng ta sử dụng port-forward (chuyển tiếp cổng) hoặc chúng ta sử dụng cách lệnh cụ thể trong minikube để có quyền truy cập vào các ứng dụng của mình, nhưng điều này sẽ không hoạt động trong môi trường sản xuất (production). Chúng ta sẽ muốn có một cách tốt hơn để truy cập các ứng dụng của mình trên quy mô lớn với nhiều người dùng. + +Chúng ta cũng đã nói về NodePort là một tuỳ chọn, nhưng một lần nữa, điều này chỉ dành cho mục đích thử nghiệm. + +Ingress cung cấp cho chúng ta một cách tốt hơn để expose ứng dụng của mình, điều này cho phép xác định các quy tắc định tuyến trong Kubernetes cluster của mình. + +Đối với ingress, chúng ta sẽ tạo một yêu cầu chuyển tiếp tới internal service của ứng dụng. + +### Khi nào bạn cần ingress? + +Nếu bạn đang sử dụng nhà cung cấp điện toán đám mây, một dịch vụ Kubernetes được quản lý rất có thể sẽ có tuỳ chọn ingress của họ hoặc họ sẽ cung cấp cho bạn tuỳ chọn cân bằng tải. Bạn không phải tự mình triển khai điều này, một trong những lợi ích của dịch vụ Kubernetes được quản lý. + +Nếu bạn đang chạy cluster của mình thì bạn sẽ cần cấu hình một entrypoint +If you are running your cluster then you will need to configure an entrypoint. + +### Cấu hình Ingress với Minikube + +Trên clsuter đang chạy của tôi với tên gọi mc-demo, tôi có thể chạy lệnh sau để bật tính năng ingress trên cluster của mình. + +`minikube --profile='mc-demo' addons enable ingress` + +![](../../Days/Images/Day55_Kubernetes13.png) + +Nếu chúng ta kiểm tra các namespace bây giờ, bạn sẽ thấy rằng chúng ta có một namespace mới với tên ingress-nginx `kubectl get ns` + +![](../../Days/Images/Day55_Kubernetes14.png) + +Bây giờ, chúng ta phải tạo cấu hình YAML cho ingress để truy cập dịch vụ pacman. Tôi đã thêm tệp này vào repository này [pacman-ingress.yaml](../../Days/Kubernetes/pacman-ingress.yaml) + +Sau đó, chúng ta có thể tạo nó trong ingress namespace của chúng ta với lệnh `kubectl create -f Pacman-ingress.yaml` + +![](../../Days/Images/Day55_Kubernetes15.png) + +Sau đó, nếu chúng ta chạy `kubectl get ingress -n Pacman` + +![](../../Days/Images/Day55_Kubernetes16.png) + +Sau đó, tôi được thông báo rằng vì chúng ta đang sử dụng minikube chạy trên WSL2 trong Windows nên chúng ta phải tạo minikube tunnel bằng cách sử dụng lệnh `minikube tunnel --profile=mc-demo` + +Nhưng tôi vẫn không thể truy cập vào 192.168.49.2 và chơi game Pacman của mình. + +Nếu bất kỳ ai có hoặc có thể làm cho điều này hoạt động trên Windows và WSL, tôi sẽ rất biết ơn nếu bạn bổ sung vào phần này. Tôi cảm thấy bài viết này sẽ giúp xác định nguyên nhân có thể khiến ingress không hoạt động với WSL [Configuring Ingress to run Minikube on WSL2 using Docker runtime](https://hellokube.dev/posts/configure-minikube-ingress-on-wsl2/) + +## Tài liệu tham khảo + +Nếu bạn có tài liệu MIỄN PHÍ mà bạn đã sử dụng thì vui lòng thêm chúng vào đây thông qua PR cho repository này và tôi sẽ sẵn lòng thêm chúng vào. + +- [Kubernetes StatefulSet simply explained](https://www.youtube.com/watch?v=pPQKAR1pA9U) +- [Kubernetes Volumes explained](https://www.youtube.com/watch?v=0swOh5C3OVM) +- [Kubernetes Ingress Tutorial for Beginners](https://www.youtube.com/watch?v=80Ew_fsV4rM) +- [Kubernetes Documentation](https://kubernetes.io/docs/home/) +- [TechWorld with Nana - Kubernetes Tutorial for Beginners [FULL COURSE in 4 Hours]](https://www.youtube.com/watch?v=X48VuDVv0do) +- [TechWorld with Nana - Kubernetes Crash Course for Absolute Beginners](https://www.youtube.com/watch?v=s_o8dwzRlu4) +- [Kunal Kushwaha - Kubernetes Tutorial for Beginners | What is Kubernetes? Architecture Simplified!](https://www.youtube.com/watch?v=KVBON1lA9N8) + +Bài viết này kết thúc phần Kubernetes của chúng ta, có rất nhiều nội dung khác mà chúng ta có thể trình bày về Kubernetes và 7 ngày chỉ giúp chúng ta có được kiến thức cơ bản, mọi người có thể xem qua [100DaysOfKubernetes](https://100daysofkubernetes.io/overview.html) để có một cái nhìn đầy đủ hơn. + +Tiếp theo, chúng ta sẽ xem xét đến Cơ sở hạ tầng dưới dạng mã (Infrastructure as Code - IaC) và tầm quan trọng của nó từ góc độ DevOps. + +Hẹn gặp lại vào [ngày 56](day56.md) diff --git a/2022/vi/README.md b/2022/vi/README.md index 4fe4756..6a38c20 100644 --- a/2022/vi/README.md +++ b/2022/vi/README.md @@ -72,33 +72,32 @@ Cách nhanh nhất để liên lạc với tôi là thông qua Twitter tại [@M ### Cách sử dụng Git hiệu quả -- [✔️] 📚 35 > [The Big Picture: Git - Version Control](Days/day35.md) -- [✔️] 📚 36 > [Installing & Configuring Git](Days/day36.md) -- [✔️] 📚 37 > [Gitting to know Git](Days/day37.md) +- [✔️] 📚 35 > [Bức tranh toàn cảnh: Git - Quản lý phiên bản](Days/day35.md) +- [✔️] 📚 36 > [Cài đặt & Cấu hình Git](Days/day36.md) +- [✔️] 📚 37 > [Giới thiệu về Git](Days/day37.md) - [✔️] 📚 38 > [Staging & Changing](Days/day38.md) -- [✔️] 📚 39 > [Viewing, unstaging, discarding & restoring](Days/day39.md) -- [✔️] 📚 40 > [Social Network for code](Days/day40.md) -- [✔️] 📚 41 > [The Open Source Workflow](Days/day41.md) - +- [✔️] 📚 39 > [Xem, unstaging, loại bỏ & khôi phục](Days/day39.md) +- [✔️] 📚 40 > [Mạng xã hội dành cho code](Days/day40.md) +- [✔️] 📚 41 > [Quy trình làm việc với mã nguồn mở](Days/day41.md) ### Containers -- [✔️] 🏗️ 42 > [The Big Picture: Containers](Days/day42.md) -- [✔️] 🏗️ 43 > [What is Docker & Getting installed](Days/day43.md) -- [✔️] 🏗️ 44 > [Docker Images & Hands-On with Docker Desktop](Days/day44.md) -- [✔️] 🏗️ 45 > [The anatomy of a Docker Image](Days/day45.md) +- [✔️] 🏗️ 42 > [Bức tranh toàn cảnh: Containers](Days/day42.md) +- [✔️] 🏗️ 43 > [Docker là gì & Cài đặt](Days/day43.md) +- [✔️] 🏗️ 44 > [Docker Images & Thực hành với Docker Desktop](Days/day44.md) +- [✔️] 🏗️ 45 > [Phân tích một Docker Image](Days/day45.md) - [✔️] 🏗️ 46 > [Docker Compose](Days/day46.md) - [✔️] 🏗️ 47 > [Docker Networking & Security](Days/day47.md) -- [✔️] 🏗️ 48 > [Alternatives to Docker](Days/day48.md) +- [✔️] 🏗️ 48 > [Các lựa chọn thay thế cho Docker](Days/day48.md) ### Kubernetes -- [✔️] ☸ 49 > [The Big Picture: Kubernetes](Days/day49.md) -- [✔️] ☸ 50 > [Choosing your Kubernetes platform](Days/day50.md) -- [✔️] ☸ 51 > [Deploying your first Kubernetes Cluster](Days/day51.md) -- [✔️] ☸ 52 > [Setting up a multinode Kubernetes Cluster](Days/day52.md) -- [✔️] ☸ 53 > [Rancher Overview - Hands On](Days/day53.md) -- [✔️] ☸ 54 > [Kubernetes Application Deployment](Days/day54.md) -- [✔️] ☸ 55 > [State and Ingress in Kubernetes](Days/day55.md) +- [✔️] ☸ 49 > [Bức tranh toàn cảnh: Kubernetes](Days/day49.md) +- [✔️] ☸ 50 > [Chọn nền tảng chạy Kubernetes](Days/day50.md) +- [✔️] ☸ 51 > [Triển khai Kubernetes cluster đầu tiên](Days/day51.md) +- [✔️] ☸ 52 > [Thiết lập Kubernetes cluster đa node](Days/day52.md) +- [✔️] ☸ 53 > [Tổng quan về Rancher - Thực hành](Days/day53.md) +- [✔️] ☸ 54 > [Triển khai ứng dụng Kubernetes](Days/day54.md) +- [✔️] ☸ 55 > [State và Ingress trong Kubernetes](Days/day55.md) ### Học cơ sở hạ tầng dưới dạng mã (Infrastructure as Code) diff --git a/2022/zh_cn/Days/day70.md b/2022/zh_cn/Days/day70.md index 1ae8bbe..0ebb1d9 100644 --- a/2022/zh_cn/Days/day70.md +++ b/2022/zh_cn/Days/day70.md @@ -1,115 +1,116 @@ --- -title: '#90DaysOfDevOps - The Big Picture: CI/CD Pipelines - Day 70' +title: '#90DaysOfDevOps - 概览:CI/CD 管道 - 第七十天' published: false -description: 90DaysOfDevOps - The Big Picture CI/CD Pipelines -tags: "devops, 90daysofdevops, learning" +description: 90DaysOfDevOps - 概览:CI/CD 管道 +tags: 'devops, 90daysofdevops, learning' cover_image: null canonical_url: null id: 1048836 --- -## The Big Picture: CI/CD Pipelines -A CI/CD (Continous Integration/Continous Deployment) Pipeline implementation is the backbone of the modern DevOps environment. +## 概览:CI/CD 管道 -It bridges the gap between development and operations by automating the build, test and deployment of applications. +CI/CD(持续集成/持续部署)管道实现的是现代DevOps环境的支柱。 -We covered a lot of this Continous mantra in the opening section of the challenge. But to reiterate: +它通过自动化应用程序的构建、测试和部署,将开发和运营联系了起来。 -Continous Integration (CI) is a more modern software development practice in which incremental code changes are made more frequently and reliabily. Automated build and test workflow steps triggered by Contininous Integration ensures that code changes being merged into the repository are reliable. +我们在挑战的开头部分介绍了很多这种持续不断的“咒语”。但这里要重申: -That code / Application is then delivered quickly and seamlessly as part of the Continuous Deployment process. +持续集成(CI)是一种更现代的软件开发实践活动,其想法是使代码增加、更改得更频繁、更可靠。由持续集成触发的自动化构建和测试工作流步骤确保了合并到仓库中的代码变更是可靠的。 -### The importance of CI/CD? +作为持续部署过程的一部分,这些代码/应用程序将快速无缝地交付。 -- Ship software quickly and efficiently -- Facilitates an effective process for getting applications to market as fast as possible -- A continous flow of bug fixes and new features without waiting months or years for version releases. +### CI/CD的重要特点? -The ability for developers to make small impactful changes regular means we get faster fixes and more features quicker. +- 快速高效地推送软件 +- 是帮助应用程序尽快推向市场的有效流程 +- 持续不断地进行错误修复和新功能添加,且无需等待数月或数年进行版本发布。 -### Ok, so what does this mean? +开发人员能够定期进行有影响力的小变更,这意味着我们可以更快地进行修复和添加更多功能。 -On [Day 5](day5.md) we covered a lot of the theory behind DevOps and as already mentioned here already that the CI/CD Pipeline is the backbone of the modern DevOps environment. +### 所以这意味着什么? -![DevOps](Images/Day5_DevOps8.png) +在[第五天](day05.md),我们介绍了DevOps背后的许多理论。正如这里已经提到的,CI/CD管道是现代DevOps环境的支柱。 -I want to reiterate some of the key points on this image above, now that we are a little further into our journey of learning the fundamentals of DevOps. +![DevOps](../../Days/Images/Day5_DevOps8.png) -We are referring to the software development life cycle (SDLC). +我想重申上图中的一些关键点,现在我们在学习DevOps基础知识的过程中又向前迈进了一步。 -The steps are usually written out within an infinity loop since it's a cycle that repeats forever. +我们指的是软件开发生命周期(SDLC)。 -The steps in the cycle are, developers write the **code** then it gets **built** or all compiled together then it's **tested** for bugs then it's **deployed** into production where it's used (**Operated**) by end users or customers then we **monitor** and collect feedback and finally we **plan** improvements around that feedback **rinse and repeat**. +这些步骤通常是在无限循环中的,因为这是一个一直重复的循环流程。 -### Let's go a little deeper into CI/CD +这个循环中的步骤是,开发人员编写**代码code**,然后将其**构建built**或全部编译在一起,对其中的bugs进行**测试tested**,接着是**部署deployed**到最终用户或客户(**操作/使用operated**)的产品中,然后我们**监控monitor**并收集反馈,最后我们围绕收集到的反馈进行**计划plan**并**重复rinse and repeat**。 -### CI +### 更深入了解 CI/CD -CI is a development practice that requires developers to integrate code into a shared repository several times a day. +### CI 持续集成 -When the code is written and pushed to a repository like github or gitlab that's where the magic begins. +CI是一种开发实践活动,要求开发人员每天多次将代码集成到共享的仓库中。 -![](Images/Day70_CICD1.png) +当代码被编写并推送(pushed)到Github或GitLab这样的仓库时,魔法就开始了。 -The code is verified by an automated build which allows teams or the project owner to detect any problems early. +![](../../Days/Images/Day70_CICD1.png) -![](Images/Day70_CICD2.png) +代码通过一个自动化构建活动进行验证,这个步骤可以使团队或项目所有者尽早发现问题。 -From there the code is analysed and given a series of automated tests three examples are +![](../../Days/Images/Day70_CICD2.png) -- Unit testing this tests the individual units of the source code -- Validation testing this makes sure that the software satisfies or fits the intended use -- Format testing this checks for syntax and other formatting errors - -These tests are created as a workflow and then are run every time you push to the master branch so pretty much every major development team has some sort of CI/CD workflow and remember on a development team the new code could be coming in from teams all over the world at different times of the day from developers working on all sorts of different projects it's more efficient to build an automated workflow of tests that make sure that everyone is on the same page before the code is accepted. It would take much longer for a human to do this each time. +提交的代码会被分析,并给出了一系列自动化测试,这里给出三个例子 -![](Images/Day70_CICD3.png) +- 单元测试,测试源代码的各个单元 +- 验证测试,确保软件满足或适合预期用途 +- 格式测试,检查语法和其他格式错误 -Once we have our tests complete and they are successful then we can compile and send to our repository. For example I am using Docker Hub but this could be anywhere that then gets leveraged for the CD aspect of the pipeline. +这些测试是作为一个工作流被创建,每当你推送到主分支(master branch)时都会运行。所以几乎每个主要的开发团队都有某种CI/CD工作流。请记住,在开发团队中,新代码可能会在一天中的不同时间从世界各地的团队、从事各种不同项目的开发人员那里传入到测试的工作流程中。因此确保在接受代码之前每个人都在同一页面上。人们每次都要花更长的时间才能做到这一点。 -![](Images/Day70_CICD4.png) +![](../../Days/Images/Day70_CICD3.png) -So this process is obviously very much down to the software development process, we are creating our application, adding, fixing bugs etc and then updating our source control and versioning that whilst also testing. +一旦我们完成了测试并通过,我们就可以编译它们并将其发送到我们的仓库。例如,我正在使用Docker Hub,但这可能是任何可以用于管道的CD(持续部署)的地方。 -Moving onto the next phase is the CD element which in fact more and more is what we generally see from any off the shelf software, I would argue that we will see a trend that if we get our software from a vendor such as Oracle or Microsoft we will consume that from a Docker Hub type repository and then we would use our CD pipelines to deploy that into our environments. +![](../../Days/Images/Day70_CICD4.png) -### CD +因此,这个过程很大程度上取决于软件开发过程,我们会是正在创建我们的应用程序,添加功能,修复bugs等,然后更新我们的源代码控制和版本控制,同时进行测试。 -Now we have our tested version of our code and we are ready to deploy out into the wild and like I say, the Software vendor will run through this stage but I strongly believe this is how we will all deploy the off the shelf software we require in the future. +进入下一阶段是CD,这更多的是我们通常在任何现成的软件中看到的。如果我们需要从Oracle或Microsoft等供应商那里获得软件,我们将看到一种趋势,从Docker Hub这类仓库中获取这些软件,然后使用我们的CD管道将其部署到我们的环境中。 -It is now time to release our code into an environment. This is going to include Production but also likely other environments as well such as staging. +### CD 持续部署 -![](Images/Day70_CICD5.png) +现在我们已经有了代码的测试版本,我们已经准备好进行广泛的部署,正如我上文所说,软件供应商将完成这一阶段,但我坚信这就是我们未来部署所需现成软件的方式。 -Our next step at least on Day 1 of v1 of the software deployment is we need to make sure we are pulling the correct code base to the correct environment. This could be pulling elements from the software repository (DockerHub) but it is more than likely that we are also pulling additional configuration from maybe another code repository, the configuration for the application for example. In the diagram below we are pulling the latest release of the software from DockerHub and then we are releasing this to our environments whilst possibly picking up configuration from a Git repository. Our CD tool is performing this and pushing everything to our environment. +是时候将我们的代码发布到环境中了。这将包括生产环境,但也可能包括其他环境,如暂存staging。 -It is most likely that this is not done at the same time. i.e we would go to a staging environment run against this with our own configuration make sure things are correct and this could be a manual step for testing or it could again be automated (lets go with automated) before then allowing this code to be deployed into production. +![](../../Days/Images/Day70_CICD5.png) -![](Images/Day70_CICD6.png) +至少在软件部署v1的第一天,我们的下一步是需要确保将正确的代码库拉到(pull)正确的环境中。这可能是从软件仓库(DockerHub)中提取元素,也是可能从另一个代码仓库中提取额外的配置,例如应用程序的配置。在下图中,我们从DockerHub获取最新版本的软件,然后将其发布到我们的环境中,同时可能从Git仓库中获取配置。我们的CD工具正在执行此操作,并将所有内容推送到我们的环境中。 -Then after this when v2 of the application comes out we rinse and repeat the steps this time we ensure our application + configuration is deployed to staging ensure everything is good and then we deploy to production. +这些很可能不是同时进行的。例如,我们将使用我们的配置进入一个针对此运行的暂存环境,以确保事情是正确的,这可能是一个手动测试步骤,也可能之前实现自动化且可以将此代码部署到生产中。 -### Why use CI/CD? +![](../../Days/Images/Day70_CICD6.png) -I think we have probably covered the benefits a number of time but it is because it automates things that otherwise would have to be done manually it finds small problems before it sneaks into the main codebase, you can probably imagine that if you push bad code out to your customers then you're going to have a bad time! +然后,当应用程序的v2版本发布时,我们重复这些步骤,这一次我们确保我们的应用程序+配置被部署到暂存staging,确保一切正常,然后我们部署到生产中。 -It also helps to prevent something that we call technical debt which is the idea that since the main code repos are constantly being built upon over time then a shortcut fix taken on day one is now an exponentially more expensive fix years later because now that band-aid of a fix would be so deeply intertwined and baked into all the code bases and logic. +### 为什么使用CI/CD? -### Tooling +我觉得我们已经多次介绍了这些好处,但正是因为它将原来需要手动完成的事情进行自动化了,它可以在加入到主代码库之前发现了一些小问题。你可能可以想象,如果你把坏代码推送给你的客户,这会是多么糟糕! -Like with other sections we are going to get hands on with some of the tools that achieve the CI/CD pipeline process. +这也有助于防止我们称之为技术债务(technical debt)的事情,即由于主要代码仓库是随着时间推移而不断构建的,那么有一天做的小修复在几年后会变得更加昂贵,因为现在修复的地方将彻底融入到所有的代码仓库和逻辑中。 -I think it is also important to note that not all tools have to do both CI and CD, We will take a look at ArgoCD which you guessed it is great at the CD element of deploying our software to a Kubernetes cluster. But something like Jenkins can work across many different platforms. +### 工具 -My plan is to look at the following: +与其他章节一样,我们将实操一些CI/CD管道流程的工具。 -- Jenkins -- ArgoCD -- GitHub Actions +我认为同样重要的是要注意,并不是所有的工具都必须有CI和CD的功能。我们将看看ArgoCD,你可能觉得它在部署软件到Kubernetes集群的CD功能方面非常出色。而像Jenkins这类工具则可以在许多不同的平台上工作。 -## Resources +我计划关注以下内容: +- Jenkins +- ArgoCD +- GitHub Actions + +## 相关资料 - [Jenkins is the way to build, test, deploy](https://youtu.be/_MXtbjwsz3A) +- [Introduction to Jenkins](https://www.edx.org/course/introduction-to-jenkins) - [Jenkins.io](https://www.jenkins.io/) - [ArgoCD](https://argo-cd.readthedocs.io/en/stable/) - [ArgoCD Tutorial for Beginners](https://www.youtube.com/watch?v=MeU5_k9ssrs) @@ -118,4 +119,4 @@ My plan is to look at the following: - [GitHub Actions](https://www.youtube.com/watch?v=R8_veQiYBjI) - [GitHub Actions CI/CD](https://www.youtube.com/watch?v=mFFXuXjVgkU) -See you on [Day 71](day71.md) +[第七十一天](day71.md)见。 diff --git a/2022/zh_cn/Days/day71.md b/2022/zh_cn/Days/day71.md index 869db6d..842c9e9 100644 --- a/2022/zh_cn/Days/day71.md +++ b/2022/zh_cn/Days/day71.md @@ -1,99 +1,102 @@ --- -title: '#90DaysOfDevOps - What is Jenkins? - Day 71' +title: '#90DaysOfDevOps - 什么是 Jenkins? - 第七十一天' published: false -description: 90DaysOfDevOps - What is Jenkins? -tags: "devops, 90daysofdevops, learning" +description: 90DaysOfDevOps - 什么是 Jenkins? +tags: 'DevOps, 90daysofdevops, learning' cover_image: null canonical_url: null id: 1048745 --- -## What is Jenkins? -Jenkins is a continous integration tool that allows continous development, test and deployment of newly created code. +## 什么是 Jenkins? -There are two ways we can achieve this with either nightly builds or continous development. The first option is that our developers are developing throughout the day on their tasks and come the end of the set day they push their changes to the source code repository. Then during the night we run our unit tests and build of the software. This could be deemed as the old way to integrate all code. +Jenkins是一个持续集成工具,允许对新建的代码进行持续开发、测试和部署。 -![](Images/Day71_CICD1.png) +可以通过夜间构建或持续开发两种方法来实现这些。第一种选择是,我们的开发人员全天都在开发他们的任务,并在当天结束时将他们的更改推送(push)到源代码仓库。然后在晚上,我们运行单元测试并构建软件。这可以被认为是集成所有代码的旧方法。 -The other option and the preferred way is that our developers are still committing their changes to source code, then when that code commit has been made there is a build process kicked off continously. +![](../../Days/Images/Day71_CICD1.png) -![](Images/Day71_CICD2.png) +另一种选择也是首选的方式是,我们的开发人员仍在提交他们对源代码的更改,然后当代码提交完成后,构建过程就会不断启动。 -The above methods means that with distributed developers across the world we don't have a set time each day where we have to stop committing our code changes. This is where Jenkins comes in to act as that CI server to control those tests and build processes. +![](../../Days/Images/Day71_CICD2.png) -![](Images/Day71_CICD3.png) +上述方法意味着,对于分布在世界各地的开发人员来说,我们每天都没有固定的时间来停止提交代码更改。这就是Jenkins作为CI服务器来控制这些测试和构建过程。 -I know we are talking about Jenkins here but I also want to add a few more to maybe look into later on down the line to get an understanding why I am seeing Jenkins as the overall most popular, why is that and what can the others do over Jenkins. +![](../../Days/Images/Day71_CICD3.png) -- TravisCI - A hosted, distributed continous integration service used to build and test software projects hosted on GitHub. - -- Bamboo - Can run multiple builds in parallel for faster compilation, built in functionality to connect with repositories and has build tasks for Ant, Maven. - -- Buildbot - is an open-source framework for automating software build, test and release processes. It is written in Python and supports distributed, parallel execution of jobs across multiple platforms. - -- Apache Gump - Specific to Java projects, designed with the aim to build and test those Java projects every night. ensures that all projects are compatible at both API and functionality level. +虽然我们在这里讨论的是Jenkins,但我也想补充一些内容(也许以后会深入研究),了解为什么我会认为Jenkins是最受欢迎的,为什么会得出这样的判断,以及其他人能在Jenkins上做些什么。 -Because we are now going to focus on Jenkins - Jenkins is again open source like all of the above tools and is an automation server written in Java. It is used to automate the software development process via continous integration adn faciliates continous delivery. +- TravisCI,一种托管的分布式持续集成服务,用于构建和测试托管在GitHub上的软件项目。 +- Bamboo,可以并行运行多个构建以实现更快的编译,内置与仓库连接的功能,并具有Ant和Maven的构建任务功能。 +- Buildbot,是一个用于自动化软件构建、测试和发布过程的开源框架。它是用Python编写的,支持跨多个平台分布式并行执行作业。 +- ApacheGump,专门针对Java项目,旨在每晚构建和测试这些Java项目。确保所有项目在API和功能级别都兼容。 -### Features of Jenkins +因为我们现在将重点关注Jenkins - Jenkins和上述所有工具一样,是开源的,是一个用Java编写的自动化服务器。它用于通过持续集成实现软件开发过程的自动化,并有助于持续交付。 -As you can probably expect Jenkins has a lot of features spanning a lot of areas. +### Jenkins的特性 -**Easy Installation** - Jenkins is a self contained java based program ready to run with packages for Windows, macOS and Linux operating systems. +正如你所料,Jenkins有很多功能,涵盖了很多领域。 -**Easy Configuration** - Easy setup and configured via a web interface which includes error checks and built in help. +**易于安装** - Jenkins是一个独立的基于java的程序,可以与Windows、macOS和Linux操作系统上的软件包一起运行。 -**Plug-ins** - Lots of plugins available in the Update Centre and integrates with many tools in the CI / CD toolchain. +**轻松配置** - 通过内置的web界面进行设置和配置,包括错误检查和内置帮助。 -**Extensible** - In addition to the Plug-Ins available, Jenkins can be extended by that plugin architecture which provides nearly infinite options for what it can be used for. +**插件** - 更新中心提供了许多插件,并与CI/CD工具链中的许多工具集成。 -**Distributed** - Jenkins easily distributes work across multiple machines, helping to speed up builds, tests and deployments across multiple platforms. +**可扩展** - 除了可用的插件外,Jenkins还可以通过该插件架构进行扩展,该架构为它的用途提供了几乎无限的选项。 -### Jenkins Pipeline +**分布式** - Jenkins可以轻松地在多台机器上分配工作,有助于加快跨多个平台的构建、测试和部署。 -You will have seen this pipeline but used in a much broader and we have not spoken about specific tools. +### Jenkins的管道pipeline -You are going to be committing code to Jenkins, which then will build out your application, with all automated tests, it will then release and deploy that code when each step is completed. Jenkins is what allows for the automation of this process. -![](Images/Day71_CICD4.png) +你将会了解这个管道流程,但其还有更广的使用范围,而且我们还没有谈到具体的工具。 -### Jenkins Architecture +您会把代码提交给Jenkins,然后它将构建您的应用程序,并进行所有自动化测试。接着在每个步骤都完成后进行代码的发布和部署。Jenkins是实现这一过程自动化的工具。 -First up and not wanting to reinvent the wheel, the [Jenkins Documentation](https://www.jenkins.io/doc/developer/architecture/) is always the place to start but I am going to put down my notes and learnings here as well. +![](../../Days/Images/Day71_CICD4.png) -Jenkins can be installed on many different operating systems, Windows, Linux and macOS but then also the ability to deploy as a Docker container and within Kubernetes. [Installing Jenkins](https://www.jenkins.io/doc/book/installing/) +### Jenkins的架构 -As we get into this we will likely take a look at installing Jenkins within a minikube cluster simulating the deployment to Kubernetes. But this will depend on the scenarios we put together throughout the rest of the section. +首先,不要想着重新造轮子,[Jenkins Documentation](https://www.jenkins.io/doc/developer/architecture/)总是一个开始开始学习的地方,但我也会在这里记下我的笔记和学到的东西。 -Let's now break down the image below. +Jenkins可以被安装在许多不同的操作系统上,包括Windows、Linux和macOS,也可以作为Docker容器或在Kubernetes中进行部署。[安装Jenkins](https://www.jenkins.io/doc/book/installing/) -Step 1 - Developers commit changes to the source code repository. +当我们开始使用它时,我们可能会考虑在一个minikube集群中安装Jenkins,模拟部署到Kubernetes的过程。但这将取决于我们在本节后续部分中所设置的场景。 -Step 2 - Jenkins checks the repository at regular intervals and pulls any new code. +现在让我们对下面的图像进行拆解。 -Step 3 - A build server then builds the code into an executable, in this example we are using maven as a well known build server. Another area to cover. +步骤1 - 开发人员提交对源代码仓库的更改。 -Step 4 - If the build fails then feedback is sent back to the developers. +步骤2 - Jenkins定期检查仓库并提取(pull)任何新代码。 -Step 5 - Jenkins then deploys the build app to the test server, in this example we are using selenium as a well known test server. Another area to cover. +步骤3 - 构建服务器(build server)将代码构建为可执行文件,在本例中,我们使用maven作为构建服务器。 -Step 6 - If the test fails then feedback is passed to the developers. +步骤4 - 如果构建失败,则将反馈发送至开发人员。 -Step 7 - If the tests are successful then we can release to production. +步骤5 - Jenkins将构建应用程序部署到测试服务器,在本例中,我们使用selenium作为测试服务器。 -This cycle is continous, this is what allows applications to be updated in minutes vs hours, days, months, years! +步骤6 - 如果测试失败,则将反馈发送至开发人员。 -![](Images/Day71_CICD5.png) +步骤7 - 如果测试成功,那么我们可以将它们发布到生产中。 -There is a lot more to the architecture of Jenkins if you require it, they have a master-slave capability, which enables a master to distribute the tasks to slave jenkins environment. +这个周期是连续的,这使得应用程序可以在几分钟内更新,而不是几小时、几天、几个月和几年! -For reference with Jenkins being open source, there are going to be lots of enterprises that require support, CloudBees is that enterprise version of Jenkins that brings support and possibly other functionality for the paying enterprise customer. +![](../../Days/Images/Day71_CICD5.png) + +Jenkins的架构中还有很多东西,如果你需要的话,它们有主从功能,可以使主机能够将任务分配到从属Jenkins环境。 + +参考开源的Jenkins,将会有很多企业需要支持,CloudBees是Jenkins的企业版本,为付费企业客户提供支持,并可能提供其他功能。 An example of this in a customer is Bosch, you can find the Bosch case study [here](https://assets.ctfassets.net/vtn4rfaw6n2j/case-study-boschpdf/40a0b23c61992ed3ee414ae0a55b6777/case-study-bosch.pdf) -I am going to be looking for a step by step example of an application that we can use to walkthrough using Jenkins and then also use this with some other tools. +I am going to be looking for a step-by-step example of an application that we can use to walk through using Jenkins and then also use this with some other tools. -## Resources +博世Bosch就是一个例子,您可以在这里找到博世案例研究(https://assets.ctfassets.net/vtn4rfaw6n2j/case-study-boschpdf/40a0b23c61992ed3ee414ae0a55b6777/case-study-bosch.pdf) + +我将通过一个应用程序示例,我们可以一步步地使用Jenkins进行实操,然后也可以将它与其他一些工具一起使用。 + +## 相关资料 - [Jenkins is the way to build, test, deploy](https://youtu.be/_MXtbjwsz3A) - [Jenkins.io](https://www.jenkins.io/) @@ -104,4 +107,4 @@ I am going to be looking for a step by step example of an application that we ca - [GitHub Actions](https://www.youtube.com/watch?v=R8_veQiYBjI) - [GitHub Actions CI/CD](https://www.youtube.com/watch?v=mFFXuXjVgkU) -See you on [Day 72](day72.md) +[第七十二天](day72.md)见。 diff --git a/2023.md b/2023.md index 19b3485..f13dc86 100644 --- a/2023.md +++ b/2023.md @@ -86,10 +86,10 @@ Or contact us via Twitter, my handle is [@MichaelCade1](https://twitter.com/Mich ### Secrets Management -- [] 🕵 35 > [](2023/day35.md) -- [] 🕵 36 > [](2023/day36.md) -- [] 🕵 37 > [](2023/day37.md) -- [] 🕵 38 > [](2023/day38.md) +- [✔️] 🕵 35 > [Understanding the Importance of Secrets Management](2023/day35.md) +- [✔️] 🕵 36 > [Securing Secrets with HashiCorp Vault](2023/day36.md) +- [✔️] 🕵 37 > [Working with HashiCorp Vault's Secrets Engines](2023/day37.md) +- [✔️] 🕵 38 > [Increase the Security Posture of Your Organization with Dynamic Credentials](2023/day38.md) - [] 🕵 39 > [](2023/day39.md) - [] 🕵 40 > [](2023/day40.md) - [] 🕵 41 > [](2023/day41.md) @@ -107,59 +107,60 @@ Or contact us via Twitter, my handle is [@MichaelCade1](https://twitter.com/Mich ### AWS - [✔️] ☁️ 49 > [AWS Cloud Overview](2023/day49.md) -- [✔️] ☁️ 50 > [Get a Free Tier Account & Enable Billing Alarms](2023/day50.md) +- [✔️] ☁️ 50 > [Create Free Tier Account & Enable Billing Alarms](2023/day50.md) - [✔️] ☁️ 51 > [Infrastructure as Code (IaC) and CloudFormation](2023/day51.md) -- [] ☁️ 52 > [](2023/day52.md) -- [] ☁️ 53 > [](2023/day53.md) -- [] ☁️ 54 > [](2023/day54.md) -- [] ☁️ 55 > [](2023/day55.md) +- [✔️] ☁️ 52 > [Identity and Access Management (IAM)](2023/day52.md) +- [✔️] ☁️ 53 > [AWS Systems Manager](2023/day53.md) +- [✔️] ☁️ 54 > [AWS CodeCommit](2023/day54.md) +- [✔️] ☁️ 55 > [AWS CodePipeline](2023/day55.md) ### Red Hat OpenShift - [✔️] ⛑️ 56 > [What does Red Hat OpenShift bring to the party? An Overview](2023/day56.md) -- [] ⛑️ 57 > [Understanding the OpenShift Architecture + Spinning up an instance](2023/day57.md) -- [] ⛑️ 58 > [](2023/day58.md) -- [] ⛑️ 59 > [](2023/day59.md) -- [] ⛑️ 60 > [](2023/day60.md) -- [] ⛑️ 61 > [](2023/day61.md) -- [] ⛑️ 62 > [](2023/day62.md) +- [✔️] ⛑️ 57 > [Understanding the OpenShift Architecture, Installation Methods and Process](2023/day57.md) +- [✔️] ⛑️ 58 > [Deploying Red Hat OpenShift on VMware vSphere](2023/day58.md) +- [✔️] ⛑️ 59 > [Deploying applications and getting a handle on Security Constraints Context (SCC)](2023/day59.md) +- [✔️] ⛑️ 60 > [Looking at OpenShift Projects - Creation, Configuration and Governance](2023/day60.md) +- [✔️] ⛑️ 61 > [Understanding Authentication, Role-Based Access Control (RBAC) and Auditing in Red Hat OpenShift: Control and Secure Your Cluster](2023/day61.md) +- [✔️] ⛑️ 62 > [Compliance and Vulnerability Scanning provided by Red Hat OpenShift Operators](2023/day62.md) ### Databases -- [] 🛢 63 > [An introduction to databases](2023/day63.md) -- [] 🛢 64 > [Querying data in databases](2023/day64.md) -- [] 🛢 65 > [Backing up and restoring databases](2023/day65.md) -- [] 🛢 66 > [High availability and disaster recovery](2023/day66.md) -- [] 🛢 67 > [Performance tuning](2023/day67.md) -- [] 🛢 68 > [Database security](2023/day68.md) -- [] 🛢 69 > [Monitoring and troubleshooting database issues](2023/day69.md) +- [✔️] 🛢 63 > [An introduction to databases](2023/day63.md) +- [✔️] 🛢 64 > [Querying data in databases](2023/day64.md) +- [✔️] 🛢 65 > [Backing up and restoring databases](2023/day65.md) +- [✔️] 🛢 66 > [High availability and disaster recovery](2023/day66.md) +- [✔️] 🛢 67 > [Performance tuning](2023/day67.md) +- [✔️] 🛢 68 > [Database security](2023/day68.md) +- [✔️] 🛢 69 > [Monitoring and troubleshooting database issues](2023/day69.md) ### Serverless -- [] 👩🏿‍💻 70 > [](2023/day70.md) -- [] 👩🏿‍💻 71 > [](2023/day71.md) -- [] 👩🏿‍💻 72 > [](2023/day72.md) -- [] 👩🏿‍💻 73 > [](2023/day73.md) -- [] 👩🏿‍💻 74 > [](2023/day74.md) -- [] 👩🏿‍💻 75 > [](2023/day75.md) -- [] 👩🏿‍💻 76 > [](2023/day76.md) +- [✔️] 👩🏿‍💻 70 > [What is Serverless?](2023/day70.md) +- [✔️] 👩🏿‍💻 71 > [Serverless Compute](2023/day71.md) +- [✔️] 👩🏿‍💻 72 > [Serverless Storage](2023/day72.md) +- [✔️] 👩🏿‍💻 73 > [Serverless APIs](2023/day73.md) +- [✔️] 👩🏿‍💻 74 > [Serverless Orchestration](2023/day74.md) +- [✔️] 👩🏿‍💻 75 > [Serverless & Well Architected](2023/day75.md) +- [✔️] 👩🏿‍💻 76 > [Serverless - Beyond the Basics](2023/day76.md) ### Service Mesh -- [] 🧩 77 > [](2023/day77.md) -- [] 🧩 78 > [](2023/day78.md) -- [] 🧩 79 > [](2023/day79.md) -- [] 🧩 80 > [](2023/day80.md) -- [] 🧩 81 > [](2023/day81.md) -- [] 🧩 82 > [](2023/day82.md) -- [] 🧩 83 > [](2023/day83.md) +- [✔️] 🧩 77 > [Let's break down a Service Mesh](2023/day77.md) +- [✔️] 🧩 78 > [Install and Test a Service Mesh](2023/day78.md) +- [✔️] 🧩 79 > [Comparing Different Service Meshes](2023/day79.md) +- [✔️] 🧩 80 > [Traffic Engineering Basics](2023/day80.md) +- [✔️] 🧩 81 > [Observability in your Mesh](2023/day81.md) +- [✔️] 🧩 82 > [Securing your microservices](2023/day82.md) +- [✔️] 🧩 83 > [Sidecar or Sidecar-less? Enter Ambient Mesh](2023/day83.md) ### Engineering for Day 2 Ops -- [] 👷🏻‍♀️ 84 > [](2023/day84.md) -- [] 👷🏻‍♀️ 85 > [](2023/day85.md) -- [] 👷🏻‍♀️ 86 > [](2023/day86.md) -- [] 👷🏻‍♀️ 87 > [](2023/day87.md) -- [] 👷🏻‍♀️ 88 > [](2023/day88.md) -- [] 👷🏻‍♀️ 89 > [](2023/day89.md) + +- [] 👷🏻‍♀️ 84 > [Writing an API - What is an API?](2023/day84.md) +- [] 👷🏻‍♀️ 85 > [Queues, Queue workers and Tasks (Asynchronous architecture)](2023/day85.md) +- [] 👷🏻‍♀️ 86 > [Designing for Resilience, Redundancy and Reliability](2023/day86.md) +- [] 👷🏻‍♀️ 87 > [Zero Downtime Deployments](2023/day87.md) +- [] 👷🏻‍♀️ 88 > [Monitoring, Alerting and On-Call](2023/day88.md) +- [] 👷🏻‍♀️ 89 > [Oops: When something goes wrong - Post Mortems](2023/day89.md) - [] 👷🏻‍♀️ 90 > [](2023/day90.md) diff --git a/2023/.DS_Store b/2023/.DS_Store new file mode 100644 index 0000000..65cd630 Binary files /dev/null and b/2023/.DS_Store differ diff --git a/2023/day04.md b/2023/day04.md index 08fb585..2c7b04d 100644 --- a/2023/day04.md +++ b/2023/day04.md @@ -62,11 +62,11 @@ As Cybersecurity grows in importance with all the big brands getting hit there i The above abstract was taken from the top resource listed at the end of the post. -**Red**, **Blue**, **Yellow** are primary colours, combine them and we start to understand where the other colours or secondary colours come into play, again really great explanation in that first link. +**Red**, **Blue**, **Yellow** are primary colours, combine them and we start to understand where the other colours or secondary colours come into play, again a really great explanation in that first link. -- **Purple Team** - The special team! If the you take **Blue** and **Red** you get **Purple**. If you integrate defence with offence and you collaborate and share knowledge between the teams you overall provide a better posture throughout. +- **Purple Team** - The special team! If you take **Blue** and **Red** you get **Purple**. If you integrate defence with offence and you collaborate and share knowledge between the teams you overall provide a better posture throughout. -- **Green Team** - Feedback loop, the **Green** team are going to take insights from the **Blue** team and work closely with the **Yellow** team to be more effcient. Mix **Blue** and **Green** and what do you **get**? +- **Green Team** - Feedback loop, the **Green** team are going to take insights from the **Blue** team and work closely with the **Yellow** team to be more efficient. Mix **Blue** and **Green** and what do you **get**? - **Orange Team** - Much like the **Green** team working with the **Blue** team for feedback, the **Orange** team works with the **Red** team and pass on what they have learnt to the **Yellow** team to build better security into their code. @@ -80,3 +80,6 @@ Also please add any additional resources. - [Introducing the InfoSec colour wheel — blending developers with red and blue security teams.](https://hackernoon.com/introducing-the-infosec-colour-wheel-blending-developers-with-red-and-blue-security-teams-6437c1a07700) + +See you on [Day 5](day05.md). + diff --git a/2023/day05.md b/2023/day05.md index 34cc89f..ad4535c 100644 --- a/2023/day05.md +++ b/2023/day05.md @@ -53,3 +53,4 @@ The reason I am raising this is that security never stops, the growth of Open-So - [IBM - The 3 A's of Open Source Security](https://www.youtube.com/watch?v=baZH6CX6Zno) - [Log4j (CVE-2021-44228) RCE Vulnerability Explained](https://www.youtube.com/watch?v=0-abhd-CLwQ) +See you on [Day 6](day06.md). diff --git a/2023/day09.md b/2023/day09.md index 0a104be..2f19753 100644 --- a/2023/day09.md +++ b/2023/day09.md @@ -129,4 +129,4 @@ By default SonarCloud comes with a default quality gate “Sonar way”. You can - [How to create Quality gates on SonarQube](https://www.youtube.com/watch?v=8_Xt9vchlpY) - [Source Code of the repo I used for SAST implementation](https://github.com/prateekjaindev/nodejs-todo-app-demo) -In the next part [Day 10](day10.md), we will discuss Software Composition Analysis (SCA). \ No newline at end of file +In the next part [Day 10](day10.md), we will discuss Software Composition Analysis (SCA). diff --git a/2023/day16.md b/2023/day16.md index b3fa95c..c26ff82 100644 --- a/2023/day16.md +++ b/2023/day16.md @@ -92,3 +92,5 @@ It contains the example I used in this article + a fuzz test that triggers a fai - - [Fuzzing in Go by Valentin Deleplace, Devoxx Belgium 2022](https://www.youtube.com/watch?v=Zlf3s4EjnFU) - [Write applications faster and securely with Go by Cody Oss, Go Day 2022](https://www.youtube.com/watch?v=aw7lFSFGKZs) + +See you on [Day 17](day17.md). diff --git a/2023/day17.md b/2023/day17.md index cf7f191..0f40367 100644 --- a/2023/day17.md +++ b/2023/day17.md @@ -240,3 +240,5 @@ There are many tools that can help us in fuzzy testing our web applications, bot [Fuzzing Session: Finding Bugs and Vulnerabilities Automatically](https://youtu.be/DSJePjhBN5E) [Fuzzing the CNCF Landscape](https://youtu.be/zIyIZxAZLzo) + +See you on [Day 18](day18.md). diff --git a/2023/day18.md b/2023/day18.md index 8a9fc53..be63a03 100644 --- a/2023/day18.md +++ b/2023/day18.md @@ -24,3 +24,5 @@ As with all other tools part of DevSecOps pipeline DAST should not be the only s - https://github.com/zaproxy/zaproxy - https://www.arachni-scanner.com/ - https://owasp.org/www-project-devsecops-guideline/latest/02b-Dynamic-Application-Security-Testing + +See you on [Day 19](day19.md). diff --git a/2023/day19.md b/2023/day19.md index 0bdb802..74f5fe6 100644 --- a/2023/day19.md +++ b/2023/day19.md @@ -1,26 +1,31 @@ -# IAST (Interactive Application Security Testing) +# IAST (Interactive Application Security Testing) IAST is a type of security testing tool that is designed to identify vulnerabilities in web applications and help developers fix them. It works by injecting a small agent into the application's runtime environment and monitoring its behaviour in real-time. This allows IAST tools to identify vulnerabilities as they occur, rather than relying on static analysis or simulated attacks. -IAST works through software instrumentation, or the use of instruments to monitor an application as it runs and gather information about what it does and how it performs. IAST solutions instrument applications by deploying agents and sensors in running applications and continuously analyzing all application interactions initiated by manual tests, automated tests, or a combination of both to identify vulnerabilities in real time Instrumentation. -IAST agent is running inside the application and monitoring for known attack patterns. As it is part of the application, it can monitor traffic between different components (either as classic MVC deployments and in microservices deployment). +IAST works through software instrumentation, or the use of instruments to monitor an application as it runs and gather information about what it does and how it performs. IAST solutions instrument applications by deploying agents and sensors in running applications and continuously analyzing all application interactions initiated by manual tests, automated tests, or a combination of both to identify vulnerabilities in real time Instrumentation. +IAST agent is running inside the application and monitoring for known attack patterns. As it is part of the application, it can monitor traffic between different components (either as classic MVC deployments and in microservices deployment). + +## For IAST to be used, there are few prerequisites. -## For IAST to be used, there are few prerequisites. - Application should be instrumented (inject the agent). - Traffic should be generated - via manual or automated tests. Another possible approach is via DAST tools (OWASP ZAP can be used for example). -## Advantages +## Advantages + One of the main advantages of IAST tools is that they can provide detailed and accurate information about vulnerabilities and how to fix them. This can save developers a lot of time and effort, as they don't have to manually search for vulnerabilities or try to reproduce them in a testing environment. IAST tools can also identify vulnerabilities that might be missed by other testing methods, such as those that require user interaction or are triggered under certain conditions. Testing time depends on the tests used (as IAST is not a standalone system) and with faster tests (automated tests) can be included into CI/CD pipelines. It can be used to detect different kind of vulnerabilities and due to the nature of the tools (it looks for “real traffic only) false positives/negatives findings are relatively rear compared to other testing types. IAST can be used in two flavours - as a typical testing tool and as real-time protection (it is called RAST in this case). Both work at the same principles and can be used together. ## There are several disadvantages of the technology as well: + - It is relatively new technology so there is not a lot of knowledge and experience both for the security teams and for the tools builders (open-source or commercial). - The solution cannot be used alone - something (or someone) should generate traffic patterns. It is important that all possible endpoints are queried during the tests. - Findings are based on traffic. This is especially true if used for testing alone - if there is no traffic to a portion of the app / site it would not be tested so no findings are going to be generated. - Due to need of instrumentation of the app, it can be fairly complex, especially compared to the source scanning tools (SAST or SCA). There are several different IAST tools available, each with its own features and capabilities. + ## Some common features of IAST tools include: + - Real-time monitoring: IAST tools monitor the application's behaviour in real-time, allowing them to identify vulnerabilities as they occur. - Vulnerability identification: IAST tools can identify a wide range of vulnerabilities, including injection attacks, cross-site scripting (XSS), and cross-site request forgery (CSRF). - Remediation guidance: IAST tools often provide detailed information about how to fix identified vulnerabilities, including code snippets and recommendations for secure coding practices. @@ -29,5 +34,8 @@ There are several different IAST tools available, each with its own features and IAST tools can be a valuable addition to a developer's toolkit, as they can help identify and fix vulnerabilities in real-time, saving time and effort. If you are a developer and are interested in using an IAST tool, there are many options available, so it is important to research and compare different tools to find the one that best fits your needs. ## Tool example + There are almost no open-source tools on the market. Example is the commercial tool: Contrast Community Edition (CE) - Fully featured version for 1 app and up to 5 users (some Enterprise features disabled). Contrast CE supports Java and .NET only. Can be found here - https://www.contrastsecurity.com/contrast-community-edition + +See you on [Day 20](day20.md). diff --git a/2023/day2-ops-code/README.md b/2023/day2-ops-code/README.md new file mode 100644 index 0000000..d411428 --- /dev/null +++ b/2023/day2-ops-code/README.md @@ -0,0 +1,44 @@ +# Getting started + +This repo expects you to have a working kubernetes cluster already setup and +available with kubectl + +We expect you already have a kubernetes cluster setup and available with kubectl and helm. + +I like using (Civo)[https://www.civo.com/] for this as it is easy to setup and run clusters + +The code is available in this folder to build/push your own images if you wish - there are no instructions for this. + +## Start the Database +```shell +kubectl apply -f database/mysql.yaml +``` + + +## deploy the day1 - sync +```shell +kubectl apply -f synchronous/k8s.yaml +``` + +Check your logs +```shell +kubectl logs deploy/generator + +kubectl logs deploy/requestor +``` + +## deploy nats +helm repo add nats https://nats-io.github.io/k8s/helm/charts/ +helm install my-nats nats/nats + +## deploy day 2 - async +```shell +kubectl apply -f async/k8s.yaml +``` + +Check your logs +```shell +kubectl logs deploy/generator + +kubectl logs deploy/requestor +``` diff --git a/2023/day2-ops-code/async/generator/Dockerfile b/2023/day2-ops-code/async/generator/Dockerfile new file mode 100644 index 0000000..9e40abf --- /dev/null +++ b/2023/day2-ops-code/async/generator/Dockerfile @@ -0,0 +1,17 @@ +# Set the base image to use +FROM golang:1.17-alpine + +# Set the working directory inside the container +WORKDIR /app + +# Copy the source code into the container +COPY . . + +# Build the Go application +RUN go build -o main . + +# Expose the port that the application will run on +EXPOSE 8080 + +# Define the command that will run when the container starts +CMD ["/app/main"] diff --git a/2023/day2-ops-code/async/generator/go.mod b/2023/day2-ops-code/async/generator/go.mod new file mode 100644 index 0000000..85f3760 --- /dev/null +++ b/2023/day2-ops-code/async/generator/go.mod @@ -0,0 +1,17 @@ +module main + +go 1.20 + +require ( + github.com/go-sql-driver/mysql v1.7.0 + github.com/nats-io/nats.go v1.24.0 +) + +require ( + github.com/golang/protobuf v1.5.3 // indirect + github.com/nats-io/nats-server/v2 v2.9.15 // indirect + github.com/nats-io/nkeys v0.3.0 // indirect + github.com/nats-io/nuid v1.0.1 // indirect + golang.org/x/crypto v0.6.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect +) diff --git a/2023/day2-ops-code/async/generator/go.sum b/2023/day2-ops-code/async/generator/go.sum new file mode 100644 index 0000000..89ed185 --- /dev/null +++ b/2023/day2-ops-code/async/generator/go.sum @@ -0,0 +1,32 @@ +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/nats-io/jwt/v2 v2.3.0 h1:z2mA1a7tIf5ShggOFlR1oBPgd6hGqcDYsISxZByUzdI= +github.com/nats-io/nats-server/v2 v2.9.15 h1:MuwEJheIwpvFgqvbs20W8Ish2azcygjf4Z0liVu2I4c= +github.com/nats-io/nats-server/v2 v2.9.15/go.mod h1:QlCTy115fqpx4KSOPFIxSV7DdI6OxtZsGOL1JLdeRlE= +github.com/nats-io/nats.go v1.24.0 h1:CRiD8L5GOQu/DcfkmgBcTTIQORMwizF+rPk6T0RaHVQ= +github.com/nats-io/nats.go v1.24.0/go.mod h1:dVQF+BK3SzUZpwyzHedXsvH3EO38aVKuOPkkHlv5hXA= +github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8= +github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4= +github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff --git a/2023/day2-ops-code/async/generator/main.go b/2023/day2-ops-code/async/generator/main.go new file mode 100644 index 0000000..49234e3 --- /dev/null +++ b/2023/day2-ops-code/async/generator/main.go @@ -0,0 +1,100 @@ +package main + +import ( + "database/sql" + "fmt" + _ "github.com/go-sql-driver/mysql" + nats "github.com/nats-io/nats.go" + "math/rand" + "time" +) + +func generateAndStoreString() (string, error) { + // Connect to the database + db, err := sql.Open("mysql", "root:password@tcp(mysql:3306)/mysql") + if err != nil { + return "", err + } + defer db.Close() + + // Generate a random string + // Define a string of characters to use + characters := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + + // Generate a random string of length 10 + randomString := make([]byte, 64) + for i := range randomString { + randomString[i] = characters[rand.Intn(len(characters))] + } + + // Insert the random number into the database + _, err = db.Exec("INSERT INTO generator_async(random_string) VALUES(?)", string(randomString)) + if err != nil { + return "", err + } + + fmt.Printf("Random string %s has been inserted into the database\n", string(randomString)) + return string(randomString), nil +} + +func main() { + err := createGeneratordb() + if err != nil { + panic(err.Error()) + } + + nc, _ := nats.Connect("nats://my-nats:4222") + defer nc.Close() + + nc.Subscribe("generator", func(msg *nats.Msg) { + s, err := generateAndStoreString() + if err != nil { + print(err) + } + nc.Publish("generator_reply", []byte(s)) + nc.Publish("confirmation", []byte(s)) + }) + + nc.Subscribe("confirmation_reply", func(msg *nats.Msg) { + stringReceived(string(msg.Data)) + }) + // Subscribe to the queue + // when a message comes in call generateAndStoreString() then put the string on the + // reply queue. also add a message onto the confirmation queue + + // subscribe to the confirmation reply queue + // when a message comes in call + + for { + time.Sleep(1 * time.Second) + } + +} + +func createGeneratordb() error { + db, err := sql.Open("mysql", "root:password@tcp(mysql:3306)/mysql") + if err != nil { + return err + } + defer db.Close() + + // try to create a table for us + _, err = db.Exec("CREATE TABLE IF NOT EXISTS generator_async(random_string VARCHAR(100), seen BOOLEAN, requested BOOLEAN)") + + return err +} + +func stringReceived(input string) { + + // Connect to the database + db, err := sql.Open("mysql", "root:password@tcp(mysql:3306)/mysql") + if err != nil { + print(err) + } + defer db.Close() + + _, err = db.Exec("UPDATE generator_async SET requested = true WHERE random_string = ?", input) + if err != nil { + print(err) + } +} diff --git a/2023/day2-ops-code/async/k8s.yaml b/2023/day2-ops-code/async/k8s.yaml new file mode 100644 index 0000000..e77dd6c --- /dev/null +++ b/2023/day2-ops-code/async/k8s.yaml @@ -0,0 +1,69 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: requestor +spec: + replicas: 1 + selector: + matchLabels: + app: requestor + template: + metadata: + labels: + app: requestor + spec: + containers: + - name: requestor + image: heyal/requestor:async + imagePullPolicy: Always + ports: + - containerPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: requestor-service +spec: + selector: + app: requestor + ports: + - name: http + protocol: TCP + port: 8080 + targetPort: 8080 + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: generator +spec: + replicas: 1 + selector: + matchLabels: + app: generator + template: + metadata: + labels: + app: generator + spec: + containers: + - name: generator + image: heyal/generator:async + imagePullPolicy: Always + ports: + - containerPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: generator-service +spec: + selector: + app: generator + ports: + - name: http + protocol: TCP + port: 8080 + targetPort: 8080 + type: ClusterIP diff --git a/2023/day2-ops-code/async/requestor/Dockerfile b/2023/day2-ops-code/async/requestor/Dockerfile new file mode 100644 index 0000000..9e40abf --- /dev/null +++ b/2023/day2-ops-code/async/requestor/Dockerfile @@ -0,0 +1,17 @@ +# Set the base image to use +FROM golang:1.17-alpine + +# Set the working directory inside the container +WORKDIR /app + +# Copy the source code into the container +COPY . . + +# Build the Go application +RUN go build -o main . + +# Expose the port that the application will run on +EXPOSE 8080 + +# Define the command that will run when the container starts +CMD ["/app/main"] diff --git a/2023/day2-ops-code/async/requestor/go.mod b/2023/day2-ops-code/async/requestor/go.mod new file mode 100644 index 0000000..85f3760 --- /dev/null +++ b/2023/day2-ops-code/async/requestor/go.mod @@ -0,0 +1,17 @@ +module main + +go 1.20 + +require ( + github.com/go-sql-driver/mysql v1.7.0 + github.com/nats-io/nats.go v1.24.0 +) + +require ( + github.com/golang/protobuf v1.5.3 // indirect + github.com/nats-io/nats-server/v2 v2.9.15 // indirect + github.com/nats-io/nkeys v0.3.0 // indirect + github.com/nats-io/nuid v1.0.1 // indirect + golang.org/x/crypto v0.6.0 // indirect + google.golang.org/protobuf v1.30.0 // indirect +) diff --git a/2023/day2-ops-code/async/requestor/go.sum b/2023/day2-ops-code/async/requestor/go.sum new file mode 100644 index 0000000..89ed185 --- /dev/null +++ b/2023/day2-ops-code/async/requestor/go.sum @@ -0,0 +1,32 @@ +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= +github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/nats-io/jwt/v2 v2.3.0 h1:z2mA1a7tIf5ShggOFlR1oBPgd6hGqcDYsISxZByUzdI= +github.com/nats-io/nats-server/v2 v2.9.15 h1:MuwEJheIwpvFgqvbs20W8Ish2azcygjf4Z0liVu2I4c= +github.com/nats-io/nats-server/v2 v2.9.15/go.mod h1:QlCTy115fqpx4KSOPFIxSV7DdI6OxtZsGOL1JLdeRlE= +github.com/nats-io/nats.go v1.24.0 h1:CRiD8L5GOQu/DcfkmgBcTTIQORMwizF+rPk6T0RaHVQ= +github.com/nats-io/nats.go v1.24.0/go.mod h1:dVQF+BK3SzUZpwyzHedXsvH3EO38aVKuOPkkHlv5hXA= +github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8= +github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4= +github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= diff --git a/2023/day2-ops-code/async/requestor/main.go b/2023/day2-ops-code/async/requestor/main.go new file mode 100644 index 0000000..a3a09b6 --- /dev/null +++ b/2023/day2-ops-code/async/requestor/main.go @@ -0,0 +1,108 @@ +package main + +import ( + "database/sql" + "errors" + "fmt" + _ "github.com/go-sql-driver/mysql" + nats "github.com/nats-io/nats.go" + "time" +) + +func storeString(input string) error { + // Connect to the database + db, err := sql.Open("mysql", "root:password@tcp(mysql:3306)/mysql") + defer db.Close() + // Insert the random number into the database + _, err = db.Exec("INSERT INTO requestor_async(random_string) VALUES(?)", input) + if err != nil { + return err + } + + fmt.Printf("Random string %s has been inserted into the database\n", input) + return nil +} + +func getStringFromDB(input string) error { + // see if the string exists in the db, if so return nil + // if not, return an error + db, err := sql.Open("mysql", "root:password@tcp(mysql:3306)/mysql") + defer db.Close() + result, err := db.Query("SELECT * FROM requestor_async WHERE random_string = ?", input) + if err != nil { + return err + } + + for result.Next() { + var randomString string + err = result.Scan(&randomString) + if err != nil { + return err + } + if randomString == input { + return nil + } + } + + return errors.New("string not found") +} + +func main() { + + err := createRequestordb() + if err != nil { + panic(err.Error()) + } + // setup a goroutine loop calling the generator every minute, saving the result in the DB + + nc, _ := nats.Connect("nats://my-nats:4222") + defer nc.Close() + + ticker := time.NewTicker(60 * time.Second) + quit := make(chan struct{}) + go func() { + for { + select { + case <-ticker.C: + nc.Publish("generator", []byte("")) + case <-quit: + ticker.Stop() + return + } + } + }() + + nc.Subscribe("generator_reply", func(msg *nats.Msg) { + err := storeString(string(msg.Data)) + if err != nil { + print(err) + } + }) + + nc.Subscribe("confirmation", func(msg *nats.Msg) { + err := getStringFromDB(string(msg.Data)) + if err != nil { + print(err) + } + nc.Publish("confirmation_reply", []byte(string(msg.Data))) + }) + // create a goroutine here to listen for messages on the queue to check, see if we have them + + for { + time.Sleep(10 * time.Second) + } + +} + +func createRequestordb() error { + db, err := sql.Open("mysql", "root:password@tcp(mysql:3306)/mysql") + if err != nil { + return err + } + defer db.Close() + + // try to create a table for us + _, err = db.Exec("CREATE TABLE IF NOT EXISTS requestor_async(random_string VARCHAR(100))") + + return err +} diff --git a/2023/day2-ops-code/buildpush.sh b/2023/day2-ops-code/buildpush.sh new file mode 100755 index 0000000..5a25b3f --- /dev/null +++ b/2023/day2-ops-code/buildpush.sh @@ -0,0 +1,2 @@ +docker build ./async/requestor/ -f async/requestor/Dockerfile -t heyal/requestor:async && docker push heyal/requestor:async +docker build ./async/generator/ -f async/generator/Dockerfile -t heyal/generator:async&& docker push heyal/generator:async \ No newline at end of file diff --git a/2023/day2-ops-code/database/mysql.yaml b/2023/day2-ops-code/database/mysql.yaml new file mode 100644 index 0000000..3806eaa --- /dev/null +++ b/2023/day2-ops-code/database/mysql.yaml @@ -0,0 +1,77 @@ +apiVersion: v1 +kind: Service +metadata: + name: mysql +spec: + ports: + - port: 3306 + selector: + app: mysql + clusterIP: None +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mysql +spec: + selector: + matchLabels: + app: mysql + strategy: + type: Recreate + template: + metadata: + labels: + app: mysql + spec: + containers: + - image: mysql:5.6 + name: mysql + env: + # Use secret in real usage + - name: MYSQL_ROOT_PASSWORD + value: password + - name: MYSQL_DATABASE + value: example + - name: MYSQL_USER + value: example + - name: MYSQL_PASSWORD + value: password + ports: + - containerPort: 3306 + name: mysql + volumeMounts: + - name: mysql-persistent-storage + mountPath: /var/lib/mysql + volumes: + - name: mysql-persistent-storage + persistentVolumeClaim: + claimName: mysql-pv-claim +--- +apiVersion: v1 +kind: PersistentVolume +metadata: + name: mysql-pv-volume + labels: + type: local +spec: + storageClassName: manual + capacity: + storage: 20Gi + accessModes: + - ReadWriteOnce + hostPath: + path: "/mnt/data" +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: mysql-pv-claim +spec: + storageClassName: manual + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi +# https://kubernetes.io/docs/tasks/run-application/run-single-instance-stateful-application/ \ No newline at end of file diff --git a/2023/day2-ops-code/synchronous/generator/Dockerfile b/2023/day2-ops-code/synchronous/generator/Dockerfile new file mode 100644 index 0000000..9e40abf --- /dev/null +++ b/2023/day2-ops-code/synchronous/generator/Dockerfile @@ -0,0 +1,17 @@ +# Set the base image to use +FROM golang:1.17-alpine + +# Set the working directory inside the container +WORKDIR /app + +# Copy the source code into the container +COPY . . + +# Build the Go application +RUN go build -o main . + +# Expose the port that the application will run on +EXPOSE 8080 + +# Define the command that will run when the container starts +CMD ["/app/main"] diff --git a/2023/day2-ops-code/synchronous/generator/go.mod b/2023/day2-ops-code/synchronous/generator/go.mod new file mode 100644 index 0000000..efa37a3 --- /dev/null +++ b/2023/day2-ops-code/synchronous/generator/go.mod @@ -0,0 +1,5 @@ +module main + +go 1.20 + +require github.com/go-sql-driver/mysql v1.7.0 diff --git a/2023/day2-ops-code/synchronous/generator/go.sum b/2023/day2-ops-code/synchronous/generator/go.sum new file mode 100644 index 0000000..7109e4c --- /dev/null +++ b/2023/day2-ops-code/synchronous/generator/go.sum @@ -0,0 +1,2 @@ +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= diff --git a/2023/day2-ops-code/synchronous/generator/main.go b/2023/day2-ops-code/synchronous/generator/main.go new file mode 100644 index 0000000..bcac755 --- /dev/null +++ b/2023/day2-ops-code/synchronous/generator/main.go @@ -0,0 +1,139 @@ +package main + +import ( + "database/sql" + "fmt" + _ "github.com/go-sql-driver/mysql" + "math/rand" + "net/http" + "time" +) + +func generateAndStoreString() (string, error) { + // Connect to the database + db, err := sql.Open("mysql", "root:password@tcp(mysql:3306)/mysql") + if err != nil { + return "", err + } + defer db.Close() + + // Generate a random string + // Define a string of characters to use + characters := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + + // Generate a random string of length 10 + randomString := make([]byte, 64) + for i := range randomString { + randomString[i] = characters[rand.Intn(len(characters))] + } + + // Insert the random number into the database + _, err = db.Exec("INSERT INTO generator(random_string) VALUES(?)", string(randomString)) + if err != nil { + return "", err + } + + fmt.Printf("Random string %s has been inserted into the database\n", string(randomString)) + return string(randomString), nil +} + +func main() { + // Create a new HTTP server + server := &http.Server{ + Addr: ":8080", + } + + err := createGeneratordb() + if err != nil { + panic(err.Error()) + } + + ticker := time.NewTicker(60 * time.Second) + quit := make(chan struct{}) + go func() { + for { + select { + case <-ticker.C: + checkStringReceived() + case <-quit: + ticker.Stop() + return + } + } + }() + + // Handle requests to /generate + http.HandleFunc("/new", func(w http.ResponseWriter, r *http.Request) { + // Generate a random number + randomString, err := generateAndStoreString() + if err != nil { + http.Error(w, "unable to generate and save random string", http.StatusInternalServerError) + return + } + + print(fmt.Sprintf("random string: %s", randomString)) + w.Write([]byte(randomString)) + }) + + // Start the server + fmt.Println("Listening on port 8080") + err = server.ListenAndServe() + if err != nil { + panic(err.Error()) + } +} + +func createGeneratordb() error { + db, err := sql.Open("mysql", "root:password@tcp(mysql:3306)/mysql") + if err != nil { + return err + } + defer db.Close() + + // try to create a table for us + _, err = db.Exec("CREATE TABLE IF NOT EXISTS generator(random_string VARCHAR(100), seen BOOLEAN)") + + return err +} + +func checkStringReceived() { + // get a list of strings from database that dont have the "seen" bool set top true + // loop over them and make a call to the requestor's 'check' endpoint and if we get a 200 then set seen to true + + // Connect to the database + db, err := sql.Open("mysql", "root:password@tcp(mysql:3306)/mysql") + if err != nil { + print(err) + } + defer db.Close() + + // Insert the random number into the database + results, err := db.Query("SELECT random_string FROM generator WHERE seen IS NOT true") + if err != nil { + print(err) + } + + // loop over results + for results.Next() { + var randomString string + err = results.Scan(&randomString) + if err != nil { + print(err) + } + + // make a call to the requestor's 'check' endpoint + // if we get a 200 then set seen to true + r, err := http.Get("http://requestor-service:8080/check/" + randomString) + if err != nil { + print(err) + } + if r.StatusCode == 200 { + _, err = db.Exec("UPDATE generator SET seen = true WHERE random_string = ?", randomString) + if err != nil { + print(err) + } + } else { + fmt.Println(fmt.Sprintf("Random string has not been received by the requestor: %s", randomString)) + } + } +} diff --git a/2023/day2-ops-code/synchronous/k8s.yaml b/2023/day2-ops-code/synchronous/k8s.yaml new file mode 100644 index 0000000..73426d1 --- /dev/null +++ b/2023/day2-ops-code/synchronous/k8s.yaml @@ -0,0 +1,69 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: requestor +spec: + replicas: 1 + selector: + matchLabels: + app: requestor + template: + metadata: + labels: + app: requestor + spec: + containers: + - name: requestor + image: heyal/requestor:sync + imagePullPolicy: Always + ports: + - containerPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: requestor-service +spec: + selector: + app: requestor + ports: + - name: http + protocol: TCP + port: 8080 + targetPort: 8080 + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: generator +spec: + replicas: 1 + selector: + matchLabels: + app: generator + template: + metadata: + labels: + app: generator + spec: + containers: + - name: generator + image: heyal/generator:sync + imagePullPolicy: Always + ports: + - containerPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: generator-service +spec: + selector: + app: generator + ports: + - name: http + protocol: TCP + port: 8080 + targetPort: 8080 + type: ClusterIP diff --git a/2023/day2-ops-code/synchronous/requestor/Dockerfile b/2023/day2-ops-code/synchronous/requestor/Dockerfile new file mode 100644 index 0000000..9e40abf --- /dev/null +++ b/2023/day2-ops-code/synchronous/requestor/Dockerfile @@ -0,0 +1,17 @@ +# Set the base image to use +FROM golang:1.17-alpine + +# Set the working directory inside the container +WORKDIR /app + +# Copy the source code into the container +COPY . . + +# Build the Go application +RUN go build -o main . + +# Expose the port that the application will run on +EXPOSE 8080 + +# Define the command that will run when the container starts +CMD ["/app/main"] diff --git a/2023/day2-ops-code/synchronous/requestor/go.mod b/2023/day2-ops-code/synchronous/requestor/go.mod new file mode 100644 index 0000000..efa37a3 --- /dev/null +++ b/2023/day2-ops-code/synchronous/requestor/go.mod @@ -0,0 +1,5 @@ +module main + +go 1.20 + +require github.com/go-sql-driver/mysql v1.7.0 diff --git a/2023/day2-ops-code/synchronous/requestor/go.sum b/2023/day2-ops-code/synchronous/requestor/go.sum new file mode 100644 index 0000000..7109e4c --- /dev/null +++ b/2023/day2-ops-code/synchronous/requestor/go.sum @@ -0,0 +1,2 @@ +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= diff --git a/2023/day2-ops-code/synchronous/requestor/main.go b/2023/day2-ops-code/synchronous/requestor/main.go new file mode 100644 index 0000000..98c1ca3 --- /dev/null +++ b/2023/day2-ops-code/synchronous/requestor/main.go @@ -0,0 +1,134 @@ +package main + +import ( + "database/sql" + "errors" + "fmt" + _ "github.com/go-sql-driver/mysql" + "io" + "net/http" + "strings" + "time" +) + +func storeString(input string) error { + // Connect to the database + db, err := sql.Open("mysql", "root:password@tcp(mysql:3306)/mysql") + defer db.Close() + // Insert the random number into the database + _, err = db.Exec("INSERT INTO requestor(random_string) VALUES(?)", input) + if err != nil { + return err + } + + fmt.Printf("Random string %s has been inserted into the database\n", input) + return nil +} + +func getStringFromDB(input string) error { + // see if the string exists in the db, if so return nil + // if not, return an error + db, err := sql.Open("mysql", "root:password@tcp(mysql:3306)/mysql") + defer db.Close() + result, err := db.Query("SELECT * FROM requestor WHERE random_string = ?", input) + if err != nil { + return err + } + + for result.Next() { + var randomString string + err = result.Scan(&randomString) + if err != nil { + return err + } + if randomString == input { + return nil + } + } + + return errors.New("string not found") +} + +func getStringFromGenerator() { + // make a request to the generator + // save sthe string to db + r, err := http.Get("http://generator-service:8080/new") + if err != nil { + fmt.Println(err) + return + } + + body, err := io.ReadAll(r.Body) + if err != nil { + fmt.Println(err) + return + } + + fmt.Println(fmt.Sprintf("body from generator: %s", string(body))) + + storeString(string(body)) + +} + +func main() { + // setup a goroutine loop calling the generator every minute, saving the result in the DB + + ticker := time.NewTicker(60 * time.Second) + quit := make(chan struct{}) + go func() { + for { + select { + case <-ticker.C: + getStringFromGenerator() + case <-quit: + ticker.Stop() + return + } + } + }() + + // Create a new HTTP server + server := &http.Server{ + Addr: ":8080", + } + + err := createRequestordb() + if err != nil { + panic(err.Error()) + } + + // Handle requests to /generate + http.HandleFunc("/check/", func(w http.ResponseWriter, r *http.Request) { + // get the value after check from the url + id := strings.TrimPrefix(r.URL.Path, "/check/") + + // check if it exists in the db + err := getStringFromDB(id) + if err != nil { + http.Error(w, "string not found", http.StatusNotFound) + return + } + + fmt.Fprintf(w, "string found", http.StatusOK) + }) + + // Start the server + fmt.Println("Listening on port 8080") + err = server.ListenAndServe() + if err != nil { + panic(err.Error()) + } +} + +func createRequestordb() error { + db, err := sql.Open("mysql", "root:password@tcp(mysql:3306)/mysql") + if err != nil { + return err + } + defer db.Close() + + // try to create a table for us + _, err = db.Exec("CREATE TABLE IF NOT EXISTS requestor(random_string VARCHAR(100))") + + return err +} diff --git a/2023/day20.md b/2023/day20.md index 824381f..70fd07d 100644 --- a/2023/day20.md +++ b/2023/day20.md @@ -151,3 +151,5 @@ Container Image Scanning can help us find vulnerabilities in our application bas Image Scanning and IAST/DAST are not mutually-exclusive. They both have their place in a Secure SDLC and can help us find different problems before the attackers do. + +See you on [Day 21](day21.md). diff --git a/2023/day22.md b/2023/day22.md index 4ec8548..a0cf0dd 100644 --- a/2023/day22.md +++ b/2023/day22.md @@ -75,3 +75,4 @@ Another place is your container registry (as seen today). Both are good options, both have their pros and cons. It is up to the DevSecOps architect to decide which approach works better for them and their thread model. +See you on [Day 23](day23.md). diff --git a/2023/day23.md b/2023/day23.md index 8670423..46071c0 100644 --- a/2023/day23.md +++ b/2023/day23.md @@ -159,3 +159,4 @@ A Secure SDLC would include scanning of all artifacts that end up in our product Today we learned how to scan non-container artifacts like Kubernetes manifests, Helm charts and Terraform code. The tools we looked at are free and open-source and can be integrated into any workflow or CI pipeline. +See you on [Day 24](day24.md). diff --git a/2023/day24.md b/2023/day24.md index 11fbd61..f81d157 100644 --- a/2023/day24.md +++ b/2023/day24.md @@ -145,3 +145,4 @@ However, integrating signing into your workflow adds yet another layer of defenc Signing artifacts prevents supply-chain and man-in-the-middle attacks, by allowing you to verify the integrity of your artifacts. [Sigstore](https://sigstore.dev/) and [cosign](https://docs.sigstore.dev/cosign/overview/) are useful tools to sign your artifacts and they come with many integrations to choose from. +See you on [Day 25](day25.md). diff --git a/2023/day25.md b/2023/day25.md index a9b3517..25edd32 100644 --- a/2023/day25.md +++ b/2023/day25.md @@ -82,3 +82,4 @@ A scan can detect something that is vulnerability, but it cannot be actively exp This makes the vulnerability a low priority one, because why fix something that presents no danger to you. If an issue comes up in penetration testing then that means that this issue is exploitable, and probably a high priority - in the penetation testers managed to exploit it, so will the hackers. +See you on [Day 26](day26.md). diff --git a/2023/day26.md b/2023/day26.md index b375a57..63c985e 100644 --- a/2023/day26.md +++ b/2023/day26.md @@ -126,4 +126,5 @@ More on VM security: - \ No newline at end of file + +See you on [Day 27](day27.md). diff --git a/2023/day27.md b/2023/day27.md index 03fdbdd..8e51b94 100644 --- a/2023/day27.md +++ b/2023/day27.md @@ -82,3 +82,5 @@ That will be done by either patching up the system, closing a hole that is not n + +See you on [Day 28](day28.md). diff --git a/2023/day28.md b/2023/day28.md index b01ead0..61ba4eb 100644 --- a/2023/day28.md +++ b/2023/day28.md @@ -1,6 +1,6 @@ # Introduction to Runtime Defence & Monitoring -Welcome to all the DevOps and DevSecOps enthusiasts! 🙌 +Welcome to all the DevOps and DevSecOps enthusiasts! 🙌 We are here to learn about "Runtime defence". This is a huge subject, but we are not deterred by it and will learn about it together in the next 7 days. @@ -39,7 +39,6 @@ Elaborating on this, here are the key reasons why monitoring is important for ru * Gaining visibility: Monitoring provides insight into system activity, which can be used to optimize performance, troubleshoot issues, and identify opportunities for improvement. - ## What to monitor and record? In theory, the ideal solution would be to log everything that is happening in the system and keep the data forever. @@ -63,6 +62,7 @@ Security configurations: Monitor security configurations, such as firewall rules Backup and disaster recovery systems: Monitor backup and disaster recovery systems to ensure that they are operating correctly and data can be recovered in the event of a failure or disaster. ## A practical implementation + In this part, we move from theory to practice. There isn't a silver bullet here, every system has its tools. We will work on Kubernetes as infrastructure with [Microservices demo](https://github.com/GoogleCloudPlatform/microservices-demo) application. @@ -145,3 +145,4 @@ Browse Grafana for more dashboards [here](https://grafana.com/grafana/dashboards # Next... Tomorrow we will continue to the application level. Application logs and behavior monitoring will be in focue. We will continue to use the same setup and go deeper into the rabbit hole 😄 +See you on [Day 29](day29.md). diff --git a/2023/day29.md b/2023/day29.md index 7609bb3..245e750 100644 --- a/2023/day29.md +++ b/2023/day29.md @@ -129,6 +129,5 @@ Now you should see Falco events in your Grafana! 😎 # Next... -Next day we will look into how to detect attacks in runtime. See you tomorrow 😃 - - +Next day we will look into how to detect attacks in runtime. +See you tomorrow 😃 [Day 30](day30.md). diff --git a/2023/day30.md b/2023/day30.md index b710e87..f5c89ab 100644 --- a/2023/day30.md +++ b/2023/day30.md @@ -113,4 +113,4 @@ I hope this part gave you an insight into how this system works. # Next Tomorrow we will move away from the world of applications and go to the network layer, see you then! - +Unto [Day 31](day31.md). diff --git a/2023/day31.md b/2023/day31.md index e8a15eb..4b06687 100644 --- a/2023/day31.md +++ b/2023/day31.md @@ -89,3 +89,4 @@ There are several tools available to monitor network traffic in Kubernetes, each These are just a few examples of the many tools available for monitoring network traffic in Kubernetes. When selecting a tool, consider the specific needs of your application and infrastructure, and choose a tool that provides the features and capabilities that best fit your requirements. +See you on [Day 32](day32.md). \ No newline at end of file diff --git a/2023/day32.md b/2023/day32.md index f9a7f64..82ca171 100644 --- a/2023/day32.md +++ b/2023/day32.md @@ -71,6 +71,16 @@ Auditing Kubernetes configuration is simple and there are multiple tools you can We will see the simple way to scan our cluster with Kubescape: + +``` +kubescape installation in macOs M1 and M2 chip error fixed + +[kubescape](https://github.com/kubescape/kubescape) + +``` + + + ```bash curl -s https://raw.githubusercontent.com/kubescape/kubescape/master/install.sh | /bin/bash kubescape scan --enable-host-scan --verbose @@ -102,3 +112,5 @@ After the installation you can access the vulnerabilities via CRD with kubectl: kubectl get vulnerabilityreports --all-namespaces -o wide ``` ![](images/day32-2.png) + +[Day 33](day33.md). diff --git a/2023/day33.md b/2023/day33.md index e9888ec..a7c18a6 100644 --- a/2023/day33.md +++ b/2023/day33.md @@ -295,5 +295,4 @@ status: {} ### Summary These were examples of how to turn behavior to policy! Good stuff 😃 - - +See you on [Day 34](day34.md). diff --git a/2023/day34.md b/2023/day34.md index f0d68de..04e19db 100644 --- a/2023/day34.md +++ b/2023/day34.md @@ -216,4 +216,4 @@ no-privileged-containers: ``` I hope this short intro gave a little taste of how admission controllers can help you to enforce runtime rules over a Kubernetes cluster!. - +See you on [Day 35](day35.md). diff --git a/2023/day35.md b/2023/day35.md index e69de29..47fd241 100644 --- a/2023/day35.md +++ b/2023/day35.md @@ -0,0 +1,49 @@ +# Understanding the Importance of Secrets Management + +## Introduction +Regardless of the type of environment you work in, there will be privileged credentials needed by applications, users, or other software platforms to manage your environment. Secrets can be anything your organization deems confidential and could cause harm to the company if shared or exposed. Examples could be database credentials to read customer data, a private key used to decrypt communications to your app server, or domain admin creds used by your vulnerability scanner during nightly runs. Managing these privileged credentials is an essential process that is critical to an organization's security posture. + +Secrets are used EVERYWHERE in organizations. Think about the credentials that were required for the last application or deployment you participated in, regardless of how basic or complex it was. As a human user, you likely need privileged credentials to provision resources in your production environment, like gaining access to VMware vCenter to deploy virtual machines, requesting a TLS certificate for your application, or logging into Terraform Cloud to provision Amazon EC2 instances. Moving over to the application side, they need access to additional services within your organization, like an internal API, a file share, or the ability to read/write to a database server to store data. The applications might need to register the service within your service catalog (service mesh) or execute a script that traverses a proxy and pulls down packages from Artifactory. These actions all require some privileged credential or secret that needs to be managed appropriately. + +## Consolidation + +So where should all these secrets live? Most organizations understand these secrets should be managed in some secret management solution. However, that doesn't always reflect what is actually in practice. I've worked with countless organizations that keep credentials in an Excel sheet, a OneNote document, or even a text file on their desktop. That strategy provides absolutely no security and exposes these companies to security breaches. Other organizations have taken a step further and used a consumer-based solution, like 1Password or LastPass, to store these long-lived credentials. It's better than nothing, but it doesn't provide the organization with complete visibility and management of credentials. Plus, we're talking about the practice of DevOps here, so it doesn't offer much in terms of automated retrieval or rotation either. + +Ideally, organizations need to adopt a proper secret management tool that can be used to consolidate secrets and provide features such as role-based access control, rotation and revocation, expiration, and auditing capabilities. + +## Long-Lived Secrets vs. Dynamic Secrets +Let's talk about the difference between long-lived secrets and dynamic secrets + +### Long-Lived Credentials +Not all secrets are created equal. Most organizations default to creating long-lived, static credentials that are often shared among teams and applications. Creating these credentials usually requires a long process, such as ticket creation, security approval, management approval, etc. Because obtaining credentials is often tedious, engineers and administrators will reuse or share these credentials among different applications rather than repeat this process. Be honest, how many times have you clicked this button in Active Directory? I know I have done it 100s of times in the past…. + +![](images/day35-0.png) + +These reused and often shared credentials are hard to audit, can be impossible to rotate, and provide very little accountability. Additionally, these static credentials offer 24/7 access to the target system, even though access might only be needed for minutes per day. + +### Dynamic Secrets + +In contrast with static credentials, many organizations realize the benefits of migrating to dynamically generated secrets. Rather than create the credentials beforehand, applications can request credentials on-demand when needed. The application uses dynamic credentials to access a system or platform to perform work, and the credentials are then revoked/deleted afterward. If these dynamic credentials are accidentally written to a log file or committed to a code repository, it no longer becomes a security threat because they are already invalidated. And because dynamic credentials are accessible to applications (with proper authentication, of course), each instance of an application can generate its own credential to access the backend system. + +For example, let's assume we're using Terraform to deploy our infrastructure to our favorite public cloud platform. If you were using static credentials, you would log into the cloud platform, create static credentials (probably highly privileged ones), and provide those credentials for Terraform to provision and manage your infrastructure. Those highly privileged credentials are valid 24/7, even though you only run Terraform a few times daily. On the other hand, if you were using a dynamic credential, Terraform could first obtain a credential, provision, or manage the infrastructure, and the credential would be invalidated after. When Terraform isn't running, there is no credential that can be exposed or misused. Even if the dynamic credential were written to logs or accidentally committed to a public GitHub repo, it wouldn't matter since it was revoked when the job was completed or after a minimal TTL. + +![](images/day35-1.png) + +## Access Control and Auditing + +Access to secrets should be tightly controlled, and only authorized personnel should be able to access them. Ideally, two-factor authentication or a multi-step approval process should be in place for highly-privileged credentials, such as domain access, root credentials, or secrets used to obtain confidential data. Access should be limited to secrets based on an employee's role within the organization or an application's requirements to fulfill its duties. + +It is important that access to secrets should be closely monitored, and a log should be maintained of all actions taken of them. Logs should be ingested into a SIEM or log correlation systems, like Splunk, SumoLogic, or DataDog, to create dashboards and alert on specific actions. This can help quickly detect and respond to potential security threats within the organization. + +## Common Solutions + +In a DevOps and automated world, secrets management solutions must be centered around a fully featured REST API. With such, access to the platform can be automated entirely by any orchestrator or pipeline tool the organization uses, simplifying company-wide adoption. Secrets Management tools such as HashiCorp Vault, AWS Secrets Manager, or Azure Key Vault can provide organizations with features such as encryption at rest, role-based access control, and auditing capabilities to help protect secrets. From my experience, the most popular tools used by organizations are: + +* HashiCorp Vault +* CyberArk +* AWS Secrets Manager +* Azure Key Vault +* GCP Secret Manager +* Thycotic Secret Server + +See you on [Day 36](day36.md). \ No newline at end of file diff --git a/2023/day36.md b/2023/day36.md index e69de29..c23625d 100644 --- a/2023/day36.md +++ b/2023/day36.md @@ -0,0 +1,49 @@ +# Securing Secrets with HashiCorp Vault +  +In the world of secrets management, HashiCorp Vault tends to be the de facto standard, especially when it comes to DevOps environments. Tools such as Jenkins, Terraform, or even Kubernetes have tight integrations with Vault that allow you to securely store and retrieve secrets from your infrastructure as code pipelines. With a fully featured REST API, it's relatively simple to integrate into your existing workflows. As a result, secrets are consolidated and retrieved from a secure platform, all while improving your organization's security posture. +  +## Deploying a Simple Vault Environment +  +You have plenty of options when you need to get started with HashiCorp Vault. Depending on your skill set and available environment, Vault can be deployed on a physical server, a virtual machine (Amazon EC2, VMware vSphere, etc.), or in a containerized environment like Docker or Kubernetes. You can even launch Vault on a laptop/desktop if you just want to play around with a temporary instance using Vault "dev" mode. Regardless of your preference, integrating Vault with your applications and pipelines will be very similar. +  +## Deploy Vault on Kubernetes +  +When it comes to deploying Vault on Kubernetes, HashiCorp has made it incredibly simple by providing an official Helm chart. This [Helm chart](https://github.com/hashicorp/vault-helm) can be customized per your needs and can allow you to simply "install" an entire Vault environment right to your k8s cluster. Personally, I prefer [minikube](https://minikube.sigs.k8s.io/docs/start/) on my local machine to quickly launch a k8s cluster and, ultimately, quickly deploy a Vault environment to use for testing. If you want an example of a customized Helm chart, check out this [simple example](https://github.com/btkrausen/hashicorp/blob/master/vault/k8s/values.yml) on my GitHub, which was written for an OpenShift environment. More advanced configurations can be added, but this example should get you up and running quickly. +  +## Deploying on Virtual Machines +  +If Kubernetes isn't your thing, Vault also works flawlessly on traditional virtual machines. It's not as simple as a Helm chart, but having scripts and productional-level configuration files does simplify the process. From different Linux distros to Windows, you can choose almost any operating system you're comfortable with to run Vault in your environment. The Vault binary can be downloaded from the [HashiCorp releases page](https://releases.hashicorp.com/vault). This site makes it easy to download Vault manually or through automated means. Vault simply needs to be placed in your **$PATH** to start using it. +  +Beyond installing Vault, there are additional requirements that you'll want to consider. These requirements are similar to what you would need when running any service on a server, such as configuration files, service files, etc. The following are some of the requirements to consider: +* A [Vault configuration file](https://github.com/btkrausen/hashicorp/blob/master/vault/scripts/install_vault.sh) for each server +* A [system](https://github.com/btkrausen/hashicorp/blob/master/vault/config_files/vault.service) (or similar) file to manage the service (start, stop, etc.) +* Directory to store config files and logs +* A local, non-root user to run the Vault service +* Permissions/ownership of the directories for the user +  +As somebody who has worked on Vault for over six years and a dedicated member of the HashiCorp community, I have all of this on [my GitHub](https://github.com/btkrausen/hashicorp) for your consumption. These are files that I use for production-level deployments, so they are tried and tested in the real world. Feel free to use these as a starting point and customize them per your needs. +  +> If all this seems confusing, you can check out my [Getting Started with HashiCorp Vault Course](https://btk.me/v) to learn all about these configurations (and so much more!), along with getting access to hands-on labs. +  +## Vault is Up and Running. What's Next? +  +Once you have Vault up and running, there are a few steps to complete before integrating your workflows and applications. When any Vault cluster is first started, it needs to be initialized. In short, initialization is when Vault creates the encryption key, unseal or recovery keys, and prepares the storage backend for you. The simplest way to initialize a cluster is to use the 'vault operator init' command. If you're doing this in a production environment, consider encrypting the resulting unseal/recovery keys using PGP keys to ensure no one person has access to all the keys to the kingdom (pun intended!). Check out [my video here](https://youtu.be/QErHqzGH1mk) to see how to perform this step securely. Vault initialization will also return the initial root token, which, at this point, is the ONLY authentication mechanism to gain access to Vault. + + +![](images/day36-1.png) + +Once Vault is initialized, you're only one step away from consuming all the goodness Vault has to offer. If you decided to use auto unseal, you're already there! Without auto unseal, Vault needs to be unsealed. Unsealing is the process of reconstructing the root key used to decrypt the encryption key, which is ultimately stored in memory and used to read/write data to the storage backend. If Vault is sealed, it's essentially useless, so this is an important step. You can use the 'vault operator unseal' command to unseal Vault. Vault will request an 'unseal key,' which was returned during the initialization process discussed above. Perform this step three times (assuming the defaults) to unseal Vault. By the way, you can [migrate to an auto unseal mechanism](https://youtu.be/HolUACQutpk) when you're ready. Once Vault is unsealed, we can start configuring the various components, such as auth methods, secrets engines, and audit devices. More on those on a later day! + + +![](images/day36-2.png) +  +Before wrapping up the day, there are a few additional topics I wanted to mention and discuss. Some aren't required for a lab environment but should be considered (or required!) for a production environment: +  +* Use TLS everywhere. Go ahead and mint a certificate from a trusted (internal) CA and practice good security from the start. If you like running vulnerable and insecure environments, or if you are running in a lab or for testing purposes, Vault supports disabling TLS by setting 'tls_disable = true' in the configuration file (listener +stanza). +  +* Using a root token gives you complete, unrestricted access to anything in Vault. The root token is highly privileged and should NOT be shared. In fact, it is not evaluated against any Vault policies. Therefore, it is recommended to use the root token to perform the initial configuration, namely auth methods, and then the token should be revoked. [Another root token can be generated](https://youtu.be/rcQsNinVl0Y) in the future if needed. +  +* A single Vault node may be sufficient for lab environments if redundancy and high availability aren't a concern. If service uptime is essential, use a minimum of 3 nodes (assuming integrated storage). I recommend five nodes for production clusters to give you n + 2 redundancy, meaning you can lose up to two nodes, and the Vault service remains functional. + +See you on [Day 37](day37.md). \ No newline at end of file diff --git a/2023/day37.md b/2023/day37.md index e69de29..de53109 100644 --- a/2023/day37.md +++ b/2023/day37.md @@ -0,0 +1,86 @@ +# Working with HashiCorp Vault's Secrets Engines + +While there are multiple components in HashiCorp Vault that are important, none are more foundational than secrets engines. That's because secrets engines are responsible for providing the functionality that you want from Vault. All other components, such as auth methods, audit devices, and storage backends, can be viewed as supporting components and ultimately provide the mechanism to get to a secrets engine. + +## Enabling a Secrets Engine + +By default, Vault does not enable any secrets engines. Therefore, any functionality needed from a secrets engine requires that you enable it. You can enable as many secrets engines as you need and enable many secrets engines of the same type (as long as they are enabled on different paths), which is very common with Vault customers. Many will enable 10s or 100s of the key/value secrets engine to segregate secrets by a team, business unit, or application. Or you can use a single key/value secrets engine and separate each team under it. It's totally up to you or whatever works for your organization. + +Since secrets engines are the core functionality of Vault, HashiCorp has included many secrets engines out of the box. You can use a community or vendor-supported plugin if you need additional functionality. An example of the most prevalent secrets engines that Vault supports include: + +• Key/Value – store and retrieve static, long-lived credentials +• PKI – configure Vault as an intermediate/issuing CA to automate TLS certificates +• Transit – centralize your encryption workflow across your organization +• AWS/Azure/GCP – dynamically generate AWS credentials to gain access to your accounts +• Database – dynamically generate credentials against your databases + +You can use the `vault secrets enable ` command to enable a secrets engine. You can also enable and configure many secrets engines directly in the Vault UI. + +![](images/day37-1.png) + +## Working with the KV Secrets Engine + +As a consultant working on Vault for quite a while, I've yet to work with a customer/client that didn't want to use the Key/Value secrets engine. I attribute this to the fact that most organizations have been using static, long-lived credentials for decades (and probably won't go away anytime soon!) and need a place to securely store them. When working with the key/value secrets engine, remember that it does NOT interact with any external source to replicate/update/retrieve secrets. It's simply a key/value store where you can store, update, and retrieve your credentials through the UI, CLI, or API request. + +Let's enable a KV secrets engine (version 2) to see how this works, and we'll start storing and retrieving secrets from it. On the command line, use `vault secrets enable -path=90daysofdevops kv-v2`. This enables the KVv2 secrets engine on the path of `90daysofdevops`, which means that all interactions with this secrets engine will use the `90daysofdevops/` path, such as reading, writing, or updating secrets. + +![](images/day37-2.png) + +## Writing Data to the KV Secrets Engine + +We now have a new, blank key/value store to store our secrets. We can organize these secrets any way that we want beneath this path. Many organizations choose to organize by teams or applications but talk with your team to determine the best structure for your organization. The biggest factor here is simplifying the policies that will permit/deny access to these secrets. If you can write a simple policy or even a templated policy, it will make your Day 2 Ops much easier. In this example, let's assume we have three different teams using this key/value secrets engine, the **cloud** team, the **automation** team, and the **development** team. + +Let's write our first secret to the KV secrets engine for the cloud team. Again, like anything else in Vault, you can do this on any of the three Vault interfaces, the UI, CLI, or API. To write a secret, you can use the following command: + +`vault kv put 90daysofdevops/cloud/aws secret_key=ABC123 access_key=987zyx` + +![](images/day37-3.png) + +In this example, we wrote two key/value pairs, one for our _secret_key_ and one for our _access_key_, each with its respective value. The path that these secrets are now stored is `90daysofdevops/data/cloud/aws`. Don't let that _data_ segment fool you. It's necessary when working with the KVv2 secrets engine. The `vault kv put` obfuscates the need to add `data` in our path but this is the path you'll need to retrieve secrets from when reading from the API and when writing policies to access this path. + +Let's write some data for the development team. In this scenario, the dev team has decided to organize secrets based on the applications they are responsible for. They need to store a certificate and a private key for application deployment, along with a static database credential for another app. + +`vault kv put 90daysofdevops/development/apps/customer-app user=db-admin password=P@ssw0rd1` + +`vault kv put 90daysofdevops/development/apps/cache-app cert="----BEGIN CERTIFICATE----asdfwefsadfa23jjklnsdfkl2jns9n2a32sdaffgrsyhgsfwefdsan---END CERTIFICATE----" private_key="---BEGIN PRIVATE KEY----nwljdwsxcvmnrejhq394hdsfjfgadjkhfajkl----END PRIVATE KEY---"` +![](images/day37-4.png) + +In this example, we wrote different types of secrets to two different paths: +• `90daysofdevops/development/apps/customer-app` +• `90daysofdevops/development/apps/cache-app` + +Again, you and your team should decide how to organize and store the credentials in your organization. It's common that the Vault operators "own" the organization of the paths down to a certain level but then allow the teams to organize their data however they see fit. Different teams are, well, different and likely have different needs. + +## Reading Data from the KV Secrets Engine + +Ok, now that we have secrets written to our KV secrets engine, it makes sense that we will want to read these secrets. These secrets may be manually retrieved by a developer. They may be retrieved by an Azure DevOps pipeline when a containerized application is provisioned on AKS. Either way, the data is consumed by _something_ and used for deployment or configuration. + +When reading a secret, you will use the same path as you used when writing the secret to the KV secrets engine. The path will vary slightly depending on if you're using the CLI vs. API (I know, it's sort of annoying!), but it's not too confusing. API calls must include that _data_ path we mentioned earlier. In this example, we will assume the CLI for now. However, remember that many orchestrators or provisioning tools include native integrations with Vault, such as the Jenkins plugin or AzureDevOps Extensions. GitLab also includes tight integrations to consume the HashiCorp Vault service as well. + +To read the secret stored for the cloud team using the Vault CLI, use the following command: + +`vault kv get 90daysofdevops/cloud/aws` + +![](images/day37-5.png) + +Note some of the key components of the response. Vault displays the API path (which includes that _data_ segment), the metadata associated with the secret (because this is a key/value version 2 secrets engine), and the data we want (the secrets!). But what if we want to return ONLY the value of our secret and not include the additional information? We can do that in several ways. + +The first way is to use the -field flag on the command line: + +`vault kv get -field=secret_key 90daysofdevops/cloud/aws` + +![](images/day37-6.png) + +In this case, Vault returned ONLY the value for `secret_key`, which may be helpful for an automated job where we don't want to parse through the entire response. The other way we can easily do this is to request the response be JSON-formatted and parse through the data using `jq` to obtain what we need: + +`vault kv get -format=json 90daysofdevops/cloud/aws | jq -r '.data.data.secret_key'` + +![](images/day37-7.png) + +## Summary + +I hope that this quick tutorial gave you a glimpse of how you can use Vault's KV secrets engine to write and read data form your applications. There are, of course, lots of additional configurations and settings you can you in the KV secrets engine to improve the security and organization of your data, but this should at least get you started. + +> Don't forget to check out my [YouTube channel](https://btk.me/yt) that showcase lots of different configurations for Vault and other tools. Planning to continue to adding more and more content to this channel, so subscribe and let me know what else you want to see. + +See you on [Day 38](day38.md). \ No newline at end of file diff --git a/2023/day38.md b/2023/day38.md index e69de29..e4d8c7d 100644 --- a/2023/day38.md +++ b/2023/day38.md @@ -0,0 +1,93 @@ +# Increase the Security Posture of Your Organization with Dynamic Credentials + +As we talked about yesterday, Vault is commonly used as a platform to consolidate your static, long-lived credentials. However, you're still stuck with the management nightmare of rotating those credentials based on your organization's security policies. This credential rotation "tradition" is a manual, laborious task and is susceptible to errors resulting in application downtime. But… + +What if you could get rid of static credentials altogether? If your app only needs database access once a week to run reports, why do you give it a credential that is valid 24/7/365? Wouldn't it be great to have your applications generate dynamic, self-destructing credentials on-demand for the systems needed to function? + +Well, it's all possible using many of the secrets engines available in Vault. + +## Intro to Dynamic Secrets + +Dynamic secrets are credentials that are generated on demand on behalf of the requesting Vault client. Rather than simply reading a static credential stored in the KV store, Vault can make an API call to the requested platform, create a credential, and pass the credential back to the user. In the process, Vault attaches a lease (TTL) to the credential, which indicates how long the credential is valid. The Vault client can then use the credential to communicate directly with the platform for its intended function. Once the credential's lease expires, Vault calls back to the platform and deletes the credential, making it invalid. + +## Benefits of Using Dynamic Secrets + +There are so many benefits of migrating to dynamic credentials. The obvious benefit is not having long-lived credentials that are manually rotated. Because these long-lived credentials are often shared between teams and application stacks, they are more susceptible to misuse or abuse. However, when you migrate to dynamic creds, each application instance can retrieve a unique credential to access the required platform when using dynamic credentials. And if that application instance is terminated (think containerization or auto-scaling), the credential will be invalidated by Vault and not impact other instances or applications in your environment. + +Dynamic secrets also eliminate the manual process of rotating credentials. Rather than rotating the credentials once a year, these highly privileged creds are now rotated once a month, once a week, or once every hour. For example, consider how you might use Terraform to deploy resources on your public or private cloud. You likely create a credential on the target platform and use it repeatedly via environment variables or sensitive workspace variables in TFC/TFE. But why are you giving Terraform highly privileged credentials that are valid 24/7/365 when your Terraform runs only take 15 minutes each day? Switch to dynamic credentials. Using a combination of Vault secrets engine and the Vault provider for Terraform, you can have Terraform generate a dynamic credential for the platform it needs to access for resource deployment or management. + +## Configure a Dynamic Secrets Engine + +With that long-winded introduction out of the way, let's talk about how we can accomplish this goal of using dynamic credentials. HashiCorp Vault offers a plethora of secrets engines that generate dynamic credentials or data, such as: +• AWS +• Azure +• GCP +• Active Directory +• AliCloud +• Consul +• Databases (supports about 15 different database platforms) +• PKI certificates +• Kubernetes +• RabbitMQ +• SSH +• Terraform Cloud + +I think you'd agree that's a lot of options for a single platform. The cool thing is that you can use as many of these secrets engines as you want, and even enable many of the same type of secrets engine. Let's take a look at how we would enable one of these, using AWS as the example. + +Each secrets engine must be enabled on a path, and all interactions with the secrets engine is then done using the path. Because of this, each secrets engine must be enabled on a unique path so Vault knows where to route the request. To enable a secrets engine, use the following structure for the command `vault secrets enable -path= `. Enabling the AWS secrets engine on the path of `cloud` would look like this: + +`vault secrets engine -path=cloud aws` + +> Note that if you do not provide the path flag, the secrets engine will be enabled on the default path, which is the same name of the secrets engine type. For example, the AWS secrets engine would be enabled at aws/. + +Ok, so we've got a secrets engine enabled, let's start configuring it. Configuration of a secrets engine generally requires a few things. The first is a way for Vault to communicate with the platform (in this case, AWS). Just like any other AWS client, Vault needs credentials to authenticate to the target platform to perform actions. In the case of AWS, you can provide Vault with an Access Key and Secret Key or use an IAM role if Vault was deployed on AWS. + +In addition to authentication, Vault needs the proper authorization to perform actions on the platform. For AWS, that equates to having an IAM policy attached to the credentials you will give to Vault. Depending on the type of credential you want to generate (Vault supports 3 types for AWS), the policy should allow permission to create/manage/delete a user, generate keys, manage the keys, etc. These policies are provided by HashiCorp in their documentation. I also have some pre-defined policies for Vault [on my GitHub](https://github.com/btkrausen/hashicorp). + +To provide credentials to Vault to access your AWS account, you can use the following command: + +``` +vault write aws/config/root \ + access_key=AKIAIOSFODNN7EXAMPLE \ + secret_key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY \ + region=us-east-1 +``` + +> Although you can add your credentials using this configuration, you can also provide them using environment variables as well. + +Ok, now Vault has access to our AWS account, it doesn't yet know what credentials to create and the level of access those credentials should have in your AWS account. Each unique requirement for credentials will be defined in a role (that's a Vault role, not to be confused with an AWS role). Roles are used to map a user to a set of permissions on the platform. For example, you can create a role for a developer that provides read-only access to the AWS account, or you can create a role for Terraform that provides a broader set of privileges to create, manage, and delete resources. Roles can be used by many applications, but keep in mind that a different role will be required for each UNIQUE set of permissions you want to give the Vault client. + +Let's create our first role. This role will be for our developer who needs read-only access to an AWS so they can obtain logs for troubleshooting an application. The role name will be `developer`. + +``` +vault write aws/roles/developer \ + policy_arns=arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess \ + credential_type=iam_user +``` + +> In this example, I used the IAM_USER credential type but for production environments, I'd recommend using ASSUME_ROLE so you can have a + +When a developer requests credentials, they will be tied to the AWS-managed policy named ` arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess`. You can use AWS-managed policies, Customer-Managed policies, or simply provide the policy within the Vault role configuration and Vault will create the inline policy when the user is created. + +## Let's Get Credentials + +Ok, we have the secrets engine mounted (enabled!), the secrets engine configured to access our account, and now we have a role. The next logical step is to test it and obtain our first set of dynamic credentials. Since the role we created is named `developer`, that will come into play for the path needed to get credentials. To get creds, use the following command: + +`vault read aws/creds/developer` + +If successful, Vault should have returned a set of credentials that the client can use to interact directly with AWS. Woohoo! + +Keep in mind that when the lease (TTL) expires, Vault will go back and delete the credentials on AWS, permanently invaliding them. + +## Day 2 Ops + +The last thing I wanted to touch on was managing the credentials used by Vault to access the platform. The whole purpose of a dynamic secrets engine is to eliminate your static, long-lived credentials. However, the first step here was to provide Vault…..static, long-lived credentials to access the platform? Hmm…sounds somewhat counterproductive, right? What if THAT credential gets compromised or shared? + +Fear not, as Vault provides a simple endpoint for secrets engines which allows Vault to quickly rotate that 'root' credential. You can hit this endpoint as often as needed to rotate the credential Vault uses to access the platform. In this example, you can use the following command to rotate the AWS credential we provided above. + +`vault write -f aws/config/rotate-root` + +Once you run this command, only AWS and Vault know the credentials. No human user has the root credential, and even a Vault administrator can read back the full access key and secret key. This operation can be run as often as needed to meet your internal security policies for credential rotation. + +See you on [Day 39](day39.md) + diff --git a/2023/day42.md b/2023/day42.md index 3d22b4a..9618ba3 100644 --- a/2023/day42.md +++ b/2023/day42.md @@ -70,4 +70,6 @@ The print argument is a string, which is one of Python's basic data types for st - [Learn Python - Full course by freeCodeCamp](https://youtu.be/rfscVS0vtbw) - [Python tutorial for beginners by Nana](https://youtu.be/t8pPdKYpowI) -- [Python Crash Course book](https://amzn.to/40NfY45) \ No newline at end of file +- [Python Crash Course book](https://amzn.to/40NfY45) + +See you on [Day 43](day43.md). \ No newline at end of file diff --git a/2023/day43.md b/2023/day43.md index 54948f1..56373d7 100644 --- a/2023/day43.md +++ b/2023/day43.md @@ -111,4 +111,4 @@ try: ## Conclusion -That is it for today, I will see you tomorrow in Day 3 of Python! +That is it for today, I will see you tomorrow in [Day 44 | Day 3 of Python!](day44.md). diff --git a/2023/day44.md b/2023/day44.md index 3f09435..3ccea18 100644 --- a/2023/day44.md +++ b/2023/day44.md @@ -123,3 +123,4 @@ student = Student("John", "Canada", "Computer Science") person.speak() # "Hello, my name is Rishab and I am from Canada." student.speak() # "Hello, my name is John and I am a Computer Science major." ``` + See you tomorrow in [Day 45](day45.md). \ No newline at end of file diff --git a/2023/day45.md b/2023/day45.md index 9672bbb..64804ad 100644 --- a/2023/day45.md +++ b/2023/day45.md @@ -122,3 +122,6 @@ Output: - [pdb - The Python Debugger](https://docs.python.org/3/library/pdb.html) - [re - Regular expressions operations](https://docs.python.org/3/library/re.html) - [datetime - Basic date and time types](https://docs.python.org/3/library/datetime.html) + + See you tomorrow in [Day 46](day46.md). + \ No newline at end of file diff --git a/2023/day46.md b/2023/day46.md index 8b0c6bc..7b87890 100644 --- a/2023/day46.md +++ b/2023/day46.md @@ -45,3 +45,4 @@ Having a good understanding of how these web apps work, will help you with autom You can dive deeper into how you can build APIs using Python and serverless technologies like AWS Lambda, Azure Functions etc. I have a demo on [how I built a serverless resume API](https://github.com/rishabkumar7/AzureResumeAPI). +See you tomorrow in [Day 47](day47.md). diff --git a/2023/day47.md b/2023/day47.md index ad354e4..b89b27b 100644 --- a/2023/day47.md +++ b/2023/day47.md @@ -60,3 +60,5 @@ In this example, we're using the Pulumi Python SDK to define an EC2 instance on - [Learn more about Fabric](https://docs.fabfile.org/en/stable/index.html) - [PyWinRM](https://github.com/diyan/pywinrm) - [Pulumi - IaC Tool](https://www.pulumi.com/docs/reference/pkg/python/pulumi/) + +See you tomorrow in [Day 48](day48.md). diff --git a/2023/day48.md b/2023/day48.md index 110fce1..daaabac 100644 --- a/2023/day48.md +++ b/2023/day48.md @@ -153,3 +153,5 @@ Here is how it would look, I have 2 blog posts and have some gifs in my blog pos If we click on the `hello` blog post: ![Hello blog post](/2023/images/day48-2.png) + +See you tomorrow in [Day 49](day49.md). diff --git a/2023/day49.md b/2023/day49.md index f813768..0a1dc24 100644 --- a/2023/day49.md +++ b/2023/day49.md @@ -1,5 +1,14 @@ # Day 49: AWS Cloud Overview +Welcome to the AWS section of the 90 Days of DevOps! Picking 7 items to learn about is difficult for several reasons: + +1. At last count, there were 250+ AWS services +2. Each service could get it's own multi-day deep dive 😅 + +Because of that, we're going to do a gentle intro that starts off easy, goes into some very DevOps-salient services, then ends with a section-capstone project that will give you a lot of exposure to AWS DevOps services. + +I hope you enjoy the next 7 days as much as I did creating them. If you have any questions feel free to ask! + AWS Cloud is a cloud computing platform provided by Amazon Web Services (AWS). It offers a wide range of services, including computing, storage, networking, database, analytics, machine learning, security, and more. AWS Cloud allows businesses and organizations to access these services on a pay-as-you-go basis, which means they only pay for what they use and can scale their resources up or down as needed. ![](images/day49-1.png) @@ -8,7 +17,7 @@ AWS Cloud is a cloud computing platform provided by Amazon Web Services (AWS). I One of the main benefits of AWS Cloud is its flexibility. You can choose the services that best meet your needs and only pay for what you use. This makes it an ideal solution for small businesses, startups, and enterprises, as it allows them to access the resources they need without having to make a significant upfront investment in infrastructure. -## Security +## Security Another benefit of AWS Cloud is its security. AWS has a number of security measures in place to protect your data and resources, including encryption, identity and access management, and network security. It also has a number of compliance programs in place, including HIPAA, PCI DSS, and GDPR, to ensure that your data is secure and compliant with relevant regulations. @@ -20,13 +29,13 @@ One of the most popular services offered by AWS Cloud is Amazon Elastic Compute ![](images/day49-2.png) -## S3 +## S3 Another popular service offered by AWS Cloud is Amazon Simple Storage Service (S3). S3 is an object storage service that allows you to store and retrieve large amounts of data from anywhere on the internet. It is highly scalable, durable, and secure, making it an ideal solution for storing and managing data in the cloud. ![](images/day49-3.png) -## Databases +## Databases AWS Cloud also offers a range of other services, including Amazon Relational Database Service (RDS) for managing databases, Amazon Redshift for data warehousing and analytics, and Amazon Elasticsearch Service for search and analytics. These services make it easy to build and manage complex applications in the cloud, without having to worry about infrastructure or scaling. @@ -36,3 +45,4 @@ Overall, AWS Cloud is a powerful and flexible cloud computing platform that offe ## Resources +See you tomorrow in [Day 50](day50.md). diff --git a/2023/day50.md b/2023/day50.md index 9a0cfa6..d485968 100644 --- a/2023/day50.md +++ b/2023/day50.md @@ -41,4 +41,5 @@ Once you have access to your free tier account, there are a few additional steps ## Resources [Create your free AWS account](https://youtu.be/uZT8dA3G-S4) -[Generate credentials, budget, and billing alarms via CLI](https://youtu.be/OdUnNuKylHg) \ No newline at end of file +[Generate credentials, budget, and billing alarms via CLI](https://youtu.be/OdUnNuKylHg) +See you in [Day 52](day52.md). diff --git a/2023/day51.md b/2023/day51.md index 43edf7d..3798f7e 100644 --- a/2023/day51.md +++ b/2023/day51.md @@ -22,4 +22,6 @@ In addition to these benefits, CloudFormation also offers a range of other featu [AWS CloudFormation User Guide](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html) -[AWS CloudFormation Getting Started step-by-step guides](https://aws.amazon.com/cloudformation/getting-started/) \ No newline at end of file +[AWS CloudFormation Getting Started step-by-step guides](https://aws.amazon.com/cloudformation/getting-started/) + +See you in [Day 52](day52.md). \ No newline at end of file diff --git a/2023/day52.md b/2023/day52.md index e69de29..56856d7 100644 --- a/2023/day52.md +++ b/2023/day52.md @@ -0,0 +1,57 @@ +# Day 52: Identity and Access Management (IAM) + +As cloud computing continues to gain popularity, more and more organizations are turning to cloud platforms to manage their infrastructure. However, with this comes the need to ensure proper security measures are in place to protect data and resources. One of the most critical tools for managing security in AWS is Identity and Access Management (IAM). + +## What is AWS IAM? +|![](images/day52-1.png)| +|:-:| +| IAM is (1) WHO (2) CAN ACCESS (3) WHAT| + + +AWS IAM is a web service that allows you to manage users and their access to AWS resources. With IAM, you can create and manage AWS users and groups, control access to AWS resources, and set permissions that determine what actions users can perform on those resources. IAM provides fine-grained access control, which means that you can grant or deny permissions to specific resources at a granular level. + +IAM is an essential tool for securing your AWS resources. Without it, anyone with access to your AWS account would have unrestricted access to all your resources. With IAM, you can control who has access to your resources, what actions they can perform, and what resources they can access. IAM also enables you to create and manage multiple AWS accounts, which is essential as large organizations will always have many accounts that will need some level of interaction with each other: + +|![](images/day52-2.png)| +|:-:| +| Multi-Account IAM access is essential knowledge| + + +## How to Get Started with AWS IAM + +Getting started with AWS IAM is straightforward. Here are the steps you need to follow: + +### Step 1: Create an AWS Account + +The first step is to create an AWS account if you don't already have one. We did this on day 50 so you should be good to go 😉 + +### Step 2: Set up IAM + +Once you have an AWS account, you can set up IAM by navigating to the IAM console. The console is where you'll manage IAM users, groups, roles, and policies. + +### Step 3: Create an IAM User + +The next step is to create an IAM user. An IAM user is an entity that you create in IAM that represents a person or service that needs access to your AWS resources. When you create an IAM user, you can specify the permissions that the user should have. One of the homework assignments from Day 50 was to [Create an IAM user](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html), if you haven't completed that go back and make one now. + +### Step 4: Create an IAM Group + +After you've created an IAM user, the next step is to create an IAM group. An IAM group is a collection of IAM users. When you create an IAM group, you can specify the permissions that the group should have. Watch "IAM Basics" and read "IAM User Guide:Getting Started" in the resources section to accomplish this. + +### Step 5: Assign Permissions to the IAM Group + +Once you've created an IAM group, you can assign permissions to the group. This involves creating an IAM policy that defines the permissions that the group should have. You can then attach the policy to the group. Watch "IAM Tutorial & Deep Dive" and go through the IAM Tutorial in the resources section to accomplish this. + +### Step 6: Test the IAM User + +After you've assigned permissions to the IAM group, you can test the IAM user to ensure that they have the correct permissions. To do this, you can log in to the AWS Management Console using the IAM user's credentials and attempt to perform the actions that the user should be able to perform. + +## Resources: +[IAM Basics](https://youtu.be/iF9fs8Rw4Uo) + +[IAM User Guide: Getting started](https://docs.aws.amazon.com/IAM/latest/UserGuide/getting-started.html) + +[IAM Video Tutorial & Deep Dive](https://youtu.be/ExjW3HCFG1U) + +[IAM Tutorial: Delegate access across AWS accounts using IAM roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/tutorial_cross-account-with-roles.html) + +See you in [Day 53](day53.md). diff --git a/2023/day53.md b/2023/day53.md index e69de29..776e832 100644 --- a/2023/day53.md +++ b/2023/day53.md @@ -0,0 +1,50 @@ +# Day 53: AWS Systems Manager + +![](images/day53-01.png) + +AWS Systems Manager is a fully managed service that allows users to manage and automate operational tasks both on their AWS and on-premises resources. It provides a centralized platform for managing AWS resources, virtual machines, and applications. It enables DevOps professionals to automate operational tasks, maintain compliance, and reduce operational costs. + +With AWS Systems Manager, users can perform tasks such as automating patch management, automating OS and application deployments, creating and managing Amazon Machine Images (AMIs), and monitoring resource utilization. It also provides a set of tools for configuring and managing instances, which includes run commands, state manager, inventory, and maintenance windows. + +Furthermore, AWS Systems Manager provides a unified view of operational data, allowing users to visualize and monitor operational data across their AWS infrastructure, including EC2 instances, on-premises servers, and AWS services. This allows users to identify and resolve issues faster, improving operational efficiency and reducing downtime. + +## How to Get Started with AWS System Manager? + +Getting started with AWS System Manager is as easy as 1, 2, 3, 4 😄: + +![](images/day53-03.png) + +### Step 1: Navigate to the AWS System Manager Console + +Once you have an AWS account, create 2 windows servers and 2 linus servers (free tier of course 😉) and navigate to the AWS System Manager console. The console provides a unified interface for managing AWS resources, including EC2 instances, on-premises servers, and other resources: + +![](images/day53-02.png) +Click the "get started" button and choose your preferred region (I picked us-east-1) + +### Step 2: Choose a configuration type + +The next step is to configure AWS Systems Manager to manage your resources. You can do this by selecting one of the quick setup common tasks (or create a custom setup type of your own choosing): +![](images/day53-04.png) +For my needs I'm going to choose "Patch Manager" - in the resources below we will have additional scenarios that you can experiment with. Watch "Patch and manage your AWS Instances in MINUTES with AWS Systems Manager" to see this step in action. + +### Step 3: Specify configuration options + +Each configuration type has a unique set of parameters to apply for this step... +|![](images/day53-05.png)| +|:-:| +| You will see something different depending on which quick start config you chose| + +so I won't be getting into the required arguments for each one. Generally speaking the next step is to create a resource group to organize your resources. Resource groups are collections of resources that share common attributes. By grouping resources, you can view them collectively and apply policies and actions to them together. Watch "Patch and manage your AWS Instances in MINUTES with AWS Systems Manager" to see this step in action. + +### Step 4: Deploy, Review, and Manage Your Resources + +Once you have created a resource group, you can view and manage your resources from the AWS System Manager console. You can also create automation workflows, run patch management, and perform other operations on your resources. + +## Resources: +[AWS Systems Manager Introduction](https://youtu.be/pSVK-ingvfc) + +[Patch and manage your AWS Instances in MINUTES with AWS Systems Manager](https://youtu.be/DEQFJba3h4M) + +[Getting started with AWS System Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-launch-managed-instance.html) + +See you in [Day 54](day54.md). diff --git a/2023/day54.md b/2023/day54.md index e69de29..777ee55 100644 --- a/2023/day54.md +++ b/2023/day54.md @@ -0,0 +1,31 @@ +# Day 54: AWS CodeCommit + +![](images/day54-01.png) + +AWS CodeCommit is a fully managed source control service provided by Amazon Web Services (AWS) that makes it easy for developers to host and manage private Git repositories. Think "GitHub but with less features" 🤣 (j/k, see the resource "CodeCommit vs GitHub" for a breakdown) It allows teams to collaborate on code and keep their code securely stored in the cloud, with support for secure access control, encryption, and automatic backups. + +With AWS CodeCommit, developers can easily create, manage, and collaborate on Git repositories with powerful code review and workflow tools. It integrates seamlessly with other AWS services like AWS CodePipeline and AWS CodeBuild, making it easier to build and deploy applications in a fully automated manner. + +Some key features of AWS CodeCommit include: + +- Git-based repositories with support for code reviews and pull requests +- Integration with AWS Identity and Access Management (IAM) for secure access control (this is a big plus) +- Encryption of data at rest and in transit +- Highly scalable and available, with automatic backups and failover capabilities +- Integration with other AWS developer tools like AWS CodePipeline and AWS CodeBuild + +In order to effectively leverage CodeCommit, you of course need to know how to use Git. There are [many](https://www.youtube.com/playlist?list=PL2rC-8e38bUXloBOYChAl0EcbbuVjbE3t) [excellent](https://youtu.be/tRZGeaHPoaw) [Git](https://youtu.be/USjZcfj8yxE) [tutorials](https://youtu.be/RGOj5yH7evk) out there, (and that's not my section anyway 😉) so I won't go into that myself. + +Overall, AWS CodeCommit is a powerful tool for teams that need to collaborate on code, manage their repositories securely, and streamline their development workflows. + +## Resources: + +[AWS CodeCommit User Guide](https://docs.aws.amazon.com/codecommit/latest/userguide/welcome.html) + +[AWS CodeCommit Overview](https://youtu.be/5kFmfgFYOx4) + +[AWS CodeCommit tutorial: your first Repo, Commit and Push](https://youtu.be/t7M8pHCh5Xs) + +[AWS CodeCommit vs GitHub: Which will Shine in 2023?](https://appwrk.com/aws-codecommit-vs-github) + +See you in [Day 55](day55.md). diff --git a/2023/day55.md b/2023/day55.md index e69de29..b12958e 100644 --- a/2023/day55.md +++ b/2023/day55.md @@ -0,0 +1,66 @@ +# Day 55: AWS CodePipeline + +On this last day of AWS services we are going to talk about a big one that has a lot of moving parts and integrations. There are a few free resources out there that will help in your learning/understanding of this... but honestly some of the best ones will cost you some money. I will list them out seperately in the resources section and call them out, but I would be remiss in NOT mentioning them as they are fantastic for learning this complex service + +CodePipeline is a fully managed continuous delivery service that allows you to automate your IaC or software release processes. It enables you to create pipelines that build, test, and deploy your code changes continuously and (with proper testing in place) reliably: + +![](images/day55-01.jpg) + +With CodePipeline, you can create pipelines that automate your build, test, and deployment workflows, ensuring that your code changes are reliably deployed to your target environments. It enables you to achieve faster release cycles, improve collaboration among development and operations teams, and improve the overall quality and reliability of your software releases. + +AWS CodePipeline integrates with other AWS services: + +- [Source Action Integrations](https://docs.aws.amazon.com/codepipeline/latest/userguide/integrations-action-type.html#integrations-source) +- [Build Action Integrations](https://docs.aws.amazon.com/codepipeline/latest/userguide/integrations-action-type.html#integrations-build) +- [Test Action Integrations](https://docs.aws.amazon.com/codepipeline/latest/userguide/integrations-action-type.html#integrations-test) +- [Deploy Action Integrations](https://docs.aws.amazon.com/codepipeline/latest/userguide/integrations-action-type.html#integrations-deploy) +- [Approval Action Integrations](https://docs.aws.amazon.com/codepipeline/latest/userguide/integrations-action-type.html#integrations-approval) +- [Invoke Action Integrations](https://docs.aws.amazon.com/codepipeline/latest/userguide/integrations-action-type.html#integrations-invoke) + + It also integrates with third-party tools such as GitHub, Jenkins, and Bitbucket. You can use AWS CodePipeline to manage your application updates across multiple AWS accounts and regions. + +## Getting started with AWS CodePipeline + +To get started with AWS CodePipeline, there are several excellent [tutorials](https://docs.aws.amazon.com/codepipeline/latest/userguide/tutorials.html) in the [AWS User Guide](https://docs.aws.amazon.com/codepipeline/latest/userguide/welcome.html). They all basically break down into the following 3 steps: + +### Step 1: Create an IAM role + +You need to create an IAM role that allows AWS CodePipeline to access the AWS resources required to run your pipelines. To create an IAM role, review the steps from [Day 52](day52.md) + +### Step 2: Create a CodePipeline pipeline + +To create a CodePipeline pipeline, go to the AWS CodePipeline console, click on the "Create pipeline" button, and then follow the instructions to create your pipeline. You will need to specify the source location for your code, the build provider you want to use, the deployment provider you want to use, and the IAM role you created in step 2. + +### Step 3: Test and deploy your code changes + +Once you have created your CodePipeline pipeline, you can test and deploy your code changes. AWS CodePipeline will automatically build, test, and deploy your code changes to your target environments. You can monitor the progress of your pipeline in the AWS CodePipeline console. + +## Capstone Project + +To tie up this AWS section of the 90 Days of DevOps, I recommend that you go through Adrian Cantrill's excellent mini-project, the [CatPipeline](https://www.youtube.com/playlist?list=PLTk5ZYSbd9MgARTJHbAaRcGSn7EMfxRHm). In it you will be exposed to CodeCommit, CodeBuild, CodeDeploy, and CodePipeline in a fun little project that will give you a taste of a day in the life of a DevOps engineer. + +- [YouTube CatPipeline Playlist](https://www.youtube.com/playlist?list=PLTk5ZYSbd9MgARTJHbAaRcGSn7EMfxRHm) +- [GitHub CatPipeline Repo](https://github.com/acantril/learn-cantrill-io-labs/tree/master/aws-codepipeline-catpipeline) + +## Resources (Free) + +[AWS: Real-world CodePipeline CI/CD Examples](https://youtu.be/MNt2HGxClZ0) + +[AWS CodePipeline User Guide](https://docs.aws.amazon.com/codepipeline/latest/userguide/welcome.html) + +[AWS CodePipeline Tutorials](https://docs.aws.amazon.com/codepipeline/latest/userguide/tutorials.html) + +[AWS CodeCommit tutorial: your first Repo, Commit and Push](https://youtu.be/t7M8pHCh5Xs) + +[AWS CodeCommit vs GitHub: Which will Shine in 2023?](https://appwrk.com/aws-codecommit-vs-github) + +## Resources (Paid) + +There are a number of excellent instructors out there and picking 2-3 is always hard, but [Adrian Cantrill](https://learn.cantrill.io/), [Andrew Brown](https://www.exampro.co/), and [Stephane Maarek](https://www.udemy.com/user/stephane-maarek/) always come to mind when discussing fantastic content out there. + +## Final Thoughts + +I hope that this section of the 90 Days of DevOps has given you a taste of what is available in the AWS ecosystem. + +Good luck in your studies! Up next is Red Hat OpenShift! +See you in [Day 56](day56.md). diff --git a/2023/day56.md b/2023/day56.md index df3da52..9e15c62 100644 --- a/2023/day56.md +++ b/2023/day56.md @@ -10,21 +10,20 @@ Of course for this section, we are dedicating ourselves to Red Hat OpenShift. I decided to cheat a bit for this opening, and consult ChatGPT, the AI Service of the moment, to provide an opinion on why Red Hat OpenShift. -``` -Why choose an enterprise Kubernetes platform such as Red Hat OpenShift? +>Why choose an enterprise Kubernetes platform such as Red Hat OpenShift? +> +> +>1. Automation and Enterprise-grade Security: Red Hat OpenShift provides an automated platform to help you deploy, manage, and scale your applications quickly and easily while ensuring that the underlying infrastructure is secure. +> +>2. Open Source: Red Hat OpenShift is built on top of open source technologies such as Kubernetes, Docker, and Red Hat Enterprise Linux. This ensures that your applications are always up-to-date with the latest technologies. +> +>3. Continuous Integration and Delivery: Red Hat OpenShift provides an integrated set of tools for continuous integration and delivery that make it easy to deploy and manage your applications in a secure and reliable manner. +> +>4. Scalability and High Availability: Red Hat OpenShift provides a highly available and scalable platform that can handle large amounts of traffic and data without any downtime. +> +>5. Cost Savings: Red Hat OpenShift provides a cost-effective solution for running your applications in the cloud. You can save money on infrastructure and operations costs by leveraging OpenShift's automated platform. -1. Automation and Enterprise-grade Security: Red Hat OpenShift provides an automated platform to help you deploy, manage, and scale your applications quickly and easily while ensuring that the underlying infrastructure is secure. - -2. Open Source: Red Hat OpenShift is built on top of open source technologies such as Kubernetes, Docker, and Red Hat Enterprise Linux. This ensures that your applications are always up-to-date with the latest technologies. - -3. Continuous Integration and Delivery: Red Hat OpenShift provides an integrated set of tools for continuous integration and delivery that make it easy to deploy and manage your applications in a secure and reliable manner. - -4. Scalability and High Availability: Red Hat OpenShift provides a highly available and scalable platform that can handle large amounts of traffic and data without any downtime. - -5. Cost Savings: Red Hat OpenShift provides a cost-effective solution for running your applications in the cloud. You can save money on infrastructure and operations costs by leveraging OpenShift's automated platform. -``` - # What does Red Hat OpenShift bring to the party? Red Hat has developed OpenShift based on a Open Souce platform (Kubernetes) and even distributes the OpenShift platform enhancements as Open Source as well under the guise of [OpenShift Kubernetes Distribution (OKD)](https://www.okd.io). @@ -48,7 +47,7 @@ Again, this is not an exhausive list: You can read a more indepth coverage of the benefits and features of Red Hat OpenShift in [this datasheet](https://www.redhat.com/en/resources/openshift-container-platform-datasheet), or a full breakdown on the [Red Hat Developers page](https://developers.redhat.com/products/openshift/overview) -![OpenShift Overview](images/cl-OpenShift-container-platform-datasheet-f31593_image1.png) +![OpenShift Overview](images/Day56-OpenShift-container-platform-datasheet.png) ## Where can I deploy OpenShift? @@ -108,4 +107,5 @@ In [day 57](/day57.md) we will dive into the Architecture and components of Open - [OKD](https://www.okd.io/) - [Official Red Hat OpenShift product page](https://www.redhat.com/en/technologies/cloud-computing/openshift) -- [Red Hat Hybrid Cloud Learning Hub](https://cloud.redhat.com/learn) \ No newline at end of file +- [Red Hat Hybrid Cloud Learning Hub](https://cloud.redhat.com/learn) + diff --git a/2023/day57.md b/2023/day57.md index e69de29..6c025e3 100644 --- a/2023/day57.md +++ b/2023/day57.md @@ -0,0 +1,163 @@ +# Red Hat OpenShift - Architecture + +## Base Operating System - Red Hat CoreOS + +[In 2018 Red Hat acquired](https://www.redhat.com/en/about/press-releases/red-hat-acquire-coreos-expanding-its-kubernetes-and-containers-leadership) a small startup called CoreOS, which designed and produced the cloud-native focused operating system "CoreOS". + +This product was folding into the portfolio as "Red Hat CoreOS" (RHCOS), to become their primary operating system for Red Hat OpenShift. In fact, RHCOS is only supported for use as part of a Red Hat OpenShift environment. Meaning you cannot just spin an instance to use as your general purpose linux. This is different to competitors such as VMware, whom are the guardians of [PhotonOS](https://vmware.github.io/photon/assets/files/html/3.0/Introduction.html), which is the base OS for their Tanzu Kubernetes Grid platform, as well as many other of their software appliances, and available for general use by the community as an open-source project. + +The most important note about RHCOS, is that it is the only supported operating system for the Red Hat OpenShift Control Plane (a.k.a Master) nodes. For Compute Plane (a.k.a Worker) nodes, you have the choice to deploy either RHCOS or[ Red Hat Enterprise Linux (RHEL)](https://www.redhat.com/en/technologies/linux-platforms/enterprise-linux) as the operating system. You can read about the RHCOS [key features here](https://docs.openshift.com/container-platform/4.12/architecture/architecture-rhcos.html#rhcos-key-features_architecture-rhcos). + +RHCOS is designed as a minimal user-interaction platform from a configuration standpoint. It is not [encouraged to directly configure](https://docs.openshift.com/container-platform/4.12/architecture/architecture-rhcos.html#rhcos-configured_architecture-rhcos) a RHCOS instance, as it's management comes from the Red Hat OpenShift platform itself, meaning any configuarations would be controlled via Kubernetes Objects. + +Bringing a RHCOS machine online is enabled through [Ignition](https://docs.openshift.com/container-platform/4.12/architecture/architecture-rhcos.html#rhcos-about-ignition_architecture-rhcos), a utility designed to manipulate the disks during initial configuration of the machine. This runs at first boot, and typically will be used to configure disk partitions for the machine, and provide the necessary details for the machine to connect ot the bootstrapping machine in the environment, from which it will recieve it's configuration to become part of the Red Hat OpenShift Cluster. + +- When booting an RHCOS machine, you provide an ignition file, which contains the various components/settings for first boot. This is a JSON file which is base64 encoded. Typically for a Cluster Node, this will be details on how to connect to the bootstrap machine. For the bootstrap machine, when building a new Red Hat OpenShift cluster, this ignition file will contain details such as secrets/locations to pull the necessary Red Hat software and configuration manifests for the Red Hat OpenShift Cluster. +- Ignition files are typically created from the install-config.yaml file used with the OpenShift-Install CLI tool. + +To summarize this section, RHCOS brings the following, as a specifically designed cloud native operating system: + +- Ignition, for first boot configuration of machines. +- CRI-O, a Kubernetes native container runtime implementation. (OpenShift 3.x (Deprecated version) installations used Docker). +- Kubelet, a kubernetes node agent for launching and monitoring containers. + +## Product Architecture + +At a basic level, Red Hat OpenShift if built ontop of the open-source platform, Kubernetes. Meaning that all components you have learned about from this base platform, are apparent and available in the Red Hat OpenShift platform. + +If you haven't visited the [#90DaysOfDevOps - Kubernetes section](https://github.com/MichaelCade/90DaysOfDevOps/blob/main/2022.md#kubernetes), then I urge you to do so, before continuing with this section on Red Hat OpenShift. + +![Red Hat OpenShift - Product Architect](images/Day57%20-%20Red%20Hat%20OpenShift%20Architecture/Red%20Hat%20OpenShift%20-%20Product%20Architecture.png) + +Ontop of the Kubernetes platform, Red Hat then delivers it's enterprise sauce sprinkled around to help make your cloud native strategy a sucess: + +- Ability to deploy to variety of clouds or your on-premises datacenter. +- Integrating Red Hat Technologies from Red Hat Enterprise Linux +- Open Source development mode. This means source code is available in public software repositories. + +Red Hat believes that although Kubernetes is a great platform for managing your applicaitons, it doesn't do a great job of platform-level requirements management (think supporting services to make your apps work) or deployment process handling. Therefore they layer ontop they additional components to give you a full enterprise ready Kubernetes platform. + +- Custom Operating system based on Red Hat Enterprise Linux (RHCOS)(See above). +- Simplified installation and lifecycle management at a cluster platform level (See below). +- Operators - serving as platform foundation, removing the need to upgrade operating systems and control-plane applications, leading to a simplier lifecycle management. This is based on [OperatorHub](https://operatorhub.io/). (See below for an explanation). +- Red Hat Quay Container Image Registry - based on [Quay.io](quay.io) +- Other Enhancements to the base Kubernetes platform include: + - Software Defined Networking + - Authentication + - Log aggregation + - Montioring + - Routing + +And finally to round off, you can interact with a Red Hat OpenShift Cluster, either via a "Comprehensive" web console, or the custom [OpenShift CLI tool ```oc```](https://docs.openshift.com/container-platform/4.12/cli_reference/openshift_cli/getting-started-cli.html), which is a mix of ```kubectl```, ```kubeadm``` and some specific CLI for Red Hat OpenShift. + +The below image nicely finishes off this section covering the product and it's components and why you would potentially choose Red Hat OpenShift over a vanilla Kubernetes platform. + +- Simplification of creating and managing a cluster +- Built in tooling for the Application Developer to create and deploy their applications, with workload lifecycle management included, such as ability to monitor and scale those applications. + +![Red Hat OpenShift Container Platform Lifecycle](images/Day57%20-%20Red%20Hat%20OpenShift%20Architecture/OpenShift%20Container%20Platform%20lifecycle.png) + +For a further deep dive into the control plane architecture, you can read the [official documentation here](https://docs.openshift.com/container-platform/4.12/architecture/control-plane.html). + +### What is an Operator? + +A little side note here, to explain what an Operator is in regards to a Kubernetes platform. It was created by CoreOS, and hence it's significance in the Red Hat OpenShift Platform. + +> Operators implement and automate common Day-1 (installation, configuration, etc) and Day-2 (re-configuration, update, backup, failover, restore, etc.) activities in a piece of software running inside your Kubernetes cluster, by integrating natively with Kubernetes concepts and APIs. We call this a Kubernetes-native application. With Operators you can stop treating an application as a collection of primitives like Pods, Deployments, Services or ConfigMaps, but instead as a single object that only exposes the knobs that make sense for the application. + +[Source](https://operatorhub.io/what-is-an-operator) + +# Installation methods for Red Hat OpenShift + +Red Hat OpenShift Container Platform (OCP) offers the flexibility of: + +- Deploy a cluster on provisioned infrastructure and the cluster it maintains. +- Deploy a cluster on infrastructure that you prepare and maintain. + +And with these options, there are two types of installation methods/deployment methods for clusters: + +- Installer provisioned infrastructure (IPI) +- User provisioned infrastructure (UPI) + +There is a third method, which is Agent-based, providing the flexbility of UPI, driven by the Assisted Installer (AI) tool. + +Either method, IPI or UPI is driven from the ```openshift-install``` installation program, which is a CLI tool provided for Linux and Mac Operating systems only. + +The installation program will generate the necessary components to build a cluster such as the Ignition files for bootstrap, master and worker machines. It will further monitor the installation for known targets that an installation must achieve for a successful deployment of a cluster, and provide error handling in the event of a failed cluster deployment, by collecting the necessary troubleshooting logs. + +To visualise bringing all these moving parts together, I have provided the below image from the Red Hat OpenShift documentation. + +A cluster definition is created in a special file called ```install-config.yaml```, this file contains the following information: + +- Cluster name +- Base domain (FDQN for the network where the cluster will run) +- Details to pull the software from an image registry (Pull Secret) +- SSH Key (so you can access the nodes for troubleshooting) +- Specific Infrastructure platform details (Login details, which networks and storage to use, for example) +- Workload Customizations, such what instance types to use for your Control Plane (Master) and Compute Plane (Worker) nodes. + +There is also additional files which may be stored along side the root of the ```install-config.yaml``` in a folder called ```manifests``` these are additional files which can be configured to assist the bootstrapping of a cluster to integrate with your infrastructure, such as your Networking platform. + +Once you have all of these files, by running the ```openshift-install``` CLI tool, this will create the ignition files for your boostrap, control plane, and compute plane nodes. Returning to the earlier descriptions of RHCOS, these files contain the first boot information to configure the Operation System and start the process of building a consistent Kubernetes cluster with minimal to no interaction. + +![OpenShift Container Platform installation targets and dependencies](images/Day57%20-%20Red%20Hat%20OpenShift%20Architecture/OpenShift%20Container%20Platform%20installation%20targets%20and%20dependencies.png) + +## Installer provisioned infrastructure (IPI) + +This is the default installation method, and preferred by Red Hat for their customers to initiate a cluster installation, as it provides a reference architectural deployment out of the box. + +The ```openshift-install``` CLI tool can act as it's own installation wizard, presenting you with a number of queries for the values it needs to deploy to your choosen platform. You can also customize the installation process to support more advanced scenerios, such as the number of machines deployed, instance type/size, CIDR range for the Kubernetes service network, + +The main point here, is that the installation software provisions the underlying infrastructure for the cluster. + +By using an IPI installation method, the provisioned cluster then has the further ability to continue to manage all aspects of the cluster and provisioned infrastructure going forward from a lifecycle management point of view. For example, if you scale the number of compute plane (worker) nodes in your cluster, the OpenShift Container Platform can interact with the underlying platform (for example, AWS, VMware vSphere) to create the new virtual machines and bootstrap them to the cluster. + + +## User provisioned infrastructure (UPI) + +With a UPI method, the OpenShift Container Platform will be installed to infrastucture that you have provided. The installation software will still be used to generate the assets needed to provision the cluster, however you will manually build the nodes and provide the necessary ignition to bring the nodes online. You must also manage the infrastructure supporting cluster resources such as: + +- Any infrastructure the nodes are deployed to/upon (Azure Stack Hub, vSphere, IBM Power, Bare Metal, for example) +- Load Balancers +- Cluster networking, including DNS records and required subnets +- Storage for both cluster infrastructure and workloads + +When using a UPI installation, you have the option to deploy your Compute Plane (worker) nodes as Red Hat Enterprise Linux machines. + +## Assisted Installer + +As mentioned earlier, the assisted installer is a kind of hybrid of the UPI method, but offers the hosting of the installation artifacts and removing the need for a bootstrap machine, essentially you provision/install your nodes from a live boot cd, which has the necessary configuration to bring up your node and pull down the rest of the hosted files from a known location. + +You can find out more from this [Red Hat blog post](How to use the OpenShift Assisted Installer), or [official documentation](https://docs.openshift.com/container-platform/4.12/installing/installing_on_prem_assisted/installing-on-prem-assisted.html) + +# Installation Process + +A temporary bootstrap machine is provisioned using IPI or UPI, which contains the necessary information to build the OpenShift cluster itself (which becomes the permanent control plane nodes). Once the control plane is online, the control plane will initiate the creation of the compute plane (worker) nodes. + +![Creating the bootstrap, control plane, and compute machines](images/Day57%20-%20Red%20Hat%20OpenShift%20Architecture/Creating%20the%20bootstrap%20control%20plane%20and%20compute%20machines.png) + +Once the control plane is initialised, the bootstrap machine is destroyed. If you are manually provisioning the platform (UPI), then you complete a number of the provisioning steps manually. + +>Bootstrapping a cluster involves the following steps: +> 1. The bootstrap machine boots and starts hosting the remote resources required for the control plane machines to boot. (Requires manual intervention if you provision the infrastructure) +> 2. The bootstrap machine starts a single-node etcd cluster and a temporary Kubernetes control plane. +> 3. The control plane machines fetch the remote resources from the bootstrap machine and finish booting. (Requires manual intervention if you provision the infrastructure) +> 4. The temporary control plane schedules the production control plane to the production control plane machines. +> 5. The Cluster Version Operator (CVO) comes online and installs the etcd Operator. The etcd Operator scales up etcd on all control plane nodes. +> 6. The temporary control plane shuts down and passes control to the production control plane. +> 7. The bootstrap machine injects OpenShift Container Platform components into the production control plane. +> 8. The installation program shuts down the bootstrap machine. (Requires manual intervention if you provision the infrastructure) +> 9. The control plane sets up the compute nodes. +> 10. The control plane installs additional services in the form of a set of Operators. +> +>The result of this bootstrapping process is a running OpenShift Container Platform cluster. The cluster then downloads and configures remaining components needed for the day-to-day operation, including the creation of compute machines in supported environments. + +# Summary + +We have covered the components that make up a Red Hat OpenShift Container Platform environment, why they are important to the environment, and what enteprise features they bring over a vanilla Kubernetes environment. We then dived into the methods available to deploy an OpenShift Cluster and the process that a Cluster build undertakes. + +In [Day 58](/day58.md) will cover the steps to install Red Hat OpenShift to a VMware vSphere environment. + +# Resources + +- [Glossary of common terms for OpenShift Container Platform architecture](https://docs.openshift.com/container-platform/4.12/architecture/index.html#openshift-architecture-common-terms_architecture-overview) \ No newline at end of file diff --git a/2023/day58.md b/2023/day58.md index e69de29..cef241d 100644 --- a/2023/day58.md +++ b/2023/day58.md @@ -0,0 +1,328 @@ +# Installing Red Hat OpenShift on VMware vSphere + +In the [previous day](day57.md) one of the areas covered was the available installation methods for Red Hat OpenShift. In this guide, I am going to detail the IPI method, where by the installation software deploys the necessary infrastructure as part of the cluster deployment. You will see that even with this method, we still get a lot of control around the deployment of our cluster. + +The platform for this example will be [VMware vSphere](https://www.vmware.com/uk/cloud-solutions/cloud-infrastructure.html), the popular hypervisor virtualisation platform available for your datacenter and public cloud environments. + +## Pre-requisites + +We will need the following: +- Jump host to run the installation software from +- Access to the DNS server which supports the infrastructure platform you are deploying to +- A pull secret file/key from the Red Hat Cloud Console website + - You can get one of these by just signing up for an account, any cluster created using this key will get a trial activation for a cluster for 60 days +- A SSH Key used for access to the deployed nodes + +### Configuring the Jump host Machine + +For this example, I've used a Ubuntu Server Virtual Machine, you can use another distribution of Linux or Mac OS X for these steps. (Note: the ```OpenShift-install``` CLI tool only supports Linux and MAC OS X) + +Download the OpenShift-Install tool and OpenShift-Client (OC) command line tool. (I’ve used version 4.12.6 in my install) + +- https://mirror.openshift.com/pub/openshift-v4/clients/ocp/ + +![OpenShift Clients Download](images/Day58%20-%20OpenShift%20Cluster%20Install/OpenShift%20Clients%20Download.jpg) + +Extract the files and copy to your /usr/bin/local directory +```` +tar -zxvf openshift-client-linux.tar.gz +tar -zxvf openshift-install-linux.tar.gz + +sudo cp openshift-install /usr/bin/local/openshift-install +sudo cp oc /usr/bin/local/oc +sudo cp kubectl /usr/bin/local/kubectl +```` +Have an available SSH key from your jump box, so that you can connect to your CoreOS VMs one they are deployed for troubleshooting purposes. Generate one using ````ssh-keygen```` if needed. + +Next, we need to download the VMware vCenter trusted root certificates and import them to your Jump Host. + +```` +curl -O https://{vCenter_FQDN}/certs/download.zip +```` + +Now unzip the file (you may need to install a software package for this ````sudo apt install unzip````), and import them to the trusted store (ubuntu uses the .crt files, hence importing the win folder). +```` +unzip download.zip +cp certs/win/* /usr/local/share/ca-certificates +update-ca-certificates +```` +You will need a user account to connect to vCenter with the correct permissions for the OpenShift-Install to deploy the cluster. If you do not want to use an existing account and permissions, you can use this [PowerCLI script](https://github.com/saintdle/PowerCLI/blob/master/Create_vCenter_OpenShift_Install_Role.ps1) to create the roles with the correct privileges based on the Red Hat documentation. + +### Configuring DNS Records + +A mandatory pre-req is DNS records. You will need the two following records to be available on your OpenShift cluster network in the same IP address space that your nodes will be deployed to. These records will follow the format: +```` + {clusterID}.{domain_name} + example: ocp412.veducate.local + *.apps.{clusterID}.{domain_name} + example: *.apps.ocp412.veducate.local +```` +If your DNS is a Windows server, you can use this [script here](https://github.com/saintdle/OCP-4.3-vSphere-Static-IP/tree/master/DNS). I've included a quick screenshot of my DNS Server settings below for both records. + +![OpenShift - Example DNS Records](images/Day58%20-%20OpenShift%20Cluster%20Install/OpenShift%20-%20Example%20DNS%20records.jpg) + +### Minimum Resources to deploy a cluster + +You need to be aware of the [minimum deployment options](https://docs.openshift.com/container-platform/4.12/installing/installing_vsphere/installing-vsphere.html#installation-minimum-resource-requirements_installing-vsphere) to successfully bring up a cluster. +```` + 1 Bootstrap + This machine is created automatically and deleted after the cluster build. + 3 Control Plane + 2 Compute Plane +```` +![OpenShift - Minimum resource requirements](images/Day58%20-%20OpenShift%20Cluster%20Install/OpenShift%20-%20Minimum%20resource%20requirements.jpg) + +## Using the OpenShift-Install tool + +Now that we have our pre-reqs in place, we can start to deploy our cluster. When using the ````OpenShift-Install```` tool, you have three main command line options when creating a cluster + +>````openshift-install create cluster```` +>- This will run you through a wizard to create the install-config.yaml file and then create the cluster automatically using terraform which is packaged as part of the installer software (meaning you don't need terraform on your system as a pre-req). +>- If you run the below two commands listed, you can then still run this command to provision your cluster. +> +>````openshift-install create install-config```` +>- This will run you through a wizard to create the install-config.yaml file, and leave it in the root directory, or directory you specify with the --dir= argument. +>- It is supported for you to modify the install-config.yaml file, before running the above ```create cluster``` command. +> +>````openshift-install create manifests```` +>- This will create the manifests folder which controls the provisioning of the cluster. Most of the time this command is only use with UPI installations. However some platform integrations support IPI installation, such as VMware's NSX Advanced Load Balancer, but they require you create the manifest folder and upload adding YAML files to this folder, which helps OpenShift integrate to the Load Balancer upon deployment.. + +There are other commands such as ```create ignition``` which would be used for when you are performing the UPI installation method. + +![OpenShift-install create help](images/Day58%20-%20OpenShift%20Cluster%20Install/OpenShift-Install%20create%20help.jpg) + +Now let's jump into creating our cluster in the easiest possible way, with the ```openshift-install create cluster```command and press enter, this will take you into the wizard format. Below I've selected my SSH key I want to use and the Platform as vSphere. + +![OpenShift-Install Create cluster](images/Day58%20-%20OpenShift%20Cluster%20Install/OpenShift-Install%20create%20cluster.jpg) + +Next I enter the vCenter FQDN, the username, and password. The tool then connects to the vCenter and pulls the necessary datastores and networks I can deploy to. If you have missed the certificate step above, it will error out here. + +After selecting datastore and the network, I need to now input the address for: +> api.{cluster_name}.{base_domain} +> *.apps.{cluster_name}.{base_domain} + +However I hit a bug ([GitHub PR](https://github.com/openshift/installer/pull/6783),[Red Hat Article](https://access.redhat.com/solutions/6994972)) in the installer, where by the software installer is hardcoded to only accept addresses in the 10.0.0.0/16 range. + +![OpenShift-Install create cluster - Sorry, your reply was invalid: IP expected to be in one of the machine networks: 10.0.0.0/16](images/Day58%20-%20OpenShift%20Cluster%20Install/OpenShift-Install%20create%20cluster%20-%20Sorry%2C%20your%20reply%20was%20invalid-%20IP%20expected%20to%20be%20in%20one%20of%20the%20machine%20networks-%2010.0.0.0-16.jpg) + +The current work around for this is to run ````openshift-install create install-config```` provide ip addresses in the 10.0.0.0/16 range, and then alter the ```install-config.yaml``` file manually before running ````openshift-install create cluster````, which will read the available ```install-config.yaml``` file and create the cluster (rather than presenting you another wizard). + +So, let's back track a bit, and do that. Running the ```create install-config``` argument, provides the same wizard run through as before. + +In the wizard, I've provided IP's on the range from above, and set my base domain and cluster name as well. The final piece is to paste in my Pull Secret from the Red Hat Cloud console. + +![OpenShift-install create install-config](images/Day58%20-%20OpenShift%20Cluster%20Install/OpenShift-install%20create%20install-config.jpg) + +Now if I run ```ls``` on my current directory I'll see the ```install-config.yaml``` file. It is recommended to save this file now before you run the ```create cluster``` command, as this file will be removed after this, as it contains plain text passwords. + +I've highlighted in the below image the lines we need to alter. + +![OpenShift-install install-config.yaml file](images/Day58%20-%20OpenShift%20Cluster%20Install/OpenShift-install%20-%20install-config.yaml%20file.jpg) + +For the section +```` + machineNetwork: + - cidr: 10.0.0.0/16 +```` +This needs to be changed the network subnet the nodes will run on. And for the platform section, you need to map the right IP addresses from your DNS records. + +```` +platform: + vsphere: + apiVIP: 192.168.200.192 <<<<<<< This is your api.{cluster_name}.{base_domain} DNS record + cluster: Cluster-1 + folder: /vEducate-DC/vm/OpenShift/ + datacenter: vEducate-DC + defaultDatastore: Datastore01 + ingressVIP: 192.168.200.193 <<<<<<< This is your *.apps.{cluster_name}.{base_domain} DNS record +```` + +I've also included a further example of a ```install-config.yaml``` file, I want to highlight under the "compute" and "controlPlane" sections, where by I've specified resouce configuration settings for my virtual machines. You cannot change these below the minimum specified in the documentation, otherwise you will your cluster will not build successfully. + +You can read about further [supported customizations here](https://github.com/openshift/installer/blob/master/docs/user/customization.md). + +```` +apiVersion: v1 +baseDomain: veducate.local +compute: +- hyperthreading: Enabled + name: worker + replicas: 1 + platform: + vsphere: + cpus: 8 + coresPerSocket: 4 + memoryMB: 16384 + osDisk: + diskSizeGB: 120 +controlPlane: + hyperthreading: Enabled + name: master + replicas: 3 + platform: + vsphere: + cpus: 8 + coresPerSocket: 4 + memoryMB: 16384 + osDisk: + diskSizeGB: 120 +metadata: + creationTimestamp: null + name: ocp48 +networking: + clusterNetwork: + - cidr: 10.128.0.0/14 + hostPrefix: 23 + machineNetwork: + - cidr: 10.0.0.0/16 + networkType: OpenShiftSDN + serviceNetwork: + - 172.30.0.0/16 +platform: + vsphere: + apiVIP: 192.168.200.192 + cluster: Cluster-1 + folder: /vEducate-DC/vm/OpenShift/ + datacenter: vEducate-DC + defaultDatastore: Datastore01 + ingressVIP: 192.168.200.193 + network: "network_NW1" + password: Password@! + username: admin@veducate.local + vCenter: vcenter.veducate.local +publish: External +pullSecret: '{"auths":{"cloud.openshift.com":{"auth":"bxxxxxx==","email":"openshift@veducate.co.uk"},"registry.redhat.io":{"auth":"Nxxx=","email":"openshift@veducate.co.uk"}}}' +sshKey: | + ssh-rsa AAAABxxxxxx openshift@veducate +```` +Now that we have our correctly configured ```install-config.yaml``` file, we can proceed with the installation of the cluster, which after running the ```openshift-install create cluster``` command, is hands off from this point forward. The system will output logging to the console for you, which you can modify using the ```--log-level=``` argument at the end of the command. + +Below is the normal output without any modifiers. We now have a working Red Hat OpenShift Cluster, and can use the export command provided to access the cluster via the ```oc``` CLI tool, or you can use ```kubectl``` + +```` +dean@dean [ ~/90days-ocp412 ] # ./openshift-install create cluster +INFO Consuming Install Config from target directory +INFO Creating infrastructure resources... + +INFO Waiting up to 20m0s (until 9:52AM) for the Kubernetes API at https://api.90days-ocp.simon.local:6443... +INFO API v1.25.4+18eadca up +INFO Waiting up to 30m0s (until 10:04AM) for bootstrapping to complete... +INFO Destroying the bootstrap resources... +INFO Waiting up to 40m0s (until 10:30AM) for the cluster at https://api.90days-ocp.simon.local:6443 to initialize... +INFO Checking to see if there is a route at openshift-console/console... +INFO Install complete! +INFO To access the cluster as the system:admin user when using 'oc', run 'export KUBECONFIG=/home/dean/90days-ocp412/auth/kubeconfig' +INFO Access the OpenShift web-console here: https://console-openshift-console.apps.90days-ocp.simon.local +INFO Login to the console with user: "kubeadmin", and password: "ur6xT-gxmVW-WVUuD-Sd44J" +INFO Time elapsed: 35m16s +```` +![OpenShift-Install Create Cluster - output](images/Day58%20-%20OpenShift%20Cluster%20Install/OpenShift-Install%20create%20cluster%20-%20output.jpg) + +### Viewing the installation logs + +If we now look within our directory where we ran the ```openshift-install``` installation from, you can see a number of new folders and files are created: + +- auth Folder + - Within this folder is your kubeconfig file, as mentioned in the above console output +- tls Folder + - this contains the certificates of the journal-gateway service on the nodes to collect logs and debug +- Terraform files + - There are various ```.tfvars``` and ```.tfstate``` files used by the terraform component which is part of ```openshift-install``` software, and well as the output Terraform state file. +- Log Files + - Finally the verbose output is located in the hidden file ```.openshift_install.log```, this contains all the details about your installation and the running of Terraform to create the various resources. + +Below is a screenshot showing the directory, folders and example of my logging output. + +![OpenShift-Install - .openshift_install.log output](images/Day58%20-%20OpenShift%20Cluster%20Install/OpenShift-Install%20create%20cluster%20-%20.openshift_install.log%20output.jpg) + +## Connecting to your cluster + +To communicate with your cluster, like a vanilla Kubernetes environment, you can interact via the CLI tooling or directly with the API. However with Red Hat OpenShift, you also get a web console out of the box as well, this web console is designed for both personas, the platform administrator, and the developer who is deploying their applications. There is actually a drop down to change between these persona views as well (If you have the appropiate permissions to see both interfaces). + +### Using the Openshift Client (oc) and Kubectl + +Aa you will have seen from the final output of the installation, you will be provided a kubeconfig file in the ```auth``` folder, and the ouput provides you the necessary command to start consuming that straight away, as per the below example. + +> INFO To access the cluster as the system:admin user when using 'oc', run 'export KUBECONFIG=/home/dean/90days-ocp412/auth/kubeconfig' + +Once set as your environment variable, you can now interact with the cluster the same way you would with a vanilla Kubernetes cluster. When using the OpenShift Client (oc) tool, you'll find that all of your favourite ```kubectl``` commands will still work, you just replace the first part of the command with ```oc```. Below I've detailed a few examples: + +```` +kubectl get ns +oc get ns + +kubectl get pods -A +oc get pods -A + + +kubectl get pods -n openshift-apiserver +oc get pods -n openshift-apiserver +```` +![kubectl get pods -n openshift-apiserver - oc get pods -n openshift-apiserver ](images/Day58%20-%20OpenShift%20Cluster%20Install/kubectl%20get%20pods%20-n%20openshift-apiserver%20-%20oc%20get%20pods%20-n%20openshift-apiserver%20.jpg) +![kubectl get pods -A - oc get pods -A](images/Day58%20-%20OpenShift%20Cluster%20Install/kubectl%20get%20pods%20-A%20-%20oc%20get%20pods%20-A.jpg) +![kubectl get ns - oc get ns](images/Day58%20-%20OpenShift%20Cluster%20Install/kubectl%20get%20ns%20-%20oc%20get%20ns.jpg) +I've created an image of the output from ```oc -help``` and ```kubectl -help``` and mapped the two commands together, you will see that the ```oc``` tool is far more rich in terms of functionality + +![oc -help compared to kubectl -help](images/Day58%20-%20OpenShift%20Cluster%20Install/oc%20-help%20compared%20to%20kubectl%20-help.jpg) + +You can also login into the OpenShift cluster via the ```oc login``` command. + +```` +# Log in to the given server with the given credentials (will not prompt interactively) +oc login localhost:8443 --username=myuser --password=mypass +```` +A final footnote here, if you are not planning on using an image registry in your environment, it recommended to run this command to use the inbuilt registry as ephemeral whilst you do your testing: + +```` +oc patch configs.imageregistry.operator.openshift.io cluster --type merge --patch '{"spec":{"managementState":"Managed","storage":{"emptyDir":{}}}}' +```` + +### Using the OpenShift Console UI + +The final access point into the cluster, is via the UI, again the output of the installation software, gives you the full FQDN to access this console, if you look closely you'll see it uses the ingress record under *.apps.{cluster_name}.{base_domain}. + +```` +INFO Access the OpenShift web-console here: https://console-openshift-console.apps.90days-ocp.simon.local +INFO Login to the console with user: "kubeadmin", and password: "ur6xT-gxmVW-WVUuD-Sd44J" +```` +![Red Hat OpenShift Web Console](images/Day58%20-%20OpenShift%20Cluster%20Install/Red%20Hat%20OpenShift%20Web%20Console.jpg) + +Once logged in, you'll view the persona that you have access to (1). In my example, I'm using the kubeadmin account, so I see the administrative view first, and I can change this to the Developer view as well (see second screenshot). + +Under the left-hand navigation pane (2), you can easily browse all the common areas for platform administration, and view details of the live cluster, as well as make changes to existing configurations, or commit new configurations. + +In the middle (3) we have an overall status of the cluster, and connectivity to update services, and Red Hat cloud services such as their Insights feature. An activity log flanks the far right-hand side (4) of all the events in the system. Clicking any of these will take you into the object they are related to for further details. If it's about a pod, you then can see the logs from each container that runs within the pod. + +![Red Hat OpenShift - Web Console - Administrator Homepage](images/Day58%20-%20OpenShift%20Cluster%20Install/Red%20Hat%20OpenShift%20-%20Web%20Console%20-%20Administrator%20Homepage.jpg) + +Clicking the Administrator word in the top left-hand side (above screenshot, 1), you can switch to the Developer mode, which you can see below. + +On the the developer homepage screen, you can see straight away you are presented with a rich-deployment options to get up and running, you can deploy Kubernetes Operators for services, Helm Charts, import code from Git which can be built into a container by the cluster, deploy app samples, bring in individual containers, import content from your local machine, and control who can access your projects (Kubernetes namespaces with more features added in). + +![Red Hat OpenShift - Web Console - Developer Homepage](images/Day58%20-%20OpenShift%20Cluster%20Install/Red%20Hat%20OpenShift%20-%20Web%20Console%20-%20Developer%20Homepage.jpg) + +For this example today, I deployed my trusty [pacman app](https://github.com/saintdle/pacman-tanzu) from the [Helm Chart hosted on GitHub](https://github.com/saintdle/helm-charts), unfortunately I've not configured images for the app, but you can see, a topology is built, I can click into each component and see information about it. + +![Red Hat OpenShift - Web Console - Developer Topology](images/Day58%20-%20OpenShift%20Cluster%20Install/Red%20Hat%20OpenShift%20-%20Web%20Console%20-%20Developer%20Topology.jpg) + +If I take a step back I also can look at my project as a whole, see resource utilization, and events in my project, as well as control access for other developers to collaborate with me. + +![Red Hat OpenShift - Web Console - Developer Project](images/Day58%20-%20OpenShift%20Cluster%20Install/Red%20Hat%20OpenShift%20-%20Web%20Console%20-%20Developer%20Project.jpg) + +# Summary + +I think I'll stop here and wrap up. As you now know from [day 57](/day57.md), there are a few deployment methods, and numerous platforms to deploy to. This walkthrough covered the simpliest deployment to one of the most popular platforms, VMware vSphere. For those of you who want to try out OpenShift, you have two options, you can now deploy a [single node OpenShift environment](https://cloud.redhat.com/blog/visual-guide-to-single-node-openshift-deploy) running on your local machine, you can run [OpenShift sandbox](https://developers.redhat.com/developer-sandbox) via their website, or you can run [OKD](https://www.okd.io/), the open-source version in your home lab. Or stick with a trial of the enterprise software like I have. + +In [day 59](/day59.md), we will cover application deployment in a little more detail, and look start to look at Security Contraints Context (SCC), the out of the box security features of OpenShift which enhance further upon the older PodSecurityPolicies from Kubernetes. SCC is sometimes a little hard to get used to, and be a source of frustration out of the box for many when getting started with OpenShift. + +# Resources + +- vEducate.co.uk + - [OpenShift on VMware – Integrating with vSphere Storage, Networking and Monitoring](https://veducate.co.uk/openshift-on-vmware/) + - [How to specify your vSphere virtual machine resources when deploying Red Hat OpenShift](https://veducate.co.uk/deploy-vsphere-openshift-machine-resources/) + - [Red Hat OpenShift on VMware vSphere – How to Scale and Edit your cluster deployments](https://veducate.co.uk/openshift-vsphere-scale-clusters/) +- Red Hat OpenShift Commons - Community sessions helping steer the future of OpenShift as an open-source developed project - [Link](https://cloud.redhat.com/blog/tag/openshift-commons) +- Red Hat Sysadmin Blog - [Deploy and run OpenShift on AWS: 4 options](https://www.redhat.com/sysadmin/run-openshift-aws) +- Red Hat OpenShift Documentation - [Installing a cluster quickly on Azure](https://docs.openshift.com/container-platform/4.12/installing/installing_azure/installing-azure-default.html) +- YouTube - [TAM Lab 069 - Deploying OpenShift 4.3 to VMware vSphere (UPI install)](https://www.youtube.com/watch?v=xZpoZZ2EfYc) +- [Red Hat OpenShift Container Platform 4.10 on VMware Cloud Foundation 4.5](https://core.vmware.com/resource/red-hat-openshift-container-platform-410-vmware-cloud-foundation-45) \ No newline at end of file diff --git a/2023/day59.md b/2023/day59.md index e69de29..17ff16a 100644 --- a/2023/day59.md +++ b/2023/day59.md @@ -0,0 +1,489 @@ +# Deploying a Sample Application on Red Hat OpenShift: Handling Security Context Constraints (SCC) + +On [Day 58](/day58.md) we finished looking around the developer and administrator interfaces of a newly deployed cluster. + +In this submission (Day 59), we will walk through the process of deploying a sample MongoDB application to a newly deployed Red Hat OpenShift cluster. However, this deployment will fail due to the default security context constraints (SCC) in OpenShift. We will explain why the deployment fails, how to resolve the issue, and provide a brief overview of SCC in OpenShift with examples. + +## Understanding Security Context Constraints (SCC) + +Security context constraints in OpenShift are a security feature that allows administrators to control various aspects of the container runtime, such as user and group IDs, SELinux context, and the use of host resources. In Short, SCCs determine which security settings are allowed or disallowed for containerized applications. By default, OpenShift comes with several predefined SCCs, such as ```restricted```, ```anyuid```, and ```hostaccess```. These SCCs serve as templates for creating custom SCCs to meet specific security requirements. + +> Warning: Do not modify the default SCCs. Customizing the default SCCs can lead to issues when some of the platform pods deploy or OpenShift Container Platform is upgraded. Additionally, the default SCC values are reset to the defaults during some cluster upgrades, which discards all customizations to those SCCs. Instead of modifying the default SCCs, create and modify your own SCCs as needed. + +For example, the restricted SCC (default for most deployments, or restricted-v2 for new installs of OCP 4.11 and later) does not allow containers to run as root or with privileged access, while the ```anyuid``` SCC permits containers to run with any user ID, including root. By creating custom SCCs and granting them to service accounts or users, administrators can ensure that applications adhere to the desired security policies without compromising functionality. + +Security context constraints allow an administrator to control: + + - Whether a pod can run privileged containers with the allowPrivilegedContainer flag + + - Whether a pod is constrained with the allowPrivilegeEscalation flag + + - The capabilities that a container can request + + - The use of host directories as volumes + + - The SELinux context of the container + + - The container user ID + + - The use of host namespaces and networking + + - The allocation of an FSGroup that owns the pod volumes + + - The configuration of allowable supplemental groups + + - Whether a container requires to write access to its root file system + + - The usage of volume types + + - The configuration of allowable seccomp profiles + +To learn more details about what each of the out-of-the-box default security context constraints does, see [this official documentation page](https://docs.openshift.com/container-platform/4.12/authentication/managing-security-context-constraints.html#default-sccs_configuring-internal-oauth). + +![Red Hat OpenShift - oc get scc](/2023/images/day59-Red%20Hat%20OpenShift%20-%20oc%20get%20scc.jpg) + +### Anatomy of a Security Context Constraint configuration + +SCCs consist of settings and strategies that control the security features that a pod has access to. These settings fall into three categories: + +- Controlled by a boolean + - Fields of this type default to the most restrictive value. For example; + - ```AllowPrivilegedContainer``` is always set to ```false``` if unspecified. +- Controlled by an allowable set + - Fields of this type are checked against the set to ensure their value is allowed. +- Controlled by a strategy + - Items that have a strategy to generate a value provide: + - A mechanism to generate the value, and + - A mechanism to ensure that a specified value falls into the set of allowable values. + +CRI-O has the following [default list of capabilities](https://github.com/cri-o/cri-o/blob/main/docs/crio.conf.5.md#crioruntime-table) that are allowed for each container of a pod: + +```` + default_capabilities = [ + "CHOWN", + "DAC_OVERRIDE", + "FSETID", + "FOWNER", + "SETGID", + "SETUID", + "SETPCAP", + "NET_BIND_SERVICE", + "KILL", + ] +```` + +You can learn more about Linux capabilities [here](https://linuxera.org/container-security-capabilities-seccomp/) and [here](https://man7.org/linux/man-pages/man7/capabilities.7.html). The containers use the capabilities from this default list, but pod manifest authors (the person writing the application YAML for Kubernetes) can alter the list by requesting additional capabilities or removing some of the default behaviors. To control the capabilities allowed or denied for Pods running in the cluster, use the ```allowedCapabilities```, ```defaultAddCapabilities```, and ```requiredDropCapabilities``` parameters in your SCC to control such requests from the pods. + +#### Quick Snippet: configuring a pod with capabilities + +You can [specify additional capabilities for your pod](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-capabilities-for-a-container) as per the below example. + +````yaml +apiVersion: v1 +kind: Pod +metadata: + name: security-context-demo-4 +spec: + containers: + - name: sec-ctx-4 + image: gcr.io/google-samples/node-hello:1.0 + securityContext: + capabilities: + add: ["NET_ADMIN", "SYS_TIME"] +```` + +Let's look at some of the default contexts in further detail. + +### Example SCC Configurations + +1. Restricted SCC: + +Denies access to all host features and requires pods to be run with a UID, and SELinux context that are allocated to the namespace. + +The restricted-v2 SCC: + + Ensures that pods cannot run as privileged + + Ensures that pods cannot mount host directory volumes + + Requires that a pod is run as a user in a pre-allocated range of UIDs + + Requires that a pod is run with a pre-allocated MCS label + + Allows pods to use any FSGroup + + Allows pods to use any supplemental group + + Ensures that no child process of a container can gain more privileges than its parent (AllowPrivilegeEscalation=False) + +You can get this SCC configuration by running ```oc get scc restricted-v2 -o yaml``` + +````yaml +allowHostDirVolumePlugin: false +allowHostIPC: false +allowHostNetwork: false +allowHostPID: false +allowHostPorts: false +allowPrivilegeEscalation: true +allowPrivilegedContainer: false +allowedCapabilities: null +apiVersion: security.openshift.io/v1 +defaultAddCapabilities: null +fsGroup: + type: MustRunAs +groups: [] +kind: SecurityContextConstraints +metadata: + annotations: + include.release.openshift.io/ibm-cloud-managed: "true" + include.release.openshift.io/self-managed-high-availability: "true" + include.release.openshift.io/single-node-developer: "true" + kubernetes.io/description: restricted denies access to all host features and requires + pods to be run with a UID, and SELinux context that are allocated to the namespace. + release.openshift.io/create-only: "true" + creationTimestamp: "2023-03-16T09:34:36Z" + generation: 1 + name: restricted + resourceVersion: "401" + uid: 8ced4b4e-7fed-4369-a0b8-da40880f4a3d +priority: null +readOnlyRootFilesystem: false +requiredDropCapabilities: +- KILL +- MKNOD +- SETUID +- SETGID +runAsUser: + type: MustRunAsRange +seLinuxContext: + type: MustRunAs +supplementalGroups: + type: RunAsAny +users: [] +volumes: +- configMap +- downwardAPI +- emptyDir +- ephemeral +- persistentVolumeClaim +- projected +- secret +```` + +2. Privileged SCC: + +Allows access to all privileged and host features and the ability to run as any user, any group, any FSGroup, and with any SELinux context. + +The privileged SCC allows: + + Users to run privileged pods + + Pods to mount host directories as volumes + + Pods to run as any user + + Pods to run with any MCS label + + Pods to use the host’s IPC namespace + + Pods to use the host’s PID namespace + + Pods to use any FSGroup + + Pods to use any supplemental group + + Pods to use any seccomp profiles + + Pods to request any capabilities + +You can get this SCC configuration by running ```oc get scc privileged -o yaml``` + +````yaml +allowHostDirVolumePlugin: true +allowHostIPC: true +allowHostNetwork: true +allowHostPID: true +allowHostPorts: true +allowPrivilegeEscalation: true +allowPrivilegedContainer: true +allowedCapabilities: +- '*' +allowedUnsafeSysctls: +- '*' +apiVersion: security.openshift.io/v1 +defaultAddCapabilities: null +fsGroup: + type: RunAsAny +groups: +- system:cluster-admins +- system:nodes +- system:masters +kind: SecurityContextConstraints +metadata: + annotations: + include.release.openshift.io/ibm-cloud-managed: "true" + include.release.openshift.io/self-managed-high-availability: "true" + include.release.openshift.io/single-node-developer: "true" + kubernetes.io/description: 'privileged allows access to all privileged and host + features and the ability to run as any user, any group, any fsGroup, and with + any SELinux context. WARNING: this is the most relaxed SCC and should be used + only for cluster administration. Grant with caution.' + release.openshift.io/create-only: "true" + creationTimestamp: "2023-03-16T09:34:35Z" + generation: 1 + name: privileged + resourceVersion: "398" + uid: 19a16cc2-ce1f-4037-b70e-49ba261cb599 +priority: null +readOnlyRootFilesystem: false +requiredDropCapabilities: null +runAsUser: + type: RunAsAny +seLinuxContext: + type: RunAsAny +seccompProfiles: +- '*' +supplementalGroups: + type: RunAsAny +users: +- system:admin +- system:serviceaccount:openshift-infra:build-controller +volumes: +- '*' +```` +Now let's look at some specific items from the above YAML: + +- **allowedCapabilities:** - A list of capabilities that a pod can request. An empty list means that none of the capabilities can be requested while the special symbol * allows any capabilities. +- **defaultAddCapabilities: []** - A list of additional capabilities that are added to any pod. +- **fsGroup:** - The FSGroup strategy, dictates the allowable values for the security context. +- **groups** - The groups that can access this SCC. +- **requiredDropCapabilities** A list of capabilities to drop from a pod. Or, specify ALL to drop all capabilities. +- **runAsUser:** - The runAsUser strategy type, which dictates the allowable values for the security context. +- **seLinuxContext:** - The seLinuxContext strategy type, dictates the allowable values for the security context. +- **supplementalGroups** - The supplementalGroups strategy, dictates the allowable supplemental groups for the security context. +- **users:** - The users who can access this SCC. +- **volumes:** - The allowable volume types for the security context. In the example, * allows the use of all volume types. + +The users and groups fields on the SCC control which users can access the SCC. By default, cluster administrators, nodes, and the build controller are granted access to the privileged SCC. All authenticated users are granted access to the restricted-v2 SCC. + +## Let's deploy a sample application + +I'm going to deploy some of the basic components of my [trusty Pac-Man application for Kubernetes](https://github.com/saintdle/pacman-tanzu). The MongoDB deployment, PVC and Secret. + +First, I need to create the namespace to place the components in, ```oc create ns pacman```. + +Now I apply the below YAML file ```oc apply -f mongo-test.yaml``` + +````yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + name: mongo + name: mongo + namespace: pacman + annotations: + source: "https://github.com/saintdle/pacman-tanzu" +spec: + replicas: 1 + selector: + matchLabels: + name: mongo + template: + metadata: + labels: + name: mongo + spec: + initContainers: + - args: + - | + mkdir -p /bitnami/mongodb + chown -R "1001:1001" "/bitnami/mongodb" + command: + - /bin/bash + - -ec + image: docker.io/bitnami/bitnami-shell:10-debian-10-r158 + imagePullPolicy: Always + name: volume-permissions + resources: {} + securityContext: + runAsUser: 0 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /bitnami/mongodb + name: mongo-db + restartPolicy: Always + schedulerName: default-scheduler + securityContext: + fsGroup: 1001 + serviceAccountName: default + terminationGracePeriodSeconds: 30 + volumes: + - name: mongo-db + persistentVolumeClaim: + claimName: mongo-storage + containers: + - image: bitnami/mongodb:4.4.8 + name: mongo + env: + - name: MONGODB_ROOT_PASSWORD + valueFrom: + secretKeyRef: + key: database-admin-password + name: mongodb-users-secret + - name: MONGODB_DATABASE + valueFrom: + secretKeyRef: + key: database-name + name: mongodb-users-secret + - name: MONGODB_PASSWORD + valueFrom: + secretKeyRef: + key: database-password + name: mongodb-users-secret + - name: MONGODB_USERNAME + valueFrom: + secretKeyRef: + key: database-user + name: mongodb-users-secret + ports: + - name: mongo + containerPort: 27017 + volumeMounts: + - name: mongo-db + mountPath: /bitnami/mongodb/ +--- +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: mongo-storage + namespace: pacman +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi +--- +apiVersion: v1 +kind: Secret +metadata: + name: mongodb-users-secret + namespace: pacman +type: Opaque +data: + database-admin-name: Y2x5ZGU= + database-admin-password: Y2x5ZGU= + database-name: cGFjbWFu + database-password: cGlua3k= + database-user: Ymxpbmt5 +```` +Once applied, I see the following output: + +>Warning: would violate PodSecurity "restricted:v1.24": allowPrivilegeEscalation != false (containers "volume-permissions", "mongo" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (containers "volume-permissions", "mongo" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or containers "volume-permissions", "mongo" must set securityContext.runAsNonRoot=true), runAsUser=0 (container "volume-permissions" must not set runAsUser=0), seccompProfile (pod or containers "volume-permissions", "mongo" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost") +> +>deployment.apps/mongo created +> +>secret/mongodb-users-secret created + +If I now inspect the deployment and replicaset in the ```pacman``` namespace, we'll see that's stuck, I have no pods running. + +```` +# oc get all -n pacman + +NAME READY UP-TO-DATE AVAILABLE AGE +deployment.apps/mongo 0/1 0 0 3m9s + +NAME DESIRED CURRENT READY AGE +replicaset.apps/mongo-56cc764fb 1 0 0 3m9s +```` + + +## Why the Deployment Fails + +The provided Kubernetes application includes an initContainer with the following security context: + +````yaml +securityContext: + runAsUser: 0 +```` + +This configuration means that the initContainer will attempt to run as the root user (UID 0). However, OpenShift's default SCCs restrict the use of the root user for security reasons. As a result, the deployment fails because it violates the default security context constraints. The same is true of the other configuration settings mentioned in the above output as well. Remember in OCP 4.11 and later (new installs), the default SCC is the restricted-v2 policy. + +## How to Resolve the Issue + +To resolve this issue, we need to modify the deployment configuration to comply with the SCC policies in OpenShift. There are several ways to achieve this, but in this example, we will create a custom SCC that allows the initContainer to run as root. Follow these steps: + +1. Create a new custom SCC, and save the below YAML in a file called mongo-custom-scc.yaml: + +````yaml +apiVersion: security.openshift.io/v1 +kind: SecurityContextConstraints +metadata: + name: mongo-custom-scc +allowPrivilegedContainer: false +allowHostNetwork: false +allowHostPorts: false +allowHostPID: false +allowHostIPC: false +runAsUser: + type: RunAsAny +seLinuxContext: + type: MustRunAs +fsGroup: + type: RunAsAny +supplementalGroups: + type: RunAsAny +```` + +2. Apply the custom SCC to your OpenShift cluster: + +````sh +oc apply -f mongo-custom-scc.yaml +```` + +3. Grant the mongo-custom-scc SCC to the service account that the MongoDB deployment is using: + +````sh +oc adm policy add-scc-to-user mongo-custom-scc system:serviceaccount::default + +# In my environment, I run: +oc adm policy add-scc-to-user mongo-custom-scc system:serviceaccount:pacman:default +```` + +Replace with the namespace where your MongoDB deployment is located. + +4. Redeploy the MongoDB application. + +```` +# oc scale deploy mongo -n pacman --replicas=0 + +deployment.apps/mongo scaled + +# oc scale deploy mongo -n pacman --replicas=1 + +deployment.apps/mongo scaled +```` +In the real world, the first port of call should always be to work to ensure your containers and applications run with the least privileges necessary and therefore don't need to run as root. + +If they do need some sort of privilege, then defining tight RBAC and SCC control in place is key. + +# Summary + +In this post, we discussed how the default security context constraints in OpenShift can prevent deployments from running as expected. We provided a solution to the specific issue of running an initContainer as root for a MongoDB application. Understanding and managing SCCs in OpenShift is essential for maintaining secure and compliant applications within your cluster. + +On [Day 60](/day60.md)](/day60.md), we will look at OpenShift Projects Creation, Configuration and Governance, for example consuming SCC via the project level, and other features of Red Hat OpenShift. + +## Resources + +- Red Hat OpenShift - [Managing security context constraints](https://docs.openshift.com/container-platform/4.12/authentication/managing-security-context-constraints.html) +- Red Hat Blog - [Managing SCCs in OpenShift](https://cloud.redhat.com/blog/managing-sccs-in-openshift) +- Linuxera - [Capabilities and Seccomp Profiles on Kubernetes](https://linuxera.org/capabilities-seccomp-kubernetes/) +- Red Hat OpenShift - [Important OpenShift changes to Pod Security Standards](https://connect.redhat.com/en/blog/important-openshift-changes-pod-security-standards) + - OCP 4.11 and later - With the introduction of a new built-in admission controller that enforces the [Pod Security Standards](https://kubernetes.io/docs/concepts/security/pod-security-standards/), namespaces and pods can be defined with three different policies: Privileged, Baseline and Restricted. Therefore, pods not configured according to the enforced security standards defined globally, or on the namespace level, will not be admitted and will not run. +- [Pods fail to create due to "allowPrivilegeEscalation: true" in OpenShift 4.11](https://access.redhat.com/solutions/6976492) +- [Using the legacy restricted SCC in OCP 4.11+](https://access.redhat.com/articles/6973044) +- [Role-based access to security context constraints](https://docs.openshift.com/container-platform/4.12/authentication/managing-security-context-constraints.html#role-based-access-to-ssc_configuring-internal-oauth) + - You can specify SCCs as resources that are handled by RBAC. This allows you to scope access to your SCCs to a certain project or to the entire cluster. +- Kubernetes.io - [Configure a Security Context for a Pod or Container](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/) \ No newline at end of file diff --git a/2023/day60.md b/2023/day60.md index e69de29..a87ddff 100644 --- a/2023/day60.md +++ b/2023/day60.md @@ -0,0 +1,272 @@ +# OpenShift Projects - Creation, Configuration and Governance + +## Understanding OpenShift Projects: How They Differ from Kubernetes Namespaces + +Red Hat OpenShift adds many features to simplify and enhance the management of Kubernetes clusters. One such feature is OpenShift Projects, which are similar to Kubernetes Namespaces but with added benefits tailored to the enterprise environment. In this post, we will explore the concept of OpenShift Projects, how they differ from Kubernetes Namespaces, and provide examples of creating and configuring Projects. + +### OpenShift Projects: A Brief Overview + +OpenShift Projects are an abstraction layer built on top of Kubernetes Namespaces. They provide a convenient way to organize and manage resources within an OpenShift cluster, and they offer additional features such as: + +- Simplified multi-tenancy: Projects enable better isolation between users and teams, ensuring that each group works within its own environment without impacting others. +- Access control: Projects facilitate role-based access control (RBAC), allowing administrators to define and manage user permissions at the project level. +- Resource quotas and limits: Projects support setting resource quotas and limits to prevent overconsumption of cluster resources by individual projects. + +## Creating and Configuring an OpenShift Project + +Let's walk through the process of creating and configuring an OpenShift Project. + +1. Create a new project: + +To create a new project, use the oc new-project command: + +````sh + +$ oc new-project my-sample-project --description="My Sample OpenShift Project" --display-name="Sample Project" +```` +This command creates a new project called my-sample-project with a description and display name. + +2. Switch between projects: + +You can switch between projects using the oc project command: + +````sh +$ oc project my-sample-project +```` + +This command sets the active project to my-sample-project. + +3. Configure resource quotas: + +You can apply resource quotas to your project to limit the consumption of resources. Create a file called resource-quota.yaml with the following content: + +````yaml + +apiVersion: v1 +kind: ResourceQuota +metadata: + name: my-resource-quota +spec: + hard: + requests.cpu: "2" + requests.memory: 2Gi + limits.cpu: "4" + limits.memory: 4Gi +```` +## Adding Resource Quotas to projects + +To apply the resource quota to your project: + +````sh +$ oc apply -f resource-quota.yaml -n my-sample-project +```` + +This command applies the resource quota to the my-sample-project, limiting the total CPU and memory consumption for the project. + +5. Configure role-based access control (RBAC): + +To manage access control for your project, you can define and assign roles to users. For example, create a file called developer-role.yaml with the following content: + +````yaml + +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: developer +rules: +- apiGroups: [""] + resources: ["pods", "services", "configmaps", "persistentvolumeclaims"] + verbs: ["create", "get", "list", "watch", "update", "delete"] + ```` + +Apply the role to your project: + +````sh +$ oc apply -f developer-role.yaml -n my-sample-project +```` + +Now, you can grant the developer role to a specific user: + +````sh +$ oc policy add-role-to-user developer my-user -n my-sample-project +```` +This command grants the developer role to my-user in the my-sample-project. + +## Adding SCC to a project + +Remember in [Day 59](/2023/day59.md), we covered the Security Context Contraints, and how they provide security against the workloads we run inside the cluster, in the examples I provided, we fixed the security violation of the workload (pod) by ensuring the Service Account that it uses, is added to the correct SCC policy. + +In this example, I'm going to which SCC at the project level, so that any workloads deployed to this project, conform to the correct policy. + +1. Create a new project and change to that projects context + +````sh +$ oc new-project scc-ns-test + +$ oc project ssc-ns-test +```` + +2. Create a file called ```ngnix.yaml``` with the below content + +````yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nginx-deployment +spec: + selector: + matchLabels: + app: nginx + replicas: 2 # tells deployment to run 2 pods matching the template + template: + metadata: + labels: + app: nginx + spec: + containers: + - name: nginx + image: nginx:1.14.2 + ports: + - containerPort: 80 +```` +2. Deploy an Ngnix Deployment to this project, and watch for the failure + +````sh +$ oc apply -f ngnix.yaml + +Warning: would violate PodSecurity "restricted:v1.24": allowPrivilegeEscalation != false (container "nginx" must set securityContext.allowPrivilegeEscalation=false), unrestricted capabilities (container "nginx" must set securityContext.capabilities.drop=["ALL"]), runAsNonRoot != true (pod or container "nginx" must set securityContext.runAsNonRoot=true), seccompProfile (pod or container "nginx" must set securityContext.seccompProfile.type to "RuntimeDefault" or "Localhost") +deployment.apps/nginx-deployment created +```` +As per Day 59's example, the deployment is created, but the pod will not be running. + +3. Let's inspect the project's configuration before we continue further + +````sh +$ oc get project scc-ns-test -o json +```` +````json +{ + "apiVersion": "project.openshift.io/v1", + "kind": "Project", + "metadata": { + "annotations": { + "openshift.io/description": "", + "openshift.io/display-name": "", + "openshift.io/requester": "system:admin", + "openshift.io/sa.scc.mcs": "s0:c27,c4", + "openshift.io/sa.scc.supplemental-groups": "1000710000/10000", + "openshift.io/sa.scc.uid-range": "1000710000/10000" + }, + "creationTimestamp": "2023-03-29T09:23:18Z", + "labels": { + "kubernetes.io/metadata.name": "scc-ns-test", + "pod-security.kubernetes.io/audit": "restricted", + "pod-security.kubernetes.io/audit-version": "v1.24", + "pod-security.kubernetes.io/warn": "restricted", + "pod-security.kubernetes.io/warn-version": "v1.24" + }, + "name": "scc-ns-test", + "resourceVersion": "11247602", + "uid": "3f720113-1e30-4a3f-b97e-48f88735e510" + }, + "spec": { + "finalizers": [ + "kubernetes" + ] + }, + "status": { + "phase": "Active" + } +} +```` + +Note that under ```labels``` section, we have several pod-security settings that are specified by default. That is because the most restrictive policy is applied to namespaces and their workloads by default. + +4. Now let's delete our deployment + +````sh +$ oc delete -f nginx.yaml +```` + +5. Let's alter the configuration of this project to consume the ````privileged```` SCC, allowing us to brute force our pod to run. (In the real world, we would create an appropriate SCC and this use, rather than giving workloads god mode type access) + +We are going to use the `oc patch` command and pass in the modifications to the labels. There are two ways to achieve this using the patch argument, we can either pass in the changes within the command line in JSON format, or we can pass in a file that is either JSON or YAML content. I'll detail both options below. + +This first command passes JSON content as part of the executions to alert the configuration. + +````sh +$ oc patch namespace/scc-ns-test -p '{"metadata":{"labels":{"pod-security.kubernetes.io/audit":"privileged","pod-security.kubernetes.io/enforce":"privileged","pod-security.kubernetes.io/warn":"privileged","security.openshift.io/scc.podSecurityLabelSync":"false"}}}' +```` + +To break this down further, from the above example showing the Project configuration in JSON, we are altering the "audit", "warn" and "enforce" settings for Pod-Security to have the "privileged" value, and we also add a new label called "security.openshift.io/scc.podSecurityLabelSync" with a value of false. This stops the security admission controller from overwriting our changes. As the default SCC enforced is "restricted". + +Rather than including the JSON changes in the same command line, which can get very long if you have a lot of changes, you can simply create a JSON or YAML file, containing content such as below and then apply it using the ```--patch-file``` argument. + +````yaml +metadata: + labels: + pod-security.kubernetes.io/audit: privileged + pod-security.kubernetes.io/enforce: privileged + pod-security.kubernetes.io/warn: privileged + security.openshift.io/scc.podSecurityLabelSync: false +```` + +````sh +oc patch namespace/scc-ns-test --patch-file ns-patch.yaml +```` + +5. Now if we inspect our Project, we will see the changes in effect. + +````sh +oc get project scc-ns-test -o json +```` + +```json +{ + "apiVersion": "project.openshift.io/v1", + "kind": "Project", + "metadata": { + "annotations": { + "openshift.io/description": "", + "openshift.io/display-name": "", + "openshift.io/requester": "system:admin", + "openshift.io/sa.scc.mcs": "s0:c27,c4", + "openshift.io/sa.scc.supplemental-groups": "1000710000/10000", + "openshift.io/sa.scc.uid-range": "1000710000/10000" + }, + "creationTimestamp": "2023-03-29T09:23:18Z", + "labels": { + "kubernetes.io/metadata.name": "scc-ns-test", + "pod-security.kubernetes.io/audit": "privileged", + "pod-security.kubernetes.io/audit-version": "v1.24", + "pod-security.kubernetes.io/enforce": "privileged", + "pod-security.kubernetes.io/warn": "privileged", + "pod-security.kubernetes.io/warn-version": "v1.24", + "security.openshift.io/scc.podSecurityLabelSync": "false" + }, + "name": "scc-ns-test", + "resourceVersion": "11479286", + "uid": "3f720113-1e30-4a3f-b97e-48f88735e510" + }, + "spec": { + "finalizers": [ + "kubernetes" + ] + }, + "status": { + "phase": "Active" + } +} +```` + +6. Redeploy the nginx instances or other containers you've been working with. + +# Summary + +There is just so much to cover, but hopefully you've now learned that Projects are more than just a Kubernetes Namespace with a different name. One of the areas we didn't cover, is the ability to [control Project creation](https://docs.openshift.com/container-platform/4.12/applications/projects/configuring-project-creation.html) by OpenShift users, either from a governed default template, or simply removing the ability for self-service access to create templates. + +On [Day 61](/2023/day61.md), we shall cover the larger subject of RBAC within the cluster, and bring it back to applying access to projects. + +## Resources + +- Red Hat OpenShift Documentation - Building Applications - [Projects](https://access.redhat.com/documentation/en-us/openshift_container_platform/4.12/html/building_applications/projects#doc-wrapper) \ No newline at end of file diff --git a/2023/day61.md b/2023/day61.md index e69de29..7c183bd 100644 --- a/2023/day61.md +++ b/2023/day61.md @@ -0,0 +1,484 @@ +# Understanding Authentication, Role-Based Access Control (RBAC) and Auditing in Red Hat OpenShift: Control and Secure Your Cluster + +In this post, we are going to look at expanding access to our clusters to other users, we've already tackled the more complex subject of Security Contexts, which looks at the permissions that workloads have when they run on the platform, now we turn this focus to the users of the platform. + +## Back to Basics: Authentication, Authorization, Accounting + +AAA stands for Authentication, Authorization, and Accounting. These are three essential components of IT systems' security and access control. AAA ensures that users are who they claim to be, have the right permissions to access resources, and keep track of their activities within the system. Let's break down each component: + +- **Authentication**: This is the process of validating a user's identity when they attempt to access an IT system. Authentication typically involves requesting a user to provide their credentials, such as a username and password, or using other mechanisms like multi-factor authentication (MFA) and single sign-on (SSO). + +- **Authorization**: After a user has been authenticated, authorization determines the level of access they have within the system. It controls which resources a user can access and what actions they can perform. This is usually managed by defining roles or permissions and assigning them to users or groups. + +- **Accounting**: Also referred to as auditing, is the process of recording and monitoring user activities within an IT system. This includes logging information like when a user logs in, what actions they perform, and what resources they access. Accounting is essential for security, compliance, and troubleshooting purposes. + +Together, these three components form the AAA framework that helps IT administrators manage and secure access to their systems, ensuring that only authorized users can access resources and that their actions are logged for auditing purposes. +## Back to Red Hat Openshift: Introduction to Authentication, Access Control and Auditing + +Authentication in Red Hat OpenShift is the process of validating the identity of a user or system attempting to access the cluster. OpenShift supports various identity providers (IdPs) for authentication, such as LDAP, GitHub, GitLab, Google, Keystone, and many more. The authentication process in OpenShift 4 is handled by the OAuth server, which is responsible for managing OAuth tokens and interacting with the configured identity providers. + +Role-Based Access Control (RBAC) (Authorization) is an essential security feature in Red Hat OpenShift that enables administrators to manage and control access to resources within a cluster. + +Red Hat OpenShift uses the Kubernetes audit logging mechanism to perform accounting. The audit logs record requests made to the Kubernetes API server, providing detailed information about the user, resource, action, and outcome. The audit logs are essential for understanding user behavior, detecting security incidents, and meeting compliance requirements. + +## Configuring an Identity provider for Authorization + +Before we dig into any RBAC configurations, we need to start by giving our OpenShift cluster some form of identity provider that allows our users to login. In my previous posts, I was simply using the ```kubeadmin``` god mode account that is generated at bootstrap. + +To specify an identity provider, will need to create a custom resource (CR) that describes that identity provider and add it to the cluster. For the example of this post, I will detail how to configure a ldap identity provider to validate user names and passwords against an LDAPv3 server, using simple bind authentication. In my lab environment, I already have a Windows Server which is set up as a [domain controller](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/get-started/virtual-dc/active-directory-domain-services-overview). + +In short, when a user logs in to the OpenShift cluster, OpenShift will contact the domain controller via a configured provided domain account, and perform a lookup of the users account, if it is returned, it will try to bind to the LDAP provider with the users account and password provided. If this bind is successful, the user will be authenticated to the OpenShift cluster. + +1. On your domain controller, create a user account for the OpenShift Cluster to use for lookups, and ensure this account has the appropriate permissions. For Windows Server domain services, this user account can be a member of the standard ```domain users``` group. It is also a good time to record and have to hand the following information ready; + +- LDAP server URL (e.g., ldap://ldap.example.com:389) +- Bind DN and password for the LDAP server (e.g., cn=admin,dc=example,dc=com and password) + - This password will be [base64](https://en.wikipedia.org/wiki/Base64) encoded in the secret. +- User search base and filter (e.g., ou=users,dc=example,dc=com and (uid=%u)) +- Group search base and filter (e.g., ou=groups,dc=example,dc=com and (member=%u)) + +2. Create a secret that contains the ```bindPassword```, i.e the password of the domain account used to connect to the LDAP server for the user lookups. + +````sh +$ oc create secret generic ldap-secret --from-literal=bindPassword= -n openshift-config + +# my example +oc create secret generic ldap-secret --from-literal=bindPassword=VMware1! -n openshift-config +```` + +3. Now we apply the configuration that tells the OAuth service about our LDAP server and how to connect to it. I have not performed the extra steps to save the CA cert from the LDAP Server, as I am using the insecure LDAP port 389. + +Save the below file as ```ldap-provider.yaml```, change for your user details, and apply to your cluster using ```oc apply -f ldap-provider.yaml```. + +````yaml +apiVersion: config.openshift.io/v1 +kind: OAuth +metadata: + name: cluster +spec: + identityProviders: + - name: ldapidp + mappingMethod: claim + type: LDAP + ldap: + attributes: + id: + - name + name: + - cn + preferredUsername: + - sAMAccountName + bindDN: "CN=svc_openshift,OU=Services,OU=Accounts,DC=simon,DC=local" + bindPassword: + name: ldap-secret + insecure: true + url: "ldap://sc-step-01.simon.local:389/CN=Users,DC=simon,DC=local?sAMAccountName" +```` + +Some notes about the above configuration; +- attributes - The first non-empty attribute is used. At least one attribute is required. If none of the listed attribute have a value, authentication fails. Defined attributes are retrieved as raw, allowing for binary values to be used. + - Ensure the values provided appear as attributes in your domain controller, this is usually a cause of failures. +- bindDN - DN to use to bind during the search phase. Must be set if bindPassword is defined. +- insecure - When true, no TLS connection is made to the server. When false, ldaps:// URLs connect using TLS, and ldap:// URLs are upgraded to TLS. +- url - ensure you add the port, and that your search OU/CN path is correct, as well as the [search filter attribute](https://docs.openshift.com/container-platform/4.12/authentication/identity_providers/configuring-ldap-identity-provider.html#identity-provider-about-ldap_configuring-ldap-identity-provider), in this example it is ```sAMAccountName``` + +> If a CR does not exist, oc apply creates a new CR and might trigger the following warning: Warning: oc apply should be used on resources created by either oc create --save-config or oc apply. In this case you can safely ignore this warning. + + +4. Now you can login to the OpenShift cluster as an LDAP user either via the ```oc login``` CLI command, or via the Console UI. You can logout with ```oc logout``` + +![oc login](/2023/images/Day61%20-%20Authentication%20-%20Role-Based%20Access%20Control%20and%20Auditing%20in%20Red%20Hat%20OpenShift/oc%20login.jpg) + +Final note on this subject which caught me out. Once you log out, you will remain in the ```oc context``` of that user you've logged in, and if you view your ```KUBECONFIG``` file, you will see that user's context has now been added. So for me, I wanted to get back to using my kubeadmin account, but I had to run ```oc config use-context admin``` command. + +Now we have a way for our users to log into the platform, we can start to look at controlling what they can do on the platform. + +## What is Role-Based Access Control (RBAC)? + +RBAC is a method of managing permissions by assigning roles to users, groups, or service accounts. In OpenShift, roles are sets of rules that define the actions (verbs) allowed on specific resources (API objects). By granting roles to users or groups, you control their access to cluster resources based on the principle of least privilege, ensuring that users have only the necessary permissions to perform their tasks. Here, Red Hat OpenShift is just consuming the native features of Kubernetes, concerning RBAC. However, it's important to understand this area, as it then features in the enterprise features OpenShift brings, such as Projects and pipelines to name but a few. + +## RBAC in Red Hat OpenShift + +In OpenShift, RBAC is implemented through a set of built-in roles and custom roles, which can be assigned to users, groups, and service accounts. The key components of RBAC in OpenShift are: + +- Roles: A role is a collection of policies that define a set of permissions, including what actions users can perform on resources. These are applied to a namespace. +- ClusterRoles: Similar to roles, but these permissions are applicable cluster-wide, rather than in a specific namespace. +- RoleBindings: These are objects that associate roles with users, groups, or service accounts, granting them the permissions defined by the role + +The below image shows the relationships between the different components. + +![Red Hat OpenShift - Relationships between cluster roles, local roles, cluster role bindings, local role bindings, users, groups and service accounts](/2023/images/Day61%20-%20Authentication%20-%20Role-Based%20Access%20Control%20and%20Auditing%20in%20Red%20Hat%20OpenShift/Red%20Hat%20OpenShift%20-%20Access%20Control%20-%20Relationship%20between%20cluster%20roles%2C%20local%20roles%20and%20role%20bindings.png) + +To set up a new RBAC for a user to deploy and manage an application in a new project called "rbac-test-ns", follow the steps below: + +1. First, we need to create the "rbac-test-ns" project. Run the following command: + +````sh +$ oc new-project rbac-test-ns +```` + +2. Create a new custom role that grants the necessary permissions for deploying and managing applications. In this example, we will create a role called "app-mgr". Save the following YAML content to a file named "app-mgr-role.yaml": + +````yaml +kind: Role +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: app-mgr + namespace: rbac-test-ns +rules: +- apiGroups: ["project.openshift.io"] + resources: ["projects"] + verbs: ["get"] +- apiGroups: [""] + resources: ["pods", "services", "endpoints", "persistentvolumeclaims", "configmaps", "secrets"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +- apiGroups: ["apps"] + resources: ["deployments", "replicasets", "statefulsets"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +```` + +Create the custom role by applying the YAML file: + +````sh +$ oc apply -f app-mgr-role.yaml +```` + +3. Now, we need to bind the custom role to the user. In this example, let's assume the user's username is "johndoe". Create a RoleBinding by saving the following YAML content to a file named "app-mgr-rolebinding.yaml": + +````yaml +kind: RoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: app-mgr-binding + namespace: rbac-test-ns +subjects: +- kind: User + name: test + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: Role + name: app-mgr + apiGroup: rbac.authorization.k8s.io +```` + +Create the RoleBinding by applying the YAML file: +As a alternative to add a user to an existing role, we can use the following command line: + +````sh +$ oc adm policy add-role-to-user -n + +# For my example above, once I created the "app-mgr" role in the rbac-test-ns namespace I can run the following to create the roleBinding +oc adm policy add-role-to-user app-mgr test -n rbac-test-ns +```` +We can also see who can perform actions against certain resources too by using the command: + +````sh +oc adm policy who-can {verb} {resource} + +# for example +oc adm policy who-can create pods -n rbac-test-ns + +# below is the output (shortened) you can see my test user at the bottom +resourceaccessreviewresponse.authorization.openshift.io/ + +Namespace: rbac-test-ns +Verb: create +Resource: pods + +Users: system:admin + system:serviceaccount:kube-system:daemon-set-controller + system:serviceaccount:kube-system:job-controller + ....... + system:serviceaccount:rbac-test-ns:deployer + test +Groups: system:cluster-admins + system:masters + +```` + +With these steps, we have successfully set up a brand new RBAC for the user "test" (from my LDAP setup and testing earlier) to deploy and manage an application in the "rbac-test-ns" project. The user can now interact with the cluster, creating deployments, managing services, and configuring resources within the scope of the "app-mgr" role in the "rbac-test-ns" namespace. + +## How Accounting Works in Red Hat OpenShift 4 + +Here are the main components of accounting in Red Hat OpenShift: + +- Audit Policy: The audit policy determines which requests should be logged and the level of detail to include in the logs. You can configure the audit policy using a YAML file that specifies rules for each type of resource and action. + +- Audit Backend: The audit backend is responsible for processing and storing the audit logs. Red Hat OpenShift supports two types of audit backends: log backend and webhook backend. The log backend writes logs to a file on the API server node, while the webhook backend sends logs to an external HTTP(S) endpoint. + +- Log Retention and Rotation: OpenShift provides mechanisms for managing audit log retention and rotation to ensure that logs do not consume excessive disk space. Log rotation settings can be configured to control the maximum log file size and the number of old log files to keep. + +To enable and configure audit logging in OpenShift, administrators can create an audit policy, configure the audit backend, and set log retention and rotation settings. Once configured, the audit logs can be used to monitor user activities, identify security issues, and comply with regulatory requirements. + +Auditing is conducted at the API Server level, as it captures all requests coming into the server. This means that the audit logs by default will be stored on each of the control-plane nodes. + +Each audit log will contain the following fields: + +- level - The audit level at which the event was generated. + +- auditID - A unique audit ID, generated for each request. + +- stage - The stage of the request handling when this event instance was generated. + +- requestURI - The request URI is sent by the client to a server. + +- verb - The Kubernetes verb associated with the request. For non-resource requests, this is the lowercase HTTP method. + +- user - The authenticated user information. + +- impersonatedUser - Optional. The impersonated user information, if the request is impersonating another user. + +- sourceIPs - Optional. The source IPs, from where the request originated and any intermediate proxies. + +- userAgent - Optional. The user agent string is reported by the client. Note that the user agent is provided by the client, and must not be trusted. + +- objectRef - Optional. The object reference this request is targeted at. This does not apply to List-type requests, or non-resource requests. + +- responseStatus - Optional. The response status is populated even when the ResponseObject is not a Status type. For successful responses, this will only include the code. For non-status type error responses, this will be auto-populated with the error message. + +- requestObject - Optional. The API object from the request is in JSON format. The RequestObject is recorded as is in the request (possibly re-encoded as JSON), prior to version conversion, defaulting, admission or merging. It is an external versioned object type, and might not be a valid object on its own. This is omitted for non-resource requests and is only logged at the request level and higher. + +- responseObject - Optional. The API object is returned in the response, in JSON format. The ResponseObject is recorded after conversion to the external type and serialized as JSON. This is omitted for non-resource requests and is only logged at the response level. + +- requestReceivedTimestamp - The time that the request reached the API server. + +- stageTimestamp - The time that the request reached the current audit stage. + +- annotations - Optional. An unstructured key-value map is stored with an audit event that may be set by plugins invoked in the request serving chain, including authentication, authorization and admission plugins. Note that these annotations are for the audit event, and do not correspond to the ```metadata.annotations``` of the submitted object. Keys should uniquely identify the informing component to avoid name collisions, for example, podsecuritypolicy.admission.k8s.io/policy. Values should be short. Annotations are included in the metadata level. + +Below is an example of output from the Kubernetes API Server from the official documentation: + +````json +{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"ad209ce1-fec7-4130-8192-c4cc63f1d8cd","stage":"ResponseComplete","requestURI":"/api/v1/namespaces/openshift-kube-controller-manager/configmaps/cert-recovery-controller-lock?timeout=35s","verb":"update","user":{"username":"system:serviceaccount:openshift-kube-controller-manager:localhost-recovery-client","uid":"dd4997e3-d565-4e37-80f8-7fc122ccd785","groups":["system:serviceaccounts","system:serviceaccounts:openshift-kube-controller-manager","system:authenticated"]},"sourceIPs":["::1"],"userAgent":"cluster-kube-controller-manager-operator/v0.0.0 (linux/amd64) kubernetes/$Format","objectRef":{"resource":"configmaps","namespace":"openshift-kube-controller-manager","name":"cert-recovery-controller-lock","uid":"5c57190b-6993-425d-8101-8337e48c7548","apiVersion":"v1","resourceVersion":"574307"},"responseStatus":{"metadata":{},"code":200},"requestReceivedTimestamp":"2020-04-02T08:27:20.200962Z","stageTimestamp":"2020-04-02T08:27:20.206710Z","annotations":{"authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":"RBAC: allowed by ClusterRoleBinding \"system:openshift:operator:kube-controller-manager-recovery\" of ClusterRole \"cluster-admin\" to ServiceAccount \"localhost-recovery-client/openshift-kube-controller-manager\""}} +```` + +To view the audit logs: + +1. List the available audit logs on the control-plane nodes + +````sh +$ oc adm node-logs --role=master --path=openshift-apiserver/ + +# Example output +90days-ocp-72ptq-master-0 audit-2023-03-18T13-32-30.141.log +90days-ocp-72ptq-master-0 audit-2023-03-20T18-52-05.290.log +90days-ocp-72ptq-master-0 audit-2023-03-22T23-59-32.898.log +90days-ocp-72ptq-master-0 audit-2023-03-25T05-18-17.982.log +90days-ocp-72ptq-master-0 audit-2023-03-27T10-18-07.255.log +90days-ocp-72ptq-master-0 audit-2023-03-29T15-39-12.983.log +90days-ocp-72ptq-master-0 audit.log +90days-ocp-72ptq-master-1 audit-2023-03-18T13-40-29.849.log +90days-ocp-72ptq-master-1 audit-2023-03-20T18-48-37.329.log +90days-ocp-72ptq-master-1 audit-2023-03-23T00-03-57.031.log +90days-ocp-72ptq-master-1 audit-2023-03-25T05-14-28.573.log +90days-ocp-72ptq-master-1 audit-2023-03-27T10-25-27.601.log +90days-ocp-72ptq-master-1 audit-2023-03-29T15-34-14.462.log +90days-ocp-72ptq-master-1 audit.log +90days-ocp-72ptq-master-2 audit-2023-03-18T13-15-35.530.log +90days-ocp-72ptq-master-2 audit-2023-03-20T18-22-40.880.log +90days-ocp-72ptq-master-2 audit-2023-03-22T23-18-33.055.log +90days-ocp-72ptq-master-2 audit-2023-03-25T04-18-56.637.log +90days-ocp-72ptq-master-2 audit-2023-03-27T09-44-50.243.log +90days-ocp-72ptq-master-2 audit-2023-03-29T14-39-01.789.log +90days-ocp-72ptq-master-2 audit.log +```` + +2. To view a specific audit log: + +````sh +$ oc adm node-logs --path=openshift-apiserver/ + +# Example command +$ oc adm node-logs 90days-ocp-72ptq-master-2 --path=openshift-apiserver/audit-2023-03-29T14-39-01.789.log +```` + +Example output: + +````json +{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"5d08341a-8fa2-4fab-8e4a-4fb1c01d2d6e","stage":"ResponseStarted","requestURI":"/apis/template.openshift.io/v1/namespaces/openshift/templates?allowWatchBookmarks=true\u0026resourceVersion=9537849\u0026timeout=5m44s\u0026timeoutSeconds=344\u0026watch=true","verb":"watch","user":{"username":"system:serviceaccount:openshift-cluster-samples-operator:cluster-samples-operator","groups":["system:serviceaccounts","system:serviceaccounts:openshift-cluster-samples-operator","system:authenticated"],"extra":{"authentication.kubernetes.io/pod-name":["cluster-samples-operator-7f8d575897-s7566"],"authentication.kubernetes.io/pod-uid":["8a96caaf-1de9-4cef-915f-ace02c764e52"]}},"sourceIPs":["192.168.200.181","10.130.0.2"],"userAgent":"cluster-samples-operator/v0.0.0 (linux/amd64) kubernetes/$Format","objectRef":{"resource":"templates","namespace":"openshift","apiGroup":"template.openshift.io","apiVersion":"v1"},"responseStatus":{"metadata":{},"code":200},"requestReceivedTimestamp":"2023-03-27T09:44:50.239076Z","stageTimestamp":"2023-03-27T09:44:50.242747Z","annotations":{"authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":"RBAC: allowed by RoleBinding \"shared-resource-viewers/openshift\" of Role \"shared-resource-viewer\" to Group \"system:authenticated\""}} +{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"e65876d9-6fca-422c-93a9-110921648d1b","stage":"ResponseComplete","requestURI":"/metrics","verb":"get","user":{"username":"system:serviceaccount:openshift-monitoring:prometheus-k8s","groups":["system:authenticated"]},"sourceIPs":["10.129.2.13"],"userAgent":"Prometheus/2.39.1","responseStatus":{"metadata":{},"code":200},"requestReceivedTimestamp":"2023-03-27T09:44:51.044096Z","stageTimestamp":"2023-03-27T09:44:51.065007Z","annotations":{"authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":"RBAC: allowed by ClusterRoleBinding \"prometheus-k8s\" of ClusterRole \"prometheus-k8s\" to ServiceAccount \"prometheus-k8s/openshift-monitoring\""}} +```` + +Next, we have the OpenShift OAuth API Server audit logs, which will capture our user interactions + +1. List the relevant logs on the control-plane nodes + +````sh +oc adm node-logs --role=master --path=oauth-apiserver/ + +# Example output +90days-ocp-72ptq-master-0 audit-2023-03-22T20-22-19.424.log +90days-ocp-72ptq-master-0 audit-2023-03-29T08-44-53.926.log +90days-ocp-72ptq-master-0 audit.log +90days-ocp-72ptq-master-1 audit-2023-03-22T20-34-32.796.log +90days-ocp-72ptq-master-1 audit-2023-03-29T08-41-39.406.log +90days-ocp-72ptq-master-1 audit.log +90days-ocp-72ptq-master-2 audit-2023-03-22T20-08-20.762.log +90days-ocp-72ptq-master-2 audit-2023-03-29T08-10-51.942.log +90days-ocp-72ptq-master-2 audit.log +```` + +2. View a specific OAuth API Server log: + +````sh +$ oc adm node-logs --path=oauth-apiserver/ + +# Example command +$ oc adm node-logs 90days-ocp-72ptq-master-2 --path=oauth-apiserver/audit-2023-03-29T08-10-51.942.log +````` + +Example output + +````json +{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"6472c130-436a-4454-9bf9-77b6066d8ce2","stage":"ResponseComplete","requestURI":"/apis/oauth.openshift.io/v1/oauthclients/console","verb":"get","user":{"username":"system:serviceaccount:openshift-console-operator:console-operator","groups":["system:serviceaccounts","system:serviceaccounts:openshift-console-operator","system:authenticated"],"extra":{"authentication.kubernetes.io/pod-name":["console-operator-7cc8457b5b-rpz7f"],"authentication.kubernetes.io/pod-uid":["4b73b593-9cde-4ae4-a8f7-00e7f7ee7902"]}},"sourceIPs":["192.168.200.181","10.129.0.2"],"userAgent":"console/v0.0.0 (linux/amd64) kubernetes/$Format","objectRef":{"resource":"oauthclients","name":"console","apiGroup":"oauth.openshift.io","apiVersion":"v1"},"responseStatus":{"metadata":{},"code":200},"requestReceivedTimestamp":"2023-03-22T23:35:00.970020Z","stageTimestamp":"2023-03-22T23:35:00.972703Z","annotations":{"authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":"RBAC: allowed by ClusterRoleBinding \"console-operator\" of ClusterRole \"console-operator\" to ServiceAccount \"console-operator/openshift-console-operator\""}} +{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"db3d3280-fcb9-4368-b7db-17b97bcb9826","stage":"ResponseComplete","requestURI":"/apis/oauth.openshift.io/v1/oauthclients/console","verb":"get","user":{"username":"system:serviceaccount:openshift-console-operator:console-operator","groups":["system:serviceaccounts","system:serviceaccounts:openshift-console-operator","system:authenticated"],"extra":{"authentication.kubernetes.io/pod-name":["console-operator-7cc8457b5b-rpz7f"],"authentication.kubernetes.io/pod-uid":["4b73b593-9cde-4ae4-a8f7-00e7f7ee7902"]}},"sourceIPs":["192.168.200.181","10.129.0.2"],"userAgent":"console/v0.0.0 (linux/amd64) kubernetes/$Format","objectRef":{"resource":"oauthclients","name":"console","apiGroup":"oauth.openshift.io","apiVersion":"v1"},"responseStatus":{"metadata":{},"code":200},"requestReceivedTimestamp":"2023-03-22T23:35:00.976516Z","stageTimestamp":"2023-03-22T23:35:00.980651Z","annotations":{"authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":"RBAC: allowed by ClusterRoleBinding \"console-operator\" of ClusterRole \"console-operator\" to ServiceAccount \"console-operator/openshift-console-operator\""}} +{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"b5a99a12-637a-4bb2-b733-1f3812ca76fe","stage":"ResponseComplete","requestURI":"/openapi/v2","verb":"get","user":{"username":"system:aggregator","groups":["system:authenticated"]},"sourceIPs":["10.128.0.2"],"responseStatus":{"metadata":{},"code":304},"requestReceivedTimestamp":"2023-03-22T23:35:21.077019Z","stageTimestamp":"2023-03-22T23:35:21.085460Z","annotations":{"authorization.k8s.io/decision":"allow","authorization.k8s.io/reason":"RBAC: allowed by ClusterRoleBinding \"cluster-status-binding\" of ClusterRole \"cluster-status\" to Group \"system:authenticated\""}} +```` + +And finally the OAuth server audit logs + +1. List the available logs on the control-plane nodes: + +````sh +oc adm node-logs --role=master --path=oauth-server/ + +# Example output +90days-ocp-72ptq-master-0 audit.log +90days-ocp-72ptq-master-1 audit.log +90days-ocp-72ptq-master-2 audit.log +```` + +2. View a specific log: + +````sh +$ oc adm node-logs --path=oauth-server/ + +# Example command +$ oc adm node-logs 90days-ocp-72ptq-master-2 --path=oauth-server/audit.log +```` + +Example output: + +````json +{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"0ae79d4b-a44e-4f16-aadf-a600f42a63d0","stage":"RequestReceived","requestURI":"/","verb":"head","user":{"username":"system:anonymous","groups":["system:unauthenticated"]},"sourceIPs":["10.131.0.2"],"userAgent":"Go-http-client/1.1","requestReceivedTimestamp":"2023-03-30T14:13:04.446550Z","stageTimestamp":"2023-03-30T14:13:04.446550Z"} +{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"0ae79d4b-a44e-4f16-aadf-a600f42a63d0","stage":"ResponseComplete","requestURI":"/","verb":"head","user":{"username":"system:anonymous","groups":["system:unauthenticated"]},"sourceIPs":["10.131.0.2"],"userAgent":"Go-http-client/1.1","responseStatus":{"metadata":{},"status":"Failure","message":"forbidden: User \"system:anonymous\" cannot head path \"/\"","reason":"Forbidden","details":{},"code":403},"requestReceivedTimestamp":"2023-03-30T14:13:04.446550Z","stageTimestamp":"2023-03-30T14:13:04.456751Z","annotations":{"authorization.k8s.io/decision":"forbid","authorization.k8s.io/reason":""}} +{"kind":"Event","apiVersion":"audit.k8s.io/v1","level":"Metadata","auditID":"a151df17-578c-415f-a83e-64753a0d16dc","stage":"RequestReceived","requestURI":"/oauth/authorize?client_id=openshift-challenging-client\u0026code_challenge=L56_-VuTMU7qF36WuKxF6mnA2nj_oEEETPsAdQ-w24I\u0026code_challenge_method=S256\u0026redirect_uri=https%3A%2F%2Foauth-openshift.apps.90days-ocp.simon.local%2Foauth%2Ftoken%2Fimplicit\u0026response_type=code","verb":"get","user":{"username":"system:anonymous","groups":["system:unauthenticated"]},"sourceIPs":["10.131.0.2"],"userAgent":"Go-http-client/1.1","requestReceivedTimestamp":"2023-03-30T14:13:04.489643Z","stageTimestamp":"2023-03-30T14:13:04.489643Z"} +```` + +You can filter the logs using the ```jq``` tool (See the [jq Manual](https://stedolan.github.io/jq/manual/) for detailed information). An example command would be: + +````sh +$ oc adm node-logs 90days-ocp-72ptq-master-2 --path=openshift-apiserver/audit.log | jq 'select(.user.username == "test")' +```` + +Example output: + +````json +{ + "kind": "Event", + "apiVersion": "audit.k8s.io/v1", + "level": "Metadata", + "auditID": "97ce5c38-4e0c-447b-8e9f-a2c8c84ebc19", + "stage": "ResponseComplete", + "requestURI": "/apis/project.openshift.io/v1/projectrequests", + "verb": "list", + "user": { + "username": "test", + "groups": [ + "system:authenticated:oauth", + "system:authenticated" + ], + "extra": { + "scopes.authorization.openshift.io": [ + "user:full" + ] + } + }, + "sourceIPs": [ + "10.129.0.35", + "10.129.0.2" + ], + "objectRef": { + "resource": "projectrequests", + "apiGroup": "project.openshift.io", + "apiVersion": "v1" + }, + "responseStatus": { + "metadata": {}, + "status": "Success", + "code": 200 + }, + "requestReceivedTimestamp": "2023-03-30T14:42:37.237408Z", + "stageTimestamp": "2023-03-30T14:42:37.250606Z", + "annotations": { + "authorization.k8s.io/decision": "allow", + "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"basic-users\" of ClusterRole \"basic-user\" to Group \"system:authenticated\"" + } +} +{ + "kind": "Event", + "apiVersion": "audit.k8s.io/v1", + "level": "Metadata", + "auditID": "5868d505-1c46-47ed-b0ab-d53d9878d495", + "stage": "ResponseStarted", + "requestURI": "/apis/project.openshift.io/v1/projects?cluster=local-cluster&watch=true", + "verb": "watch", + "user": { + "username": "test", + "groups": [ + "system:authenticated:oauth", + "system:authenticated" + ], + "extra": { + "scopes.authorization.openshift.io": [ + "user:full" + ] + } + }, + "sourceIPs": [ + "192.168.200.10", + "10.129.0.35", + "10.129.0.2" + ], + "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36", + "objectRef": { + "resource": "projects", + "apiGroup": "project.openshift.io", + "apiVersion": "v1" + }, + "responseStatus": { + "metadata": {}, + "code": 101 + }, + "requestReceivedTimestamp": "2023-03-30T14:42:40.166647Z", + "stageTimestamp": "2023-03-30T14:42:40.170013Z", + "annotations": { + "authorization.k8s.io/decision": "allow", + "authorization.k8s.io/reason": "RBAC: allowed by ClusterRoleBinding \"basic-users\" of ClusterRole \"basic-user\" to Group \"system:authenticated\"" + } +} +```` + +To wrap up this section, I think it's worth highlighting that keeping the logs on the nodes themselves is not best practice, and you will want to offload these to an external logging service. I won't cover that in detail in this post, but I will provide you a [link to a blog post](https://veducate.co.uk/openshift-forward-logs-log-insight-cloud/) I created previously, showing how you can offload the logs to the VMware Aria Operations for Logs product (previously known as vRealize Log Insight) + +# Summary + +In this post, we've seen more of how Red Hat OpenShift takes the out-of-the-box functionality from upstream Kubernetes and entwines it with enterprise engineering, such as the ability to easily add an Identity provider for Authorization without having to pull in more open-source components. The AAA model is a basic premise when it comes to managing the security stance of your environment, and before you let users consume the Red Hat OpenShift platform, it's key to understand how this works and start putting in the structure upfront around the likes of Roles and Role Bindings for user privileges. + +This post only takes you into the beginnings of setting up RBAC, and we haven't discussed a cohesive strategy of how to implement it within your organisation. It's safe to say least privilege is the best, and the outcome you need to aim for. I've included several links below for you to understand RBAC in Kubernetes and OpenShift in more detail, and I'm sure with a quick search on your favourite search engine, you'll also find lots of posts around how best to implement a least privilege model. + +To wrap up this section on Red Hat OpenShift with [Day 62](/2023/day62.md) we will cover compliance and vulnerability scanning provided by Red Hat Operators. + +## Resources +- Kubernetes.io + - [Authenicating](https://kubernetes.io/docs/reference/access-authn-authz/authentication/) + - [Using RBAC Authorization](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) +- Red Hat OpenShift Documentation + - [Configuring an LDAP identity provider](https://docs.openshift.com/container-platform/4.12/authentication/identity_providers/configuring-ldap-identity-provider.html) + - [Using RBAC to define and apply permissions](https://access.redhat.com/documentation/en-us/openshift_container_platform/4.12/html/authentication_and_authorization/using-rbac) + - [Viewing Audit logs](https://docs.openshift.com/container-platform/4.12/security/audit-log-view.html) + - [Configuring the audit log policy](https://docs.openshift.com/container-platform/4.12/security/audit-log-policy-config.html#audit-log-policy-config) + - [Monitoring cluster events and logs](https://docs.openshift.com/container-platform/4.12/security/container_security/security-monitoring.html) +- Red Hat Blog - [Multiple ways of Authentication on OpenShift Container Platform (OCP), Part 2](https://cloud.redhat.com/blog/multiple-ways-of-authentication-on-openshift-container-platform-ocp-part-2) +- OpenShift Examples - [Active Directory/LDAP](https://examples.openshift.pub/cluster-configuration/authentication/activedirectory-ldap/) +- vEducate.co.uk - [How to configure Red Hat OpenShift to forward logs to VMware vRealize Log Insight Cloud](https://veducate.co.uk/openshift-forward-logs-log-insight-cloud/) \ No newline at end of file diff --git a/2023/day62.md b/2023/day62.md index e69de29..e706b50 100644 --- a/2023/day62.md +++ b/2023/day62.md @@ -0,0 +1,711 @@ +# Compliance and Vulnerability Scanning provided by Red Hat OpenShift Operators + +Many components make up the security posture of a well-designed and architected platform. For a Red Hat OpenShift platform, this will include implementing the AAA model we covered on [Day 61](/2023/day61.md), container security, certificates to validate access to the platform and between the workloads that run and communicate on and with the platform, data encryption, vulnerability scanning, compliance auditing and remediation, as just a shortlisted example. + +In this post, I'm going to focus on just two areas of security inside of Red Hat OpenShift; Compliance and Vulnerability Scanning. + +# Red Hat OpenShift Compliance Operator + +## Compliance Overview + +In the context of Kubernetes, compliance refers to the adherence of OpenShift deployments to various industry standards, regulations, and best practices. Compliance is essential for organizations operating in regulated industries like healthcare, finance, or government sectors, as well as for those who prioritize security and privacy. + +OpenShift, as a Kubernetes-based container orchestration platform, provides several features and tools to help organizations achieve and maintain compliance. These features include: + +- Security and access control: OpenShift provides robust security features like Role-Based Access Control (RBAC), network policies, and Security Context Constraints (SCCs) to manage access to cluster resources and ensure the secure deployment and operation of applications. + +- Auditing and monitoring: OpenShift's built-in auditing and monitoring capabilities make it easy to track user activities, resource usage, and system events. This information is crucial for detecting and responding to security incidents, meeting regulatory requirements, and troubleshooting issues. + +- Image and container security: OpenShift's integrated container registry, image signing, and image scanning features help ensure the integrity and security of container images. Additionally, OpenShift enforces security best practices through resource constraints and pod security policies. + +- Encrypted communication: OpenShift supports TLS/SSL for secure communication between cluster components, as well as between the cluster and external clients. This helps protect sensitive data in transit. + +- Compliance Operator: Red Hat OpenShift provides the Compliance Operator, with an OpenShift-native tool that helps organizations evaluate and enforce compliance policies. The Compliance Operator leverages the OpenSCAP framework and can be configured to meet specific regulatory requirements or security standards, such as NIST, PCI-DSS, HIPAA, or GDPR. + +Achieving and maintaining compliance in OpenShift involves configuring the platform according to industry standards, regulations, and best practices, continuously monitoring and auditing the environment, and promptly addressing any identified issues. By utilising the capabilities and resources offered by OpenShift, organisations have the opportunity to establish secure and regulation-compliant ecosystems for their applications and workloads, ensuring optimal performance and adherence to industry standards. + +In this post, we'll be focusing on the Compliance Operator, which empowers the platform administrators by allowing them to define the desired compliance state for their cluster. It offers a comprehensive overview of discrepancies between the current and target states, as well as actionable insights to address these gaps effectively. + +The Compliance Operator provides the ability to describe the required compliance state of a cluster and report overviews of gaps and ways to remediate them. The Compliance Operator assesses compliance of both the Kubernetes API resources of OpenShift Container Platform, as well as the nodes running the cluster. The Compliance Operator uses OpenSCAP, a NIST-certified tool, to scan and enforce security policies provided by the content. You can view details of the out-of-the-box compliance profiles that are [provided here](https://docs.openshift.com/container-platform/4.12/security/compliance_operator/compliance-operator-supported-profiles.html). + +### Installing the Compliance Operator + +1. We need to create a specially managed OpenShift namespace. Save the below content as ```openshift-compliance-namespace.yaml``` and apply using the ```oc apply -f openshift-compliance-namespace.yaml``` command. + +````yaml +apiVersion: v1 +kind: Namespace +metadata: + labels: + openshift.io/cluster-monitoring: "true" + pod-security.kubernetes.io/enforce: privileged + name: openshift-compliance +```` + +2. Now we need to define an ```OperatorGroup``` for the Compliance operator. Save the below content as ```openshift-compliance-operator-group.yaml``` and apply using the ```oc apply -f openshift-compliance-operator-group.yaml``` command. + +````yaml +apiVersion: operators.coreos.com/v1 +kind: OperatorGroup +metadata: + name: compliance-operator + namespace: openshift-compliance +spec: + targetNamespaces: + - openshift-compliance +```` + +3. Define and apply a subscription to the Operator. Save the below content as ```openshift-compliance-operator-subscription.yaml``` and apply using the ```oc apply -f openshift-compliance-operator-subscription.yaml``` command. + +````yaml +apiVersion: operators.coreos.com/v1alpha1 +kind: Subscription +metadata: + name: compliance-operator-sub + namespace: openshift-compliance +spec: + channel: "release-0.1" + installPlanApproval: Automatic + name: compliance-operator + source: redhat-operators + sourceNamespace: openshift-marketplace +```` + +4. You can verify the Operator installation with the below command; + +````sh +$ oc get csv -n openshift-compliance +$ oc get deploy -n openshift-compliance +```` +### Reviewing the profiles and the rules + +We can see the installed profiles by running the below command, each profile has the product name that it applies to added as a prefix to the profile’s name. ocp4-e8 applies the Essential 8 benchmark to the OpenShift Container Platform product, while rhcos4-e8 applies the Essential 8 benchmark to the Red Hat Enterprise Linux CoreOS (RHCOS) product. + +````sh +$ oc get -n openshift-compliance profiles.compliance +NAME AGE +ocp4-cis 107m +ocp4-cis-node 107m +ocp4-e8 107m +ocp4-high 107m +ocp4-high-node 107m +ocp4-moderate 107m +ocp4-moderate-node 107m +ocp4-nerc-cip 107m +ocp4-nerc-cip-node 107m +ocp4-pci-dss 107m +ocp4-pci-dss-node 107m +rhcos4-e8 107m +rhcos4-high 107m +rhcos4-moderate 107m +rhcos4-nerc-cip 107m +```` + +We can view the details of a profile by running: + +````sh +$ oc get -n openshift-compliance -oyaml profiles.compliance ocp4-cis +```` + +````yaml +apiVersion: compliance.openshift.io/v1alpha1 +description: This profile defines a baseline that aligns to the Center for Internet + Security® Red Hat OpenShift Container Platform 4 Benchmark™, V1.1. This profile + includes Center for Internet Security® Red Hat OpenShift Container Platform 4 CIS + Benchmarks™ content. Note that this part of the profile is meant to run on the Platform + that Red Hat OpenShift Container Platform 4 runs on top of. This profile is applicable + to OpenShift versions 4.6 and greater. +id: xccdf_org.ssgproject.content_profile_cis +kind: Profile +metadata: + annotations: + compliance.openshift.io/image-digest: pb-ocp477wpm + compliance.openshift.io/product: redhat_openshift_container_platform_4.1 + compliance.openshift.io/product-type: Platform + creationTimestamp: "2023-03-31T09:09:52Z" + generation: 1 + labels: + compliance.openshift.io/profile-bundle: ocp4 + name: ocp4-cis + namespace: openshift-compliance + ownerReferences: + - apiVersion: compliance.openshift.io/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: ProfileBundle + name: ocp4 + uid: 19c2e4a5-094f-416a-a06b-eb0598e39618 + resourceVersion: "12971302" + uid: 6dc3cca4-5649-43ae-8c46-614f82fd6744 +rules: +- ocp4-accounts-restrict-service-account-tokens +- ocp4-accounts-unique-service-account +- ocp4-api-server-admission-control-plugin-alwaysadmit +- ocp4-api-server-admission-control-plugin-alwayspullimages +- ocp4-api-server-admission-control-plugin-namespacelifecycle +- ocp4-api-server-admission-control-plugin-noderestriction +- ocp4-api-server-admission-control-plugin-scc +- ocp4-api-server-admission-control-plugin-securitycontextdeny +- ocp4-api-server-admission-control-plugin-service-account +- ocp4-api-server-anonymous-auth +- ocp4-api-server-api-priority-flowschema-catch-all +- ocp4-api-server-api-priority-gate-enabled +- ocp4-api-server-audit-log-maxbackup +- ocp4-api-server-audit-log-maxsize +- ocp4-api-server-audit-log-path +- ocp4-api-server-auth-mode-no-aa +- ocp4-api-server-auth-mode-node +- ocp4-api-server-auth-mode-rbac +- ocp4-api-server-basic-auth +- ocp4-api-server-bind-address +... +- ocp4-scc-limit-privileged-containers +- ocp4-scc-limit-process-id-namespace +- ocp4-scc-limit-root-containers +- ocp4-scheduler-no-bind-address +- ocp4-secrets-consider-external-storage +- ocp4-secrets-no-environment-variables +- ocp4-version-detect-in-hypershift +- ocp4-version-detect-in-ocp +title: CIS Red Hat OpenShift Container Platform 4 Benchmark +```` + +To read the descriptions of one of the rules that form the policy: + +````sh +$ oc get -n openshift-compliance rules ocp4-api-server-anonymous-auth -oyaml +```` + +````yaml +apiVersion: compliance.openshift.io/v1alpha1 +checkType: Platform +description: |- + By default, anonymous access to the OpenShift API is enabled, but at the same time, all requests must be authorized. If no authentication mechanism is used, the request is assigned the system:anonymous virtual user and the system:unauthenticated virtual group. This allows the authorization layer to determin which requests, if any, is an anonymous user authorized to make. To verify the authorization rules for anonymous requests run the following: + + $ oc describe clusterrolebindings + + and inspect the bidnings of the system:anonymous virtual user and the system:unauthenticated virtual group. To test that an anonymous request is authorized to access the readyz endpoint, run: + + $ oc get --as="system:anonymous" --raw='/readyz?verbose' + + In contrast, a request to list all projects should not be authorized: + + $ oc get --as="system:anonymous" projects +id: xccdf_org.ssgproject.content_rule_api_server_anonymous_auth +instructions: |- + Run the following command to view the authorization rules for anonymous requests: + $ oc describe clusterrolebindings + Make sure that there exists at least one clusterrolebinding that binds + either the system:unauthenticated group or the system:anonymous + user. + To test that an anonymous request is authorized to access the readyz + endpoint, run: + $ oc get --as="system:anonymous" --raw='/readyz?verbose' + In contrast, a request to list all projects should not be authorized: + $ oc get --as="system:anonymous" projects +kind: Rule +metadata: + annotations: + compliance.openshift.io/image-digest: pb-ocp477wpm + compliance.openshift.io/rule: api-server-anonymous-auth + control.compliance.openshift.io/CIS-OCP: 1.2.1 + control.compliance.openshift.io/NERC-CIP: CIP-003-8 R6;CIP-004-6 R3;CIP-007-3 + R6.1 + control.compliance.openshift.io/NIST-800-53: CM-6;CM-6(1) + control.compliance.openshift.io/PCI-DSS: Req-2.2 + policies.open-cluster-management.io/controls: 1.2.1,CIP-003-8 R6,CIP-004-6 R3,CIP-007-3 + R6.1,CM-6,CM-6(1),Req-2.2 + policies.open-cluster-management.io/standards: CIS-OCP,NERC-CIP,NIST-800-53,PCI-DSS + creationTimestamp: "2023-03-31T09:09:53Z" + generation: 1 + labels: + compliance.openshift.io/profile-bundle: ocp4 + name: ocp4-api-server-anonymous-auth + namespace: openshift-compliance + ownerReferences: + - apiVersion: compliance.openshift.io/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: ProfileBundle + name: ocp4 + uid: 19c2e4a5-094f-416a-a06b-eb0598e39618 + resourceVersion: "12971338" + uid: 12db5786-4ff6-4e80-90e0-2b370541f6e1 +rationale: When enabled, requests that are not rejected by other configured authentication + methods are treated as anonymous requests. These requests are then served by the + API server. If you are using RBAC authorization, it is generally considered reasonable + to allow anonymous access to the API Server for health checks and discovery purposes, + and hence this recommendation is not scored. However, you should consider whether + anonymous discovery is an acceptable risk for your purposes. +severity: medium +title: Ensure that anonymous requests to the API Server are authorized +```` + +### Running a Scan + +Now that we have the operator installed, we have two key configurations: + +- ScanSettings - This is the Schema for the scansettings API, and therefore you will provide configurations for running the scan, such as where it stores data, configurations for the container that is run on the platform to perform the scan, which components are subject to be scanned, and schedules to run the scan. +- ScanSettingsBinding - This is the Schema for the scansettingbindings API. This is used to bind the ScanSettings configuration to the compliance profiles you want to run against your chosen components. + +There is a default ScanSettings called ```default``` supplied when you install the Compliance Operator, which you can run against your system. + +````sh +$ oc describe scansettings default -n openshift-compliance + +Name: default +Namespace: openshift-compliance +Labels: +Annotations: +API Version: compliance.openshift.io/v1alpha1 +Kind: ScanSetting +Max Retry On Timeout: 3 +Metadata: + Creation Timestamp: 2023-03-31T09:09:33Z + Generation: 1 + Resource Version: 12971055 + UID: 78945c1e-c323-40d8-87d9-c571275d58e3 +Raw Result Storage: + Node Selector: + node-role.kubernetes.io/master: + Pv Access Modes: + ReadWriteOnce + Rotation: 3 + Size: 1Gi + Tolerations: + Effect: NoSchedule + Key: node-role.kubernetes.io/master + Operator: Exists + Effect: NoExecute + Key: node.kubernetes.io/not-ready + Operator: Exists + Toleration Seconds: 300 + Effect: NoExecute + Key: node.kubernetes.io/unreachable + Operator: Exists + Toleration Seconds: 300 + Effect: NoSchedule + Key: node.kubernetes.io/memory-pressure + Operator: Exists +Roles: + master + worker +Scan Tolerations: + Operator: Exists +Schedule: 0 1 * * * +Show Not Applicable: false +Strict Node Scan: true +Timeout: 30m +Events: +```` +You can read more details about the above [configuration here](https://docs.openshift.com/container-platform/4.12/security/compliance_operator/compliance-scans.html#running-compliance-scans_compliance-operator-scans), however, most of the lines are self-explanatory. + +There is a second provided ScanSettings called ```default-auto-apply```, which follows the same premise as the above, however` will auto-remediate any findings as part of the scan. + +Now we need to create a ScanSettingBinding to the CIS benchmark profiles. Create a YAML file using the below content called ````compliance-scansettingbinding.yaml```` and apply with ````oc apply -f compliance-scansettingbinding.yaml````. + +````yaml +apiVersion: compliance.openshift.io/v1alpha1 +kind: ScanSettingBinding +metadata: + name: cis-compliance + namespace: openshift-compliance +profiles: + - name: ocp4-cis-node + kind: Profile + apiGroup: compliance.openshift.io/v1alpha1 + - name: ocp4-cis + kind: Profile + apiGroup: compliance.openshift.io/v1alpha1 +settingsRef: + name: default + kind: ScanSetting + apiGroup: compliance.openshift.io/v1alpha1 +```` + +At this stage of the workflow, the Compliance Operator reconciles the ScanSettingBinding object, taking into account both the ```Binding``` and ```Bound``` settings. As a result, it generates a ComplianceSuite object along with the corresponding ComplianceScan objects to streamline the compliance evaluation process. + + +````sh +$ oc get compliancescan -n openshift-compliance +NAME PHASE RESULT +ocp4-cis AGGREGATING NOT-AVAILABLE +ocp4-cis-node-master AGGREGATING NOT-AVAILABLE +ocp4-cis-node-worker AGGREGATING NOT-AVAILABLE +```` +The scans will now work through the scanning phases and finish on the ```DONE``` phase once completed. At this point, you are probably going to find that the result is ```NON-COMPLIANT```. Now we can review the scan results and apply any necessary remediations to bring the cluster into compliance with the profile. + +````sh +$ oc get compliancescan -n openshift-compliance +NAME PHASE RESULT +ocp4-cis DONE NON-COMPLIANT +ocp4-cis-node-master DONE NON-COMPLIANT +ocp4-cis-node-worker DONE NON-COMPLIANT +```` + +Let's look at the first scan in more detail, as we also want to capture the label attached, so we can get the full results to view. + +````sh +$ oc get compliancescan -n openshift-compliance ocp4-cis -o yaml +```` + +````yaml +oc get compliancescan -n openshift-compliance ocp4-cis -o yaml +apiVersion: compliance.openshift.io/v1alpha1 +kind: ComplianceScan +metadata: + creationTimestamp: "2023-03-31T10:49:41Z" + finalizers: + - scan.finalizers.compliance.openshift.io + generation: 1 + labels: + compliance.openshift.io/suite: cis-compliance + name: ocp4-cis + namespace: openshift-compliance + ownerReferences: + - apiVersion: compliance.openshift.io/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: ComplianceSuite + name: cis-compliance + uid: c40db43f-0635-4731-b537-5ad3fc08cc06 + resourceVersion: "13035410" + uid: 9d5b10b8-f67c-44f3-b13d-0765cb037091 +spec: + content: ssg-ocp4-ds.xml + contentImage: registry.redhat.io/compliance/openshift-compliance-content-rhel8@sha256:c4bf5b2b20ff538adbc430b7ee993fbd7c291203a9810534005148304e3b169b + maxRetryOnTimeout: 3 + profile: xccdf_org.ssgproject.content_profile_cis + rawResultStorage: + nodeSelector: + node-role.kubernetes.io/master: "" + pvAccessModes: + - ReadWriteOnce + rotation: 3 + size: 1Gi + tolerations: + - effect: NoSchedule + key: node-role.kubernetes.io/master + operator: Exists + - effect: NoExecute + key: node.kubernetes.io/not-ready + operator: Exists + tolerationSeconds: 300 + - effect: NoExecute + key: node.kubernetes.io/unreachable + operator: Exists + tolerationSeconds: 300 + - effect: NoSchedule + key: node.kubernetes.io/memory-pressure + operator: Exists + scanTolerations: + - operator: Exists + scanType: Platform + showNotApplicable: false + strictNodeScan: true + timeout: 30m +status: + conditions: + - lastTransitionTime: "2023-03-31T10:51:20Z" + message: Compliance scan run is done running the scans + reason: NotRunning + status: "False" + type: Processing + - lastTransitionTime: "2023-03-31T10:51:20Z" + message: Compliance scan run is done and has results + reason: Done + status: "True" + type: Ready + phase: DONE + remainingRetries: 3 + result: NON-COMPLIANT + resultsStorage: + name: ocp4-cis + namespace: openshift-compliance + warnings: |- + could not fetch /apis/flowcontrol.apiserver.k8s.io/v1alpha1/flowschemas/catch-all: the server could not find the requested resource + could not fetch /apis/logging.openshift.io/v1/namespaces/openshift-logging/clusterlogforwarders/instance: the server could not find the requested resource + could not fetch /apis/apps/v1/namespaces/openshift-sdn/daemonsets/sdn: daemonsets.apps "sdn" not found + could not fetch "/api/v1/nodes/NODE_NAME/proxy/configz": the server could not find the requested resource + could not fetch "/api/v1/nodes/NODE_NAME/proxy/configz": the server could not find the requested resource + could not fetch "/api/v1/nodes/NODE_NAME/proxy/configz": the server could not find the requested resource + could not fetch "/api/v1/nodes/NODE_NAME/proxy/configz": the server could not find the requested resource + could not fetch "/api/v1/nodes/NODE_NAME/proxy/configz": the server could not find the requested resource + could not fetch "/api/v1/nodes/NODE_NAME/proxy/configz": the server could not find the requested resource + could not fetch "/api/v1/nodes/NODE_NAME/proxy/configz": the server could not find the requested resource + could not fetch "/api/v1/nodes/NODE_NAME/proxy/configz": the server could not find the requested resource + could not fetch "/api/v1/nodes/NODE_NAME/proxy/configz": the server could not find the requested resource + could not fetch "/api/v1/nodes/NODE_NAME/proxy/configz": the server could not find the requested resource + could not fetch "/api/v1/nodes/NODE_NAME/proxy/configz": the server could not find the requested resource + could not fetch "/api/v1/nodes/NODE_NAME/proxy/configz": the server could not find the requested resource + could not fetch "/api/v1/nodes/NODE_NAME/proxy/configz": the server could not find the requested resource + could not fetch "/api/v1/nodes/NODE_NAME/proxy/configz": the server could not find the requested resource + could not fetch /apis/hypershift.openshift.io/v1beta1/namespaces/clusters/hostedclusters/None: the server could not find the requested resource + Kubelet configs for 90days-ocp-72ptq-master-1 are not consistent with role master, Diff: [{"op":"replace","path":"/address","value":"192.168.200.183"}] of KubeletConfigs for master role will not be saved. + Kubelet configs for 90days-ocp-72ptq-worker-x7v4j are not consistent with role worker, Diff: [{"op":"replace","path":"/address","value":"192.168.200.194"}] of KubeletConfigs for worker role will not be saved. + Kubelet configs for 90days-ocp-72ptq-master-2 are not consistent with role master, Diff: [{"op":"add","path":"/address","value":"192.168.200.181"}] of KubeletConfigs for master role will not be saved. + Kubelet configs for 90days-ocp-72ptq-master-0 are not consistent with role control-plane, Diff: [{"op":"replace","path":"/address","value":"192.168.200.185"}] of KubeletConfigs for control-plane role will not be saved. + Kubelet configs for 90days-ocp-72ptq-master-2 are not consistent with role control-plane, Diff: [{"op":"add","path":"/address","value":"192.168.200.181"}] of KubeletConfigs for control-plane role will not be saved. + Kubelet configs for 90days-ocp-72ptq-worker-5cgp8 are not consistent with role worker, Diff: [{"op":"add","path":"/address","value":"192.168.200.187"}] of KubeletConfigs for worker role will not be saved. +```` + +In the output, we can see the warnings from the results straight away. To view the full results we can run the command below using the label from the above output. Alternatively, I can list all failed results across the conducted scans by running the command: + +````sh +$ oc get compliancecheckresults -n openshift-compliance -l 'compliance.openshift.io/check-status=FAIL' +NAME STATUS SEVERITY +ocp4-cis-api-server-encryption-provider-cipher FAIL medium +ocp4-cis-api-server-encryption-provider-config FAIL medium +ocp4-cis-audit-log-forwarding-enabled FAIL medium +ocp4-cis-configure-network-policies-namespaces FAIL high +ocp4-cis-kubeadmin-removed FAIL medium +ocp4-cis-node-master-kubelet-enable-protect-kernel-defaults FAIL medium +ocp4-cis-node-master-kubelet-enable-protect-kernel-sysctl FAIL medium +ocp4-cis-node-worker-kubelet-enable-protect-kernel-defaults FAIL medium +ocp4-cis-node-worker-kubelet-enable-protect-kernel-sysctl FAIL medium +```` + +We can look at the individual ```ComplianceRemediation``` in more detail with the command; + +````sh + oc get compliancecheckresults -n openshift-compliance ocp4-cis-audit-log-forwarding-enabled -o yaml +```` + +Which provides us the following output: + +````yaml +apiVersion: compliance.openshift.io/v1alpha1 +description: |- + Ensure that Audit Log Forwarding Is Enabled + OpenShift audit works at the API server level, logging all requests coming to the server. Audit is on by default and the best practice is to ship audit logs off the cluster for retention. The cluster-logging-operator is able to do this with the + + ClusterLogForwarders + + resource. The forementioned resource can be configured to logs to different third party systems. For more information on this, please reference the official documentation: https://docs.openshift.com/container-platform/4.6/logging/cluster-logging-external.html +id: xccdf_org.ssgproject.content_rule_audit_log_forwarding_enabled +instructions: |- + Run the following command: + oc get clusterlogforwarders instance -n openshift-logging -ojson | jq -r '.spec.pipelines[].inputRefs | contains(["audit"])' + The output should return true. +kind: ComplianceCheckResult +metadata: + annotations: + compliance.openshift.io/rule: audit-log-forwarding-enabled + creationTimestamp: "2023-03-31T10:51:02Z" + generation: 1 + labels: + compliance.openshift.io/check-severity: medium + compliance.openshift.io/check-status: FAIL + compliance.openshift.io/scan-name: ocp4-cis + compliance.openshift.io/suite: cis-compliance + name: ocp4-cis-audit-log-forwarding-enabled + namespace: openshift-compliance + ownerReferences: + - apiVersion: compliance.openshift.io/v1alpha1 + blockOwnerDeletion: true + controller: true + kind: ComplianceScan + name: ocp4-cis + uid: 9d5b10b8-f67c-44f3-b13d-0765cb037091 + resourceVersion: "13034914" + uid: c5b7342d-af35-4944-86bd-8a4f907acccc +rationale: Retaining logs ensures the ability to go back in time to investigate or + correlate any events. Offloading audit logs from the cluster ensures that an attacker + that has access to the cluster will not be able to tamper with the logs because + of the logs being stored off-site. +severity: medium +status: FAIL +```` + +This particular remediation has no automatic remediation, but you can see [another example here](https://docs.openshift.com/container-platform/4.12/security/compliance_operator/compliance-operator-remediation.html#compliance-review_compliance-remediation), whereby a ```MachineConfig``` resource will be applied by the remediation. Applying remediation can take different forms, depending on what the remediation is. Therefore I won't dive into this detail today, I think we've covered enough to understand how to run and view compliance checks against our platform. You can read more about [remediations here](https://docs.openshift.com/container-platform/4.12/security/compliance_operator/compliance-operator-remediation.html#compliance-applying_compliance-remediation). The final point I wanted to highlight on this topic, is the ```oc-compliance``` plugin, which extends the functionality of the ```oc``` CLI tool, you can few the [details and how to use it here](https://docs.openshift.com/container-platform/4.12/security/compliance_operator/oc-compliance-plug-in-using.html). + +# Red Hat Quay Container Security Operator + +## Vulnerability Scanning Overview + +Vulnerability scanning in Red Hat OpenShift refers to the process of inspecting container images for known security issues, such as outdated software packages, misconfigurations, or exposed sensitive information. The goal of vulnerability scanning is to identify and remediate potential security risks in container images before they are deployed to the OpenShift cluster, thus enhancing the overall security posture of the platform. + +OpenShift provides several features and tools to facilitate vulnerability scanning: + +- Integrated container registry: OpenShift includes a built-in container registry to store and manage container images. The integrated registry allows for a more streamlined and secure process when scanning images for vulnerabilities, as it eliminates the need to rely on external registries. + +- ImageStreams: An ImageStream in OpenShift is an abstraction that represents a series of related container images, typically different versions of the same application. ImageStreams simplify the process of tracking and deploying container images, making it easier to apply vulnerability scanning and remediation across multiple versions of an application. + +- Image signing and trust: OpenShift supports container image signing and the enforcement of signature-based trust policies. This feature ensures that only trusted and verified images can be deployed to the cluster, helping to prevent the deployment of images with known vulnerabilities. + +- Third-party integrations: OpenShift can be easily integrated with external vulnerability scanning tools and platforms, such as Aqua Security, Sysdig, or Twistlock. These tools can be configured to automatically scan container images stored in the OpenShift registry and provide detailed reports on identified vulnerabilities and suggested remediation steps. + +- OpenShift Operators: OpenShift supports the use of Operators, which are automated software extensions that manage applications and their components. Operators can be used to deploy and manage vulnerability scanning tools within the OpenShift cluster, ensuring a consistent and automated scanning process. Red Hat provides the ```Red Hat Quay Container Security Operator```, however, you can also implement third-party scanners such as [Trivy](https://github.com/aquasecurity/trivy) from [Aqua Security](https://aquasec.com/). + +By leveraging these features and tools, Red Hat OpenShift enables organizations to perform comprehensive vulnerability scanning on container images, reducing the risk of security breaches and enhancing the overall security of the platform. + +Focusing on the ```Red Hat Quay Container Security Operator```, this provides the following: + +- Watches containers associated with pods on all or specified namespaces + +- Queries the container registry where the containers came from for vulnerability information, provided an image’s registry is running image scanning (such as Quay.io or a Red Hat Quay registry with Clair scanning) + +- Exposes vulnerabilities via the ImageManifestVuln object in the Kubernetes API + +## Installing the Red Hat Quay Container Security Operator + +This time I'm going to provide instructions on how to perform these steps in the Red Hat Console interface, rather than CLI. + +1. In the administrator view within the console, navigate to Operators > OperatorHub and search for "Red Hat Quay Container Security Operator". +2. Select the tile, and click to install. +3. Confirm the settings + - All namespaces and automatic approval strategy are selected, by default. +4. Select Install. The Container Security Operator appears after a few moments on the Installed Operators screen. + +When you now browse to the homepage of the Red Hat OpenShit Console, you will see an "Image vulnerability" component on the status tile, which you can select to see high-level information about your estate. + +![Red Hat OpenShift Console - Image vulnerability](/2023/images/Day62%20-%20Red%20Hat%20Quay%20Container%20Security%20Operator/Red%20Hat%20Console%20-%20Image%20vulnerability.jpg) + +You can click on the circle graph or the namespaces to see more details which takes you to the navigation page of Adminstration (1) > Image Vulnerabilities (2). + +Now you can see a list of the vulnerabilities and you can change the project view for all projects or a specific one to curate this list. + +![Red Hat OpenShift Console - Administration - Image vulnerabilities](/2023/images/Day62%20-%20Red%20Hat%20Quay%20Container%20Security%20Operator/Red%20Hat%20OpenShift%20Console%20-%20Administration%20-%20Image%20vulnerabilities.jpg) + +Clicking the image name (3) will show further manifest details via the OpenShift console, including which pods are affected. Or you can click the Manifest details on the right-hand side (4) which will take you to the Quay Security Scanner report hosted on [Quay.io](https://Quay.io). + +Below shows the Image manifest details including each vulnerability found with that image, and links to appropriate documentation, such as CVE information held on [access.redhat.com](https://access.redhat.com +) +![Red Hat OpenShift Console - Administration - Image vulnerabilities - Manifest details](/2023/images/Day62%20-%20Red%20Hat%20Quay%20Container%20Security%20Operator/Red%20Hat%20OpenShift%20Console%20-%20Administration%20-%20Image%20vulnerabilities%20-%20Manifest%20details.jpg) + +Below is the ```affected pods``` tab view on the Image manifests page. + +![Red Hat OpenShift Console - Administration - Image vulnerabilities - Manifest details - Affected pods](/2023/images/Day62%20-%20Red%20Hat%20Quay%20Container%20Security%20Operator/Red%20Hat%20OpenShift%20Console%20-%20Administration%20-%20Image%20vulnerabilities%20-%20Manifest%20details%20-%20Affected%20pods.jpg) + +And finally the Quay Security Scanner page for one of the images shown in the report. This was for my pacman application, you can see the Quay.io report yourself [here](https://quay.io/repository/ifont/pacman-nodejs-app/manifest/sha256:196ae9a1a33a2d32046a46739779ca273667f1d4f231f8a721e8064c3509405e?tab=vulnerabilities)(free sign up account required). + +![Red Hat OpenShift Console - Administration - Image vulnerabilities - Quay Manifest](/2023/images/Day62%20-%20Red%20Hat%20Quay%20Container%20Security%20Operator/Red%20Hat%20OpenShift%20Console%20-%20Administration%20-%20Image%20vulnerabilities%20-%20Quay%20Manifest.jpg) + +Of course we can also see information in the command line too, to see all vulnerabilities found, use the command: + +```sh +oc get vuln --all-namespaces +NAMESPACE NAME AGE +openshift-apiserver-operator sha256.01974e4c0e0d112e09bee8fe2625d565d3d62fa42013b38d7ce43d2d40f6057a 20h +openshift-apiserver sha256.13640b919950fc648219c528ee7ed30262bae856566fbd6c4cb5e15ffd457d6f 20h +openshift-apiserver sha256.8829aefa24dd606d2fe3ff86b97858c07acedae5f5eb3f044c20395762e7c02b 20h +openshift-authentication-operator sha256.31b617cec5c22e187cc22da606fc6998ea3529b1b6e8d80d1799c3dc9705997e 20h +openshift-authentication sha256.41e06255fc823c0082a74466b69ccfb672947b7075ea43a10e729c5f39314d00 20h +openshift-cloud-controller-manager-operator sha256.a7856b6371fc4a7ade8a678daca149db6c6a55ee7137d9e308721d2d3bebf364 20h +openshift-cloud-credential-operator sha256.1986315effe0f3ee415e86df3a87765268ed1da405c7a297c278e1d7030286a4 20h +... +openshift-vsphere-infra sha256.ddf81e535cf7a6b2775f3db690ec1e6eaa1c7427a0f9b98ce120d8ad06520440 20h +test-app sha256.196ae9a1a33a2d32046a46739779ca273667f1d4f231f8a721e8064c3509405e 20h +``` + +You can inspect the details of a specific vulnerability by running the command: + +```sh +oc describe vuln -n {namespace} {sha ID of vuln} + +# Example + +oc describe vuln -n openshift-apiserver-operator sha256.01974e4c0e0d112e09bee8fe2625d565d3d62fa42013b38d7ce43d2d40f6057a +``` + +Example output: + +```yaml +Name: sha256.01974e4c0e0d112e09bee8fe2625d565d3d62fa42013b38d7ce43d2d40f6057a +Namespace: openshift-apiserver-operator +Labels: openshift-apiserver-operator/openshift-apiserver-operator-7bd84bd596-pgpct=true +Annotations: +API Version: secscan.quay.redhat.com/v1alpha1 +Kind: ImageManifestVuln +Metadata: + Creation Timestamp: 2023-03-30T19:01:40Z + Generation: 17 + Resource Version: 13206497 + UID: dbec02e5-e4c6-412f-b561-757237844d43 +Spec: + Features: + Name: pip + Version: 9.0.3 + Vulnerabilities: + Description: Pip 21.1 updates its dependency 'urllib3' to v1.26.4 due to security issues. + Metadata: {"UpdatedBy": "pyupio", "RepoName": "pypi", "RepoLink": "https://pypi.org/simple", "DistroName": "", "DistroVersion": "", "NVD": {"CVSSv3": {"Vectors": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N", "Score": 6.5}}} + Name: pyup.io-40291 (CVE-2021-28363) + Namespace Name: pyupio + Severity: Medium + Description: A flaw was found in python-pip in the way it handled Unicode separators in git references. A remote attacker could possibly use this issue to install a different revision on a repository. The highest threat from this vulnerability is to data integrity. This is fixed in python-pip version 21.1. + Metadata: {"UpdatedBy": "pyupio", "RepoName": "pypi", "RepoLink": "https://pypi.org/simple", "DistroName": "", "DistroVersion": "", "NVD": {"CVSSv3": {"Vectors": "CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:N/I:H/A:N", "Score": 5.7}}} + Name: pyup.io-42559 (CVE-2021-3572) + Namespace Name: pyupio + Severity: Medium + Description: Pip before 19.2 allows Directory Traversal when a URL is given in an install command, because a Content-Disposition header can have ../ in a filename, as demonstrated by overwriting the /root/.ssh/authorized_keys file. This occurs in _download_http_url in _internal/download.py. + Metadata: {"UpdatedBy": "pyupio", "RepoName": "pypi", "RepoLink": "https://pypi.org/simple", "DistroName": "", "DistroVersion": "", "NVD": {"CVSSv3": {"Vectors": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N", "Score": 7.5}}} + Name: pyup.io-38765 (CVE-2019-20916) + Namespace Name: pyupio + Severity: High + Name: openssl-libs + Version: 1:1.1.1k-7.el8_6 + Vulnerabilities: + Description: OpenSSL is a toolkit that implements the Secure Sockets Layer (SSL) and Transport Layer Security (TLS) protocols, as well as a full-strength general-purpose cryptography library. + +Security Fix(es): + +* openssl: X.400 address type confusion in X.509 GeneralName (CVE-2023-0286) + +For more details about the security issue(s), including the impact, a CVSS score, acknowledgments, and other related information, refer to the CVE page(s) listed in the References section. + Fixedby: 1:1.1.1k-8.el8_6 + Link: https://access.redhat.com/errata/RHSA-2023:1441 https://access.redhat.com/security/cve/CVE-2023-0286 + Metadata: {"UpdatedBy": "RHEL8-rhel-8.6-eus", "RepoName": "cpe:/o:redhat:rhel_eus:8.6::baseos", "RepoLink": null, "DistroName": "Red Hat Enterprise Linux Server", "DistroVersion": "8", "NVD": {"CVSSv3": {"Vectors": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:H", "Score": 7.4}}} + Name: RHSA-2023:1441: openssl security update (Important) + Namespace Name: RHEL8-rhel-8.6-eus + Severity: High + Name: urllib3 + Version: 1.24.2 + Vulnerabilities: + Description: Urllib3 1.26.5 includes a fix for CVE-2021-33503: When provided with a URL containing many @ characters in the authority component, the authority regular expression exhibits catastrophic backtracking, causing a denial of service if a URL were passed as a parameter or redirected to via an HTTP redirect. + Metadata: {"UpdatedBy": "pyupio", "RepoName": "pypi", "RepoLink": "https://pypi.org/simple", "DistroName": "", "DistroVersion": "", "NVD": {"CVSSv3": {"Vectors": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H", "Score": 7.5}}} + Name: pyup.io-43975 (CVE-2021-33503) + Namespace Name: pyupio + Severity: High + Description: urllib3 before 1.25.9 allows CRLF injection if the attacker controls the HTTP request method, as demonstrated by inserting CR and LF control characters in the first argument of putrequest(). NOTE: this is similar to CVE-2020-26116. + Metadata: {"UpdatedBy": "pyupio", "RepoName": "pypi", "RepoLink": "https://pypi.org/simple", "DistroName": "", "DistroVersion": "", "NVD": {"CVSSv3": {"Vectors": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N", "Score": 7.2}}} + Name: pyup.io-38834 (CVE-2020-26137) + Namespace Name: pyupio + Severity: High + Name: setuptools + Version: 39.2.0 + Vulnerabilities: + Description: Python Packaging Authority (PyPA) setuptools before 65.5.1 allows remote attackers to cause a denial of service via HTML in a crafted package or custom PackageIndex page. There is a Regular Expression Denial of Service (ReDoS) in package_index.py. + Metadata: {"UpdatedBy": "pyupio", "RepoName": "pypi", "RepoLink": "https://pypi.org/simple", "DistroName": "", "DistroVersion": "", "NVD": {"CVSSv3": {"Vectors": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H", "Score": 5.9}}} + Name: pyup.io-52495 (CVE-2022-40897) + Namespace Name: pyupio + Severity: Medium + Image: quay.io/openshift-release-dev/ocp-v4.0-art-dev@sha256 + Manifest: sha256:01974e4c0e0d112e09bee8fe2625d565d3d62fa42013b38d7ce43d2d40f6057a +Status: + Affected Pods: + openshift-apiserver-operator/openshift-apiserver-operator-7bd84bd596-pgpct: + cri-o://dd4fcb700a95c041d19bf7829d3e07516ccf2a36522027f920d76ed0aa57f84c + Fixable Count: 1 + High Count: 4 + Highest Severity: High + Last Update: 2023-03-31 15:31:32.853602342 +0000 UTC + Medium Count: 3 +Events: +``` + +# Summary + +Whilst for this 2023 edition focusing on DevSecOps, we could have purely spent time focusing on Security and Compliance for Red Hat OpenShift in-depth, I wanted to start at a higher level, understanding why you would choose an enterprise Kubernetes offering, and what features will enhance your cloud-native platform. Hopefully, this has given you a solid understanding of this offering, as well as being able to understand the basics of how to run and operate it. Another area we only touched upon briefly was application deployment, instead focusing on the security posture of deploying workloads, rather than the methods of building and running the applications themselves. This topic of application build, deployment and management requires a whole section on its own. + +I urge you to spend time reading through the official documentation for Red Hat OpenShift, it's quite comprehensive with the information you need to fully get to grips and operate the platform. + +## Resources + +- Red Hat OpenShift Documentation + - [OpenShift Container Platform security and compliance](https://docs.openshift.com/container-platform/4.12/security/index.html) + - [Understanding container security](https://docs.openshift.com/container-platform/4.12/security/container_security/security-understanding.html#security-understanding) + - [Troubleshooting the Compliance Operator](https://docs.openshift.com/container-platform/4.12/security/compliance_operator/compliance-operator-troubleshooting.html) + - [Running the Red Hat Quay Container Security Operator](https://docs.openshift.com/container-platform/4.12/security/pod-vulnerability-scan.html) + - [Securing container content](https://docs.openshift.com/container-platform/4.12/security/container_security/security-container-content.html) +- [Red Hat OpenShift security guide (ebook)](https://www.redhat.com/en/resources/openshift-security-guide-ebook) +- YouTube - [ CVE and CVSS explained | Security Detail | Presented by Red Hat](https://www.youtube.com/watch?v=oSyEGkX6sX0) \ No newline at end of file diff --git a/2023/day63.md b/2023/day63.md index e018133..8dc0ac9 100644 --- a/2023/day63.md +++ b/2023/day63.md @@ -14,7 +14,7 @@ Here’s what we’ll be covering: - - Database security - Monitoring and troubleshooting database issues -We’ll also be providing examples to accompany the concepts discussed. In order to do so you will need Docker Desktop installed. Docker can be downloaded here (https://www.docker.com/products/docker-desktop/) and is completely free. +We’ll also be providing examples to accompany the concepts discussed. In order to do so you will need Docker Desktop installed. Docker can be downloaded here (https://www.docker.com/products/docker-desktop/) and is completely free. Alternatives to Docker Desktop can be used (such as Rancher Desktop or Finch) but the examples will focus on Docker. @@ -131,4 +131,6 @@ The great thing about databases is that there are so many choices to choose from Join us tommorrow when we'll be talking about querying databases. -Thanks for reading! \ No newline at end of file +Thanks for reading! + +See you in [Day 64](day64.md). diff --git a/2023/day64.md b/2023/day64.md index 3bbf028..df46157 100644 --- a/2023/day64.md +++ b/2023/day64.md @@ -288,3 +288,5 @@ So that’s how to retrieve, update, and delete data from a database. We also lo Join us tommorrow where we will be looking at backing up and restoring databases. Thank you for reading! + +See you in [Day 65](day65.md). diff --git a/2023/day65.md b/2023/day65.md index f07eae5..2fab0a7 100644 --- a/2023/day65.md +++ b/2023/day65.md @@ -251,3 +251,5 @@ The data is back! We have successfully performed a point in time restore of our Join us tomorrow where we will be talking about high availability and disaster recovery. Thanks for reading! + +See you in [Day 66](day66.md). diff --git a/2023/day66.md b/2023/day66.md index 2837813..3601640 100644 --- a/2023/day66.md +++ b/2023/day66.md @@ -1,6 +1,5 @@ # High availability and disaster recovery - Hello and welcome to the fourth post in the database part of the 90 Days of DevOps blog series! Today we’ll be talking about high availability and disaster recovery. One of the main jobs of a database administrator is to configure and maintain disaster recovery and high availability strategies for the databases that they look after. In a nutshell they boil down to: - @@ -207,3 +206,4 @@ Join us tomorrow where we'll be talking about performance tuning. Thanks for reading! +See you in [Day 67](day67.md). diff --git a/2023/day67.md b/2023/day67.md index 348ffaf..3671d3c 100644 --- a/2023/day67.md +++ b/2023/day67.md @@ -136,3 +136,5 @@ And there we have it! Our query now has a supporting index! Join us tommorrow where we'll be talking about database security. Thanks for reading! + +See you in [Day 68](day68.md). \ No newline at end of file diff --git a/2023/day68.md b/2023/day68.md index 75274e4..5f073a3 100644 --- a/2023/day68.md +++ b/2023/day68.md @@ -205,3 +205,4 @@ So if we have sensitive data within our database, this is one method of encrypti Join us tomorrow for the final post in the database series of 90DaysOfDevOps where we'll be talking about monitoring and troubleshooting. Thanks for reading! +See you in [Day 69](day69.md). diff --git a/2023/day69.md b/2023/day69.md index 22b8131..0f27854 100644 --- a/2023/day69.md +++ b/2023/day69.md @@ -161,4 +161,6 @@ Caution does need to be taken with some of these tools as they can have a negati So having the correct monitoring, log collection, and query tracking tools are vital when it comes to not only preventing issues from arising but allowing for quick resolution when they do occur. -And that’s it for the database part of the 90DaysOfDevOps blog series. We hope this has been useful…thanks for reading! \ No newline at end of file +And that’s it for the database part of the 90DaysOfDevOps blog series. We hope this has been useful…thanks for reading! + +See you in [Day 70](day70.md). diff --git a/2023/day70.md b/2023/day70.md index e69de29..b5dc40f 100644 --- a/2023/day70.md +++ b/2023/day70.md @@ -0,0 +1,19 @@ +# What is Serverless? + +The term "Serverless" has become quite the buzzword over these past few years, some folks today even arguing whether or not the term still holds weight. You may or may not have heard about serverless technology up to this point in your journey through development. But what exactly is serverless? What does it mean to design applications in a serverless manner? What constitutes a serverless service or offering? I hope to answer all these questions and more over this series of blog posts. + +As an [AWS Hero](https://aws.amazon.com/developer/community/heroes/kristi-perreault/?did=dh_card&trk=dh_card) and a Principal Software engineer at a large Fortune 100 enterprise, I have been focused solely on serverless technologies and enablement over the last 3 years. I have spoken quite extensively about our [serverless journey](https://youtu.be/ciCz8dnDuEs), [what serverless means in a large enterprise](https://syntax.fm/show/484/supper-club-70-000-serverless-functions-with-kristi-perreault-of-liberty-mutual), and [how to be successful in a corporate setting](https://www.youtube.com/watch?v=ctdviJ2Ewio). Everything I have learned has been through experience, on-the-job. The [serverless definition](https://aws.amazon.com/serverless/) I resonate with most states that serverless is event-driven, your resources scale up and down without you needing to manage them, and follows an "only pay for what you use" model. Let's break this down a bit further: + +- [Event-driven architecture](https://aws.amazon.com/event-driven-architecture/#:~:text=An%20event%2Ddriven%20architecture%20uses,on%20an%20e%2Dcommerce%20website.) is exactly how it sounds. You build your applications following the flow of your events. When x happens, I want to trigger y, to run service z. We write our serverless applications with this flow in mind. + +- Automatically scaling up and down as your service demands is a key component of serverless functionality. I fault the name "serverless" here a quite a bit, because contrary to popular belief, serverless does in fact include servers - you just don't need to manage them in the same way you would with your on-premises ecosystem or other cloud resources. You still need to provision the resources you need, and some configuration is required, but gone are the days of estimating exactly how much storage and processing power you need - your cloud provider handles this for you. This frees the developer up for focusing more on business code, and less on physical infrastructure. + +- With automatic scaling, this also lends you to only pay for exactly what you are using. You no longer need to buy and maintain a physical server you may only use to half its capacity, save for the one time of year your traffic hits its peak, for instance. You don't need to pay for all the storage and processing power you have to have "just in case" - you pay exactly for what you use, exactly when you need it. No more, no less. + +I am a large proponent of serverless, and I believe these are huge benefits to adopting serverless, but that does not mean it is for everyone or every architecture. I talk quite a bit about the concept of "[serverless-first](https://www.liberty-it.co.uk/stories/articles/tomorrow-talks-how-build-serverless-first-developer-experience)" design, meaning that you approach every architecture in a serverless manner first, and if that is not the most optimal design, you move on to other solutions like containers, relational databases, reserved compute instances, and so on. Equally as important, especially in a large enterprise, is to evaluate your time constraints and areas of expertise. Serverless is not going to be for everyone, and depending on your background, there can be a large learning curve associated with adopting it. The trade off is worth it, but if you do not have the adequate time or drive to dedicate to this transformation, you will not be successful. + +That being said, I hope to provide you with a strong starting point for the land of serverless. Over the next few days, we will be exploring serverless resources and services, from compute, to storage, to API design, and more. We will keep our discussions high-level, but I'll be sure to include relevant examples, resources, and further reading from other leading industry experts. No prerequisites are necessary, I just ask you approach each and every article with an open mind, continue to ask questions & provide feedback, and let's dive in!* + +*As a quick disclaimer - as I am an AWS Serverless Hero, most of the examples and explanations I give will reference the AWS ecosystem since that is where my expertise is. Many of the AWS services and tools we will discuss have equivalents across Azure, GCP, or other tooling. I will do my best to call these out going forward. This is part of a series that will be covered here, but I also encourage you to follow along on [Medium](https://kristiperreault.medium.com/what-is-serverless-1b46a5ffa7b3) or [Dev.to](https://dev.to/aws-heroes/what-is-serverless-4d4p) for more. + +See you in [Day 71](day71.md). diff --git a/2023/day71.md b/2023/day71.md index e69de29..9724a25 100644 --- a/2023/day71.md +++ b/2023/day71.md @@ -0,0 +1,29 @@ +# Serverless Compute + +Compute is one of the basic building blocks of building any application. What is your application aiming to accomplish? Where are you keeping your business logic? What are you _running_ and **how**? + +![Woman at computer. Image via Unsplash.](images/day71-1.jpg) + +The key compute resource everyone immediately associates serverless with is [AWS Lambda](https://aws.amazon.com/lambda/). I want to be clear here - AWS Lambda is a large part of the serverless ecosystem, BUT Lambda ≠ serverless. Just because you include a lambda function in your application does not automatically make you serverless. Likewise, just because you build a service completely out of lambda functions also does not mean you have a serverless application. Serverless is a mindset, a new way of thinking; there are tons of tools and services out there that will help you build serverless applications, but implementing them does not mean you have a serverless application. We need to be intentional with our design, and where & how we use these resources. + +**AWS Lambda** +If you're in Azure, your equivalent service is [Azure Functions](https://learn.microsoft.com/en-us/azure/azure-functions/). For Google, this is [Google Functions](https://cloud.google.com/functions) (yes, AWS just HAD to be different). Regardless of its name, all of these services fulfill the same purpose - a small compute building block to house your business logic code. An AWS Lambda function is simply the code you want to run, written in your language of choice (I preference Python, but Typescript and Java are popular options). In your [infrastructure code](https://learn.microsoft.com/en-us/devops/deliver/what-is-infrastructure-as-code#:~:text=Infrastructure%20as%20code%20(IaC)%20uses,load%20balancers%2C%20and%20connection%20topologies.), you specify some [lambda function basics](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-function.html?highlight=create%20lambda%20function), like name, path to the business logic code, security role, and what runtime you're using, and optionally have the ability to control more parameters like timeout, concurrency, aliases, and more. Lambda even has built in integrations to other AWS services, such as [S3](https://aws.amazon.com/s3/) and [SQS](https://aws.amazon.com/sqs/) (we'll get to these) to make application development even easier. Additionally, [lambda functions are priced](https://aws.amazon.com/lambda/pricing/) based on the number of times they're invoked and the duration of time they run, making them exceptionally affordable. + + +![Lambda is one single building block of a larger application. Image via Unsplash.](images/day71-3.jpg) + +Of course, there are cases where lambda functions may not be the best option for compute, if you have long-running, highly complex computational processes, lambda functions may not be the best fit for your application. If you're migrating an application to serverless, it's also very likely that this is not a 1:1 changeover. Throwing all of your code into one lambda function is not optimizing for serverless, meaning that your monolith architecture may need to be written into [microservices](https://aws.amazon.com/microservices/) to take full advantage of everything lambda and serverless has to offer. Whether you're migrating or building something brand new however, lambda functions are (dare I say) the choice for serverless compute as they're lightweight, easy to provision, and cost effective. + +**AWS Fargate** +AWS defines [Fargate](https://docs.aws.amazon.com/AmazonECS/latest/userguide/what-is-fargate.html) as a 'serverless compute engine', but I prefer to define it as a serverless container. [Containers](https://aws.amazon.com/containers/services/) are an entirely different topic of discussion so I won't dive into them too much, but they do fall under the same "[modern applications](https://aws.amazon.com/modern-apps/)" umbrella that serverless does, making them a sort of sibling option. Containerizing an application is a fancy way of saying you are bundling all aspects of your application into a more portable service (ie, basically sticking your app into a box for ease of movement and use). This makes containers very popular for migrating applications, batch processing, AI/ML, and more. + +Fargate stands sort of in the middle as a container service that offers many of the same serverless benefits that lambda has - no need to manage your infrastructure, built-in integrations to other AWS services, and pay-as-you-go pricing. What makes you choose one compute option over the other then? In my experience, this really comes down to what you want your end product to be, what time you have, and what experience you have. Personally, Fargate is more of a 'lift-and-shift' solution for applications that you don't want to change much of, but need to move quickly and easily while wanting to take advantage of serverless benefits. It definitely has its place as part of other applications as well, but it also comes down to the level of comfort you or your teams have with serverless or containerization. Containers may be quicker to adopt, whereas serverless requires more of a mindset shift, and typically comes with some rearchitecting. I believe this does pay off tenfold in the long run, but given your particular use cases and time constraints, Fargate may be a better option. + + +![Fargate is a serverless container service. Image via Unsplash.](images/day71-2.jpg) + +These two options pretty much sum up serverless compute, believe it or not. When it comes to your business logic code in AWS or other cloud provider, these two services cover most, if not all, serverless application needs. As we continue on in this series, you'll realize there are a ton of other 'supporting' serverless services for storage, APIs, orchestration, and more to dive into. I hope this has given you a good preview on serverless compute and what's to come, tune in tomorrow where we'll discuss the various serverless storage solutions available to us. See you then! + +*This is part of a series that will be covered here, but I also encourage you to follow along with the rest of the series on [Medium](https://kristiperreault.medium.com/serverless-compute-b19df2ea0935) or [Dev.to](https://dev.to/aws-heroes/serverless-compute-3bgo). + +See you in [Day 72](day72.md). diff --git a/2023/day72.md b/2023/day72.md index e69de29..a1e4b43 100644 --- a/2023/day72.md +++ b/2023/day72.md @@ -0,0 +1,35 @@ +# Serverless Storage + +[Lambda functions](https://aws.amazon.com/lambda/) and [Fargate](https://aws.amazon.com/fargate/) serve a great purpose and might accomplish what you need for a very small, [hello world-type project](https://aws.amazon.com/getting-started/hands-on/run-serverless-code/), but chances are you want to do a bit more with your serverless applications. Maybe you have a subscription-based product and you have user profiles with data. Or maybe your application is an e-commerce site and you need to store sensitive information, like credit card details. Or maybe you're just trying to save some images or files. Whatever the reason, you clearly need a storage solution, and this is where our serverless storage options come in. + +![Storage Solutions for every need! Image via Unsplash.](images/day72-1.jpg) + +Depending on what you're storing, how frequently you access stored items, and how you want to interact with them, you have a number of choices regarding file & image stores and serverless databases. Over the years, AWS has released a number of choices (some, may argue, aren't necessarily within the 'serverless' category even when named as such) but the number one choice in its humble beginnings was Amazon S3. + +**Amazon S3** +[Amazon S3](https://aws.amazon.com/s3/) is a popular abbreviation for 'Simple Storage Solution' and is known as [object storage](https://aws.amazon.com/what-is/object-storage/). You can store any number of items in S3, from various documents, to images, videos, entire file systems, and so on. In order to store these resources, you provision your own storage space, known as an S3 'Bucket'. The easiest way to describe a bucket is to compare it to a folder on your computer. Your 'Documents' folder, for instance, may contain all of your Word documents, and you may have sub folders within it, say for 'recipes' or 'projects' or 'schoolwork'. S3 buckets operate similarly, and just like your Documents folder, you can include sub folders and all different resource types. S3 is also a very popular choice for hosting static websites, and just like any other cloud offering, there are also plenty of security constraints in place for you to take advantage of, like bucket encryption, read-only access, and [more](https://aws.amazon.com/s3/security/). + + +![S3 Buckets are an example of an object storage solution. Image via Unsplash.](images/day72-2.jpg) + +Of course, there are tons of other great advantages to using S3 buckets. Many of AWS's other great resources, like Lambda, have [direct integration with S3](https://docs.aws.amazon.com/lambda/latest/dg/with-s3-example.html), making it easy to access and read/write directly to your bucket. S3 also has [different types of storage classes](https://aws.amazon.com/s3/storage-classes/), like Intelligent Tiering and Glacier, that are more cost-effective for items that are accessed infrequently or for very large storage amounts. S3 is a global storage solution though, meaning that the name of your bucket must be unique across all AWS accounts within your regional partition (so yes, it is likely 'test-bucket' is taken). Whatever your storage need may be, S3 can be an effective solution, and one that is significantly cheaper and more secure than your on-premises solution or office filing cabinet. + +**Amazon DynamoDB** +As developers, sometimes we are working with larger, very structured datasets that involve [schemas](https://www.ibm.com/topics/database-schema) and specific [access patterns](https://docs.aws.amazon.com/prescriptive-guidance/latest/dynamodb-data-modeling/step3.html). For these, a database solution makes much more sense, and luckily we have a serverless option for that too! [DynamoDB](https://aws.amazon.com/dynamodb/) is a NoSQL database solution that offers lightning fast performance, 'near unlimited' throughput and storage, and backup, restore, and multi-region replication to ensure your data is always available and secure. You can interact with your database using queries, scans, read/writes, and more, all from the AWS console or the comfort of your favorite programming language. + + +![Sort of like the Dewey Decimal System, Single Table Design with DynamoDB allows you to store and 'catalog' all different types of data you may need to collect. Image via Unsplash.](images/day72-3.jpg) + +DynamoDB is a powerful service, but you really will not be able to capitalize on all it has to offer unless you structure your data for Single Table Design. I will admit, mastering the art of [Single Table Design](https://aws.amazon.com/blogs/compute/creating-a-single-table-design-with-amazon-dynamodb/) (I just tried to abbreviate that, and I will never do that again..) is not easy; I would go so far to say that it is probably one of the most difficult parts of serverless development (if you're having trouble, the resources [Alex DeBrie](https://aws.amazon.com/blogs/compute/creating-a-single-table-design-with-amazon-dynamodb/) puts out for this are unparalleled). You really need to have a good grasp on your dataset, understand ALL of your access patterns up front to plan your [Primary Keys (PKs)](https://aws.amazon.com/premiumsupport/knowledge-center/primary-key-dynamodb-table/) and [Global Secondary Indices (GSIs)]( +https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GSI.html) accordingly. I don't want to go too in-depth into this topic, since there are literally [full books on the subject](https://www.dynamodbbook.com/), but just know that although I think the advantages you have when using DynamoDB to its full potential are well worth it, this can be a steep learning curve and isn't going to be the database storage solution for everyone. + +**Amazon EFS, Amazon RDS Proxy, Amazon Aurora Serverless, Amazon Redshift Serverless, Amazon Neptune Serverless** +This is my serverless database catch-all section. In my opinion, S3 and DynamoDB are really the storage solutions you need for serverless development, however, you may find some use cases for these remaining serverless storage options. [EFS is the Elastic File System](https://aws.amazon.com/efs/), which automagically sizes for the number of files you have (S3 covers many file storage situations, but if you have something specific in mind, you may want to use EFS). [RDS Proxy](https://aws.amazon.com/rds/proxy/) makes relational database connections more secure. [Aurora](https://aws.amazon.com/rds/aurora/serverless/), [Redshift](https://aws.amazon.com/redshift/redshift-serverless/), and [Neptune Serverless](https://aws.amazon.com/neptune/serverless/) are basically the serverless versions of these three AWS service offerings. Some of these are up for debate in the serverless community as to whether or not they really constitute as serverless offerings, but since they are not databases I have had a use for in my short career, I will abstain from weighing in here. + +![Keep your files safe and secure with any number of serverless file storage options, like EFS. Image via Unsplash.](images/day72-4.jpg) + +Well, this about sums up the serverless storage solutions available. As always, there are definitely equivalents of these resources in your cloud provider of choice, and you can't go wrong with any service you choose, as long as you're evaluating based on your specific application needs. Join me tomorrow, as we take another step further into serverless with API design.* + +*This is part of a series that will be covered here, but I also encourage you to follow along with the rest of the series on [Medium](https://kristiperreault.medium.com/serverless-storage-4b7974683d3d) or [Dev.to](https://dev.to/aws-heroes/serverless-storage-50i3). + +See you in [Day 73](day73.md). diff --git a/2023/day73.md b/2023/day73.md index e69de29..a7120ca 100644 --- a/2023/day73.md +++ b/2023/day73.md @@ -0,0 +1,23 @@ +# Serverless APIs + +If you're new to the application development world, [API stands for Application Programming Interface](https://aws.amazon.com/what-is/api/), an interface that offers a 'service' of sorts for applications to consume. [Google Maps](https://www.google.com/maps), for instance, has a [public API](https://developers.google.com/maps) that you or I could use if we're building an application to locate all of the restaurants in our town. They surface this, and many, many other data points via documented endpoints, and we can use things like [API keys](https://cloud.google.com/endpoints/docs/openapi/when-why-api-key) to access this data. If you're a developer, chances are you will build an API at some point in your career, if not several, and you will definitely work with them. As a key building block in application development, [AWS provides a few API solutions](https://aws.amazon.com/serverless/). + +![Open laptop with code. Image via Unsplash.](images/day73-1.jpg) + +**Amazon API Gateway** +Let's say you have a travel website - you have your frontend application, and you have your backend application that has some [lambda functions](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) to handle users creating, updating, and deleting their vacation reservations, which interacts with a [DynamoDB table](https://aws.amazon.com/dynamodb/) that is saving all this information for you. Your frontend application, however, needs to be able to communicate and pass information back and forth with these lambda functions. This is where an [API Gateway](https://aws.amazon.com/api-gateway/) comes in. An API Gateway is typically a [REST API](https://aws.amazon.com/what-is/restful-api/) ([Websocket](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-overview.html) is also an option) that manages different endpoints for your application. For instance, when a user creates a reservation, the frontend application may hit a POST endpoint on your API called 'createReservation', and you can configure your API to directly integrate with your 'createReservation' lambda function, where you might do something like create a new reservation ID and save it to a DynamoDB table. + +![Google Maps API. Image via Unsplash.](images/day73-2.jpg) + +This is just one fairly straightforward example; you might already be able to see how this can get very complex very quickly. It helps that API Gateway has tons of [configuration options](https://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-develop.html), allowing you to set up your level of application monitoring and logging, set concurrency and throttling on your API calls, directly integrate with multiple services, and, of course, your authorization and access levels. With API Gateway, [you pay for the calls you receive and the data you send out](https://aws.amazon.com/api-gateway/pricing/). When you define a REST API, the API Gateway is actually made up of three different resources - the API itself, a [Stage resource](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-stages.html) for each environment which can aid in version control and other configuration options per environment, and a [Deployment resource](https://docs.aws.amazon.com/apigateway/latest/developerguide/how-to-deploy-api-with-console.html), which is essentially a 'snapshot' of your API for the Stage to use. In addition to these resources, you also need to define each of your endpoints as a new route on the API Gateway individually. API Gateway is a very powerful and useful tool at your disposal, but it can grow quickly and easily get fairly complex, so make sure you are designing your application to account for your specific needs. + +**AWS AppSync** +I'm keeping this section a bit shorter for you all, since [AppSync](https://aws.amazon.com/appsync/) is not something I have actually used personally, but have heard great things about. AppSync is another API option AWS has made available specifically for applications that want to take advantage of [GraphQL](https://graphql.org/) or a [Publish/Subscribe](https://aws.amazon.com/pub-sub-messaging/) model. The GraphQL model may be of interest to front end developers that need to query multiple sources of data from one API endpoint, like databases or [microservices](https://aws.amazon.com/microservices/). The Pub/Sub model I am more familiar with in the [IoT](https://aws.amazon.com/what-is/iot/) hardware-communicates-with-software aspect, however this is also powerful for frontend developers looking to take advantage of real-time updates with serverless WebSocket connections. With AppSync, you also have caching, offline data synchronization, and real-time updates. You can learn more and [check out the developer docs](https://docs.aws.amazon.com/appsync/latest/APIReference/Welcome.html) on the AWS Website. + +![Graph depiction, like GraphQL. Image via Unsplash.](images/day73-3.jpg) + +As with all of these short, daily articles, there is so much more that I could dive into here, but my purpose this week is to provide you with a little taste of what the serverless space has to offer, and get you started as a newbie to serverless. I'd highly encourage you to read up even more on [effective API Design](https://thenewstack.io/werner-vogels-6-rules-for-good-api-design/), and even get started with a tutorial, workshop, or even your own project (feel free to try out the travel website and let me know how it goes!) Believe it or not, there is still more to explore in the serverless space, so in my next post we will continue on with some really helpful integration & orchestration services.* + +*This is part of a series that will be covered here, but I also encourage you to follow along with the rest of the series on [Medium](https://kristiperreault.medium.com/serverless-apis-4c852f0955ef) or [Dev.to](https://dev.to/aws-heroes/serverless-apis-5bdp). + +See you in [Day 74](day74.md). diff --git a/2023/day74.md b/2023/day74.md index e69de29..884f32e 100644 --- a/2023/day74.md +++ b/2023/day74.md @@ -0,0 +1,43 @@ +# Serverless Orchestration + +![Conductor. Image via Unsplash.](images/day74-1.jpg) + +Are you still with me? I hope so, because I'm excited to discuss some of the really cool services in serverless that go beyond the basics of APIs, storage, and compute. This is the space where you can really see the benefits of serverless shine, and, compared to on-premises or other cloud development spaces, where there has been a lot of innovation that may not compare 1:1 to what you're used to in application development. I've included these services under the broad umbrella of 'orchestration', because they really exist in-between the core services and help with your event-driven flow. You may not have a need for all, or even any, of these services in all of your applications, but they can be useful technologies to take advantage of, especially if your application is truly configured for [event driven architecture](https://aws.amazon.com/event-driven-architecture/). + +**AWS Step Functions** + +![A person walking up steps. Image via Unsplash.](images/day74-2.jpg) + +Is it weird to have a favorite serverless service? Because this one might be mine. [AWS Step Functions](https://aws.amazon.com/step-functions/) is a workflow orchestration tool that helps you manage your distributed application by breaking it down into multiple steps (the name should make sense now). Step Functions integrated with over 220 AWS services, but personally I have found it most useful with my [lambda functions](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html), as it helps keep them small, concise, logical units of business code that are called systematically. It's easier to control and monitor your event as it flows through your application, so you can track which step your application is or identify where you may be running into issues. Step Functions also gives you more flexibility, as you can add in different '[states](https://docs.aws.amazon.com/step-functions/latest/dg/concepts-states.html)' like PASS or WAIT, and you can even run processes in parallel, or give your application Choices to execute on different steps depending on what the input or parameters are. + +![Step Functions Workflow in Studio. Example via AWS Documentation.](images/day74-3.jpg) + +As with most of the AWS resources, you can provision and configure your step function however you choose. For me, this is typically using an [Infrastructure as Code](https://docs.aws.amazon.com/whitepapers/latest/introduction-devops-aws/infrastructure-as-code.html) tool like [CDK](https://aws.amazon.com/cdk/) to provision in python or typescript, and then defining the actual steps - otherwise known as the '[state machine](https://docs.aws.amazon.com/step-functions/latest/dg/amazon-states-language-state-machine-structure.html)' - in a JSON file. Since its release in 2016, Step Functions have had a visual component in the AWS Console that allows you to see the steps of your application and the flow of your event through it, but in 2021 AWS released [Workflow Studio](https://docs.aws.amazon.com/step-functions/latest/dg/workflow-studio.html), which actually allows you to drag and drop the components you want to use into a visual editor, and it will auto-generate the code for you. Unfortunately working in a large enterprise this isn't something I can really take advantage of, but as a visual learner I think this is an awesome tool, and can definitely streamline your development. + +**Amazon EventBridge** + +![Large bridge. Image via Unsplash](images/day74-4.jpg) + +[EventBridge](https://aws.amazon.com/eventbridge/) has seemed to be a hot topic as of late, and I'm seeing more and more content depicting EventBridge resources. Somewhat similarly to Step Functions, Amazon EventBridge is a serverless orchestration service for your application events. Its three key components are an Event Bus, to handle interactions with your events, like sending/receiving and transforming, a [Scheduler](https://aws.amazon.com/eventbridge/scheduler/), to help you schedule tasks associated with your events, and finally [Pipes](https://aws.amazon.com/eventbridge/pipes/), which integrate directly with your serverless services "end-to-end" and optionally filter or transform your event as needed. EventBridge Pipes were only recently released at the end of 2022, but the seamless integration with your event producers and consumers have been a huge selling point for developers (which explains the recent uptick in EventBridge usage). + +![Illustration of EventBridge Pipes. Example from AWS Documentation.](images/day74-5.jpg) + +Similar to other services, you can define and configure your EventBridge instance to your application needs, with the security constraints, service integrations, and appropriate event transforms you need. I won't say never, but it is particularly likely that you will not have EventBridge and Step Functions in the same application, or at least microservices, since their service offerings are quite similar. When might you use one over the other? As always, neither option is 'better' and this comes down to some personal preference and your application needs. If you have processes that need to run in parallel and maybe have more states dependent on each other, where you may want to wait or skips steps or have different workflows, Step Functions is probably a better choice. If you are looking to integrate directly between multiple different AWS services, and need to do quite a bit of transformation or filtering on your event, EventBridge may be a better starting place. + +**Amazon SQS** + +![Queue outside of a store. Image via Unsplash.](images/day74-6.jpg) + +[Amazon SQS](https://aws.amazon.com/sqs/) is also known as the Simple Queue Service. Much like people waiting in line for a busy ride at a theme park, sometimes you have places in your application where events may get backed up, creating a bit of a bottleneck and harming your application's performance (and potentially your wallet, too). A queue service such as SQS will help you process and maintain your events and messages as they come in. SQS specifically is what is known as a [First-In First-Out or FIFO queue](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html), meaning the first item in is the first item to be processed, just like the first person in line for our ride is the first person to get on. Sometimes with high volumes of messages waiting to be processed, there is risk that they get lost or skipped over in processing (disgruntled individuals leaving the long wait at the theme park ride) - having SQS in place prevents this problem from happening. It also means you do not have to worry about your other services being up and ready to handle incoming events, as SQS manages and stores the messages for you (the fun, roped off queue handles the people waiting and the order in which they arrived at our theme park ride). Just like our other services you can configure SQS, however this is a fairly 'Simple' service, so you'll find creating and maintaining an SQS queue to be uncomplicated. + +**Amazon SNS** + +![Email notification. Image via Unsplash.](images/day74-7.jpg) + +[Amazon SNS](https://aws.amazon.com/sns/) or Simple Notification Service, is less of an orchestration service and more of a communication service. I am going to deem this a utility service, since it is a small service you can utilize for sending and receiving messages. One of the most common use cases for the SNS service is to send email alerts - maybe to developers to monitor application status, or maybe to users, to communicate new features or send email confirmations based on something like a booking reservation. You can also send as SMS text messages or mobile pushes, and you can [customize your queue type and add encryption](https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html). Like SQS, this service is definitely 'Simple' and can be configured in just a few short lines of code, or button clicks in the AWS Console. + +Although not what I would consider 'core' cloud services, the orchestration and communication services are key to event driven development and robust application design. If you are structuring your application to take advantage of event flow, these are tools you are going to want to be familiar with, and will be instrumental in your success by saving you time, money, complexity, and management overhead. This about wraps up what I want to cover with [serverless cloud services](https://aws.amazon.com/serverless/), though there is so much out there to explore. Tune in tomorrow as we start to put all of this together with best practices.* + +*This is part of a series that will be covered here, but I also encourage you to follow along with the rest of the series on [Medium](https://kristiperreault.medium.com/serverless-orchestration-d012aa7cae38) or [Dev.to](https://dev.to/aws-heroes/serverless-orchestration-3879). + +See you in [Day 75](day75.md). \ No newline at end of file diff --git a/2023/day75.md b/2023/day75.md index e69de29..a76dc2d 100644 --- a/2023/day75.md +++ b/2023/day75.md @@ -0,0 +1,52 @@ +# Serverless & Well Architected + +![Pillars. Image via Unsplash.](images/day75-1.jpg) + +Over the last few days, we've discussed a number of topics in the serverless space, covering [storage](https://dev.to/aws-heroes/serverless-storage-50i3), [APIs](https://dev.to/aws-heroes/serverless-apis-5bdp), [compute](https://dev.to/aws-heroes/serverless-compute-3bgo), and [everything in between](https://dev.to/aws-heroes/serverless-orchestration-3879). We've got all the components to build a fully functional, robust application in place, but before you run off and create The Next Big Thing, we have to cover one more crucial topic: [Well Architected](https://aws.amazon.com/architecture/well-architected/?wa-lens-whitepapers.sort-by=item.additionalFields.sortDate&wa-lens-whitepapers.sort-order=desc&wa-guidance-whitepapers.sort-by=item.additionalFields.sortDate&wa-guidance-whitepapers.sort-order=desc). The Well Architected Framework is a set of guidelines or best practices that AWS introduced a few years ago. The six "pillars" of Well Architected are [Security](https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/welcome.html), [Cost](https://docs.aws.amazon.com/wellarchitected/latest/cost-optimization-pillar/welcome.html), [Operational Excellence](https://docs.aws.amazon.com/wellarchitected/latest/operational-excellence-pillar/welcome.html), [Reliability](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/welcome.html), [Performance Efficiency](https://docs.aws.amazon.com/wellarchitected/latest/performance-efficiency-pillar/welcome.html), and [Sustainability](https://docs.aws.amazon.com/wellarchitected/latest/sustainability-pillar/sustainability-pillar.html). These concepts are not new, but by defining them in this way, AWS has established a reference that is easy to use and understand when evaluating your applications for best practices. In fact, AWS has created a [Well Architected Tool & Review process](https://aws.amazon.com/well-architected-tool/) centered around the six pillars, asking you questions about your application to review yourself or with your team. Before you start building your application, I would highly recommend you go through a formal Well Architected Review. You don't need to answer every single question, in fact some might not be applicable, but going through this exercise gets you thinking about how you want to architect your application, even highlighting key decision trade-offs, or potential issues that you haven't thought of just yet. In the subsections that follow, we'll talk about each of the pillars in a little more detail, and I'll briefly cover [Well Architected Lenses](https://docs.aws.amazon.com/wellarchitected/latest/userguide/lenses.html). + +**Security** + +![Lock keeping items secure. Image via Unsplash.](images/day75-2.jpg) + +Simply put, how are you securing your app? Are you using authorization and authentication with [IAM users, roles, and policies](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html) to limit access to your resources? Setting up [permission boundaries](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_boundaries.html) and using [KMS keys](https://aws.amazon.com/kms/) for encryption? This can look like any number of measures, but the important idea here is, are you thinking about how to secure your app? Some of the questions in this space may not be applicable. This could be an app just for you, or one that isn't storing any data to worry about, or it could be wide open to the public and have no personal information to worry about. You don't need to have every single security measure in place for your application, but you do need to think about these things, and make conscious, defendable decisions about your [application security](https://docs.aws.amazon.com/wellarchitected/latest/security-pillar/welcome.html). + +**Cost** + +![Jar of money with a plant. Image via Unsplash.](images/day75-3.jpg) + +This one is pretty straightforward - I don't know anyone who gets excited when their cost or bills go up in price. Obviously, we all want to optimize for a low-cost application solution, whether this is for personal use, your business, or the company you work for (you may not care about that one personally, but I can tell you THEY certainly care about the bottom line). Look at the [pricing model](https://aws.amazon.com/pricing/?aws-products-pricing.sort-by=item.additionalFields.productNameLowercase&aws-products-pricing.sort-order=asc&awsf.Free%20Tier%20Type=*all&awsf.tech-category=*all) and see if there are any ways to cut costs. Some easy ones could be to minimize the number of API calls you're making, or utilize [Lambda Powertools](https://awslabs.github.io/aws-lambda-powertools-python/2.9.1/) to optimize your lambda function for memory & performance. If you've exhausted every option here, that's okay. Cost is typically a trade-off; you may be ok spending more money to make sure your application is secure, reliable, and not hindered in performance. Again, the idea here is that you're actively aware of where your money is going, and you've [reviewed your optimization options thoroughly](https://docs.aws.amazon.com/wellarchitected/latest/cost-optimization-pillar/welcome.html). + +**Operational Excellence** + +![Group working at laptop computers. Image via Unsplash.](images/day75-4.jpg) + +One of my favorite topics to talk about is '[Clean Code](https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882)', or better known as best practices within your code. Although this could cover many of these pillars, it arguably fits squarely within [Operational Excellence](https://docs.aws.amazon.com/wellarchitected/latest/operational-excellence-pillar/welcome.html). This pillar is all about building robust applications, code that is easy to understand, read, and maintainable, and having effective development processes in place. Creating small, logical code blocks, making small & frequent code changes, [reviewing code](https://about.gitlab.com/topics/version-control/what-is-code-review/#:~:text=Code%20reviews%2C%20also%20known%20as,developers%20learn%20the%20source%20code.) periodically, having ample error handling, logging, and monitoring, and so much more fall into this category. For me, this one is sort of like a "catch all" pillar; not because it isn't well defined, but because it encompasses so many parts of the application development cycle. Many of the pillars overlap, but it is very likely that this one in particular will have overlap with one or more of the other pillars at any given time. + +**Reliability** + +![Chairs relying on each other. Image via Unsplash.](images/day75-5.jpg) + +Is your application stable? Do you [backup your data](https://aws.amazon.com/backup/) regularly? Do you have [failovers](https://docs.aws.amazon.com/whitepapers/latest/web-application-hosting-best-practices/failover-with-aws.html) or other fail-safe measures in place? Can your application handle a large influx of traffic, or will any changes to the 'average' case break your current functionality? The key question this pillar asks is - are you prepared? Outages are never fun, especially when they significantly impact your customers, but they can (and they do) happen to the best of us. By reviewing the questions in the reliability pillar, you are thinking about your application's [disaster recovery plans](https://docs.aws.amazon.com/whitepapers/latest/disaster-recovery-workloads-on-aws/disaster-recovery-options-in-the-cloud.html), backing up your data, and having processes in place for the 'worst-case scenario'. Hopefully by completing a [reliability review](https://docs.aws.amazon.com/wellarchitected/latest/reliability-pillar/welcome.html), these things don't occur as often, or aren't as widespread as they might've been before a review. + +**Performance Efficiency** + +![Performance on the track. Image via Unsplash.](images/day75-6.jpg) + +Closely related to the Operational Excellence and Reliability pillars, the [Performance Efficiency](https://docs.aws.amazon.com/wellarchitected/latest/performance-efficiency-pillar/welcome.html) pillar is, you guessed it, all about how well your application is performing. What I enjoy most about this pillar is if you're taking advantage of serverless architectures, you're already well on your way to having this one covered, as it's one of the [five design principles](https://aws.amazon.com/blogs/apn/the-6-pillars-of-the-aws-well-architected-framework/) to adhere to. This is about your application running smoothly, scaling effectively, and taking advantage of only the resources you need. This is another big "trade-off" pillar, since you may compromise your performance in some cases to comply with security or save on cost. + +**Sustainability** + +![Person holding a plant. Image via Unsplash.](images/day75-7.jpg) + +[Sustainability](https://docs.aws.amazon.com/wellarchitected/latest/sustainability-pillar/sustainability-pillar.html) is a recent addition to the Well Architected pillars, and I think it's a good one. It was [introduced at the end of 2021](https://aws.amazon.com/blogs/aws/sustainability-pillar-well-architected-framework/), and even though it's a focus I love to see, it also means there has not been a ton of guidance shared to optimize for sustainability. If you're invested in areas involving hardware, AI/ML, large sets of data, IoT, etc., this is a bit more obvious to contend to - simply put, you want to use less resources, and more sustainable (or at least recyclable) hardware. WIth serverless, you are already scaling automatically, only paying for what you use, and optimizing for your [event driven architecture](https://aws.amazon.com/event-driven-architecture/), which makes it more difficult to find areas to cut down on usage. My best advice is to review your architecture early & often, and continually try to find ways to [lower your carbon footprint](https://www.nature.org/en-us/get-involved/how-to-help/carbon-footprint-calculator/#:~:text=A%20carbon%20footprint%20is%20the,is%20closer%20to%204%20tons.) with optimal architectural design, and if you haven't made the jump to serverless yet, maybe that's the first step! + +**Serverless Lens** + +![A pair of eyeglasses with lenses. Image via Unsplash.](images/day75-8.jpg) + +In addition to the six pillars, AWS Well Architected has this concept of [Well Architected Lenses](https://docs.aws.amazon.com/wellarchitected/latest/userguide/lenses.html). Much like a pair of reading glasses, you can apply a specific Lens to your application to 'see' your application in a bit more detail. There are Lenses for [Machine Learning](https://docs.aws.amazon.com/wellarchitected/latest/machine-learning-lens/machine-learning-lens.html), [Data Analytics](https://docs.aws.amazon.com/wellarchitected/latest/analytics-lens/analytics-lens.html?did=wp_card&trk=wp_card), [Financial Services](https://docs.aws.amazon.com/wellarchitected/latest/financial-services-industry-lens/welcome.html?did=wp_card&trk=wp_card), and, of course, [Serverless Applications](https://docs.aws.amazon.com/wellarchitected/latest/serverless-applications-lens/welcome.html?did=wp_card&trk=wp_card). These Lenses are simply a set of extra guidelines and questions for each of these six pillars relating specifically to the type of application you are building. They are 'optional', as is the entire Well Architected Review process, but again, if you are building a serverless application, I would highly recommend you complete a Well Architected Review with the Serverless Lens, as it will only strengthen your application posture in the context of these six pillars. + +If you'd like to learn more about Well Architected or hear about it in practice, I have actually given a [recent talk on the subject with Build On at AWS Re:Invent](https://www.twitch.tv/videos/1674539542?collection=T1passDrLhdY6Q). This is an area of technology I have been very passionate about, and I truly believe these pillars and Well Architected Reviews are well worth the time and effort. We're coming up to end of our team together this week (I know, already?!) so for our last day tomorrow, I'm excited to summarize what we've learned so far, and present you with some next steps for going beyond the serverless basics.* +*This is part of a series that will be covered here, but I also encourage you to follow along with the rest of the series on [Medium](https://kristiperreault.medium.com/serverless-well-architected-b379d5be10ad) or [Dev.to](https://dev.to/aws-heroes/serverless-well-architected-40jn). + +See you in [Day 76](day76.md). diff --git a/2023/day76.md b/2023/day76.md index e69de29..624980f 100644 --- a/2023/day76.md +++ b/2023/day76.md @@ -0,0 +1,33 @@ +# Serverless - Beyond the Basics + +![Computer screen telling us to 'Do More'. Yes we shall! Image via Unsplash.](images/day76-1.jpg) + +Well folks, it appears the Serverless week for [90DaysOfDevOps](https://github.com/MichaelCade/90DaysOfDevOps) has (already) come to an end. We have covered a ton of topics in serverless to get you started, and hopefully you're already well on your way to building your first serverless, event-driven application! We've [defined what serverless means](https://dev.to/aws-heroes/what-is-serverless-4d4p), we've talked about everything from [lambda functions](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html), to [DynamoDB tables](https://aws.amazon.com/dynamodb/), [Step Functions](https://docs.aws.amazon.com/step-functions/latest/dg/welcome.html), [EventBridge](https://aws.amazon.com/eventbridge/), and so many other core & supporting AWS services to aid in your development journey. Although it's been a very high-level overview, I truly hoped you have enjoyed our week together, and have learned a thing or two about serverless development. Even if you've left this week with more questions than answers, I would say I've done my job - which is, made you interested and curious enough about serverless to want to explore it even more! + +Instead of going into a ton of depth on various topics in serverless on our last day, I thought it would be much more useful to provide you all with resources where you can go to learn more. The problem is, there is so much content, so many well-formed opinions, and tons of sample projects out there, **_I_** don't even know where to begin! I know that if I start to list out individuals or blogs, I am going to forget so many, and not give proper credit where credit is due, so instead, I will provide you with some places or projects to get started, and let you explore on your own and form your own thoughts & opinions. The only ask I have for you is this - **_please_** do your best to support and encourage diversity & our minority content creators. Too often I see folks share lists of their favorite people, accounts, conference talks, blogs, or open source projects, and there is no diverse representation. There are tons of incredible content creators (or to-be content creators!) of all different backgrounds and identities that never get enough credit, and if all of us can help in any small way, it can make a huge impact. I encourage you to take advantage of the comment section below to promote some of your favorite diverse individuals - I'd love to add them to my network too! + +![Group hug, since we're all friends now. Image via Unsplash.](images/day76-2.jpg) + +Thanks again for taking this serverless journey with me this week, and please enjoy this list of more resources to explore. Until next time, my serverless friends!* + +**Resources to Learn More** + +- [Medium](https://medium.com/) - Blogging platform with tons of great content +- [Dev.to](https://dev.to/) - Blogging platform with tons of great content, specific to developers +- [aCloudGuru](https://acloudguru.com/) - Video learning platform, great for certifications +- [ServerlessLand](https://serverlessland.com/) - All things serverless, resources & announcements from AWS +- [AWS Twitch](https://www.twitch.tv/aws) - Space for podcasts, walkthroughs, and casual conversations with AWS employees +- [AWS Docs](https://aws.amazon.com/serverless/) - Official documentation for all things AWS serverless +- [AWS Certifications](https://aws.amazon.com/certification/) - Explore getting certified +- [AWS Youtube](https://www.youtube.com/@amazonwebservices/featured) - Great deep dive talks & features on AWS services from years past +- [AWS CDK](https://aws.amazon.com/cdk/) - Infrastructure as Code tool, popular in serverless development +- [AWS SAM](https://aws.amazon.com/serverless/sam/) - Infrastructure as Code tool, specifically for serverless development +- [AWS User Groups](https://aws.amazon.com/developer/community/usergroups/?community-user-groups-cards.sort-by=item.additionalFields.ugName&community-user-groups-cards.sort-order=asc&awsf.location=*all&awsf.category=*all) - Get involved in your local community! +- [AWS Hero Program](https://aws.amazon.com/developer/community/heroes/?community-heroes-all.sort-by=item.additionalFields.sortPosition&community-heroes-all.sort-order=asc&awsf.filter-hero-category=heroes%23serverless&awsf.filter-location=*all&awsf.filter-year=*all&awsf.filter-activity=*all) - Learn more about our community evangelists +- [AWS Community Builder Program](https://aws.amazon.com/developer/community/community-builders/) - Keep this bookmarked for the next round of applicants + +….and so much more out there for you to explore! + +*This is part of a series that will be covered here, but I also encourage you to follow along with the rest of the series on [Medium](https://kristiperreault.medium.com/serverless-beyond-the-basics-22ba22733dd1) or [Dev.to](https://dev.to/aws-heroes/serverless-beyond-the-basics-kom). + +See you in [Day 77](day77.md). diff --git a/2023/day77.md b/2023/day77.md index e69de29..0df8ba2 100644 --- a/2023/day77.md +++ b/2023/day77.md @@ -0,0 +1,72 @@ +## Day 77 - Let's break down a Service Mesh - #90DaysOfDevOps +> **Informational** +> *An introduction to Service Mesh, the use-cases, and the problems it aims to solve.* +### What is a Service Mesh? +In modern distributed environments, applications are broken up into small chunks of code that run inside of a container. These containers need to be able to communicate with each other, and while they normally can, in a Kubernetes environment, there is a higher order of control, visiblity, and security that's required. Each of these containers, or services interact with other services, but must do so in an encrypted an authorized manner. There are other challenges with having coordinate service to service communication. What happens when one particular service is unavailable to provide a response? How would you troubleshoot this, and fix it so it doesn't happen again? How can we tune our applications to respond in an appropriate amount of time? + +These are small subset of challenges when it comes to running and managing applications, or microservices on a network. The unpredictability of the network means we shouldn't rely too much on it being there. We also can't keep changing our code to adapt to changing network conditions, so what do we do? + +Enter a Service Mesh. A Service Mesh is an application network layer that handles service-to-service communication, by providing a layer for granular traffic control, AuthN, AuthZ, and observability. + + +### What are the challenges a Service Mesh aims to solve?m +1. Unreliable and changing networks that are complex, while having to adapt while your microservices scale +2. Ensuring a near zero-trust like environment where, RBAC, AuthZ and AuthN are critical. +3. Ensuring a data-loss prevention approach using encryption and traffic filtration techniques +4. Determining and visualizing the health of an application and the characteristics of how it handles requests +5. Ensuring availability and reliability of services. + +### Key features of a service mesh +Here are key features of a service mesh: +- Load balancing of services +- Service discovery across multiple environments +- Granular traffic control and routing of HTTP and gRPC requests +- Automatic retries of requests +- Fault injection for resiliency +- Logging, monitoring and metrics +- Peer authentication and authorization +- Service-to-service encryption with mTLS + + +### What does a Service Mesh look like? +![ServiceMesh](images/Day77-1.png) + +A service mesh usually has a few key components: +- A control plane for which to deploy configurations to +- A data plane implemented in both the sidecar and gateways +- The Kubernetes cluster it resides on + +To describe how a service mesh behaves, an operator will apply a traffic routing or security policy, and the service mesh control plane will push any configuritions or policy to either the gateways or sidecar proxies. The gateway and sidecars will enforce any traffic rule. In the diagram above, the ingress gateway is the first to receive the external inbound request. It will forward it along to the first service in the request path, service A. Service A has a sidecar to process this request, and send back any telemetry data to the control plane. There's more to this but we'll explore in depth in the following days. + +### Relationship to Kubernetes +Kubernetes has some challenges in how it can handle things like multi-cluster and cross-cluster communication, identity stewardship. What a Service Mesh does is it takes on the responsibilities for things like: +- certificate rotation and management +- encryption between services +- granular traffic routing by way of Ingress and service-to-service routing +- visibility and metrics of application health + +### Service Mesh Offerings +There are PLENTY of service mesh offerings out there. Some are highly proprietary while others are very open. +We will cover some options for the next day, *Comparing Different Service Meshes*. Here's a start to get a sense of what Service Mesh solutions are out there. + +#### Istio +Istio is an open-source service mesh built by Google, IBM, and Lyft, and currently actively developed on and maintained by companies such as Solo.io. It is based on the Envoy proxy which is adopted for the sidecar pattern. Istio offers a high degree of customization and extensibility with advanced traffic routing, observability, and security for microservices. A new mode of operation for sidecar-less service mesh, called Ambient Mesh, was launched in 2022. + +#### AppMesh +AppMesh is a service mesh implementation that is proprietary to AWS but primarily focuses in on applications deployed to various AWS services such as ECS, EKS, EC2. Its tight-nit integration into the AWS ecosystem allows for quick onboarding of services into the mesh. + +#### Consul +Consul is a serivce mesh offering from Hashicorp that also provides traffic routing, observability, and sercurity much like Istio does. + +#### Linkerd +Linkerd is an open-source service mesh offering that is lightweight. Similar to Istio, it provides traffic management, observability, and security, using a similar architecture. Linkerd adopts a sidecar-pattern using a Rust-based proxy. + +#### Cilium +Cilium is a Container Networking Interface that leverages eBPF to optimize packet processing using the Linux kernel. It offers some Service Mesh capabilities, and doesn't use the sidecar model. It proceeds to deploy a per-node instance of Envoy for any sort of Layer 7 processing of requests. + +### Conclusion +A serivce mesh is a power application networking layer that provides traffic management, observability, and security. We will explore more in the next 6 days of #90DayofDevOps! + +Want to get deeper into Service Mesh? Head over to [#70DaysofServiceMesh](https://github.com/distributethe6ix/70DaysOfServiceMesh)! + +See you in [Day 78](day78.md). diff --git a/2023/day78.md b/2023/day78.md index e69de29..0bf7866 100644 --- a/2023/day78.md +++ b/2023/day78.md @@ -0,0 +1,234 @@ +## Day 78 - Install and Test a Service Mesh +> **Tutorial** +> *Let's install our first service mesh.* + +I spent enough time on some theory on Day 77. Let's dig right into getting a service mesh up and running. + +### Tasks +- Install the Istio service mesh with Demo Profile +- Deploy Bookinfo Application into the service mesh +- Test it's functionality +- Externally expose the application + +### Installation + Prequisites +I highly advise using something like minikube or a cloud-based K8s cluster that allows you to have load-balancer functionality. + +- A Kubernetes cluster running 1.22, 1.23, 1.24, 1.25 + - KinD + - Minikube + - Civo K8s + - EKS +- Access to a Loadbalancer service + - Metallb + - port-forwarding (not preferred) + - Cloud Load-balancer + - Inlets +- Linux or macOS to run istoctl + +**Environment setup** +In my case, I spun up a Civo K3s cluster with 3-nodes, 2 CPU per node, and 4GB of RAM per node. +This is important because you will need enough resources to run the service mesh control plane, which, is Istiod in our case. If you need a cluster in a pinch register for free credit @ civo.com. + +#### Install Istio +1. Verify your cluster is up and operational and make sure there aren't any errors. The commands below will output nodes and their IPs and OS info and the running pods in all namespaces, respectively. + ``` + kubectl get nodes -o wide + kubectl get pods -A + ``` +2. Download Istio, which will pick up the latest version (at the time of writing its 1.16.1) + ``` + curl -L https://istio.io/downloadIstio | sh - + ``` +3. Change to the Istio directory + ``` + cd istio-1.16.1 + ``` +4. Add the istioctl binary to your path + ``` + export PATH=$PWD/bin:$PATH + ``` +5. Check to verify that your environment is ready to go: + ``` + istioctl x precheck + ``` + And the output + ``` + ✔ No issues found when checking the cluster. Istio is safe to install or upgrade! + To get started, check out https://istio.io/latest/docs/setup/getting-started/ + ``` +6. Let's proceed to install Istio. We use the demo profile because it allows us to provide a minimal configuration to demonstrate functionality. + ``` + istioctl install --set profile=demo -y + ``` + You will see the following output: + ``` + ✔ Istio core installed + ✔ Istiod installed + ✔ Egress gateways installed + ✔ Ingress gateways installed + ✔ Installation complete + ``` +7. Next, we can verify all the components are deployed as expected by running the command below, which proceeds to output all the Istio components. + ``` + kubectl get all -n istio-system + ``` + Your output should look similar in that all components are working. I changed my External-IP to *bring.your.LB.IP*, whcih means your IP will be different. Why do you need mine :P + ``` + NAME READY STATUS RESTARTS AGE + pod/istiod-885df7bc9-f9k7c 1/1 Running 0 31m + pod/istio-ingressgateway-6688c7f65d-szxf9 1/1 Running 0 31m + pod/istio-egressgateway-7475c75b68-mpxf7 1/1 Running 0 31m + + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + service/istiod ClusterIP 10.43.249.242 15010/TCP,15012/TCP,443/TCP,15014/TCP 31m + service/istio-egressgateway ClusterIP 10.43.75.47 80/TCP,443/TCP 31m + service/istio-ingressgateway LoadBalancer 10.43.51.40 bring.your.LB.IP 15021:31000/TCP,80:32697/TCP,443:30834/TCP,31400:30953/TCP,15443:30733/TCP 31m + + NAME READY UP-TO-DATE AVAILABLE AGE + deployment.apps/istiod 1/1 1 1 31m + deployment.apps/istio-ingressgateway 1/1 1 1 31m + deployment.apps/istio-egressgateway 1/1 1 1 31m + + NAME DESIRED CURRENT READY AGE + replicaset.apps/istiod-885df7bc9 1 1 1 31m + replicaset.apps/istio-ingressgateway-6688c7f65d 1 1 1 31m + replicaset.apps/istio-egressgateway-7475c75b68 1 1 1 31m + ``` +#### Sidecar injection and Bookinfo deployment. +8. While everything looks good, we also want to deploy an application and simulataneously add it to the Service Mesh. +Let's label our default namespace with the *istio-injection=enabled* label. This tells Istiod to push the sidecar to any new microservice deployed to the namespace. + ``` + kubectl label namespace default istio-injection=enabled + ``` + Verify it + ``` + kubectl get ns --show-labels + ``` +9. Let's deploy our app. Make sure you are the in the same directory as before. If not, change to *istio-1.16.1* + ``` + kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml + ``` + Let's give it one minute and check the application + ``` + kubectl get all + ``` + Let's see the output + ``` + NAME READY STATUS RESTARTS AGE + pod/details-v1-698b5d8c98-l8r5t 2/2 Running 0 7m30s + pod/reviews-v3-6dc9897554-8pgtx 2/2 Running 0 7m30s + pod/reviews-v1-9c6bb6658-lvzsr 2/2 Running 0 7m30s + pod/reviews-v2-8454bb78d8-9tm2j 2/2 Running 0 7m30s + pod/productpage-v1-bf4b489d8-q29jp 2/2 Running 0 7m29s + pod/ratings-v1-5967f59c58-s9f88 2/2 Running 0 7m30s + + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + service/kubernetes ClusterIP 10.43.0.1 443/TCP 80m + service/details ClusterIP 10.43.198.240 9080/TCP 7m31s + service/ratings ClusterIP 10.43.121.72 9080/TCP 7m30s + service/reviews ClusterIP 10.43.173.247 9080/TCP 7m30s + service/productpage ClusterIP 10.43.142.39 9080/TCP 7m30s + + NAME READY UP-TO-DATE AVAILABLE AGE + deployment.apps/details-v1 1/1 1 1 7m30s + deployment.apps/reviews-v3 1/1 1 1 7m30s + deployment.apps/reviews-v1 1/1 1 1 7m30s + deployment.apps/reviews-v2 1/1 1 1 7m30s + deployment.apps/productpage-v1 1/1 1 1 7m30s + deployment.apps/ratings-v1 1/1 1 1 7m30s + + NAME DESIRED CURRENT READY AGE + replicaset.apps/details-v1-698b5d8c98 1 1 1 7m30s + replicaset.apps/reviews-v3-6dc9897554 1 1 1 7m30s + replicaset.apps/reviews-v1-9c6bb6658 1 1 1 7m30s + replicaset.apps/reviews-v2-8454bb78d8 1 1 1 7m30s + replicaset.apps/productpage-v1-bf4b489d8 1 1 1 7m30s + replicaset.apps/ratings-v1-5967f59c58 1 1 1 7m30s + ``` + The one thing to notice here is that all pods have *2/2* containers ready, meaning, the sidecar is now present. + +#### Testing functionality +10. One test I'll run is to verify that I can connect to any one of these pods and get a response. Let's deploy a sleep pod. If you were in the same *istio-1.16.1* directory, then you can run this command. + ``` + kubectl apply -f samples/sleep/sleep.yaml + ``` + Let's check to see that the pod is deployed to the default namespace AND has the sidecar injected: + ``` + kubectl get pods + ``` + ``` + sleep-75bbc86479-xw5lw 2/2 Running 0 36s + ``` + +11. I'm going to use the sleep pod to curl over to the product-page. Please use yours which has a different name, to curl. + ``` + kubectl exec sleep-75bbc86479-xw5lw -c sleep -- curl -sS productpage:9080 + ``` + And we should see something similar to the below which tells us the app is working!: + ``` + % Total % Received % Xferd Average Speed Time Time Time Current + Dload Upload Total Spent Left Speed + 100 1683 100 1683 0 0 69202 0 --:--:-- --:--:-- --:--:-- 70125 + + + + Simple Bookstore App + + + + + + + + + + + + + + +

+

Hello! This is a simple bookstore application consisting of three services as shown below

+

+ ``` + +#### Externally exposing the app + +12. Let's deploy the Istio ingress gateway configuration and virtual-service configuration. The Ingress Gateway Configuration is an abstraction for the Istio-ingress-gateway and simply tells it which host and port is listening for requests. The virtual-service configuration tells the gateway how to route the request (or who to route it to). If you didn't navigate away from the original folder, run the following command: + ``` + kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml + ``` + You will see two objects created: + ``` + gateway.networking.istio.io/bookinfo-gateway created + virtualservice.networking.istio.io/bookinfo created + ``` + +13. Because we don't have external DNS setup, we'll gather the information we need and piece together our URL: + Grab the External IP, and the HTTP2 port, which would be TCP port 80 from the Istio Ingress Gateway. + ``` + kubectl get svc -n istio-system + ``` + Store it in a variable + ``` + export INGRESS_HOST=[IP_from_Istio_ingress_gateway] + export INGRESS_PORT=80 + ``` + now curl this host: + ``` + curl INGRESS_HOST:INGRESS_PORT/productpage + ``` + And the RESULT: + ``` + !DOCTYPE html> + + + Simple Bookstore App + ``` + +### Conclusion +I decided to jump into getting a service mesh up and online. It's easy enough if you have the right pieces in place, like a Kubernetes cluster and a load-balancer service. Using the demo profile, you can have Istiod, and the Ingress/Egress gateway deployed. Deploy a sample app with a service definition, and you can expose it via the Ingress-Gateway and route to it using a virtual service. + +Want to get deeper into Service Mesh? Head over to [#70DaysofServiceMesh](https://github.com/distributethe6ix/70DaysOfServiceMesh)! + +See you on [Day 79](day79.md) and beyond of #90DaysofServiceMesh diff --git a/2023/day79.md b/2023/day79.md index e69de29..f773198 100644 --- a/2023/day79.md +++ b/2023/day79.md @@ -0,0 +1,71 @@ +## Day 79 - Comparing Different Service Meshes +> **Informational** +> *A comparison of Istio, Linkerd, Consul, AWS App Mesh and Cilium* + +### Service Mesh Offerings +There are PLENTY of service mesh offerings out there. Some are highly proprietary while others are very open. +Here are offerings you should definitely look into: + +Service Mesh | Open Source or Proprietary | Notes | +---|---|---| +Istio | Open Source | Widely adopted and abstracted +Linkerd | Open Source | Built by Buoyant +Consul | Open Source | Owned by Hashcorp, Cloud offering available +Kuma | Open Source | Maintained by Kong +Traefik Mesh | Open Source | Specialized Proxy +Open Service Mesh | Open Source | By Microsoft +Gloo Mesh | Proprietary | Built by Solo.io ontop of Istio +AWS App Mesh | Proprietary | AWS specific services +OpenShift Service Mesh | Proprietary | Built by Redhad, based on Istio +Tanzu Service Mesh | Proprietary | SaaS based on Istio, built by VMware +Anthos Service Mesh | Proprietary | SaaS based on Istio, built by Google +Bouyant Cloud | Proprietary | SaaS based on Linkerd +Cilium Service Mesh | Open Source | Orginally a CNI + + +I'll quickly recap some of the key options I'll compare. This was taken from Day 1. + +#### Istio +Istio is an open-source service mesh built by Google, IBM, and Lyft, and currently actively developed on and maintained by companies such as Solo.io. It is based on the Envoy proxy which is adopted for the sidecar pattern. Istio offers a high degree of customization and extensibility with advanced traffic routing, observability, and security for microservices. A new mode of operation for sidecar-less service mesh, called Ambient Mesh, was launched in 2022. + +#### AppMesh +AppMesh is a service mesh implementation that is proprietary to AWS but primarily focuses in on applications deployed to various AWS services such as ECS, EKS, EC2. Its tight-nit integration into the AWS ecosystem allows for quick onboarding of services into the mesh. + +#### Consul +Consul is a serivce mesh offering from Hashicorp that also provides traffic routing, observability, and sercurity much like Istio does. + +#### Linkerd +Linkerd is an open-source service mesh offering that is lightweight. Similar to Istio, it provides traffic management, observability, and security, using a similar architecture. Linkerd adopts a sidecar-pattern using a Rust-based proxy. + +#### Cilium +Cilium is a Container Networking Interface that leverages eBPF to optimize packet processing using the Linux kernel. It offers some Service Mesh capabilities, and doesn't use the sidecar model. It proceeds to deploy a per-node instance of Envoy for any sort of Layer 7 processing of requests. + +### Comparsion Table + +Feature | Istio | Linkerd | AppMesh | Consul | Cilium | +---|---|---|---|---|---| +Current Version | 1.16.1 | 2.12 | N/A (it's AWS :D ) | 1.14.3 | 1.12 +Project Creators | Google, Lyft, IBM, Solo | Buoyant | AWS | Hashicorp | Isovalent +Service Proxy | Envoy, Rust-Proxy (experimental) | Linkerd2-proxy | Envoy | Interchangeable, Envoy default | Per-node Envoy +Ingress Capabilities | Yes via the Istio Ingress-Gateway | No; BYO | Yes via AWS | Envoy | Cilium-Based Ingress +Traffic Management (Load Balancing, Traffic Split) | Yes | Yes | Yes | Yes | Yes, but manual Envoy config required for traffic splits +Resiliency Capabilities (Circuit Breaking, Retries/Timeouts, Faults, Delays) | Yes | Yes, no Circuit Breaking or Delays | Yes, No Fault or Delays | Yes, No Fault or Delays | Circuit Breaking, Retries and Timeouts require manual Envoy configuration, no other resiliency capabilities +Monitoring | Access Logs, Kiali, Jaegar/Zikin, Grafana, Prometheus, LETS, OTEL | LETS, Prometheus, Grafana, OTEL | AWS X-RAY, and Cloud Watch provides these | Datadog, Jaegar, Zipkin, OpenTracing, OTEL, Honeycomb | Hubble, OTEL, Prometheus, Grafana +Security Capabilities (mTLS, External CA) | Yes | Yes | Yes | Yes | Yes, with Wireguard +Getting Started | Yes | Yes | Yes | Yes | Yes +Production Ready | Yes | Yes | Yes | Yes | Yes +Key Features | Sidecar and Sidecar-less, Wasm Extensibility, VM support, Multi-cloud Support, Data Plane extensions | Simplistic and non-invasive | Highly focused and tight integration into AWS Ecosystem | Tight integration into Nomad and Hashicorp Ecosystem | Usage of eBPF for enhanced packet processing, Cilium Control Plane used to manage Service Mesh, No sidecars +Limitations | Complex, learning curve | Strictly K8s, additional config for BYO Ingress | Limited to just AWS services | Storage tied to Consul and not K8s | Not a complete Service Mesh, requires manual configuration +Protocol Support (TCP, HTTP 1.1 & 2, gRPC) | Yes | Yes | Yes | Yes | Yes +Sidecar Modes | Sidecar and Sidecar-less | Sidecar | Sidecar | Sidecar | No sidecar +CNI Redirection | Istio CNI Plugin | linkerd-cni | ProxyConfiguration Required | Consul CNI | eBPF Kernel processing +Platform Support | K8s and VMs | K8s | EC2, EKS, ECS, Fargate, K8s on EC2 | K8s, Nomad, ECS, Lambda, VMs | K8s, VMs, Nomad +Multi-cluster Mesh | Yes | Yes | Yes, only AWS | Yes | Yes +Governance and Oversight | Istio Community | Linkered Community | AWS | Hashicorp | Cilium Community + +### Conclusion +Service Meshes have come a long way in terms of capabilities and the environments they support. Istio appears to be the most feature-complete service mesh, providing a balance of platform support, customizability, extensibility, and is most production ready. Linkered trails right behind with a lighter-weight approach, and is mostly complete as a service mesh. AppMesh is mostly feature-filled but specific to the AWS Ecosystem. Consul is a great contender to Istio and Linkered. The Cilium CNI is taking the approach of using eBPF and climbing up the networking stack to address Service Mesh capabilities, but it has a lot of catching up to do. + +Want to get deeper into Service Mesh? Head over to [#70DaysofServiceMesh](https://github.com/distributethe6ix/70DaysOfServiceMesh)! + +See you on [Day 80](day80.md) of #70DaysOfServiceMesh! \ No newline at end of file diff --git a/2023/day80.md b/2023/day80.md index e69de29..76ddf49 100644 --- a/2023/day80.md +++ b/2023/day80.md @@ -0,0 +1,339 @@ +## Day 80 - Traffic Engineering Basics +> **Tutorial** +> *Let's test out traffic routing, and shifting* + +### Reviewing Key Traffic Management Concepts +HEY YOU MADE IT THIS FAR! Let's keep going :smile:!!! + +I'm going to review some of these concepts very briefly and if you'd like the expanded approach, check out #70DaysofServiceMesh + +Traffic management is an important topic in the world of microservices communication because, you have not one or two, you have thousands of services making requests to each other. In the world of physical networking, network devices can be used for flow control and packet routing, but because the size of our networks have grown to accomodate microservices communications, manually creating the path way for each to connect does not scale well. + +Kubernetes has done quite a lot to simplify networking for microservices through technologies like CNI, Ingress (and more recently), Gateway API. There are other challenges around traffic routing that can be solved with custom-tailored solutions. + +Some of the key areas to address with traffic management are: +- Request Routing +- Traffic Splitting +- Traffic Shifting +- Releasing (new versions of your app) +- Traffic mirroring +- Load-balancing + +Traffic, or requests, will always enter the Service Mesh through some Ingress, such as the Istio-Ingress-Gateway. Once in the mesh, the request might need to make its way through multiple services before a final response is formed. Each of the microservices, will have a sidecar to process the request and return some response. But, we also need to know how each of these services gets to other services, and what to do when these inbound requests come in. + +Client ---> Bookinfo ----> | ProductPage ---> Reviews ---> Ratings | + +In the flow above, the client makes a request to Bookinfo (via a DNS name) which is then translated into request towards the first service in the path, ProductPage, which then needs to illicit a respect from Reviews, and Reviews from Ratings. + +Let's explore the components that make this happen, briefly, and revisit these in the future. + +#### Istio Ingress Gateway +As mentioned previously, the Istio Ingress Gateway is the entrypoint for requests getting into the mesh. The Istio Ingress Gateway is a resource deployed with both a Deployment and Service defined with a Load Balancer. This is advantageous, because you can create an Istio Ingress resource that listens on certain ports (HTTP) for request to hostnames like istio.io. And you can do this for multiple hosts. This is important because you can virtually overload the resource by creating multiple Ingress resources for the same gateway. This saves you on procuring multiple load-balancers per service. + +Interestingly enough, any service you expose with the Istio Ingress Gateway, means that its service type will be set to ClusterIP. We don't connect to the service directly, we do so via the Ingress Gateway. This is also a layer of security with TLS. + +You configure an Istio Ingress Gateway resource, and then an associated Virtual Service to route to your services + +Istio's Ingress Gateway uses the Proxyv2 image which is purpose-built Envoy proxy, for Istio. + +The Gateway configuration we used previously... +``` +cat istio-1.16.1/samples/bookinfo/networking/bookinfo-gateway.yaml +``` +``` +marinow@mwm1mbp networking % cat bookinfo-gateway.yaml +apiVersion: networking.istio.io/v1alpha3 +kind: Gateway +metadata: + name: bookinfo-gateway +spec: + selector: + istio: ingressgateway # use istio default controller + servers: + - port: + number: 80 + name: http + protocol: HTTP + hosts: + - "*" +``` +The output shows us a few key pieces of information: +- The name of the Gateway resources +- The specific Istio Ingress gateway we use, using the label-selector mechanism +- The wildcard denoted by an asterisk specifies the host we are listening on, basically any host +- The port number, port 80 +- The protocol which is HTTP + +*Istio Ingress Gateway: I will listen for requests coming into any DNS hostname directed to port 80 using the HTTP protocol.* + +#### Sidecars +Sidecars are an important traffic management tool as they live right alongside each microservice and will proxy requests on behalf of them. +The sidecars behave in the same manner as the Istio Ingress Gateway, and will receive and process requests, and provide responses appropriately (as they are configured to). The sidecars also play a huge role with observability and security, which I'll explore later. + +Istio's sidecar uses the Proxyv2 image which is purpose-built Envoy proxy, for Istio. + +#### Virtual Services +Virtual Services are the "how do we get there" set of rules for Istio. I view this as routing rules for request. If a request is received destined towards a particular service, route it here. + +Here is an example of a Virtual Service definition we'll be using for each of the microservices in our environment: + +``` +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: productpage +spec: + hosts: + - productpage + http: + - route: + - destination: + host: productpage + subset: v1 +--- +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - route: + - destination: + host: reviews + subset: v1 +--- +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: ratings +spec: + hosts: + - ratings + http: + - route: + - destination: + host: ratings + subset: v1 +--- +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: details +spec: + hosts: + - details + http: + - route: + - destination: + host: details + subset: v1 +--- +``` + +There are 4 virtual service configurations present, each one's "host" field corresponds to the microservice and it's Kubernetes Service resource. +The protocol being HTTP is specified, with the destination and a *subset* which is translated to a particular microservice with a label affixed to it. This is important to distinguish multiple versions of the same resource. We also need another resource to help with distinguishing, the Destination Rule resource. + +#### Destination Rules +While Virtual Services point us to the service and host entries of where our services live, Destination Rules provide a granular action list. What happens when a request arrives at this destination? +Destination Rules allow us to specify multiple versions of a service based on the back-end pods using Subsets. This is referenced by the Virtual Service resource to establish which available services can be routed to. +This might be useful for dark launches and canary releasing so you can split traffic to different versions. + +Looking at the Destination Rule Resource for the Reviews services we can see the 3 different subsets for the 3 different versions. Notice that the labels actually correspond with the deployment resources for each version of reviews. +This is how we know how to route to each version. VS tells us *where*, DR tells us *how* and *what to do*. + +``` +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: reviews +spec: + host: reviews + subsets: + - name: v1 + labels: + version: v1 + - name: v2 + labels: + version: v2 + - name: v3 + labels: + version: v3 +``` + +#### Service Entries +I'll dive into this later, but Service Entries provide a mechanism for internal services to know how to route to external services, like a Database, or Git repo, or Object storage, for example. This can all be controlled using Service Entries. + +This can be used to control outbound requests as well, but requires a bit of control plane rework. More on this on later. + + +### Setting up Request Routing +We are using the same environment for Day 2. Go back and review it if you have not set up Istio. + +To set up request routing to Reviews-v1, we need to have a destination rule and virtual service configuration in place. +Let's apply them: + +#### Destination Rule (make sure you are in the right directory) +``` +cd istio-1.16.1 +kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml +``` + +#### Virtual Service +``` +kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml +``` + +Let's verify that the resources were created: +``` +kubectl get vs && kubectl get dr +``` + +AND THE RESULT +``` +marinow@mwm1mbp istio-1.16.1 % kubectl get vs && kubectl get dr +NAME GATEWAYS HOSTS AGE +bookinfo ["bookinfo-gateway"] ["*"] 4d15h +productpage ["productpage"] 14h +reviews ["reviews"] 14h +ratings ["ratings"] 14h +details ["details"] 14h +NAME HOST AGE +productpage productpage 96s +reviews reviews 96s +ratings ratings 96s +details details 96s +``` +Now, if I head over to my browser (I have a localhost DNS entry), I can get to bookinfo.io/productpage. If I hit refresh a few times, only the **Reviews-v1** service is hit. + +![ServiceMesh](images/Day80-1.png) + +This is because I configured my virtual service resource to only route to **v1** of Reviews as seen in the configuration below. + +``` +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - route: + - destination: + host: reviews + subset: v1 +--- +``` + +Now I'll update the configuration to route to **v2** IF and ONLY IF, I pass along a request header with the string "jason" as the end-user. Otherwise, my requests will continue to go to **v1**. + +Before I update it, let's look at it +``` +cat samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml + +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - match: + - headers: + end-user: + exact: jason + route: + - destination: + host: reviews + subset: v2 + - route: + - destination: + host: reviews + subset: v1 +``` +Notice the match field and what follows below. The route field has been indented because it's under a *match* condition. + +Now I'll apply it: +``` +kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml +``` + +And we can test by logging in via the website and entering jason as the user. + +![ServiceMesh](images/Day80-2.png) + +So now we know our Destination Rule works with our Virtual Service Configuration. + +Let's shift some traffic! + + +### Setting up Traffic Shifting + +To begin, we need to remove our previous virtual service configuration that routes using the *jason* header. +``` +kubectl delete -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml +``` + +Next, I'll quickly review the traffic-shifting we'll do. +``` +cat samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml + +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - route: + - destination: + host: reviews + subset: v1 + weight: 70 + - destination: + host: reviews + subset: v3 + weight: 30 +``` +Within each destination, it points to a subset. v1 points to Reviews-v1, while v3 points to Reviews-v3. We can apply this reviews VS resource, and it will then split the traffic with 70% of requests going to v1, while v3 receives 30% of the requests. + +Let's apply the config and test: +``` +kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml +``` +Now we can test this using a curl command in a for-loop. The for-loop runs 10 times, to make requests to the Product page, I've used grep to narrow down output to either v1 or v3, to witness the split of 70/30 Reviews-v1 getting 70% of the requests: +``` +for i in {1..10}; do curl -s http://bookinfo.io/productpage | grep "reviews-v"; done +``` +AND THE RESULT: +``` + reviews-v3-6dc9897554-8pgtx + reviews-v1-9c6bb6658-lvzsr + reviews-v1-9c6bb6658-lvzsr + reviews-v1-9c6bb6658-lvzsr + reviews-v3-6dc9897554-8pgtx + reviews-v3-6dc9897554-8pgtx + reviews-v1-9c6bb6658-lvzsr + reviews-v1-9c6bb6658-lvzsr + reviews-v1-9c6bb6658-lvzsr + reviews-v1-9c6bb6658-lvzsr +``` + +### Conclusion +Day 4 of #70DaysOfServiceMesh scratches the surface of Traffic management capabilities. We'll explore more in future modules. +I briefly covered several traffic management components that allow requests to flow within a Service Mesh: +- Istio Ingress Gateway +- Sidecar +- Virtual Services +- Destination Rules +- Service Entries + +And I got to show you all of this in action! + +Want to get deeper into Service Mesh Traffic Engineering? Head over to [#70DaysofServiceMesh](https://github.com/distributethe6ix/70DaysOfServiceMesh)! + +See you on [Day 81](day81.md) and beyond! :smile:! diff --git a/2023/day81.md b/2023/day81.md index e69de29..f5cd8ed 100644 --- a/2023/day81.md +++ b/2023/day81.md @@ -0,0 +1,206 @@ +## Day 81 - Observability in your Mesh +> **Tutorial** +> *LETS see what's going on in our mesh* + +What do you do when an application responds too slowly? Sometimes, there are network conditions well outside of our control, especially in Cloud and Data Center environments where QoS can be challenging to tune. But before we can tune up, we need to see what's up. + +A Service Mesh provides the right key pieces to capture this data. +The Istio Service Mesh generates a few types of telemetry and metrics to give a sense of what's happening with: +- The control plane +- The data plane +- Services inside of the mesh + +Istio provides details around: +- Metrics for latency, errors, traffic and saturation (LETS) +- Distributed tracing for spans to understand request flows +- Access logs, to determine source/destination metadata of requests. + +I have set up specific days to cover deeper observability but, let's get it going and use some tools like: +- Prometheus +- Grafana +- Jaegar +- Kiali + +One consideration is that there are more production and enterprise-ready offerings that absolutely should be explored. + +### Installing the sample observability addons +I'm using the same Civo Kubernetes cluster I've been using since I started this, but I plan to create some automation to turn up and down new clusters. + +I'm going to change back to the Istio-1.16.1 directory +``` +cd istio-1.16.1 +``` +And then I'll deploy the sample add-ons provided in the original zip file. +``` +kubectl apply -f samples/addons +``` +Give it a couple of minutes and then double check. +``` +kubectl get pods -n istio-system +``` +``` +NAME READY STATUS RESTARTS AGE +istio-egressgateway-7475c75b68-mpxf7 1/1 Running 0 5d15h +istiod-885df7bc9-f9k7c 1/1 Running 0 5d15h +istio-ingressgateway-6688c7f65d-szxf9 1/1 Running 0 5d15h +jaeger-54b7b57547-vsnhl 1/1 Running 0 34s +prometheus-7b8b9dd44c-kd77d 2/2 Running 0 32s +grafana-b854c6c8-fhjlh 1/1 Running 0 35s +kiali-5ff88f8595-fnk8t 1/1 Running 0 33s +``` +Perfect, let's proceed with Prometheus. + +### Prometheus +Since Prometheus is already installed we want to verify that it's currently running. + +Let's check the service and verify it's online. +``` +kubectl get svc prometheus -n istio-system +``` +``` +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +prometheus ClusterIP 10.43.234.212 9090/TCP 25h +``` + +I'm going to generate traffic from my host to the Bookinfo app and I'll go review this in Prometheus, which we'll expose using istoctl. +``` +curl "http://bookinfo.io/productpage" +``` + +Let's turn up the dashboard the *istioctl dashboard [name_of_k8s_service]*: +``` +istioctl dashboard prometheus +``` +At this point, a web-browser (your default) should open up with Prometheus. I want to feed it a query and I will do so in the *Expression* address bar, and proceed to hit execute. +When your browser launches with Promtheus, simply enter the following to execute a query on the total requests Istio will process. + +Paste the below into the query bar. This query simply outputs all the requests Istio sees. +``` +istio_requests_total +``` +![observeday81](images/Day81-1.png) + +There's much more to what we can see in Prometheus. If you have this up in your environment, play around. I'll revisit this in later days as I intend to dig into some of the key metrcis around SLAs, SLOs, SLIs, nth-percentile and latency, requests per second and others. + +Hit *ctrl+c* to exist the dashboard process. + +### Grafana +Grafana is an open-source and multi-platform analystics and visualization system that can be deployed alongside Prometheus to help us visually chart our apps and infra performance. + +I've already installed the sample addons which contained Grafana. Let's check the services and see that it's there. + +``` +kubectl get svc -n istio-system +``` +And we can verify it's there. +``` +NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE +istiod ClusterIP 10.43.249.242 15010/TCP,15012/TCP,443/TCP,15014/TCP 7d +istio-egressgateway ClusterIP 10.43.75.47 80/TCP,443/TCP 7d +istio-ingressgateway LoadBalancer 10.43.51.40 [HAHA.NO.NICE.TRY] 15021:31000/TCP,80:32697/TCP,443:30834/TCP,31400:30953/TCP,15443:30733/TCP 7d +grafana ClusterIP 10.43.115.239 3000/TCP 32h +tracing ClusterIP 10.43.237.214 80/TCP,16685/TCP 32h +zipkin ClusterIP 10.43.241.104 9411/TCP 32h +jaeger-collector ClusterIP 10.43.43.212 14268/TCP,14250/TCP,9411/TCP 32h +kiali ClusterIP 10.43.51.161 20001/TCP,9090/TCP 32h +prometheus ClusterIP 10.43.234.212 9090/TCP 32h +``` + +Let's use the *istioctl dashboard* command again +``` +istioctl dashboard grafana +``` +A web browser with the Grafana tab should have opened up. On the far left, click the 4 boxes that make up a square, and then select the Istio folder. + +![graph_grafana](images/Day81-2.png) + +Select the Istio Mesh Dashboard. + +In another terminal, let's generate some load +``` +for i in $(seq 1 100); do curl -s -o /dev/null "http://bookinfo.io/productpage"; done +``` +The metrics for each of the services (except reviews v2) receive requests and ultimately will produce valuable metrics indicative of success, latency and other key details. We can see this below: + +![grafana_mesh_dash](images/Day81-3.png) + +In the second terminal, let's generate some more load +``` +for i in $(seq 1 300); do curl -s -o /dev/null "http://bookinfo.io/productpage"; done +``` + +Go back to where the Istio dashboards are located, and click the Service dashboard. This will give you an idea of how the services in the mesh are performing and the client-success rate. + +![grafana_service_dash](images/Day81-4.png) + +I'll dive more into these details in future days. Kill the dashboard by hitting *ctrl+c* + +### Jaegar +Jaegar is all ready to go. It's an excellent tracing tool to help piece together a trace, which is comprised of multiple spans for a given request flow. + +Let's enable the dashboard: +``` +istioctl dashboard jaegar +``` +A new window should pop up with a curious-looking gopher. That gopher is inspecting stuff. + +In our second terminal, let's issue that curl command to reach bookinfo.io. +``` +for i in $(seq 1 300); do curl -s -o /dev/null "http://bookinfo.io/productpage"; done +``` +In the new window with Jaeger, the left pane allows us to select a service, pick any. + +By picking a service, you are looking from it's POV, how it's apart of the request flow. While you'll see it's span, it'll be a part of a larger trace comprised of multiple spans. + +I picked the ratings service which shows me all the spans it's associated with in a single trace. We'll expand upon this later on. + +All the different traces: + +![all_traces_jaegar](images/Day81-5.png) + +All the different spans within the *ratings* trace: +![all_spans_jaegar](images/Day81-6.png) + + +Ever used wireshark before? + +Kill the jaeger dashboard with *ctrl+c* + +### Kiali +Kiali is another great tool to visualize how traffic and request flow inside of mesh. + +But the visual component is captivating! It's because it shows us how one service communicates with another, using a visual map! + +Let's enable the Kiali dashboard: +``` +istioctl dashboard kiali +``` +A web-browser will open with Kiali and on the left-hand pane, click on "Graph". + +There are a few dropdowns, one says *Namespace*. Click on it and make sure the default namespace is selected. Under the *Display* dropdown, click on *Traffic Animation* and *Security*. There are other options but I'll revisit these later. + +I'm going to open up another terminal and run this curl command: +``` +for i in $(seq 1 300); do curl -s -o /dev/null "http://bookinfo.io/productpage"; done +``` + +In about a few minutes you'll start to see a visual map show up in Kiali as mentioned before. + +The screenshot below shows the directional flow of traffic, but, also notice that lock icon! It means mTLS is available. We'll explore this in the Security sections. + +![kiali_flows](images/Day81-7.png) + +Finally, check out this video and see the visualization. + +![kiali_video_visualizations](images/Day81-8.gif) + +Or visit the video here: https://www.youtube.com/watch?v=vhV8nHgytNM + +Go ahead and end the Kiali dashboard process with *ctrl+c*. + +### Conclusion +I've explored a few of the tools to be able to understand how we can observe services in our mesh and better understand how our applications are performing, or, if there are any issues. + +Want to get deeper into Service Mesh Observability? Head over to [#70DaysofServiceMesh](https://github.com/distributethe6ix/70DaysOfServiceMesh)! + +See you on [Day 82](day82.md) diff --git a/2023/day82.md b/2023/day82.md index e69de29..a0cf540 100644 --- a/2023/day82.md +++ b/2023/day82.md @@ -0,0 +1,289 @@ +## Day 82 - Securing your microservices +> **Tutorial** +>> *Let's secure our microservices* + +Security is an extensive area when in comes to microservices. I could basically spend an entire 70days on just security alone but, I want to get to the specifics of testing this out in a lab environment with a Service Mesh. + +Before I do, what security concerns am I addressing with a Service Mesh? +- Identity +- Policy +- Authorization +- Authentication +- Encrpytion +- Data Loss Prevention. + +There's plenty to dig into with these but what specifically of Service Mesh helps us acheive these? + +The sidecar, an ingress gateway, a node-level proxy, and the service mesh control plane interacting with the Kubernetes layer. + +As a security operator, I may issue policy configurations, or authentication configurations to the Istio control plane which in turn provides this to the Kubernetes API to turn these into runtime configurations for pods and other resources. + +In Kubernetes, the CNI layer may be able to provide a limited amount of network policy and encryption. Looking at a service mesh, encryption can be provided through mutual-TLS, or mTLS for service-to-service communication, and this same layer can provide a mechanism for Authentication using strong identities in SPIFFE ID format. Layer 7 Authorization is another capability of a service mesh. We can authorize certain services to perform actions (HTTP operations) against other services. + +mTLS is used to authenticate peers in both directions; more on mTLS and TLS in later days. + +To simplify this, Authentication is about having keys to unlock and enter through the door, and Authorization is about what you are allowed to do/touch, once you're in. Defence in Depth. + +Let's review what Istio offers and proceed to configure some of this. We will explore some of these in greater detail in future days. + +### Istio Peer Authentication and mTLS +One of the key aspects of the Istio service mesh is its ability to issue and manage identity for workloads that are deployed into the mesh. To put it into perspective, if all services have a sidecar, and are issued an identity (it's own identity) from the Istiod control plane, a new ability to trust and verify services now exists. This is how Peer Authentication is achieved using mTLS. I plan to go into lots more details in future modules. + +In Istio, Peer Authentication must be configured for services and can be scoped to workloads, namespaces, or the entire mesh. + +There are three modes, I'll explain them briefly and we'll get to configuring! +* PERMISSIVE: for when you have plaintext AND encrypted traffic. Migration-oriented +* STRICT: Only mTLS enabled workloads +* DISABLE: No mTLS at all. + +We can also take care of End-user Auth using JWT (JSON Web Tokens) but I'll explore this later. + +### Configuring Istio Peer AuthN and Strict mTLS +Let's get to configuring our environment with Peer Authentication and verify. + +We already have our environment ready to go so we just need to deploy another sample app that won't have the sidecar, and we also need to turn up an Authentication policy. + +Let's deploy a new namespace called sleep and deploy a sleeper pod to it. +``` +kubectl create ns sleep +``` +``` +kubectl get ns +``` +``` +cd istio-1.16.1 +kubectl apply -f samples/sleep/sleep.yaml -n sleep +``` + +Let's test to make sure the sleeper pod can communicate with the bookinfo app! +This command simply execs into the name of the sleep pod with the "app=sleep" label in the sleep namespace and proceeds to curl productpage in the default namespace. +The status code should be 200! +``` +kubectl exec "$(kubectl get pod -l app=sleep -n sleep -o jsonpath={.items..metadata.name})" -c sleep -n sleep -- curl productpage.default.svc.cluster.local:9080 -s -o /dev/null -w "%{http_code}\n" +``` +``` +200 +``` + +Let's apply our PeerAuthentication +``` +kubectl apply -f - < **Tutorial** +>> *Let's investigate sidecar-less with Ambient Mesh* + +### Enter Ambient Mesh + +For Day 83 (and the final day of Service Mesh for #90DaysOfDevOps), I decided to provide some background on Istio Ambient Mesh, to provide more approaches to onboard a service mesh. + +Istio has been around for a while and has been significantly battle-tested against various conditions, scenarios, configurations, and use-cases. + +Design patterns have emerged where the sidecar might inhibit performance of applications and through experimentation and a constant feedback loop, Ambient Mesh was born. Ambient Mesh was a joint collaboration between [Solo.io](https://Solo.io) and Google. You can read abut the announcement [here](https://istio.io/latest/blog/2022/introducing-ambient-mesh/). + +Ambient Mesh is still a part of Istio and as of this moment, is in Alpha under Istio 1.17. When you download istioctl, there is an Ambient Mesh profile. + + +### The Benefits of Ambient Mesh + +1. Reduced resource consumption: Sidecar proxies can consume a significant amount of resources, particularly in terms of memory and CPU. Eliminating the need for sidecar proxies, allows us to reduce the resource overhead associated with your service mesh. + +2. Simplified deployment: Without sidecar proxies, the deployment process becomes more straightforward, making it easier to manage and maintain your service mesh. You no longer need to worry about injecting sidecar proxies into your application containers or maintaining their configurations. + +3. Faster startup times: Sidecar proxies can add latency to the startup time of your services, as they need to be initialized before your applications can start processing traffic. A sidecar-less approach can help improve startup times and reduce overall latency. + +4. Lower maintenance: Sidecar proxies require regular updates, configuration management, and maintenance. A sidecar-less approach can simplify your operational tasks and reduce the maintenance burden. + +5. Easier experimentation: A sidecar-less approach like Ambient Mesh allows you to experiment with service mesh architectures without making significant changes to your existing applications. This lowers the barrier to entry and allows you to more easily evaluate the benefits of a service mesh. + +6. Faster time to Zero-Trust: Ambient Mesh deploys the necessary key components to employ mTLS, Authentication, L4 Authorization and L7 Authorization + +7. Still Istio: Istio Ambient Mesh still has all the same CRDS present like Virtual Services, Gateway, Destination Rules, Service Entries, Authentication, and Authorization Policies. + +8. Sidecar AND Sidecarless: With Istio in Ambient mode, you can still deploy sidecars to necessary resources, and still have communication between + + +### Ambient Mesh Architecture + +There are several main components that drive Ambient Mesh today: +- **Istiod**: Which is the control plane for the Istio service mesh and is the point of configuration, and certificate management. +- **The L4 Ztunnel**: This is strictly responsible for handle mTLS for communicating pods through ztunnel pods on each node. The ztunnel pods form mTLS between each other. The ztunnel is responsible for L4 Authorization as well. This is a `daemonset` in Kubernetes. +- **The Istio CNI Node**: Responsible for directing traffic from a workload pod to the ztunnel. This is a `daemonset` in Kubernetes. +- **The WayPoint Proxy**: The L7 proxy which provides the same functionality as the sidecar, except deployed at the destination of a request to process things like L7 Authorization Policies. This leverages the Gateway API resource. +- **HBONE**: The tunnel protocol which uses TCP Port 15008 to form tunnels between ztunnels on different nodes and between ztunnels and Waypoint Proxies. + +This diagram from this [Ambient Security Blog](https://istio.io/latest/blog/2022/ambient-security/) provides a good representation of the architecture. + +![Ambient Mesh](https://istio.io/latest/blog/2022/ambient-security/ambient-layers.png) + + + +### ztunnels and Rust + +To enhance the experience and performance of Ambient Mesh, the ztunnel which previously used a slimmed down Envoy instance, now uses Rust. Read more over at this [Rust-Based Ztunnel blog](https://istio.io/latest/blog/2023/rust-based-ztunnel/) + + +### Deploying Ambient Mesh + +Before we get started, you want to make sure you have a basic Kubernetes cluster. *K3s will not work today.* +I'd recommend KinD or Minikube so you have less restrictions and the setup is pretty easy. + +**Note** You can actually run this on ARM, or x86, so this will run well on your ARM-based MAC. In my setup i'm using x86 based Ubuntu 22.04. + +Let's first download the binary which you can select your flavour here: https://github.com/istio/istio/releases/tag/1.18.0-alpha.0 + +``` +wget https://github.com/istio/istio/releases/download/1.18.0-alpha.0/istio-1.18.0-alpha.0-linux-amd64.tar.gz +``` + +And then uncompress the file and change to the directory so you'll have access to the istioctl binary: + + +``` +tar -xf istio-1.18.0-alpha.0-linux-amd64.tar.gz istio-1.18.0-alpha.0/ +``` +``` +cd istio-1.18.0-alpha.0/ +``` + +Finally, let's make istioctl executable everywhere +``` +export PATH=$PWD/bin:$PATH +``` + +Next, let's create your KinD cluster (assuming you already have Docker ready to go) +``` +kind create cluster --config=- <.*" +``` +``` +kubectl exec deploy/sleep -- curl -s http://productpage:9080/ | grep -o ".*" +``` +``` + kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | grep -o ".*" +``` +Which will all produce the result: +``` +Simple Bookstore App +``` +So we know, we can access our apps and even with Istio installed, we need to enable the Mesh. So.... + +FINALLY, we're going to throw our services into the ambient-enabled mesh, notice how we label the namespace with the `dataplane-mode=ambient` versus using the normal `istio-injection=enabled` label. +``` +kubectl label namespace default istio.io/dataplane-mode=ambient +``` +This label effectively tells the `ztunnel` to capture the identity of an out-bound workload and act on its behalf for mTLS, whle also telling the `istio-cni-node` pods to route traffic towards the ztunnel. + +You can re-run the `curl` commands above if you'd like but, I'd recommend just running this looped-curl, and we can check the logs: +``` +for i in {1..10}; do kubectl exec deploy/notsleep -- curl -s http://productpage:9080/ | grep -o ".*"; sleep 1; done +``` +Now, let's review the ztunnel logs: +``` +kubectl logs -n istio-system -l app=ztunnel +``` +And the output: +``` +2023-03-25T15:21:34.772090Z INFO inbound{id=50c102c520ed8af1a79e89b9dc38c4ba peer_ip=10.244.1.4 peer_id=spiffe://cluster.local/ns/default/sa/notsleep}: ztunnel::proxy::inbound: got CONNECT request to 10.244.2.8:9080 +2023-03-25T15:21:29.935241Z INFO outbound{id=a9056d62a14941a70613094ac981c5e6}: ztunnel::proxy::outbound: proxy to 10.244.2.8:9080 using HBONE via 10.244.2.8:15008 type Direct +``` +The output is very interesting because you can see that `notsleep` is using the HBONE protocol on port `15008` to tunnel via the ztunnel over to `productpage`. If you ran `kubectl get pods -o wide` you will see that the IPs are owned by the notsleep and productpage pods. So NOW you've got a bit exposure to Ambient Mesh, go explore more! + + +### There is so much more to Ambient Mesh + +This module has gotten pretty long, but I encourage you to dig deeper into Ambient Mesh and see how you can potentially use it for things like Edge Computing for low-resource environments. If you want some more guided labs, check out [Solo Academy](https://academy.solo.io)!!! + + +### The end of the Service Mesh section for #90DaysofDevOps + +We have certainly reached the end of the Service Mesh section but, I encourage y'all to check out [#70DaysofServiceMesh](https://github.com/distributethe6ix/70DaysOfServiceMesh) to get even deeper and get ultra meshy :smile:! + +See you on [Day 84](day84.md) and beyond! :smile:! + diff --git a/2023/day84.md b/2023/day84.md index e69de29..a5d7f93 100644 --- a/2023/day84.md +++ b/2023/day84.md @@ -0,0 +1,58 @@ +# Writing an API - What is an API? + +The acronym API stands for “application programming interface”. What does this really mean though? It’s a way of +controlling an application programmatically. So when you use a website that displays some data to you (like Twitter) +there will be an action taken by the interface to get data or send data to the application (the twitter backend in this +example) - this is done programmatically in the background by code running in the user interface. + +In the example given above we looked at an example of a public API, however the vast majority of APIs are private, one +request to the public twitter API will likely cause a cascade of interactions between programs in the backend. These +could be to save the tweet text into a datastore, to update the number of likes or views a tweet has or to take an image +that has been uploaded and resize it for a better viewing experience. + +We build programs with APIs that other people can call so that we can expose program logic to other developers, teams +and our customers or suppliers. They are a predefined way of sharing information. For example, we can define an API +using [openapi specification](https://swagger.io/resources/open-api/) which is used +for [RESTful](https://en.wikipedia.org/wiki/Representational_state_transfer) API design. This api specification forms a +contract that we can fulfil. For example, If you make an API request to me and pass a specific set of content, such as a +date range, I will respond with a specific set of data. Therefore you can reliably expect to receive data of a certain +type when calling my API. + +We are going to build up an example set of applications that communicate using an API for this section of the learning +journey to illustrate the topics and give you a hands-on look at how things can be done. + +Design: +2 programs that communicate bi-directionally, every minute or so one application will request a random string from the +other, once one is received it will store this number in a database for future use + +The Random Number generator will generate a random string when requested and save this into a database, the application +will then ask the first program for confirmation that it received the string, and store this information against the +string in the database + +The applications will be called: +generator +requestor + +This may sound like a silly example but it allows us to quickly look into the various tasks involved with building, +deploying, monitoring and owning a service that runs in production. There are bi-directional failure modes as each +application needs something from the other to complete successfully and things we can monitor such as API call rates - +We can see if one application stops running. + +We need to now decide what our API Interfaces should look like. We have 2 API calls that will be used to communicate +here. Firstly, the `requestor` will call the `generator` and ask for a string. This is likely going to be an API call +without any additional content other than making a request for a string. Secondly, the `generator` will start to ask +the `requestor` for confirmation that it received and stored the string, in this case we need to pass a parameter to +the `requestor` which will be the string we are interested in knowing about. + +The `generator` will use a URL path of `/new` to serve up random strings +The `requestor` is going to use URL paths to receive string information from the `generator` to check the status, so we +will setup a URL of `/strings/` where is the string of interest. + + +## Building the API +There is a folder on the Github repository under the 2023 section called `day2-ops-code` and we will be using this +folder to store our code for this, and future, section of the learning journey. + +We are using Golang's built in HTTP server to serve up our endpoints and asynchronous goroutines to handle the +checks. Every 60 seconds we will look into the generators database and get all the strings which we dont have +conformation for and then calling the requesters endpoint to check if the string is there. \ No newline at end of file diff --git a/2023/day85.md b/2023/day85.md index e69de29..c9e05a6 100644 --- a/2023/day85.md +++ b/2023/day85.md @@ -0,0 +1,62 @@ +# Queues, Queue workers and Tasks (Asynchronous architecture) +Yesterday we looked at how we can use HTTP based APIs for communication between services. This works well until you need +to scale, release a new version or one of your services goes down. Then we start to see the calling service fail because +it’s dependency is not working as expected. We have tightly coupled our two services, one can’t work without the other. + +There are many ways to solve this problem, a light touch approach for existing applications is to use something called a +circuit breaker to buffer failures and retry until we get a successful response. This is explained well in this blog +by [Martin Fowler](https://martinfowler.com/bliki/CircuitBreaker.html). However, this is synchronous, if we were to wrap +our calls in a circuit breaker we would start to block processes and our user could see a slowdown in response times. + +Additionally, we can’t scale our applications using this approach, the way that the code is currently written every +instance of our `generator` api would be asking +the `requestor for confirmation of receiving the string. This won’t scale well when we move to having 2, 5, 10, or 100 instances running. We would quickly see the ` +requestor` being overwhelmed with requests from the 100 generator applications. + +There is a way to solve these problems which is to use Queues. This is a shift in thinking to using an asynchronous +approach to solving our problem. This can work well when the responses don’t need to be immediate between applications. +In this case it doesn't matter if we add some delay in the requests between the applications. As long as the data +eventually flows between them we are happy. + +![Queues, producers and Consumers](./images/day84-queues.png) +(https://dashbird.io/knowledge-base/well-architected/queue-and-asynchronous-processing/) + +In the drawing above we can see how we can add a Queue in between our applications and the Queue stores the intent of +the message across the bridge. If the Consumer was to fail and stop reacting messages then, providing our Queue software +has sufficient storage, the messages to the consumer would still “succeed” as far as the producer is concerned. + +This is a powerful pattern that isolates components of a system from each other and limits the blast radius of failure. +It does however add complexity. The Consumer and Producer must share a common understanding of the shape of a message +otherwise the Consumer will be unable to act on the message. + +We are going to implement a Queue in between our two applications in our data flows. + +By the end of the section we will have the following data flows + +Requestor (asks for a random string) → Queue → Generator (gets the message, generates a string and passes it back to the +Requestor on another Queue) → Requestor (gets the string back on a queue and stores it, then sends a message to the +queue saying it has received it) → Queue → Generator (marks that the message was received) + +The last section here, where the Generator needs to know if the Requestor got the message is a simplification of a real +process where an application may pass back an enriched data record or some further information but it allows us to have +a simple two way communication. + +Can you see how by the end of this section we will be able to stop, scale, deploy or modify each of the two components +without the other needing to know? + +## Modifying our application + +We are now going to modify our app to fit the model described above. Where we previously made a HTTP api call to our +partner app we are now going to place a message on a named queue and then subscribe to the corresponding response +queues. + +Finally we are going to stop using HTTP endpoints to listen for requests, we are now subscribing to queues and waiting +for messages before we perform any work. + +I have picked [NATSio](https://nats.io/) as the queue technology as I have worked with it previously and it’s very easy +to set up and use. + +Head over to the 2023/day2-ops-code/README.md to see how to deploy day 2's application. + +It sends messages to a queue and then waits for a response. The response is a message on a different queue. The message +contains the data that we are interested in. \ No newline at end of file diff --git a/2023/day86.md b/2023/day86.md index e69de29..b58ad07 100644 --- a/2023/day86.md +++ b/2023/day86.md @@ -0,0 +1,95 @@ +# Designing for Resilience, Redundancy and Reliability + +We now have an application which uses asynchronous queue based messaging to communicate. This gives us some real +flexibility on how we design our system to withstand failures. We are going to look at the concept of Failure Zones, +Replication, Contract testing, Logging and Tracing to build more robust systems. + +## Failure Zones + +Imagine building an application and deploying everything onto a single VM or server. What happens when, inevitably, this +server fails. Your application goes offline and your customers won’t be happy! There’s a fix to this. Spread your +workloads over multiple points of failure. This doesn’t just go for your application instances but you can build +multiple redundant points for every aspect of your system. + +Ever wonder what some of the things large cloud providers do to keep their services running despite external and +unpredictable factors? For starters they will have generators on-site for when they inevitably suffer a power cut. They +have at least two internet connections into the datacentres and they often provide multiple availability zones in each +region. Take Amazon’s eu-west-2 (London) region. This has 3 availability zones, eu-west-2a, eu-west-2b and eu-west-2c. +There are 3 separate datacenters (physically separated) that all inter-connect to provide a single region. This means by +deploying services across these availability zones (AZs) we increase our redundancy and resilience over factors such as +a fire in one of these facilities. If you run a homelab you could distribute work over failure zones by running more +than one computer, placing these computers in separate parts of the house or buying 2 internet connections to stay +online if one goes down (This does mean checking that these connections don’t just run on the same infrastructure as +soon as they leave your door. At my house I can get fibre to my house and also a connection over the old phone lines) + +## Replication + +This links nicely into having multiple replicas of our “stuff”, this doesn’t just mean running 2 or 3 copies of our +application over our previously mentioned availability zones we also need to consider our data - If we ran a database in +AZ1 and our application code over AZ1, AZ2 and AZ3 what do you think would happen if AZ1 was to go offline, potentially +permanently? There have been instances of cloud datacenters being completely destroyed by fire and many customers had +not been backing up their data or running across multiple AZs. Your data in this case is… gone. Do you think the +business you workin in could survive if their data, or their customers data, just disappeared overnight? + +Many of our data storage tools come with the ability to be configured for replication across multiple failure zones. +NATS.io that we used previously can be configured to replicate messages across multiple instances to survive failure of +one or more zones. Postgresql databases can be configured to stream their WAL (Write ahead log), which stores an +in-order history of all the transactions, to a standby instance running somewhere else. If our primary fails then the +most we would lose would be the amount of data in our WAL that was not transferred to the replica. Much less data loss +than if we didn’t have any replication. + +## Contract Testing + +We are going to change direction now and look at making our applications more reliable. This means reducing the change +of failures. You may appreciate that the time most likely to cause failures in your system is during deployments. New +code hits our system and if it has not been tested thoroughly in production-like environments then we may end up with +undefined behaviours. + +There’s a concept called Contract testing where we can test the interfaces between our applications at development and +build time. This allows us to rapidly get feedback (a core principle of DevOps) on our progress. + +## Async programming and queues + +We have already discussed how breaking the dependencies without our system can lead to increased reliability. Our +changes become smaller, less likely to impact other areas of our application and easy to roll-back. + +If our users are not expecting an immediate tactile response to an event, such as requesting a PDF be generated then we +can always place a message onto a queue and just wait for the consumer of that message to eventually get round to it. We +could see a situation where thousands of people request their PDF at once and an application that does this +synchronously would just fall over, run out of memory and collapse. This would leave all our customers without their +PDFs and needing to take an action again to wait for them to be generated. Without developer intervention we may not get +back to a state where the service can recover. + +Using a queue we can slowly work away in the background to generate these PDFs and could even scale the service in the +background automatically when we noticed the queue getting longer. Each new application would just take the next message +from the queue and work through the backlog. Once we were seeing less demand we could automatically scale these services +down when our queue depth reached 0. + +## Logging and Tracing + +It goes without saying that our applications and systems will fail. What we are doing in this section of 90daysOfDevOps +is thinking about what we can do to make our lives less bad when things do. Logging and tracing are some really +important tools in our toolbox to keep ourselves happy. + +If we log frequently with both success and failure messages we can follow the progress of our requests and customer +journeys through our system then when things go wrong we can quickly rule out specific services or focus down on +applications that are logging warning or error messages. My general rule is that you can’t log too much - its not +possible! It is however important to use a log framework that lets you tune the log level that gets printed to your +logs. For example if i have 5 log levels (as is common), TRACE, DEBUG, INFO, WARN and ERROR we should have a mechanism +for ever application to set the level of logs we want to print. Most of the time we only want WARN and ERROR to be +visible in logs, to quickly show us theres and issue. However if we are in development or debugging a specific +application its important to be able to turn up the verbosity of our logs and see those INFO/DEBUG or TRACE levels. + +Tracing is a concept of being able to attack a unique identifier to a request in our system that then gets populated and +logged throughout that requests journey, we could see a HTTP request hit a LoadBalancer, get a correlationID and then we +want to see that correlationID in ever log line as our request’s actions percolate through our system. + +## Conclusion + +It’s hard to build a fully fault-tolerant system. It involves learning from our, and other people’s, mistakes. I have +personally made many changes to company infrastructure after we discovered a previously unknown failure zone in our +application. + +We could change our application running in Kubernetes to tolerate our underlying infrastructure’s failure zones by +leveraging [topology spread constraints](https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/) +to spread replicas around. We won’t in this example as we have much more to cover! diff --git a/2023/day87.md b/2023/day87.md index e69de29..b2fcbd4 100644 --- a/2023/day87.md +++ b/2023/day87.md @@ -0,0 +1,72 @@ +# Zero Downtime Deployments + +Another important part of your application lifecycle is deployment time. There are lots of strategies for deploying +software. Like with anything there are pros and cons to the various strategies so I will run through a few options from +least complex to most complex, and as you may imagine the most complex deployment types tend come with the highest +guarantees of uptime and least disruption to your customer. + +You may be asking why it's important to consider how we deploy our applications as the vast majority of our application +lifecycle time will be in the “running” state and therefore we could focus our time on strategies that support our +running application’s resilience. My answer is: Have you ever been on-call? Almost all incidents are due to code +releases or changes. The first thing I do when im on-call and called to an incident is see what was recently deployed - +I focus my main attention on that component and more often than not it was to blame. + +We do also need to consider that some of these deployment strategies will require us to make specific code changes or +application architecture decisions to allow us to support the specific deployment in question. + +### Rolling Deployments + +One of the simplest deployment strategies is a rolling deployment. This is where we slowly, one by one (or many be many, +depending on how many instances of a service you have) we replace old deployments with their new tasks. We can check +that the new deployments are healthy before moving onto the next, only have a few tasks not healthy at a time. + +This is the default deployment strategy in Kubernetes. It actually borrows some characteristics from Surge, which is +coming next. It starts slightly more new tasks and waits for them to be healthy before removing old ones. + +### Surge Deployments + +Surge deployments are exactly what they sound like. We start a large number of new tasks before cutting over traffic to +those tasks and then draining traffic from our old tasks. This is a good strategy when you have high usage applications +that may not cope well with reducing their availability at all. Usually surge deployments can be configured to run a +certain percentage more than the existing tasks and then wait for them to be healthy before doing a cutover. + +The problem with surge deployments is that we need a large capacity of spare compute resources to spin up a lot of new +tasks before rolling over and removing the old ones. This can work well where you have very elastic compute such as AWS +Fargate where you don’t need to provision more compute yourself. + +### Blue/Green + +The idea behind a Blue/Green deployment is that your entire stack (or application) is spun up, tested and then finally +once you are happy you change config to send traffic to the entire new deployment. Sometimes companies will always have +both a Blue and a Green stack running. This is a good strategy where you need very fast rollback and recovery to a known +good state. You can leave your “old” stack running for any amount of time once you are running on your new stack. + +### Canary + +Possibly one of the most complicated deployment strategies. This involves deploying a small number of your new +application and then sending a small portion of load to the new service, checking that nothing has broken by monitoring +application performance and metrics such as 4XX or 5XX error rates and then deciding if we continue with the deployment. +In advanced setups the canary controllers can do automatic rollbacks if error thresholds are exceeded. + +This approach does involve a lot more configuration, code and effort. + +Interestingly the name comes from from coal mining and the phrase "canary in the coal mine." Canary birds have a lower +tolerance to toxic gases than humans, so they were used to alert miners when these gases reached dangerous levels inside +the mine. + +We use our metrics and monitoring to decide if our “canary” application is healthy and if it is, we then proceed with a +larger deployment. + +## Application design considerations + +You may have worked out by now that the more advanced deployment strategies require you to have both old and new +versions of your application running at once. This means that we need to ensure backwards compatibility with all the +other software running at the time. For instance, you couldn't use a database migration to rename a table or column +because the old deployment would no longer work. + +Additionally, our canary deployment strategy requires our application to have health checks, metrics, good logging and +monitoring so that we can detect a problem in our specific canary application deployment. Without these metrics we would +be unable to programmatically decide if our new application works. + +Both these considerations, along with others, mean that we need to spend extra time both on our application code, +deployment code and our monitoring and alerting stacks to take advantage of the most robust deployments. diff --git a/2023/day88.md b/2023/day88.md index e69de29..a50496d 100644 --- a/2023/day88.md +++ b/2023/day88.md @@ -0,0 +1,29 @@ +# Monitoring, Alerting and On-Call + +As we have discussed there is no such thing as a perfect system that will never fail. Therefore we need to think about what to do when things go wrong. First and foremost the most important thing is not to panic. What tools and processes can we put in place to make incidents less stressful, easier to resolve and less likely to occur again? + +## On-Call Practices + +If you have never been “on-call” then you are an extremely lucky human. Being on-call for a system means being alerted when something is going wrong and being responsible for logging on, diagnosing the problem and helping to fix it. + +When we build software that people and businesses rely on we become liable for keeping those systems going. Our customers expect a certain level of uptime and availability for the services they are paying for. Let’s look at two examples, a Business-To-Business internal app for tracking month-end accounting and a real-time payments system with thousands of transactions a second with cumulative values of millions of pounds a minute. + + +## Alerts: the good, bad and ugly + +How do you even know if your application is working? + +Alerts. These are notifications that inform you about the status or performance of your application. They can be configured to trigger when specific events or conditions occur, such as errors, timeouts, or spikes in traffic. I have seen `ERROR` log lines being used to trigger alerts as well as issues such as 4XX and 5XX http responses. You can practically alert on anything! If you wanted to know if your applications need to be scaled you could look at your message queue depth (number of messages in the queue) - if its growing or beyond a threshold you can either alert, or even better, you can automatically scale your application. +Alerts can be very useful in detecting and resolving issues quickly, which can help prevent downtime or other negative consequences. They allow you to proactively monitor your application and respond to issues before they become critical. +However, there can also be downsides to using alerts. If alerts are not properly configured or managed, they can generate a high volume of false alarms, which can be overwhelming and distract from real issues. This can lead to alert fatigue and decreased effectiveness in responding to issues. +It is important to carefully consider the types of alerts that are necessary for your application, and to regularly review and adjust your alert settings as needed. You should also have processes in place for responding to alerts, such as escalation procedures and clear documentation on how to resolve common issues. + +## The cost of on-call + +I have worked on systems similar to both of these hypothetical examples and I can tell you that the approach to on-call and incident management was wildly different. The month-end accounting software is only used by a handful of well-known customers sporadically - they may not log-in for many weeks before there being a flurry of activity for 2 days a month. The payments platform has constant and relentless use with many thousands of impacted people per minute. + +There’s an important message here around knowing your users, their tolerance for downtime and their usage patterns. +For the payments platform the on-call rota was 24-7 365 days a year. Every second counts and they expected an engineer to be online within a few minutes of being notified of a problem. This puts strain on your engineers and incident staff as even simple daily tasks become challenging - I can’t walk my dog today because I’m on-call and if called I need to be online within a few minutes. + +There’s very little fun about being on-call. You are tied to a location or always carrying your laptop, you get woken in the middle of your night and it's wildly unpredictable. If you can cope with some delay in fixing your system I highly recommend cutting your teams some slack and having good grace periods for getting online or muting alerts overnight. Obviously this isn't possible for all systems so where you need fast on-call cover make sure to keep an eye on your colleagues and look out for signs of stress and burnout. + diff --git a/2023/day89.md b/2023/day89.md index e69de29..a84c852 100644 --- a/2023/day89.md +++ b/2023/day89.md @@ -0,0 +1,25 @@ +# Oops: When something goes wrong - Post Mortems + +As we have already discussed things will go wrong! We now know how to build applications where the impact of things breaking is less and where we know when things break. However, there will always be unknowns in the system and there will always be human error. + +We need to build up a culture that fosters learning and improving from mistakes and one that understands that failure is inevitable. It’s the only way we learn. If the culture does not recognise this then we can quickly get into a situation where everyone is scared to make changes or take risks and therefore nothing improves. + +## Blameless culture + +We are trying to build a “Blameless culture” where people are free to experiment, change and adapt. The key to this culture is always assuming someone had the best intentions based on the available information. This means that if somebody pressed a big button on your backend dashboard that dropped your production database they only did this because they did not have enough information to know not to do this! It means not blaming the intern for taking down production (As, why did they have the ability to make such a change?). + +Having a blameless culture leads to “Psychological Safety”. Psychological safety is a term used to describe a workplace environment where employees feel comfortable and safe to take interpersonal risks, such as sharing ideas, asking for help, or admitting mistakes, without fear of negative consequences. +In a psychologically safe workplace, employees feel that their opinions and contributions are valued, and they are free to express themselves without fear of ridicule, retribution, or ostracism. This can lead to increased trust and collaboration among team members, as well as improved innovation and problem-solving. +Psychological safety has been found to be an important factor in team effectiveness and organisational performance, and it has been linked to positive outcomes such as higher job satisfaction, lower turnover rates, and better overall team performance. +Can you see how important it is to have a blameless culture with psychological safety? Without it nothing gets done. + +## Post Mortems + +Hopefully this section will explain why we have looked into a blameless culture with psychological safety. When things go wrong we need to be able to look at the objectively and ask “What went wrong? Why and What can we do to reduce the likelihood (or risk) of this happening again?” + +If your team or organisation are not mature enough to sit down together and admit their mistakes, what information was missing to them at 2AM when they were trying to fix a system outage or to take the emotion of failure out of the picture then its going to be hard for everyone to share honestly. + +Can you say that your organisation would be happy to hear from a new employee on what mistake they made that had a big customer impact without blaming them? They should. If they made that mistake then it means that anyone was able to make it, at any time. Build guard rails into your system around these incidents. [This is covered well by this website covering retrospectives](https://www.funretrospectives.com/the-retrospective-prime-directive/) as at the end of the day, a post mortem is just a retrospective. + +So, after an incident its very important to sit down and have an honest and open conversation about what went wrong and what should be done to fix those issues, and who is responsible for making those changes. This can be as informal as having a coffee with the key stakeholders or as formal as putting a calendar invite in and getting everyone together from across the business. + diff --git a/2023/images/.DS_Store b/2023/images/.DS_Store new file mode 100644 index 0000000..c5c5c7d Binary files /dev/null and b/2023/images/.DS_Store differ diff --git a/2023/images/cl-OpenShift-container-platform-datasheet-f31593_image1.png b/2023/images/Day56-OpenShift-container-platform-datasheet.png similarity index 100% rename from 2023/images/cl-OpenShift-container-platform-datasheet-f31593_image1.png rename to 2023/images/Day56-OpenShift-container-platform-datasheet.png diff --git a/2023/images/Day57 - Red Hat OpenShift Architecture/Creating the bootstrap control plane and compute machines.png b/2023/images/Day57 - Red Hat OpenShift Architecture/Creating the bootstrap control plane and compute machines.png new file mode 100644 index 0000000..07d9ea6 Binary files /dev/null and b/2023/images/Day57 - Red Hat OpenShift Architecture/Creating the bootstrap control plane and compute machines.png differ diff --git a/2023/images/Day57 - Red Hat OpenShift Architecture/OpenShift Container Platform installation targets and dependencies.png b/2023/images/Day57 - Red Hat OpenShift Architecture/OpenShift Container Platform installation targets and dependencies.png new file mode 100644 index 0000000..91fa65d Binary files /dev/null and b/2023/images/Day57 - Red Hat OpenShift Architecture/OpenShift Container Platform installation targets and dependencies.png differ diff --git a/2023/images/Day57 - Red Hat OpenShift Architecture/OpenShift Container Platform lifecycle.png b/2023/images/Day57 - Red Hat OpenShift Architecture/OpenShift Container Platform lifecycle.png new file mode 100644 index 0000000..b6a7872 Binary files /dev/null and b/2023/images/Day57 - Red Hat OpenShift Architecture/OpenShift Container Platform lifecycle.png differ diff --git a/2023/images/Day57 - Red Hat OpenShift Architecture/Red Hat OpenShift - Product Architecture.png b/2023/images/Day57 - Red Hat OpenShift Architecture/Red Hat OpenShift - Product Architecture.png new file mode 100644 index 0000000..92af5f6 Binary files /dev/null and b/2023/images/Day57 - Red Hat OpenShift Architecture/Red Hat OpenShift - Product Architecture.png differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/OpenShift - Example DNS records.jpg b/2023/images/Day58 - OpenShift Cluster Install/OpenShift - Example DNS records.jpg new file mode 100644 index 0000000..0a38fc7 Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/OpenShift - Example DNS records.jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/OpenShift - Minimum resource requirements.jpg b/2023/images/Day58 - OpenShift Cluster Install/OpenShift - Minimum resource requirements.jpg new file mode 100644 index 0000000..47d038d Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/OpenShift - Minimum resource requirements.jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/OpenShift Clients Download.jpg b/2023/images/Day58 - OpenShift Cluster Install/OpenShift Clients Download.jpg new file mode 100644 index 0000000..16bfa1d Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/OpenShift Clients Download.jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/OpenShift-Install create cluster - .openshift_install.log output.jpg b/2023/images/Day58 - OpenShift Cluster Install/OpenShift-Install create cluster - .openshift_install.log output.jpg new file mode 100644 index 0000000..4f2ff5c Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/OpenShift-Install create cluster - .openshift_install.log output.jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/OpenShift-Install create cluster - Sorry, your reply was invalid- IP expected to be in one of the machine networks- 10.0.0.0-16.jpg b/2023/images/Day58 - OpenShift Cluster Install/OpenShift-Install create cluster - Sorry, your reply was invalid- IP expected to be in one of the machine networks- 10.0.0.0-16.jpg new file mode 100644 index 0000000..c1a950c Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/OpenShift-Install create cluster - Sorry, your reply was invalid- IP expected to be in one of the machine networks- 10.0.0.0-16.jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/OpenShift-Install create cluster - output.jpg b/2023/images/Day58 - OpenShift Cluster Install/OpenShift-Install create cluster - output.jpg new file mode 100644 index 0000000..aa60e74 Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/OpenShift-Install create cluster - output.jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/OpenShift-Install create cluster.jpg b/2023/images/Day58 - OpenShift Cluster Install/OpenShift-Install create cluster.jpg new file mode 100644 index 0000000..0fac3ce Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/OpenShift-Install create cluster.jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/OpenShift-Install create help.jpg b/2023/images/Day58 - OpenShift Cluster Install/OpenShift-Install create help.jpg new file mode 100644 index 0000000..9afcb2a Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/OpenShift-Install create help.jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/OpenShift-install - install-config.yaml file.jpg b/2023/images/Day58 - OpenShift Cluster Install/OpenShift-install - install-config.yaml file.jpg new file mode 100644 index 0000000..6e4dd78 Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/OpenShift-install - install-config.yaml file.jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/OpenShift-install create install-config.jpg b/2023/images/Day58 - OpenShift Cluster Install/OpenShift-install create install-config.jpg new file mode 100644 index 0000000..d7dfe1a Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/OpenShift-install create install-config.jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/Red Hat OpenShift - Web Console - Administrator Homepage.jpg b/2023/images/Day58 - OpenShift Cluster Install/Red Hat OpenShift - Web Console - Administrator Homepage.jpg new file mode 100644 index 0000000..3ba82d7 Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/Red Hat OpenShift - Web Console - Administrator Homepage.jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/Red Hat OpenShift - Web Console - Developer Homepage.jpg b/2023/images/Day58 - OpenShift Cluster Install/Red Hat OpenShift - Web Console - Developer Homepage.jpg new file mode 100644 index 0000000..55162d4 Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/Red Hat OpenShift - Web Console - Developer Homepage.jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/Red Hat OpenShift - Web Console - Developer Project.jpg b/2023/images/Day58 - OpenShift Cluster Install/Red Hat OpenShift - Web Console - Developer Project.jpg new file mode 100644 index 0000000..6036562 Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/Red Hat OpenShift - Web Console - Developer Project.jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/Red Hat OpenShift - Web Console - Developer Topology.jpg b/2023/images/Day58 - OpenShift Cluster Install/Red Hat OpenShift - Web Console - Developer Topology.jpg new file mode 100644 index 0000000..e9867d5 Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/Red Hat OpenShift - Web Console - Developer Topology.jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/Red Hat OpenShift Web Console.jpg b/2023/images/Day58 - OpenShift Cluster Install/Red Hat OpenShift Web Console.jpg new file mode 100644 index 0000000..4e58532 Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/Red Hat OpenShift Web Console.jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/kubectl get ns - oc get ns.jpg b/2023/images/Day58 - OpenShift Cluster Install/kubectl get ns - oc get ns.jpg new file mode 100644 index 0000000..dcfa731 Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/kubectl get ns - oc get ns.jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/kubectl get pods -A - oc get pods -A.jpg b/2023/images/Day58 - OpenShift Cluster Install/kubectl get pods -A - oc get pods -A.jpg new file mode 100644 index 0000000..f57b28c Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/kubectl get pods -A - oc get pods -A.jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/kubectl get pods -n openshift-apiserver - oc get pods -n openshift-apiserver .jpg b/2023/images/Day58 - OpenShift Cluster Install/kubectl get pods -n openshift-apiserver - oc get pods -n openshift-apiserver .jpg new file mode 100644 index 0000000..8b99a74 Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/kubectl get pods -n openshift-apiserver - oc get pods -n openshift-apiserver .jpg differ diff --git a/2023/images/Day58 - OpenShift Cluster Install/oc -help compared to kubectl -help.jpg b/2023/images/Day58 - OpenShift Cluster Install/oc -help compared to kubectl -help.jpg new file mode 100644 index 0000000..30186bc Binary files /dev/null and b/2023/images/Day58 - OpenShift Cluster Install/oc -help compared to kubectl -help.jpg differ diff --git a/2023/images/Day61 - Authentication - Role-Based Access Control and Auditing in Red Hat OpenShift/Red Hat OpenShift - Access Control - Relationship between cluster roles, local roles and role bindings.png b/2023/images/Day61 - Authentication - Role-Based Access Control and Auditing in Red Hat OpenShift/Red Hat OpenShift - Access Control - Relationship between cluster roles, local roles and role bindings.png new file mode 100644 index 0000000..63312ea Binary files /dev/null and b/2023/images/Day61 - Authentication - Role-Based Access Control and Auditing in Red Hat OpenShift/Red Hat OpenShift - Access Control - Relationship between cluster roles, local roles and role bindings.png differ diff --git a/2023/images/Day61 - Authentication - Role-Based Access Control and Auditing in Red Hat OpenShift/oc login.jpg b/2023/images/Day61 - Authentication - Role-Based Access Control and Auditing in Red Hat OpenShift/oc login.jpg new file mode 100644 index 0000000..43db9ee Binary files /dev/null and b/2023/images/Day61 - Authentication - Role-Based Access Control and Auditing in Red Hat OpenShift/oc login.jpg differ diff --git a/2023/images/Day62 - Red Hat Quay Container Security Operator/Red Hat Console - Image vulnerability.jpg b/2023/images/Day62 - Red Hat Quay Container Security Operator/Red Hat Console - Image vulnerability.jpg new file mode 100644 index 0000000..d37055b Binary files /dev/null and b/2023/images/Day62 - Red Hat Quay Container Security Operator/Red Hat Console - Image vulnerability.jpg differ diff --git a/2023/images/Day62 - Red Hat Quay Container Security Operator/Red Hat OpenShift Console - Administration - Image vulnerabilities - Manifest details - Affected pods.jpg b/2023/images/Day62 - Red Hat Quay Container Security Operator/Red Hat OpenShift Console - Administration - Image vulnerabilities - Manifest details - Affected pods.jpg new file mode 100644 index 0000000..f5f85af Binary files /dev/null and b/2023/images/Day62 - Red Hat Quay Container Security Operator/Red Hat OpenShift Console - Administration - Image vulnerabilities - Manifest details - Affected pods.jpg differ diff --git a/2023/images/Day62 - Red Hat Quay Container Security Operator/Red Hat OpenShift Console - Administration - Image vulnerabilities - Manifest details.jpg b/2023/images/Day62 - Red Hat Quay Container Security Operator/Red Hat OpenShift Console - Administration - Image vulnerabilities - Manifest details.jpg new file mode 100644 index 0000000..a7a4527 Binary files /dev/null and b/2023/images/Day62 - Red Hat Quay Container Security Operator/Red Hat OpenShift Console - Administration - Image vulnerabilities - Manifest details.jpg differ diff --git a/2023/images/Day62 - Red Hat Quay Container Security Operator/Red Hat OpenShift Console - Administration - Image vulnerabilities - Quay Manifest.jpg b/2023/images/Day62 - Red Hat Quay Container Security Operator/Red Hat OpenShift Console - Administration - Image vulnerabilities - Quay Manifest.jpg new file mode 100644 index 0000000..c59de13 Binary files /dev/null and b/2023/images/Day62 - Red Hat Quay Container Security Operator/Red Hat OpenShift Console - Administration - Image vulnerabilities - Quay Manifest.jpg differ diff --git a/2023/images/Day62 - Red Hat Quay Container Security Operator/Red Hat OpenShift Console - Administration - Image vulnerabilities.jpg b/2023/images/Day62 - Red Hat Quay Container Security Operator/Red Hat OpenShift Console - Administration - Image vulnerabilities.jpg new file mode 100644 index 0000000..87233f5 Binary files /dev/null and b/2023/images/Day62 - Red Hat Quay Container Security Operator/Red Hat OpenShift Console - Administration - Image vulnerabilities.jpg differ diff --git a/2023/images/Day77-1.png b/2023/images/Day77-1.png new file mode 100644 index 0000000..dd0f994 Binary files /dev/null and b/2023/images/Day77-1.png differ diff --git a/2023/images/Day80-1.png b/2023/images/Day80-1.png new file mode 100644 index 0000000..6f1748c Binary files /dev/null and b/2023/images/Day80-1.png differ diff --git a/2023/images/Day80-2.png b/2023/images/Day80-2.png new file mode 100644 index 0000000..5f68bfb Binary files /dev/null and b/2023/images/Day80-2.png differ diff --git a/2023/images/Day81-1.png b/2023/images/Day81-1.png new file mode 100644 index 0000000..daa7da3 Binary files /dev/null and b/2023/images/Day81-1.png differ diff --git a/2023/images/Day81-2.png b/2023/images/Day81-2.png new file mode 100644 index 0000000..addcde6 Binary files /dev/null and b/2023/images/Day81-2.png differ diff --git a/2023/images/Day81-3.png b/2023/images/Day81-3.png new file mode 100644 index 0000000..1bd4b62 Binary files /dev/null and b/2023/images/Day81-3.png differ diff --git a/2023/images/Day81-4.png b/2023/images/Day81-4.png new file mode 100644 index 0000000..7e85ee5 Binary files /dev/null and b/2023/images/Day81-4.png differ diff --git a/2023/images/Day81-5.png b/2023/images/Day81-5.png new file mode 100644 index 0000000..697580f Binary files /dev/null and b/2023/images/Day81-5.png differ diff --git a/2023/images/Day81-6.png b/2023/images/Day81-6.png new file mode 100644 index 0000000..c75fd34 Binary files /dev/null and b/2023/images/Day81-6.png differ diff --git a/2023/images/Day81-7.png b/2023/images/Day81-7.png new file mode 100644 index 0000000..f77481b Binary files /dev/null and b/2023/images/Day81-7.png differ diff --git a/2023/images/Day81-8.gif b/2023/images/Day81-8.gif new file mode 100644 index 0000000..40d1717 Binary files /dev/null and b/2023/images/Day81-8.gif differ diff --git a/2023/images/Day82-1.png b/2023/images/Day82-1.png new file mode 100644 index 0000000..e632db4 Binary files /dev/null and b/2023/images/Day82-1.png differ diff --git a/2023/images/Day82-2.png b/2023/images/Day82-2.png new file mode 100644 index 0000000..20c0020 Binary files /dev/null and b/2023/images/Day82-2.png differ diff --git a/2023/images/Day82-3.png b/2023/images/Day82-3.png new file mode 100644 index 0000000..c2b59c1 Binary files /dev/null and b/2023/images/Day82-3.png differ diff --git a/2023/images/day35-0.png b/2023/images/day35-0.png new file mode 100644 index 0000000..2fca794 Binary files /dev/null and b/2023/images/day35-0.png differ diff --git a/2023/images/day35-1.png b/2023/images/day35-1.png new file mode 100644 index 0000000..91fb644 Binary files /dev/null and b/2023/images/day35-1.png differ diff --git a/2023/images/day36-1.png b/2023/images/day36-1.png new file mode 100644 index 0000000..1943731 Binary files /dev/null and b/2023/images/day36-1.png differ diff --git a/2023/images/day36-2.png b/2023/images/day36-2.png new file mode 100644 index 0000000..8a1815d Binary files /dev/null and b/2023/images/day36-2.png differ diff --git a/2023/images/day37-1.png b/2023/images/day37-1.png new file mode 100644 index 0000000..4754ef1 Binary files /dev/null and b/2023/images/day37-1.png differ diff --git a/2023/images/day37-2.png b/2023/images/day37-2.png new file mode 100644 index 0000000..9f378b0 Binary files /dev/null and b/2023/images/day37-2.png differ diff --git a/2023/images/day37-3.png b/2023/images/day37-3.png new file mode 100644 index 0000000..166559d Binary files /dev/null and b/2023/images/day37-3.png differ diff --git a/2023/images/day37-4.png b/2023/images/day37-4.png new file mode 100644 index 0000000..bff5402 Binary files /dev/null and b/2023/images/day37-4.png differ diff --git a/2023/images/day37-5.png b/2023/images/day37-5.png new file mode 100644 index 0000000..106e1df Binary files /dev/null and b/2023/images/day37-5.png differ diff --git a/2023/images/day37-6.png b/2023/images/day37-6.png new file mode 100644 index 0000000..5d4df83 Binary files /dev/null and b/2023/images/day37-6.png differ diff --git a/2023/images/day37-7.png b/2023/images/day37-7.png new file mode 100644 index 0000000..49481e4 Binary files /dev/null and b/2023/images/day37-7.png differ diff --git a/2023/images/day52-1.png b/2023/images/day52-1.png new file mode 100644 index 0000000..c84da87 Binary files /dev/null and b/2023/images/day52-1.png differ diff --git a/2023/images/day52-2.png b/2023/images/day52-2.png new file mode 100644 index 0000000..252f94a Binary files /dev/null and b/2023/images/day52-2.png differ diff --git a/2023/images/day53-01.png b/2023/images/day53-01.png new file mode 100644 index 0000000..2ed9e2d Binary files /dev/null and b/2023/images/day53-01.png differ diff --git a/2023/images/day53-02.png b/2023/images/day53-02.png new file mode 100644 index 0000000..83efc10 Binary files /dev/null and b/2023/images/day53-02.png differ diff --git a/2023/images/day53-03.png b/2023/images/day53-03.png new file mode 100644 index 0000000..0252010 Binary files /dev/null and b/2023/images/day53-03.png differ diff --git a/2023/images/day53-04.png b/2023/images/day53-04.png new file mode 100644 index 0000000..675ddae Binary files /dev/null and b/2023/images/day53-04.png differ diff --git a/2023/images/day53-05.png b/2023/images/day53-05.png new file mode 100644 index 0000000..52605ed Binary files /dev/null and b/2023/images/day53-05.png differ diff --git a/2023/images/day54-01.png b/2023/images/day54-01.png new file mode 100644 index 0000000..939ebab Binary files /dev/null and b/2023/images/day54-01.png differ diff --git a/2023/images/day55-01.jpg b/2023/images/day55-01.jpg new file mode 100644 index 0000000..7eac233 Binary files /dev/null and b/2023/images/day55-01.jpg differ diff --git a/2023/images/day59-Red Hat OpenShift - oc get scc.jpg b/2023/images/day59-Red Hat OpenShift - oc get scc.jpg new file mode 100644 index 0000000..dff1e25 Binary files /dev/null and b/2023/images/day59-Red Hat OpenShift - oc get scc.jpg differ diff --git a/2023/images/day71-1.jpg b/2023/images/day71-1.jpg new file mode 100644 index 0000000..4b333be Binary files /dev/null and b/2023/images/day71-1.jpg differ diff --git a/2023/images/day71-2.jpg b/2023/images/day71-2.jpg new file mode 100644 index 0000000..dbf467e Binary files /dev/null and b/2023/images/day71-2.jpg differ diff --git a/2023/images/day71-3.jpg b/2023/images/day71-3.jpg new file mode 100644 index 0000000..077d13e Binary files /dev/null and b/2023/images/day71-3.jpg differ diff --git a/2023/images/day72-1.jpg b/2023/images/day72-1.jpg new file mode 100644 index 0000000..69d4cc1 Binary files /dev/null and b/2023/images/day72-1.jpg differ diff --git a/2023/images/day72-2.jpg b/2023/images/day72-2.jpg new file mode 100644 index 0000000..29fd492 Binary files /dev/null and b/2023/images/day72-2.jpg differ diff --git a/2023/images/day72-3.jpg b/2023/images/day72-3.jpg new file mode 100644 index 0000000..a4ba419 Binary files /dev/null and b/2023/images/day72-3.jpg differ diff --git a/2023/images/day72-4.jpg b/2023/images/day72-4.jpg new file mode 100644 index 0000000..86c9cf7 Binary files /dev/null and b/2023/images/day72-4.jpg differ diff --git a/2023/images/day73-1.jpg b/2023/images/day73-1.jpg new file mode 100644 index 0000000..72b5306 Binary files /dev/null and b/2023/images/day73-1.jpg differ diff --git a/2023/images/day73-2.jpg b/2023/images/day73-2.jpg new file mode 100644 index 0000000..2d8d430 Binary files /dev/null and b/2023/images/day73-2.jpg differ diff --git a/2023/images/day73-3.jpg b/2023/images/day73-3.jpg new file mode 100644 index 0000000..d0838be Binary files /dev/null and b/2023/images/day73-3.jpg differ diff --git a/2023/images/day74-1.jpg b/2023/images/day74-1.jpg new file mode 100644 index 0000000..5c32c06 Binary files /dev/null and b/2023/images/day74-1.jpg differ diff --git a/2023/images/day74-2.jpg b/2023/images/day74-2.jpg new file mode 100644 index 0000000..3e55b42 Binary files /dev/null and b/2023/images/day74-2.jpg differ diff --git a/2023/images/day74-3.jpg b/2023/images/day74-3.jpg new file mode 100644 index 0000000..87555fa Binary files /dev/null and b/2023/images/day74-3.jpg differ diff --git a/2023/images/day74-4.jpg b/2023/images/day74-4.jpg new file mode 100644 index 0000000..c714bc1 Binary files /dev/null and b/2023/images/day74-4.jpg differ diff --git a/2023/images/day74-5.jpg b/2023/images/day74-5.jpg new file mode 100644 index 0000000..2eff3c0 Binary files /dev/null and b/2023/images/day74-5.jpg differ diff --git a/2023/images/day74-6.jpg b/2023/images/day74-6.jpg new file mode 100644 index 0000000..440a440 Binary files /dev/null and b/2023/images/day74-6.jpg differ diff --git a/2023/images/day74-7.jpg b/2023/images/day74-7.jpg new file mode 100644 index 0000000..7049825 Binary files /dev/null and b/2023/images/day74-7.jpg differ diff --git a/2023/images/day75-1.jpg b/2023/images/day75-1.jpg new file mode 100644 index 0000000..9e933ad Binary files /dev/null and b/2023/images/day75-1.jpg differ diff --git a/2023/images/day75-2.jpg b/2023/images/day75-2.jpg new file mode 100644 index 0000000..8a42401 Binary files /dev/null and b/2023/images/day75-2.jpg differ diff --git a/2023/images/day75-3.jpg b/2023/images/day75-3.jpg new file mode 100644 index 0000000..f8d9b89 Binary files /dev/null and b/2023/images/day75-3.jpg differ diff --git a/2023/images/day75-4.jpg b/2023/images/day75-4.jpg new file mode 100644 index 0000000..f91c32b Binary files /dev/null and b/2023/images/day75-4.jpg differ diff --git a/2023/images/day75-5.jpg b/2023/images/day75-5.jpg new file mode 100644 index 0000000..46cdb14 Binary files /dev/null and b/2023/images/day75-5.jpg differ diff --git a/2023/images/day75-6.jpg b/2023/images/day75-6.jpg new file mode 100644 index 0000000..4c31b98 Binary files /dev/null and b/2023/images/day75-6.jpg differ diff --git a/2023/images/day75-7.jpg b/2023/images/day75-7.jpg new file mode 100644 index 0000000..a2fae80 Binary files /dev/null and b/2023/images/day75-7.jpg differ diff --git a/2023/images/day75-8.jpg b/2023/images/day75-8.jpg new file mode 100644 index 0000000..fb098e3 Binary files /dev/null and b/2023/images/day75-8.jpg differ diff --git a/2023/images/day76-1.jpg b/2023/images/day76-1.jpg new file mode 100644 index 0000000..0e9311a Binary files /dev/null and b/2023/images/day76-1.jpg differ diff --git a/2023/images/day76-2.jpg b/2023/images/day76-2.jpg new file mode 100644 index 0000000..e9e55d8 Binary files /dev/null and b/2023/images/day76-2.jpg differ diff --git a/2023/images/day84-queues.png b/2023/images/day84-queues.png new file mode 100644 index 0000000..3ba5e3f Binary files /dev/null and b/2023/images/day84-queues.png differ diff --git a/README.md b/README.md index c9e4bc4..115bd65 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ 90DaysOfDevOps Logo

-[![Website](https://img.shields.io/website?url=https%3A%2F%2Fwww.90daysofdevops.com)](https://www.90daysofdevops.com) [![GitHub Repo stars](https://img.shields.io/github/stars/MichaelCade/90DaysOfDevOps)](https://github.com/MichaelCade/90DaysOfDevOps) + [![Website](https://img.shields.io/website?url=https%3A%2F%2Fwww.90daysofdevops.com)](https://www.90daysofdevops.com) [![GitHub Repo stars](https://img.shields.io/github/stars/MichaelCade/90DaysOfDevOps)](https://github.com/MichaelCade/90DaysOfDevOps) [![GitHub Repo stars](https://img.shields.io/github/forks/MichaelCade/90DaysOfDevOps)](https://github.com/MichaelCade/90DaysOfDevOps) [![GitHub Repo issues](https://img.shields.io/github/issues/MichaelCade/90DaysOfDevOps)](https://github.com/MichaelCade/90DaysOfDevOps) This repository is used to document my journey on getting a better foundational knowledge of "DevOps". I will be starting this journey on the 1st January 2022 but the idea is that we take 90 days which just so happens to be January 1st to March 31st.