Compose 支持 Linux、macOS、Windows 10 三大平台。在 Linux 上的也安装十分简单,从 官方 GitHub Release 处直接下载编译好的二进制文件即可。
curl -L https://github.com/docker/compose/releases/download/1.24.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-composechmod +x /usr/local/bin/docker-composedocker-compose version# 输出如下docker-compose version 1.24.0, build 0aa59064docker-py version: 3.7.2CPython version: 3.6.8OpenSSL version: OpenSSL 1.1.0j 20 Nov 2018
首先介绍几个术语。
可见,一个项目可以由多个服务(容器)关联而成,Compose 面向项目进行管理。
最常见的项目是 Web 网站,该项目应该包含 Web 应用和缓存。下面我们用 Python 来建立一个能够记录页面访问次数的 Web 网站。
新建文件夹,在该目录中编写 app.py 文件
from flask import Flaskfrom redis import Redisapp = Flask(__name__)redis = Redis(host='redis', port=6379)@app.route('/')def hello():count = redis.incr('hits')return 'Hello World! 该页面已被访问 {} 次。\n'.format(count)if __name__ == "__main__":app.run(host="0.0.0.0", debug=True)编写 Dockerfile 文件,内容为
FROM python:3.6-alpineADD . /codeWORKDIR /codeRUN pip install redis flaskCMD ["python", "app.py"]编写 docker-compose.yml 文件,这个是 Compose 使用的主模板文件。
version: '3'services:web:build: .ports:- "5000:5000"redis:image: "redis:alpine"docker-compose up -d此时访问本地 5000 端口,每次刷新页面,计数就会加 1。
YAML 是专门用来写配置文件的语言,非常简洁和强大,远比 JSON 格式方便。YAML 语言的设计目标,就是方便人类读写。它实质上是一种通用的数据串行化格式。它的基本语法规则如下:
# 表示注释,从这个字符一直到行尾,都会被解析器忽略。YAML 支持的数据结构有三种:
YAML 对象
对象的一组键值对,使用冒号结构表示
animal: petsYAML 数组
一组连词线开头的行,构成一个数组
- Cat- Dog- Goldfish数据结构的子成员是一个数组,则可以在该项下面缩进一个空格
- Array- Cat- Dog- GoldfishYAML 复合结构
对象和数组可以结合使用,形成复合结构
languages:- Ruby- Perl- Python websites:YAML: yaml.org Ruby: ruby-lang.org Python: python.org Perl: use.perl.org YAML 纯量
纯量是最基本的、不可再分的值。以下数据类型都属于 JavaScript 的纯量
课程演示会采用多虚拟机模拟分布式场景,为防止 IP 冲突,无法联网等问题,需要预先设置好主机名、IP、DNS 配置
修改主机名
vi /etc/cloud/cloud.cfg# 该配置默认为 false,修改为 true 即可preserve_hostname: true# 修改主机名hostnamectl set-hostname deployment# 配置 hostscat >> /etc/hosts << EOF192.168.141.130 deploymentEOF修改 IP
编辑 vi /etc/netplan/50-cloud-init.yaml 配置文件,修改内容如下
network:ethernets:ens33:addresses: [192.168.141.130/24]gateway4: 192.168.141.2nameservers:addresses: [192.168.141.2]version: 2使用 netplan apply 命令让配置生效
修改 DNS
# 取消 DNS 行注释,并增加 DNS 配置如:114.114.114.114,修改后重启下计算机vi /etc/systemd/resolved.confversion: '3.1'services:tomcat:restart: alwaysimage: tomcatcontainer_name: tomcatports:- 8080:8080volumes:- ./webapps:/usr/local/tomcat/webappsenvironment:TZ: Asia/Shanghaiversion: '3.1'services:db:# 目前 latest 版本为 MySQL8.ximage: mysqlrestart: alwaysenvironment:MYSQL_ROOT_PASSWORD: 123456command:--default-authentication-plugin=mysql_native_password--character-set-server=utf8mb4--collation-server=utf8mb4_general_ci--explicit_defaults_for_timestamp=true--lower_case_table_names=1ports:- 3306:3306volumes:- ./data:/var/lib/mysql# MySQL 的 Web 客户端adminer:image: adminerrestart: alwaysports:- 8080:8080GitLab 是利用 Ruby on Rails 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面进行访问公开的或者私人项目。它拥有与 Github 类似的功能,能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库。团队成员可以利用内置的简单聊天程序 (Wall) 进行交流。它还提供一个代码片段收集功能可以轻松实现代码复用,便于日后有需要的时候进行查找。
我们使用 Docker 来安装和运行 GitLab 中文版,docker-compose.yml 配置如下:
version: '3'services:web:image: 'twang2218/gitlab-ce-zh'restart: alwayshostname: '192.168.75.145'environment:TZ: 'Asia/Shanghai'GITLAB_OMNIBUS_CONFIG: |external_url 'http://192.168.75.145'gitlab_rails['gitlab_shell_ssh_port'] = 2222unicorn['port'] = 8888nginx['listen_port'] = 80ports:- '80:80'- '443:443'- '2222:22'volumes:- ./config:/etc/gitlab- ./data:/var/opt/gitlab- ./logs:/var/log/gitlab我们使用 Docker 来安装和运行 Nexus,docker-compose.yml 配置如下:
version: '3.1'services:nexus:restart: alwaysimage: sonatype/nexus3container_name: nexusports:- 80:8081volumes:- data:/nexus-datavolumes:data:注意: 新版本密码在
cat /var/lib/docker/volumes/nexus_data/_data/admin.password
通常包含了多个代理仓库和宿主仓库,在项目中只要引入仓库组就可以下载到代理仓库和宿主仓库中的包
在 Maven settings.xml 中添加 Nexus 认证信息 (servers 节点下)
nexus-releases admin admin123 nexus-snapshots admin admin123 Release 版本与 Snapshot 定义
Release: 1.0.0/1.0.0-RELEASESnapshot: 1.0.0-SNAPSHOTpom.xml 中设置的版本号添加 SNAPSHOT 标识的都会发布为 SNAPSHOT 版本,没有 SNAPSHOT 标识的都会发布为 RELEASE 版本。SNAPSHOT 版本会自动加一个时间作为标识,如:1.0.0-SNAPSHOT 发布后为变成 1.0.0-SNAPSHOT-20180522.123456-1.jar在 pom.xml 中添加如下代码
nexus-releases Nexus Release Repository http://127.0.0.1:8081/repository/maven-releases/ nexus-snapshots Nexus Snapshot Repository http://127.0.0.1:8081/repository/maven-snapshots/ 注意事项
settings.xml 中 Servers 配置的 ID 名称保持一致SNAPSHOT 标识的,会发布到 Nexus Snapshots Repository, 否则发布到 Nexus Release Repository,并根据 ID 去匹配授权账号mvn deploynexus Nexus Repository http://127.0.0.1:8081/repository/maven-public/ true true nexus Nexus Plugin Repository http://127.0.0.1:8081/repository/maven-public/ true true Nexus 3.1.x 开始支持页面上传第三方依赖功能,以下为手动上传命令
# 如第三方JAR包:aliyun-sdk-oss-2.2.3.jarmvn deploy:deploy-file -DgroupId=com.aliyun.oss -DartifactId=aliyun-sdk-oss -Dversion=2.2.3 -Dpackaging=jar -Dfile=D:\aliyun-sdk-oss-2.2.3.jar -Durl=http://127.0.0.1:8081/repository/maven-3rd/ -DrepositoryId=nexus-releases注意事项
-DrepositoryId=nexus-releases 对应的是 settings.xml 中 Servers 配置的 ID 名称。(授权)官方 GitHub 上下载最新离线安装版(我已经下载并放置在群分享的 Linux 目录下)并上传至服务器
tar -zxvf harbor-offline-installer-v1.8.0.tgz# 输出如下harbor/harbor.v1.8.0.tar.gzharbor/prepareharbor/LICENSEharbor/install.shharbor/harbor.ymlvi harbor.yml# 修改为域名或你服务器 IPhostname: 192.168.141.150./install.sh# 输出如下[Step 0]: checking installation environment ...Note: docker version: 18.09.6Note: docker-compose version: 1.24.0[Step 1]: loading Harbor images ...23d9f72a5270: Loading layer [==================================================>] 33.25MB/33.25MB1d4a1da12c02: Loading layer [==================================================>] 50.51MB/50.51MB8eb1a006f3b0: Loading layer [==================================================>] 3.584kB/3.584kB41b6f75847f4: Loading layer [==================================================>] 3.072kB/3.072kBec9bd6e4d4e8: Loading layer [==================================================>] 2.56kB/2.56kB6d852bb664c2: Loading layer [==================================================>] 3.072kB/3.072kB0e4ed2b5a5b8: Loading layer [==================================================>] 3.584kB/3.584kB8dfb2b644f30: Loading layer [==================================================>] 12.29kB/12.29kBLoaded image: goharbor/harbor-log:v1.8.0d8c53538042b: Loading layer [==================================================>] 63.34MB/63.34MB1b5fb7ee22e0: Loading layer [==================================================>] 47.96MB/47.96MBa8bdca5e9d71: Loading layer [==================================================>] 6.656kB/6.656kBf7cec940b52c: Loading layer [==================================================>] 2.048kB/2.048kB301a4a2af7db: Loading layer [==================================================>] 7.68kB/7.68kBe588e1e3a775: Loading layer [==================================================>] 2.56kB/2.56kB539f28a5d0ea: Loading layer [==================================================>] 2.56kB/2.56kB8b4a72241226: Loading layer [==================================================>] 2.56kB/2.56kBLoaded image: goharbor/harbor-db:v1.8.0c88db349fb2f: Loading layer [==================================================>] 8.972MB/8.972MB1f2d4d72bba2: Loading layer [==================================================>] 35.77MB/35.77MBdddbcf598df5: Loading layer [==================================================>] 2.048kB/2.048kB0ced476c2d9c: Loading layer [==================================================>] 3.072kB/3.072kBaf24eb0bf40b: Loading layer [==================================================>] 35.77MB/35.77MBLoaded image: goharbor/chartmuseum-photon:v0.8.1-v1.8.0b185d348bd7d: Loading layer [==================================================>] 2.56kB/2.56kBf032ded7f92e: Loading layer [==================================================>] 1.536kB/1.536kBc6c822edbc47: Loading layer [==================================================>] 66.9MB/66.9MB73ef3c4363bf: Loading layer [==================================================>] 39.75MB/39.75MB0c490e002448: Loading layer [==================================================>] 144.4kB/144.4kB31afe2abafb4: Loading layer [==================================================>] 3.004MB/3.004MBLoaded image: goharbor/prepare:v1.8.0257ebcc1c9c4: Loading layer [==================================================>] 8.967MB/8.967MB7579d3c94fca: Loading layer [==================================================>] 38.68MB/38.68MB323611f7dd17: Loading layer [==================================================>] 38.68MB/38.68MBLoaded image: goharbor/harbor-jobservice:v1.8.0587a5757a7f6: Loading layer [==================================================>] 3.548MB/3.548MBLoaded image: goharbor/nginx-photon:v1.8.0a61ab2060e6e: Loading layer [==================================================>] 8.967MB/8.967MB25359ae00f57: Loading layer [==================================================>] 5.143MB/5.143MB610a1668f8bf: Loading layer [==================================================>] 15.13MB/15.13MBdb2252abd9e0: Loading layer [==================================================>] 26.47MB/26.47MB4f406312560b: Loading layer [==================================================>] 22.02kB/22.02kB1cee0947e5a7: Loading layer [==================================================>] 3.072kB/3.072kB48db2b9b0752: Loading layer [==================================================>] 46.74MB/46.74MBLoaded image: goharbor/notary-server-photon:v0.6.1-v1.8.0aaf447150765: Loading layer [==================================================>] 113MB/113MB6835441e1a1d: Loading layer [==================================================>] 10.94MB/10.94MB9f4739e3a532: Loading layer [==================================================>] 2.048kB/2.048kB928f489135f0: Loading layer [==================================================>] 48.13kB/48.13kB1495a1a09ada: Loading layer [==================================================>] 3.072kB/3.072kB1a5f5b141717: Loading layer [==================================================>] 10.99MB/10.99MBLoaded image: goharbor/clair-photon:v2.0.8-v1.8.066006ea937c6: Loading layer [==================================================>] 337.8MB/337.8MBd272ba122880: Loading layer [==================================================>] 106.5kB/106.5kBLoaded image: goharbor/harbor-migrator:v1.8.005bc5efb1724: Loading layer [==================================================>] 8.967MB/8.967MBaf3a6f89469a: Loading layer [==================================================>] 46.85MB/46.85MB452d238b3e48: Loading layer [==================================================>] 5.632kB/5.632kB36e1cb2d6ffa: Loading layer [==================================================>] 27.14kB/27.14kB5385ffb8451e: Loading layer [==================================================>] 46.85MB/46.85MBLoaded image: goharbor/harbor-core:v1.8.0268091c30a67: Loading layer [==================================================>] 71.66MB/71.66MB4433bcd802e7: Loading layer [==================================================>] 3.072kB/3.072kB420b26399278: Loading layer [==================================================>] 59.9kB/59.9kB8864c4b9ac3d: Loading layer [==================================================>] 61.95kB/61.95kBLoaded image: goharbor/redis-photon:v1.8.063645c97bf5d: Loading layer [==================================================>] 8.968MB/8.968MBccb295818ad9: Loading layer [==================================================>] 3.072kB/3.072kB1ec2d1eefa8f: Loading layer [==================================================>] 2.56kB/2.56kBb88acf0f9f5f: Loading layer [==================================================>] 20.1MB/20.1MB0e7375de12e6: Loading layer [==================================================>] 20.1MB/20.1MBLoaded image: goharbor/registry-photon:v2.7.1-patch-2819-v1.8.0444b0c8bfeee: Loading layer [==================================================>] 3.548MB/3.548MBed0415346760: Loading layer [==================================================>] 6.568MB/6.568MB572bd51089e0: Loading layer [==================================================>] 160.8kB/160.8kB1410c2919a92: Loading layer [==================================================>] 215kB/215kB8ecdca210598: Loading layer [==================================================>] 3.584kB/3.584kBLoaded image: goharbor/harbor-portal:v1.8.07fb66591fb58: Loading layer [==================================================>] 8.968MB/8.968MB42ec4a6394bf: Loading layer [==================================================>] 3.072kB/3.072kBbe6c2180cb57: Loading layer [==================================================>] 20.1MB/20.1MBd956d9e974c5: Loading layer [==================================================>] 3.072kB/3.072kBe2e0b4f17ad8: Loading layer [==================================================>] 7.465MB/7.465MB7e29d670afe9: Loading layer [==================================================>] 27.56MB/27.56MBLoaded image: goharbor/harbor-registryctl:v1.8.0453732ea69d4: Loading layer [==================================================>] 13.72MB/13.72MBc985f3824f33: Loading layer [==================================================>] 26.47MB/26.47MB76eaa2763221: Loading layer [==================================================>] 22.02kB/22.02kB0ef55a752948: Loading layer [==================================================>] 3.072kB/3.072kBc5749b90723d: Loading layer [==================================================>] 45.33MB/45.33MBLoaded image: goharbor/notary-signer-photon:v0.6.1-v1.8.0[Step 2]: preparing environment ...prepare base dir is set to /usr/local/docker/harbor/harborGenerated configuration file: /config/log/logrotate.confGenerated configuration file: /config/nginx/nginx.confGenerated configuration file: /config/core/envGenerated configuration file: /config/core/app.confGenerated configuration file: /config/registry/config.ymlGenerated configuration file: /config/registryctl/envGenerated configuration file: /config/db/envGenerated configuration file: /config/jobservice/envGenerated configuration file: /config/jobservice/config.ymlGenerated and saved secret to file: /secret/keys/secretkeyGenerated certificate, key file: /secret/core/private_key.pem, cert file: /secret/registry/root.crtGenerated configuration file: /compose_location/docker-compose.ymlClean up the input dir[Step 3]: starting Harbor ...Creating network "harbor_harbor" with the default driverCreating harbor-log ... doneCreating harbor-db ... doneCreating registryctl ... doneCreating redis ... doneCreating registry ... doneCreating harbor-core ... doneCreating harbor-jobservice ... doneCreating harbor-portal ... doneCreating nginx ... done✔ ----Harbor has been installed and started successfully.----Now you should be able to visit the admin portal at http://192.168.141.150. For more details, please visit https://github.com/goharbor/harbor .通过浏览器访问 http://192.168.141.150 ,看到登录页面
输入账号 admin,密码 Harbor12345,登录成功后
Harbor 的日常运维管理是通过 docker-compose 来完成的,Harbor 本身有多个服务进程,都放在 docker 容器之中运行,我们可以通过 docker ps 命令查看。
docker ps | grep goharbor# 输出如下07b401504357 goharbor/nginx-photon:v1.8.0 "nginx -g 'daemon of…" 23 minutes ago Up 23 minutes (healthy) 0.0.0.0:80->80/tcp nginx050f39a147bc goharbor/harbor-portal:v1.8.0 "nginx -g 'daemon of…" 23 minutes ago Up 23 minutes (healthy) 80/tcp harbor-portal305077bc0a3e goharbor/harbor-jobservice:v1.8.0 "/harbor/start.sh" 23 minutes ago Up 23 minutes harbor-jobservice4eb33b09b268 goharbor/harbor-core:v1.8.0 "/harbor/start.sh" 23 minutes ago Up 23 minutes (healthy) harbor-coree9efb7a6abf9 goharbor/registry-photon:v2.7.1-patch-2819-v1.8.0 "/entrypoint.sh /etc…" 24 minutes ago Up 23 minutes (healthy) 5000/tcp registryf9bc75d47752 goharbor/harbor-registryctl:v1.8.0 "/harbor/start.sh" 24 minutes ago Up 23 minutes (healthy) registryctl76d33d1755f6 goharbor/redis-photon:v1.8.0 "docker-entrypoint.s…" 24 minutes ago Up 23 minutes 6379/tcp redis3870b3b93f46 goharbor/harbor-db:v1.8.0 "/entrypoint.sh post…" 24 minutes ago Up 23 minutes (healthy) 5432/tcp harbor-db6e848e4d8bc2 goharbor/harbor-log:v1.8.0 "/bin/sh -c /usr/loc…" 24 minutes ago Up 24 minutes (healthy) 127.0.0.1:1514->10514/tcp harbor-log# 启动docker-compose start# 停止docker-comose stop# 重启docker-compose restart说明:
这几个容器通过 Docker link 的形式连接在一起,这样,在容器之间可以通过容器名字互相访问。对终端用户而言,只需要暴露 proxy (即 Nginx)的服务端口。
在 /etc/docker/daemon.json 中增加如下内容(如果文件不存在请新建该文件)
{"registry-mirrors": ["https://registry.docker-cn.com"],"insecure-registries": ["192.168.141.150"]}注意: 该文件必须符合 JSON 规范,否则 Docker 将不能启动。
重启服务
systemctl daemon-reloadsystemctl restart docker使用 docker info 命令手动检查,如果从配置中看到如下内容,说明配置成功
Insecure Registries:192.168.141.150127.0.0.0/8我们以推送 Nginx 为例,首先需要在 Harbor 上创建一个 公开/私有 的项目
# 在项目中标记镜像docker tag nginx 192.168.141.150/myshop/nginx:latest# 登录 Harbordocker login 192.168.141.150 -u admin -p Harbor12345# 推送镜像到项目docker push 192.168.141.150/myshop/nginx:latest在其它机器下载镜像只需要配置好客户端即可
docker pull 192.168.141.150/myshop/nginx:latest默认情况下,Compose 会为我们的应用创建一个网络,服务的每个容器都会加入该网络中。这样,容器就可被该网络中的其他容器访问,不仅如此,该容器还能以服务名称作为 Hostname 被其他容器访问。
默认情况下,应用程序的网络名称基于 Compose 的工程名称,而项目名称基于 docker-compose.yml 所在目录的名称。如需修改工程名称,可使用 --project-name 标识或 COMPOSE_PORJECT_NAME 环境变量。
假如一个应用程序在名为 myapp 的目录中,并且 docker-compose.yml 如下所示:
version: '2'services:web:build: .ports:- "8000:8000"db:image: postgres当我们运行 docker-compose up 时,将会执行以下几步:
容器间可使用服务名称(web 或 db)作为 Hostname 相互访问。例如,web 这个服务可使用 postgres://db:5432 访问 db 容器。
当服务的配置发生更改时,可使用 docker-compose up 命令更新配置。此时,Compose 会删除旧容器并创建新容器。新容器会以不同的 IP 地址加入网络,名称保持不变。任何指向旧容器的连接都会被关闭,容器会重新找到新容器并连接上去。
默认情况下,服务之间可使用服务名称相互访问。links 允许我们定义一个别名,从而使用该别名访问其他服务。
version: '2'services:web:build: .links:- "db:database"db:image: postgres一些场景下,默认的网络配置满足不了我们的需求,此时我们可使用 networks 命令自定义网络。networks 命令允许我们创建更加复杂的网络拓扑并指定自定义网络驱动和选项。不仅如此,我们还可使用 networks 将服务连接到不是由 Compose 管理的、外部创建的网络。
version: '2'services:proxy:build: ./proxynetworks:- frontapp:build: ./appnetworks:- front- backdb:image: postgresnetworks:- backnetworks:front:# Use a custom driverdriver: custom-driver-1back:# Use a custom driver which takes special optionsdriver: custom-driver-2driver_opts:foo: "1"bar: "2"其中,proxy 服务与 db 服务隔离,两者分别使用自己的网络;app 服务可与两者通信。使用 networks 命令,即可方便实现服务间的网络隔离与连接。
version: '2'services:web:build: .ports:- "8000:8000"db:image: postgresnetworks:default:# Use a custom driverdriver: custom-driver-1这样,就可为该应用指定自定义的网络驱动
我们可以预先创建一个名为 myapp 的网络,让 Compose 加入这个新创建的网络,使所有 Compose 可以通信,此时使用 external 选项。
# 创建网络docker network create # 查看已存在的网络docker network listnetworks:default:external:name: myapp