wiki
  • Introduction
  • Ansible
    • 1 初识Ansible
    • 2 Ansible Inventory 配置详解
    • 3 Ansible Ad-hoc 命令集
    • 3 Ansible lineinfile 模块详解
    • 4 Ansible Playbook
      • 4.1 Playbook的结构及handler用法
      • 4.2 Playbook循环语句
      • 4.3 Playbook条件语句
      • 4.4 Playbook高级用法
      • 4.5 Playbook之tags
      • 4.6 巧用Roles
      • 4.7 文件管理模块及Jinja2过滤器
      • 4.8 yaml 语法
    • 5 Ansible变量
      • 5.1 自定义变量
      • 5.2 Fact变量
      • 5.3 魔法变量
      • 5.4 使用lookup生成变量
      • 5.5 使用vault配置加密
    • 6 Ansible使用优化
  • Linux
    • linux简介
    • 文件管理
      • 查看文件类型
      • 查看文件详细属性
      • 创建、复制、移动、删除
      • 查看文件内容
      • 打包、压缩
    • 文件权限
      • 基本权限UGO
    • 计划任务
    • 用户管理
    • 进程管理
    • 管道及I/O重定向
    • 软件包管理
    • 网络管理
    • 日志logrotate
    • /etc/security/limits.conf 详解与配置
    • 常用知识
  • Shell
    • 第一部分 初见shell
      • 1. 为什么使用shell编程
      • 2. 和Sha-Bang(#!)一起出发
        • 2.1 调用一个脚本
        • 2.2 牛刀小试
    • 第二部分 shell基础
      • 3. 特殊字符
      • 4. 变量与参数
        • 4.1 变量替换
        • 4.2 变量赋值
        • 4.3 Bash弱类型变量
        • 4.4 特殊变量类型
      • 5. 引用
        • 5.1 引用变量
        • 5.2 转义
      • 6. 退出与退出状态
      • 7. 测试
        • 7.1 测试结构
        • 7.2 文件测试操作
        • 7.3 其他比较操作
        • 7.4 嵌套 if/then 条件测试
        • 7.5 牛刀小试
      • 8. 运算符相关话题
        • 8.1 运算符
        • 8.2 数字常量
        • 8.3 双圆括号结构
        • 8.4 运算符优先级
    • 第三部分 shell进阶
      • 9. 换个角度看变量
        • 9.1 内部变量
        • 9.2 变量类型标注:declare 与 typeset
          • 9.2.1 declare 的另类用法
        • 9.3 $RANDOM:生成随机数
      • 10. 变量处理
        • 10.1 字符串处理
          • 10.1.1 使用 awk 处理字符串
          • 10.1.2 参考资料
        • 10.2 参数替换
      • 11. 循环与分支
        • 11.1 循环
        • 11.2 嵌套循环
        • 11.3 循环控制
        • 11.4 测试与分支
      • 12. 命令替换
      • 13. 算术扩展
    • 第四部分 命令
    • 第五部分 高级话题
      • 18.正则表达式
        • 18.1正则表达式简介
        • 18.2文件名替换
        • 18.3 正则表达式对照表
      • 19. 嵌入文档
      • 20. I/O 重定向
        • 20.1 使用 exec
        • 20.2 重定向代码块
        • 20.3 应用程序
      • 21. 子shell
      • 22. 限制模式的Shell
      • 23. 进程替换
      • 24. 函数
        • 24.1 复杂函数和函数复杂性
        • 24.2 局部变量
        • 24.3 不适用局部变量的递归
      • 25. 别名
      • 26. 列表结构
      • 27. 数组
      • 30. 网络编程
      • 33. 选项
      • 34. 陷阱
      • 36. 其他
        • 36.5 有颜色的脚本
        • 36.11 ssh远程操作
    • 第六部分 Google Shell 风格指南
    • 第七部分 实例
  • 3 Python
    • 3.1 简介
    • 3.2 数据类型
    • python subprocess模块的使用
    • python解析nginx配置文件
    • python调用jenkinsAPI批量拷贝视图job
    • python调用zabbixAPI批量添加web监控
    • python监控activemq集群
  • 4 Golang
    • 4.1 程序结构
    • 4.2 数据类型
      • 4.2.1 基础数据类型
      • 4.2.2 复合数据类型
    • 4.3 函数
  • Docker
    • Docker文章推荐
    • Docker Harbor
    • Docker Harbor HA
    • 快速搭建rabbitmq高可用集群
  • Nginx
    • 1.初识Nginx
    • 2.nginx架构基础
    • 3.nginx配置文件详解
      • 3.1 nginx全局块和events块配置
      • 3.2 nginxHTTP块配置
      • 3.3 nginxSERVER块配置
      • 3.4 nginxLOCATION块配置
      • 3.5 nginx常用模块
    • 4.内核参数优化
    • 5.状态码
    • 6.nginx的常见问题
      • Nginx出现403 forbidden的三种原因
  • 8 Tomcat
    • 8.1 tomcat简介
    • 生产环境中的tomcat配置
    • tomcat假死现象
    • Tomcat 错误代号及状态码
    • tomcat注意事项
  • 9 Elasticsearch
    • 9.1 概述
      • 9.1.1 Elasticsearch 简介及其发展历史
      • 9.1.2 Elastic Stack 家族成员及其应用场景
    • 9.2 安装上手
      • 9.2.1 Elasticsearch的安装和简单配置
      • 9.2.2 Kibana的安装和界面快速浏览
      • 9.2.3 在Docker容器中运行Elasticsearch,Kibana和Cerebro
    • 9.3 Elasticsearch入门
      • 9.3.1 基本概念
      • 9.3.2 文档的基本操作CRUP与批量操作
      • 9.3.3 倒排索引入门
      • 9.3.4 通过分析器进行分词
      • 9.3.5 Search API概览
      • 9.3.6 URI Search详解
      • 9.3.7 Request Body和Query DSL简介
  • 10 Zabbix
    • 10.1 zabbix4.4新功能
    • 10.2 zabbix借助ansible安装
    • 10.3 zabbix添加报警媒介
    • 10.4 MySQL监控模块
    • 10.5 Redis监控模块
    • 10.6 常见问题
    • 10.7 用zabbix api批量添加web监控
    • 10.8 activemq监控
    • 10.9 zookeeper集群监控
    • 10.10 Todolist
  • 11 消息中间件
    • 11.1 activemq集群
    • 11.2 rabbitmq
  • 12 常见集群的搭建
    • 12.1 keepalived和heartbeat对比
    • 12.2 zookeeper集群
    • 12.3 fastdfs
    • 12.4 rocketmq集群的搭建
  • 13 常见服务的搭建
    • none
    • 13.2 jdk
    • 13.3 python3.6
    • 13.4 新建博客方法
    • 13.5 confluence
  • 14 Markdown
    • 14.1 让Markdown写作更简单Typora完全使用指南
  • 16 Mysql
    • 16.1 MySQL基本操作
    • 16.2 列表类型和数据完整性
    • 16.3 数据库设计与查询语句
    • 16.4 视图、事务、索引、函数
    • 16.5 MySQL存储引擎
    • 16.6 用户权限和访问控制
    • 16.7 备份恢复
    • 16.8 AB复制
    • 16.9 主主和keepalived
    • 16.10 读写分离和Amoeba
    • 16.11 MySQL逻辑架构
    • 16.12 MySQL锁等待
    • 16.13 MySQL常见问题
    • 16.14 MySQL bin-log日志清理
  • 17 Redis
    • 17.1 安装
    • 17.2 配置
    • 17.3 服务器端和客户端命令
    • 17.4 数据库操作
      • 17.4.1 string类型
      • 17.4.2 键命令
      • 17.4.3 hash类型
      • 17.4.4 list类型
      • 17.4.5 set类型
      • 17.4.6 zset类型
    • 17.5 centos7安装redis-5.0.0主从
    • 17.6 redis5.0.4集群搭建步骤
    • 17.7 centos7安装升级ruby
    • 17.8 redis-dump方式导入导出数据
    • redis面试题
  • 18 HTML
    • 18.1 html入门
  • 19 CSS
    • 19.1 列表、div、span
    • 19.2 整体感知、常见属性、选择器
    • 19.3 css性质、盒模型、标准文档流、浮动
    • 19.4 行高和字号、超链接美化、background
    • 19.5 相对定位、绝对定位、固定定位、z-index
  • 20 jenkins
    • 20.1 jenkins的安装配置
    • 20.2 Jenkins Job迁移
    • Jenkins常见问题
    • Jenkins关闭和重启的实现方式
    • 使用Jenkins Pipeline自动化构建发布
  • 21 vim
    • vim设置参数以方便YAML语句录入
    • vim常用命令
  • 22 网络
    • TCP协议三次握手四次挥手
    • ip地址
  • 23 未分类
    • DEV SIT UAT PET SIM PRD PROD常见环境英文缩写含义
    • 调优
    • 编程语言的分类
    • curl方式执行shell脚本时如何传参
    • 中文技术文档写作规范
    • PrometheusAlert
  • 24 常见问题
    • centos时区
    • curl https报错
    • du-df磁盘使用不一致
    • linux下增加交换分区
    • mysql最大连接数
  • 25 openldap
    • Centos7 搭建openldap
    • phpldapadmin操作指导
  • 26 gitlab
    • gitlab备份迁移升级&集成openldap
  • 27 监控体系
    • 聊头监控体系
    • grafana问题
  • git
    • git的基本使用
    • Commit message 和 Change log 编写指南
Powered by GitBook
On this page
  • Harbor简介
  • 高可用架构:双主复制
  • 主从同步
  • 双主复制说明
  • 高可用架构:多实例共享后端存储
  • 方案说明
  • 环境说明
  • 多实例共享后端存储 部署
  • Docker
  • Compose
  • NFS
  • PostgreSQL
  • Harbor
  • Nginx
  • 参考文章

Was this helpful?

  1. Docker

Docker Harbor HA

PreviousDocker HarborNext快速搭建rabbitmq高可用集群

Last updated 4 years ago

Was this helpful?

Harbor简介

是一个用于存储和分发Docker镜像的企业级Registry服务器,通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源Docker Distribution。

作为一个企业级私有Registry服务器,Harbor提供了更好的性能和安全。

提升用户使用Registry构建和运行环境传输镜像的效率。

Harbor支持安装在多个Registry节点的镜像资源复制,镜像全部保存在私有Registry中, 确保数据和知识产权在公司内部网络中管控。

另外,Harbor也提供了高级的安全特性,诸如用户管理,访问控制和活动审计等。

高可用架构:双主复制

主从同步

harbor官方默认提供主从复制的方案来解决镜像同步问题,通过复制的方式,我们可以实时将测试环境harbor仓库的镜像同步到生产环境harbor,类似于如下流程:

img

在实际生产运维的中,往往需要把镜像发布到几十或上百台集群节点上。这时,单个Registry已经无法满足大量节点的下载需求,因此要配置多个Registry实例做负载均衡。手工维护多个Registry实例上的镜像,将是十分繁琐的事情。Harbor可以支持一主多从的镜像发布模式,可以解决大规模镜像发布的难题:

只要往一台Harbor上发布,镜像就会像"仙女散花"般地同步到多个Registry中,高效可靠。

如果是地域分布较广的集群,还可以采用层次型发布方式,比如从集团总部机房同步到分公司1机房,再从分公司1机房同步到分公司2机房:

然而单靠主从同步,仍然解决不了harbor主节点的单点问题。

双主复制说明

所谓的双主复制其实就是复用主从同步实现两个harbor节点之间的双向同步,来保证数据的一致性,然后在两台harbor前端顶一个负载均衡器将进来的请求分流到不同的实例中去,只要有一个实例中有了新的镜像,就是自动的同步复制到另外的的实例中去,这样实现了负载均衡,也避免了单点故障,在一定程度上实现了Harbor的高可用性:

这个方案有一个问题就是有可能两个Harbor实例中的数据不一致。假设如果一个实例A挂掉了,这个时候有新的镜像进来,那么新的镜像就会在另外一个实例B中,后面即使恢复了挂掉的A实例,Harbor实例B也不会自动去同步镜像,这样只能手动的先关掉Harbor实例B的复制策略,然后再开启复制策略,才能让实例B数据同步,让两个实例的数据一致。另外,这里还需要多吐槽一句:在实际生产使用中,主从复制十分的不靠谱!!所以这里推荐使用下面要说的这种方案。

高可用架构:多实例共享后端存储

方案说明

共享后端存储算是一种比较标准的方案,就是多个Harbor实例共享同一个后端存储,任何一个实例持久化到存储的镜像,都可被其他实例中读取。通过前置LB进来的请求,可以分流到不同的实例中去处理,这样就实现了负载均衡,也避免了单点故障。

本次搭建以NFS作为共享存储存放Harbor相关data,并分离PostgreSQL与Redis为多个Harbor共同连接使用,使用Nginx做负载均衡。

如果最终生产环境集群中服务器较多,依赖做完LB的Harbor也无法完全达到需求时,可以使用如下架构,部署下级Harbor节点从主节点同步镜像,然后再分发给生产服务器。

这个方案在实际生产环境中部署需要考虑三个问题:

1. 共享存储的选取,Harbor的后端存储目前支持AWS S3、Openstack Swift, Ceph等,在下面的实验环境里,暂且直接使用nfs。

2. Session在不同的实例上共享,这个现在其实已经不是问题了,在最新的harbor中,默认session会存放在redis中,只需要将redis独立出来即可。可以通过redis sentinel或者redis cluster等方式来保证redis的可用性。在下面的实验环境里,暂且使用单台redis。

3. Harbor多实例数据库问题,这个也只需要将harbor中的数据库拆出来独立部署即可。让多实例共用一个外部数据库,数据库的高可用也可以通过数据库的高可用方案保证。

环境说明

  • 操作系统:CentOS 7.6

  • 演示环境软件版本

软件

版本

Docker

19.03.8

docker-compose

1.25.5

Harbor

1.10.2

Nginx

1.14.0

PostgreSQL

9.6.17

Redis

3.2.12

  • 演示环境网络

这里主要做Harbor高可用演示,真实生产环境请按需分离NFS与DB单独部署。

IP

主机名

192.168.16.141

Nginx

192.168.166.122

NFS

192.168.166.203

postgresql

192.168.166.245

Redis

192.168.166.81

Harbor-01

192.168.166.212

Harbor-02

多实例共享后端存储 部署

Docker

1)安装依赖包:

