一、为什么需要Ansible与Kubernetes集成

如果你同时管理着大量服务器和容器化应用,可能会遇到这样的烦恼:既要写YAML文件部署Kubernetes资源,又要用Ansible管理服务器配置。这时候把两者结合起来,就能用熟悉的Ansible语法直接操作Kubernetes集群,既省去了切换工具的麻烦,又能复用现有的Ansible技能栈。

二、准备工作:环境与权限配置

在开始前需要确保:

  1. 本地已安装kubectl并配置好集群访问权限
  2. Ansible控制节点已安装openshift模块(包含k8s功能)
# 技术栈:Ansible 2.10+
# 安装k8s模块
ansible-galaxy collection install community.kubernetes

三、核心操作实战

1. 管理Pod资源

下面示例创建一个Nginx Pod并设置环境变量:

# 技术栈:Ansible + Kubernetes
- name: 创建基础Pod
  hosts: localhost
  tasks:
    - name: 启动Nginx容器
      community.kubernetes.k8s:
        # 资源定义
        definition:
          apiVersion: v1
          kind: Pod
          metadata:
            name: nginx-demo
            labels:
              app: web
          spec:
            containers:
              - name: nginx
                image: nginx:1.21
                env:
                  - name: NGINX_PORT  # 环境变量
                    value: "8080"
                ports:
                  - containerPort: 80

2. 部署Deployment

更推荐用Deployment管理Pod副本,示例包含滚动更新配置:

- name: 部署Web应用
  community.kubernetes.k8s:
    definition:
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: flask-backend
      spec:
        replicas: 3
        selector:
          matchLabels:
            app: api
        template:
          metadata:
            labels:
              app: api
          spec:
            containers:
              - name: flask
                image: registry.example.com/flask:v1.2
                livenessProbe:  # 健康检查
                  httpGet:
                    path: /health
                    port: 5000
                resources:
                  limits:
                    cpu: "1"
                    memory: 512Mi

3. 暴露Service

这个示例创建NodePort类型的Service:

- name: 暴露Web服务
  community.kubernetes.k8s:
    definition:
      apiVersion: v1
      kind: Service
      metadata:
        name: web-service
      spec:
        type: NodePort
        selector:
          app: web  # 关联Pod标签
        ports:
          - protocol: TCP
            port: 80
            targetPort: 80
            nodePort: 31000  # 外部访问端口

四、高级技巧与最佳实践

1. 变量动态注入

通过Jinja2模板动态生成资源配置:

vars:
  replica_count: 5
tasks:
  - name: 动态扩展Deployment
    community.kubernetes.k8s:
      definition:
        spec:
          replicas: "{{ replica_count }}"

2. 资源状态检查

使用wait: yes确保操作完成:

- name: 等待Pod就绪
  community.kubernetes.k8s:
    kind: Pod
    name: nginx-demo
    wait: yes
    wait_timeout: 60

五、应用场景分析

典型用例

  • 混合环境管理(同时存在虚拟机与容器)
  • 已有Ansible资产的企业向K8s迁移
  • 需要编排复杂部署流程(如先准备存储卷再启动Pod)

优势

  1. 统一工具链减少学习成本
  2. 利用Ansible的幂等性保证操作安全
  3. 结合Vault实现配置加密

注意事项

  • 版本兼容性(Ansible模块与K8s API版本要匹配)
  • 生产环境建议结合kubectl diff预览变更
  • 敏感信息应使用K8s Secret而非明文存储

六、技术对比

与传统kubectl apply方式相比:
| 特性 | Ansible方式 | 原生kubectl | |---------------|-------------------|-----------------| | 学习曲线 | 复用现有知识 | 需要新学语法 | | 变量处理 | 支持Jinja2模板 | 依赖helm等工具 | | 执行模式 | 可分段执行 | 通常全量应用 | | 审计追踪 | 集成Ansible日志 | 依赖集群审计 |

七、完整示例:三层架构部署

部署包含前端、后端、数据库的完整应用:

- name: 全栈应用部署
  hosts: localhost
  vars:
    db_password: "{{ lookup('env', 'DB_PASS') }}"
  tasks:
    # MySQL部署
    - name: 创建数据库
      community.kubernetes.k8s:
        definition: "{{ lookup('file', 'mysql-deployment.yaml') }}"
      vars:
        MYSQL_ROOT_PASSWORD: "{{ db_password }}"
    
    # 后端服务
    - name: 部署API服务
      community.kubernetes.k8s:
        definition:
          kind: Deployment
          metadata:
            name: api-server
          spec:
            containers:
              - image: backend:1.0
                envFrom:
                  - secretRef:
                      name: db-creds
    
    # 前端服务
    - name: 部署Web界面
      community.kubernetes.k8s:
        definition:
          kind: Service
          metadata:
            name: frontend-lb
          spec:
            type: LoadBalancer
            ports:
              - port: 443

八、总结建议

对于已经投资Ansible基础建设的团队,通过k8s模块可以平滑过渡到容器编排领域。建议从小规模测试开始,逐步将静态YAML文件转换为参数化Playbook。记住结合ansible-lint做语法检查,并利用k8s_info模块实现状态验证。