Insecure Docker registry and self-signed certificates - docker

I have already setup a localized docker registry with self-signed certificates based on this reference: https://docs.docker.com/registry/insecure/#deploy-a-plain-http-registry.
I pussed an example image using:
sudo docker run hello-world
sudo docker tag hello-world registry.local.doc:5045/hello-world
sudo docker push registry.local.doc:5045/hello-world
I am able to see the "contents" of the registry on https://registry.local.doc:5045/v2/_catalog:
{"repositories":["hello-world"]}
1st Problem
I have used self-signed certificates using:
openssl req -newkey rsa:4096 -nodes -sha256 -keyout ./certs/tls.key -x509 -days 365 -subj "/C=GR/ST=./L=./O=./CN=registry.local.doc" -addext "subjectAltName = DNS:registry.local.doc" -out ./certs/tls.crt
However, in order to make it work I have to add in /etc/docker/daemon.json the following:
{ "insecure-registries" : ["registry.local.doc:5000"] }
which is confusing as I am using self-signed certificates as already mentioned.
2nd Problem
I have a k3s node and I want to pull images from inside a Pod.
apiVersion: apps/v1
kind: Deployment
metadata:
name: registry-test
labels:
app: registry-test
spec:
replicas: 1
selector:
matchLabels:
app: registry-test
template:
metadata:
labels:
app: registry-test
spec:
containers:
- name: registry-test
image: registry.local.doc:5045/hello-world
It works but first I need to run:
sudo update-ca-certificates
sudo systemctl restart containerd
sudo systemctl restart k3s
I understand the reasons behind the execution of the first two commnads sudo update-ca-certificates & sudo systemctl restart containerd, however I have no clue why I have to run sudo systemctl restart k3s to make it works.
Is there a solution without restarting the cluster, as something like this is forbidden when we talk about a cluster in production?
And if I had a k8s cluster, what exactly would Ι have to restart?

1st Problem
registry is a server side, your docker is client side, the config insecure-registries tell your docker to skip server cert validation.
Without this settings, docker will not pull image because the cert is invalid.
2st Problem
you need to restart k3s only because you using insecure-registries config. docker need restart to reload this config.
When you using self-sign cert registry, you have two way to pull image from there.
Add { "insecure-registries" : ["registry.local.doc:5000"] } to /etc/docker/daemon.json and restart k3s
sudo systemctl restart containerd
sudo systemctl restart k3s
In production, normally you should have more then one worker and follow below step:
drain the worker, see doc here. This will move your pod to other worker.
add insecure-registries and restart k3s.
uncordon the worker, pod can move back to this worker.
repeat above step on every worker.
Add your self-sign cert to trust store on every woker. This way don't require restart k3s.
For ubuntu see below.
sudo cp tls.crt /usr/local/share/ca-certificates
sudo update-ca-certificates
add cert to docker certs folder
Instruct every Docker daemon to trust that certificate. The way to do this depends on your OS.
Linux: Copy the domain.crt file to /etc/docker/certs.d/myregistrydomain.com:5000/ca.crt on every Docker host. You do not need to restart Docker.
sudo cp tls.crt /etc/docker/certs.d/registry.local.doc:5000/ca.crt

Related

Unable to PULL image into minikube from insecure private registry - http: server gave HTTP response to HTTPS client

