Hero Image
Trellis Ansible 錯誤的解譯器

Trellis Ansible Bad Interpreter Error Bad Interpreter Error 使用 Ansible 時遇到錯誤的解譯器問題。找不到 Python 2.7: zsh: /usr/local/bin/ansible-vault: bad interpreter: /usr/local/opt/python@2/bin/python2.7: no such file or directory 這是正常的,因為我們檢查 /usr/local/opt 後只看到 Python 3。 安裝 Python 2 brew install python@2 Python 嚴重崩潰 接著在檢查 Ansible 版本時又出現錯誤: ➜ trellis git:(master) ansible --version [1] 19153 abort ansible --version 它在 Python 2.7 上崩潰了,但理論上應該可以正常執行。我決定升級 Ansible。 sudo pip install ansible --upgrade ..... Requirement already satisfied, skipping upgrade: six>=1.4.1 in /usr/local/lib/python2.7/site-packages (from cryptography->ansible) (1.11.0) Requirement already satisfied, skipping upgrade: pycparser in /usr/local/lib/python2.7/site-packages (from cffi>=1.7; platform_python_implementation != "PyPy"->cryptography->ansible) (2.18) Installing collected packages: ansible Found existing installation: ansible 2.7.5 Uninstalling ansible-2.7.5: Successfully uninstalled ansible-2.7.5 Successfully installed ansible-2.9.1 Still I had the Python error and iTerm was showing a MacOS popup that Python was crashing unexpectedly: Python quit unexpectedly. Click Reopen to open the application again. Click Report to see more detailed information and send a report to Apple. Application Specific Information: /usr/lib/libcrypto.dylib abort() called Invalid dylib load. Clients should not load the unversioned libcrypto dylib as it does not have a stable ABI. Invalid DyLib 找到 https://stackoverflow.com/questions/58272830/python-crashing-on-macos-10-15-beta-19a582a-with-usr-lib-libcrypto-dylib 這篇,知道是動態函式庫載入錯誤,於是決定安裝 openssl。

Hero Image
用 iptables 和 ip rule 做負載均衡

用 iptables 和 ip rule 做負載均衡 操作 這裡以一台透過有線 + 無線出口連線到網際網路的 Arch Linux 裝置為例。共有兩個出口,分別使用網卡 eth0 和 eth1。大致對應關係如下: 標記 10 (0xa) - 路由表 #110 - 使用 eth0 出口 標記 11 (0xb) - 路由表 #111 - 使用 eth1 出口 我們會根據封包上的標記值判斷它應該走哪個出口。首先,使用 ip rule 為每個標記值指定一張路由表。 通常預設路由表的權重是 32768。為了讓我們的路由表生效,需要將權重調高一些(例如 31000)。 # 讓帶標記 10 (0xa) 的封包使用 110 號路由表,權重 31000 ip rule add fwmark 10 table 110 prio 31000 # 讓帶標記 11 (0xb) 的封包使用 111 號路由表,權重 31000 ip rule add fwmark 11 table 111 prio 31000 # 如果你的連線更多,可以繼續新增標記 <-> 路由表的對應關係 # #110 路由表的路由 ip route add 10.20.0.0/24 dev eth0 table 110 ip route add default via 10.20.0.254 table 110 # #111 路由表的路由 ip route add 10.25.0.0/24 dev eth1 table 111 ip route add default via 10.25.0.254 table 111 # 如果這條連線已經被標記,將標記設定到封包上 iptables -t mangle -A OUTPUT -j CONNMARK --restore-mark # 如果封包已經有標記,直接放行 iptables -t mangle -A OUTPUT -m mark ! --mark 0 -j ACCEPT # 如果封包沒有被標記 # 把封包標記為 10 (0xa) iptables -t mangle -A OUTPUT -j MARK --set-mark 10 # 每 2 個封包就把一個封包標記為 11 (0xb) iptables -t mangle -A OUTPUT -m statistic --mode nth --every 2 --packet 0 -j MARK --set-mark 11 # 如果你有三條出口,這裡可以類似於 # iptables -t mangle -A OUTPUT -j MARK --set-mark 10 # iptables -t mangle -A OUTPUT -m statistic --mode nth --every 3 --packet 0 -j MARK --set-mark 11 # iptables -t mangle -A OUTPUT -m statistic --mode nth --every 3 --packet 1 -j MARK --set-mark 12 # 把封包的標記儲存到整條連線上,讓整個連線使用同一個出口 iptables -t mangle -A OUTPUT -j CONNMARK --save-mark # 讓封包的出口與我們選擇的一致 iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE 之後可以用 iptables -L OUTPUT -t mangle 看一下規則是否正確,再用 Wireshark 驗證連線是否真的分流。

Hero Image
Hero Image
Jenkinsfile 範例

Some Jenkinsfile examples 並行 #!/usr/bin/env groovy pipeline { agent any stages { stage("Build") { steps { sh 'mvn -v' } } stage("Testing") { parallel { stage("Unit Tests") { agent { docker 'openjdk:7-jdk-alpine' } steps { sh 'java -version' } } stage("Functional Tests") { agent { docker 'openjdk:8-jdk-alpine' } steps { sh 'java -version' } } stage("Integration Tests") { steps { sh 'java -version' } } } } stage("Deploy") { steps { echo "Deploy!" } } } } When #!/usr/bin/env groovy pipeline { agent any environment { VALUE_ONE = '1' VALUE_TWO = '2' VALUE_THREE = '3' } stages { // skip a stage while creating the pipeline stage("A stage to be skipped") { when { expression { false } //skip this stage } steps { echo 'This step will never be run' } } // Execute when branch = 'master' stage("BASIC WHEN - Branch") { when { branch 'master' } steps { echo 'BASIC WHEN - Master Branch!' } } // Expression based when example with AND stage('WHEN EXPRESSION with AND') { when { expression { VALUE_ONE == '1' && VALUE_THREE == '3' } } steps { echo 'WHEN with AND expression works!' } } // Expression based when example stage('WHEN EXPRESSION with OR') { when { expression { VALUE_ONE == '1' || VALUE_THREE == '2' } } steps { echo 'WHEN with OR expression works!' } } // When - AllOf Example stage("AllOf") { when { allOf { environment name:'VALUE_ONE', value: '1' environment name:'VALUE_TWO', value: '2' } } steps { echo "AllOf Works!!" } } // When - Not AnyOf Example stage("Not AnyOf") { when { not { anyOf { branch "development" environment name:'VALUE_TWO', value: '4' } } } steps { echo "Not AnyOf - Works!" } } } }