10-算力中心运维三剑客:Ansible + Jenkins + K8s 高效实战

10-算力中心运维三剑客:Ansible + Jenkins + K8s 高效实战

在算力中心运维工作中,我们经常需要处理降内核版本、安装网卡驱动、GPU驱动等任务。如果手动一台台操作,效率极低且容易出错。Ansible、Jenkins、K8s 这三个工具结合使用,可以构建一个高效的自动化运维体系。

1. 三剑客的角色定位

场景类比:

想象一个现代化的工厂生产线:

  • Ansible自动化装配线工人 - 负责具体的安装、配置操作
  • Jenkins生产调度中心 - 负责协调、触发、监控整个流程
  • K8s智能仓储系统 - 负责管理容器化应用的部署和调度

1.1 Ansible - 配置管理专家

核心职责:

  • 批量操作服务器(降内核、装驱动)
  • 配置管理(统一配置、版本控制)
  • 任务自动化(定时任务、批量更新)

适用场景:

  • ✅ 降内核版本(需要重启服务器)
  • ✅ 安装网卡驱动(操作系统层面)
  • ✅ 安装GPU驱动(操作系统层面)
  • ✅ 批量配置系统参数
  • ✅ 批量部署软件包

1.2 Jenkins - CI/CD 流水线

核心职责:

  • 自动化流程编排
  • 任务调度和触发
  • 构建和部署自动化
  • 通知和监控

适用场景:

  • ✅ 定时执行运维任务
  • ✅ 代码提交触发自动化流程
  • ✅ 多阶段任务编排(先降内核,再装驱动,最后部署应用)
  • ✅ 团队协作和权限管理

1.3 K8s - 容器编排平台

核心职责:

  • 容器化应用管理
  • 资源调度和分配
  • 服务发现和负载均衡
  • 自动扩缩容

适用场景:

  • ✅ 部署和管理AI训练任务
  • ✅ 部署Web服务、API服务
  • ✅ 管理有状态服务(数据库、Redis)
  • ✅ 资源配额和调度优化

2. 实战场景:降内核版本 + 安装GPU驱动

2.1 传统方式 vs 自动化方式

传统方式(痛苦):

bash 复制代码
# 1. 手动登录每台服务器
ssh server1
# 2. 检查当前内核版本
uname -r
# 3. 降内核版本
yum install kernel-4.18.0-348.el8.x86_64
# 4. 重启服务器
reboot
# 5. 等待重启完成
# 6. 重新登录
ssh server1
# 7. 安装GPU驱动
./NVIDIA-Linux-x86_64-535.129.03.run
# 8. 验证驱动
nvidia-smi
# 9. 重复以上步骤对server2、server3...server100

问题: 耗时长、容易出错、无法并行、难以回滚

自动化方式(高效):

bash 复制代码
# 1. 在Jenkins点击"降内核+装驱动"按钮
# 2. Jenkins触发Ansible Playbook
# 3. Ansible并行操作100台服务器
# 4. 自动验证结果
# 5. 发送通知

2.2 完整自动化流程

流程图:

复制代码
用户触发
    ↓
Jenkins Pipeline
    ↓
阶段1: 备份当前配置
    ↓
阶段2: 降内核版本(Ansible)
    ↓
阶段3: 重启服务器(Ansible)
    ↓
阶段4: 等待服务器恢复(Jenkins)
    ↓
阶段5: 安装GPU驱动(Ansible)
    ↓
阶段6: 验证驱动(Ansible)
    ↓
阶段7: 部署应用到K8s(Jenkins + K8s)
    ↓
完成通知

3. Ansible实战:降内核版本

3.1 Ansible Playbook示例

文件结构:

复制代码
ansible-playbooks/
├── inventory/
│   └── hosts                    # 服务器清单
├── roles/
│   ├── downgrade-kernel/
│   │   ├── tasks/
│   │   │   └── main.yml       # 降内核任务
│   │   └── handlers/
│   │       └── main.yml       # 处理器
│   └── install-gpu-driver/
│       ├── tasks/
│       │   └── main.yml       # 安装GPU驱动任务
│       └── files/
│           └── NVIDIA-Linux-x86_64-535.129.03.run
└── playbooks/
    ├── downgrade-kernel.yml     # 降内核playbook
    └── install-gpu-driver.yml  # 安装GPU驱动playbook

降内核Playbook:

yaml 复制代码
# 以下代码为示例,实际操作前请在测试环境验证

---
- name: 降内核版本
  hosts: gpu_servers
  become: yes
  serial: 10  # 每次同时操作10台服务器,避免全部重启

  tasks:
    - name: 检查当前内核版本
      command: uname -r
      register: current_kernel
      changed_when: false

    - name: 显示当前内核版本
      debug:
        msg: "当前内核版本: {{ current_kernel.stdout }}"

    - name: 备份当前内核配置
      copy:
        src: /etc/grub2.cfg
        dest: /etc/grub2.cfg.backup
        remote_src: yes
        backup: yes

    - name: 安装指定版本的内核
      yum:
        name: kernel-4.18.0-348.el8.x86_64
        state: present
        disable_gpg_check: yes

    - name: 设置默认启动内核
      command: grub2-set-default 0
      changed_when: false

    - name: 显示默认启动内核
      command: grub2-editenv list
      register: default_kernel
      changed_when: false

    - name: 通知需要重启
      debug:
        msg: "内核已降级,默认启动内核: {{ default_kernel.stdout }},需要重启服务器"

  handlers:
    - name: 重启服务器
      reboot:
        reboot_timeout: 600
        connect_timeout: 15
        test_command: whoami
      async: 1
      poll: 0

3.2 安装GPU驱动Playbook

yaml 复制代码
# 以下代码为示例,实际操作前请在测试环境验证

---
- name: 安装GPU驱动
  hosts: gpu_servers
  become: yes
  serial: 10

  tasks:
    - name: 检查GPU驱动版本
      command: nvidia-smi --query-gpu=driver_version --format=csv,noheader
      register: current_driver
      changed_when: false
      ignore_errors: yes

    - name: 显示当前GPU驱动版本
      debug:
        msg: "当前GPU驱动版本: {{ current_driver.stdout | default('未安装') }}"

    - name: 检查内核版本
      command: uname -r
      register: kernel_version
      changed_when: false

    - name: 检查内核头文件
      yum:
        name: kernel-devel-{{ kernel_version.stdout }}
        state: present

    - name: 安装依赖包
      yum:
        name:
          - gcc
          - make
          - dkms
          - kernel-headers
        state: present

    - name: 复制GPU驱动安装包
      copy:
        src: files/NVIDIA-Linux-x86_64-535.129.03.run
        dest: /tmp/NVIDIA-Linux-x86_64-535.129.03.run
        mode: '0755'

    - name: 安装GPU驱动
      command: /tmp/NVIDIA-Linux-x86_64-535.129.03.run --silent
      register: install_result
      async: 1800  # 最长等待30分钟
      poll: 10

    - name: 验证GPU驱动安装
      command: nvidia-smi
      register: nvidia_smi
      changed_when: false

    - name: 显示GPU信息
      debug:
        msg: "{{ nvidia_smi.stdout }}"

    - name: 检查GPU驱动版本
      command: nvidia-smi --query-gpu=driver_version --format=csv,noheader
      register: new_driver
      changed_when: false

    - name: 显示新安装的GPU驱动版本
      debug:
        msg: "新安装的GPU驱动版本: {{ new_driver.stdout }}"

4. Jenkins Pipeline实战

4.1 Jenkinsfile示例

groovy 复制代码
// 以下代码为示例,实际操作前请在测试环境验证

