GitOps 实践:使用 Gitea + Jenkins + ArgoCD 实现 Kubernetes 配置自动同步

AI 驱动代码审查实战

Claude code-review 插件深度解析,把 AI 智能审查接进 CI/CD 流水线

为什么需要 GitOps?

在传统的 Kubernetes 配置管理实践中,我们常常面临以下痛点:

痛点描述
配置分散配置文件散落在各个开发人员的本地电脑,缺乏统一管理
变更无记录谁在什么时候改了什么配置,难以追溯
回滚困难配置出问题后,不知道上一个正确版本是什么
多环境管理混乱开发、预发布、生产环境的配置差异难以维护
手动操作风险直接 kubectl edit 修改配置,容易出错且无法审计

本文旨在帮助你搭建一套完整的 GitOps 配置管理流程,实现:

  1. 配置统一管理:所有配置文件存储在 Git 仓库中,Gitea 作为私有代码托管平台
  2. 变更可追溯:每次配置变更都有 commit 记录,可查看修改内容和提交人
  3. 自动化同步:代码推送后,Jenkins 自动触发构建,重启对应服务
  4. 实时通知:部署结果通过钉钉实时通知到团队
  5. 问题追溯:支持关联 Jira 任务,在问题下自动添加部署评论

整体流程概览

开发人员 → 本地仓库 → Gitea → Jenkins → Kuboard API → K8s集群 → Nginx Pod
   │          │        │        │           │           │          │
   ▼          ▼        ▼        ▼           ▼           ▼          ▼
 修改配置   git push  Webhook  执行构建    重启Pod     重启完成   配置生效
                              	│
                                ▼
                         钉钉通知 + Jira评论(可选)

一、环境概览

1.1 环境信息

IP说明
172.16.109.100master
172.16.109.101node1
172.16.109.102node2
组件版本/地址说明
K8s 集群v1.34.71 master+2 node
容器运行时containerd v2.2.3
Gitea最新版代码仓库,地址: http://172.16.109.102:3000
ArgoCDv3.4.3GitOps 工具
Nginxlatest示例应用,ARM64 镜像

1.2 注意事项

  • 需提前准备好k8s环境
  • 我的虚拟机环境是ARM架构的,所以下面的一些安装包可以自行找包切换至X86的

1.3 最终目标

当开发者推送代码到 Gitea 仓库时,ArgoCD 自动将最新的 ConfigMap 同步到 Kubernetes 集群,实现配置的 GitOps 管理。


二、环境准备

2.1 配置 containerd 代理

由于服务器无法直接访问外网,需要为 containerd 配置 SOCKS5 代理(自己搭建的):

# 创建代理配置目录
sudo mkdir -p /etc/systemd/system/containerd.service.d

# 配置代理
sudo tee /etc/systemd/system/containerd.service.d/http-proxy.conf << 'EOF'
[Service]
Environment="HTTP_PROXY=socks5://192.168.50.142:7891"
Environment="HTTPS_PROXY=socks5://192.168.50.142:7891"
Environment="NO_PROXY=localhost,127.0.0.1,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16,.cluster.local,.svc"
EOF

# 重启 containerd
sudo systemctl daemon-reload
sudo systemctl restart containerd

2.2 拉取所需镜像

后续将服务部署到k8s可以不操作这一步

# 拉取 Nginx ARM64 镜像,测试效果用
sudo ctr -n k8s.io image pull docker.io/library/nginx:latest --platform linux/arm64

# 拉取 ArgoCD 镜像
sudo ctr -n k8s.io image pull docker.io/argoproj/argocd:v3.4.3 --platform linux/arm64

2.3 安装 ArgoCD CLI

# 通过代理下载
curl -L -x http://192.168.50.142:7890 \
  -o argocd-linux-arm64 \
  https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-arm64

# 安装
chmod +x argocd-linux-arm64
sudo mv argocd-linux-arm64 /usr/local/bin/argocd

# 验证
argocd version --client

三、部署 Nginx 应用

3.1 创建 ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
  namespace: default
