воскресенье, 22 декабря 2024 г.

tuning linux for high load (net)

Pages with twicks


https://www.thegeekdiary.com/sysctl-setting-for-high-load-and-prevent-ddos/

https://easyengine.io/tutorials/linux/sysctl-conf/

https://reintech.io/blog/tuning-linux-kernel-parameters-rocky-linux-9

https://stupin.su/wiki/linux_sysctl/

http://kb.ictbanking.net/article.php?id=348

https://www.cyberciti.biz/tips/linux-increase-outgoing-network-sockets-range.html

https://www.cyberciti.biz/tips/linux-increase-outgoing-network-sockets-range.html

https://habr.com/ru/articles/108763/

https://docs.emqx.com/en/emqx/latest/performance/tune.html







среда, 18 декабря 2024 г.

Публикация VPN сервера Windows 2019 (pptp, l2tp) из приватной сети через NAT checkpoint

1)  При стандартной настройке NAT (incoming NAT for ANY) pptp не работает, хотя tcp/1723  и GRE транслируются во внутрь, проблема в том, что только обратный GRE трафик от сервера не транслируется. Для этого необходимо добавить и  исходящее правило NAT (any, hide) только для GRE трафика и разрешить в ACL исходящий трафик только для GRE.  Ответные же TCP и UDP  от VPN сервера будут автоматический выпущены в контексте инициирующего их  входящего NAT.

2) L2tp по умолчанию не работает, так Windows (клиент и сервер) не понимают NAT-T. для этого необходимо включить  опцию в registy по статье:

https://winitpro.ru/index.php/2017/10/24/reshaem-problemu-podklyucheniya-k-l2tp-ipsec-vpn-serveru-za-nat/

или использовать командлет PowerShell для внесения изменений в реестр:

Set-ItemProperty -Path "HKLM:SYSTEM\CurrentControlSet\Services\PolicyAgent" -Name "AssumeUDPEncapsulationContextOnSendRule" -Type DWORD -Value 2 –Force


понедельник, 10 июня 2024 г.

Архитектура (ИТ)


Матрица Захмана:


или







 TOGAF (the open group architecture framework)

ADM (Architecture Deployment Method)

ADM describes 10 phases and preliminary phase




среда, 17 апреля 2024 г.

Postgresql cluster patroni

разворачиваем кластер с помощью ansible

https://github.com/vitabaks/postgresql_cluster?tab=readme-ov-file


ставим dbeaver

https://pq.hosting/help/instructions/407-ustanovka-dbeaver-v-ubuntu-2204.html


ставим jmeter

https://www.how2shout.com/linux/2-ways-to-install-apache-jmeter-on-ubuntu-22-04-lts-linux/

вторник, 16 апреля 2024 г.

Ansible установка, настройка SSH

Для установки Ansible (ubuntu) есть несколько способов:

1)  С помощью "apt"

sudo apt update

sudo apt upgrade -y

sudo apt install ansible

Но вероятнее всего установится устаревшая версия, 2.10.хх ,

("ansible --version")

которая не поддерживает современные playbook

для поднятия версии до актуальной:

sudo add-apt-repository --yes --update ppa:ansible/ansible

sudo apt install ansible

если версия не поднимется или ansible вообще пропадет, то можно воспользоваться:

apt --fix-broken install

и уточнить версию:

"ansible --version"

https://www.cherryservers.com/blog/install-ansible-ubuntu

2) С помощью pip

Установим pip:

curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py

python3 get-pip.py --user

проверим наличие: python3 -m pip -V

Установим ansible:

python3 -m pip install --user ansible

( при необходимости, минимальная версия:

python3 -m pip install --user ansible-core

или конкретная версия:

python3 -m pip install --user ansible-core==2.12.3 )

Обновление через pip (не проверял):

python3 -m pip install --upgrade --user ansible

этот и другие способы: https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html



Для того чтобы ansible мог подключаться к хостам (на которых он будем изменять что-то)

необходимо настроить вход по ключу (без пароля) есть несколько способов:


1) создаем (linux) пару ключей (pub and priv, pass-фразу не вводим, просто "enter")

ssh-keygen -f ~/.ssh/id_rsa  (можно отдельное название использовать для ключа вместо id_rsa )

ssh-copy-id -i ~/.ssh/id_rsa.pub user-ansbl@192.168.58.58 

#(192.168.58.58 машина которой будем управлять, в ней , в файле $HOME/.ssh/authorized_keys, должно появиться что-то типа: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICc/6Mhk0/y....)

в inventory file можно добавить: 

all:

  vars:

    ansible_user: ta

  hosts:

    ta-lxlt:

      ansible_host: 192.168.58.58

      ansible_ssh_private_key_file: ~/.ssh/id_rsa


или запусить ssh-agent:

ssh-agent $SHELL

ssh-add ~/.ssh/id_rsa


после чего проверить:

ssh user-ansbl@192.168.58.58

должно открыться ssh сессия на удаленную машину без ввода пароля.


https://dev.to/rimelek/ansible-playbook-and-ssh-keys-33bo

проверяем:

ansible all -m ping

можно приватный ключ указать и через параметр:

ansible -playbook ХХХХХХ.yaml --private-key ~/.ssh/id_rsa


2) использовать сгенерированные в putty ключи:

в putty key generator создаем ключи типа:  ssh-ed25519, сохраняем оба ключа (приватный).

(в окошке же сразу видно и публичный ключ, при необходимости можно его скоприровать)

если разворачиваем виртуалку в клауде, то при создании ВМ есть возможность сразу вставить (если реализован cloud-init у провайдера)  публичный ключ из окошка "putty key generator" (если ранее загружен/сгенерирован приватный ключ)

Затем выбираем пункт "Conversion" и Export OpenSSH key, сохраняем в файле (без пароля)

(в файле будет что-то типа -----BEGIN OPENSSH PRIVATE KEY-----) 

именно из этого файла необходимо будет скопировать содержимое и вставить ~/.ssh/id_rsa на машинке с ansible.

выставить права:

chmod 600 /root/.ssh/id_rsa

Если же подключаться с рабочей машинки с Putty, то надо прикрепить приватный ключ .ppk к ssh-сессии.



суббота, 6 января 2024 г.

Cilium hubble ui подключение

 Cilium имеет реализацию service-mesh поэтому подключусь к UI интерфейсу (HUBBLE UI), чтобы увидеть и отрассировать связности между контейнерами. В YC есть возможность выбрать cilium как основу для связности в кластере (наряду calico). И наличие cilium позволяет подключать (разносить) ноды (worker and master) по произвольным (разным) L3 сегментам. Важно чтобы трафик пропускался для VXLAN (в принципе, сам VXLAN работает и через 1:1 NAT, возможно и через маскарадинг?) 

Для подключения необходимо установить контейнер HUBBLE UI, ставим манифестом (kubectl apply -f hubble-ui.yaml)

# Source: cilium/templates/hubble-ui-serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: "hubble-ui"
  namespace: kube-system
---
# Source: cilium/templates/hubble-ui-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: hubble-ui-envoy
  namespace: kube-system
data:
  envoy.yaml: |
    static_resources:
      listeners:
        - name: listener_hubble_ui
          address:
            socket_address:
              address: 0.0.0.0
              port_value: 8081
          filter_chains:
            - filters:
                - name: envoy.filters.network.http_connection_manager
                  typed_config:
                    "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                    codec_type: auto
                    stat_prefix: ingress_http
                    route_config:
                      name: local_route
                      virtual_hosts:
                        - name: local_service
                          domains: ["*"]
                          routes:
                            - match:
                                prefix: "/api/"
                              route:
                                cluster: backend
                                prefix_rewrite: "/"
                                timeout: 0s
                                max_stream_duration:
                                  grpc_timeout_header_max: 0s
                            - match:
                                prefix: "/"
                              route:
                                cluster: frontend
                          cors:
                            allow_origin_string_match:
                              - prefix: "*"
                            allow_methods: GET, PUT, DELETE, POST, OPTIONS
                            allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout
                            max_age: "1728000"
                            expose_headers: grpc-status,grpc-message
                    http_filters:
                      - name: envoy.filters.http.grpc_web
                      - name: envoy.filters.http.cors
                      - name: envoy.filters.http.router
      clusters:
        - name: frontend
          connect_timeout: 0.25s
          type: strict_dns
          lb_policy: round_robin
          load_assignment:
            cluster_name: frontend
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: 127.0.0.1
                          port_value: 8080
        - name: backend
          connect_timeout: 0.25s
          type: logical_dns
          lb_policy: round_robin
          http2_protocol_options: {}
          load_assignment:
            cluster_name: backend
            endpoints:
              - lb_endpoints:
                  - endpoint:
                      address:
                        socket_address:
                          address: 127.0.0.1
                          port_value: 8090
---
# Source: cilium/templates/hubble-ui-clusterrole.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: hubble-ui
rules:
  - apiGroups:
      - networking.k8s.io
    resources:
      - networkpolicies
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - ""
    resources:
      - componentstatuses
      - endpoints
      - namespaces
      - nodes
      - pods
      - services
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - apiextensions.k8s.io
    resources:
      - customresourcedefinitions
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - cilium.io
    resources:
      - "*"
    verbs:
      - get
      - list
      - watch
---
# Source: cilium/templates/hubble-ui-clusterrolebinding.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: hubble-ui
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: hubble-ui
subjects:
  - kind: ServiceAccount
    namespace: kube-system
    name: "hubble-ui"
---
# Source: cilium/templates/hubble-ui-service.yaml
kind: Service
apiVersion: v1
metadata:
  name: hubble-ui
  labels:
    k8s-app: hubble-ui
  namespace: kube-system
spec:
  selector:
    k8s-app: hubble-ui
  ports:
    - name: http
      port: 80
      targetPort: 8081
  type: ClusterIP
---
# Source: cilium/templates/hubble-ui-deployment.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  namespace: kube-system
  labels:
    k8s-app: hubble-ui
  name: hubble-ui
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: hubble-ui
  template:
    metadata:
      annotations:
      labels:
        k8s-app: hubble-ui
    spec:
      securityContext:
        runAsUser: 1001
      serviceAccount: "hubble-ui"
      serviceAccountName: "hubble-ui"
      containers:
        - name: frontend
          image: "quay.io/cilium/hubble-ui:v0.7.9@sha256:e0e461c680ccd083ac24fe4f9e19e675422485f04d8720635ec41f2ba9e5562c"
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080
              name: http
          resources: {}
        - name: backend
          image: "quay.io/cilium/hubble-ui-backend:v0.7.9@sha256:632c938ef6ff30e3a080c59b734afb1fb7493689275443faa1435f7141aabe76"
          imagePullPolicy: IfNotPresent
          env:
            - name: EVENTS_SERVER_PORT
              value: "8090"
            - name: FLOWS_API_ADDR
              value: "hubble-relay:80"
          ports:
            - containerPort: 8090
              name: grpc
          resources: {}
        - name: proxy
          image: "docker.io/envoyproxy/envoy:v1.18.2@sha256:e8b37c1d75787dd1e712ff389b0d37337dc8a174a63bed9c34ba73359dc67da7"
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8081
              name: http
          resources: {}
          command: ["envoy"]
          args: ["-c", "/etc/envoy.yaml", "-l", "info"]
          volumeMounts:
            - name: hubble-ui-envoy-yaml
              mountPath: /etc/envoy.yaml
              subPath: envoy.yaml
      volumes:
        - name: hubble-ui-envoy-yaml
          configMap:
            name: hubble-ui-envoy

проверяем что поставилось: 

C:\work\projects>kubectl get deployment -n kube-system

NAME                  READY   UP-TO-DATE   AVAILABLE   AGE

cilium-operator       1/1     1            1           21h

coredns               1/1     1            1           21h

hubble-relay          1/1     1            1           21h

hubble-ui             1/1     1            1           42m

kube-dns-autoscaler   1/1     1            1           21h

metrics-server        1/1     1            1           21h

C:\Users\adm>kubectl get svc -n kube-system

NAME              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE

cilium-agent      ClusterIP   None            <none>        9090/TCP,9095/TCP        21h

cilium-operator   ClusterIP   None            <none>        6942/TCP                 21h

hubble-metrics    ClusterIP   None            <none>        9091/TCP                 21h

hubble-relay      ClusterIP   10.96.212.143   <none>        80/TCP                   21h

hubble-ui         ClusterIP   10.96.42.39     <none>        80/TCP                   45m

kube-dns          ClusterIP   10.96.0.2       <none>        53/UDP,53/TCP,9153/TCP   21h

metrics-server    ClusterIP   10.96.124.89    <none>        443/TCP                  21h

Затем биндим порт командой:

kubectl port-forward -n kube-system svc/hubble-ui 12000:80 

Заходим без авторизации и находим такие визуализации (старые деплойменты надо будет перезапустить, иначе их связностей не будет видно - но они появятся после рестарта)








Разворачивание в кластере кубернетес базы данных postgres и wiki.js

 Разворачиваем через консоль управляемый кластер (master) в яндекс облаке (YC) и сразу добавляем рабочие узлы (worker node(s)). Также, в той же локации (зоне обслуживания ...-a (b,c,d)), добавляем отдельный диск под Persistent Volume (PV), и  запоминаем его "disk-id" Настраиваем локальную работу kubectl по инструкции от яндекс облако.

Затем развернем 2 деплоймента: postgres and wiki.js 

1. Postgres, 

сначала создадим PV и PV Claim (PVC): (pv-pvc.yaml) 

apiVersion: v1
kind: PersistentVolume
metadata:
  name: persistent-volume-pv
  labels:
    type: local
    app: my-database
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  storageClassName: yc-network-hdd # match to disk type in ya cloud
  csi:
    driver: disk-csi-driver.mks.ycloud.io
    fsType: ext4
    volumeHandle: epd6onn7r80053mlt1ad # "Disk-id" from ya cloud
  storageClassName: manual
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-db # will apply to this name of PVC in deployment
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: manual
  volumeName: persistent-volume-pv

запускаем:  kubectl apply -f .\pv-pvc.yaml

в консоли яндекс клауд должно появиться "Bound" для обоих сущностей (пункт Хранилище)

красным  цветом указано как ссылаются сущности, на зеленый будет ссылка ниже, из деплоймента PG. 

далее разворачиваем еще 2 сущности ConfigMap and Secret (conf-map-sec.yaml)

kind: ConfigMap
apiVersion: v1
metadata:
  name: database-cm
data:
  create-database-table.sql: |
    CREATE TABLE gifts (
      id SERIAL PRIMARY KEY,
      name VARCHAR,
      sold INT
    );

    INSERT INTO gifts (name,sold) VALUES ('Pumpkin', 3000);
    INSERT INTO gifts (name,sold) VALUES ('Christmas Tree', 1000);
    INSERT INTO gifts (name,sold) VALUES ('Socks', 10000);
---
apiVersion: v1
kind: Secret

metadata:
  name: db-secret-credentials
  labels:
    app: my-database
data:
  POSTGRES_DB: Z2lmdHMtdGFibGU= # gifts-table all coded by base64, below too
  POSTGRES_USER: YWRtaW4= # admin
  POSTGRES_PASSWORD: UEBzc3cwcmQ= # P@ssw0rd
 

запускаем:  kubectl apply -f .\conf-map-sec.yaml

ConfigMap здесь только для примера, чтобы понять как могут  передаваться в контейнер файл с нужным содержимым, там можно создать базу, таблицу, внести строки, создать пользователя и т.д. Использовал для проверки работоспособности базы и чтобы потом, подключившись к Pod руками пролить нужные настройки, т.к. пока не изучал как может повлиять многоразовая инициализация рабочей (нужной) базы, которая хранится в отдельном, от кластера кубернетис, диске. Если всё правильно, то должны появиться в секции "Конфигурация" обе сущности с нужными переменными. На белый и светло-коричневый пункты будет ссылка из деплоймента PG

Разворачиваем деплоймент postgres (kubectl apply -f .\depl-pd.yaml)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-db
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-database
  template:
    metadata:
      labels:
        app: my-database
    spec:
      containers:
        - name: my-database
          image: postgres:latest
          ports:
            - containerPort: 5432
          env:
            - name: POSTGRES_DB
              valueFrom:
                secretKeyRef:
                  name: db-secret-credentials
                  key: POSTGRES_DB

            - name: POSTGRES_USER
              valueFrom:
                secretKeyRef:
                  name: db-secret-credentials
                  key: POSTGRES_USER

            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: db-secret-credentials
                  key: POSTGRES_PASSWORD

          volumeMounts:
            - mountPath: /var/lib/postgresql/data
              name: db-data
              subPath: data

            - mountPath: /docker-entrypoint-initdb.d
              name: postgresdb-loadsql
      volumes:
        - name: postgresdb-loadsql
          configMap:
            name: database-cm

        - name: db-data
          persistentVolumeClaim:
            claimName: pvc-db

Здесь видно, что запрошено (зеленым) PVC который описан ранее, и ему дано имя db-data (голубым) и уже это имя тома/раздела будет подмонтировано к каталогу "/var/lib/postgresql/data" -где лежат сами файлы БД, важно добавить параметр subPath: data

т.к. он указывает и на подкаталоги(?), иначе postgres (PG) находит прежние файлы БД, но считает их чужими, т.к. его конфиг возможно ничего не знает о старой, с параметром же, он находит и конфиг в этом же каталоге и запускается без ошибок. Можно это увидеть в секции "Логи" в YC для данного деплоймента.

Для опубликования внутри кластера порта (5432) для подключения к PG запустим service (svc-db.yaml)

apiVersion: v1
kind: Service
metadata:
  name: svc-db # hostname to connect from app (wiki.js)
  labels:
    app: my-database
spec:
  selector:
    app: my-database
#  type: NodePort
  ports:
  - protocol: TCP
    port: 5432
    targetPort: 5432

запускаем   kubectl apply -f .\svc-db.yaml

