В предыдущей статье мы рассмотрели, как можно легко создать slack-docker-proxy, используя go и пару небольших библиотек. Во второй статье мы покажем, как легко добавлять дополнительные команды, и рассмотрим, как докеризировать этот компонент, чтобы вы могли легко запустить его в демоне docker. Обратите внимание, что полные источники для различных файлов go, конечно, можно найти в репозитории slack-proxy github.
Запуск го приложения в докере
Давайте сначала посмотрим, как мы можем развернуть и запустить этот прокси. Мы увидели, что можем запустить его прямо из командной строки следующим образом:
| 1 2 3 4 | $ export GOPATH=directory/where/you/cloned/the/repo$ go get github.com/fsouza/go-dockerclient$ go build src/github.com/josdirksen/slackproxy/slack-proxy.go$ ./slackproxy -config ./resources/config.json | 
Но это не самый практичный способ сделать это. И поскольку мы уже используем это для мониторинга докера, почему бы просто не запустить этот прокси и внутри докера.
Для запуска приложения go-lang в Docker мы можем использовать два разных подхода. Мы можем скомпилировать приложение из командной строки и просто скопировать его в образ докера, или мы можем добавить источники к образу, который содержит все необходимое для работы, и скомпилировать его как шаг при создании нашего образа докера. Мы пойдем на этот второй подход.
Мы показали файл Docker, который мы будем использовать для этого здесь:
| 01 02 03 04 05 06 07 08 09 10 11 12 | FROM golang:latest COPY src/ /go/src/COPY resources/config.json /EXPOSE 9000# If external packages are needed, install them manually. Not needed ifinstalled in the GOPATHRUN go get github.com/fsouza/go-dockerclient && go install github.com/fsouza/go-dockerclientWORKDIR srcRUN go build -o /app/main github.com/josdirksen/slackproxy/slack-proxy.goCMD ["/app/main", "--config", "/config.json"] | 
Шаги должны быть довольно очевидными. Мы проверяем, находятся ли источники в том месте, которое ожидает образ докера (папка / go / src), устанавливаем все внешние зависимости и просто запускаем ‘сборку докера’. Что приводит к следующему выводу:
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | $ docker build .Sending build context to Docker daemon 203.8kBStep 1: FROM golang:latest ---> bc422006801eStep 2: COPY src/ /go/src/ ---> Using cache ---> a7c813facaf8Step 3: COPY resources/config.json / ---> Using cache ---> b6fd55de16f6Step 4: EXPOSE 9000 ---> Using cache ---> d30199bcc59aStep 5: WORKDIR /go/src ---> Using cache ---> e861b557571dStep 6: RUN go get github.com/fsouza/go-dockerclient && go install github.com/fsouza/go-dockerclient ---> Running in 6f712526bb99 ---> 76cecb4c7a19Removing intermediate container 6f712526bb99Step 7: RUN go build -o /app/main github.com/josdirksen/slackproxy/slack-proxy.go ---> Running in 77c092d1bcf2 ---> f7ca02665f94Removing intermediate container 77c092d1bcf2Step 8: CMD /app/main --config /config.json ---> Running in 0bbeb60ca608 ---> ebd9d3fe8ce7Removing intermediate container 0bbeb60ca608Successfully built ebd9d3fe8ce7 | 
Полученное изображение теперь можно запустить так:
| 1 2 | $ docker run 94abcb31af14{5cLHiZjpWaRDb0fP6ka02XCR {[{local tcp://192.168.99.100:2376 true /Users/jos/.docker/machine/machines/eris ca.pem cert.pem key.pem}]}} | 
Или загрузите в свой локальный реестр, отметив его:
| 1 | docker tag 94abcb31af14 my.own.registry/slack-proxy:latest | 
Расширение с новой функциональностью
Расширить этот прокси с новой функциональностью действительно легко. Распространенный сценарий, который у нас есть, заключается в том, что после того, как мы что-то развернули и все перестало работать, мы можем быстро проверить файлы журнала. Теперь войти в систему и использовать Docker Log не так сложно, но это займет пару шагов. Поэтому мы добавим поддержку для просмотра файлов журналов прямо из Slack. Сначала мы определим функцию в файле dockerCommandHandlers.go.
| 1 2 3 4 5 6 7 8 | func handleLogsCommand(client *docker.Client, cmd *Command, w http.ResponseWriter) {    var tail = "all"    if(len(cmd.OtherArguments) == 2) {        tail = cmd.OtherArguments[1]    }    logoptions := docker.LogsOptions{Container: cmd.OtherArguments[0], Stdout: true, Stderr: true, Follow: false, Tail: tail, OutputStream: w, ErrorStream: w}    client.Logs(logoptions)} | 
Обратите внимание, что мы еще раз не делаем никакой проверки ввода. Мы просто предполагаем, что передано правильное количество аргументов. Теперь, когда у нас есть функция, мы обновляем функцию HandleCommand в том же файле следующим образом:
| 01 02 03 04 05 06 07 08 09 10 | func (dh DockerHandler) HandleCommand(cmdToExecute *Command, w http.ResponseWriter) {    client := setupDockerClient(cmdToExecute.Environment)    fmt.Printf("%+v\n", cmdToExecute)    switchcmdToExecute.SlackCommand {    case"ps": handlePsCommand(client, w)    case"logs": handleLogsCommand(client, cmdToExecute, w)    case"imgs": handleListImagesCommand(client, w)    } | 
И мы сделали. Теперь, когда вызов сделан так:
| 01 02 03 04 05 06 07 08 09 10 11 12 13 | $ curl 'http://localhost:9000/handleSlackCommand'-H 'Content-Type: application/x-www-form-urlencoded'--data    'token=5cLHiZjpWaRDb0fP6ka02XCR&team_id=T0001&team_domain=example&channel_id=C2147483705&channel_name=test&user_id=jos,nd=docker&text=local+logs+669265a13436+10' > 2016/02/0718:48:04[WARN] agent: Check 'service:wiremock'is now warning> 2016/02/0718:48:09[WARN] agent: Check 'service:dag-storage'is now warning> 2016/02/0718:48:17[WARN] agent: Check 'service:wiremock'is now warning> 2016/02/0718:48:19[WARN] agent: Check 'service:dag-storage'is now warning> 2016/02/0718:48:29[WARN] agent: Check 'service:dag-storage'is now warning> 2016/02/0718:48:30[WARN] agent: Check 'service:wiremock'is now warning> 2016/02/0718:48:39[WARN] agent: Check 'service:dag-storage'is now warning> 2016/02/0718:48:43[WARN] agent: Check 'service:wiremock'is now warning> 2016/02/0718:48:49[WARN] agent: Check 'service:dag-storage'is now warning> 2016/02/0718:48:56[WARN] agent: Check 'service:wiremock'is now warning | 
Мы возвращаем последние 10 записей журнала для контейнера с идентификатором 669265a13436.
Или, если вы более склонны использовать Почтальон.
Расширение помимо докера
До сих пор мы рассматривали докер только через этот минимальный прокси. Экспонировать другие сервисы, компоненты и источники информации с помощью этой настройки на самом деле очень просто. В качестве примера давайте напишем пару команд, которые предоставляют информацию о хосте, на котором работает slack-прокси. Для этого мы сначала добавим новый CommandHandler:
| 1 2 3 4 5 6 7 8 9 | func handleHostCommand(w http.ResponseWriter) {    var buffer bytes.Buffer    info, _ := host.HostInfo()    buffer.WriteString(fmt.Sprintf("Boottime: %v\n", info.BootTime))    buffer.WriteString(fmt.Sprintf("Hostname: %v\n", info.Hostname))    buffer.WriteString(fmt.Sprintf("Uptime: %v\n", info.Uptime))    io.WriteString(w, buffer.String()) | 
Если вы посмотрели, как мы настроили обработчик докера, то этот не должен удивлять. Мы используем простой переключатель, чтобы соответствовать команде, которую нам нужно выполнить, и в этом случае используем библиотеку gopsutil для возврата информации о файловой системе. Обратите внимание, что если вы хотите запустить это без докера, сначала вы должны выполнить «go get github.com/shirou/gopsutil». Поскольку мы добавили дополнительный обработчик команд, нам также нужно внести небольшое изменение в функцию GetHandler из handlerFactory:
| 1 2 3 4 5 6 7 | func GetHandler(handlerName string, config *config.Configuration) CommandHandler {    switchhandlerName {    case"docker": returnNewDockerHandler(config)    case"system": returnNewSystemHandler()    default: returnNewDummyHandler()    }} | 
С этим изменением, когда команда системная, мы возвращаем только что созданный обработчик, а если команда docker, мы возвращаем тот, который может обрабатывать команды Docker. Чтобы увидеть это в действии, вы можете использовать следующую команду curl для информации о памяти:
| 1 2 3 | $ curl 'http://localhost:9000/handleSlackCommand'-H 'Content-Type: application/x-www-form-urlencoded'--data 'token=5cLHiZjpWaRDb0fP6ka02XCR&team_id=T0001&team_domain=example&channel_id=C2147483705&channel_name=test&user_id=jos,nd=system&text=local+mem' > Total: 17179869184, Free:41549824, UsedPercent:65.031576 | 
И для проверки информации о хосте используйте это:
| 1 2 3 | $ curl 'http://localhost:9000/handleSlackCommand'-H 'Content-Type: application/x-www-form-urlencoded'--data 'token=5cLHiZjpWaRDb0fP6ka02XCR&team_id=T0001&team_domain=example&channel_id=C2147483705&channel_name=test&user_id=jos,nd=system&text=local+host' > Boottime: 1453982905Hostname: Joss-MacBook-Pro.localUptime: 889269% | 
И с этим мы в конце этой статьи на slack / docker (и других источниках) с go-lang. Вы можете найти полные источники для этой статьи здесь . И если у вас есть предложения, пожалуйста, дайте мне знать.
| Ссылка: | Создайте прокси Slack Docker в Go — часть 2 от нашего партнера JCG Йоса Дирксена из блога Smart Java . | 
