Перейти к содержанию

▍Разворачиваем Kubernetes через Ansible

Подготовка:

virt-customize -a noble-server-cloudimg-amd64.img --install qemu-guest-agent

virt-customize -a noble-server-cloudimg-amd64.img --run-command 'useradd --shell /bin/bash kube_admin'

Установка коллекций:

ansible-galaxy collection install kubernetes.core
ansible-galaxy collection install community.kubernetes
ansible-galaxy collection install cloud.common

Создаём директорию, где будут храниться плейбуки:

mkdir -pv ~/ansible/playbook ~/ansible/inventory

Устанавливаем kubectl:

sudo apt update && sudo apt upgrade –y
sudo apt install python3-pip

#Download Kubernetes Tools using Curl:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"

#Verify Checksum (Response should be kubectl:OK):
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"

echo "$(cat kubectl.sha256)  kubectl" | sha256sum --check

#Install Kubernetes Tools:
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

#Validate install:
┌─( daffin@srv-manager ) - ( 36 files, 55M ) - ( ~ )
└─> kubectl version
Client Version: v1.30.1
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
The connection to the server localhost:8080 was refused - did you specify the right host or port?

Создаём плейбуки для подготовки нод:

nano ~/ansible/playbooks/kube_dependencies.yml
- name: Kubernetes Dependencies
  hosts: all
  become: yes
  tasks:
    - name: Updates
      apt:
        update_cache: yes

    - name: Reboot
      reboot:

    - name: Disable SWAP
      shell: |
        swapoff -a

    - name: Disable SWAP in fstab
      replace:
        path: /etc/fstab
        regexp: '^([^#].*?\sswap\s+sw\s+.*)$'
        replace: '# \1'

    - name: Create an empty file for the containerd module
      copy:
        content: ""
        dest: /etc/modules-load.d/containerd.conf
        force: no

    - name: Configure modules for containerd
      blockinfile:
        path: /etc/modules-load.d/containerd.conf
        block: |
          overlay
          br_netfilter

    - name: Create an empty file for K8S sysctl parameters
      copy:
        content: ""
        dest: /etc/sysctl.d/99-kubernetes-cri.conf
        force: no

    - name: Configure sysctl parameters for K8S
      lineinfile:
        path: /etc/sysctl.d/99-kubernetes-cri.conf
        line: "{{ item }}"
      with_items:
        - "net.bridge.bridge-nf-call-iptables  = 1"
        - "net.ipv4.ip_forward                 = 1"
        - "net.bridge.bridge-nf-call-ip6tables = 1"

    - name: Apply sysctl parameters
      command: sysctl --system

    - name: Install APT Transport HTTPS
      apt:
        name: apt-transport-https
        state: present

    - name: Add Docker apt-key
      get_url:
        url: https://download.docker.com/linux/ubuntu/gpg
        dest: /etc/apt/keyrings/docker-apt-keyring.asc
        mode: "0644"
        force: true

    - name: Add Docker's APT repo
      apt_repository:
        repo: "deb [arch={{ 'amd64' if ansible_architecture == 'x86_64' else 'arm64' }} signed-by=/etc/apt/keyrings/docker-apt-keyring.asc] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable"
        state: present
        update_cache: yes

    - name: Add Kubernetes apt-key
      get_url:
        url: https://pkgs.k8s.io/core:/stable:/v1.29/deb/Release.key
        dest: /etc/apt/keyrings/kubernetes-apt-keyring.asc
        mode: "0644"
        force: true

    - name: Add Kubernetes APT repository
      apt_repository:
        repo: "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.asc] https://pkgs.k8s.io/core:/stable:/v1.29/deb/ /"
        state: present
        update_cache: yes

    - name: Install containerd
      apt:
        name: containerd.io
        state: present

    - name: Create containerd directory
      file:
        path: /etc/containerd
        state: directory

    - name: Add containerd configuration
      shell: /usr/bin/containerd config default > /etc/containerd/config.toml

    - name: Configuring Systemd cgroup driver for containerd
      lineinfile:
        path: /etc/containerd/config.toml
        regexp: "            SystemdCgroup = false"
        line: "            SystemdCgroup = true"

    - name: Enable the containerd service and start service
      systemd:
        name: containerd
        state: restarted
        enabled: yes
        daemon-reload: yes

    - name: Install Kubelet
      apt:
        name: kubelet=1.29.*
        state: present
        update_cache: true

    - name: Install Kubeadm
      apt:
        name: kubeadm=1.29.*
        state: present

    - name: Enable the Kubelet service
      service:
        name: kubelet
        enabled: yes

    - name: Load br_netfilter kernel module
      modprobe:
        name: br_netfilter
        state: present

    - name: Set bridge-nf-call-iptables
      sysctl:
        name: net.bridge.bridge-nf-call-iptables
        value: 1

    - name: Set ip_forward
      sysctl:
        name: net.ipv4.ip_forward
        value: 1

    - name: Reboot
      reboot:

