Contents
この投稿は vExperts Advent Calendar 2019 の7日目の記事です。
vExpert 2019 Second Half ApplicationからvExpertを頂き初めてvExpert Advent Calendarに投稿します。よろしくお願いします。
簡単な自己紹介ですが、私はAnsible界隈方面でワイワイやっている者でして趣味でAnsibleのモジュール(VMwareとか)を作ったりパッチ書いたりしてアップストリームにPRしたり、暇があればissue解決したりしています。
vExpertに申し込んだのは、NSXのAnsibleモジュールやVMwareのSDK話をVM meetup tokyoやVMware DevOps Meetupで話したときに@IrieMasahiroさんからvExpertのSecond Half Applicationがあるから挑戦してみたらどうでしょう?というのがきっかけで申し込んだらなんと頂けた(わーい:))と言うのが簡単な経緯になります。(あの時はありがとうございます)
それでは、今回のアドベントカレンダー用のネタですが以前のVMware DevOps Meetup #3で@masanaraさんが話をされていたk8sのオペレーターからVMをデプロイすると言う話を聞いて、「これはAnsibleと組み合わせたらOSのセットアップまで一貫して出来るのでは?」と思ったのでやってみようとおもいます 🙂
やりたいこと
ここでは、以下のことをやってみます。
- kindでクラスタを作る
- kindで作ったクラスタにkopf-operator-vmworldのオペレーターを起動
- Ansibleのモジュールを使って、マニフェストの実行およびVMクローン後のミドルウェア導入(Apacheを例にする)
- クローンしたVMはDHCPでIPが自動で割当たるようにします
- アクセス確認
環境
項目 | バージョン | 備考 |
---|---|---|
ESXi | 6.7.0 | |
vCenter | 6.7.0 | |
kind | 0.6.0 | |
CentOS | 7 | テンプレート、kindホスト |
Ansible | 2.9.1 | Python3.6を使う |
kindセットアップ
公式ドキュメント
インストール
必要なパッケージをインストールします。
1 2 |
[root@kind ~]# yum -y install docker |
dockerを起動します。
1 2 3 |
[root@kind ~]# systemctl start docker [root@kind ~]# systemctl enable docker |
kindをインストールします。
1 2 3 4 |
[root@kind ~]# curl -Lo ./kind https://github.com/kubernetes-sigs/kind/releases/download/v0.6.0/kind-$(uname)-amd64 [root@kind ~]# chmod +x kind [root@kind ~]# mv kind /usr/local/bin/ |
kubectlをインストールします。
1 2 3 4 |
[root@kind ~]# curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl [root@kind ~]# chmod +x kubectl [root@kind ~]# mv kubectl /usr/local/bin/ |
クラスタの作成
クラスタを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[root@kind ~]# kind create cluster Creating cluster "kind" ... ✓ Ensuring node image (kindest/node:v1.16.3) 🖼 ✓ Preparing nodes 📦 ✓ Writing configuration 📜 ✓ Starting control-plane 🕹️ ✓ Installing CNI 🔌 ✓ Installing StorageClass 💾 Set kubectl context to "kind-kind" You can now use your cluster with: kubectl cluster-info --context kind-kind Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community |
podの状態を確認します。
1 2 3 4 5 6 7 8 9 |
[root@kind ~]# kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-5644d7b6d9-7fhw9 1/1 Running 0 56s kube-system coredns-5644d7b6d9-rkblm 1/1 Running 0 56s kube-system etcd-kind-control-plane 1/1 Running 0 14s kube-system kindnet-5lwtl 1/1 Running 0 56s kube-system kube-apiserver-kind-control-plane 1/1 Running 0 17s kube-system kube-proxy-w2njn 1/1 Running 0 56s |
これで、k8sの準備は出来ました 🙂
オペレーターのセットアップ
インストール
必要なパッケージをインストールします。
1 2 |
[root@kind ~]# yum -y install git |
クローン
リポジトリをクローンします。
1 2 |
[root@kind ~]# git clone https://github.com/embano1/kopf-operator-vmworld |
オペレーターのDockerイメージ作成
controller.py
の一部を環境に合わせて修正します。
ここでは以下のように修正しています。
1 2 3 4 5 6 7 8 9 10 |
[root@kind ~]# cd kopf-operator-vmworld/ [root@kind kopf-operator-vmworld]# vi controller.py (snip) # hard-coded template settings to clone configuration TEMPLATE_FOLDER = "Templates" DATACENTER = "DC" CLUSTER = "Cluster" DATASTORE = "VM3" (snip) |
Dockerfile
の一部を環境に合わせて修正します。
ここでは以下のように修正しています。
また、追加パッケージ(gccとmusl-dev)が必要だったので追記します。
1 2 3 4 5 6 7 8 9 10 |
[root@kind kopf-operator-vmworld]# vi Dockerfile FROM python:3.7-alpine RUN apk add --no-cache git gcc musl-dev # ここにgccとmusl-devを追加 (snip) # vCenter username/password/host to be used by the operator ENV VC_USER=administrator@vsphere.local ENV VC_PASS=password ENV VC_HOST=192.168.0.210 (snip) |
イメージを作成します。
1 2 3 4 5 6 |
[root@kind kopf-operator-vmworld]# IMAGE=embano1/kopf-operator-vmworld:$(git rev-parse --short HEAD) [root@kind kopf-operator-vmworld]# docker build -t $IMAGE . (snip) Removing intermediate container ebb0c105bb70 Successfully built e076f80635b6 |
イメージが作成できているか確認します。
1 2 3 4 5 6 |
[root@kind kopf-operator-vmworld]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE embano1/kopf-operator-vmworld 1f859da e076f80635b6 23 seconds ago 245 MB docker.io/kindest/node v1.16.3 066d19ae6707 2 weeks ago 1.22 GB docker.io/python 3.7-alpine 8922d588eec6 2 weeks ago 98.4 MB |
CRDの作成
オペレーターが使うCRD(Custom Resource Definition)を作成します。
1 2 3 |
[root@kind kopf-operator-vmworld]# kubectl create -f deploy/crd.yaml customresourcedefinition.apiextensions.k8s.io/vmgroups.vsphere.vmware.com created |
CRDが作成されたか確認します。
1 2 3 4 |
[root@kind kopf-operator-vmworld]# kubectl get crd NAME CREATED AT vmgroups.vsphere.vmware.com 2019-12-01T14:59:30Z |
オペレーターの起動
オペレーターを起動します。
一先ず、動かすのが目的なので config
をコンテナから読めるようパーミッションを変更します。
1 2 3 |
[root@kind kopf-operator-vmworld]# chmod 666 /root/.kube/config [root@kind kopf-operator-vmworld]# docker run --name kopf-vsphere --network host -itd --rm -e KUBECONFIG=/home/kopf-operator/.kube/config -v ~/.kube:/home/kopf-operator/.kube $IMAGE |
Ansibleのセットアップ
インストール
必要なパッケージをインストールします。
1 2 3 |
# yum -y install epel-release # yum -y install python36 sshpass |
virtualenvを作成して有効化します。
1 2 3 4 |
[root@kind ~]# python3 -m venv venv [root@kind ~]# source venv/bin/activate (venv) [root@kind ~]# |
Ansibleをインストールします。
1 2 |
(venv) [root@kind ~]# pip install ansible |
モジュールのインストール
Ansibleのk8sモジュールを動作させるために必要なモジュールをインストールします。
1 2 |
(venv) [root@kind ~]# pip install openshift |
VMwareのモジュールを動作させるために必要なモジュールをインストールします。
1 2 |
(venv) [root@kind ~]# pip install pyvmomi |
Playbook作成
Operator経由でデプロイするVM処理とデプロイしたVMにApacheをインストールする処理をするPlaybookを作成します。
vcenter_auth_info
と guest_auth_info
の部分は環境に合わせて変更してください。
今回はrootでSSHログインするので guest_auth_info
にはゲストOSにログインする用のパスワードを記述しています。
1 2 |
(venv) [root@kind ~]# vi web_vm_deploy.yml |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
--- - name: Deploy vm using vSphere Operator hosts: localhost gather_facts: no vars: namespace: web-servers folder: web tasks: - name: Create a k8s namespace k8s: api_version: v1 kind: Namespace definition: metadata: name: "{{ namespace }}" labels: name: test state: present - name: Deploy web server VMs k8s: kind: VmGroup definition: apiVersion: vsphere.vmware.com/v1alpha1 metadata: name: "{{ folder }}" namespace: "{{ namespace }}" labels: name: test spec: cpu: 1 memory: 2 template: CentOS7_TMP replicas: 3 state: present - name: Gather VM information and add host hosts: localhost gather_facts: no vars: vcenter_auth_info: &vcenter_auth_info hostname: 192.168.0.210 username: administrator@vsphere.local password: secret validate_certs: no datacenter: DC folder: /vm/web guest_auth_info: &guest_auth_info ansible_user: root ansible_password: secret tasks: - name: Get vm basic info vmware_vm_info: <<: *vcenter_auth_info folder: "{{ datacenter }}/{{ folder }}" vm_type: vm retries: 60 delay: 5 until: - "'virtual_machines' in vm_info_result" register: vm_info_result - name: Wait for VMware tools to become available vmware_guest_tools_wait: <<: *vcenter_auth_info folder: "{{ folder }}" uuid: "{{ item.uuid }}" retries: 60 delay: 5 until: - "'instance' in vmware_tools_result" - vmware_tools_result.instance.guest_tools_status == "guestToolsRunning" - vmware_tools_result.instance.ipv4 is not none loop: "{{ vm_info_result.virtual_machines }}" loop_control: label: "{{ item.guest_name }}" register: vmware_tools_result - name: add hosts add_host: hostname: "{{ item.instance.hw_name }}" ansible_host: "{{ item.instance.ipv4 }}" ansible_port: 22 <<: *guest_auth_info groups: - web_servers loop: "{{ vmware_tools_result.results }}" loop_control: label: "{{ item.instance.hw_name }}" changed_when: no - name: Install apache and start hosts: web_servers gather_facts: no tasks: - name: install httpd yum: name: httpd state: latest - name: start httpd systemd: name: httpd state: started |
最後にPlaybookを実行します。
1 2 |
(venv) [root@kind ~]# ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook web_vm_deploy.yml |
ANSIBLE_HOST_KEY_CHECKING=False
にしているのはSSH接続時にホストキーチェックを無効にするためです。
デモ動画
実際にPlaybookを動かした時のデモ動画です。
Demo to deploy Web server using Ansible and vSphere Operation from sky_joker on Vimeo.
こんな感じでVMのデプロイからMWのインストール・起動が出来ました 🙂
最後に
将来(Project Pacific?)はこんな感じでVMやコンテナはマニフェストで定義してデプロイし、同時にVMのOS以上はAnsibleなどの自動化ツールで構築するようになっていくかもしれませんね 🙂
全てYAMLで管理する時代…うーん、慣れないとインデント地獄沼に落ちそうな気がしますw
後は同じYAMLでも宣言的と違ってAnsibleの冪統制は処理を書かないといけないので、そこの違いも慣れる必要があると思います。
今回は一つのPlaybookでまとめてしまいましたが、AWXやAnsible Towerを使ってPlaybookを分割しワークフローで組み合わせてあげれば使い回しができる構成にもできそうですね。
以上になります 🙂
明日は Kunihiro さんです!