Top.Mail.Ru
поддержка 24/7
поддержка 24/7

K3s — установка Stateful приложения с базой данных

Наш эксперт Михаил Сергеев подготовил подробный материал (в двух форматах: статья и видеоурок), в этом уроке:

  • Расскажем, что такое K3s
  • Рассмотрим отличия Stateful и Stateless;
  • Установим K3s на ВМ;
  • Сделаем домен, SSL-сертификат и внешний доступ к нашему приложению;
  • Установим Stateful приложение — WordРress;
  • Установим Mariadb в K3s.

Расскажем, что такое K3s

K3s - это легковесный дистрибутив Kubernetes, разработанный компанией Rancher Labs. K3s был создан для того, чтобы предоставить простой и удобный способ установки, использования и управления Kubernetes.

K3s потребляет меньше оперативной памяти и меньше CPU, чем полноценная установка Kubernetes. Он имеет небольшой размер (устанавливается всего за 30 секунд одной командой и сразу готов к работе) и может быть запущен на различных устройствах, например, Raspberry Pi. K3s можно легко масштабировать на несколько нод (node).

Raspberry Pi — одноплатный компьютер габаритами с банковскую карту, изначально разработанный в качестве бюджетной системы для обучения информатике, но позднее получивший более широкое применение и известность. Разработан британской компанией Raspberry Pi Foundation во главе с Эбеном Аптоном.

K3s поддерживает все основные функции Kubernetes, включая автоматическое масштабирование, хранение данных, сетевую настройку и управление ресурсами.

Рассмотрим отличия Stateful и Stateless

Сначала рассмотрим Stateful и Stateless приложения. Сетевые приложения условно делятся  на Stateful (с сохранением состояния) и Stateless (без сохранения состояния).

Stateless приложения не хранят информацию о состоянии клиента и обрабатывают каждый запрос независимо. Вся необходимая информация передается с каждым запросом, часто в виде токена аутентификации.

Stateful приложения сохраняют информацию о состоянии (например, данные сессии, историю запросов, персональные данные и т.д.) на сервере или в базе данных. Большинство Stateful приложений требуют наличия хранилища, доступ к которому должен быть у каждой node (сетевого устройства). Если у вас одна node, то можно использовать локальное хранилище, а если их несколько, то необходимо отдельное сетевое хранилище. Единственный минус сетевых хранилищ -  это их медленность.

Stateless подход упрощает масштабирование, так как нет необходимости хранить состояние между запросами.

Со Stateless приложениями всё проще, вы при создании образа весь свой код приложения копируете в этот образ, разворачиваете под (pod) и его масштабируете на множество node, и у вас всё необходимое уже содержится в этом поде. Но в этом уроке мы будем рассматривать однонодовый k3s c локальным хранилищем. А в качестве рассматриваемого приложения выступит WordPress.

Pods (Поды) — базовые строительные блоки Kubernetes. Обычно под подом понимают сущность, состоящую из одного или нескольких контейнеров, размещённых на одном хосте и настроенных на совместное использование ресурсов сетевого стека и других ресурсов наподобие томов.

WordPress — это популярная система управления содержимым (CMS) для создания и управления веб-сайтами. Она предоставляет простой интерфейс и расширяемость с помощью плагинов и тем для настройки функциональности и внешнего вида сайта.

Установим K3s на ВМ

Перейдём на официальный сайт k3s https://k3s.io/ и посмотрим его документацию с описанием установки. 

Рис.1 Сайт K3s с описанием его установки.Рис.1 Сайт K3s с описанием его установки.
Рис.2 Схема работы K3s.Рис.2 Схема работы K3s.

Далее смотрим системные требования и возможные параметры установки. Мы будем выставлять установки по умолчанию (дефолтные). Нам этого будет вполне достаточно.

Устанавливать k3s мы будем в облаке Corpsoft24. Для этого я сделал виртуальную машину на Ubuntu 22.04.2 LTS (Jammy Jellyfish). Это чистая машина с максимальными обновлениями, 12 Гб оперативной памяти, 4 CPU, 100 Гб свободного дискового места и внешним IP-адресом 194.126.162.54.

