Linux基础教程 第17课:自动化运维工具

浏览量:32 次 发布时间:2026-01-23 19:48 作者:明扬工控商城 下载docx

最近更新:Linux基础教程 第15课:Linux内核和驱动管理


好的,我们继续第十七课。今天学习Linux自动化运维工具,重点介绍Ansible、Puppet和Chef。


第一部分:自动化运维概述

1.1 为什么需要自动化运维?

一致性:确保所有服务器配置一致


效率:批量部署和配置,节省时间


可重复:快速重建和恢复服务


版本控制:配置变更可追踪


减少人为错误


1.2 主流工具对比

特性 Ansible Puppet Chef

架构 无代理,SSH 主从/无主,有代理 主从/无主,有代理

配置语言 YAML 自定义DSL Ruby DSL

学习曲线 简单 中等 较陡

执行模式 推送 拉取 拉取

适用场景 中小型环境 大型企业 大型企业

社区 非常活跃 活跃 活跃

第二部分:Ansible

2.1 Ansible基础

Ansible是目前最流行的自动化工具,基于Python,无需在客户端安装代理。


bash

# 安装Ansible

sudo apt update

sudo apt install -y ansible


# 验证安装

ansible --version


# 基础命令结构

ansible <pattern> -m <module_name> -a <arguments>

2.2 Ansible Inventory(清单)

Inventory定义要管理的服务器。


bash

# 创建Inventory文件

vim ~/ansible-inventory.ini

内容示例:


ini

# 按组组织服务器

[web_servers]

web1 ansible_host=192.168.1.101 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa

web2 ansible_host=192.168.1.102 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa


[db_servers]

db1 ansible_host=192.168.1.201 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa


[load_balancers]

lb1 ansible_host=192.168.1.100 ansible_user=ubuntu ansible_ssh_private_key_file=~/.ssh/id_rsa


# 组变量

[web_servers:vars]

http_port=80

max_clients=200


# 嵌套组

[production:children]

web_servers

db_servers

load_balancers

2.3 Ansible Ad-hoc命令

bash

# 测试连接

ansible all -i ~/ansible-inventory.ini -m ping


# 在所有服务器上执行命令

ansible all -i ~/ansible-inventory.ini -a "uptime"


# 在特定组执行命令

ansible web_servers -i ~/ansible-inventory.ini -a "free -h"


# 使用模块管理包

ansible web_servers -i ~/ansible-inventory.ini -m apt -a "name=nginx state=present" --become


# 管理服务

ansible web_servers -i ~/ansible-inventory.ini -m systemd -a "name=nginx state=started" --become


# 复制文件

ansible web_servers -i ~/ansible-inventory.ini -m copy -a "src=/local/file dest=/remote/file" --become


# 获取信息

ansible all -i ~/ansible-inventory.ini -m setup | less

2.4 Ansible Playbook基础

Playbook是Ansible的核心,使用YAML格式。


yaml

# nginx-install.yml

---

- name: Install and configure Nginx

 hosts: web_servers

 become: yes

 vars:

   nginx_version: "1.18.0"

   worker_processes: "auto"

   worker_connections: 1024

 

 tasks:

   - name: Update apt cache

     apt:

       update_cache: yes

       cache_valid_time: 3600

   

   - name: Install Nginx

     apt:

       name: nginx

       state: present

       force_apt_get: yes

   

   - name: Configure Nginx

     template:

       src: nginx.conf.j2

       dest: /etc/nginx/nginx.conf

       mode: '0644'

     notify:

       - restart nginx

   

   - name: Ensure Nginx is running

     systemd:

       name: nginx

       state: started

       enabled: yes

 

 handlers:

   - name: restart nginx

     systemd:

       name: nginx

       state: restarted

2.5 Jinja2模板

jinja2

# nginx.conf.j2

user www-data;

worker_processes {{ worker_processes }};

pid /run/nginx.pid;


events {

   worker_connections {{ worker_connections }};

   multi_accept off;

}


