EtherChannelの設定
今度、MLAGを設定する必要があり、そもそもLAG設定を忘れていたので、復習として、Cisco Packet TracerでEtherChannelの設定をしてみました。
構成は、以下のようになってます。
以下、履歴です。
■Switch8
Switch>en
Switch#conf t
Enter configuration commands, one per line. End with CNTL/Z.
Switch(config)#hostname SW08
SW08(config)#int range fa0/1-2
SW08(config-if-range)#switchport mode access
SW08(config-if-range)#exit
SW08(config)#vlan 2
SW08(config-vlan)#exit
SW08(config-if)#int fa0/2
SW08(config-if)#switchport access vlan 2
SW08(config-if)#exit
SW08(config)#int range fa0/23-24
SW08(config-if-range)#switchport mode trunk
SW08(config-if-range)#channel-group 1 mode on
SW08(config-if-range)#
SW08(config-if-range)#do show etherchannel summary
Flags: D - down P - in port-channel
I - stand-alone s - suspended
H - Hot-standby (LACP only)
R - Layer3 S - Layer2
U - in use f - failed to allocate aggregator
u - unsuitable for bundling
w - waiting to be aggregated
d - default port
Number of channel-groups in use: 1
Number of aggregators: 1
Group Port-channel Protocol Ports
------+-------------+-----------+----------------------------------------------
1 Po1(SU) - Fa0/23(P) Fa0/24(P)
■Switch9
Switch>en
Switch#conf t
Switch(config)#hostname SW09
SW09(config)#vlan 2
SW09(config-vlan)#exit
SW09(config)#int range fa0/1-2
SW09(config-if-range)#switchport mode access
SW09(config-if)#int fa0/2
SW09(config-if)#switchport access vlan 2
SW09(config-if)#exit
SW09(config)#int range fa0/23-24
SW09(config-if-range)#switchport mode trunk
SW09(config-if-range)#channel-group 1 mode on
protocol on Interface FastEthernet0/24, changed state to up
SW09(config-if-range)#
SW09#show etherchannel summary
Flags: D - down P - in port-channel
I - stand-alone s - suspended
H - Hot-standby (LACP only)
R - Layer3 S - Layer2
U - in use f - failed to allocate aggregator
u - unsuitable for bundling
w - waiting to be aggregated
d - default port
Number of channel-groups in use: 1
Number of aggregators: 1
Group Port-channel Protocol Ports
------+-------------+-----------+----------------------------------------------
1 Po1(SU) - Fa0/23(P) Fa0/24(P)
■負荷分散方法の設定と確認
SW08(config)#port-channel load-balance src-mac
SW08(config)#exit
SW08#show etherchannel load-balance
EtherChannel Load-Balancing Operational State (src-mac):
Non-IP: Source MAC address
#負荷分散方法
※ちなみに、EtherChannelを設定しない場合は、以下のようにSTPで片方のポートがブロックされる。
SW09#show spanning-tree
VLAN0001
Spanning tree enabled protocol ieee
Root ID Priority 32769
Address 0002.1696.3EC7
Cost 19
Port 23(FastEthernet0/23)
Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec
Bridge ID Priority 32769 (priority 32768 sys-id-ext 1)
Address 0003.E455.7E17
Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec
Aging Time 20
Interface Role Sts Cost Prio.Nbr Type
---------------- ---- --- --------- -------- --------------------------------
Fa0/1 Desg FWD 19 128.1 P2p
Fa0/24 Altn BLK 19 128.24 P2p
Fa0/23 Root FWD 19 128.23 P2p
VLAN0002
Spanning tree enabled protocol ieee
Root ID Priority 32770
Address 0002.1696.3EC7
Cost 19
Port 23(FastEthernet0/23)
Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec
Bridge ID Priority 32770 (priority 32768 sys-id-ext 2)
Address 0003.E455.7E17
Hello Time 2 sec Max Age 20 sec Forward Delay 15 sec
Aging Time 20
Interface Role Sts Cost Prio.Nbr Type
---------------- ---- --- --------- -------- --------------------------------
Fa0/2 Desg FWD 19 128.2 P2p
Fa0/24 Altn BLK 19 128.24 P2p
Fa0/23 Root FWD 19 128.23 P2p
VLAN間ルーティング(L3Switch)
CCNA取得からだいぶ経って、勉強した内容をほとんど忘れてしまったので、復習がてらにCisco Packet Tracerで以下の構成を組んでみました。
構成は、単純なL3Switchを用いたVLAN間ルーティングです。
以下、実際に入力した履歴です。
■Swtich-CW01
設定
Switch-CW01>
Switch-CW01>en
Switch-CW01#conf t
Enter configuration commands, one per line. End with CNTL/Z.
Switch-CW01(config)#int vlan 1
Switch-CW01(config-if)#ip address 192.168.100.5 255.255.255.0 <-マネジメントIP設定
Switch-CW01(config-if)#no shutdown
Switch-CW01(config-if)#exit
Switch-CW01(config)#ip routing <-ルーティングの有効可
Switch-CW01(config)#vlan 10
Switch-CW01(config-vlan)#exit
Switch-CW01(config)#vlan 20
Switch-CW01(config-vlan)#exit
Switch-CW01(config)#int vlan 10
Switch-CW01(config-if)#ip address 192.168.1.254 255.255.255.0
Switch-CW01(config-if)#no shutdown
Switch-CW01(config-if)#exit
Switch-CW01(config)#int vlan 20
Switch-CW01(config-if)#ip address 192.168.2.254 255.255.255.0
Switch-CW01(config-if)#no shutdown
Switch-CW01(config-if)#exit
Switch-CW01(config)#int range g0/1-2 <-Switchportの確認
Switch-CW01(config-if-range)#switchport trunk encapsulation dot1q
Switch-CW01(config-if-range)#switchport mode trunk
Switch-CW01(config-if-range)#switchport trunk allowed vlan 10,20
Switch-CW01(config-if-range)#exit
設定確認
Switch-CW01#show vlan <- Vlanの確認
VLAN Name Status Ports
---- -------------------------------- --------- -------------------------------
1 default active Fa0/1, Fa0/2, Fa0/3, Fa0/4
Fa0/5, Fa0/6, Fa0/7, Fa0/8
Fa0/9, Fa0/10, Fa0/11, Fa0/12
Fa0/13, Fa0/14, Fa0/15, Fa0/16
Fa0/17, Fa0/18, Fa0/19, Fa0/20
Fa0/21, Fa0/22, Fa0/23, Fa0/24
10 VLAN0010 active
20 VLAN0020 active
1002 fddi-default active
1003 token-ring-default active
1004 fddinet-default active
1005 trnet-default active
Switch-CW01#show int trunk <- trunkポートの確認
Port Mode Encapsulation Status Native vlan
Gig0/1 on 802.1q trunking 1
Gig0/2 on 802.1q trunking 1
Port Vlans allowed on trunk
Gig0/1 10,20
Gig0/2 10,20
Port Vlans allowed and active in management domain
Gig0/1 10,20
Gig0/2 10,20
Port Vlans in spanning tree forwarding state and not pruned
Gig0/1 10,20
Gig0/2 10,20
Switch-CW01#show ip int brief <-物理インタフェースとSVIの確認
…
FastEthernet0/22 unassigned YES unset down downFastEthernet0/23 unassigned YES unset down down
FastEthernet0/24 unassigned YES unset down down
GigabitEthernet0/1 unassigned YES unset up up
GigabitEthernet0/2 unassigned YES unset up up
Vlan1 192.168.100.5 YES manual up down
Vlan10 192.168.1.254 YES manual up up
Vlan20 192.168.2.254 YES manual up up
■Switch01
Switch>
Switch>en
Switch#conf t
Enter configuration commands, one per line. End with CNTL/Z.
Switch(config)#hostname SW01
SW01(config)#int vlan 1
SW01(config-if)#ip address 192.168.100.1 255.255.255.0
SW01(config-if)#no shutdown
SW01(config-if)#
%LINK-5-CHANGED: Interface Vlan1, changed state to up
%LINEPROTO-5-UPDOWN: Line protocol on Interface Vlan1, changed state to up
SW01(config-if)#exit
SW01(config)#vlan 10
SW01(config-vlan)#exit
SW01(config)#vlan 20
SW01(config-vlan)#exit
SW01(config)#int range fa0/1-2
SW01(config-if-range)#switchport mode access
SW01(config-if-range)#int fa0/1
SW01(config-if)#switchport access vlan 10
SW01(config-if)#int fa0/2
SW01(config-if)#switchport access vlan 20
SW01(config-if)#int g0/1
SW01(config-if)#switchport mode trunk
SW01(config-if)#switchport trunk allowed vlan 10,20
SW01(config-if)#exit
SW01(config)#exit
SW01#
■Switch02
Switch>
Switch>en
Switch#conf t
Enter configuration commands, one per line. End with CNTL/Z.
Switch(config)#hostname SW02
SW02(config)#int vlan 1
SW02(config-if)#ip address 192.168.100.2 255.255.255.0
SW02(config-if)#no shutdown
SW02(config-if)#
%LINK-5-CHANGED: Interface Vlan1, changed state to up
%LINEPROTO-5-UPDOWN: Line protocol on Interface Vlan1, changed state to up
SW02(config-if)#exit
SW02(config)#vlan 10
SW02(config-vlan)#exit
SW02(config)#vlan 20
SW02(config-vlan)#exit
SW02(config)#int range fa0/1-2
SW02(config-if-range)#switchport mode access
SW02(config-if-range)#int fa0/1
SW02(config-if)#switchport access vlan 10
SW02(config-if)#int fa0/2
SW02(config-if)#switchport access vlan 20
SW02(config-if)#int g0/1
SW02(config-if)#switchport mode trunk
SW02(config-if)#switchport trunk allowed vlan 10,20
SW02(config-if)#exit
SW02(config)#exit
SW02#
PC0(192.168.1.1)からPC3(192.168.2.2)に問題なく疎通とれることを確認できました。
仕事でネットワークを触ることがほとんどないので、時間があるタイミングで今後もやったことをアップしていきたいと思います。
Slack API を用いた容量監視
概要
awxサーバの容量がひっ迫してサーバがダウンする事象が発生していたため、 毎週月曜日に容量を取得しSlackに投稿するボットを作りました
手順
結果
1. slack apiのenableとスレッド指定
※下記を参考に設定
https://api.slack.com/messaging/webhooks#getting_started
2. slack webhook urlの取得
1の設定後に下記のようなwebhook urlを取得できる
https://hooks.slack.com/services/XXXXXXXXXXXXXXXXXXXXXXXX
3. python スクリプトの作成
2で取得したwebhook url宛にリクエスト(post)を投げるスクリプトを作成。
ルートディレクトリの容量はsubprocessモジュールを使用して取得。
※dataの書き方は少し独特なので、もしトラブった場合は以下を参照。
formatを使用した文字列内で波括弧({)を使用する
import requests import subprocess, sys import socket def create_message(): hostname = socket.gethostname() cap = subprocess.run('df -h /', shell=True, encoding='utf-8', stdout=subprocess.PIPE, stderr=subprocess.STDOUT) if cap.returncode != 0: cap_msg = "error" else: cap_msg = cap.stdout message = f"[{hostname}]\n {cap_msg}" return message def post_message(message): headers = { "Content-type": "application/json" } data = f'{{"text":"{message}"}}' response = requests.post('https://hooks.slack.com/services/XXXXXXX', headers=headers, data=data) # 2で取得したwebhook urlを指定 def main(): message = create_message() post_message(message) if __name__ == '__main__': main()
実際にSlackに送られたメッセージ
[centos7] Filesystem Size Used Avail Use% Mounted on /dev/mapper/centos-root 104G 22G 82G 21% /
curlでもテスト
curl -i -H "Content-type: application/json" -s -S -X POST -d '{"text":"test"}' https://hooks.slack.com/services/XXXXXX
問題なく「test」というメッセージが送られてきました。
4. cronの設定
毎週月曜日に容量を確認
$crontab -e
0 9 * * 1 python /root/slackapp/post_message_to_slack.py
参照
https://qiita.com/momotaro98/items/fe567041cbd2bd3f2281 https://api.slack.com/messaging/webhooks#getting_started
formatを使用した文字列内で波括弧({)を使用する
概要
python で format を使う場合に、文字列内で波括弧({)を使う場合は波括弧({)を重ねる必要がある。
事象
Slack APIを使う際にdataの文字列に波括弧({)を入れる必要があった。また、文字列には変数も展開する必要があったので、 formatを使い、以下のように書いていたが、その場合pep8でも引っかかり、また、プログラムもエラーとなった。
data = f'{"text": "{message}"}'
実行時のエラー
'...'.format(...) has unused arguments at position(s): 0 '...'.format(...) is missing arguments(s) for placeholder(s):
解決策
formatを使った文字列内で、そのまま波括弧({)を表示されたい場合は、波括弧({)を重ねて "{{" とする。
data = '{{"text": "{}"}}'.format("message") # data: {"text": "{}"}
また、Pythonのバージョン3.6から追加されたfを使うと以下のようになる。
data = f'{{"text":"{message}"}}'
is bool は template error while templating string
概要
プレイブックのwhen文でis trueを使っていたところ、ansible 2.10.5では動いていたが ansible-core 2.11.0rc2 で動かなくなった。 ※3/26時点の最新バージョンである2.12.3でも同様の結果
事象
ansible 2.10.5では動いていた以下のプレイブックがansibleをバージョンアップした所、動かなくなった。
- hosts: localhost name: Test connection: local gather_facts: False vars: b: True tasks: - name: Test debug: msg: "test" when: b is True
動かなかった時のエラー内容
fatal: [localhost]: FAILED! => {"msg": "The conditional check 'b is True' failed. The error was: template error while templating string: no test named 'True'. String: {% if b is True %} True {% else %} False {% endif %}\n\nThe error appears to be in ... : line 18, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: Test\n ^ here\n"}
おそらく、いつのバージョンからか is bool という書き方がサポートされなくなったと思われる。
解決策
== True(もしくは、比較の部分の記載を消して変数だけにする)
※冗長だけど、自分的には==Trueなどの記載があった方が分かりやすくて好き
そのため、以下のように変更したところ、問題なく動いた。
- hosts: localhost name: Test connection: local gather_facts: False vars: b: True tasks: - name: Test debug: msg: "test" when: b == True
Ansible extra-varsで真偽値(True/False)を使う
概要
ansibleの実行時にextra-varsで変数の真偽値(True/False)を変更する場合、 そのまま指定しても変更できません。
例えば、以下のように実行すると、test_boolに"True"という文字列が入るため、 真偽値のTrueのような使い方は出来ません。
$ ansible-playbook exstra_vars_boolean.yml -e test_bool=true
解決策
extra-varsで値を辞書型で宣言すれば、真偽値をアップデートできます。
$ ansible-playbook exstra_vars_boolean.yml -e '{"test_bool": True}'
実行例
# exstra_vars_boolean.yml --- - hosts: localhost gather_facts: no vars: test_bool: false tasks: - name: debug test_bool debug: var=test_bool when: test_bool == True
上記のymlを実行する場合、下記のように実行することで、test_boolの値をアップデート出来る
$ ansible-playbook exstra_vars_boolean.yml -e '{"test_bool": True}' PLAY [localhost] ************************************************************************* TASK [debug test_bool] ******************************************************************* ok: [localhost] => { "test_bool": true } PLAY RECAP ******************************************************************************* localhost : ok=1 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
kubeadm ノードの追加
kubeadmのクラスターで新規ノードを追加したときの備忘録。
一般的にはコントロールプレーンノードでkubeadm initをしたときに出力されるkubeadm initを実行すれば良い
kubeadm join --token <token> <control-plane-host>:<control-plane-port> --discovery-token-ca-cert-hash sha256:<hash>
ただ、それを記録していなかった場合、24時間以内であれば、次のコマンドで<token>を取得可能
kubeadm token list
24時間たってしまい、上記で取得できない場合は、次のコマンドで新しいトークンを作成する必要がある。
kubeadm token create
--discovery-token-ca-cert-hash sha256:<hash>の値は、コントロールプレーンノードで次のコマンドチェーンを実行することで取得可能
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \ openssl dgst -sha256 -hex | sed 's/^.* //'
実際に実行した結果
既存のクラスタ(kube01: master, kubeadm02: worker)にkubeadm03: workerを追加する
作業前の状態
[root@kube01 ~]# k get node NAME STATUS ROLES AGE VERSION kube01 Ready control-plane,master 7d18h v1.21.0 kubeadm02 Ready <none> 7d18h v1.21.0
トークンの作成
[root@kube01 ~]# kubeadm token list #何も表示されなかった場合、createを実施 [root@kube01 ~]# kubeadm token create a2fybd.2j7fvqa71urarpl2
ca-certのハッシュ値確認
[root@kube01 ~]# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \ > openssl dgst -sha256 -hex | sed 's/^.* //' 4ea2ed8b2642a06bcf4f9117e33b590b9d5e3209ba5ba2aec3e9e5326fe179c8
ipアドレスの確認
[root@kube01 ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens192: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 00:50:56:8d:c4:88 brd ff:ff:ff:ff:ff:ff inet 192.168.1.249/24 brd 192.168.1.255 scope global noprefixroute ens192 valid_lft forever preferred_lft forever inet6 fe80::b56b:899e:2c88:ab13/64 scope link noprefixroute valid_lft forever preferred_lft forever …
kubeadm03でkubeadm joinの実行(デフォルトの<control-plane-port>は6443)
[root@kubeadm03 ~]# kubeadm join --token a2fybd.2j7fvqa71urarpl2 192.168.1.249:6443 --discovery-token-ca-cert-hash sha256:4ea2ed8b2642a06bcf4f9117e33b590b9d5e3209ba5ba2aec3e9e5326fe179c8 [preflight] Running pre-flight checks [preflight] Reading configuration from the cluster... [preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml' [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env" [kubelet-start] Starting the kubelet [kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap... This node has joined the cluster: * Certificate signing request was sent to apiserver and a response was received. * The Kubelet was informed of the new secure connection details. Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
kubeadm03が追加されたことを確認
[root@kube01 ~]# k get nodes NAME STATUS ROLES AGE VERSION kube01 Ready control-plane,master 7d18h v1.21.0 kubeadm02 Ready <none> 7d18h v1.21.0 kubeadm03 NotReady <none> 7s v1.21.0 [root@kube01 ~]# k get nodes NAME STATUS ROLES AGE VERSION kube01 Ready control-plane,master 7d18h v1.21.0 kubeadm02 Ready <none> 7d18h v1.21.0 kubeadm03 Ready <none> 13s v1.21.0