20260114Linux学习笔记

一、管理 SECRETS

Ansible Vault

Ansible随附的 Ansible Vault 可以加密任何由Ansible使用的结构化数据文件,包括清单变量、playbook中含有的变量文件、在执行playbook时作为参数传递的变量文件,以及Ansible角色中定义的变量。

复制代码
 #创建加密文件,内容是yaml格式
 ansible-vault create user.yml
 New Vault password: `123`
 Confirm New Vault password: `123`
 #写入
 user:zhangsan
 passwd:1234
 #查看
 cat user.yml
 $ANSIBLE_VAULT;1.1;AES256
 37376665376162386437366533663632373966363338373662343361613130383037386235306633
 6133373261306564396432363664363939343337653962340a346565333139336530336165343233
 61373430326566313663376436646632373030633862656533663161646435353339366165613939
 3965313061656232340a373737623033633137343037653361363262313863613532646439323036
 37396532383934396534313162376230353366376562306438333931626663653633
 #查看加密文件
 ansible-vault view user.yml
 Vault password: `123`
 user:zhangsan
 passwd:1234
 #编辑加密文件
 ansible-vault edit user.yml
 Vault password:`123`
 #解密文件
 ansible-vault decrypt user.yml
 Vault password: `123`
 Decryption successful
 #加密文件
 ansible-vault encrypt user.yml
 New Vault password: `123`
 Confirm New Vault password: `123`
 Encryption successful

案例

复制代码
 #将私钥更改名字,这样就不能免密登录node1了
 mv ~/.ssh/id_rsa{,.bak}
 #验证
 ansible node1 -a id
 node1 | UNREACHABLE! => {
     "changed": false, 
     "msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).", 
     "unreachable": true
 }
 #查看主机清单
 cat inventory
 [nodes]
 node[1:4]
 # group_vars 是 Ansible 的标准目录结构,其中的文件(如 nodes.yml)会自动关联到 Inventory 中同名的主机组(nodes)
 vim group_vars/nodes.yml
 ansible_ssh_pass: 123
 #验证
 ansible node1 -a id
 node1 | CHANGED | rc=0 >>
 uid=0(root) gid=0(root) groups=0(root)
 #加密 group_vars/nodes.yml 文件
 ansible-vault encrypt group_vars/nodes.yml 
 New Vault password:  `123`
 Confirm New Vault password:  `123`
 Encryption successful
 #验证
 ansible node1 -a id
 ERROR! Attempting to decrypt but no vault secrets found
 #把加密密码放入一个文件
 echo 123 > password
 #使用 --vault-password-file=./password 命令可登录
 ansible node1 -a id --vault-password-file=./password
 node1 | CHANGED | rc=0 >>
 uid=0(root) gid=0(root) groups=0(root)

二、管理 FACTS

FACTS Ansible 在受管主机上自动检测到的变量,默认保存在内容中,只存在于本次playbook执行期间。

FACTS含有主机相关的信息,可以像play中的常规变量一样使用。

受管主机的 facts 包括:

主机名称 • 内核版本 • 网络接口 • IP地址 • 操作系统版本 • 各种环境变量

CPU数量 • 提供的或可用的内存 • 可用磁盘空间

通常,每个play在执行第一个任务之前会先自动收集FACTS。

复制代码
 #收集node1主机的信息
 ansible node1 -m debug -a var=ansible_facts
 #查看信息,重定向生成一个文件
 ansible node1 -m setup > node1.facts
 #可以传到windows上查看
 sz node1.facts
 #也可以是用less命令查看,可以通过/搜索信息
 less node1.facts

关闭FACTS收集 即使关闭以后,也可以随时使用setup模块收集facts。

复制代码
 # Ansible 配置文件设置
 [defaults]
 gathering = explicit
 # play 中设置
 ---
 - name: Fact dump
  hosts: node1
  gather_facts: no

部分FACTS

