логирование docker в ECS


Это первая статья из цикла “инфраструктура Jenkins в ECS”. Для тех, кто не знаком с ECS, предлагаю начать с прочтения этого ресурса. В двух словах, ECS — это Docker as a Service от Amazon.

Все дальнейшие действия будут происходить на Debian 8, но и для Ubuntu описанные инструкции тоже должны сработать. Docker используется версии 1.12.5.

После того, как вы установили Docker, вы захотите читать логи своих контейнеров в удобном формате. Для этого нужно настроить опции логирования при запуске контейнеров, а также настроить rsyslog на запись логов в отдельное место, ну и еще сказать ECS агенту, чтоб он поддержал нужный драйвер логирования, иначе таски не запустятся в кластере.

Настроим rsyslog. Для этого необходимо создать следующий файл конфигурации /etc/rsyslog.d/22-docker.conf:

$template DockerLogs, "/var/log/docker/%syslogtag:R,ERE,1,ZERO:.*docker/([^\[]+)--end%.log"
if $syslogtag contains 'docker/' then \
    ?DockerLogs
& stop

После создания файла необходимо перезапустить rsyslog

service rsyslog restart

При запуске контейнеров необходимо указать, что мы хотим писать логи через syslog, т.к. по умолчанию ипользуется json, и проставить нужные тэги. Вот пример запуска контейнера:

docker run --name ecs-slave --log-driver syslog \
    --log-opt "tag=docker/ecs-slave" \
    --log-opt "labels=jenkins,ecs-slave" \
    jenkinsci/jnlp-slave -url http://<jenkins-server>:<port>

Логи контейнера вы сможете обнаружить в /var/log/docker/ecs-slave.log и соответственно настроить их централизованный сбор/доставку любимым способом. Я использую filebeat + ELK.

Вот пример конфигурации ECS task definition.

[
  {
    "name" : "jenkins-master",
    "image" : "jenkins:2.32.1-alpine",
    "cpu" : 1024,
    "memory" : 2048,
    "essential" : true,
    "environment" : [
        {
            "name": "JAVA_OPTS",
            "value" : "-Xmx2048m"
        }
    ],
    "portMappings": [
        {
            "containerPort": 8080,
            "hostPort": 8080
        },
        {
            "containerPort": 50000,
            "hostPort": 50000
        }
    ],
    "mountPoints" : [
      {
        "sourceVolume" : "jenkins_home",
        "containerPath" : "/var/jenkins_home",
        "readonly" : false
      }
    ],
    "logConfiguration": {
        "logDriver": "syslog",
        "options": {
            "tag": "docker/jenkins-master",
            "labels": "jenkins,jenkins-master"
        }
    }
  }
]

После того, как логи контейнера успешно записываются, нужно сконфигурировать ECS агент.

Вот пример запуска агента:

docker run --name ecs-agent amazon/amazon-ecs-agent:latest \
    --restart=on-failure:10 \
    --volume=/var/run/docker.sock:/var/run/docker.sock \
    --volume=/sys/fs/cgroup:/sys/fs/cgroup:ro \
    --volume=/var/run/docker/execdriver/native:/var/lib/docker/execdriver/native:ro \
    --publish=127.0.0.1:51678:51678 \
    --env-file=/etc/ecs/ecs.config \
    --env=ECS_AVAILABLE_LOGGING_DRIVERS=["json-file","syslog","awslogs"]

После этого вы сможете запускать ECS таски с драйвером логирования syslog и собирать логи любым удобным способом.

Да, не забудьте про ротирование этих логов, а то место на диске может внезапно закончиться. Вот вам пример конфигурации logrotate /etc/logrotate.d/docker

/var/log/docker/*.log {
    daily
    compress
    delaycompress
    missingok
    notifempty
    rotate 7
    copytruncate
}