{"id":481636,"date":"2026-05-29T16:59:11","date_gmt":"2026-05-29T16:59:11","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=481636"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=481636","title":{"rendered":"# Bare-metal Kubernetes \u043d\u0430 5 VM: Calico IPIP + MetalLB + GitOps \u2014 \u0447\u0435\u0441\u0442\u043d\u044b\u0439 \u043e\u043f\u044b\u0442 \u0441 \u0433\u0440\u0430\u0431\u043b\u044f\u043c\u0438"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u041f\u0440\u0435\u0434\u044b\u0441\u0442\u043e\u0440\u0438\u044f<\/h3>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0438\u0437\u0443\u0447\u0430\u0435\u0448\u044c DevOps \u043f\u043e \u043a\u0443\u0440\u0441\u0430\u043c \u2014 \u0432\u0441\u0451 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u043e\u0441\u0442\u043e. \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043b minikube, \u043f\u043e\u0434\u043d\u044f\u043b pod, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b \u043d\u0430 <code>kubectl get pods<\/code> \u2014 \u043a\u0440\u0430\u0441\u043e\u0442\u0430. \u0410 \u043f\u043e\u0442\u043e\u043c \u043f\u044b\u0442\u0430\u0435\u0448\u044c\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0438 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0448\u044c: \u043c\u0435\u0436\u0434\u0443 \u201chello world \u0432 Kubernetes\u201d \u0438 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 \u2014 \u043f\u0440\u043e\u043f\u0430\u0441\u0442\u044c.<\/p>\n<p>\u042f \u0440\u0435\u0448\u0438\u043b \u044d\u0442\u0443 \u043f\u0440\u043e\u043f\u0430\u0441\u0442\u044c \u043f\u0440\u043e\u0439\u0442\u0438. \u0412\u0437\u044f\u043b 5 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0448\u0438\u043d \u043d\u0430 VMware Workstation \u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043b \u043d\u0430 \u043d\u0438\u0445 production-ready \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0441 \u043d\u0443\u043b\u044f. \u0421 CI\/CD, GitOps, \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u043e\u043c, \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c\u044e \u0438 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c.<\/p>\n<p>\u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c, \u043a\u0430\u043a \u0438\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u2014 \u0438 \u0433\u043b\u0430\u0432\u043d\u043e\u0435, \u043a\u0430\u043a\u0438\u0435 \u0433\u0440\u0430\u0431\u043b\u0438 \u044f \u0441\u043e\u0431\u0440\u0430\u043b \u043f\u043e \u0434\u043e\u0440\u043e\u0433\u0435. \u0418\u0445 \u0431\u044b\u043b\u043e \u043d\u0435\u043c\u0430\u043b\u043e.<\/p>\n<blockquote>\n<p><strong>\u041e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435:<\/strong> Ubuntu 22.04 LTS (ubuntu-22.04.4-live-server-amd64), VMware Workstation 17, Kubernetes 1.29, Calico 3.29.3<\/p>\n<\/blockquote>\n<hr\/>\n<h3>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442<\/h3>\n<p><em>React + Go + FastAPI + PostgreSQL, \u0432\u0441\u0451 \u0432 Kubernetes<\/em><\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0412\u0435\u0440\u0441\u0438\u044f \/ \u0414\u0435\u0442\u0430\u043b\u0438<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Kubernetes<\/p>\n<\/td>\n<td>\n<p align=\"left\">1.29, kubeadm, 1 master + 4 workers<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">CNI<\/p>\n<\/td>\n<td>\n<p align=\"left\">Calico v3.29.3, <strong>\u0440\u0435\u0436\u0438\u043c IPIP<\/strong><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Load Balancer<\/p>\n<\/td>\n<td>\n<p align=\"left\">MetalLB v0.14.9, L2 ARP<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Ingress<\/p>\n<\/td>\n<td>\n<p align=\"left\">ingress-nginx v1.10<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">CI\/CD<\/p>\n<\/td>\n<td>\n<p align=\"left\">GitHub Actions + ArgoCD v2.10<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0411\u0414<\/p>\n<\/td>\n<td>\n<p align=\"left\">CloudNativePG v1.23, 1 primary + 2 replica<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u041c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433<\/p>\n<\/td>\n<td>\n<p align=\"left\">kube-prometheus-stack chart v65.1.1<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">IaC<\/p>\n<\/td>\n<td>\n<p align=\"left\">Terraform + Ansible<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Security<\/p>\n<\/td>\n<td>\n<p align=\"left\">Trivy \u0432 \u043a\u0430\u0436\u0434\u043e\u043c pipeline<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<hr\/>\n<h3>\u0427\u0430\u0441\u0442\u044c 1 \u2014 \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430<\/h3>\n<h4>5 VM \u0438 Ansible \u0432\u043c\u0435\u0441\u0442\u043e \u0440\u0443\u0447\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438<\/h4>\n<pre><code>k8s-master   192.168.11.101   control-plane   2 CPU \/ 4GB RAMk8s-node-1   192.168.11.102   worker          2 CPU \/ 4GB RAMk8s-node-2   192.168.11.103   worker          2 CPU \/ 4GB RAMk8s-node-3   192.168.11.104   worker          2 CPU \/ 4GB RAMk8s-node-4   192.168.11.105   worker          2 CPU \/ 4GB RAM<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430\u043f\u0438\u0441\u0430\u043b Ansible playbook \u0441 \u0442\u0440\u0435\u043c\u044f \u0440\u043e\u043b\u044f\u043c\u0438. \u0417\u0430\u043f\u0443\u0441\u043a:<\/p>\n<pre><code class=\"bash\">ansible-playbook -i inventory.ini install-k8s.yml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 <code>k8s-common<\/code> (\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u043d\u043e\u0434\u0435):<\/p>\n<pre><code class=\"yaml\">- name: Disable swap permanently  ansible.builtin.replace:    path: \/etc\/fstab    regexp: '^([^#].*\\sswap\\s.*)$'    replace: '# \\1'- name: Load kernel modules  ansible.builtin.modprobe:    name: \"{{ item }}\"  loop: [overlay, br_netfilter]- name: Set sysctl for Kubernetes networking  ansible.posix.sysctl:    name: \"{{ item.key }}\"    value: \"{{ item.value }}\"    sysctl_file: \/etc\/sysctl.d\/k8s.conf    reload: true  loop:    - { key: net.bridge.bridge-nf-call-iptables, value: \"1\" }    - { key: net.bridge.bridge-nf-call-ip6tables, value: \"1\" }    - { key: net.ipv4.ip_forward, value: \"1\" }- name: Configure containerd with SystemdCgroup  # Ubuntu 22.04 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 cgroups v2 \u2014 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c SystemdCgroup  ansible.builtin.shell: |    containerd config default &gt; \/etc\/containerd\/config.toml    sed -i 's\/SystemdCgroup = false\/SystemdCgroup = true\/' \/etc\/containerd\/config.toml- name: Install Kubernetes 1.29 (hold versions)  ansible.builtin.apt:    name: [kubelet=1.29.*, kubeadm=1.29.*, kubectl=1.29.*]    state: present<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<blockquote>\n<p><strong>Ubuntu 22.04 + cgroups v2:<\/strong> \u0411\u0435\u0437 <code>SystemdCgroup = true<\/code> \u0432 containerd kubelet \u043d\u0435 \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442. \u041d\u0430 Ubuntu 24.04 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0435.<\/p>\n<\/blockquote>\n<p><strong>\u2192 <\/strong><a href=\"https:\/\/github.com\/TokarenkoKonstantin\/ansible-k8s\" rel=\"noopener noreferrer nofollow\"><strong>ansible-k8s \u043d\u0430 GitHub<\/strong><\/a><\/p>\n<hr\/>\n<h4>Calico CNI: \u043f\u043e\u0447\u0435\u043c\u0443 IPIP, \u0430 \u043d\u0435 BGP<\/h4>\n<p>Calico \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0436\u0438\u043c\u043e\u0432 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0442\u0440\u0430\u0444\u0438\u043a\u0430:<\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u0420\u0435\u0436\u0438\u043c<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041a\u043e\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>IPIP<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0418\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u0438\u0440\u0443\u0435\u0442 pod-\u0442\u0440\u0430\u0444\u0438\u043a \u0432 IP<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0412\u0435\u0437\u0434\u0435, \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 L2 \u043c\u0435\u0436\u0434\u0443 \u043d\u043e\u0434\u0430\u043c\u0438<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>VXLAN<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0418\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u044f\u0446\u0438\u044f \u0432 UDP<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041a\u043e\u0433\u0434\u0430 IPIP \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d \u0444\u0430\u0439\u0440\u0432\u043e\u043b\u043e\u043c<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\"><strong>Native BGP<\/strong><\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041f\u0440\u044f\u043c\u0430\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0424\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0436\u0435\u043b\u0435\u0437\u043e \u0441 BGP-\u0440\u043e\u0443\u0442\u0435\u0440\u043e\u043c<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u042f \u0432\u044b\u0431\u0440\u0430\u043b <strong>IPIP<\/strong> \u2014 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 VMware \u0431\u0435\u0437 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a.<\/p>\n<p>\u0412\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c: Calico \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 BGP \u0432 \u043e\u0431\u043e\u0438\u0445 \u0440\u0435\u0436\u0438\u043c\u0430\u0445 (IPIP \u0438 VXLAN) \u2014 <strong>\u0434\u043b\u044f \u043e\u0431\u043c\u0435\u043d\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u043d\u043e\u0434\u0430\u043c\u0438<\/strong> (node-to-node mesh, iBGP). \u041d\u043e \u0441\u0430\u043c \u0442\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0434\u043e\u0432 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0438\u0434\u0451\u0442 \u0447\u0435\u0440\u0435\u0437 \u0442\u0443\u043d\u043d\u0435\u043b\u0438, \u0430 \u043d\u0435 \u043d\u0430\u0442\u0438\u0432\u043d\u043e. BGP \u0437\u0434\u0435\u0441\u044c \u2014 \u043d\u0435 \u043f\u0440\u043e \u0432\u043d\u0435\u0448\u043d\u044e\u044e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044e, \u0430 \u043f\u0440\u043e \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044e \u0442\u0430\u0431\u043b\u0438\u0446 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430.<\/p>\n<pre><code class=\"bash\">kubectl apply -f https:\/\/raw.githubusercontent.com\/projectcalico\/calico\/v3.29.3\/manifests\/calico.yaml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<hr\/>\n<h4>\u0413\u0440\u0430\u0431\u043b\u0438 #1 \u2014 MTU \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0431\u0438\u043b TLS<\/h4>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 Calico \u043d\u043e\u0434\u044b \u043f\u0435\u0440\u0435\u0448\u043b\u0438 \u0432 Ready. \u041f\u043e\u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0437\u0430\u0434\u0435\u043f\u043b\u043e\u0438\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u2014 pods \u0443\u0448\u043b\u0438 \u0432 <code>ImagePullBackOff<\/code>.<\/p>\n<pre><code class=\"bash\">kubectl describe pod product-service-xxx | grep -A5 Warning# Warning  Failed  Failed to pull image \"ghcr.io\/...\": EOF<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430\u0447\u0430\u043b \u043a\u043e\u043f\u0430\u0442\u044c. \u0422\u043e\u043a\u0435\u043d\u044b \u2014 \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435. \u041f\u0440\u0430\u0432\u0430 \u2014 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e. \u041d\u0438\u0447\u0435\u0433\u043e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u0433\u043e.<\/p>\n<p><strong>\u0414\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430 MTU:<\/strong><\/p>\n<pre><code class=\"bash\"># \u0421\u043c\u043e\u0442\u0440\u0438\u043c MTU \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430ip link show ens33# ens33: mtu 1500# \u0421\u043c\u043e\u0442\u0440\u0438\u043c MTU IPIP \u0442\u0443\u043d\u043d\u0435\u043b\u044fip link show tunl0# tunl0: mtu 1480# \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0440\u0430\u0437\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430ping -M do -s 1400 192.168.11.102  # OKping -M do -s 1450 192.168.11.102  # message too long \u2190 \u0432\u043e\u0442 \u043e\u043d\u043e<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0427\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442:<\/strong><\/p>\n<pre><code>\u0424\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 MTU = 1500IPIP \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a = 20 \u0431\u0430\u0439\u0442\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 MTU \u0434\u043b\u044f pod \u0442\u0440\u0430\u0444\u0438\u043a\u0430 = 1480TLS Certificate \u043f\u0430\u043a\u0435\u0442 \u2248 1460 \u0431\u0430\u0439\u0442\u0421 IPIP \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u043c: 1460 + 20 = 1480 \u2014 \u043d\u0430 \u0433\u0440\u0430\u043d\u0438\u041f\u0440\u0438 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 TLS \u0440\u0430\u0437\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u2192 EOF<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0424\u0438\u043a\u0441 \u2014 MTU 1350 \u0441 \u0437\u0430\u043f\u0430\u0441\u043e\u043c:<\/strong><\/p>\n<pre><code class=\"bash\"># \u041f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0447\u0435\u0440\u0435\u0437 netplan (Ubuntu 22.04)nano \/etc\/netplan\/00-installer-config.yaml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"yaml\">network:  ethernets:    ens33:      dhcp4: false      addresses: [192.168.11.102\/24]      mtu: 1350        # \u2190 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u0443 \u0441\u0442\u0440\u043e\u043a\u0443      routes:        - to: default          via: 192.168.11.1<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"bash\">netplan apply<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e <code>ImagePullBackOff<\/code> \u043f\u0440\u043e\u043f\u0430\u043b \u043c\u0433\u043d\u043e\u0432\u0435\u043d\u043d\u043e. \u041f\u043e\u043b\u0434\u043d\u044f \u0434\u0435\u0431\u0430\u0436\u0438\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u043e\u0434\u043d\u043e \u0447\u0438\u0441\u043b\u043e.<\/p>\n<hr\/>\n<h3>\u0427\u0430\u0441\u0442\u044c 2 \u2014 \u0421\u0435\u0442\u044c \u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u0438\u0437\u0432\u043d\u0435<\/h3>\n<h4>MetalLB: \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 IP \u0434\u043b\u044f bare-metal<\/h4>\n<p>\u0412 \u043e\u0431\u043b\u0430\u043a\u0435 <code>Service: LoadBalancer<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 IP \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438. \u0412 bare-metal \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435 \u043e\u043d \u043d\u0430\u0432\u0441\u0435\u0433\u0434\u0430 \u0432 <code>&lt;pending&gt;<\/code>. MetalLB \u0432\u044b\u0434\u0430\u0451\u0442 IP \u0438\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0443\u043b\u0430 \u0447\u0435\u0440\u0435\u0437 L2 ARP:<\/p>\n<pre><code class=\"bash\">kubectl apply -f https:\/\/raw.githubusercontent.com\/metallb\/metallb\/v0.14.9\/config\/manifests\/metallb-native.yaml<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"yaml\">apiVersion: metallb.io\/v1beta1kind: IPAddressPoolspec:  addresses:    - 192.168.11.200-192.168.11.210---apiVersion: metallb.io\/v1beta1kind: L2Advertisementmetadata:  name: l2adv  namespace: metallb-system<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<blockquote>\n<p><strong>\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 L2 \u0440\u0435\u0436\u0438\u043c\u0430:<\/strong> \u043f\u0440\u0438 \u043e\u0442\u043a\u0430\u0437\u0435 \u043d\u043e\u0434\u044b-\u043b\u0438\u0434\u0435\u0440\u0430 ARP \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u0434\u043e \u043c\u0438\u043d\u0443\u0442\u044b, \u0447\u0430\u0441\u0442\u044c \u0442\u0440\u0430\u0444\u0438\u043a\u0430 \u0442\u0435\u0440\u044f\u0435\u0442\u0441\u044f. \u0414\u043b\u044f production \u043d\u0430 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0436\u0435\u043b\u0435\u0437\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u0435\u0435 \u0440\u0435\u0436\u0438\u043c BGP \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0440\u043e\u0443\u0442\u0435\u0440\u0430. \u0412 \u043c\u043e\u0451\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438 VMware L2 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e.<\/p>\n<\/blockquote>\n<p>Ingress-NGINX \u043f\u043e\u043b\u0443\u0447\u0438\u043b IP <code>192.168.11.200<\/code>. \u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0441\u0430\u0439\u0442.<\/p>\n<hr\/>\n<h3>\u0427\u0430\u0441\u0442\u044c 3 \u2014 GitOps \u0438 CI\/CD<\/h3>\n<h4>ArgoCD: \u043e\u0442 push \u0434\u043e Running \u0437\u0430 2 \u043c\u0438\u043d\u0443\u0442\u044b<\/h4>\n<pre><code>git push    \u2193GitHub Actions: build \u2192 push image \u2192 update tag \u0432 k8s\/base\/deployment.yaml \u2192 git commit    \u2193ArgoCD \u0432\u0438\u0434\u0438\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0430 (polling \u043a\u0430\u0436\u0434\u044b\u0435 3 \u043c\u0438\u043d \u0438\u043b\u0438 webhook)    \u2193kubectl apply \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438    \u2193\u041d\u043e\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<hr\/>\n<h4>\u0413\u0440\u0430\u0431\u043b\u0438 #2 \u2014 git push rejected \u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u043c\u043e\u0451 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u2014 \u043a\u043e\u0441\u0442\u044b\u043b\u044c<\/h4>\n<p>\u041f\u0440\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c GitOps \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0433\u043e\u043d\u043a\u0430: GitHub Actions \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442 \u0438 \u043f\u0443\u0448\u0438\u0442 \u043a\u043e\u043c\u043c\u0438\u0442. \u0415\u0441\u043b\u0438 \u0432 \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u0443\u0448\u0438\u0448\u044c \u0442\u044b \u2014 rejected.<\/p>\n<p><strong>\u041c\u043e\u0451 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f pet-\u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/strong><\/p>\n<pre><code class=\"bash\">git stash &amp;&amp; git pull --rebase &amp;&amp; git stash pop &amp;&amp; git push<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u041f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e \u043a\u043e\u0441\u0442\u044b\u043b\u044c:<\/strong> \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 <code>git pull --rebase<\/code> \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0447\u0443\u0436\u0438\u0435 \u043a\u043e\u043c\u043c\u0438\u0442\u044b. \u042d\u0442\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u043e\u0435 \u043a\u043e\u0433\u0434\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043e\u0434\u0438\u043d.<\/p>\n<p><strong>\u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e:<\/strong><\/p>\n<ul>\n<li>\n<p><a href=\"https:\/\/argocd-image-updater.readthedocs.io\/\" rel=\"noopener noreferrer nofollow\"><strong>ArgoCD Image Updater<\/strong><\/a> \u2014 \u0441\u043b\u0435\u0434\u0438\u0442 \u0437\u0430 \u043d\u043e\u0432\u044b\u043c\u0438 \u0442\u0435\u0433\u0430\u043c\u0438 \u0432 registry \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u043e\u0431\u0440\u0430\u0437 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0430 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438. \u041d\u0438\u043a\u0430\u043a\u0438\u0445 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p><strong>Pull Request + auto-merge<\/strong> \u2014 GitHub Actions \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 PR \u0441 \u043d\u043e\u0432\u044b\u043c \u0442\u0435\u0433\u043e\u043c, \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u0435\u0440\u0436\u0438\u0442 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a.<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f pet-\u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u043e\u0434\u043d\u0438\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c rebase \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0414\u043b\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 Image Updater.<\/p>\n<hr\/>\n<h3>\u0427\u0430\u0441\u0442\u044c 4 \u2014 Observability \u0438 \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445<\/h3>\n<h4>Prometheus + Grafana<\/h4>\n<pre><code class=\"bash\">helm install kube-prometheus prometheus-community\/kube-prometheus-stack \\  --namespace monitoring \\  --create-namespace \\  --version 65.1.1    # \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u0432\u0435\u0440\u0441\u0438\u044e \u0447\u0430\u0440\u0442\u0430<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/url\" alt=\"https:\/\/raw.githubusercontent.com\/TokarenkoKonstantin\/cloud-shop\/main\/screenshots\/grafana-cluster-overview.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/url 780w,&#10;       https:\/\/url 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>https:\/\/raw.githubusercontent.com\/TokarenkoKonstantin\/cloud-shop\/main\/screenshots\/grafana-cluster-overview.png<\/figcaption><\/div>\n<\/figure>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/url\" alt=\"https:\/\/raw.githubusercontent.com\/TokarenkoKonstantin\/cloud-shop\/main\/screenshots\/grafana-node-exporter.png\" sizes=\"(max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/url 780w,&#10;       https:\/\/url 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>https:\/\/raw.githubusercontent.com\/TokarenkoKonstantin\/cloud-shop\/main\/screenshots\/grafana-node-exporter.png<\/figcaption><\/div>\n<\/figure>\n<p>\u041d\u0430 \u0434\u0430\u0448\u0431\u043e\u0440\u0434\u0435 \u0432\u0438\u0434\u043d\u043e CPU\/RAM \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u0439 \u043d\u043e\u0434\u0435, \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c, \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u0434\u043e\u0432 <code>product-service<\/code>, <code>order-service<\/code>.<\/p>\n<hr\/>\n<h4>PostgreSQL HA \u0447\u0435\u0440\u0435\u0437 CloudNativePG<\/h4>\n<pre><code class=\"bash\">helm install cnpg cloudnative-pg\/cloudnative-pg \\  --namespace cnpg-system \\  --create-namespace \\  --version 0.21.0    # \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u0432\u0435\u0440\u0441\u0438\u044e<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code class=\"yaml\">apiVersion: postgresql.cnpg.io\/v1kind: Clustermetadata:  name: postgresspec:  instances: 3          # 1 primary + 2 replica  storage:    size: 10Gi<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0442\u043e\u043a\u043e\u0432\u0430\u044f \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u044f, \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 failover \u043f\u0440\u0438 \u043f\u0430\u0434\u0435\u043d\u0438\u0438 Primary.<\/p>\n<hr\/>\n<h3>\u0427\u0430\u0441\u0442\u044c 5 \u2014 \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0438 \u043f\u043b\u0430\u043d\u044b<\/h3>\n<h4>\u0413\u0440\u0430\u0431\u043b\u0438 #3 \u2014 Calico BGP \u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430\u044f \u043d\u043e\u0434\u0430<\/h4>\n<p>\u0412 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u0434\u044b \u043d\u0430 k8s-node-4 \u0441\u0442\u0430\u043b\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0441 \u0434\u0440\u0443\u0433\u0438\u0445 \u043d\u043e\u0434. \u041f\u043e\u0434\u044b \u0436\u0438\u0432\u044b\u0435, \u0442\u0440\u0430\u0444\u0438\u043a \u043d\u0435 \u0434\u043e\u0445\u043e\u0434\u0438\u0442.<\/p>\n<p><strong>\u0414\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430:<\/strong><\/p>\n<pre><code class=\"bash\"># \u0421\u0442\u0430\u0442\u0443\u0441 BGP \u0441\u0435\u0441\u0441\u0438\u0439 \u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043d\u043e\u0439 \u043d\u043e\u0434\u0435kubectl exec -n calico-system calico-node-XXXXX -- birdcl show protocols | grep BGP# BGP \u0441\u0435\u0441\u0441\u0438\u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043d\u043e\u0434\u0430\u043c\u0438 \u2014 Established# BGP \u0441 node-4 \u2014 Active (\u043d\u0435 Established)# \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u043b\u0438 BGP \u0434\u0435\u043c\u043e\u043d \u043d\u0430 node-4ssh ubuntu@192.168.11.105 \"ss -tulpn | grep 179\"# tcp LISTEN 0 128 *:179  *:*  users:((\"bird\",pid=1234))# \u0414\u0435\u043c\u043e\u043d \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u0438 \u0441\u043b\u0443\u0448\u0430\u0435\u0442 \u2014 \u0437\u043d\u0430\u0447\u0438\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0441\u0435\u0442\u0438, \u043d\u0435 \u0432 \u0434\u0435\u043c\u043e\u043d\u0435# \u0421\u043c\u043e\u0442\u0440\u0438\u043c \u043b\u043e\u0433\u0438 calico-node \u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043d\u043e\u0439 \u043d\u043e\u0434\u0435kubectl logs -n calico-system calico-node-XXXXX | grep -i bgp | tail -20# ... BGP session with 192.168.11.105 went down: Hold timer expired# Hold timer expired \u2014 keepalive \u043f\u0430\u043a\u0435\u0442\u044b \u043d\u0435 \u0434\u043e\u0445\u043e\u0434\u044f\u0442# \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043f\u043e\u0442\u0435\u0440\u044e \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u043d\u043e\u0434\u0430\u043c\u0438ping -c 100 192.168.11.105 | tail -2# 8 packets transmitted, 8 received, 0% packet loss \u2190 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 ping OK# \u041d\u043e BGP keepalive \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 179nc -zv 192.168.11.105 179  # \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442# \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0432 \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u0434 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u043d\u0430 VMware VMNet<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u0412\u044b\u0432\u043e\u0434:<\/strong> bird \u0437\u0430\u043f\u0443\u0449\u0435\u043d, \u043f\u043e\u0440\u0442 \u0441\u043b\u0443\u0448\u0430\u0435\u0442, \u043e\u0431\u044b\u0447\u043d\u044b\u0439 ping \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041d\u043e BGP keepalive \u043f\u0430\u043a\u0435\u0442\u044b \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0442\u0435\u0440\u044f\u044e\u0442\u0441\u044f \u0438\u043c\u0435\u043d\u043d\u043e \u0432 VMware VMNet \u043f\u043e\u0434 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u2014 Hold timer \u0438\u0441\u0442\u0435\u043a\u0430\u0435\u0442, \u0441\u0435\u0441\u0441\u0438\u044f \u0440\u0432\u0451\u0442\u0441\u044f.<\/p>\n<p><strong>\u0412\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435<\/strong> \u2014 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u043a\u0440\u0438\u0442\u0438\u0447\u043d\u044b\u0435 \u043f\u043e\u0434\u044b (PostgreSQL) \u043d\u0430 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0435 \u043d\u043e\u0434\u044b:<\/p>\n<pre><code class=\"yaml\">spec:  template:    spec:      nodeSelector:        kubernetes.io\/hostname: k8s-node-2<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>\u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435<\/strong> \u2014 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 VXLAN \u0440\u0435\u0436\u0438\u043c Calico, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u0438 BGP \u0434\u043b\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0440\u0430\u0444\u0438\u043a\u0430. \u0412 \u043f\u043b\u0430\u043d\u0430\u0445.<\/p>\n<hr\/>\n<h4>\u0427\u0442\u043e \u0435\u0449\u0451 \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u043d\u043e<\/h4>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<th>\n<p align=\"left\">\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u0422\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435<\/p>\n<\/th>\n<th>\n<p align=\"left\">\u041f\u043b\u0430\u043d<\/p>\n<\/th>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">MTU persistence<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0422\u043e\u043b\u044c\u043a\u043e node-1 \u0447\u0435\u0440\u0435\u0437 netplan, \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u2014 runtime<\/p>\n<\/td>\n<td>\n<p align=\"left\">Ansible \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043d\u043e\u0434<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Calico VXLAN<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f IPIP, BGP \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u0435\u043d \u043d\u0430 VMware<\/p>\n<\/td>\n<td>\n<p align=\"left\">Migrate to VXLAN<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">\u0411\u044d\u043a\u0430\u043f\u044b<\/p>\n<\/td>\n<td>\n<p align=\"left\">\u041d\u0435\u0442<\/p>\n<\/td>\n<td>\n<p align=\"left\">Velero + MinIO<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">TLS\/HTTPS<\/p>\n<\/td>\n<td>\n<p align=\"left\">HTTP<\/p>\n<\/td>\n<td>\n<p align=\"left\">Cert-Manager + Let\u2019s Encrypt<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">Secrets<\/p>\n<\/td>\n<td>\n<p align=\"left\">Plaintext \u0432 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0430\u0445<\/p>\n<\/td>\n<td>\n<p align=\"left\">Sealed Secrets<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td>\n<p align=\"left\">GitOps \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u044b<\/p>\n<\/td>\n<td>\n<p align=\"left\">git rebase (\u043a\u043e\u0441\u0442\u044b\u043b\u044c)<\/p>\n<\/td>\n<td>\n<p align=\"left\">ArgoCD Image Updater<\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u041f\u0435\u0440\u0444\u0435\u043a\u0446\u0438\u043e\u043d\u0438\u0437\u043c \u2014 \u0432\u0440\u0430\u0433 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441\u0430. \u041b\u0443\u0447\u0448\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0441 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u043c\u0438 \u0441\u043b\u0430\u0431\u043e\u0441\u0442\u044f\u043c\u0438, \u0447\u0435\u043c \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u043b\u0430\u043d \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0441\u044f.<\/p>\n<hr\/>\n<h3>\u0418\u0442\u043e\u0433<\/h3>\n<pre><code class=\"bash\">kubectl get nodes# NAME         STATUS   ROLES           AGE   VERSION# k8s-master   Ready    control-plane   42d   v1.29.4# k8s-node-1   Ready    &lt;none&gt;          42d   v1.29.4# k8s-node-2   Ready    &lt;none&gt;          42d   v1.29.4# k8s-node-3   Ready    &lt;none&gt;          42d   v1.29.4# k8s-node-4   Ready    &lt;none&gt;          42d   v1.29.4kubectl get pods -n ecommerce# NAME                                READY   STATUS# frontend-65bb4b9d8d-wlxbk           1\/1     Running# order-service-64d768ddff-2gqf4      1\/1     Running# postgres-0                          1\/1     Running# product-service-67cf48889b-9gmtr    1\/1     Running# user-service-5b7bbf799b-5gvwd       1\/1     Running<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><strong>GitHub \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438:<\/strong><\/p>\n<ul>\n<li>\n<p>\ud83c\udfd7\ufe0f <a href=\"https:\/\/github.com\/TokarenkoKonstantin\/cloud-shop\" rel=\"noopener noreferrer nofollow\"><strong>cloud-shop<\/strong><\/a> \u2014 \u043f\u043e\u043b\u043d\u0430\u044f \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 + \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435<\/p>\n<\/li>\n<li>\n<p>\u2699\ufe0f <a href=\"https:\/\/github.com\/TokarenkoKonstantin\/ansible-k8s\" rel=\"noopener noreferrer nofollow\"><strong>ansible-k8s<\/strong><\/a> \u2014 Ansible playbook: \u043e\u0434\u0438\u043d \u0437\u0430\u043f\u0443\u0441\u043a \u2192 \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0442\u0435\u0440<\/p>\n<\/li>\n<li>\n<p>\ud83d\udd04 <a href=\"https:\/\/github.com\/TokarenkoKonstantin\/github-actions-templates\" rel=\"noopener noreferrer nofollow\"><strong>github-actions-templates<\/strong><\/a> \u2014 \u0433\u043e\u0442\u043e\u0432\u044b\u0435 CI\/CD \u0448\u0430\u0431\u043b\u043e\u043d\u044b<\/p>\n<\/li>\n<\/ul>\n<p>\u0415\u0441\u043b\u0438 \u0441\u0442\u0430\u043b\u043a\u0438\u0432\u0430\u043b\u0438\u0441\u044c \u0441 \u043f\u043e\u0445\u043e\u0436\u0438\u043c\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438 \u0438\u043b\u0438 \u0435\u0441\u0442\u044c \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u2014 \u043f\u0438\u0448\u0438\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445!<\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1041356\/\">https:\/\/habr.com\/ru\/articles\/1041356\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u041f\u0440\u0435\u0434\u044b\u0441\u0442\u043e\u0440\u0438\u044f\u041a\u043e\u0433\u0434\u0430 \u0438\u0437\u0443\u0447\u0430\u0435\u0448\u044c DevOps \u043f\u043e \u043a\u0443\u0440\u0441\u0430\u043c \u2014 \u0432\u0441\u0451 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u0440\u043e\u0441\u0442\u043e. \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u043b minikube, \u043f\u043e\u0434\u043d\u044f\u043b pod, \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u043b \u043d\u0430 kubectl get pods \u2014 \u043a\u0440\u0430\u0441\u043e\u0442\u0430. \u0410 \u043f\u043e\u0442\u043e\u043c \u043f\u044b\u0442\u0430\u0435\u0448\u044c\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0435\u0435 \u0438 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0448\u044c: \u043c\u0435\u0436\u0434\u0443 \u201chello world \u0432 Kubernetes\u201d \u0438 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0439 \u0438\u043d\u0444\u0440\u0430\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439 \u2014 \u043f\u0440\u043e\u043f\u0430\u0441\u0442\u044c.\u042f \u0440\u0435\u0448\u0438\u043b \u044d\u0442\u0443 \u043f\u0440\u043e\u043f\u0430\u0441\u0442\u044c \u043f\u0440\u043e\u0439\u0442\u0438. \u0412\u0437\u044f\u043b 5 \u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u0448\u0438\u043d \u043d\u0430 VMware Workstation \u0438 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u043b \u043d\u0430 \u043d\u0438\u0445 production-ready \u043a\u043b\u0430\u0441\u0442\u0435\u0440 \u0441 \u043d\u0443\u043b\u044f. \u0421 CI\/CD, GitOps, \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u043e\u043c, \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e\u0441\u0442\u044c\u044e \u0438 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435\u043c.\u0420\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0447\u0442\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c, \u043a\u0430\u043a \u0438\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u2014 \u0438 \u0433\u043b\u0430\u0432\u043d\u043e\u0435, \u043a\u0430\u043a\u0438\u0435 \u0433\u0440\u0430\u0431\u043b\u0438 \u044f \u0441\u043e\u0431\u0440\u0430\u043b \u043f\u043e \u0434\u043e\u0440\u043e\u0433\u0435. \u0418\u0445 \u0431\u044b\u043b\u043e \u043d\u0435\u043c\u0430\u043b\u043e.\u041e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435: Ubuntu 22.04 LTS (ubuntu-22.04.4-live-server-amd64), VMware Workstation 17, Kubernetes 1.29, Calico 3.29.3\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442React + Go + FastAPI + PostgreSQL, \u0432\u0441\u0451 \u0432 Kubernetes\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0412\u0435\u0440\u0441\u0438\u044f \/ \u0414\u0435\u0442\u0430\u043b\u0438Kubernetes1.29, kubeadm, 1 master + 4 workersCNICalico v3.29.3, \u0440\u0435\u0436\u0438\u043c IPIPLoad BalancerMetalLB v0.14.9, L2 ARPIngressingress-nginx v1.10CI\/CDGitHub Actions + ArgoCD v2.10\u0411\u0414CloudNativePG v1.23, 1 primary + 2 replica\u041c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433kube-prometheus-stack chart v65.1.1IaCTerraform + AnsibleSecurityTrivy \u0432 \u043a\u0430\u0436\u0434\u043e\u043c pipeline\u0427\u0430\u0441\u0442\u044c 1 \u2014 \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u04305 VM \u0438 Ansible \u0432\u043c\u0435\u0441\u0442\u043e \u0440\u0443\u0447\u043d\u043e\u0439 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438k8s-master   192.168.11.101   control-plane   2 CPU \/ 4GB RAMk8s-node-1   192.168.11.102   worker          2 CPU \/ 4GB RAMk8s-node-2   192.168.11.103   worker          2 CPU \/ 4GB RAMk8s-node-3   192.168.11.104   worker          2 CPU \/ 4GB RAMk8s-node-4   192.168.11.105   worker          2 CPU \/ 4GB RAM\u041d\u0430\u043f\u0438\u0441\u0430\u043b Ansible playbook \u0441 \u0442\u0440\u0435\u043c\u044f \u0440\u043e\u043b\u044f\u043c\u0438. \u0417\u0430\u043f\u0443\u0441\u043a:ansible-playbook -i inventory.ini install-k8s.yml\u041a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0437\u0430\u0434\u0430\u0447\u0438 k8s-common (\u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u043a\u0430\u0436\u0434\u043e\u0439 \u043d\u043e\u0434\u0435):- name: Disable swap permanently  ansible.builtin.replace:    path: \/etc\/fstab    regexp: &#8216;^([^#].*\\sswap\\s.*)$&#8217;    replace: &#8216;# \\1&#8217;- name: Load kernel modules  ansible.builtin.modprobe:    name: &#171;{{ item }}&#187;  loop: [overlay, br_netfilter]- name: Set sysctl for Kubernetes networking  ansible.posix.sysctl:    name: &#171;{{ item.key }}&#187;    value: &#171;{{ item.value }}&#187;    sysctl_file: \/etc\/sysctl.d\/k8s.conf    reload: true  loop:    &#8212; { key: net.bridge.bridge-nf-call-iptables, value: &#171;1&#187; }    &#8212; { key: net.bridge.bridge-nf-call-ip6tables, value: &#171;1&#187; }    &#8212; { key: net.ipv4.ip_forward, value: &#171;1&#187; }- name: Configure containerd with SystemdCgroup  # Ubuntu 22.04 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 cgroups v2 \u2014 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c SystemdCgroup  ansible.builtin.shell: |    containerd config default &gt; \/etc\/containerd\/config.toml    sed -i &#8216;s\/SystemdCgroup = false\/SystemdCgroup = true\/&#8217; \/etc\/containerd\/config.toml- name: Install Kubernetes 1.29 (hold versions)  ansible.builtin.apt:    name: [kubelet=1.29.*, kubeadm=1.29.*, kubectl=1.29.*]    state: presentUbuntu 22.04 + cgroups v2: \u0411\u0435\u0437 SystemdCgroup = true \u0432 containerd kubelet \u043d\u0435 \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442. \u041d\u0430 Ubuntu 24.04 \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u043e\u0435.\u2192 ansible-k8s \u043d\u0430 GitHubCalico CNI: \u043f\u043e\u0447\u0435\u043c\u0443 IPIP, \u0430 \u043d\u0435 BGPCalico \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0436\u0438\u043c\u043e\u0432 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0442\u0440\u0430\u0444\u0438\u043a\u0430:\u0420\u0435\u0436\u0438\u043c\u041a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442\u041a\u043e\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044cIPIP\u0418\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u0438\u0440\u0443\u0435\u0442 pod-\u0442\u0440\u0430\u0444\u0438\u043a \u0432 IP\u0412\u0435\u0437\u0434\u0435, \u043d\u0435 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 L2 \u043c\u0435\u0436\u0434\u0443 \u043d\u043e\u0434\u0430\u043c\u0438VXLAN\u0418\u043d\u043a\u0430\u043f\u0441\u0443\u043b\u044f\u0446\u0438\u044f \u0432 UDP\u041a\u043e\u0433\u0434\u0430 IPIP \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u043d \u0444\u0430\u0439\u0440\u0432\u043e\u043b\u043e\u043cNative BGP\u041f\u0440\u044f\u043c\u0430\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f\u0424\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0436\u0435\u043b\u0435\u0437\u043e \u0441 BGP-\u0440\u043e\u0443\u0442\u0435\u0440\u043e\u043c\u042f \u0432\u044b\u0431\u0440\u0430\u043b IPIP \u2014 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 VMware \u0431\u0435\u0437 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a.\u0412\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c: Calico \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 BGP \u0432 \u043e\u0431\u043e\u0438\u0445 \u0440\u0435\u0436\u0438\u043c\u0430\u0445 (IPIP \u0438 VXLAN) \u2014 \u0434\u043b\u044f \u043e\u0431\u043c\u0435\u043d\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430\u043c\u0438 \u043c\u0435\u0436\u0434\u0443 \u043d\u043e\u0434\u0430\u043c\u0438 (node-to-node mesh, iBGP). \u041d\u043e \u0441\u0430\u043c \u0442\u0440\u0430\u0444\u0438\u043a \u043f\u043e\u0434\u043e\u0432 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0438\u0434\u0451\u0442 \u0447\u0435\u0440\u0435\u0437 \u0442\u0443\u043d\u043d\u0435\u043b\u0438, \u0430 \u043d\u0435 \u043d\u0430\u0442\u0438\u0432\u043d\u043e. BGP \u0437\u0434\u0435\u0441\u044c \u2014 \u043d\u0435 \u043f\u0440\u043e \u0432\u043d\u0435\u0448\u043d\u044e\u044e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044e, \u0430 \u043f\u0440\u043e \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044e \u0442\u0430\u0431\u043b\u0438\u0446 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0430.kubectl apply -f https:\/\/raw.githubusercontent.com\/projectcalico\/calico\/v3.29.3\/manifests\/calico.yaml\u0413\u0440\u0430\u0431\u043b\u0438 #1 \u2014 MTU \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0443\u0431\u0438\u043b TLS\u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 Calico \u043d\u043e\u0434\u044b \u043f\u0435\u0440\u0435\u0448\u043b\u0438 \u0432 Ready. \u041f\u043e\u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0437\u0430\u0434\u0435\u043f\u043b\u043e\u0438\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u2014 pods \u0443\u0448\u043b\u0438 \u0432 ImagePullBackOff.kubectl describe pod product-service-xxx | grep -A5 Warning# Warning  Failed  Failed to pull image &#171;ghcr.io\/&#8230;&#187;: EOF\u041d\u0430\u0447\u0430\u043b \u043a\u043e\u043f\u0430\u0442\u044c. \u0422\u043e\u043a\u0435\u043d\u044b \u2014 \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435. \u041f\u0440\u0430\u0432\u0430 \u2014 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e. \u041d\u0438\u0447\u0435\u0433\u043e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e\u0433\u043e.\u0414\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430 MTU:# \u0421\u043c\u043e\u0442\u0440\u0438\u043c MTU \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430ip link show ens33# ens33: mtu 1500# \u0421\u043c\u043e\u0442\u0440\u0438\u043c MTU IPIP \u0442\u0443\u043d\u043d\u0435\u043b\u044fip link show tunl0# tunl0: mtu 1480# \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043f\u0440\u043e\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0440\u0430\u0437\u043d\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430ping -M do -s 1400 192.168.11.102  # OKping -M do -s 1450 192.168.11.102  # message too long \u2190 \u0432\u043e\u0442 \u043e\u043d\u043e\u0427\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442:\u0424\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u0438\u0439 MTU = 1500IPIP \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a = 20 \u0431\u0430\u0439\u0442\u042d\u0444\u0444\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 MTU \u0434\u043b\u044f pod \u0442\u0440\u0430\u0444\u0438\u043a\u0430 = 1480TLS Certificate \u043f\u0430\u043a\u0435\u0442 \u2248 1460 \u0431\u0430\u0439\u0442\u0421 IPIP \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u043e\u043c: 1460 + 20 = 1480 \u2014 \u043d\u0430 \u0433\u0440\u0430\u043d\u0438\u041f\u0440\u0438 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 TLS \u0440\u0430\u0437\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u2192 EOF\u0424\u0438\u043a\u0441 \u2014 MTU 1350 \u0441 \u0437\u0430\u043f\u0430\u0441\u043e\u043c:# \u041f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e \u0447\u0435\u0440\u0435\u0437 netplan (Ubuntu 22.04)nano \/etc\/netplan\/00-installer-config.yamlnetwork:  ethernets:    ens33:      dhcp4: false      addresses: [192.168.11.102\/24]      mtu: 1350        # \u2190 \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u0443 \u0441\u0442\u0440\u043e\u043a\u0443      routes:        &#8212; to: default          via: 192.168.11.1netplan apply\u041f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e ImagePullBackOff \u043f\u0440\u043e\u043f\u0430\u043b \u043c\u0433\u043d\u043e\u0432\u0435\u043d\u043d\u043e. \u041f\u043e\u043b\u0434\u043d\u044f \u0434\u0435\u0431\u0430\u0436\u0438\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u043e\u0434\u043d\u043e \u0447\u0438\u0441\u043b\u043e.\u0427\u0430\u0441\u0442\u044c 2 \u2014 \u0421\u0435\u0442\u044c \u0438 \u0434\u043e\u0441\u0442\u0443\u043f \u0438\u0437\u0432\u043d\u0435MetalLB: \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 IP \u0434\u043b\u044f bare-metal\u0412 \u043e\u0431\u043b\u0430\u043a\u0435 Service: LoadBalancer \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u0432\u043d\u0435\u0448\u043d\u0438\u0439 IP \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438. \u0412 bare-metal \u043a\u043b\u0430\u0441\u0442\u0435\u0440\u0435 \u043e\u043d \u043d\u0430\u0432\u0441\u0435\u0433\u0434\u0430 \u0432 &lt;pending&gt;. MetalLB \u0432\u044b\u0434\u0430\u0451\u0442 IP \u0438\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u043f\u0443\u043b\u0430 \u0447\u0435\u0440\u0435\u0437 L2 ARP:kubectl apply -f https:\/\/raw.githubusercontent.com\/metallb\/metallb\/v0.14.9\/config\/manifests\/metallb-native.yamlapiVersion: metallb.io\/v1beta1kind: IPAddressPoolspec:  addresses:    &#8212; 192.168.11.200-192.168.11.210&#8212;apiVersion: metallb.io\/v1beta1kind: L2Advertisementmetadata:  name: l2adv  namespace: metallb-system\u041e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 L2 \u0440\u0435\u0436\u0438\u043c\u0430: \u043f\u0440\u0438 \u043e\u0442\u043a\u0430\u0437\u0435 \u043d\u043e\u0434\u044b-\u043b\u0438\u0434\u0435\u0440\u0430 ARP \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u0434\u043e \u043c\u0438\u043d\u0443\u0442\u044b, \u0447\u0430\u0441\u0442\u044c \u0442\u0440\u0430\u0444\u0438\u043a\u0430 \u0442\u0435\u0440\u044f\u0435\u0442\u0441\u044f. \u0414\u043b\u044f production \u043d\u0430 \u0444\u0438\u0437\u0438\u0447\u0435\u0441\u043a\u043e\u043c \u0436\u0435\u043b\u0435\u0437\u0435 \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u0435\u0435 \u0440\u0435\u0436\u0438\u043c BGP \u0441 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0440\u043e\u0443\u0442\u0435\u0440\u0430. \u0412 \u043c\u043e\u0451\u043c \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438 VMware L2 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e.Ingress-NGINX \u043f\u043e\u043b\u0443\u0447\u0438\u043b IP 192.168.11.200. \u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0441\u0430\u0439\u0442.\u0427\u0430\u0441\u0442\u044c 3 \u2014 GitOps \u0438 CI\/CDArgoCD: \u043e\u0442 push \u0434\u043e Running \u0437\u0430 2 \u043c\u0438\u043d\u0443\u0442\u044bgit push    \u2193GitHub Actions: build \u2192 push image \u2192 update tag \u0432 k8s\/base\/deployment.yaml \u2192 git commit    \u2193ArgoCD \u0432\u0438\u0434\u0438\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0430 (polling \u043a\u0430\u0436\u0434\u044b\u0435 3 \u043c\u0438\u043d \u0438\u043b\u0438 webhook)    \u2193kubectl apply \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438    \u2193\u041d\u043e\u0432\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u0437\u0430\u043f\u0443\u0449\u0435\u043d\u0430\u0413\u0440\u0430\u0431\u043b\u0438 #2 \u2014 git push rejected \u0438 \u043f\u043e\u0447\u0435\u043c\u0443 \u043c\u043e\u0451 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u2014 \u043a\u043e\u0441\u0442\u044b\u043b\u044c\u041f\u0440\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c GitOps \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0433\u043e\u043d\u043a\u0430: GitHub Actions \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442 \u0438 \u043f\u0443\u0448\u0438\u0442 \u043a\u043e\u043c\u043c\u0438\u0442. \u0415\u0441\u043b\u0438 \u0432 \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u0443\u0448\u0438\u0448\u044c \u0442\u044b \u2014 rejected.\u041c\u043e\u0451 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0434\u043b\u044f pet-\u043f\u0440\u043e\u0435\u043a\u0442\u0430:git stash &amp;&amp; git pull &#8212;rebase &amp;&amp; git stash pop &amp;&amp; git push\u041f\u043e\u0447\u0435\u043c\u0443 \u044d\u0442\u043e \u043a\u043e\u0441\u0442\u044b\u043b\u044c: \u0432 \u043a\u043e\u043c\u0430\u043d\u0434\u0435 git pull &#8212;rebase \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0447\u0443\u0436\u0438\u0435 \u043a\u043e\u043c\u043c\u0438\u0442\u044b. \u042d\u0442\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u043e\u0435 \u043a\u043e\u0433\u0434\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u043e\u0434\u0438\u043d.\u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e:ArgoCD Image Updater \u2014 \u0441\u043b\u0435\u0434\u0438\u0442 \u0437\u0430 \u043d\u043e\u0432\u044b\u043c\u0438 \u0442\u0435\u0433\u0430\u043c\u0438 \u0432 registry \u0438 \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u043e\u0431\u0440\u0430\u0437 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0430 \u0432 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438. \u041d\u0438\u043a\u0430\u043a\u0438\u0445 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u043e\u0432.Pull Request + auto-merge \u2014 GitHub Actions \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442 PR \u0441 \u043d\u043e\u0432\u044b\u043c \u0442\u0435\u0433\u043e\u043c, \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u0435\u0440\u0436\u0438\u0442 \u043f\u043e\u0441\u043b\u0435 \u043f\u0440\u043e\u0432\u0435\u0440\u043e\u043a.\u0414\u043b\u044f pet-\u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u043e\u0434\u043d\u0438\u043c \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u043c rebase \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0414\u043b\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u2014 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 Image Updater.\u0427\u0430\u0441\u0442\u044c 4 \u2014 Observability \u0438 \u0431\u0430\u0437\u0430 \u0434\u0430\u043d\u043d\u044b\u0445Prometheus + Grafanahelm install kube-prometheus prometheus-community\/kube-prometheus-stack \\  &#8212;namespace monitoring \\  &#8212;create-namespace \\  &#8212;version 65.1.1    # \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u0432\u0435\u0440\u0441\u0438\u044e \u0447\u0430\u0440\u0442\u0430https:\/\/raw.githubusercontent.com\/TokarenkoKonstantin\/cloud-shop\/main\/screenshots\/grafana-cluster-overview.pnghttps:\/\/raw.githubusercontent.com\/TokarenkoKonstantin\/cloud-shop\/main\/screenshots\/grafana-node-exporter.png\u041d\u0430 \u0434\u0430\u0448\u0431\u043e\u0440\u0434\u0435 \u0432\u0438\u0434\u043d\u043e CPU\/RAM \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u0439 \u043d\u043e\u0434\u0435, \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c, \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043f\u043e\u0434\u043e\u0432 product-service, order-service.PostgreSQL HA \u0447\u0435\u0440\u0435\u0437 CloudNativePGhelm install cnpg cloudnative-pg\/cloudnative-pg \\  &#8212;namespace cnpg-system \\  &#8212;create-namespace \\  &#8212;version 0.21.0    # \u0444\u0438\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u0432\u0435\u0440\u0441\u0438\u044eapiVersion: postgresql.cnpg.io\/v1kind: Clustermetadata:  name: postgresspec:  instances: 3          # 1 primary + 2 replica  storage:    size: 10Gi\u041f\u043e\u0442\u043e\u043a\u043e\u0432\u0430\u044f \u0440\u0435\u043f\u043b\u0438\u043a\u0430\u0446\u0438\u044f, \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 failover \u043f\u0440\u0438 \u043f\u0430\u0434\u0435\u043d\u0438\u0438 Primary.\u0427\u0430\u0441\u0442\u044c 5 \u2014 \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0438 \u043f\u043b\u0430\u043d\u044b\u0413\u0440\u0430\u0431\u043b\u0438 #3 \u2014 Calico BGP \u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430\u044f \u043d\u043e\u0434\u0430\u0412 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u043e\u0434\u044b \u043d\u0430 k8s-node-4 \u0441\u0442\u0430\u043b\u0438 \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0441 \u0434\u0440\u0443\u0433\u0438\u0445 \u043d\u043e\u0434. \u041f\u043e\u0434\u044b \u0436\u0438\u0432\u044b\u0435, \u0442\u0440\u0430\u0444\u0438\u043a \u043d\u0435 \u0434\u043e\u0445\u043e\u0434\u0438\u0442.\u0414\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430:# \u0421\u0442\u0430\u0442\u0443\u0441 BGP \u0441\u0435\u0441\u0441\u0438\u0439 \u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043d\u043e\u0439 \u043d\u043e\u0434\u0435kubectl exec -n calico-system calico-node-XXXXX &#8212; birdcl show protocols | grep BGP# BGP \u0441\u0435\u0441\u0441\u0438\u0438 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u043d\u043e\u0434\u0430\u043c\u0438 \u2014 Established# BGP \u0441 node-4 \u2014 Active (\u043d\u0435 Established)# \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u043b\u0438 BGP \u0434\u0435\u043c\u043e\u043d \u043d\u0430 node-4ssh ubuntu@192.168.11.105 &#171;ss -tulpn | grep 179&#8243;# tcp LISTEN 0 128 *:179  *:*  users:((&#171;bird&#187;,pid=1234))# \u0414\u0435\u043c\u043e\u043d \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u0438 \u0441\u043b\u0443\u0448\u0430\u0435\u0442 \u2014 \u0437\u043d\u0430\u0447\u0438\u0442 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0432 \u0441\u0435\u0442\u0438, \u043d\u0435 \u0432 \u0434\u0435\u043c\u043e\u043d\u0435# \u0421\u043c\u043e\u0442\u0440\u0438\u043c \u043b\u043e\u0433\u0438 calico-node \u043d\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043d\u043e\u0439 \u043d\u043e\u0434\u0435kubectl logs -n calico-system calico-node-XXXXX | grep -i bgp | tail -20# &#8230; BGP session with 192.168.11.105 went down: Hold timer expired# Hold timer expired \u2014 keepalive \u043f\u0430\u043a\u0435\u0442\u044b \u043d\u0435 \u0434\u043e\u0445\u043e\u0434\u044f\u0442# \u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043f\u043e\u0442\u0435\u0440\u044e \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u043c\u0435\u0436\u0434\u0443 \u043d\u043e\u0434\u0430\u043c\u0438ping -c 100 192.168.11.105 | tail -2# 8 packets transmitted, 8 received, 0% packet loss \u2190 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 ping OK# \u041d\u043e BGP keepalive \u043d\u0430 \u043f\u043e\u0440\u0442\u0443 179nc -zv 192.168.11.105 179  # \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442# \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0432 \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043f\u043e\u0434 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u043d\u0430 VMware VMNet\u0412\u044b\u0432\u043e\u0434: bird \u0437\u0430\u043f\u0443\u0449\u0435\u043d, \u043f\u043e\u0440\u0442 \u0441\u043b\u0443\u0448\u0430\u0435\u0442, \u043e\u0431\u044b\u0447\u043d\u044b\u0439 ping \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041d\u043e BGP keepalive \u043f\u0430\u043a\u0435\u0442\u044b \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0442\u0435\u0440\u044f\u044e\u0442\u0441\u044f \u0438\u043c\u0435\u043d\u043d\u043e \u0432 VMware VMNet \u043f\u043e\u0434 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u043e\u0439 \u2014 Hold timer \u0438\u0441\u0442\u0435\u043a\u0430\u0435\u0442, \u0441\u0435\u0441\u0441\u0438\u044f \u0440\u0432\u0451\u0442\u0441\u044f.\u0412\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u2014 \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u043a\u0440\u0438\u0442\u0438\u0447\u043d\u044b\u0435 \u043f\u043e\u0434\u044b (PostgreSQL) \u043d\u0430 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0435 \u043d\u043e\u0434\u044b:spec:  template:    spec:      nodeSelector:        kubernetes.io\/hostname: k8s-node-2\u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u2014 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 VXLAN \u0440\u0435\u0436\u0438\u043c Calico, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u0442 \u043e\u0442 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u0438 BGP \u0434\u043b\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0440\u0430\u0444\u0438\u043a\u0430. \u0412 \u043f\u043b\u0430\u043d\u0430\u0445.\u0427\u0442\u043e \u0435\u0449\u0451 \u043d\u0435 \u0441\u0434\u0435\u043b\u0430\u043d\u043e\u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0422\u0435\u043a\u0443\u0449\u0435\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u041f\u043b\u0430\u043dMTU persistence\u0422\u043e\u043b\u044c\u043a\u043e node-1 \u0447\u0435\u0440\u0435\u0437 netplan, \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u2014 runtimeAnsible \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043d\u043e\u0434Calico VXLAN\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f IPIP, BGP \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u0435\u043d \u043d\u0430 VMwareMigrate to VXLAN\u0411\u044d\u043a\u0430\u043f\u044b\u041d\u0435\u0442Velero + MinIOTLS\/HTTPSHTTPCert-Manager + Let\u2019s EncryptSecretsPlaintext \u0432 \u043c\u0430\u043d\u0438\u0444\u0435\u0441\u0442\u0430\u0445Sealed SecretsGitOps \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u044bgit rebase (\u043a\u043e\u0441\u0442\u044b\u043b\u044c)ArgoCD Image Updater\u041f\u0435\u0440\u0444\u0435\u043a\u0446\u0438\u043e\u043d\u0438\u0437\u043c \u2014 \u0432\u0440\u0430\u0433 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441\u0430. \u041b\u0443\u0447\u0448\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0441 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u043c\u0438 \u0441\u043b\u0430\u0431\u043e\u0441\u0442\u044f\u043c\u0438, \u0447\u0435\u043c \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u043b\u0430\u043d \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0441\u044f.\u0418\u0442\u043e\u0433kubectl get nodes# NAME         STATUS   ROLES           AGE   VERSION# k8s-master   Ready    control-plane   42d   v1.29.4# k8s-node-1   Ready    &lt;none&gt;          42d   v1.29.4# k8s-node-2   Ready    &lt;none&gt;          42d   v1.29.4# k8s-node-3&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-481636","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/481636","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=481636"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/481636\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=481636"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=481636"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=481636"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}