[笔记] 记录docker-compose使用和Harbor的部署过程

容器技术

第三章 记录docker-compose使用和Harbor的部署过程

  • 容器技术
  • 记录docker-compose使用和Harbor的部署过程
    • Harbor
      • https方式部署:测试环境部署使用自签名SSL证书
      • https方式部署:正式环境部署使用企业颁发的SSL证书
      • 给Docker守护进程添加Harbor的SSL证书认证
      • 安装Harbor
      • 验证Harbor
      • 构建自定义镜像
        • (可选)使用composerize生成docker-compose.yml
      • 上传镜像到harbor,修改harbor的镜像标签
      • Harbor注意事项
    • 参考来源


记录docker-compose使用和Harbor的部署过程

1. 使用CentOS 7.9系列的Linux操作系统
2. docker社区版:docker-ce
3. docker部署编排工具:docker-compose
4. docker私有镜像仓库管理工具:docker-harbor
5. docker轻量级可视化容器管理工具:Portainer

# 默认已初始化安装 CentOS 7.9 + docker-ce
CPU: 4* 2
Memory: 16G
Disk: 2块物理硬盘(sda,sdb) sda: 40GB(预装最小化Linux), sdb: 200GB
Swap: 12G
hostname: docker01.myside.com
ip: 10.0.0.210
gateway: 10.0.0.254
dns: 223.5.5.5 114.114.114.114
docker应用的映射存储目录: /opt/mydocker

设置docker服务端的目录结构

/opt/mydocker/
├── certs			# 存放证书的目录, 按项目名称划分, ca证书放当前目录下
│   ├── ca.crt		# CA根证书
│   ├── ca.key		# CA私钥
│   └── harbor		# Harbor项目的SSL证书目录
├── docker-root		# docker-ce应用的目录
├── packages		# 存储安装包、软件包
│   ├── harbor
│   └── harbor-offline-installer-v2.10.2.tgz
└── projects
    └── harbor		# Harbor项目的数据目录

Harbor

https方式部署:测试环境部署使用自签名SSL证书

测试环境部署
## harbor配置HTTPS方式部署, 测试环境使用自签名SSL证书, 正式环境使用企业颁发的SSL证书
# 配置CA证书(CN=mysite.com) 和 自签名SSL证书(CN=harbor.mysite.com SAN=DNS:harbor.mysite.com,DNS:*.harbor.mysite.com)
cd /opt/mydocker/certs
# 生成CA的私钥CA证书 ca.crt
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -sha512 -days 3650 -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=mysite.com" \
 -key ca.key -out ca.crt
 
# 生成私钥和证书签名请求文件(CSR)
openssl genrsa -out harbor/harbor.mysite.com.key 4096
openssl req -sha512 -new -subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=harbor.mysite.com" \
    -key harbor/harbor.mysite.com.key -out harbor/harbor.mysite.com.csr

# 给harbor服务生成临时的x509 v3 扩展文件,使CA签发时附加SAN及更多扩展属性
cat <<EOF > v3.ext
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1=harbor.mysite.com
DNS.2=*.harbor.mysite.com
EOF
# 使用CA证书给CSR文件签发CRT证书
openssl x509 -req -sha512 -days 3650 -extfile v3.ext -CA ca.crt -CAkey ca.key -CAcreateserial \
    -in harbor/harbor.mysite.com.csr -out harbor/harbor.mysite.com.crt

https方式部署:正式环境部署使用企业颁发的SSL证书

正式环境部署
# 正式环境部署Harbor的SSL证书仅需要生成 私钥、证书签名请求(CSR),使用企业CA给csr颁发crt证书即可
# 证书签名请求(CSR)一般要手工添加SAN扩展属性
openssl genrsa -out harbor/harbor.mysite.com.key 4096
openssl req -sha512 -new -subj "/C=CN/ST=Beijing/L=Beijing/O=Technology Co., Ltd./OU=Department/CN=harbor.mysite.com" \
    -reqexts SAN -config <(cat /etc/pki/tls/openssl.cnf \
    <(printf "[SAN]\nsubjectAltName=DNS:harbor.mysite.com,*.harbor.mysite.com")) \
    -key harbor/harbor.mysite.com.key -out harbor/harbor.mysite.com.csr

给Docker守护进程添加Harbor的SSL证书认证

# Docker 守护进程会把 .crt当成CA证书 .cert当成客户端证书。所以这里要将harbor的ssl证书转换成后缀.cert的pem格式证书
# 文件内容是一样的可以用 cp ,不是pem格式则使用 openssl x509 -inform PEM 转换成pem格式
\cp harbor/harbor.mysite.com.crt harbor/harbor.mysite.com.cert
openssl x509 -inform PEM -in harbor/harbor.mysite.com.crt -out harbor/harbor.mysite.com.cert

# 复制证书文件到docker目录, 为后续的 docker login 提供证书认证。 login缺失下列文件将报错,见下文
mkdir -p /etc/docker/certs.d/harbor.mysite.com
cp ca.crt harbor/harbor.mysite.com.cert harbor/harbor.mysite.com.key /etc/docker/certs.d/harbor.mysite.com/

安装Harbor

安装 Harbor

## 官方tag包独立安装。  如下方法是获取到latest节点的版本,但仓库会存在有-rc的候选测试版本,建议从github仓库对照过最新的正式版本tag再构建二进制包的下载命令
HARBOR_TAG=`curl -s https://api.github.com/repos/goharbor/harbor/releases/latest | grep -i tag_name | awk -F '"' '{print $4}'`
wget -P /opt/mydocker/packages/ https://github.com/goharbor/harbor/releases/download/$HARBOR_TAG/harbor-offline-installer-$HARBOR_TAG.tgz

cd /opt/mydocker/packages/
tar zxvf harbor-offline-installer-$HARBOR_TAG.tgz; cd harbor
cp harbor.yml.tmpl harbor.yml
sed -i '/^$\|^\s*#/d' harbor.yml  	# 删除空行和注释行

# (可选)给core组件设置quota_update_provider,配额更新提供程序为redis
cat <<EOF >> harbor.yml
core:
  quota_update_provider: redis
  
EOF
# harbor.yml
hostname: harbor.mysite.com  # 主机名
http:
  port: 80
https:
  port: 443
  certificate: /opt/mydocker/certs/harbor/harbor.mysite.com.crt  # harbor的ssl证书,CN要跟hostname一致,否则会出现HSTS问题
  private_key: /opt/mydocker/certs/harbor/harbor.mysite.com.key  # harbor的ssl证书私钥
harbor_admin_password: Harbor12345
database:
  password: root123
  max_idle_conns: 100
  max_open_conns: 900
  conn_max_lifetime: 5m
  conn_max_idle_time: 0
data_volume: /opt/mydocker/projects/harbor	# 指定宿主机的数据目录
trivy:
  ignore_unfixed: false
  skip_update: false
  skip_java_db_update: false
  offline_scan: false
  security_check: vuln
  insecure: false
jobservice:
  max_job_workers: 10
  job_loggers:
    - STD_OUTPUT
    - FILE
  logger_sweeper_duration: 1 #days
notification:
  webhook_job_max_retry: 3
  webhook_job_http_client_timeout: 3 #seconds
log:
  level: info
  local:
    rotate_count: 50
    rotate_size: 200M
    location: /var/log/harbor
_version: 2.10.0
proxy:
  http_proxy:
  https_proxy:
  no_proxy:
  components:
    - core
    - jobservice
    - trivy
upload_purging:
  enabled: true
  age: 168h
  interval: 24h
  dryrun: false
cache:
  enabled: true  # 开启cache缓存
  expire_hours: 24
core:
  quota_update_provider: redis

[root@docker01 harbor]# ./install.sh  	# 执行harbor目录下的install.sh安装脚本
[Step 5]: starting Harbor ...
WARN[0000] /opt/mydocker/packages/harbor/docker-compose.yml: `version` is obsolete 
[+] Running 10/10
 ✔ Network harbor_harbor        Created
 ✔ Container harbor-log         Started 
 ✔ Container harbor-db          Started 
 ✔ Container harbor-portal      Started 
 ✔ Container registry           Started 
 ✔ Container registryctl        Started 
 ✔ Container redis              Started 
 ✔ Container harbor-core        Started 
 ✔ Container harbor-jobservice  Started 
 ✔ Container nginx              Started 
