Audra  Haag

Audra Haag

1660490040

Automate Set Up Of A Kubernetes Cluster with Python and Fabric

In this tutorial, we'll spin up a three-node Kubernetes cluster using Ubuntu 20.04 DigitalOcean droplets. We'll also look at how to automate the set up of a Kubernetes cluster with Python and Fabric.

Source: https://testdriven.io

#kubernetes #python #fabric 

Automate Set Up Of A Kubernetes Cluster with Python and Fabric
Duyen Hoang

Duyen Hoang

1660482840

Tự Động Hóa Thiết Lập Một Cụm Kubernetes Với Python Và Fabric

Trong hướng dẫn này, chúng tôi sẽ tạo ra một cụm Kubernetes ba nút bằng cách sử dụng các giọt Ubuntu 20.04 DigitalOcean. Chúng ta cũng sẽ xem xét cách tự động hóa việc thiết lập một cụm Kubernetes với Python và Fabric.

Hãy trao đổi DigitalOcean cho một nhà cung cấp dịch vụ lưu trữ đám mây khác hoặc môi trường tại chỗ của riêng bạn.

Sự phụ thuộc :

  1. Docker v20.10
  2. Kubernetes v1.21

Fabric là gì?

Fabric là một thư viện Python được sử dụng để tự động hóa các lệnh shell thông thường qua SSH, mà chúng tôi sẽ sử dụng để tự động hóa việc thiết lập một cụm Kubernetes.

Cài đặt:

$ pip install fabric==2.6.0

Xác minh phiên bản:

$ fab --version

Fabric 2.6.0
Paramiko 2.8.0
Invoke 1.6.0

Kiểm tra bằng cách thêm mã sau vào tệp mới có tên fabfile.py :

from fabric import task


@task
def ping(ctx, output):
    """Sanity check"""
    print("pong!")
    print(f"hello {output}!")

Hãy dùng thử:

$ fab ping --output="world"

pong!
hello world!

For more, review the official Fabric docs.

Droplets Setup

First, sign up for an account on DigitalOcean (if you don’t already have one), add a public SSH key to your account, and then generate an access token so you can access the DigitalOcean API.

Add the token to your environment:

$ export DIGITAL_OCEAN_ACCESS_TOKEN=<YOUR_DIGITAL_OCEAN_ACCESS_TOKEN>

Next, to interact with the API programmatically, install the python-digitalocean module:

$ pip install python-digitalocean==1.17.0

Now, let's create another task to spin up three droplets: One for the Kubernetes master and two for the workers. Update fabfile.py like so:

import os

from digitalocean import Droplet, Manager
from fabric import task

DIGITAL_OCEAN_ACCESS_TOKEN = os.getenv("DIGITAL_OCEAN_ACCESS_TOKEN")


# tasks


@task
def ping(ctx, output):
    """Sanity check"""
    print("pong!")
    print(f"hello {output}!")


@task
def create_droplets(ctx):
    """
    Create three new DigitalOcean droplets -
    node-1, node-2, node-3
    """
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    keys = manager.get_all_sshkeys()
    for num in range(3):
        node = f"node-{num + 1}"
        droplet = Droplet(
            token=DIGITAL_OCEAN_ACCESS_TOKEN,
            name=node,
            region="nyc3",
            image="ubuntu-20-04-x64",
            size="s-2vcpu-4gb",
            tags=[node],
            ssh_keys=keys,
        )
        droplet.create()
        print(f"{node} has been created.")

Take note of the arguments passed to the Droplet class. Essentially, this will create three Ubuntu 20.04 droplets in the NYC3 region with 4 GB of memory each. It will also add all SSH keys to each droplet. You may want to update this to only include the SSH key that you created specifically for this project:

@task
def create_droplets(ctx):
    """
    Create three new DigitalOcean droplets -
    node-1, node-2, node-3
    """
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    # Get ALL SSH keys
    all_keys = manager.get_all_sshkeys()
    keys = []
    for key in all_keys:
        if key.name == "<ADD_YOUR_KEY_NAME_HERE>":
            keys.append(key)
    for num in range(3):
        node = f"node-{num + 1}"
        droplet = Droplet(
            token=DIGITAL_OCEAN_ACCESS_TOKEN,
            name=node,
            region="nyc3",
            image="ubuntu-20-04-x64",
            size="s-2vcpu-4gb",
            tags=[node],
            ssh_keys=keys,
        )
        droplet.create()
        print(f"{node} has been created.")

Create the droplets:

$ fab create-droplets

node-1 has been created.
node-2 has been created.
node-3 has been created.

Moving along, let's add a task that checks the status of each droplet, to ensure that each are up and ready to go before we start installing Docker and Kubernetes:

@task
def wait_for_droplets(ctx):
    """Wait for each droplet to be ready and active"""
    for num in range(3):
        node = f"node-{num + 1}"
        while True:
            status = get_droplet_status(node)
            if status == "active":
                print(f"{node} is ready.")
                break
            else:
                print(f"{node} is not ready.")
                time.sleep(1)

Add the get_droplet_status helper function:

def get_droplet_status(node):
    """Given a droplet's tag name, return the status of the droplet"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    droplet = manager.get_all_droplets(tag_name=node)
    return droplet[0].status

Don't forget the import:

import time

Before we test, add another task to destroy the droplets:

@task
def destroy_droplets(ctx):
    """Destroy the droplets - node-1, node-2, node-3"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    for num in range(3):
        node = f"node-{num + 1}"
        droplets = manager.get_all_droplets(tag_name=node)
        for droplet in droplets:
            droplet.destroy()
        print(f"{node} has been destroyed.")

Destroy the three droplets we just created:

$ fab destroy-droplets

node-1 has been destroyed.
node-2 has been destroyed.
node-3 has been destroyed.

Then, bring up three new droplets and verify that they are good to go:

$ fab create-droplets

node-1 has been created.
node-2 has been created.
node-3 has been created.

$ fab wait-for-droplets

node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is ready.
node-2 is not ready.
node-2 is not ready.
node-2 is ready.
node-3 is ready.

Provision the Machines

The following tasks need to be run on each droplet...

Set Addresses

Start by adding a task to set the host addresses in the hosts environment variable:

@@task
def get_addresses(ctx, type):
    """Get IP address"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    if type == "master":
        droplet = manager.get_all_droplets(tag_name="node-1")
        print(droplet[0].ip_address)
        hosts.append(droplet[0].ip_address)
    elif type == "workers":
        for num in range(2, 4):
            node = f"node-{num}"
            droplet = manager.get_all_droplets(tag_name=node)
            print(droplet[0].ip_address)
            hosts.append(droplet[0].ip_address)
    elif type == "all":
        for num in range(3):
            node = f"node-{num + 1}"
            droplet = manager.get_all_droplets(tag_name=node)
            print(droplet[0].ip_address)
            hosts.append(droplet[0].ip_address)
    else:
        print('The "type" should be either "master", "workers", or "all".')
    print(f"Host addresses - {hosts}")

Define the following variables at the top, just below DIGITAL_OCEAN_ACCESS_TOKEN = os.getenv('DIGITAL_OCEAN_ACCESS_TOKEN'):

user = "root"
hosts = []

Run:

$ fab get-addresses --type=all

165.227.96.238
134.122.8.106
134.122.8.204
Host addresses - ['165.227.96.238', '134.122.8.106', '134.122.8.204']

With that, we can start installing the Docker and Kubernetes dependencies.

Install Dependencies

Install Docker along with-

  1. kubeadm - bootstraps a Kubernetes cluster
  2. kubelet - configures containers to run on a host
  3. kubectl - command line tool used managing a cluster

Add a task to install Docker to the fabfile:

@task
def install_docker(ctx):
    """Install Docker"""
    print(f"Installing Docker on {ctx.host}")
    ctx.sudo("apt-get update && apt-get install -qy docker.io")
    ctx.run("docker --version")
    ctx.sudo("systemctl enable docker.service")

Let's disable the swap file:

@task
def disable_selinux_swap(ctx):
    """
    Disable SELinux so kubernetes can communicate with other hosts
    Disable Swap https://github.com/kubernetes/kubernetes/issues/53533
    """
    ctx.sudo('sed -i "/ swap / s/^/#/" /etc/fstab')
    ctx.sudo("swapoff -a")

Install Kubernetes:

@task
def install_kubernetes(ctx):
    """Install Kubernetes"""
    print(f"Installing Kubernetes on {ctx.host}")
    ctx.sudo("apt-get update && apt-get install -y apt-transport-https")
    ctx.sudo(
        "curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -"
    )
    ctx.sudo(
        'echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | \
          tee -a /etc/apt/sources.list.d/kubernetes.list && apt-get update'
    )
    ctx.sudo(
        "apt-get update && apt-get install -y kubelet=1.21.1-00 kubeadm=1.21.1-00 kubectl=1.21.1-00"
    )
    ctx.sudo("apt-mark hold kubelet kubeadm kubectl")

Instead of running each of these separately, create a main provision_machines task:

@task
def provision_machines(ctx):
    for conn in get_connections(hosts):
        install_docker(conn)
        disable_selinux_swap(conn)
        install_kubernetes(conn)

Add the get_connections helper function:

def get_connections(hosts):
    for host in hosts:
        yield Connection(
            f"{user}@{host}",
        )

Update the import:

from fabric import Connection, task

Run:

$ fab get-addresses --type=all provision-machines

Quá trình này sẽ mất vài phút để cài đặt các gói cần thiết.

Định cấu hình nút chính

Init cụm Kubernetes và triển khai mạng flannel :

@task
def configure_master(ctx):
    """
    Init Kubernetes
    Set up the Kubernetes Config
    Deploy flannel network to the cluster
    """
    ctx.sudo("kubeadm init")
    ctx.sudo("mkdir -p $HOME/.kube")
    ctx.sudo("cp -i /etc/kubernetes/admin.conf $HOME/.kube/config")
    ctx.sudo("chown $(id -u):$(id -g) $HOME/.kube/config")
    ctx.sudo(
        "kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml"
    )

Lưu mã thông báo tham gia:

@task
def get_join_key(ctx):
    sudo_command_res = ctx.sudo("kubeadm token create --print-join-command")
    token = re.findall("^kubeadm.*$", str(sudo_command_res), re.MULTILINE)[0]

    with open("join.txt", "w") as f:
        with stdout_redirected(f):
            print(token)

Thêm các lần nhập sau:

import re
import sys
from contextlib import contextmanager

Tạo trình stdout_redirectedquản lý ngữ cảnh:

@contextmanager
def stdout_redirected(new_stdout):
    save_stdout = sys.stdout
    sys.stdout = new_stdout
    try:
        yield None
    finally:
        sys.stdout = save_stdout

Một lần nữa, hãy thêm một nhiệm vụ cha để chạy những điều này:

@task
def create_cluster(ctx):
    for conn in get_connections(hosts):
        configure_master(conn)
        get_join_key(conn)

Chạy nó:

$ fab get-addresses --type=master create-cluster

Quá trình này sẽ mất một hoặc hai phút để chạy. Sau khi hoàn tất, lệnh mã thông báo tham gia sẽ được xuất ra màn hình và được lưu vào tệp join.txt :

kubeadm join 165.227.96.238:6443 --token mvk32y.7z7i5x3viga4f4kn --discovery-token-ca-cert-hash sha256:f358dfc00ae7160fff3cb8fa3e3a3c8865f3c5b83c1f242fc9e51efe94108960

Định cấu hình các nút công nhân

Sử dụng lệnh tham gia đã lưu từ bên trên, thêm một nhiệm vụ để "nối" các công nhân với tổng thể:

@task
def configure_worker_node(ctx):
    """Join a worker to the cluster"""
    with open("join.txt") as f:
        join_command = f.readline()
        for conn in get_connections(hosts):
            conn.sudo(f"{join_command}")

Chạy điều này trên hai nút công nhân:

$ fab get-addresses --type=workers configure-worker-node

Kiểm tra sự tỉnh táo

Cuối cùng, để đảm bảo cụm đang hoạt động, hãy thêm một nhiệm vụ để xem các nút:

@task
def get_nodes(ctx):
    for conn in get_connections(hosts):
        conn.sudo("kubectl get nodes")

Chạy:

$ fab get-addresses --type=master get-nodes

Bạn sẽ thấy một cái gì đó tương tự như:

NAME     STATUS   ROLES                  AGE    VERSION
node-1   Ready    control-plane,master   3m6s   v1.21.1
node-2   Ready    <none>                 84s    v1.21.1
node-3   Ready    <none>                 77s    v1.21.1

Loại bỏ các giọt sau khi hoàn tất:

$ fab destroy-droplets

node-1 has been destroyed.
node-2 has been destroyed.
node-3 has been destroyed.

Tập lệnh tự động hóa

Một điều cuối cùng: Thêm tập lệnh create.sh để tự động hóa toàn bộ quá trình này:

#!/bin/bash


echo "Creating droplets..."
fab create-droplets
fab wait-for-droplets
sleep 20

echo "Provision the droplets..."
fab get-addresses --type=all provision-machines


echo "Configure the master..."
fab get-addresses --type=master create-cluster


echo "Configure the workers..."
fab get-addresses --type=workers configure-worker-node
sleep 20

echo "Running a sanity check..."
fab get-addresses --type=master get-nodes

Hãy dùng thử:

$ sh create.sh

Đó là nó!


Bạn có thể tìm thấy các tập lệnh trong repo kubernetes-Fabric trên GitHub.

Nguồn:  https://testdriven.io

#kubernetes #python #fabric 

Tự Động Hóa Thiết Lập Một Cụm Kubernetes Với Python Và Fabric

Создание кластера Kubernetes с помощью Python и Fabric

В этом руководстве мы развернем кластер Kubernetes с тремя узлами, используя капли Ubuntu 20.04 DigitalOcean. Мы также рассмотрим, как автоматизировать настройку кластера Kubernetes с помощью Python и Fabric.

Не стесняйтесь менять DigitalOcean на другого поставщика облачного хостинга или на собственную локальную среду.

Зависимости :

  1. Докер v20.10
  2. Кубернетес v1.21

Что такое ткань?

Fabric — это библиотека Python, используемая для автоматизации рутинных команд оболочки через SSH, которую мы будем использовать для автоматизации настройки кластера Kubernetes.

Установить:

$ pip install fabric==2.6.0

Проверьте версию:

$ fab --version

Fabric 2.6.0
Paramiko 2.8.0
Invoke 1.6.0

Проверьте это, добавив следующий код в новый файл с именем fabfile.py :

from fabric import task


@task
def ping(ctx, output):
    """Sanity check"""
    print("pong!")
    print(f"hello {output}!")

Попробуйте:

$ fab ping --output="world"

pong!
hello world!

Чтобы узнать больше, ознакомьтесь с официальной документацией Fabric .

Настройка капель

Сначала зарегистрируйте учетную запись в DigitalOcean (если у вас ее еще нет), добавьте открытый ключ SSH в свою учетную запись, а затем создайте токен доступа, чтобы вы могли получить доступ к DigitalOcean API.

Добавьте токен в свою среду:

$ export DIGITAL_OCEAN_ACCESS_TOKEN=<YOUR_DIGITAL_OCEAN_ACCESS_TOKEN>

Далее для программного взаимодействия с API установите модуль python-digitalocean :

$ pip install python-digitalocean==1.17.0

Теперь давайте создадим еще одну задачу для запуска трех дроплетов: одного для мастера Kubernetes и двух для рабочих. Обновите fabfile.py следующим образом:

import os

from digitalocean import Droplet, Manager
from fabric import task

DIGITAL_OCEAN_ACCESS_TOKEN = os.getenv("DIGITAL_OCEAN_ACCESS_TOKEN")


# tasks


@task
def ping(ctx, output):
    """Sanity check"""
    print("pong!")
    print(f"hello {output}!")


@task
def create_droplets(ctx):
    """
    Create three new DigitalOcean droplets -
    node-1, node-2, node-3
    """
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    keys = manager.get_all_sshkeys()
    for num in range(3):
        node = f"node-{num + 1}"
        droplet = Droplet(
            token=DIGITAL_OCEAN_ACCESS_TOKEN,
            name=node,
            region="nyc3",
            image="ubuntu-20-04-x64",
            size="s-2vcpu-4gb",
            tags=[node],
            ssh_keys=keys,
        )
        droplet.create()
        print(f"{node} has been created.")

Обратите внимание на аргументы , переданные классу Droplet. По сути, это создаст три капли Ubuntu 20.04 в регионе NYC3 с 4 ГБ памяти каждая. Он также добавит все ключи SSH в каждую каплю. Вы можете обновить это, чтобы включить только ключ SSH, который вы создали специально для этого проекта:

@task
def create_droplets(ctx):
    """
    Create three new DigitalOcean droplets -
    node-1, node-2, node-3
    """
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    # Get ALL SSH keys
    all_keys = manager.get_all_sshkeys()
    keys = []
    for key in all_keys:
        if key.name == "<ADD_YOUR_KEY_NAME_HERE>":
            keys.append(key)
    for num in range(3):
        node = f"node-{num + 1}"
        droplet = Droplet(
            token=DIGITAL_OCEAN_ACCESS_TOKEN,
            name=node,
            region="nyc3",
            image="ubuntu-20-04-x64",
            size="s-2vcpu-4gb",
            tags=[node],
            ssh_keys=keys,
        )
        droplet.create()
        print(f"{node} has been created.")

Создайте капли:

$ fab create-droplets

node-1 has been created.
node-2 has been created.
node-3 has been created.

Двигаясь дальше, давайте добавим задачу, которая проверяет состояние каждой капли, чтобы убедиться, что каждая из них запущена и готова к работе, прежде чем мы начнем установку Docker и Kubernetes:

@task
def wait_for_droplets(ctx):
    """Wait for each droplet to be ready and active"""
    for num in range(3):
        node = f"node-{num + 1}"
        while True:
            status = get_droplet_status(node)
            if status == "active":
                print(f"{node} is ready.")
                break
            else:
                print(f"{node} is not ready.")
                time.sleep(1)

Добавьте get_droplet_statusвспомогательную функцию:

def get_droplet_status(node):
    """Given a droplet's tag name, return the status of the droplet"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    droplet = manager.get_all_droplets(tag_name=node)
    return droplet[0].status

