Докер: перейдите на частный репозиторий GitHub

Я пытаюсь запустить контейнер, который будет предоставлять службу golang из пакета, который у меня есть в частном репозитории GitHub.

Поскольку я работаю с GCE, мой начальный образ - google / debian: wheezy.

После установки всех необходимых зависимостей и инструментов я запускаю

RUN go get github.com/<my_org>/<my_package>

где пакет является частным репо.

Я добавил свои SSH-ключи GitHub, чтобы разрешить клонирование из частного репо в файл докера:

ADD priv/id_rsa /root/.ssh/id_rsa
ADD priv/id_rsa.pub /root/.ssh/id_rsa.pub

Тем не менее, я получаю сообщение об ошибке во время процесса получения, когда go пытался клонировать репо:

# cd .; git clone https://github.com/<my_org>/<my_package> /gopath/src/github.com/<my_org>/<my_package>
Cloning into '/gopath/src/github.com/<my_org>/<my_package>'...
fatal: could not read Username for 'https://github.com': No such device or address
package github.com/<my_org>/<my_package>: exit status 128

Чтобы отладить проблему, из Dockerfile я запускаю:

RUN ssh-keyscan -t rsa github.com 2>&1 >> /root/.ssh/known_hosts

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

OpenSSH_6.0p1 Debian-4+deb7u2, OpenSSL 1.0.1e 11 Feb 2013
Pseudo-terminal will not be allocated because stdin is not a terminal.
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 19: Applying options for *
debug1: Connecting to github.com [192.30.252.129] port 22.
debug1: Connection established.
debug1: permanently_set_uid: 0/0
debug1: identity file /root/.ssh/id_rsa type 1
debug1: Checking blacklist file /usr/share/ssh/blacklist.RSA-2048
debug1: Checking blacklist file /etc/ssh/blacklist.RSA-2048
debug1: identity file /root/.ssh/id_rsa-cert type -1
debug1: identity file /root/.ssh/id_dsa type -1
debug1: identity file /root/.ssh/id_dsa-cert type -1
debug1: identity file /root/.ssh/id_ecdsa type -1
debug1: identity file /root/.ssh/id_ecdsa-cert type -1
debug1: Remote protocol version 2.0, remote software version libssh-0.6.0
debug1: no match: libssh-0.6.0
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_6.0p1 Debian-4+deb7u2
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-sha1 none
debug1: kex: client->server aes128-ctr hmac-sha1 none
debug1: sending SSH2_MSG_KEX_ECDH_INIT
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: Server host key: RSA 16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48
debug1: Host 'github.com' is known and matches the RSA host key.
debug1: Found key in /root/.ssh/known_hosts:1
Warning: Permanently added the RSA host key for IP address '192.30.252.129' to the list of known hosts.
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: Roaming not allowed by server
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /root/.ssh/id_rsa
debug1: Server accepts key: pkalg ssh-rsa blen 279
debug1: key_parse_private_pem: PEM_read_PrivateKey failed
debug1: read PEM private key done: type <unknown>
debug1: read_passphrase: can't open /dev/tty: No such device or address
debug1: Trying private key: /root/.ssh/id_dsa
debug1: Trying private key: /root/.ssh/id_ecdsa
debug1: No more authentication methods to try.
Permission denied (publickey).

Я пробовал chmod 600 и chmod 700 на приватных / открытых ключах, это не помогло.

Какие-нибудь подсказки? Кому-нибудь удалось запустить go get, который загружается из частных репозиториев на debian из докера?


person orcaman    schedule 02.10.2014    source источник
comment
Вы выполняете свои go get команды как root? Вы должны использовать go get со своей учетной записью и хранить свой ключ в /home/yourAccount.   -  person VonC    schedule 02.10.2014
comment
Поможет ли проверка разрешений и общих предпочтений, как в stackoverflow.com/a/19798820/6309?   -  person VonC    schedule 03.10.2014


Ответы (4)


Я понял это после небольшого взлома. Не идеальное решение, поскольку оно включает в себя установку SSH и встраивание закрытого ключа в контейнер. Этот пример основан на официальном образе Docker golang (Debian Wheezy):

Основное отличие от вашего примера заключается в том, что вам нужна команда git config для принудительного использования ssh вместо https по умолчанию.

FROM golang

RUN apt-get update && apt-get install -y ca-certificates git-core ssh

ADD keys/my_key_rsa /root/.ssh/id_rsa
RUN chmod 700 /root/.ssh/id_rsa
RUN echo "Host github.com\n\tStrictHostKeyChecking no\n" >> /root/.ssh/config
RUN git config --global url.ssh://[email protected]/.insteadOf https://github.com/

ADD . /go/src/github.com/myaccount/myprivaterepo

RUN go get github.com/myaccount/myprivaterepo
RUN go install github.com/myaccount/myprivaterepo
person Tom Jowitt    schedule 09.12.2014
comment
Проблема, с которой я столкнулся с этим решением, заключается в том, что оно требует, чтобы мой закрытый ключ ssh был скопирован в каталог, в котором находится мой исходный код. Есть ли способ этого избежать? - person nojo; 03.05.2015
comment
Согласитесь с nojo, закрытый ключ не должен попадать внутрь контейнера, в конце концов, он приватный - person Ualter Jr.; 24.11.2020

go get пытается использовать https, полностью игнорируя ssh.

Вам нужно будет настроить ~/.netrc:

ADD priv/.netrc /root/.netrc

Где netrc выглядит так:

machine github.com login github-username password github-password

ссылка:

person OneOfOne    schedule 02.10.2014
comment
Спасибо за помощь. Дело в том, что на моей машине (Mac) go get отлично работает с частным репо (аутентификация проходит гладко). проблема возникает только в образе докера Debian, над которым я работаю. Кроме того, обратите внимание, что ошибки наблюдаются еще до того, как произойдет их устранение (вывод ssh-keyscan показывает, что есть ошибки, как я опубликовал). - person orcaman; 02.10.2014
comment
@orcaman read PEM private key done: type <unknown> может быть поврежденным закрытым ключом. - person OneOfOne; 02.10.2014
comment
go get пытается использовать https, полностью игнорируя ssh. На самом деле это можно исправить с помощью RUN git config --global url."[email protected]:".insteadOf "https://github.com" - person Eksapsy; 17.05.2021

Разрабатывая ответ OneOfOne ~/.netrc, вот что я делаю с Дженкинсом в Linux:

FROM golang:1.6

ARG GITHUB_USER=$GITHUB_USER
ARG GITHUB_PASS=$GITHUB_PASS

# Copy local package files to the container's workspace.
ADD . /go/src/github.com/my-org/my-project
WORKDIR /go/src/github.com/my-org/my-project/

# Build application inside the container.
RUN echo "machine github.com\n\tlogin $GITHUB_USER\n\tpassword $GITHUB_PASS" >> ~/.netrc && \
    go get github.com/tools/godep && \
    go get github.com/onsi/ginkgo/ginkgo && \
    godep restore && \
    ginkgo -r --randomizeAllSpecs --randomizeSuites --failOnPending && \
    godep go install && \
    rm -f ~/.netrc

ENTRYPOINT /go/bin/my-project

EXPOSE 8080

Команда сборки докера:

docker build \
    --build-arg GITHUB_USER=xxxxx \
    --build-arg GITHUB_PASS=yyyyy \
    -t my-project .

Две директивы ARG сопоставляют --build-args, поэтому docker может использовать их внутри Dockerfile.

Первая и последняя строки RUN создают и удаляют ~/.netrc.

В Jenkins я использую те же кредиты из git pull в команде сборки.

В этой стратегии пароль не отображается эхом во время процесса сборки докера и не сохраняется на каком-либо уровне вашего образа докера. Также обратите внимание, что результаты теста gingko выводятся на консоль во время сборки.

person Steve Tarver    schedule 20.08.2016
comment
Проблемы с этой стратегией: 1. История записывает ваше имя пользователя и пароль в виде обычного текста. Таким образом, любой, у кого есть доступ к вашему компьютеру, может просто запустить историю и посмотреть ваши учетные данные, случайно или нет. 2. Вы не можете использовать эту стратегию в docker-compose. Если вы это сделаете, вы предоставите свои учетные данные в файле теперь в виде обычного текста и, что еще хуже, с риском случайного принятия изменения в файле. Это действительно бесполезно, если вы хотите сочинять докеры. - person Eksapsy; 17.05.2021
comment
@Eksapsy - достойная забота о безопасности - каждый пользователь должен приспособиться к своей толерантности к риску. Docker & GitHub значительно продвинулся за 5 лет и предоставляет несколько безопасных альтернатив, но мы не знаем достаточно в этих вопросах, чтобы предложить - только для того, чтобы начать. - person Steve Tarver; 18.05.2021
comment
Вопрос вообще напрягает. Кажется, не существует хорошего универсального решения для всех, и это разочаровывает. Docker определенно должен немного продвинуться в этом вопросе и предоставить нам хорошее решение. В любом случае, хорошая работа по поиску решения, и это может сработать для некоторых из нас. Лично я считаю это слишком рискованным и безопасным, на мой вкус, особенно с docker-compose, который большинство из нас использует в настоящее время. - person Eksapsy; 20.05.2021

В последней версии golang (v1.11) теперь есть модули.

Процитируем источник:

Модуль - это набор связанных пакетов Go, которые управляются версиями вместе как единое целое. Чаще всего один репозиторий контроля версий соответствует в точности одному модулю.

Использование последней версии golang позволит вам иметь зависимости в частных репозиториях. По сути, запуск команды $ go mod vendor создаст каталог vendor локально для всех внешних зависимостей. Теперь, убедившись, что ваш образ докера имеет Golang v1.11, вы обновите свой Dockerfile следующим образом:

WORKDIR /<your repostiory>

COPY . ./
person danielsmith1789    schedule 26.11.2018