Docker新手宝典(必备)

目录

•写在前面

•为啥我们要用Docker?

•Docker核心组件

Docker客户端和服务器

Docker镜像

Docker 容器

Registry

•安装Docker

•Docker上手使用

使用DockerHub

Dockerfile是啥

运行服务器Web程序

•Docker指令汇总以及学习地址汇总

Docker常用指令

Dockerfile常用指令


•写在前面

如果使用上了Docker,我觉得你肯定会被它吸引住,因为它可以帮助保证应用程序快速、可靠、一致地部署,妈妈再也不用担心我换机子跑程序又要装环境,部署出Bug了。用一个形象的比喻来形容就是,如果你爱上了GitHub,我相信你也会爱上Docker。咱们言归正传,学习这一篇文章你可以学到什么?

  • 清晰的Docker架构层级(这个还是很重要的,脑子里有清晰的架构,学啥都明明白白的);
  • Docker在Linux上的安装
  • Docker上手使用(运行一个程序,透过使用了解流程)
  • Docker指令汇总以及深入学习地址汇总(授人以鱼不如授人以渔嘛,可以随手当做参考手册,也告诉你怎么深入学习)

宝典在手,天下我有,赶紧继续学下去(觉得看完有收获的点个关注和给个赞吧!!!)。

•为啥我们要用Docker?

如果我们开发一个应用,需要在不同的机子上运行,这个时候我们会怎么办?打包程序,然后在新的机子上安装系统、环境、各种依赖、各种配置、服务器,一切准备好了之后,就开始跑程序。这个流程不仅效率低,而且过程中还容易出现各种问题,甚至可能因为环境没有配置好,导致原本正常的程序运行时出现问题,很让人苦恼。这个时候如果我们能打包整个环境依赖以及程序,那么是不是换新机子的时候,就可以直接运行了。说到这里,可能很多人会想到用虚拟机,毕竟虚拟机可以模拟整个操作系统级的环境甚至硬件,不过我这里要告诉你,Docker比虚拟机更好用,至于为什么。你接着往下看就知道了。

我们用的传统虚拟机如 VMware , VisualBox 之类的需要模拟整台机器包括硬件,每台虚拟机都需要有自己的操作系统,虚拟机一旦被开启,预分配给它的资源将全部被占用。每一台虚拟机包括应用,必要的二进制和库,以及一个完整的用户操作系统。而Docker使用的容器技术是和我们的宿主机共享硬件资源及操作系统,可以实现资源的动态分配。容器包含应用和其所有的依赖包,但是与其他容器共享内核。容器在宿主机操作系统中,在用户空间以分离的进程运行。容器技术是实现操作系统虚拟化的一种途径,可以让您在资源受到隔离的进程中运行应用程序及其依赖关系。通过使用容器,我们可以轻松打包应用程序的代码、配置和依赖关系,将其变成容易使用的构建块,从而实现环境一致性、运营效率、开发人员生产力和版本控制等诸多目标。容器可以帮助保证应用程序快速、可靠、一致地部署,其间不受部署环境的影响。容器还赋予我们对资源更多的精细化控制能力,让我们的基础设施效率更高。我们可以通过下面这幅图我们可以很直观的反映出这两者的区别。

我们看上图,对于容器有个大致的认识,不过还是不够直观,那么我们把真实的应用放在这个层级中,大概就是下面这个图的样子。

要注意,容器不是模拟一个完整的操作系统,而是对进程进行隔离,相当于是在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了Docker,就不用担心环境问题。总体来说, Docker 的接口相当简单,用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。它还有DockerHub哦,和GitHub一样提供托管服务,非常方便,后面我们会讲到。总结Docker的优势就是

  • docker 启动快速属于秒级别。虚拟机通常需要几分钟去启动
  • docker 需要的资源更少, docker 在操作系统级别进行虚拟化, docker 容器和内核交互,几乎没有性能损耗,性能优于通过 Hypervisor 层与内核层的虚拟化
  • docker 更轻量, docker 的架构可以共用一个内核与共享应用程序库,所占内存极小。同样的硬件环境, Docker 运行的镜像数远多于虚拟机数量,对系统的利用率非常高
  • 与虚拟机相比, docker 隔离性更弱, docker 属于进程之间的隔离,虚拟机可实现系统级别隔离
  • 安全性: docker 的安全性也更弱。 Docker 的租户 root 和宿主机 root 等同,一旦容器内的用户从普通用户权限提升为root权限,它就直接具备了宿主机的root权限,进而可进行无限制的操作。虚拟机租户 root 权限和宿主机的 root 虚拟机权限是分离的,并且虚拟机利用如 Intel 的 VT-d 和 VT-x 的 ring-1 硬件隔离技术,这种隔离技术可以防止虚拟机突破和彼此交互,而容器至今还没有任何形式的硬件隔离,这使得容器容易受到攻击
  • 可管理性: docker 的集中化管理工具还不算成熟。各种虚拟化技术都有成熟的管理工具,例如 VMware vCenter 提供完备的虚拟机管理能力
  • 高可用和可恢复性: docker 对业务的高可用支持是通过快速重新部署实现的。虚拟化具备负载均衡,高可用,容错,迁移和数据保护等经过生产实践检验的成熟保障机制, VMware 可承诺虚拟机 99.999% 高可用,保证业务连续性
  • 快速创建、删除:虚拟化创建是分钟级别的, Docker 容器创建是秒级别的, Docker 的快速迭代性,决定了无论是开发、测试、部署都可以节约大量时间
  • 交付、部署:虚拟机可以通过镜像实现环境交付的一致性,但镜像分发无法体系化。 Docker 在 Dockerfile 中记录了容器构建过程,可在集群中实现快速分发和快速部署

相比虚拟机我们可以简单的这么说他们的区别

特性容器虚拟机
隔离级别进程级操作系统级
隔离策略CGroupsHypervisor
系统资源0%~5%5%~15%
启动时间秒级分钟级
镜像存储KB-MBGB-TB
集群规模上万上百
高可用策略弹性、负载、动态备份、容灾、迁移

•Docker核心组件

  • Docker客户端和服务器;
  • Docker 镜像;
  • Registry;
  • Docker 容器;

Docker客户端和服务器

Docker是一个客户-服务器(C/S)架构的程序。Docker客户端只需向Docker服务器或 守护进程发出请求,服务器或守护进程将完成所有工作并返回结果。Docker提供了一个命 令行工具docker以及一整套RESTful API®。你可以在同一台宿主机上运行Docker守护进 程禾口客户端,也可以从本地的Docker客户端连接到运行在另一台宿主机上的远程Docker守 护进程。

Docker Client ,也称 Docker 客户端。它其实就是 Docker 提供命令行界面 (CLI) 工具,是许多 Docker 用户与 Docker 进行交互的主要方式。客户端可以构建,运行和停止应用程序,还可以远程与Docker_Host进行交互。最常用的 Docker 客户端就是 docker 命令,我们可以通过 docker 命令很方便地在 host 上构建和运行 docker 容器,说白了就是在命令行中使用docker客户端部分,如下如查看相关信息。

Docker daemon 是服务器组件,以 Linux 后台服务的方式运行,是 Docker 最核心的后台进程,我们也把它称为守护进程。它负责响应来自 Docker Client 的请求,然后将这些请求翻译成系统调用完成容器管理操作。该进程会在后台启动一个 API Server ,负责接收由 Docker Client 发送的请求,接收到的请求将通过Docker daemon 内部的一个路由分发调度,由具体的函数来执行请求,如下如查看相关信息。

Docker镜像

Docker 镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。镜像(Image)就是一堆只读层(read-only layer)的统一视角,也许这个定义有些难以理解,我们看看下面的图。

我们看到了多个只读层,它们重叠在一起。除了最下面一层,其它层都会有一个指针指向下一层。这些层是Docker 内部的实现细节,并且能够在主机的文件系统上访问到。统一文件系统 (union file system) 技术能够将不同的层整合成一个文件系统,为这些层提供了一个统一的视角,这样就隐藏了多层的存在,在用户的角度看来,只存在一个文件系统。我们可以在图片的右边看到这个视角的形式。镜像有多种生成方法:

  • 从无到有开始创建镜像
  • 下载并使用别人创建好的现成的镜像
  • 在现有镜像上创建新的镜像

 

 

 

 

Docker 容器

容器 (container) 的定义和镜像 (image) 几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。

由于容器的定义并没有提及是否要运行容器,所以实际上,容器可以简单的理解成:镜像加上读写层。

Registry

