上一篇我們簡單的說到了使用jenkins+supervisor實現了一個單機版的多副本部署,但是在更多的場景下還是需要netcore程式的多機一鍵部署,那麼多
機器間如何分發呢? 肯定不能使用scp這麼低階別的命令,所以你的技術棧中要引進ansible,用它來實現這個功能不要太爽。
一:ansible部署
ansible是一個自動化運維工具,實現方法就是在主控機上通過ssh免祕鑰的方式自動分發你的程式到多臺機器上,所以第一步你要配置主控機到遠端機
的ssh免祕鑰登陸。我這裡有兩臺機器:
10.25.198.96 【主控機】
10.25.59.59 【遠端機】
大概的一個簡圖就是這樣。
1. 免密登陸
[root@localhost ~]# ssh-keygen -t rsa -P '' Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created directory '/root/.ssh'. Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: 40:72:cc:f4:c3:e7:15:c9:9f:ee:f8:48:ec:22:be:a1 root@localhost.localdomain The key's randomart image is: +--[ RSA 2048]----+ | .++ ... | | +oo o. | | . + . .. . | | . + . o | | S . . | | . . | | . oo | | ....o... | | E.oo .o.. | +-----------------+ [root@localhost ~]# ls /root/.ssh/id_rsa /root/.ssh/id_rsa [root@localhost ~]# ls /root/.ssh id_rsa id_rsa.pub [root@localhost ~]# scp /root/.ssh/id_rsa.pub root@10.25.59.59:/root/.ssh/authorized_keys root@10.25.59.59's password: id_rsa.pub 100% 408 0.4KB/s 00:00 [root@localhost ~]# cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys
2. 安裝ansible
因為ansible是python寫的,通常有兩種安裝方式:yum 和 pip install 。 我這裡就採用yum安裝,安裝完成之後,直接鍵入ansible命令如下:
[root@localhost ~]# ansible ERROR! Unexpected Exception, this is probably a bug: (cryptography 0.8.2 (/usr/lib64/python2.7/site-packages), Requirement.parse('cryptography>=1.1')) the full traceback was:
可以看到上面報錯了,如果你不瞭解python,還是有點頭疼的,上面說的是你的cryptography包版本太低,需要安裝>=1.1的,你可以到pipy上down一個
新包下來。 https://pypi.org/project/cryptography/2.5/
對了,如果你的pip也沒裝的話,那你還是先通過yum install pip吧。
[root@localhost ~]# pip install cryptography==2.5 DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7. Collecting cryptography==2.5 Downloading https://files.pythonhosted.org/packages/17/fd/4c2c8953a9dfe38fbe0c3adafb6355540bd98cef70cc82734acb0a4c0e2f/cryptography-2.5-cp27-cp27mu-manylinux1_x86_64.whl (2.4MB) 100% |████████████████████████████████| 2.4MB 14kB/s Collecting cffi!=1.11.3,>=1.8 (from cryptography==2.5) Downloading https://files.pythonhosted.org/packages/14/dd/3e7a1e1280e7d767bd3fa15791759c91ec19058ebe31217fe66f3e9a8c49/cffi-1.11.5-cp27-cp27mu-manylinux1_x86_64.whl (407kB) 100% |████████████████████████████████| 409kB 15kB/s Requirement already satisfied: six>=1.4.1 in /usr/lib/python2.7/site-packages (from cryptography==2.5) (1.9.0) Collecting ipaddress; python_version < "3" (from cryptography==2.5) Downloading https://files.pythonhosted.org/packages/fc/d0/7fc3a811e011d4b388be48a0e381db8d990042df54aa4ef4599a31d39853/ipaddress-1.0.22-py2.py3-none-any.whl Collecting asn1crypto>=0.21.0 (from cryptography==2.5) Downloading https://files.pythonhosted.org/packages/ea/cd/35485615f45f30a510576f1a56d1e0a7ad7bd8ab5ed7cdc600ef7cd06222/asn1crypto-0.24.0-py2.py3-none-any.whl (101kB) 100% |████████████████████████████████| 102kB 34kB/s Requirement already satisfied: enum34; python_version < "3" in /usr/lib/python2.7/site-packages (from cryptography==2.5) (1.0.4) Requirement already satisfied: pycparser in /usr/lib/python2.7/site-packages (from cffi!=1.11.3,>=1.8->cryptography==2.5) (2.14) Installing collected packages: cffi, ipaddress, asn1crypto, cryptography Found existing installation: cffi 0.8.6 Uninstalling cffi-0.8.6: Successfully uninstalled cffi-0.8.6 Found existing installation: cryptography 0.8.2 Uninstalling cryptography-0.8.2: Successfully uninstalled cryptography-0.8.2 Successfully installed asn1crypto-0.24.0 cffi-1.11.5 cryptography-2.5 ipaddress-1.0.22
再輸入ansbile如果沒有報錯那就恭喜你搞定了,否則的話還是迭代迴圈吧。
[root@localhost ~]# ansible Usage: ansible <host-pattern> [options] Define and run a single task 'playbook' against a set of hosts
3. ansible簡單介紹
安裝好了ansible之後,在/etc/ansible目錄下會有三個檔案,如下:
[root@localhost ~]# cd /etc/ansible [root@localhost ansible]# ls ansible.cfg hosts roles
《1》 ansible.cfg
這個是ansible自身的config檔案,預設就這樣,我們暫不管。
《2》 hosts
這裡面配置的就是ansible要操控的遠端機器,比如我在末尾加上的10.25.59.59 和 10.25.198.96 兩臺我要分發的機器。
# This is the default ansible 'hosts' file. # # It should live in /etc/ansible/hosts # # - Comments begin with the '#' character # - Blank lines are ignored # - Groups of hosts are delimited by [header] elements # - You can enter hostnames or ip addresses # - A hostname/ip can be a member of multiple groups # Ex 1: Ungrouped hosts, specify before any group headers. ## green.example.com ## blue.example.com ## 192.168.100.1 ## 192.168.100.10 # Ex 2: A collection of hosts belonging to the 'webservers' group ## [webservers] ## alpha.example.org ## beta.example.org ## 192.168.1.100 ## 192.168.1.110 # If you have multiple hosts following a pattern you can specify # them like this: ## www[001:006].example.com # Ex 3: A collection of database servers in the 'dbservers' group ## [dbservers] ## ## db01.intranet.mydomain.net ## db02.intranet.mydomain.net ## 10.25.1.56 ## 10.25.1.57 # Here's another example of host ranges, this time there are no # leading 0s: ## db-[99:101]-node.example.com [memsql-test] 10.25.59.59 10.25.198.96
《3》 roles
一般來說ansible推薦都是以role模板格式作為playbook來實現非常強大的功能,比如這個地方:https://galaxy.ansible.com/ 都是一些供你學習的role模板。
4. 編寫playbook
《1》 deploy.yaml
--- - hosts: all remote_user: root vars: inifile: "memsql-test" program: "MemSql.Test" workspace: "/var/lib/jenkins/workspace/{{ program }}/MemSql.NetCore/{{ program }}/bin/Release/netcoreapp2.1/publish/" tasks: - name: 1. directory publish files copy: src: "{{ workspace }}" dest: "/data/output/{{ program }}" - name: 2. copy *.ini file for supervisor copy: src: "{{ workspace }}/doc/{{ inifile }}.ini" dest: /data/supervisor/conf/ - name: 3. supervisord file supervisorctl: name: memsql-test state: restarted supervisorctl_path: /usr/bin/supervisorctl config: /data/supervisor/supervisord.conf
這個配置檔案大概是什麼意思呢?
《1》 hosts: memsql-test 表示要操作memsql-test組下的所有主機,還記得你在hosts中配置的ip地址嗎?
《2》 remote_user: root 告訴你遠端操控的角色是什麼。
《3》 vars 定義一些變數,方便後面少些一些重複的程式碼。
《4》 tasks: 定義一些按順序執行的Action
《5》 name: 某一個action動作的描述
copy: copy命令,這個算是ansible的模組了,具體參見:https://docs.ansible.com/ansible/latest/modules/copy_module.html
supervisorctl: 這個ansible整合了supervisor,挺好的,具體參見:https://docs.ansible.com/ansible/latest/modules/supervisorctl_module.html
三:ansible 和 jenkins 整合
在我的doc資料夾下有三個檔案,方便jenkins在指令碼執行的時候獲取相關檔案。
《1》 deploy.yaml 這個就是上面介紹的
《2》 entrypoint.sh 這個指令碼是準備copy到jenkins的command命令框中
cd ./MemSql.NetCore/MemSql.Test \ && dotnet publish -c Release \ && ansible-playbook ./doc/deploy.yaml
《3》 memsql-test.ini 如果看過上一篇,那這個就不介紹了
[program:memsql-test] command=/usr/bin/dotnet /data/output/MemSql.Test/MemSql.Test.dll autostart=false autorestart=true stdout_logfile=/data/output/MemSql.Test/1.log
《4》 最後就是一個簡單的program.cs
class Program { static void Main(string[] args) { var cts = new CancellationTokenSource(); var bgtask = Task.Run(() => { for (int i = 0; i < int.MaxValue; i++) { Log.Info($"當前index={i}, 時間為:{DateTime.Now}"); Thread.Sleep(new Random().Next(1000, 3000)); } }); Log.Info($"{DateTime.Now} Test 後端服務程式正常啟動!"); Console.WriteLine($"{DateTime.Now} Test 後端服務程式正常啟動!"); bgtask.Wait(); } }
《5》 在jenkins中執行一下, 當然你也可以使用jenkins的ansible外掛,簡單的話用指令碼也可以。
點選jenkins構建之後,就可以看到console介面中 playbook的指令碼在跑了。
然後你到兩臺機器都驗證一起,process可是起來了。
[root@10-25-59-59 ~]# ps -ef | grep dotnet root 22949 1371 0 11:28 ? 00:00:01 /usr/bin/dotnet /data/output/MemSql.Test/MemSql.Test.dll root 26337 18477 0 11:45 pts/0 00:00:00 grep --color=auto dotnet [root@10-25-198-96 ~]# ps -ef | grep dotnet root 4831 21660 6 11:45 ? 00:00:00 /usr/bin/dotnet /data/output/MemSql.Test/MemSql.Test.dll
好了,本篇就說到這裡,希望對你有幫助。