pipeline {
    agent any

    parameters {
        choice(
            name: 'OPERATION',
            choices: ['downgrade_kernel', 'install_gpu_driver', 'all'],
            description: '选择要执行的操作'
        )
        string(
            name: 'KERNEL_VERSION',
            defaultValue: '4.18.0-348.el8.x86_64',
            description: '目标内核版本'
        )
        string(
            name: 'GPU_DRIVER_VERSION',
            defaultValue: '535.129.03',
            description: 'GPU驱动版本'
        )
    }

    environment {
        ANSIBLE_HOST_KEY_CHECKING = 'False'
        ANSIBLE_INVENTORY = '/etc/ansible/hosts'
    }

    stages {
        stage('前置检查') {
            steps {
                script {
                    echo "开始执行运维任务"
                    echo "操作类型: ${params.OPERATION}"
                    echo "目标内核版本: ${params.KERNEL_VERSION}"
                    echo "GPU驱动版本: ${params.GPU_DRIVER_VERSION}"
                }
            }
        }

        stage('备份配置') {
            when {
                expression { params.OPERATION in ['downgrade_kernel', 'all'] }
            }
            steps {
                script {
                    echo "备份当前配置..."
                    sh """
                        ansible-playbook \
                            -i ${ANSIBLE_INVENTORY} \
                            ansible-playbooks/playbooks/backup-config.yml
                    """
                }
            }
        }

        stage('降内核版本') {
            when {
                expression { params.OPERATION in ['downgrade_kernel', 'all'] }
            }
            steps {
                script {
                    echo "开始降内核版本..."
                    sh """
                        ansible-playbook \
                            -i ${ANSIBLE_INVENTORY} \
                            -e "kernel_version=${params.KERNEL_VERSION}" \
                            ansible-playbooks/playbooks/downgrade-kernel.yml
                    """
                }
            }
        }

        stage('等待服务器重启') {
            when {
                expression { params.OPERATION in ['downgrade_kernel', 'all'] }
            }
            steps {
                script {
                    echo "等待服务器重启..."
                    sleep(time: 10, unit: 'MINUTES')
                    sh """
                        ansible-playbook \
                            -i ${ANSIBLE_INVENTORY} \
                            ansible-playbooks/playbooks/wait-for-servers.yml
                    """
                }
            }
        }

        stage('安装GPU驱动') {
            when {
                expression { params.OPERATION in ['install_gpu_driver', 'all'] }
            }
            steps {
                script {
                    echo "开始安装GPU驱动..."
                    sh """
                        ansible-playbook \
                            -i ${ANSIBLE_INVENTORY} \
                            -e "gpu_driver_version=${params.GPU_DRIVER_VERSION}" \
                            ansible-playbooks/playbooks/install-gpu-driver.yml
                    """
                }
            }
        }

        stage('验证结果') {
            steps {
                script {
                    echo "验证操作结果..."
                    sh """
                        ansible-playbook \
                            -i ${ANSIBLE_INVENTORY} \
                            ansible-playbooks/playbooks/verify.yml
                    """
                }
            }
        }

        stage('部署应用到K8s') {
            steps {
                script {
                    echo "部署应用到K8s集群..."
                    sh """
                        kubectl apply -f k8s-manifests/
                        kubectl rollout status deployment/ai-training
                    """
                }
            }
        }
    }

    post {
        success {
            echo "运维任务执行成功!"
            emailext (
                subject: "✅ 运维任务成功: ${params.OPERATION}",
                body: "运维任务执行成功,详细信息请查看Jenkins日志。",
                to: 'ops-team@example.com'
            )
        }
        failure {
            echo "运维任务执行失败!"
            emailext (
                subject: "❌ 运维任务失败: ${params.OPERATION}",
                body: "运维任务执行失败,请立即检查Jenkins日志。",
                to: 'ops-team@example.com'
            )
        }
    }
}

5. K8s集成:部署AI训练任务

5.1 K8s Deployment示例

yaml 复制代码
# 以下代码为示例,实际操作前请在测试环境验证

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ai-training
  namespace: ai-workspace
spec:
  replicas: 3
  selector:
    matchLabels:
      app: ai-training
  template:
    metadata:
      labels:
        app: ai-training
    spec:
      nodeSelector:
        gpu: "true"  # 只调度到有GPU的节点
      containers:
      - name: ai-training
        image: registry.example.com/ai-training:latest
        resources:
          limits:
            nvidia.com/gpu: 4  # 使用4块GPU
            memory: "32Gi"
            cpu: "8"
          requests:
            nvidia.com/gpu: 4
            memory: "16Gi"
            cpu: "4"
        volumeMounts:
        - name: data
          mountPath: /data
        - name: models
          mountPath: /models
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: data-pvc
      - name: models
        persistentVolumeClaim:
          claimName: models-pvc

5.2 K8s Job示例(一次性任务)

yaml 复制代码
# 以下代码为示例,实际操作前请在测试环境验证

apiVersion: batch/v1
kind: Job
metadata:
  name: model-training-job
  namespace: ai-workspace
