вторник, 24 марта 2015 г.

Задачки по алгоритмам

Тренировка алгоритмики(задачки) -
https://projecteuler.net/
http://www.spoj.com/

суббота, 14 марта 2015 г.

Создание распределенной системы на Amazon AWS. Установка DNS слоя.

Amazon Route 53 - высокодоступный масштабируемый облачный сервис разрешения доменных имен.
Перенаправляет запросы пользователей к инфраструктуре AWS: напрямую к инстанциям EC2, или же на балансировщики нагрузки Elastic Load Balancing; или даже на внешнюю инфраструктуру не AWS.

Стратегии принятия решений разрешения доменных имен:

  1. Latency Based Routing - Route 53 пингует каждый узел распределенной системы и откуда быстрее приходит ответ, туда и отправляется запрос.
  2. Geo DNS - решение о перенаправлении принимается на основании из какого региона посетитель, нужно не забывать также указывать направление по умолчанию, чтобы не предусмотренный регион не остался без ответа. Также если какой-то сервер лежит(а Route53 пингует перед там как туда отправлять запрос), то запрос пойдет также на дефолтовый сервер.
  3. Weighted Round Robin - любимая стратегия маркетологов, потому что с ее помощью можно организовать A/B тестирование. Каждому узлу устанавливается вес и с соответсвующей распределенной вероятносью запросы пользователей распределяются по узлам. Также она применяется когда мы хотим какой-то новый релиз протестировать на продакшине, но чтобы если что-то там не так только маленький процент пользователей, испытал неудобства, для этого на узел с новым кодом ставим маленький вес.
  4. DNS Failover - есть основной узел и есть запасной, на который идут запросы, когда упал первый, обычно вторым может быть простая страничка с сообщением что, что-то не так, но мы уже фиксим.
Также могут быть комбинации этих стратегий, когда Route53 перенаправяет на другой Route53. Самый яркий пример это когда на входе стоит Route53 со стратегией DNS Failover, второй узел - вебсервер со страницей извинения, а первый это Route53 с какойнибудь Latency Based Routing, за которой находятся узлы с балансировщиками, за ними же десятки, а то и сотни серверов.

пятница, 13 марта 2015 г.

NativeScript&ReactNative

новые тренды в разработке нейтивных мобильных приложений… с помощью javascript :)

NativeScript:
https://www.nativescript.org/
http://developer.telerik.com/featured/nativescript-works/

И React Native:
http://www.railslove.com/stories/fresh-on-our-radar-react-native
http://jlongster.com/First-Impressions-using-React-Native

суббота, 7 марта 2015 г.

Docker Troubleshooting

Docker deamon logging

Чтобы поменять уровень логировния нужно для начала остановить демон и запустить с измененным уровнем логирования


# service docker stop
docker stop/waiting
# docker -d -l debug &

Но чтобы это было более удобно для сервиса(когда он подымается атоматически, а не руками):
# /etc/default/docker
DOCKER_OPTS="--log-level=fatal"

вторник, 3 марта 2015 г.

Docker networking

Виды сетей у докера(Docker Network Types)

Closed Network/ None Network - контейнеры находясь в такой сети закрыты от и для внешнего мира
Bridge Network - вид по-умолчанию, где создается мост, через который контейнеры могут общаться с внешним миром и между собой на поточном хосте. В каждом контейнере созадется свой личный сетевой интерфейс, который соединяется с мостом для общений.
Host Network - прямой доступ на сетевой интерфейс хозяйской машины, как на родной
Overlay Network - тип сети, который позволяет находиться контейнерам в одной сети, не смотря на то, что они между собой запущены на разных хостах.

Посмотреть доступные сети докера на хосте. По умолчанию будут следующие:

$ docker network ls
NETWORK ID      NAME            DRIVER          SCOPE
77bf6b8ff5cf    bridge          bridge          local
9aac4cefdaf1    host            host            local
b8aa8b4a699f    none            null            local

Closed Network/ None Network

Пример как запустить изолированный конртейнер:
$ docker run -d --net none busybox sleep 1000
Внутри у такого контейнера только один сетевой интерфейс lo, который лупбек - тоесть это только локалхост.

Bridge Network

Внутри у контейнера, который по умолчанию подключен к bridge сети, уже два сетевых интерфейса lo и eth0, которая уже локальная сеть типа Mask: 255.255.0.0
Но контейнеры с разных сетей типа мост не могут уже иметь доступа к друг другу. Можем создать еще одну сеть типа мост:
$ docker network create --driver bridge my_bridge_network
$ docker network inspect my_bridge_network
[
   {
      "Name": "my_bridge_network",
      ...
      "IPAM": {
        "Driver": "default",
        "Config": [
           {
             "Subnet": "172.18.0.0/16",
             "Gateway": "172.18.0.1"
           }
        ]
      },
      ...
   }
]
$ docker run -d --name container_3 --net my_bridge_network busybox sleep 1000
Но мы можем подключать контейнеры к нескольким сетям, так контейнер который запущен был в другой сети сможет общаться с контейнера с сети по умолчанию
$ docker network connect bridge container_3
Вот так контейнер получил, доступ к контейнерам с другой сети. Так он получил еще +один сетевой интерфейс eth1.
Ну и когда доступ больше предоставлять не стоит, то
$ docker network disconnect bridge container_3
Так сетевой интерфейс eth1 удаляется у контейнера.
  Следующя информация может быть уже устаревшей, но принцип остается следующим.
