3

虚拟化、容器化是这几年来十分流行的一个理念,它使用“隔离”的手段,将不同服务的依赖、配置等隔离开来,
大大降低了管理成本及维护负担。
vagrant是一款抽象层次更高的虚拟环境配置工具,基于virtualbox或者docker。
通过配置文件定义虚拟环境的各项参数,之后vagrant就能自动帮你搞定这些繁琐事情。
接下来是不是该折腾下vagrant如何模拟集群、搞devops了?
No、No,我使用这把牛刀的最初目的是为了杀鸡,把它当一个方便的、自动化的linux虚拟机使用,哈哈。

<!-- more -->

沙盒环境

在平时的学习和折腾中,比如说看到了一个新鲜的东西,想搭建一个看看,把玩把玩。
这个时候,如果在自己的主系统中捣鼓各种不熟悉的应用和服务,
一来如果出问题可能会把系统搞炸,二来系统本身的复杂环境也会影响到服务和应用的搭建。

而且,把服务安装在自己的系统里,和把服务安装到远程主机上去,无论是ssh上去还是最终体验自己的成果,
那感觉是完全不一样的。所以,我需要:

  1. 一个完全隔离的沙盒环境,并且是一个完整的linux系统,就像一台远程的主机那样。
  2. 对一个买不起阿里云的码农来说,该虚拟环境能够给人一种是远程主机的错觉。

一个选择是virtualbox,但是初始的配置和安装很麻烦。并且要用virutlabox的命令行工具,有些麻烦。
所以,用vagrant解决这个问题。

vagrant

vagrant的安装

虽然debian的源里有vagrant,但是还是建议去官方网站下载安装最新版,老版本的vagrant有一些bug,在之前使用的时候就碰到过。使用命令:

sudo apt-get install virtualbox
wget https://releases.hashicorp.com/vagrant/2.1.4/vagrant_2.1.4_x86_64.deb
sudo dpkg -i vagrant_2.1.4_x86_64.deb

由于vagrant是virtualbox的前端,因此如果没有安装virtualbox的话,得先安装virtualbox。

安装一台虚拟机

执行命令:

mkdir ~/myproject && cd ~/myproject
vagrant init debian/contrib-jessie64
vagrant up # 下载box镜像并且安装

vagrant init命令会在本地目录中创建vagrantFile。打开这个文件,可以看到:

Vagrant.configure("2") do |config|
  config.vm.box = "debian/contrib-jessie64"
end

config.vm.boxdebian/contrib-jessie64,这项配置指定该虚拟机使用什么镜像初始化。
vagrant为我们预制了大量的丰富镜像,成为box。比如说,上面的debian/contrib-jessie64,那么在vagrant初始化的时候就会下载对应的镜像然后安装虚拟机。
更多box可以在这里找到:https://app.vagrantup.com/box...

好,当vagrant up执行成功时,虚拟机环境也就创建好了。
假如这个时候,打开virtualbox,你会发现实际上vagrant创建了一个virtualbox的虚拟机。

Vagrantfile文件

Vagrantfile中配置了虚拟机的各项基本参数。

网络配置

首先是虚拟机网络,和virtualbox一样,它有三种类型的网络:

  1. NAT映射。
  2. host-only。
  3. 桥接。

vagrant默认为在NAT映射,虚拟机是在一个私有网络内部,并且通过NAT方式访问外网。
这种方式主机是看不到虚拟机的,因此,需要配置端口映射:

config.vm.network "forwarded_port", guest: 80, host: 8080

这样,虚拟机的80端口就被映射为主机的8080端口。

第二种方式,私有网络,配置如下:

config.vm.network "private_network", ip: "192.168.50.4"

虚拟机和主机在同一个私有网络内,主机和虚拟机能够互相访问。
但是,这个私有网络是被虚拟出来的,根本不连接外网,所以虚拟机无法访问外网。
当然,从网络的角度来看,主机也在这个私有网络里,而且主机能够连接外网。
理论上可以通过配置将主机作为跳板(将私有网络网卡和真实网卡桥接),让这个私有网络内的虚拟机也能访问网络。

第三钟方式,桥接网络:

config.vm.network "public_network" # DHCP获取ip
config.vm.network "public_network", ip: "192.168.0.17" # 静态ip
config.vm.network "public_network", bridge: "en1: Wi-Fi (AirPort)" # 指定桥接网卡

桥接网络即将虚拟机置入和主机同一网络内。假如主机通过无线网卡连接了自己的wifi,那么虚拟机就像一台真实机器一样也连接到了这台wifi,有该wifi网络的ip地址。

