# Docker 运维管理


<!--more-->


## 1.常见软件安装

mysql主从、主主，elasticsearch, fastDFS, gitlab...................感兴趣可以通过dockerfile练习

## 2. Swarm集群管理

compose、machine 和 swarm 是docker 原生提供的三大编排工具。简称docker三剑客。

准备3台服务器，分别安装docker

当前应用状态：![docker](https://img.zhaojq.top/20260727184918113.png "docker")

**容器化部署=大麻烦**

```
怎么保证数据完整性
怎么保护客户隐私数据
怎么去调度容器
怎么去监控追踪容器
怎么去更新容器而不影响客户的业务
如果容器down掉了。怎么自动恢复
怎么去管很多微服容器
怎么根据客户业务需求，快速方便的扩展容器
```

![img_10](https://img.zhaojq.top/20260727091743828.png "img_10")

### 2.1 安装docker swarm

#### 2.1.1 概述

> 官方文档: https://docs.docker.com/engine/swarm/

Docker Swarm 和 Docker Compose 一样，都是 Docker 官方容器编排项目，但不同的是，Docker Compose 是一个在单个服务器或主机上创建多个容器的工具，可以将组成某个应用的多个docker容器编排在一起，同时管理。

而 Docker Swarm 则可以在多个服务器或主机上创建容器集群服务，其主要作用是把若干台Docker主机抽象为一个整体，并且通过一个入口（docker stack）统一管理这些Docker主机上的各种Docker资源

stack 是构成特定环境中的 service 集合, 它是自动部署多个相互关联的服务的简便方法，而无需单独定义每个服务。

stack file 是一种 yaml 格式的文件，类似于 docker-compose.yml 文件，它定义了一个或多个服务，并定义了服务的环境变量、部署标签、容器数量以及相关的环境特定配置等。

Docker Swarm由两部分组成：

- Docker集群：将一个或多个Docker节点组织起来，用户就能以集群的方式进行管理；

- 应用编排：有一套API用来部署和管理容器

![img_11](https://img.zhaojq.top/20260727091744004.png "img_11")

#### 2.1.2 配置私有仓库

私有仓库不是集群必备的组件。集群的每个节点都需要安装镜像，如果不搭建私有仓库，下载镜像速度比较耗时

```sh
vim /etc/docker/daemon.json 

"insecure-registries":["192.168.198.101:5000"]

systemctl daemon-reload
systemctl restart docker
```

#### 2.1.3 初始化第一个管理节点

关于advertise-addr和listen-addr这两个参数:

```
前者用来指定其他节点连接manager0时的地址
后者指定承载swarm流量的IP和端口
会在本地新建docker网络
```

```sh
docker swarm init --advertise-addr 192.168.0.87:2377 --listen-addr 192.168.0.87:2377

docker node ls 
docker network ls
```

#### 2.1.4 如何加入新的节点

Docker Swarm的新节点加入策略是从管理节点获取一长串命令，被称为**join token**，任何想加入集群的机器只要自己执行这个join token即可加入Swarm集群；

如果有新的管理节点需要加入，在manager 0执行命令**docker swarm join-token manager**即可得到管理manager节点的join token

如果有新的work节点需要加入，在manager  0执行命令**docker swarm join-token worker**即可得到管理work节点的join token

```sh
在manager节点执行。可以作为manager节点加入集群 
docker swarm join-token manager

在manager节点执行。可以作为worker节点加入集群 
docker swarm join-token worker

docker node ls
```

#### 2.1.5 manager节点说明

MANAGER STATUS列说明：

- Leader 意味着该节点是使得群的所有群管理和编排决策的主要管理器节点。

- Reachable 意味着节点是管理者节点正在参与Raft共识。如果领导节点不可用，则该节点有资格被选为新领导者。

- Unavailable 意味着节点是不能与其他管理器通信的管理器。如果管理器节点不可用，您应该将新的管理器节点加入群集，或者将工作器节点升级为管理器。

AVAILABILITY列说明：

- Active 意味着调度程序可以将任务分配给节点。

- Pause 意味着调度程序不会将新任务分配给节点，但现有任务仍在运行。

- Drain 意味着调度程序不会向节点分配新任务。调度程序关闭所有现有任务并在可用节点上调度它们。

#### 2.1.6 验证节点

```
master节点:
docker info 

work节点:
docker info
```

#### 2.1.7 节点权限提升/降低

```sh
#将worker 提升为manager, 在manager 节点执行如下命令
docker node promote [node name]
docker node ls

#将manager 降低为worker, 在manager 节点执行如下命令
docker node demote [node name]
docker node ls
```

#### 2.1.8 脱离集群

```sh
# 在worker 节点使用命令: 
docker swarm leave
```

#### 2.1.9 删除脱离集群的节点

```sh
# 先使用命令
docker node demote [node name],将一个节点降为worker后, 再删除

# 使用命令
docker node rm [node name|id]

# manager节点只能强制退出。命令：docker swarm leave --force。manager退出后意味着整个swarm 不复存在。
```

### 2.2 图形界面

> 官网: https://hub.docker.com/r/dockersamples/visualizer

```sh
# 基础镜像
docker pull dockersamples/visualizer:latest

# 备份镜像 (不是必要步骤)
docker save dockersamples/visualizer:latest -o dockersamples.visualizer.tar 

#还原镜像 (不是必要步骤)
docker load -i dockersamples.visualizer.tar

# 运行镜像
docker run -itd --name visualizer -p 8099:8080 -e HOST=192.168.198.105 -e PORT=8080 -v /var/run/docker.sock:/var/run/docker.sock dockersamples/visualizer:latest

docker service create \ 
--name=viz \ 
--publish=8080:8080/tcp \ 
--constraint=node.role==manager \ --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \ dockersamples/visualizer

# 测试连接
http://ip:8099
```

### 2.3 swarm 命令

| 命令                    | 描述                     |
| ----------------------- | ------------------------ |
| docker swarm init       | 初始化一个 swarm 群集    |
| docker swarm join       | 加入群集作为节点或管理器 |
| docker swarm join-token | 管理用于加入群集的令牌   |
| docker swarm leave      | 离开 swarm 群集          |
| docker swarm unlock     | 解锁 swarm 群集          |
| docker swarm unlock-key | 管理解锁钥匙             |
| docker swarm update     | 更新 swarm 群集          |

### 2.4 node 命令

| 命令                | 描述                                             |
| ------------------- | ------------------------------------------------ |
| docker node demote  | 从 swarm 群集管理器中降级一个或多个节点          |
| docker node inspect | 显示一个或多个节点的详细信息                     |
| docker node ls      | 列出 swarm 群集中的节点                          |
| docker node promote | 将一个或多个节点推入到群集管理器中               |
| docker node ps      | 列出在一个或多个节点上运行的任务，默认为当前节点 |
| docker node rm      | 从 swarm 群集删除一个或多个节点                  |
| docker node update  | 更新一个节点                                     |

### 2.5 service 命令

| 命令                    | 描述                         |
| ----------------------- | ---------------------------- |
| docker service create   | 创建服务                     |
| docker service inspect  | 显示一个或多个服务的详细信息 |
| docker service logs     | 获取服务的日志               |
| docker service ls       | 列出服务                     |
| docker service rm       | 删除一个或多个服务           |
| docker service scale    | 设置服务的实例数量           |
| docker service update   | 更新服务                     |
| docker service rollback | 恢复服务至update之前的配置   |

例 : ![img_12](https://img.zhaojq.top/20260727091744238.png "img_12")

- 基础镜像

  ```sh
  #3台机器都准备基础镜像
  docker pull nginx:1.18.0-alpine 
  docker pull nginx:1.19.3-alpine
  ```

- 部署nginx

  ```sh
  #在manager节点中创建overlay网络：
  docker network create -d overlay nginx-net
  
  #创建5个nginx:alpines容器的集群：
  docker service create --name nginx --network nginx-net -p 80:80 --replicas 5 nginx:1.18.0-alpine
  
  #在manager节点使用docker service ls 命令查看服务情况，worker节点无法查看：
  docker service ls
  
  #在manager或者worker节点都可以执行docker ps命令查看本虚拟机容器情况：
  docker ps
  
  #manager节点只用于管理集群，不希望部署服务。
  docker node update --availability drain master-01[此处为manager name]
  
  #使用docker service scale nginx=2命令将服务缩减为2个容器：
  docker service scale nginx=2
  ```

- 升级nginx版本

  ```sh
  #进入其中一个容器查看nginx的版本信息： 注意事项：因nginx是alpine的linux版本。不能使用/bin/bash指令。
  docker exec -it 503fe639bb89 sh
  nginx -v
  
  #1.更新镜像：
  docker service update --image nginx:1.19.3-alpine nginx
  
  #2.添加或者更新一个对外端口：
  docker service update --publish-add 8090:80 nginx
  ```

- 删除服务

  ```sh
  docker service rm nginx
  docker network rm nginx-net
  ```

### 2.6 stack命令

| 命令                  | 描述                       |
| --------------------- | -------------------------- |
| docker stack deploy   | 部署新的堆栈或更新现有堆栈 |
| docker stack ls       | 列出现有堆栈               |
| docker stack ps       | 列出堆栈中的任务           |
| docker stack rm       | 删除一个或多个堆栈         |
| docker stack services | 列出堆栈中的服务           |

- 部署nginx

  ```yaml
  version: "3"
  services: 
  	nginx-web: 
  		image: nginx:1.19.3-alpine 
  		container_name: nginx 
  		networks: 
  			- nginx-net
           restart: always
           ports: 
           	- 80:80
           deploy: 
           	replicas: 5 
  networks: 
  	nginx-net: 
  		driver: overlay
  ```

- 运行nginx

  ```sh
  #在manager节点中创建docker-compose.yml文件。执行如下命令：
  docker stack deploy nginx-stack --compose-file=docker-compose.yml 
  或者是 
  docker stack deploy nginx-stack -c docker-compose.yml
  
  #查看stack服务运行情况。执行如下命令： 
  docker stack services nginx-stack
  
  #查看5个容器运行在哪个节点中。执行如下命令：
  docker service ls 查看到NAME中的服务名为：nginx-stack_nginx-web 
  docker service ps nginx-stack_nginx-web
  
  #删除stack服务。执行如下命令： 
  docker stack rm nginx-stack
  ```

- ```
  总结：
  networks中也可以不指定driver:overlay，因为docker swarm默认网络类型是overlay。
  整个networks都可以不用配置。stack部署时会默认创建网络。如果我们定义网络。在docker
  stack deploy时会先默认创建一个网络，在创建一个我们定义的网络。
  一定要把镜像先拉取到本地再执行
  ```

- docker stack 和docker compose区别

  ```
  1.Docker stack会忽略了“构建”指令，无法使用stack命令构建新镜像，它是需要镜像是预先已经构建
  好的。 所以docker-compose更适合于开发场景；
  2.Docker Compose是一个Python项目，在内部，它使用Docker API规范来操作容器。所以需要安
  装Docker -compose，以便与Docker一起在您的计算机上使用；
  3.Docker Stack功能包含在Docker引擎中。你不需要安装额外的包来使用它，docker stacks 只是
  swarm mode的一部分。
  4.Docker stack不支持基于第2版写的docker-compose.yml ，也就是version版本至少为3。然而
  Docker Compose对版本为2和3的 文件仍然可以处理；
  5.docker stack把docker compose的所有工作都做完了，因此docker stack将占主导地位。同时，
  对于大多数用户来说，切换到使用docker stack既不困难，也不需要太多的开销。如果您是Docker
  新手，或正在选择用于新项目的技术，请使用docker stack。
  ```

## 3. harbor企业级部署

默认情况下，harbor不提供证书。可以在没有安全性的情况下部署harbor，就可以通过HTTP方式连接到harbor。但是，只有在没有连接到外部internet的测试环境或开发环境中才可以使用HTTP。在生产环境中，始终使用**HTTPS**。要配置HTTPS，必须创建SSL证书。可以使用由受信任的第三方CA签名的证书，也可以使用自签名证书。本节介绍如何使用OpenSSL创建CA，以及如何使用CA签署服务器证书和客户端证书。下面的过程假设harbor注册表的主机名是harbor.lagouedu.com，并且它的DNS记录指向运行harbor的主机。

> 官网https配置帮助文档: https://github.com/goharbor/harbor/blob/v1.9.4/docs/configure_https.md

- 解压harbor

  在harbor中创建一个目录，用于存放证书

  ```sh
  echo "192.168.198.101 harbor.my.com" >> /etc/hosts
  cat /etc/hosts 
  
  cd /data 
  tar zxf harbor-offline-installer-v1.9.4.tgz
  
  cd harbor/ 
  mkdir -p ssl 
  
  cd ssl
  ```

- 获得证书颁发机构

  在生产环境中，应该从CA官方获取证书。在测试或开发环境中，可以生成自己的CA。若要生成CA证书，请运行以下命令。

  ```sh
  cd /data/harbor/ssl 
  创建CA根证书 
  openssl genrsa -out ca.key 4096 
  
  openssl req -x509 -new -nodes -sha512 -days 3650 -subj 
  "/C=TW/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=harbor.my.com"
  -key ca.key -out ca.crt
  ```

- 获取服务器证书

  证书通常包含**.crt**文件和.key文件，例如 `harbor.my.com.crt `和 `harbor.my.com.key`。

  - 创建自己的私钥

    ```sh
    openssl genrsa -out harbor.my.com.key 4096
    ```

  - 生成证书签名请求

    ```sh
    调整-subj选项中的值以反映您的组织。如果使用域名方式连接harbor主机，则必须将其指定为
    common name（CN）属性，并在key和CSR文件名中使用它。
    openssl req -sha512 -new -subj 
    "/C=TW/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=harbor.my.com" 
    -key harbor.my.com.key -out harbor.my.com.csr
    ```

  - 生成注册表主机的证书

    无论是使用域名还是使用IP地址连接到您的Harbor主机，都必须创建此文件，以便您可以为harbor主机生成符合使用者替代名称（SAN）和x509 v3扩展要求的证书。替换DNS条目以反映harbor的域。

    ```sh
    cat > v3.ext <<-EOF
    authorityKeyIdentifier=keyid,issuer 
    basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
    extendedKeyUsage = serverAuth 
    subjectAltName = @alt_names
    [alt_names] DNS.1=harbor.my.com 
    EOF
    ```

    使用v3.ext文件为harbor主机生成证书。

    ```sh
    openssl x509 -req -sha512 -days 3650 -extfile v3.ext -CA ca.crt -CAkey 
    ca.key - CAcreateserial -in harbor.my.com.csr -out harbor.my.com.crt
    ```

- 为docker配置服务器证书,密钥和CA

  生成ca.crt、harbor.my.com.crt和harbor.my.com.key文件后，必须将它们提供给Harbor和Docker，并重新配置Harbor以使用它们。

  将yourdomain.com.crt转换为yourdomain.com.cert，供Docker使用。

  Docker守护进程将.crt文件解释为CA证书，.cert文件解释为客户端证书。

  ```sh
  openssl x509 -inform PEM -in harbor.my.com.crt -out harbor.my.com.cert 
  
  mkdir -p /etc/docker/certs.d/harbor.my.com/ 
  cp harbor.my.com.cert /etc/docker/certs.d/harbor.my.com/ 
  cp harbor.my.com.key /etc/docker/certs.d/harbor.my.com/ 
  cp ca.crt /etc/docker/certs.d/harbor.my.com/ 
  
  重启docker服务： 
  systemctl daemon-reload
  systemctl restart docker
  ```

- 修改harbor.yml文件

  ```yaml
  hostname: harbor.my.com
  https: 
      port: 443 
      certificate: /data/harbor/ssl/harbor.my.com.crt 
      private_key: /data/harbor/ssl/harbor.my.com.key
  ```

- 安装harbor

  ```sh
  docker pull goharbor/prepare:v1.9.4
  
  cd /data/harbor
  ./prepared
  ./install.sh
  ```

- 访问

  ```
  #先在host文件配置ip与域名的映射
  https://harbor.my.com/
  ```

- 上传镜像

  ```sh
  docker login harbor.my.com 
  admin 
  Harbor12345 
  
  docker load -i nginx.1.19.3.alpine.tar 
  docker tag nginx:1.19.3-alpine harbor.my.com/my/nginx:v1 
  docker push harbor.my..com/my./nginx:v1
  ```

  

