使用ansible kubectl插件鏈接kubernetes pod以及實現原理

ansible kubectl connection plugin

ansible是目前業界很是火熱的自動化運維工具。ansible能夠經過ssh鏈接到目標機器上,從而完成指定的命令或者操做。
在kubernetes集羣中,由於並非全部的服務都是那麼容器化。有時候也會用到ansible進行一些批量運維的工做。
一種方式是能夠在容器中啓動ssh,而後再去鏈接執行。可是並非全部的容器都會啓動ssh。html

針對於這種狀況,我想到了直接用kubectl進行鏈接操做,所以開發了kubectl的connection插件,並貢獻給了社區。
該功能無需容器中啓動ssh服務便可使用,已經合入ansible的主幹,自ansible 2.5版本後隨ansible發佈。
詳細操做文檔能夠參考https://docs.ansible.com/ansible/latest/plugins/connection/kubectl.html。本文將對其主要功能和設計的思路原理進行一下介紹。python

安裝使用

ansible 2.5後內置了該connection plugin,因此以後的版本均可以自動支持。若是是以前的版本,須要自行合併該PR。git

PR參考:https://github.com/ansible/ansible/commit/ca4eb07f46e7e3112757cb1edc7bd71fdd6dacad#diff-12d9b364560fd0bec5a1cee5bd0b3c24。github

該connection plugin須要使用kubectl的二進制文件,務必將kubectl先進行安裝,通常能夠放置在/usr/bin下。sql

操做樣例

如下是一個inventory的配置。docker

[root@f34cee76e36a kubesql]# cat inventory 
[kube-test:vars]
ansible_connection=kubectl
ansible_kubectl_kubeconfig=/etc/kubeconfig
[kube-test]
hcnmore-32385abb-9f753dda-nxr8h ansible_kubectl_namespace=nevermore

對於kube-test組,ansible_connection=kubectl用於標識使用kubectl的鏈接插件。shell

ansible_kubectl_kubeconfig用於標識使用的kubeconfig的位置。固然,也支持使用無認證、使用用戶名密碼認證等等方式進行鏈接。這些配置能夠參考官網的說明: https://docs.ansible.com/ansible/latest/plugins/connection/kubectl.html#parameters運維

在inventory配置完成後,便可進行ansible的操做了。這裏咱們查看一下當前的工做目錄。ssh

[root@f34cee76e36a kubesql]# ansible -i inventory kube-test -m shell -a "pwd"     
hcnmore-32385abb-9f753dda-nxr8h | CHANGED | rc=0 >>
/

playbook樣例使用

該connection plugin一樣支持使用playbook對批量任務進行執行。如下是一個playbook的樣例。工具

- hosts: kube-test
  gather_facts: False
  tasks:
    - shell: pwd

咱們複用了先前樣例的inventory進行執行,同時打開-v進行觀察。

[root@f34cee76e36a kubesql]# ansible-playbook -i inventory playbook -v 
Using /etc/ansible/ansible.cfg as config file

PLAY [kube-test] *************************************************************************************************************************************************************************************************

TASK [shell] *****************************************************************************************************************************************************************************************************
changed: [hcnmore-32385abb-9f753dda-nxr8h] => {"changed": true, "cmd": "pwd", "delta": "0:00:00.217860", "end": "2019-03-18 20:55:39.479859", "rc": 0, "start": "2019-03-18 20:55:39.261999", "stderr": "", "stderr_lines": [], "stdout": "/", "stdout_lines": ["/"]}

PLAY RECAP *******************************************************************************************************************************************************************************************************
hcnmore-32385abb-9f753dda-nxr8h : ok=1    changed=1    unreachable=0    failed=0

能夠看到在目標機器上成功進行了命令執行。

優點與弊端

kubectl connection plugin不只支持命令的執行,其餘如cp文件、fetch文件等基本操做均可以執行。固然如執行shell、script腳本、密鑰管理等複雜操做也均可以經過這個插件進行執行。可是這些複雜操做有的須要目標機器上安裝python等環境進行支持,這個要根據不一樣模塊的需求具體來看。

使用openshift的插件oc的使用方式與kubectl相似,這裏不重複介紹了。

能夠說這個kubectl的插件能夠解決大部分的平常運維操做,可是也有一些弊端,就是使用kubectl的二進制進行鏈接。每次每一個鏈接都須要啓動一個進程進行kubectl執行,並且鏈接速度不快。所以不太適合大批量的容器高頻操做。

我我的的建議是能夠用這個插件進行注入密鑰、低頻啓停服務的運維操做。大批量的操做仍然最好使用ssh進行。

實現原理

ansible connection plugin

ansible的connection plugin有不少,目前支持的有ssh、docker、kubectl等等。要實現一個ansible的鏈接插件,其實主要實現的是三個接口:

  • exec_command: 在目標機執行一個命令,並返回執行結果。
  • put_file: 將本地的一個文件傳送到目標機上。
  • fetch_file: 將目標機的一個文件拉回到本地。

這三個接口對應三個原生的模塊,依次是raw,cp和fetch。而ansible的幾乎全部複雜功能,都是經過這三個接口來進行實現的。好比shell或者script,就是經過將腳本或者命令造成的腳本cp到目標機上,然後進行命令執行完成的。

kubectl exec

kubectl exec自然就是執行命令的。docker client 有cp的功能,可是kubectl並不具備(kubectl 1.5版本後也支持了cp)。這裏用了一個小的技巧,就是使用dd命令配合kubectl exec進行文件的傳輸和拉取。

所以要求目標容器中也要有dd命令,不然該插件也沒法工做。

dd主要用於讀取、轉換和輸出數據。咱們將一個src文件拷貝到另一個地方dest,可使用dd if=/tmp/src of=/tmp/dest。dd也支持從標準輸入中獲取數據或者輸出到標準輸出中。所以拷貝也就可使用dd if=/tmp/src | dd of=/tmp/dest的方法。

理解了這些,咱們就可使用kubectl來進行文件的傳輸了。那麼向容器中傳輸文件的方式就可使用 dd if=/tmp/src | kubectl exec -i podname dd of=/tmp/dest。反過來,從容器中拉取文件就對應可使用kubectl exec -i podname dd of=/tmp/src | dd of=/tmp/src

特別注意,向容器中傳輸文件的-i參數是必須的。由於須要用-i參數開啓支持kubectl從標準輸入中獲取數據。

這樣就經過kubectl exec,實現了執行命令、文件傳輸以及拉取的效果。對應在ansible的connection plugin中進行實現,便可使得kubernetes的pod容器也支持ansible的運維控制。具體實現代碼就再也不重複講述,詳細能夠參考https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/connection/kubectl.py

相關文章
相關標籤/搜索