One place for hosting & domains

      Kubeadm

      How To Create a Kubernetes 1.11 Cluster Using Kubeadm on Ubuntu 18.04


      The author selected the Free and Open Source Fund to receive a donation as part of the Write for DOnations program.

      Introduction

      Kubernetes is a container orchestration system that manages containers at scale. Initially developed by Google based on its experience running containers in production, Kubernetes is open source and actively developed by a community around the world.

      Kubeadm automates the installation and configuration of Kubernetes components such as the API server, Controller Manager, and Kube DNS. It does not, however, create users or handle the installation of operating-system-level dependencies and their configuration. For these preliminary tasks, it is possible to use a configuration management tool like Ansible or SaltStack. Using these tools makes creating additional clusters or recreating existing clusters much simpler and less error prone.

      In this guide, you will set up a Kubernetes cluster from scratch using Ansible and Kubeadm, and then deploy a containerized Nginx application to it.

      Goals

      Your cluster will include the following physical resources:

      The master node (a node in Kubernetes refers to a server) is responsible for managing the state of the cluster. It runs Etcd, which stores cluster data among components that schedule workloads to worker nodes.

      Worker nodes are the servers where your workloads (i.e. containerized applications and services) will run. A worker will continue to run your workload once they’re assigned to it, even if the master goes down once scheduling is complete. A cluster’s capacity can be increased by adding workers.

      After completing this guide, you will have a cluster ready to run containerized applications, provided that the servers in the cluster have sufficient CPU and RAM resources for your applications to consume. Almost any traditional Unix application including web applications, databases, daemons, and command line tools can be containerized and made to run on the cluster. The cluster itself will consume around 300-500MB of memory and 10% of CPU on each node.

      Once the cluster is set up, you will deploy the web server Nginx to it to ensure that it is running workloads correctly.

      Prerequisites

      Step 1 — Setting Up the Workspace Directory and Ansible Inventory File

      In this section, you will create a directory on your local machine that will serve as your workspace. You will configure Ansible locally so that it can communicate with and execute commands on your remote servers. Once that’s done, you will create a hosts file containing inventory information such as the IP addresses of your servers and the groups that each server belongs to.

      Out of your three servers, one will be the master with an IP displayed as master_ip. The other two servers will be workers and will have the IPs worker_1_ip and worker_2_ip.

      Create a directory named ~/kube-cluster in the home directory of your local machine and cd into it:

      • mkdir ~/kube-cluster
      • cd ~/kube-cluster

      This directory will be your workspace for the rest of the tutorial and will contain all of your Ansible playbooks. It will also be the directory inside which you will run all local commands.

      Create a file named ~/kube-cluster/hosts using nano or your favorite text editor:

      • nano ~/kube-cluster/hosts

      Add the following text to the file, which will specify information about the logical structure of your cluster:

      ~/kube-cluster/hosts

      [masters]
      master ansible_host=master_ip ansible_user=root
      
      [workers]
      worker1 ansible_host=worker_1_ip ansible_user=root
      worker2 ansible_host=worker_2_ip ansible_user=root
      
      [all:vars]
      ansible_python_interpreter=/usr/bin/python3
      

      You may recall that inventory files in Ansible are used to specify server information such as IP addresses, remote users, and groupings of servers to target as a single unit for executing commands. ~/kube-cluster/hosts will be your inventory file and you’ve added two Ansible groups (masters and workers) to it specifying the logical structure of your cluster.

      In the masters group, there is a server entry named “master” that lists the master node’s IP (master_ip) and specifies that Ansible should run remote commands as the root user.

      Similarly, in the workers group, there are two entries for the worker servers (worker_1_ip and worker_2_ip) that also specify the ansible_user as root.

      The last line of the file tells Ansible to use the remote servers’ Python 3 interpreters for its management operations.

      Save and close the file after you’ve added the text.

      Having set up the server inventory with groups, let’s move on to installing operating system level dependencies and creating configuration settings.

      Step 2 — Creating a Non-Root User on All Remote Servers

      In this section you will create a non-root user with sudo privileges on all servers so that you can SSH into them manually as an unprivileged user. This can be useful if, for example, you would like to see system information with commands such as top/htop, view a list of running containers, or change configuration files owned by root. These operations are routinely performed during the maintenance of a cluster, and using a non-root user for such tasks minimizes the risk of modifying or deleting important files or unintentionally performing other dangerous operations.

      Create a file named ~/kube-cluster/initial.yml in the workspace:

      • nano ~/kube-cluster/initial.yml

      Next, add the following play to the file to create a non-root user with sudo privileges on all of the servers. A play in Ansible is a collection of steps to be performed that target specific servers and groups. The following play will create a non-root sudo user:

      ~/kube-cluster/initial.yml

      - hosts: all
        become: yes
        tasks:
          - name: create the 'ubuntu' user
            user: name=ubuntu append=yes state=present createhome=yes shell=/bin/bash
      
          - name: allow 'ubuntu' to have passwordless sudo
            lineinfile:
              dest: /etc/sudoers
              line: 'ubuntu ALL=(ALL) NOPASSWD: ALL'
              validate: 'visudo -cf %s'
      
          - name: set up authorized keys for the ubuntu user
            authorized_key: user=ubuntu key="{{item}}"
            with_file:
              - ~/.ssh/id_rsa.pub
      

      Here’s a breakdown of what this playbook does:

      • Creates the non-root user ubuntu.

      • Configures the sudoers file to allow the ubuntu user to run sudo commands without a password prompt.

      • Adds the public key in your local machine (usually ~/.ssh/id_rsa.pub) to the remote ubuntu user’s authorized key list. This will allow you to SSH into each server as the ubuntu user.

      Save and close the file after you’ve added the text.

      Next, execute the playbook by locally running:

      • ansible-playbook -i hosts ~/kube-cluster/initial.yml

      The command will complete within two to five minutes. On completion, you will see output similar to the following:

      Output

      PLAY [all] **** TASK [Gathering Facts] **** ok: [master] ok: [worker1] ok: [worker2] TASK [create the 'ubuntu' user] **** changed: [master] changed: [worker1] changed: [worker2] TASK [allow 'ubuntu' user to have passwordless sudo] **** changed: [master] changed: [worker1] changed: [worker2] TASK [set up authorized keys for the ubuntu user] **** changed: [worker1] => (item=ssh-rsa AAAAB3...) changed: [worker2] => (item=ssh-rsa AAAAB3...) changed: [master] => (item=ssh-rsa AAAAB3...) PLAY RECAP **** master : ok=5 changed=4 unreachable=0 failed=0 worker1 : ok=5 changed=4 unreachable=0 failed=0 worker2 : ok=5 changed=4 unreachable=0 failed=0

      Now that the preliminary setup is complete, you can move on to installing Kubernetes-specific dependencies.

      Step 3 — Installing Kubernetetes’ Dependencies

      In this section, you will install the operating-system-level packages required by Kubernetes with Ubuntu’s package manager. These packages are:

      • Docker – a container runtime. It is the component that runs your containers. Support for other runtimes such as rkt is under active development in Kubernetes.

      • kubeadm – a CLI tool that will install and configure the various components of a cluster in a standard way.

      • kubelet – a system service/program that runs on all nodes and handles node-level operations.

      • kubectl – a CLI tool used for issuing commands to the cluster through its API Server.

      Create a file named ~/kube-cluster/kube-dependencies.yml in the workspace:

      • nano ~/kube-cluster/kube-dependencies.yml

      Add the following plays to the file to install these packages to your servers:

      ~/kube-cluster/kube-dependencies.yml

      - hosts: all
        become: yes
        tasks:
         - name: install Docker
           apt:
             name: docker.io
             state: present
             update_cache: true
      
         - name: install APT Transport HTTPS
           apt:
             name: apt-transport-https
             state: present
      
         - name: add Kubernetes apt-key
           apt_key:
             url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
             state: present
      
         - name: add Kubernetes' APT repository
           apt_repository:
            repo: deb http://apt.kubernetes.io/ kubernetes-xenial main
            state: present
            filename: 'kubernetes'
      
         - name: install kubelet
           apt:
             name: kubelet
             state: present
             update_cache: true
      
         - name: install kubeadm
           apt:
             name: kubeadm
             state: present
      
      - hosts: master
        become: yes
        tasks:
         - name: install kubectl
           apt:
             name: kubectl
             state: present
      

      The first play in the playbook does the following:

      • Installs Docker, the container runtime.

      • Installs apt-transport-https, allowing you to add external HTTPS sources to your APT sources list.

      • Adds the Kubernetes APT repository’s apt-key for key verification.

      • Adds the Kubernetes APT repository to your remote servers’ APT sources list.

      • Installs kubelet and kubeadm.

      The second play consists of a single task that installs kubectl on your master node.

      Save and close the file when you are finished.

      Next, execute the playbook by locally running:

      • ansible-playbook -i hosts ~/kube-cluster/kube-dependencies.yml

      On completion, you will see output similar to the following:

      Output

      PLAY [all] **** TASK [Gathering Facts] **** ok: [worker1] ok: [worker2] ok: [master] TASK [install Docker] **** changed: [master] changed: [worker1] changed: [worker2] TASK [install APT Transport HTTPS] ***** ok: [master] ok: [worker1] changed: [worker2] TASK [add Kubernetes apt-key] ***** changed: [master] changed: [worker1] changed: [worker2] TASK [add Kubernetes' APT repository] ***** changed: [master] changed: [worker1] changed: [worker2] TASK [install kubelet] ***** changed: [master] changed: [worker1] changed: [worker2] TASK [install kubeadm] ***** changed: [master] changed: [worker1] changed: [worker2] PLAY [master] ***** TASK [Gathering Facts] ***** ok: [master] TASK [install kubectl] ****** ok: [master] PLAY RECAP **** master : ok=9 changed=5 unreachable=0 failed=0 worker1 : ok=7 changed=5 unreachable=0 failed=0 worker2 : ok=7 changed=5 unreachable=0 failed=0

      After execution, Docker, kubeadm, and kubelet will be installed on all of the remote servers. kubectl is not a required component and is only needed for executing cluster commands. Installing it only on the master node makes sense in this context, since you will run kubectl commands only from the master. Note, however, that kubectl commands can be run from any of the worker nodes or from any machine where it can be installed and configured to point to a cluster.

      All system dependencies are now installed. Let’s set up the master node and initialize the cluster.

      Step 4 — Setting Up the Master Node

      In this section, you will set up the master node. Before creating any playbooks, however, it’s worth covering a few concepts such as Pods and Pod Network Plugins, since your cluster will include both.

      A pod is an atomic unit that runs one or more containers. These containers share resources such as file volumes and network interfaces in common. Pods are the basic unit of scheduling in Kubernetes: all containers in a pod are guaranteed to run on the same node that the pod is scheduled on.

      Each pod has its own IP address, and a pod on one node should be able to access a pod on another node using the pod’s IP. Containers on a single node can communicate easily through a local interface. Communication between pods is more complicated, however, and requires a separate networking component that can transparently route traffic from a pod on one node to a pod on another.

      This functionality is provided by pod network plugins. For this cluster, you will use Flannel, a stable and performant option.

      Create an Ansible playbook named master.yml on your local machine:

      • nano ~/kube-cluster/master.yml

      Add the following play to the file to initialize the cluster and install Flannel:

      ~/kube-cluster/master.yml

      - hosts: master
        become: yes
        tasks:
          - name: initialize the cluster
            shell: kubeadm init --pod-network-cidr=10.244.0.0/16 >> cluster_initialized.txt
            args:
              chdir: $HOME
              creates: cluster_initialized.txt
      
          - name: create .kube directory
            become: yes
            become_user: ubuntu
            file:
              path: $HOME/.kube
              state: directory
              mode: 0755
      
          - name: copy admin.conf to user's kube config
            copy:
              src: /etc/kubernetes/admin.conf
              dest: /home/ubuntu/.kube/config
              remote_src: yes
              owner: ubuntu
      
          - name: install Pod network
            become: yes
            become_user: ubuntu
            shell: kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml >> pod_network_setup.txt
            args:
              chdir: $HOME
              creates: pod_network_setup.txt
      

      Here’s a breakdown of this play:

      • The first task initializes the cluster by running kubeadm init. Passing the argument --pod-network-cidr=10.244.0.0/16 specifies the private subnet that the pod IPs will be assigned from. Flannel uses the above subnet by default; we’re telling kubeadm to use the same subnet.

      • The second task creates a .kube directory at /home/ubuntu. This directory will hold configuration information such as the admin key files, which are required to connect to the cluster, and the cluster’s API address.

      • The third task copies the /etc/kubernetes/admin.conf file that was generated from kubeadm init to your non-root user’s home directory. This will allow you to use kubectl to access the newly-created cluster.

      • The last task runs kubectl apply to install Flannel. kubectl apply -f descriptor.[yml|json] is the syntax for telling kubectl to create the objects described in the descriptor.[yml|json] file. The kube-flannel.yml file contains the descriptions of objects required for setting up Flannel in the cluster.

      Save and close the file when you are finished.

      Execute the playbook locally by running:

      • ansible-playbook -i hosts ~/kube-cluster/master.yml

      On completion, you will see output similar to the following:

      Output

      PLAY [master] **** TASK [Gathering Facts] **** ok: [master] TASK [initialize the cluster] **** changed: [master] TASK [create .kube directory] **** changed: [master] TASK [copy admin.conf to user's kube config] ***** changed: [master] TASK [install Pod network] ***** changed: [master] PLAY RECAP **** master : ok=5 changed=4 unreachable=0 failed=0

      To check the status of the master node, SSH into it with the following command:

      Once inside the master node, execute:

      You will now see the following output:

      Output

      NAME STATUS ROLES AGE VERSION master Ready master 1d v1.11.1

      The output states that the master node has completed all initialization tasks and is in a Ready state from which it can start accepting worker nodes and executing tasks sent to the API Server. You can now add the workers from your local machine.

      Step 5 — Setting Up the Worker Nodes

      Adding workers to the cluster involves executing a single command on each. This command includes the necessary cluster information, such as the IP address and port of the master's API Server, and a secure token. Only nodes that pass in the secure token will be able join the cluster.

      Navigate back to your workspace and create a playbook named workers.yml:

      • nano ~/kube-cluster/workers.yml

      Add the following text to the file to add the workers to the cluster:

      ~/kube-cluster/workers.yml

      - hosts: master
        become: yes
        gather_facts: false
        tasks:
          - name: get join command
            shell: kubeadm token create --print-join-command
            register: join_command_raw
      
          - name: set join command
            set_fact:
              join_command: "{{ join_command_raw.stdout_lines[0] }}"
      
      
      - hosts: workers
        become: yes
        tasks:
          - name: join cluster
            shell: "{{ hostvars['master'].join_command }} >> node_joined.txt"
            args:
              chdir: $HOME
              creates: node_joined.txt
      

      Here's what the playbook does:

      • The first play gets the join command that needs to be run on the worker nodes. This command will be in the following format:kubeadm join --token <token> <master-ip>:<master-port> --discovery-token-ca-cert-hash sha256:<hash>. Once it gets the actual command with the proper token and hash values, the task sets it as a fact so that the next play will be able to access that info.

      • The second play has a single task that runs the join command on all worker nodes. On completion of this task, the two worker nodes will be part of the cluster.

      Save and close the file when you are finished.

      Execute the playbook by locally running:

      • ansible-playbook -i hosts ~/kube-cluster/workers.yml

      On completion, you will see output similar to the following:

      Output

      PLAY [master] **** TASK [get join command] **** changed: [master] TASK [set join command] ***** ok: [master] PLAY [workers] ***** TASK [Gathering Facts] ***** ok: [worker1] ok: [worker2] TASK [join cluster] ***** changed: [worker1] changed: [worker2] PLAY RECAP ***** master : ok=2 changed=1 unreachable=0 failed=0 worker1 : ok=2 changed=1 unreachable=0 failed=0 worker2 : ok=2 changed=1 unreachable=0 failed=0

      With the addition of the worker nodes, your cluster is now fully set up and functional, with workers ready to run workloads. Before scheduling applications, let's verify that the cluster is working as intended.

      Step 6 — Verifying the Cluster

      A cluster can sometimes fail during setup because a node is down or network connectivity between the master and worker is not working correctly. Let's verify the cluster and ensure that the nodes are operating correctly.

      You will need to check the current state of the cluster from the master node to ensure that the nodes are ready. If you disconnected from the master node, you can SSH back into it with the following command:

      Then execute the following command to get the status of the cluster:

      You will see output similar to the following:

      Output

      NAME STATUS ROLES AGE VERSION master Ready master 1d v1.11.1 worker1 Ready <none> 1d v1.11.1 worker2 Ready <none> 1d v1.11.1

      If all of your nodes have the value Ready for STATUS, it means that they're part of the cluster and ready to run workloads.

      If, however, a few of the nodes have NotReady as the STATUS, it could mean that the worker nodes haven't finished their setup yet. Wait for around five to ten minutes before re-running kubectl get nodes and inspecting the new output. If a few nodes still have NotReady as the status, you might have to verify and re-run the commands in the previous steps.

      Now that your cluster is verified successfully, let's schedule an example Nginx application on the cluster.

      Step 7 — Running An Application on the Cluster

      You can now deploy any containerized application to your cluster. To keep things familiar, let's deploy Nginx using Deployments and Services to see how this application can be deployed to the cluster. You can use the commands below for other containerized applications as well, provided you change the Docker image name and any relevant flags (such as ports and volumes).

      Still within the master node, execute the following command to create a deployment named nginx:

      • kubectl run nginx --image=nginx --port 80

      A deployment is a type of Kubernetes object that ensures there's always a specified number of pods running based on a defined template, even if the pod crashes during the cluster's lifetime. The above deployment will create a pod with one container from the Docker registry's Nginx Docker Image.

      Next, run the following command to create a service named nginx that will expose the app publicly. It will do so through a NodePort, a scheme that will make the pod accessible through an arbitrary port opened on each node of the cluster:

      • kubectl expose deploy nginx --port 80 --target-port 80 --type NodePort

      Services are another type of Kubernetes object that expose cluster internal services to clients, both internal and external. They are also capable of load balancing requests to multiple pods, and are an integral component in Kubernetes, frequently interacting with other components.

      Run the following command:

      This will output text similar to the following:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d nginx NodePort 10.109.228.209 <none> 80:nginx_port/TCP 40m

      From the third line of the above output, you can retrieve the port that Nginx is running on. Kubernetes will assign a random port that is greater than 30000 automatically, while ensuring that the port is not already bound by another service.

      To test that everything is working, visit http://worker_1_ip:nginx_port or http://worker_2_ip:nginx_port through a browser on your local machine. You will see Nginx's familiar welcome page.

      If you would like to remove the Nginx application, first delete the nginx service from the master node:

      • kubectl delete service nginx

      Run the following to ensure that the service has been deleted:

      You will see the following output:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d

      Then delete the deployment:

      • kubectl delete deployment nginx

      Run the following to confirm that this worked:

      Output

      No resources found.

      Conclusion

      In this guide, you've successfully set up a Kubernetes cluster on Ubuntu 18.04 using Kubeadm and Ansible for automation.

      If you're wondering what to do with the cluster now that it's set up, a good next step would be to get comfortable deploying your own applications and services onto the cluster. Here's a list of links with further information that can guide you in the process:

      • Dockerizing applications - lists examples that detail how to containerize applications using Docker.

      • Pod Overview - describes in detail how Pods work and their relationship with other Kubernetes objects. Pods are ubiquitous in Kubernetes, so understanding them will facilitate your work.

      • Deployments Overview - provides an overview of deployments. It is useful to understand how controllers such as deployments work since they are used frequently in stateless applications for scaling and the automated healing of unhealthy applications.

      • Services Overview - covers services, another frequently used object in Kubernetes clusters. Understanding the types of services and the options they have is essential for running both stateless and stateful applications.

      Other important concepts that you can look into are Volumes, Ingresses and Secrets, all of which come in handy when deploying production applications.

      Kubernetes has a lot of functionality and features to offer. The Kubernetes Official Documentation is the best place to learn about concepts, find task-specific guides, and look up API references for various objects.



      Source link

      Como Criar um Cluster Kubernetes 1.11 Usando Kubeadm no Ubuntu 18.04


      O autor escolheu o Free and Open Source Fund para receber uma doação como parte do programa Write for DOnations.

      Introdução

      O Kubernetes é um sistema de orquestração de container em escala. Inicialmente desenvolvido pelo Google baseado em suas experiências executando containers em produção. O Kubernetes é open source e desenvolvido ativamente por uma comunidade em todo o mundo.

      O Kubeadm atomatiza a instalação e a configuração de componentes do Kubernetes tais como o servidor de API, o Controller Manager, e o Kube DNS. Contudo, ele não cria usuários ou lida com a instalação de dependências no nível do sistema operacional e sua configuração. Para essa tarefas preliminares, é possível utilizar uma ferramenta de gerência de configuração como o Ansible ou o SaltStack. A utilização dessas ferramentas torna a criação de clusters adicionais ou a recriação de clusters existentes muito mais simples e menos propensa a erros.

      Neste guia, você vai configurar um cluster Kubernetes a partir do zero utilizando o Ansible e o Kubeadm, e a seguir fazer o deploy de uma aplicação Nginx containerizada nele.

      Objetivos

      Seu cluster irá incluir os seguintes recursos físicos:

      O node master (um node no Kubernetes refere-se a um servidor) é responsável por gerenciar o estado do cluster. Ele roda o Etcd, que armazena dados de cluster entre componentes que fazem o scheduling de cargas de trabalho para nodes worker ou nodes de trabalho.

      Nodes worker são os servidores onde suas cargas de trabalho (i.e. aplicações e serviços containerizados) irão executar. Um worker continuará a executar sua carga de trabalho uma vez que estejam atribuídos a ela, mesmo se o master for desativado quando o scheduling estiver concluído. A capacidade de um cluster pode ser aumentada adicionando workers.

      Após a conclusão desse guia, você terá um cluster pronto para executar aplicações containerizadas, desde que os servidores no cluster tenham recursos suficientes de CPU e RAM para suas aplicações consumirem. Quase todas as aplicações Unix tradicionais, incluindo aplicações web, bancos de dados, daemons, e ferramentas de linha de comando podem ser containerizadas e feitas para rodar no cluster. O cluster em si consumirá cerca de 300-500MB de memória e 10% de CPU em cada node.

      Uma vez que o cluster esteja configurado, você fará o deploy do servidor web Nginx nele para assegurar que ele está executando as cargas de trabalho corretamente.

      Pré-requisitos

      Passo 1 — Configurando o Diretório da Área de Trabalho e o Arquivo de Inventário Ansible

      Nessa seção, você vai criar um diretório em sua máquina local que irá servir como sua área de trabalho. Você configurará o Ansible localmente para que ele possa se comunicar e executar comandos em seus servidores remotos. Depois disso pronto, você irá criar um arquivo hosts contendo informações de inventário tais como os endereços IP de seus servidores e os grupos aos quais cada servidor pertence.

      Dos seus três servidores, um será o master com um IP exibido como master_ip. Os outros dois servidores serão workers e terão os IPs worker_1_ip e worker_2_ip.

      Crie um diretório chamado ~/kube-cluster no diretório home de sua máquina local e faça um cd para dentro dele:

      • mkdir ~/kube-cluster
      • cd ~/kube-cluster

      Esse diretório será sua área de trabalho para o restante desse tutorial e conterá todos os seus playbooks de Ansible. Ele também será o diretório no qual você irá executar todos os comandos locais.

      Crie um arquivo chamado ~/kube-cluster/hosts usando o nano ou o seu editor de textos favorito:

      • nano ~/kube-cluster/hosts

      Adicione o seguinte texto ao arquivo, que irá especificar informações sobre a estrutura lógica do cluster:

      ~/kube-cluster/hosts

      
      [masters]
      master ansible_host=master_ip ansible_user=root
      
      [workers]
      worker1 ansible_host=worker_1_ip ansible_user=root
      worker2 ansible_host=worker_2_ip ansible_user=root
      
      [all:vars]
      ansible_python_interpreter=/usr/bin/python3
      

      Você deve se lembrar de que arquivos de inventário no Ansible são utilizados para especificar informações de servidor tais como endereços IP, usuários remotos, e agrupamentos de servidores para tratar como uma unidade única para a execução de comandos. O ~/kube-cluster/hosts será o seu arquivo de inventário e você adicionou dois grupos Ansible a ele (masters e workers) especificando a estrutura lógica do seu cluster.

      No grupo masters, existe uma entrada de servidor chamada “master” que lista o IP do node master (master_ip) e especifica que o Ansible deve executar comandos remotos como root.

      De maneira similar, no grupo workers, existem duas entradas para os servidores workers (worker_1_ip e worker_2_ip) que também especificam o ansible_user como root.

      A última linha do arquivo diz ao Ansible para utilizar os intepretadores Python dos servidores remotos para suas operações de gerenciamento.

      Salve e feche o arquivo depois de ter adicionado o texto.

      Tendo configurado o inventário do servidor com grupos, vamos passar a instalar dependências no nível do sistema operacional e a criar definições de configuração.

      Passo 2 — Criando um Usuário Não-Root em Todos os Servidores Remotos

      Nesta seção você irá criar um usuário não-root com privilégios sudo em todos os servidores para que você possa fazer SSH manualmente neles como um usuário sem privilégios. Isso pode ser útil se, por exemplo, você gostaria de ver informações do sistema com comandos como top/htop, ver a lista de containers em execução, ou alterar arquivos de configuração de propriedade do root. Estas operações são rotineiramente executadas durante a manutenção de um cluster, e a utilização de um usuário que não seja root para tarefas desse tipo minimiza o risco de modificação ou exclusão de arquivos importantes ou a realização não intencional de operações perigosas.

      Crie um arquivo chamado ~/kube-cluster/initial.yml na área de trabalho:

      • nano ~/kube-cluster/initial.yml

      A seguir, adicione o seguinte play ao arquivo para criar um usuário não-root com privilégios sudo em todos os servidores. Um play no Ansible é uma coleção de passos a serem realizados que visam servidores e grupos específicos. O seguinte play irá criar um usuário sudo não-root:

      ~/kube-cluster/initial.yml

      
      - hosts: all
        become: yes
        tasks:
          - name: create the 'ubuntu' user
            user: name=ubuntu append=yes state=present createhome=yes shell=/bin/bash
      
          - name: allow 'ubuntu' to have passwordless sudo
            lineinfile:
              dest: /etc/sudoers
              line: 'ubuntu ALL=(ALL) NOPASSWD: ALL'
              validate: 'visudo -cf %s'
      
          - name: set up authorized keys for the ubuntu user
            authorized_key: user=ubuntu key="{{item}}"
            with_file:
              - ~/.ssh/id_rsa.pub
      

      Aqui está um detalhamento do que este playbook faz:

      • Cria um usuário não-root ubuntu.

      • Configura o arquivo sudoers para permitir o usuário ubuntu executar comandos sudo sem uma solicitação de senha.

      • Adiciona a chave pública em sua máquina local (normalmente ~/.ssh/id_rsa.pub) para a lista de chaves autorizadas do usuário remoto ubuntu. Isto o permitirá fazer SSH para dentro de cada servidor como usuário ubuntu.

      Salve e feche o arquivo depois que tiver adicionado o texto.

      Em seguida, rode o playbook localmente executando:

      • ansible-playbook -i hosts ~/kube-cluster/initial.yml

      O comando será concluído dentro de dois a cinco minutos. Na conclusão, você verá uma saída semelhante à seguinte:

      Output

      PLAY [all] **** TASK [Gathering Facts] **** ok: [master] ok: [worker1] ok: [worker2] TASK [create the 'ubuntu' user] **** changed: [master] changed: [worker1] changed: [worker2] TASK [allow 'ubuntu' user to have passwordless sudo] **** changed: [master] changed: [worker1] changed: [worker2] TASK [set up authorized keys for the ubuntu user] **** changed: [worker1] => (item=ssh-rsa AAAAB3...) changed: [worker2] => (item=ssh-rsa AAAAB3...) changed: [master] => (item=ssh-rsa AAAAB3...) PLAY RECAP **** master : ok=5 changed=4 unreachable=0 failed=0 worker1 : ok=5 changed=4 unreachable=0 failed=0 worker2 : ok=5 changed=4 unreachable=0 failed=0

      Agora que a configuração preliminar está completa, você pode passar para a instalação de dependências específicas do Kubernetes.

      Step 3 — Instalando as Dependências do Kubernetes

      Nesta seção, você irá instalar os pacotes no nível do sistema operacional necessários pelo Kubernetes com o gerenciador de pacotes do Ubuntu. Esses pacotes são:

      • Docker – um runtime de container. Este é o componente que executa seus containers. Suporte a outros runtimes como o rkt está em desenvolvimento ativo no Kubernetes.

      • kubeadm – uma ferramenta CLI que irá instalar e configurar os vários componentes de um cluster de uma maneira padrão.

      • kubelet – um serviço/programa de sistema que roda em todos os nodes e lida com operações no nível do node.

      • kubectl – uma ferramenta CLI usada para emitir comandos para o cluster através de seu servidor de API.

      Crie um arquivo chamado ~/kube-cluster/kube-dependencies.yml na área de trabalho:

      • nano ~/kube-cluster/kube-dependencies.yml

      Adicione os seguintes plays ao arquivo para instalar esses pacotes em seus servidores:

      ~/kube-cluster/kube-dependencies.yml

      
      - hosts: all
        become: yes
        tasks:
         - name: install Docker
           apt:
             name: docker.io
             state: present
             update_cache: true
      
         - name: install APT Transport HTTPS
           apt:
             name: apt-transport-https
             state: present
      
         - name: add Kubernetes apt-key
           apt_key:
             url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
             state: present
      
         - name: add Kubernetes' APT repository
           apt_repository:
            repo: deb http://apt.kubernetes.io/ kubernetes-xenial main
            state: present
            filename: 'kubernetes'
      
         - name: install kubelet
           apt:
             name: kubelet
             state: present
             update_cache: true
      
         - name: install kubeadm
           apt:
             name: kubeadm
             state: present
      
      - hosts: master
        become: yes
        tasks:
         - name: install kubectl
           apt:
             name: kubectl
             state: present
      

      O primeiro play no playbook faz o seguinte:

      • Instala o Docker, o runtime de container.

      • Instala o apt-transport-https, permitindo que você adicione fontes HTTPS externas à sua lista de fontes do APT.

      • Adiciona a apt-key do repositório APT do Kubernetes para verificação de chave.

      • Adiciona o repositório APT do Kubernetes à lista de fontes do APT dos seus servidores remotos.

      • Instala kubelet e kubeadm.

      O segundo play consiste de uma única tarefa que instala o kubectl no seu node master.

      Salve e feche o arquivo quando você tiver terminado.

      A seguir, rode o playbook executando localmente:

      • ansible-playbook -i hosts ~/kube-cluster/kube-dependencies.yml

      Na conclusão, você verá uma saída semelhante à seguinte:

      Output

      PLAY [all] **** TASK [Gathering Facts] **** ok: [worker1] ok: [worker2] ok: [master] TASK [install Docker] **** changed: [master] changed: [worker1] changed: [worker2] TASK [install APT Transport HTTPS] ***** ok: [master] ok: [worker1] changed: [worker2] TASK [add Kubernetes apt-key] ***** changed: [master] changed: [worker1] changed: [worker2] TASK [add Kubernetes' APT repository] ***** changed: [master] changed: [worker1] changed: [worker2] TASK [install kubelet] ***** changed: [master] changed: [worker1] changed: [worker2] TASK [install kubeadm] ***** changed: [master] changed: [worker1] changed: [worker2] PLAY [master] ***** TASK [Gathering Facts] ***** ok: [master] TASK [install kubectl] ****** ok: [master] PLAY RECAP **** master : ok=9 changed=5 unreachable=0 failed=0 worker1 : ok=7 changed=5 unreachable=0 failed=0 worker2 : ok=7 changed=5 unreachable=0 failed=0

      Após a execução, o Docker, o kubeadm e o kubelet estarão instalados em todos os seus servidores remotos. O kubectl não é um componente obrigatório e somente é necessário para a execução de comandos de cluster. A instalação dele somente no node master faz sentido nesse contexto, uma vez que você irá executar comandos kubectl somente a partir do master. Contudo, observe que os comandos kubectl podem ser executados a partir de quaisquer nodes worker ou a partir de qualquer máquina onde ele possa ser instalado e configurado para apontar para um cluster.

      Todas as dependências de sistema agora estão instaladas. Vamos configurar o node master e inicializar o cluster.

      Passo 4 — Configurando o Node Master

      Nesta seção, você irá configurar o node master. Antes da criação de quaisquer playbooks, contudo, vale a pena cobrir alguns conceitos como Pods e Plugins de Rede do Pod, uma vez que seu cluster incluirá ambos.

      Um pod é uma unidade atômica que executa um ou mais containers. Esses containers compartilham recursos tais como volumes de arquivo e interfaces de rede em comum. Os pods são a unidade básica de scheduling no Kubernetes: todos os containers em um pod têm a garantia de serem executados no mesmo node no qual foi feito o scheduling do pod.

      Cada pod tem seu próprio endereço IP, e um pod em um node deve ser capaz de acessar um pod em outro node utilizando o IP do pod. Os containers em um único node podem se comunicar facilmente através de uma interface local. Contudo, a comunicação entre pods é mais complicada e requer um componente de rede separado que possa encaminhar o tráfego de maneira transparente de um pod em um node para um pod em outro node.

      Essa funcionalidade é fornecida pelos plugins de rede para pods. Para este cluster vamos utilizar o Flannel, uma opção estável e de bom desempenho.

      Crie um playbook Ansible chamado master.yml em sua máquina local:

      • nano ~/kube-cluster/master.yml

      Adicione o seguinte play ao arquivo para inicializar o cluster e instalar o Flannel:

      ~/kube-cluster/master.yml

      
      - hosts: master
        become: yes
        tasks:
          - name: initialize the cluster
            shell: kubeadm init --pod-network-cidr=10.244.0.0/16 >> cluster_initialized.txt
            args:
              chdir: $HOME
              creates: cluster_initialized.txt
      
          - name: create .kube directory
            become: yes
            become_user: ubuntu
            file:
              path: $HOME/.kube
              state: directory
              mode: 0755
      
          - name: copy admin.conf to user's kube config
            copy:
              src: /etc/kubernetes/admin.conf
              dest: /home/ubuntu/.kube/config
              remote_src: yes
              owner: ubuntu
      
          - name: install Pod network
            become: yes
            become_user: ubuntu
            shell: kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml >> pod_network_setup.txt
            args:
              chdir: $HOME
              creates: pod_network_setup.txt
      

      Aqui está um detalhamento deste play:

      • A primeira tarefa inicializa o cluster executando kubeadm init. A passagem do argumento --pod-network-cidr=10.244.0.0/16 especifica a sub-rede privada que os IPs do pod serão atribuídos. O Flannel utiliza a sub-rede acima por padrão; estamos dizendo ao kubeadm para utilizar a mesma sub-rede.

      • A segunda tarefa cria um diretório .kube em /home/ubuntu. Este diretório irá manter as informações de configuração tais como os arquivos de chaves do admin, que são requeridas para conectar no cluster, e o endereço da API do cluster.

      • A terceira tarefa copia o arquivo /etc/kubernetes/admin.conf que foi gerado a partir do kubeadm init para o diretório home do seu usuário não-root. Isso irá permitir que você utilize o kubectl para acessar o cluster recém-criado.

      • A última tarefa executa kubectl apply para instalar o Flannel. kubectl apply -f descriptor.[yml|json] é a sintaxe para dizer ao kubectl para criar os objetos descritos no arquivo descriptor.[yml|json]. O arquivo kube-flannel.yml contém as descrições dos objetos requeridos para a configuração do Flannel no cluster.

      Salve e feche o arquivo quando você tiver terminado.

      Rode o playbook localmente executando:

      • ansible-playbook -i hosts ~/kube-cluster/master.yml

      Na conclusão, você verá uma saída semelhante à seguinte:

      Output

      PLAY [master] **** TASK [Gathering Facts] **** ok: [master] TASK [initialize the cluster] **** changed: [master] TASK [create .kube directory] **** changed: [master] TASK [copy admin.conf to user's kube config] ***** changed: [master] TASK [install Pod network] ***** changed: [master] PLAY RECAP **** master : ok=5 changed=4 unreachable=0 failed=0

      Para verificar o status do node master, faça SSH nele com o seguinte comando:

      Uma vez dentro do node master, execute:

      Agora você verá a seguinte saída:

      Output

      NAME STATUS ROLES AGE VERSION master Ready master 1d v1.11.1

      A saída informa que o node master concluiu todas as tarefas de inicialização e está em um estado Ready do qual pode começar a aceitar nodes worker e executar tarefas enviadas ao Servidor de API. Agora você pode adicionar os workers a partir de sua máquina local.

      Passo 5 — Configurando os Nodes Worker

      A adição de workers ao cluster envolve a execução de um único comando em cada um. Este comando inclui as informações necessárias sobre o cluster, tais como o endereço IP e a porta do Servidor de API do master, e um token seguro. Somentes os nodes que passam no token seguro estarão aptos a ingressar no cluster.

      Navegue de volta para a sua área de trabalho e crie um playbook chamado workers.yml:

      • nano ~/kube-cluster/workers.yml

      Adicione o seguinte texto ao arquivo para adicionar os workers ao cluster:

      ~/kube-cluster/workers.yml

      
      - hosts: master
        become: yes
        gather_facts: false
        tasks:
          - name: get join command
            shell: kubeadm token create --print-join-command
            register: join_command_raw
      
          - name: set join command
            set_fact:
              join_command: "{{ join_command_raw.stdout_lines[0] }}"
      
      
      - hosts: workers
        become: yes
        tasks:
          - name: join cluster
            shell: "{{ hostvars['master'].join_command }} >> node_joined.txt"
            args:
              chdir: $HOME
              creates: node_joined.txt
      

      Aqui está o que o playbook faz:

      • O primeiro play obtém o comando de junção que precisa ser executado nos nodes workers. Este comando estará no seguinte formato: kubeadm join --token <token> <master-ip>:<master-port> --discovery-token-ca-cert-hash sha256:<hash>. Assim que obtiver o comando real com os valores apropriados de token e hash, a tarefa define isso como um fact para que o próximo play possa acessar essa informação.

      • O segundo play tem uma única tarefa que executa o comando de junção em todos os nodes worker. Na conclusão desta tarefa, os dois nodes worker farão parte do cluster.

      Salve e feche o arquivo quando você tiver terminado.

      Rode o playbook localmente executando:

      • ansible-playbook -i hosts ~/kube-cluster/workers.yml

      Na conclusão, você verá uma saída semelhante à seguinte:

      Output

      PLAY [master] **** TASK [get join command] **** changed: [master] TASK [set join command] ***** ok: [master] PLAY [workers] ***** TASK [Gathering Facts] ***** ok: [worker1] ok: [worker2] TASK [join cluster] ***** changed: [worker1] changed: [worker2] PLAY RECAP ***** master : ok=2 changed=1 unreachable=0 failed=0 worker1 : ok=2 changed=1 unreachable=0 failed=0 worker2 : ok=2 changed=1 unreachable=0 failed=0

      Com a adição dos nodes worker, seu cluster está agora totalmente configurado e funcional, com os workers prontos para executar cargas de trabalho. Antes de fazer o scheduling de aplicações, vamos verificar se o cluster está funcionando conforme o esperado.

      Step 6 — Verificando o Cluster

      Às vezes, um cluster pode falhar durante a configuração porque um node está inativo ou a conectividade de rede entre o master e o worker não está funcionando corretamente. Vamos verificar o cluster e garantir que os nodes estejam operando corretamente.

      Você precisará verificar o estado atual do cluster a partir do node master para garantir que os nodes estejam prontos. Se você se desconectou do node master, pode voltar e fazer SSH com o seguinte comando:

      Em seguida, execute o seguinte comando para obter o status do cluster:

      Você verá uma saída semelhante à seguinte:

      Output

      NAME STATUS ROLES AGE VERSION master Ready master 1d v1.11.1 worker1 Ready <none> 1d v1.11.1 worker2 Ready <none> 1d v1.11.1

      Se todos os seus nodes têm o valor Ready para o STATUS, significa que eles são parte do cluster e estão prontos para executar cargas de trabalho.

      Se, contudo, alguns dos nodes têm NotReady como o STATUS, isso pode significar que os nodes worker ainda não concluíram sua configuração. Aguarde cerca de cinco a dez minutos antes de voltar a executar kubectl get nodes e fazer a inspeção da nova saída. Se alguns nodes ainda têm NotReady como status, talvez seja necessário verificar e executar novamente os comandos nas etapas anteriores.

      Agora que seu cluster foi verificado com sucesso, vamos fazer o scheduling de um exemplo de aplicativo Nginx no cluster.

      Step 7 — Executando Uma Aplicação no Cluster

      Você pode fazer o deploy de qualquer aplicação containerizada no seu cluster. Para manter as coisas familiares, vamos fazer o deploy do Nginx utilizando Deployments e Services para ver como pode ser feito o deploy dessa aplicação no cluster. Você também pode usar os comandos abaixo para outros aplicativos em container, desde que você altere o nome da imagem do Docker e quaisquer flags relevantes (tais como ports e volumes).

      Ainda no node master, execute o seguinte comando para criar um deployment chamado nginx:

      • kubectl run nginx --image=nginx --port 80

      Um deployment é um tipo de objeto do Kubernetes que garante que há sempre um número especificado de pods em execução com base em um modelo definido, mesmo se o pod falhar durante o tempo de vida do cluster. O deployment acima irá criar um pod com um container do registro do Docker Nginx Docker Image.

      A seguir, execute o seguinte comando para criar um serviço chamado nginx que irá expor o app publicamente. Ele fará isso por meio de um NodePort, um esquema que tornará o pod acessível através de uma porta arbitrária aberta em cada node do cluster:

      • kubectl expose deploy nginx --port 80 --target-port 80 --type NodePort

      Services são outro tipo de objeto do Kubernetes que expõe serviços do cluster para os clientes, tanto internos quanto externos. Eles também são capazes de fazer balanceamento de solicitações para vários pods e são um componente integral no Kubernetes, interagindo frequentemente com outros componentes.

      Execute o seguinte comando:

      Isso produzirá uma saída semelhante à seguinte:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d nginx NodePort 10.109.228.209 <none> 80:nginx_port/TCP 40m

      A partir da terceira linha da saída acima, você pode obter a porta em que o Nginx está sendo executado. O Kubernetes atribuirá uma porta aleatória maior que 30000 automaticamente, enquanto garante que a porta já não esteja vinculada a outro serviço.

      Para testar se tudo está funcionando, visite http://worker_1_ip:nginx_port ou http://worker_2_ip:nginx_port através de um navegador na sua máquina local. Você verá a familiar página de boas-vindas do Nginx.

      Se você quiser remover o aplicativo Nginx, primeiro exclua o serviço nginx do node master:

      • kubectl delete service nginx

      Execute o seguinte para garantir que o serviço tenha sido excluído:

      Você verá a seguinte saída:

      [secondary label Output]
      NAME         TYPE        CLUSTER-IP       EXTERNAL-IP           PORT(S)        AGE
      kubernetes   ClusterIP   10.96.0.1        <none>                443/TCP        1d
      

      Para excluir o deployment:

      • kubectl delete deployment nginx

      Execute o seguinte para confirmar que isso funcionou:

      Output

      No resources found.

      Conclusão

      Neste guia, você configurou com sucesso um cluster do Kubernetes no Ubuntu 18.04 usando Kubeadm e Ansible para automação.

      Se você está se perguntando o que fazer com o cluster, agora que ele está configurado, um bom próximo passo seria sentir-se confortável para implantar suas próprias aplicações e serviços no cluster. Aqui está uma lista de links com mais informações que podem orientá-lo no processo:

      • Dockerizing applications - lista exemplos que detalham como containerizar aplicações usando o Docker.

      • Pod Overview - descreve em detalhes como os Pods funcionam e seu relacionamento com outros objetos do Kubernetes. Os pods são onipresentes no Kubernetes, então compreendê-los facilitará seu trabalho.

      • Deployments Overview - fornece uma visão geral dos deployments. É útil entender como os controladores, como os deployments, funcionam, pois eles são usados com frequência em aplicações stateless para escalonamento e na recuperação automatizada de aplicações não íntegras.

      • Services Overview - cobre os serviços ou services, outro objeto frequentemente usado em clusters do Kubernetes. Entender os tipos de serviços e as opções que eles têm é essencial para executar aplicações stateless e stateful.

      Outros conceitos importantes que você pode analisar são Volumes, Ingresses e Secrets, os quais são úteis ao realizar o deploy de aplicações em produção.

      O Kubernetes tem muitas funcionalidades e recursos a oferecer. A Documentação Oficial do Kubernetes é o melhor lugar para aprender sobre conceitos, encontrar guias específicos de tarefas e procurar referências de API para vários objetos.

      Por bsder



      Source link

      Como Criar um Cluster Kubernetes 1.10 Usando Kubeadm no CentOS 7


      O autor escolheu o Free and Open Source Fund para receber uma doação como parte do programa Write for DOnations.

      Introdução

      O Kubernetes é um sistema de orquestração de container em escala. Inicialmente desenvolvido pelo Google baseado em suas experiências executando containers em produção. O Kubernetes é open source e desenvolvido ativamente por uma comunidade em todo o mundo.

      O Kubeadm atomatiza a instalação e a configuração de componentes do Kubernetes tais como o servidor de API, o Controller Manager, e o Kube DNS. Contudo, ele não cria usuários ou lida com a instalação de dependências no nível do sistema operacional e sua configuração. Para essa tarefas preliminares, é possível utilizar uma ferramenta de gerência de configuração como o Ansible ou o SaltStack. A utilização dessas ferramentas torna a criação de clusters adicionais ou a recriação de clusters existentes muito mais simples e menos propensa a erros.

      Neste guia, você vai configurar um cluster Kubernetes a partir do zero utilizando o Ansible e o Kubeadm, e a seguir fazer o deploy de uma aplicação Nginx containerizada nele.

      Objetivos

      Seu cluster irá incluir os seguintes recursos físicos:

      O node master (um node no Kubernetes refere-se a um servidor) é responsável por gerenciar o estado do cluster. Ele roda o Etcd, que armazena dados de cluster entre componentes que fazem o scheduling de cargas de trabalho para nodes de trabalho.

      Nodes worker são os servidores onde suas cargas de trabalho (i.e. aplicações e serviços containerizados) irão executar. Um worker continuará a executar sua carga de trabalho uma vez que estejam atribuídos a ela, mesmo se o master for desativado quando o scheduling estiver concluído. A capacidade de um cluster pode ser aumentada adicionando workers.

      Após a conclusão desse guia, você terá um cluster pronto para executar aplicações containerizadas, desde que os servidores no cluster tenham recursos suficientes de CPU e RAM para suas aplicações consumirem. Quase todas as aplicações Unix tradicionais, incluindo aplicações web, bancos de dados, daemons, e ferramentas de linha de comando podem ser containerizadas e feitas para rodar no cluster. O cluster em si consumirá cerca de 300-500MB de memória e 10% de CPU em cada node.

      Uma vez que o cluster esteja configurado, você fará o deploy do servidor web Nginx nele para assegurar que ele está executando as cargas de trabalho corretamente.

      Pré-requisitos

      Passo 1 — Configurando o Diretório da Área de Trabalho e o Arquivo de Inventário Ansible

      Nessa seção, você vai criar um diretório em sua máquina local que irá servir como sua área de trabalho. Você configurará o Ansible localmente para que ele possa se comunicar e executar comandos em seus servidores remotos. Depois disso pronto, você irá criar um arquivo hosts contendo informações de inventário tais como os endereços IP de seus servidores e os grupos aos quais cada servidor pertence.

      Dos seus três servidores, um será o master com um IP exibido como master_ip. Os outros dois servidores serão workers e terão os IPs worker_1_ip e worker_2_ip.

      Crie um diretório chamado ~/kube-cluster no diretório home de sua máquina local e faça um cd para dentro dele:

      • mkdir ~/kube-cluster
      • cd ~/kube-cluster

      Esse diretório será sua área de trabalho para o restante desse tutorial e conterá todos os seus playbooks de Ansible. Ele também será o diretório no qual você irá executar todos os comandos locais.

      Crie um arquivo chamado ~/kube-cluster/hosts usando o vi ou o seu editor de textos favorito:

      Pressione i para inserir o seguinte texto ao arquivo, que irá especificar informações sobre a estrutura lógica do cluster:

      ~/kube-cluster/hosts

      
      [masters]
      master ansible_host=master_ip ansible_user=root
      
      [workers]
      worker1 ansible_host=worker_1_ip ansible_user=root
      worker2 ansible_host=worker_2_ip ansible_user=root
      

      Quando tiver terminado, pressione ESC seguido de :wq para gravar as alterações no arquvo e sair.

      Você deve se lembrar de que arquivos de inventário no Ansible são utilizados para especificar informações de servidor tais como endereços IP, usuários remotos, e agrupamentos de servidores para tratar como uma unidade única para a execução de comandos. O ~/kube-cluster/hosts será o seu arquivo de inventário e você adicionou dois grupos Ansible a ele (masters e workers) especificando a estrutura lógica do seu cluster.

      No grupo masters, existe uma entrada de servidor chamada "master" que lista o IP do node master (master_ip) e especifica que o Ansible deve executar comandos remotos como root.

      De maneira similar, no grupo workers, existem duas entradas para os servidores workers (worker_1_ip e worker_2_ip) que também especificam o ansible_user como root.

      Tendo configurado o inventário do servidor com grupos, vamos passar a instalar dependências no nível do sistema operacional e a criar definições de configuração.

      Passo 2 — Criando um Usuário Não-Root em Todos os Servidores Remotos

      Nesta seção você irá criar um usuário não-root com privilégios sudo em todos os servidores para que você possa fazer SSH manualmente neles como um usuário sem privilégios. Isso pode ser útil se, por exemplo, você gostaria de ver informações do sistema com comandos como top/htop, ver a lista de containers em execução, ou alterar arquivos de configuração de propriedade do root. Estas operações são rotineiramente executadas durante a manutenção de um cluster, e a utilização de um usuário que não seja root para tarefas desse tipo minimiza o risco de modificação ou exclusão de arquivos importantes ou a realização não intencional de operações perigosas.

      Crie um arquivo chamado ~/kube-cluster/initial.yml na área de trabalho:

      • vi ~/kube-cluster/initial.yml

      A seguir, adicione o seguinte play ao arquivo para criar um usuário não-root com privilégios sudo em todos os servidores. Um play no Ansible é uma coleção de passos a serem realizados que visam servidores e grupos específicos. O seguinte play irá criar um usuário sudo não-root:

      ~/kube-cluster/initial.yml

      
      - hosts: all
        become: yes
        tasks:
          - name: create the 'centos' user
            user: name=centos append=yes state=present createhome=yes shell=/bin/bash
      
          - name: allow 'centos' to have passwordless sudo
            lineinfile:
              dest: /etc/sudoers
              line: 'centos ALL=(ALL) NOPASSWD: ALL'
              validate: 'visudo -cf %s'
      
          - name: set up authorized keys for the centos user
            authorized_key: user=centos key="{{item}}"
            with_file:
              - ~/.ssh/id_rsa.pub
      

      Aqui está um detalhamento do que este playbook faz:

      • Cria um usuário não-root centos.

      • Configura o arquivo sudoers para permitir o usuário centos executar comandos sudo sem uma solicitação de senha.

      • Adiciona a chave pública em sua máquina local (normalmente ~/.ssh/id_rsa.pub) para a lista de chaves autorizadas do usuário remoto centos. Isto o permitirá fazer SSH para dentro de cada servidor como usuário centos.

      Salve e feche o arquivo depois que tiver adicionado o texto.

      Em seguida, rode o playbook localmente executando:

      • ansible-playbook -i hosts ~/kube-cluster/initial.yml

      O comando será concluído dentro de dois a cinco minutos. Na conclusão, você verá uma saída semelhante à seguinte:

      Output

      PLAY [all] **** TASK [Gathering Facts] **** ok: [master] ok: [worker1] ok: [worker2] TASK [create the 'centos' user] **** changed: [master] changed: [worker1] changed: [worker2] TASK [allow 'centos' user to have passwordless sudo] **** changed: [master] changed: [worker1] changed: [worker2] TASK [set up authorized keys for the centos user] **** changed: [worker1] => (item=ssh-rsa AAAAB3...) changed: [worker2] => (item=ssh-rsa AAAAB3...) changed: [master] => (item=ssh-rsa AAAAB3...) PLAY RECAP **** master : ok=5 changed=4 unreachable=0 failed=0 worker1 : ok=5 changed=4 unreachable=0 failed=0 worker2 : ok=5 changed=4 unreachable=0 failed=0

      Agora que a configuração preliminar está completa, você pode passar para a instalação de dependências específicas do Kubernetes.

      Passo 3 — Instalando as Dependências do Kubernetes

      Nesta seção, você irá instalar os pacotes no nível do sistema operacional necessários pelo Kubernetes com o gerenciador de pacotes yum do CentOS. Esses pacotes são:

      • Docker - um runtime de container. Este é o componente que executa seus containers. Suporte a outros runtimes como o rkt está em desenvolvimento ativo no Kubernetes.

      • kubeadm - uma ferramenta CLI que irá instalar e configurar os vários componentes de um cluster de uma maneira padrão.

      • kubelet - um serviço/programa de sistema que roda em todos os nodes e lida com operações no nível do node.

      • kubectl - uma ferramenta CLI usada para emitir comandos para o cluster através de seu servidor de API.

      Crie um arquivo chamado ~/kube-cluster/kube-dependencies.yml na área de trabalho:

      • vi ~/kube-cluster/kube-dependencies.yml

      Adicione os seguintes plays ao arquivo para instalar esses pacotes em seus servidores:

      ~/kube-cluster/kube-dependencies.yml

      
      - hosts: all
        become: yes
        tasks:
         - name: install Docker
           yum:
             name: docker
             state: present
             update_cache: true
      
         - name: start Docker
           service:
             name: docker
             state: started
      
         - name: disable SELinux
           command: setenforce 0
      
         - name: disable SELinux on reboot
           selinux:
             state: disabled
      
         - name: ensure net.bridge.bridge-nf-call-ip6tables is set to 1
           sysctl:
            name: net.bridge.bridge-nf-call-ip6tables
            value: 1
            state: present
      
         - name: ensure net.bridge.bridge-nf-call-iptables is set to 1
           sysctl:
            name: net.bridge.bridge-nf-call-iptables
            value: 1
            state: present
      
         - name: add Kubernetes' YUM repository
           yum_repository:
            name: Kubernetes
            description: Kubernetes YUM repository
            baseurl: https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
            gpgkey: https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
            gpgcheck: yes
      
         - name: install kubelet
           yum:
              name: kubelet
              state: present
              update_cache: true
      
         - name: install kubeadm
           yum:
              name: kubeadm
              state: present
      
         - name: start kubelet
           service:
             name: kubelet
             enabled: yes
             state: started
      
      - hosts: master
        become: yes
        tasks:
         - name: install kubectl
           yum:
              name: kubectl
              state: present
      

      O primeiro play no playbook faz o seguinte:

      • Instala o Docker, o runtime de container.

      • Inicia o serviço do Docker.

      • Desativa o SELinux, uma vez que ele ainda não é totalmente suportado pelo Kubernetes.

      • Define alguns valores sysctl relacionados ao netfilter, necessários para o trabalho em rede. Isso permitirá que o Kubernetes defina regras de iptables para receber tráfego de rede IPv4 e IPv6 em bridge nos nodes.

      • Adiciona o repositório YUM do Kubernetes às listas de repositórios de seus servidores remotos.

      • Instala kubelet e kubeadm.

      O segundo play consiste de uma única tarefa que instala o kubectl no seu node master.

      Salve e feche o arquivo quando você tiver terminado.

      A seguir, execute o playbook:

      • ansible-playbook -i hosts ~/kube-cluster/kube-dependencies.yml

      Na conclusão, você verá uma saída semelhante à seguinte:

      Output

      PLAY [all] **** TASK [Gathering Facts] **** ok: [worker1] ok: [worker2] ok: [master] TASK [install Docker] **** changed: [master] changed: [worker1] changed: [worker2] TASK [disable SELinux] **** changed: [master] changed: [worker1] changed: [worker2] TASK [disable SELinux on reboot] **** changed: [master] changed: [worker1] changed: [worker2] TASK [ensure net.bridge.bridge-nf-call-ip6tables is set to 1] **** changed: [master] changed: [worker1] changed: [worker2] TASK [ensure net.bridge.bridge-nf-call-iptables is set to 1] **** changed: [master] changed: [worker1] changed: [worker2] TASK [start Docker] **** changed: [master] changed: [worker1] changed: [worker2] TASK [add Kubernetes' YUM repository] ***** changed: [master] changed: [worker1] changed: [worker2] TASK [install kubelet] ***** changed: [master] changed: [worker1] changed: [worker2] TASK [install kubeadm] ***** changed: [master] changed: [worker1] changed: [worker2] TASK [start kubelet] **** changed: [master] changed: [worker1] changed: [worker2] PLAY [master] ***** TASK [Gathering Facts] ***** ok: [master] TASK [install kubectl] ****** ok: [master] PLAY RECAP **** master : ok=9 changed=5 unreachable=0 failed=0 worker1 : ok=7 changed=5 unreachable=0 failed=0 worker2 : ok=7 changed=5 unreachable=0 failed=0

      Após a execução, o Docker, o kubeadm e o kubelet estarão instalados em todos os seus servidores remotos. O kubectl não é um componente obrigatório e somente é necessário para a execução de comandos de cluster. A instalação dele somente no node master faz sentido nesse contexto, uma vez que você irá executar comandos kubectl somente a partir do master. Contudo, observe que os comandos kubectl podem ser executados a partir de quaisquer nodes worker ou a partir de qualquer máquina onde ele possa ser instalado e configurado para apontar para um cluster.

      Todas as dependências de sistema agora estão instaladas. Vamos configurar o node master e inicializar o cluster.

      Passo 4 — Configurando o Node Master

      Nesta seção, você irá configurar o node master. Antes da criação de quaisquer playbooks, contudo, vale a pena cobrir alguns conceitos como Pods e Plugins de Rede do Pod, uma vez que seu cluster incluirá ambos.

      Um pod é uma unidade atômica que executa um ou mais containers. Esses containers compartilham recursos tais como volumes de arquivo e interfaces de rede em comum. Os pods são a unidade básica de scheduling no Kubernetes: todos os containers em um pod têm a garantia de serem executados no mesmo node no qual foi feito o scheduling do pod.

      Cada pod tem seu próprio endereço IP, e um pod em um node deve ser capaz de acessar um pod em outro node utilizando o IP do pod. Os containers em um único node podem se comunicar facilmente através de uma interface local. Contudo, a comunicação entre pods é mais complicada e requer um componente de rede separado que possa encaminhar o tráfego de maneira transparente de um pod em um node para um pod em outro node.

      Essa funcionalidade é fornecida pelos plugins de rede para pods. Para este cluster vamos utilizar o Flannel, uma opção estável e de bom desempenho.

      Crie um playbook Ansible chamado master.yml em sua máquina local:

      • vi ~/kube-cluster/master.yml

      Adicione o seguinte play ao arquivo para inicializar o cluster e instalar o Flannel:

      ~/kube-cluster/master.yml

      
      - hosts: master
        become: yes
        tasks:
          - name: initialize the cluster
            shell: kubeadm init --pod-network-cidr=10.244.0.0/16 >> cluster_initialized.txt
            args:
              chdir: $HOME
              creates: cluster_initialized.txt
      
          - name: create .kube directory
            become: yes
            become_user: centos
            file:
              path: $HOME/.kube
              state: directory
              mode: 0755
      
          - name: copy admin.conf to user's kube config
            copy:
              src: /etc/kubernetes/admin.conf
              dest: /home/centos/.kube/config
              remote_src: yes
              owner: centos
      
          - name: install Pod network
            become: yes
            become_user: centos
            shell: kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.9.1/Documentation/kube-flannel.yml >> pod_network_setup.txt
            args:
              chdir: $HOME
              creates: pod_network_setup.txt
      

      Aqui está um detalhamento deste play:

      • A primeira tarefa inicializa o cluster executando kubeadm init. A passagem do argumento --pod-network-cidr=10.244.0.0/16 especifica a sub-rede privada que os IPs do pod serão atribuídos. O Flannel utiliza a sub-rede acima por padrão; estamos dizendo ao kubeadm para utilizar a mesma sub-rede.

      • A segunda tarefa cria um diretório .kube em /home/centos. Este diretório irá manter as informações de configuração tais como os arquivos de chaves do admin, que são requeridas para conectar no cluster, e o endereço da API do cluster.

      • A terceira tarefa copia o arquivo /etc/kubernetes/admin.conf que foi gerado a partir do kubeadm init para o diretório home do seu usuário não-root centos. Isso irá permitir que você utilize o kubectl para acessar o cluster recém-criado.

      • A última tarefa executa kubectl apply para instalar o Flannel. kubectl apply -f descriptor.[yml|json] é a sintaxe para dizer ao kubectl para criar os objetos descritos no arquivo descriptor.[yml|json]. O arquivo kube-flannel.yml contém as descrições dos objetos requeridos para a configuração do Flannel no cluster.

      Salve e feche o arquivo quando você tiver terminado.

      Execute o playbook:

      • ansible-playbook -i hosts ~/kube-cluster/master.yml

      Na conclusão, você verá uma saída semelhante à seguinte:

      Output

      PLAY [master] **** TASK [Gathering Facts] **** ok: [master] TASK [initialize the cluster] **** changed: [master] TASK [create .kube directory] **** changed: [master] TASK [copy admin.conf to user's kube config] ***** changed: [master] TASK [install Pod network] ***** changed: [master] PLAY RECAP **** master : ok=5 changed=4 unreachable=0 failed=0

      Para verificar o status do node master, faça SSH nele com o seguinte comando:

      Uma vez dentro do node master, execute:

      Agora você verá a seguinte saída:

      Output

      NAME STATUS ROLES AGE VERSION master Ready master 1d v1.10.1

      A saída informa que o node master concluiu todas as tarefas de inicialização e está em um estado Ready do qual pode começar a aceitar nodes worker e executar tarefas enviadas ao Servidor de API. Agora você pode adicionar os workers a partir de sua máquina local.

      Passo 5 — Configurando os Nodes Worker

      A adição de workers ao cluster envolve a execução de um único comando em cada um. Este comando inclui as informações necessárias sobre o cluster, tais como o endereço IP e a porta do Servidor de API do master, e um token seguro. Somentes os nodes que passam no token seguro estarão aptos a ingressar no cluster.

      Navegue de volta para a sua área de trabalho e crie um playbook chamado workers.yml:

      • vi ~/kube-cluster/workers.yml

      Adicione o seguinte texto ao arquivo para adicionar os workers ao cluster:

      ~/kube-cluster/workers.yml

      
      - hosts: master
        become: yes
        gather_facts: false
        tasks:
          - name: get join command
            shell: kubeadm token create --print-join-command
            register: join_command_raw
      
          - name: set join command
            set_fact:
              join_command: "{{ join_command_raw.stdout_lines[0] }}"
      
      
      - hosts: workers
        become: yes
        tasks:
          - name: join cluster
            shell: "{{ hostvars['master'].join_command }} >> node_joined.txt"
            args:
              chdir: $HOME
              creates: node_joined.txt
      

      Aqui está o que o playbook faz:

      • O primeiro play obtém o comando de junção que precisa ser executado nos nodes workers. Este comando estará no seguinte formato: kubeadm join --token <token> <master-ip>:<master-port> --discovery-token-ca-cert-hash sha256:<hash>. Assim que obtiver o comando real com os valores apropriados de token e hash, a tarefa define isso como um fact para que o próximo play possa acessar essa informação.

      • O segundo play tem uma única tarefa que executa o comando de junção em todos os nodes worker. Na conclusão desta tarefa, os dois nodes worker farão parte do cluster.

      Salve e feche o arquivo quando você tiver terminado.

      Execute o playbook:

      • ansible-playbook -i hosts ~/kube-cluster/workers.yml

      Na conclusão, você verá uma saída semelhante à seguinte:

      Output

      PLAY [master] **** TASK [get join command] **** changed: [master] TASK [set join command] ***** ok: [master] PLAY [workers] ***** TASK [Gathering Facts] ***** ok: [worker1] ok: [worker2] TASK [join cluster] ***** changed: [worker1] changed: [worker2] PLAY RECAP ***** master : ok=2 changed=1 unreachable=0 failed=0 worker1 : ok=2 changed=1 unreachable=0 failed=0 worker2 : ok=2 changed=1 unreachable=0 failed=0

      Com a adição dos nodes worker, seu cluster está agora totalmente configurado e funcional, com os workers prontos para executar cargas de trabalho. Antes de fazer o scheduling de aplicações, vamos verificar se o cluster está funcionando conforme o esperado.

      Step 6 — Verificando o Cluster

      Às vezes, um cluster pode falhar durante a configuração porque um node está inativo ou a conectividade de rede entre o master e o worker não está funcionando corretamente. Vamos verificar o cluster e garantir que os nodes estejam operando corretamente.

      Você precisará verificar o estado atual do cluster a partir do node master para garantir que os nodes estejam prontos. Se você se desconectou do node master, pode voltar e fazer SSH com o seguinte comando:

      Em seguida, execute o seguinte comando para obter o status do cluster:

      Você verá uma saída semelhante à seguinte:

      Output

      NAME STATUS ROLES AGE VERSION master Ready master 1d v1.10.1 worker1 Ready <none> 1d v1.10.1 worker2 Ready <none> 1d v1.10.1

      Se todos os seus nodes têm o valor Ready para o STATUS, significa que eles são parte do cluster e estão prontos para executar cargas de trabalho.

      Se, contudo, alguns dos nodes têm NotReady como o STATUS, isso pode significar que os nodes worker ainda não concluíram sua configuração. Aguarde cerca de cinco a dez minutos antes de voltar a executar kubectl get nodes e fazer a inspeção da nova saída. Se alguns nodes ainda têm NotReady como status, talvez seja necessário verificar e executar novamente os comandos nas etapas anteriores.

      Agora que seu cluster foi verificado com sucesso, vamos fazer o scheduling de um exemplo de aplicativo Nginx no cluster.

      Passo 7 — Executando Uma Aplicação no Cluster

      Você pode fazer o deploy de qualquer aplicação containerizada no seu cluster. Para manter as coisas familiares, vamos fazer o deploy do Nginx utilizando Deployments e Services para ver como pode ser feito o deploy dessa aplicação no cluster. Você também pode usar os comandos abaixo para outros aplicativos em container, desde que você altere o nome da imagem do Docker e quaisquer flags relevantes (tais como ports e volumes).

      Ainda no node master, execute o seguinte comando para criar um deployment chamado nginx:

      • kubectl run nginx --image=nginx --port 80

      Um deployment é um tipo de objeto do Kubernetes que garante que há sempre um número especificado de pods em execução com base em um modelo definido, mesmo se o pod falhar durante o tempo de vida do cluster. O deployment acima irá criar um pod com um container do registro do Docker Nginx Docker Image.

      A seguir, execute o seguinte comando para criar um serviço chamado nginx que irá expor o app publicamente. Ele fará isso por meio de um NodePort, um esquema que tornará o pod acessível através de uma porta arbitrária aberta em cada node do cluster:

      • kubectl expose deploy nginx --port 80 --target-port 80<^> --type NodePort

      Services são outro tipo de objeto do Kubernetes que expõe serviços internos do cluster para os clientes, tanto internos quanto externos. Eles também são capazes de fazer balanceamento de solicitações para vários pods e são um componente integral no Kubernetes, interagindo frequentemente com outros componentes.

      Execute o seguinte comando:

      Isso produzirá uma saída semelhante à seguinte:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d nginx NodePort 10.109.228.209 <none> 80:nginx_port/TCP 40m

      A partir da terceira linha da saída acima, você pode obter a porta em que o Nginx está sendo executado. O Kubernetes atribuirá uma porta aleatória maior que 30000 automaticamente, enquanto garante que a porta já não esteja vinculada a outro serviço.

      Para testar se tudo está funcionando, visite http://worker_1_ip:nginx_port ou http://worker_2_ip:nginx_port através de um navegador na sua máquina local. Você verá a familiar página de boas-vindas do Nginx.

      Se você quiser remover o aplicativo Nginx, primeiro exclua o serviço nginx do node master:

      • kubectl delete service nginx

      Execute o seguinte para garantir que o serviço tenha sido excluído:

      Você verá a seguinte saída:

      Output

      NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d

      Para excluir o deployment:

      kubectl delete deployment nginx
      

      Execute o seguinte para confirmar que isso funcionou:

      Output

      No resources found.

      Conclusão

      Neste guia, você configurou com sucesso um cluster do Kubernetes no CentOS 7 usando Kubeadm e Ansible para automação.

      Se você está se perguntando o que fazer com o cluster, agora que ele está configurado, um bom próximo passo seria sentir-se confortável para implantar suas próprias aplicações e serviços no cluster. Aqui está uma lista de links com mais informações que podem orientá-lo no processo:

      • Dockerizing applications - lista exemplos que detalham como containerizar aplicações usando o Docker.

      • Pod Overview - descreve em detalhes como os Pods funcionam e seu relacionamento com outros objetos do Kubernetes. Os pods são onipresentes no Kubernetes, então compreendê-los facilitará seu trabalho.

      • Deployments Overview - fornece uma visão geral dos deployments. É útil entender como os controladores, como os deployments, funcionam, pois eles são usados com frequência em aplicações stateless para escalonamento e na recuperação automatizada de aplicações não íntegras.

      • Services Overview - cobre os serviços ou services, outro objeto frequentemente usado em clusters do Kubernetes. Entender os tipos de serviços e as opções que eles têm é essencial para executar aplicações stateless e stateful.

      Outros conceitos importantes que você pode analisar são Volumes, Ingresses e Secrets, os quais são úteis ao realizar o deploy de aplicações em produção.

      O Kubernetes tem muitas funcionalidades e recursos a oferecer. A Documentação Oficial do Kubernetes é o melhor lugar para aprender sobre conceitos, encontrar guias específicos de tarefas e procurar referências de API para vários objetos.

      Por bsder



      Source link