spec:
  backoffLimit: 3
  parallelism: 2
  completions: 10
  template:
    spec:
      nodeSelector:
        gpu: "true"
      containers:
      - name: training
        image: registry.example.com/model-training:latest
        command: ["python", "train.py"]
        args:
          - "--epochs=100"
          - "--batch-size=32"
        resources:
          limits:
            nvidia.com/gpu: 8
            memory: "64Gi"
            cpu: "16"
      restartPolicy: OnFailure

6. 完整工作流程示例

6.1 场景:批量更新GPU驱动并重新部署AI训练任务

步骤1:在Jenkins创建任务

  1. 登录Jenkins
  2. 创建新的Pipeline任务
  3. 配置参数选择(驱动版本、目标服务器组等)

步骤2:执行任务

  1. 点击"Build with Parameters"
  2. 选择操作类型:all(降内核+装驱动)
  3. 填写GPU驱动版本:535.129.03
  4. 点击"开始构建"

步骤3:自动化执行

复制代码
Jenkins自动执行:
├── 前置检查(验证参数、检查服务器状态)
├── 备份配置(备份grub配置、驱动配置)
├── 降内核版本(Ansible并行操作100台服务器)
├── 等待服务器重启(分批重启,每批10台)
├── 安装GPU驱动(Ansible并行安装)
├── 验证结果(检查内核版本、GPU驱动版本)
├── 部署应用到K8s(更新Deployment、启动训练任务)
└── 发送通知(邮件、Slack、钉钉)

步骤4:监控和验证

  1. 在Jenkins查看执行日志
  2. 在Grafana查看服务器状态
  3. 在K8s Dashboard查看Pod状态
  4. 验证AI训练任务正常运行

7. 最佳实践

7.1 Ansible最佳实践

1. 使用Inventory分组管理服务器

ini 复制代码
# 以下代码为示例,实际操作前请在测试环境验证

[gpu_servers]
server[01:50].example.com

[network_servers]
server[51:70].example.com

[storage_servers]
server[71:80].example.com

[all_servers:children]
gpu_servers
network_servers
storage_servers

2. 使用Role组织Playbook

复制代码
roles/
├── common/          # 通用配置
├── kernel/          # 内核管理
├── gpu-driver/      # GPU驱动
├── network-driver/  # 网卡驱动
└── monitoring/      # 监控配置

3. 使用变量管理不同环境

yaml 复制代码
# vars/production.yml
kernel_version: 4.18.0-348.el8.x86_64
gpu_driver_version: 535.129.03
network_driver_version: 1.2.3

# vars/staging.yml
kernel_version: 4.18.0-348.el8.x86_64
gpu_driver_version: 535.129.03
network_driver_version: 1.2.3

7.2 Jenkins最佳实践

1. 使用多阶段Pipeline

groovy 复制代码
// 以下代码为示例,实际操作前请在测试环境验证

stages {
    stage('测试环境') {
        when { branch 'staging' }
        steps {
            // 在测试环境先执行
        }
    }
    stage('生产环境') {
        when { branch 'main' }
        input {
            message "确认在生产环境执行?"
        }
        steps {
            // 在生产环境执行
        }
    }
}

2. 使用参数化构建

groovy 复制代码
// 以下代码为示例,实际操作前请在测试环境验证

parameters {
    choice(name: 'ENVIRONMENT', choices: ['staging', 'production'])
    string(name: 'SERVER_GROUP')
    booleanParam(name: 'DRY_RUN', defaultValue: true)
}

3. 使用通知集成

groovy 复制代码
// 以下代码为示例,实际操作前请在测试环境验证

post {
    success {
        slackSend(
            color: 'good',
            message: "✅ 任务成功: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
        )
    }
    failure {
        slackSend(
            color: 'danger',
            message: "❌ 任务失败: ${env.JOB_NAME} #${env.BUILD_NUMBER}"
        )
    }
}

7.3 K8s最佳实践

1. 使用Namespace隔离环境

bash 复制代码
# 以下代码为示例,实际操作前请在测试环境验证

kubectl create namespace staging
kubectl create namespace production
kubectl config set-context --current --namespace=staging

2. 使用ResourceQuota限制资源

yaml 复制代码
# 以下代码为示例,实际操作前请在测试环境验证

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-resources
  namespace: ai-workspace
