教程目標(biāo)
Docker已經(jīng)上市很多年,不是什么新鮮事物了,很多企業(yè)或者開發(fā)同學(xué)以前也不多不少有所接觸,但是有實(shí)操經(jīng)驗(yàn)的人不多,本系列教程主要偏重實(shí)戰(zhàn),盡量講干貨,會根據(jù)本人理解去做闡述,具體官方概念可以查閱官方教程,本章目標(biāo)如下:
- 了解什么是Docker
- 了解Docker解決了什么
- 了解什么是鏡像和容器
- 了解容器與虛擬機(jī)的區(qū)別
- 了解Vagrant與Docker的區(qū)別
- 了解Docker引擎和架構(gòu)
- 了解Docker的鏡像分層
- 了解VirturalBox和Docker如何搭配使用
- 了解主體機(jī)器如何與客體機(jī)器上的容器進(jìn)行通信
- 了解Vagrant、VirtualBox、Docker搭建與基本操作
預(yù)備工作
因?yàn)槲沂荕ac用戶,所以這里VirturalBox和vagrant使用的是Mac版本,大家到官網(wǎng)各自下載對應(yīng)的系統(tǒng)版本即可,強(qiáng)烈建議使用迅雷下載!
- VirtualBox-6.0.14-133895-OSX.dmg
- Vagrant_2.2.6_x86_64.dmg
- Centos7鏡像
容器與虛擬化技術(shù)
什么是Docker
簡單來說Docker是一款可以將應(yīng)用程序與基礎(chǔ)設(shè)施分離、代碼及其所有依賴項(xiàng)打包,使應(yīng)用程序能夠從一個(gè)計(jì)算環(huán)境快速可靠地運(yùn)行到另一個(gè)計(jì)算環(huán)境,達(dá)到快速交付、測試、部署的容器化技術(shù)。
使用Linux容器部署應(yīng)用程序稱為容器化。
為什么要用Docker
我們可以反過來思考,不用Docker這些容器化技術(shù)會怎么樣,會遇到什么問題和瓶頸。
事例
想要發(fā)布一個(gè)應(yīng)用到測試、生產(chǎn)環(huán)境使用,都會經(jīng)歷以下流程:
物理機(jī)時(shí)代
每個(gè)團(tuán)隊(duì)會需要申請一臺物理機(jī)作為測試開發(fā)環(huán)境,進(jìn)行一系列的環(huán)境搭建
通過上圖可以看出直接使用物理機(jī)會存在一些問題
- 成本高 - 需要購買一臺實(shí)體機(jī)器,沒辦法共享
- 部署慢 - 發(fā)布一個(gè)應(yīng)用需要走漫長的流程
- 資源浪費(fèi) - 平時(shí)應(yīng)用實(shí)際用不到那么多物理資源,除了搞活動時(shí)期,大部分時(shí)候處于閑置狀態(tài),還有一部分資源被操作系統(tǒng)運(yùn)行程序占用
- 硬件限制 - 不同硬件廠商有兼容問題
- 不利于遷移擴(kuò)展 - 如果想遷移到其他服務(wù)器上,需要重頭打包配置應(yīng)用依賴
虛擬化時(shí)代
在虛擬化技術(shù)出現(xiàn)之后,每個(gè)團(tuán)隊(duì)只需要申請一臺虛擬機(jī),多臺虛擬機(jī)可以共享同一臺物理機(jī),大大降低了成本,一定程度上提升了資源利用率,當(dāng)公司搞活動時(shí)系統(tǒng)需要擴(kuò)展,只需要通過虛擬機(jī)鏡像創(chuàng)建多個(gè)虛擬機(jī)即可,提升了系統(tǒng)擴(kuò)展性和可用性
Hypervisor,又稱虛擬機(jī)監(jiān)視器(英語:virtual machine monitor,縮寫為 VMM),是用來建立與執(zhí)行虛擬機(jī)器的軟件、固件或硬件。
被Hypervisor用來執(zhí)行一個(gè)或多個(gè)虛擬機(jī)器的電腦稱為主體機(jī)器(host machine),這些虛擬機(jī)器則稱為客體機(jī)器(guest machine)。hypervisor提供虛擬的作業(yè)平臺來執(zhí)行客體操作系統(tǒng)(guest operating systems),負(fù)責(zé)管理其他客體操作系統(tǒng)的執(zhí)行階段;這些客體操作系統(tǒng),共同分享虛擬化后的硬件資源。(引用自百度百科)
從上圖不難發(fā)現(xiàn),主機(jī)機(jī)器會為每個(gè)客體機(jī)器(虛擬機(jī))提前分配好資源,與物理機(jī)時(shí)代一樣,實(shí)際上應(yīng)用本身可能并不需要那么多物理資源,有一部分資源被操作系統(tǒng)所占用,大部分時(shí)候處于閑置狀態(tài),仍然存在一些問題如下:
- 資源利用率低 - 操作系統(tǒng)占用了一部分資源
- 移植性差 - 虛擬機(jī)上的應(yīng)用對操作系統(tǒng)有較大依賴
- 啟動速度慢 - 每次運(yùn)行一個(gè)虛擬機(jī)上的應(yīng)用都需要先啟動系統(tǒng)
- 部署麻煩 - 如果從開發(fā)環(huán)境切換到測試和生產(chǎn)環(huán)境,仍然需要重新搭建應(yīng)用相關(guān)依賴
容器化時(shí)代
Docker容器類似沙箱,每個(gè)容器之間相互獨(dú)立、資源隔離、互不干擾,Docker容器化技術(shù)出現(xiàn)后,基本解決了上面提到的問題,Docker有以下優(yōu)勢:
- 啟動速度更快: 秒級啟動。
- 快速的部署和交付: 開發(fā)者可以使用一個(gè)標(biāo)準(zhǔn)的鏡像來構(gòu)建一套開發(fā)容器,開發(fā)完成之后, 運(yùn)維人員可以直接使用這個(gè)容器來部署代碼。
- 更高效的虛擬化: 它是內(nèi)核級的虛擬化,因此可以實(shí)現(xiàn)更高的性能和效率。
- 高效的遷移: Docker可以運(yùn)行在不同的平臺,用戶可以輕松的將一個(gè)應(yīng)用從一個(gè)平臺遷移到另一個(gè)平臺。
- 節(jié)省開支: Docker容器除了運(yùn)行其中應(yīng)用外,基本不消耗額外的系統(tǒng)資源,一臺設(shè)備可以運(yùn)行上千個(gè)容器。
- 資源隔離:可以對Docker進(jìn)行資源限制,每個(gè)容器可以享用自己的物理資源,互不干擾
從上圖可以看到,我把物理資源變成可選了,這是因?yàn)槟J(rèn)的情況下,docker沒有對容器進(jìn)行硬件資源的限制,當(dāng)一臺主機(jī)上運(yùn)行幾百個(gè)容器,這些容器雖然互相隔離,但是底層卻使用著相同的 CPU、內(nèi)存和磁盤資源。如果不對容器使用的資源進(jìn)行限制,那么容器之間會互相影響,小的來說會導(dǎo)致容器資源使用不公平;大的來說,可能會導(dǎo)致主機(jī)和集群資源耗盡,服務(wù)完全不可用。
Docker提供資源隔離機(jī)制,利用Linux內(nèi)核的 namespace機(jī)制來做容器之間的隔離,通過內(nèi)核的 cgroups 機(jī)制來做容器的資源限制(CPU、Memory、Disk等)。
但是直接在主體機(jī)器安裝Docker,也會導(dǎo)致Docker容器直接依賴主體機(jī)器操作系統(tǒng),沒辦法實(shí)現(xiàn)多租戶隔離,后面章節(jié)會提到對應(yīng)解決方案。
什么是容器鏡像和容器
鏡像是一個(gè)可執(zhí)行包,包含運(yùn)行應(yīng)用程序所需的所有內(nèi)容——代碼、運(yùn)行時(shí)、庫、環(huán)境變量和配置文件。容器是通過運(yùn)行鏡像啟動容器,是鏡像的運(yùn)行時(shí)實(shí)例。鏡像實(shí)際上就是一個(gè)容器的模板,通過這個(gè)模板可以創(chuàng)建很多相同的容器。
通過Java去類比理解Docker的一些概念:
- Class文件 - 相當(dāng)于Docker鏡像,定義了類的一些所需要的信息
- 對象 - 相當(dāng)于容器,通過Class文件創(chuàng)建出來的實(shí)例
- JVM - 相當(dāng)于Docker引擎,可以讓Docker容器屏蔽底層復(fù)雜邏輯,實(shí)現(xiàn)跨平臺操作
容器與虛擬機(jī)的區(qū)別
容器在Linux上本地運(yùn)行,并與其他容器共享主機(jī)的內(nèi)核。它運(yùn)行一個(gè)獨(dú)立的進(jìn)程,不占用比其他任何可執(zhí)行程序更多的內(nèi)存,使其輕量級。
虛擬機(jī)(VM) 運(yùn)行一個(gè)成熟的“游客”操作系統(tǒng),通過虛擬機(jī)監(jiān)控程序?qū)χ鳈C(jī)資源進(jìn)行虛擬訪問。通常,vm提供的資源比大多數(shù)應(yīng)用程序所需的要多。
總的來說,容器不需要依賴操作系統(tǒng),減少了很多系統(tǒng)資源開銷,使得容器可以更關(guān)注應(yīng)用的需求,而虛擬機(jī)可以為每個(gè)應(yīng)用靈活提供不同的操作系統(tǒng),避免了docker容器直接依賴主體機(jī)器操作系統(tǒng),兩者結(jié)合使用,可以讓整個(gè)系統(tǒng)架構(gòu)更加靈活,擴(kuò)展性更強(qiáng)。
Vagrant與Docker的區(qū)別
其實(shí)兩款產(chǎn)品沒有什么可比性,因?yàn)槭褂脠鼍安煌@里列出來主要是避免一些童鞋誤解。
Vagrant是一款管理虛擬機(jī)的工具,簡化了虛擬機(jī)的搭建和管理工作,不需要再像以前一樣,需要人工一個(gè)個(gè)去創(chuàng)建、啟動、停止虛擬機(jī),可以通過vagrant腳本同一時(shí)間輕松搭建和管理多個(gè)虛擬機(jī)節(jié)點(diǎn)。
docker是一款用于快速交付、測試、部署的工具,簡化了應(yīng)用環(huán)境的搭建和管理工作。兩者適用范圍不同。一個(gè)容器就是一個(gè)包含了應(yīng)用執(zhí)行所依賴的數(shù)據(jù)(包括lib,配置文件等等),Docker可以通過同一個(gè)鏡像文件快速在不同的環(huán)境(開發(fā)、測試、生產(chǎn))搭建多個(gè)相同的容器。
Vagrant是用于管理虛擬機(jī),Docker用于管理應(yīng)用環(huán)境。
Docker引擎和架構(gòu)
Docker引擎是一個(gè)客戶端-服務(wù)器應(yīng)用程序,主要組件如下:
- 服務(wù)器是一種長時(shí)間運(yùn)行的程序,稱為守護(hù)進(jìn)程(dockerd)
命令)。 - 一個(gè)REST API,它指定了程序可以用來與守護(hù)進(jìn)程對話的接口
指導(dǎo)它做什么。 - 命令行接口(CLI)客戶端(docker命令)。
平時(shí)我們使用的docker指令都是通過docker客戶端去與docker服務(wù)端進(jìn)行通訊
Docker架構(gòu)體系
Docker使用客戶機(jī)-服務(wù)器架構(gòu)。
Docker客戶機(jī)與Docker守護(hù)進(jìn)程進(jìn)行對話,后者負(fù)責(zé)構(gòu)建、運(yùn)行和分發(fā)Docker容器。
Docker客戶機(jī)和守護(hù)進(jìn)程可以在同一系統(tǒng)上運(yùn)行,也可以將Docker客戶機(jī)連接到遠(yuǎn)程Docker守護(hù)進(jìn)程。Docker客戶機(jī)和守護(hù)進(jìn)程通過UNIX套接字或網(wǎng)絡(luò)接口使用REST API進(jìn)行通信。
Docker的鏡像分層
Docker鏡像是由一系列層構(gòu)成的。每一層代表鏡像Dockerfile中的一條指令。除了最后一層之外,每一層都是只讀的。Docker鏡像分層最大的好處是共享資源,其他相同環(huán)境的軟件鏡像都共同去享用同一個(gè)環(huán)境鏡像,而不需要每個(gè)軟件鏡像要去創(chuàng)建一個(gè)底層環(huán)境。
上圖以Tomcat鏡像為例子,對于用戶而言,用戶面向的是一個(gè)疊加后的文件系統(tǒng),我們對Tomcat容器做任何操作都會記錄在容器層,底層鏡像文件不會受影響。Docker容器底層共享主機(jī)內(nèi)核,只保留少量運(yùn)行Image必須的組件,在容器啟動時(shí)不需要啟動內(nèi)核空間,所以啟動時(shí)比虛機(jī)較快,開銷少,易遷移。
VirturalBox和Docker如何搭配使用
上面章節(jié)也提到過,如果我們把Docker直接安裝在主體機(jī)器,會導(dǎo)致Docker直接依賴了我們主體機(jī)器的操作系統(tǒng),如果不同的團(tuán)隊(duì)共用一臺物理機(jī)時(shí),沒辦法做到每個(gè)團(tuán)隊(duì)或每個(gè)環(huán)境都獨(dú)享自己的操作系統(tǒng)和相應(yīng)的權(quán)限。
目前一般的部署模式有以下幾種:
- 物理機(jī)+Docker模式 - 適合高I/O要求的業(yè)務(wù),如一些數(shù)據(jù)庫服務(wù)、文件服務(wù)、緩存服務(wù)等
- 虛擬機(jī) - 虛擬機(jī)的多租戶的強(qiáng)隔離特性,保證租戶在擁有虛機(jī)root權(quán)限的同時(shí),其他租戶和主機(jī)的安全
- 物理機(jī)+虛擬機(jī)+Docker混合模式 - 集合上面的優(yōu)點(diǎn),既可以提供安全隔離,也能實(shí)現(xiàn)靈活擴(kuò)展和高可用
從上圖可以看出,本教程采用的是混合模式,Docker容器可以在虛擬機(jī)內(nèi)部運(yùn)行,虛擬機(jī)并為它們提供經(jīng)過驗(yàn)證的隔離,安全屬性,移動性,動態(tài)虛擬網(wǎng)絡(luò)等,可實(shí)現(xiàn)安全隔離和資源的高利用率。基本應(yīng)該遵循:不同租戶的業(yè)務(wù)運(yùn)行采用虛擬機(jī)隔離,相似類型的業(yè)務(wù)部署在同一組容器上的思路。
當(dāng)虛擬機(jī)太多的時(shí)候,我們也沒辦法手動一個(gè)個(gè)去管理,因此這里用到Vagrant工具去管理虛擬機(jī)。
主體機(jī)器如何與客體機(jī)器上的容器進(jìn)行通信
從上圖可以看到,當(dāng)我們使用Docker+虛擬機(jī)的混合模式時(shí),實(shí)際上整體結(jié)構(gòu)可以分為三大部分:主體機(jī)器、客體機(jī)器和容器。主體機(jī)器不能直接訪問客體機(jī)器上的容器的IP地址訪問容器,因?yàn)椴辉偻粋€(gè)網(wǎng)段,而要通過客體主機(jī)和對應(yīng)的映射端口訪問客體機(jī)器的容器。
以Tomcat容器作為一個(gè)例子,這里虛擬機(jī)網(wǎng)絡(luò)模式默認(rèn)是bridge
方式,在實(shí)戰(zhàn)部分也有詳細(xì)步驟,應(yīng)用部署圖如下:
我在客體機(jī)器Centos上啟動一個(gè)Tomcat容器,容器端口為8080,映射端口為9090
docker run -d --name evan-tomcat -p 9090:8080 tomcat
通過命令查看得到,主體機(jī)器、客體機(jī)器、Tomcat容器IP地址(跟圖片一致)如下:
- 主體機(jī)器 - 我機(jī)器自帶的MacOS,IP地址為
192.168.100.4
- 客體機(jī)器 - 虛擬機(jī)上的Centos系統(tǒng),IP地址為
192.168.100.9
- 容器 - Tomcat容器(linux內(nèi)核),IP地址為
172.17.0.3
嘗試主體機(jī)器(MacOS)訪問客體機(jī)器(Centos)
192:~ evan$ ping 192.168.100.9
PING 192.168.100.9 (192.168.100.9): 56 data bytes
64 bytes from 192.168.100.9: icmp_seq=0 ttl=64 time=0.481 ms
64 bytes from 192.168.100.9: icmp_seq=1 ttl=64 time=0.477 ms
64 bytes from 192.168.100.9: icmp_seq=2 ttl=64 time=0.447 ms
64 bytes from 192.168.100.9: icmp_seq=3 ttl=64 time=0.339 ms
64 bytes from 192.168.100.9: icmp_seq=4 ttl=64 time=0.400 ms
64 bytes from 192.168.100.9: icmp_seq=5 ttl=64 time=0.324 ms
可以看到,主體機(jī)器是可以直接與客體機(jī)器進(jìn)行通信,因?yàn)樵谕粋€(gè)網(wǎng)段
嘗試客體機(jī)器(Centos)訪問Tomcat容器
[root@10 /]# ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=0.036 ms
64 bytes from 172.17.0.3: icmp_seq=2 ttl=64 time=0.043 ms
64 bytes from 172.17.0.3: icmp_seq=3 ttl=64 time=0.047 ms
64 bytes from 172.17.0.3: icmp_seq=4 ttl=64 time=0.042 ms
在虛擬機(jī)上可以直接與Tomcat容器進(jìn)行通信
嘗試主體機(jī)器(MacOS)通過客體機(jī)器(Centos)端口9090訪問Tomcat容器
192:~ evan$ curl 192.168.100.9:9090
<!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Message</b> Not found</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/8.5.50</h3></body></html>192:~ Evan$
可以看到主體機(jī)器可以通過客體機(jī)器IP+端口方式訪問容器,因此主體機(jī)器訪問的并不是容器真實(shí)的端口,而是虛擬機(jī)上端口的映射。
環(huán)境搭建與實(shí)戰(zhàn)
使用Vagrant管理虛擬機(jī)創(chuàng)建Centos7
1.創(chuàng)建一個(gè)centos7文件夾
mkdir centos7
2.在當(dāng)前文件夾初始化Vagrantfile
vagrant init centos7
輸出結(jié)果如下:
192:centos7 evan$ vagrant init centos7
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.
3.進(jìn)入Vagrantfile,更改配置如下:
# -*- mode: ruby -*-
# vi: set ft=ruby :
# All Vagrant configuration is done below. The "2" in Vagrant.configure
# configures the configuration version (we support older styles for
# backwards compatibility). Please don't change it unless you know what
# you're doing.
Vagrant.configure("2") do |config|
# The most common configuration options are documented and commented below.
# For a complete reference, please see the online documentation at
# https://docs.vagrantup.com.
# Every Vagrant development environment requires a box. You can search for
# boxes at https://vagrantcloud.com/search.
config.vm.box = "centos7"
# Disable automatic box update checking. If you disable this, then
# boxes will only be checked for updates when the user runs
# `vagrant box outdated`. This is not recommended.
# config.vm.box_check_update = false
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
# NOTE: This will enable public access to the opened port
# config.vm.network "forwarded_port", guest: 80, host: 8080
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine and only allow access
# via 127.0.0.1 to disable public access
# config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
# Create a private network, which allows host-only access to the machine
# using a specific IP.
# config.vm.network "private_network", ip: "192.168.33.10"
# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
config.vm.network "public_network"
# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.
# config.vm.synced_folder "../data", "/vagrant_data"
# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for VirtualBox:
#
# config.vm.provider "virtualbox" do |vb|
# # Display the VirtualBox GUI when booting the machine
# vb.gui = true
#
# # Customize the amount of memory on the VM:
# vb.memory = "1024"
# end
config.vm.provider "virtualbox" do |vb|
vb.memory = "4000"
vb.name= "evan-centos7"
vb.cpus= 2
end
#
# View the documentation for the provider you are using for more
# information on available options.
# Enable provisioning with a shell script. Additional provisioners such as
# Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the
# documentation for more information about their specific syntax and use.
# config.vm.provision "shell", inline: <<-SHELL
# apt-get update
# apt-get install -y apache2
# SHELL
end
4.下載centos7鏡像文件
百度網(wǎng)盤下載
官網(wǎng)下載
5.將下載的鏡像文件保存到你系統(tǒng)的一個(gè)目錄下,我本機(jī)的存放目錄是:
/Users/evan/development/visualbox/virtualbox.box
6.將centos7鏡像文件添加到vagrant管理的鏡像中,并將鏡像命名為centos7
vagrant box add centos7 /Users/evan/development/visualbox/virtualbox.box
添加成功輸出結(jié)果如下:
192:visualbox evan$ vagrant box add centos7 /Users/evan/development/visualbox/virtualbox.box
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'centos7' (v0) for provider:
box: Unpacking necessary files from: file:///Users/evan/development/visualbox/virtualbox.box
==> box: Successfully added box 'centos7' (v0) for 'virtualbox'!
7.查看已添加的虛擬機(jī)鏡像,可通過vagrant box list
192:visualbox evan$ vagrant box list
centos7 (virtualbox, 0)
可以看到,已經(jīng)成功添加centos7
8.根據(jù)Vagrantfile文件啟動創(chuàng)建虛擬機(jī),去到剛才初始化Vagrantfile的文件夾,執(zhí)行vagrant up
創(chuàng)建虛擬機(jī),vagrant會自動根據(jù)我們在Vagrant配置好的參數(shù)來創(chuàng)建虛擬機(jī),注意我們上面添加的虛擬機(jī)名字centos7
要與配置文件中的config.vm.box = "centos7"
一致。(執(zhí)行過程中,Virtualbox應(yīng)用不需要打開)
192:centos7 evan$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Available bridged network interfaces:
1) en0: Wi-Fi (Wireless)
2) en5: USB Ethernet(?)
3) p2p0
4) awdl0
5) llw0
6) en7: USB 10/100/1000 LAN
7) en1: Thunderbolt 1
8) en2: Thunderbolt 2
9) en3: Thunderbolt 3
10) en4: Thunderbolt 4
11) bridge0
==> default: When choosing an interface, it is usually the one that is
==> default: being used to connect to the internet.
default: Which interface should the network bridge to? 1
==> default: Preparing network interfaces based on configuration...
default: Adapter 1: nat
default: Adapter 2: bridged
==> default: Forwarding ports...
default: 22 (guest) => 2222 (host) (adapter 1)
==> default: Running 'pre-boot' VM customizations...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
default: SSH address: 127.0.0.1:2222
default: SSH username: vagrant
default: SSH auth method: private key
default:
default: Vagrant insecure key detected. Vagrant will automatically replace
default: this with a newly generated keypair for better security.
default:
default: Inserting generated public key within guest...
default: Removing insecure key from the guest if it's present...
default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
==> default: Checking for guest additions in VM...
default: No guest additions were detected on the base box for this VM! Guest
default: additions are required for forwarded ports, shared folders, host only
default: networking, and more. If SSH fails on this machine, please install
default: the guest additions and repackage the box to continue.
default:
default: This is not an error message; everything may continue to work properly,
default: in which case you may ignore this message.
==> default: Configuring and enabling network interfaces...
==> default: Rsyncing folder: /Users/evan/development/centos7/ => /vagrant
執(zhí)行完畢,可以打開Visualbox查看是否已經(jīng)多了一個(gè)centos7虛擬機(jī)
在虛擬機(jī)安裝Docker
安裝Docker之前,需要進(jìn)入剛才安裝好的Centos7操作系統(tǒng),因此需要先設(shè)置下SSH配置,這里使用的是賬號密碼登陸
通過SSH客戶端訪問Centos
1.使用vagrant ssh
命令進(jìn)入虛擬機(jī)
192:centos7 evan$ vagrant ssh
-bash: warning: setlocale: LC_CTYPE: cannot change locale (UTF-8): No such file or directory
[vagrant@10 ~]$ ls
2.執(zhí)行sudo -i
命令切換到root用戶,然后進(jìn)入通過vi /etc/ssh/sshd_config
命令修改SSH安全認(rèn)證配置
[vagrant@10 ~]$ sudo -I
[root@10 ~]# vi /etc/ssh/sshd_config
3.修改SSH安全認(rèn)證如下
PasswordAuthentication yes
4.修改完成,退出sshd_config后,更換SSH登陸密碼,我這里使用的密碼是evan123
[root@10 ~]# passwd
Changing password for user root.
New password:
BAD PASSWORD: The password fails the dictionary check - it is too simplistic/systematic
Retype new password:
passwd: all authentication tokens updated successfully.
5.重啟SSH服務(wù),使配置生效
[root@10 ~]# systemctl restart sshd
6.測試SSH連接
查看當(dāng)前Centos系統(tǒng)ip,通過ip add
命令進(jìn)行查看
[root@10 /]# ip add
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 52:54:00:8a:fe:e6 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
valid_lft 74572sec preferred_lft 74572sec
inet6 fe80::5054:ff:fe8a:fee6/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 08:00:27:ba:0a:28 brd ff:ff:ff:ff:ff:ff
inet 192.168.100.9/24 brd 192.168.100.255 scope global noprefixroute dynamic eth1
valid_lft 160972sec preferred_lft 160972sec
inet6 fe80::a00:27ff:feba:a28/64 scope link
valid_lft forever preferred_lft forever
可以看到,當(dāng)前外網(wǎng)ip是192.168.100.9
退出虛擬機(jī),回到主體機(jī)器,測試是否可以連接上虛擬機(jī)上的Centos系統(tǒng)
192:~ evan$ ssh root@192.168.100.9
The authenticity of host '192.168.100.9 (192.168.100.9)' can't be established.
ECDSA key fingerprint is SHA256:1yutVoFjWAa0o2vCNP+kOxS/rITjxhqTV/48XsTNKGo.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.100.9' (ECDSA) to the list of known hosts.
root@192.168.100.9's password:
Last login: Mon Jan 27 12:19:55 2020 from 127.0.0.1
-bash: warning: setlocale: LC_CTYPE: cannot change locale (UTF-8): No such file or directory
[root@10 ~]#
此時(shí)已經(jīng)成功連接上,下一步開始Docker安裝
在Centos上安裝Docker
1.執(zhí)行以下命令清理之前已安裝的Docker文件,如果之前曾經(jīng)安裝過
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
因?yàn)檫@個(gè)系統(tǒng)是新安裝,之前沒有Docker相關(guān)文件,執(zhí)行結(jié)果如下:
[root@10 /]# sudo yum remove docker \
> docker-client \
> docker-client-latest \
> docker-common \
> docker-latest \
> docker-latest-logrotate \
> docker-logrotate \
> docker-engine
Failed to set locale, defaulting to C
Loaded plugins: fastestmirror
No Match for argument: docker
No Match for argument: docker-client
No Match for argument: docker-client-latest
No Match for argument: docker-common
No Match for argument: docker-latest
No Match for argument: docker-latest-logrotate
No Match for argument: docker-logrotate
No Match for argument: docker-engine
No Packages marked for removal
2.輸入以下命令安裝環(huán)境必要依賴
sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
3.通過以下命令配置阿里云鏡像加速器,否則下載鏡像會比較慢,這里鏡像加速器做了脫敏處理,大家可以自己去申請一個(gè)
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://***.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
怎么獲取鏡像加速器地址,可以查看我另一篇文章
使用Docker安裝Oracle
4.設(shè)置Docker倉庫,Docker默認(rèn)倉庫hub.docker.com
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
5.安裝Docker
sudo yum install -y docker-ce docker-ce-cli containerd.io
6.啟動Docker服務(wù)
sudo systemctl start docker
7.通過Docker倉庫自帶鏡像,測試Docker是否已經(jīng)安裝成功
[root@10 /]# sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:9572f7cdcee8591948c2963463447a53466950b3fc15a247fcad1917ca215a2f
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
Docker會自動下載鏡像,如果在本地查找不到
通過Docker安裝Tomcat
1.從遠(yuǎn)方倉庫拉去Tomcat鏡像,這里不帶版本號默認(rèn)拉取最新版本
docker pull tomcat
2.啟動Tomcat容器,指定容器命名為evan-tomcat,并且配置容器端口9090映射到內(nèi)置mysql 3306端口
docker run -d --name evan-tomcat -p 9090:8080 tomcat
通過Docker安裝Mysql
1.從遠(yuǎn)方倉庫拉去Tomcat鏡像,這里不帶版本號默認(rèn)拉取最新版本
docker pull mysql
2.啟動MySQL容器,并改名為evan-mysql,配置容器端口 3301映射到3306端口,并設(shè)置密碼為evan123
docker run -d --name evan-mysql -p 3301:3306 -e MYSQL_ROOT_PASSWORD=evan123 --privileged mysql
檢查容器是否啟動
1.通過以下Docker指令可以查看上面我們安裝和啟動的容器是否正常運(yùn)行:
[root@10 /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
358207fa8d8b tomcat "catalina.sh run" 3 minutes ago Up 3 minutes 0.0.0.0:9090->8080/tcp evan-tomcat
b58999f0524f mysql "docker-entrypoint.s…" 5 minutes ago Up 5 minutes 33060/tcp, 0.0.0.0:3301->3306/tcp evan-mysql
[root@10 /]#
2.我們可以通過上面的容器ID去進(jìn)入到容器內(nèi)部,這里以Tomcat為例子:
[root@10 /]# docker exec -it 358207fa8d8b /bin/bash
root@358207fa8d8b:/usr/local/tomcat# ls
BUILDING.txt LICENSE README.md RUNNING.txt conf lib native-jni-lib webapps work
CONTRIBUTING.md NOTICE RELEASE-NOTES bin include logs temp webapps.dist
root@358207fa8d8b:/usr/local/tomcat#
這樣我們本章所有環(huán)境SETUP已經(jīng)順利完成,后面的章節(jié)將會更深入介紹容器的原理、集群部署、管理以及結(jié)合真實(shí)微服務(wù)的應(yīng)用。
Q&A
1.在Mac中安裝Visualbox時(shí)失敗,提示“the installation failed”
原因是MacOS阻止了VirtualBox安裝kernel extension。在system preferences中選擇security&privacy在general中點(diǎn)擊下方的allow即可解決。
2.vagrant up
命令啟動失敗,提示No Usable default provider could be found for your system
這是由于Vagrant與Virtualbox版本不一致,Vagrant的版本比Virtualbox的舊,可以將Virtualbox降級,或者直接使用本文推薦的版本
附錄
Vagrant常用命令
- vagrant up
啟動虛擬機(jī) - vagrant ssh
進(jìn)入虛擬機(jī) - )vagrant status
查看centos7的狀態(tài) - vagrant halt
停止/關(guān)閉centos7 - vagrant destroy
刪除centos7 - vagrant status
查看當(dāng)前vagrant創(chuàng)建的虛擬機(jī) - Vagrantfile中也可以寫腳本命令,使得centos7更加豐富
但是要注意,修改了Vagrantfile,要想使正常運(yùn)行的centos7生效,必須使用vagrant reload
Docker常用命令
- docker pull
拉取鏡像到本地 - docker run
根據(jù)某個(gè)鏡像創(chuàng)建容器 - -d 讓容器在后臺運(yùn)行,其實(shí)就是一個(gè)進(jìn)程
- --name 給容器指定一個(gè)名字
- -p 將容器的端口映射到宿主機(jī)的端口
- docker exec -it
進(jìn)入到某個(gè)容器中并交互式運(yùn)行
更多詳細(xì)內(nèi)容,可以關(guān)注我個(gè)人Gitchat,一起交流