Разместить данные в защищенном отказоустойчивом облаке Corpsoft24

Необходимые команды:

# установить k3s:
curl -sfL https://get.k3s.io | sh -

# посмотреть статус k3s:
service k3s status

Рис.3 Проверка процесса установки k3s.Рис.3 Проверка процесса установки k3s.
#Используемые в уроке алиасы:
echo "alias k='kubectl'" >> ~/.bashrc
echo "alias kg='kubectl get'" >> ~/.bashrc
echo "alias kgp='kubectl get po'" >> ~/.bashrc
echo "alias kd='kubectl delete -f'" >> ~/.bashrc
echo "alias ka='kubectl apply -f'" >> ~/.bashrc
echo "alias ke='kubectl exec -it'" >> ~/.bashrc
echo "alias k1='kubectl describe'" >> ~/.bashrc
echo "alias kl='kubectl logs'" >> ~/.bashrc
echo "alias kgs='kubectl get svc -A'" >> ~/.bashrc
echo "alias kr='kubectl rollout restart deployment'" >> ~/.bashrc
echo "alias krs='kubectl rollout restart sts'" >> ~/.bashrc
echo "alias krd='kubectl rollout restart ds'" >> ~/.bashrc
echo "alias kpa='kubectl get po -A'" >> ~/.bashrc
source ~/.bashrc

Также выкладываю ссылку на список Ингрессов — смотреть

Первое, что нам нужно — это хелм (helm). Как показывает практика, по умолчанию его тут нет. Для этого мы идём на официальный сайт https://helm.sh/, скачиваем скрипт, даём ему права на выполнение и устанавливаем.

Helm — это инструмент развертывания Kubernetes для автоматизации создания, упаковки, настройки и развертывания приложений и служб в кластерах Kubernetes.

Установка helm:

curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

Запускаем helm и проводим его настройку.

Теперь установим Nginx с помощью заранее подготовленного скрипта.

####### INSTALL Nginx HELM
mkdir /home/ms/helms -p
cd /home/ms/helms
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm pull ingress-nginx/ingress-nginx
tar zxf ingress-nginx-4.6.0.tgz
rm ingress-nginx-4.6.0.tgz -f
cp ingress-nginx/values.yaml ingress-nginx-values.yaml
vi ingress-nginx-values.yaml

helm upgrade --install ingress-nginx -f ingress-nginx-values.yaml ingress-nginx/

kubectl patch svc ingress-nginx-controller -p '{"spec":{"externalTrafficPolicy":"Local"}}'

k edit cm ingress-nginx-controller
data:
  use-forwarded-headers: 'true'
kr ingress-nginx-controller

#############################

Затем устанавливаем cert-manager, также с помощью заранее подготовленного скрипта.

####### INSTALL CERTMANAGER HELM
mkdir /home/ms/helms -p
cd /home/ms/helms
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm pull jetstack/cert-manager
tar zxf cert-manager-*.tgz
rm cert-manager-*.tgz -f
cp cert-manager/values.yaml cert-manager-values.yaml
helm upgrade --install cert-manager -f cert-manager-values.yaml cert-manager/ --set installCRDs=true



mkdir /home/ms/ci/ -p
cd /home/ms/ci

 cat << \EOF > cert-manager-issuer.yaml
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
	email: mail@msergeev.ru
	server: https://acme-v02.api.letsencrypt.org/directory
	privateKeySecretRef:
  	name: letsencrypt-prod
	solvers:
	- http01:
    	ingress:
      	class: nginx
EOF
ka cert-manager-issuer.yaml

#############################

Сделаем домен, SSL-сертификат и внешний доступ к нашему приложению

Ещё есть такая вещь, как Portainer — это платформа для управления доставкой контейнерных приложений, которая может использоваться для управления средами Docker, Docker Swarm, Kubernetes и ACI. С помощью неё через веб-интерфейс можно управлять кластером Kubernetes, смотреть логи подов, зайти в консоль. Ему будет необходим Volumes в котором будут храниться его данные.

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

####### INSTALL PORTAINER

mkdir /data/ -p
chmod 777 -R /data/

mkdir -p /data/volumes/portainer
chmod 777 /data/volumes/portainer

mkdir /home/ms/pvc -p
cd /home/ms/pvc
 cat << \EOF > portainerpv.yml
---
kind: PersistentVolume
apiVersion: v1
metadata:
  name: portainer
  namespace: default
  labels:
	type: local
spec:
  storageClassName: local-path
  capacity:
	storage: 20Gi
  accessModes:
	- ReadWriteOnce
  hostPath:
	path: "/data/volumes/portainer"
...
EOF
ka portainerpv.yml

cd /home/ms/pvc
 cat << \EOF > portainerpvc.yml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: portainer
  namespace: default
spec:
  storageClassName: local-path
  accessModes:
	- ReadWriteOnce
  resources:
	requests:
  	storage: 20Gi
...
EOF
ka portainerpvc.yml

mkdir /home/ms/helms -p
cd /home/ms/helms
### portainer
helm repo add portainer https://portainer.github.io/k8s/
helm repo update

helm pull portainer/portainer
tar zxf portainer-*
rm portainer-* -f
cp portainer/values.yaml portainer-values.yaml
vi portainer-values.yaml
#### !!!!! Change NodePort to ClusterIP
cd /home/ms/helms
helm upgrade --install portainer -f portainer-values.yaml portainer/

mkdir /home/ms/ingress/  -p
cd /home/ms/ingress
 cat << \EOF > portainer-ingress.yaml
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: portainer-ingress
  namespace: default
  annotations:
	nginx.ingress.kubernetes.io/whitelist-source-range: 78.47.67.129/32
	cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  rules:
  - host: portainer.194.126.162.54.sslip.io
	http:
  	paths:
  	- path: /
    	pathType: Prefix
    	backend:
      	service:
        	name: portainer
        	port:
          	number: 9000
  ingressClassName: nginx
  tls:
  - hosts:
	- portainer.194.126.162.54.sslip.io
	secretName: portainer-ssl
EOF

ka portainer-ingress.yaml

url: portainer.194.126.162.54.sslip.io
login: ms
pass: Cfeg65vd3rDSer3tr34111111111ddf
####################################

Рис.4 Админка Portainer.Рис.4 Админка Portainer.

Из важных моментов нужно прописать IP-адреса, с которых разрешён вход в наш Portainer. Например, мы разрешаем вход только с IP-адреса 78.47.67.129/32, поскольку защита паролем ещё не гарантирует полную безопасность. Далее создаём SSL-сертификат.

SSL-сертификат – это цифровой сертификат, удостоверяющий подлинность веб-сайта и позволяющий использовать зашифрованное соединение.

Теперь установим POSTGRESQL HELM.

######### POSTGRESQL HELM

mkdir -p /data/volumes/postgresql
chmod 777 /data/volumes/postgresql

mkdir /home/ms/pvc -p
cd /home/ms/pvc
cat << \EOF > postgresqlpv.yml
---
kind: PersistentVolume
apiVersion: v1
metadata:
  name: postgresql
  namespace: default
  labels:
	type: local
spec:
  storageClassName: local-path
  capacity:
	storage: 100Gi
  accessModes:
	- ReadWriteOnce
  hostPath:
	path: "/data/volumes/postgresql"
...
EOF
ka postgresqlpv.yml

cd /home/ms/pvc
 cat << \EOF > postgresqlpvc.yml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: postgresql
  namespace: default
spec:
  storageClassName: local-path
  accessModes:
	- ReadWriteOnce
  resources:
	requests:
  	storage: 100Gi
...
EOF
ka postgresqlpvc.yml

mkdir /home/ms/helms -p
cd /home/ms/helms
### postgresql
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

helm pull bitnami/postgresql
tar zxf postgresql-*
rm postgresql-* -f
cp postgresql/values.yaml postgresql-values.yaml
vi postgresql-values.yaml
helm upgrade --install postgresql -f postgresql-values.yaml postgresql/

