Baykanurov microservices repository
- Установка Docker (уже был Docker Desktop, работаю на WSL2)
- Выполнено знакомство с основными командами Docker
- Результат команды
docker images
был сохранен вdocker-monolith/docker-1.log
- Yandex Cloud CLI был установлен раннее
- Установка Docker machine v0.16.2
sudo curl -o /usr/local/bin/docker-machine -L https://github.com/docker/machine/releases/download/v0.16.2/docker-machine-`uname -s`-`uname -m` && \
sudo chmod +x /usr/local/bin/docker-machine
- Создан инстанс
yc compute instance create \
--name docker-host \
--zone ru-central1-a \
--network-interface subnet-name=default-ru-central1-a,nat-ip-version=ipv4 \
--create-boot-disk image-folder-id=standard-images,image-family=ubuntu-2004-lts,size=15 --preemptible --cores=2 \
--ssh-key ~/.ssh/id_ed25519.pub
- Инициализировано окружение Docker
docker-machine --debug create \
--driver generic \
--generic-ip-address=51.250.92.127 \
--generic-ssh-user yc-user \
--generic-ssh-key ~/.ssh/id_ed25519 \
docker-host
- Активируем окружение Docker
eval $(docker-machine env docker-host)
- Собраз образ reddit:latest
- Отправлен образ в Docker hub
docker push baykanurov/otus-reddit:1.0
- Проверить образ можно командой
docker pull baykanurov/otus-reddit:1.0
- Написал Dockerfile и собрал образ для каждого из сервисов приложения:
- post-py
- comment
- ui
docker build -t baykanurov/post:1.0 ./post-py
docker build -t baykanurov/comment:1.0 ./comment
docker build -t baykanurov/ui:1.0 ./ui
- Запустил и проверил, что всё работает
docker network create reddit
docker run -d --network=reddit --network-alias=post_db --network-alias=comment_db mongo:4.4
docker run -d --network=reddit --network-alias=post baykanurov/post:1.0
docker run -d --network=reddit --network-alias=comment baykanurov/comment:1.0
docker run -d --network=reddit -p 9292:9292 baykanurov/ui:1.0
- С какими проблемами столкнулся:
- Образ
mongo:latest
не работал с той кодовой базой которая была в приложении, поэтому я опустил версию до 4.4 - Сервис post-py не собирался и было необходимо добавить
pip install --upgrade pip
- Для сервисов comment и ui необходимо было добавить
gem install bundler:1.17.2
Т.к. я сразу писал на alpine образах, поэтому оптимизировать их не было смысла.
Вес образов до выполнения дополнительного задания:
REPOSITORY TAG IMAGE ID CREATED SIZE
baykanurov/comment 1.0 4a0cdac51e5b 30 seconds ago 286MB
baykanurov/ui 1.0 1def719ed381 45 seconds ago 289MB
baykanurov/post 1.0 23c8f2aca095 35 minutes ago 121MB
mongo 4.4 e772806c1f73 2 weeks ago 432MB
Протестировал сборку с Ubuntu для сервиса ui, результаты:
REPOSITORY TAG IMAGE ID CREATED SIZE
baykanurov/ui 2.0 2d7b29a1f364 About a minute ago 487MB
baykanurov/comment 1.0 4a0cdac51e5b 6 minutes ago 286MB
baykanurov/ui 1.0 1def719ed381 6 minutes ago 289MB
baykanurov/post 1.0 23c8f2aca095 40 minutes ago 121MB
mongo 4.4 e772806c1f73 2 weeks ago 432MB
Как можно увидеть вес существенно отличается от образа ui:1.0
.
src/ui/ubuntu.Dockerfile - Dockerfile для сервиса ui на основе образа Ubuntu.
Также тестировал запуск образов с альтернативными alias меняя переменные окружения в Dockerfile соответственно.
Дополнительно добавил для MongoDB volume чтобы данные сохранялись.
docker volume create reddit_db
docker run -d --network=reddit --network-alias=post_db --network-alias=comment_db -v reddit_db:/data/db mongo:4.4
docker run -d --network=reddit --network-alias=post baykanurov/post:1.0
docker run -d --network=reddit --network-alias=comment baykanurov/comment:1.0
docker run -d --network=reddit -p 9292:9292 baykanurov/ui:1.0
- Изучено как работают сети Docker
- Написан docker-compose для сервисов нашего приложения
- Параметризированы значения в docker compose для:
- тегов образов для всех сервисов
- порт публикации сервиса ui
- username
- Также для всех параметров добавлены default values
- Задано имя для каждого контейнера
- Имя проекта можно задать через name в docker-compose
Добавил файл docker-compose.override.yml который пробрасывает код сервиса как volume и добавляет возможность запускать puma для руби приложений в дебаг режиме с двумя воркерами
- Развернул Gitlab с помощью omnibus-установки (docker-compose.yml)
- Зашёл под root в Gitlab P.S. Чтобы получить пароль от root надо выполнить команду
sudo docker exec -it gitlab_web_1 grep 'Password:' /etc/gitlab/initial_root_password
- Создал группу homework и в ней проект example и запушил свой репозиторий в него
- Поднял раннер
docker run -d --name gitlab-runner --restart always -v /srv/gitlabrunner/config:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner:latest
- Зарегистрировал раннер в группе
docker exec -it gitlab-runner gitlab-runner register \
--url http://62.84.127.187/ \
--non-interactive \
--locked=false \
--name DockerRunner \
--executor docker \
--docker-image alpine:latest \
--registration-token GR1348941Q63XnHnAzsVaqBBbxFJ_ \
--tag-list "linux,xenial,ubuntu,docker" \
--run-untagged
- Провёл тесты с приложением reddit на CI
- Написал стадии для Staging и Production
- Добавил условия для джобы
- Добавил динамические окружения
- Запустил prometheus
docker run --rm -p 9090:9090 -d --name prometheus prom/prometheus
- Упорядочил структуру репозитория для Docker
- Создал Dockerfile и конфигурацию для Prometheus
- Собрал все образы для сервисов приложения
for i in ui post-py comment; do cd src/$i; bash docker_build.sh; cd -; done
- Добавил сервис prometheus в docker-compose
- Изучил взаимодействие с метриками Prometheus и протестировал отслеживание состояния сервисов которые подключены к мониторингу
- Добавил Node exporter для сбора информации о работе Docker хоста
- Запушил образы в Docker Hub
- Развернул ВМ для master ноды
yc compute instance create \
--name k8s-master-node \
--zone ru-central1-a \
--cores 4 \
--memory 4GB \
--preemptible \
--network-interface subnet-name=default-ru-central1-a,nat-ip-version=ipv4 \
--create-boot-disk image-folder-id=standard-images,image-family=ubuntu-2004-lts,size=40,type=network-ssd \
--ssh-key ~/.ssh/id_ed25519.pub
- Установил на неё docker через docker-machine
docker-machine create \
--driver generic \
--generic-ip-address=62.84.115.226 \
--generic-ssh-user yc-user \
--generic-ssh-key ~/.ssh/id_ed25519 \
k8s-master-node
- Подключился к ВМ
docker-machine ssh k8s-master-node
- Настроил ВМ для установки master ноды кластера Kubernetes
sudo su -
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb http://apt.kubernetes.io/ kubernetes-xenial main
EOF
apt-get update
apt-get install -y kubelet kubeadm kubectl
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system
rm /etc/containerd/config.toml
systemctl restart containerd
- Установил master ноду
kubeadm init \
--apiserver-cert-extra-sans=62.84.115.226 \
--apiserver-advertise-address=0.0.0.0 \
--control-plane-endpoint=62.84.115.226 \
--pod-network-cidr=10.244.0.0/16
Вывод:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
You can now join any number of control-plane nodes by copying certificate authorities
and service account keys on each node and then running the following as root:
kubeadm join 62.84.115.226:6443 --token 8ccohc.w08nqkgiblfldqo4 \
--discovery-token-ca-cert-hash sha256:85832ab657eb313170aaef519a0c9ad3b1fe0768ed7843896f2fab53361dd556 \
--control-plane
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 62.84.115.226:6443 --token 8ccohc.w08nqkgiblfldqo4 \
--discovery-token-ca-cert-hash sha256:85832ab657eb313170aaef519a0c9ad3b1fe0768ed7843896f2fab53361dd556
- Добавил kubeconfig в домашнюю директорию
su - yc-user
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
- Присоединяемся к хосту
kubeadm join 62.84.115.226:6443 --token 8ccohc.w08nqkgiblfldqo4 \
--discovery-token-ca-cert-hash sha256:85832ab657eb313170aaef519a0c9ad3b1fe0768ed7843896f2fab53361dd556 \
--control-plane
- Установка надстройки Pod network
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
P.S. Я взял Flannel 9. Проверим что всё успешно поднялось
root@k8s-master-node:~# kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-flannel kube-flannel-ds-ps26v 1/1 Running 0 52s
kube-system coredns-5dd5756b68-76xf5 1/1 Running 0 5m18s
kube-system coredns-5dd5756b68-nbznk 1/1 Running 0 5m18s
kube-system etcd-k8s-master-node 1/1 Running 0 5m37s
kube-system kube-apiserver-k8s-master-node 1/1 Running 0 5m39s
kube-system kube-controller-manager-k8s-master-node 1/1 Running 0 5m37s
kube-system kube-proxy-qm8h5 1/1 Running 0 5m18s
kube-system kube-scheduler-k8s-master-node 1/1 Running 0 5m37s
- Проделал аналогичные операции для worker ноды, кроме
kubeadm init
- Соединяем master ноду с worker нодой с помощью команды полученной при инициализации master ноды (от root)
root@k8s-worker-node:~# kubeadm join 62.84.115.226:6443 --token guab0t.smmqatepoj14a0t4 --discovery-token-ca-cert-hash sha256:85832ab657eb313170aaef519a0c9ad3b1fe0768ed7843896f2fab53361dd556
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
- Проверим что всё успешно
yc-user@k8s-master-node:~$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master-node Ready control-plane 21m v1.28.2
k8s-worker-node Ready <none> 18s v1.28.2
-
Дополнительно: Установка calico wget https://projectcalico.docs.tigera.io/manifests/calico.yaml sed -i -r -e 's/^([ ]+)# (- name: CALICO_IPV4POOL_CIDR)$\n/\1\2\n\1 value: "10.244.0.0/16"/g' calico.yaml kubectl apply -f calico.yaml
-
Запустим наши deployments
yc-user@k8s-master-node:~$ kubectl apply -f reddit/
deployment.apps/comment-deployment created
deployment.apps/mongo-deployment created
deployment.apps/post-deployment created
deployment.apps/ui-deployment created
- Проверим, что всё успешно
yc-user@k8s-master-node:~$ kubectl get pods -A -o custom-columns=NAME:.metadata.name,IP:.status.podIP,NAME:.spec.nodeName
NAME IP NAME
comment-deployment-57c7d5855d-f5qdd 10.244.24.196 k8s-worker-node
mongo-deployment-6d5bf6767b-gp8dw 10.244.24.195 k8s-worker-node
post-deployment-8657f4bb56-l7q57 10.244.24.194 k8s-worker-node
ui-deployment-549696fdd-dnmmw 10.244.24.193 k8s-worker-node
kube-flannel-ds-6vgqv 10.128.0.35 k8s-worker-node
kube-flannel-ds-ps26v 10.128.0.24 k8s-master-node
calico-kube-controllers-7ddc4f45bc-225tx 10.244.24.197 k8s-worker-node
calico-node-86bvx 10.128.0.24 k8s-master-node
calico-node-hzjm6 10.128.0.35 k8s-worker-node
coredns-5dd5756b68-76xf5 10.244.0.3 k8s-master-node
coredns-5dd5756b68-nbznk 10.244.0.2 k8s-master-node
etcd-k8s-master-node 10.128.0.24 k8s-master-node
kube-apiserver-k8s-master-node 10.128.0.24 k8s-master-node
kube-controller-manager-k8s-master-node 10.128.0.24 k8s-master-node
kube-proxy-54z7w 10.128.0.35 k8s-worker-node
kube-proxy-qm8h5 10.128.0.24 k8s-master-node
kube-scheduler-k8s-master-node 10.128.0.24 k8s-master-node
yc-user@k8s-master-node:~$ kubectl get pods -A
NAMESPACE NAME READY STATUS RESTARTS AGE
default comment-deployment-57c7d5855d-f5qdd 1/1 Running 0 11m
default mongo-deployment-5d754ccc49-2d9mg 1/1 Running 0 59s
default post-deployment-8657f4bb56-l7q57 1/1 Running 0 11m
default ui-deployment-549696fdd-dnmmw 1/1 Running 0 11m
kube-flannel kube-flannel-ds-6vgqv 1/1 Running 0 17m
kube-flannel kube-flannel-ds-ps26v 1/1 Running 0 33m
kube-system calico-kube-controllers-7ddc4f45bc-225tx 1/1 Running 0 8m14s
kube-system calico-node-86bvx 1/1 Running 0 8m14s
kube-system calico-node-hzjm6 1/1 Running 0 8m14s
kube-system coredns-5dd5756b68-76xf5 1/1 Running 0 38m
kube-system coredns-5dd5756b68-nbznk 1/1 Running 0 38m
kube-system etcd-k8s-master-node 1/1 Running 0 38m
kube-system kube-apiserver-k8s-master-node 1/1 Running 0 38m
kube-system kube-controller-manager-k8s-master-node 1/1 Running 0 38m
kube-system kube-proxy-54z7w 1/1 Running 0 17m
kube-system kube-proxy-qm8h5 1/1 Running 0 38m
kube-system kube-scheduler-k8s-master-node 1/1 Running 0 38m
- После успешного выполнения ДЗ удалили docker хосты и ВМ
docker-machine rm -f $(docker-machine ls -q)
yc compute instance delete k8s-worker-node
yc compute instance delete k8s-master-node
- Установил minikube и kubectl
[22:30:17] baykanurov:baykanurov_microservices git:(kubernetes-2) $ minikube version
minikube version: v1.31.2
commit: fd7ecd9c4599bef9f04c0986c4a0187f98a4396e
[22:32:21] baykanurov:baykanurov_microservices git:(kubernetes-2) $ kubectl version
Client Version: v1.28.3
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.27.4
- Развернул кластер с помощью minikube на драйвере docker
minikube start --driver=docker
- Написал deployment и services для приложения reddit
kubectl apply -f kubernetes/reddit/
- Получил доступ к сервису ui
minikube service ui
- Развернул аддон для kubernetes dashboard
minikube addons enable dashboard
minikube dashboard --url 0.0.0.0
- Развернул кластер kubernetes-2-baykanurov через Yandex Cloud Managed Service for kubernetes
- Создал группы узлов для данного кластера
- Подключился к кластеру
22:50:23] baykanurov:baykanurov_microservices git:(kubernetes-2) $ yc managed-kubernetes cluster get-credentials kubernetes-2-baykanurov --external
Context 'yc-kubernetes-2-baykanurov' was added as default to kubeconfig '/home/baykanurov/.kube/config'.
Check connection to cluster using 'kubectl cluster-info --kubeconfig /home/baykanurov/.kube/config'.
Note, that authentication depends on 'yc' and its config profile 'default'.
To access clusters using the Kubernetes API, please use Kubernetes Service Account.
There is a new yc version '0.113.0' available. Current version: '0.111.0'.
See release notes at https://cloud.yandex.ru/docs/cli/release-notes
You can install it by running the following command in your shell:
$ yc components update
[22:50:32] baykanurov:baykanurov_microservices git:(kubernetes-2) $ kubectl config current-context
yc-kubernetes-2-baykanurov
- Нашёл внешний IP-адрес развернутых нод и порт публикации сервиса UI
[23:48:07] baykanurov:baykanurov_microservices git:(kubernetes-2) $ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUN
TIME
cl1dc3oohjcqfp5nk94o-oniv Ready <none> 56m v1.24.8 10.128.0.11 158.160.54.62 Ubuntu 20.04.6 LTS 5.4.0-165-generic containerd://
1.6.22
cl1dc3oohjcqfp5nk94o-ybez Ready <none> 56m v1.24.8 10.128.0.31 158.160.109.86 Ubuntu 20.04.6 LTS 5.4.0-165-generic containerd://
1.6.22
[23:48:17] baykanurov:baykanurov_microservices git:(kubernetes-2) $ kubectl describe service ui -n dev | grep NodePort
Type: NodePort
NodePort: <unset> 32092/TCP
- Запустил приложение
kubectl apply -f ./kubernetes/reddit/dev-namespace.yml
kubectl apply -f ./kubernetes/reddit/ -n dev
- Проверил, что приложение работает на каждой из нод P.S. Удалил инстанс кластера т.к. домашние задания проверяются долго, а потребление кластера на YC очень дорогое.
- Разобрался и подключил сущности Kubernetes:
- Ingress Controller
- Ingress
- Secret
- TLS
- LoadBalancer Service
- Network Policies
- PersistentVolumes
- PersistentVolumeClaims
- Установил ingress nginx
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml
- Защитил сервис с помощью TLS
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=158.160.124.211"
kubectl create secret tls ui-ingress --key tls.key --cert tls.crt -n dev
- Создал диск в ya.cloud
yc compute disk create \
--name k8s \
--size 4 \
--description "disk for k8s"
- Установил и настроил helm
- Написал helm чарты для компонентов приложения
- Разобрался с управлением зависимостями в helm
- Установил Gitlab в Kubernetes
- Настроил CI и выстроил пайплайн