Docker入门指南

一、关于Docker

几乎一晚上,Docker就成为了开发者和系统管理员用来打包、部署、运行分布式或云应用的事实标准。它提供了用来简化DevOps的工具,开发者创建叫镜像的模板来创建轻量级的虚拟机,叫做容器,容器包含了程序和程序的所有依赖。这些轻量的虚拟机通过测试和系统管理员部署运行产品的环境来实现。

Docker令大家更容易的自动构建基础设施,独立的应用,维持一致性,提高资源利用。

就像很流行的版本控制软件Git一样,开发者和系统管理员可以通过Doker Hub来分享他们的镜像文件。

Docker是一个开源的解决方案,它提供免费的社区版,和基于捐赠的企业版。Docker最适合在Linux上运行,因为它本来就是由Linux容器构建的,但是它也可以运行在Mac和Windows。许多企业级工具已经出现,使Docker在复杂的分布式和集群架构下更容易管理。

二、Docker架构

Docker使用C/S架构和远程API,来管理和创建Docker容器及镜像。Docker容器通过Docker镜像来创建。容器和镜像的关系类似于面向对象编程中对象和类的关系,镜像描述了容器,容器是镜像的一个运行实例。 此处输入图片的描述

  • Docker镜像 创建Docker容器的方法。包含了安装和运行必须软件的步骤
  • Docker容器 类似很小的虚拟机,由Docker镜像中的架构创建
  • Docker客户端 提供命令行或能使用Docker API高级特性的其它工具(https://docs.docker.com/reference/api/docker_remote_api) ,与Docker后台进程通讯
  • Docker主机 运行Docker后台进程的物理机或虚机,包含了缓存的镜像和从镜像创建出来的可运行的容器
  • Docker Registry 一个Docker镜像仓库,可以用来创建Docker容器。Docker Hub (https://hub.docker.com) 是现在最流行的一个Docker仓库
  • Docker Machine 用来管理多个Docker主机,可以运行在本地的VirtualBox上或远程的云服务上,比如Amazon Web Services, Microsoft Azure, Google Cloud Platform, Digital Ocean

三、入门指南

安装Docker

安装社区版时,Mac和Windows有一些不同。安装Docker比较好的方式是,分别使用Docker for Mac (https://www.docker.com/docker-mac) 或 Docker for Windows (https://www.docker.com/docker-windows) 。安装包含了Docker平台、命令行、组件、公证工具。这个方法的好处是,它使用了本地平台虚拟化可以更好的利用资源。对于Windows,有个额外的好处可以运行Windows容器和Linux容器,但是不能同时运行。

注意:Docker for Windows 需要64位 Windows 10 Professional/Enterprise。

还有一种方法在Mac和Windows安装Docker就是用Docker Toolbox (https://www.docker.com/products/docker-toolbox) 。它包括了Docker平台、命令行(包括Docker Machine)、组件、Kitematic、VirtualBox。Docker Toolbox 的优点是它可以运行在老版本的Windows,还让模拟集群场景容易些。缺点是,它在Virtual Box上运行了Linux虚拟机,需要额外的资源,而且每个虚拟机都需要用一个单独的IP。

对于Linux,每个发行版都有一个Docker安装方法,所以建议你去https://docs.docker.com/engine/installation/ 找指定的安装说明。

Linux可以以root用户安装Docker-Machine,执行下面的命令:


curl -L https://github.com/docker/machine/releases/download/v0.12.2/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine

运行容器

Docker安装完,可以在命令行运行容器了。如果还没有准备好要运行的镜像,Docker会自动的从Docker Hub拉取或下载必要的镜像并执行它来构建容器。

运行一个简单的Hello-world容器确定配置正常,执行下面命令:

docker run --rm hello-world

下载完镜像并且运行容器之后,这个命令会打印 “Hello from Docker!”信息到标准输出说明所有步骤正常的显示了信息。使用--rm选项会自动的移除容器回收磁盘空间。

典型的本地工作流程

Docker有一个典型工作流程使你可以创建镜像、拉取镜像、发布镜像、运行容器。此处输入图片的描述

典型的Docker工作流程包括从Dockerfile构建镜像,Dockerfile包含一些命令用来配置容器或从Docker Registry比如Docker Hub拉取镜像。在Docker环境中有了镜像,可以运行这个镜像,来创建一个容器作为运行环境,它包含了操作系统、软件和镜像描述的配置。举个例子,你会得到一个这样的容器,在Debian系统上运行MySQL5.5,创建了你的web应用需要的一个带用户和表的指定数据库。这些可运行的容器可以被启动和停止就像虚拟机或电脑一样。如果进行了手工配置或者安装了软件,容器可以被提交创建一个新的镜像,以后可以用它来创建容器。最后,当你想与团队或世界分享一个镜像,可以把它推到一个Docker registry上。

从Docker Registry拉取镜像

最简单获取镜像的方式是访问https://hub.docker.com ,找到一个准备好的镜像去创建容器。这有许多通用软件的官方账号比如MySQL、Node.js、Java、Nginx、WordPress,还有由普通的个人创建的数十万个镜像。如果你找到你想要的镜像,比如mysql,执行拉取命令来下载镜像。

docker pull mysql

如果你本地还没有这个镜像,Docker会从Docker Hub下载镜像最新的版本并在本地缓存。如果你不想要最新的版本而是想要一个指定的版本,可以使用一个标签来标示想要的版本。

docker pull mysql:8.0.2

如果你想在拉取镜像后直接运行它,可以省一步,直接使用run命令,这样会在后台自动拉取。

从Dockerfile构建镜像

如果你没找到想要的镜像,或是不信任Docker Hub上的,你可以通过创建一个Dockerfile来创建自己的镜像。Dockerfile包含一些命令来继承已经存在的镜像,你可以添加软件或者个性化设置。

下面是一个简单的例子,你会在一个Dockerfile文件中看到:

FROM mysql:5.5.45
RUN echo America/New_York | tee /etc/timezone && dpkg-reconfigure --frontend noninteractive tzdata

这个Dockerfile表示镜像的创建会继承官方mysql仓库。随后它运行个Linux命令把时区更新到东部时间。

更多的创建Dockerfile的细节后面会提供。

想通过一个包含Dockerfile的目录来创建镜像,使用下面命令:

docker build .

这个命令会创建一个没有名字的镜像。你可以运行这个命令来列出镜像。

docker images

这显示了所有缓存的镜像,包括那些用build命令创建的。

REPOSITORY TAG IMAGE ID VIRTUAL SIZE
<none> <none> 4b9b8b27fb42 214.4 MB
mysql 8.0.2 0da0b10c6fd8 213.5 MB

正如你看到的,build命令创建出的镜像,库名称和标签名称都是<none>。这不易使用,所以你可以用-t选项来命名这个镜像,可以更易使用。

docker build –t est-mysql .

再列出镜像可以看的更明白了。

REPOSITORY TAG IMAGE ID VIRTUAL SIZE
est-mysql latest 4b9b8b27fb42 214.4 MB
mysql 8.0.2 0da0b10c6fd8 213.5 MB`

除了Dockerfile还有一个方法可以创建镜像。你对一个已经存在的镜像直接进入,然后安装软件或手工修改配置来自定义这个镜像。完成后,运行commit命令对运行的容器创建一个镜像。这不是一个好的实践,因为相对于Dockerfile来说,这种方式不可重复,也不能自描述。

运行镜像

要运行一个Docker镜像,你只需要docker run命令跟着一个本地镜像的名字或者Docker Hub上的。通常,Docker镜像需要些额外的配置。多数情况下这已经被环境变量做了,也可以使用-e选项来指定。要长时间运行的进程比如守护进程,你还需要使用-d选项。要开始est-mysql镜像,你应该执行下面的命令来配置MySQLroot用户的密码和一个新数据库,就像Docker Hub上mysql库中文档所写:

docker run -d -e MYSQL_ROOT_PASSWORD=root+1 -e MYSQL_DATABASE=mydb est-mysql

想看运行中的容器,使用Docker ps命令:

docker ps

ps命令列出所有运行中的容器、创建它们的镜像的名字、已经执行的命令、监听的端口、容器的名字。

CONTAINER ID IMAGE COMMAND PORTS NAMES
30645f307114 est-mysql "/entrypoint.sh mysql" 3306/tcp serene_brahmagupta

就像你所看到的上面那个进程,容器的名字是serene_brahmagupta。这是自动生成的名字,不好维护。所以,明确这个容器的名字是一个最佳实践,使用 --name选项在容器启动时提供名字:

docker run --name my-est-mysql -d -e MYSQL_ROOT_PASSWORD=root+1 -e MYSQL_DATABASE=mydb est-mysql

从ps的输出你会注意到,容器正在监听3306端口,但这并不意味着你可以在本地使用mysql命令行或是MySQL Workbench与数据库交互,因为这个端口只可以Docker自己加载的安全的环境访问。要想在外面也能访问,你必须使用-p选项映射端口。

docker run --name my-est-mysql -d -e MYSQL_ROOT_PASSWORD=root+1 -e MYSQL_DATABASE=mydb -p 3306:3306 -d est-mysql

现在你可以连接mysql监听的端口了。但你还必须知道要连接哪个IP。如果你用的Docker for Mac/Windows/Linux ,它就是localhost。使用Docker Toolbox要确定地址,你可以使用docker-machine的ip命令来获得。

docker-machine ip default

使用default作为机器名称,这是安装Docker Toolbox后默认名字,你会收到搭载你的docker容器的机器的IP地址。

有了IP地址,现在你可以用本地的mysql命令行来连接mysql了。

mysql -h 192.168.99.100 -u root -proot+1

停止和启动容器

现在你有一个正在运行的容器,你可以通过容器名字用Docker stop命令来停止它:

docker stop my-est-mysql

容器整个状态已经写入磁盘,在这个状态下想启动它,可以使用start命令:

docker start my-est-mysql

网络容器

有个经常的情况是,一个容器中的应用使用另外一个容器的服务,比如一个web应用访问数据库。可以使用一个容器中mysql命令行访问另外一个容器的mysql数据库来模拟,如下图所示: 此处输入图片的描述

Docker会自动为你创建3个网络。你可以使用下面的命令看到这些包括其它用户自定义的网络:

docker network create mysql-network

如果你想添加容器到这个网络,比如把运行的my-est-mysql容器连接到网络,使用下面的网络连接命令:

docker network connect mysql-network my-est-mysql

也可以在启动容器时,通过--network选项,像这样:

docker run --rm --network mysql-network -it mysql:8.0.2 bash

上面这个例子,你启动了一个会自动移除的MySQL容器,并且用选项在容器中启动了一个交互终端。network选项把它加入了mysql-network网络。bash命令的用处是使容器启动时覆盖默认启动行为。

现在在这个新启动的容器里,你可以连接运行在my-est-mysql容器中的MySQL数据库,使用下面这个命令。-h是主机,用容器的名字:

mysql -h my-est-mysql -u root -p

硬盘映射

还有一个经常的情况,在运行的容器和它的主机之间共享文件夹。比如容器内的数据库,需要从主机获取数据持久化和备份,或是开发中,开发者需要用他们主机上的IDE但代码全在容器里。可以使用-v选项来映射主机目录和容器内的目录。

docker run --name my-est-mysql -d -v /my/host/datadir:/var/lib/msyql -e MYSQL_ROOT_PASSWORD=root+1 -e MYSQL_DATABASE=mydb -p 3306:3306 -d est-mysql

给镜像添加标签

现在你有了一个可运行的镜像,并且验证过了,在发布到仓库之前,使用用户名、镜像名称、版本号给镜像添加上标签是个好主意。你可以使用Docker tag命令:

docker tag est-mysql javajudd/est-mysql:1.0

推镜像到仓库

最后,你准备好了把你的镜像推到Docker Hub,让你的团队或全世界人可以通过一个地址使用。首先,你还没完全准备好,你需要去https://hub.docker.com/ 创建一个账号。其次,你需要使用docker login命令登录。

docker login

当提示时,输入你注册的用户名、密码、email。

现在使用push命令推镜像,标明你的用户名、镜像名、版本号。

docker push javajudd/est-mysql:1.0

过一会,你会收到仓库已经成功被推的消息。如果你再登回到Docker Hub上,你会看到新仓库。 此处输入图片的描述

四、其它命令

列出容器

你已经知道了列出运行中容器的docker ps命令,但要是列出所有状态的容器呢?添加 -a选项,可以看到所有的。

docker ps -a

列出所有容器后,你可以选择哪些要开始,哪些要移除。

移除容器

当你用完容器,与其让它无所事事,不如移除它来回收磁盘空间。要移除容器,使用rm命令:

docker rm my-est-mysql

移除镜像

你已经知道了可以列出所有本地缓存镜像的命令。这些镜像会占据大量空间,从几兆到几百兆字节,所以可以使用rmi命令清除不需要的镜像:

docker rmi est-mysql

在测试生成镜像的时候,也许会生成很多你不想要的没名字的镜像,它们的名字是<none>。你可以用下面这个命令轻松的删除这些不确定的镜像:

docker rmi $(docker images -q -f dangling=true)

列出端口

知道容器暴露出哪些端口是非常有用的,比如3306是访问MySQL的或80是访问web服务的。port命令可以显示暴露的端口。

docker port my-est-mysql

列出进程

如果你想看到容器内所有进程,可以用top命令(类似Linux的top):

docker top my-est-mysql

执行命令

你可以用exec命令在一个运行的容器内执行命令。比如要列出硬盘根目录所有内容,用下面的方法:

docker exec my-est-mysql ls

如果你想以root身份ssh到容器,这有一个exec命令可以进入shell,因为Docker客户端和Docker进程所有的通讯是加密的,所以这个方法是安全的。

docker exec -it my-est-mysql bash`

运行容器

run命令是Docker中最复杂也是最有特色的命令。它可以管理网络配置;管理资源比如内存、CPU、文件系统;还可以安全的配置。访问https://docs.docker.com/reference/run/ 可以看到所有可用的选项。

Dockerfile

就像你已经看到的,Dockerfile 主要作用是创建Docker镜像。它包含了一些指令比如Linux命令,来安装和配置软件。build命令可以引用到你的路径上的Dockerfile或是URL上的,比如GitHub。有了Dockerfile,在同样目录或其子目录下的所有文件,也会作为构建进程的一部分。这对你部署时想用一些脚本或文件去构建是非常有帮助的。

如果你想排除些文件或目录,可以使用.dockerignore文件。

指令

在Dockerfile中的指令按顺序执行。Dockerfile还可以包含用#开头的注释。

这个表格列出了可用的指令。

  • FROM 必须是Dockerfile的第一个指令,指定了继承的镜像
  • MAINTAINER 为镜像作者提供知名度和声望
  • RUN 执行Linux命令
  • ENTRYPOINT 用来启动容器最后的脚本,它应该是个可执行的程序
  • CMD 以JSON数组的格式为ENTRYPOINT提供默认参数
  • LABEL 这个镜像的名字
  • ENV 设置环境变量
  • COPY 拷贝文件进容器
  • ADD 可选的拷贝
  • WORKDIR 为RUN, CMD, ENTRYPOINT, COPY, ADD指令设置工作路径
  • EXPOSE 容器监听的端口
  • VOLUME 创建一个挂载点
  • USER 运行RUN, CMD, ENTRYPOINT指令的用户

Dockerfile例子

这是MySQL 5.5的Dockerfile官方例子,在https://github.com/docker-library/mysql/blob/5836bc9af9deb67b68c32bebad09a0f7513da36e/5.5/Dockerfile ,用了很多指令。

FROM debian:jessie
RUN groupadd -r mysql && useradd -r -g mysql mysql
RUN mkdir /docker-entrypoint-initdb.d
RUN apt-get update && apt-get install -y perl --no-install-recommends && rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y libaio1 && rm -rf /var/lib/apt/lists/*
RUN gpg --keyserver ha.pool.sks-keyservers.net --recv-keys A4A9406876FCBD3C456770C88C718D3B5072E1F5
ENV MYSQL_MAJOR 5.5
ENV MYSQL_VERSION 5.5.45
RUN apt-get update && apt-get install -y curl --no-install-recommends && rm -rf /var/lib/apt/lists/* \
         && curl -SL "http://dev.mysql.com/get/Downloads/MySQL-$MYSQL_MAJOR/mysql-$MYSQL_VERSION-linux2.6-x86_64.tar.gz" -o mysql.tar.gz \
         && curl -SL "http://mysql.he.net/Downloads/MySQL-$MYSQL_MAJOR/mysql-$MYSQL_VERSION-linux2.6-x86_64.tar.gz.asc" -o mysql.tar.gz.asc \
         && apt-get purge -y --auto-remove curl \
         && gpg --verify mysql.tar.gz.asc \
         && mkdir /usr/local/mysql \
         && tar -xzf mysql.tar.gz -C /usr/local/mysql \
         && rm mysql.tar.gz* \
         && rm -rf /usr/local/mysql/mysql-test /usr/local/mysql/sql-bench \
         && rm -rf /usr/local/mysql/bin/*-debug /usr/local/mysql/bin/*_embedded \
         && find /usr/local/mysql -type f -name "*.a" -delete \
         && apt-get update && apt-get install -y binutils && rm -rf /var/lib/apt/lists/* \
         && { find /usr/local/mysql -type f -executable -exec strip --strip-all '{}' + || true; } \
         && apt-get purge -y --auto-remove binutils
ENV PATH $PATH:/usr/local/mysql/bin:/usr/local/mysql/scripts
RUN mkdir -p /etc/mysql/conf.d \
         && { \
                  echo '[mysqld]'; \
                  echo 'skip-host-cache'; \
                  echo 'skip-name-resolve'; \
                  echo 'user = mysql'; \
                  echo 'datadir = /var/lib/mysql'; \
                  echo '!includedir /etc/mysql/conf.d/'; \
         } > /etc/mysql/my.cnf
VOLUME /var/lib/mysql
COPY docker-entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
EXPOSE 3306
CMD ["mysqld"]

这个Dockerfile例子做了下面这些动作:

  • 继承了叫做“debian:jessie”的一个Debian镜像
  • 使用RUN指令配置了镜像,添加了一些组、创建一个目录、用Debian的apt-get包管理来安装软件
  • 用gpg安装一些PGP加密
  • 用ENV指令定义了镜像中MySQL的major版本和镜像版本
  • 运行了非常长的命令来安装和配置系统,接着设置了系统PATH
  • 用RUN命令创建个配置文件
  • 用VOLUME命令映射了文件系统
  • 用COPY 命令拷贝和重命名了脚本,容器启动时,执行ENTRYPOINT指定的脚本
  • 使用EXPOSE 声明3306为MySQL的端口
  • 使用CMD指定ENTRYPOINT 的命令行参数为 “mysqld”

五、Docker Machine

Docker Machine能使用命令行管理本地或远程的多个机器,本地机器经常运行在独立的VirtualBox实例中。远程的机器也许装在云服务中,比如Amazon Web Services (AWS), Digital Ocean, Microsoft Azure。

创建本地机器

当安装了 Docker Toolbox,你得到一个名为“default”的默认Docker Machine。这很方便,但是,你需要多个机器被分割在不同容器中运行。你可以用docker-machine create命令来做:

docker-machine create -d virtualbox qa

使用一个VirtualBox镜像创建了一个叫“qa”的本地机器。

列出机器

如果你想看到已经配置了哪些机器,可以运行docker-machine ls 命令:

docker-machine ls

启动和停止机器

Docker Machine可以用docker-machine start来启动。

docker-machine start qa

一旦机器启动,必须配置Docker命令行关联哪个Docker进程。可以使用docker-machine env命令,eval命令显示它。

docker-machine env qa
eval “$(docker-machine env qa)”

要停止机器,用docker-machine stop命令:

docker-machine stop qa

docker-machine start stop命令直接去启动和停止VirtualBox VM。如果打开了VirtualBox Manager,执行命令时可以看到 VM状态的变化。

六、企业级Docker

想要更好的高适配、高可用、高容错的扩展部署,这有一些不错的工具可用来简化Docker使用。

本文译自 https://dzone.com/refcardz/getting-started-with-docker-1

转载于:https://my.oschina.net/wangbo888/blog/1524818

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值