FACT VARIABLE
短主机名 ansible_facts['hostname']
完全限定的域名 ansible_facts['fqdn']
主要IPv4地址(基于路由) ansible_facts['default_ipv4'] ['address']
所有网络接口的名称列表 ansible_facts['interfaces']
/dev/vdal磁盘分区的大小 ansible_facts['devices'] ['vda'] ['partitions'] ['vda1] ['size']
DNS服务器列表 ansible_facts['dns'] ['nameservers']
当前运行的内核的版本 ansible_facts['kernel']

三、使用JINJA2模板部署文件

Jinja2 模板是功能强大的工具,可用于自定义要在受管节点上部署的配置文件。 创建Jinja2 模板后,可以通过template模块部署到受管节点上, 该模块支持将控制节点中的本地文件转移到受管节点。

复制代码
 #创建模板文件
 vim testfile
 hello {{ ansible_fqdn }}
 #创建使用 template 模块的 play
 vim template.yaml
 ---
 - name: show facts
   hosts: node1
   tasks: 
     - name: push file
       template:
         src: /home/zhangzhe/webapp/testfile
         dest: /webdev
 ...
 #运行ansible
 ansible-playbook template.yaml 
 #在 node1 里查看 testfile 文件内容
 cat testfile
 hello node1.zhangzhe.cloud

Jinja2 模板语法

Jinja2 模板由多个元素组成:数据、变量和表达式。在呈现Jinja2模板时, 这些变量和表达式被替换为对应的值。模板中使用的变量可以在playbook的vars部分中指定,也可以使用受管主机FACTS。

变量和逻辑表达式置于分隔符之间:

{{ EXPR }} ,用于装载表达式,比如变量,运算表达式,比较表达式。

{% EXPR %} ,用于装载控制语句,比如iffor等。

{# #},用于装载注释,模板文件中的注释不会包含在最终生成文件中。

for语句 Jinja2使用for语句来提供循环功能。

复制代码
 #创建for语句文件
 vim testfile.j2
 {% for user in users %}
 {{ user }}
 {% endfor %}
 #创建使用 template 模块的 play
 vim for.yaml
 ---
 - name: test template
   hosts: node1
   vars:
     users:
       - tom
       - jack
       - Snoopy
       - lucy
   tasks:
     - name: test template
       template:
         src: testfile.j2
         dest: /webdev/testfile
 ...
 #运行ansible
 ansible-playbook for.yaml
 #在 node1 里查看 testfile 文件内容
 cat testfile
 tom
 jack
 Snoopy
 lucy

四、编写循环任务

Ansible支持使用 loop 关键字对一组项目迭代任务。您可以配置循环以利用列表中的各个项目、列表中各个文件的内容、生成的数字序列或更为复杂的结构来重复任务。

复制代码
 #示例:
 vim add.yaml
 ---
 - name: add several users
   hosts: node1
   gather_facts: no
   tasks:
     - name: add user jane
       user: 
         name: "jane"
         groups: "wheel"
         state: present
     - name: add user joe
       user:
         name: "joe"
         groups: "wheel"
         state: present
 ...

简单循环对一组项目迭代任务。loop关键字添加到任务中, 将应对其迭代任务的项目列表取为值。循环变量item保存每个迭代过程中使用的值。

复制代码
 #使用loop循环改写:
 vim loop1.yaml
 ---
 - name: test loop
   hosts: node1
   gather_facts: no
   tasks:
     - name: add users
       user:
         name: "{{ item }}"
         groups: "wheel"
         state: present
       loop:
         - jane
         - joe
 ...
 #删除
 vim loop2.yaml
 ---
 - name: test loop
   hosts: node1
   gather_facts: no
   tasks:
     - name: del users
       user:
         name: "{{ item }}"
         groups: "wheel"
         state: absent
         remove: yes
       loop:
         - jane
         - joe
 ...
 #新建属于不同组的用户
 vim loop3.yaml
 ---
 - name: test loop
   hosts: node1
   gather_facts: no
   tasks:
     - name: add users
       user:
         name: "{{ item.name }}"
         groups: "{{ item.groups }}"
         state: present
       loop:
         - name: jane
           groups: wheel
         - name: joe
           groups: root
 ...

五、编写条件任务

when语句

when 用于有条件地运行任务,取要测试的条件作为值。如果条件满足,则运行任务。若条件不满足,则跳过任务。

复制代码
 #判断node1上是否存在sdb硬盘
 vim when1.yaml
 ---
 - name: check device sdb
   hosts: node1
   tasks:
     - name: sdb is exist
       debug:
         msg: sdb is exist
       when: ansible_devices.sdb is defined
     - name: sdb is not exist
       debug:
         msg: sdb is not exist
       when: ansible_devices.sdb is not defined
 ...
 #判断受管主机是否具有相应设备
 vim when2.yaml
 ---
 - name: create and use lv
   hosts: node1
   tasks:
     - name: Create a logical volume of 4000m
       lvol:
         vg: research
         lv: data
         size: 4000
       when: ansible_lvm.vgs.research is defined
     - debug:
         msg: Volume group does not exist
       when: ansible_lvm.vgs.research is not defined
 ...

Ansible block 多个任务作为block子条目,block作为多个任务整体。

复制代码
 #所有受控主机cpu数量大于等于3时安装并运行nginx软件服务
 vim deploy.yaml
 ---
 - name: deploy web
   hosts: all
   vars:
     package_name: nginx
     service_name: nginx
     min_cpu_count: 3
 ​
   tasks:
     - block:
       - name: install {{ package_name }}
         yum:
           name: "{{ package_name }}"
           state: present
       - name: enable and start {{ service_name }}
         service:
           name: "{{ service_name }}"
           state: started
           enabled: yes
       when: ansible_processor_vcpus >= min_cpu_count

blocks 还可以与 rescue和always一起使用

block:定义主要任务。

rescue:block中任务执行失败后,就会执行rescue中定义的任务。

always:无论block和rescue中任务执行是否成功和失败,都会执行的任务。

block配置when指令,同样适用rescue和always。

复制代码
 #如果目录存在直接创建文件,如果目录不存在先创建目录再创建文件
 vim create.yaml
 ---
 - name: create file
   hosts: node1,node2
   vars:
     data_path: /usr/share/nginx/html
 ​
   tasks:
     - block:
       - name: create file index.html
         copy:
           content: "Hello World From Nginx"
           dest: "{{ data_path }}/index.html"
       rescue:
         - name: create data path
           file:
             path: "{{ data_path }}"
             state: directory
         - name: create file index.html
           copy:
             content: "Hello World From Nginx"
             dest: "{{ data_path }}/index.html"
 ...

部署myhosts

复制代码
 vim inventory
 [controllers]
 controller
 ​
 [dev]
 node1
 ​
 [test]
 node2
 ​
 [prod]
 node3
 node4
 vim myhosts.yaml
 ---
 - name: push my hosts
   hosts: all
   tasks:
     - name: push hosts
       template:
         src: hosts.j2
         dest: /etc/myhosts
       when: inventory_hostname in groups.dev
 ...
 vim hosts.j2
 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
 ​
 {% for host in groups.all %}
 {{ hostvars[host].ansible_default_ipv4.address }} {{hostvars[host].ansible_fqdn }} {{ hostvars[host].ansible_hostname }}
 {% endfor %}
 #说明:
 #hostvars是magic 变量,通过该变量引用其他受管主机facts。
 #[server]不能使用单引号,因为server作为变量处理,替换为all中主机。
 #play 必须针对所有主机执行,收集所有主机facts,因为模版需要引用所有主机的facts。
 #只部署到dev主机组,使用when语句。groups.dev是magic变量,该变量获取dev主机组中主机清单。

六、Ansible 角色管理

Ansible 角色目录位置

默认role使用以下三个目录:

~/.ansible/roles

/usr/share/ansible/roles

/etc/ansible/roles

优先级从上到下依次降低。

可以在ansible.cfg配置文件[defaults]块中通过变量roles_path定义role位置:

复制代码
 [defaults]
 roles_path  = ./roles
 ...
 #多个路径使用冒号分隔
 roles_path = /etc/ansible/roles:/home/student/web/roles

创建角色

复制代码
 mkdir roles
 vim ansible.cfg
 [defaults]
 inventory = ./inventory
 remote_user = zhangzhe
 roles_path=./roles
 #创建角色
 ansible-galaxy role init nginx
 mv nginx roles
 #查找角色
 ansible-galaxy role list
 # /home/zhangzhe/webapp/roles
 - nginx, (unknown version)
 #进入角色查看tree
 cd roles/nginx
 sudo yum install -y tree
 tree
 #编辑要执行的任务
 vim tasks/main.yaml
 ---
 - name: install package
   yum:
     name: "{{ package_name }}"
     state: present
 ​
 - name: enable and start {{ service_name }}
   service:
     name: "{{ service_name }}"
     enabled: yes
     state: started
 ​
 - name: push test page
   copy:
     src: test.html
     dest: "{{ web_root_path }}/test.html"
 ​
 - name: push index page
   template:
     src: index.j2
     dest: "{{ web_root_path }}/index.html"
 ...
 #编辑模板文件
 vim templates/index.j2
 Welcome to {{ ansible_fqdn }}
 #编辑默认变量
 vim defaults/main.yaml
 package_name: nginx
 service_name: nginx
 web_root_path: /usr/share/nginx/html
 #准备测试页面
 echo test page > files/test.html
 #改手册
 echo ask for zhangzhe > README.md
 #准备说明
 vim meta/main.yml
 ---
 galaxy_info:
   author: zhangzhe
   description: zhangzhe web
   company: zhangzhe world
   license: license (GPLv2, CC-BY, etc)
   min_ansible_version: 2.4
 ​
   platforms:
   - name: Fedora
     versions:
     - all
     - 25
   - name: SomePlatform
     versions:
     - all
   galaxy_tags: [apache,web]
 dependencies: []
 #退回webapp目录
 cd ../../
 #创建play使用nginx角色
 vim use_role.yaml
 ---
 - name: deploy nginx with nginx role
   hosts: node1
   roles:
     - nginx
 ...
 #执行paly
 ansible-playbook use_role.yaml
 #验证
 curl http://node1/
 Welcome to node1.zhangzhe.cloud
 curl http://node1/test.html
 test page
相关推荐
羊村积极分子懒羊羊1 小时前
软件管理(网络软件仓库的使用方法)
linux
匀泪1 小时前
CE(SELinux)
运维·服务器
dxnb222 小时前
Datawhale26年1月组队学习:Agentic AI+Task2反思设计模式
学习·设计模式
viqjeee2 小时前
Linux ALSA驱动详解
linux·运维·服务器·alsa
夜未央312 小时前
HTTPS 原理与 PHP 文件包含及伪协议详解
运维·服务器·安全·网络安全
云川之下2 小时前
【网络】变长子网划分 (VLSM) 示例、点到点网络
运维·服务器·网络·变长子网
Dovis(誓平步青云)2 小时前
《epoll深度解析:从原理到使用,解锁Linux高并发I/O的核心能力(终篇)》
linux·运维·服务器·网络
lkbhua莱克瓦242 小时前
HTML与CSS核心概念详解
前端·笔记·html·javaweb
不会kao代码的小王2 小时前
服务器、存储与网络核心知识全解析
运维·服务器·网络