Docker入门

Posted susanhonly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker入门相关的知识,希望对你有一定的参考价值。

目    录
一、docker简要
二、docker基本概念
三、手工构建
四、Dockerfile构建
 
一、docker简要
什么是docker
  Docker是一个开放源代码软件项目,项目主要代码在2013年开源于GitHub。它是云服务技术上的一次创新,让应用程序部署在软件容器下的工作可以自动化进行,借此在Linux操作系统上,提供一个额外的软件抽象层,以及操作系统曾虚拟化的自动管理机制。
  Docker利用Linux核心中的资源分脱机制,例如cgroups,以及Linux核心名字空间(name space),来创建独立的软件容器(containers),属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其他的隔离的进程,因此也称其为容器。Docker在容器的基础上进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护,使得其比虚拟机技术更为轻便、快捷。Docker可以在单一Linux实体下运行,避免因为创建一个虚拟机而造成的额外负担。
 
Docker和虚拟机的区别与特点
  对于新手来说,第一个觉得困惑的地方可能就是不清楚Docker和虚拟机之间到底是什么关系。以下两张图分别介绍了虚拟机与Docker容器的结构。
技术图片
 
技术图片
技术图片
  对于虚拟机技术来说,传统的虚拟机需要模拟整台机器包括硬件,每台虚拟机都需要有自己的操作系统,虚拟机一旦被开启,预分配给它的资源将全部被占用。每一个虚拟机包括应用,必要的二进制和库,以及一个完整的用户操作系统。
技术图片
 
技术图片
  容器技术和我们的宿主机共享硬件资源及操作系统,可以实现资源的动态分配。容器包含应用和其所有的依赖包,但是与其他容器共享内核。容器在宿主机操作系统中,在用户空间以分离的进程运行。容器没有自己的内核,也没有进行硬件虚拟。
  具体来说与虚拟技术对比,Docker容器存在以下几个特点:
  1. 更快的启动速度:因为Docker直接运行与宿主内核,无需启动完整的操作系统,因此启动速度属于秒级别,而虚拟机通常需要几分钟去启动。
  2. 更高效的资源利用率:由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker对系统资源的利用率更高。
  3. 更高的系统支持量:Docker的架构可以公用一个内核与共享应用程序库,所占内存极小。同样的硬件环境,Docker运行的镜像数远多于虚拟机数量,对系统的利用率非常高。
  4. 持续交付与部署:对开发和运维人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。使用Docker可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过Dockerfile来进行镜像构建,并进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至进行自动部署。
  5. 更轻松的迁移:由于Docker确保了执行环境的一致性,使得应用的迁移更加容易。Docker可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻松的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
  6. 更轻松的维护与扩展:Docker使用的分层存储以及镜像的技术,使得应用重复补发的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker团队同各个开源项目团队一起维护了一大批高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。
  7. 更弱的隔离性:Docker属于进程之间的隔离,虚拟机可实现系统级别隔离。
  8. 更弱的安全性:Docker的租户root和宿主机root等同,一旦容器内的用户从普通用户权限提升为root权限,它就直接具备了宿主机的root权限,进而可进行无限制的操作。虚拟机租户root权限和宿主机的root虚拟机权限是分离的,并且利用硬件隔离技术可以防止虚拟机突破和彼此交互,而容器至今还没有任何形式的硬件隔离,这使得容器容易受到攻击。
 
docker版本
Docker提供了两个版本:社区版(CE)和企业版(EE)。
Docker社区版(CE)是开发人员和小型团队开始使用Docker并尝试使用基于容器的应用的理想之选。Docker CE有两个更新渠道,即stable和edge;
  • Stable每个季度为您提供可靠更新;
  • Edge每个月为您提供新功能
 
受支持平台
Docker CE和EE可用于多种平台、云和内部部署。使用下表选择适用于您的最佳安装路径。
 
桌面
Platform
Docker CE x86_64
Docker CE ARM
Docker EE
Docker for Mac(macOS)
yes
   
Docker for Windows(Microsoft Windows 10)
yes
   
 
Platform
Docker CE x86_64
Docker CE ARM
Docker EE
Amazon WebServices
yes
 
yes
Microsoft Azure
yes
 
yes
 
服务器
Platform
Docker CE x86_64
Docker CE ARM
Docker EE
CentOS
yes
 
yes
Debian
yes
yes
 
Fedora
yes
   
Microsoft Windows Server 2016
   
yes
Orcal Linux
   
yes
Red Hat Enterprise Linux
   
yes
SUSE Linux Enterprise Server
   
yes
Ubuntu
yes
yes
yes
 