✔ ----Harbor has been installed and started successfully.----
# 出现如上字样 说明harbor安装完成了

验证Harbor

# 查看harbor的监听端口和配置
# 在/opt/mydocker/packages/harbor/ 目录下执行 docker compose [OPTIONS]
# 或任意目录下执行 docker compose -f /opt/mydocker/packages/harbor/docker-compose.yml [OPTIONS]
[root@docker01 harbor]# docker compose ps
WARN[0000] /opt/mydocker/packages/harbor/docker-compose.yml: `version` is obsolete 
NAME                IMAGE                                 COMMAND                  SERVICE       CREATED         STATUS                   PORTS
harbor-core         goharbor/harbor-core:v2.10.2          "/harbor/entrypoint.…"   core          6 minutes ago   Up 6 minutes (healthy)   
harbor-db           goharbor/harbor-db:v2.10.2            "/docker-entrypoint.…"   postgresql    6 minutes ago   Up 6 minutes (healthy)   
harbor-jobservice   goharbor/harbor-jobservice:v2.10.2    "/harbor/entrypoint.…"   jobservice    6 minutes ago   Up 6 minutes (healthy)   
harbor-log          goharbor/harbor-log:v2.10.2           "/bin/sh -c /usr/loc…"   log           6 minutes ago   Up 6 minutes (healthy)   127.0.0.1:1514->10514/tcp
harbor-portal       goharbor/harbor-portal:v2.10.2        "nginx -g 'daemon of…"   portal        6 minutes ago   Up 6 minutes (healthy)   
nginx               goharbor/nginx-photon:v2.10.2         "nginx -g 'daemon of…"   proxy         6 minutes ago   Up 6 minutes (healthy)   0.0.0.0:80->8080/tcp, 0.0.0.0:443->8443/tcp
redis               goharbor/redis-photon:v2.10.2         "redis-server /etc/r…"   redis         6 minutes ago   Up 6 minutes (healthy)   
registry            goharbor/registry-photon:v2.10.2      "/home/harbor/entryp…"   registry      6 minutes ago   Up 6 minutes (healthy)   
registryctl         goharbor/harbor-registryctl:v2.10.2   "/home/harbor/start.…"   registryctl   6 minutes ago   Up 6 minutes (healthy)   

[root@docker01 harbor]# iptables -t nat -nL DOCKER
[root@docker01 harbor]# netstat -tnlp | grep docker

1


构建自定义镜像

Dockerfile构建自定义镜像

# python+flask项目镜像, name:dingtalk-monitorbook	tag:1.0
# 自定义镜像的ENV环境变量建议以 _ 开头,方便区分基础镜像与自定义镜像的ENV参数
[root@docker01 dingtalk-monitorbook]# vim Dockerfile
# 一阶段构建
FROM python:3.9-buster as builder-image

# 安装py项目的requirements依赖文件
COPY requirements.txt .
RUN pip3 install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple


# 二阶段构建
FROM python:3.9-slim-buster
# 作者信息
LABEL maintainer "ww1372247148@163.com"

# 复制python的二进制执行文件和包文件
COPY --from=builder-image /usr/local/bin /usr/local/bin
COPY --from=builder-image /usr/local/lib/python3.9/site-packages /usr/local/lib/python3.9/site-packages

# 设置环境变量
ENV _CODE_DIR=/app \
    _APP_PORT=8000

# 推荐容器内使用非root用户运行进程
RUN groupadd -r _users; useradd -r -g _users _user
USER _user

# 设置工作目录
WORKDIR $_CODE_DIR
# 复制源码文件
COPY . .
# 暴露TCP端口给容器做端口映射
EXPOSE $_APP_PORT

# 添加网站的健康检查
HEALTHCHECK CMD curl --fail http://localhost:$_APP_PORT || exit 1

# 运行python命令
CMD ["python3","app.py"]
# 项目的main入口文件可能不是app.py,为保留项目的目录结构,使用 ln -s 挂载 app.py
[root@docker01 dingtalk-monitorbook]# ln -s [项目实际入口文件] ./app.py

# 新增.dockerignore文件, 根据项目目录结构添加忽略的文件
[root@docker01 dingtalk-monitorbook]# vim .dockerignore
Dockerfile
README.md
.git/
# Dockerfile构建镜像
docker build -t wwzhg77777/dingtalk-monitorbook:1.0 -f Dockerfile .
# 查看镜像构建历史
docker history wwzhg77777/dingtalk-monitorbook:1.0

docker run运行镜像,生成容器

# docker run 测试镜像是否可运行. 推荐设置 限制CPU核数、内存容量硬限制、容器不使用swap内存
docker run -itd --name dingtalk-monitorbook -p 8000:8000 --restart=unless-stopped --cpus=1 -m 256m --memory-swappiness=0  wwzhg77777/dingtalk-monitorbook:1.0
# 查看容器运行日志
docker logs dingtalk-monitorbook

docker compose up -d运行容器编排,生成容器

# docker-compose.yml
version: "3"
services:
  dingtalk-monitorbook:
    container_name: dingtalk-monitorbook
    ports:
      - 8000:8000
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: "1"
          memory: 256m
    networks:
      - dingtalk-monitorbook
    image: wwzhg77777/dingtalk-monitorbook:1.0
networks:
  dingtalk-monitorbook:
    name: dingtalk-monitorbook
# docker-compose 测试镜像是否可运行
docker compose up -d
# 查看容器运行日志
docker compose logs
(可选)使用composerize生成docker-compose.yml
# (可选)使用 Composerize 将Container running之后的容器配置转换成 docker-compose.yml 再进行优化
# Composerize github: https://github.com/composerize/composerize
# Composerize的在线网站: https://www.composerize.com/
# Composerize的容器下载(仅支持web访问): https://hub.docker.com/r/gettionhub/composerize
# 自己构建一个composerize镜像, 设置alias别名 用于CLI执行composerize
cat <<EOF > Dockerfile
FROM node:14-alpine
RUN npm install composerize -g
ENTRYPOINT ["composerize"]
EOF
docker build -t local-composerize .
echo "alias composerize='docker run -it --rm local-composerize'" >> /etc/profile.d/_alias.sh
source /etc/profile.d/_alias.sh
[root@docker01 ~]# composerize docker run -itd --name dingtalk-monitorbook -p 8000:8000 --restart=unless-stopped --cpus=1 -m 256m wwzhg77777/dingtalk-monitorbook:1.0
name: <your project name>
services:
  dingtalk-monitorbook:
    stdin_open: true
    tty: true
    container_name: dingtalk-monitorbook
    ports:
      - 8000:8000
    restart: unless-stopped
    deploy:
      resources:
        limits:
          cpus: 1
          memory: 256m
    image: wwzhg77777/dingtalk-monitorbook:1.0

上传镜像到harbor,修改harbor的镜像标签

# Docker守护进程已添加Harbor的SSL证书认证,执行 docker login 登录
[root@docker01 ~]# docker login -u admin -p Harbor12345 harbor.mysite.com
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded
# 出现如上字样 说明docker登录harbor成功
# 给本地的镜像打tag,加上harbor服务器地址作为前缀,默认放library项目下
docker tag wwzhg77777/dingtalk-monitorbook:1.0 harbor.mysite.com/library/dingtalk-monitorbook:1.0
# push镜像到harbor
docker push harbor.mysite.com/library/dingtalk-monitorbook:1.0

3

Harbor注意事项

### Docker守护进程没有添加Harbor的SSL证书认证,测试登录Harbor
[root@docker02 ~]# docker login -u admin -p Harbor12345 harbor.mysite.com
Error response from daemon: Get "https://harbor.mysite.com/v2/": tls: failed to verify certificate: x509: certificate signed by unknown authority
# 添加CA证书到 /etc/docker/certs.d/harbor.mysite.com/ 目录即可解决

