本文所指的”合体”是从技术层面将Nutanix超融合基础架构和Harbor开源镜像仓库基于企业级需求进行的一次部署实践,旨在开源热潮中抛砖引玉似的分享一些新的尝试。
企业级
标题中提到的企业级这个词,并非夸大其词博人眼球,而是Nutanix和Harbor都是这么说的…
Nutanix:实现隐形数据中心基础架构的企业级云计算公司。
The enterprise cloud company making datacenter infrastructure invisible.
注:Nutanix虽为企业提供商业化的服务,但是也很良心的发布了NCE(Nutanix Community Edition)社区版,同步商业版的主要功能且可免费长期使用,本文中的实践环境就是基于该版本。
参考:next.nutanix.com
Harbor:存储和分发Docker镜像的企业级注册服务。
An enterprise-class registry server that stores and distributes Docker images.
注:Harbor是由VMware中国研发团队负责开发的开源Docker容器镜像仓库,可帮助用户迅速搭建Registry服务。
参考:https://github.com/vmware/harbor
说到企业级,也谈一下个人浅薄的认识,也算是为此篇文章交代一下背景。
个人对企业级(特别是传统企业IT)需求的理解,离不开三点:安全、稳定和高效。这三点在企业级IT的需求中都有着举足轻重的地位,且相对而言的优先级是从前到后依次递减的。安全永远排在企业级IT需求的第一位,其次是稳定,然后是高效。
对于本次实践中,企业级需求的实现如下:
安全层面
应用安全
Harbor作为最后交付的应用/服务,使用如下方式匹配安全层面的考量:
- 使用SSL协议在传输层对网络连接进行加密,实现应用访问的安全及数据的完整。
- 自有的管理员、开发者和访客三种角色,对镜像仓库的访问实行严格的控制。
数据安全
Nutanix作为底层的基础架构,使用如下方式匹配安全层面的考量:
- 利用Nutanix ACS的Volume Plugin功能,将容器中的关键数据存放到ABS提供的存储池中,从而实现数据的持久化。
稳定层面
应用高可用
Harbor应用自身可通过多实例共享存储的方式实现高可用部署。
基础架构高可用
Nutanix的AHV虚拟化平台HA功能可实现VM层面的高可用。
PS:以上功能因环境受限(单节点),在后续的内容中没有演示。
高效层面
Harbor应用自身以容器的形式运行在Docker宿主机上,整个环境的部署基于Docker Compose来完成。在对配置文件进行定制化的修改后,可以使用一条简单的命令直接完成Harbor应用的部署和启动。
Nutanix ACS的Docker Machine Driver可实现标准化Docker宿主机的快速部署。同样也是使用一条简单的命令即可在自身的虚拟化平台或者云环境中生成一台Docker宿主机。
前戏略长,下面我们基于以上描述的功能在Nutanix的超融合环境中高效的部署出一套安全的Harbor容器镜像仓库服务。
环境准备
Docker Host
使用Nutanix Docker Machine Driver生成一台Docker宿主机
[root@docker-machine ~]# docker-machine -D create -d nutanix \ --nutanix-username admin \ --nutanix-password Admin4NCE \ --nutanix-endpoint 192.168.2.21:9440 \ --nutanix-vm-image docker \ --nutanix-vm-network Bridge \ --nutanix-vm-cores 1 \ --nutanix-vm-mem 2048 \ reg.docanix.com
可以从Nutanix Prism控制台中可看到名为reg.docanix.com的虚拟机已创建成功并启动。
Docker Engine
在Docker Host生成的同时会自动安装Docker发布的最新稳定版Engine
[root@reg ~]# docker version Client: Version: 1.12.1 API version: 1.24 Go version: go1.6.3 Git commit: 23cf638 Built: OS/Arch: linux/amd64 Server: Version: 1.12.1 API version: 1.24 Go version: go1.6.3 Git commit: 23cf638 Built: OS/Arch: linux/amd64
Docker Engine 1.12.1已成功安装并运行。
Docker Compose
安装Harbor部署所需要的Docker Compose
[root@reg ~]# curl -L https://github.com/docker/compose/releases/download/1.8.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose [root@reg ~]# chmod +x /usr/local/bin/docker-compose [root@reg ~]# docker-compose -v docker-compose version 1.8.0, build f3628c7 Docker Compose的版本为1.8.0
Python
安装Harbor部署所需要的Python 2.7或更高版本(默认已安装)
[root@reg ~]# python --version Python 2.7.5
Harbor Repo
从Github获取安装Harbor所需要的文件 [root@reg ~]# git clone https://github.com/vmware/harbor Cloning into 'harbor'... remote: Counting objects: 11888, done. remote: Total 11888 (delta 0), reused 0 (delta 0), pack-reused 11888 Receiving objects: 100% (11888/11888), 9.04 MiB | 24.00 KiB/s, done. Resolving deltas: 100% (7514/7514), done. [root@reg harbor]# pwd /root/harbor [root@reg harbor]# ls -l total 144 drwxr-xr-x. 3 root root 4096 Aug 26 02:27 api drwxr-xr-x. 4 root root 49 Aug 26 02:27 auth -rw-r--r--. 1 root root 1034 Aug 26 02:27 AUTHORS drwxr-xr-x. 4 root root 4096 Aug 26 02:27 contrib drwxr-xr-x. 2 root root 4096 Aug 26 02:27 controllers drwxr-xr-x. 2 root root 4096 Aug 26 02:27 dao drwxr-xr-x. 10 root root 4096 Sep 8 02:07 Deploy drwxr-xr-x. 3 root root 4096 Aug 26 02:27 docs -rw-r--r--. 1 root root 7455 Aug 26 02:27 favicon.ico drwxr-xr-x. 5 root root 4096 Aug 26 02:27 job drwxr-xr-x. 2 root root 36 Aug 26 02:27 jobservice -rw-r--r--. 1 root root 74372 Aug 26 02:27 LICENSE drwxr-xr-x. 3 root root 4096 Aug 26 02:27 migration drwxr-xr-x. 2 root root 4096 Aug 26 02:27 models -rw-r--r--. 1 root root 501 Aug 26 02:27 NOTICE -rw-r--r--. 1 root root 5530 Aug 26 02:27 README.md -rw-r--r--. 1 root root 2347 Aug 26 02:27 ROADMAP.md drwxr-xr-x. 5 root root 64 Aug 26 02:27 service drwxr-xr-x. 5 root root 85 Aug 26 02:27 static drwxr-xr-x. 3 root root 103 Aug 26 02:27 tests drwxr-xr-x. 2 root root 36 Aug 26 02:27 ui drwxr-xr-x. 4 root root 77 Aug 26 02:27 utils drwxr-xr-x. 4 root root 58 Aug 26 02:27 vendor drwxr-xr-x. 3 root root 4096 Aug 26 02:27 views
本文中harbor的路径为/root/harbor,compose和相关配置文件的路径为/root/harbor/Deploy
Docker Images
拉取Harbor所需要的Docker基础镜像
[root@reg ~]# docker images REPOSITORY TAG SIZE mysql 5.6 328.8 MB ubuntu 14.04 187.9 MB registry 2.5.0 33.28 MB golang 1.6.2 753.5 MB nginx 1.9 182.7 MB
PS:因在国内经常遇到网络抽风的问题,个人推荐使用业界良心的DaoCloud加速器来拉取镜像。
https://www.daocloud.io/mirror.html
附:Harbor架构简单介绍
Harbor的应用基于6个重要组件来工作,如下图:
Proxy——Harbor的registry, UI, token等服务,通过一个前置的反向代理统一接收浏览器、Docker客户端的请求,并将请求转发给后端不同的服务。
运行容器proxy: 由Nginx服务器构成的反向代理。
基础镜像: library/nginx:1.9
Registry——负责储存Docker镜像,并处理docker push/pull 命令。由于我们要对用户进行访问控制,即不同用户对Docker image有不同的读写权限,Registry会指向一个token服务,强制用户的每次docker pull/push请求都要携带一个合法的token,Registry会通过公钥对token进行解密验证。
运行容器registry: 由Docker官方的开源registry镜像构成的容器实例
基础镜像: library/registry:2.5.0
Core services——这是Harbor的核心功能,主要提供以下服务:
UI:提供图形化界面,帮助用户管理registry上的镜像(image), 并对用户进行授权。
webhook:为了及时获取registry上image状态变化的情况,在Registry上配置webhook,把状态变化传递给UI模块。
token服务:负责根据用户权限给每个push/pull请求签发token。Docker客户端向Registry服务发起的请求,如果不包含token,会被重定向到这里,获得token后再重新向Registry进行请求。
运行容器ui: 即架构中的core services, 构成此容器的代码是Harbor项目的主体。
基础镜像: library/golang:1.6.2
Database——为coreservices提供数据库服务,负责储存用户权限、审计日志、Docker image分组信息等数据。
运行容器mysql: 由官方MySql镜像构成的数据库容器。
基础镜像: library/mysql:5.6
Job Services——提供镜像远程复制功能,可以把本地镜像同步到其他Harbor实例中。
运行容器job services: 通过状态机机制实现远程镜像复制功能,包括镜像删除也可以同步到远端Harbor实例。
基础镜像: library/golang:1.6.2
Log collector——为了帮助监控Harbor运行,负责收集其他组件的log,供日后进行分析。
运行容器log: 运行着rsyslogd的容器,通过log-driver的形式收集其他容器的日志。
基础镜像: library/ubuntu:14.04
配置准备
Volume Plugin 激活Nutanix Volume Plugin [root@reg ~]# ./start-volume-plugin.sh Starting Nutanix volume plugin container... ... Enter prism ip address: 192.168.2.21 Enter Dataservices ip address: 192.168.2.23 Enter prism username: admin Enter prism password: Enter nutanix container where you want persistent volumes: docker_vol01 ... 84d093518ac075416c8c05a81877bf437f633844139fdd2a1b4e870650074b5b [root@reg ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 84d093518ac0 orionapps/vol-plugin "/code/scripts/docker" 4 minutes ago Up 4 minutes NutanixVolumePlugin
NutanixVolumePlugin作为一个容器运行在Docker宿主机。在应用相关的容器需要使用Nutanix提供外接Volume的时候则会调用该容器并在Nutanix的ABS存储池中创建需要的Volume。
SSL证书
生成自签发的SSL证书
[root@reg ~]# openssl req \ > -newkey rsa:4096 -nodes -sha256 -keyout ca.key \ > -x509 -days 365 -out ca.crt Generating a 4096 bit RSA private key ... Country Name (2 letter code) [XX]:CN State or Province Name (full name) []:Hubei Locality Name (eg, city) [Default City]:Wuhan Organization Name (eg, company) [Default Company Ltd]:Docanix Organizational Unit Name (eg, section) []:DevOps Common Name (eg, your name or your server's hostname) []:reg.docanix.com Email Address []:admin@docanix.com [root@reg ~]# ls -l total 16 -rw-r--r--. 1 root root 2114 Aug 26 03:26 ca.crt -rw-r--r--. 1 root root 3272 Aug 26 03:26 ca.key
证书相关信息按需填写,需要注意server’s hostname
Harbor配置
激活SSL
激活Harbor的SSL功能
[root@reg Deploy]# pwd /root/harbor/Deploy [root@reg Deploy]# vi harbor.cfg hostname = reg.docanix.com ui_url_protocol = https
激活Proxy的SSL功能
[root@reg cert]# pwd /root/harbor/Deploy/config/nginx/cert [root@reg cert]# cp ~/ca.crt ~/ca.key . [root@reg cert]# ls ca.crt ca.key
(以上为拷贝证书到nginx的证书目录)
[root@reg nginx]# pwd /root/harbor/Deploy/config/nginx [root@reg nginx]# ls cert nginx.conf nginx.https.conf [root@reg nginx]# mv nginx.conf nginx.conf.bak [root@reg nginx]# cp nginx.https.conf nginx.conf [root@reg nginx]# ls cert nginx.conf nginx.conf.bak nginx.https.conf
(以上为备份并生成nginx配置文件)
[root@reg nginx]# vi nginx.conf server { listen 443 ssl; server_name reg.docanix.com; # SSL ssl_certificate /etc/nginx/cert/ca.crt; ssl_certificate_key /etc/nginx/cert/ca.key; server { listen 80; server_name reg.docanix.com; rewrite ^/(.*) https://$server_name:443/$1 permanent;
nginx的配置文件中需要修改server_name和ssl_certificate相关的参数
为Docker客户端配置证书
(本例Docker客户端和Harbor服务端为同一台Docker宿主机)
[root@reg ~]# mkdir /etc/docker/certs.d/reg.docanix.com [root@reg ~]# cp ~/ca.crt /etc/docker/certs.d/reg.docanix.com [root@reg reg.docanix.com]# pwd /etc/docker/certs.d/reg.docanix.com [root@reg reg.docanix.com]# ls ca.crt
如果不配置证书则在登录Harbor Registry的时候会出现如下报错:
Error response from daemon: Get https://reg.docanix.com/v1/users/: x509: certificate signed by unknown authority
配置证书后就不需要在Docker Daemon里面添加insecure-registry参数了。
修改Compose文件
Harbor的Compose文件为v2版本,默认会将核心服务的数据放到本地,我们需要将数据放到Nutanix提供的存储池中。
[root@reg Deploy]# pwd /root/harbor/Deploy [root@reg Deploy]# vi docker-compose.yml registry: volumes: - harborreg:/storage mysql: volumes: - harbordb:/var/lib/mysql jobservice: volumes: - harborjob:/var/log/jobs
(以上为registry、mysql和jobservice三个核心容器需要挂载的harborreg、harbordb和harborjob三个外部卷)
volumes: harbordb: driver: nutanix harborreg: driver: nutanix harborjob: driver: nutanix
(以上为volumes声明,指定driver为nutanix来实现voulume在Nutanix ABS存储池上的创建)
注: 由于Compose v2在启动的时候会默认在每个对象(容器、网络、数据卷等)前面打上一个以当前执行路径命名的前缀,而且该前缀后面还会加上”_”符号(本例为”deploy_”),但是NutanixVolumePlugin创建的iSCSI目标端不识别”_”这类字符。
本人也暂时没有找到指定外部的Volume不加这个前缀的办法,所以将docker-compose.yml用v1的语法重写了一遍。
[root@reg Deploy]# vi docker-compose.yml jobservice: volume_driver: nutanix volumes: - harborjob:/var/log/jobs - /root/harbor/Deploy/config/jobservice/app.conf:/etc/jobservice/app.conf mysql: volume_driver: nutanix volumes: - harbordb:/var/lib/mysql registry: volume_driver: nutanix volumes: - harborreg:/storage - /root/harbor/Deploy/config/registry/:/etc/registry/
以上仅截取了volume相关的内容,需要注意的是本地文件系统的目录或者文件需要以绝对路径的形式挂载。
配置准备
完成部署准备
绑定安装Harbor需要的环境变量配置
[root@reg Deploy]# ./prepare Generated configuration file: ./config/ui/env Generated configuration file: ./config/ui/app.conf Generated configuration file: ./config/registry/config.yml Generated configuration file: ./config/db/env Generated configuration file: ./config/jobservice/env Clearing the configuration file: ./config/ui/private_key.pem Clearing the configuration file: ./config/registry/root.crt Generated configuration file: ./config/ui/private_key.pem Generated configuration file: ./config/registry/root.crt The configuration files are ready, please use docker-compose to start the service.
启动Harbor
基于编辑完成的compose yml文件直接启动Harbor
[root@reg Deploy]# docker-compose up -d Creating deploy_log_1 Creating deploy_mysql_1 Creating deploy_ui_1 Creating deploy_registry_1 Creating deploy_jobservice_1 Creating deploy_proxy_1
(第一次启动会build镜像,时间上面会略微长一点)
[root@reg Deploy]# docker ps CONTAINER ID IMAGE NAMES 7a4b29047c27 library/nginx:1.9 deploy_proxy_1 14baedbd5e94 deploy_jobservice:latest deploy_jobservice_1 08924e20090f library/registry:2.5.0 deploy_registry_1 3c184808a93f deploy_ui:latest deploy_ui_1 4b3825bf1935 deploy_mysql:latest deploy_mysql_1 82c6a21afeed deploy_log:latest deploy_log_1
可以看到前面提到Harbor服务需要的6个容器已经成功启动(为方便观看仅截取了部分输出)
功能测试
Volume验证
查看定义的Nutanix Volume是否创建成功
可以看到我们之前定义的harborreg(registry),harborjob(jobservice)和harbordb(mysql)三个外部的volume已自动创建成功。这意味着三个核心服务的数据将存放到Nutanix ABS的存储池中,从而实现了关键数据的持久化。
UI访问测试
访问Harbor的Web UI,本例为https://reg.docanix.com
UI登录测试
尝试登录到Harbor UI,默认用户名和密码为admin/Harbor12345
UI仓库列表
Harbor在部署完成后会自动创建一个名为library的镜像仓库,Harbor里的命名为Project
Registry登录测试
[root@reg ~]# docker login reg.docanix.com Username: admin Password: Login Succeeded
镜像推送测试
以推送一个busybox镜像为例
[root@reg ~]# docker tag busybox:latest reg.docanix.com/library/busybox:1.0 [root@reg ~]# docker images |grep busybox reg.docanix.com/library/busybox 1.0 2b8fd9751c4c 10 weeks ago 1.093 MB [root@reg ~]# docker push reg.docanix.com/library/busybox:1.0 The push refers to a repository [reg.docanix.com/library/busybox] 8ac8bfaff55a: Pushed latest: digest: sha256:1359608115b94599e5641638bac5aef1ddfaa79bb96057ebf41ebc8d33acf8a7 size: 527
通过UI可以看到busybox在推送成功后已在library中存在
镜像拉取测试
以拉取之前所推送的busybox镜像为例
[root@reg ~]# docker rmi reg.docanix.com/library/busybox:1.0 Untagged: reg.docanix.com/library/busybox:latest [root@reg ~]# docker pull reg.docanix.com/library/busybox:1.0 latest: Pulling from library/busybox Digest: sha256:1359608115b94599e5641638bac5aef1ddfaa79bb96057ebf41ebc8d33acf8a7 Status: Downloaded newer image for reg.docanix.com/library/busybox:latest [root@reg ~]# docker images |grep busybox reg.docanix.com/library/busybox 1.0 2b8fd9751c4c 10 weeks ago 1.093 MB
删除后的busybox镜像在经过再次拉取后已在本地存在
至此基于企业级IT需求在Nutanix超融合基础架构部署Harbor开源Docker镜像仓库的一次简单实践已经完成。
评论前必须登录!
注册