data:
  nginx.conf: |
    events {
        worker_connections 1024;
    }
    http {
        server {
            listen 80;
            location / {
                root /usr/share/nginx/html;
                index index.html;
            }
            location /health {
                return 200 "healthy\n";
            }
            location /version {
                return 200 "Version: 2.0.0\n";
            }
        }
    }
  index.html: |
    <!DOCTYPE html>
    <html>
    <head><title>Nginx GitOps</title></head>
    <body><h1>Managed by ArgoCD</h1></body>
    </html>

3.2 创建 Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: docker.io/library/nginx:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        volumeMounts:
        - name: config
          mountPath: /etc/nginx/nginx.conf
          subPath: nginx.conf
        - name: config
          mountPath: /usr/share/nginx/html/index.html
          subPath: index.html
      volumes:
      - name: config
        configMap:
          name: nginx-config

3.3 创建 Service

apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: default
spec:
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
  type: NodePort

3.4 部署并验证

# 应用所有资源
kubectl apply -f configmap.yaml -f deployment.yaml -f service.yaml

# 获取访问端口
NODE_PORT=$(kubectl get svc nginx -o jsonpath='{.spec.ports[0].nodePort}')
echo "访问端口: $NODE_PORT"

# 测试
curl http://localhost:$NODE_PORT/version
# 输出: Version: 2.0.0

四、部署 ArgoCD

4.1 创建命名空间

kubectl create namespace argocd

4.2 部署 ArgoCD Server

# 使用阿里云镜像加速部署
curl -sSL https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml | \
  sed 's/quay.io/registry.cn-hangzhou.aliyuncs.com/g' | \
  kubectl apply -n argocd -f -

4.3 暴露 ArgoCD 服务

# 创建 NodePort 服务
cat << EOF | kubectl apply -n argocd -f -
apiVersion: v1
kind: Service
metadata:
  name: argocd-server-nodeport
spec:
  type: NodePort
  ports:
  - name: https
    port: 443
    targetPort: 8080
    nodePort: 30443
  selector:
    app.kubernetes.io/name: argocd-server
EOF

# 创建 HTTP 服务用于 Webhook
cat << EOF | kubectl apply -n argocd -f -
apiVersion: v1
kind: Service
metadata:
  name: argocd-server-http
spec:
  type: NodePort
  ports:
  - name: http
    port: 80
    targetPort: 8080
    nodePort: 30444
  selector:
    app.kubernetes.io/name: argocd-server
EOF

4.4 获取初始密码

ARGO_PWD=$(kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d)
echo "ArgoCD Admin Password: $ARGO_PWD"

4.5 登录 ArgoCD

# 登录 CLI
argocd login 172.16.109.100:30443 \
  --username admin \
  --password $ARGO_PWD \
  --insecure

# 修改密码(可选)
argocd account update-password \
  --current-password $ARGO_PWD \
  --new-password your-new-password

4.6 ArgoCD Web UI

访问 https://172.16.109.100:30443 查看:

  • 应用拓扑图
  • 同步历史
  • 资源清单
  • 配置对比
    在这里插入图片描述

五、安装并配置 Git 仓库

5.1 安装Gitea(node2)

项目信息
部署方式二进制部署
安装路径/usr/local/bin/gitea
配置文件/etc/gitea/app.ini
数据目录/var/lib/gitea
仓库存储/var/lib/gitea/data/gitea-repositories
服务管理systemd
访问地址http://172.16.109.102:3000
5.1.1 下载 Gitea 二进制文件
wget https://dl.gitea.com/gitea/1.22.0/gitea-1.22.0-linux-arm64
sudo mv gitea-1.22.0-linux-arm64 /usr/local/bin/gitea
sudo chmod +x /usr/local/bin/gitea
gitea --version
5.1.2 创建 Gitea 用户和数据目录
# 创建 git 用户
sudo adduser --system --group --home /var/lib/gitea git

