Private warehouse Harbor deployment
Docker Registry
Many Registry servers on the Internet support third-party user registration, and then make their own warehouse based on user names. However, there is a defect in using Registry on the Internet, that is, we will not push and download images quickly, and there will be dozens or hundreds of containers that can be started in parallel in the production environment, Moreover, it is likely that each server does not have an image locally. At this time, if you download an image through the Internet, there will be many problems, such as slow download speed, a lot of bandwidth, etc. if the bandwidth is not enough, the process from download to startup may take several or ten minutes, which is contrary to the original intention and purpose of using containers to be lighter and faster. Therefore, many times we may need to make our own private Registry.
Registry is used to save the docker image, including the hierarchy and metadata of the image. Users can create their own registry or use the official Docker Hub.
Docker Registry classification:
- Sponsor Registry: a third-party Registry for customers and Docker communities
- Mirror Registry: a third-party Registry for customers only
- Vendor Registry: the registry provided by the vendor that publishes the docker image
- Private Registry: a registry provided by private entities with firewalls and additional security layers
In fact, if the system environment of operation and maintenance is hosted on cloud computing services, such as Alibaba cloud, Alibaba cloud Registry is the best choice. Most of the time, our production environment is not local, but hosted in the data center computer room. If we deploy Registry on a host in the data center computer room, because they are all in the same computer room, they belong to the same LAN. At this time, the data transmission goes through the intranet, and the efficiency will be greatly improved.
All registries work based on https by default, which is the basic requirement of Docker. When I build my own registry, it is likely to work based on http, but Docker refuses to use http to provide Registry Services by default. Unless it is explicitly told, we want to use the registry of http protocol.
Environmental description:
host | IP | service |
---|---|---|
registry.example.com/CentOS8 (Harbor warehouse) | 192.168.220.17 | docker docker-compose harbor |
localhost.localdomain/CentOS8 | 192.168.220.20 | docker |
Harbor
Harbor image warehouse deployment
Harbor
Whether you use docker distribution to build your own warehouse or run the container through the official image, we can find that it is very simple through the previous demonstration. It is not as convenient as directly using the official Docker Hub to manage the image. At least the official Docker Hub can manage the image through the web interface and perform search on the web interface, You can also use Webhooks and Automated Builds to automatically build images based on Dockerfile. Instead of executing docker build locally, users push all build context files to github as a warehouse, so that Docker Hub can pull these files from github to complete automatic construction.
However, no matter how powerful the official Docker Hub is, it is abroad after all, so the speed is the biggest bottleneck. It is impossible for us to consider using the official warehouse many times. However, the two self built warehouse methods mentioned above are very simple and inconvenient to manage, so a project favored by CNCF organization, named Harbor, emerged later.
Introduction to Harbor
Harbor is secondary encapsulated by VMWare on the basis of Docker Registry, with many additional programs added, and provides a very beautiful web interface.
Harbor is an open source trusted cloud native warehouse project for storage, user management and image discovery.
Harbor extends the open source Docker distribution by adding functions that users usually need, such as security, identity and management.
Harbor supports advanced features such as user management, access control, activity monitoring, and replication between instances.
Harbor features
-
Multi tenant content signing and validation
-
Security and vulnerability analysis
-
Audit log record
-
Identity integration and role-based access control
-
Image replication between instances
-
Extensible API and graphical UI
-
Internationalization (currently Chinese and English Culture)
Docker compose
It is very difficult to deploy Harbor on physical machines. In order to simplify Harbor applications, Harbor officials directly make Harbor into applications running in containers. Moreover, this container relies on many storage systems such as redis, mysql and pgsql in Harbor, so it needs to arrange many containers to work together. Therefore, when deploying and using VMWare Harbor, It needs the help of Docker for stand-alone scheduling
Compose is a tool for defining and running multi container Docker applications. With compose, you can use YAML files to configure the services of your application. Then, with one command, you can create and start all the services in the configuration
Harbor deployment:
Install docker
registry.example.com host installation
[root@localhost ~]# dnf -y install vim wget # Configure docker source [root@localhost ~]# cd /etc/yum.repos.d/ [root@localhost yum.repos.d]# curl -o docker-ce.repo https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1919 100 1919 0 0 11156 0 --:--:-- --:--:-- --:--:-- 11156 [root@localhost yum.repos.d]# ls CentOS-Stream-AppStream.repo CentOS-Stream-Extras.repo CentOS-Stream-PowerTools.repo CentOS-Stream-BaseOS.repo CentOS-Stream-HighAvailability.repo CentOS-Stream-RealTime.repo CentOS-Stream-Debuginfo.repo CentOS-Stream-Media.repo docker-ce.repo # Replace docker CE The keyword in repo is mirrors aliyun. com [root@localhost yum.repos.d]# sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo # Install docker [root@localhost yum.repos.d]# dnf -y install docker-ce # Turn off firewall and seLinux [root@localhost yum.repos.d]# systemctl disable --now firewalld Removed /etc/systemd/system/multi-user.target.wants/firewalld.service. Removed /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service. [root@localhost yum.repos.d]# setenforce 0 [root@localhost yum.repos.d]# getenforce Permissive # Set docker to start automatically [root@localhost yum.repos.d]# systemctl enable --now docker Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /usr/lib/systemd/system/docker.service. [root@localhost yum.repos.d]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE # Configure alicloud accelerator [root@localhost ~]# vim /etc/docker/daemon.json { "registry-mirrors": ["https://wn5c7d7w.mirror.aliyuncs.com"] } [root@localhost ~]# systemctl daemon-reload [root@localhost ~]# systemctl restart docker [root@localhost ~]# docker info Client: Context: default Debug Mode: false Plugins: app: Docker App (Docker Inc., v0.9.1-beta3) buildx: Docker Buildx (Docker Inc., v0.7.1-docker) scan: Docker Scan (Docker Inc., v0.12.0) Server: Containers: 0 Running: 0 Paused: 0 ......... Experimental: false Insecure Registries: 127.0.0.0/8 Registry Mirrors: https://wn5c7d7w.mirror.aliyuncs.com / # view effective Live Restore Enabled: false
Install docker compose
registry.example.com host installation
Installation official website: Install Docker Compose |Docker documentation
[root@localhost yum.repos.d]# cd [root@localhost ~]# ls /usr/local/bin/ [root@localhost ~]# [root@localhost ~]# curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 664 100 664 0 0 750 0 --:--:-- --:--:-- --:--:-- 749 100 12.1M 100 12.1M 0 0 587k 0 0:00:21 0:00:21 --:--:-- 885k [root@localhost ~]# ls /usr/local/bin/ docker-compose [root@localhost ~]# chmod +x /usr/local/bin/docker-compose [root@localhost ~]# which docker-compose /usr/local/bin/docker-compose [root@localhost ~]# echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin [root@localhost ~]# docker --version Docker version 20.10.12, build e91ed57
Build Harbor
registry.example.com host installation
Download address: Release v2.3.5 · goharbor/harbor · GitHub
# Download and upload Harbor package [root@localhost ~]# cd /usr/src [root@localhost src]# ls debug harbor-offline-installer-v2.3.5.tgz kernels md5sum # Compare the md5sum value to ensure the integrity of the installation package [root@localhost src]# cat md5sum f1e01bbb4b62bf4a31a103d8c7c5a215 harbor-offline-installer-v2.3.5.tgz 762377f15c4483c18434fb43ec4efdab harbor-offline-installer-v2.3.5.tgz.asc aa7c52f1aae0e46aaeb9cb426a190721 harbor-online-installer-v2.3.5.tgz 4ada42697aa7d6bd8ab3b2cfa1559aaa harbor-online-installer-v2.3.5.tgz.asc [root@localhost src]# md5sum harbor-offline-installer-v2.3.5.tgz f1e01bbb4b62bf4a31a103d8c7c5a215 harbor-offline-installer-v2.3.5.tgz # decompression [root@localhost src]# ls /usr/local/ bin etc games include lib lib64 libexec sbin share src [root@localhost src]# tar xf harbor-offline-installer-v2.3.5.tgz -C /usr/local/ [root@localhost src]# cd /usr/local/ [root@localhost local]# ls bin etc games harbor include lib lib64 libexec sbin share src # Modify host name [root@localhost local]# cd harbor [root@localhost harbor]# hostnamectl set-hostname registry.example.com [root@localhost harbor]# bash [root@registry harbor]# hostname registry.example.com [root@registry harbor]# cp harbor.yml.tmpl harbor.yml # Modify profile [root@registry harbor]# vim harbor.yml # Configuration file of Harbor # 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 accessed by external clients. hostname: registry.example.com # Modify to current hostname # http related config http: # port for http, default is 80. If https enabled, this port will redirect to https port port: 80 # https related config #https: # Add comments # https port for harbor, default is 443 #port: 443 # Add comments # The path of cert and key files for nginx #certificate: /your/certificate/path # Add comments #private_key: /your/private/key/path # Add comments ........ # Remember Change the admin password from UI after launching Harbor. harbor_admin_password: Harbor12345 # Harbor web interface login password # Harbor DB configuration database: # The password for the root user of Harbor DB. Change this before any production use. password: root123 # Database password # The maximum number of connections in the idle connection pool. If it <=0, no idle connections are retained. max_idle_conns: 100 # Maximum idle connections # The maximum number of open connections to the database. If it <= 0, then there is no limit on the number of open connections. # Note: the default number of connections is 1024 for postgres of harbor. max_open_conns: 900 # Maximum number of open files # The default data volume data_volume: /data # Data storage location # Modify hosts file to add mapping [root@registry harbor]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.220.17 registry.example.com [root@registry harbor]# ping registry.example.com PING registory.example.com (192.168.220.17) 56(84) bytes of data. 64 bytes from registory.example.com (192.168.220.17): icmp_seq=1 ttl=64 time=0.054 ms 64 bytes from registory.example.com (192.168.220.17): icmp_seq=2 ttl=64 time=0.034 ms 64 bytes from registory.example.com (192.168.220.17): icmp_seq=3 ttl=64 time=0.027 ms # Execute installation script [root@registry harbor]# ./install.sh [Step 0]: checking if docker is installed ... Note: docker version: 20.10.12 [Step 1]: checking docker-compose is installed ... Note: docker-compose version: 1.29.2 [Step 2]: loading Harbor images ... ............... [Step 5]: starting Harbor ... Creating network "harbor_harbor" with the default driver Creating harbor-log ... done Creating registryctl ... done Creating redis ... done Creating registry ... done Creating harbor-portal ... done Creating harbor-db ... done Creating harbor-core ... done Creating nginx ... done Creating harbor-jobservice ... done ✔ ----Harbor has been installed and started successfully.---- # see [root@registry harbor]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE goharbor/harbor-exporter v2.3.5 1730c6f650e2 5 days ago 81.9MB goharbor/chartmuseum-photon v2.3.5 47004f032938 5 days ago 179MB goharbor/redis-photon v2.3.5 3d0cedc89a0d 5 days ago 156MB goharbor/trivy-adapter-photon v2.3.5 5c0212e98070 5 days ago 133MB goharbor/notary-server-photon v2.3.5 f20a76c65359 5 days ago 111MB goharbor/notary-signer-photon v2.3.5 b9fa38eef4d7 5 days ago 108MB goharbor/harbor-registryctl v2.3.5 7a52567a76ca 5 days ago 133MB goharbor/registry-photon v2.3.5 cf22d3e386b8 5 days ago 82.6MB goharbor/nginx-photon v2.3.5 5e3b6d9ce11a 5 days ago 45.7MB goharbor/harbor-log v2.3.5 a03e4bc963d6 6 days ago 160MB goharbor/harbor-jobservice v2.3.5 2ac32df5a2e0 6 days ago 211MB goharbor/harbor-core v2.3.5 23baee01156f 6 days ago 193MB goharbor/harbor-portal v2.3.5 bb545cdedf5a 6 days ago 58.9MB goharbor/harbor-db v2.3.5 9826c57a5749 6 days ago 221MB goharbor/prepare v2.3.5 a1ceaabe47b2 6 days ago 255MB [root@registry harbor]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 779cf4b59089 goharbor/harbor-jobservice:v2.3.5 "/harbor/entrypoint...." 59 seconds ago Up 58 seconds (healthy) harbor-jobservice 686123a9e789 goharbor/nginx-photon:v2.3.5 "nginx -g 'daemon of..." 59 seconds ago Up 58 seconds (healthy) 0.0.0.0:80->8080/tcp, :::80->8080/tcp nginx 192afc12b0df goharbor/harbor-core:v2.3.5 "/harbor/entrypoint...." About a minute ago Up 59 seconds (healthy) harbor-core f22ed219514c goharbor/harbor-db:v2.3.5 "/docker-entrypoint...." About a minute ago Up About a minute (healthy) harbor-db 68e99a0f8b1d goharbor/registry-photon:v2.3.5 "/home/harbor/entryp..." About a minute ago Up About a minute (healthy) registry f31a1a3db38f goharbor/harbor-portal:v2.3.5 "nginx -g 'daemon of..." About a minute ago Up About a minute (healthy) harbor-portal 230852b4624f goharbor/harbor-registryctl:v2.3.5 "/home/harbor/start...." About a minute ago Up About a minute (healthy) registryctl 4b251b48fa0c goharbor/redis-photon:v2.3.5 "redis-server /etc/r..." About a minute ago Up About a minute (healthy) redis debb1c1a36d6 goharbor/harbor-log:v2.3.5 "/bin/sh -c /usr/loc..." About a minute ago Up About a minute (healthy) 127.0.0.1:1514->10514/tcp harbor-log [root@registry harbor]# ss -antl State Recv-Q Send-Q Local Address:Port Peer Address:Port Process LISTEN 0 128 0.0.0.0:22 0.0.0.0:* LISTEN 0 128 127.0.0.1:1514 0.0.0.0:* LISTEN 0 128 0.0.0.0:80 0.0.0.0:* LISTEN 0 128 [::]:22 [::]:* LISTEN 0 128 [::]:80 [::]:*
Browser access
localhost. The steps of installing docker on the localdomain host are the same as those of installing docker on the Harbor warehouse above
localhost. The localdomain host configuration parameter is secure because https is not used and http is used
[root@registry harbor]# cat /etc/docker/daemon.json { "insecure-registries": ["registry.example.com"] # Add the corresponding host name of Harbor warehouse } [root@registry harbor]# systemctl daemon-reload [root@registry harbor]# systemctl restart docker
Modify localhost Localdomain hosts file
# Configure hosts file [root@localhost ~]# cat /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 192.168.220.17 registry.example.com # IP and hostname of Harbor warehouse [root@localhost ~]# ping registry.example.com # Test ping PING registry.example.com (192.168.220.17) 56(84) bytes of data. 64 bytes from registry.example.com (192.168.220.17): icmp_seq=1 ttl=64 time=0.359 ms 64 bytes from registry.example.com (192.168.220.17): icmp_seq=2 ttl=64 time=0.445 ms 64 bytes from registry.example.com (192.168.220.17): icmp_seq=3 ttl=64 time=0.234 ms
localhost. The local domain host uses docker to pull the official image and then transfer it to the newly built Harbor warehouse
[root@localhost docker]# docker pull busybox # Pull the official image busybox Using default tag: latest latest: Pulling from library/busybox 3cb635b06aa2: Pull complete Digest: sha256:b5cfd4befc119a590ca1a81d6bb0fa1fb19f1fbebd0397f25fae164abe1e8a6a Status: Downloaded newer image for busybox:latest docker.io/library/busybox:latest [root@localhost docker]# docker images # see REPOSITORY TAG IMAGE ID CREATED SIZE busybox latest ffe9d497c324 8 days ago 1.24MB # Rename the busybox image and upload it to the newly built Harbor warehouse [root@localhost docker]# docker tag busybox:latest registry.example.com/library/busybox:latest [root@localhost docker]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE busybox latest ffe9d497c324 8 days ago 1.24MB registry.example.com/library/busybox latest ffe9d497c324 8 days ago 1.24MB # Sign in [root@localhost ~]# docker login registry.example.com Username: admin Password: # The password is the password to log in to the web interface WARNING! Your password will be stored unencrypted in /root/.docker/config.json. Configure a credential helper to remove this warning. See https://docs.docker.com/engine/reference/commandline/login/#credentials-store Login Succeeded # Upload to Harbor warehouse [root@localhost ~]# docker push registry.example.com/library/busybox:latest The push refers to repository [registry.example.com/library/busybox] 64cac9eaf0da: Pushed latest: digest: sha256:50e44504ea4f19f141118a8a8868e6c5bb9856efa33f2183f5ccea7ac62aacc9 size: 527
web interface view
Test: delete localhost Localdomain host local image, pulled from Harbor warehouse
# View before deleting [root@localhost ~]# docker images # View before deleting REPOSITORY TAG IMAGE ID CREATED SIZE busybox latest ffe9d497c324 8 days ago 1.24MB registry.example.com/library/busybox latest ffe9d497c324 8 days ago 1.24MB # Delete image registry example. com/library/busybox [root@localhost ~]# docker rmi registry.example.com/library/busybox Untagged: registry.example.com/library/busybox:latest Untagged: registry.example.com/library/busybox@sha256:50e44504ea4f19f141118a8a8868e6c5bb9856efa33f2183f5ccea7ac62aacc9 # View after deletion [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE busybox latest ffe9d497c324 8 days ago 1.24MB # Pull image from Harbor warehouse [root@localhost ~]# docker push registry.example.com/library/busybox:latest The push refers to repository [registry.example.com/library/busybox] 64cac9eaf0da: Pushed latest: digest: sha256:50e44504ea4f19f141118a8a8868e6c5bb9856efa33f2183f5ccea7ac62aacc9 size: 527 # see [root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE busybox latest ffe9d497c324 8 days ago 1.24MB registry.example.com/library/busybox latest ffe9d497c324 8 days ago 1.24MB
user management
Create a new user
Add the created harry user to the project for visitors to view
Exit and log in with the guest harry you created
Login successful, you can access
Docker compose control container
registry.example.com host operation
# Stop container [root@registry ~]# hostname registry.example.com [root@registry ~]# cd /usr/local/harbor/ [root@registry harbor]# pwd /usr/local/harbor [root@registry harbor]# docker-compose stop Stopping harbor-jobservice ... done Stopping nginx ... done Stopping harbor-core ... done Stopping harbor-db ... done Stopping registry ... done Stopping harbor-portal ... done Stopping registryctl ... done Stopping redis ... done Stopping harbor-log ... done [root@registry harbor]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Write a script to start the container when docker compose starts up
[root@registry harbor]# cat >harbor_start.sh <<EOF > #!/bin/bash > cd /usr/local/harbor > docker-compose start > EOF [root@registry harbor]# cat harbor_start.sh #!/bin/bash cd /usr/local/harbor docker-compose start [root@registry harbor]# chmod +x harbor_start.sh [root@registry harbor]# cat /etc/rc.local #!/bin/bash /bin/bash /usr/local/harbor/harbor_start.sh # add to # THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES # # It is highly advisable to create own systemd services or udev rules # to run scripts during boot instead of using this file. # # In contrast to previous versions due to parallel execution during boot # this script will NOT be run after all other services. # # Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure # that this script will be executed during boot. touch /var/lock/subsys/local [root@registry harbor]# chmod +x /etc/rc.local [root@registry harbor]# ll /etc/rc.local lrwxrwxrwx. 1 root root 13 Dec 1 2020 /etc/rc.local -> rc.d/rc.local [root@registry harbor]# ll /etc/rc.d/ total 4 drwxr-xr-x. 2 root root 37 Sep 30 05:10 init.d -rwxr-xr-x. 1 root root 518 Dec 16 04:37 rc.local
Precautions for using Harbor:
-
When uploading an image on the client, you must remember to execute docker login for user authentication, otherwise you cannot directly push
-
If https is not used on the client, it must be in / etc / docker / daemon Configure the insert registers parameter in the JSON configuration file
-
The data storage path shall be configured into a shared storage with sufficient capacity in the configuration file
-
Harbor is managed by using the docker compose command. If you need to stop harbor, you can also use docker compose stop. For other parameters, please – help