yum install -y yum-utils \
  device-mapper-persistent-data \
  lvm2

2)官方一键脚本安装

curl -fsSL get.docker.com -o get-docker.sh
sh get-docker.sh --mirror Aliyun

3)添加内核参数

tee -a /etc/sysctl.conf <<-EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

将net.ipv4.ip_forward赋值为1

然后刷新内核参数

sysctl -p

4)修改Docker仓库为国内镜像站

curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s https://pclhthp0.mirror.aliyuncs.com

5)启动Docker

systemctl enable docker && systemctl start docker

Compose

由于国内政策原因,可能在海外网站上下载文件速度较慢,建议下载本地后上传至服务器

1)下载docker-compose并赋予可执行权限

# curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
cd /usr/local/bin
scp 192.168.166.96:/usr/local/bin/docker-compose .

注意:由于我其他服务器已经存在,所以我直接拷贝了

2)安装bash补全命令

# curl -L https://raw.githubusercontent.com/docker/compose/1.24.1/contrib/completion/bash/docker-compose > /etc/bash_completion.d/docker-compose
scp 192.168.166.96:/etc/bash_completion.d/docker-compose /etc/bash_completion.d/

重新连接终端即生效

注意:由于我其他服务器已经存在,所以我直接拷贝了

NFS