# 创建必要目录
sudo mkdir -p /etc/gitea /var/lib/gitea/{data,log,git}
sudo chown -R git:git /var/lib/gitea
sudo chmod 750 /var/lib/gitea
5.1.3 创建配置文件
# 编辑配置文件
sudo tee /etc/gitea/app.ini << 'EOF'
APP_NAME = GitOps 配置仓库
RUN_USER = git
RUN_MODE = prod

[server]
DOMAIN = 172.16.109.102
HTTP_PORT = 3000
ROOT_URL = http://172.16.109.102:3000
HTTP_ADDR = 0.0.0.0

[database]
DB_TYPE = sqlite3
PATH = /var/lib/gitea/data/gitea.db

[repository]
ROOT = /var/lib/gitea/data/gitea-repositories

[log]
MODE = file
LEVEL = Info
ROOT_PATH = /var/lib/gitea/log

[security]
INSTALL_LOCK = true
SECRET_KEY = $(openssl rand -base64 32)
INTERNAL_TOKEN = $(openssl rand -base64 32)

[service]
REGISTER_EMAIL_CONFIRM = false
ENABLE_NOTIFY_MAIL = false
EOF

# 设置权限
sudo chown git:git /etc/gitea/app.ini
sudo chmod 644 /etc/gitea/app.ini
5.1.4 创建 systemd 服务
sudo tee /etc/systemd/system/gitea.service << 'EOF'
[Unit]
Description=Gitea (Git with a cup of tea)
After=network.target
After=syslog.target
After=network-online.target
Wants=network-online.target

[Service]
User=gitea
Group=gitea
Type=simple
WorkingDirectory=/var/lib/gitea
ExecStart=/usr/local/bin/gitea web --config /etc/gitea/app.ini
Restart=always
RestartSec=10
LimitNOFILE=524288:524288
Environment=USER=gitea HOME=/var/lib/gitea GITEA_WORK_DIR=/var/lib/gitea

[Install]
WantedBy=multi-user.target
EOF
5.1.5 启动 Gitea
# 重载 systemd
sudo systemctl daemon-reload

# 启动 Gitea
sudo systemctl start gitea

# 设置开机自启
sudo systemctl enable gitea

# 查看状态
sudo systemctl status gitea
5.1.6 访问 Gitea 完成安装
  1. 浏览器访问 http://172.16.109.102:3000
  2. 首次访问会进入安装页面,但由于已配置 app.ini,会自动完成

注册管理员用户

  1. 点击 “注册”
  2. 填写信息:
字段建议值
用户名kk
邮箱kk@example.com
密码设置强密码

第一个注册的用户自动成为管理员

创建测试用的配置仓库

  1. 登录 Gitea
  2. 点击右上角 “+”“新建仓库”
  3. 填写:
    • 仓库名称:nginx-config
    • 可见性:公开
  4. 点击 “创建仓库”

5.2 创建并推送配置文件

# 克隆 Gitea 仓库
git clone http://172.16.109.102:3000/kk/nginx-config.git
cd nginx-config

# 创建配置目录
mkdir -p k8s-manifests

# 复制 ConfigMap 配置到 Git
cp ../configmap.yaml k8s-manifests/

# 提交并推送
git config user.name "Admin"
git config user.email "admin@example.com"
git add .
git commit -m "Initial commit: nginx configmap"
git push origin main

5.3 添加 Gitea 仓库到 ArgoCD

argocd repo add http://172.16.109.102:3000/kk/nginx-config.git \
  --name gitea-repo \
  --insecure-skip-server-verification

# 验证
argocd repo list

六、创建 ArgoCD Application

argocd app create nginx-app \
  --repo http://172.16.109.102:3000/kk/nginx-config.git \
  --revision main \
  --path k8s-manifests \
  --dest-server https://kubernetes.default.svc \
  --dest-namespace default \
  --sync-policy automated \
  --auto-prune \
  --self-heal

# 手动同步(首次)
argocd app sync nginx-app

# 查看状态
argocd app get nginx-app

预期输出显示:

Sync Status:        Synced to main (xxx)
Health Status:      Healthy

七、配置 Webhook 实现自动同步

