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倍以上,同时大大降低人为错误的风险。

相关推荐
志栋智能2 小时前
AI驱动的监控系统自动化巡检:从“告警噪音”到“业务洞察”的智能跃迁
运维·人工智能·网络安全·云原生·自动化
匀泪4 小时前
云原生(nginx实验(4))
运维·nginx·云原生
daad77710 小时前
USB_抓包
linux·运维·服务器
weixin_5316518111 小时前
Elasticsearch 检索原理分析
大数据·elasticsearch·jenkins
未来之窗软件服务11 小时前
服务器运维(四十)日服务器linux-ps分析工具—东方仙盟
linux·运维·服务器·服务器运维·仙盟创梦ide·东方仙盟
礼拜天没时间.11 小时前
Docker自动化构建实战:从手工到多阶段构建的完美进化
运维·docker·容器·centos·自动化·sre
Trouvaille ~13 小时前
【Linux】数据链路层与以太网详解:从 MAC 地址到 ARP 的完整指南
linux·运维·服务器·网络·以太网·数据链路层·arp
xiaoliuliu1234513 小时前
Xftp-7.0.0109p文件传输安装步骤详解(附FTP/SFTP连接与文件传输教程)
运维·服务器
小鸡食米13 小时前
LVS(Linux Virtual Server)
运维·服务器·网络