服务端

1)安装必需的RPM包

yum -y install nfs-utils rpcbind

2)创建NFS共享目录

mkdir -p /data/harbor_data
chown nobody:nobody /data/harbor_data/

3)修改NFS服务配置文件

echo "/data/harbor_data 192.168.166.0/24(rw,sync,no_root_squash)"  >> /etc/exports

4)启动NFS服务器

systemctl enable rpcbind && systemctl restart rpcbind
systemctl enable nfs && systemctl restart nfs

客户端

1)安装nfs-utils

yum -y install nfs-utils

2)在NFS客户端上查看NFS的连通性

# showmount -e 192.168.166.122
Export list for 192.168.166.122:
/data/harbor_data 192.168.166.0/24

3)挂载NFS共享存储

创建挂载目录

mkdir /data

修改/etc/fstab配置文件加入以下内容

192.168.166.122:/data/harbor_data  /data  nfs defaults 0 0

mount挂载

mount -a

PostgreSQL

1)下载PostgreSQL官方YUM源配置文件包并安装

wget https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm
rpm -ivh pgdg-redhat-repo-latest.noarch.rpm

2)安装PostgreSQL

yum  -y install postgresql96-server postgresql96-contrib

3)初始化数据库

/usr/pgsql-9.6/bin/postgresql96-setup initdb

4)启动数据库

systemctl enable postgresql-9.6 && systemctl restart postgresql-9.6

5)PostgreSQL数据库配置

  1. 修改密码

    # su - postgres
    -bash-4.2$ psql
    psql (9.6.17)
    Type "help" for help.
    postgres=# ALTER USER postgres WITH PASSWORD 'postgres';
    ALTER ROLE
  2. 开启远程访问

    vi /var/lib/pgsql/9.6/data/postgresql.conf

    # listen_addresses = 'localhost' 改为 listen_addresses='*'

  3. 信任远程连接

    vim /var/lib/pgsql/9.6/data/pg_hba.conf

    加入:

    host    all  all  192.168.166.203/32 trust
    host    all  all  192.168.166.81/32 trust
    host    all  all  192.168.166.212/32 trust

6)重启PostgreSQL服务

systemctl restart postgresql-9.6

7)验证服务

psql -h 192.168.166.203 -p 5432 -U postgres

8)迁移数据库

  1. 在postgresql所在服务器,先启动一套harbor环境

简要步骤如下:

# yum install -y yum-utils   device-mapper-persistent-data   lvm2
# curl -fsSL get.docker.com -o get-docker.sh
# sh get-docker.sh --mirror Aliyun
#curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s https://pclhthp0.mirror.aliyuncs.com
# systemctl enable docker && systemctl start docker
# cd /usr/local/bin
# scp 192.168.166.96:/usr/local/bin/docker-compose .
# scp 192.168.166.96:/etc/bash_completion.d/docker-compose /etc/bash_completion.d/
# cd ~
# scp 192.168.166.96:/root/harbor-offline-installer-v1.10.2.tgz .
# tar -xvf harbor-offline-installer-v1.10.2.tgz -C /usr/local/
# cd /usr/local/harbor/
# vim harbor.yml ###修改hostname: 192.168.166.203  ####注释掉https段即可
# ./prepare 
# ./install.sh 
# docker-compose up -d
  1. 进入harbor-db容器导出相关表及数据

    # docker container exec -it harbor-db /bin/bash
    pg_dump -U postgres registry > /tmp/registry.sql 
    pg_dump -U postgres notarysigner > /tmp/notarysigner.sql  
    pg_dump -U postgres notaryserver > /tmp/notaryserver.sql
  2. 导出数据库

    docker container cp harbor-db:/tmp/registry.sql /tmp
    docker container cp harbor-db:/tmp/notarysigner.sql /tmp
    docker container cp harbor-db:/tmp/notaryserver.sql /tmp
  3. 将数据导入至外部PostgreSQL数据库

    # psql -h 192.168.166.203 -U postgres
    postgres=# create database registry;
    CREATE DATABASE
    postgres=# create database notarysigner;
    CREATE DATABASE
    postgres=# create database notaryserver;
    CREATE DATABASE
    psql -h 192.168.166.203 -U postgres registry < /tmp/registry.sql
    psql -h 192.168.166.203 -U postgres notarysigner  < /tmp/notarysigner.sql
    psql -h 192.168.166.203 -U postgres notaryserver < /tmp/notaryserver.sql

    Redis

1)安装redis

yum -y install redis

2) 修改配置参数

sed -i 's/bind 127.0.0.1/bind 0.0.0.0/g' /etc/redis.conf   
sed -i 's/daemonize no/daemonize yes/g' /etc/redis.conf

3)启动并测试redis连接

systemctl enable redis && systemctl restart redis
redis-cli

Harbor

1)下载

cd ~
scp 192.168.166.96:/root/harbor-offline-installer-v1.10.2.tgz .

2)解压

tar -xvf harbor-offline-installer-v1.10.2.tgz -C /usr/local/

3)修改配置文件

# cd /usr/local/harbor/
# vim harbor.yml

修改的内容有

  • hostname修改为本机ip

  • 注释掉https

  • 修改harbor默认的admin账号密码

  • 数据存储位置,改为nfs挂载目录,因为我们本来就挂载到了/data目录下,所以不用动

  • 注释掉database

  • 注释掉clair

  • 打开external_database和external_redis块的注释,并改为刚刚部署的地址

修改完的样例文件,如下

hostname: 192.168.166.81
http:
  port: 80
harbor_admin_password: Harbor12345
data_volume: /data
jobservice:
  max_job_workers: 10
notification:
  webhook_job_max_retry: 10
chart:
  absolute_url: disabled
log:
  level: info
  local:
    rotate_count: 50
    rotate_size: 200M
    location: /var/log/harbor
