Linux: збереження заряду батареї ноутбуку
0 (0)

18 Листопада 2022

На цей раз стало мені цікаво – а чи можна якось поекономити заряд батерії ноутбука? Не сказати, що швидко разряжається – на 5-6 годин роботи вистачає, але зайвим не буде.

Знайшов декілька утіліт, про них сьогодні й запишу.

Upower

Перша утілітка – upower:

[simterm]

$ sudo pacman -S upower

[/simterm]

Спочатку можна визвати з опцією --monitor-detail – буде в ріалтаймі виводити інформацію про стан батареї:

[simterm]

$ $ sudo upower --monitor-detail
Monitoring activity from the power daemon. Press Ctrl+C to cancel.
[20:42:20.071]  device changed:     /org/freedesktop/UPower/devices/battery_BAT0
  native-path:          BAT0
  vendor:               SMP
  model:                LNV-5B10W13895
  serial:               2056
  power supply:         yes
  updated:              Fri Nov 18 20:42:20 2022 (0 seconds ago)
  has history:          yes
  has statistics:       yes
  battery
    present:             yes
    rechargeable:        yes
    state:               charging
    warning-level:       none
    energy:              36.7 Wh
    energy-empty:        0 Wh
    energy-full:         0 Wh
    energy-full-design:  0 Wh
    energy-rate:         15.538 W
    voltage:             12.391 V
    charge-cycles:       N/A
    time to full:        22.7 minutes
    percentage:          86%
    technology:          lithium-polymer
    icon-name:          'battery-full-charging-symbolic'
  History (charge):
    1668796940  86.000  charging
    1668796850  85.000  charging
  History (rate):
    1668796940  15.538  charging
    1668796910  15.784  charging
    1668796880  16.006  charging
    1668796850  16.253  charging

[/simterm]

Відразу бачимо модель батареї ноута – LNV-5B10W13895, та її стан – кількість ватт-годин (36.7 Wh), та скількі споживає зараз (15.538 W), і на якій потужності – 12.391 V.

Можна порахувати в ампер-годинах:

[simterm]

>>> 37.31/12.3
3.03

[/simterm]

Тобто зараз 3033 mAh заряду в батареї.

Заодно побачили сам девайс батареї – /org/freedesktop/UPower/devices/battery_BAT0.

Отримати інфо про неї без моніторингу, а один раз – опція -i з пристроєм – sudo upower -i /org/freedesktop/UPower/devices/battery_BAT0.

ACPI

Друга, аналогічна утіліта – acpi, але ще вміє відображати температуру (і не тільки – див. About ACPI):

[simterm]

$ sudo pacman -S acpi

[/simterm]

Виводимо інформацію щодо батареї:

[simterm]

$ acpi -i
Battery 0: Charging, 91%, 00:21:40 until charged
Battery 0: design capacity 3649 mAh, last full capacity 3431 mAh = 94%

[/simterm]

“design capacity 3649 mAh” – все майже як рахували вище, тільки там брали поточний заряд, який зараз десь 94% від design capacity.

Batstat

Третя корисна річ – batstat. Простенька, але може стати в нагоді.

Качаємо репозіторій, збираємо:

[simterm]

$ git clone https://github.com/Juve45/batstat.git
$ cd batstat
$ make
$ chmod +x batstat
$ sudo mv batstat /usr/local/bin/

[/simterm]

І запускаємо:

Powertop

Powertop вміє не просто виводити інформацю про батарею, але й по-перше – виводити інформацю про процеси, які споживать енергію, по-друге – може виконати налаштування для економії заряду.

[simterm]

$ sudo pacman -S powertop

[/simterm]

Запускаємо під рутом:

[simterm]

$ sudo powertop

[/simterm]

В табі Tunables виводиться інформація по налаштуванням, які можуть оптимізувати споживання енергії.

Вибираємо потрібний пункт, Enter – і опція переключається:

Вміє генерувати html:

[simterm]

$ sudo powertop --html=powerreport.html

[/simterm]

І результат:

Можна додати systemd-сервіс, який буде виконувати автоматичний тюнінг при старті системи.

Створюємо файл /etc/systemd/system/powertop.service:

[Unit]
Description=Powertop tunings

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/powertop --auto-tune

[Install]
WantedBy=multi-user.target

Та активуємо:

[simterm]

$ sudo systemctl start powertop.service
$ sudo systemctl enable powertop.service

[/simterm]

TLP

Це просто монстр. Краще почитати більше інформації тут>>> та тут>>>, а зараз про основні можливості.

Встановлюємо:

[simterm]

$ sudo pacman -S tlp
$ sudo pacman -S tlp-rdw

[/simterm]

Є графічний інтерфейс:

[simterm]

$ yay -S tlpui
$ sudo tlpui

[/simterm]

Під капотом вже має всі налаштування, що робить powertop, тож powertop.service краще вікдлючити.

Стартуємо сервіс:

[simterm]

$ sudo systemctl enable tlp.service

[/simterm]

І блокуємо (mask) сервіси, які можуть завадити tlp:

[simterm]

$ sudo systemctl mask systemd-rfkill.service
$ sudo systemctl mask systemd-rfkill.socket

[/simterm]

Файл налаштувань – /etc/tlp.conf, в каталозі /etc/tlp.d/ можна задавати свої параметри.

Вивести параметри, що є зараз:

[simterm]

$ sudo tlp-stat
--- TLP 1.5.0 --------------------------------------------

+++ Configured Settings:
defaults.conf L0004: TLP_ENABLE="1"
defaults.conf L0005: TLP_WARN_LEVEL="3"
defaults.conf L0006: TLP_PERSISTENT_DEFAULT="0"
defaults.conf L0007: DISK_IDLE_SECS_ON_AC="0"
...

[/simterm]

Виводить прям купу всього, що стосується заліза та опцій по оптимізації, і все це можна налаштувати під себе.

Загальні поради

Ну і не забуваємо про самі базові речі.

Яскравість екрану та девайси

Перш за все це, звичайно, яскравість екрану – знизити кнопками Fn +/-brightness, або через файл, в мене це /sys/class/backlight/amdgpu_bl0/brightness:

[simterm]

$ sudo bash -c  'echo -n 25 > /sys/class/backlight/amdgpu_bl0/brightness'

[/simterm]

Ще можна відключити непотрібні USB-девайси, такі як миша/клава/зовнішній диск, та Bluetooth чи/або WiFi, якщо підключені кабелем.

Сервіси

Також має сенс перевірити сервіси в автостарті:

[simterm]

$ systemctl list-unit-files --state=enabled
UNIT FILE                          STATE   PRESET  
acpid.service                      enabled disabled
bluetooth-autoconnect.service      enabled disabled
bluetooth.service                  enabled disabled
gdm.service                        enabled disabled
[email protected]                     enabled enabled 
NetworkManager-dispatcher.service  enabled disabled
NetworkManager-wait-online.service enabled disabled
NetworkManager.service             enabled disabled
pritunl-client.service             enabled disabled
sshd.service                       enabled disabled
tlp.service                        enabled disabled
remote-fs.target                   enabled enabled 

[/simterm]

Bluetooth мені постійно не потрібен, рідко його включаю, теж саме з Притунлом.

tick_sched_timer та Polybar

Ще виявив цікаву річ – tick_sched_timer, шедулєр ядра, з’їдав аж 1.7W:

Погуглив, знайшов цей тред, прибив процес Polybar, який зверху виводить всяку інформацю по системі, використовуючи власні модулі – і tick_sched_timer почав споживати лише 150-300 mW.

Networking: коли немає світла – модем 4G ZTE + зовнішня антена
0 (0)

13 Листопада 2022

Що робити, коли немає світла, вежі мобильного зв’язку відключаються, а подивитися відосиків з нашими котиками хочеться? Правильно – купити собі 3/4G модем з антеною!

До того ж самій антені живлення не треба, а модем можна вставити в звичайний павербанк, якого вистачає надовго, бо модему багато не треба.