二、docker基本概念
核心概念:镜像、容器于仓库 Docker主要包含三个基本概念,分别是镜像、容器和仓库,理解了这三个概念,就理解了Docker的整个生命周期。以下简要总结一下这三点,详细介绍可以移步Docker从入门到实践对应章节。
 
  • 镜像:Docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
  • 容器:容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的读理的命名空间。容器可以被创建、启动、停止、删除和暂停等等,说到镜像与容器之间的关系,可以类比面向对象程序设计中的类和实例。
  • 仓库:镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其他服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务。一个Docker Registery中可以包含多个仓库;每个仓库可以包含多个标签;每个标签对应一个镜像,其中标签可以理解为镜像的版本号。
 
三、手工构建
  1. 准备工作
  • 安装docker
  • 配置docker关联私有镜像库
  • 编译好的部署包
 
  1. 安装docker
 
配置docker关联私有镜像库
绑定公司内部harbor镜像库。
docker login harbor.com.cn
 
  1. 手工构建镜像
目的:将注册中心部署在docker中
构建思路:由于注册中心启动需要依赖java环境,所以需要拉取java:8版本的镜像作为母版。拉取了java镜像后以后台的方式启动
 
常用命令
  • docker login harbor.xxx.xxx -登录指定镜像库
  • docker pull image:tag -拉取远程镜像到本地
  • docker run image:tag -加载指定镜像运行容器,扩展参数可以在run后面输入help参数进行查看
  • docker exec -it <id/container_name> bash -进入到正在运行的容器中
  • docker image ls - 列出本地已下载镜像
  • docker image rm [选项] <镜像1> [<镜像2>...] - 删除镜像
  • docker logs <id/container_name> - 查看容器日志
  • docker ps - 列出当前所有正在运行的容器
  • docker ps -l - 列出最近一次启动的容器
  • docker search image_name - 从Docker Hub检索镜像
  • docker history image_name - 显示镜像历史
  • docker push new_image_name - 发布镜像
 
实操
  1. 下载镜像
docker pull java:8

 

  1. 查看本机镜像
docker image ls

 

  1. 以后台方式启动镜像,并映射端口
docker run -it -d -p 8000:80 java:8

 

docker run -it -i 表示交互式操作,-t为终端。我们这里打算进入bash执行一些命令并查看返回结果,因此我们需要交互式终端。-d后台启动 -p映射容器的80端口到宿主的8000端口中 -rm 容器推出后随之将其删除
 
  1. 查找以后台方式启动的容器id并记录下来
docker ps

如果输入docker ps没能找到,说明该镜像的CMD命令执行有问题。解决方法可以通过dockerfile覆盖CMD命令的方式来重新构建。

 
  1. 复制本地文件中编译和的部署包到容器中
docker cp F:\\build\\cloud-register-server 40bee2cfca54:\\opt\\cloud-register-server

 

  1. 进入容器中进行操作
 
> 在第4步中,可以手工将服务启动起来。然后在宿主机器上访问以下地址进行验证:http://localhost:8000
 
  1. 将容器打包成镜像并指定tag(按需操作)docker commit 40bee2cfca54 harbor.bluemoon.com.cn/rancher/cloud-register-server:test
 
  1. 将本地的镜像发布到harbor镜像库中(按需操作)docker push harbor.bluemoon.com.cn/rancher/cloud-register-server:test
 
4.设置端口转发(按需操作)
    需要将容器中的端口映射到宿主中时,有以下两种操作方式。推荐使用方法2。
 
方法1
1.获得容器IP
   将container_name换成实际环境中的容器名
   docker inspect container_name | grep IPAddress
2.iptable转发端口
   将容器的8000端口映射到docker主机的8001端口
   iptable -t nat -A DOCKER -p tcp -dport 8001 -j -DNAT -to-destnation 172.17.0.19:8000
 
方法2
1.提交一个运行中的容器为镜像
   docker commit containerid foo/live
2.运行镜像并添加端口
   docker run -d -p 8000:80 foo/live /bin/bash
 
四、Dockerfile构建
说明
利用Dockerfile构建镜像的方式,可以解决无法重复、镜像构建透明性及镜像体积的问题。Dockerfile是一个文本文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,旧是描述该层应当如何构建。
 
操作
1.关联私有镜像库
在本机上登陆你的harbor账户,以便之后发布使用。本机登录命令:
docker login harbor.com.cn 所谓定制镜像,是指以一个镜像为基础,在其上进行定制修改后产出的镜像。
 
