Docker 私有Registry
Registry用于保存docker镜像,包括镜像的层次结构和元数据。用户可以自建Registry,也可使用官方的Docker Hub。
Docker Registry 分类:
- Sponsor Registry: 第三方的registry,供客户和Docker社区使用
- Mirror Registry: 第三方的registryy,只让客户使用
- Vendor Registry: 由发布Docker镜像的供应商提供的registry
- Private Registry: 通过设有防火墙和额外的安全层的私有实体提供的registry
私有Registry
使用前先要将服务部署到服务器上。
YUM安装
可以通过yum安装:
yum install docker-registryyum install docker-distribution上面两个命令都会安装docker-distribution只要执行一个就好了。
软件包的信息:
[root@Docker ~]# yum info docker-distribution已加载插件:fastestmirrorLoading mirror speeds from cached hostfile * base: mirrors.aliyun.com * extras: mirrors.aliyun.com * updates: mirrors.aliyun.com可安装的软件包名称 :docker-distribution架构 :x86_64版本 :2.6.2发布 :2.git48294d9.el7大小 :3.5 M源 :extras/7/x86_64简介 : Docker toolset to pack, ship, store, and deliver content网址 :https://github.com/docker/distribution协议 : ASL 2.0描述 : Docker toolset to pack, ship, store, and deliver content[root@Docker ~]# 这个就不装了,因为还可以将服务安装在容器中运行。
容器安装
docker官方也提供了容器,基于容器提供Registry服务。
下载镜像:
[root@Docker ~]# docker image pull registryUsing default tag: latestlatest: Pulling from library/registryc87736221ed0: Pull complete 1cc8e0bb44df: Pull complete 54d33bcb37f5: Pull complete e8afc091c171: Pull complete b4541f6d3db6: Pull complete Digest: sha256:8004747f1e8cd820a148fb7499d71a76d45ff66bac6a29129bfdbfdc0154d146Status: Downloaded newer image for registry:latest[root@Docker ~]# 启动容器:
docker run -d -p 5000:5000 --restart always --name registry registry配置文件
查看registry的配置文件:
[root@Docker ~]# docker container exec -it registry cat /etc/docker/registry/config.ymlversion: 0.1log: fields: service: registrystorage: cache: blobdescriptor: inmemory filesystem: rootdirectory: /var/lib/registryhttp: addr: :5000 headers: X-Content-Type-Options: [nosniff]health: storagedriver: enabled: true interval: 10s threshold: 3[root@Docker ~]# 这里是默认的配置文件。配置文件是通过CMD命令指定的,默认的dockerfile的CMD指令如下:
CMD ["/etc/docker/registry/config.yml"]镜像存放的位置
镜像Dockerfile中有一条VOLUME指令,这个路径就是容器是存放镜像的路径:
VOLUME ["/var/lib/registry"]启动镜像时,可以使用-v参数,指定宿主机的目录。
上传镜像
上传镜像前,先要给镜像打标:
[root@Docker ~]# docker push busybox loclhost:5000/busybox这里要准备将本地的busybox推送到服务器loclhost:5000。这里省略了仓库的用户名,没有用户名就是一个顶层仓库。
推送:
[root@Docker ~]# docker push localhost:5000/busyboxThe push refers to repository [localhost:5000/busybox]0d315111b484: Pushed latest: digest: sha256:895ab622e92e18d6b461d671081757af7dbaa3b00e3e28e12505af7817f73649 size: 527[root@Docker ~]# 不往本机lo接口推,也就是服务器地址不使用localhost或127.0.0.1。而是向本机的网卡地址推。就像其他主机要向本机的registry推送一样了。然后会产生如下的错误:
[root@Docker ~]# docker push 192.168.24.170:5000/busyboxThe push refers to repository [192.168.24.170:5000/busybox]Get https://192.168.24.170:5000/v2/: http: server gave HTTP response to HTTPS client[root@Docker ~]# 这里的问题是,docker默认是使用https协议工作的,而registry服务器的响应是http协议。解决的办法有两个。
第一个方法是修改registry来适应docker,registry服务器改为https协议
第二个方法是修改docker来使用registry,将registry服务器地址加入到docker的insecure-registries中去
配置insecure-registries
修改配置文件,然后重启加载后就可以推送上去了:
[root@Docker ~]# cat /etc/docker/daemon.json{ "registry-mirrors": ["http://hub-mirror.c.163.com", "https://docker.mirrors.ustc.edu.cn"], "insecure-registries": ["192.168.24.170:5000"]}[root@Docker ~]# systemctl reload docker[root@Docker ~]# docker push 192.168.24.170:5000/busyboxThe push refers to repository [192.168.24.170:5000/busybox]0d315111b484: Layer already exists latest: digest: sha256:895ab622e92e18d6b461d671081757af7dbaa3b00e3e28e12505af7817f73649 size: 527[root@Docker ~]# 下载镜像
指定Registry下载之前上传的镜像:
[root@Docker ~]# docker pull 192.168.24.170:5000/busyboxUsing default tag: latestlatest: Pulling from busyboxee153a04d683: Pull complete Digest: sha256:895ab622e92e18d6b461d671081757af7dbaa3b00e3e28e12505af7817f73649Status: Downloaded newer image for 192.168.24.170:5000/busybox:latest[root@Docker ~]# Harbor
Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器。
Harbor特性
基于角色的访问控制:用户与Docker镜像仓库通过"项目"进行组织管理,一个用户可以对多个镜像仓库在同一命名空间(project)里有不同的权限。
镜像复制:镜像可以在多个Registry实例中复制(同步)。尤其适合于负载均衡,高可用,混合云和多云的场景。
图形化用户界面:用户可以通过浏览器来浏览,检索当前Docker镜像仓库,管理项目和命名空间。
AD/LDAP 支持:Harbor可以集成企业内部已有的AD/LDAP,用于鉴权认证管理。
审计管理:所有针对镜像仓库的操作都可以被记录追溯,用于审计管理。
国际化:已拥有英文、中文、德文、日文和俄文的本地化版本。更多的语言将会添加进来。
RESTful API:RESTful API 提供给管理员对于Harbor更多的操控, 使得与其它管理软件集成变得更容易。
部署简单:提供在线和离线两种安装工具, 也可以安装到vSphere平台(OVA方式)虚拟设备。
安装准备
github项目地址:
https://github.com/vmware/harbor
这是一个vmware的开源项目,实际会跳转到下面这个地址:
https://github.com/goharbor/harbor
下载 harbor
查看项目的README,Features的内容上面提过了,这里主要看Install & Run部分的内容。
首先是下载
Harbor release:
https://github.com/goharbor/harbor/releases
$ wget https://storage.googleapis.com/harbor-releases/release-1.8.0/harbor-offline-installer-v1.8.2-rc1.tgz安装配置向导
Installation & Configuration Guide:
https://github.com/goharbor/harbor/blob/master/docs/installation_guide.md
硬件要求:
| Resource | Capacity | Description |
|---|---|---|
| CPU | minimal 2 CPU | 4 CPU is preferred |
| Mem | minimal 4GB | 8GB is preferred |
| Disk | minimal 40GB | 160GB is preferred |
软件要求:
| Software | Version | Description |
|---|---|---|
| Docker engine | version 17.06.0-ce+ or higher | For installation instructions, please refer to: docker engine doc |
| Docker Compose | version 1.18.0 or higher | For installation instructions, please refer to: docker compose doc |
| Openssl | latest is preferred | Generate certificate and keys for Harbor |
安装步骤:
- Download the installer;
- Configure harbor.yml;
- Run install.sh to install and start Harbor;
下载完之后,先解压:
[root@Harbor ~]# tar xvf harbor-offline-installer-v1.8.1.tar -C /optharbor/harbor.v1.8.1.tar.gzharbor/prepareharbor/LICENSEharbor/install.shharbor/harbor.yml[root@Harbor ~]# 下载的文件在解压后就不需要了。解压后的文件在安装完成后也都是不需要的。所以下载到哪里,解压到哪里其实都不重要。建议可以解压到 /opt 或 /usr/local 这两个目录里。
安装包中的镜像
解压后的文件中,有一个文件harbor.v1.8.1.tar.gz。这个是被导出的docker镜像。还记得docker save命令吧,可以打包导出多个镜像并完成压缩:
$ docker save myimg/httpd:v1 myimg/httpd:v2 | gzip > myimage_latest.tar.gz这个文件应该就是这么来的。之后的安装过程中,则是会把这个文件里的所有镜像做一次批量导入:
$ docker load -i myimage_latest.tar.gz在安装时执行的install.sh脚本里有解压并导入镜像的语句:
if [ -f harbor*.tar.gz ]then h3 "[Step $item]: loading Harbor images ..."; let item+=1 docker load -i ./harbor*.tar.gzfi安装的依赖和过程
Harbor的安装,就是给当前的主机安装很多容器,并且把这些容器都启动起来。启动Harbor就是用docker-compose把这些容器的启动起来,而关闭harbor也是通过docker-compose来把容器一次关闭。之所以需要借助docker-compose,因为harbor是由很多容器协同过程的,容器之间又依赖关系,这些都需要docker-compose这个单机编排工具来协调。
所以安装harbor前,需要安装好docker-compose,才能实现本地的容器的编排。需要安装好docker,才能把本地的镜像启动起来。镜像就在下载解压的文件中。并且还需要启动docker,这样才能运行容器。
准备工作完成后,就是执行harbor准备的install.sh脚本,在本地加载好镜像,通过docker-compose把这些镜像依次启动起来,并且运行在本地的docker上。
修改harbor.yml配置文件,主机名一定看改掉,最好使用本机的域名,如果没有域名那么就用本机的IP地址。没改的话,会有如下的错误提示:
[root@Harbor harbor]# ./install.sh ➜ Please set hostname and other necessary attributes in harbor.yml first. DO NOT use localhost or 127.0.0.1 for hostname, because Harbor needs to be accessed by external clients.Please set --with-notary if needs enable Notary in Harbor, and set ui_url_protocol/ssl_cert/ssl_cert_key in harbor.yml bacause notary must run under https. Please set --with-clair if needs enable Clair in HarborPlease set --with-chartmuseum if needs enable Chartmuseum in Harbor[root@Harbor harbor]# 检查发现没有安装docker:
[root@Harbor harbor]# ./install.sh [Step 0]: checking installation environment ...✖ Need to install docker(17.06.0+) first and run this script again.[root@Harbor harbor]# 检查发现没有安装docker-compose:
[root@Harbor harbor]# ./install.sh [Step 0]: checking installation environment ...Note: docker version: 19.03.1✖ Need to install docker-compose(1.18.0+) by yourself first and run this script again.[root@Harbor harbor]# 检查发现docker没有启动:
[root@Harbor harbor]# ./install.sh [Step 0]: checking installation environment ...Note: docker version: 19.03.1Note: docker-compose version: 1.18.0[Step 1]: loading Harbor images ...Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?[root@Harbor harbor]# Docker Compose
Docker的单机编排工具。官方文档:
https://docs.docker.com/compose/
为了简化harbor的安装和部署,所以harbor做成了在容器中运行的应用。但是harbor的运行还依赖很多其他的应用,所以需要编排几个容器来协同工作。所以harbor的部署和使用时需要借助Docker的单机编排工具Docker Compose。
安装docker-compose,位于epel源中:
yum install docker-composeCompose模板文件
模板文件是使用Compose的核心,设计的指令关键字也有很多,默认的模板文件名称为docker-compose.yml,格式为YAML格式。
这个不是重点,能安装使用harbor就好了,不过还是简单了解一下。
要使用docker-compose就要写一个编排脚本,和dockerfile类似,也是有很多指令。定义要启动的每一个容器,指明依赖关系,这样被依赖的容器需要先启动。关闭容器的时候也要对称,先把没有被依赖的容器关闭掉。
顺便就来看下harbor的docker-compose.yml文件:
[root@Harbor harbor]# cat docker-compose.yml version: '2.3' # docker-compose的版本services: # 定义一个服务 log: # 服务的名称,服务是通过容器来提供的,具体就是下面的设置 image: goharbor/harbor-log:v1.8.1 # 指定容器的镜像,也可以用build指令通过dockerfile创建 container_name: harbor-log # 生成的容器的名称 restart: always # 容器自动重启 dns_search: . cap_drop: - ALL cap_add: - CHOWN - DAC_OVERRIDE - SETGID - SETUID volumes: # 定义卷 - /var/log/harbor/:/var/log/docker/:z - ./common/config/log/:/etc/logrotate.d/:z ports: - 127.0.0.1:1514:10514 networks: # 加入的网络 - harbor registry: image: goharbor/registry-photon:v2.7.1-patch-2819-v1.8.1 container_name: registry restart: always cap_drop: - ALL cap_add: - CHOWN - SETGID - SETUID volumes: - /data/registry:/storage:z - ./common/config/registry/:/etc/registry/:z - type: bind source: /data/secret/registry/root.crt target: /etc/registry/root.crt networks: - harbor dns_search: . depends_on: # 依赖的容器名称 - log logging: driver: "syslog" options: syslog-address: "tcp://127.0.0.1:1514" tag: "registry" registryctl: image: goharbor/harbor-registryctl:v1.8.1 container_name: registryctl env_file: - ./common/config/registryctl/env restart: always cap_drop: - ALL cap_add: - CHOWN - SETGID - SETUID volumes: - /data/registry:/storage:z - ./common/config/registry/:/etc/registry/:z - type: bind source: ./common/config/registryctl/config.yml target: /etc/registryctl/config.yml networks: - harbor dns_search: . depends_on: - log logging: driver: "syslog" options: syslog-address: "tcp://127.0.0.1:1514" tag: "registryctl" postgresql: image: goharbor/harbor-db:v1.8.1 container_name: harbor-db restart: always cap_drop: - ALL cap_add: - CHOWN - DAC_OVERRIDE - SETGID - SETUID volumes: - /data/database:/var/lib/postgresql/data:z networks: harbor: dns_search: . env_file: - ./common/config/db/env depends_on: - log logging: driver: "syslog" options: syslog-address: "tcp://127.0.0.1:1514" tag: "postgresql" core: image: goharbor/harbor-core:v1.8.1 container_name: harbor-core env_file: - ./common/config/core/env restart: always cap_drop: - ALL cap_add: - SETGID - SETUID volumes: - /data/ca_download/:/etc/core/ca/:z - /data/psc/:/etc/core/token/:z - /data/:/data/:z - ./common/config/core/certificates/:/etc/core/certificates/:z - type: bind source: ./common/config/core/app.conf target: /etc/core/app.conf - type: bind source: /data/secret/core/private_key.pem target: /etc/core/private_key.pem - type: bind source: /data/secret/keys/secretkey target: /etc/core/key networks: harbor: dns_search: . depends_on: - log - registry logging: driver: "syslog" options: syslog-address: "tcp://127.0.0.1:1514" tag: "core" portal: image: goharbor/harbor-portal:v1.8.1 container_name: harbor-portal restart: always cap_drop: - ALL cap_add: - CHOWN - SETGID - SETUID - NET_BIND_SERVICE networks: - harbor dns_search: . depends_on: - log - core logging: driver: "syslog" options: syslog-address: "tcp://127.0.0.1:1514" tag: "portal" jobservice: image: goharbor/harbor-jobservice:v1.8.1 container_name: harbor-jobservice env_file: - ./common/config/jobservice/env restart: always cap_drop: - ALL cap_add: - CHOWN - SETGID - SETUID volumes: - /data/job_logs:/var/log/jobs:z - type: bind source: ./common/config/jobservice/config.yml target: /etc/jobservice/config.yml networks: - harbor dns_search: . depends_on: - redis - core logging: driver: "syslog" options: syslog-address: "tcp://127.0.0.1:1514" tag: "jobservice" redis: image: goharbor/redis-photon:v1.8.1 container_name: redis restart: always cap_drop: - ALL cap_add: - CHOWN - SETGID - SETUID volumes: - /data/redis:/var/lib/redis networks: harbor: dns_search: . depends_on: - log logging: driver: "syslog" options: syslog-address: "tcp://127.0.0.1:1514" tag: "redis" proxy: image: goharbor/nginx-photon:v1.8.1 container_name: nginx restart: always cap_drop: - ALL cap_add: - CHOWN - SETGID - SETUID - NET_BIND_SERVICE volumes: - ./common/config/nginx:/etc/nginx:z networks: - harbor dns_search: . ports: - 80:80 depends_on: - postgresql - registry - core - portal - log logging: driver: "syslog" options: syslog-address: "tcp://127.0.0.1:1514" tag: "proxy"networks: harbor: external: false[root@Harbor harbor]# 安装 Harbor
安装前,需要去修改一下harbor.yml这个文件的配置,至少要把主机名改掉,之前已经说过了。其他配置按需要修改,不改也能够安装了。
一切准备就行,就可以安装了:
[root@Harbor harbor]# ./install.sh [Step 0]: checking installation environment ...Note: docker version: 19.03.1Note: docker-compose version: 1.18.0[Step 1]: loading Harbor images ...ba58b7bb3f17: Loading layer 33.32MB/33.32MB......略过......Loaded image: goharbor/clair-photon:v2.0.8-v1.8.1[Step 2]: preparing environment ...prepare base dir is set to /opt/harborGenerated configuration file: /config/log/logrotate.conf......略过......Generated certificate, key file: /secret/core/private_key.pem, cert file: /secreCreating harbor-log ... doneGenerated configuration file: /compose_location/docker-compose.ymlClean up the input dirCreating registry ... doneCreating harbor-core ... done[Step 3]: starting Harbor ...Creating harbor-portal ... doneCreating nginx ... doneCreating harbor-db ... Creating redis ... Creating registryctl ... Creating registry ... Creating harbor-core ... Creating harbor-portal ... Creating harbor-jobservice ... Creating nginx ... ✔ ----Harbor has been installed and started successfully.----Now you should be able to visit the admin portal at http://HarborStudy. For more details, please visit https://github.com/goharbor/harbor .[root@Harbor harbor]# 安装成功,可以看看监听的端口,安装了哪些镜像,启动了哪些容器:
$ ss -tnl$ docker images$ docker ps登录 Harbor
默认的密码在harbor.yml有设置的:
harbor_admin_password: Harbor12345用户名是admin,密码没改的话就是默认的,可以登录进去。
使用浏览器访问Web页面,可以看到一些管理界面。
另外要上传或下载镜像,需要在命令行使用docker命令,在那之前也需要登录Harbor,使用docker login命令来完成登录:
[root@Harbor harbor]# docker login localhostUsername: adminPassword: WARNING! Your password will be stored unencrypted in /root/.docker/config.json.Configure a credential helper to remove this warning. Seehttps://docs.docker.com/engine/reference/commandline/login/#credentials-storeLogin Succeeded[root@Harbor harbor]# 登录成功之后,才能推送镜像。
停止 Harbor
要想停止或启动harbor,需要通过docker-compose命令。
在操作之前,最好先切换目录到要操作的docker-compose.yml所在的目录,这样docker-compose能够自动找到模板文件并进行操作。
停止harbor:
[root@Harbor harbor]# cd /opt/harbor/[root@Harbor harbor]# docker-compose stopStopping nginx ... doneStopping harbor-portal ... doneStopping harbor-jobservice ... doneStopping harbor-core ... doneStopping registryctl ... doneStopping harbor-db ... doneStopping registry ... doneStopping redis ... doneStopping harbor-log ... done[root@Harbor harbor]# 然后再次启动:
[root@Harbor harbor]# docker-compose startStarting log ... doneStarting registry ... doneStarting registryctl ... doneStarting postgresql ... doneStarting core ... doneStarting portal ... doneStarting redis ... doneStarting jobservice ... doneStarting proxy ... done[root@Harbor harbor]#