Купував комплект 4G Zte Mf79U + Квадрат Mimo – цікавий магазин (не реклама), і продають відразу комплектами, що дуже зручно для таких як я, які не шарять в тому, як його вибирати, особливо коли діло стосується самої антени.

Окрема подяка @Artem за ідею та поміч при налаштуванні)

Сам комплект виглядає так:

Networking: модем 4G ZTE + зовнішня антена - коли немає світла

Підключення модему

Вставляємо карту micro-SIM в порт карти, я взяв карточку Водафона – він тут наче краще всіх робить, коли вирубає вишки.

Другий – під карту памя’ті:

Пароль та SSID є на девайсі:

Вставляємо в комп/ноут:

Сигнали описані в інструкції, кратко:

  • зверху – WiFi, знизу – мобільний
  • мобільний блимає зеленим – підключено до 3G, трафік йде
  • мобільний блимає блакитним – підключено до 4G, трафік йде

Заходимо на http://192.168.0.1:

Переходимо до налаштувань WiFi:

За бажанням – міняємо SSID та пароль на свої:

Сигнал модему навіть кращий за домашній роутер, який стоїть поруч – setevoy-linksys:

Переходимо до антени.

Підключення антени

Готуємо кабелі.

В комплекті йде один довгий, розрізаємо на дві однакові частини.

На кінцівках надрізаємо пластик, обережно, бо під ним обмотка. Знімаємо верхній шар ізоляції:

Мідну обмотку під ним разом з алюмінюєвий екраном загортаємо донизу, надрізаємо внутрішню ізоляцю, та оголяємо внутрішній мідний стержень:

 

Накручуємо конектор (всередені різьба) – готово:

З витою парою гемору більше 🙂

Повторюмо для всіх чотирьох, и врешті-решт підключаємо всю систему:

Розміщення антени

Встановлюємо на телефон утілітку Network Cell Info Lite & Wifi – показує найближчі вежі, до яких конектиться телефон.

В мене вишка Водафону як раз навпроти вікон, тож і антену розміщуємо “обличчям” до вежі:

Сила сигналу та тест швидкості

Краще антену взагалі виносити за вікно, бо, сюрпрайз – навіть склопакет впливає на силу сигналу.

Отже, за допомогою Network Cell Info знаходимо напрямок вежі, виставляємо антену в її напрямку, і перевіряємо сигнал, прямо на стартовій сторінці адміністрування самого модему:

-91 decibel-milliwatts (децибел-мілівати) – не вражає, але враховуючи, що я живу за містом, і вишка від мене приблизно в трьох кілометрах – то не так вже й погано.

Швидкість до відключення живлення “на районі”:

І під час вимкнення свіла:

Швидкість не найкраща, але для роботи/месенджерів та навіть Ютубу вистачає.

При цьому мобільний інтернет на телефоні не працює взагалі – Speedtest навіть не стартує, видає помилку.

В самому Києві результати набагато краще – кажуть, що 2Мбс на загрузку видає стабильно.

Або навіть так – Оболонь, з таким же комплектом обладнання:

Столичні мажори 😀

Google: прибрати сайти з .RU із результатів пошуку
0 (0)

18 Жовтня 2022

Хочеться прибрати россійські сайти із результатів пошуку в Гуголі, тож нагуглив декілька варіантів.

Перші два – “ручні”, через додавання параметру ?lr=-lang_ru або ?cr=-countryRU в URL Гугла, тобто виглядатиме він як https://google.com.ua/?lr=-lang_ru:

 

Але ж це мануальщина…

Нажаль, в Хромі автоматизувати не вийшло – вирізає цю частину при виконанні запиту:

Хоча, можливо, не вмію готувати.

Проте, існує інше рішення – плагін uBlacklist.

Встановлюємо, задаємо регулярку на кшталт *://*.ru/*:

Перевіряємо:

Та перевірити що саме було скрито із результатів пошуку – uBlacklist has blocked 3 sites Show:

Плюс, uBlacklist додає можливість банити сайти вручну – дуже часто хотілося, але не знав як:

ФОП: податки для нубасів, ч3 – сплата податків ЄП та ЄСВ
0 (0)

14 Жовтня 2022

Сьогодні вперше сам платив податки – така приємна і цікава процедура) Ну і справді дуже проста, як розібратися що і кому ми платимо.

Ще треба буде розібратися з поданням декларацій, але на цей раз за мене зробить добра людина, а я вже буду подавати сам (майже) в січні, до того ж там буде подача годової декларації.

Взагалі-то є купа сервісів, які ще більше спрощують життя, наприклад taxer.ua (не реклама), до якого я ще дойду, або та ж Дія. Але спочатку – “Learn Accounting the Hard Way“.

Отже, повернемося до податків.

ФОП та 3 група оподаткування в Україні

Що ми маємо: ФОП, 3 група оподаткування, 5%. Досить лаконічно описана на сайті Дії – 3 група – Які податки ви будете сплачувати.

Тобто платимо два податки – Єдиний податок та Єдиний соціальний внесок.

Єдиний податок

Тут я сплачую 5%, бо я не є платником ПДВ.

Сплачувати ЄП можно як щомісяця, так і раз на квартал, головне не пропустити останній день сплати – для ЄП це 50 днів після завершення кварталу.

Для зарплат в валюті, сума податку рахується на день зарахування доллару на долларовий рахунок, але в гривні по курсу НБУ – на сьогодні він все ще фіксований та становить 36.65 грн за один американський доллар. Хоча в Моно все рахуеться автоматом, тож тут все просто.

Платимо ми ГУДКСУ – Головному Управлінню Державної казначейської служби України. Але тут ще скоріш за все ще важливо місце реєстрації… Треба уточнити, доречі, якось пропустив цей момент.

На данний час її рахунки такі – тут чисто для прикладу, бо вони змінюються, начебто раз на рік у січні:

  • Код ЄДРПОУ отримувача 37955989
  • Назва отримувача ГОЛОВНЕ УДКСУ У КИЇВСЬКІЙ ОБЛАСТІ
  • Бюджетний рахунок UA878999980314060699000010782

По коду ЄДРПОУ 37955989 можемо знайти отримувача, наприклад на ОпендатаботіГОЛОВНЕ УПРАВЛІННЯ ДЕРЖАВНОЇ КАЗНАЧЕЙСЬКОЇ СЛУЖБИ УКРАЇНИ У КИЇВСЬКІЙ ОБЛАСТІ.

Про ЄП наче все – глянемо на другий податок.

Єдиний соціальний внесок

ЄСВ всі ФОП-и платять однаково – це 22% від місячної мінімальної зарплати – вона взагалі на рівні держави впливає на купу показників, тому про неї так часто говорять.

Більш того, треба і самому відстежувати зміни тут, бо, наприклад, у вересні (сентябрь) мінімалка була 6500, отже податок маємо платити 1430 грн, а вже в жовтні (октябрь) стала 6700, тому і подадок вже буде 1474 грн/міс.

По датам оплати – це  до 20-ти днів після завершеня кварталу, і реквізити інші, бо тепер платимо Головному Управлінню Державної Податкової Служби:

  • Код ЄДРПОУ отримувача 44096797
  • Назва отримувача ГОЛОВНЕ УПРАВЛІННЯ ДПС У КИЇВСЬКІЙ ОБЛАСТІ
  • Бюджетний рахунок UA938999980000355699204021036

Розібралися? Поїхали до Монобанку.

Monobank – кабінет бухгалтера

Моно зробив прям чудо, і через просту таку собі веб-сторніку можна виконувати всі операціі по податкам. Плюс, можна зробити два додаткових доступи для бухгалтерії, якщо у вас є кому це робити за вас та немає натхнення вести все самому.

Відкриваємо Моно, свайпаємо вліво:

Читаємо про кабінет:

Та відкриваємо в браузері https://web.monobank.ua:

Щоб залогінитись – на телефоні відкриваємо Сканер QA-коду, та скануємо код із браузеру:

Підтвержуємо дозвіл на вхід:

І сама юайка – все дуже швидко, зручно і начебто зрозуміло:

Тепер погнали робити платежі на користь держави.

Сплата ЄСВ

Тут у нас 22% від мінімальної зарплати, тож якщо платити за вересень, то це буде 1430 гривень, а за вересень та жовтень – 1430+1474 == 2904 грн.

Відкриваємо Створити платіж – Платіж до бюджету:

Шукаємо по IBAN UA938999980000355699204021036 – система сама підгрузить ЄДРПОУ та назву – ГУ ДПС.

Далі, шукаємо в полі Код виду оплати 101 – це “Сплата податків і зборів/єдиного внеску“:

В Призначенні платежу автоматично сформується строка у вигляді *;<КОД ВИДУ ОПЛАТИ>;<ІНН ПЛАТНИКА>;<ТЕХНОЛОГІЧНИЙ КОД>, та коментар.

<ТЕХНОЛОГІЧНИЙ КОД> підтянеться автоматично з Назви установи – зверніть увагу на цифри 7104000 наприкінці.

Він не завжди використувється при створенні платежиів, наприклад в Укрсіб банку його не вказували.

Якщо дуже цікаво (як стало мені), то можно навіть нагулити що то за такий “технологічний код” ось тут:

37193204002651

71040000

Єдиний соціальний внесок, що сплачується фізичними особами – підприємствами, у т.ч. які обрали спрощену систему оподаткування та осіб, які проводять незалежну професійну діяльність (34,7 %).

Отже, вказуємо суму, підписуємо і відправляємо. Якщо платите за кілька місяців – то можно об’єднати в один платіж, голове щоб податкова отримала вірну (можна більше) кількість податків:

Зверніть увагу, что Технологічний код теж змінився – чудо автоматизації! 😀

Сплата Єдиного Податку

Тут у нас 5% від суми отриманного доходу в гривні.

Вікриваємо Валютний рахунок, і під сумою надходження в долларах бачимо суму в гривні:

Формула проста – (сума надходження в гривні * 5) / 100, тобто якщо отримали 100.000 гривень, то платимо:

[simterm]

$ echo "(100000*5)/100" | bc
5000

[/simterm]

5000 гривень податку.

Шукаємо так само – спочатку по IBAN UA878999980314060699000010782, потім по коду 101:

Перевірка бюджетних надходжень

Переказ має поступити і бути обробленим як звичайно – протягом трьох банківских днів, тож трохи почекаємо.

Електронний кабінет платника податків – варіант раз.

Логінимось з ЄЦП-ключем, переходимо в Стан розрахунків з бюджетом:

В мене тут якісь переплати з попередніх розрахунків.

Також отримання грошей податковою можна перевірити в Дії – Розрахунки х бюджетом:

Наразі це все. Чекаємо на надходженя грошей до бюджету.

Pritunl: запуск VPN в Kubernetes
0 (0)

5 Жовтня 2022

Pritunl – VPN-сервер з пачкою додаткових можливостей для безпеки та управління доступами.

По суті, Притунл є просто обгорткою над OpenVPN, додаючи до нього такі собі Access Control Lists у вигляді Організацій, юзерів та роутів.

Завдання – розгорнути тестовий інстанс Pritunl в Kubernetes, щоб помацати його зсередини.

Поки будемо використовувати безкоштовну версію, потім глянемо платну. Відмінності та вартість можна подивитися ось тут>>> .

Запускати будемо в Minikube, а для встановлення використовуємо Helm-чарт від Dysnix .

Запуск Pritunl в Kubernetes

Створюємо неймспейс:

[simterm]

$ kubectl create ns pritunl-local
namespace/pritunl-local created

[/simterm]

Додаємо репозиторій:

[simterm]

$ helm repo add dysnix https://dysnix.github.io/charts

[/simterm]

І встановлюємо чарт з Pritunl:

[simterm]

$ helm -n pritunl-local install pritunl dysnix/pritunl
...
Pritunl default access credentials:

export POD_ID=$(kubectl get pod --namespace pritunl-local -l app=pritunl,release=pritunl -o jsonpath='{.items[0].metadata.name}')
kubectl exec -t -i --namespace pritunl-local  $POD_ID pritunl default-password
...
export VPN_IP=$(kubectl get svc --namespace pritunl-local pritunl --template "{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}")
echo "VPN access IP address: ${VPN_IP}"

[/simterm]

Перевіряємо поди:

[simterm]

$ kubectl -n pritunl-local get pod
NAME                               READY   STATUS    RESTARTS   AGE
pritunl-54dd47dc4d-672xw           1/1     Running   0          31s
pritunl-mongodb-557b7cd849-d8zmj   1/1     Running   0          31s

[/simterm]

Отримуємо логін-пароль із майстер-поду:

[simterm]

$ kubectl exec -t -i --namespace pritunl-local pritunl-54dd47dc4d-672xw pritunl default-password
...
Administrator default password:
  username: "pritunl"
  password: "zZymAt1tH2If"

[/simterm]

Сервіси:

[simterm]

$ kubectl -n pritunl-local get svc
NAME              TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
pritunl           LoadBalancer   10.104.33.93    <pending>     1194:32350/TCP   116s
pritunl-mongodb   ClusterIP      10.97.144.132   <none>        27017/TCP        116s
pritunl-web       ClusterIP      10.98.31.71     <none>        443/TCP          116s

[/simterm]

Тут LoadBalancer pritunl – для доступу клієнтів до сервера ВПН, а сервіс pritunl-web ClusterIP – для доступу до веб-інтерфейсу.

Прокидаємо порт до Інтернету:

[simterm]

$ kubectl -n pritunl-local port-forward svc/pritunl-web 8443:443
Forwarding from 127.0.0.1:8443 -> 443
Forwarding from [::1]:8443 -> 443

[/simterm]

Відкриваємо https://localhost:8443:

Логінимося, і потрапляємо в основні налаштування:

Тут у Public Address автоматом буде заданий публічний адресу хоста, на якому запущений сам Прітунл, і потім він буде підставлятися в клієнтські конфіги як адреса хоста VPN.

Так як Pritunl у нас працює в Kubernetes, який працює у VirtualBox, який працює на Linux на звичайному домашньому PC – то нам цей варіант не підходить, але до нього повернемось пізніше. Поки що можна залишити, як є.

Інші налаштування нам поки що не цікаві.

Налаштування Pritunl VPN

Organization, Users

Див. Initial Setup.

Для об’єднання користувачів є Групи – але вони доступні у платній версії, її побачимо згодом.

Також, користувачів можна згрупувати через Organizations.

Переходимо до Users, додаємо Organization:

Додаємо юзера:

PIN, email – опціональні, зараз не потрібні.

Pritunl Server та роути

Див. Server configuration.

Переходимо до Servers, додаємо новий:

Тут:

  • DNS Server : до якого ДНС будемо відправляти клієнтів
  • Port, Protocol : порт і протокол для OpenVPN, який буде запущений “всередині” Притунла і прийматиме підключення від наших користувачів
  • Virtual Network : мережа, з пулу адрес якої виділятимемо приватні IP для клієнтів

Virtual Network я б виділив 172.16.0.0 – тоді у нас домашня мережа, мережа Кубера та клієнтські IP будуть відрізнятися – зручніше буде дебажит, див. IPv4 Private Address Space and Filtering .

При цьому важливо, щоб порт Сервера тут збігався з портом і протоколом на LoadBalancer – 1194 TCP .

Тобто. запит з робочої машини піде за маршрутом:

  • 192.168.3.0/24 – домашня мережа
  • потрапить до мережі VirtualBox 192.168.59.1/24 (див. Proxy )
  • піде на LoadBalancer у мережі Кубера 10.96.0.0/12
  • а LoadBalancer відроутить запит у Kubernetes Pod, в якому у нас OpenVPN слухає TCP порт 1194

Перевіряємо сам LoadBalancer:

[simterm]

$ kubectl -n pritunl-local get svc pritunl
NAME      TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
pritunl   LoadBalancer   10.104.33.93   <pending>     1194:32350/TCP   22m

[/simterm]

Port 1194 – TCP. Зі статусом Pending розберемося трохи пізніше.

Вказуємо Virtual Network, порт та протокол для Server:

Далі, підключаємо Організацію з усіма її користувачами:

Стартуємо сервер:

Перевіряємо процес та порт у Kubernetes Pod – бачимо наш OpenVNP Сервер на порту 1194:

[simterm]

$ kubectl -n pritunl-local exec -ti pritunl-54dd47dc4d-672xw -- netstat -anp | grep 1194
Defaulted container "pritunl" out of: pritunl, alpine (init)
tcp6       0      0 :::1194                 :::*                    LISTEN      1691/openvpn

[/simterm]

І йдемо фіксити LoabBalancer.

minikube tunnel

Див. Kubernetes: Minikube, та LoadBalancer в статусі “Pending” для повної інформації, зараз просто викликаємо minikube tunnel:

[simterm]

$ minikube tunnel
[sudo] password for setevoy: 
Status:
        machine: minikube
        pid: 1467286
        route: 10.96.0.0/12 -> 192.168.59.108
        minikube: Running
        services: [pritunl]
    errors: 
                minikube: no errors
                router: no errors
                loadbalancer emulator: no errors
...

[/simterm]

Перевіряємо Loadbalancer:

[simterm]

$ kubectl -n pritunl-local get svc pritunl
NAME      TYPE           CLUSTER-IP     EXTERNAL-IP    PORT(S)          AGE
pritunl   LoadBalancer   10.104.33.93   10.104.33.93   1194:32350/TCP   139m

[/simterm]

З’явився EXTERNAL-IP– перевіряємо підключення:

[simterm]

$ telnet 10.104.33.93 1194
Trying 10.104.33.93...
Connected to 10.104.33.93.
Escape character is '^]'.

[/simterm]

Повертаємося до основних Settings, вказуємо Public Address == LoadBalancer IP:

OpenVPN – підключення до серверу

Переходимо в Users, клікаємо Download profile:

Розпаковуємо архів:

[simterm]

$ tar xfp local-user.tar

[/simterm]

І підключаємося за допомогою звичайного OpenVPN клієнта:

[simterm]

$ sudo openvpn --config local-org_local-user_local-server.ovpn 
[sudo] password for setevoy: 
...
2022-10-04 15:58:32 Attempting to establish TCP connection with [AF_INET]10.104.33.93:1194 [nonblock]
2022-10-04 15:58:32 TCP connection established with [AF_INET]10.104.33.93:1194
...
2022-10-04 15:58:33 net_addr_v4_add: 172.16.0.2/24 dev tun0
2022-10-04 15:58:33 WARNING: this configuration may cache passwords in memory -- use the auth-nocache option to prevent this
2022-10-04 15:58:33 Initialization Sequence Completed

[/simterm]

Проте зараз мережа не працюватиме:

[simterm]

$ traceroute 1.1.1.1
traceroute to 1.1.1.1 (1.1.1.1), 30 hops max, 60 byte packets
 1  * * *
 2  * * *
 3  * * *
...

[/simterm]

Так як у нас у ВПН роут в 0.0.0.0/0 спрямований через той самий хост, на якому власне ВПН і працює – виходить “кільце”.

Переходимо в Servers, зупиняємо сервер і видаляємо Default route:

Клікаємо Add Route – додамо маршрут до 1.1.1.1 через наш ВПН, а решта запитів з клієнта будуть йти звичайними маршрутами:

 

Запускаємо підключення заново:

[simterm]

$ sudo openvpn --config local-org_local-user_local-server.ovpn

[/simterm]

Перевіряємо роути на хост-машині, локально:

[simterm]

$ route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.3.1     0.0.0.0         UG    100    0        0 enp38s0
1.1.1.1         172.16.0.1      255.255.255.255 UGH   0      0        0 tun0
...

[/simterm]

І перевіряємо мережу – запит пійшов через VPN:

[simterm]

$ traceroute 1.1.1.1
traceroute to 1.1.1.1 (1.1.1.1), 30 hops max, 60 byte packets
 1  172.16.0.1 (172.16.0.1)  0.211 ms  41.141 ms  41.146 ms
 2  * * *
...

[/simterm]

“It works!” (с)

Готово.

Loading

Kubernetes: Minikube, та LoadBalancer в статусі “Pending”
0 (0)

4 Жовтня 2022

Після запуску Pritunl в Minikube неможливо підключитися до ВПН:


2022-10-03 13:50:32 TCP/UDP: Preserving recently used remote address: [AF_INET]194.168.3.100:1194
2022-10-03 13:50:32 UDP link local: (not bound)
2022-10-03 13:50:32 UDP link remote: [AF_INET]194.168.3.100:1194

Перевіряємо його Kubernetes Service:

[simterm]

$ kubectl -n pritunl-local get svc
NAME              TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
pritunl           LoadBalancer   10.102.129.25   <pending>     1194:30166/TCP   47m
...

[/simterm]

Тип – LoadBalancer, але його EXTERNAL-IP – в статусі Pending, так як у Minikube немає сервісу з типом LoadBalancer, бо вони мають створюватися на рівні інфрастуктури – AWS, GCE, Azure, і потім вже від них Kubernetes отримує IP або URL, на який роутить запити до цього лоад-балансеру.

Рішення LoadBalancer <pending>

Для Мінікуба є декілька рішень:

  • затосувати minikube tunnel – зробить тунель між хостом та Сервісом в Кубернетесі
  • або minikube service – отримуємо прямий URL для підключення
  • або вказати externalIPs для Kubenetes LoadBalancer Service  – налаштувати його вручну

Спробуємо всі.

Minikube tunnel

Перевіряємо роути на хост-машині:

[simterm]

$ route -n 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.3.1     0.0.0.0         UG    100    0        0 enp38s0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-9c291321e71a
192.168.3.0     0.0.0.0         255.255.255.0   U     100    0        0 enp38s0
192.168.59.0    0.0.0.0         255.255.255.0   U     0      0        0 vboxnet0

[/simterm]

Бачимо тут маршрут до нашого VirtualBox – 192.168.59.0 0.0.0.0 255.255.255.0 U 0 0 0 vboxnet0.

Запускаємо tunnel:

[simterm]

$ minikube tunnel
[sudo] password for setevoy: 
Status:
        machine: minikube
        pid: 333552
        route: 10.96.0.0/12 -> 192.168.59.107
        minikube: Running
        services: [pritunl]
    errors: 
                minikube: no errors
                router: no errors
                loadbalancer emulator: no errors
...

[/simterm]

Перевіряємо роути зараз – з’явився новий маршрут в мережу 10.96.0.0 (Kubernetes CIDR)  через 192.168.59.107 – це віртуалка з VirtualBox, на якій запущено сам Minikube:

[simterm]

$ route -n 
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.3.1     0.0.0.0         UG    100    0        0 enp38s0
10.96.0.0       192.168.59.107  255.240.0.0     UG    0      0        0 vboxnet0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
172.18.0.0      0.0.0.0         255.255.0.0     U     0      0        0 br-9c291321e71a
192.168.3.0     0.0.0.0         255.255.255.0   U     100    0        0 enp38s0
192.168.59.0    0.0.0.0         255.255.255.0   U     0      0        0 vboxnet0

[/simterm]

Перевіряємо Kubernetes LoadBalancer тепер:

[simterm]

$ kubectl -n pritunl-local get svc pritunl
NAME      TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
pritunl   LoadBalancer   10.102.129.25   10.102.129.25   1194:30166/TCP   54m

[/simterm]

“It works!” (c)

Minikube service

Запускаємо minikube service, вказуємо неймспейс та им’я Сервісу – Мінікуб поверне нам URL для подключення:

[simterm]

