Запуск Insecure Docker Registry для хранения своих docker-образов не самый лучший вариант с точки зрения безопасности, но порой это самое простое и разумное решение. Давайте разберемся!
При использовании приватного реестра образов нужно хотя бы попытаться защитить его SSL-сертификатами, но в реальных условиях мало кто это делает, пытаясь как можно быстрее и проще запустить свой Docker Registry.
Для работы с приватным реестром образов (считаем, что он уже запущен и работает на хосте myregistry.example.com и 80-м порту) необходимо добавить дополнительный параметр insecure-registry
на все хосты, где работает docker (Docker daemon).
В операционной системе Ubuntu 14.x это можно сделать, изменив параметр DOCKER_OPTS
в конфигурационном файле /etc/default/docker
, например так:
DOCKER_OPTS="--insecure-registry myregistry.example.com -H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock"
И перезапустить docker командой:
sudo service docker restart
В операционных системах Ubuntu 16.x и CentOS настройка несколько отличается — нужно изменить (или создать, если такового нет) конфигурационный файл /etc/docker/daemon.json
, добавив в него следующие строки:
{
"insecure-registries" : ["myregistry.example.com"]
}
После чего выполнить перезапуск сервиса с помощью:
sudo systemctl restart docker
В docker для Windows / Mac добавить Insecure Docker Registry можно в настройках приложения (вкладка daemon).
На этом все, теперь можно загружать / скачивать docker-образы из приватного реестра.
Provide feedback
Saved searches
Use saved searches to filter your results more quickly
Sign up
Appearance settings
-
Understanding Insecure Registries in Docker
-
Configuring Docker to Use Insecure Registries
-
Best Practices for Using Insecure Registries
-
Conclusion
-
FAQ
In the world of containerization, Docker has emerged as a powerful tool for developers. However, when it comes to using private registries, you might encounter issues with secure connections. By default, Docker requires HTTPS for all registry communications. But sometimes, using an insecure registry over HTTP is necessary, especially in development environments.
In this article, we will guide you through the process of adding insecure registry entries to Docker. This will allow you to connect over unencrypted HTTP connections seamlessly. We’ll cover the steps involved, the necessary configurations, and some best practices to keep your Docker environment running smoothly.
Understanding Insecure Registries in Docker
Before we dive into the practical steps, it’s essential to understand what an insecure registry is. An insecure registry is a Docker registry that communicates over HTTP instead of HTTPS. This setup can be useful in controlled environments where security risks are minimal, such as local development or testing scenarios. However, it’s crucial to note that using an insecure registry can expose your Docker images and data to potential threats. Therefore, it is recommended only for development purposes and not for production environments.
Configuring Docker to Use Insecure Registries
Adding an insecure registry entry to Docker is a straightforward process. You will need to modify the Docker daemon configuration file, typically located at /etc/docker/daemon.json
. Here’s how you can do it:
- Open the terminal on your machine.
- Use your preferred text editor to open the Docker configuration file. If the file does not exist, you can create it.
Here’s the command to open the file using nano
:
sudo nano /etc/docker/daemon.json
If the file is empty or does not exist, you can add the following JSON structure to include your insecure registry:
{
"insecure-registries": ["your-insecure-registry:port"]
}
Replace your-insecure-registry:port
with the actual address and port of your registry.
Once you have made the necessary changes, save the file and exit the editor. To apply the changes, restart the Docker service using the following command:
sudo systemctl restart docker
After restarting Docker, you can verify that your insecure registry has been added successfully by running:
docker info | grep "Insecure Registries"
Output:
Insecure Registries: your-insecure-registry:port
This command will display your newly added insecure registry, confirming that Docker is now configured to connect to it.
Best Practices for Using Insecure Registries
While adding an insecure registry can solve immediate connectivity issues, it’s vital to follow some best practices to mitigate potential risks. Here are a few recommendations:
- Limit Access: Ensure that only trusted users and systems can access your insecure registry. Implement network-level security measures to restrict access.
- Use in Development Only: Insecure registries should be used solely in development and testing environments. Avoid using them in production, where sensitive data is handled.
- Monitor Traffic: Keep an eye on the traffic to and from your insecure registry. This can help you identify any unusual activity that may indicate security threats.
- Transition to Secure Registries: Whenever possible, plan to transition to secure registries. Use HTTPS to encrypt communications and protect your data.
By following these best practices, you can minimize risks while taking advantage of the flexibility that insecure registries offer.
Conclusion
Adding an insecure registry entry in Docker is a simple yet effective way to facilitate communication with private registries that do not support HTTPS. While this approach is beneficial for development environments, it’s crucial to be aware of the potential security risks involved. By following the steps outlined in this article and adhering to best practices, you can ensure a smoother Docker experience while keeping your environment secure. Always remember to transition to secure registries for production use to safeguard your applications and data.
FAQ
-
What is an insecure registry in Docker?
An insecure registry is a Docker registry that communicates over HTTP instead of HTTPS, typically used in development environments. -
Is it safe to use an insecure registry?
Using an insecure registry can expose your data to security risks. It is recommended only for development purposes and not for production environments. -
How do I verify if my insecure registry is configured correctly?
You can verify your configuration by running the commanddocker info | grep "Insecure Registries"
in your terminal. -
Can I use multiple insecure registries in Docker?
Yes, you can specify multiple insecure registries by adding them as a comma-separated list in thedaemon.json
file. -
What should I do if my Docker service fails to restart after adding an insecure registry?
Check the syntax of yourdaemon.json
file for errors. Use a JSON validator to ensure the structure is correct before restarting the Docker service.
Enjoying our tutorials? Subscribe to DelftStack on YouTube to support us in creating more high-quality video guides. Subscribe
Одно из решений ошибки:
Error response from daemon: invalid registry endpoint https://superhost.ru:5000/v0/: unable to ping registry endpoint https://superhost.ru:5000/v0/
v2 ping attempt failed with error: Get https://superhost.ru:5000/v2/: tls: oversized record received with length 20527
v1 ping attempt failed with error: Get https://superhost.ru:5000/v1/_ping: tls: oversized record received with length 20527. If this private registry supports only HTTP or HTTPS with an unknown CA certificate, please add --insecure-registry superhost.ru:5000
to the daemon’s arguments. In the case of HTTPS, if you have access to the registry’s CA certificate, no need for the flag; simply place the CA certificate at /etc/docker/certs.d/superhost.ru:5000/ca.crt
Такая ошибка возникает при обращении к Docker Registry, где не настроено должным образом защищенное соединение. Если Docker Registry расположен в интернете, то необходимо добавить на сервер валидный сертификат, например, Let’s Encrypt.
Если реджестри расположен в локальной сети и доступен только из нее, то можно отключить проверку сертификата на стороне клиента.
При использовании Docker Toolbox на Windows или MacOS, добавляем наш Registry в спосок исключений:
- Подключяемся к виртуальной машине по ssh. Например, вот так: docker-machine ssh default
- редактируем файл profile с root правами: sudo vi /var/lib/boot2docker/profile
- добавляем параметр запуска –insecure-registry с нашим хостом registry:
EXTRA_ARGS=‘
—label provider=virtualbox —insecure-registry myregistry:5000
‘
- перезапускаем Docker:
sudo /etc/init.d/docker restart
ВНИМАНИЕ! Данный метод можно использовать ТОЛЬКО если ваш Docker Registry и Docker Client находятся в локальной сети, и ваша сеть защищена. Иначе, с большой долей вероятности, ваш Docker взломают.
В других случаях:
Для начала, найдите файл с параметрами запуска Docker Daemon Process. Он, скорее всего, расположен по пути /etc/default/docker file или /etc/sysconfig/docker.
Если в нем уже есть параметр DOCKER_OPTS или other_args, то добавляем туда строку –insecure-registry superhost.ru:5000. Должно получиться примерно такое:
other_args=«—insecure-registry superhost.ru:5000» DOCKER_OPTS=«—insecure-registry superhost.ru:5000» |
Если у вас CentOS 7, то можно попробовать добавить в файл /etc/docker/daemon.json следующую строчку:
{«insecure-registries»:[«myregistry.example.com:5000»]} |
There are 52 Dockerfiles in the source code for my book, Docker on Windows. Perfect for a year-long blog series.
Each week I’ll look at one Dockerfile in detail, showing you what it does and how it works. This is #20 in the series, where I’ll look at running your own registry server in a Docker container on Windows.
Docker Registry
The registry is the “ship” part of the build, ship, run workflow. You package your app in a Docker image using a Dockerfile and docker image build
, and the output is an image on your machine (or the CI server that ran the build).
To make the image available to other users, you ship it to a registry with docker image push
. The default registry is Docker Hub, which is a free public registry service. If you want to keep your images private, so they’re only accessible within your own network, you can use a commercial registry like Docker Trusted Registry — which also provides security scanning and image signing.
You can also run your own basic registry server in a container. You won’t get a UI or any of the advanced security features, but you do get a registry server on your fast local network. It’s fine for storing your own images, or storing a local copy of images from Docker Hub.
The registry API is an open standard, so you use your own registry server or a third-party registry in exactly the same way you use Docker Hub.
Docker Registry is an open-source reference implementation of the registry server. It’s written in Go and it works cross-platform. There’s an official Linux image you can use on Docker Hub, but if you want to run on Windows you need to build your own image.
ch04-registry
This week’s Dockerfile does just that, building the registry server from source and then packaging it using a multi-stage build.
I’ve updated this Dockerfile since the book was released, to package version 2.6.2 of the registry, which has a security fix.
The builder stage uses the official golang image for the toolchain, which has a Windows Server Core variant. It starts by capturing a version number and creating a working directory for the source:
FROM golang:1.10.0-windowsservercore-ltsc2016 AS builder
ARG REGISTRY_VERSION=v2.6.2
WORKDIR C:\gopath\src\github.com\docker
The rest of the builder stage is really simple. It clones the GitHub repo where the registry source code lives (the golang
image has git
installed), checks out the specified version and builds the app:
RUN git clone https://github.com/docker/distribution.git; `
cd distribution; `
git checkout $env:REGISTRY_VERSION; `
go build -o C:\out\registry.exe .\cmd\registry
The GitHub repo is called
docker/distribution
, but the app is calledregistry
.
The builder is a Windows image, so Go will compile a Windows binary. When that stage completes, there’s a registry.exe
in the output directory. The next stage packages that up on top of Nano Server.
I can use Nano Server because the registry is a Go app that doesn’t need the full Windows Server Core runtime. See How to Dockerize Windows Applications: The 5 Steps if you want to understand that decision.
The app stage starts with the 2016 semi-annual channel (SAC) release of Nano Server and sets up some environment variables:
FROM microsoft/nanoserver:sac2016
ENV DATA_PATH="C:\data" `
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY="G:\\"
DATA_PATH
is used in the container setup to capture a path for a Docker volume, which is C:\data
REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY
is used by the registry app to specify where it should store data — this is the location for all the image layers and the metadata, which is set to G:\
Then it has this crazy line to set a value in the Windows Registry:
RUN Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\DOS Devices' -Name 'G:' -Value "\??\$($env:DATA_PATH)" -Type String
That’s how you create a mapped drive in PowerShell. It’s creating a G:
drive and pointing it to C:\data
. Apps can refer to paths starting G:
and Windows will actually use C:\data
, which is the path for a Docker volume. So when the registry server writes to the G:
drive, Windows actually writes to the Docker volume, which could be an external storage location.
This is a workaround for an issue where apps get confused trying to resolve paths which are Docker volumes. See Docker Volumes on Windows — Introducing the G Drive if you want to learn more.
Next the Dockerfile sets up the integration between the container and the host:
VOLUME ${DATA_PATH}
EXPOSE 5000
WORKDIR C:\registry
CMD ["registry", "serve", "config.yml"]
This creates a volume for storage at the expected data path, exposes port 5000 (which is the default registry API port), and configures the container to start by running registry.exe
in serve
mode, using the a local config file.
The last part is to copy in the compiled binary and the default configuration file from the builder stage:
COPY --from=builder C:\out\registry.exe .
COPY --from=builder C:\gopath\src\github.com\docker\distribution\cmd\registry\config-example.yml .\config.yml
Usage
It’s the usual thing to get the image. You can either download my public image from Docker Hub:
docker image pull dockeronwindows/ch04-registry
Or you can clone the source for the book’s code samples and build your own version:
git clone https://github.com/sixeyed/docker-on-windows.git
cd docker-on-windows/ch04/ch04-registry
docker image build -t dockeronwindows/ch04-registry .
Either way you’ll get a image which you can use to run the Docker registry in a Windows container:
docker container run -d -p 5000:5000 dockeronwindows/ch04-registry
But for a long-lived registry server, you’ll want to map the volume to a specific place on the host, which makes it easier to upgrade the registry container in future. This example stores all the registry data in the C:\registry-data
folder on the host:
mkdir C:\registry-data
docker container run -d -p 5000:5000 `
-v C:\registry-data:C:\data `
dockeronwindows/ch04-registry
That’s only the first part of running your own registry though The registry runs a REST API which Docker connects with, and by default Docker wants a secure connection. Your registry container is using HTTP, not HTTPS.
You can configure the open-source registry to use HTTPS, but it takes a little more work. The Windows Registry lab on GitHub shows you how to do it.
If you’re running in a private network, or if you’re cavalier about security, you can configure Docker to connect to the registry over HTTP . The setting you need is allow-insecure-registries, and the easiest way to configure it is with the UI in Docker for Windows:
That actually stores the setting in Docker’s config file at C:\ProgramData\Docker\config\daemon.json
:
"insecure-registries" : [
"registry.sixeyed:5000",
"registry.local:5000"
]
You can see any insecure registries that are configured from
docker info
too.
I’ve added my local registry address registry.local:5000
as an insecure registry (registry.sixeyed:5000
is another registry container which I have running on a Windows Server machine). That registry.local
address is set in my hosts
file — this is a much better option than using an IP address for an insecure registry. The hosts entry could point to 127.0.0.1
, or a container IP address, but is more likely to point to a real Windows Server IP on your network.
Working with Private Registries
Now you can push and pull images to your registry with abandon. But your image tag needs to include the registry domain (or IP address if you insist), and port.
Docker images can have up to four parts in the repository name: {registry-domain}/{account}/{image}:{tag}
. Local images can have any name — you can build your own image called microsoft/nanoserver
, but you won’t be able to push it to Docker Hub because the account
is microsoft
, and you don’t have write permissions.
The tag
is optional and defaults to latest
, and the registry-domain
part is optional too — it defaults to Docker Hub. So microsoft/nanoserver
is actually a short version of the full name docker.io/microsoft/nanoserver:latest
.
To push to a custom registry, your tag needs to include the domain name. You can do that with the --tag
option in the docker image build
command, or you can add a new tag to an existing image with docker image tag
. This adds my local registry domain to the registry image, so I can store my registry image in my registry:
docker image tag `
dockeronwindows/ch04-registry `
registry.local:5000/dockeronwindows/ch04-registry
Now my image has a tag that includes the registry domain, registry.local:5000/dockeronwindows/ch04-registry
. That’s enough detail for Docker to know that it’s going to a custom registry, and I can push it there:
docker image push `
registry.local:5000/dockeronwindows/ch04-registry
The image layers get pushed to your local registry in the same way as when you push to Docker Hub:
Docker Registry uses the same smart layer caching as your local version of Docker, so if your Docker images are optimized to make use of the cache, you’ll save network traffic and disk space in the registry too (existing layers get re-used if there’s a cache hit).
Those layers are stored in a Docker volume, or at a known location on the host if you run the container with a volume mount. Mine is writing to C:\registry-data
on the host, and the tree
command shows me the nest of subdirectories where the registry stores the layers:
PS> tree
Folder PATH listing for volume Local Disk
Volume serial number is 9AE0-64CC
C:.
└───docker
└───registry
└───v2
├───blobs
│ └───sha256
│ ├───04
│ │ └───04f5dd49765ac9ea252ccb44...c
│ ├───1c
│ │ └───1cefc1b4fa900dec68ab899c...7
...
You can push and pull from the registry, but there are no extra features with the OSS registry server. If you want to see what images you have, you’ll need to use the registry api. This lists all the repositories in the registry:
PS> (iwr http://registry.local:5000/v2/_catalog).Content
{"repositories":["dockeronwindows/ch04-registry"]}
Next Up
There was only one image in Chapter 4 (but there’s a very useful discussion on commercial registries — including DTR — which you should definitely read on your way to production). Next week it’s on to Chapter 5, Adopting Container-First Solution Design which Manoj particularly enjoyed.
We’re back onto Nerd Dinner to see how we can use Docker to modernize a legacy monolithic application. ch05-nerd-dinner-web makes some changes to the app to load configuration settings from environment variables.