004.Docker Compose

特别说明: 本人平时混迹于 B 站,不咋回复这里的评论,有问题可以到 B 站视频评论区留言找我
视频地址: https://space.bilibili.com/31137138/favlist?fid=326428938
课件说明: 本次提供的课件是 Spring Cloud Netflix 版微服务架构指南,如果有兴趣想要学习 Spring Cloud Alibaba 版,可以前往 http://www.qfdmy.com 查看相关课程资源
案例代码: https://github.com/topsale/hello-spring-cloud-netflix

简介

Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。从功能上看,跟 OpenStack 中的 Heat 十分类似。

其代码目前在 https://github.com/docker/compose 上开源。

Compose 定位是 「定义和运行多个 Docker 容器的应用(Defining and running multi-container Docker applications)」,其前身是开源项目 Fig。

我们知道使用一个 Dockerfile 模板文件,可以让用户很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。

Compose 恰好满足了这样的需求。它允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(Project)。Compose 中有两个重要的概念:

  • 服务 (Service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
  • 项目 (Project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。

Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。Compose 项目由 Python 编写,实现上调用了 Docker 服务提供的 API 来对容器进行管理。因此,只要所操作的平台支持 Docker API,就可以在其上利用 Compose 来进行编排管理。

安装

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-compose
chmod +x /usr/local/bin/docker-compose

验证安装是否成功

docker-compose version

# 输出如下
docker-compose version 1.24.0, build 0aa59064
docker-py version: 3.7.2
CPython version: 3.6.8
OpenSSL version: OpenSSL 1.1.0j  20 Nov 2018

术语

首先介绍几个术语。

  • 服务 (Service):一个应用容器,实际上可以运行多个相同镜像的实例。
  • 项目 (Project):由一组关联的应用容器组成的一个完整业务单元。

可见,一个项目可以由多个服务(容器)关联而成,Compose 面向项目进行管理。

场景

最常见的项目是 Web 网站,该项目应该包含 Web 应用和缓存。下面我们用 Python 来建立一个能够记录页面访问次数的 Web 网站。

Python 应用

新建文件夹,在该目录中编写 app.py 文件

from flask import Flask
from redis import Redis

app = 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

编写 Dockerfile 文件,内容为

FROM python:3.6-alpine
ADD . /code
WORKDIR /code
RUN pip install redis flask
CMD ["python", "app.py"]

Docker Compose 模板

编写 docker-compose.yml 文件,这个是 Compose 使用的主模板文件。

version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
     
  redis:
    image: "redis:alpine"

运行 Compose 项目

docker-compose up -d

此时访问本地 5000 端口,每次刷新页面,计数就会加 1。

YAML 配置文件语言

YAML 是专门用来写配置文件的语言,非常简洁和强大,远比 JSON 格式方便。YAML 语言的设计目标,就是方便人类读写。它实质上是一种通用的数据串行化格式。它的基本语法规则如下:

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进时不允许使用 TAB 键,只允许使用空格。
  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可

# 表示注释,从这个字符一直到行尾,都会被解析器忽略。YAML 支持的数据结构有三种:

  • 对象: 键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
  • 数组: 一组按次序排列的值,又称为序列(sequence) / 列表(list)
  • 纯量(scalars): 单个的、不可再分的值

YAML 对象

对象的一组键值对,使用冒号结构表示

animal: pets

YAML 数组

一组连词线开头的行,构成一个数组

- Cat
- Dog
- Goldfish

数据结构的子成员是一个数组,则可以在该项下面缩进一个空格

- Array
 - Cat
 - Dog
 - Goldfish

YAML 复合结构

对象和数组可以结合使用,形成复合结构

languages:
 - Ruby
 - Perl
 - Python 
websites:
 YAML: yaml.org 
 Ruby: ruby-lang.org 
 Python: python.org 
 Perl: use.perl.org 

YAML 纯量

纯量是最基本的、不可再分的值。以下数据类型都属于 JavaScript 的纯量

  • 字符串
  • 布尔值
  • 整数
  • 浮点数
  • Null
  • 时间
  • 日期

修改 IP 和 DNS

课程演示会采用多虚拟机模拟分布式场景,为防止 IP 冲突,无法联网等问题,需要预先设置好主机名、IP、DNS 配置

修改主机名

  • 修改 cloud.cfg 防止重启后主机名还原
vi /etc/cloud/cloud.cfg

# 该配置默认为 false,修改为 true 即可
preserve_hostname: true
  • 修改主机名
# 修改主机名
hostnamectl set-hostname deployment

# 配置 hosts
cat >> /etc/hosts << EOF
192.168.141.130 deployment
EOF

修改 IP

编辑 vi /etc/netplan/50-cloud-init.yaml 配置文件,修改内容如下

network:
    ethernets:
        ens33:
          addresses: [192.168.141.130/24]
          gateway4: 192.168.141.2
          nameservers:
            addresses: [192.168.141.2]
    version: 2

使用 netplan apply 命令让配置生效

修改 DNS

# 取消 DNS 行注释,并增加 DNS 配置如:114.114.114.114,修改后重启下计算机
vi /etc/systemd/resolved.conf

部署应用程序

部署 Tomcat

version: '3.1'
services:
  tomcat:
    restart: always
    image: tomcat
    container_name: tomcat
    ports:
      - 8080:8080
    volumes:
      - ./webapps:/usr/local/tomcat/webapps
    environment:
      TZ: Asia/Shanghai

部署 MySQL

version: '3.1'
services:
  db:
    # 目前 latest 版本为 MySQL8.x
    image: mysql
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: 123456
    command:
      --default-authentication-plugin=mysql_native_password
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_general_ci
      --explicit_defaults_for_timestamp=true
      --lower_case_table_names=1
    ports:
      - 3306:3306
    volumes:
      - ./data:/var/lib/mysql

  # MySQL 的 Web 客户端
  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080
``

部署 GitLab

什么是 GitLab

GitLab 是利用 Ruby on Rails 一个开源的版本管理系统,实现一个自托管的 Git 项目仓库,可通过 Web 界面进行访问公开的或者私人项目。它拥有与 Github 类似的功能,能够浏览源代码,管理缺陷和注释。可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库。团队成员可以利用内置的简单聊天程序 (Wall) 进行交流。它还提供一个代码片段收集功能可以轻松实现代码复用,便于日后有需要的时候进行查找。

部署 GitLab

我们使用 Docker 来安装和运行 GitLab 中文版,docker-compose.yml 配置如下:

version: '3'
services:
    web:
      image: 'twang2218/gitlab-ce-zh'
      restart: always
      hostname: '192.168.75.145'
      environment:
        TZ: 'Asia/Shanghai'
        GITLAB_OMNIBUS_CONFIG: |
          external_url 'http://192.168.75.145'
          gitlab_rails['gitlab_shell_ssh_port'] = 2222
          unicorn['port'] = 8888
          nginx['listen_port'] = 80
      ports:
        - '80:80'
        - '443:443'
        - '2222:22'
      volumes:
        - ./config:/etc/gitlab
        - ./data:/var/opt/gitlab
        - ./logs:/var/log/gitlab

配置 GitLab

Lusifer1511797825.png
  • 设置管理员初始密码,这里的密码最好是 字母 + 数字组合,并且大于等于 8 位
  • 配置完成后登录,管理员账号是 root
Lusifer1511798229.png

注意: 如果服务器配置较低,启动运行可能需要较长时间,请耐心等待

设置 GitLab

第一次使用时可以做一些初始化设置,点击 管理区域 -> 设置

Lusifer1511798480.png
  • 关闭头像功能,由于 Gravatar 头像为网络头像,在网络情况不理想时可能导致访问时卡顿
Lusifer1511798637.png
  • 由于是内部代码托管服务器,可以直接关闭注册功能,由管理员统一创建用户即可
Lusifer1511798763.png

账户管理

使用时请不要直接通过 root 用户操作,需要先创建用户,然后通过创建的用户操作,如果你是管理员还需要为其他开发人员分配账户

  • 创建账户,点击 管理区域 -> 新建用户
Lusifer1511799413.png
  • 设置账户信息,同时你可以将自己设置为管理员
Lusifer1511799508.png
  • 修改用户密码,由于我们创建时并没有配置邮箱,所以还需要重新编辑用户信息并手动设置密码
Lusifer1511799858.png
Lusifer1511799897.png
  • 退出并使用新账户登录
Lusifer1511800022.png

注意: 创建完账户,第一次登录时还会提示你修改登录密码

项目管理

  • 点击 + 号 -> 新建项目
Lusifer1511800438.png
  • 输入项目名称及描述信息,设置可见等级为私有,这样别人就看不见你的项目
Lusifer1511800627.png
  • 我们选择通过增加一个 README 的方式来初始化项目
Lusifer1511800836.png
  • 直接提交修改即可
Lusifer1511800904.png

使用 SSH 方式拉取和推送

生成 SSH KEY

  • 使用 ssh-keygen 工具生成,位置在 Git 安装目录下,我的是 C:\Program Files\Git\usr\bin,输入命令:
ssh-keygen -t rsa -C "your_email@example.com"
  • 执行成功后的效果:
Microsoft Windows [版本 10.0.14393]
(c) 2016 Microsoft Corporation。保留所有权利。

C:\Program Files\Git\usr\bin>ssh-keygen -t rsa -C "topsale@vip.qq.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/Lusifer/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /c/Users/Lusifer/.ssh/id_rsa.
Your public key has been saved in /c/Users/Lusifer/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:cVesJKa5VnQNihQOTotXUAIyphsqjb7Z9lqOji2704E topsale@vip.qq.com
The key's randomart image is:
+---[RSA 2048]----+
|  + ..=o=.  .+.  |
| o o + B .+.o.o  |
|o   . + +=o+..   |
|.=   .  oo...    |
|= o     So       |
|oE .    o        |
| .. .. .         |
| o*o+            |
| *B*oo           |
+----[SHA256]-----+

C:\Program Files\Git\usr\bin>

复制 SSH-KEY 信息到 GitLab

  • 密钥位置在:C:\Users\你的用户名\.ssh 目录下,找到 id_rsa.pub 并使用编辑器打开,如:
Lusifer1511801618.png
  • 登录 GitLab,点击“用户头像”-->“设置”-->“SSH 密钥”
Lusifer1511801730.png
  • 成功增加密钥后的效果
Lusifer1511801884.png

使用 TortoiseGit

克隆项目

  • 新建一个存放代码仓库的本地文件夹
  • 在文件夹空白处按右键
  • 选择 Git 克隆...
Lusifer1511802101.png
  • 复制项目地址到 URL
Lusifer1511802242.png
  • 如果弹出连接信息请选择是
Lusifer1511802354.png
  • 成功克隆项目到本地
Lusifer1511802402.png

推送项目

  • 创建或修改文件(这里的文件为所有文件,包括:代码、图片等)
  • 我们以创建 .gitignore 过滤配置文件为例,该文件的主要作用为过滤不需要上传的文件,比如:IDE 生成的工程文件、编译后的 class 文件等
  • 在工程目录下,新建 .gitignore 文件,并填入如下配置
target/
!.mvn/wrapper/maven-wrapper.jar

## STS ##
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans

## IntelliJ IDEA ##
.idea
*.iws
*.iml
*.ipr

## JRebel ##
rebel.xml

## MAC ##
.DS_Store

## Other ##
logs/
temp/
  • 右键呼出菜单,选择 提交 Master...
Lusifer1511802947.png
  • 点击 全部 并填入 日志信息
Lusifer1511803046.png
  • 点击 提交并推送
Lusifer1511803174.png
  • 成功后的效果图
Lusifer1511803209.png

查看 GitLab 确认提交成功

Lusifer1511803280.png

部署 Nexus

什么是 Nexus

Nexus 是一个强大的 Maven 仓库管理器,极大地简化了内部仓库的维护和外部仓库的访问。2016 年 4 月 6 日 Nexus 3.0 版本发布,相较 2.x 版本有了很大的改变

  • 对低层代码进行了大规模重构,提升性能,增加可扩展性以及改善用户体验。
  • 升级界面,极大的简化了用户界面的操作和管理。
  • 提供新的安装包,让部署更加简单。
  • 增加对 Docker, NeGet, npm, Bower 的支持。
  • 提供新的管理接口,以及增强对自动任务的管理。

部署 Nexus

我们使用 Docker 来安装和运行 Nexus,docker-compose.yml 配置如下:

version: '3.1'
services:
  nexus:
    restart: always
    image: sonatype/nexus3
    container_name: nexus
    ports:
      - 8081:8081
    volumes:
      - ./data:/nexus-data

注意: 启动时如果出现权限问题可以使用 chmod 777 /usr/local/docker/nexus/data 赋予数据卷目录可读可写的权限

验证安装是否成功

注意: 新版本密码在 cat /var/lib/docker/volumes/nexus_data/_data/admin.password

Lusifer1521047001.png

Maven 仓库介绍

代理仓库(Proxy Repository)

  • 第三方仓库
    • maven-central
    • nuget.org-proxy
  • 版本策略(Version Policy)
    • Release: 正式版本
    • Snapshot: 快照版本
    • Mixed: 混合模式
  • 布局策略(Layout Policy)
    • Strict: 严格
    • Permissive: 宽松

宿主仓库(Hosted Repository)

  • 存储本地上传的组件和资源的
    • maven-releases
    • maven-snapshots
    • nuget-hosted
  • 部署策略(Deployment Policy)
    • Allow Redeploy: 允许重新部署
    • Disable Redeploy: 禁止重新部署
    • Read-Only: 只读

仓库组(Repository Group)

通常包含了多个代理仓库和宿主仓库,在项目中只要引入仓库组就可以下载到代理仓库和宿主仓库中的包

  • maven-public
  • nuget-group

在项目中使用 Nexus

配置认证信息

在 Maven settings.xml 中添加 Nexus 认证信息 (servers 节点下)

<server>
  <id>nexus-releases</id>
  <username>admin</username>
  <password>admin123</password>
</server>

<server>
  <id>nexus-snapshots</id>
  <username>admin</username>
  <password>admin123</password>
</server>

Snapshots 与 Releases 的区别

  • nexus-releases: 用于发布 Release 版本
  • nexus-snapshots: 用于发布 Snapshot 版本(快照版)

Release 版本与 Snapshot 定义

Release: 1.0.0/1.0.0-RELEASE
Snapshot: 1.0.0-SNAPSHOT
  • 在项目 pom.xml 中设置的版本号添加 SNAPSHOT 标识的都会发布为 SNAPSHOT 版本,没有 SNAPSHOT 标识的都会发布为 RELEASE 版本。
  • SNAPSHOT 版本会自动加一个时间作为标识,如:1.0.0-SNAPSHOT 发布后为变成 1.0.0-SNAPSHOT-20180522.123456-1.jar

配置自动化部署

pom.xml 中添加如下代码

<distributionManagement>  
  <repository>  
    <id>nexus-releases</id>  
    <name>Nexus Release Repository</name>  
    <url>http://127.0.0.1:8081/repository/maven-releases/</url>  
  </repository>  
  <snapshotRepository>  
    <id>nexus-snapshots</id>  
    <name>Nexus Snapshot Repository</name>  
    <url>http://127.0.0.1:8081/repository/maven-snapshots/</url>  
  </snapshotRepository>  
</distributionManagement> 

注意事项

  • ID 名称必须要与 settings.xml 中 Servers 配置的 ID 名称保持一致
  • 项目版本号中有 SNAPSHOT 标识的,会发布到 Nexus Snapshots Repository, 否则发布到 Nexus Release Repository,并根据 ID 去匹配授权账号

部署到仓库

mvn deploy

配置代理仓库

<repositories>
    <repository>
        <id>nexus</id>
        <name>Nexus Repository</name>
        <url>http://127.0.0.1:8081/repository/maven-public/</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
        <releases>
            <enabled>true</enabled>
        </releases>
    </repository>
</repositories>
<pluginRepositories>
    <pluginRepository>
        <id>nexus</id>
        <name>Nexus Plugin Repository</name>
        <url>http://127.0.0.1:8081/repository/maven-public/</url>
        <snapshots>
            <enabled>true</enabled>
        </snapshots>
        <releases>
            <enabled>true</enabled>
        </releases>
    </pluginRepository>
</pluginRepositories>

部署 Harbor

什么是 Harbor

Harbor 是一个用于存储和分发 Docker 镜像的企业级 Registry 服务器,通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源 Docker Distribution。作为一个企业级私有 Registry 服务器,Harbor 提供了更好的性能和安全。提升用户使用 Registry 构建和运行环境传输镜像的效率。Harbor 支持安装在多个 Registry 节点的镜像资源复制,镜像全部保存在私有 Registry 中, 确保数据和知识产权在公司内部网络中管控。另外,Harbor 也提供了高级的安全特性,诸如用户管理,访问控制和活动审计等。

Harbor 特性

  • 基于角色的访问控制 : 用户与 Docker 镜像仓库通过 “项目” 进行组织管理,一个用户可以对多个镜像仓库在同一命名空间(project)里有不同的权限。
  • 镜像复制 : 镜像可以在多个 Registry 实例中复制(同步)。尤其适合于负载均衡,高可用,混合云和多云的场景。
  • **图形化用户界面 : ** 用户可以通过浏览器来浏览,检索当前 Docker 镜像仓库,管理项目和命名空间。
  • AD/LDAP 支持 : Harbor 可以集成企业内部已有的 AD/LDAP,用于鉴权认证管理。
  • 审计管理 : 所有针对镜像仓库的操作都可以被记录追溯,用于审计管理。
  • 国际化 : 已拥有英文、中文、德文、日文和俄文的本地化版本。更多的语言将会添加进来。
  • RESTful API : RESTful API 提供给管理员对于 Harbor 更多的操控,使得与其它管理软件集成变得更容易。
  • 部署简单 : 提供在线和离线两种安装工具, 也可以安装到 vSphere 平台 (OVA 方式) 虚拟设备。

Harbor 组件

  • Proxy: Harbor 的 registry, UI, token 等服务,通过一个前置的反向代理统一接收浏览器、Docker 客户端的请求,并将请求转发给后端不同的服务。
  • Registry: 负责储存 Docker 镜像,并处理 docker push/pull 命令。由于我们要对用户进行访问控制,即不同用户对 Docker image 有不同的读写权限,Registry 会指向一个 token 服务,强制用户的每次 docker pull/push 请求都要携带一个合法的 token, Registry 会通过公钥对 token 进行解密验证。
  • Core services: 这是 Harbor 的核心功能,主要提供以下服务:
    • UI: 提供图形化界面,帮助用户管理 registry 上的镜像(image), 并对用户进行授权。
    • WebHook: 为了及时获取 registry 上 image 状态变化的情况, 在 Registry 上配置 webhook,把状态变化传递给 UI 模块。
    • Token: 负责根据用户权限给每个 docker push/pull 命令签发 token. Docker 客户端向 - Registry 服务发起的请求,如果不包含 token,会被重定向到这里,获得 token 后再重新向 Registry 进行请求。
  • Database: 为 core services 提供数据库服务,负责储存用户权限、审计日志、Docker image 分组信息等数据。
  • Job Services: 提供镜像远程复制功能,可以把本地镜像同步到其他 Harbor 实例中。
  • Log Collector: 为了帮助监控 Harbor 运行,负责收集其他组件的 log,供日后进行分析。
2017101103304659.png

安装 Harbor

官方 GitHub 上下载最新离线安装版(我已经下载并放置在群分享的 Linux 目录下)并上传至服务器

解压安装包

tar -zxvf harbor-offline-installer-v1.8.0.tgz

# 输出如下
harbor/harbor.v1.8.0.tar.gz
harbor/prepare
harbor/LICENSE
harbor/install.sh
harbor/harbor.yml

修改配置文件

vi harbor.yml

# 修改为域名或你服务器 IP
hostname: 192.168.141.150

执行安装脚本

./install.sh

# 输出如下
[Step 0]: checking installation environment ...

Note: docker version: 18.09.6

Note: docker-compose version: 1.24.0

[Step 1]: loading Harbor images ...
23d9f72a5270: Loading layer [==================================================>]  33.25MB/33.25MB
1d4a1da12c02: Loading layer [==================================================>]  50.51MB/50.51MB
8eb1a006f3b0: Loading layer [==================================================>]  3.584kB/3.584kB
41b6f75847f4: Loading layer [==================================================>]  3.072kB/3.072kB
ec9bd6e4d4e8: Loading layer [==================================================>]   2.56kB/2.56kB
6d852bb664c2: Loading layer [==================================================>]  3.072kB/3.072kB
0e4ed2b5a5b8: Loading layer [==================================================>]  3.584kB/3.584kB
8dfb2b644f30: Loading layer [==================================================>]  12.29kB/12.29kB
Loaded image: goharbor/harbor-log:v1.8.0
d8c53538042b: Loading layer [==================================================>]  63.34MB/63.34MB
1b5fb7ee22e0: Loading layer [==================================================>]  47.96MB/47.96MB
a8bdca5e9d71: Loading layer [==================================================>]  6.656kB/6.656kB
f7cec940b52c: Loading layer [==================================================>]  2.048kB/2.048kB
301a4a2af7db: Loading layer [==================================================>]   7.68kB/7.68kB
e588e1e3a775: Loading layer [==================================================>]   2.56kB/2.56kB
539f28a5d0ea: Loading layer [==================================================>]   2.56kB/2.56kB
8b4a72241226: Loading layer [==================================================>]   2.56kB/2.56kB
Loaded image: goharbor/harbor-db:v1.8.0
c88db349fb2f: Loading layer [==================================================>]  8.972MB/8.972MB
1f2d4d72bba2: Loading layer [==================================================>]  35.77MB/35.77MB
dddbcf598df5: Loading layer [==================================================>]  2.048kB/2.048kB
0ced476c2d9c: Loading layer [==================================================>]  3.072kB/3.072kB
af24eb0bf40b: Loading layer [==================================================>]  35.77MB/35.77MB
Loaded image: goharbor/chartmuseum-photon:v0.8.1-v1.8.0
b185d348bd7d: Loading layer [==================================================>]   2.56kB/2.56kB
f032ded7f92e: Loading layer [==================================================>]  1.536kB/1.536kB
c6c822edbc47: Loading layer [==================================================>]   66.9MB/66.9MB
73ef3c4363bf: Loading layer [==================================================>]  39.75MB/39.75MB
0c490e002448: Loading layer [==================================================>]  144.4kB/144.4kB
31afe2abafb4: Loading layer [==================================================>]  3.004MB/3.004MB
Loaded image: goharbor/prepare:v1.8.0
257ebcc1c9c4: Loading layer [==================================================>]  8.967MB/8.967MB
7579d3c94fca: Loading layer [==================================================>]  38.68MB/38.68MB
323611f7dd17: Loading layer [==================================================>]  38.68MB/38.68MB
Loaded image: goharbor/harbor-jobservice:v1.8.0
587a5757a7f6: Loading layer [==================================================>]  3.548MB/3.548MB
Loaded image: goharbor/nginx-photon:v1.8.0
a61ab2060e6e: Loading layer [==================================================>]  8.967MB/8.967MB
25359ae00f57: Loading layer [==================================================>]  5.143MB/5.143MB
610a1668f8bf: Loading layer [==================================================>]  15.13MB/15.13MB
db2252abd9e0: Loading layer [==================================================>]  26.47MB/26.47MB
4f406312560b: Loading layer [==================================================>]  22.02kB/22.02kB
1cee0947e5a7: Loading layer [==================================================>]  3.072kB/3.072kB
48db2b9b0752: Loading layer [==================================================>]  46.74MB/46.74MB
Loaded image: goharbor/notary-server-photon:v0.6.1-v1.8.0
aaf447150765: Loading layer [==================================================>]    113MB/113MB
6835441e1a1d: Loading layer [==================================================>]  10.94MB/10.94MB
9f4739e3a532: Loading layer [==================================================>]  2.048kB/2.048kB
928f489135f0: Loading layer [==================================================>]  48.13kB/48.13kB
1495a1a09ada: Loading layer [==================================================>]  3.072kB/3.072kB
1a5f5b141717: Loading layer [==================================================>]  10.99MB/10.99MB
Loaded image: goharbor/clair-photon:v2.0.8-v1.8.0
66006ea937c6: Loading layer [==================================================>]  337.8MB/337.8MB
d272ba122880: Loading layer [==================================================>]  106.5kB/106.5kB
Loaded image: goharbor/harbor-migrator:v1.8.0
05bc5efb1724: Loading layer [==================================================>]  8.967MB/8.967MB
af3a6f89469a: Loading layer [==================================================>]  46.85MB/46.85MB
452d238b3e48: Loading layer [==================================================>]  5.632kB/5.632kB
36e1cb2d6ffa: Loading layer [==================================================>]  27.14kB/27.14kB
5385ffb8451e: Loading layer [==================================================>]  46.85MB/46.85MB
Loaded image: goharbor/harbor-core:v1.8.0
268091c30a67: Loading layer [==================================================>]  71.66MB/71.66MB
4433bcd802e7: Loading layer [==================================================>]  3.072kB/3.072kB
420b26399278: Loading layer [==================================================>]   59.9kB/59.9kB
8864c4b9ac3d: Loading layer [==================================================>]  61.95kB/61.95kB
Loaded image: goharbor/redis-photon:v1.8.0
63645c97bf5d: Loading layer [==================================================>]  8.968MB/8.968MB
ccb295818ad9: Loading layer [==================================================>]  3.072kB/3.072kB
1ec2d1eefa8f: Loading layer [==================================================>]   2.56kB/2.56kB
b88acf0f9f5f: Loading layer [==================================================>]   20.1MB/20.1MB
0e7375de12e6: Loading layer [==================================================>]   20.1MB/20.1MB
Loaded image: goharbor/registry-photon:v2.7.1-patch-2819-v1.8.0
444b0c8bfeee: Loading layer [==================================================>]  3.548MB/3.548MB
ed0415346760: Loading layer [==================================================>]  6.568MB/6.568MB
572bd51089e0: Loading layer [==================================================>]  160.8kB/160.8kB
1410c2919a92: Loading layer [==================================================>]    215kB/215kB
8ecdca210598: Loading layer [==================================================>]  3.584kB/3.584kB
Loaded image: goharbor/harbor-portal:v1.8.0
7fb66591fb58: Loading layer [==================================================>]  8.968MB/8.968MB
42ec4a6394bf: Loading layer [==================================================>]  3.072kB/3.072kB
be6c2180cb57: Loading layer [==================================================>]   20.1MB/20.1MB
d956d9e974c5: Loading layer [==================================================>]  3.072kB/3.072kB
e2e0b4f17ad8: Loading layer [==================================================>]  7.465MB/7.465MB
7e29d670afe9: Loading layer [==================================================>]  27.56MB/27.56MB
Loaded image: goharbor/harbor-registryctl:v1.8.0
453732ea69d4: Loading layer [==================================================>]  13.72MB/13.72MB
c985f3824f33: Loading layer [==================================================>]  26.47MB/26.47MB
76eaa2763221: Loading layer [==================================================>]  22.02kB/22.02kB
0ef55a752948: Loading layer [==================================================>]  3.072kB/3.072kB
c5749b90723d: Loading layer [==================================================>]  45.33MB/45.33MB
Loaded 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/harbor
Generated configuration file: /config/log/logrotate.conf
Generated configuration file: /config/nginx/nginx.conf
Generated configuration file: /config/core/env
Generated configuration file: /config/core/app.conf
Generated configuration file: /config/registry/config.yml
Generated configuration file: /config/registryctl/env
Generated configuration file: /config/db/env
Generated configuration file: /config/jobservice/env
Generated configuration file: /config/jobservice/config.yml
Generated and saved secret to file: /secret/keys/secretkey
Generated certificate, key file: /secret/core/private_key.pem, cert file: /secret/registry/root.crt
Generated configuration file: /compose_location/docker-compose.yml
Clean up the input dir



[Step 3]: starting Harbor ...
Creating network "harbor_harbor" with the default driver
Creating harbor-log ... done
Creating harbor-db   ... done
Creating registryctl ... done
Creating redis       ... done
Creating registry    ... done
Creating harbor-core ... done
Creating harbor-jobservice ... done
Creating harbor-portal     ... done
Creating 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 ,看到登录页面

Lusifer_20190617010524.png

输入账号 admin,密码 Harbor12345,登录成功后

Lusifer_20190617010713.png

Harbor 启动和停止

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          nginx
050f39a147bc        goharbor/harbor-portal:v1.8.0                       "nginx -g 'daemon of…"   23 minutes ago      Up 23 minutes (healthy)   80/tcp                      harbor-portal
305077bc0a3e        goharbor/harbor-jobservice:v1.8.0                   "/harbor/start.sh"       23 minutes ago      Up 23 minutes                                         harbor-jobservice
4eb33b09b268        goharbor/harbor-core:v1.8.0                         "/harbor/start.sh"       23 minutes ago      Up 23 minutes (healthy)                               harbor-core
e9efb7a6abf9        goharbor/registry-photon:v2.7.1-patch-2819-v1.8.0   "/entrypoint.sh /etc…"   24 minutes ago      Up 23 minutes (healthy)   5000/tcp                    registry
f9bc75d47752        goharbor/harbor-registryctl:v1.8.0                  "/harbor/start.sh"       24 minutes ago      Up 23 minutes (healthy)                               registryctl
76d33d1755f6        goharbor/redis-photon:v1.8.0                        "docker-entrypoint.s…"   24 minutes ago      Up 23 minutes             6379/tcp                    redis
3870b3b93f46        goharbor/harbor-db:v1.8.0                           "/entrypoint.sh post…"   24 minutes ago      Up 23 minutes (healthy)   5432/tcp                    harbor-db
6e848e4d8bc2        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

说明:

  • nginx: nginx 负责流量转发和安全验证,对外提供的流量都是从 nginx 中转,所以开放 https 的 443 端口,它将流量分发到后端的 ui 和正在 docker 镜像存储的 docker registry。
  • harbor-jobservice: harbor-jobservice 是 harbor 的 job 管理模块,job 在 harbor 里面主要是为了镜像仓库之前同步使用的;
  • harbor-ui: harbor-ui 是 web 管理页面,主要是前端的页面和后端 CURD 的接口;
  • registry: registry 就是 docker 原生的仓库,负责保存镜像。
  • harbor-adminserver: harbor-adminserver 是 harbor 系统管理接口,可以修改系统配置以及获取系统信息。
  • harbor-db: harbor-db 是 harbor 的数据库,这里保存了系统的 job 以及项目、人员权限管理。由于本 harbor 的认证也是通过数据,在生产环节大多对接到企业的 ldap 中;
  • harbor-log: harbor-log 是 harbor 的日志服务,统一管理 harbor 的日志。通过 inspect 可以看出容器统一将日志输出的 syslog。

这几个容器通过 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-reload
systemctl restart docker

检查客户端配置是否生效

使用 docker info 命令手动检查,如果从配置中看到如下内容,说明配置成功

Insecure Registries:
 192.168.141.150
 127.0.0.0/8

Harbor 上传镜像

新建项目

我们以推送 Nginx 为例,首先需要在 Harbor 上创建一个 公开/私有 的项目

Lusifer_20190618052805.png
Lusifer_20190618052902.png

推送镜像

Lusifer_20190618052957.png
# 在项目中标记镜像
docker tag nginx 192.168.141.150/myshop/nginx:latest

# 登录 Harbor
docker login 192.168.141.150 -u admin -p Harbor12345

# 推送镜像到项目
docker push 192.168.141.150/myshop/nginx:latest

查看镜像

Lusifer_20190618053555.png
Lusifer_20190618053614.png

Harbor 下载镜像

在其它机器下载镜像只需要配置好客户端即可

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 时,将会执行以下几步:

  • 创建一个名为 myapp_default 的网络
  • 使用 web 服务的配置创建容器,它以 web 这个名称加入网络 myapp_default
  • 使用 db 服务的配置创建容器,它以 db 这个名称加入网络 myapp_default

容器间可使用服务名称(web 或 db)作为 Hostname 相互访问。例如,web 这个服务可使用 postgres://db:5432 访问 db 容器。

当服务的配置发生更改时,可使用 docker-compose up 命令更新配置。此时,Compose 会删除旧容器并创建新容器。新容器会以不同的 IP 地址加入网络,名称保持不变。任何指向旧容器的连接都会被关闭,容器会重新找到新容器并连接上去。

使用 links

默认情况下,服务之间可使用服务名称相互访问。links 允许我们定义一个别名,从而使用该别名访问其他服务。

version: '2'
services:
  web:
    build: .
    links:
      - "db:database"
  db:
    image: postgres

自定义网络

一些场景下,默认的网络配置满足不了我们的需求,此时我们可使用 networks 命令自定义网络。networks 命令允许我们创建更加复杂的网络拓扑并指定自定义网络驱动和选项。不仅如此,我们还可使用 networks 将服务连接到不是由 Compose 管理的、外部创建的网络。

version: '2'

services:
  proxy:
    build: ./proxy
    networks:
      - front
  app:
    build: ./app
    networks:
      - front
      - back
  db:
    image: postgres
    networks:
      - back

networks:
  front:
    # Use a custom driver
    driver: custom-driver-1
  back:
    # Use a custom driver which takes special options
    driver: custom-driver-2
    driver_opts:
      foo: "1"
      bar: "2"

其中,proxy 服务与 db 服务隔离,两者分别使用自己的网络;app 服务可与两者通信。使用 networks 命令,即可方便实现服务间的网络隔离与连接。

配置默认网络

version: '2'

services:
  web:
    build: .
    ports:
      - "8000:8000"
  db:
    image: postgres

networks:
  default:
    # Use a custom driver
    driver: custom-driver-1

这样,就可为该应用指定自定义的网络驱动

已存在的网络

我们可以预先创建一个名为 myapp 的网络,让 Compose 加入这个新创建的网络,使所有 Compose 可以通信,此时使用 external 选项。

# 创建网络
docker network create <Network Name>

# 查看已存在的网络
docker network list
networks:
  default:
    external:
      name: myapp

特别说明: 本人平时混迹于 B 站,不咋回复这里的评论,有问题可以到 B 站视频评论区留言找我
视频地址: https://space.bilibili.com/31137138/favlist?fid=326428938
课件说明: 本次提供的课件是 Spring Cloud Netflix 版微服务架构指南,如果有兴趣想要学习 Spring Cloud Alibaba 版,可以前往 http://www.qfdmy.com 查看相关课程资源
案例代码: https://github.com/topsale/hello-spring-cloud-netflix

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容