可以按照自己的需要选择。比如我,想催眠自己把这台虚拟机想象成远程的服务器,就使用第三种方式,然后给个主机名,通过主机名访问里面的服务。

共享文件夹

默认vagrant已经将存放vagrantfile文件的目录映射到虚拟机的/vagrant下。
当然,也可以自己配置添加更多的目录:

config.vm.synced_folder "src/", "/srv/website"

主机名

config.vm.hostname = "myserver"

主机名不仅用于网络,当有多台虚拟机时,也用来标记区分不同的虚拟机。

内存和CPu

默认是512M,如下配置修改:

config.vm.provider "virtualbox" do |v|
  v.memory = 1024
  v.cpus = 2
end

vagrant使用

好了,当配置完Vagrantfile文件后,使用vagrant reload命令重新使之生效。
vagrant up启动虚拟机,vagrant halt命令关闭虚拟机,vagrant status查看运行状态。vagrant destory删除虚拟机。
最重要的是,vagrant sshssh到虚拟机上去。

docker和docker-compose的安装

好了,现在我假象的远程服务器已经搭建安装完毕了。
接下来,开始在服务器上安装些有趣的服务了。

先是安装docker:

sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates \
     curl gnupg2 software-properties-common
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo apt-key add -
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/debian \
   $(lsb_release -cs) \
   stable"
sudo apt-get update
sudo apt-get install docker-ce

Docker Compose是docker的一个辅助工具,可以将一组docker的配置、启动参数等写入到配置文件里去,然后通过docker compose管理。

安装docker-compose,这个工具是python编写的,因此pip安装它:

pip install docker-compose

docker安装nginx

由于使用的是docker-compose,安装nginx十分方便,全部配置文件化。
首先在本地新建一个目录,所有与nginx有关的配置文件都放在这里:

mkdir nginx
cd nginx

然后,编辑docker-compose.yml文件:

# vim: set shiftwidth=2 tabstop=2 softtabstop=-1 expandtab:
version: '2'
services:
  nginx:
    image: nginx:stable-alpine
    network_mode: host
    volumes:
      - ./conf:/etc/nginx
      - ./html:/var/www/html
      - ./log:/var/log/nginx
    ports:
      - "80:80"
    environment:
      - NGINX_HOST=your.domain
      - NGINX_PORT=80

其中,nginx:stable-alpine为选择的docker镜像,在第一次启动时,会自动下载镜像并创建docker容器。

在这里,docker镜像不存储任何的状态信息,镜像内的服务所有会读写的文件目录,都映射到了主机的文件系统来。

之后,执行docker-compose up来初始化容器。此外:

  1. 如果修改了docker-compose.yml,也是执行该命令重新创建容器。
  2. 该命令会同时会在前台启动容器并打印容器内的控制台日志,方便查看是否启动成功。

切记容器内部不存放状态,所有的文件系统读写都要映射出来,以防丢失。

之后,还需要配置nginx的配置文件,从docker-compose.yml可以看到,
配置文件放在了./conf中。我是直接从原生安装的nginx的配置文件中直接拷贝过来的一份。
当一切都配置好后,使用docker-compose start启动服务。之后,使用docker ps就能够看到运行中的服务了。使用docker-compose stop停止服务。

可以看到,使用docker将nginx容器化后,不仅运行实例和整个系统隔离,
而且,nginx的相关的所有配置可以全部存放在一个局部目录内。甚至还可以直接提交到git上去。
在另外一台机器,无论环境如何,只要安装了docker和docker-compose,就能从这些配置文件中docker-compose up一下,快速创建并部署nginx服务。

docker安装redis

通过docker部署redis也是十分简单,不用纠结版本和依赖及配置的问题。

首先是dokcer-compose.yml文件:

# vim: set shiftwidth=2 tabstop=2 softtabstop=-1 expandtab:

version: '2'
services:
  redis:
    image: redis:4.0.5-alpine
    network_mode: host
    volumes:
      - ./data:/data
    ports:
      - "6379:6379"
    command: [redis-server, '--appendonly', 'yes']

好了,之后docer-compose up初始化,docker-compose start即可启动。

最后

有了vagrant,我就在本地拥有了一个完全的、方便的linux沙盒环境,可以用来尝试各种新玩意,试验自己的新想法。

有了docker,我可以先将需要的服务在本地配置、调试好。由于docker的隔离性,所以只要本地的docker配置和服务配置无误,那么就能够用这些配置直接快速的在远程服务器上部署。

之后有时间,我准备将我在一台国外vps的小水管上的服务,将其配置抽取为一组配置文件,之后使用这组配置文件,以后无论在那台vps上都能快速部署。


frapples
253 声望9 粉丝

热爱编程的geek一枚!