0x00 容器与虚拟机
我们用的传统虚拟机如 VMware
, VisualBox
之类的需要模拟整台机器包括硬件,每台虚拟机都需要有自己的操作系统,虚拟机一旦被开启,预分配给它的资源将全部被占用。
而容器技术是和我们的宿主机共享硬件资源及操作系统,可以实现资源的动态分配。容器包含应用和其所有的依赖包,但是与其他容器共享内核。容器在宿主机操作系统中,在用户空间以分离的进程运行。容器技术是实现操作系统虚拟化的一种途径,可以让您在资源受到隔离的进程中运行应用程序及其依赖关系。
Docker
将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker
,就不用担心环境问题。
0x01 Docker的优势
Docker相比于传统虚拟化方式具有更多的优势:
docker
启动快速属于秒级别。虚拟机通常需要几分钟去启动。docker
需要的资源更少,docker
在操作系统级别进行虚拟化,docker
容器和内核交互,几乎没有性能损耗,性能优于通过Hypervisor
层与内核层的虚拟化。
-
docker
更轻量,docker
的架构可以共用一个内核与共享应用程序库,所占内存极小。同样的硬件环境,Docker
运行的镜像数远多于虚拟机数量,对系统的利用率非常高。 -
高可用和可恢复性:
docker
对业务的高可用支持是通过快速重新部署实现的。虚拟化具备负载均衡,高可用,容错,迁移和数据保护等经过生产实践检验的成熟保障机制,VMware
可承诺虚拟机99.999%
高可用,保证业务连续性。 -
快速创建、删除:虚拟化创建是分钟级别的,
Docker
容器创建是秒级别的,Docker
的快速迭代性,决定了无论是开发、测试、部署都可以节约大量时间。 -
交付、部署:虚拟机可以通过镜像实现环境交付的一致性,但镜像分发无法体系化。
Docker
在Dockerfile
中记录了容器构建过程,可在集群中实现快速分发和快速部署。
0x02 Docker基础架构
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。Docker 包括是三个最基本的概念:Image(镜像),Container(容器),Repository(仓库)。
Docker 镜像(Images) | Docker 镜像是用于创建 Docker 容器的模板。 |
---|---|
Docker 容器(Container) | 容器是独立运行的一个或一组应用。 |
Docker 仓库(Registry) | Docker 仓库用来保存镜像,可以理解为代码仓库。 |
Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。Docker 设计时,就充分利用 Union FS 的技术,将其设计为分层存储的架构。镜像实际是由多层文件系统联合组成。镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。
镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等,容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。
镜像构建完成后,可以很容易的在当前宿主上运行,但是,如果需要在其他服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。一个 Docker Registry中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。
在上面分别介绍了docker的三个基本概念:Image(镜像),Container(容器),Repository(仓库)和C/S的架构。现在在详细记录一下这些组件协作运行容器的过程:
Docker
客户端执行docker run
命令Dockerdaemon
发现本地没有我们需要的镜像daemon
从DockerHub
下载镜像- 下载完成后,镜像被保存到本地
Dockerdaemon
启动容器
Dockerdaemon
是服务器组件,以 Linux
后台服务的方式运行,是 Docker
最核心的后台进程,我们也把它称为守护进程。它负责响应来自 Docker Client
的请求,然后将这些请求翻译成系统调用完成容器管理操作。
0x03 Docker 安装与使用
LXC (Linux Container)内核虚拟化技术,可以提供轻量级虚拟化,以便隔离进程和资源。
Ubuntu12.04 安装Docker需要升级内核(Docker 在3.8内核下运行最佳,Ubuntu1204内核版本为3.2)
# install the backported kernel
sudo apt-get update
sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring
# reboot
sudo reboot
安装Docker
# 添加Docker库的密钥
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
# 把Docker的库添加到apt的源列表中,更新并安装lxc-docker包。
sudo sh -c "echo deb http://get.docker.io/ubuntu docker main\
> /etc/apt/sources.list.d/docker.list"
sudo apt-get update
sudo apt-get install lxc-docker
按照这个步骤安装后,发现报了很多错误,调试了半天也没能解决,后来发现自己的Ubuntu12.04 是32位的,Docker需要运行在64位的机子上,所以失败了。后面查了一下说docker也可以安装在32位的系统,不过pull下来的镜像也必须是32位的,这个有点麻烦,所以放弃了。
在安装docker或者其他软件时记得要使用命令uname -a
、uname -r
、lsb_release -a
查看系统相关信息,来避免一些不必要的麻烦。另外注意通过uname -a
命令查看内核和版本显示系统版本为i386和i686的为 32位系统;显示为X86_64的,才是64位系统。
后面选择了我的阿里云CentOS 安装Docker,一路pass,没有遇到任何bug,大致步骤如下:
1、清理原有的docker目录和文件,确保安装环境的干净:
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine
2、使用yum安装docker
安装一些必要的工具,设备映射器存储驱动程序需要设备映射器-持久数据和lvm2。
sudo yum install -y yum-utils \
device-mapper-persistent-data \
lvm2
设定软件源地址,国外慢的可怜,我这里使用国内源:
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
更新源信息
sudo yum makecache fast
下载docker,直接下载最新版:
sudo yum install docker-ce
也可以选择下载指定版本:
yum list docker-ce --showduplicates | sort -r
sudo yum install docker-ce-<VERSION STRING>
至此docker就下载安装成功了,可以直接使用命令docker -v 查看docker版本。
通过网上查资料说还有更简单的安装方法,直接使用脚本安装,只需要简单的两条命令就可以,我没有测试,应该是可以的。
curl -fsSL get.docker.com -o get-docker.sh
sudo sh get-docker.sh --mirror Aliyun
3、安装成功后可以进行一些配置和测试。可以设置系统启动时同时启动docker
sudo systemctl enable docker
启动docker并测试
sudo systemctl start docker
sudo docker run hello-world
0x04 Docker 常用命令
1.docker images ls # 列出本地docker镜像
2.docker rmi -f {image id} # 删除docker镜像
3.docker stop [docker_names]|[docker_id] # 停止容器运行
4.docker rename [docker_names] [newname] # 重命名容器
5.docker rm [docker_names] # 删除容器
6.docker ps -a # 已创建docker image列表
以创建Nginx容器为例
# 查找 Docker Hub 上的 nginx 镜像
docker search nginx
# 拉取镜像
docker pull nginx
# 查看本地镜像
docker images nginx
# 启动一个Nginx容器实例
# --name(容器名)、-p(端口映射)、-d(后台执行)
docker run --name nginx-test -p 8080:80 -d nginx
# 查看容器是否有在运行
docker ps
创建Nginx容器成功后,可以使用 ip + 端口号进行访问,Ubuntu系统可以直接使用127.0.0.1:端口号,如果是云服务器的话就是 ip+端口号,注意端口号要进行防火墙设置以保证可用。
0x05 Dockerfile
除了上述的拉取镜像生成容器实例的基本方法,还可以使用Dockerfile
来定义镜像创建容器,这里的Dockerfile
非常类似Makefile 和 Linux下shell。Dockerfile
是由一行行命令语句组成,并且支持已 #
开头的注释行。一般来说,可以将 Dockerfile
分为四个部分:
-
基础镜像(父镜像)信息指令 FROM
-
维护者信息指令 MAINTAINER
-
镜像操作指令 RUN 、 EVN 、 ADD 和 WORKDIR 等
-
容器启动指令 CMD 、 ENTRYPOINT 和 USER 等
通过Dockerfile 构建Tomcat 镜像
创建目录tomcat,用于存放后面的相关东西
# webapps目录将映射为tomcat容器配置的应用程序目录、logs目录将映射为tomcat容器的日# 志目录、conf目录里的配置文件将映射为tomcat容器的配置文件
mkdir -p ~/tomcat/webapps ~/tomcat/logs ~/tomcat/conf
进入创建的tomcat目录,创建Dockerfile
FROM openjdk:8-jre
ENV CATALINA_HOME /usr/local/tomcat
ENV PATH $CATALINA_HOME/bin:$PATH
RUN mkdir -p "$CATALINA_HOME"
WORKDIR $CATALINA_HOME
# 可以直接访问 https://hub.docker.com/_/tomcat/
# 选择代码仓库,里面就有Dockerfile,
# 自己复制下来然后自定义修改就行
EXPOSE 8080
CMD ["catalina.sh", "run"]
通过Dockerfile创建一个镜像,并命名。
docker build -t tomcat2.
创建完成后,我们可以在本地的镜像列表里查找到刚刚创建的镜像
docker images|grep tomcat2
# 运行容器
# 将主机中当前目录下的test挂载到容器的/test
docker run --name tomcat -p 8080:8080 -v $PWD/test:/usr/local/tomcat/webapps/test -d tomcat
0x06 总结
至此就把Docker的一些基本的概念和使用进行了简单总结,看了一些资料,自己对Docker也有了一些了解和认识,特别是它设计一个理念和架构,对于复杂的应用开发部署真的做到了简单高效,上面总结了Docker应用的优势和基础的架构,自己也亲自装了Docker并创建了一些容器实例,熟悉了Docker的一些常用指令和使用Dockerfile创建Image,也算是一个简单的入门吧。因为接触并不是很多,至于它的具体应用场景个人还是不太清楚,但个人认为应该是很有应用前景的。