### push镜像时, 如果不加harbor服务器地址作为前缀, 将默认push到docker.io
[root@docker01 ~]# docker push wwzhg77777/dingtalk-monitorbook:1.0
The push refers to repository [docker.io/wwzhg77777/dingtalk-monitorbook]

参考来源

  1. Harbor Installation and Configuration
  2. python 多阶段构建docker镜像,有效减少镜像大小
  3. 24条Dockerfile及指令最佳实践
  4. 如何编写最佳的Dockerfile
  5. Docker 8:Docker 资源(内存/CPU)限制实验

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/680082.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++面向对象-继承,多态,重载

目录 零. 简介 一. 继承 1.基类,派生类 2.访问控制和继承: 3.多继承 二. 多态 关键字 virtual override : 用例:工厂模式 三. 重载 函数重载: 操作符重载: 零. 简介 继承&#xff1a;允许一个类从另一个类获取属性和方法。子类可以继承父类的特性&#xff0c;并可以…

python11 序列的相关操作

枚举遍历 序列的相关操作 text "hello,python" # in 判断字符是否在序列中&#xff0c;存在返回true,否则返回false print(p是否存在:,(p in text)) print(a是否存在:,(a in text)) # not in 判断字符不在序列中&#xff0c;不存在返回true,否则返回false print(p不…

代码随想录——二叉搜索树的最近公共祖先(Leetcode235)

