Introduce a,

The development and operation of Docker container applications do not have reliable image management. Although Docker officially provides a public image warehouse, it is also necessary to deploy Registry for our private environment in terms of security and efficiency. Harbor is an open source enterprise Docker Registry project managed by VMware, including rights management (RBAC), LDAP, log audit, management interface, self-registration, image replication and Chinese support, etc.

Second, the component

The Docker Compose template for deploying Harbor is located in /Deployer/docker-compose.yml. Open the template file and you’ll find that Harbor is made up of five containers:

  • Proxy: Reverse proxy formed by the Nginx server.
  • Registry: Container instance composed of Docker official open source Registry images.
  • UI: Core Services in the architecture. The code that makes up this container is the body of the Harbor project.
  • Mysql: Database container consisting of official mysql images.
  • Log: A container running RSYSlogD that collects logs from other containers in log-driver form.

These containers are connected by a Docker link so that each container can be accessed by the container name. For the end user, only the proxy (that is, Nginx) service port needs to be exposed.

Three, the working principle

Suppose we deploy Harbor on a virtual machine with the hostname registry.abcdocker.com. A user initiates a login request to the Harbor service using the Docker login command :docker login registry.abcdocker.com After entering the required information and hitting Enter, Docker client to address “registry.abcdocker.com/v2/” HTTP GET requests.

Harbor containers go through the following steps:

(1)Docker login

(a) First, the request is received by the proxy container listening on port 80. According to the pre-set matching rules, Nginx in the container forwards the request to the registry container at the back end;

(b) On the registry container side, because token-based authentication is configured, Registry returns error code 401, prompting the Docker client to access the TOKEN service binding URL. In Harbor, this URL points to Core Services;

(c) after receiving this error code, the Docker client will send a request to the URL of the token service, combine and encode the user name and password according to the BasicAuthentication specification of HTTP protocol, and put it in the header of the request;

(d) Similarly, after the request is sent to the proxy container through port 80, Nginx will forward the request to the UI container according to the rules. The UI container will decode the request header to obtain the user name and password after the handler listening to the TOKEN service URL receives the request.

(e) After getting the user name and password, the code in the UI container queries the database and compares the user name and password with data in the mysql container (note: the UI container also supports LDAP authentication, in which case the UI attempts to communicate with an external LDAP service and verify the user name and password). If the comparison is successful, the UI container will return the status code indicating success and generate the token with the key, which will be returned to the Docker client in the response body. The interaction between components in this process is shown below

So far, oncedocker loginUpon successful completion, the Docker client saves the encoded username and password in step (c) in a local hidden file.

(2) Docker Push

(a) First, the Docker client will repeat the login process, first sending a request to Registry, and then getting the address of the Token service;

(b) After that, the Docker client will provide additional information when accessing the token service on the UI container, indicating that it wants to apply for a token to push imagelibrary/ Hello-world;

(c) After Nginx forwards the request, the token service accesses the database to verify whether the current user has permission to push the image. If it has permission, it will encode image information and push action, sign with private key, generate token and return to Docker client.

(d) After obtaining the token, the Docker client will put the token in the request header and send a request to Registry to try to start pushing the image. After receiving the request, Registry will decode the token with the public key and check it. After all is successful, the transmission of the image begins. We omit the step of proxy forwarding. The following figure describes the communication of each component during this process

Iv. Installation environment

The IP address The docker version Docker – compose version The kernel Centos
192.168.1.197 17.03 1.22 4.17.12 7.4

Note: All Harbor service components are deployed in Docker, so the official installation uses Docker-compose for rapid deployment, so we need to install Docker, docker-compose. Harbor is based on Docker Registry V2 version, so Docker version must be at least 1.10.0 and Docker-compose version must be at least 1.6.0

Five, environmental preparation

Set hostname
hostnamectl set-hostname harbor

# Time synchronization
yum -y install ntp
 systemctl enable ntpd
 systemctl start ntpd
 ntpdate -u cn.pool.ntp.org
 hwclock --systohc
 timedatectl set-timezone Asia/Shanghai
 
Disable the swap partition
vim /etc/fstab  Disable swap permanently
swap was on /dev/sda11 during installation
UUID=0a55fdb5-a9d8-4215-80f7-f42f75644f69 none  swap    sw      0       0
Comment out the SWAP entryorCopy the code

echo “vm.swappiness = 0”>> /etc/sysctl.conf

sysctl -p

swapoff -a && swapon -a

# Disable firewall Selinux
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
sed -i '/SELINUX/s/enforcing/disabled/' /etc/selinux/config
 
# Upgrade the kernelrpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm yum - enablerepo = elrepo - kernel install the kernel - ml - && y sed -i s/saved/0/g /etc/default/grub&& grub2-mkconfig -o /boot/grub2/grub.cfg && rebootCopy the code

Docker, docker-compose installation

Download the Docker installation package

Wget wget HTTP: / / https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm  https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch.rpmCopy the code
➜ yum install docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch. RPM -y ➜ yum install Docker - ce - 17.03.2. The ce - 1. El7. Centos. X86_64. RPM - yCopy the code

Set up the boot and start docker SystemctlenableDocker systemctl start Docker Replace the docker-related configuration sed -iExecStart= /usr /bin /dockerd/ I \ExecStartPost= /sbin/iptables -I FORWARD -s 0.0.0.0\/0 -d 0.0.0.0\/0 -j ACCEPT' /usr/lib/systemd/system/docker.service
sed -i '/ dockerd/s / $/ \ \ - storage \ - driver \ = overlay2 - insecure - registry 192.168.60.26 / g' /usr/lib/systemd/system/docker.serviceCopy the code
Note: 1.Docker pulls the image from the official by default, and after version 1.12, the default private repository uses HTTPS to connect. We need to modify the Docker startup file on the host using private server. Add --insecure-registry 192.168.1.197 docker-compose Install to the startup commandCopy the code

Github address: github.com/docker/comp…

Docker Compose profile

Docker Compose is the last piece of Docker orchestration service, the aforementioned Machine allows users to quickly install Docker on other platforms, Swarm allows Docker containers to run efficiently in clusters, and Compose allows users to deploy distributed applications in clusters. Docker Compose is an “application layer” service that allows users to define which container group to run which application. Docker Compose allows users to dynamically change applications and expand as needed.

 Copy the code

Install the Docker – compose

The curl -l https://github.com/docker/compose/releases/download/1.22.0/docker-compose- ` uname-s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/localDocker-compose $docker-compose --version docker-compose version 1.22.0, build f46880feCopy the code

Docker-compose common command

docker-compose up -d               If the container does not exist, it will be created automatically based on the image

docker-compose down   -v         Stop the container and delete the container

docker-compose start                 ### Start the container. If the container does not exist, it cannot be started

docker-compose stop                 ### Stop container


Copy the code

Install the Harbor

Harbor official address github.com/vmware/harb…

Harbor two ways to install

1. Offline installation $wget https://storage.googleapis.com/harbor-releases/harbor-offline-installer-v1.5.0.tgz $tar xf Harbor - online - the installer - v1.5.0. TGZ 2. Online installation $wget https://storage.googleapis.com/harbor-releases/harbor-online-installer-v1.5.2.tgz $tar xf Harbor-online-installer-v1.5.2. TGZ Important: download the 823M installationCopy the code

The configuration of Harbor

To edit harbor. CFG we actually only need to change the Hostname field

[root@harbor harbor]# head harbor.cfg
## Configuration file of Harbor

#This attribute is for migrator to detect the version of the .cfg file, DO NOT MODIFY!
_version = 1.5.0
#The IP address or hostname to access admin UI and registry service.
#DO NOT use localhost or 127.0.0.1, because Harbor needs to be email exchange with external clients.The hostname = 192.168.1.197Copy the code

Harbor. CFG Configuration description

[root@master harbor]# grep -Ev "^$|^[#;] " harbor.cfg
# version of the Harbor
_version = 1.5.0

Use IP/ domain name instead of 127.0.0.1 && localhostThe hostname = 192.168.60.24Nginx SSL can also be set to HTTPS. If HTTPS is set, nginx SSL must be set to ON
ui_url_protocol = http

# Job Indicates the maximum number of processes
max_job_workers = 50 

Create a certificate. The certificate will be generated in the following path
customize_crt = on
ssl_cert = /data/cert/server.crt
ssl_cert_key = /data/cert/server.key

# Private key storage path
secretkey_path = /data

Set the log size
admiral_url = NA
log_rotate_count = 50
log_rotate_size = 200M

# Whether to use proxyHttp_proxy = https_proxy = no_proxy = 127.0.0.1,localhost, UIEmail Settings, used when sending a password reset email
email_identity = 
email_server = smtp.mydomain.com
email_server_port = 25
email_username = [email protected]
email_password = abc
email_from = admin <[email protected]>
email_ssl = false
email_insecure = false

The default password for logging in to the administrator UI is Harbor12345
harbor_admin_password = Harbor12345

Authentication mode: supports various authentication modes, such as LDAP and database authentication. The default is db_auth
auth_mode = db_auth

# LDAP authentication configuration item
ldap_url = ldaps://ldap.mydomain.com
ldap_basedn = ou=people,dc=mydomain,dc=com
ldap_uid = uid 
ldap_scope = 2 
ldap_timeout = 5
ldap_verify_cert = true
ldap_group_basedn = ou=group,dc=mydomain,dc=com
ldap_group_filter = objectclass=group
ldap_group_gid = cn
ldap_group_scope = 2

# Whether to enable automatic registration
self_registration = on

The Token validity period is 30 minutes by default
token_expiration = 30

Create project permissions for users. Default to everyone, adminOnly
project_creation_restriction = everyone

The default password for user root of the Mysql database is root123
db_host = mysql
db_password = root123
db_port = 3306
db_user = root

# Redis configuration
redis_url = redis:6379
clair_db_host = postgres
clair_db_password = password
clair_db_port = 5432
clair_db_username = postgres
clair_db = postgres
uaa_endpoint = uaa.mydomain.org
uaa_clientid = id
uaa_clientsecret = secret
uaa_verify_cert = true
uaa_ca_cert = /path/to/ca.pem
registry_storage_provider_name = filesystem
registry_storage_provider_config = 
Copy the code

This time we use offline installation, installation package above

Tar xf harbor - offline installer - v1.5.0. TGZ. / installCopy the code

7. Visit Harbor

Access: 192.168.1.197

The default port number is 80. To change the port number, modify the mapping of docker-comemage. yaml

8. HTTPS is not required on the client

[root@localhost ~]# echo '{"insecure-registries":["172.16.1.146:8888"]}' > /etc/docker-daemon.json
 [root@localhost ~]# cat /etc/docker/daemon.json
{ "insecure-registries": ["172.16.1.146:8888"] } 
restart docker 
[root@localhost ~]# service docker restart
Copy the code

Error response from daemon: Get https:// 172.16.1.146:5000/v1/_ping: HTTP: server gave HTTP response to HTTPS client

[root@localhost harbor]# docker login 172.16.1.146:8888
Username (admin): admin
Password: 
Login Succeeded
Copy the code

9. Managing mirrors

Tag and upload

Docker push your IP: port/project name/image name: tagCopy the code
[root@localhost harbor]# docker tag registry: 2.6.2 172.16.1.146:8888 / wondertek/registry: 2.6.2
[root@localhost harbor]# docker push 172.16.1.146:8888 / wondertek/registry: 2.6.2The push refers to a repository 172.16.1.146:8888 / wondertek/registry 9113493 eaae1: Layer already exists 621 c2399d41a: Layer already exists 59e80739ed3f: Layer already exists febf19f93653: Layer already exists e53f74215d12: Layer already exists 2.6.2: Digest: SHA256: FEB40D14cd33e646b9985e2d6754ed66616fedb840226c4d917ef53d616dcd6c size: 1364Copy the code

Delete the local image and download it again

[root@localhost harbor]# docker rmi 172.16.1.146:8888 / wondertek/registry: 2.6.2Untagged: 172.16.1.146:8888 / wondertek/registry: 2.6.2 Untagged: 172.16.1.146:8888 / wondertek/registry @ sha256: feb40d14cd33e646b9985e2d6754ed66616fedb840226c4d917ef53d616dcd6c

[root@localhost harbor]# docker pull 172.16.1.146:8888 / wondertek/registry: 2.6.2Trying to pull the repository 172.16.1.146:8888 / wondertek/registry... 2.6.2: Pulling the from 172.16.1.146:8888 / wondertek/registry Digest: sha256: feb40d14cd33e646b9985e2d6754ed66616fedb840226c4d917ef53d616dcd6c
Status: Downloaded newer image for172.16.1.146:8888 / wondertek/registry: 2.6.2Copy the code