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容器存在以下几个特点:
- 更快的启动速度:因为Docker直接运行与宿主内核,无需启动完整的操作系统,因此启动速度属于秒级别,而虚拟机通常需要几分钟去启动。
- 更高效的资源利用率:由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker对系统资源的利用率更高。
- 更高的系统支持量:Docker的架构可以公用一个内核与共享应用程序库,所占内存极小。同样的硬件环境,Docker运行的镜像数远多于虚拟机数量,对系统的利用率非常高。
- 持续交付与部署:对开发和运维人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。使用Docker可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过Dockerfile来进行镜像构建,并进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至进行自动部署。
- 更轻松的迁移:由于Docker确保了执行环境的一致性,使得应用的迁移更加容易。Docker可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻松的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
- 更轻松的维护与扩展:Docker使用的分层存储以及镜像的技术,使得应用重复补发的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker团队同各个开源项目团队一起维护了一大批高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。
- 更弱的隔离性:Docker属于进程之间的隔离,虚拟机可实现系统级别隔离。
- 更弱的安全性: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中可以包含多个仓库;每个仓库可以包含多个标签;每个标签对应一个镜像,其中标签可以理解为镜像的版本号。
三、手工构建
- 准备工作
- 安装docker
- 配置docker关联私有镜像库
- 编译好的部署包
- 安装docker
配置docker关联私有镜像库
绑定公司内部harbor镜像库。
docker login harbor.com.cn
- 手工构建镜像
目的:将注册中心部署在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 - 发布镜像
实操
- 下载镜像
docker pull java:8
- 查看本机镜像
docker image ls
- 以后台方式启动镜像,并映射端口
docker run -it -d -p 8000:80 java:8
docker run -it -i 表示交互式操作,-t为终端。我们这里打算进入bash执行一些命令并查看返回结果,因此我们需要交互式终端。-d后台启动 -p映射容器的80端口到宿主的8000端口中 -rm 容器推出后随之将其删除
- 查找以后台方式启动的容器id并记录下来
docker ps
如果输入docker ps没能找到,说明该镜像的CMD命令执行有问题。解决方法可以通过dockerfile覆盖CMD命令的方式来重新构建。
- 复制本地文件中编译和的部署包到容器中
docker cp F:\\build\\cloud-register-server 40bee2cfca54:\\opt\\cloud-register-server
- 进入容器中进行操作
> 在第4步中,可以手工将服务启动起来。然后在宿主机器上访问以下地址进行验证:http://localhost:8000
- 将容器打包成镜像并指定tag(按需操作)docker commit 40bee2cfca54 harbor.bluemoon.com.cn/rancher/cloud-register-server:test
- 将本地的镜像发布到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 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
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命令:
curl http://localhost:80
7.发布镜像
接下来我们发布这个镜像到harbor。首先给这个镜像打上一个tag(可选):
# 打tag
docker tag vuedemo harbor.com.cn/rancher/vuedemo:test
# 推送
docker push harbor.bluemoon.com.cn/rancher/vuedemo:test
以上是关于Docker入门的主要内容,如果未能解决你的问题,请参考以下文章