7.1 修改 Gitea 配置(临时跳过 TLS 验证)

解决webhook报错:tls: failed to verify certificate: x509: cannot validate certificate for xxx

# 编辑 Gitea 配置文件
vi /etc/gitea/app.ini

# 添加以下内容
[webhook]
SKIP_TLS_VERIFY = true

# 重启 Gitea
systemctl restart gitea

7.2 在 Gitea 添加 Webhook

  1. 访问 http://172.16.109.102:3000/kk/nginx-config/settings/hooks
  2. 点击 “添加 Webhook” → “Gitea”
  3. 配置参数:
参数
目标 URLhttp://172.16.109.100:30444/api/webhook
HTTP 方法POST
内容类型application/json
触发条件勾选 “推送代码”
是否启用
  1. 点击 “添加 Webhook”

7.3 测试 Webhook

# 手动测试
curl -X POST http://172.16.109.100:30444/api/webhook \
  -H "Content-Type: application/json" \
  -d '{
    "ref": "refs/heads/main",
    "repository": {
      "clone_url": "http://172.16.109.102:3000/kk/nginx-config.git"
    }
  }'

八、验证 GitOps 全流程

8.1 修改配置并推送

cd /tmp/nginx-config

# 修改版本号
sed -i 's/Version: 2.0.0/Version: 3.0.0/g' k8s-manifests/configmap.yaml

# 提交推送
git add .
git commit -m "Update version to 3.0.0"
git push origin main

8.2 观察自动同步

# 查看 ArgoCD 同步状态
argocd app get nginx-app --watch

# 等待 5-10 秒,同步状态应变为 Synced

8.3 让 Nginx 加载新配置

# Reload Nginx(ConfigMap 更新后需要重载)
kubectl exec deployment/nginx -- nginx -s reload

# 验证版本已更新
NODE_PORT=$(kubectl get svc nginx -o jsonpath='{.spec.ports[0].nodePort}')
curl -s http://localhost:$NODE_PORT/version
# 输出: Version: 3.0.0

8.4 部署Jenkins

8.4.1 创建 Jenkins 部署文件
# 创建 Jenkins 命名空间
kubectl create namespace jenkins

# 创建 Jenkins Deployment 和 Service
cat << EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins
  namespace: jenkins
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jenkins
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      containers:
      - name: jenkins
        image: jenkins/jenkins:lts
        ports:
        - containerPort: 8080
        - containerPort: 50000
        env:
        - name: JAVA_OPTS
          value: "-Djenkins.install.runSetupWizard=false"
        volumeMounts:
        - name: jenkins-home
          mountPath: /var/jenkins_home
      volumes:
      - name: jenkins-home
        emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
  name: jenkins
  namespace: jenkins
spec:
  type: NodePort
  ports:
  - port: 8080
    targetPort: 8080
    nodePort: 32000
  - port: 50000
    targetPort: 50000
    nodePort: 32001
  selector:
    app: jenkins
EOF
8.4.2 拉取 Jenkins 镜像
# 测试通过代理拉取 Jenkins ARM64 镜像
sudo HTTP_PROXY=socks5://192.168.50.142:7891 \
     HTTPS_PROXY=socks5://192.168.50.142:7891 \
     ctr -n k8s.io image pull docker.io/jenkins/jenkins:lts --platform linux/arm64
8.4.3 获取 Jenkins 初始密码
# 等待 Jenkins 启动
kubectl wait --for=condition=ready pod -l app=jenkins -n jenkins --timeout=300s

# 获取初始密码
kubectl exec -n jenkins deployment/jenkins -- cat /var/jenkins_home/secrets/initialAdminPassword
8.4.4 配置 Jenkins
  1. 访问 Jenkins:http://172.16.109.100:32000
  2. 输入初始密码登录
  3. 安装推荐插件(或选择"选择插件来安装",勾选 Pipeline 和 Git 相关插件)
  4. 创建管理员用户
  5. 添加Gitea凭据
    在这里插入图片描述
  6. 新建 Pipeline 任务:nginx-config-pipeline
  7. 配置 Pipeline:
    • Definition: Pipeline script from SCM
    • SCM: Git
    • Repository URL: http://172.16.109.102:3000/kk/nginx-config.git
    • Credentials: 添加 Gitea 凭据
    • 分支: */main
    • Script Path: Jenkinsfile
      在这里插入图片描述
      在这里插入图片描述
  8. 新建钉钉机器人
