One place for hosting & domains

      Deploy

      How to Deploy to Kubernetes using Argo CD and GitOps


      Introduction

      Using Kubernetes to deploy your application can provide significant infrastructural advantages, such as flexible scaling, management of distributed components, and control over different versions of your application. However, with that increased control comes increased complexity. Continuous Integration and Continuous Deployment (CI/CD) systems usually work at a high level of abstraction in order to provide version control, change logging, and rollback functionality. A popular approach to this abstraction layer is called GitOps.

      GitOps, as originally proposed by Weaveworks in a 2017 blog post, uses Git as a “single source of truth” for CI/CD processes, integrating code changes in a single, shared repository per project and using pull requests to manage infrastructure and deployment.

      There are several tools that use Git as a focal point for DevOps processes on Kubernetes. In this tutorial, you will learn to use Argo CD, a declarative Continuous Delivery tool. Argo CD provides Continuous Delivery tooling that automatically synchronizes and deploys your application whenever a change is made in your GitHub repository. By managing the deployment and lifecycle of an application, it provides solutions for version control, configurations, and application definitions in Kubernetes environments, organizing complex data with an easy-to-understand user interface. It can handle several types of Kubernetes manifests, including Jsonnet, Kustomize applications, Helm charts, and YAML/json files, and supports webhook notifications from GitHub, GitLab, and Bitbucket.

      In this article, you will use Argo CD to synchronize and deploy an application from a GitHub repository.

      Prerequisites

      To follow this tutorial, you will need:

      Step 1 — Installing Argo CD on Your Cluster

      In order to install Argo CD, you should first have a valid Kubernetes configuration set up with kubectl, from which you can ping your worker nodes. You can test this by running kubectl get nodes:

      This command should return a list of nodes with the Ready status:

      Output

      NAME STATUS ROLES AGE VERSION pool-uqv8a47h0-ul5a7 Ready <none> 22m v1.21.5 pool-uqv8a47h0-ul5am Ready <none> 21m v1.21.5 pool-uqv8a47h0-ul5aq Ready <none> 21m v1.21.5

      If kubectl does not return a set of nodes with the Ready status, you should review your cluster configuration and the Kubernetes documentation.

      Next, create the argocd namespace in your cluster, which will contain Argo CD and its associated services:

      • kubectl create namespace argocd

      After that, you can run the Argo CD install script provided by the project maintainers.

      • kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

      Once the installation completes successfully, you can use the watch command to check the status of your Kubernetes pods:

      • watch kubectl get pods -n argocd

      By default, there should be five pods that eventually receive the Running status as part of a stock Argo CD installation.

      Output

      NAME READY STATUS RESTARTS AGE argocd-application-controller-0 1/1 Running 0 2m28s argocd-dex-server-66f865ffb4-chwwg 1/1 Running 0 2m30s argocd-redis-5b6967fdfc-q4klp 1/1 Running 0 2m30s argocd-repo-server-656c76778f-vsn7l 1/1 Running 0 2m29s argocd-server-cd68f46f8-zg7hq 1/1 Running 0 2m28s

      You can press Ctrl+C to exit the watch interface. You now have Argo CD running in your Kubernetes cluster! However, because of the way Kubernetes creates abstractions around your network interfaces, you won’t be able to access it directly without forwarding ports from inside your cluster. You’ll learn how to handle that in the next step.

      Step 2 — Forwarding Ports to Access Argo CD

      Because Kubernetes deploys services to arbitrary network addresses inside your cluster, you’ll need to forward the relevant ports in order to access them from your local machine. Argo CD sets up a service named argocd-server on port 443 internally. Because port 443 is the default HTTPS port, and you may be running some other HTTP/HTTPS services, it’s common practice to forward those to arbitrarily chosen other ports, like 8080, like so:

      • kubectl port-forward svc/argocd-server -n argocd 8080:443

      Port forwarding will block the terminal it’s running in as long as it’s active, so you’ll probably want to run this in a new terminal window while you continue to work. You can press Ctrl+C to gracefully quit a blocking process such as this one when you want to stop forwarding the port.

      In the meantime, you should be able to access Argo CD in a web browser by navigating to localhost:8080. However, you’ll be prompted for a login password which you’ll need to use the command line to retrieve in the next step. You’ll probably need to click through a security warning because Argo CD has not yet been configured with a valid SSL certificate.

      Note: Using LetsEncrypt HTTPS certificates with Kubernetes is best accomplished with the use of additional tooling like Cert-Manager.

      Step 3 — Working with Argo CD from the Command Line

      For the next steps, you’ll want to have the argocd command installed locally for interfacing with and changing settings in your Argo CD instance. Argo CD’s official documentation recommends that you install it via the Homebrew package manager. Homebrew is very popular for managing command line tools on MacOS, and has more recently been ported to Linux to facilitate maintaining tools like this one.

      If you don’t already have Homebrew installed, you can retrieve and install it with a one-line command:

      • ​​/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

      You may be prompted for your password during the installation process. Afterward, you should have the brew command available in your terminal. You can use it to install Argo CD:

      This in turn provides the argocd command. Before using it, you’ll want to use kubectl again to retrieve the admin password which was automatically generated during your installation, so that you can use it to log in. You’ll pass it a path to a particular JSON file that’s stored using Kubernetes secrets, and extract the relevant value:

      • kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo

      Output

      fbP20pvw-o-D5uxH

      You can then log into your Argo CD dashboard by going back to localhost:8080 in a browser and logging in as the admin user with your own password:

      Argo CD app status

      Once everything is working, you can use the same credentials to log in to Argo CD via the command line, by running argocd login. This will be necessary for deploying from the command line later on:

      • argocd login localhost:8080

      You’ll receive the equivalent certificate warning again on the command line here, and should enter y to proceed when prompted. If desired, you can then change your password to something more secure or more memorable by running argocd account update-password. After that, you’ll have a fully working Argo CD configuration. In the final steps of this tutorial, you’ll learn how to use it to actually deploy some example applications.

      Step 4 — Handling Multiple Clusters (Optional)

      Before deploying an application, you should review where you actually want to deploy it. By default, Argo CD will deploy applications to the same cluster that Argo CD itself is running in, which is fine for a demo, but is probably not what you’ll want in production. In order to list all of the clusters known to your current machine, you can use kubectl config:

      • kubectl config get-contexts -o name

      Output

      test-deploy-cluster test-target-cluster

      Assuming that you’ve installed Argo CD into test-deploy-cluster, and you wanted to use it to deploy applications onto test-target-cluster, you could register test-target-cluster with Argo CD by running argocd cluster add:

      • argocd cluster add target-k8s

      This will add the additional cluster’s login details to Argo CD, and enable Argo CD to deploy services on the cluster.

      Step 5 — Deploying an Example Application (Optional)

      Now that you have Argo CD running and you have an understanding of how to deploy applications to different Kubernetes clusters, it’s time to put it into practice. The Argo CD project maintains a repository of example applications that have been architected to showcase GitOps fundamentals. Many of these examples are ports of the same guestbook demo app to different kinds of Kubernetes manifests, such as Jsonnet. In this case, you’ll be deploying the helm-guestbook example, which uses a Helm chart, one of the most durable Kubernetes management solutions.

      In order to do that, you’ll use the argocd app create command, providing the path to the Git repository, the specific helm-guestbook example, and passing your default destination and namespace:

      • argocd app create helm-guestbook --repo https://github.com/argoproj/argocd-example-apps.git --path helm-guestbook --dest-server https://kubernetes.default.svc --dest-namespace default

      After “creating” the application inside of Argo CD, you can check its status with argocd app get:

      • argocd app get helm-guestbook

      Output

      Name: helm-guestbook Project: default Server: https://kubernetes.default.svc Namespace: default URL: https://localhost:8080/applications/helm-guestbook Repo: https://github.com/argoproj/argocd-example-apps.git Target: Path: helm-guestbook SyncWindow: Sync Allowed Sync Policy: <none> Sync Status: OutOfSync from (53e28ff) Health Status: Missing GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE Service default helm-guestbook OutOfSync Missing apps Deployment default helm-guestbook OutOfSync Missing

      The OutOfSync application status is normal. You’ve retrieved the application’s helm chart from Github and created an entry for it in Argo CD, but you haven’t actually spun up any Kubernetes resources for it yet. In order to actually deploy the application you’ll run argocd app sync:

      • argocd app sync helm-guestbook

      sync is synonymous with deployment here in keeping with the principles of GitOps – the goal when using Argo CD is for your application to always track 1:1 with its upstream configuration.

      Output

      TIMESTAMP GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE 2022-01-19T11:01:48-08:00 Service default helm-guestbook OutOfSync Missing 2022-01-19T11:01:48-08:00 apps Deployment default helm-guestbook OutOfSync Missing 2022-01-19T11:01:48-08:00 Service default helm-guestbook Synced Healthy 2022-01-19T11:01:48-08:00 Service default helm-guestbook Synced Healthy service/helm-guestbook created 2022-01-19T11:01:48-08:00 apps Deployment default helm-guestbook OutOfSync Missing deployment.apps/helm-guestbook created 2022-01-19T11:01:49-08:00 apps Deployment default helm-guestbook Synced Progressing deployment.apps/helm-guestbook created Name: helm-guestbook Project: default Server: https://kubernetes.default.svc Namespace: default URL: https://localhost:8080/applications/helm-guestbook Repo: https://github.com/argoproj/argocd-example-apps.git Target: Path: helm-guestbook SyncWindow: Sync Allowed Sync Policy: <none> Sync Status: Synced to (53e28ff) Health Status: Progressing Operation: Sync Sync Revision: 53e28ff20cc530b9ada2173fbbd64d48338583ba Phase: Succeeded Start: 2022-01-19 11:01:49 -0800 PST Finished: 2022-01-19 11:01:50 -0800 PST Duration: 1s Message: successfully synced (all tasks run) GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE Service default helm-guestbook Synced Healthy service/helm-guestbook created apps Deployment default helm-guestbook Synced Progressing deployment.apps/helm-guestbook created

      You have now successfully deployed an application using Argo CD! It is possible to accomplish the same thing from the Argo CD web interface, but it is usually quicker and more reproducible to deploy via the command line. However, it is very helpful to check on your Argo CD web dashboard after deployment in order to verify that your applications are running properly. You can see that by opening localhost:8080 in a browser:

      Argo CD app status

      At this point, the last thing to do is to ensure you can access your new deployment in a browser. To do that, you’ll forward another port, the way you did for Argo CD itself. Internally, the helm-guestbook app runs on the regular HTTP port 80, and in order to avoid conflicting with anything that might be running on your own port 80 or on the port 8080 you’re using for Argo CD, you can forward it to port 9090:

      • kubectl port-forward svc/helm-guestbook 9090:80

      As before, you’ll probably want to do this in another terminal, because it will block that terminal until you press Ctrl+C to stop forwarding the port. You can then open localhost:9090 in a browser window to see your example guestbook app:

      Guestbook app

      Any further pushes to this Github repository will automatically be reflected in ArgoCD, which will resync your deployment while providing continuous availability.

      Conclusion

      You’ve now seen the fundamentals of installing and deploying applications using Argo CD. Because Kubernetes requires so many layers of abstraction, it’s important to ensure that your deployments are as maintainable as possible, and the GitOps philosophy is a good solution.

      Next, you may want to learn about deploying TOBS, The Observability Stack, for monitoring the uptime, health, and logging of your Kubernetes cluster.



      Source link

      How To Build and Deploy a Flask Application Using Docker on Ubuntu 20.04


      The author selected the Tech Education Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      Docker is an open-source application that allows administrators to create, manage, deploy, and replicate applications using containers. Containers can be thought of as a package that houses dependencies that an application requires to run at an operating system level. This means that each application deployed using Docker lives in an environment of its own and its requirements are handled separately.

      Flask is a web micro-framework that is built on Python. It is called a micro-framework because it does not require specific tools or plug-ins to run. The Flask framework is lightweight and flexible, yet highly structured, making it especially popular for small web apps written in Python.

      Deploying a Flask application with Docker will allow you to replicate the application across different servers with minimal reconfiguration.

      In this tutorial, you will create a Flask application and deploy it with Docker. This tutorial will also cover how to update an application after deployment.

      Prerequisites

      To follow this tutorial, you will need the following:

      Step 1 — Setting Up the Flask Application

      To get started, you will create a directory structure that will hold your Flask application. This tutorial will create a directory called TestApp in /var/www, but you can modify the command to name it whatever you’d like.

      • sudo mkdir /var/www/TestApp

      Move in to the newly created TestApp directory:

      Next, create the base folder structure for the Flask application:

      • sudo mkdir -p app/static app/templates

      The -p flag indicates that mkdir will create a directory and all parent directories that don’t exist. In this case, mkdir will create the app parent directory in the process of making the static and templates directories.

      The app directory will contain all files related to the Flask application such as its views and blueprints. Views are the code you write to respond to requests to your application. Blueprints create application components and support common patterns within an application or across multiple applications.

      The static directory is where assets such as images, CSS, and JavaScript files live. The templates directory is where you will put the HTML templates for your project.

      Now that the base folder structure is complete, you need to create the files needed to run the Flask application. First, create an __init__.py file inside the app directory using nano or a text editor of your choice. This file tells the Python interpreter that the app directory is a package and should be treated as such.

      Run the following command to create the file:

      • sudo nano app/__init__.py

      Packages in Python allow you to group modules into logical namespaces or hierarchies. This approach enables the code to be broken down into individual and manageable blocks that perform specific functions.

      Next, you will add code to the __init__.py that will create a Flask instance and import the logic from the views.py file, which you will create after saving this file. Add the following code to your new file:

      /var/www/TestApp/app/__init__.py

      from flask import Flask
      app = Flask(__name__)
      from app import views
      

      Once you’ve added that code, save and close the file. You can save and close the file by pressing Ctrl+X, then when prompted, Y and Enter.

      With the __init__.py file created, you’re ready to create the views.py file in your app directory. This file will contain most of your application logic.

      Next, add the code to your views.py file. This code will return the hello world! string to users who visit your web page:

      /var/www/TestApp/app/views.py

      from app import app
      
      @app.route('/')
      def home():
         return "hello world!"
      

      The @app.route line above the function is called a decorator. Decorators are a Python language convention that are widely used by Flask; their purpose is to modify the functions immediately following them. In this case, the decorator tells Flask which URL will trigger the home() function. The hello world text returned by the home function will be displayed to the user on the browser.

      With the views.py file in place, you’re ready to create the uwsgi.ini file. This file will contain the uWSGI configurations for our application. uWSGI is a deployment option for Nginx that is both a protocol and an application server; the application server can serve uWSGI, FastCGI, and HTTP protocols.

      To create this file, run the following command:

      Next, add the following content to your file to configure the uWSGI server:

      /var/www/TestApp/uwsgi.ini

      [uwsgi]
      module = main
      callable = app
      master = true
      

      This code defines the module that the Flask application will be served from. In this case, this is the main.py file, referenced here as main. The callable option instructs uWSGI to use the app instance exported by the main application. The master option allows your application to keep running, so there is little downtime even when reloading the entire application.

      Next, create the main.py file, which is the entry point to the application. The entry point instructs uWSGI on how to interact with the application.

      Next, copy and paste the following into the file. This imports the Flask instance named app from the application package that was previously created.

      /var/www/TestApp/main.py

      from app import app
      

      Finally, create a requirements.txt file to specify the dependencies that the pip package manager will install to your Docker deployment:

      • sudo nano requirements.txt

      Add the following line to add Flask as a dependency:

      /var/www/TestApp/requirements.txt

      Flask>=2.0.2
      

      This specifies the version of Flask to be installed. At the time of writing this tutorial, 2.0.2 is the latest Flask version, and specifying >=2.0.2 will ensure you get version 2.0.2 or newer. Because you’re making a basic test app in this tutorial, the syntax is unlikely to go out of date due to future updates to Flask, but if you wanted to be safe and still receive minor updates, you could specify that you don’t want to install a future major version by specifying something like Flask>=2.0.2,<3.0. You can check for updates at the official website for Flask, or on the Python Package Index’s landing page for the Flask library.

      Save and close the file. You have successfully set up your Flask application and are ready to set up Docker.

      Step 2 — Setting Up Docker

      In this step you will create two files, Dockerfile and start.sh, to create your Docker deployment. The Dockerfile is a text document that contains the commands used to assemble the image. The start.sh file is a shell script that will build an image and create a container from the Dockerfile.

      First, create the Dockerfile.

      Next, add your desired configuration to the Dockerfile. These commands specify how the image will be built, and what extra requirements will be included.

      /var/www/TestApp/Dockerfile

      FROM tiangolo/uwsgi-nginx-flask:python3.8-alpine
      RUN apk --update add bash nano
      ENV STATIC_URL /static
      ENV STATIC_PATH /var/www/app/static
      COPY ./requirements.txt /var/www/requirements.txt
      RUN pip install -r /var/www/requirements.txt
      

      In this example, the Docker image will be built off an existing image, tiangolo/uwsgi-nginx-flask, which you can find on DockerHub. This particular Docker image is a good choice over others because it supports a wide range of Python versions and OS images.

      The first two lines specify the parent image that you’ll use to run the application and install the bash command processor and the nano text editor. It also installs the git client for pulling and pushing to version control hosting services such as GitHub, GitLab, and Bitbucket. ENV STATIC_URL /static is an environment variable specific to this Docker image. It defines the static folder where all assets such as images, CSS files, and JavaScript files are served from.

      The last two lines will copy the requirements.txt file into the container so that it can be executed, and then parses the requirements.txt file to install the specified dependencies.

      Save and close the file after adding your configuration.

      With your Dockerfile in place, you’re almost ready to write your start.sh script that will build the Docker container. Before writing the start.sh script, first make sure that you have an open port to use in the configuration. To check if a port is free, run the following command:

      • sudo nc localhost 56733 < /dev/null; echo $?

      If the output of the command above is 1, then the port is free and usable. Otherwise, you will need to select a different port to use in your start.sh configuration file.

      Once you’ve found an open port to use, create the start.sh script:

      The start.sh script is a shell script that will build an image from the Dockerfile and create a container from the resulting Docker image. Add your configuration to the new file:

      /var/www/TestApp/start.sh

      #!/bin/bash
      app="docker.test"
      docker build -t ${app} .
      docker run -d -p 56733:80 
        --name=${app} 
        -v $PWD:/app ${app}
      

      The first line is called a shebang. It specifies that this is a bash file and will be executed as commands. The next line specifies the name you want to give the image and container and saves as a variable named app. The next line instructs Docker to build an image from your Dockerfile located in the current directory. This will create an image called docker.test in this example.

      The last three lines create a new container named docker.test that is exposed at port 56733. Finally, it links the present directory to the /var/www directory of the container.

      You use the -d flag to start a container in daemon mode, or as a background process. You include the -p flag to bind a port on the server to a particular port on the Docker container. In this case, you are binding port 56733 to port 80 on the Docker container. The -v flag specifies a Docker volume to mount on the container, and in this case, you are mounting the entire project directory to the /var/www folder on the Docker container.

      Save and close the file after adding your configuration.

      Execute the start.sh script to create the Docker image and build a container from the resulting image:

      Once the script finishes running, use the following command to list all running containers:

      You will receive output that shows the containers:

      Output

      CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 58b05508f4dd docker.test "/entrypoint.sh /sta…" 12 seconds ago Up 3 seconds 443/tcp, 0.0.0.0:56733->80/tcp docker.test

      You will find that the docker.test container is running. Now that it is running, visit the IP address at the specified port in your browser: http://ip-address:56733

      You’ll see a page similar to the following:

      the home page

      In this step you have successfully deployed your Flask application on Docker. Next, you will use templates to display content to users.

      Step 3 — Serving Template Files

      Templates are files that display static and dynamic content to users who visit your application. In this step, you will create a HTML template to create a homepage for the application.

      Start by creating a home.html file in the app/templates directory:

      • sudo nano app/templates/home.html

      Add the code for your template. This code will create an HTML5 page that contains a title and some text.

      /var/www/TestApp/app/templates/home.html

      
      <!doctype html>
      
      <html lang="en-us">   
        <head>
          <meta charset="utf-8">
          <meta http-equiv="x-ua-compatible" content="ie=edge">
          <title>Welcome home</title>
        </head>
      
        <body>
          <h1>Home Page</h1>
          <p>This is the home page of our application.</p>
        </body> 
      </html>
      

      Save and close the file once you’ve added your template.

      Next, modify the app/views.py file to serve the newly created file:

      First, add the following line at the beginning of your file to import the render_template method from Flask. This method parses an HTML file to render a web page to the user.

      /var/www/TestApp/app/views.py

      from flask import render_template
      ...
      

      At the end of the file, you will also add a new route to render the template file. This code specifies that users are served the contents of the home.html file whenever they visit the /template route on your application.

      /var/www/TestApp/app/views.py

      ...
      
      @app.route('/template')
      def template():
          return render_template('home.html')
      

      The updated app/views.py file will look like this:

      /var/www/TestApp/app/views.py

      from flask import render_template
      from app import app 
      
      @app.route('/')
      def home():
          return "Hello world!"
      
      @app.route('/template')
      def template():
          return render_template('home.html')
      

      Save and close the file when done.

      In order for these changes to take effect, you will need to stop and restart the Docker containers. Run the following command to rebuild the container:

      • sudo docker stop docker.test && sudo docker start docker.test

      Visit your application at http://your-ip-address:56733/template to see the new template being served.

      homepage

      In this you’ve created a Docker template file to serve visitors on your application. In the next step you will see how the changes you make to your application can take effect without having to restart the Docker container.

      Step 4 — Updating the Application

      Sometimes you will need to make changes to the application, whether it is installing new requirements, updating the Docker container, or HTML and logic changes. In this section, you will configure touch-reload to make these changes without needing to restart the Docker container.

      Python autoreloading watches the entire file system for changes and refreshes the application when it detects a change. Autoreloading is discouraged in production because it can become resource intensive very quickly. In this step, you will use touch-reload to watch for changes to a particular file and reload when the file is updated or replaced.

      To implement this, start by opening your uwsgi.ini file:

      Next, add the highlighted line to the end of the file:

      /var/www/TestApp/uwsgi.ini

      module = main
      callable = app
      master = true
      touch-reload = /app/uwsgi.ini
      

      This specifies a file that will be modified to trigger an entire application reload. Once you’ve made the changes, save and close the file.

      To demonstrate this, make a small change to your application. Start by opening your app/views.py file:

      Replace the string returned by the home function:

      /var/www/TestApp/app/views.py

      from flask import render_template
      from app import app
      
      @app.route('/')
      def home():
          return "<b>There has been a change</b>"
      
      @app.route('/template')
      def template():
          return render_template('home.html')
      

      Save and close the file after you’ve made a change.

      Next, if you open your application’s homepage at http://ip-address:56733, you will notice that the changes are not reflected. This is because the condition for reload is a change to the uwsgi.ini file. To reload the application, use touch to activate the condition:

      Reload the application homepage in your browser again. You will find that the application has incorporated the changes:

      Homepage Updated

      In this step, you set up a touch-reload condition to update your application after making changes.

      Conclusion

      In this tutorial, you created and deployed a Flask application to a Docker container. You also configured touch-reload to refresh your application without needing to restart the container.

      With your new application on Docker, you can now scale with ease. To learn more about using Docker, check out their official documentation.



      Source link

      Opening Keynote With DigitalOcean CEO Yancey Spruill | deploy: The Americas


      Video

      About the Talk

      DigitalOcean CEO Yancey Spruill shares insights on how developers and businesses can simplify cloud computing and spend more time creating software that changes the world.

      Co-Presenters from DigitalOcean

      Jake Levirne, Senior Director of Product Management
      Admas Kanyagia, VP of Social Impact

      Customer highlights

      Tim Osborne, CTO, Atom Learning
      Andres Paglayan, Co-Founder, EMR-Bear



      Source link