2020-12-28
Меня зовут Павел Дерендяев, я руководитель Java-разработчиков в Альфа-Банке.
Свою карьеру в IT я начинал как системный администратор и сетевой инженер в различных телеком-компаниях. Основными языками программирования были Perl и Bash (и PHP!). В 2010 году я полностью забросил Perl/PHP и переключился на Java-разработку. В основном, писал около-биллинговые решения для тех же телекомов. Я все еще люблю настраивать сети, возиться с инфраструктурой и писать скрипты на Bash или Python.
Конкретно в Альфе-банке я занимался разработкой микросервисов для корпоративного Интернет-банка и, естественно, плотно занимался инфраструктурой нашего Mesos/Marathon-кластера.
В конце 2017 года в моей жизни случился очередной перелом. IT-блок банка трансформировался в матричную структуру, дабы разработчики не были разбросаны по разным отделам, а находились в одном центре компетенции. Цель - погружение всех в одно коммьюнити, обмен знаниями и опытом, следование общей технической стратегии и, вообще, уменьшение степени велосипедостроения.
Как руководитель Центра компетенции Java я, в основном, занимаюсь наймом разработчиков, их дальнейшим развитием, участвую в развитии общего технического слоя Java в Банке. Также занимаюсь организацией коммьюнити и продвижением HR-бренда Альфа-Банка.
Моя цель - не внедрить бесплатную раздачу печенек и бананов и не развесить гамаки рядом с каждым рабочим местом. Я хочу, чтобы разработчики занимались интересными задачами, которые их драйвят и приносят реальную ценность банку и его сотням тысяч клиентов. Не секрет, что к крутому стеку технологий у нас прилагаются сложная банковская архитектура, большие нагрузки, работа 24/7, требования безопасности и командная ответственность. Помочь разработчику не утонуть во всем этом, получать кайф от работы и “нормально делать, чтобы нормально было” - это и есть моя основная задача.
Кого я ищу в свою команду:
- Если ты хочешь быть “в тренде” в мире Java.
- Если ты хочешь создавать конечные решения - not only code, но и инфраструктура.
- Если ты хочешь развивать технологии private cloud.
- Если ты хочешь работать в команде с ведущими экспертами в области Java и DevOps.
- Если ты хочешь стартовать новые проекты и принимать архитектурные решения.
2019-08-10
9 августа прошел Java-митап Backend stories 4.0 в Альфа-банке.
Презентации доступны на страничке с отчетом о событии.
Прямая ссылка на запись трансляции.
Мой доклад - Отказоустойчивость в большом Интернете
2019-04-01
29 марта прошел Java-митап Backend stories 3.0 в Альфа-банке.
Материалы доступны на страничке с отчетом о событии.
Прямая ссылка на запись трансляции.
2018-10-15
04 октября прошел Java-митап Backend stories 2.0 в Альфа-банке.
Все материалы доступны на страничке с отчетом о событии.
Прямая ссылка на запись трансляции.
2018-06-23
Список консьюмер-групп
docker run wurstmeister/kafka /opt/kafka/bin/kafka-consumer-groups.sh --bootstrap-server kafka:9092 --list
Информация по консьюмер-группе
docker run wurstmeister/kafka /opt/kafka/bin/kafka-consumer-groups.sh --bootstrap-server kafka:9092 --group id1 --describe
Установка оффсета на начало
docker run wurstmeister/kafka /opt/kafka/bin/kafka-consumer-groups.sh --bootstrap-server kafka:9092 --topic topic --group id1 --reset-offsets --to-earliest --execute
Установка оффсета на конец
docker run wurstmeister/kafka /opt/kafka/bin/kafka-consumer-groups.sh --bootstrap-server kafka:9092 --topic topic --group id1 --reset-offsets --to-latest --execute
Установка оффсета на дату-время
docker run wurstmeister/kafka /opt/kafka/bin/kafka-consumer-groups.sh --bootstrap-server kafka:9092 --topic topic --group id1 --reset-offsets --to-datetime "2017-12-22T00:00:00.000" --execute
Установка оффсета на дату-время для партишенов 0, 1 (одно время для всех партишенов)
docker run wurstmeister/kafka /opt/kafka/bin/kafka-consumer-groups.sh --bootstrap-server kafka:9092 --topic topic:0,1 --group id1 --reset-offsets --to-datetime "2017-12-22T00:00:00.000" --execute
Установка оффсета на дату-время для партишенов 0, 1 (разное время для партишенов)
docker run dddpaul/kafka-rewind --servers=kafka:9092 --group-id=id1 --topic=topic -o 0=2017-12-01 -o 1=2018-01-01
Создать топик
docker exec -it wurstmeister/kafka sh -c "JMX_PORT=10001 /opt/kafka/bin/kafka-topics.sh --create --topic topic --replication-factor 1 --partitions 1 --zookeeper zookeeper:2181"
Накидать сообщений
docker exec -it wurstmeister/kafka sh -c "JMX_PORT=10001 /opt/kafka/bin/kafka-verifiable-producer.sh --topic topic --max-messages 200000 --broker-list localhost:9092"
Консольный консьюмер
docker exec -it wurstmeister/kafka sh -c "JMX_PORT=10001 /opt/kafka/bin/kafka-console-consumer.sh --topic topic --bootstrap-server host:9092"
docker run -it wurstmeister/kafka -c "JMX_PORT=10001 /opt/kafka/bin/kafka-console-consumer.sh --topic topic --bootstrap-server host:9092"
docker run --entrypoint=/opt/kafka/bin/kafka-console-consumer.sh wurstmeister/kafka --topic topic --bootstrap-server host:9092
Python консьюмер
#!/usr/bin/env python
from kafka import KafkaConsumer
consumer = KafkaConsumer(bootstrap_servers='kafka1:9092',
group_id=None,
auto_offset_reset='earliest')
consumer.subscribe(['rsyslog_apps'])
for msg in consumer:
print msg
Kafkacat консьюмер
docker run -it confluentinc/cp-kafkacat kafkacat -b host:9092 -t topic -o beginning -v
Установка retention на топик
docker exec -it kafka /opt/kafka/bin/kafka-configs.sh --zookeeper host:2181 --entity-type topics --entity-name topic --describe
docker exec -it kafka /opt/kafka/bin/kafka-topics.sh --zookeeper host:2181 --topic topic --describe
docker exec -it kafka /opt/kafka/bin/kafka-topics.sh --zookeeper host:2181 --topic topic --alter --config retention.ms=1000
2018-06-22
21 июня прошел Java-митап Backend stories в Альфа-банке.
Доклады:
Также есть запись трансляции.
2016-11-13
Install migration Ruby gem and run it:
gem install mysql2psql
mysql2psql
Update database credentials in generated mysql2psql.yml file:
mysql:
database: redmine
hostname: localhost
port: 3306
username: redmine
password: xxxxxxx
encoding: utf8
destination:
# if file is given, output goes to file, else postgres
file: /tmp/redmine-pg.sql
postgres:
hostname: localhost
port: 5432
username: mysql2psql
password:
database: mysql2psql_test
Run command again:
mysql2psql
Links:
2016-11-07
Træfɪk is a modern HTTP reverse proxy and load balancer made to deploy microservices with ease. Since 1.1.0-rc1 it supports Docker Swarm mode as backend. It means that Træfɪk will automatically create proxying frontends which will be binded to corresponding Docker Swarm services.
This post is based on Docker Swarm (mode) cluster example.
Assuming we have Docker Swarm mode cluster already, we will need to create an overlay network:
docker network create --driver=overlay traefik-net
Backends are the simple emilevauge/whoami services:
docker service create --name test1 --label traefik.port=80 --network traefik-net emilevauge/whoami
docker service create --name test2 --label traefik.port=80 --network traefik-net emilevauge/whoami
Træfɪk itself may be ran in rich variety of configurations.
1. HTTP only proxy
docker service create \
--name traefik \
--constraint=node.role==manager \
--publish 80:80 --publish 8080:8080 \
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
--network traefik-net \
traefik:v1.1.0-rc3 \
--docker \
--docker.swarmmode \
--docker.domain=example.org \
--docker.watch \
--logLevel=DEBUG \
--web
Remarks:
2. HTTPS proxy with Let’s Encrypt certificate and HTTP to HTTPS redirection
docker service create \
--name traefik \
--constraint=node.role==manager \
--publish 80:80 --publish 443:443 --publish 8080:8080 \
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock,readonly \
--mount type=bind,source=/var/tmp,target=/etc/traefik/acme \
--network traefik-net \
traefik:v1.1.0-rc3 \
--entryPoints='Name:http Address::80 Redirect.EntryPoint:https' \
--entryPoints='Name:https Address::443 TLS' \
--defaultEntryPoints=http,https \
--acme.entryPoint=https \
--acme.email=owner@example.org \
--acme.storage=/etc/traefik/acme/acme.json \
--acme.domains=example.org \
--acme.onHostRule=true \
--docker \
--docker.swarmmode \
--docker.domain=example.org \
--docker.watch \
--web
3. HTTPS-only proxy with Let’s Encrypt certificate
docker service create \
--name traefik \
--constraint=node.role==manager \
--publish 443:443 --publish 8080:8080 \
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock,readonly \
--mount type=bind,source=/var/tmp,target=/etc/traefik/acme \
--network traefik-net \
traefik:v1.1.0-rc3 \
--entryPoints='Name:https Address::443 TLS' \
--defaultEntryPoints=https \
--acme.entryPoint=https \
--acme.email=owner@example.org \
--acme.storage=/etc/traefik/acme/acme.json \
--acme.domains=example.org \
--acme.onHostRule=true \
--docker \
--docker.swarmmode \
--docker.domain=example.org \
--docker.watch \
--logLevel=DEBUG \
--web
4. HTTPS-only proxy with Let’s Encrypt certificate and HTTPS web UI
docker service create \
--name traefik \
--constraint=node.role==manager \
--publish 443:443 --publish 8443:8443 \
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock,readonly \
--mount type=bind,source=/etc/pki/realms/domain,target=/etc/traefik/tls,readonly \
--mount type=bind,source=/var/tmp,target=/etc/traefik/acme \
--network traefik-net \
traefik:v1.1.0-rc3 \
--entryPoints='Name:https Address::443 TLS:/etc/traefik/tls/default.crt,/etc/traefik/tls/default.key' \
--defaultEntryPoints=https \
--acme.entryPoint=https \
--acme.email=owner@example.org \
--acme.storage=/etc/traefik/acme/acme.json \
--acme.domains=example.org \
--acme.onHostRule=true \
--docker \
--docker.swarmmode \
--docker.domain=example.org \
--docker.watch \
--logLevel=DEBUG \
--web.address=:8443 \
--web.certfile=/etc/traefik/tls/default.crt \
--web.keyfile=/etc/traefik/tls/default.key
5. For debugging purposes you can run Træfɪk without Docker
traefik -d \
--entryPoints='Name:http Address::8080 Redirect.EntryPoint:https' \
--entryPoints='Name:https Address::8443 TLS' \
--defaultEntryPoints=http,https \
--acme.entryPoint=https \
--acme.email=owner@example.org \
--acme.storage=acme.json \
--acme.domains=example.org
--logLevel=DEBUG \
--web
Links:
2016-11-02
1. Create logical volumes for direct-lvm
production mode
Assume that we have 40 GByte block device named as /dev/sdb
with one full-size Linux partition on it.
Official Device Mapper storage driver guide recommends to use thin pools now. Use these commands to create thin-provisioned logical volumes:
pvcreate /dev/sdb1 # Create physical volume
vgcreate docker /dev/sdb1 # Create volume group and add this physical volume to it
# Create logical volumes
lvcreate --wipesignatures y -n data docker -l 40%VG
lvcreate --wipesignatures y -n registry docker -l 40%VG
lvcreate --wipesignatures y -n metadata docker -l 2%VG
# Convert data volume to thin pool's data volume
lvconvert -y --zero n -c 512K --thinpool docker/data --poolmetadata docker/metadata
# Set thin pool autoextend features
cat > /etc/lvm/profile/docker-data.profile
activation {
thin_pool_autoextend_threshold = 80
thin_pool_autoextend_percent = 20
}
lvchange --metadataprofile docker-data docker/data
# Check thin pool volume (must be monitored)
lvs -o+seg_monitor
LV VG Attr LSize Pool Origin Data% Meta% Move Log Cpy%Sync Convert Monitor
root centos -wi-ao---- 117,19g
swap centos -wi-ao---- 1,95g
data docker twi-a-t--- 16,00g 0,00 0,01 monitored
registry docker -wi-a----- 16,00g
Or if you do not trust thin pools use more traditional (but deprecated in Docker) way:
pvcreate /dev/sdb1 # Create physical volume
vgcreate docker /dev/sdb1 # Create volume group and add this physical volume to it
lvcreate -L 2G -n metadata docker # Create logical volume for Docker metadata
lvcreate -L 15G -n data docker # Create logical volume for Docker data (layers, containers etc)
lvcreate -L 15G -n registry docker # Create logical volume for Docker Registry data
Mount volume for Docker registry:
mkfs.xfs /dev/docker/registry
echo "/dev/docker/registry /var/lib/docker-registry xfs defaults 1 3" >> /etc/fstab
mount -a
Check:
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 120G 0 disk
├─sda1 8:1 0 876M 0 part /boot
└─sda2 8:2 0 119,1G 0 part
├─centos-swap 253:0 0 2G 0 lvm [SWAP]
└─centos-root 253:1 0 117,2G 0 lvm /
sdb 8:16 0 40G 0 disk
└─sdb1 8:17 0 40G 0 part
├─docker-metadata 253:2 0 2G 0 lvm
│ └─docker-253:1-23762136-pool 253:5 0 15G 0 dm
├─docker-data 253:3 0 15G 0 lvm
│ └─docker-253:1-23762136-pool 253:5 0 15G 0 dm
└─docker-registry 253:4 0 15G 0 lvm /var/lib/docker-registry
2. Configure Docker daemon
Create systemd drop-in file:
mkdir -p /etc/systemd/system/docker.service.d
cat > /etc/systemd/system/docker.service.d/env.conf
[Service]
EnvironmentFile=-/etc/sysconfig/docker
ExecStart=
ExecStart=/usr/bin/dockerd $OPTIONS $DOCKER_NETWORK_OPTIONS $DOCKER_STORAGE_OPTIONS
Specify Docker configuration:
cat > /etc/sysconfig/docker
OPTIONS='--iptables=false'
DOCKER_NETWORK_OPTIONS=''
DOCKER_STORAGE_OPTIONS='--storage-driver=devicemapper --storage-opt dm.datadev=/dev/docker/data --storage-opt dm.metadatadev=/dev/docker/metadata'
Check:
systemctl daemon-reload
systemctl show docker | grep EnvironmentFile
EnvironmentFile=/etc/sysconfig/docker (ignore_errors=yes)
And run:
systemctl enable docker
systemctl restart docker
Check again:
docker info | grep data
Data file: /dev/docker/data
Metadata file: /dev/docker/metadata
Metadata Space Used: 639 kB
Metadata Space Total: 2.147 GB
Metadata Space Available: 2.147 GB
3. Obtain SSL certificate from Let’s Encrypt
It’s can be done by different ways, see Let’s Encrypt with lego and Nginx for one of these.
Assume that certificate and key was obtained and stored in /etc/pki/tls/lego/certificates
directory.
4. Run Docker registry container as systemd unit
Create systemd unit:
cat > /etc/systemd/system/docker-registry.service
[Unit]
Description=Docker registry container
Requires=docker.service
After=docker.service
[Service]
Restart=always
ExecStartPre=/usr/bin/docker create -p 5000:5000 -v /var/lib/docker-registry:/var/lib/registry -v /etc/pki/tls/lego/certificates:/certs -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/example.org.crt -e REGISTRY_HTTP_TLS_KEY=/certs/example.org.key --name registry registry:2
ExecStart=/usr/bin/docker start -a registry
ExecStop=/usr/bin/docker stop -t 5 registry
ExecStopPost=/usr/bin/docker rm registry
[Install]
WantedBy=multi-user.target
5. Permit access to Docker registry only from trusted networks
firewall-cmd --zone=trusted --add-port=5000/tcp --permanent
firewall-cmd --zone=trusted --add-source=192.168.1.0/24 --permanent
firewall-cmd --reload
Since Docker daemon was launched with --iptables=false
option, Docker registry port may be accessed from trusted networks only.
Links:
2016-10-20
xenolf/lego it’s a feature-rich Let’s Encrypt client and ACME library written in Go.
1. Prepare Nginx server
server {
listen 80 default;
server_name example.org www.example.org;
location /.well-known/acme-challenge {
proxy_pass http://127.0.0.1:81;
proxy_set_header Host $host;
}
# Other directives
}
2. Update ca-certificates for CentOS 5 (optional)
Let’s Encrypt CA certificate is not included into root CA bundle of old Linux distributions like RHEL/Centos 5. You have to replace this bundle manually with fresh one from cURL website:
cp /etc/pki/tls/certs/ca-bundle.crt /etc/pki/tls/certs/ca-bundle.crt.bak
wget -O /etc/pki/tls/certs/ca-bundle.crt http://curl.haxx.se/ca/cacert.pem
3. Order the certificate from Let’s Encrypt
lego -d example.org -d www.example.org -m cert-owner@example.org -a --path=/etc/pki/tls/lego --http=:81 run
4. Update Nginx server
server {
listen 80 default;
server_name example.org www.example.org;
location /.well-known/acme-challenge {
proxy_pass http://127.0.0.1:81;
proxy_set_header Host $host;
}
# Other directives
}
server {
listen 443 ssl;
server_name example.org www.example.org;
ssl_certificate /etc/pki/tls/lego/certificates/example.org.crt;
ssl_certificate_key /etc/pki/tls/lego/certificates/example.org.key;
location /.well-known/acme-challenge {
proxy_pass http://127.0.0.1:444;
proxy_set_header Host $host;
}
# Other directives
}
5. Renew certificate every 2 month at 01:30 of first day of the month
Add to crontab:
30 01 01 */2 * /usr/local/bin/lego -d example.org -d www.example.org -m cert-owner@example.org -a --path=/etc/pki/tls/lego --http=:81 --tls=:444 renew && /usr/sbin/nginx -s reload
Links: