概要
devops-cd之vagrant virtualbox實戰
https://www.yuque.com/wushifengcn/kb/qo3kmu
這篇文章講解和示范了vagrant自動化virtualbox的情況
在vmware跨機器和docker場景下如下使用呢,本文總結下
- vmware esxi
- 通過vagrant操控
- 通過terraform操控
- docker
- docker-compose
- docker swarm
名詞
Vmware 服務器虛擬化第一個產品叫ESX,該產品只有60天測試,沒有官方認可的免費版。后來Vmware在4版本的時候推出了ESXI,ESXI和ESX的版本最大的技術區別是內核的變化,ESXI更小,更安全,從其他方面來說ESXI可以在網上申請永久免費的license,但是兩個版本的收費版功能是完全一樣的。
從4版本開始VMware把ESX及ESXi產品統稱為vSphere,但是VMware從5版本開始以后取消了原來的ESX版本,所以現在來講的話vSphere就是ESXI,只是兩種叫法而已。一般官方文檔中以稱呼vSphere為主。
- ESXi Free版被更名為VMware vSphere Hypervisor
- vSphere的免費產品名字叫vSphere Hypervisor,而收費產品有各個版本,包括Essentials,Standard,Enterprise和Enterprise Plus。
- vCenter Server則是另外一個獨立產品,用於集中式管理vSphere環境。
【 VMware ESX 和 VMware ESXi 都是直接安裝在服務器硬件上的裸機管理程序】
ESXI上部署
軟件可以在官方下載
具體的esxi server可以通過WEB瀏覽器進行管理
下面我們關注的是遠程的自動化操作,vagrant和terrafom都可以來操控,可以根據自己的熟悉程度和自己的團隊的技術棧來選擇
vagrant操控
#
vagrant plugin list | grep vagrant-vmware-esxi || {
vagrant plugin install --plugin-clean-sources --plugin-source https://gems.ruby-china.com/ --debug vagrant-vmware-esxi
}
vagrant box list|grep 'centos7.4_vmware' || {
vagrant init centos7.4_vmware "http://cloud.centos.org/centos/7/vagrant/x86_64/images/CentOS-7-x86_64-Vagrant-1708_01.VMwareFusion.box"
#導入后在 ~/.vagrant.d/boxes/centos7.4_vmware/0/vmware_desktop 可以看到虛擬機文件
}
# 修改Vagrantfile后執行即可遠程部署和啟動我們設置的虛擬機vagrant up --provider=vmware_esxi
vagrant up
Vagrantfile的vmware_esxi插件語法和例子參考如下
https://hub.fastgit.org/josenk/vagrant-vmware-esxi
https://hub.fastgit.org/josenk/vagrant-vmware-esxi/tree/master/example_box
設置好Vagrantfile后,即可使用vagrant的命令語法來操控了
terraform操控
https://registry.terraform.io/providers/hashicorp/vsphere/latest terraform官方針對vsphere的操作說明是針對大多是針對vcenter進行操作,有的也可以直接在esxi server上執行執行,如果安裝vcenter有些復雜
我們選這一個比較簡潔的方式,社區的一個實現https://hub.fastgit.org/josenk/terraform-provider-esxi
【注意這個依賴於
- ovftool from VMware.
安裝 Vmare workstation 后直接有這個工具 【或者https://code.vmware.com/web/tool/4.4.0/ovf 下載,VMware-ovftool-4.4.1-16812187-lin.x86_64.bundle 】
- You MUST enable ssh access on your ESXi Server
terraform配置文件main.tf
variable "vm_name" {
description = "VM to be created's name"
default = "testvm"
}
variable "vcpus" {
description = "VM to be created's Cpu count"
default = "1"
}
variable "memsize" {
description = "VM to be created's memory[mb]"
default = "1024"
}
variable "state" {
description = "VM state[on / off]"
default = "on"
}
terraform {
required_version = ">= 0.13"
required_providers {
esxi = {
source = "josenk/esxi"
version = "1.8.1"
}
}
}
#esxi server的信息
provider "esxi" {
esxi_hostname = "192.168.80.201"
esxi_hostport = "22"
esxi_hostssl = "443"
esxi_username = "root"
esxi_password = "Root123!"
}
resource "esxi_guest" "vmtest" {
guest_name = var.vm_name
disk_store = "datastore1"
power = var.state
numvcpus = var.vcpus
memsize = var.memsize
#准備部署的ova文件,這個提前准備好
ovf_source = "./ovaexp/vmtest.ova"
network_interfaces {
virtual_network = "VM Network"
# mac_address =
# nic_type = "e1000"
}
}
output "ip" {
value = esxi_guest.vmtest.ip_address
}
部署腳本vm.sh
執行如下的內容,即可動態的建立一個虛擬機了【由於josenk/esxi這個provider不能直接設置ip,因此腳本中換了種方式使用ansible進行設置】
#!/bin/bash
set -xeuo pipefail
BaseDir=$(cd "$(dirname "$0")"; pwd)
cd ${BaseDir}
#原始的IP和需要改變成的IP
#192.168.80.100
RIP=192.168.80.100 #inventory的地址和這個一樣
NAME=${1-TEST}
VCPUS=${2-1}
MEMSIZE=${3-1024}
IP=${4-192.168.80.100}
echo "Create VM: ${NAME} ${VCPUS} ${MEMSIZE} ${IP}"
#1 通過terraform導入一個固定IP的虛擬機
#指定虛擬機名字、CPU個數、內存大小[MB]
terraform apply -auto-approve -var "vm_name=${NAME}" -var "vcpus=${VCPUS}" -var "memsize=${MEMSIZE}"
#2 如上固定的IP可用后,使用ansbile修改IP
# ova鏡像先期條件 ssh -o StrictHostKeyChecking=no -i ./id_rsa vagrant@192.168.80.100
[ "${IP}" = "${RIP}" ] || {
ansible all -i inventory -m ping
ansible all -i inventory -m replace -a "path=/etc/sysconfig/network-scripts/ifcfg-eth0 regexp=${RIP} replace=${IP}" -b
#修改后重啟下機器
terraform apply -auto-approve -var "vm_name=${NAME}" -var "vcpus=${VCPUS}" -var "memsize=${MEMSIZE}" -var "state=off"
terraform apply -auto-approve -var "vm_name=${NAME}" -var "vcpus=${VCPUS}" -var "memsize=${MEMSIZE}" -var "state=on"
}
#如上做完了,在這個虛擬機上可以自由發揮了
echo "done"
inventory文件內容
[ovfbase]
192.168.80.100
[ovfbase:vars]
# ansible_ssh_user ansible_ssh_pass
ansible_ssh_port=22
ansible_ssh_user=vagrant
ansible_ssh_private_key_file=./id_rsa.pub
host_key_checking=false
docker上部署
- 單機上
- 只是運行某個容器,直接命令行或者shell腳本即可
- 如果是多個容器並有依賴關系等比較復雜的設置,可以使用docker-compose
- 多機上
- docker swarm進行分布式部署【不過這個逐步淘汰了,k8s是目前更主流的形式】,但優點是比k8s簡單易用
docker-compose
docker-compose是在單機上進行容器編排的工具
在多機分布式式容器編排,docker公司提供的是swarm產品,目前主流的是k8s
docker-compose是python寫的程序,可以從這下載單個的打包執行文件,放入/usr/bin/下直接使用【 https://github.com/docker/compose/releases ,python方式的安裝方法pip install docker-compose】
docker-compose通過配置好的compose文件運行【compose文件中指定了運行的所有設置,默認讀取的文件名為docker-compose.yml】,compose文件語法
https://docs.docker.com/compose/compose-file/compose-file-v3/
從這個例子可以看到概貌
https://docs.docker.com/compose/compose-file/compose-file-v3/#compose-file-structure-and-examples
例子解釋
version: "3.9" compose的版本
services: 啟動的容器服務節,這個下面可以定義各種服務
redis: 定義一個服務
image: redis:alpine 容器鏡像名稱
ports: 提供服務的端口,也可以設置映射到host機器的端口
- "6379"
networks:使用的網絡
- frontend
deploy: swarm方式下的部署條件設置
replicas: 2
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
db:
image: postgres:9.4
volumes: 存儲卷設置
- db-data:/var/lib/postgresql/data 將docker的db-data卷映射到容器的/var/lib/postgresql/data目錄
networks:
- backend
deploy:
placement:
max_replicas_per_node: 1
constraints:
- "node.role==manager"
vote:
image: dockersamples/examplevotingapp_vote:before
ports:
- "5000:80"
networks:
- frontend
depends_on:
- redis
deploy:
replicas: 2
update_config:
parallelism: 2
restart_policy:
condition: on-failure
result:
image: dockersamples/examplevotingapp_result:before
ports:
- "5001:80"
networks:
- backend
depends_on:
- db
deploy:
replicas: 1
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
worker:
image: dockersamples/examplevotingapp_worker
networks:
- frontend
- backend
deploy:#swarm集群下管理節點上【node.role==manager】部署1個實例,可彈性部署【replicated】
mode: replicated
replicas: 1
labels: [APP=VOTING] #標簽用於分類和過濾等,k8s中一個很關鍵的屬性
restart_policy:
condition: on-failure
delay: 10s
max_attempts: 3
window: 120s
placement:
constraints:
- "node.role==manager"
visualizer:
image: dockersamples/visualizer:stable
environment: #部署主機的主機名hostname
- node.name=visualizer
ports:
- "8080:8080"
stop_grace_period: 1m30s
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
placement: #swarm集群下僅在管理節點部署這個容器
constraints:
- "node.role==manager"
networks: 網絡設置,如下設置了2個網絡,網絡的配置使用默認
frontend:
backend:
volumes: 卷配置
db-data:
大體的邏輯關系:
frontend網絡中
redis容器:redis 6379服務
vote容器:依賴於redis容器,80服務,映射到主機的端口是5000
backend網絡
db容器:postgres 服務,持久化數據到db-data卷
result容器:依賴於db, 80服務端端口,映射到主機的端口是5001
跨越frontend backend網絡
worker容器:
默認的docker網絡:
visualizer容器: 8080服務端端口,映射到主機的端口是8080
常用命令
- 啟動
- 服務方式:
- docker-compose up -d:容器不存在創建並運行
- docker-compose start: 容器已經存在時運行
- 阻塞方式:docker-compose up
- 指定某個配置運行:docker-compose -f docker-composeV3.yml up
- 停止
- docker-compose down: Stop and remove containers, networks, images, and volumes
- docker-compose stop: Stop services
- 清理
- docker-compose rm
docker常用運行例子
- docker run --rm/-itd -v $PWD:/rally --name rally --network host dev.docker:8085/elastic/rally:2.0.0 --track=nyc_taxis --test-mode --pipeline=benchmark-only --target-hosts=localhost:9200
- --rm/-itd:--rm運行后直接刪除容器; itd 服務方式運行容器
- -v $PWD:/rally: 將當前目錄掛載到容器的/rally目錄下,作為存放數據目錄使用
- --name rally:執行容器的名字,這樣docker exec之類的方便使用
- --network host:直接使用主機的ip地址
- dev.docker:8085/elastic/rally:2.0.0:鏡像的名稱和版本
- --track=nyc_taxis... :運行是傳遞的參數,這個是和容器內啟動程序配合的,如果直接寫bash/sh之類,那就會啟動個shell
- docker exec -uroot -it rally sh
- 已經運行的容器,以root用戶shell登錄進去
- docker logs rally -f
- 查看運行的rally容器的輸出日志
https://developer.aliyun.com/article/783289?spm=a2c6h.12883283.1362932.3.5f1f201cdosA8U 《AI開發者的Docker實踐》這個電子書可以參考
Tip
- 多容器間主機名的通訊
- 在同一個網絡的容器可以直接通過主機名【或容器名】通訊,docker內部相當於有個dns,直接解析成了ip
- docker的數據存儲
- 數據不要在容器內直接存儲,因此容器的格式是aufs,效率沒有ext等文件系統高
- 數據一般使用docker建立卷或者映射主機的目錄,具體有如下幾種
- docker volume命令建立的卷
- -v 映射主機的數據目錄掛載到容器的卷
- 在容器內使用nfs之類遠程掛載
- host主機ip幫助
- docker-compose -h
- docker-compose help up ....
- docker-compose中變量使用
- 啟動時設置變量 export ELASTIC_VERSION=7.9.0
- compose文件中引用
- image: dev.docker:8085/kibana:${ELASTIC_VERSION:-7.8.0}
- 容器內的服務提供服務
- 容器想提供服務,需要首先確保容器內對應的服務進程的正常
- 服務端口需要暴露,expose
- 對外提供服務
- 方式1:使用容器的:ip+端口
- 方式2:設置端口映射,使用:host主機ip+映射端口
- 方式3:僅在網絡模式設置了host模式時,使用:host主機ip+expose端口
- 【方式1,2如果對其他的主機提供服務還需要一些特別的設置,方式3其他主機可以直接訪問這個服務;服務的診斷curl tcpdump工具很重要】
- docker的鏡像
- Dockerfile文件的約定 https://docs.docker.com/engine/reference/builder/
- 自己做鏡像是,鏡像大小需要注意下,這個有較多的優化技巧【當然如果只是局域網內部用,大小不受限的話就無所謂】
- docker鏡像被牆了
- 方式1:使用vpnFQ下載
- 方式2:使用阿里雲容器服務或者github上進行海外構建方式,可以規避這個問題【執行查找docker海外構建】
- 容器的資源如何限制
- cpu 、內存等都是可以設置的,具體參考官方文檔,命令行和compose文件都可以設置
- 容器和HOST主機如何傳遞數據文件
- 方式1:基於sftp相互拷貝【需要容器配置好ssh服務並開啟sftp】
- 方式2:使用docker cp FILES containerName:FILES 互相拷貝
- 方式3:使用共享的卷傳遞,docker運行時-v指定的共享目錄
- 容器運行數據如何清理
- 運行相關的數據涉及 network volume container system【這個包含了前面3個】,清理這些數據時這些數據資源不能正在使用,其中volume這個需要慎重,這是程序運行保存的數據,需要做好備份
- 使用方法類似:docker system prune -f
- 容器的資源使用情況如何監控
- 在容器內執行top看到的數據不是容器的數據,監控需要使用類似
- 容器內運行:ctop
- HOST機器上運行:cadvisor、metricbeat、docker stats 命令行查看
- 在HOST主機上如何自動運行容器內的腳本等執行文件
- 類似: docker exec -it radius sh "apk add freeradius-client",權限不對的可以增加-u username 參數
參考
devops-hasicorp產品圖 https://www.yuque.com/wushifengcn/kb/bbvrtw
devops-cd之esxi和docker實戰 https://www.yuque.com/wushifengcn/kb/tyy1r6
devops-cd之vagrant virtualbox實戰 https://www.yuque.com/wushifengcn/kb/qo3kmu