Описание задания

  • Автоматизируйте кластер Kubernetes с помощью Ansible.
  • Запустите EC2-инстансы в облаке AWS для ведущего и ведомого.
  • Создайте роли, которые будут настраивать главный узел и подчиненный узел отдельно.
  • Запустите базу данных WordPress и MySQL, подключенную к ней, на соответствующих ведомых устройствах.
  • Откройте модуль WordPress, и клиент сможет подключиться к IP-адресу WordPress через соответствующий порт.

Давайте сначала создадим динамический инвентарь

Установка Python3: $ yum install python3 -y

Установка библиотеки boto3: $ pip3 install boto

Создание каталога инвентаря:

$ mkdir -p /opt/ansible/inventory
$ cd /opt/ansible/inventory

Создание файла aws_ec2.yaml в каталоге inventory со следующей конфигурацией:

plugin: aws_ec2
aws_access_key: <YOUR-AWS-ACCESS-KEY-HERE>
aws_secret_key: <YOUR-AWS-SECRET-KEY-HERE>
keyed_groups:
  - key: tags
    prefix: tag

Откройте /etc/ansible/ansible.cfg, найдите раздел [inventory] и добавьте следующую строку, чтобы включить плагин ec2:

[inventory]
enable_plugins = aws_ec2

Теперь давайте протестируем конфигурацию динамической инвентаризации, перечислив экземпляры EC2:

$ ansible-inventory -i /opt/ansible/inventory/aws_ec2.yaml --list

Приведенная выше команда возвращает список экземпляров EC2 со всеми его параметрами в формате JSON.

Теперь проверьте, может ли Ansible пинговать все машины, возвращаемые динамической инвентаризацией: ansible all -m ping

Настройка динамического инвентаря завершена.

Запуск одного главного и двух подчиненных узлов на AWS

ansible-playbook <file_name>

Я использовал файл aws.yml для запуска трех экземпляров поверх облака AWS для запуска двух подчиненных узлов и одного главного узла.

- hosts: localhost
  vars_files:
          secret.yml
  tasks:
         - name: "Creating Master Node"
           ec2:
                 region: ap-south-1
                 aws_access_key: "{{ access_key }}"
                 aws_secret_key: "{{ secret_key }}"
                 vpc_subnet_id: subnet-0288bbf00ed3128d7
                 count: 1
                 state: present
                 instance_type: t2.micro
                 key_name: redhat-key
                 assign_public_ip: yes
                 group_id: sg-0612a79a1fdb041ff
                 image: ami-08f63db601b82ff5f
                 instance_tags:
                     name: master
                
         - name: "Creating Slave Nodes"
           ec2:
                 region: ap-south-1
                 aws_access_key: "{{ access_key }}"
                 aws_secret_key: "{{ secret_key }}"
                 vpc_subnet_id: subnet-0288bbf00ed3128d7
                 count: 2
                 state: present
                 instance_type: t2.micro
                 key_name: redhat-key
                 assign_public_ip: yes
                 group_id: sg-0612a79a1fdb041ff
                 image: ami-08f63db601b82ff5f
                 instance_tags:
                      name: slave

Файл secret.yml:

aws_access_key: <YOUR-AWS-ACCESS-KEY-HERE>
aws_secret_key: <YOUR-AWS-SECRET-KEY-HERE>

Создание файла yml для MySQL и Wordpress

Файл создает секрет, который содержит имя пользователя и пароль базы данных и службы, которые доступны только в частном мире, чтобы приложение Wordpress могло подключаться только к порту с номером 3306 и развертывать со стратегией воссоздания с использованием версии mysql: 5.6:

apiVersion: v1
kind: Secret
metadata:
  name: mysecure
data:
  rootpass: cmVkaGF0
  userpass: cmVkaGF0
--- 
apiVersion: v1
kind: Service
metadata:
  name: wordpress-mysql
  labels:
    app:  wordpress
spec:
  ports:
    - port: 3306
  selector:
    app: wordpress
    tier: mysql
  clusterIP: None
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name:  wordpress-mysql
  labels:
    app:  wordpress
spec:
  selector:
    matchLabels:
      app:  wordpress
      tier: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app:  wordpress
        tier: mysql
    spec:
      containers:
      - image: mysql:5.6
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysecure
              key: rootpass
        - name: MYSQL_USER
          value: vd
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysecure
              key: userpass
        - name: MYSQL_DATABASE
          value: sqldb
        ports:
        - containerPort: 3306
          name: mysql

Этот файл создает службу с типом LoadBalancer, выставленным с номером порта 80, развертыванием с той же стратегией, называемой воссозданием, и получением имени пользователя и пароля базы данных с помощью секретной базы данных, созданной на вышеуказанных шагах.

apiVersion: v1
kind: Service
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  ports:
    - port: 80
  selector:
    app: wordpress
    tier: mysql
  type: LoadBalancer
---
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
  name: wordpress
  labels:
    app: wordpress