Docker всегда создает дополнительный сетевой интерфейс в системе с именем bridge0(скорее всего на момент 11.02.2017 он уже с именем docker0).
Этот интерфейс является ничем иным как мостом(bridge) или виртуальным свитчером - устройство которое перебрасывает пакеты между двумя устройствами для коммуникации между ними.
Чтобы исследовать любой сетевой мост в системе нужна следующая утилита:
# apt-get install bridge-utils
# yum install bridge-utils

Посмотрим что он нам раскажет о нашем мосте:
# brctl show docker0
bridge name       bridge id           STP enabled      interfaces
docker0           8000.56847afe9799   no
Сейчас мы не видим ни одного интерфейса подключенного к мосту - это означает, что у нас нет запущенных образов:)

Наваляем побыстрому образок:
echo "\
#Test for networking module \
FROM ubuntu:15.04 \
RUN apt-get update && apt-get install -y iputils-ping traceroute \
ENTRYPOINT /bin/bash " > Dockerfile
#
# docker build -t="net-img" .
И запустим с него два контейнера
# docker run -it --name=net1 net-img #Ctrl+P+Q
# docker run -it --name=net2 net-img #Ctrl+P+Q
#
# docker ps
CONTAINER ID       IMAGE             COMMAND       CREATED
STATUS             PORTS             NAMES
d37d347f84d8       net-img:latest    "/bin/bash"   0 minutes ago Up 0 minutes
c0e85b69ecce       net-img:latest    "/bin/bahs"   1 minutes ago Up 1 minutes
Вураля и у нас появились два дополнительных сетевых интерфейса, которые завязаны на наш докеровский мост:
# brctl show docker0
bridge name       bridge id           STP enabled      interfaces
docker0           8000.56847afe9799   no               veth095066e
                                                       vethe7516ef
# ifconfig
...
veth095066e Link encap:Ethernet HWaddr ...
...
vethe7516ef Link encap:Ethernet HWaddr ...

Virtual Ethernet  - имя интерфейсов.

Host Network

Наименее защищенная сеть, такие контейнеры называются\ открытыми. Они получают доступ на пряму к сетевым интерфесам хостовой машины.

Линкование контейнеров

https://docs.docker.com/userguide/dockerlinks/
Обычно апликация у нас находится на одном контейнере, а база данных на другом. Нужен унифицированный механизм, который бы нам давал возможность связывать новоподнятый узел горизонтального масштабирования.
Тут нам приходит на помощь линкование контейнеров, мы не выставляем порты наружу, и связь апликация с базой сверхсекьюрная - доступа снаружи нет - коммуникация возможна только между контейнерами.

$ sudo docker run -d --name db training/postgres
$ sudo docker run -d -P --name web --link db:db training/webapp python app.py
Залинкованные порты описаны в переменных окружения контейнера, откуда апликация их и может достать:
 DB_NAME=/web2/db
 DB_PORT=tcp://172.17.0.5:5432
 DB_PORT_5432_TCP=tcp://172.17.0.5:5432
 DB_PORT_5432_TCP_PROTO=tcp
 DB_PORT_5432_TCP_PORT=5432
 DB_PORT_5432_TCP_ADDR=172.17.0.5
А вообще если конкретный контейнер даже если не предоставляет никаких переменных окружения, то линкование, добавляет в /etc/hosts по имени прилинкованного контейнера его ip адрес, и мы можем использовать это имя для сетевых конектов.

Раскрытие портов из контейнера

Чтобы апликация из контейнера вышла "в свет" по сети, нужно контейнерный порт привязать на хостовый.
Для начала в Dockerfile:
EXPOSE 80
Потом при запуске контейнера нужно сделать собственно привязку на конкретный порт:
root# docker run -d -p 5000:80 --name=web1 apache-img

Чтобы увидеть что куда привязано, можем либо это посмотреть через docker ps или лучше через специальзированную команду, чтобы не распыляться на лишнюю информацию:
root# docker port web1
80/tcp -> 0.0.0.0:5000
0.0.0.0 - кстати означает, что порт 5000 подвязан на все сетевые интерфейсы хоста, которые имеют адресс IP4. Если нужно на конкретный, то нужно кроме порта указывать и конкретный ip.

Мы тоже можем раскрывать не только tcp, но и другие траспортные протоколы:
root# docker run -d -p 192.168.56.50:5001:80/udp --name=web2 apache-img

С ключем -P происходит запуск, который мапит все выставленные наружу порты контейнера на случайные порты хоста:
root# docker run -d -P --name=web-random-host-port apache-img

Network protocols

Протоколы, которые базируются на IP.

Сетевые службы пользуются предопределенными портами, описание портов и служб находится в файле:
/etc/services
Возле порта также находится указание по какому транспортному протоколу происходит соединение TCP, UDP, другие.


strace

утилита, через которую можно увидить какие системные вызовы делает и отправляет сигналы указанная команда.
Это как некий лог сишных вызовов по чтению файлов и дергания системных процедур.
Например, чтобы посмотреть действительно ли netstat пользуется файлом /etc/services мы можем выполнить:
root# strace netstat -atl 2>&1 | grep services
open("/etc/services", O_RDONLY|O_CLOEXEC) = 4
read(4, "# /etc/service:\n# $Id: services"..., 4096) = 4096
Как видим открывает и читает.

Эта утилита полезна, когда мы понимаем, что у нас какая-то ошибка в команде/утилите/апликации, но не понятно по ее логам, какая и как ее исправлять, то иногда трасировка дает нам шанс. Иногда это даже спасение в NodeJs приложениях.

Подвязать локальную бранчу на удаленную с другим именем

git branch -u remotename/remotebranchname localbranchname
или
git branch --set-upstream-to=remotename/remotebranchname localbranchname