kubectl get secret postgresql -o jsonpath="{.data.postgres-password}" | base64 -d

ke postgresql-0 -- bash
 PGPASSWORD="Hc2w6hIok4" psql --host 127.0.0.1 -U postgres -d postgres -p 5432

CREATE DATABASE wp;
CREATE USER wp WITH PASSWORD 'S2IBBRMefi0m2p0new3Q';
GRANT ALL PRIVILEGES ON DATABASE wp to wp;

HOST: postgresql
DATABASE: wp
USER: wp
PASSWORD: S2IBBRMefi0m2p0new3Q

#######################

Установим Stateful приложение — WordРress

Теперь установим WordPress.

######### WORDPRESS HELM

mkdir -p /data/volumes/wordpress /data/volumes/wordpressdb
chmod 777 /data/volumes/wordpress /data/volumes/wordpressdb

mkdir /home/ms/pvc -p
cd /home/ms/pvc
cat << \EOF > wordpresspv.yml
---
kind: PersistentVolume
apiVersion: v1
metadata:
  name: wordpress
  namespace: default
  labels:
	type: local
spec:
  storageClassName: local-path
  capacity:
	storage: 100Gi
  accessModes:
	- ReadWriteOnce
  hostPath:
	path: "/data/volumes/wordpress"
...
EOF

cat << \EOF > wordpressdbpv.yml
---
kind: PersistentVolume
apiVersion: v1
metadata:
  name: wordpressdb
  namespace: default
  labels:
	type: local
spec:
  storageClassName: local-path
  capacity:
	storage: 100Gi
  accessModes:
	- ReadWriteOnce
  hostPath:
	path: "/data/volumes/wordpressdb"
...
EOF
ka wordpresspv.yml
ka wordpressdbpv.yml


cd /home/ms/pvc
 cat << \EOF > wordpresspvc.yml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wordpress
  namespace: default
spec:
  storageClassName: local-path
  accessModes:
	- ReadWriteOnce
  resources:
	requests:
  	storage: 100Gi
...
EOF

 cat << \EOF > wordpressdbpvc.yml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: wordpressdb
  namespace: default
spec:
  storageClassName: local-path
  accessModes:
	- ReadWriteOnce
  resources:
	requests:
  	storage: 100Gi
...
EOF
ka wordpresspvc.yml
ka wordpressdbpvc.yml


mkdir /home/ms/helms -p
cd /home/ms/helms
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

helm pull bitnami/wordpress
tar zxf wordpress-*
rm wordpress-* -f
cp wordpress/values.yaml wordpress-values.yaml
vi wordpress-values.yaml
# Loadbalancer to ClusterIP
helm upgrade --install wordpress -f wordpress-values.yaml wordpress/


mkdir /home/ms/ingress/  -p
cd /home/ms/ingress
 cat << \EOF > wordpress-ingress.yaml
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: wordpress-ingress
  namespace: default
  annotations:
	nginx.ingress.kubernetes.io/whitelist-source-range: 0.0.0.0/0
	cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  rules:
  - host: wordpress.194.126.162.54.sslip.io
	http:
  	paths:
  	- path: /
    	pathType: Prefix
    	backend:
      	service:
        	name: wordpress
        	port:
          	number: 80
  ingressClassName: nginx
  tls:
  - hosts:
	- wordpress.194.126.162.54.sslip.io
	secretName: wordpress-ssl
EOF


ka wordpress-ingress.yaml

user
kubectl get secret --namespace default wordpress -o jsonpath="{.data.wordpress-password}" | base64 -d
VxHGG7WQcW

# Удалить k3s

/usr/local/bin/k3s-uninstall.sh
Рис.5 Админка WordPress. Рис.5 Админка WordPress.

Установим Mariadb в K3s

Она устанавливается автоматически совместно с WordPress из одного хелма (helm). Почитать её описание можно на официальном сайте https://mariadb.org/.

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

Kubernetes в облаке


Загрузка ...