- hosts: master
  become: yes
  tasks:
    - name: Install Kubectl
      apt:
        name: kubectl=1.29.*
        state: present
        force: yes

Чтобы запустить плейбук зависимостей (Dependency playbook), используйте следующую команду на контрольной ноде Ansible:

ansible-playbook ~/ansible/playbooks/kube_dependencies.yml -i ~/ansible/inventory/kube_inventory

После успешного развёртывания зависимостей на всех нодах мы можем перейти к инициализации Мастер ноды с Kubernetes. Создайте плейбук kube_master.yml в папке ~/ansible/playbooks/.

Обязательно замените YOUR_USERPROFILE_NAME на имя вашего профиля пользователя, который находится в каталоге /home/ (например, я использую kube_admin).

nano ~/ansible/playbooks/kube_master.yml
- hosts: master
  become: yes
  tasks:
    - name: Create an Empty file for Kubeadm configuring
      copy:
        content: ""
        dest: /etc/kubernetes/kubeadm-config.yaml
        force: no

    - name: Configure container runtime
      blockinfile:
        path: /etc/kubernetes/kubeadm-config.yaml
        block: |
          kind: ClusterConfiguration
          apiVersion: kubeadm.k8s.io/v1beta3
          networking:
            podSubnet: "10.244.0.0/16"
          ---
          kind: KubeletConfiguration
          apiVersion: kubelet.config.k8s.io/v1beta1
          runtimeRequestTimeout: "15m"
          cgroupDriver: "systemd"
          systemReserved:
            cpu: 100m
            memory: 350M
          kubeReserved:
            cpu: 100m
            memory: 50M
          enforceNodeAllocatable:
          - pods

    - name: Initialize the cluster
      shell: kubeadm init --config /etc/kubernetes/kubeadm-config.yaml >> cluster_initialized.log
      args:
        chdir: /home/YOUR_USERPROFILE_NAME
        creates: cluster_initialized.log

    - name: Create .kube directory
      become: yes
      become_user: YOUR_USERPROFILE_NAME
      file:
        path: $HOME/.kube
        state: directory
        mode: 0755

    - name: Copy admin.conf to User's kube config
      copy:
        src: /etc/kubernetes/admin.conf
        dest: /home/YOUR_USERPROFILE_NAME/.kube/config
        remote_src: yes
        owner: YOUR_USERPROFILE_NAME

    - name: Install Pod Network
      become: yes
      become_user: YOUR_USERPROFILE_NAME
      shell: kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml >> pod_network_setup.log
      args:
        chdir: $HOME
        creates: pod_network_setup.log

Чтобы запустить мастер-плейбук, используйте следующую команду на контрольной ноде Ansible:

ansible-playbook ~/ansible/playbooks/kube_master.yml -i ~/ansible/inventory/kube_inventory

После успешного развёртывания на мастер ноде мы можем перейти к развёртыванию на рабочих нодах, чтобы подключить их к мастер ноде. Создадим kube_workers.yml в папке ~/ansible/playbooks/.

Обязательно замените YOUR_MASTER_IP на IP-адрес вашей мастер ноды, а также замените YOUR_USERPROFILE_NAME на имя вашего профиля пользователя, который находится в каталоге /home/.

nano ~/ansible/playbooks/kube_workers.yml
- name: Configure Join Commands on Master Node
  hosts: master
  become: yes
  tasks:
    - name: Retrieve Join Command
      shell: kubeadm token create --print-join-command
      register: join_command_raw

    - name: Set Join Command
      set_fact:
        join_command: "{{ join_command_raw.stdout_lines[0] }}"

- name: Join Worker Nodes
  hosts: workers
  become: yes
  tasks:
    - name: Enable TCP port 6443 (On Master) is able to connect from Worker
      wait_for: "host=YOUR_MASTER_IP port=6443 timeout=1"

    - name: Join worker to cluster
      shell: "{{ hostvars['YOUR_MASTER_IP'].join_command }} >> node_joined.log"
      args:
        chdir: /home/YOUR_USERPROFILE_NAME
        creates: node_joined.log

Чтобы запустить плейбук для рабочих нодах, используйте следующую команду на вашей контрольной ноде Ansible:

ansible-playbook ~/ansible/playbooks/kube_workers.yml -i ~/ansible/inventory/kube_inventory

После успешного выполнения плейбука вы можете проверить, что кластер работает правильно, выполнив следующие команды с Мастер ноды:

kubectl get nodes
kubectl get all -A

Теперь добавим kube config мастер ноды в наш /etc/kube/config на прокси.

К началу