mycpen

Mycpen

记录学习历程与受益知识
github
telegram
bilibili

23_Linux基礎-ansible2

一。クラウドコンピューティング#

クラウドコンピューティング
openstack
docker
kvm
仮想化技術:物理マシンの上にクラウドホストを仮想化する
#唯一の欠点は セキュリティが低い 他人のところにデータが保存されている (影響は少ない)

#トラブルシューティングの能力 問題解決の能力

#注:ssh は 2 種類の認証を有効にする - 先に公開鍵認証 その後パスワード認証 パスワード認証が失敗した場合は permit deny と表示


二. ansible はデーモンではない#

#ansible はデーモンではなく、ansible コマンドを実行する時だけ実行される
#デーモン:常にメモリの中にいて、他の接続を待つ
#ssh はデーモンである
#1 つのコマンドを実行する コマンドはデーモンではない

#ansible はデーモンではない(デーモン:起動後ずっとメモリ内で実行され、他の人のアクセスを待つ)
#ansible は Python で書かれたコマンドスクリプトである

#[root@cPen_A ansible]# sudo -i # 注:直接 root ユーザーに戻る


三. ansible のモジュール#

ansible のモジュール

1. copy モジュール#

ローカルからファイルをディレクトリホストパスにコピーする
パラメータの説明:
src= ソースファイルパス # 注:source ソース

​ dest= 目的地パス # 注:destination 目的地

​ src= パスの後に / が付くと、内部のすべての内容を目的のディレクトリにコピーすることを示し、/ が付かない場合はディレクトリを再帰的にコピーする
​ content= 自分で記入するファイル内容
​ owner 所有者
​ group グループ
​ mode 権限

例1:shellモジュール、copyモジュール
---------------------------------------------------------------------------------------------------------------------------------
#例1:ansibleを使用してB、Cホストに/lianxiディレクトリを作成する
#-m	モジュールを指定
#-a	渡すパラメータ
ansible 指定ホスト -m 指定モジュール -a 実行するパラメータ
[root@cPen_A ansible]# ansible all -m shell -a "mkdir /lianxi -p"
#注:rc ==> return code --> 0は実行成功を示す
#注:rc ==> return code --> 1は実行失敗を示す

#例2:ansible-copyファイルをホストB、Cの/lianxi/ansibleディレクトリにコピーし、指定された権限所有者配列を指定する
[root@cPen_A lianxi]# vim ansible-copy
[root@cPen_A lianxi]# ansible all -m copy -a "src=/lianxi/ansible-copy dest=/lianxi/ansible mode=777 owner=sanchuang group=sanchuang"
#注:ホストB、Cに指定されたユーザーsanchuangとグループsanchuangが存在することを確認する
#md5sum	一般的には 情報の要約		ファイルが変更されたかどうかを判定する
例2:webserグループを指定し、/etc/passwdをホスト/tmpディレクトリにコピーし、権限777を指定する
---------------------------------------------------------------------------------------------------------------------------------
[root@cPen_A lianxi]# ansible webser -m copy -a "src=/etc/passwd dest=/tmp mode=777"

===========================================================================================

例3:srcパスの後に/が付くか付かないかの違い
---------------------------------------------------------------------------------------------------------------------------------
#注:src= パスの後に/が付くと、内部のすべての内容を目的のディレクトリにコピーすることを示し、/が付かない場合はディレクトリを再帰的にコピーする
#注:/が付かない場合
[root@cPen_A copy_dir]# ansible all -m copy -a "src=/lianxi/copy_dir dest=/lianxi/ansible"
#注:/が付く場合
[root@cPen_A copy_dir]# ansible all -m copy -a "src=/lianxi/copy_dir/ dest=/lianxi/ansible"

#/が付くと、ディレクトリ内のサブファイルまたはサブフォルダをコピーすることを示す
#/が付かないと、ディレクトリ全体をコピーすることを示す

2. fetch モジュール#

#注:リモートホストからファイルをローカルに取得する