$ minikube service -n pritunl-local pritunl
|---------------|---------|--------------|-----------------------------|
|   NAMESPACE   |  NAME   | TARGET PORT  |             URL             |
|---------------|---------|--------------|-----------------------------|
| pritunl-local | pritunl | openvpn/1194 | http://192.168.59.108:32350 |
|---------------|---------|--------------|-----------------------------|
🎉  Opening service pritunl-local/pritunl in default browser...

[/simterm]

Тут 192.168.59.108 – адрес нашого серверу VirtualBox, а 32350 – NodePort на ньому, на якому працює Pritunl Server.

Також, можно вивести всі Kubernetes Service за допомогою list:

[simterm]

$ minikube service -n pritunl-local list
|---------------|-----------------|--------------|-----------------------------|
|   NAMESPACE   |      NAME       | TARGET PORT  |             URL             |
|---------------|-----------------|--------------|-----------------------------|
| pritunl-local | pritunl         | openvpn/1194 | http://192.168.59.108:32350 |
| pritunl-local | pritunl-mongodb | No node port |
| pritunl-local | pritunl-web     | No node port |
|---------------|-----------------|--------------|-----------------------------|

[/simterm]

Або отримати URL однією строкою замість таблиці:

[simterm]

$ kubectl -n priminikube service -n pritunl-local pritunl --url
http://192.168.59.108:32350

[/simterm]

Пробуємо підключитися:

[simterm]

$ telnet 192.168.59.108 32350
Trying 192.168.59.108...
Connected to 192.168.59.108.
Escape character is '^]'.

[/simterm]

Логи Pritunl:

“It works!” (c)

LoadBalancer externalIPs

Отримаємо IP машинки VirtualBox:

[simterm]

$ minikube ip
192.168.59.108

[/simterm]

Редагуємо LoadBalancer:

[simterm]

$ kubectl -n pritunl-local edit svc pritunl

[/simterm]

Вказуємо externalIPs:

...
  externalIPs:
  - 192.168.59.108
...

Збергіаємо, перевіряємо сам Service:

[simterm]

$ kubectl -n pritunl-local get svc pritunl
NAME      TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)          AGE
pritunl   LoadBalancer   10.104.33.93   192.168.59.108   1194:32350/TCP   81m

[/simterm]

Та підключення до нього:

[simterm]

$ telnet 192.168.59.108 1194
Trying 192.168.59.108...
Connected to 192.168.59.108.
Escape character is '^]'.

[/simterm]

“It works!” (c)

Готово.

Loading

ФОП: податки для нубасів, ч2 – “ІТ- Експорт – документи до надходження”
0 (0)

4 Жовтня 2022

Ще одна історія, яка добре демонструє те, як взагалі відбувається взаємодія між ІТ-фахівцем та замовниками.

Отже, мені на ФОП-рахунок в Укрсіб банку прийшли гроші – перша зарплата на новому проекті, після чого я отримав такого собі “листа щастя”:

Що трапилося?

  • на ФОП-рахунок прийшли гроші
  • банк гадки не має – хто та чому мені їх відправив, але він має звітувати перед Податковою службою в разі, якщо у тої до мене виникнуть питання (“Звідки гроші, Галя?!“)

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

Для цього банк потребує відправити їм лист-роз’яснення – на підставі чого ці гроші прийшли.

Для того, щоб врешті-решт таки отримати свої гроші – потрібно два документи:

  • договір з проектом – він буде підставою для оформленя Інвойсу
  • інвойс за серпень – він буде підставою для зарахування вам грошей

Договір про надання послуг / Service Agreement

Мій договір з проектом виглядає якось так:

Найменування ВЕД

В Договорі варто звернути увагу на пункт 1.2:

1.2. Виконавець є суб’єктом підприємницької
діяльності-фізичною особою з видом діяльності:
консультування з питань інформатизації.

Бо саме він має відповідати вашому Виду економічної діяльності (Найменування ВЕД), який вказано для вашого ФОП.

Перевірити його можно в Кабінеті платника податків – https://cabinet.tax.gov.ua:

Та перевіряємо ВЕД:

Реквізити сторін

Крім того, в Договорі мають бути вказани ваші реквізити, по яких (за якими?) компанія буде нараховувати вам гроші, та має право це робити виключно згідно цього пункту:

І – важливо – назва компаніі, з рахунку якої прийшли гроші – вочевидь, вона має співпадати з назвою компаніі в Договорі.

Рахунок – оферта / Invoice

Другим – потрібно знайти інвойс, за яким вам нарахували гроші – його вам має вислати компанія-замовник. Мій виглядає ось так:

Знов-таки – увага на Опис – саме там вказана послуга, за яку ви отримали гроші – і вона знов-таки має співпадати з вашим ВЕД.

Відповідь банку та отримання грошей

І тепер, коли знайшли всі документи – клікаємо на Відповісти на запит:

Прикріпляємо два документи – Договір та Інвойс:

У полі “Додаткова інформація” – вказуємо:

“У відповідь на “ІТ- Експорт – документи до надходження NNNN.73 USD 31.08.2022″ повідомляємо, що кошти надійшли як оплата згідно договору №NNNN від 22.08.2022. Документи надаємо разом з відповіддю.”

Тобто роз’яснюємо банку – на підставі чого ви отримали гроші.

Monobank та зміна реквізитів

В Монобанку все це наче якось простіше відбувається, принаймні після першої зарплати на рахунок Моно мені ніхто не писав, все обробилося автоматично:

І зверніть увагу на SWIFT Code – MT103 – виявляється, там ціла система, див. MT103.

Доречі, коли я змінював рахунок ФОП з Укрсібу на Моно, то до основного Договіру з Проектом треба було підписати додаток, в якому зазначалися нові реквізити – саме на підставі його Проект може далі робити переводи.

Слава Податковій службі України!))

Loading

Apache Druid: PostgreSQL в ролі metadata storage, та заміна ZooKeeper на Kubernetes Extensions
0 (0)

23 Вересня 2022

Продовжимо серію постів про Apache Druid. В першій частині розібралися з самім Друідом – його архітектурою та моніторингом, в другій частині – розгорнули кластер PostgreSQL та налаштували його моніторинг.

Наступні задачі:

Почнемо з PostgreSQL.

Налаштування Apache Druid з PostgreSQL

Див. PostgreSQL Metadata Store та Metadata Storage.

PostgreSQL users

Повертаємося до файлу manifests/minimal-master-replica-svcmonitor.yaml, з якого створювали PostgreSQL кластер – додаємо юзера druid та базу druid:

...
  users:
    zalando:  # database owner
    - superuser
    - createdb
    foo_user: []  # role for application foo
    druid:       
    - createdb
  databases:
    foo: zalando  # dbname: owner
    druid: druid
...

Оновлюємо кластер:

[simterm]

$ kubectl apply -f maniapplyminimal-master-replica-svcmonitor.yaml

[/simterm]

Отримуємо пароль юзера druid:

[simterm]

$ kubectl -n test-pg get secret druid.acid-minimal-cluster.credentials.postgresql.acid.zalan.do -o 'jsonpath={.data.password}' | base64 -d
Zfqeb0oJnW3fcBCZvEz1zyAn3TMijIvdv5D8WYOz0Y168ym6fXahta05zJjnd3tY

[/simterm]

Відкриваємо порт до PostgreSQL-мастера:

[simterm]

$ kubectl -n test-pg port-forward acid-minimal-cluster-0 6432:5432 
Forwarding from 127.0.0.1:6432 -> 5432
Forwarding from [::1]:6432 -> 5432

[/simterm]

Підключаємося:

[simterm]