Не забудьте импорт:

import time

Перед тем, как мы проверим, добавим еще одну задачу на уничтожение дроплетов:

@task
def destroy_droplets(ctx):
    """Destroy the droplets - node-1, node-2, node-3"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    for num in range(3):
        node = f"node-{num + 1}"
        droplets = manager.get_all_droplets(tag_name=node)
        for droplet in droplets:
            droplet.destroy()
        print(f"{node} has been destroyed.")

Уничтожьте три капли, которые мы только что создали:

$ fab destroy-droplets

node-1 has been destroyed.
node-2 has been destroyed.
node-3 has been destroyed.

Затем поднимите три новых капли и убедитесь, что они готовы к работе:

$ fab create-droplets

node-1 has been created.
node-2 has been created.
node-3 has been created.

$ fab wait-for-droplets

node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is ready.
node-2 is not ready.
node-2 is not ready.
node-2 is ready.
node-3 is ready.

Предоставление машин

Следующие задачи необходимо выполнить на каждой капле...

Установить адреса

Начните с добавления задачи для установки адресов хостов в hostsпеременной окружения:

@@task
def get_addresses(ctx, type):
    """Get IP address"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    if type == "master":
        droplet = manager.get_all_droplets(tag_name="node-1")
        print(droplet[0].ip_address)
        hosts.append(droplet[0].ip_address)
    elif type == "workers":
        for num in range(2, 4):
            node = f"node-{num}"
            droplet = manager.get_all_droplets(tag_name=node)
            print(droplet[0].ip_address)
            hosts.append(droplet[0].ip_address)
    elif type == "all":
        for num in range(3):
            node = f"node-{num + 1}"
            droplet = manager.get_all_droplets(tag_name=node)
            print(droplet[0].ip_address)
            hosts.append(droplet[0].ip_address)
    else:
        print('The "type" should be either "master", "workers", or "all".')
    print(f"Host addresses - {hosts}")

Определите следующие переменные вверху, чуть ниже DIGITAL_OCEAN_ACCESS_TOKEN = os.getenv('DIGITAL_OCEAN_ACCESS_TOKEN'):

user = "root"
hosts = []

Бежать:

$ fab get-addresses --type=all

165.227.96.238
134.122.8.106
134.122.8.204
Host addresses - ['165.227.96.238', '134.122.8.106', '134.122.8.204']

После этого мы можем начать установку зависимостей Docker и Kubernetes.

Установить зависимости

Установите Docker вместе с

  1. kubeadm — загружает кластер Kubernetes
  2. kubelet — настраивает контейнеры для запуска на хосте
  3. kubectl — инструмент командной строки, используемый для управления кластером

Добавьте задачу на установку Docker в fabfile:

@task
def install_docker(ctx):
    """Install Docker"""
    print(f"Installing Docker on {ctx.host}")
    ctx.sudo("apt-get update && apt-get install -qy docker.io")
    ctx.run("docker --version")
    ctx.sudo("systemctl enable docker.service")

Отключим файл подкачки:

@task
def disable_selinux_swap(ctx):
    """
    Disable SELinux so kubernetes can communicate with other hosts
    Disable Swap https://github.com/kubernetes/kubernetes/issues/53533
    """
    ctx.sudo('sed -i "/ swap / s/^/#/" /etc/fstab')
    ctx.sudo("swapoff -a")

Установите Кубернетес:

@task
def install_kubernetes(ctx):
    """Install Kubernetes"""
    print(f"Installing Kubernetes on {ctx.host}")
    ctx.sudo("apt-get update && apt-get install -y apt-transport-https")
    ctx.sudo(
        "curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -"
    )
    ctx.sudo(
        'echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | \
          tee -a /etc/apt/sources.list.d/kubernetes.list && apt-get update'
    )
    ctx.sudo(
        "apt-get update && apt-get install -y kubelet=1.21.1-00 kubeadm=1.21.1-00 kubectl=1.21.1-00"
    )
    ctx.sudo("apt-mark hold kubelet kubeadm kubectl")

Вместо того, чтобы запускать каждую из них по отдельности, создайте основную provision_machinesзадачу:

@task
def provision_machines(ctx):
    for conn in get_connections(hosts):
        install_docker(conn)
        disable_selinux_swap(conn)
        install_kubernetes(conn)

Добавьте get_connectionsвспомогательную функцию:

def get_connections(hosts):
    for host in hosts:
        yield Connection(
            f"{user}@{host}",
        )

Обновите импорт:

from fabric import Connection, task

Бежать:

$ fab get-addresses --type=all provision-machines

Установка необходимых пакетов займет несколько минут.

Настройте главный узел

Запустите кластер Kubernetes и разверните фланелевую сеть:

@task
def configure_master(ctx):
    """
    Init Kubernetes
    Set up the Kubernetes Config
    Deploy flannel network to the cluster
    """
    ctx.sudo("kubeadm init")
    ctx.sudo("mkdir -p $HOME/.kube")
    ctx.sudo("cp -i /etc/kubernetes/admin.conf $HOME/.kube/config")
    ctx.sudo("chown $(id -u):$(id -g) $HOME/.kube/config")
    ctx.sudo(
        "kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml"
    )

Сохраните токен присоединения:

@task
def get_join_key(ctx):
    sudo_command_res = ctx.sudo("kubeadm token create --print-join-command")
    token = re.findall("^kubeadm.*$", str(sudo_command_res), re.MULTILINE)[0]

    with open("join.txt", "w") as f:
        with stdout_redirected(f):
            print(token)

Добавьте следующий импорт:

import re
import sys
from contextlib import contextmanager

Создайте stdout_redirectedконтекстный менеджер:

@contextmanager
def stdout_redirected(new_stdout):
    save_stdout = sys.stdout
    sys.stdout = new_stdout
    try:
        yield None
    finally:
        sys.stdout = save_stdout

Опять же, добавьте родительскую задачу для запуска:

@task
def create_cluster(ctx):
    for conn in get_connections(hosts):
        configure_master(conn)
        get_join_key(conn)

Запустить его:

$ fab get-addresses --type=master create-cluster

Это займет минуту или две. После этого команда токена присоединения должна быть выведена на экран и сохранена в файле join.txt :

kubeadm join 165.227.96.238:6443 --token mvk32y.7z7i5x3viga4f4kn --discovery-token-ca-cert-hash sha256:f358dfc00ae7160fff3cb8fa3e3a3c8865f3c5b83c1f242fc9e51efe94108960

Настройте рабочие узлы

Используя сохраненную команду присоединения сверху, добавьте задачу на «присоединение» воркеров к мастеру:

@task
def configure_worker_node(ctx):
    """Join a worker to the cluster"""
    with open("join.txt") as f:
        join_command = f.readline()
        for conn in get_connections(hosts):
            conn.sudo(f"{join_command}")

Запустите это на двух рабочих узлах:

$ fab get-addresses --type=workers configure-worker-node

Санитарная проверка

Наконец, чтобы убедиться, что кластер запущен и работает, добавьте задачу для просмотра узлов:

@task
def get_nodes(ctx):
    for conn in get_connections(hosts):
        conn.sudo("kubectl get nodes")

Бежать:

$ fab get-addresses --type=master get-nodes

Вы должны увидеть что-то похожее на:

NAME     STATUS   ROLES                  AGE    VERSION
node-1   Ready    control-plane,master   3m6s   v1.21.1
node-2   Ready    <none>                 84s    v1.21.1
node-3   Ready    <none>                 77s    v1.21.1

Удалите капли после завершения:

$ fab destroy-droplets

node-1 has been destroyed.
node-2 has been destroyed.
node-3 has been destroyed.

Скрипт автоматизации

И последнее: добавьте скрипт create.sh для полной автоматизации этого процесса:

#!/bin/bash


echo "Creating droplets..."
fab create-droplets
fab wait-for-droplets
sleep 20

echo "Provision the droplets..."
fab get-addresses --type=all provision-machines


echo "Configure the master..."
fab get-addresses --type=master create-cluster


echo "Configure the workers..."
fab get-addresses --type=workers configure-worker-node
sleep 20

echo "Running a sanity check..."
fab get-addresses --type=master get-nodes

Попробуйте:

$ sh create.sh

Вот и все!


Скрипты можно найти в репозитории kubernetes-fabric на GitHub.

Источник:  https://testdriven.io

#kubernetes #python #fabric 

Создание кластера Kubernetes с помощью Python и Fabric

使用 Python 和 Fabric 自動設置 Kubernetes 集群

在本教程中,我們將使用 Ubuntu 20.04 DigitalOcean droplets 啟動一個三節點 Kubernetes 集群。我們還將了解如何使用 Python 和 Fabric 自動設置 Kubernetes 集群。

隨意將 DigitalOcean 換成不同的雲託管服務提供商或您自己的本地環境。

依賴項

  1. 碼頭工人 v20.10
  2. Kubernetes v1.21

什麼是面料?

Fabric是一個 Python 庫,用於通過 SSH 自動執行常規 shell 命令,我們將使用它來自動設置 Kubernetes 集群。

安裝:

$ pip install fabric==2.6.0

驗證版本:

$ fab --version

Fabric 2.6.0
Paramiko 2.8.0
Invoke 1.6.0

通過將以下代碼添加到名為fabfile.py的新文件中來測試它:

from fabric import task


@task
def ping(ctx, output):
    """Sanity check"""
    print("pong!")
    print(f"hello {output}!")

試試看:

$ fab ping --output="world"

pong!
hello world!

有關更多信息,請查看官方 Fabric文檔

液滴設置

首先,在 DigitalOcean 上註冊一個帳戶(如果您還沒有),向您的帳戶添加一個公共 SSH 密鑰,然後生成一個訪問令牌,以便您可以訪問 DigitalOcean API。

將令牌添加到您的環境中:

$ export DIGITAL_OCEAN_ACCESS_TOKEN=<YOUR_DIGITAL_OCEAN_ACCESS_TOKEN>

接下來,要以編程方式與 API 交互,請安裝python-digitalocean模塊:

$ pip install python-digitalocean==1.17.0

現在,讓我們創建另一個任務來啟動三個 Droplet:一個用於 Kubernetes 主服務器,兩個用於工作人員。像這樣更新fabfile.py

import os

from digitalocean import Droplet, Manager
from fabric import task

DIGITAL_OCEAN_ACCESS_TOKEN = os.getenv("DIGITAL_OCEAN_ACCESS_TOKEN")


# tasks


@task
def ping(ctx, output):
    """Sanity check"""
    print("pong!")
    print(f"hello {output}!")


@task
def create_droplets(ctx):
    """
    Create three new DigitalOcean droplets -
    node-1, node-2, node-3
    """
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    keys = manager.get_all_sshkeys()
    for num in range(3):
        node = f"node-{num + 1}"
        droplet = Droplet(
            token=DIGITAL_OCEAN_ACCESS_TOKEN,
            name=node,
            region="nyc3",
            image="ubuntu-20-04-x64",
            size="s-2vcpu-4gb",
            tags=[node],
            ssh_keys=keys,
        )
        droplet.create()
        print(f"{node} has been created.")

記下傳遞給 Droplet 類的參數。從本質上講,這將在 NYC3 區域中創建三個 Ubuntu 20.04 液滴,每個液滴具有 4 GB 內存。它還將所有SSH 密鑰添加到每個 Droplet。您可能希望將其更新為僅包含您專門為此項目創建的 SSH 密鑰:

@task
def create_droplets(ctx):
    """
    Create three new DigitalOcean droplets -
    node-1, node-2, node-3
    """
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    # Get ALL SSH keys
    all_keys = manager.get_all_sshkeys()
    keys = []
    for key in all_keys:
        if key.name == "<ADD_YOUR_KEY_NAME_HERE>":
            keys.append(key)
    for num in range(3):
        node = f"node-{num + 1}"
        droplet = Droplet(
            token=DIGITAL_OCEAN_ACCESS_TOKEN,
            name=node,
            region="nyc3",
            image="ubuntu-20-04-x64",
            size="s-2vcpu-4gb",
            tags=[node],
            ssh_keys=keys,
        )
        droplet.create()
        print(f"{node} has been created.")

創建液滴:

$ fab create-droplets

node-1 has been created.
node-2 has been created.
node-3 has been created.

接下來,讓我們添加一個任務來檢查每個 droplet 的狀態,以確保在我們開始安裝 Docker 和 Kubernetes 之前每個都已啟動並準備就緒:

@task
def wait_for_droplets(ctx):
    """Wait for each droplet to be ready and active"""
    for num in range(3):
        node = f"node-{num + 1}"
        while True:
            status = get_droplet_status(node)
            if status == "active":
                print(f"{node} is ready.")
                break
            else:
                print(f"{node} is not ready.")
                time.sleep(1)

添加get_droplet_status輔助函數:

def get_droplet_status(node):
    """Given a droplet's tag name, return the status of the droplet"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    droplet = manager.get_all_droplets(tag_name=node)
    return droplet[0].status

不要忘記導入:

import time

在我們測試之前,添加另一個任務來銷毀水滴:

@task
def destroy_droplets(ctx):
    """Destroy the droplets - node-1, node-2, node-3"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    for num in range(3):
        node = f"node-{num + 1}"
        droplets = manager.get_all_droplets(tag_name=node)
        for droplet in droplets:
            droplet.destroy()
        print(f"{node} has been destroyed.")

銷毀我們剛剛創建的三個液滴:

$ fab destroy-droplets

node-1 has been destroyed.
node-2 has been destroyed.
node-3 has been destroyed.

然後,調出三個新的小滴並驗證它們是否可以使用:

$ fab create-droplets

node-1 has been created.
node-2 has been created.
node-3 has been created.

$ fab wait-for-droplets

node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is ready.
node-2 is not ready.
node-2 is not ready.
node-2 is ready.
node-3 is ready.

配置機器

需要在每個 Droplet 上運行以下任務...

設置地址

首先添加一個任務來設置hosts環境變量中的主機地址:

@@task
def get_addresses(ctx, type):
    """Get IP address"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    if type == "master":
        droplet = manager.get_all_droplets(tag_name="node-1")
        print(droplet[0].ip_address)
        hosts.append(droplet[0].ip_address)
    elif type == "workers":
        for num in range(2, 4):
            node = f"node-{num}"
            droplet = manager.get_all_droplets(tag_name=node)
            print(droplet[0].ip_address)
            hosts.append(droplet[0].ip_address)
    elif type == "all":
        for num in range(3):
            node = f"node-{num + 1}"
            droplet = manager.get_all_droplets(tag_name=node)
            print(droplet[0].ip_address)
            hosts.append(droplet[0].ip_address)
    else:
        print('The "type" should be either "master", "workers", or "all".')
    print(f"Host addresses - {hosts}")

在頂部定義以下變量,就在下面DIGITAL_OCEAN_ACCESS_TOKEN = os.getenv('DIGITAL_OCEAN_ACCESS_TOKEN')

user = "root"
hosts = []

跑:

$ fab get-addresses --type=all

165.227.96.238
134.122.8.106
134.122.8.204
Host addresses - ['165.227.96.238', '134.122.8.106', '134.122.8.204']

這樣,我們就可以開始安裝 Docker 和 Kubernetes 依賴項了。

安裝依賴項

安裝 Docker 以及 -

  1. kubeadm - 引導 Kubernetes 集群
  2. kubelet - 將容器配置為在主機上運行
  3. kubectl - 用於管理集群的命令行工具

添加任務以將 Docker 安裝到 fabfile:

@task
def install_docker(ctx):
    """Install Docker"""
    print(f"Installing Docker on {ctx.host}")
    ctx.sudo("apt-get update && apt-get install -qy docker.io")
    ctx.run("docker --version")
    ctx.sudo("systemctl enable docker.service")

讓我們禁用交換文件:

@task
def disable_selinux_swap(ctx):
    """
    Disable SELinux so kubernetes can communicate with other hosts
    Disable Swap https://github.com/kubernetes/kubernetes/issues/53533
    """
    ctx.sudo('sed -i "/ swap / s/^/#/" /etc/fstab')
    ctx.sudo("swapoff -a")

安裝 Kubernetes:

@task
def install_kubernetes(ctx):
    """Install Kubernetes"""
    print(f"Installing Kubernetes on {ctx.host}")
    ctx.sudo("apt-get update && apt-get install -y apt-transport-https")
    ctx.sudo(
        "curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -"
    )
    ctx.sudo(
        'echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | \
          tee -a /etc/apt/sources.list.d/kubernetes.list && apt-get update'
    )
    ctx.sudo(
        "apt-get update && apt-get install -y kubelet=1.21.1-00 kubeadm=1.21.1-00 kubectl=1.21.1-00"
    )
    ctx.sudo("apt-mark hold kubelet kubeadm kubectl")

不要單獨運行這些,而是創建一個主provision_machines任務:

@task
def provision_machines(ctx):
    for conn in get_connections(hosts):
        install_docker(conn)
        disable_selinux_swap(conn)
        install_kubernetes(conn)

添加get_connections輔助函數:

def get_connections(hosts):
    for host in hosts:
        yield Connection(
            f"{user}@{host}",
        )

更新導入:

from fabric import Connection, task

跑:

$ fab get-addresses --type=all provision-machines

這將需要幾分鐘來安裝所需的軟件包。

配置主節點

初始化 Kubernetes 集群並部署flannel網絡:

@task
def configure_master(ctx):
    """
    Init Kubernetes
    Set up the Kubernetes Config
    Deploy flannel network to the cluster
    """
    ctx.sudo("kubeadm init")
    ctx.sudo("mkdir -p $HOME/.kube")
    ctx.sudo("cp -i /etc/kubernetes/admin.conf $HOME/.kube/config")
    ctx.sudo("chown $(id -u):$(id -g) $HOME/.kube/config")
    ctx.sudo(
        "kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml"
    )

保存加入令牌:

@task
def get_join_key(ctx):
    sudo_command_res = ctx.sudo("kubeadm token create --print-join-command")
    token = re.findall("^kubeadm.*$", str(sudo_command_res), re.MULTILINE)[0]

    with open("join.txt", "w") as f:
        with stdout_redirected(f):
            print(token)

添加以下導入:

import re
import sys
from contextlib import contextmanager

創建stdout_redirected上下文管理器:

@contextmanager
def stdout_redirected(new_stdout):
    save_stdout = sys.stdout
    sys.stdout = new_stdout
    try:
        yield None
    finally:
        sys.stdout = save_stdout

同樣,添加一個父任務來運行這些:

@task
def create_cluster(ctx):
    for conn in get_connections(hosts):
        configure_master(conn)
        get_join_key(conn)

運行:

$ fab get-addresses --type=master create-cluster

這將需要一兩分鐘才能運行。完成後,應將 join token 命令輸出到屏幕並保存到join.txt文件中:

kubeadm join 165.227.96.238:6443 --token mvk32y.7z7i5x3viga4f4kn --discovery-token-ca-cert-hash sha256:f358dfc00ae7160fff3cb8fa3e3a3c8865f3c5b83c1f242fc9e51efe94108960

配置工作節點

使用上面保存的加入命令,添加一個任務以將工作人員“加入”到主服務器:

@task
def configure_worker_node(ctx):
    """Join a worker to the cluster"""
    with open("join.txt") as f:
        join_command = f.readline()
        for conn in get_connections(hosts):
            conn.sudo(f"{join_command}")

在兩個工作節點上運行:

$ fab get-addresses --type=workers configure-worker-node

完整性檢查

最後,為確保集群啟動並運行,添加一個任務來查看節點:

@task
def get_nodes(ctx):
    for conn in get_connections(hosts):
        conn.sudo("kubectl get nodes")

跑:

$ fab get-addresses --type=master get-nodes

您應該會看到類似於以下內容的內容:

NAME     STATUS   ROLES                  AGE    VERSION
node-1   Ready    control-plane,master   3m6s   v1.21.1
node-2   Ready    <none>                 84s    v1.21.1
node-3   Ready    <none>                 77s    v1.21.1

完成後去除液滴:

$ fab destroy-droplets

node-1 has been destroyed.
node-2 has been destroyed.
node-3 has been destroyed.

自動化腳本

最後一件事:添加一個create.sh腳本來自動化整個過程:

#!/bin/bash


echo "Creating droplets..."
fab create-droplets
fab wait-for-droplets
sleep 20

echo "Provision the droplets..."
fab get-addresses --type=all provision-machines


echo "Configure the master..."
fab get-addresses --type=master create-cluster


echo "Configure the workers..."
fab get-addresses --type=workers configure-worker-node
sleep 20

echo "Running a sanity check..."
fab get-addresses --type=master get-nodes

試試看:

$ sh create.sh

而已!


您可以在 GitHub 上的kubernetes-fabric 存儲庫中找到這些腳本。

來源:  https ://testdriven.io

#kubernetes #python #fabric 

使用 Python 和 Fabric 自動設置 Kubernetes 集群
Shayna  Lowe

Shayna Lowe

1660460700

Créer Un Cluster Kubernetes Avec Python Et Fabric

Dans ce didacticiel, nous allons créer un cluster Kubernetes à trois nœuds à l'aide de droplets Ubuntu 20.04 DigitalOcean. Nous verrons également comment automatiser la configuration d'un cluster Kubernetes avec Python et Fabric.

N'hésitez pas à échanger DigitalOcean contre un autre fournisseur d'hébergement cloud ou votre propre environnement sur site.

Dépendances :

  1. Docker v20.10
  2. Kubernetes v1.21

Qu'est-ce que le tissu ?

Fabric est une bibliothèque Python utilisée pour automatiser les commandes shell de routine sur SSH, que nous utiliserons pour automatiser la configuration d'un cluster Kubernetes.

Installer:

$ pip install fabric==2.6.0

Vérifiez la version :

$ fab --version

Fabric 2.6.0
Paramiko 2.8.0
Invoke 1.6.0

Testez-le en ajoutant le code suivant à un nouveau fichier appelé fabfile.py :

from fabric import task


@task
def ping(ctx, output):
    """Sanity check"""
    print("pong!")
    print(f"hello {output}!")

Essaye le:

$ fab ping --output="world"

pong!
hello world!

Pour en savoir plus, consultez la documentation Fabric officielle .

Configuration des gouttelettes

Tout d'abord, créez un compte sur DigitalOcean (si vous n'en avez pas déjà un), ajoutez une clé SSH publique à votre compte, puis générez un jeton d'accès pour pouvoir accéder à l'API DigitalOcean.

Ajoutez le jeton à votre environnement :

$ export DIGITAL_OCEAN_ACCESS_TOKEN=<YOUR_DIGITAL_OCEAN_ACCESS_TOKEN>

Ensuite, pour interagir avec l'API par programmation, installez le module python-digitalocean :

$ pip install python-digitalocean==1.17.0

Maintenant, créons une autre tâche pour lancer trois gouttelettes : une pour le maître Kubernetes et deux pour les nœuds de calcul. Mettez à jour fabfile.py comme ceci :

import os

from digitalocean import Droplet, Manager
from fabric import task

DIGITAL_OCEAN_ACCESS_TOKEN = os.getenv("DIGITAL_OCEAN_ACCESS_TOKEN")


# tasks


@task
def ping(ctx, output):
    """Sanity check"""
    print("pong!")
    print(f"hello {output}!")


@task
def create_droplets(ctx):
    """
    Create three new DigitalOcean droplets -
    node-1, node-2, node-3
    """
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    keys = manager.get_all_sshkeys()
    for num in range(3):
        node = f"node-{num + 1}"
        droplet = Droplet(
            token=DIGITAL_OCEAN_ACCESS_TOKEN,
            name=node,
            region="nyc3",
            image="ubuntu-20-04-x64",
            size="s-2vcpu-4gb",
            tags=[node],
            ssh_keys=keys,
        )
        droplet.create()
        print(f"{node} has been created.")

Prenez note des arguments passés à la classe Droplet. Essentiellement, cela créera trois gouttelettes Ubuntu 20.04 dans la région NYC3 avec 4 Go de mémoire chacune. Il ajoutera également toutes les clés SSH à chaque droplet. Vous voudrez peut-être mettre à jour ceci pour n'inclure que la clé SSH que vous avez créée spécifiquement pour ce projet :

@task
def create_droplets(ctx):
    """
    Create three new DigitalOcean droplets -
    node-1, node-2, node-3
    """
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    # Get ALL SSH keys
    all_keys = manager.get_all_sshkeys()
    keys = []
    for key in all_keys:
        if key.name == "<ADD_YOUR_KEY_NAME_HERE>":
            keys.append(key)
    for num in range(3):
        node = f"node-{num + 1}"
        droplet = Droplet(
            token=DIGITAL_OCEAN_ACCESS_TOKEN,
            name=node,
            region="nyc3",
            image="ubuntu-20-04-x64",
            size="s-2vcpu-4gb",
            tags=[node],
            ssh_keys=keys,
        )
        droplet.create()
        print(f"{node} has been created.")

Créez les gouttelettes :

$ fab create-droplets

node-1 has been created.
node-2 has been created.
node-3 has been created.

Continuons, ajoutons une tâche qui vérifie l'état de chaque droplet, pour nous assurer que chacun est opérationnel et prêt à fonctionner avant de commencer à installer Docker et Kubernetes :

@task
def wait_for_droplets(ctx):
    """Wait for each droplet to be ready and active"""
    for num in range(3):
        node = f"node-{num + 1}"
        while True:
            status = get_droplet_status(node)
            if status == "active":
                print(f"{node} is ready.")
                break
            else:
                print(f"{node} is not ready.")
                time.sleep(1)

Ajoutez la get_droplet_statusfonction d'assistance :

def get_droplet_status(node):
    """Given a droplet's tag name, return the status of the droplet"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    droplet = manager.get_all_droplets(tag_name=node)
    return droplet[0].status

N'oubliez pas l'importation :

import time

Avant de tester, ajoutez une autre tâche pour détruire les gouttelettes :

@task
def destroy_droplets(ctx):
    """Destroy the droplets - node-1, node-2, node-3"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    for num in range(3):
        node = f"node-{num + 1}"
        droplets = manager.get_all_droplets(tag_name=node)
        for droplet in droplets:
            droplet.destroy()
        print(f"{node} has been destroyed.")

Détruisez les trois gouttelettes que nous venons de créer :

$ fab destroy-droplets

node-1 has been destroyed.
node-2 has been destroyed.
node-3 has been destroyed.

Ensuite, faites apparaître trois nouvelles gouttelettes et vérifiez qu'elles sont prêtes à partir :

$ fab create-droplets

node-1 has been created.
node-2 has been created.
node-3 has been created.

$ fab wait-for-droplets

node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is ready.
node-2 is not ready.
node-2 is not ready.
node-2 is ready.
node-3 is ready.

Provisionner les machines

Les tâches suivantes doivent être exécutées sur chaque droplet...

Définir les adresses

Commencez par ajouter une tâche pour définir les adresses des hôtes dans la hostsvariable d'environnement :

@@task
def get_addresses(ctx, type):
    """Get IP address"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    if type == "master":
        droplet = manager.get_all_droplets(tag_name="node-1")
        print(droplet[0].ip_address)
        hosts.append(droplet[0].ip_address)
    elif type == "workers":
        for num in range(2, 4):
            node = f"node-{num}"
            droplet = manager.get_all_droplets(tag_name=node)
            print(droplet[0].ip_address)
            hosts.append(droplet[0].ip_address)
    elif type == "all":
        for num in range(3):
            node = f"node-{num + 1}"
            droplet = manager.get_all_droplets(tag_name=node)
            print(droplet[0].ip_address)
            hosts.append(droplet[0].ip_address)
    else:
        print('The "type" should be either "master", "workers", or "all".')
    print(f"Host addresses - {hosts}")

Définissez les variables suivantes en haut, juste en dessous DIGITAL_OCEAN_ACCESS_TOKEN = os.getenv('DIGITAL_OCEAN_ACCESS_TOKEN'):

user = "root"
hosts = []

Courir:

$ fab get-addresses --type=all

165.227.96.238
134.122.8.106
134.122.8.204
Host addresses - ['165.227.96.238', '134.122.8.106', '134.122.8.204']

Avec cela, nous pouvons commencer à installer les dépendances Docker et Kubernetes.

Installer les dépendances

Installez Docker avec-

  1. kubeadm - démarre un cluster Kubernetes
  2. kubelet - configure les conteneurs pour qu'ils s'exécutent sur un hôte
  3. kubectl - outil de ligne de commande utilisé pour gérer un cluster

Ajoutez une tâche pour installer Docker dans le fabfile :

@task
def install_docker(ctx):
    """Install Docker"""
    print(f"Installing Docker on {ctx.host}")
    ctx.sudo("apt-get update && apt-get install -qy docker.io")
    ctx.run("docker --version")
    ctx.sudo("systemctl enable docker.service")

Désactivons le fichier d'échange :

@task
def disable_selinux_swap(ctx):
    """
    Disable SELinux so kubernetes can communicate with other hosts
    Disable Swap https://github.com/kubernetes/kubernetes/issues/53533
    """
    ctx.sudo('sed -i "/ swap / s/^/#/" /etc/fstab')
    ctx.sudo("swapoff -a")

Installez Kubernetes :

@task
def install_kubernetes(ctx):
    """Install Kubernetes"""
    print(f"Installing Kubernetes on {ctx.host}")
    ctx.sudo("apt-get update && apt-get install -y apt-transport-https")
    ctx.sudo(
        "curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -"
    )
    ctx.sudo(
        'echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | \
          tee -a /etc/apt/sources.list.d/kubernetes.list && apt-get update'
    )
    ctx.sudo(
        "apt-get update && apt-get install -y kubelet=1.21.1-00 kubeadm=1.21.1-00 kubectl=1.21.1-00"
    )
    ctx.sudo("apt-mark hold kubelet kubeadm kubectl")

Au lieu d'exécuter chacune de ces tâches séparément, créez une provision_machinestâche principale :

@task
def provision_machines(ctx):
    for conn in get_connections(hosts):
        install_docker(conn)
        disable_selinux_swap(conn)
        install_kubernetes(conn)

Ajoutez la get_connectionsfonction d'assistance :

def get_connections(hosts):
    for host in hosts:
        yield Connection(
            f"{user}@{host}",
        )

Mettez à jour l'importation :

from fabric import Connection, task

Courir:

$ fab get-addresses --type=all provision-machines

Cela prendra quelques minutes pour installer les packages requis.

Configurer le nœud maître

Initialisez le cluster Kubernetes et déployez le réseau Flannel :

@task
def configure_master(ctx):
    """
    Init Kubernetes
    Set up the Kubernetes Config
    Deploy flannel network to the cluster
    """
    ctx.sudo("kubeadm init")
    ctx.sudo("mkdir -p $HOME/.kube")
    ctx.sudo("cp -i /etc/kubernetes/admin.conf $HOME/.kube/config")
    ctx.sudo("chown $(id -u):$(id -g) $HOME/.kube/config")
    ctx.sudo(
        "kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml"
    )

Enregistrez le jeton de jointure :

@task
def get_join_key(ctx):
    sudo_command_res = ctx.sudo("kubeadm token create --print-join-command")
    token = re.findall("^kubeadm.*$", str(sudo_command_res), re.MULTILINE)[0]

    with open("join.txt", "w") as f:
        with stdout_redirected(f):
            print(token)

Ajoutez les importations suivantes :

import re
import sys
from contextlib import contextmanager

Créez le stdout_redirectedgestionnaire de contexte :

@contextmanager
def stdout_redirected(new_stdout):
    save_stdout = sys.stdout
    sys.stdout = new_stdout
    try:
        yield None
    finally:
        sys.stdout = save_stdout

Encore une fois, ajoutez une tâche parent pour les exécuter :

@task
def create_cluster(ctx):
    for conn in get_connections(hosts):
        configure_master(conn)
        get_join_key(conn)

Exécuter:

$ fab get-addresses --type=master create-cluster

