虚拟化技术的优点
- 一个物理机的资源分配到了不同的虚拟机里
- 很容易扩展,可以加物理机器或者虚拟机
- 很容易云化,亚马逊AWS或阿里云提供虚拟机
虚拟化的局限性
- 每一个虚拟机都需要占用操作系统本身的资源,虚拟机数量增多时,消耗资源也增多。
- 开发和运维面临的挑战是每涉及到相关技术就需要设置环境,当测试环境、开发环境、线上环境之间切换的时候在各种配置和软件安装上就变得非常麻烦,由此引入容器技术,容器就像一个集装箱,它是对软件和其依赖的标准化打包,应用之间相互隔离,共享同一个kernel。
容器和虚拟化技术的区别
image.pngdocker-容器技术的一种实现
docker提供了一个开发,打包,运行app的平台,它把app和底层隔离开来。
image.png
其中docker engine是docker平台的核心。
docker engine
docker engine主要分为三部分:
- 后台进程(dockerd)
- rest api server
- cli接口(docker)
-
docker结构
image.png
从上图可见,docker也是CS架构,client可以访问本地或者远程的host。
docker的三大核心概念--镜像,容器和仓库
- 镜像类似于虚拟机镜像,是一个只读的模板,里面可以包含一个基本的操作系统和需要的应用程序。
- 容器类似于一个沙箱,docker利用容器来运行和隔离应用。容器是从镜像创建的应用运行实例。
- docker仓库是集中存放镜像文件的场所。另外仓库又存放在仓库注册服务器中,不同的仓库通过标签来区分,一个仓库中存放一类镜像文件。
镜像/image
image的概念:
image.png
'
image的获取方式:
- 通过dockerfile获取,在dockerfile同目录下使用docker build命令创建镜像。
- 从仓库(Registry)中pull image,默认的仓库是官方的dockerHub,使用的命令为docker pull
如何自行创建一个base image:
示例:创建一个hello world镜像:
首先在linux环境中建立一个hello-world目录,在其中创建一个hello.c文件,具体代码如下:
#include <stdio.h>
int main() {
printf("hello docker\n");
}
为了编译这个文件,我们需要安装gcc编译器:
sudo yum install gcc
sudo yum install glibc-static
通过执行:
gcc -static hello.c -o hello
生成可执行文件后,在创建一个Dockerfile,把上面生成的可执行文件hello打成一个image,Dockerfile的内容如下:
FROM scratch
ADD hello /
CMD ["/hello"]
最后在Dockerfile所在目录下进行打包生成镜像文件:
docker build -t yubuyun/hello-world .
通过docker iamge ls
命令就可以看到我们做好的镜像文件了。
当我们执行docker run yubuyun/hello-world
命令后就打印出:hello docker,说明成功了。
Container
- 通过image创建(copy)
- 在image layer之上建议一个container layer(可读写)。
-
image负责app的存储和分发,container负责运行app。
image.png
实际上在hello-world示例中docker run 命令就是通过镜像创建并运行一个容器实例。
-
docker container ls
命令,查看正在运行的容器实例。 -
docker container ls -a
命令,查看所有的容器(包括已关闭的)。在显示的列表中有个字段名为COMMAND,这个值就是我们之前在Dockerfile中填的CMD的值,意思是启动容器后自动执行的语句。另外最左边一列字段名为CONTAINER ID,标识容器。 -
docker container rm 容器id
对容器进行删除(包括删除已经结束的) -
docker container ls -a
命令也可以简写为docker ps -a
,docker container rm ...
也可以简写为docker rm ...
,docker image ls
命令也可以简写为docker image
来查看镜像,docker image rm 镜像id
也可以简写为docker rmi 镜像id
来删除镜像。 -
docker container ls -aq
命令列出所有的已经结束的容器实例的id,使用docker rm $(docker container ls -aq)
则可以把所有已经结束的容器全部删除。
示例:
根据镜像ID启动容器实例:
docker run -it IMAGE ID //-it 可以进入容器的终端进行交互
把container 提交成为一个新的image
使用docker commit NAMES IMAGE的命令来基于一个现有的容器创建一个新的镜像。比如我们从centos镜像实例了一个容器,然后在容器上装了vim,当我们使用这个装好vim的容器来创建出一个新的镜像后,这个镜像就已经装好了vim。
使用Dockerfile创建一个镜像
在某个Dockerfile文件中:
FROM centos
RUN yum install -y vim
FROM语句表示镜像的来源,比如之前写的FROM scratch表示没有来源,而FROM centos表示基于centos的镜像。第二句RUN命令表示预先安装vim(-y表示安装的时候都选同意)。当我们使用这个文件来执行docker build -t yubuyun/centos-vim-new .
的时候发现它先创建一个容器,紧接着就在这个容器上安装vim。
Dockerfile语法
- FROM ... :最好是使用官方提供的image作为来源,目的是为了安全
- LABEL 定义了镜像的metadata,类似于注释,其中maintainer表示作者信息,version表示版本信息,description表示镜像的描述。
- RUN :表示预先执行某些命令,由于每执行一次RUN都是在image上加一层,为此尽量将多个命令放到一个RUN中去执行,多个命令之间可以用&&符号进行连接。
- WORKDIR ...:类似于cd,进入指定的目录,使用是尽量使用绝对路径。
- ADD和COPY:表示拷贝某些文件到容器目录中去,如之前执行ADD hello /表示拷贝当前目录下的可执行文件hello到容器的根目录下去。ADD除了和COPY一样具有拷贝的功能外,ADD还具有解压缩的功能,如执行ADD test.tar.gz / 命令则会添加到容器的根目录下并解压。下面是一个ADD 和 WORKDIR命令的配合使用:
WORKDIR /root
ADD hello test/
表示将hello文件拷贝到容器的/root/test/目录下。
- 如果想添加一个远程文件到docker容器中,可以使用curl或者wget命令将远程文件下载到docker容器中。
- ENV ... :设置常量 ,如 ENV MYSQL_VERSION 5.6,之后就可以使用MYSQL_VERSION这个常量了,使用时格式为${MYSQL_VERSION},使用ENV可以增加Dockerfile的可维护性。
上传docker image
- 首先在docker hub上注册。
- 注册完后,执行docker image push(可以简写为docker push)命令:
docker image push yubuyun/hello-world:latest
这样就开始上传自己的镜像了。
拉取docker image
执行:docker pull yubuyun/hello-world
即可从docker hub上拉取image
如何发布和获取仅对自己可见的docker image
此处先略过。
网友评论