Здесь объявлен hostname (светло-бежевым) , который мы укажем в деплойменте wiki.js для подключения к БД.

проверяем:

  C:\work\projects>kubectl get deployments

NAME            READY   UP-TO-DATE   AVAILABLE   AGE

deployment-db   1/1     1            1           106m

C:\work\projects>kubectl get pods

NAME                             READY   STATUS    RESTARTS   AGE

deployment-db-7f9649d79f-65swk   1/1     Running   0          97m

подключаемся к БД и убеждаемся, что БД работает:

C:\work\projects>kubectl exec -it deployment-db-7f9649d79f-65swk -- psql -h localhost -U admin --password -p 5432 gifts-table

Password:

psql (16.1 (Debian 16.1-1.pgdg120+1))

Type "help" for help.

gifts-table=#

Создаем пользователя, базу данных и права для wiki.js (вставляем в промт)

CREATE DATABASE wikijs;

CREATE USER wikijs WITH PASSWORD 'wikijsrocks';

GRANT CONNECT ON DATABASE wikijs TO wikijs;

GRANT USAGE ON SCHEMA public TO wikijs;

GRANT SELECT,UPDATE,INSERT,DELETE ON ALL TABLES IN SCHEMA public TO wikijs;

ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO wikijs;

ALTER DATABASE wikijs OWNER TO wikijs;

Выходим из БД и заходим повторно но уже с пользователем wikijs:

kubectl exec -it deployment-db-7f9649d79f-65swk -- psql -h localhost -U wikijs --password -p 5432 wikijs

Должно пустить.


2. Wiki.js

Создаем ConfigMap  (conf-map-sec-wiki-js.yaml)

apiVersion: v1
kind: ConfigMap
metadata:
  name: wikijs
data:
  DB_TYPE: postgres
  DB_HOST: svc-db # hostname from svc-db.yaml
  DB_PORT: "5432"
  DB_NAME: "wikijs"
  DB_USER: "wikijs"
  DB_PASS: "wikijsrocks"

запускам:  kubectl apply -f .\conf-map-sec-wiki-js.yaml

Передаем таким образом параметры в переменные для контейнера с wiki.js 

Создаем деплоймент (и сразу service) для приложения Wiki.js (depl-wiki-js.yaml)

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: wikijs
  name: wikijs
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wikijs
  template:
    metadata:
      labels:
        app: wikijs
    spec:
      containers:
        - name: wikijs
          image: 'requarks/wiki:2'
          ports:
            - name: http-3000
              protocol: TCP
              containerPort: 3000
          envFrom:
          - configMapRef:
              name: wikijs
---
apiVersion: v1
kind: Service
metadata:
  name: wikijs
spec:
  selector:
    app: wikijs
  ports:
    - protocol: TCP
      port: 3000
      targetPort: http-3000

Запускаем:  kubectl apply -f .\depl-wiki-js.yaml

Желтым цветом показана привязка к ConfigMap wikijs. В секции "полезная нагрузка" , в соответствующем  деплойменте, провалившись в строку, можно посмотреть "Логи" там должно быть успешное соединение с БД. (используется Deployment c replica=1, но правильно д.б. StatefulSet).

для публикации Wiki.js в интернет понадобится еще один сервис типа loadBalancer 

запускаю его вручную (т.к. это для теста и учебы):

kubectl expose deployment wikijs --type=LoadBalancer --name=my-serv-wiki


Важно, создается новый сервис my-serv-wiki, 

узнаем внешний IP:

 kubectl get services my-serv-wiki

и можно соединяться по 3000 порту  на внешний IP, который виден в выводе комнады.


Замечания:

можно собрать в один файл, но кубернетес нет  команды "depends on:, считается, что все компоненты/сущности, что работают в кубернетес, должно быть толерантны к времени своего запуска/перезапуска.

Деплоймент читает ConfigMap и Secret только один раз, при запуске/перезапуcке, т.е. даже изменив их, надо заставить обновиться Pod-ы (рестарт/scaling и т.д.)


команды для тестирования (kubectl port-forward <pod-name> <localhost-port>:<pod-port>):

kubectl port-forward wikijs-678fdfd978-7tgdj 3000:3000  (прибиндить порт Pod к 127.0.0.1:3000)


ниже полный (по опциям) эквивалент сервиса ...expose ...  LoadBalancer

kubectl expose deployment example --port=8765 --target-port=9376 \
     --name=example-service --type=LoadBalancer



apiVersion: v1
kind: Service
metadata: 
  name: example-service
spec:
  selector:
    app: example
  ports:
    - port: 8765
      targetPort: 9376
  type: LoadBalancer