Cela prendra une minute ou deux à exécuter. Une fois cela fait, la commande join token doit être affichée à l'écran et enregistrée dans un fichier join.txt :

kubeadm join 165.227.96.238:6443 --token mvk32y.7z7i5x3viga4f4kn --discovery-token-ca-cert-hash sha256:f358dfc00ae7160fff3cb8fa3e3a3c8865f3c5b83c1f242fc9e51efe94108960

Configurer les nœuds de travail

À l'aide de la commande jointe enregistrée ci-dessus, ajoutez une tâche pour "joindre" les travailleurs au maître :

@task
def configure_worker_node(ctx):
    """Join a worker to the cluster"""
    with open("join.txt") as f:
        join_command = f.readline()
        for conn in get_connections(hosts):
            conn.sudo(f"{join_command}")

Exécutez ceci sur les deux nœuds de calcul :

$ fab get-addresses --type=workers configure-worker-node

Verification sanitaire

Enfin, pour vous assurer que le cluster est opérationnel, ajoutez une tâche pour afficher les nœuds :

@task
def get_nodes(ctx):
    for conn in get_connections(hosts):
        conn.sudo("kubectl get nodes")

Courir:

$ fab get-addresses --type=master get-nodes

Vous devriez voir quelque chose de similaire à :

NAME     STATUS   ROLES                  AGE    VERSION
node-1   Ready    control-plane,master   3m6s   v1.21.1
node-2   Ready    <none>                 84s    v1.21.1
node-3   Ready    <none>                 77s    v1.21.1

Retirez les gouttelettes une fois terminé :

$ fab destroy-droplets

node-1 has been destroyed.
node-2 has been destroyed.
node-3 has been destroyed.

Script d'automatisation

Une dernière chose : ajoutez un script create.sh pour automatiser ce processus complet :

#!/bin/bash


echo "Creating droplets..."
fab create-droplets
fab wait-for-droplets
sleep 20

echo "Provision the droplets..."
fab get-addresses --type=all provision-machines


echo "Configure the master..."
fab get-addresses --type=master create-cluster


echo "Configure the workers..."
fab get-addresses --type=workers configure-worker-node
sleep 20

echo "Running a sanity check..."
fab get-addresses --type=master get-nodes

Essaye le:

$ sh create.sh

C'est ça!


Vous pouvez trouver les scripts dans le référentiel kubernetes-fabric sur GitHub.

Source :  https://testdrive.io

#kubernetes #python #fabric 

Créer Un Cluster Kubernetes Avec Python Et Fabric

Creación De Un Clúster De Kubernetes Con Python Y Fabric

En este tutorial, pondremos en marcha un clúster de Kubernetes de tres nodos con gotitas de DigitalOcean de Ubuntu 20.04. También veremos cómo automatizar la configuración de un clúster de Kubernetes con Python y Fabric.

No dude en cambiar DigitalOcean por un proveedor de alojamiento en la nube diferente o por su propio entorno local.

Dependencias :

  1. Ventana acoplable v20.10
  2. Kubernetes v1.21

¿Qué es la tela?

Fabric es una biblioteca de Python que se usa para automatizar los comandos de shell de rutina a través de SSH, que usaremos para automatizar la configuración de un clúster de Kubernetes.

Instalar:

$ pip install fabric==2.6.0

Verifique la versión:

$ fab --version

Fabric 2.6.0
Paramiko 2.8.0
Invoke 1.6.0

Pruébelo agregando el siguiente código a un nuevo archivo llamado fabfile.py :

from fabric import task


@task
def ping(ctx, output):
    """Sanity check"""
    print("pong!")
    print(f"hello {output}!")

Pruébalo:

$ fab ping --output="world"

pong!
hello world!

Para obtener más información, consulte los documentos oficiales de Fabric .

Configuración de gotas

Primero, regístrese para obtener una cuenta en DigitalOcean (si aún no tiene una), agregue una clave SSH pública a su cuenta y luego genere un token de acceso para que pueda acceder a la API de DigitalOcean.

Agregue el token a su entorno:

$ export DIGITAL_OCEAN_ACCESS_TOKEN=<YOUR_DIGITAL_OCEAN_ACCESS_TOKEN>

A continuación, para interactuar con la API mediante programación, instale el módulo python-digitalocean :

$ pip install python-digitalocean==1.17.0

Ahora, creemos otra tarea para activar tres gotas: una para el maestro de Kubernetes y dos para los trabajadores. Actualice fabfile.py así:

import os

from digitalocean import Droplet, Manager
from fabric import task

DIGITAL_OCEAN_ACCESS_TOKEN = os.getenv("DIGITAL_OCEAN_ACCESS_TOKEN")


# tasks


@task
def ping(ctx, output):
    """Sanity check"""
    print("pong!")
    print(f"hello {output}!")


@task
def create_droplets(ctx):
    """
    Create three new DigitalOcean droplets -
    node-1, node-2, node-3
    """
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    keys = manager.get_all_sshkeys()
    for num in range(3):
        node = f"node-{num + 1}"
        droplet = Droplet(
            token=DIGITAL_OCEAN_ACCESS_TOKEN,
            name=node,
            region="nyc3",
            image="ubuntu-20-04-x64",
            size="s-2vcpu-4gb",
            tags=[node],
            ssh_keys=keys,
        )
        droplet.create()
        print(f"{node} has been created.")

Tome nota de los argumentos pasados ​​a la clase Droplet. Esencialmente, esto creará tres gotas de Ubuntu 20.04 en la región NYC3 con 4 GB de memoria cada una. También agregará todas las claves SSH a cada gota. Es posible que desee actualizar esto para incluir solo la clave SSH que creó específicamente para este proyecto:

@task
def create_droplets(ctx):
    """
    Create three new DigitalOcean droplets -
    node-1, node-2, node-3
    """
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    # Get ALL SSH keys
    all_keys = manager.get_all_sshkeys()
    keys = []
    for key in all_keys:
        if key.name == "<ADD_YOUR_KEY_NAME_HERE>":
            keys.append(key)
    for num in range(3):
        node = f"node-{num + 1}"
        droplet = Droplet(
            token=DIGITAL_OCEAN_ACCESS_TOKEN,
            name=node,
            region="nyc3",
            image="ubuntu-20-04-x64",
            size="s-2vcpu-4gb",
            tags=[node],
            ssh_keys=keys,
        )
        droplet.create()
        print(f"{node} has been created.")

Crea las gotas:

$ fab create-droplets

node-1 has been created.
node-2 has been created.
node-3 has been created.

Continuando, agreguemos una tarea que verifique el estado de cada droplet, para asegurarnos de que cada uno esté activo y listo antes de comenzar a instalar Docker y Kubernetes:

@task
def wait_for_droplets(ctx):
    """Wait for each droplet to be ready and active"""
    for num in range(3):
        node = f"node-{num + 1}"
        while True:
            status = get_droplet_status(node)
            if status == "active":
                print(f"{node} is ready.")
                break
            else:
                print(f"{node} is not ready.")
                time.sleep(1)

Agregue la get_droplet_statusfunción auxiliar:

def get_droplet_status(node):
    """Given a droplet's tag name, return the status of the droplet"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    droplet = manager.get_all_droplets(tag_name=node)
    return droplet[0].status

No olvides la importación:

import time

Antes de probar, agregue otra tarea para destruir las gotas:

@task
def destroy_droplets(ctx):
    """Destroy the droplets - node-1, node-2, node-3"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    for num in range(3):
        node = f"node-{num + 1}"
        droplets = manager.get_all_droplets(tag_name=node)
        for droplet in droplets:
            droplet.destroy()
        print(f"{node} has been destroyed.")

Destruye las tres gotitas que acabamos de crear:

$ fab destroy-droplets

node-1 has been destroyed.
node-2 has been destroyed.
node-3 has been destroyed.

Luego, muestre tres gotas nuevas y verifique que estén listas para funcionar:

$ fab create-droplets

node-1 has been created.
node-2 has been created.
node-3 has been created.

$ fab wait-for-droplets

node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is ready.
node-2 is not ready.
node-2 is not ready.
node-2 is ready.
node-3 is ready.

Aprovisionar las máquinas

Las siguientes tareas deben ejecutarse en cada gota...

Establecer direcciones

Comience agregando una tarea para configurar las direcciones de host en la hostsvariable de entorno:

@@task
def get_addresses(ctx, type):
    """Get IP address"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    if type == "master":
        droplet = manager.get_all_droplets(tag_name="node-1")
        print(droplet[0].ip_address)
        hosts.append(droplet[0].ip_address)
    elif type == "workers":
        for num in range(2, 4):
            node = f"node-{num}"
            droplet = manager.get_all_droplets(tag_name=node)
            print(droplet[0].ip_address)
            hosts.append(droplet[0].ip_address)
    elif type == "all":
        for num in range(3):
            node = f"node-{num + 1}"
            droplet = manager.get_all_droplets(tag_name=node)
            print(droplet[0].ip_address)
            hosts.append(droplet[0].ip_address)
    else:
        print('The "type" should be either "master", "workers", or "all".')
    print(f"Host addresses - {hosts}")

Defina las siguientes variables en la parte superior, justo debajo DIGITAL_OCEAN_ACCESS_TOKEN = os.getenv('DIGITAL_OCEAN_ACCESS_TOKEN'):

user = "root"
hosts = []

Correr:

$ fab get-addresses --type=all

165.227.96.238
134.122.8.106
134.122.8.204
Host addresses - ['165.227.96.238', '134.122.8.106', '134.122.8.204']

Con eso, podemos comenzar a instalar las dependencias de Docker y Kubernetes.

Instalar dependencias

Instale Docker junto con-

  1. kubeadm : inicia un clúster de Kubernetes
  2. kubelet : configura contenedores para que se ejecuten en un host
  3. kubectl : herramienta de línea de comandos utilizada para administrar un clúster

Agregue una tarea para instalar Docker en el archivo fabfile:

@task
def install_docker(ctx):
    """Install Docker"""
    print(f"Installing Docker on {ctx.host}")
    ctx.sudo("apt-get update && apt-get install -qy docker.io")
    ctx.run("docker --version")
    ctx.sudo("systemctl enable docker.service")

Desactivemos el archivo de intercambio:

@task
def disable_selinux_swap(ctx):
    """
    Disable SELinux so kubernetes can communicate with other hosts
    Disable Swap https://github.com/kubernetes/kubernetes/issues/53533
    """
    ctx.sudo('sed -i "/ swap / s/^/#/" /etc/fstab')
    ctx.sudo("swapoff -a")

Instalar Kubernetes:

@task
def install_kubernetes(ctx):
    """Install Kubernetes"""
    print(f"Installing Kubernetes on {ctx.host}")
    ctx.sudo("apt-get update && apt-get install -y apt-transport-https")
    ctx.sudo(
        "curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -"
    )
    ctx.sudo(
        'echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | \
          tee -a /etc/apt/sources.list.d/kubernetes.list && apt-get update'
    )
    ctx.sudo(
        "apt-get update && apt-get install -y kubelet=1.21.1-00 kubeadm=1.21.1-00 kubectl=1.21.1-00"
    )
    ctx.sudo("apt-mark hold kubelet kubeadm kubectl")

En lugar de ejecutar cada uno de estos por separado, cree una provision_machinestarea principal:

@task
def provision_machines(ctx):
    for conn in get_connections(hosts):
        install_docker(conn)
        disable_selinux_swap(conn)
        install_kubernetes(conn)

Agregue la get_connectionsfunción auxiliar:

def get_connections(hosts):
    for host in hosts:
        yield Connection(
            f"{user}@{host}",
        )

Actualizar la importación:

from fabric import Connection, task

Correr:

$ fab get-addresses --type=all provision-machines

Esto llevará unos minutos para instalar los paquetes necesarios.

Configurar el nodo maestro

Inicie el clúster de Kubernetes e implemente la red de franela :

@task
def configure_master(ctx):
    """
    Init Kubernetes
    Set up the Kubernetes Config
    Deploy flannel network to the cluster
    """
    ctx.sudo("kubeadm init")
    ctx.sudo("mkdir -p $HOME/.kube")
    ctx.sudo("cp -i /etc/kubernetes/admin.conf $HOME/.kube/config")
    ctx.sudo("chown $(id -u):$(id -g) $HOME/.kube/config")
    ctx.sudo(
        "kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml"
    )

Guarde el token de unión:

@task
def get_join_key(ctx):
    sudo_command_res = ctx.sudo("kubeadm token create --print-join-command")
    token = re.findall("^kubeadm.*$", str(sudo_command_res), re.MULTILINE)[0]

    with open("join.txt", "w") as f:
        with stdout_redirected(f):
            print(token)

Agregue las siguientes importaciones:

import re
import sys
from contextlib import contextmanager

Crear el stdout_redirectedadministrador de contexto:

@contextmanager
def stdout_redirected(new_stdout):
    save_stdout = sys.stdout
    sys.stdout = new_stdout
    try:
        yield None
    finally:
        sys.stdout = save_stdout

Nuevamente, agregue una tarea principal para ejecutar estos:

@task
def create_cluster(ctx):
    for conn in get_connections(hosts):
        configure_master(conn)
        get_join_key(conn)

Ejecutarlo:

$ fab get-addresses --type=master create-cluster

Esto tardará uno o dos minutos en ejecutarse. Una vez hecho esto, el comando token de unión debe mostrarse en la pantalla y guardarse en un archivo join.txt :

kubeadm join 165.227.96.238:6443 --token mvk32y.7z7i5x3viga4f4kn --discovery-token-ca-cert-hash sha256:f358dfc00ae7160fff3cb8fa3e3a3c8865f3c5b83c1f242fc9e51efe94108960

Configurar los nodos trabajadores

Usando el comando de unión guardado desde arriba, agregue una tarea para "unir" a los trabajadores al maestro:

@task
def configure_worker_node(ctx):
    """Join a worker to the cluster"""
    with open("join.txt") as f:
        join_command = f.readline()
        for conn in get_connections(hosts):
            conn.sudo(f"{join_command}")

Ejecute esto en los dos nodos trabajadores:

$ fab get-addresses --type=workers configure-worker-node

Prueba de cordura

Finalmente, para asegurarse de que el clúster esté en funcionamiento, agregue una tarea para ver los nodos:

@task
def get_nodes(ctx):
    for conn in get_connections(hosts):
        conn.sudo("kubectl get nodes")

Correr:

$ fab get-addresses --type=master get-nodes

Debería ver algo similar a:

NAME     STATUS   ROLES                  AGE    VERSION
node-1   Ready    control-plane,master   3m6s   v1.21.1
node-2   Ready    <none>                 84s    v1.21.1
node-3   Ready    <none>                 77s    v1.21.1

Retire las gotas una vez hecho:

$ fab destroy-droplets

node-1 has been destroyed.
node-2 has been destroyed.
node-3 has been destroyed.

Guión de automatización

Una última cosa: agregue un script create.sh para automatizar este proceso completo:

#!/bin/bash


echo "Creating droplets..."
fab create-droplets
fab wait-for-droplets
sleep 20

echo "Provision the droplets..."
fab get-addresses --type=all provision-machines


echo "Configure the master..."
fab get-addresses --type=master create-cluster


echo "Configure the workers..."
fab get-addresses --type=workers configure-worker-node
sleep 20

echo "Running a sanity check..."
fab get-addresses --type=master get-nodes

Pruébalo:

$ sh create.sh

¡Eso es todo!


Puede encontrar los scripts en el repositorio kubernetes-fabric en GitHub.

Fuente:  https://testdriven.io

#kubernetes #python #fabric 

Creación De Un Clúster De Kubernetes Con Python Y Fabric

Automatize A Configuração De Um Cluster Kubernetes Com Python E Fabric

Neste tutorial, criaremos um cluster Kubernetes de três nós usando os droplets do Ubuntu 20.04 DigitalOcean. Também veremos como automatizar a configuração de um cluster Kubernetes com Python e Fabric.

Sinta-se à vontade para trocar a DigitalOcean por um provedor de hospedagem em nuvem diferente ou por seu próprio ambiente local.

Dependências :

  1. Docker v20.10
  2. Kubernetes v1.21

O que é Tecido?

Fabric é uma biblioteca Python usada para automatizar comandos de shell de rotina sobre SSH, que usaremos para automatizar a configuração de um cluster Kubernetes.

Instalar:

$ pip install fabric==2.6.0

Verifique a versão:

$ fab --version

Fabric 2.6.0
Paramiko 2.8.0
Invoke 1.6.0

Teste-o adicionando o seguinte código a um novo arquivo chamado fabfile.py :

from fabric import task


@task
def ping(ctx, output):
    """Sanity check"""
    print("pong!")
    print(f"hello {output}!")

Experimente:

$ fab ping --output="world"

pong!
hello world!

Para saber mais, consulte os documentos oficiais do Fabric .

Configuração de gotas

Primeiro, inscreva-se em uma conta na DigitalOcean (se ainda não tiver uma), adicione uma chave SSH pública à sua conta e gere um token de acesso para poder acessar a API da DigitalOcean.

Adicione o token ao seu ambiente:

$ export DIGITAL_OCEAN_ACCESS_TOKEN=<YOUR_DIGITAL_OCEAN_ACCESS_TOKEN>

Em seguida, para interagir com a API programaticamente, instale o módulo python-digitalocean :

$ pip install python-digitalocean==1.17.0

Agora, vamos criar outra tarefa para ativar três droplets: um para o mestre do Kubernetes e dois para os trabalhadores. Atualize fabfile.py assim:

import os

from digitalocean import Droplet, Manager
from fabric import task

DIGITAL_OCEAN_ACCESS_TOKEN = os.getenv("DIGITAL_OCEAN_ACCESS_TOKEN")


# tasks


@task
def ping(ctx, output):
    """Sanity check"""
    print("pong!")
    print(f"hello {output}!")


@task
def create_droplets(ctx):
    """
    Create three new DigitalOcean droplets -
    node-1, node-2, node-3
    """
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    keys = manager.get_all_sshkeys()
    for num in range(3):
        node = f"node-{num + 1}"
        droplet = Droplet(
            token=DIGITAL_OCEAN_ACCESS_TOKEN,
            name=node,
            region="nyc3",
            image="ubuntu-20-04-x64",
            size="s-2vcpu-4gb",
            tags=[node],
            ssh_keys=keys,
        )
        droplet.create()
        print(f"{node} has been created.")

Observe os argumentos passados ​​para a classe Droplet. Essencialmente, isso criará três droplets do Ubuntu 20.04 na região NYC3 com 4 GB de memória cada. Ele também adicionará todas as chaves SSH a cada droplet. Você pode querer atualizar isso para incluir apenas a chave SSH que você criou especificamente para este projeto:

@task
def create_droplets(ctx):
    """
    Create three new DigitalOcean droplets -
    node-1, node-2, node-3
    """
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    # Get ALL SSH keys
    all_keys = manager.get_all_sshkeys()
    keys = []
    for key in all_keys:
        if key.name == "<ADD_YOUR_KEY_NAME_HERE>":
            keys.append(key)
    for num in range(3):
        node = f"node-{num + 1}"
        droplet = Droplet(
            token=DIGITAL_OCEAN_ACCESS_TOKEN,
            name=node,
            region="nyc3",
            image="ubuntu-20-04-x64",
            size="s-2vcpu-4gb",
            tags=[node],
            ssh_keys=keys,
        )
        droplet.create()
        print(f"{node} has been created.")

Crie as gotas:

$ fab create-droplets

node-1 has been created.
node-2 has been created.
node-3 has been created.

Continuando, vamos adicionar uma tarefa que verifica o status de cada droplet, para garantir que cada um esteja ativo e pronto para começar antes de começarmos a instalar o Docker e o Kubernetes:

@task
def wait_for_droplets(ctx):
    """Wait for each droplet to be ready and active"""
    for num in range(3):
        node = f"node-{num + 1}"
        while True:
            status = get_droplet_status(node)
            if status == "active":
                print(f"{node} is ready.")
                break
            else:
                print(f"{node} is not ready.")
                time.sleep(1)

Adicione a get_droplet_statusfunção auxiliar:

def get_droplet_status(node):
    """Given a droplet's tag name, return the status of the droplet"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    droplet = manager.get_all_droplets(tag_name=node)
    return droplet[0].status

Não esqueça da importação:

import time

Antes de testarmos, adicione outra tarefa para destruir as gotículas:

@task
def destroy_droplets(ctx):
    """Destroy the droplets - node-1, node-2, node-3"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    for num in range(3):
        node = f"node-{num + 1}"
        droplets = manager.get_all_droplets(tag_name=node)
        for droplet in droplets:
            droplet.destroy()
        print(f"{node} has been destroyed.")

Destrua as três gotículas que acabamos de criar:

$ fab destroy-droplets

node-1 has been destroyed.
node-2 has been destroyed.
node-3 has been destroyed.

Em seguida, abra três novas gotículas e verifique se elas estão prontas:

$ fab create-droplets

node-1 has been created.
node-2 has been created.
node-3 has been created.

$ fab wait-for-droplets

node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is not ready.
node-1 is ready.
node-2 is not ready.
node-2 is not ready.
node-2 is ready.
node-3 is ready.

Provisionar as máquinas

As seguintes tarefas precisam ser executadas em cada droplet...

Definir endereços

Comece adicionando uma tarefa para definir os endereços de host na hostsvariável de ambiente:

@@task
def get_addresses(ctx, type):
    """Get IP address"""
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    if type == "master":
        droplet = manager.get_all_droplets(tag_name="node-1")
        print(droplet[0].ip_address)
        hosts.append(droplet[0].ip_address)
    elif type == "workers":
        for num in range(2, 4):
            node = f"node-{num}"
            droplet = manager.get_all_droplets(tag_name=node)
            print(droplet[0].ip_address)
            hosts.append(droplet[0].ip_address)
    elif type == "all":
        for num in range(3):
            node = f"node-{num + 1}"
            droplet = manager.get_all_droplets(tag_name=node)
            print(droplet[0].ip_address)
            hosts.append(droplet[0].ip_address)
    else:
        print('The "type" should be either "master", "workers", or "all".')
    print(f"Host addresses - {hosts}")

Defina as seguintes variáveis ​​no topo, logo abaixo DIGITAL_OCEAN_ACCESS_TOKEN = os.getenv('DIGITAL_OCEAN_ACCESS_TOKEN'):

user = "root"
hosts = []

Corre:

$ fab get-addresses --type=all

165.227.96.238
134.122.8.106
134.122.8.204
Host addresses - ['165.227.96.238', '134.122.8.106', '134.122.8.204']

Com isso, podemos começar a instalar as dependências do Docker e do Kubernetes.

Instalar dependências

Instale o Docker junto com-

  1. kubeadm - inicializa um cluster Kubernetes
  2. kubelet - configura contêineres para serem executados em um host
  3. kubectl - ferramenta de linha de comando usada para gerenciar um cluster

Adicione uma tarefa para instalar o Docker no fabfile:

@task
def install_docker(ctx):
    """Install Docker"""
    print(f"Installing Docker on {ctx.host}")
    ctx.sudo("apt-get update && apt-get install -qy docker.io")
    ctx.run("docker --version")
    ctx.sudo("systemctl enable docker.service")

Vamos desabilitar o arquivo de troca:

@task
def disable_selinux_swap(ctx):
    """
    Disable SELinux so kubernetes can communicate with other hosts
    Disable Swap https://github.com/kubernetes/kubernetes/issues/53533
    """
    ctx.sudo('sed -i "/ swap / s/^/#/" /etc/fstab')
    ctx.sudo("swapoff -a")

Instale o Kubernetes:

@task
def install_kubernetes(ctx):
    """Install Kubernetes"""
    print(f"Installing Kubernetes on {ctx.host}")
    ctx.sudo("apt-get update && apt-get install -y apt-transport-https")
    ctx.sudo(
        "curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -"
    )
    ctx.sudo(
        'echo "deb http://apt.kubernetes.io/ kubernetes-xenial main" | \
          tee -a /etc/apt/sources.list.d/kubernetes.list && apt-get update'
    )
    ctx.sudo(
        "apt-get update && apt-get install -y kubelet=1.21.1-00 kubeadm=1.21.1-00 kubectl=1.21.1-00"
    )
    ctx.sudo("apt-mark hold kubelet kubeadm kubectl")

Em vez de executar cada um deles separadamente, crie uma provision_machinestarefa principal:

@task
def provision_machines(ctx):
    for conn in get_connections(hosts):
        install_docker(conn)
        disable_selinux_swap(conn)
        install_kubernetes(conn)

Adicione a get_connectionsfunção auxiliar:

def get_connections(hosts):
    for host in hosts:
        yield Connection(
            f"{user}@{host}",
        )

Atualize a importação:

from fabric import Connection, task

Corre:

$ fab get-addresses --type=all provision-machines

Isso levará alguns minutos para instalar os pacotes necessários.

Configurar o nó mestre

Inicie o cluster Kubernetes e implante a rede flanela :

@task
def configure_master(ctx):
    """
    Init Kubernetes
    Set up the Kubernetes Config
    Deploy flannel network to the cluster
    """
    ctx.sudo("kubeadm init")
    ctx.sudo("mkdir -p $HOME/.kube")
    ctx.sudo("cp -i /etc/kubernetes/admin.conf $HOME/.kube/config")
    ctx.sudo("chown $(id -u):$(id -g) $HOME/.kube/config")
    ctx.sudo(
        "kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml"
    )

Salve o token de associação:

@task
def get_join_key(ctx):
    sudo_command_res = ctx.sudo("kubeadm token create --print-join-command")
    token = re.findall("^kubeadm.*$", str(sudo_command_res), re.MULTILINE)[0]

    with open("join.txt", "w") as f:
        with stdout_redirected(f):
            print(token)

Adicione as seguintes importações:

import re
import sys
from contextlib import contextmanager

Crie o stdout_redirectedgerenciador de contexto:

@contextmanager
def stdout_redirected(new_stdout):
    save_stdout = sys.stdout
    sys.stdout = new_stdout
    try:
        yield None
    finally:
        sys.stdout = save_stdout

Novamente, adicione uma tarefa pai para executá-los:

@task
def create_cluster(ctx):
    for conn in get_connections(hosts):
        configure_master(conn)
        get_join_key(conn)

Executá-lo:

$ fab get-addresses --type=master create-cluster

Isso levará um minuto ou dois para ser executado. Uma vez feito, o comando join token deve ser enviado para a tela e salvo em um arquivo join.txt :

kubeadm join 165.227.96.238:6443 --token mvk32y.7z7i5x3viga4f4kn --discovery-token-ca-cert-hash sha256:f358dfc00ae7160fff3cb8fa3e3a3c8865f3c5b83c1f242fc9e51efe94108960

Configurar os nós de trabalho

Usando o comando de junção salvo acima, adicione uma tarefa para "juntar" os trabalhadores ao mestre:

@task
def configure_worker_node(ctx):
    """Join a worker to the cluster"""
    with open("join.txt") as f:
        join_command = f.readline()
        for conn in get_connections(hosts):
            conn.sudo(f"{join_command}")

Execute isso nos dois nós do trabalhador:

$ fab get-addresses --type=workers configure-worker-node

Verificação de Sanidade

Por fim, para garantir que o cluster esteja funcionando, adicione uma tarefa para visualizar os nós:

@task
def get_nodes(ctx):
    for conn in get_connections(hosts):
        conn.sudo("kubectl get nodes")

Corre:

$ fab get-addresses --type=master get-nodes

Você deve ver algo semelhante a:

NAME     STATUS   ROLES                  AGE    VERSION
node-1   Ready    control-plane,master   3m6s   v1.21.1
node-2   Ready    <none>                 84s    v1.21.1
node-3   Ready    <none>                 77s    v1.21.1

Remova as gotas uma vez feito:

$ fab destroy-droplets

node-1 has been destroyed.
node-2 has been destroyed.
node-3 has been destroyed.

Script de automação

Uma última coisa: adicione um script create.sh para automatizar esse processo completo:

#!/bin/bash


echo "Creating droplets..."
fab create-droplets
fab wait-for-droplets
sleep 20

echo "Provision the droplets..."
fab get-addresses --type=all provision-machines


echo "Configure the master..."
fab get-addresses --type=master create-cluster


echo "Configure the workers..."
fab get-addresses --type=workers configure-worker-node
sleep 20

echo "Running a sanity check..."
fab get-addresses --type=master get-nodes

Experimente:

$ sh create.sh

É isso!


Você pode encontrar os scripts no repositório kubernetes-fabric no GitHub.

Fonte:  https://testdrive.io

#kubernetes #python #fabric 

Automatize A Configuração De Um Cluster Kubernetes Com Python E Fabric
高橋  花子

高橋 花子

1652850540

CouchDBとLevelDB:状態データベースオプションの比較

Hyperledger Fabricは、エンタープライズブロックチェーンソリューションおよびアプリケーションの開発に使用される、オープンソースの許可されたブロックチェーンフレームワークです。Hyperledger Fabricプロジェクトは、Hyperledger内の主要なブロックチェーンプロジェクトの1つであり、業界を超えたブロックチェーンテクノロジーを進歩させるためにLinuxFoundationによって2015年に開始されたマルチプロジェクトの共同作業です。現在、Hyperledger Fabricには、120,000を超える貢献組織、15,000を超えるエンジニアの貢献者が協力してプロジェクトを推進しています。

Hyperledger Fabricはモジュラー(プラグアンドプレイ)アーキテクチャを備えており、毎秒1,000トランザクション(TPS)を超えるトランザクションに到達でき、20,000TPSにアップグレードできます。Hyperledger Fabricは、他のブロックチェーンテクノロジーとは異なり、企業による採用を容易にする特定の機能セットも提供します。これらの機能は次のとおりです。

Hyperledger Fabricは多くの実装が行われており、銀行や金融、国際貿易、モノのインターネットなどの業界で広く使用されています。Hyperledger Fabricは、承認者、コミッター、データベースなど、多くのコンポーネントで構成されています。

HyperledgerFabricネットワークで対話するためのオプション

Hyperledger Fabricネットワークで対話するには、チェーンコード(スマートコントラクトとも呼ばれます)が使用されます。これらのスマートコントラクトは、Go、Node.js、Javaなどのさまざまなプログラミング言語で記述できます。

Hyperledger Fabricは、チェーンコードによって実行されたトランザクションの状態をデータベースに保存します。HyperledgerFabricネットワークによって保存されるレコードには主に2つのタイプがあります。

  • トランザクションログ:これは、Hyperledger Fabricネットワークのブロックチェーンの側面であり、HyperledgerFabricネットワークの現在の状態をもたらしたすべてのトランザクションの記録で構成されます。トランザクションログに保存されるデータは不変であり、LevelDBデータベースに保存されます
  • 世界の状態:これは、特定の時点での元帳の現在の値です。デフォルトでは、FabricネットワークのメインデータベースはLevelDBデータベースであり、特定のトランザクションが完了したときにのみデータが入力されます。ただし、CouchDBデータベースに置き換えることができます

この記事では、CouchDBデータベースとLevelDBデータベースのどちらをワールドステートデータベースとして選択するかについて説明します。

楽しみ!

PostgreSQLやMySQLのようなデータベースを使ってみませんか?

Hyperledger Fabricは、LevelDBとCouchDBのみをサポートし、PostgreSQL、MongoDB、MySQLなどのデータベースはサポートしません。このHyperledgerフォーラムでの議論では、プラグ可能なデータベースのサポートを提供するには、ネットワークとデータベース自体に多くの変更を加える必要があると述べています。プロジェクトは、当面の間、Hyperledgerの開発パイプラインから削除されました。

ただし、状態データベースとしてPostgreSQLなどのデータベースを設定する方法はまだあります。これらの手順に従うことで、Fabricプロジェクトをフォークし、 PostgreSQL、MySQL、MongoDBなどのデータベースをプラグインできます。このIBMの例は、HyperledgerFabricプロジェクトでPostgreSQLをセットアップするために使用できる方法も示しています。

LevelDBとは何ですか?

LevelDBデータベースは、キーと値のペアを格納できる高速データベースです。LevelDBデータベースはSanjayGhemawatとJeffDeanによってGoogleで作成され、現在HyperledgerFabricがトランザクションログを保存するために使用している唯一のデータベースです。前述のように、これはHyperledgerFabricにワールド状態を格納するために使用されるデフォルトのデータベースでもあります。

LevelDBのキーと値のペアは、任意のバイト配列に格納されます。LevelDBは、、、および複合キークエリ、つまりKey、、、およびのみをサポートします。Key rangePut(key, value)GET(key, value)Delete(key)

LevelDBはSQLデータベースではないため、SQLクエリ、インデックス、またはリレーショナルデータモデルはサポートされていません。

LevelDBの利点

  • LevelDBは、CouchDBと比較してオーバーヘッドが少ない、シンプルで高速なデータベースです。
  • データは保存され、キーでマッピングされます
    • 、、、などPut(key, value)の単純な操作を実行できるため、LevelDBの使用が簡単になります。GET(Key, Value)Delete(Key)
  • LevelDBは、データ、スナップショット、およびアトミックバッチでの変更に対する順方向および逆方向の反復をサポートします

LevelDBの制限

  • インデックスとクエリはサポートされていません
  • Put(key, value)、、GET(key, value)やDelete(key)などの単純な操作のみが可能です。
  • SQLデータベースではないため、リレーショナルデータモデルの使い慣れた機能はありません。データはキーと値のペアでのみ保存できます
  • LevelDBデータベースからの大規模なデータセットのクエリは、複雑なクエリとインデックスが許可されていないため、非効率的で複雑です。

CouchDBとは何ですか?

CouchDBデータベースは、Erlangに実装されたオープンソースのドキュメント指向データベースであり、JSON形式でデータを収集して保存します。Hyperledger Fabricユーザーは、デフォルトのLevelDBワールドステートデータベースをCouchDBデータベースに置き換えることができます。これは、利用可能な唯一の代替手段でもあります。

CouchDBは、保存されたJSONコンテンツの豊富なクエリを可能にするNoSQLデータベースです。CouchDBデータベースのデフォルトのクエリ言語はJavaScriptであり、データはJSON形式でスキーマを設定せずに保存できます。

CouchDBはインデックスとページネーションをサポートしています。LevelDBデータベースと同様に、キーに基づいてクエリを実行することもできます。

CouchDBの利点

  • CouchDBではJSONクエリとインデックスが可能であるため、LevelDBよりもHyperledgerFabricネットワークの監査とレポートの要件を満たすことが容易になります。
  • ドキュメント指向データベースとして、CouchDBを使用すると、データを配列または辞書としてデータベースに保存できます。
  • CouchDBデータはHTTPURIを介して公開されます。これにより、データに対してHTTP操作(、、、)を実行できるようにGETなりますDELETEPUTPOST
  • CouchDBを使用すると、チェーンコードの大規模なデータセットをインデックスでより効率的かつ柔軟にクエリできます。

CouchDBの制限

  • CouchDBは、HyperledgerFabricネットワークと並行して別個のデータベースとして実行されます
  • ネットワークを実行するには、データベースの管理、セットアップ、構成などの面で、より多くのコミットメントが必要です。

次のHyperledgerFabricプロジェクトの状態データベースを選択する

状態データベースを選択する前に、Hyperledger Fabricは、Hyperledger Fabricネットワークの起動後にデータベースを変更できないため、データベースを決定する必要があることを知っておく必要があります。

トランザクションの量が少ない単純なHyperledgerFabricプロジェクトを実行している場合、LevelDBの使いやすさと速度により、使用するのが非常に望ましいです。

ただし、より複雑なプロジェクトの場合は、CouchDBデータベースを使用することをお勧めします。CouchDBは、キーに基づいてデータを取得および設定するなど、LevelDBデータベースのすべての機能を備えていますが、JSON形式でのデータの保存、インデックス、クエリの発行、ページネーションなどの追加機能へのアクセスも提供します。データの操作が簡単になります。

CouchDBが提供する機能により、大量のトランザクションを伴うHyperledgerFabricネットワークの管理が容易になります。CouchDBを使用すると、HyperledgerFabricネットワークを実行している最新の組織で必要とされる監査とレポートの要件を簡単に完了することができます。

結論

この記事では、Hyperledger Fabric、CouchDB、およびLevelDBで使用可能なワールドステートデータベースオプションについて説明しました。各データベースの利点と制限について説明し、次のHyperledgerFabricプロジェクト用にデータベースを選択する方法について説明しました。

ソース:https ://blog.logrocket.com/couchdb-vs-leveldb-comparing-state-database-options/ 

#leveldb #couchdb #hyperledger #fabric 

CouchDBとLevelDB:状態データベースオプションの比較
Saul  Alaniz

Saul Alaniz

1652850480

CouchDB Vs. LevelDB: Comparación De Las Opciones De La Base De Datos

Hyperledger Fabric es un marco de cadena de bloques autorizado de código abierto que se utiliza para desarrollar soluciones y aplicaciones de cadenas de bloques empresariales. El proyecto Hyperledger Fabric es uno de los principales proyectos de cadena de bloques dentro de Hyperledger , un esfuerzo de colaboración de varios proyectos iniciado en 2015 por la Fundación Linux para avanzar en las tecnologías de cadena de bloques entre industrias. Actualmente, Hyperledger Fabric cuenta con más de 120 000 organizaciones contribuyentes y más de 15 000 ingenieros contribuyentes que trabajan juntos para avanzar en el proyecto.

Hyperledger Fabric tiene una arquitectura modular (plug-and-play) y puede alcanzar transacciones de más de 1000 transacciones por segundo (TPS), que se pueden actualizar para llegar a 20 000 TPS . Hyperledger Fabric también proporciona un conjunto particular de características que lo diferencia de otras tecnologías de cadena de bloques y permite una adopción más fácil por parte de las empresas. Estas características son:

Hyperledger Fabric ha visto mucha implementación y se usa ampliamente en industrias como la banca y las finanzas, el comercio internacional y el Internet de las cosas. Hyperledger Fabric consta de muchos componentes, como patrocinadores, confirmadores y bases de datos.

Opciones para interactuar en una red Hyperledger Fabric

Para interactuar en una red de Hyperledger Fabric, se utilizan códigos de cadena (también conocidos como contratos inteligentes). Estos contratos inteligentes se pueden escribir en diferentes lenguajes de programación, incluidos Go, Node.js y Java.

Hyperledger Fabric almacena el estado de las transacciones realizadas por códigos de cadena en bases de datos. Hay dos tipos principales de registros almacenados por una red Hyperledger Fabric:

  • Registros de transacciones : este es el aspecto blockchain de la red Hyperledger Fabric, que comprende un registro de todas las transacciones que dieron como resultado el estado actual de la red Hyperledger Fabric. Los datos almacenados en el registro de transacciones son inmutables y se almacenan en una base de datos LevelDB
  • Estado mundial : este es el valor actual del libro mayor en un momento dado. La base de datos principal de la red Fabric, de manera predeterminada, es una base de datos LevelDB y solo se completa cuando se completa una transacción determinada; sin embargo, se puede reemplazar con una base de datos Couch DB

En este artículo, vamos a discutir cómo elegir entre las bases de datos CouchDB y LevelDB como su base de datos de estado mundial.

¡Disfrutar!

¿Por qué no usar una base de datos como PostgreSQL o MySQL?

Hyperledger Fabric solo brinda soporte para LevelDB y CouchDB y no brinda soporte para bases de datos como PostgreSQL, MongoDB o MySQL. Una discusión en este foro de Hyperledger establece que, para brindar soporte para bases de datos conectables, se deben realizar muchos cambios en la red y la base de datos. El proyecto ha sido eliminado de la tubería de desarrollo de Hyperledger por el momento.

Sin embargo, todavía hay formas de configurar una base de datos como PostgreSQL como su base de datos estatal. Puede bifurcar el proyecto Fabric y conectar una base de datos como PostgreSQL, MySQL o MongoDB siguiendo estas instrucciones. Este ejemplo de IBM también muestra un método que puede usar para configurar PostgreSQL en su proyecto Hyperledger Fabric.

¿Qué es LevelDB?

La base de datos LevelDB es una base de datos rápida que le permite almacenar pares clave-valor. La base de datos LevelDB fue escrita en Google por Sanjay Ghemawat y Jeff Dean, y actualmente es la única base de datos utilizada por Hyperledger Fabric para almacenar registros de transacciones. Como se mencionó anteriormente, también es la base de datos predeterminada utilizada para almacenar el estado mundial en Hyperledger Fabric.

Los pares clave-valor de LevelDB se almacenan en matrices de bytes arbitrarias. LevelDB proporciona soporte solo para Key, Key rangey consultas de clave compuesta, es decir, Put(key, value), GET(key, value)y Delete(key).

No hay soporte para consultas SQL, índices o modelos de datos relacionales, ya que LevelDB no es una base de datos SQL.

Ventajas de LevelDB

  • LevelDB es una base de datos simple y rápida con menos gastos generales en comparación con CouchDB
  • Los datos se almacenan y mapean con claves
    • Puede realizar operaciones simples, como Put(key, value), GET(Key, Value)y Delete(Key), lo que hace que LevelDB sea menos complejo de usar
  • LevelDB admite iteraciones hacia adelante y hacia atrás sobre los datos, instantáneas y cambios en lotes atómicos

Limitaciones de LevelDB

  • No hay soporte para índices y consultas.
  • Solo permite operaciones simples, como Put(key, value), GET(key, value)y Eliminar (tecla)
  • Ninguna de las características familiares de un modelo de datos relacional, ya que no es una base de datos SQL. Los datos solo se pueden almacenar en pares clave-valor
  • Consultar grandes conjuntos de datos desde una base de datos LevelDB es ineficiente y complejo, ya que no se permiten consultas e índices complejos.

¿Qué es CouchDB?

La base de datos CouchDB es una base de datos orientada a documentos de código abierto implementada en Erlang que recopila y almacena datos en formato JSON. Los usuarios de Hyperledger Fabric pueden reemplazar su base de datos de estado mundial LevelDB predeterminada con una base de datos CouchDB, que también es la única alternativa disponible.

CouchDB es una base de datos NoSQL que permite consultas enriquecidas del contenido JSON almacenado. El lenguaje de consulta predeterminado en una base de datos de CouchDB es JavaScript y los datos se pueden almacenar sin un esquema establecido en formato JSON.

CouchDB admite índices y paginación. También puede realizar consultas basadas en claves, como con la base de datos LevelDB.

Ventajas de CouchDB

  • CouchDB permite consultas e índices JSON, lo que facilita el cumplimiento de los requisitos de informes y auditoría de red de Hyperledger Fabric que en LevelDB.
  • Como base de datos orientada a documentos, CouchDB le permite almacenar datos como matrices o diccionarios en la base de datos.
  • Los datos de CouchDB se exponen a través de un URI HTTP. Esto hace posible realizar operaciones HTTP ( GET, DELETE, PUT, POST) contra sus datos
  • CouchDB hace que la consulta de grandes conjuntos de datos de código de cadena sea más eficiente y flexible con índices

Limitaciones de CouchDB

  • CouchDB se ejecuta como una base de datos separada junto con la red Hyperledger Fabric
  • Se necesita más compromiso en términos de administración de bases de datos, instalación, configuraciones, etc. para ejecutar la red.

Elegir una base de datos estatal para su próximo proyecto de Hyperledger Fabric

Antes de elegir una base de datos estatal, debe saber que debe decidirse por una base de datos porque Hyperledger Fabric no le permite cambiar la base de datos después de que se haya lanzado la red Hyperledger Fabric.

Si está ejecutando un proyecto simple de Hyperledger Fabric con un bajo volumen de transacciones, la facilidad de uso y la velocidad de LevelDB lo hacen muy preferible de usar.

Sin embargo, para proyectos más complejos, es preferible utilizar una base de datos CouchDB. CouchDB tiene todas las funciones de la base de datos LevelDB, como obtener y configurar datos basados ​​en claves, pero también brinda acceso a funciones adicionales, como almacenar datos en formato JSON, índices, emitir consultas, paginación, etc., todo lo cual hace trabajar con datos más fácilmente.

Las funciones proporcionadas por CouchDB facilitan la gestión de una red Hyperledger Fabric con grandes volúmenes de transacciones. CouchDB también facilita el cumplimiento de los requisitos de auditoría e informes necesarios en una organización moderna que ejecuta una red Hyperledger Fabric.

Conclusión

En este artículo, hablamos sobre las opciones de bases de datos de estado mundial disponibles en Hyperledger Fabric, CouchDB y LevelDB. Explicamos las ventajas y limitaciones de cada base de datos y discutimos cómo elegir una base de datos para su próximo proyecto de Hyperledger Fabric.

Fuente: https://blog.logrocket.com/couchdb-vs-leveldb-comparing-state-database-options/

#leveldb #couchdb #hyperledger #fabric 

CouchDB Vs. LevelDB: Comparación De Las Opciones De La Base De Datos

denny ho

1622187897

China textile manufacturer custom printed cotton fabric

China factory manufacture macaloo textile company do custom your own pattern printed cotton fabric.Vibrant color.Soft and silky smooth handfeel.Great pricing.

#fabric

China textile manufacturer custom printed cotton fabric

Execute Remote Command Over SSH Using Python Fabric

Fabric is a high level Python (2.7, 3.4+) library designed to execute shell commands remotely over SSH

In the simple explanation is we can execute some command into the remote VPS/Droplet/Machine using python script over SSH. Fabric builds on top of Invoke (subprocess command execution and command-line features) and Paramiko (SSH protocol implementation), extending their APIs to complement one another and provide additional functionality.

When We Use Fabric?

This is only a sample use case. Imagine we have two VPS. Which one is a test server, and another one is a production server. Whenever we push our code into git, the test server will be hooked to execute a test script that will test our code, run a linter, and another you want. After the test script is passed then run a remote script to execute the production script in the production server. To execute the production script, we need Fabric.

How To Get Started

Before we start to try fabric, we need to install the Fabric module first. Pip is a great python package. You can use pip to install packages from the Python Package Index and other indexes.

#python #deployment #devops #fabric #ssh

Execute Remote Command Over SSH Using Python Fabric
Myah  Conn

Myah Conn

1593530460

Creating a Kubernetes Cluster on DigitalOcean with Python and Fabric

In this tutorial, we’ll spin up a three-node Kubernetes cluster using Ubuntu 20.04 DigitalOcean droplets. We’ll also look at how to automate the setup of a Kubernetes cluster with Python and Fabric.

Feel free to swap out DigitalOcean for a different cloud hosting provider or your own on-premise environment.

Dependencies:

  1. Docker v19.03.8
  2. Kubernetes v1.18.3

What is Fabric?

Fabric is a Python library used for automating routine shell commands over SSH, which we’ll be using to automate the setup of a Kubernetes cluster.

Install:

$ pip install fabric==2.5.0

Verify the version:

$ fab --version

Fabric 2.5.0
Paramiko 2.7.1
Invoke 1.4.1

Test it out by adding the following code to a new file called fabfile.py:

from fabric import task

@task
def ping(ctx, output):
    """ Sanity check """
    print(f'pong!')
    print(f'hello {output}!')

Try it out:

$ fab ping --output="world"

pong!
hello world!

For more, review the official Fabric docs.

Droplets Setup

First, sign up for an account on DigitalOcean (if you don’t already have one), add a public SSH key to your account, and then generate an access token so you can access the DigitalOcean API.

Add the token to your environment:

$ export DIGITAL_OCEAN_ACCESS_TOKEN=<YOUR_DIGITAL_OCEAN_ACCESS_TOKEN>

Next, to interact with the API programmatically, install the python-digitalocean module:

$ pip install python-digitalocean==1.15.0

Now, let’s create another task to spin up three droplets: one for the Kubernetes master and two for the workers. Update fabfile.py like so:

import os

from fabric import task
from digitalocean import Droplet, Manager

DIGITAL_OCEAN_ACCESS_TOKEN = os.getenv('DIGITAL_OCEAN_ACCESS_TOKEN')

# tasks

@task
def ping(ctx, output):
    """ Sanity check """
    print(f'pong!')
    print(f'hello {output}!')

@task
def create_droplets(ctx):
    """
    Create three new DigitalOcean droplets -
    node-1, node-2, node-3
    """
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    keys = manager.get_all_sshkeys()
    for num in range(3):
        node = f'node-{num + 1}'
        droplet = Droplet(
            token=DIGITAL_OCEAN_ACCESS_TOKEN,
            name=node,
            region='nyc3',
            image='ubuntu-20-04-x64',
            size_slug='4gb',
            tags=[node],
            ssh_keys=keys,
        )
        droplet.create()
        print(f'{node} has been created.')

Take note of the arguments passed to the Droplet class. Essentially, we’re creating three Ubuntu 20.04 droplets in the NYC3 region with 4 GB of memory each. We’re also adding all SSH keys to each droplet. You may want to update this to only include the SSH key that you created specifically for this project:

@task
def create_droplets(ctx):
    """
    Create three new DigitalOcean droplets -
    node-1, node-2, node-3
    """
    manager = Manager(token=DIGITAL_OCEAN_ACCESS_TOKEN)
    # Get ALL SSH keys
    all_keys = manager.get_all_sshkeys()
    keys = []
    for key in all_keys:
        if key.name == '<ADD_YOUR_KEY_NAME_HERE>':
            keys.append(key)
    for num in range(3):
        node = f'node-{num + 1}'
        droplet = Droplet(
            token=DIGITAL_OCEAN_ACCESS_TOKEN,
            name=node,
            region='nyc3',
            image='ubuntu-20-04-x64',
            size_slug='4gb',
            tags=[node],
            ssh_keys=keys,
        )
        droplet.create()
        print(f'{node} has been created.')

Create the droplets:

$ fab create-droplets

node-1 has been created.
node-2 has been created.
node-3 has been created.

Moving along, let’s add a task that checks the status of each droplet, to ensure that each are up and ready to go before we start installing Docker and Kubernetes:

#kubernetes #fabric #python

Creating a Kubernetes Cluster on DigitalOcean with Python and Fabric