Как подключить bootstrap 5 к mysql
Перейти к содержимому

Как подключить bootstrap 5 к mysql

  • автор:

Модернизировать php mysql меню

У меня есть уже готовое меню на чистом php mysql с применением pdo.
Вот как выглядит меню сейчас : Скриншот меню Вот как выглядит база: Скриншот БД Вот php код:

Вот как выглядит верстка на bootstrap:

       Document [email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">  

Просьба не предлагать mvc laravel и всякие другие фреимворки и шаблонизаторы. Строго php pdo mysql.

Cуть вопроса:

Хочу добавить подменю. Скажем так, сделать товары родителем, а все, что после него — подкатегориями и так, чтобы иконки оставались. Плюс-минус идеи есть. Но я чувствую, что выбираю самый тяжелый путь ввиду малых знаний. Проект мой. Учить php начал из-за того, что все вокруг пытались убедить, что то, что мне надо, не получается, но как понял, все ищут легких путей и легкого заработка для себя.

Уроки Bootstrap

Уроки Bootstrap верстки / #1 - Основы и установка

Уроки по Bootstrap для начинающих! Новый видеокурс, в котором мы будет изучать фреймворк Bootstrap от базовых классов и до написания JavaScript скриптов. За курс вы узнаете как верстать сайты с помощью Bootstrap и какими характеристика обладаете данная технология.

Видеоурок

Полезные ссылки:

  • Видеокурс по HTML ;
  • Видеокурс по изучению CSS ;
  • Видеокурс по изучению JavaScript ;
  • Официальный сайт Bootstrap;
  • CDN для Bootstrap;
  • Обзор текстового редактора Atom .
Информация про Bootstrap

При каждом создании списка лучших фреймворков CSS в числе лидеров всегда стоит Bootstrap и это не случайно. Он занимает заслуженное место в списке благодаря наличию уникальных функций, часть из них не существует ни в одном другом фреймворке.

Изначально разрабатывался для популярнейшей соцсети Twitter, но его роль выходит далеко за пределы одного сервиса. Сегодня является одним из самых используемых и эффективных фреймворков CSS. Бутстрап включает и другие широко известные языки – HTML и Javascript .

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

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

Bootstrap верстка – популярный способ быстро создать веб сайт. А даптивная верстка Bootstrap – часть данной работы. Все сайты, что строятся на Бутстрап имеют продуманную структуру и являются адаптивными по умолчанию.

Почему используют Bootstrap?

Bootstrap содержит множество готовых стилей и JavaScript скриптов для создания веб сайта. Написание стилей для сайта можно значительно сократить за счёт использования уже готовых решений от Bootstrap.

Благодаря быстрой реализации стилей многие разработчики полюбили Bootstrap и используют его для разнообразных проектов.

Как работать с Bootstrap?

Принцип работы с Bootstrap прост. Вам предстоит:

  • скачать или подключить Bootstrap при помощи CDN;
  • выполнить верстку сайта с помощью Bootstrap, используя подготовленные стили.

Верстка сайта на Bootstrap легкая даже для новичков в сфере веб разработки. Понять как работать с бутстрап и освоить Bootstrap основы можно в течении пары часов. Далее вы сможете проектировать сайты на бутстрап, делая их адаптивными, отзывчивыми и красивыми.

Версии Bootstrap

На сегодняшний день существует несколько основных версий Bootstrap. Последние крупные обновления это:

  • Bootstrap 3 – добавлены классы для работы со множеством HTML5 объектов;
  • Bootstrap 4 – представлена возможность строить адаптивную верстку Bootstrap на основе FlexBox;
  • Bootstrap 5 – улучшены и добавлены стили к HTML объектам. Уменьшен код, увеличина производительность.
План курса

За курс мы ознакомимся с фреймворком Bootstrap. Мы изучим все основные классы, что содержаться в фреймворке. Также изучим использование подготовленных JavaScript скриптов. На основе практических Bootstrap примеров верстки вы сможете построить веб сайт и изучить B ootstrap с нуля.

Наши B ootstrap уроки отлично подойдут как новичкам, так и тем, кто хочет подтянуть свои знания в разработке адаптивных веб сайтов.

К концу курса у вас будет достаточно знаний чтобы использовать Bootstrap в ваших проектах.

Простой сайт на Bootstrap

    Bootstrap уроки        
Привет, вы на сайте itProger

Привет, вы на сайте itProger

Введение

Начните работу с Bootstrap, самой популярной в мире платформой для создания адаптивных сайтов, ориентированных на мобильные устройства, с jsDelivr и шаблонами страниц.

На этой странице

Быстрый старт

Хотите использовать Бутстрап в своем проекте? Используйте jsDelivr, бесплатную CDN с открытым исходным кодом. Нужна система управления пакетами или исходники Bootstrap? Перейдите на страницу загрузки.

CSS

Скопируйте и вставьте часть кода в свой перед всеми другими таблицами стилей, чтобы загрузить наш CSS.

link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> 

JS

Многие из наших компонентов требуют использовать для работы JavaScript. В частности, для них требуются наши собственные плагины JavaScript и Popper. Поместите один из следующих тегов в конце страницы, прямо перед закрывающим тегом , чтобы включить их.

Пакетное подключение

Включите каждый плагин Bootstrap JavaScript в один из двух наших пакетов. Оба файла, и bootstrap.bundle.js и bootstrap.bundle.min.js включают в себя Popper для наших всплывающих подсказок и всплывающих окон. Для получения дополнительной информации о том, что входит в Bootstrap, смотрите раздел содержание.

script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous">script> 
Раздельное подключение

Если вы решите использовать отдельные скрипты, сначала должен быть подключен Popper (если вы используете всплывающие подсказки или всплывающие окна), а затем наши плагины JavaScript.

script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.9.2/dist/umd/popper.min.js" integrity="sha384-IQsoLXl5PILFhosVNubq5LC7Qb9DXgDA9i+tQ8Zj3iwWAwPtgFTxbJ8NT4GN1R8p" crossorigin="anonymous">script> script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.min.js" integrity="sha384-cVKIPhGWiC2Al4u+LWgxfKTRIcfu0JTxR+EQDz/bgldoEyl4H0zUF0QKbrJ0EcQF" crossorigin="anonymous">script> 
Модули
Компоненты

Любопытно, какие компоненты явно требуют наши JavaScript и Popper.js? Нажмите ссылку «Показать компоненты» ниже. Если вы не уверены в том, как правильно написать «коренную» структуру страницы, можете использовать наши шаблоны.

  • Уведомления отмены
  • Кнопки изменения состояний и чекбоксов/»радио»
  • Карусель для поведения «слайд», элементы контроля и индикаторы
  • Коллапс для изменения видимости содержимого
  • Выпадающие элементы для отображения и расположения (также требует Popper)
  • Модальные окна для отображения, расположения и создания поведения прокрутки
  • Навбар для расширения нашего плагина коллапса для придания отзывчивого поведения
  • Выплывающие подсказки и окна для отображения и расположения (также требует Popper)
  • Отслеживание прокрутки и обновления навигации

Стартовый шаблон

Убедитесь, что ваши страницы сверстаны в соответствии с последними стандартами дизайна и разработки. Это означает использование HTML5 и включение метатега области просмотра для правильного «отзывчивого» поведения страниц. Вот как должены выглядеть ваши страницы:

 html lang="ru"> head> meta charset="utf-8"> meta name="viewport" content="width=device-width, initial-scale=1"> link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> title>Привет мир!title> head> body> h1>Привет мир!h1>  script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous">script>      --> body> html> 

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

Важные глобальные атрибуты

Бутстрап включает некоторые глобальные стили и настройки, о которых вам необходимо знать при работе с ним; все эти стили и настройки почти полностью имеют дело с и «заточены» под нормализацию кроссбраузерных стилей.

Тип текущего документа

Bootstrap требует использования doctype HTML5. Без него у вас возникнут некоторые проблемы со стилями, но его включение не должно вызывать каких-либо серьезных сбоев.

 html lang="ru"> . html> 

Мета-теги для адаптивной вёрстки

Bootstrap разрабатывался как mobile first, т.е. его настройки прежде всего оптимизированы под мобильные устройства, а уж потом с помощью медиа-запросов мы подгоняем масштаб компонентов как нам необходимо на прочих устройствах. Вставьте этот кусок кода в :

meta name="viewport" content="width=device-width, initial-scale=1">

Вы можете увидеть пример этого в действии в Начальном шаблоне страницы.

Размер ширины и высоты элемента (Box-sizing)

Для большей простоты масштабирования в CSS мы изменяем глобальное значение box-sizing с content-box на border-box . Это гарантирует, что padding не будет влиять на конечную вычисленную ширину элемента; однако может создать проблемы для сторонних приложений, таких как Google Maps или поисковой движок Google.

В том редком случае, когда вам понадобится переопределить его, делайте так:

.selector-for-some-widget  box-sizing: content-box; >

В приведенном выше фрагменте все вложенные элементы, включая сгенерированный контент с помощью ::before и ::after , будут наследовать указанный размер блока box-sizing для этого .selector-for-some-widget .

Узнайте больше о блоковой модели и параметризации размеров на CSS Tricks.

«Ребут» (новая библиотека CSS, не использующая классов, обеспечивающая «модульный подход»)

Для улучшенной кроссбраузерной визуализации мы используем «Ребут», обеспечивающий более продвинутые «сбросы стилей» для элементов HTML для коррекции мелких багов в браузерах и девайсах.

Сообщество

Оставайтесь в курсе последних новостей Bootstrap и вливайтесь в сообщество Bootstrap с помощью этих ресурсов:

  • Читайте и подписывайтесь на Официальный блог Bootstrap.
  • Спрашивайте и изучайте наши обсуждения на GitHub.
  • Общайтесь с другими Bootstrappers в IRC. На сервере irc.freenode.net , в канале ##bootstrap .
  • Справку по реализации можно найти на сайте Stack Overflow (с тегом bootstrap-5 ).
  • Разработчикам следует использовать ключевое слово bootstrap в пакетах, которые изменяют или расширяют функциональность Bootstrap при распространении через npm или аналогичные механизмы доставки для максимальной узнаваемости.

Вы также можете присоединиться к @getbootstrap on Twitter, чтобы следить за последними слухами и потрясающими музыкальными клипами.

Kubernetes tips & tricks: ускоряем bootstrap больших баз данных

Этой статьёй мы открываем череду публикаций с практическими инструкциями о том, как облегчить жизнь себе (эксплуатации) и разработчикам в различных ситуациях, случающихся буквально ежедневно. Все они собраны из реального опыта решения задач от клиентов и со временем улучшались, но по-прежнему не претендуют на идеал — рассматривайте их скорее как идеи и заготовки.

Я начну с «трюка» по подготовке больших дампов баз данных вроде MySQL и PostgreSQL для их быстрого развёртывания для различных нужд — в первую очередь, на площадках для разработчиков. Контекст описанных ниже операций — наше типовое окружение, включающее в себя работающий кластер Kubernetes и применение GitLab (и dapp) для CI/CD. Поехали!

Основная боль в Kubernetes при использовании feature branch — это большие базы данных, когда разработчики хотят протестировать/продемонстрировать свои изменения на полной (или почти полной) базе из production. Например:

  • Есть приложение с БД в MySQL на 1 Тб и 10 разработчиков, которые разрабатывают свои фичи.
  • Разработчики хотят индивидуальные тестовые контуры и ещё пару специфичных контуров для тестов и/или демонстраций.
  • Вдобавок, есть необходимость восстанавливать ночной дамп production-базы в своём тестовом контуре за вменяемое время — для воспроизведения проблемы у клиента или бага.
  • Наконец, имеется возможность облегчить размер базы хотя бы на 150 Гб — не так много, но всё равно экономия места. Т.е. нам нужно ещё как-то подготавливать дамп.

Итак, допустим, у нас есть бэкап базы данных. Что делать дальше?

Шаг 1: Подготовка новой базы из дампа

Первым делом мы создадим в Kubernetes Deployment, который будет состоять из двух init-контейнеров (т.е. таких специальных контейнеров, что запускаются до подов с приложением и позволяют выполнять предварительную настройку) и одного пода.

Но где его размещать? У нас большая база (1 Тб) и мы хотим поднять десять её экземпляров — потребуется сервер с большим диском (10+ Тб). Закажем его отдельно для этой задачи и пометим узел с этим сервером специальным лейблом dedicated: non-prod-db . Заодно воспользуемся одноимённым taint, который будет говорить Kubernetes, что на этот узел могут катиться только приложения, которые устойчивы (имеют tolerations) к нему, т.е., переводя на язык Kubernetes, dedicated Equal non-prod-db .

С помощью nodeSelector и tolerations выберём нужный узел (размещённый на сервере с большим диском):

 nodeSelector: dedicated: non-prod-db tolerations: - key: "dedicated" operator: "Equal" value: "non-prod-db" effect: "NoExecute"

… и займёмся описанием содержимого этого узла.

Init-контейнеры: get-bindump

Первый init-контейнер мы назовём get-bindump . В него монтируется emptyDir (в /var/lib/mysql ), куда будет складываться полученный с бэкап-сервера дамп базы данных. Для этого в контейнере есть все необходимое: SSH-ключи, адреса бэкап-серверов. Данная стадия в нашем случае занимает около 2 часов.

Описание этого контейнера в Deployment выглядит следующим образом:

 - name: get-bindump image: db-dumps imagePullPolicy: Always command: [ "/bin/sh", "-c", "/get_bindump.sh" ] resources: limits: memory: "5000Mi" cpu: "1" requests: memory: "5000Mi" cpu: "1" volumeMounts: - name: dump mountPath: /dump - name: mysqlbindir mountPath: /var/lib/mysql - name: id-rsa mountPath: /root/.ssh

Используемый в контейнере скрипт get_bindump.sh :

#!/bin/bash date if [ -f /dump/version.txt ]; then echo "Dump file already exists." exit 0 fi rm -rf /var/lib/mysql/* borg extract --stdout user@your.server.net:somedb-mysql::$ stdin | xbstream -x -C /var/lib/mysql/ echo $lastdump > /dump/version.txt

Init-контейнеры: prepare-bindump

После скачивания бэкапа запускается второй init-контейнер — prepare-bindump . Он выполняет innobackupex —apply-log (так как файлы уже доступны в /var/lib/mysql — благодаря emptyDir из get-bindump ) и стартует сервер MySQL.

Именно в этом init-контейнере мы делаем все необходимые преобразования в БД, готовя её к выбранному применению: очищаем таблицы, для которых это допустимо, меняем доступы внутри базы и т.п. Затем выключаем сервер MySQL и просто архивируем весь /var/lib/mysql в tar.gz-файл. В итоге, дамп умещается в файл размером 100 Гб, что уже на порядок меньше, чем исходный 1 Тб. Данная стадия занимает около 5 часов.

Описание второго init-контейнера в Deployment:

 - name: prepare-bindump image: db-dumps imagePullPolicy: Always command: [ "/bin/sh", "-c", "/prepare_bindump.sh" ] resources: limits: memory: "5000Mi" cpu: "1" requests: memory: "5000Mi" cpu: "1" volumeMounts: - name: dump mountPath: /dump - name: mysqlbindir mountPath: /var/lib/mysql - name: debian-cnf mountPath: /etc/mysql/debian.cnf subPath: debian.cnf

Используемый в нём скрипт prepare_bindump.sh выглядит примерно так:

#!/bin/bash date if [ -f /dump/healthz ]; then echo "Dump file already exists." exit 0 fi innobackupex --apply-log /var/lib/mysql/ chown -R mysql:mysql /var/lib/mysql chown -R mysql:mysql /var/log/mysql echo "`date`: Starting mysql" /usr/sbin/mysqld --character-set-server=utf8 --collation-server=utf8_general_ci --innodb-data-file-path=ibdata1:200M:autoextend --user=root --skip-grant-tables & sleep 200 echo "`date`: Creating mysql root user" echo "update mysql.user set Password=PASSWORD('password') WHERE user='root';" | mysql -uroot -h 127.0.0.1 echo "delete from mysql.user where USER like '';" | mysql -uroot -h 127.0.0.1 echo "delete from mysql.user where user = 'root' and host NOT IN ('127.0.0.1', 'localhost');" | mysql -uroot -h 127.0.0.1 echo "FLUSH PRIVILEGES;" | mysql -uroot -h 127.0.0.1 echo "truncate somedb.somedb_table_one;" | mysql -uroot -h 127.0.0.1 -ppassword somedb /usr/bin/mysqladmin shutdown -uroot -ppassword cd /var/lib/mysql/ tar -czf /dump/mysql_bindump.tar.gz ./* touch /dump/healthz rm -rf /var/lib/mysql/*

Под

Финальный аккорд — запуск основного пода, что происходит после выполнения init-контейнеров. В поде у нас стоит простой nginx, а через emtpyDir подложен сжатый и обрезанный дамп в 100 Гб. Функция данного nginx — отдавать этот дамп.

 - name: nginx image: nginx:alpine resources: requests: memory: "1500Mi" cpu: "400m" lifecycle: preStop: exec: command: ["/usr/sbin/nginx", "-s", "quit"] livenessProbe: httpGet: path: /healthz port: 80 scheme: HTTP timeoutSeconds: 7 failureThreshold: 5 volumeMounts: - name: dump mountPath: /usr/share/nginx/html - name: nginx-config mountPath: /etc/nginx/nginx.conf subPath: nginx.conf readOnly: false volumes: - name: dump emptyDir: <> - name: mysqlbindir emptyDir: <>

Вот как выглядит весь Deployment с его initContainers…

--- apiVersion: apps/v1beta1 kind: Deployment metadata: name: db-dumps spec: strategy: rollingUpdate: maxUnavailable: 0 revisionHistoryLimit: 2 template: metadata: labels: app: db-dumps spec: imagePullSecrets: - name: regsecret nodeSelector: dedicated: non-prod-db tolerations: - key: "dedicated" operator: "Equal" value: "non-prod-db" effect: "NoExecute" initContainers: - name: get-bindump image: db-dumps imagePullPolicy: Always command: [ "/bin/sh", "-c", "/get_bindump.sh" ] resources: limits: memory: "5000Mi" cpu: "1" requests: memory: "5000Mi" cpu: "1" volumeMounts: - name: dump mountPath: /dump - name: mysqlbindir mountPath: /var/lib/mysql - name: id-rsa mountPath: /root/.ssh - name: prepare-bindump image: db-dumps imagePullPolicy: Always command: [ "/bin/sh", "-c", "/prepare_bindump.sh" ] resources: limits: memory: "5000Mi" cpu: "1" requests: memory: "5000Mi" cpu: "1" volumeMounts: - name: dump mountPath: /dump - name: mysqlbindir mountPath: /var/lib/mysql - name: log mountPath: /var/log/mysql - name: debian-cnf mountPath: /etc/mysql/debian.cnf subPath: debian.cnf containers: - name: nginx image: nginx:alpine resources: requests: memory: "1500Mi" cpu: "400m" lifecycle: preStop: exec: command: ["/usr/sbin/nginx", "-s", "quit"] livenessProbe: httpGet: path: /healthz port: 80 scheme: HTTP timeoutSeconds: 7 failureThreshold: 5 volumeMounts: - name: dump mountPath: /usr/share/nginx/html - name: nginx-config mountPath: /etc/nginx/nginx.conf subPath: nginx.conf readOnly: false volumes: - name: dump emptyDir: <> - name: mysqlbindir emptyDir: <> - name: log emptyDir: <> - name: id-rsa secret: defaultMode: 0600 secretName: somedb-id-rsa - name: nginx-config configMap: name: somedb-nginx-config - name: debian-cnf configMap: name: somedb-debian-cnf --- apiVersion: v1 kind: Service metadata: name: somedb-db-dump spec: clusterIP: None selector: app: db-dumps ports: - name: http port: 80
  1. В нашем случае мы каждую ночь подготавливаем новый дамп с помощью scheduled job в GitLab. Т.е. каждую ночь у нас автоматически раскатывается этот Deployment, который подтягивает свежий дамп и подготавливает его для раздачи всем тестовым окружениям разработчиков.
  2. Для чего мы в init-контейнеры прокидываем ещё и volume /dump (и в скрипте есть проверка на существование /dump/version.txt )? Это сделано на тот случай, если будет перезапущен сервер, на котором работает под. Контейнеры будут стартовать заново и без этой проверки начнёт повторно скачиваться дамп. Если же мы один раз уже подготовили дамп, то при следующем старте (в случае ребута сервера) файл-флаг /dump/version.txt сообщит об этом.
  3. Что за образ db-dumps ? Мы его собираем dapp’ом и его Dappfile выглядит так:

dimg: "db-dumps" from: "ubuntu:16.04" docker: ENV: TERM: xterm ansible: beforeInstall: - name: "Install percona repositories" apt: deb: https://repo.percona.com/apt/percona-release_0.1-4.xenial_all.deb - name: "Add repository for borgbackup" apt_repository: repo="ppa:costamagnagianfranco/borgbackup" codename="xenial" update_cache=yes - name: "Add repository for mysql 5.6" apt_repository: repo: deb http://archive.ubuntu.com/ubuntu trusty universe state: present update_cache: yes - name: "Install packages" apt: name: ">`>>" state: present with_items: - openssh-client - mysql-server-5.6 - mysql-client-5.6 - borgbackup - percona-xtrabackup-24 setup: - name: "Add get_bindump.sh" copy: content: | > dest: /get_bindump.sh mode: 0755 - name: "Add prepare_bindump.sh" copy: content: | > dest: /prepare_bindump.sh mode: 0755

Шаг 2: Запуск базы в окружении разработчика

При выкате базы данных MySQL в тестовом окружении разработчика у него есть кнопка в GitLab, которая запускает редеплой Deployment‘а с MySQL со стратегией RollingUpdate.maxUnavailable: 0 :

Как это реализуется?

В GitLab при нажатии на reload db деплоится Deployment с такой спецификацией:

spec: strategy: rollingUpdate: maxUnavailable: 0

Т.е. мы говорим Kubernetes, чтобы он обновлял Deployment (создавал новый под) и при этом следил за тем, чтобы как минимум один под был живой. Так как при создании нового пода у него есть init-контейнеры, пока они работают, новый под не переходит в статус Running, а значит — старый под продолжает работать. И только в момент, как сам под с MySQL запустился (и отработала readiness probe), трафик переключается на него, а старый под (со старой базой) удаляется.

Подробности об этой схеме можно почерпнуть из следующих материалов:

  • Performing a Rolling Update(документация Kubernetes);
  • Rolling Updates with Kubernetes Deployments(Ta-Ching Chen);
  • Kubernetes deployment strategies(Container Solutions).

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

В init-контейнере данного Deployment используется команда следующего вида:

curl "$DUMP_URL" | tar -C /var/lib/mysql/ -xvz

Т.е. мы скачиваем сжатый дамп базы, который был подготовлен на шаге 1, разархивируем его в /var/lib/mysql , после чего стартует под Deployment‘а, в котором запускается MySQL с уже подготовленными данными. Всё это занимает примерно 2 часа.

А Deployment выглядит следующим образом…

apiVersion: apps/v1beta1 kind: Deployment metadata: name: mysql spec: strategy: rollingUpdate: maxUnavailable: 0 template: metadata: labels: service: mysql spec: imagePullSecrets: - name: regsecret nodeSelector: dedicated: non-prod-db tolerations: - key: "dedicated" operator: "Equal" value: "non-prod-db" effect: "NoExecute" initContainers: - name: getdump image: mysql-with-getdump command: ["/usr/local/bin/getdump.sh"] resources: limits: memory: "6000Mi" cpu: "1.5" requests: memory: "6000Mi" cpu: "1.5" volumeMounts: - mountPath: /var/lib/mysql name: datadir - mountPath: /etc/mysql/debian.cnf name: debian-cnf subPath: debian.cnf env: - name: DUMP_URL value: "http://somedb-db-dump.infra-db.svc.cluster.local/mysql_bindump.tar.gz" containers: - name: mysql image: mysql:5.6 resources: limits: memory: "1024Mi" cpu: "1" requests: memory: "1024Mi" cpu: "1" lifecycle: preStop: exec: command: ["/etc/init.d/mysql", "stop"] ports: - containerPort: 3306 name: mysql protocol: TCP volumeMounts: - mountPath: /var/lib/mysql name: datadir - mountPath: /etc/mysql/debian.cnf name: debian-cnf subPath: debian.cnf env: - name: MYSQL_ROOT_PASSWORD value: "password" volumes: - name: datadir emptyDir: <> - name: debian-cnf configMap: name: somedb-debian-cnf --- apiVersion: v1 kind: Service metadata: name: mysql spec: clusterIP: None selector: service: mysql ports: - name: mysql port: 3306 protocol: TCP --- apiVersion: v1 kind: ConfigMap metadata: name: somedb-debian-cnf data: debian.cnf: | [client] host = localhost user = debian-sys-maint password = password socket = /var/run/mysqld/mysqld.sock [mysql_upgrade] host = localhost user = debian-sys-maint password = password socket = /var/run/mysqld/mysqld.sock

Итоги

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

  • получает свежий дамп базы данных;
  • как-то его подготавливает для корректной работы в тестовом окружении (например, транкейтит какие-то таблицы, заменяет реальные пользовательские данные, заводит нужных юзеров и т.п.);
  • предоставляет каждому разработчику возможность по нажатию на кнопку в CI выкатывать такую подготовленную базу в свой namespace в Deployment — благодаря имеющемуся в нём Service база будет доступна по адресу mysql (например, это может быть имя сервиса в namespace).

Вопросы, критика и исправления к предложенной схеме и её компонентам — с радостью принимаются в комментариях!

P.S. Конечно, мы понимаем, что в случае VMware и некоторых других инструментов можно было бы обойтись созданием снапшота виртуалки и запуском новой вируталки из снапшота (что ещё быстрее), но этот вариант не включает в себя подготовку базы, с учётом которой получится примерно то же время… Не говоря уже о том, что не у всех есть возможность или желание использовать коммерческие продукты.

P.P.S.

Другое из цикла K8s tips & tricks:

  • «Персонализированные страницы ошибок в NGINX Ingress»;
  • «Перевод работающих в кластере ресурсов под управление Helm 2»;
  • «О выделении узлов и о нагрузках на веб-приложение»;
  • «Доступ к dev-площадкам».
  • «Сборка и дeплой приложений в Kubernetes с помощью dapp и GitLab CI»;
  • «Практика с dapp. Часть 1: Сборка простых приложений»;
  • «Практика с dapp. Часть 2. Деплой Docker-образов в Kubernetes с помощью Helm»;
  • «Оркестровка СУБД CockroachDB в Kubernetes»;
  • «Наш опыт с Kubernetes в небольших проектах» (видео доклада, включающего в себя знакомство с техническим устройством Kubernetes);
  • «Полезные утилиты при работе с Kubernetes».

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *