Docker虚拟化实战和企业案例演练
深入剖析虚拟化技术概念和应用场景
虚拟化,一是项技术~~,是一种资源解决方案。
虚拟化技术是将物理资源转变为逻辑上可以管理的资源,以打破物理结构之间的壁垒,使计算元件运行在虚拟的基础上,而不是真实的物理资源上。
通过虚拟化技术,可以将物理资源转变为逻辑资源(虚拟机),应用程序服务运行在虚拟资源上,而不是真实的物理机上。
虚拟化技术的落地,底层就必须有物理机支撑!
单纯的物理机器是不能直接虚拟化的,都需要虚拟化软件来实现。目前主流的虚拟化软件有:KVM,XEN,ESXI,HP-V,Docker,Virtual BOX等
虚拟化技术的应用场景
企业需求:部署一百套Nginx WEB服务,要求对外端口为80,要求独立服务器部署
传统方案:采购一百台低配硬件物理机,每台物理机部署一套Nginx WEB服务
虚拟化方案:采购10台高配硬件物理机,每台物理机虚拟10台虚拟机,每台虚拟机独立部署一套Nginx WEB服务
很明显,第二种方案,从成本、部署难度、维护等方面,第二种都是比第一种好的。
所以,虚拟化的意义:对于硬件设备资源的最大化利用,降低企业各种费用成本,简化后期资源部署和维护,动态满足企业需求,基于虚拟化资源来代替待淘汰的物理资源
云计算技术概念和应用场景
深入剖析Docker虚拟化概念和底层原理
Docker简介
Docker是虚拟化技术的一种,也是目前使用比较多的一种。Go语言开发引擎
Docker利用“集装箱”(容器)的原理,将系统、开发软件包、依赖环境等统一打包到容器中,将整个容器部署至其他的平台或者服务器上。
容器技术:一种虚拟化的方案,和传统的虚拟机(通过中间层"guerst OS"运行服务)不同,Docker直接运行在操作系统之上。因此容器虚拟化也被称之为操作系统虚拟化。Docker容器依赖于Linux内核特性,Namespace和Cgroups,所以只能运行在Linux之上。
Docker虚拟化技术比传统虚拟化技术的优点
假设基于传统虚拟化和Docker虚拟化部署Nginx WEB服务,两种方案部署如下:
传统虚拟化:硬件服务器-HostOS-VMM-GuestOS-Nginx WEB服务
Docker虚拟化:用剑服务器-HostOS-VMM-Nginx WEB服务
传统的虚拟化,不能直接启Nginx WEB,Docker可以直接启动Nginx WEB
如果是传统虚拟化技术,原本只需要很少资源的服务应用,就需要很大的“guestOS“资源来支撑真正的服务
Docker目标
提供简单轻量级的建模方式(docker的启动是毫秒级的)
职责的逻辑分离:开发人员只需要关注容器中运行的程序,运维人员只需要关注对容器的管理。Docker开发提高了开发程序和部署容器的一致性
快速高效的开发声明周期:缩短代码从开发、测试到部署上线的生命周期
鼓励使用面向服务的架构:docker推荐单个容器只运行一个应用程序/进程,这样就形成了一个分布式的应用程序模型,避免服务之间的互相影响。实现 高内聚 低耦合
Docker的使用场景
使用Docker容器开发、测试、部署服务。
docker本身是轻量级的,所以本地开发人员可以构建、运行并分享docker容器,容器可以在开发环境中创建,然后提交到测试,在到生产环境。
创建隔离的运行环境
在很多企业应用中,同一服务的不同版本可能服务于不同的用户,使用Docker很容易创建不同的环境来运行不同版本的服务
搭建测试环境
有于Docker的轻量化,所以开发者很容易在本地搭建测试环境,用来测试程序在不同系统下的兼容性,甚至集群式的测试环境。
构建多用户的平台服务(PaaS)基础设施
即同软件即服务(SaaS)应用程序
高性能、超大规模的宿主机部署
Docker的基本组成
Docker客户端/守护进程:
docker是C/S架构的程序,docker客户端向服务端发送请求,守护进程处理完所有的工作,并返回处理结果。客户端对服务端的访问,既可以是本地,也可以通过远程
Docker镜像:
docker镜像是docker容器的基石。跟ISO镜像类似,静止的模版,用于Docker容器的底层基础文件
Docker容器:
docker容器通过docker镜像启动,是将Docker镜像运行的实体,是活动的。
Docker镜像和容器的关系,跟程序和进程的关系类似
Docker仓库:
存放Docker镜像的地方,一般分为公共仓库和私有仓库,docker公司提供了一个自己的仓库"Docker Hub"
Docker的相关技术
Docker依赖Linux的内核特性有:Cgroup(控制组)和Namespace(命名空间)
Namespace
命名空间是一种封装的概念,在操作系统层面上,提供了系统资源的隔离,系统资源包括{进程、文件系统、网络等}。Linux实现命名空间的目的:为了实现轻量级虚拟化服务,在不同一命名空间下的进程,彼此毫无关系。
Cgroup(Control Groups)
Cgroup对隔离的资源进行管理,是一种用来限制、记录,隔离进程组资源的机制。就是为了容器技术而生的。
Docker容器的能力:
文件系统隔离:每隔容器都有自己的root文件系统
进程隔离:每个容器都运行在自己的进程环境中,互相不影响
网络隔离:容器间的虚拟网络接口和IP地址都是分开的
资源隔离和分组:使用Cgroups将CPU和内存之类的物理资源独立的分配给每个Docker容器
Docker基础命令使用
部署Docker虚拟化平台内核要求:Linux内核版本:3.8+,推荐内核版本3.10+,对应的Linux发行版:RHEL7.x和CentOS7.x;
部署Docker虚拟化技术,对物理机配置容量没有要求,生产环境尽量使用高配物理机。如:京东线上,64C(CPU)+256G(内存)+2T(分布式部署),JDOS2.0弹性云。
Docker的安装与配置
下载安装Docker软件包
[root@docker mnt]# yum install docker*
。。。
Installing:
docker-engine x86_64 1.13.1-1.el7.centos /docker-engine-1.13.1-1.el7.centos.x86_64
65 M
docker-engine-selinux noarch 1.13.1-1.el7.centos /docker-engine-selinux-1.13.1-1.el7.centos.noarch
43 k
Installing for dependencies:
audit-libs-python x86_64 2.6.5-3.el7 rhel7.3 70 k
checkpolicy x86_64 2.5-4.el7 rhel7.3 290 k
libcgroup x86_64 0.41-11.el7 rhel7.3 65 k
libseccomp x86_64 2.3.1-2.el7 rhel7.3 56 k
libsemanage-python x86_64 2.5-4.el7 rhel7.3 103 k
libtool-ltdl x86_64 2.4.2-21.el7_2 rhel7.3 49 k
policycoreutils-python x86_64 2.5-8.el7 rhel7.3 444 k
python-IPy noarch 0.75-6.el7 rhel7.3 32 k
setools-libs x86_64 3.3.8-1.1.el7 rhel7.3 610 k
。。。
[root@docker mnt]# rpm -qa | grep docker
docker-engine-1.13.1-1.el7.centos.x86_64
docker-engine-selinux-1.13.1-1.el7.centos.noarch
启动Docker
[root@docker mnt]# systemctl start doceker
Failed to start doceker.service: Unit not found.
[root@docker mnt]# systemctl start docker
[root@docker mnt]# ps -ax | grep docker
11435 ? Ssl 0:00 /usr/bin/dockerd
11438 ? Ssl 0:00 docker-containerd -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc
11544 pts/0 R+ 0:00 grep --color=auto docker
[root@docker mnt]# docker version
Client:
Version: 1.13.1
API version: 1.26
Go version: go1.7.5
Git commit: 092cba3
Built: Wed Feb 8 06:38:28 2017
OS/Arch: linux/amd64
Server:
Version: 1.13.1
API version: 1.26 (minimum version 1.12)
Go version: go1.7.5
Git commit: 092cba3
Built: Wed Feb 8 06:38:28 2017
OS/Arch: linux/amd64
Experimental: false
基于Docker引擎启动Nginx容器,并且实现通过物理机wget、curl实现访问
首先,需要从Docker官网获取Docker镜像,
docker search nginx | more
docker search nginx | more
docker pull docker.io/nginx由于国外网站下载速度比较慢,所以可以替换为国内的docker仓库,具体方法:
[root@docker ~]# cat >/etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
EOF
[root@docker ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
重启Docker服务,这样就可以取下载Docker镜像了为什么要为Docker配置国内镜像???在正常情况下,docker有一个默认连接的国外官方镜像,在国外的网友访问该官方镜像自然不成问题,但是国内毕竟不是国外,由于国情不同,中国的网络访问国外官方镜像网速一向很慢,而且往往还会遭遇断网的窘境,所以说我们要想正常使用docker的镜像,那么我们就不得不配置相应的国内镜像。
Docker可以配置的国内镜像有很多可供选择,比如说:阿里云,网易蜂巢,DaoCloud,Docker中国区官方镜像等,这些都是可以提供给大家随意选择的不错的镜像仓库。
Docker容器的基本操作
将本地tar包载入到本地镜像库使用docker load命令
[root@localhost packages]# docker load --input ubuntu.tar
454970bd163b: Loading layer [==================================================>] 196.8 MB/196.8 MB
38112156678d: Loading layer [==================================================>] 208.9 kB/208.9 kB
4e1f7c524148: Loading layer [==================================================>] 4.608 kB/4.608 kB
56063ad57855: Loading layer [==================================================>] 1.024 kB/1.024 kB
[root@localhost packages]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 07c86167cdc4 2 years ago 188 MB
启动容器:
[root@localhost packages]# docker run ubuntu echo "hello world"
hello world
一次启动执行一个命令的容器是docker中最基本的运行方式,docker提供了一个交互式启动容器的方式
[root@localhost packages]# docker run -it ubuntu /bin/bash
root@855833c3672f:/# echo "hello docker"
hello docker
root@855833c3672f:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
查看容器:
[root@localhost packages]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
855833c3672f ubuntu "/bin/bash" 45 seconds ago Exited (0) 10 seconds ago flamboyant_rosalind
797239db86e0 ubuntu "echo 'hello world'" About a minute ago Exited (0) About a minute ago flamboyant_khorana
77b29f9efa08 b809f199bbb9 "/bin/bash" 6 minutes ago Created stoic_leavitt
执行结果参数:
[root@localhost packages]# docker ps -a
CONTAINER ID(docker守护进程在启动容器时为容器分配的唯一ID)
IMAGE()
COMMAND()
CREATED()
STATUS()
PORTS()
NAMES(docekr守护进程为容器自动分配的名字)
docker inspect查看容器后面添加容器的唯一ID或者NAMES
docker自定义容器名字
[root@localhost packages]# docker run --name=fsx_docker -it ubuntu /bin/bash
root@304d46ba1c87:/# exit
exit
[root@localhost packages]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
304d46ba1c87 ubuntu "/bin/bash" 11 seconds ago Exited (0) 7 seconds ago fsx_docker
重新启动已经停止的容器
删除容器
仅仅用来删除的容器,不能删除正在用运行的命令
[root@localhost packages]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
304d46ba1c87 ubuntu "/bin/bash" 2 minutes ago Up 39 seconds fsx_docker
855833c3672f ubuntu "/bin/bash" 5 minutes ago Exited (0) 4 minutes ago flamboyant_rosalind
797239db86e0 ubuntu "echo 'hello world'" 5 minutes ago Exited (0) 5 minutes ago flamboyant_khorana
77b29f9efa08 b809f199bbb9 "/bin/bash" 10 minutes ago Created stoic_leavitt
[root@localhost packages]# docker rm 855833c3672f
855833c3672f
[root@localhost packages]# docker rm 797239db86e0
797239db86e0
[root@localhost packages]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
304d46ba1c87 ubuntu "/bin/bash" 3 minutes ago Up About a minute fsx_docker
77b29f9efa08 b809f199bbb9 "/bin/bash" 11 minutes ago Created stoic_leavitt
总结
Docker守护式容器
我们需要一个长期运行的容器提供服务,这就是守护式容器;可以长期运行
[root@localhost packages]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost packages]# docker run -it --name=fsx1 ubuntu /bin/bash
root@dcbb80e0404b:/# [root@localhost packages]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dcbb80e0404b ubuntu "/bin/bash" 26 seconds ago Up 25 seconds fsx1
//注意:此时的容器仍是启动状态,就意味着它还在运行
再次进入退出(仍在启动中)的容器(附加到运行中的容器)
[root@localhost packages]# docker attach fsx1
root@dcbb80e0404b:/#
启动守护式容器
[root@localhost packages]# docker run --name=fsx2 -d ubuntu /bin/bash -c "while true;do echo hello;sleep 1;done"
529cea9c4075854083e1d025f5639055a8cde98d17fe4d6d74a208215d706427
[root@localhost packages]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
529cea9c4075 ubuntu "/bin/bash -c 'whi..." 5 seconds ago Up 3 seconds fsx2
//容器一直在运行
使用log命令查看容器内部运行状况
[root@localhost packages]# docker logs -f -t --tail 5 fsx2
2018-05-24T03:35:35.642795622Z hello
2018-05-24T03:35:36.643727589Z hello
2018-05-24T03:35:37.644724326Z hello
2018-05-24T03:35:38.645707632Z hello
2018-05-24T03:35:39.646708718Z hello
2018-05-24T03:35:40.647727168Z hello
2018-05-24T03:35:41.648612161Z hello
2018-05-24T03:35:42.649668735Z hello
^C
查看容器内部进程
[root@localhost packages]# docker top fsx2
UID PID PPID C STIME TTY TIME CMD
root 11775 11758 0 11:32 ? 00:00:00 /bin/bash -c while true;do echo hello;sleep 1;done
root 13142 11775 0 11:37 ? 00:00:00 sleep 1
在docker运行中的容器启动新的进程(docker的理念是一个容器运行一个服务):
[root@localhost packages]# docker exec -it fsx2 /bin/bash
root@529cea9c4075:/# echo hello fsx
hello fsx
root@529cea9c4075:/# [root@localhost packages]# docker top fsx2
UID PID PPID C STIME TTY TIME CMD
root 11775 11758 0 11:32 ? 00:00:00 /bin/bash -c while true;do echo hello;sleep 1;done
root 13440 13423 0 11:40 pts/5 00:00:00 /bin/bash
root 13475 11775 0 11:40 ? 00:00:00 sleep 1
//这里使用ctrl+p ctrl+q
停止守护式容器
[root@localhost packages]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
529cea9c4075 ubuntu "/bin/bash -c 'whi..." 9 minutes ago Up 9 minutes fsx2
dcbb80e0404b ubuntu "/bin/bash" 18 minutes ago Up 18 minutes fsx1
[root@localhost packages]# docker stop fsx1
fsx1
[root@localhost packages]# docker kill fsx2
fsx2
总结
这里只介绍一些常见的docker命令,及子命令使用;更多信息可以使用docker帮助文件