spec:
  hard:
    requests.cpu: "100"
    requests.memory: 200Gi
    limits.cpu: "200"
    limits.memory: 400Gi
    requests.nvidia.com/gpu: 50

3. 使用HPA自动扩缩容

yaml 复制代码
# 以下代码为示例,实际操作前请在测试环境验证

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: ai-training-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: ai-training
  minReplicas: 3
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 80

8. 常见问题解决

8.1 Ansible常见问题

问题1:SSH连接失败

yaml 复制代码
# 解决方案:配置SSH密钥认证
# 以下代码为示例,实际操作前请在测试环境验证

[defaults]
host_key_checking = False
private_key_file = ~/.ssh/ansible_key

问题2:任务执行超时

yaml 复制代码
# 解决方案:增加超时时间
# 以下代码为示例,实际操作前请在测试环境验证

- name: 安装GPU驱动
  command: /tmp/NVIDIA-Linux-x86_64-535.129.03.run --silent
  async: 3600  # 1小时超时
  poll: 10

8.2 Jenkins常见问题

问题1:Pipeline执行失败

groovy 复制代码
// 解决方案:添加错误处理
// 以下代码为示例,实际操作前请在测试环境验证

stage('执行任务') {
    steps {
        script {
            try {
                sh 'ansible-playbook playbook.yml'
            } catch (Exception e) {
                echo "任务执行失败: ${e}"
                currentBuild.result = 'FAILURE'
                throw e
            }
        }
    }
}

问题2:并发执行冲突

groovy 复制代码
// 解决方案:使用锁机制
// 以下代码为示例,实际操作前请在测试环境验证

lock(resource: 'gpu-servers') {
    stage('降内核') {
        steps {
            sh 'ansible-playbook downgrade-kernel.yml'
        }
    }
}

8.3 K8s常见问题

问题1:Pod无法调度

bash 复制代码
# 解决方案:检查节点资源
# 以下命令为示例,实际操作前请在测试环境验证

kubectl describe pod <pod-name>
kubectl top nodes
kubectl get nodes -o wide

问题2:GPU资源不足

yaml 复制代码
# 解决方案:使用NodeSelector和Taints
# 以下代码为示例,实际操作前请在测试环境验证

apiVersion: v1
kind: Node
metadata:
  name: gpu-node-01
spec:
  taints:
  - key: nvidia.com/gpu
    value: "true"
    effect: NoSchedule

9. 总结

通过Ansible + Jenkins + K8s的组合,我们可以构建一个高效的算力中心运维体系:

核心优势:

  1. 自动化程度高:从手动操作到一键执行
  2. 可追溯性强:所有操作都有日志记录
  3. 可重复性好:相同操作可以重复执行
  4. 可扩展性强:轻松扩展到更多服务器
  5. 风险可控:分批操作、灰度发布、快速回滚

工作流程:

复制代码
Jenkins(调度中心)
    ↓ 触发任务
Ansible(执行引擎)
    ↓ 批量操作
K8s(应用管理)
    ↓ 部署应用
监控告警
    ↓ 实时监控
通知反馈

关键要点:

  • Ansible负责"做什么":降内核、装驱动、配置系统
  • Jenkins负责"什么时候做":定时触发、条件触发、手动触发
  • K8s负责"应用怎么跑":容器编排、资源调度、自动扩缩容
  • 三者结合:构建完整的自动化运维体系

通过合理使用这三个工具,算力中心运维效率可以提升10倍以上,同时大大降低人为错误的风险。

相关推荐
SelectDB16 小时前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
XIAOHEZIcode2 天前
Linux系统鼠标偏移常见原因以及修复方案
linux·运维·游戏
用户0328472220703 天前
如何搭建本地yum源(上)
运维
大树886 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠6 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质6 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
Inhand陈工6 天前
基于台达PLC与映翰通IG502的智慧水产养殖精准投喂与远程运维解决方案
运维·人工智能·物联网·阿里云·信息与通信
酣大智6 天前
ARP代理--工作原理
运维·网络·arp·arp代理
shushangyun_6 天前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
施努卡机器视觉6 天前
SNK施努卡侧滑门锁上滑轮总成自动化装配线,从零件到组件,全流程精密制造方案
运维·自动化·制造