---------------------------------------------------------------------------------------------------------------------------------
[root@cPen_A lianxi]# ansible webser -m fetch -a "src=/etc/hostname dest=/lianxi mode=644"
192.168.0.22 | CHANGED => {
    "changed": true, 
    "checksum": "c468f7340237d9f531122f5b03345ce8ac5641b4", 		  # 注:取得後に比較される
    "dest": "/lianxi/192.168.0.22/etc/hostname", 
    "md5sum": "8d23b0947f191eb9c20728677271eb4d", 
    "remote_checksum": "c468f7340237d9f531122f5b03345ce8ac5641b4", # 注:リモートと比較して内容が変更されたかどうか
    "remote_md5sum": null
}
#注:大きなファイルの転送中に突然中断された場合、ファイルが完全に転送されず、保存されたmd5sumとそのmd5sumが異なる
#注:2つの値が一致すれば、転送が完了したことを示す
[root@cPen_A lianxi]# ls				# 注:パスに自動的にIPアドレス名のフォルダが追加された
192.168.0.20  192.168.0.22  ansible-copy  copy_dir
[root@cPen_A lianxi]# cd 192.168.0.20
[root@cPen_A 192.168.0.20]# ls
etc
リモートホストからファイルをローカルに取得する
fetchは自動的にdest指定ディレクトリの後にリモートホスト名のディレクトリ構造を追加し、srcディレクトリ構造を接続する
fetchがローカルに保存するディレクトリ構造	dest + リモートホスト名 + src

#注:md5は判定できる	1、ファイルが変更されたか;2、ファイルが完全に転送されたか
#注:または任意のハッシュアルゴリズムのいずれかを使用して、値が等しいかどうかを比較する

3. command モジュール#

リモートホスト上でコマンドを実行し、裸の実行に属し、キーと値のペアで表示されず、シェル解析を行わない

例1:command、shell
---------------------------------------------------------------------------------------------------------------------------------
[root@cPen_A 192.168.0.20]# ansible all -m command -a "ifconfig"
[root@cPen_A 192.168.0.20]# ansible all -m shell -a "ifconfig"

例2:commandの裸の実行 (後に渡されるパラメータは解析されない)
---------------------------------------------------------------------------------------------------------------------------------
#注:ifconfig|grep inet全体を1つのコマンドとして実行する
[root@cPen_A 192.168.0.20]# ansible all -m command -a "ifconfig|grep inet"
192.168.0.22 | FAILED | rc=2 >>
[Errno 2] そのファイルまたはディレクトリは存在しません
#裸の実行に属し、パイプ記号を解析しないため、ifconfig|grep inetは1つのコマンドと見なされる

#注:shellは可能である (後に渡されるパラメータは解析される)
[root@cPen_A 192.168.0.20]# ansible all -m shell -a "ifconfig|grep inet"

============================================================================================
[root@cPen_A ansible]# ifconfig			# 注:ネットワークインターフェースを確認する(見るものが多い)
#注:受信パケット、返送パケット、バイト、エラーの数を確認できる
[root@cPen_A ansible]# ip a				# 注:ネットワークインターフェースを確認する

4. shell モジュール#


---------------------------------------------------------------------------------------------------------------------------------
[root@cPen_A 192.168.0.20]# ansible all -m shell -a "ifconfig|grep inet"
commandと同じだが、shellモジュールはパイプなどの機能を解析できる

5. file モジュール#

ファイル属性を設定する(ファイルを作成する)
一般的なパラメータ:
path 目的地パス
state directory はディレクトリ、link はソフトリンク
group ディレクトリのグループ
owner 所有者
など、他のパラメータは ansible-doc -s file で取得する

state --
absent ファイルとディレクトリを削除する
directory ディレクトリ
touch 空のファイルを新規作成
link ソフトリンク
hard ハードリンク

例1:fileファイルのヘルプ情報を確認する
--------------------------------------------------------------------------------------------
[root@cPen_A lianxi]# ansible-doc -s file			# 注:fileファイルのヘルプ情報を確認する
============================================================================================

例2:ターゲットホストの/tmpディレクトリにディレクトリを作成する
#注:ファイルディレクトリを作成する
---------------------------------------------------------------------------------------------------------------------------------
[root@cPen_A lianxi]# ansible all -m file -a "path=/tmp/sanchuang state=directory"
============================================================================================

例3:ファイル属性を変更する
---------------------------------------------------------------------------------------------------------------------------------
[root@cPen_A lianxi]# ansible all -m file -a "path=/tmp/passwd owner=sanchuang"

6. cron モジュール#

cron モジュールを使用してターゲットホストにスケジュールタスクを生成する
一般的なパラメータ:
分 (minute)、時 (hour)、日 (day)、月 (month)、週 (week) の他に
name: 今回のスケジュールタスクの名前
state: present 生成(デフォルト) | absent 削除(name に基づく)

#注:まずプログラムが起動しているか確認する
[root@cPen_A ~]# ps -ef |grep crond
root        702      1  0 10:59 ?        00:00:00 /usr/sbin/crond -n
root       3582   3553  0 14:41 pts/3    00:00:00 grep --color=auto crond
#注:ログを見ることを学ぶ
[root@cPen_A ~]# cd /var/log/
[root@cPen_A log]# less cron
Nov 25 12:01:01 cPen_A run-parts(/etc/cron.hourly)[3498]: finished 0anacron
例1:スケジュールタスクを追加する
---------------------------------------------------------------------------------------------------------------------------------
#注:毎日午前1時に/etc/passwdファイルが変更されているか確認し、チェックレポートを生成する
[root@cPen_A log]# ansible all -m cron -a "minute=*/3 job='date >>/tmp/time.txt' name=date_test state=present"		# 注:minute=*/3	指定する毎3分にdate >>/tmp/time.txtコマンド
[root@cPen_B ~]# crontab -l
#Ansible: date_test
*/3 * * * * date >>/tmp/time.txt

[root@cPen_A log]# ansible 192.168.0.20 -m cron -a "minute=*/3 job='date >>/tmp/time.txt' name=date_test state=present"		# 注:特定のホストに個別に設定でき、必ずしも一括処理する必要はない

============================================================================================

例2:スケジュールタスクを削除する
---------------------------------------------------------------------------------------------------------------------------------
[root@cPen_A log]# ansible 192.168.0.20 -m cron -a  "name=date_test state=absent"
ntpサービスは時間管理サーバーである
例:ntpサービス システム時間管理サービス
[root@cPen_A log]# yum install ntp				# 注:centos7
[root@cPen_B ~]# yum install chrony				# 注:centos8ではntpがchronyに置き換えられた
[root@cPen_A log]# ntpdate ntp1.aliyun.com		# 注:阿里云の時間を同期する
#注:ntpクライアントを使用してntpサーバーと時間を同期する

7. yum モジュール#

