В предыдущей статье мы рассмотрели, как можно легко создать 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 if installed in the GOPATH RUN go get github.com/fsouza/go-dockerclient && go install github.com/fsouza/go-dockerclient WORKDIR src RUN go build -o /app/main github.com/josdirksen/slackproxy/slack-proxy.go CMD [ "/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.8 kB Step 1 : FROM golang:latest ---> bc422006801e Step 2 : COPY src/ /go/src/ ---> Using cache ---> a7c813facaf8 Step 3 : COPY resources/config.json / ---> Using cache ---> b6fd55de16f6 Step 4 : EXPOSE 9000 ---> Using cache ---> d30199bcc59a Step 5 : WORKDIR /go/src ---> Using cache ---> e861b557571d Step 6 : RUN go get github.com/fsouza/go-dockerclient && go install github.com/fsouza/go-dockerclient ---> Running in 6f712526bb99 ---> 76cecb4c7a19 Removing intermediate container 6f712526bb99 Step 7 : RUN go build -o /app/main github.com/josdirksen/slackproxy/slack-proxy.go ---> Running in 77c092d1bcf2 ---> f7ca02665f94 Removing intermediate container 77c092d1bcf2 Step 8 : CMD /app/main --config /config.json ---> Running in 0bbeb60ca608 ---> ebd9d3fe8ce7 Removing intermediate container 0bbeb60ca608 Successfully 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) switch cmdToExecute.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 / 07 18 : 48 : 04 [WARN] agent: Check 'service:wiremock' is now warning > 2016 / 02 / 07 18 : 48 : 09 [WARN] agent: Check 'service:dag-storage' is now warning > 2016 / 02 / 07 18 : 48 : 17 [WARN] agent: Check 'service:wiremock' is now warning > 2016 / 02 / 07 18 : 48 : 19 [WARN] agent: Check 'service:dag-storage' is now warning > 2016 / 02 / 07 18 : 48 : 29 [WARN] agent: Check 'service:dag-storage' is now warning > 2016 / 02 / 07 18 : 48 : 30 [WARN] agent: Check 'service:wiremock' is now warning > 2016 / 02 / 07 18 : 48 : 39 [WARN] agent: Check 'service:dag-storage' is now warning > 2016 / 02 / 07 18 : 48 : 43 [WARN] agent: Check 'service:wiremock' is now warning > 2016 / 02 / 07 18 : 48 : 49 [WARN] agent: Check 'service:dag-storage' is now warning > 2016 / 02 / 07 18 : 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 { switch handlerName { case "docker" : return NewDockerHandler(config) case "system" : return NewSystemHandler() default : return NewDummyHandler() } } |
С этим изменением, когда команда системная, мы возвращаем только что созданный обработчик, а если команда 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 . |