2.创建dockerfile文件
在编译好的目录中(如F:\\build\\bm-unbusiness-admin)新建一个Dockerfile文件,内容如下所示:
# 使用node基础镜像
FROM node:lts
# 创建web服务运行的目录
RUN mkdir /opt/webapp
# 拷贝当前宿主所在目录的文件到容器的/opt/webapp/目录下
COPY . /opt/webapp/
# 切换工作目录
WORKDIR /opt/webapp
# 安装,如不需要考虑镜像大小也可以分开写
RUN npm config set registry https://registry.npm.taobao.org \\ && npm install
# 映射80端口
EXPOSE 80
# RUN npm run devbuild
# 容器启动时运行
CMD npm run dev
 
以上内容中,我们用FROM指定基础镜像,在Docker Store上有非常多的高质量的官方镜像,服务类镜像如nginx、redis、mongo、mysql、httpd、php、tomcat等;各种语言应用镜像如node、openjdk、python、ruby、golang等;操作系统镜像如ubuntu、debian、centos、fedora、alpine。除了选择现有镜像为基础镜像外,Docker还存在一个特殊的镜像,名为scratch。直接FROM scatch会让镜像体积更加小巧。
RUN指令是用来执行命令行命令的。由于我们的例子中只有一行RUN代码,我们来看看多行RUN的情况,如下代码所示:
RUN apt-get unpdate
RUN apt-get install -y gcc libc6-dev make
RUN wget -O redis.tar.gz "http://download.redis.io/release/redis-3.2.5.tar.gz"
RUN mkdir -p /usr/src/redis
RUN tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1
RUN make -C /usr/src/redis
RUN make -C /usr/src/redis install
 
Dockerfile中每一个指令都会建立一层,RUN也不例外。每一个RUN的行为,就和刚才我们手工建立镜像的过程一样:新建立一层,在其上执行这些命令,执行结束后,commit这一层的修改,构成新的镜像。
而上面的这种写法,创建了7层镜像。这是完全没有意义的,而且很多运行时不需要的东西,都被装进了镜像里,比如编译环境、更新的软件包等等。结果就是产生非常臃肿、非常多层的镜像,不仅仅增加了构建部署的时间,也很容易出错。这是很多初学Docker的人常犯的一个错误。
正确的写法应该是这样:
RUN buildDeps=gcc libc6-dev make
    && apt-get update     && apt-get install -y $buildDeps     && wget -O redis.tar.gz "http://download.redis.io/release/redis-3.2.5.tar.gz"     && mkdir -p /usr/src/redis     && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1     && make -C /usr/src/redis     && make -C /usr/src/redis install     && rm -rf /var/lib/apt/lists/*     && rm redis.tar.gz     && rm -r /usr/src/redis     && apt-get purge -y --auto-remove $buildDeps

 

需要注意的是最后添加了清理工作的命令,删除了为了编译构建所需要的软件,清理了所有下载、展开的文件,并且还清理了apt缓存文件。
 
3.执行构建
接着,我们在当前目录开始构建这个镜像吧。
# -t 可以给这个镜像取一个名字(tag)
docker build -t vuedemo .
docker build 命令,其格式如下:
docker build [选项] <上下文路径/URL/->
需要注意的是上下文路径这个概念。在本例中我们用 . 定义,那么什么是上下文环境呢?则合理我们需要了解整个build的工作原理。
Docker在运行时分为Docker引擎(也就是服务端守护进程)和客户端工具。Docker的引擎提供了一组REST API,被称为Docker Remote API,而如docker命令这样的客户端工具,则是通过这组API与Docker引擎交互,从而完成各种功能。因此,虽然表面上我们好像是在本机执行各种docker功能,但实际上,docker build得知这个路径后,会将路径下的所有内容打包,然后上传给Docker引擎。当我们代码中使用了诸如COPY等指令时,服务段会根据该指令复制调用相应的文件。
 
4.检查镜像是否构建成功
构建完毕后,可以通过docker images ls命令镜像查看
 
5.启动容器
接下来,我们运行它(若是要后台运行则记得加上 -d 参数):
docker run -p 8080:80 vuedemo
 
6.验证容器中的服务是否启动正常
验证可以通过浏览器查看效果,如果下要在容器中验证也可以通过curl命令:
 
7.发布镜像
接下来我们发布这个镜像到harbor。首先给这个镜像打上一个tag(可选):
# 打tag
docker tag vuedemo harbor.com.cn/rancher/vuedemo:test
# 推送
docker push harbor.bluemoon.com.cn/rancher/vuedemo:test
 
 

以上是关于Docker入门的主要内容,如果未能解决你的问题,请参考以下文章

Docker 入门

Docker入门教程Docker Registry

Docker部署Rstudio Server【一】:Docker入门

Docker Compose 入门(V3)

Docker入门教程介绍

Docker入门教程命令