その名の通り、yum でソフトウェアパッケージをインストールするモジュールである;
一般的なパラメータの説明:
enablerepo, disablerepo は特定の repo リポジトリを有効または無効にすることを示す
name インストールパッケージ名
state (present' or 'installed', latest') はインストールを示し、(absent' or 'removed') は削除を示す

#注:name でインストールするパッケージ名 state インストールまたはアンインストール

例:wgetをインストールする
[root@cPen_A log]# ansible all -m yum -a "name=wget state=installed"
例:wgetをアンインストールする
[root@cPen_A log]# ansible all -m yum -a "name=wget state=absent"

8. service モジュール#

サービス管理モジュール
一般的なパラメータ:
name: サービス名
state: サービス状態 started(起動) stopped(停止) restarted(再起動) reloaded(再読み込み)
enabled: 起動時に自動的に開始するかどうか true|false
runlevel: 起動レベル (systemed 方式では無視される)

#ファイル転送サービスvsftpdをインストールする
[root@cPen_A log]# ansible all -m yum -a "name=vsftpd state=installed"

例:vsftpdサービスを停止する
[root@cPen_A log]# ansible all -m service -a "name=vsftpd state=stopped"
例:vsftpdサービスを開始する
[root@cPen_A log]# ansible all -m service -a "name=vsftpd state=started"

9. script モジュール#

1、ローカルのスクリプトをリモートで実行する;前提として、リモートで実行可能であること、Linux のスクリプトを Windows で実行しないこと;

#注:スクリプトをリモートサーバーにアップロードせず、リモートサーバーでスクリプトを実行する

[root@cPen_A ~]# vim test.sh
#!/bin/bash
echo "test ansible" >>/tmp/ansible.txt
[root@cPen_A ~]# ansible all -m script -a "/root/test.sh"	# 注:/root/test.shスクリプトパス

--------------------------------------------------------------------------------------------
例:実行が遅い  マシンが多い  どう解決するか
答:マルチプロセスを使用して実行することができる
-f 6		指定した6つのプロセスで実行する

commandモジュールはパイプ記号を認識できず、shellモジュールは認識できる
copyモジュールはプッシュする
scriptモジュールはスクリプトをアップロードする必要がなく、リモートサーバーでスクリプトを実行する

四。システムバージョンの確認#

例:システムバージョンを確認する
[root@cPen_B ~]# uname -r						# 注:システムカーネルを確認する
4.18.0-193.el8.x86_64
[root@cPen_B ~]# cat /etc/redhat-release 		# 注:/etc/redhat-releaseを確認してシステムバージョンを確認する
CentOS Linux release 8.2.2004 (Core) 

五。リンク#

例:ソフトリンク
[root@cPen_A lianxi]# ln -s ansible-copy ansible-copy-likcs-s	#注:前の元ファイル 後のリンクファイル
[root@cPen_A lianxi]# ls -al 		# 注:-s ソフトリンク
lrwxrwxrwx   1 root root  12 11月 25 11:30 ansible-copy-likcs-s -> ansible-copy
#注:ソフトリンク	ショートカットのようなもの
#注:ソフトリンクを削除しても元のファイルには影響しないが、ソフトリンクの元ファイルを削除するとリンクファイルに影響する

例:ハードリンク
[root@cPen_A lianxi]# ln ansible-copy ansible-copy-link
[root@cPen_A lianxi]# ls -al
-rw-r--r--   2 root root  20 11月 25 10:12 ansible-copy-link
rm -rf 元ファイルを削除してもハードリンクファイルは影響を受けない
#注:ハードリンクはバックアップを取るために使用できる
#注:ハードリンクの元ファイルを削除してもリンクファイルには影響しない

#ソフトリンク、ハードリンク
#ハードリンクを作成すると、ファイルのリンク数が+1される
#ハードリンクファイルまたは元ファイルを削除すると、ファイルのリンク数が-1されるだけで、ファイルは実際には削除されない
#ハードリンクを作成する
[root@cPen_A lianxi]# ls -al
-rw-r--r--   2 root root  20 11月 25 10:12 ansible-copy		# 注:リンク数は2
#注:ソフトリンク
lrwxrwxrwx   1 root root  12 11月 25 11:30 ansible-copy-likcs-s -> ansible-copy # 注:リンク数は1
#注:ハードリンク
-rw-r--r--   2 root root  20 11月 25 10:12 ansible-copy-link	# 注:リンク数は2
シンボリックリンク数 1
rm -rf 削除されるのは ファイル名 ディスク内のdataのリンク
dataはディスク内に残り、しばらくすると新しいデータがdataを上書きする
#注:1は削除後に存在しないことを示し、2は削除後にも存在することを示す

六. playbook#

ansible の各モジュール(さまざまな機能を実現できる)は工場内の各ツールであり、playbook はガイドブックであり、ターゲットリモートホストは在庫と原材料のオブジェクトである
#注:構文は yaml 形式で設定する

1、playbook の核心要素
hosts : playbook 設定ファイルが作用するホスト
tasks: タスクリスト
variables: 変数
templates: テンプレート構文を含むテキストファイル
handlers : 特定の条件でトリガーされるタスク
roles : playbook を階層的かつ構造的に整理するために使用される。roles は階層構造に基づいて変数ファイル、タスク、ハンドラーなどを自動的にロードできる
2、playbook の実行方法
ansible-playbook --check 変更が発生する可能性があるかどうかを検出するが、実際の操作は実行しない
ansible-playbook --list-hosts 実行タスクのホストをリスト表示する
ansible-playbook --syntax-check playbook.yaml 構文チェック
ansible-playbook -t TAGS_NAME playbook.yaml TAGS_NAME タスクのみを実行する
ansible-playbook playbook.yaml 実行する

例:/etc/passwdをAマシンから他のマシンの/tmp/passwd_tmpにコピーする
--------------------------------------------------------------------------------------------
#注:playbookを作成する
[root@cPen_A ~]# vim ansible_playbook_sc.yaml		#注:playbookを作成する
- hosts: all
  remote_user: root
  tasks:
  - name: up file
    copy: src=/etc/passwd dest=/tmp/passwd_tmp
#playbookを実行する
[root@cPen_A ~]# ansible-playbook ansible_playbook_sc.yaml 
============================================================================================

例:yamlファイルの作成方法
--------------------------------------------------------------------------------------------
#第1歩 まずpython3をインストールする:yum install python3
#第2歩 pip3を使用してPyYamlモジュールをインストールする
[root@cPen_A ~]# pip3 install PyYaml
[root@cPen_A ~]# python3
>>> import yaml
>>> fp = open("ansible_playbook_sc.yaml")
>>> dict = yaml.load(fp)
>>> dict
[{'hosts': 'all', 'remote_user': 'root', 'tasks': [{'name': 'up file', 'copy': 'src=/etc/passwd dest=/tmp/passwd_tmp'}]}]
#注:使用
1、yamlファイルを作成する
[root@cPen_A ~]# cat ansible_playbook_sc.yaml 	# 注:辞書形式に似ている - リストに相当する;内部は辞書に相当する
- hosts: all								# 注:すべてのホストに適用(どのグループでも)
  remote_user: root							# 注:rootユーザーが実行する
  tasks:									# 注:何をするか
  - name: up file							# 注:作業名はup file
    copy: src=/etc/passwd dest=/tmp/passwd_tmp	# 注:copyモジュールを使用してソースと目的地を指定する
2、Pythonを使用してyamlを解析できる
>>> import yaml
>>> fp = open("ansible_playbook_sc.yaml")
>>> dict = yaml.load(fp)
>>> dict
[{'hosts': 'all', 'remote_user': 'root', 'tasks': [{'name': 'up file', 'copy': 'src=/etc/passwd dest=/tmp/passwd_tmp'}]}]
#注:copyモジュールを使用してsrcとdestを指定する
例:複数の操作
--------------------------------------------------------------------------------------------
[root@cPen_A ~]# vim ansible_playbook_sc.yaml					# 注:作成
- hosts: all
  remote_user: root
  tasks:
  - name: up file
    copy: src=/etc/passwd dest=/tmp/passwd_tmp
  - name: download redis
    yum: name=redis state=installed
- hosts: webser
  tasks:
  - name: remove file
    shell: rm -rf /tmp/passwd_tmp
[root@cPen_A ~]# ansible-playbook ansible_playbook_sc.yaml 		# 注:実行

七。まとめ#

ansible は一般的なモジュールを使用して、コマンドラインからホストリストに対してリモートホストの構成を管理でき、エージェントクライアントプログラムは不要であるが、ターゲットホストには ssh と python2.4 + が必要である;ssh プロトコルに基づき、ユーザー名とパスワードを使用することも、秘密鍵を使用することもでき、秘密鍵の使用を推奨する;
Windows 上では powershell と winrm サービスをインストールする必要があり、これも可能である。この点については、私の以前のブログ ansible 自動化管理 windowsを参照できる
ansib-doc を使用してモジュール情報や特定のモジュールのヘルプ情報を取得することができる;
ansible-playbook は YAML 構文に基づいて設定されており、playbook ファイルをテスト、解析、実行して指定された無端ホストに適用できる;非常に便利で、私たちのリモートホストの統一的な編成と管理を行うことができる;

八。演習#

例:毎日午前1時に/etc/passwdファイルが変更されているか確認し、チェックレポートを生成する

例:スクリプトを作成してansibleノード(管理対象ホスト)サーバーのバックアップを実現し、/var/log/messagesログを/backupディレクトリにバックアップし、2020-11-25-01-log.tar.gzという名前を付け、毎時実行する
############################################################################################
例:毎日午前1時に/etc/passwdファイルが変更されているか確認し、チェックレポートを生成する
-----------------------------------------------------------------------------------------------------------
方法1 md5sumを使用してファイルが変更されたか確認する md5sum -c --status
check_file.sh
md5sum -c --status d.md5 &&echo "ファイルは変更されていません" ||echo "ファイルは変更されました"
md5sum /etc/passwd &> d.md5			#注:ファイル名は必ずd.md5でなければならない
-----------------------------------------------------------------------------------------------------------
方法2
check_ectpasswd.sh
a='md5sum /etc/passwd'				#注:現在のmd5値
b='tail -n1 /root/b' 				#注:前回のmd5値
[[ $a==$b ]]&&echo "ファイルは変更されていません!" >> /root/c||echo "ファイルは変更されました!" >> /root/c
$a  >> /root/b
-----------------------------------------------------------------------------------------------------------
方法3
touch /tmp/passwd.log
touch /tmp/passwd.txt
a=`md5sum /etc/passwd`
b=`md5sum /tmp/passwd.txt`
c=${a:0:32}							#注:md5sumは任意の長さの入力に対して固定長の出力を生成する
d=${b:0:32}
if [ $c = $d ] 
then
    echo "$(date)ファイルは変更されていません" >>/tmp/passwd.log  
    cat /etc/passwd >/tmp/passwd.txt
else
    echo "$(date)ファイルは変更されました" >>/tmp/passwd.log
    cat /etc/passwd >/tmp/passwd.txt
fi 
===========================================================================================================
ansible_playbook_zuoye.yaml
 - hosts: all
   remote_user: root
   tasks: 
   - name: check file
     cron: hour=1 day=*/1 job='/usr/bin/bash ~/check_file.sh'
#注:スクリプトfileを各仮想マシンに配置する必要がある。このステップは書いていない
例:スクリプトを作成してansibleノード(管理対象ホスト)サーバーのバックアップを実現し、/var/log/messagesログを/backupディレクトリにバックアップし、2020-11-25-01-log.tar.gzという名前を付け、毎時実行する
 - hosts: all
   remote_user: root
   tasks: 
   - name: backup messages
     cron: hour=1 job='tar czf /backup/$(date +%Y-%m-%d-%H-log.tar.gz) /var/log/messages'
例:md5sumを使用してファイルが変更されたか確認する md5sum -c --status
[root@cPen_A lianxi]# man md5sum
       -c, --check
              read MD5 sums from the FILEs and check them
       --status
              don't output anything, status code shows success
[root@cPen_A lianxi]# md5sum /etc/passwd > d.md5		#注:このファイルに書き込む ファイル名は必ずこのままで
[root@cPen_A lianxi]# cat d.md5 
28b2503e7fb565ddc0b8ec1f9ad6a9c7  /etc/passwd
[root@cPen_A lianxi]# md5sum -c --status d.md5			#注:ファイルが変更されているか確認する
[root@cPen_A lianxi]# echo $?							#注:ファイルが変更されていない場合、戻り値は0
0
[root@cPen_A lianxi]# useradd chen223344
[root@cPen_A lianxi]# md5sum -c --status d.md5
[root@cPen_A lianxi]# echo $?							#注:ファイルが変更された場合、戻り値は1
1
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。