http {

   sendfile on;

   tcp_nopush on;

   tcp_nodelay on;

   keepalive_timeout 65;

   types_hash_max_size 2048;

   

   include /etc/nginx/mime.types;

   default_type application/octet-stream;

   

   access_log /var/log/nginx/access.log;

   error_log /var/log/nginx/error.log;

   

   gzip on;

   gzip_disable "msie6";

   

   include /etc/nginx/conf.d/*.conf;

   include /etc/nginx/sites-enabled/*;

}

2.6 运行Playbook

bash

# 语法检查

ansible-playbook nginx-install.yml --syntax-check


# 试运行(不实际执行)

ansible-playbook nginx-install.yml --check


# 详细输出

ansible-playbook nginx-install.yml -vvv


# 只执行特定标签

ansible-playbook nginx-install.yml --tags "nginx"


# 跳过特定标签

ansible-playbook nginx-install.yml --skip-tags "nginx"

2.7 Ansible Roles

Roles是Playbook的模块化组织方式。


bash

# 创建Role结构

ansible-galaxy init nginx-role

tree nginx-role/

text

nginx-role/

├── defaults

│   └── main.yml      # 默认变量(优先级最低)

├── files             # 静态文件

├── handlers

│   └── main.yml      # 处理器

├── meta

│   └── main.yml      # 角色元数据

├── README.md

├── tasks

│   └── main.yml      # 主任务列表

├── templates         # 模板文件

├── tests

│   ├── inventory

│   └── test.yml

└── vars

   └── main.yml      # 角色变量(优先级高)

yaml

# nginx-role/tasks/main.yml

---

- name: Install Nginx

 apt:

   name: nginx

   state: present


- name: Configure Nginx

 template:

   src: nginx.conf.j2

   dest: /etc/nginx/nginx.conf

 notify: restart nginx


- name: Start Nginx

 systemd:

   name: nginx

   state: started

   enabled: yes

2.8 Ansible Vault加密

bash

# 创建加密文件

ansible-vault create secrets.yml


# 编辑加密文件

ansible-vault edit secrets.yml


# 加密现有文件

ansible-vault encrypt secrets.yml


# 解密文件

ansible-vault decrypt secrets.yml


# 运行使用加密文件的Playbook

ansible-playbook site.yml --ask-vault-pass

ansible-playbook site.yml --vault-password-file ~/.vault_pass.txt

第三部分:Puppet

3.1 Puppet基础

Puppet使用主从架构,使用自己的声明式语言。


bash

# 安装Puppet Agent

sudo apt update

sudo apt install -y puppet-agent


# 验证安装

puppet --version

3.2 Puppet配置

bash

# 配置Puppet Agent

sudo vim /etc/puppetlabs/puppet/puppet.conf

ini

[main]

server = puppet-master.example.com

certname = web1.example.com

environment = production

runinterval = 30m


[agent]

report = true

pluginsync = true

3.3 Puppet Manifest基础

puppet

# /etc/puppetlabs/code/environments/production/manifests/site.pp

node 'web1.example.com' {

 # 安装Nginx

 package { 'nginx':

   ensure => installed,

 }

 

 # 配置文件

 file { '/etc/nginx/nginx.conf':

   ensure  => file,

   content => template('nginx/nginx.conf.erb'),

   owner   => 'root',

   group   => 'root',

   mode    => '0644',

   require => Package['nginx'],

   notify  => Service['nginx'],

 }

 

 # 管理服务

 service { 'nginx':

   ensure    => running,

   enable    => true,

   hasstatus => true,

   hasrestart => true,

 }

 

 # 用户管理

 user { 'webadmin':

   ensure     => present,

   uid        => '1001',

   gid        => '1001',

   shell      => '/bin/bash',

   home       => '/home/webadmin',

   managehome => true,

 }

 

 # 文件权限

 file { '/var/www/html':

   ensure => directory,

   owner  => 'www-data',

   group  => 'www-data',

   mode   => '0755',

 }

}

3.4 Puppet模板

erb

# nginx/nginx.conf.erb

user www-data;

worker_processes <%= @processorcount %>;

pid /run/nginx.pid;


events {

   worker_connections 768;

}


http {

   sendfile on;

   tcp_nopush on;

   tcp_nodelay on;

   keepalive_timeout 65;

   types_hash_max_size 2048;

   

   include /etc/nginx/mime.types;

   default_type application/octet-stream;

   

   access_log /var/log/nginx/access.log;

   error_log /var/log/nginx/error.log;

   

   gzip on;

   gzip_disable "msie6";

   

   include /etc/nginx/conf.d/*.conf;

   include /etc/nginx/sites-enabled/*;

}

3.5 Puppet模块

bash

# 创建模块结构

cd /etc/puppetlabs/code/environments/production/modules

puppet module generate user-nginx

模块结构:


text

nginx/

├── manifests

│   ├── init.pp

│   ├── install.pp

│   ├── config.pp

│   └── service.pp

├── templates

│   └── nginx.conf.erb

├── files

├── spec

└── README.md

3.6 Puppet运行

bash

# 测试配置

puppet parser validate /etc/puppetlabs/code/environments/production/manifests/site.pp


# 手动运行Puppet Agent

sudo puppet agent --test


# 查看Puppet运行状态

sudo puppet resource service puppet


# 启用Puppet服务(定期运行)

sudo systemctl enable puppet

sudo systemctl start puppet

第四部分:Chef

4.1 Chef基础

Chef使用Ruby DSL,包含三个组件:Workstation、Server、Nodes。


bash

# 安装Chef Workstation

wget https://packages.chef.io/files/stable/chef-workstation/23.10.1038/ubuntu/20.04/chef-workstation_23.10.1038-1_amd64.deb

sudo dpkg -i chef-workstation_*.deb


# 验证安装

chef --version

4.2 Chef配置

bash

# 初始化Chef Repo

chef generate repo chef-repo

cd chef-repo


# 配置knife(Chef命令行工具)

vim .chef/config.rb

ruby

current_dir = File.dirname(__FILE__)

log_level                :info

log_location             STDOUT

node_name                "admin"

client_key               "#{current_dir}/admin.pem"

chef_server_url          "https://chef-server/organizations/myorg"

cookbook_path            ["#{current_dir}/../cookbooks"]

4.3 Chef Cookbook

bash

# 创建Cookbook

chef generate cookbook nginx

cd cookbooks/nginx

ruby

# recipes/default.rb

package 'nginx' do

 action :install

end


template '/etc/nginx/nginx.conf' do

 source 'nginx.conf.erb'

 owner 'root'

 group 'root'

 mode '0644'

 variables({

   worker_processes: node['cpu']['total'],

   worker_connections: 1024

 })

 notifies :restart, 'service[nginx]'

end


service 'nginx' do

 action [:enable, :start]

 supports restart: true, reload: true

end


# 创建用户

user 'webadmin' do

 comment 'Web Administrator'

 uid '1001'

 gid '1001'

 home '/home/webadmin'

 shell '/bin/bash'

 manage_home true

end


# 创建目录

directory '/var/www/html' do

 owner 'www-data'

 group 'www-data'

 mode '0755'

 action :create

end

4.4 Chef模板

erb

# templates/default/nginx.conf.erb

user www-data;

worker_processes <%= @worker_processes %>;

pid /run/nginx.pid;


events {

   worker_connections <%= @worker_connections %>;

}


http {

   sendfile on;

   tcp_nopush on;

   tcp_nodelay on;

   keepalive_timeout 65;

   types_hash_max_size 2048;

   

   include /etc/nginx/mime.types;

   default_type application/octet-stream;

   

   access_log /var/log/nginx/access.log;

   error_log /var/log/nginx/error.log;

   

   gzip on;

   gzip_disable "msie6";

   

   include /etc/nginx/conf.d/*.conf;

   include /etc/nginx/sites-enabled/*;

}

4.5 Chef运行

bash

# 测试Cookbook语法

foodcritic .

cookstyle .


# 使用Test Kitchen测试

kitchen list

kitchen converge

kitchen verify

kitchen destroy


# 上传Cookbook到Chef Server

knife cookbook upload nginx


# Bootstrap节点(初始化Chef Agent)

knife bootstrap node1.example.com -N node1 -x root --sudo

第五部分:综合对比和实战

5.1 场景对比:部署Nginx集群

Ansible方案:


yaml

# cluster-deploy.yml

---

- name: Deploy Nginx Cluster

 hosts: all

 become: yes

 vars:

   nginx_servers:

     - { name: "web1", ip: "192.168.1.101" }

     - { name: "web2", ip: "192.168.1.102" }

   

 tasks:

   - name: Install Nginx

     apt:

       name: nginx

       state: present

   

   - name: Create load balancer config

     template:

       src: lb.conf.j2

       dest: /etc/nginx/conf.d/lb.conf

   

   - name: Start Nginx

     systemd:

       name: nginx

       state: started

Puppet方案:


puppet

# nginx_cluster.pp

class nginx_cluster {

 package { 'nginx':

   ensure => installed,

 }

 

 file { '/etc/nginx/conf.d/lb.conf':

   ensure  => file,

   content => template('nginx/lb.conf.erb'),

   require => Package['nginx'],

   notify  => Service['nginx'],

 }

 

 service { 'nginx':

   ensure    => running,

   enable    => true,

 }

}


node /^web[0-9]+\.example\.com$/ {

 include nginx_cluster

}

Chef方案:


ruby

# recipes/cluster.rb

nginx_servers = [

 { name: 'web1', ip: '192.168.1.101' },

 { name: 'web2', ip: '192.168.1.102' }

]


package 'nginx'


template '/etc/nginx/conf.d/lb.conf' do

 source 'lb.conf.erb'

 variables(servers: nginx_servers)

 notifies :restart, 'service[nginx]'

end


service 'nginx' do

 action [:enable, :start]

end

5.2 性能对比测试

bash

# Ansible性能测试

time ansible-playbook -i inventory.ini deploy.yml


# Puppet性能测试

time puppet apply site.pp


# Chef性能测试

time chef-client -z -o 'recipe[nginx]'


# 比较指标:

# 1. 执行时间

# 2. 资源占用

# 3. 网络带宽

# 4. 扩展性

5.3 自动化运维最佳实践

版本控制一切


bash

# 使用Git管理配置

git init

git add .

git commit -m "Initial automation config"

测试驱动开发


bash

# Ansible测试

ansible-lint playbook.yml

molecule test


# Puppet测试

puppet parser validate

rspec-puppet


# Chef测试

foodcritic

chefspec

持续集成/持续部署


yaml

# .gitlab-ci.yml示例

stages:

 - test

 - deploy


ansible_test:

 stage: test

 script:

   - ansible-lint

   - ansible-playbook --check


puppet_test:

 stage: test

 script:

   - puppet parser validate

   - puppet-lint


deploy_production:

 stage: deploy

 script:

   - ansible-playbook -i production deploy.yml

 when: manual

第六部分:实际项目演练

项目1:使用Ansible部署完整LAMP栈

yaml

# lamp-stack.yml

---

- name: Deploy LAMP Stack

 hosts: web_servers

 become: yes

 

 tasks:

   - name: Install Apache

     apt:

       name: apache2

       state: present

   

   - name: Install MySQL

     apt:

       name: mysql-server

       state: present

   

   - name: Install PHP

     apt:

       name:

         - php

         - php-mysql

         - libapache2-mod-php

       state: present

   

   - name: Configure MySQL

     mysql_user:

       name: webapp

       password: "{{ mysql_password }}"

       priv: "*.*:ALL"

       state: present

   

   - name: Deploy application

     git:

       repo: https://github.com/example/webapp.git

       dest: /var/www/html

       version: master

   

   - name: Configure Apache

     template:

       src: apache.conf.j2

       dest: /etc/apache2/sites-available/webapp.conf

     notify: restart apache

   

   - name: Enable site

     command: a2ensite webapp.conf

     notify: restart apache

   

 handlers:

   - name: restart apache

     systemd:

       name: apache2

       state: restarted

项目2:使用Puppet管理多环境

puppet

# environments.pp

node /^web-\d+\.dev\.example\.com$/ {

 $environment = 'development'

 include base_config

 include nginx

 include php

}


node /^web-\d+\.stg\.example\.com$/ {

 $environment = 'staging'

 include base_config

 include nginx

 include php

 include monitoring

}


node /^web-\d+\.prod\.example\.com$/ {

 $environment = 'production'

 include base_config

 include nginx

 include php

 include monitoring

 include security_hardening

}


# 使用Hiera进行数据分离

# hiera.yaml

---

version: 5

defaults:

 datadir: data

 data_hash: yaml_data

hierarchy:

 - name: "Per-node data"

   path: "nodes/%{trusted.certname}.yaml"

 - name: "Per-environment data"

   path: "environments/%{environment}.yaml"

 - name: "Common data"

   path: "common.yaml"

项目3:使用Chef实现蓝绿部署

ruby

# recipes/blue_green.rb

# 蓝绿部署实现


# 确定当前颜色

current_color = node['deployment']['current_color'] || 'blue'

next_color = current_color == 'blue' ? 'green' : 'blue'


# 部署新版本到下一个颜色组

web_app "myapp-#{next_color}" do

 version node['app_version']

 port next_color == 'blue' ? 8080 : 8081

 action :deploy

end


# 测试新版本

http_request "test-#{next_color}" do

 url "http://localhost:#{next_color == 'blue' ? 8080 : 8081}/health"

 action :get

end


# 切换负载均衡器配置

template '/etc/nginx/conf.d/myapp.conf' do

 source 'myapp.conf.erb'

 variables(

   backend_port: next_color == 'blue' ? 8080 : 8081

 )

 notifies :reload, 'service[nginx]'

end


# 更新当前颜色

node.normal['deployment']['current_color'] = next_color

第七部分:监控和日志

7.1 集成监控工具

Ansible + Prometheus:


yaml

# prometheus.yml

- name: Deploy Prometheus monitoring

 hosts: monitoring_servers

 tasks:

   - name: Install Prometheus

     apt:

       name: prometheus

       state: present

   

   - name: Configure Prometheus

     template:

       src: prometheus.yml.j2

       dest: /etc/prometheus/prometheus.yml

     notify: restart prometheus

   

   - name: Install Node Exporter on all nodes

     hosts: all

     tasks:

       - name: Install node_exporter

         apt:

           name: prometheus-node-exporter

           state: present

Puppet + Grafana:


puppet

class grafana_dashboard {

 package { 'grafana':

   ensure => installed,

 }

 

 file { '/etc/grafana/provisioning/dashboards/dashboard.yml':

   ensure  => file,

   content => template('grafana/dashboard.yml.erb'),

   notify  => Service['grafana'],

 }

 

 service { 'grafana':

   ensure    => running,

   enable    => true,

 }

}

7.2 日志集中管理

使用Ansible部署ELK栈:


yaml

- name: Deploy ELK Stack

 hosts: elk_servers

 tasks:

   - name: Install Elasticsearch

     apt:

       name: elasticsearch

       state: present

   

   - name: Install Logstash

     apt:

       name: logstash

       state: present

   

   - name: Install Kibana

     apt:

       name: kibana

       state: present

   

   - name: Configure log forwarding on all servers

     hosts: all

     tasks:

       - name: Install filebeat

         apt:

           name: filebeat

           state: present

       

       - name: Configure filebeat

         template:

           src: filebeat.yml.j2

           dest: /etc/filebeat/filebeat.yml

         notify: restart filebeat

第八部分:安全实践

8.1 安全加固自动化

Ansible安全基线:


yaml

# security-hardening.yml

- name: Apply security hardening

 hosts: all

 become: yes

 

 tasks:

   - name: Update all packages

     apt:

       upgrade: dist

       update_cache: yes

   

   - name: Configure firewall

     ufw:

       rule: allow

       port: "{{ item }}"

       proto: tcp

     loop:

       - 22

       - 80

       - 443

   

   - name: Disable root SSH login

     lineinfile:

       path: /etc/ssh/sshd_config

       regexp: '^PermitRootLogin'

       line: 'PermitRootLogin no'

     notify: restart ssh

   

   - name: Configure password policy

     pam_limits:

       domain: '*'

       limit_type: hard

       limit_item: maxlogins

       value: 3

   

   - name: Install and configure fail2ban

     apt:

       name: fail2ban

       state: present

     

   - name: Configure fail2ban

     template:

       src: jail.local.j2

       dest: /etc/fail2ban/jail.local

     notify: restart fail2ban

8.2 密钥和密码管理

使用Ansible Vault:


bash

# 创建加密变量文件

ansible-vault create group_vars/all/vault.yml


# 内容示例:

---

database_password: !vault |

         $ANSIBLE_VAULT;1.1;AES256

         66386439653236343062323439626161366262363430653235623134323433623438326531356435

         3130343865353038633938656135393935643061393864330a626438346162623434353464323638

         34396230633861356163333839653663346663386438373439623339613764356432373762333164

         6566646330326639340a336136626566396263666365353562303961323662626663633965386464

         6330


api_key: !vault |

         $ANSIBLE_VAULT;1.1;AES256

         34643262376332613763386161636532326536633861393033396361363631303730366332613638

         3639303363633534343836363535326663306538336437320a363532363339386262306339313764

         61316161396530393930666263343930313862633462376530366231386533313765373361356161

         3633326533376331610a393763373466366165643637323532396133323230626530333230383039

         3532

第九部分:练习项目

项目1:构建自动化部署流水线

使用Ansible部署Jenkins


配置Jenkins Pipeline


集成Git仓库


实现自动化测试和部署


项目2:多云环境管理

使用Terraform在AWS/Azure创建基础设施


使用Ansible配置服务器


实现跨云平台的统一管理


配置监控和告警


项目3:容器化应用自动化

使用Ansible部署Kubernetes集群


创建Docker镜像构建流水线


使用Helm部署应用


配置自动扩缩容


项目4:灾难恢复自动化

设计备份策略


创建自动化恢复脚本


定期测试恢复流程


文档化和演练


第十部分:进阶主题

10.1 Ansible高级特性

yaml

# 动态Inventory

- name: Use AWS dynamic inventory

 hosts: tag_Environment_Production

 gather_facts: false

 tasks:

   - name: List EC2 instances

     ec2_instance_facts:

       region: us-east-1

     register: ec2_info


# 异步任务

- name: Long running task

 command: /usr/bin/long_running_operation

 async: 1200  # 最多运行20分钟

 poll: 30     # 每30秒检查一次


# 错误处理

- name: Try something that might fail

 command: /bin/false

 ignore_errors: yes

 register: result

 

- name: Handle failure

 debug:

   msg: "Task failed, but we're continuing"

 when: result.failed


# 条件执行

- name: Install package only if needed

 apt:

   name: nginx

   state: present

 when: ansible_os_family == "Debian"

10.2 Puppet高级模式

puppet

# 定义类型

define web::virtual_host(

 $port = 80,

 $docroot = "/var/www/${name}",

 $ssl = false,

) {

 file { "/etc/nginx/sites-available/${name}":

   ensure  => file,

   content => template('web/virtual_host.conf.erb'),

   notify  => Service['nginx'],

 }

 

 file { "/etc/nginx/sites-enabled/${name}":

   ensure => link,

   target => "/etc/nginx/sites-available/${name}",

   notify => Service['nginx'],

 }

}


# 使用定义的类型

web::virtual_host { 'example.com':

 port    => 80,

 docroot => '/var/www/example',

 ssl     => false,

}


# 资源收集

File <<| tag == 'webconfig' |>>

10.3 Chef自定义资源

ruby

# 自定义资源

resource_name :custom_app


property :name, String, name_property: true

property :version, String, required: true

property :port, Integer, default: 8080


action :install do

 package new_resource.name do

   version new_resource.version

 end

 

 template "/etc/#{new_resource.name}/config.conf" do

   source 'config.conf.erb'

   variables(port: new_resource.port)

 end

end


# 使用自定义资源

custom_app 'myapp' do

 version '1.0.0'

 port 8080

end

今日总结

今天我们学习了三种主流的自动化运维工具:


Ansible:


无代理架构,简单易用


YAML语法,学习成本低


适合中小型环境


强大的模块生态系统


Puppet:


声明式配置语言


成熟稳定,适合企业环境


主从架构,适合大规模部署


强大的资源抽象能力


Chef:


基于Ruby DSL,灵活强大


适合开发团队


基础设施即代码理念


测试驱动开发支持


选择建议:


新手/中小项目:从Ansible开始


大型企业/已有经验:考虑Puppet或Chef


开发团队/Ruby背景:Chef可能是更好的选择


混合环境:Ansible的多平台支持更好


最佳实践:


从简单开始,逐步复杂化


版本控制所有配置


编写测试和验证


文档化一切


定期回顾和优化


自动化运维是现代IT基础设施的基石。掌握这些工具将大大提高你的效率和系统的可靠性。


有问题吗?完成练习项目后,我们可以继续第十八课:Linux云计算基础。


明扬工控商城

推荐阅读:

Linux基础教程 第20课:Linux安全攻防和渗透测试基础

Linux基础教程 第19课:性能调优和容量规划

Linux基础教程 第18课:Linux云计算基础

Linux基础教程 第17课:自动化运维工具

Linux基础教程 第16课:集群和高可用性

Linux基础教程 第15课:Linux内核和驱动管理

热门标签:
Linux基础教程 第17课:自动化运维工具.docx

将本文的Word文档下载到电脑

推荐度:

下载

全部评论

请登录
产业新闻-明扬资讯网
科技资讯-明扬资讯网