spec:
  selector:
    matchLabels:
      app:  wordpress
      tier: mysql
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: wordpress
        tier: mysql
    spec:
      containers:
      - image: wordpress:latest
        name: wordpress
        env:
        - name: WORDPRESS_DB_HOST
          value: wordpress-mysql
        - name: WORDPRESS_DB_USER
          value: vd
        - name: WORDPRESS_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysecure
              key: userpass
        - name: WORDPRESS_DB_NAME
          value: sqldb
        ports:
        - containerPort: 80
          name: wordpress

Ansible-playbook для главного узла

Сначала добавьте репозиторий kubeadm, чтобы он мог загружать kubeadm, kubelet и kubectl. Мы можем использовать модуль COPY вместо модуля yum_repository:

- name: Adding Kubeadm repo
   copy:
            src: kubernetes.repo
            dest: /etc/yum.repos.d

Файл kubernetes.repo выглядит следующим образом:

[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-$basearch
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg

Теперь давайте установим Docker и kubeadm с помощью модуля package.

Мы также можем использовать cri-o вместо Docker:

- name: Installing docker
        package:
                  name: "docker"
                  state: present
      - name: Installing kubeadm
        package:
                    name: "kubeadm"
                    state: present

Включение службы Docker:

- name: Enabling docker service
        service:
             name: docker
             state: started
             enabled: yes

Теперь извлеките весь образ из концентратора Docker, который важен для настройки главного узла.

Эти образы относятся к api-server, flannel, kube-controller, etcd, controller-manager, scheduler:

- name: Pulling all kubeadm config image
      command: kubeadm config images pull     
      ignore_errors: no

Теперь, когда мы знаем, что кубернеты поддерживают драйвер systemd, мы должны изменить эту контрольную группу на systemd. Для этого мы можем создать файл с именем daemon.json, который можно скопировать в /etc/docker/daemon.json, чтобы он автоматически изменился на драйвер systemd.

- name: Changing driver cgroup to systemd
    copy:
           src: daemon.json
           dest: /etc/docker/daemon.json

Файл daemon.json выглядит следующим образом:

{
        "exec-opts": ["native.cgroupdriver=systemd"]
}

Теперь удалите весь файл подкачки из / etc / fstab, потому что он показывает ошибки при инициализации главного узла:

- name: Removing swapfile from /etc/fstab
    mount:
                name: "{{ item }}"
                fstype: swap
                state: absent
        with_items:
                - swap
                - none

Теперь включите службу kubelet и перезапустите Docker, когда мы меняем драйвер (systemd):

- name: Enabling kubelet service
    service:
            name: kubelet
            daemon_reload: yes
            state: started
            enabled: yes
      - name: Restarting docker service
        service:
              name: docker
              state: "restarted"

Установите программное обеспечение iproute-tc, поскольку мастер Kubernetes использует это программное обеспечение при инициализации в качестве основного узла.

- name: Installing iproute-tc
    package:
           name: iproute-tc
           state: present
           update_cache: yes

Теперь мы можем инициализировать узел как главный узел. Помните, не идеально настраивать ОЗУ менее 2200 МБ и ЦП менее 2, поскольку это вызывает ошибку. Чтобы игнорировать эту ошибку, мы можем использовать - ignore-preflight-error.

- name: Initializing the kubeadm
    shell: "kubeadm init --pod-network-cidr=10.244.0.0/16 --ignore-preflight-errors=Swap --ignore-preflight-errors=NumCPU --ignore-preflight-errors=Mem --node-name=master"
   
    register: kubeadm
    ignore_errors: yes
   
- debug:
         msg: "{{ kubeadm }}"

Теперь настройте kubeconfig для домашнего пользователя, чтобы главный узел также мог работать как клиент и использовать команду kubectl.

- name: Setup kubeconfig for home user
   shell: "{{ item }}"
   with_items:
             - "mkdir -p $HOME/.kube"
             - "cp -i /etc/kubernetes/admin.conf $HOME/.kube/config"
             - "chown $(id -u):$(id -g) $HOME/.kube/config"

Теперь добавьте фланелевую сеть в главный узел, чтобы он мог настроить некоторую внутреннюю настройку наложения.

- name: Adding flannel network
    shell: kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

Теперь мы создаем токен для подчиненного узла с целью аутентификации и сохраняем этот токен в файле с именем token.sh с помощью модуля local_action.

- name: Joining token
      shell: "kubeadm token create --print-join-command"
      register: token
     - debug:
              msg: "{{ token }}"
              ignore_errors: yes
     - name: Storing token into a file
       local_action: copy content={{ token.stdout_lines[0] }}         dest=../slave1/token.sh

Теперь копируем файлы database.yml и wordpress.yml.

- name: Copying mysql-database.yml file
   copy:
	              src: database.yaml
	              dest: /root
	       
 - name: Copying wordpress.yml file
   copy:
	               src: wordpress.yml
	               dest: /root

Теперь, наконец, запущены база данных и оба файла Wordpress с использованием модуля оболочки. Не забудьте указать путь к файлам database.yml и wordpress.yml.

Мы можем увидеть вывод команды с помощью модуля отладки:

- shell: "kubectl apply -f /root/database.yaml"
	       register: mysql	
- shell: "kubectl apply -f /root/wordpress.yml"
	       register: wordpress	
- debug:
	       msg: "{{ mysql }}
- debug:
               msg: "{{ wordpress }}"

Ansible-playbook для подчиненного узла

Практически все шаги аналогичны мастер-ноде. То же самое до шага 8, за исключением шага 4. Итак, давайте посмотрим, что еще нам нужно сделать для настройки узла как подчиненного узла.

9. Копирование файла k8s.conf по пути /etc/sysctl.d/. Важно инициализировать любой узел как подчиненный узел.

- name: Copying k8s.conf file
     copy:
            src: k8s.conf
            dest: /etc/sysctl.d/k8s.conf

Файл k8s.conf:

net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1

10. Теперь включите sysctl:

- name: Enabling sysctl
     shell: "sysctl --system"

11. Теперь перед присоединением подчиненного узла к главному узлу мы должны использовать токен, созданный главным узлом. Во время запуска playbook я сохранил токен, созданный главным узлом, в файле token.sh, поэтому на этих шагах я могу его использовать. Я использовал модуль оболочки для запуска файла token.sh.

- name: Copying token file at /root location
   copy:
             src: token.sh
             dest: /root/token.sh
  - name: Joining slave node to master node
    shell: "sh /root/token.sh"
    register: joined
  - debug:
        msg: "{{ joined }}"

Теперь после запуска этой роли будет настроен весь главный узел и подчиненные узлы.

Wordpress и MySQL

  1. Теперь давайте войдем в главный узел и запустим команду kubectl get pods для перекрестной проверки.
  2. Теперь WordPress и база данных MySQL работают правильно. Теперь проверьте номер порта, на котором работает Wordpress, используя команду ниже.
$ kubectl get svc

3. Скопируйте общедоступный IP-адрес любого узла и соответствующий номер порта, перейдите в браузер Google-Chrome и вставьте его.

Мы успешно выполнили задачу.

В качестве альтернативы мы можем использовать следующий доступный сценарий для настройки Wordpress в многоузловом кластере, который мы настраиваем через AWS.

Мы можем создать роль для Wordpress и MySQL вместо использования файлов Kubernetes.

Теперь нам нужно создать модуль для Wordpress и MySQL, чтобы запускать их соответственно.

---
#tasks file for wordpress-mysql
#task to launch wordpress- name: "Launching Wordpress"
  shell: "kubectl run mywp1 --image=wordpress:5.1.1-php7.3-apache"
  register: Wordpress- debug:
    var: "Wordpress.stdout_lines"
#task to launch mysql 
- name: "Launching MySql"
  shell: "kubectl run mydb1 --image=mysql:5.7 --env=MYSQL_ROOT_PASSWORD=redhat     --env=MYSQL_DATABASE=wpdb  --env=MYSQL_USER=vd  --env=MYSQL_PASSWORD=redhat"
  register: MySql

Чтобы запустить mysql pod, нам нужно установить имя пользователя и пароль. Здесь вы можете использовать секретный ресурс Kubernetes или модуль хранилища от Ansible.

#mysql root password
MYSQL_ROOT_PASSWORD=redhat
#mysql database name
MYSQL_DATABASE=wpdb
#mysql user name
MYSQL_USER=vd
#myd=sql password
MYSQL_PASSWORD=redhat

Это обязательные переменные, на которые нужно ответить при запуске модуля MySQL. Если вы не используете эти переменные, будет выдана ошибка.

Открытие модуля Wordpress:

- name: "Exposing wordpess"
  shell: "kubectl expose pods mywp1  --type=NodePort   --port=80"
  register: expose
  ignore_errors: yes
- debug: 
    var: "expose.stdout_lines"

Чтобы получить доступ к Wordpress в публичном мире, нам нужно открыть NodePort.

- name: "get service"
  shell: "kubectl get svc"
  register: svc
- debug:
    var: "svc.stdout_lines"

Поскольку мы автоматизируем все это, нам не нужно заходить внутрь главного узла и проверять открытый порт службы. Приведенный выше код заставит службы выдавать выходные данные при запуске основной книги воспроизведения.

- name: "Pausing playbook for 60 seconds"
  pause: 
    seconds: 60
- name: "Getting the Database IP"
  shell: "kubectl get pods -o wide"
  register: Database_IP
- debug:
    var: "Database_IP.stdout_lines"

После запуска модулей требуется время для запуска. Итак, мы приостанавливаем playbook на 60 секунд, чтобы все модули были готовы, и мы получили полную информацию о модулях.

Теперь нам просто нужно запустить playbook.

URL GitHub: gursimarh / wordpress-kubernetes-aws-ansible (github.com)

Чтобы узнать о запуске многоузлового кластера Kubernetes через AWS, посетите: «Роль Ansible для настройки многоузлового кластера Kubernetes через облако AWS | Гурсимар Сингх | Апр, 2021 г. | Середина"

Больше контента на plainenglish.io