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


ansible kubectl connection plugin

ansible是目前業界非常火熱的自動化運維工具。ansible可以通過ssh連接到目標機器上,從而完成指定的命令或者操作。
在kubernetes集群中,因為並不是所有的服務都是那么容器化。有時候也會用到ansible進行一些批量運維的工作。
一種方式是可以在容器中啟動ssh,然后再去連接執行。但是並不是所有的容器都會啟動ssh。

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

安裝使用

ansible 2.5后內置了該connection plugin,所以之后的版本都可以自動支持。如果是之前的版本,需要自行合並該PR。

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

該connection plugin需要使用kubectl的二進制文件,務必將kubectl先進行安裝,一般可以放置在/usr/bin下。

操作樣例

以下是一個inventory的配置。

[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的連接插件。

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

在inventory配置完成后,即可進行ansible的操作了。這里我們查看一下當前的工作目錄。

[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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM