Docker是容器技术的一个代表,容器技术从本质上讲是将程序打包隔离的技术,不是核心的技术,核心的技术在内核里面已经存在很久了。但是这个技术变得流行,被大家所用,是因为docker。docker在2013年被开源后发展的很快,docker现在在云计算领域是一个非常火热的话题。为什么呢,任何一个技术要流行起来一般有两个要点,第一:解决了很多痛点,第二:能适应潮流。

Docker解决了软件包中的一个问题,很好的理顺了开发和运维环境的一些差异,使得开发和运维可以使用同一种语言来沟通。另外docker与现在流行的持续集成、持续交付、微服务等概念都是相辅相成的。所以不难理解docker会如此流行。

可以将docker理解为轻量级的虚拟机,但docker优于虚拟机很多:

docker安装(mac):下载docker.dmg后,可在文件目录执行open docker.dmg执行安装。也可以双击文件安装。

docker镜像加速: (详细见官方指导: https://www.docker-cn.com/registry-mirror

途径一:打开docker配置,在advanced里面的Registry mirrors填写一个加速器地址。 去阿里云盟友、dockercloud等注册一个账号,会得到你专属的加速器地址,重启docker daemon就可以了。

途径二:修改docker daemon的JSON配置文件,增加配置项  "registry-mirrors" : [ "https://registry.docker-cn.com" ] 就可以了。 

 

 

docker在Linux下的安装:运行两个命令。 第一个:安装docker。 第二个:允许非root用户运行docker(把用户加入到docker组里面,只要用户在docker组里,用户不需要sudo命令也可以执行docker)。

 

docker架构:

 

docker run -p 8080:80 -d nginx: -p端口映射 -v目录挂载 -d开启Daemon模式,让它在后台运行。

运行完后,本机访问8080端口,就可以正常访问运行在容器里的nginx服务器了。

docker cp index.html <nginx_container_id>://usr/share/nginx/html

将本地目录下的index.html拷贝到容器里面nginx的静态文件目录下,就成功更改nginx服务器的首页了。

docker stop <容器ID>:停止容器。

 

注意:如果退出nginx容器后再重新执行docker run -p 8080:80 nginx启动容器,访问8080端口,出现的还是初始的主页,不是我们改动后的主页。

原因:docker在容器内做的改动都是暂时的,缺省都没有被保存下来,如果保存要做一些另外的操作。

方法:保存到一个新的镜像

docker commit -m 'hello' <要保存的容器ID> : -m 指定注释,这行命令没有给镜像名称,docker images查看时名字显示为<none>。

docker commit -m 'hello' <要保存的容器ID> nginx-hello: 在上行保存镜像命令的基础上给镜像起了名字,实际上是同一个镜像。

 

docker ps: 只显示当前运行的容器。

docker ps -a: 显示运行过的容器。

 

在使用Docker的过程中,我们除了从Docker Hub上下载已经做好的镜像,很多时候需要我们自己制作镜像。

制作镜像的方式主要有两种:

通过docker commit 制作镜像

通过docker build 制作镜像

这两种方式都是通过改进已有的镜像来达到自己的目的。制作基础镜像,会在另外一篇文章“从零开始制作基础镜像”中介绍。

docker commit

docker commit 是往版本控制系统里提交一次变更。使用这种方式制作镜像,本质上是运行一个基础镜像,然后在基础镜像上进行软件安装和修改。最后再将改动提交到版本系统中。

 

docker命令小结:

 

 

 

第3章:Dockerfile介绍

FROM指令:指定基础镜像。                    MAINTAINER指令:指定创建人。  

CMD指令:指定要执行的命令(会写入到镜像的默认执行程序CMD里面)。

docker build -t docker-hello . : -t指定镜像标签TAG 末尾的.表示当前目录

 

rpm包和deb包是两种Linux系统下最常见的安装包格式,在安装一些软件或服务的时候免不了要和它们打交道。

rpm包主要应用在RedHat系列包括 Fedora等发行版的Linux系统上,deb包主要应用于Debian系列包括现在比较流行的Ubuntu等发行版上。

yum可以用于运作rpm包,例如在Fedora系统上对某个软件的管理:
安装:yum install <package_name>
卸载:yum remove <package_name>
更新:yum update <package_name>
apt-get可以用于运作deb包,例如在Ubuntu系统上对某个软件的管理:
安装:apt-get install <package_name>
卸载:apt-get remove <package_name>
更新:apt-get update <package_name>

 

RUN apt-get ubuntu: 更新Ubuntu程序的库。

RUN apt-get install -y nginx: 安装nginx, -y参数告诉它不要来提醒我,不要问我。

COPY index.html /var/www/html :  拷贝index.html到nginx容器里面去。(注意,不同版本的Ubuntu路径是不一样的。)

ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off"]: 入口点,作用是将nginx在前台执行,而不是作为守护进行来执行。

EXPOSE 80: 暴露一个端口。

启动nginx服务后可以:

curl http://localhost:8080: 请求8080端口,很方便测试。 

 

RUN指定在容器内执行的命令。 

ADD功能比COPY更强大。COPY可以拷贝文件或目录,ADD还可以将远程的文件加入到容器里面去,如ftp服务器上的文件。

CMD指定容器执行的入口。也可以用ENTRYPOINT指定。(若同时指定,则ENTRYPOINT作为入口,CMD内容为入口参数。)

EXPOSE暴露端口。假如我们的程序是服务器,则会监听一个或多个端口,则用EXPOSE表述端口。

WORKDIR指定运行命令的路径。

ENV为容器里边的环境设置一些变量。

USER指定执行该命令的用户。通常不会用root来在容器里执行。

VOLUMN指定容器所挂在的卷。

 

 

已经存在于IMAGE镜像里面的层是只读(RO)的,一旦IMAGE被运行成为容器,会产生一个新层,称为容器层。这一层可读可写(RW),这也保证我们的容器是可以被改变的。 

分层的好处在于,假如A镜像有7层,B镜像有10层,他们前面5层是相同的,那么就可以抽出来作为公共镜像C,A、B再用C作为基础镜像来扩展,这样存储压力会小很多。

 

 

第4章 Volumn介绍

Volume:提供独立于容器之外的持久化存储。 

在容器中的改变默认是不会被保存的,Volume提供了一个方便的、可以持久化存储的技巧。比如运行一个数据库容器,数据库真正的数据应该被持久化,Volume就可以做这些事情,并且Volume可以提供给容器与容器之间的共享的数据。

 

第一种:

docker run [-d --name wqnginx] -v /usr/share/nginx/html nginx :    /usr/share/nginx/html是容器内部的地址。-d开启Daemon模式,把它当做一个daemon来运行。--name指定容器名字。-v 是volumn的意思。

该命令会将容器中的/usr/share/nginx/html挂载到用户主机的/var/lib/docker/volumns/<hashcode?>/_data目录,若在Mac电脑上,是找不到这个目录的,Mac通过虚拟层运行了alpha主机,在里边运行docker,所以要进入到alpha才能看到该目录。
docker exec -it nginx /bin/bash: 这个命令进入到已经运行的容器里面去看。

  • -i:表示以“交互模式”运行容器

  • -t:表示容器启动后会进入其命令行

 

第二种:挂载本地目录到容器:

docker run [-p 80:80 -d] -v $PWD/html:/var/www/html nginx: 将当前目录下的html目录挂载到容器/var/www/html目录。

这样带来的方便是只要在本地开发环境更改代码,就能及时发布到测试的nginx服务器上,不需要改好后再打包发布到测试环境。

 

第三种:创建一个仅有数据的容器,并将这个容器挂载到其他容器里面去。

docker run --volumes-from ... : --volumes-from指从另外容器挂载。

docker create -v $PWD/data:/var/mydata  --name data_container ubuntu:  创建一个容器,将本地/data目录挂载到容器/var/mydata目录,指定Ubuntu(latest)作为容器基础镜像。 这样就产生了一个仅有数据的容器,同时仅有数据的容器可被多个容器挂载。

docker run [-it] --volumnes-from data_container ubuntu /bin/bash:运行一个新的容器,把上面容器的数据卷挂载到新的容器,这样数据容器的/var/mydata目录就挂载到了新容器的/var/mydata目录,在新容器的/var/mydata目录做的修改会同步到数据容器的/var/mydata目录,最终也会同步到本地/data目录。

 

 

第5章 registry介绍

registry:镜像仓库,sass服务,为了让大家共享镜像。 在Windows里面是注册表的意思。 

 

宿主机:正在使用的这台计算机。   镜像:远程或本地可以重复使用的软件的打包。   容器:镜像的运行时机。

 registry:镜像仓库。   daemon:守护进程,用来使registry共享,用来接收用户的命令。 客户端:用来给daemon输送命令。

 

和registry的交互:

国内的一些仓库: (官方仓库:dockerhub)

 

registry实战:

docker search whalesay: 从官方仓库搜索,搜索结果按照STARS排序。官方镜像会有official标志。

docker pull docker/whalesay: 好玩的一个镜像,效果:会在控制台用ASCII码画一只鲸鱼,并说一段话。

docker run docker/whalesay cowsay 'Docker很好玩'

docker tag docker/whalesay wangqiang/whalesay: 复制镜像,给不同的tag名,还可设置版本信息。

docker push wangqiang/whalesay: 上传镜像到docker hub,前提是登录了docker hub。

docker login: 登录docker hub。

 

第6章 多容器app

docker-compose(compose:作曲)介绍:

docker-compose
每次我们运行一个容器,都要手动输入一行命令行,比如: docker run -it --name demo -p 3000:3000 riskers/docker-demo

一个容器还好,要是部署一个多容器应用,这些命令行会让人累死,所以有了 docker-compose ,只要写好 docker-compose.yml,
就相当于把命令行参数保存到这个文件,固化了参数。部署的时候,只要执行:

docker-compose up

  之前介绍的都是单容器的应用,这节开始介绍通过compose搭建多容器的应用,docker for Mac/Window自带docker-compose。

 

Linux下安装docker-compose:

Linux的安装基本都是两步:从一个地址下载二进制文件 -- > 将文件变成可以执行的

下载:curl -L https://github.com/docker/compose/releases/download/1.9.0/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose    (uname -s: Linux    -uname -m: x86_64    >:管道符号传输)

修改权限: chmod a+x /usr/local/bin/docker-compose  (a+x:所有人都可以执行)

 

compose实战:

 

 

 

 

 

--------------------------------------------------------------------------------分割线--------------------------------------------------------------------------------

 

总结(docker常用容器操作命令)

查看运行容器:docker ps

查看所有容器:docker ps -a

进入容器:docker exec -it d27bd3008ad9 /bin/bash

停用全部运行中的容器: docker stop $(docker ps -q)

删除全部容器:docker rm $(docker ps -aq)

一条命令实现停用并删除容器:docker stop $(docker ps -q) & docker rm $(docker ps -aq)

 

常见问答(docker问答)
1、docker run -i -t ubuntu /bin/bash 后面的 bin/bash 是什么意思?

这是表示载入容器后运行bash ,docker中必须要保持一个进程的运行,要不然整个容器就会退出。

这个就表示启动容器后启动bash。

需要注意的是,默认有一个--rm=true参数,即完成操作后停止容器并从文件系统移除。因为Docker的容器实在太轻量级了,很多时候用户都是随时删除和新创建容器。

 

2、一个容器(container)映射多个端口到宿主机(Host)?

如果一个参数的选项格式是[],比如
-H=[]       //host
-p=[]       //portdirection
这都意味着这个flag可以多次出现,所以此处可以多次指定端口映射规则。

例:docker run -d -p 80:80 -p 22:22

 

3、疑问:既然可以通过 “docker运行操作系统镜像 --> 在操作系统容器中安装工具和应用 --> docker commit保存为镜像” 的方式创建开发环境,为什么我们还需要使用dockerfile?

解答:

开发环境一旦搭建完后,后期我们基本上很少会懂了,久而久之可能自己都忘了对开发环境做了哪些事情。

团队分享的时候,怎么样让其他人知道你环境配置了什么而不会重复做已有的工作?

时间久了,有些服务要映射哪些端口不记得了怎么办?

这就是dockerfile的作用了。
dockerfile 和 上面的方式差不多,只是用一个文件用docker 指定的方式把我们的做的操作写在了一个文件里而已。 

 

4、在Docker里面npm run dev启动Vue项目,在宿主机上访问不了(浏览器访问URL、或者curl http://localhost:<port>报错:Empty reply from server),但在Docker容器里面浏览器可以正常访问,curl返回也正常?

解答:Vue项目config目录下index.js的host默认配置为'localhost',改为0.0.0.0再在Docker中运行,宿主机就可以正常访问了。

原因:docker里面的host不能配置127.0.0.1 或者192.168.0.1 ,否则宿主机器将无法访问端口。因此redis、nginx的host配置也需要改为0.0.0.0

解释:127.0.0.1只能监听自己回路上的,不能监听网络回路上导致的?

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