$ psql -U druid -h localhost -p 6432
Password for user druid: 
psql (14.5, server 13.7 (Ubuntu 13.7-1.pgdg18.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

druid=>

[/simterm]

Перевіряємо зміст бази – поки що пусто:

[simterm]

druid-> \dt
Did not find any relations.

[/simterm]

Apache Druid metadata.storage config

Використовуємо той же файл druid-operator/examples/tiny-cluster.yaml, з якого розгортали кластер Apache Druid (див. Запуск Druid Cluster).

Зараз маємо в ньому конфіг для DerbyDB, яка зберігає дані на локальному диску:

...
    druid.metadata.storage.type=derby
    druid.metadata.storage.connector.connectURI=jdbc:derby://localhost:1527/druid/data/derbydb/metadata.db;create=true
    druid.metadata.storage.connector.host=localhost
    druid.metadata.storage.connector.port=1527
    druid.metadata.storage.connector.createTables=true
...

Для PostgreSQL нам теж треба вказати connectURI, отже знаходимо його Kubernetes Service:

[simterm]

$ kubectl -n test-pg get svc
NAME                                       TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
acid-minimal-cluster                       ClusterIP   10.97.188.225   <none>        5432/TCP   14h

[/simterm]

Та редагуємо маніфест – видаляємо або коментимо строки з Derbi, та додаємо новий конфіг:

...
    # Extensions
    #
    druid.extensions.loadList=["druid-kafka-indexing-service", "postgresql-metadata-storage", "druid-kubernetes-extensions"]
...
    # Metadata Store
    #druid.metadata.storage.type=derby
    #druid.metadata.storage.connector.connectURI=jdbc:derby://localhost:1527/druid/data/derbydb/metadata.db;create=true
    #druid.metadata.storage.connector.host=localhost
    #druid.metadata.storage.connector.port=1527
    #druid.metadata.storage.connector.createTables=true

    druid.metadata.storage.type=postgresql
    druid.metadata.storage.connector.connectURI=jdbc:postgresql://acid-minimal-cluster.test-pg.svc.cluster.local/druid
    druid.metadata.storage.connector.user=druid
    druid.metadata.storage.connector.password=Zfqeb0oJnW3fcBCZvEz1zyAn3TMijIvdv5D8WYOz0Y168ym6fXahta05zJjnd3tY
    druid.metadata.storage.connector.createTables=true
...

Оновлюємо кластер Druid:

[simterm]

$ kubectl -n druid apply -f examples/tiny-cluster.yaml

[/simterm]

Перевіримо дані в базі Постгре:

[simterm]

druid-> \dt
               List of relations
 Schema |         Name          | Type  | Owner 
--------+-----------------------+-------+-------
 public | druid_audit           | table | druid
 public | druid_config          | table | druid
 public | druid_datasource      | table | druid
 public | druid_pendingsegments | table | druid
 public | druid_rules           | table | druid
 public | druid_segments        | table | druid
 public | druid_supervisors     | table | druid

[/simterm]

Найс!

Якщо треба мігрувати дані з Derby на Postgre – див. Metadata Migration.

Далі – позбавимося необхідності в ZooKeeper.

Налаштування Druid Kubernetes Service Discovery

Документація по модулю – тут>>>.

Повертаємося до druid-operator/examples/tiny-cluster.yaml, та оновлюємо конфіг – відключаємо ZooKeeper, додаємо новий екстешен druid-kubernetes-extensions і додаткові параметри:

...
    druid.extensions.loadList=["druid-kafka-indexing-service", "postgresql-metadata-storage", "druid-kubernetes-extensions"]
    ...
    druid.zk.service.enabled=false
    druid.serverview.type=http
    druid.coordinator.loadqueuepeon.type=http
    druid.indexer.runner.type=httpRemote
    druid.discovery.type=k8s

    # Zookeeper
    #druid.zk.service.host=tiny-cluster-zk-0.tiny-cluster-zk
    #druid.zk.paths.base=/druid
    #druid.zk.service.compress=false
...

Оновлюємо:

[simterm]

$ kubectl -n druid apply -f examples/tiny-cluster.yam

[/simterm]

Druid RBAC Role

Додаємо RBAC Role та RoleBinding, інакше будемо мати помилки авторізації по типу такої:

ERROR [org.apache.druid.k8s.discovery.K8sDruidNodeDiscoveryProvider$NodeRoleWatcherbroker] org.apache.druid.k8s.discovery.K8sDruidNodeDiscoveryProvider$NodeRoleWatcher – Error while watching node type [BROKER]
org.apache.druid.java.util.common.RE: Expection in watching pods, code[403] and error[{“kind”:”Status”,”apiVersion”:”v1″,”metadata”:{},”status”:”Failure”,”message”:”pods is forbidden: User \”system:serviceaccount:druid:default\” cannot watch resource
\”pods\” in API group \”\” in the namespace \”druid\””,”reason”:”Forbidden”,”details”:{“kind”:”pods”},”code”:403}

Создаємо маніфест із документації:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: druid-cluster
rules:
- apiGroups:
  - ""
  resources:
  - pods
  - configmaps
  verbs:
  - '*'
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: druid-cluster
subjects:
- kind: ServiceAccount
  name: default
roleRef:
  kind: Role
  name: druid-cluster
  apiGroup: rbac.authorization.k8s.io

Створюємо нові ресурси в неймспейсі Друіда:

[simterm]

$ kubectl -n druid apply -f druid-serviceaccout.yaml 
role.rbac.authorization.k8s.io/druid-cluster created
rolebinding.rbac.authorization.k8s.io/druid-cluster created

[/simterm]

І за хвилину перевіряємо логи:

[simterm]

...
2022-09-21T17:01:15,916 INFO [main] org.apache.druid.k8s.discovery.K8sDruidNodeDiscoveryProvider$NodeRoleWatcher - Starting NodeRoleWatcher for [HISTORICAL]...
2022-09-21T17:01:15,916 INFO [main] org.apache.druid.k8s.discovery.K8sDruidNodeDiscoveryProvider$NodeRoleWatcher - Started NodeRoleWatcher for [HISTORICAL].
2022-09-21T17:01:15,916 INFO [main] org.apache.druid.k8s.discovery.K8sDruidNodeDiscoveryProvider - Created NodeRoleWatcher for nodeRole [HISTORICAL].
2022-09-21T17:01:15,917 INFO [main] org.apache.druid.k8s.discovery.K8sDruidNodeDiscoveryProvider - Creating NodeRoleWatcher for nodeRole [PEON].
2022-09-21T17:01:15,917 INFO [main] org.apache.druid.k8s.discovery.K8sDruidNodeDiscoveryProvider$NodeRoleWatcher - Starting NodeRoleWatcher for [PEON]...
2022-09-21T17:01:15,917 INFO [main] org.apache.druid.k8s.discovery.K8sDruidNodeDiscoveryProvider$NodeRoleWatcher - Started NodeRoleWatcher for [PEON].
2022-09-21T17:01:15,917 INFO [main] org.apache.druid.k8s.discovery.K8sDruidNodeDiscoveryProvider - Created NodeRoleWatcher for nodeRole [PEON].
2022-09-21T17:01:15,917 INFO [main] org.apache.druid.k8s.discovery.K8sDruidNodeDiscoveryProvider - Creating NodeRoleWatcher for nodeRole [INDEXER].
2022-09-21T17:01:15,917 INFO [main] org.apache.druid.k8s.discovery.K8sDruidNodeDiscoveryProvider$NodeRoleWatcher - Starting NodeRoleWatcher for [INDEXER]...
2022-09-21T17:01:15,917 INFO [main] org.apache.druid.k8s.discovery.K8sDruidNodeDiscoveryProvider$NodeRoleWatcher - Started NodeRoleWatcher for [INDEXER].
2022-09-21T17:01:15,917 INFO [main] org.apache.druid.k8s.discovery.K8sDruidNodeDiscoveryProvider - Created NodeRoleWatcher for nodeRole [INDEXER].
2022-09-21T17:01:15,917 INFO [main] org.apache.druid.k8s.discovery.K8sDruidNodeDiscoveryProvider - Creating NodeRoleWatcher for nodeRole [BROKER].
2022-09-21T17:01:15,917 INFO [main] org.apache.druid.k8s.discovery.K8sDruidNodeDiscoveryProvider$NodeRoleWatcher - Starting NodeRoleWatcher for [BROKER]...
2022-09-21T17:01:15,918 INFO [main] org.apache.druid.k8s.discovery.K8sDruidNodeDiscoveryProvider$NodeRoleWatcher - Started NodeRoleWatcher for [BROKER].
2022-09-21T17:01:15,918 INFO [main] org.apache.druid.k8s.discovery.K8sDruidNodeDiscoveryProvider - Created NodeRoleWatcher for nodeRole [BROKER].
...

[/simterm]

Готово.

Loading

PostgreSQL: запуск в Kubernetes з PostgreSQL Operator та моніторинг з Prometheus
0 (0)

21 Вересня 2022

Отже, Друід ми запустили – див. Apache Druid: огляд, запуск в Kubernetes та моніторинг з Prometheus. Поки що в дефолтному вигляді, тобто в ролі сторейджа для метаданих використовується локальна база Apache Derby.

Далі будемо переключати Друід на PostgreSQL, ще згодом – прибирати звідти ZooKeeper.

Ну а для початку – запустимо кластер PostgreSQL в Kubernetes, додамо PostgreSQL Exporter для Promethues, та налаштємо збір метрік.

Запускати знову будемо в Minikube, для PostgreSQL використаємо Zalando Operator, а Експортер будемо запускати у вигляді sidecar container.

Глибоко копати в Оператор поки що не будемо, хоча він дуже цікавий, тож якось з ним побавимося. Наразі, нам треба лише його моніторинг.

Документація – Administrator Guide.

Запуск PostgreSQL оператора

Створюємо неймспейс:

[simterm]

$ kubectl create ns postgres-operator
namespace/postgres-operator created

[/simterm]

Додаємо Хельм-репозіторій:

[simterm]

$ helm repo add postgres-operator-charts https://opensource.zalando.com/postgres-operator/charts/postgres-operator

[/simterm]

Встановлюємо сам оператор:

[simterm]

$ helm -n postgres-operator install postgres-operator postgres-operator-charts/postgres-operator

[/simterm]

За бажанням додаємо WebUI для оператора:

[simterm]

$ helm repo add postgres-operator-ui-charts https://opensource.zalando.com/postgres-operator/charts/postgres-operator-ui
$ helm -n postgres-operator install postgres-operator-ui postgres-operator-ui-charts/postgres-operator-ui

[/simterm]

Перевіряємо поди:

[simterm]

$ kubectl -n postgres-operator get pods
NAME                                    READY   STATUS    RESTARTS   AGE
postgres-operator-649799f4bd-dz5bl      1/1     Running   0          82s
postgres-operator-ui-5cfff55c65-v4bjj   1/1     Running   0          22s

[/simterm]

Вікриваємо собі доступ до Сервісу веб-морди Оператора:

[simterm]

$ kubectl port-forward svc/postgres-operator-ui 8081:80
Forwarding from 127.0.0.1:8081 -> 8081
Forwarding from [::1]:8081 -> 8081

[/simterm]

Перевіряємо:

Тут ми нічого робити не будемо – візьмемо готові приклади конфігу кластера.

Запуск PostgreSQL кластеру

Клонуємо репозіторій:

[simterm]

$ https://github.com/zalando/postgres-operator.git
$ cd postgres-operator/

[/simterm]

В каталозі manifests є декілька прикладів, візьмемо собі manifests/minimal-master-replica-svcmonitor.yaml – він описує неймспейс, кластер-юзерів-бази, два Service та два ServiceMonitors + Sidecars с Prometheus Exporter.

Застосовуємо його:

[simterm]

$ kubectl apply -f manifests/minimal-master-replica-svcmonitor.yaml
namespace/test-pg created
postgresql.acid.zalan.do/acid-minimal-cluster created
service/acid-minimal-cluster-svc-metrics-master created
service/acid-minimal-cluster-svc-metrics-replica created
servicemonitor.monitoring.coreos.com/acid-minimal-cluster-svcm-master created
servicemonitor.monitoring.coreos.com/acid-minimal-cluster-svcm-replica created

[/simterm]

Перевіряєм кластер:

[simterm]

$ kk -n test-pg get postgresql
NAME                   TEAM   VERSION   PODS   VOLUME   CPU-REQUEST   MEMORY-REQUEST   AGE     STATUS
acid-minimal-cluster   acid   13        2      1Gi                                     2m21s   Running

[/simterm]

Та його поди:

[simterm]

$ kk -n test-pg get po
NAME                     READY   STATUS    RESTARTS   AGE
acid-minimal-cluster-0   2/2     Running   0          37s
acid-minimal-cluster-1   1/2     Running   0          24s

[/simterm]

У кожного є своя роль, яка задається в лейблах – spilo-role=master або spilo-role=replica.

PostgreSQL users

Див. доки тут>>> та тут>>>.

Юзери описуються в блоці – сюрпрайз – users:

[simterm]

$ kubectl -n test-pg get postgresql -o yaml
...
    users:
      foo_user: []
      zalando:
      - superuser
      - createdb
...

[/simterm]

І для кожного з них створюється окремий Kubernetes Secret:

[simterm]

$ kk -n test-pg get secret
NAME                                                                 TYPE     DATA   AGE
foo-user.acid-minimal-cluster.credentials.postgresql.acid.zalan.do   Opaque   2      38m
postgres.acid-minimal-cluster.credentials.postgresql.acid.zalan.do   Opaque   2      38m
standby.acid-minimal-cluster.credentials.postgresql.acid.zalan.do    Opaque   2      38m
zalando.acid-minimal-cluster.credentials.postgresql.acid.zalan.do    Opaque   2      38m

[/simterm]

Які потім мапляться в поди через змінні:

[simterm]

$ kubectl -n test-pg get statefulsets acid-minimal-cluster -o yaml
...
      - env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        - name: POSTGRES_USER
          value: postgres
        - name: POSTGRES_PASSWORD
          valueFrom:
            secretKeyRef:
              key: password
              name: postgres.acid-minimal-cluster.credentials.postgresql.acid.zalan.do
...

[/simterm]

Ну і перевіримо.

Отримаємо пароль:

[simterm]

$ kubectl -n test-pg get secret postgres.acid-minimal-cluster.credentials.postgresql.acid.zalan.do -o 'jsonpath={.data.password}' | base64 -d
CcWdAaqvPA8acxwIpVyM8UHkds2QG3opC3KD7rO1TxITQ1q31cwYLTswzfBeTVsN

[/simterm]

Відкриваємо порт:

[simterm]

$ kubectl -n test-pg port-forward acid-minimal-cluster-0 6432:5432

[/simterm]

Логінимося, та перевіряємо бази:

[simterm]

$ psql -U postgres -h localhost -p 6432
Password for user postgres: 
psql (14.5, server 13.7 (Ubuntu 13.7-1.pgdg18.04+1))
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

postgres=# \l
                                  List of databases
   Name    |   Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-----------+-----------+----------+-------------+-------------+-----------------------
 bar       | bar_owner | UTF8     | en_US.utf-8 | en_US.utf-8 | 
 foo       | zalando   | UTF8     | en_US.utf-8 | en_US.utf-8 | 
 postgres  | postgres  | UTF8     | en_US.utf-8 | en_US.utf-8 | 
 template0 | postgres  | UTF8     | en_US.utf-8 | en_US.utf-8 | =c/postgres          +
           |           |          |             |             | postgres=CTc/postgres
 template1 | postgres  | UTF8     | en_US.utf-8 | en_US.utf-8 | =c/postgres          +
           |           |          |             |             | postgres=CTc/postgres
(5 rows)

postgres=#

[/simterm]

PostgreSQL Prometheus Exporter

Див. Sidecar definitions.

Сайдкар ми вже маємо – доданий із маніфесту, і в кожному поді наразі маємо два контейнери – самого PostgreSQL, та його Експортера:

[simterm]

$ kk -n test-pg get po acid-minimal-cluster-0 -o jsonpath='{.spec.containers[*].name}'
postgres exporter

[/simterm]

Глянемо чи є там метріки – відкриваємо порт:

[simterm]

$ kubectl -n test-pg port-forward svc/acid-minimal-cluster-svc-metrics-master 9187:9187
Forwarding from 127.0.0.1:9187 -> 9187
Forwarding from [::1]:9187 -> 9187

[/simterm]

І бачимо, що нічого не бачимо, а кластер взагалі “мертвий” – pg_up == 0:

[simterm]

$ curl -s localhost:9187/metrics | grep pg_ | grep -v '#'
pg_exporter_last_scrape_duration_seconds 1.00031302
pg_exporter_last_scrape_error 1
pg_exporter_scrapes_total 9
pg_up 0

[/simterm]

Чому – тому що експортер має мати дані доступу, тобто логін-пароль.

В конфізі сайдкару додаємо нові змінні, див. Environment Variables:

...
      env:
      - name: "DATA_SOURCE_URI"
        value: "$(POD_NAME)/postgres?sslmode=require"
      - name: "DATA_SOURCE_USER"
        value: "$(POSTGRES_USER)"
      - name: "DATA_SOURCE_PASS"
        value: "$(POSTGRES_PASSWORD)"
      - name: "PG_EXPORTER_AUTO_DISCOVER_DATABASES"
        value: "true"
...

Тобто, Оператор створює StatefulSet, в якому задає змінні POSTGRES_USER та POSTGRES_PASSWORD, які ми використовуємо для сайдкару, щоб задати його власні змінні.

Зберігаємо, оновлюємо:

[simterm]

$ kubectl apply -f manifests/minimal-master-replica-svcmonitor.yaml

[/simterm]

Перевіряємо змінні в самому поді:

[simterm]

$ kubectl -n test-pg get po acid-minimal-cluster-0 -o yaml
...
  - env:
    - name: POD_NAME
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.name
    - name: POD_NAMESPACE
      valueFrom:
        fieldRef:
          apiVersion: v1
          fieldPath: metadata.namespace
    - name: POSTGRES_USER
      value: postgres
    - name: POSTGRES_PASSWORD
      valueFrom:
        secretKeyRef:
          key: password
          name: postgres.acid-minimal-cluster.credentials.postgresql.acid.zalan.do
    - name: DATA_SOURCE_URI
      value: $(POD_NAME)/postgres?sslmode=require
    - name: DATA_SOURCE_USER
      value: $(POSTGRES_USER)
    - name: DATA_SOURCE_PASS
      value: $(POSTGRES_PASSWORD)
    - name: PG_EXPORTER_AUTO_DISCOVER_DATABASES
      value: "true"
...

[/simterm]

Та знову перевіряємо мектріки в експортері:

[simterm]

$ curl -s localhost:9187/metrics | grep pg_ | grep -v '#' | tail -5
pg_stat_replication_pg_current_wal_lsn_bytes{application_name="acid-minimal-cluster-0",client_addr="172.17.0.17",server="acid-minimal-cluster-1:5432",slot_name="182",state="streaming"} 1.52655344e+08
pg_stat_replication_pg_wal_lsn_diff{application_name="acid-minimal-cluster-0",client_addr="172.17.0.17",server="acid-minimal-cluster-1:5432",slot_name="182",state="streaming"} 0
pg_stat_replication_reply_time{application_name="acid-minimal-cluster-0",client_addr="172.17.0.17",server="acid-minimal-cluster-1:5432",slot_name="182",state="streaming"} 1.663625745e+09
pg_static{server="acid-minimal-cluster-1:5432",short_version="13.7.0",version="PostgreSQL 13.7 (Ubuntu 13.7-1.pgdg18.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0, 64-bit"} 1
pg_up 1

[/simterm]

pg_up == 1 – йай! Іт воркс!

Prometehus ServiceMonitors

Відкриваємо порт для доступу до самого Prometheus:

[simterm]

$ kubectl -n monitoring port-forward svc/kube-prometheus-stack-prometheus 9090:9090
Forwarding from 127.0.0.1:9090 -> 9090
Forwarding from [::1]:9090 -> 9090

[/simterm]

Перевіряємо Status > Service Discovery – PostgreSQL тут не бачимо:

СервісМонітори також були створені із маніфесту:

[simterm]

$ kubectl -n test-pg get servicemonitor
NAME                                AGE
acid-minimal-cluster-svcm-master    65m
acid-minimal-cluster-svcm-replica   65m

[/simterm]

Повторюємо “грязний хак”, як робили для Друіда – додаємо в них label "release": "kube-prometheus-stack", чекаємо хвилину-дві, и перевіряємо ще раз:

Та маємо метріки в графіках:

Готово.

Loading

ФОП: податки для нубасів, ч1 – вступ та відкриття рахунків Моно
0 (0)

18 Вересня 2022

На новому проекті бухгалтерію свого ФОП маю вести сам, отже, “Валєра! Настало твайо врємя!” – нарешті є прекрасний шанс поринути в деталі ведення власного ФОП, бо раніше за мене це робила бухгалтерія компанії.

Ну а раз така тема, а деталей там буде досить – то вирішив ще й нову рубрику на RTFM завести, а так як тема стосується тільки України та її податкової системи, то й мова постів в цій рубриці буде виключно українська.

ФОП та банки

Отже, що маємо наразі: у меня є ФОП 3 групи, 5% податку, подача декларації – раз на квартал, плюс щорічна декларація. Про групи та деклараціх якось напишу окремо, як буду подавати.

Між іншим, в Дії мають бути всі ваши документи в тому числі и по ФОП, де можна глянути деталі, наприклад – групу, бо до цього моменту я її навіть не знав 🙂

Для цього переходимо в Послуги – Податки ФОП, та при потребі – Детальна інформація (там же можна включити більше тесну інтеграцію с деякими банками, але про це теж згодом):

UkrSib Bank vs Monobank

Щодо банків та рахунків – маю відкритий колись давно ФОП-рахунок в UkrSib Bank, до якого є нарікання, наприклад операції з рахунками ФОП тільки в банківські дні та час, або необхідності відправляти на продаж валюту  до 13.00, щоб отримати кошти від продажу в той самий день, а не наступний.

Чому Моно? Бо по-перше – миттєві операції по рахунках, по друге, як кажуть – там набагато простіше виконувати всякі операціі по податкам, плюс тісна інтеграція з Дією. Але, нажаль, немає і не буде веб-морди. Будемо звикати. Доречі – є якийсь Бухалтерський кабінет, саме як WebUI, в якому мають бути доступні як раз операціі з податками та звітами.

Що буду робити – відкрию Моно ФОП в гривні, до нього – в USD, і передам IBAN нового долларового рахунку бухгалтерії нового проекту.

Перша компенсація (такий собі замінник слову “зарплатня”) тут буде на старий рахунок ФОП в Укрсибі (де мав радість знайомства с оформленням нових контрактів, хочется окремо записати), а вже всі наступні платежі підуть на новий Моно-рахунок.

Відкриття ФОП в Моно

Тут насправді особо нема й чого писати, бо як й усе в Монобанку – процесс досить тривіальний.

Вид економічної діяльності ФОП

Єдине, на що варто звернути увагу, це опис вашої діяльності – взагалі, Моно має витягти її автоматично, начебто з Дії, але можно описати вручну.

Він має співпадати з вашим Видом економічної діяльності. Якщо не знаєте його – то можно перевірити в Свідоцтві платника єдиного податку, або скористатися такими сервісами як https://opendatabot.ua, або його телегоботом – @OpenDataUABot:

Ну і сам процесс на кшалт “кілька разів кликнути “Окей, згода, погнали далі”. Нажаль, скріни з рос. версії:


Після відкриття рахунку в гривні – з’явиться можливість відкрити другий рахунок, в долларах. Там процесс ще простіший.

І нарешті маємо два рахунки – долларовий, на який приходить “експортна виручка” aka salary:

Та гривнєвий, на який буде переводитися гривня, виручена за продаж тієї самої експортної виручки, і з якого можна буде платити податки та переводити гроші на свої картки:

Далі треба буде потикати “Ліміти обігу ФОП”, ну і можно будет починати платити податки та подавати звіти.

Loading