8.4.5 创建 Jenkinsfile
cd /tmp/nginx-config

cat > Jenkinsfile << 'EOF'
pipeline {
    agent any
    
    environment {
        KUBOARD_URL = "http://172.16.109.100:30080/kuboard-api/cluster/myk8s/kind/CICDApi/admin/resource/restartWorkload"
        KUBOARD_USERNAME = "admin"
        KUBOARD_ACCESS_KEY = "b7zbxmzi8ypi.6ahnzr8c2s8nzkzfw5f7samcsmbx85fn"
        DINGTALK_WEBHOOK = "https://oapi.dingtalk.com/robot/send?access_token=5a582ca804deed4bc5cea8baa17e2df8e4f77459f22ab6b4f895ad5d802906ee"
    }
    
    stages {
        stage('Checkout') {
            steps {
                checkout scm
                script {
                    COMMIT_MSG = sh(script: "git log -1 --pretty=%B", returnStdout: true).trim()
                    COMMIT_AUTHOR = sh(script: "git log -1 --pretty=%an", returnStdout: true).trim()
                    DEPLOY_TIME = sh(script: "date '+%Y-%m-%d %H:%M:%S'", returnStdout: true).trim()
                    echo "重启 Nginx - ${COMMIT_MSG} by ${COMMIT_AUTHOR}"
                }
            }
        }
        
        stage('Restart') {
            steps {
                script {
                    sh """
                        curl -X PUT \
                            -H "Content-Type: application/json" \
                            -H "Cookie: KuboardUsername=${KUBOARD_USERNAME}; KuboardAccessKey=${KUBOARD_ACCESS_KEY}" \
                            -d '{"kind":"deployments","namespace":"default","name":"nginx"}' \
                            "${KUBOARD_URL}" 2>/dev/null
                    """
                    echo "等待 Pod 重启..."
                    sh "sleep 15"
                }
            }
        }
        
        stage('Verify') {
            steps {
                script {
                    def maxRetries = 10
                    def health = ""
                    for (int i = 1; i <= maxRetries; i++) {
                        health = sh(script: "curl -s -o /dev/null -w '%{http_code}' http://172.16.109.100:31856/health --connect-timeout 3 2>/dev/null || echo '000'", returnStdout: true).trim()
                        if (health == "200") {
                            break
                        }
                        sh "sleep 5"
                    }
                    if (health != "200") {
                        error("Nginx 重启失败")
                    }
                }
            }
        }
    }
    
    post {
        success {
            sh """
                curl -X POST '${DINGTALK_WEBHOOK}' \
                    -H 'Content-Type: application/json' \
                    -d '{"msgtype":"text","text":{"content":"✅ Nginx 重启成功\\n提交: ${COMMIT_MSG}\\n作者: ${COMMIT_AUTHOR}\\n时间: ${DEPLOY_TIME}"}}' 2>/dev/null || true
            """
        }
        failure {
            sh """
                curl -X POST '${DINGTALK_WEBHOOK}' \
                    -H 'Content-Type: application/json' \
                    -d '{"msgtype":"text","text":{"content":"❌ Nginx 重启失败\\n提交: ${COMMIT_MSG}\\n作者: ${COMMIT_AUTHOR}\\n时间: ${DEPLOY_TIME}"}}' 2>/dev/null || true
            """
        }
    }
}
EOF

git add Jenkinsfile
git commit -m "Add Jenkins pipeline"
git push origin main

8.5 完整流程测试

