diff --git a/docker_registry.go b/docker_registry.go index 74403488..5f272d48 100644 --- a/docker_registry.go +++ b/docker_registry.go @@ -1,60 +1,26 @@ package main import ( + "crypto/tls" + "net" + "net/http" + "strings" + "time" + "github.com/docker/distribution/reference" registryclient "github.com/flant/docker-registry-client/registry" "github.com/romana/rlog" - "net/http" - "strings" ) -// TODO данные для доступа к registry серверам нужно хранить в secret-ах. -// TODO по imageInfo.Registry брать данные и подключаться к нужному registry. -// Пока известно, что будет только registry.gitlab.company.com - -var DockerRegistryInfo = map[string]map[string]string{ - "registry.gitlab.company.com": map[string]string{ - "url": "https://registry.gitlab.company.com", - "user": "oauth2", - "password": "qweqwe", - }, - // minikube specific - "localhost:5000": map[string]string{ - "url": "http://kube-registry.kube-system.svc.cluster.local:5000", - }, -} - -//const DockerRegistryUrl = "https://registry.gitlab.company.com" -//const DockerRegistryUser = "oauth2" -//const DockerRegistryToken = "" - type DockerImageInfo struct { Registry string Repository string Tag string } -func DockerRegistryGetImageId(image string) (string, error) { - imageInfo, err := DockerParseImageName(image) - if err != nil { - rlog.Errorf("REGISTRY Problem parsing image %s: %v", image, err) - return "", err - } - - url := "" - user := "" - password := "" - if info, has_info := DockerRegistryInfo[imageInfo.Registry]; has_info { - url = info["url"] - user = info["user"] - password = info["password"] - } - - // Установить соединение с registry - registry := NewDockerRegistry(url, user, password) - +func DockerRegistryGetImageId(imageInfo DockerImageInfo, dockerRegistry *registryclient.Registry) (string, error) { // Получить описание образа - antiopaManifest, err := registry.ManifestV2(imageInfo.Repository, imageInfo.Tag) + antiopaManifest, err := dockerRegistry.ManifestV2(imageInfo.Repository, imageInfo.Tag) if err != nil { rlog.Errorf("REGISTRY cannot get manifest for %s:%s: %v", imageInfo.Repository, imageInfo.Tag, err) return "", err @@ -101,13 +67,28 @@ func RegistryClientLogCallback(format string, args ...interface{}) { // Этот конструктор не запускает registry.Ping и логирует события через rlog. func NewDockerRegistry(registryUrl, username, password string) *registryclient.Registry { url := strings.TrimSuffix(registryUrl, "/") - transport := http.DefaultTransport - transport = registryclient.WrapTransport(transport, url, username, password) + + transport := &http.Transport{ + Proxy: http.ProxyFromEnvironment, + DialContext: (&net.Dialer{ + Timeout: 30 * time.Second, + KeepAlive: 30 * time.Second, + DualStack: true, + }).DialContext, + MaxIdleConns: 1, + MaxIdleConnsPerHost: 1, + IdleConnTimeout: 90 * time.Second, + TLSHandshakeTimeout: 10 * time.Second, + ExpectContinueTimeout: 1 * time.Second, + TLSNextProto: make(map[string]func(string, *tls.Conn) http.RoundTripper), + } + + wrappedTransport := registryclient.WrapTransport(transport, url, username, password) return ®istryclient.Registry{ URL: url, Client: &http.Client{ - Transport: transport, + Transport: wrappedTransport, }, Logf: RegistryClientLogCallback, } diff --git a/main.go b/main.go index 4bd43109..4905b0fa 100644 --- a/main.go +++ b/main.go @@ -117,7 +117,12 @@ func Init() { } InitKubeNodeManager() - InitRegistryManager() + + err = InitRegistryManager() + if err != nil { + rlog.Errorf("Cannot initialize registry manager: %s", err) + os.Exit(1) + } } func Run() { diff --git a/registry_manager.go b/registry_manager.go index 0a57e12c..4dd1d9f3 100644 --- a/registry_manager.go +++ b/registry_manager.go @@ -1,9 +1,11 @@ package main import ( + "fmt" "os" "time" + registryclient "github.com/flant/docker-registry-client/registry" "github.com/romana/rlog" ) @@ -13,18 +15,62 @@ var ( ImageUpdated chan string AntiopaImageId string AntiopaImageName string + AntiopaImageInfo DockerImageInfo PodName string + + DockerRegistry *registryclient.Registry ) +// TODO данные для доступа к registry серверам нужно хранить в secret-ах. +// TODO по imageInfo.Registry брать данные и подключаться к нужному registry. +// Пока известно, что будет только registry.gitlab.company.com +var DockerRegistryInfo = map[string]map[string]string{ + "registry.gitlab.company.com": map[string]string{ + "url": "https://registry.gitlab.company.com", + "user": "oauth2", + "password": "qweqwe", + }, + // minikube specific + "localhost:5000": map[string]string{ + "url": "http://kube-registry.kube-system.svc.cluster.local:5000", + }, +} + // InitRegistryManager получает имя образа по имени пода и запрашивает id этого образа. -func InitRegistryManager() { +func InitRegistryManager() error { + rlog.Debug("Init registry manager") + // TODO Пока для доступа к registry.gitlab.company.com передаётся временный токен через переменную среды GitlabToken := os.Getenv("GITLAB_TOKEN") DockerRegistryInfo["registry.gitlab.company.com"]["password"] = GitlabToken ImageUpdated = make(chan string) AntiopaImageName = KubeGetPodImageName(Hostname) - AntiopaImageId, _ = DockerRegistryGetImageId(AntiopaImageName) + + var err error + AntiopaImageInfo, err = DockerParseImageName(AntiopaImageName) + if err != nil { + return fmt.Errorf("problem parsing image %s: %v", AntiopaImageName, err) + } + + url := "" + user := "" + password := "" + if info, hasInfo := DockerRegistryInfo[AntiopaImageInfo.Registry]; hasInfo { + url = info["url"] + user = info["user"] + password = info["password"] + } + // Создать клиента для подключения к docker-registry + // в единственном экземляре + DockerRegistry = NewDockerRegistry(url, user, password) + + AntiopaImageId, err = DockerRegistryGetImageId(AntiopaImageInfo, DockerRegistry) + if err != nil { + return err + } + + return nil } // RunRegistryManager каждые 10 секунд проверяет @@ -38,7 +84,8 @@ func RunRegistryManager() { select { case <-ticker.C: rlog.Debugf("Checking registry for updates") - imageID, err := DockerRegistryGetImageId(AntiopaImageName) + + imageID, err := DockerRegistryGetImageId(AntiopaImageInfo, DockerRegistry) if err != nil { rlog.Errorf("REGISTRY Cannot check image id: %v", err) } else {