_version: 1.10.0
external_database:
  harbor:
    host: 192.168.166.203
    port: 5432
    db_name: registry
    username: postgres
    password: postgres
    ssl_mode: disable
    max_idle_conns: 2
    max_open_conns: 0
  clair:
    host: 192.168.166.203
    port: 5432
    db_name: clair
    username: postgres
    password: postgres
    ssl_mode: disable
  notary_signer:
    host: 192.168.166.203
    port: 5432
    db_name: notarysigner
    username: postgres
    password: postgres
    ssl_mode: disable
  notary_server:
    host: 192.168.166.203
    port: 5432
    db_name: notaryserver
    username: postgres
    password: postgres
    ssl_mode: disable
external_redis:
  host: 192.168.166.245
  port: 6379
  password:
  registry_db_index: 1
  jobservice_db_index: 2
  chartmuseum_db_index: 3
  clair_db_index: 4
proxy:
  http_proxy:
  https_proxy:
  no_proxy:
  components:
    - core
    - jobservice
    - clair

4)生成harbor运行的必要文件(环境)以及docker-compose.yml文件;执行后会通过网络获取Docker Image,建议提前修改好国内镜像站加速。

./prepare

5)安装Harbor

./install.sh

Nginx

1)安装nginx

这里我就不再详细讲了

2)编写配置文件

# cat harbor.schengle.com.conf 
upstream harbor {
    ip_hash;
    server 192.168.166.81:80;
    server 192.168.166.212:80;
}
server {
    listen       80;
    server_name  harbor.***.com;
    rewrite ^(.*) https://$server_name$1 permanent;
}
server {
    listen  443 ssl;
    server_name harbor.schengle.com;

    ssl_certificate ***.crt;
    ssl_certificate_key ***.key;
    client_max_body_size 0;
    chunked_transfer_encoding on;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        #proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto https;
        proxy_redirect off;
        proxy_ssl_verify off;
        proxy_ssl_session_reuse on;
        proxy_pass http://harbor;
        proxy_redirect default;
        proxy_http_version 1.1;
}
    location /v2/ {
        proxy_pass http://harbor/v2/;
        proxy_redirect default;
        #proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_ssl_verify off;
        proxy_ssl_session_reuse on;
        proxy_buffering off;
        proxy_request_buffering off;
    }
}

3)平滑重启nginx

nginx -s reload

参考文章

img
img
img
img
img

是Docker提供的一个命令行工具,用来定义和运行由多个容器组成的应用。使用compose,我们可以通过YAML文件声明式的定义应用程序的各个服务,并由单个命令完成应用的创建和启动。

下载离线安装包,离线安装包文件较大(约为:590M),建议在本地使用多线程工具下载后上传服务器使用。

安装可以参考

compose
Harbor
https://wiki.clay-wangzhi.com/7-nginx/1.-chu-shi-nginx#4-bian-yi-an-zhuang-nginx
https://www.cnblogs.com/kevingrace/p/11422710.html
https://juejin.im/post/5d973e246fb9a04dfa0963fb#heading-18
https://mp.weixin.qq.com/s?__biz=MzU5Mzg4NTYyOA==&mid=2247483698&idx=1&sn=79db67ba94f7de4a681f5827b32495c3&chksm=fe08e1e1c97f68f79ce3c1de437d25a0262acdf6e50295d7b05f25fd9090c05ae17547f582c9&mpshare=1&scene=24&srcid=0426o4pE2rlbV9jiC0uU7bbf&sharer_sharetime=1587898963958&sharer_shareid=9b928482ebeb2f07e6828859301773b2&key=0c8b8599c39815a077ababf632218cf4dd47c3300ac756d5d1f91cab59a40607f01f1490e733f7642923a35122555c5af376a556d629fd23b6d57045ab998c4c8ef4c0069aaa95360699b46822a279da&ascene=1&uin=MjIyMjY5MjcyMg%3D%3D&devicetype=Windows+10&version=62080079&lang=zh_CN&exportkey=ATu2VmD5qWBN%2BODgGFu%2BLRg%3D&pass_ticket=UKe3uNkZN8oXGdb8m9nzjnYYPVa%2B6oSRKUVpiOMdQ%2BemAGGjU653K0yx2yLVIF6J
Harbor