题目链接 普通递归法 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode(int x) { val x; }* }*/class Solution {public TreeNode lowestCommonAncestor(TreeNode root, TreeNode…

python猴子补丁Monkey Patching

猴子补丁&#xff08;Monkey Patching&#xff09;是一种动态修改或扩展代码行为的技术。具体来说&#xff0c;它是在运行时改变或扩展模块、类或函数的行为&#xff0c;而不需要修改源代码本身。这在某些情况下非常有用&#xff0c;比如&#xff1a; 修复第三方库中的bug&…

MySQL中所有常见知识点汇总

存储引擎 这一张是关于整个存储引擎的汇总知识了。 MySQL体系结构 这里是MySQL的体系结构图&#xff1a; 一般将MySQL分为server层和存储引擎两个部分。 其实MySQL体系结构主要分为下面这几个部分&#xff1a; 连接器&#xff1a;负责跟客户端建立连 接、获取权限、维持和管理…

C++高级 - 接口模板

目录 一. 接口 二. 模板 一. 接口 接口通常是通过抽象类或纯虚函数来实现的。 以下是一个使用抽象类来定义接口的示例代码&#xff1a; #include <iostream>class Interface { public:virtual void operation() 0; // 纯虚函数定义接口 };class ConcreteClass : pu…

Windows CMD对MySQL进行基本操作的常用命令

目录 前言1. 数据库操作2. 表操作3. 记录操作4. 备份与恢复数据库 前言 对于基本的命令行以及优化推荐阅读&#xff1a; 数据库中增删改常用语法语句&#xff08;全&#xff09;Mysql优化高级篇&#xff08;全&#xff09;命令行登录Mysql的详细讲解 启动MySQL服务&#xff1…

渐开线花键学习之齿厚(实际作用怎么分?)

国标GB/T 3478.1-2008中对渐开线花键的齿厚相关的描述如下&#xff1a; 【基本齿槽宽】E&#xff08;basic space width&#xff09;内花键分度圆上弧齿槽宽的基本尺寸&#xff0c;其值为齿距的一半。 【实际齿槽宽】&#xff08;actual space width&#xff09;在内花键分度…

机器学习算法 —— 逻辑回归

&#x1f31f;欢迎来到 我的博客 —— 探索技术的无限可能&#xff01; &#x1f31f;博客的简介&#xff08;文章目录&#xff09; 目录 逻辑回归逻辑回归的介绍逻辑回归的优点逻辑回归的缺点逻辑回归的应用 实践演示库函数导入模型训练模型参数查看数据和模型可视化模型预测 …

CCIG 2024:大模型技术及其前沿应用论坛深度解析

一、CCIG论坛介绍 中国图象图形大会&#xff08;CCIG 2024&#xff09;是一场备受瞩目的学术盛会&#xff0c;近期在陕西省西安市曲江国际会议中心举行。这次会议以“图聚智生&#xff0c;象合慧成”为主题&#xff0c;由中国图象图形学学会主办&#xff0c;旨在汇聚图像图形领…

12 - 常用类

那就别跟他们比&#xff0c;先跟自己比&#xff0c;争取今天比昨天强一些&#xff0c;明天比今天强一些。 1.包装类 针对八种基本数据类型封装的相应的引用类型。 有了类的特点&#xff0c;就可以调用类中的方法。&#xff08;为什么要封装&#xff09; 基本数据类型包装类b…

b端系统项目进度巡检设备物资劳务台账等OA前端UI设计开发

b端系统项目进度巡检设备物资劳务台账等OA前端UI设计开发

phpstudy配置的站点不能访问了

无法打开站点 打开网站的时候出现如下 没有人为主动去更改配置项&#xff0c;今天就不能正常访问了 检查了一遍配置&#xff0c;发现并无大碍&#xff0c;那就重新配置一遍看看 配置phpstudy 1、新建网站 2、选择项目入口文件夹 3、配置伪静态 4. 确认保存 在我的电脑 C:\…

公安视频图像信息数据库及GA/T 1400视图库视频监控系统的使用场景

随着科技的快速发展&#xff0c;大数据、人工智能等新技术不断融入各行各业&#xff0c;为各行各业带来了前所未有的变革。在公安领域&#xff0c;GA/T 1400协议公安视频图像信息数据库的应用为视频监控场景提供了强有力的支持&#xff0c;极大地提升了公安工作的效率和准确性。…

风管静压箱的作用及选型

1.压力的种类 动压—由风速而产生的压力&#xff1b;空调厂家设计时均已经考虑&#xff0c;无需计算。静压—垂直作用于风管壁面的压力&#xff0c;用于克服风管阻力&#xff1b;所以&#xff0c;对于风管机组有零静压和带静压之分&#xff0c;零静压指静压为0Pa&#xff0c;不…

VUE3 学习笔记(14):VUE3 组合式API与传统选项式API用法

VUE3相较VUE2的亮点很多&#xff0c;作为后端开发置于前端最大的感受就是组合式API&#xff08;之前采用的是选项式API&#xff09;&#xff1b;它使得整体更简洁易用,但值得提醒的是官方并未强制要求二选一&#xff0c;尽管如此在同一个项目中还是不要出现两种写法。 选项式AP…

SpringCloud 微服务中网关如何记录请求响应日志?

在基于SpringCloud开发的微服务中&#xff0c;我们一般会选择在网关层记录请求和响应日志&#xff0c;并将其收集到ELK中用作查询和分析。 今天我们就来看看如何实现此功能。 日志实体类 首先我们在网关中定义一个日志实体&#xff0c;用于组装日志对象 Data public class …

U-Net: Convolutional Networks for Biomedical Image Segmentation--论文笔记

U-Net: Convolutional Networks for Biomedical Image Segmentation 资料 1.代码地址 2.论文地址 https://arxiv.org/pdf/1505.04597 3.数据集地址 论文摘要的翻译 人们普遍认为&#xff0c;深度网络的成功训练需要数千个带注释的训练样本。在本文中&#xff0c;我们提出…

“GPT-4o深度解析:技术演进、能力评估与个人体验综述“

文章目录 每日一句正能量前言对比分析模型架构性能应用场景用户体验技术创新社区和生态系统总结 技术能力语言生成能力语言理解能力技术实现总结 个人感受关于GPT-4o的假设性观点&#xff1a;关于当前语言模型的一般性观点&#xff1a; 后记 每日一句正能量 又回到了原点&#…

【前端】display:none和visibility:hidden两者的区别

&#x1f60e; 作者介绍&#xff1a;我是程序员洲洲&#xff0c;一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主。公粽号&#xff1a;洲与AI。 &#x1f913; 欢迎大家关注我的专栏&#xff0c;我将分享Web前后端开发、…