On Ubuntu 18, I installed Docker (19.03.12) from these instructions
https://docs.docker.com/engine/install/ubuntu/
And then went through these steps
manage docker as non-root user
https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user
start on boot using systemd
https://docs.docker.com/engine/install/linux-postinstall/#configure-docker-to-start-on-boot
and set up a private docker registry using this
docker run -d -p 5000:5000 -e REGISTRY_DELETE_ENABLED=true --restart=always --name registry registry:2
I also added this to the daemon.json file
{ "insecure-registries" : ["my.registrydomain.lan:5000"] }
And restarted the docker daemon
sudo /etc/init.d/docker restart
I checked docker info to make sure the setting for insecure registry was applied and I saw this at the end so it seems ok
Insecure Registries:
my.registrydomain.lan:5000
127.0.0.0/8
On the same machine I start minikube (1.12.3) with this command
minikube start --driver=docker --memory=3000 --insecure-registry=my.registrydomain.lan:5000
So everything is running and fine, and I proceed to apply my deployments using kubectl except when I get to the pod that needs to pull the container form the local registry I get an ErrImagePull status. Here is part of my deployment
spec:
containers:
- name: my-container
image: my.registrydomain.lan:5000/name:1.0.0.9
imagePullPolicy: IfNotPresent
When I describe the pod that failed using
kubectl describe pod mypod-8474577f6f-bpmp2
I see this message
Failed to pull image "my.registrydomain.lan:5000/name:1.0.0.9": rpc
error: code = Unknown desc = Error response from daemon: Get
https://my.registrydomain.lan:5000/v2/: http: server gave HTTP
response to HTTPS client
EDIT: I forgot to mention that I am able to PUSH my images into the registry without any issues from a separate machine over http (machine is Windows 10 and I set the insecure registry option in the daemon config)
I tried to reproduce your issue with exact same settings that you provided and this works just fine. Image is being pulled without any problem. I tested this with my debian 9 and fresh ubuntu installation with this settings:
minikube version: v1.12.3
docker version: v19.03.12
k8s version: v1.18.3
ubuntu version: v18
What I`ve done what is not described in the question is to place an entry in minikube container hosts file:
root#minikube:/# cat /etc/hosts
...
10.128.5.6 my.registrydomain.lan
...
And the tag/push commands:
docker tag 4e2eef94cd6b my.registrydomain.lan:5000/name:1.0.0.9
docker push my.registrydomain.lan:5000/name:1.0.0.9
Here`s the describe from the pod:
Normal Pulling 8m19s (x5 over 10m) kubelet, minikube Pulling image "my.registrydomain.lan:5000/name:1.0.0.9"
As suggested in the comments already you may want to check this github case. It goes thru couple of solution of your problem:
First is to check your hosts file and update it correctly if you hosting your repository on another node. Second solution is related to pushing images in to repository which turned for the user that both insecure-registries and docker push command are case sensitive. Third one is to use systemd to control docker daemon.
Lastly If those would not help I would try to clear all settings, uninstall docker, clear docker configuration and start again from scratch.

Docker behing transparent proxy and intermediate cert

OS: Centos 7.6.1810
Docker Version: Server Version: 18.09.5
Issue:
My company uses a transparent proxy with an intermediate cert to navigate. I was able to install the cert following doc: https://docs.docker.com/ee/dtr/user/access-dtr/ and these steps:
# Download the DTR CA certificate
sudo curl -k https://<dtr-domain-name>/ca -o /etc/pki/ca-trust/source/anchors/<dtr-domain-name>.crt
# Refresh the list of certificates to trust
sudo update-ca-trust
# Restart the Docker daemon
sudo /bin/systemctl restart docker.service
Curl and Wget are working well, but docker run is not:
bash $ docker run -it cheers
Unable to find image 'cheers:latest' locally
docker: Error response from daemon: Get https://registry-1.docker.io/v2/: remote error: tls: handshake failure.
See 'docker run --help'.
I've tried adding the registry as insecure in daemon.json but it was unsuccessfully.
Has anyone run into the same problem?
I think i figured out what’s going on:
Docker client offers only TLS_ECDHE_* ciphers but .docker.io (behind my corporate proxy) offers only TLS_RSA ciphers.
Without proxy, docker.io offers both types of ciphers.
Now, next challenge: make docker offer TLS_RSA or make my proxy support TLS_ECDHE.
I have no idea how to do either :frowning:

Docker don't run with proxy [duplicate]

This question already has answers here:
x509: certificate signed by unknown authority - both with docker and with github
(3 answers)
Closed 4 years ago.
i need your help,
My docker don't run on my enterprise, I do not know what to do
kaue default # docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
9bb5a5d4561a: Pulling fs layer
docker: error pulling image configuration: Get https://production.cloudflare.docker.com/registry-v2/docker/registry/v2/blobs/sha256/e3/e38bc07ac18ee64e6d59cf2eafcdddf9cec2364dfe129fe0af75f1b0194e0c96/data?verify=1528483070-KGbywXnskgTKu5B9AuTdFPQdYjs%3D: x509: certificate signed by unknown authority.
See 'docker run --help'
.
I have a Windows 7, and Authenticated proxy in my job...
Set the proxy in your environment before running the docker run command...
set HTTPS_PROXY=http://user:password#proxy_name_or_ip:proxy_port
For example
set HTTPS_PROXY=http://myusername:Password1#proxy.local:8080
For docker on windows, follow these steps to configure the proxy variables:
In powershell perform the following for HTTP_PROXY and HTTPS_PROXY:
[Environment]::SetEnvironmentVariable("HTTP_PROXY", "http://username:password#proxy:port/", [EnvironmentVariableTarget]::Machine)
Once the variables are set, restart the service with powershell:
Restart-Service docker
Edit: For Linux native installs of Docker using systemd, follow these steps to configure your proxy:
Create a systemd drop-in directory for the docker service:
$ sudo mkdir -p /etc/systemd/system/docker.service.d
Create a file called /etc/systemd/system/docker.service.d/http-proxy.conf that adds the HTTP_PROXY environment variable:
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:80/"
Or, if you are behind an HTTPS proxy server, create a file called /etc/systemd/system/docker.service.d/https-proxy.conf that adds the HTTPS_PROXY environment variable:
[Service]
Environment="HTTPS_PROXY=https://proxy.example.com:443/"
If you have internal Docker registries that you need to contact without proxying you can specify them via the NO_PROXY environment variable:
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:80/" "NO_PROXY=localhost,127.0.0.1,docker-registry.somecorporation.com"
Or, if you are behind an HTTPS proxy server:
[Service]
Environment="HTTPS_PROXY=https://proxy.example.com:443/" "NO_PROXY=localhost,127.0.0.1,docker-registry.somecorporation.com"
Flush changes:
$ sudo systemctl daemon-reload
Restart Docker:
$ sudo systemctl restart docker
Verify that the configuration has been loaded:
$ systemctl show --property=Environment docker
Environment=HTTP_PROXY=http://proxy.example.com:80/
Or, if you are behind an HTTPS proxy server:
$ systemctl show --property=Environment docker
Environment=HTTPS_PROXY=https://proxy.example.com:443/
For special characters in your password, you can use unicode to encode the characters:
If your original password was: F#o:o!B#ar$
The unicode equivalent would be: F%40o%3Ao%21B%23ar%24

How to download a image from default docker registry?

I'm trying to download a container image from default registry with the command:
docker run -d --name=nginx -p 80:80 nginx:alpine
The output is:
Unable to find image 'nginx:alpine' locally
docker: Error response from daemon: Get https://registry-1.docker.io/v2/: x509: certificate signed by unknown authority.
See 'docker run --help'.
I already configured the proxy with cntlm. I'm behind a corporate firewall with Deep Inspection Package (DIP, man in the middle)
Could I define the default registry (https://registry-1.docker.io/v2/) like a insecure registry? How? There are another solution?
I already try the options:
--insecure-registry=registry-1.docker.io:5000
--insecure-registry=registry-1.docker.io
--insecure-registry='*'
--insecure-registry=https://registry-1.docker.io/v2/
Problem resolved.
My SO is mint (based in ubuntu xenial) and docker version 17.06.0-ce
To resolve I needed do put the root certificate from my company's firewall to my linux ca-certificates (reference 1 - https://askubuntu.com/questions/73287/how-do-i-install-a-root-certificate). Obs.: Proxy already configured using cntlm (reference 2 - http://cntlm.sourceforge.net/) (reference 3 - https://docs.docker.com/engine/admin/systemd/)
First I exported the certicate installed in my browser, google chrome. From chrome a choose configuration->advanced->privacy and security->manage certificates->trusted root certificate authorities, so I selected the authority, in my case something like mycompany.com. After, I choose export->advance, select X.509 base64 format (*.cer). The correct format is very important. I saved the file ~/certificate.crt.
Create a extra directory:
sudo mkdir /usr/share/ca-certificates/extra
copy the certificate to extra dir:
sudo cp ~/certificate.crt /usr/share/ca-certificates/extra
update ca-certificates config:
sudo dpkg-reconfigure ca-certificates
restart docker:
sudo systemctl daemon-reload
sudo systemctl restart docker
Now docker can download images from default registry.

Can not pull docker image from private repo when using Minikube

I am attempting to use Minikube for local kubernetes development. I have set up my docker environment to use the docker daemon running in the provided Minikube VM (boot2docker) as suggested:
eval $(minikube docker-env)
It sets up these environment variables:
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/home/jasonwhite/.minikube/certs"
When I attempt to pull an image from our private docker repository:
docker pull oururl.com:5000/myimage:v1
I get this error:
Error response from daemon: Get https://oururl.com:5000/v1/_ping: x509: certificate signed by unknown authority
It appears I need to add a trusted ca root certificate somehow, but have been unsuccessful so far in my attempts.
I can hit the repository fine with curl using our ca root cert:
curl --cacert /etc/ssl/ca/ca.pem https://oururl.com:5000/v1/_ping
I've been unable to find anyway to get the cert into the minikube vm. But, minikube has a command line parameter to pass in an insecure-registry.
minikube start --insecure-registry=<HOST>:5000
Then to configure authentication on the registry, create a secret.
kubectl create secret docker-registry tp-registry --docker-server=<REGISTRY>:5000 --docker-username=<USERNAME> --docker-password=<PASSWORD> --docker-email=<EMAIL> --insecure-skip-tls-verify=true
Add secret to the default service account as described in the kubernetes docs.
I came up with a work-around for the situation with suggestions from these sources:
https://github.com/docker/machine/issues/1799
https://github.com/docker/machine/issues/1872
I logged into the Minikube VM (minikube ssh), and edited the /usr/local/etc/ssl/certs/ca-certificates.crt file by appending my own ca cert.
I then restarted the docker daemon while still within the VM: sudo /etc/init.d/docker restart
This is not very elegant in that if I restart the Minikube VM, I need to repeat these manual steps each time.
As an alternative, I also attempted to set the --insecure-registry myurl.com:5000 option in the DOCKER_OPTS environment variable (restarted docker), but this didn't work for me.
An addon was recently added to Minikube that makes access to private container registries much easier:
minikube addons configure registry-creds
minikube addons enable registry-creds
For an http registry this steps works for me:
1) minikube ssh
2) edit /var/lib/boot2docker/profile and add to $EXTRA_ARGS --insecure-registry yourdomain.com:5000
3) restart the docker daemon sudo /etc/init.d/docker restart
The Kubernetes documentation on this is pretty good.
Depending on where your private docker repository is hosted, the solution will look a bit different. The documentation explains how to handle each type of repository.
If you want an automated approach to handle this authentication, you will want to use a Kubernetes secret and specify the imagePullSecrets for your Pod.
Sounds like your question has more to do with Docker than Kubernetes. The Docker CLI supports a number of TLS-related options. Since you already have the CA cert, something like this should work:
docker --tlsverify --tlscacert=/etc/ssl/ca/ca.pem pull oururl.com:5000/myimage:v1
You need to edit /etc/default/docker to look like so:
# Docker Upstart and SysVinit configuration file
#
# THIS FILE DOES NOT APPLY TO SYSTEMD
#
# Please see the documentation for "systemd drop-ins":
# https://docs.docker.com/engine/admin/systemd/
#
# Customize location of Docker binary (especially for development testing).
#DOCKERD="/usr/local/bin/dockerd"
# Use DOCKER_OPTS to modify the daemon startup options.
DOCKER_OPTS="--insecure-registry oururl.com:5000"
# If you need Docker to use an HTTP proxy, it can also be specified here.
#export http_proxy="http://127.0.0.1:3128/"
# This is also a handy place to tweak where Docker's temporary files go.
#export DOCKER_TMPDIR="/mnt/bigdrive/docker-tmp"
Make sure to sudo service docker stop and sudo docker start to apply the changes. You should then be able to push/pull to your registry.
login account minikube
vi ~/.minikube/machines/<PROFILE_NAME>/config.json (in my case vi ~/.minikube/machines/minikube/config.json)
add private repo on InsecureRegistry attribute (json path: HostOptions.EngineOptions.InsecureRegistry)
minikube start again

Resources