8.5.1 完整架构图
                              完整 GitOps 流程
                                  
   开发人员                         
      │                            
      │ 1. git clone & 修改配置      
      ▼                            
   ┌─────────┐    2. git push     ┌─────────┐
   │ 本地仓库 │ ─────────────────→ │  Gitea  │
   └─────────┘                    └────┬────┘
                                        │
                                        │ 3. Webhook 触发
                                        ▼
                                   ┌─────────┐
                                   │ Jenkins │
                                   └────┬────┘
                                        │
                                        │ 4. 调用 API 重启 Pod
                                        ▼
                                   ┌─────────┐
                                   │ Kuboard │
                                   │   API   │
                                   └────┬────┘
                                        │
                                        │ 5. 重启 Deployment
                                        ▼
                                   ┌─────────┐
                                   │   K8s   │
                                   │ Cluster │
                                   └────┬────┘
                                        │
                                        │ 6. Pod 重启完成
                                        ▼
                                   ┌─────────┐
                                   │  Nginx  │
                                   │  Pod    │
                                   └────┬────┘
                                        │
                                        │ 7. 发送通知
                                        ▼
                                   ┌─────────┐
                                   │  钉钉   │
                                   │  通知   │
                                   └─────────┘
8.5.2 流程测试
  1. 修改配置:在 Gitea Web UI 或本地编辑 k8s-manifests/configmap.yaml,可以修改index.html的展示内容
    在这里插入图片描述

  2. 提交推送git add . && git commit -m "描述" && git push origin main

  3. 自动同步:ArgoCD 检测到变更后自动同步(约 30 秒)到k8s
    在这里插入图片描述

  4. 构建服务:Jenkins构建一次
    在这里插入图片描述

  5. 构建信息:钉钉收到构建信息

8.5.2 观察各环节状态
环节验证方式预期结果
Git 推送git log --oneline -1显示最新提交
Gitea WebhookGitea 仓库 → Webhook → 最近交付HTTP 200
Jenkins 构建Jenkins 页面 → 构建出现新构建
Kuboard API查看 Jenkins 日志返回重启成功
Pod 重启kubectl get pods -l app=nginx -wPod 重新创建
配置验证curl http://节点IP:31856/versionVersion: xxx
curl http://节点IP:31856/index.html看到更改的内容
钉钉通知钉钉群收到成功通知

九、常见问题及解决方案

9.1 镜像拉取失败

问题exec format errorno such host

解决

  • 确认使用 --platform linux/arm64 拉取镜像
  • 配置 containerd 代理
  • 使用国内镜像源

9.2 ArgoCD 不自动同步

问题:推送后 ArgoCD 没有同步

解决

  • 检查 Webhook 配置是否正确
  • 确认 Gitea 配置文件设置了 SKIP_TLS_VERIFY = true
  • 使用手动同步:argocd app sync nginx-app --revision main

9.3 Gitea Webhook 报 TLS 错误

问题x509: certificate signed by unknown authority

解决

  • 配置 Gitea 跳过 TLS 验证
  • 或使用 HTTP Webhook(端口 30444)

9.4 ConfigMap 更新后 Nginx 未生效

问题:ConfigMap 已更新,但 Nginx 返回旧版本

解决

  • ConfigMap 更新后 Pod 内文件会自动更新,但 Nginx 需要重载
  • 执行:kubectl exec deployment/nginx -- nginx -s reload

十、相关命令速查

# ArgoCD 应用管理
argocd app list                          # 列出所有应用
argocd app get nginx-app                 # 查看应用状态
argocd app sync nginx-app                # 手动同步
argocd app history nginx-app             # 查看同步历史
argocd app rollback nginx-app            # 回滚到上一版本

# Kubernetes 资源操作
kubectl get configmap nginx-config -o yaml   # 查看 ConfigMap
kubectl exec deployment/nginx -- nginx -s reload   # 重载 Nginx
kubectl rollout restart deployment nginx     # 重启 Pod

# Git 操作
git add . && git commit -m "msg" && git push origin main   # 推送配置

AI 驱动代码审查实战

Claude code-review 插件深度解析,把 AI 智能审查接进 CI/CD 流水线

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值