Docker 仓库是集中存放镜像文件的场所。镜像构建完成后,可以很容易的在当前宿主上运行,但是, 如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry (仓库注册服务器)就是这样的服务。有时候会把仓库 (Repository) 和仓库注册服务器 (Registry) 混为一谈,并不严格区分。Docker 仓库的概念跟 Git 类似,注册服务器可以理解为 GitHub 这样的托管服务。实际上,一个 Docker Registry 中可以包含多个仓库 (Repository) ,每个仓库可以包含多个标签 (Tag),每个标签对应着一个镜像。所以说,镜像仓库是 Docker 用来集中存放镜像文件的地方类似于我们之前常用的代码仓库。

通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本 。我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签.。仓库又可以分为两种形式:

  • public(公有仓库)
  • private(私有仓库)

Docker Registry 公有仓库是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。

除了使用公开服务外,用户还可以在本地搭建私有 Docker Registry 。Docker 官方提供了 Docker Registry 镜像,可以直接使用做为私有 Registry 服务。当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。

•安装Docker

这里为了不让这篇文章那么长,我直接贴我的另一篇文章,里面有Ubuntu16以及Windows10的安装方法,文章,算是最新的安装了,当然这里要提醒的一个是,如果你在Windows10 中安装出现了系统VMware与Hyper-V出现冲突的情况,可以查看我的另一篇文章,这里讲解了怎么解决这个冲突。

•Docker上手使用

使用DockerHub

首先登陆DockerHub,创建一个仓库,流程如下图

创建完毕之后如下图

这里我们通过Dockerfile创建一个docker镜像,后面我们具体讲Dockerfile,这里先用着。我们随机创建一个目录,然后再目录中创建Dockerfile,Dockerfile具体指令如下(我这里使用的Ubuntu16):

cat > Dockerfile <<EOF
FROM busybox
CMD echo "Hello world! This is my first Docker image."
EOF

编辑好之后保存,然后继续执行下面创建镜像

docker build -t <your_username>/my-first-repo .  
#注意这里的“.”,“.”意味着执行所在目录的Dockerfile

创建完毕之后,运行你的本地镜像,会创建一个容器进行执行,注意了,镜像不是用来执行,容器用来执行,创建过程大概像下面这样。

你可以执行了,使用下面指令

docker run <your_username>/my-first-repo
#如我的docker run dengbocong/hello-world

#执行之后可以提交到远程的DockerHub,指令如下
docker push <your_username>/my-first-repo

#查看当前镜像
docker images

#查看当前所有容器
docker ps -a

现在我们再通过hello-world这个例子来体会了Docker 各个组件是如何协作的。容器启动过程如下:

  • Docker 客户端执行 docker run 命令
  • Docker daemon 发现本地没有 hello-world 镜像
  • daemon 从 Docker Hub 下载镜像
  • 下载完成,镜像 hello-world 被保存到本地
  • Docker daemon 启动容器

Dockerfile是啥

Dockerfile 是镜像和容器的关键,并且 Dockerfile 还可以很轻易的去定义镜像内容。Dockerfile 是自动构建 docker 镜像的配置文件, 用户可以使用 Dockerfile 快速创建自定义的镜像。Dockerfile 中的命令非常类似于 linux 下的 shell 命令。我们可以通过下面这幅图来直观地感受下 Docker 镜像、容器和 Dockerfile 三者之间的关系。

我们从上图中可以看到, Dockerfile 可以自定义镜像,通过 Docker 命令去运行镜像,从而达到启动容器的目的。Dockerfile 是由一行行命令语句组成,并且支持已 # 开头的注释行。一般来说,我们可以将 Dockerfile 分为四个部分:

  • 基础镜像(父镜像)信息指令 FROM
  • 维护者信息指令 MAINTAINER
  • 镜像操作指令 RUN 、 EVN 、 ADD 和 WORKDIR 等
  • 容器启动指令 CMD 、 ENTRYPOINT 和 USER 等

这里举一个简单的Dockerfile例子,进行讲解

FROM python:2.7
MAINTAINER Angel_Kitty <angelkitty6698@gmail.com>
COPY . /app
WORKDIR /app
RUN pip install -r requirements.txt
EXPOSE 5000
ENTRYPOINT ["python"]
CMD ["app.py"]

我们可以分析一下上面这个过程:

  • 从 Docker Hub 上 pull 下 python 2.7 的基础镜像
  • 显示维护者的信息
  • copy 当前目录到容器中的 /app 目录下 复制本地主机的 <src> ( Dockerfile 所在目录的相对路径)到容器里 <dest>
  • 指定工作路径为 /app
  • 安装依赖包
  • 暴露 5000 端口
  • 启动 app

这个例子是启动一个 python flask app 的 Dockerfile ( flask 是 python 的一个轻量的 web 框架),相信大家从这个例子中能够稍微理解了Dockfile的组成以及指令的编写过程。

运行服务器Web程序

我们前面跑了简单的Docker,有了解了Dockerfile是啥,那么这里我们进一步来在Docker中跑一个服务器程序,这里使用Dockerfile进行构建镜像,很简单的哦。首先创建目录以及Dockerfile,指令如下


mkdir static_web
cd static_web
touch Dockerfile

然后使用vim编辑Dockerfile,内容如下,编辑完保存退出

FROM nginx
MAINTAINER Name <email>
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

我们在 Dockerfile 文件所在目录执行,结果如下:

docker build -t angelkitty/nginx_web:v1 .
#解释一下, -t 是为新镜像设置仓库和名称,其中 angelkitty 为仓
#库名, nginx_web 为镜像名, :v1 为标签(不添加为默认 latest )

#构建之后,使用如下指令运行
docker run --name nginx_web -d -p 8080:80   angelkitty/nginx_web:v1

这条命令会用 nginx 镜像启动一个容器,命名为 nginx_web ,并且映射了 8080 端口,这样我们可以用浏览器去访问这个 nginx 服务器:http://localhost:8080/ 或者 http://本机的IP地址:8080/,页面返回信息:

•Docker指令汇总以及学习地址汇总

Docker常用指令

docker info #查看信息
docker version #查看版本信息
docker --help #查看docker指令详情

docker run -i -t ubuntu /bin/bash #创建容器
docker run --name firstContainer -d ubuntu /bin/bash #创建容器,不附在容器上,俗称守护型容器
exit #退出指令

docker run --name firstContainer -i -t ubuntu /bin/bash #容器命名
docker start firstContainer 
#或者 
docker start 容器ID
docker stop firstContainer 
#或者 
docker stop 容器ID
docker attach firstContainer #重新附在会话上
#或者 
docker attach 容器ID

docker logs firstContainer #获取容器的日志,可以通过Ctrl C退出日志跟踪
docker logs -f firstContainer #输入最后几条日志项
docker logs -ft firstContainer #加时间戳

docker top firstContainer #查看容器内部运行的进程
docker exec -d firstContainer touch /etc/new_config_file #与后台运行的容器进行交互

docker run --restart=always --name firstContainer -d ubuntu #自动启动
docker inspect firstContainer

docker rm 容器ID
docker images #查看当前镜像
docker ps #查看当前正在运行的容器
docker ps -a #查看所有容器

docker pull ubuntu
#或者
docker pull ubuntu:标签名

docker search ubuntu #从docker hub上公共可用查看镜像
docker login  #登录到docker hub 信息会被保存在$HOME/.dockercfg

docker commit -m "A new custom image" --author "dengbocong" 容器id 用户名/仓库名:标签    
#现在不推荐使用

docker inspect 用户名/仓库名:标签

docker build -t 用户名/仓库名:标签 .       
#没有标签,docker将会自动为镜像设置一个latest标签,最后的“.”告诉docker去哪里找dockerfile

或者docker build -t 用户名/仓库名:标签 git@github.com:用户名/仓库名     
#这里Docker假设在这个Git仓库的根目录下存在Dockerfile文件。

docker build --no-cahe -t 用户名/仓库名:标签 . 
docker history 镜像ID
docker run -d -p 80 --name 名字 用户名/仓库名 运行命令
docker push 用户名/仓库名
docker rmi 用户名/仓库名
docker rmi 用户名/仓库名 'docker images -a -q'

Dockerfile常用指令

FROM:FROM 是用于指定基础的 images ,一般格式为 FROM <image> or FORM <image>:<tag> ,所有的 Dockerfile 都用该以 FROM 开头,FROM 命令指明 Dockerfile 所创建的镜像文件以什么镜像为基础,FROM 以后的所有指令都会在 FROM 的基础上进行创建镜像。可以在同一个 Dockerfile 中多次使用 FROM 命令用于创建多个镜像。比如我们要指定 python 2.7 的基础镜像,我们可以像如下写法一样:

FROM python:2.7
MAINTAINER
MAINTAINER 
#是用于指定镜像创建者和联系方式,一般格式为 MAINTAINER <name> 。这里设置成ID 和邮箱:

MAINTAINER Angel_Kitty <angelkitty6698@gmail.com>

COPY:COPY 是用于复制本地主机的 <src> (为 Dockerfile 所在目录的相对路径)到容器中的 <dest>。当使用本地目录为源目录时,推荐使用 COPY 。一般格式为 COPY <src><dest> 。例如我们要拷贝当前目录到容器中的 /app 目录下,我们可以这样操作:

COPY . /app
WORKDIR
WORKDIR 
#用于配合 RUN,CMD,ENTRYPOINT 命令设置当前工作路径。可以
#设置多次,如果是相对路径,则相对前一个 WORKDIR 命令。默认
#路径为/。一般格式为 WORKDIR /path/to/work/dir 。例如我们
#设置/app 路径,我们可以进行如下操作:

WORKDIR /app


RUN:RUN 用于容器内部执行命令。每个 RUN 命令相当于在原有的镜像基础上添加了一个改动层,原有的镜像不会有变化。一般格式为 RUN <command> 。例如我们要安装 python 依赖包,我们做法如下:

RUN pip install -r requirements.txt
EXPOSE
EXPOSE #命令用来指定对外开放的端口。一般格式为 EXPOSE <port> [<port>...]
#例如上面那个例子,开放5000端口:

EXPOSE 5000
ENTRYPOINT
ENTRYPOINT 
#可以让你的容器表现得像一个可执行程序一样。一个 Dockerfile 中
#只能有一个 ENTRYPOINT,如果有多个,则最后一个生效。

ENTRYPOINT 命令也有两种格式:

ENTRYPOINT ["executable", "param1", "param2"] :推荐使用的 exec形式
ENTRYPOINT command param1 param2 :shell 形式
#例如下面这个,我们要将 python 镜像变成可执行的程序,我们可以这样去做:

ENTRYPOINT ["python"]

CMD:CMD 命令用于启动容器时默认执行的命令,CMD 命令可以包含可执行文件,也可以不包含可执行文件。不包含可执行文件的情况下就要用 ENTRYPOINT 指定一个,然后 CMD 命令的参数就会作为ENTRYPOINT的参数。

CMD 命令有三种格式:

CMD ["executable","param1","param2"]  #推荐使用的 exec 形式。
CMD ["param1","param2"]   #无可执行程序形式
CMD command param1 param2   #shell 形式。

一个 Dockerfile 中只能有一个CMD,如果有多个,则最后一个生效。而 CMD 的 shell 形式默认调用 /bin/sh -c 执行命令。CMD 命令会被 Docker 命令行传入的参数覆盖:docker run busybox /bin/echo Hello Docker 会把 CMD 里的命令覆盖。

地址汇总(欢迎评论更新)

ECS上搭建Docker(CentOS7)

菜鸟教程

DockerInfo

Docker官网文档

 

最后,觉得看完有收获的点个关注和给个赞吧!!!

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
作为一个Docker新手,以下是一些学习Docker的步骤和资源: 1. 理解Docker的基本概念:Docker是一个开源的容器化平台,可以帮助开发者将应用程序打包到独立、可移植的容器中。了解Docker的基本概念,如镜像容器仓库等,是学习Docker的第一步。 2. 安装Docker:在学习Docker之前,需要先在你的机器上安装Docker。根据你的操作系统不同,可以在Docker官方网站上找到相应的安装指南。 3. 学习Docker命令:掌握一些常用的Docker命令是非常重要的。例如,`docker run`用于创建和运行一个容器,`docker build`用于构建一个镜像,`docker pull`用于从仓库中拉取镜像等等。可以通过查阅Docker官方文档或者一些在线教程学习这些命令的用法。 4. 创建自己的Docker镜像:学会创建自己的Docker镜像是非常有用的。你可以通过编写一个Dockerfile来定义镜像的构建过程,并使用`docker build`命令构建镜像。 5. 使用Docker Compose:Docker Compose是一个用于定义和运行多容器Docker应用程序的工。学习使用Docker Compose可以帮助你更好地管理和编排多个容器。 6. 探索Docker生态系统:Docker生态系统非常丰富,有许多与Docker相关的工和技术。例如,Kubernetes是一个用于容器编排和管理的开源平台,可以进一步扩展你的Docker技能。 此外,你还可以参考一些在线资源,如Docker官方文档、Docker的教程和博客文章等来深入学习Docker。希望以上信息对你有帮助!如果你还有其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值