Fork me on GitHub
RainingNight
雨夜朦胧

Docker初体验

断断续续的使用Docker好几年了,但是一直没有全面深入的去了解过,每次用到都是Google一下相关的命令解决临时的问题,到头来却毫无收获。好在,我终于意识到了这个问题,便决定从头开始,耐心的学学Docker,并把学习过程记录下来,方便以后参考,也望与大家交流学习。

本人比较偏爱Ubuntu,故本文所用命令皆基于Ubuntu 16.04,其他版本的命令会有稍有不同,本文不多做介绍。

目录

  1. 简介
  2. 安装
  3. 常用命令
  4. Dockerfile

简介

容器:将软件打包成标准化单元,以用于开发、交付和部署,而 Docker 是世界领先的软件容器平台。

容器镜像是轻量的、可执行的独立软件包,包含软件运行所需的所有内容:代码、运行时环境、系统工具、系统库和设置。

容器 VS 虚拟机:

容器和虚拟机具有相似的资源隔离和分配优势,但功能有所不同,因为容器虚拟化的是操作系统,而不是硬件,因此容器更容易移植,效率也更高。

  • 容器是一个应用层抽象,用于将代码和依赖资源打包在一起。多个容器可以在同一台机器上运行,共享操作系统内核,但各自作为独立的进程在用户空间中运行。与虚拟机相比,容器占用的空间较少(容器镜像大小通常只有几十兆),瞬间就能完成启动。

  • 虚拟机 (VM) 是一个物理硬件层抽象,用于将一台服务器变成多台服务器。管理程序允许多个 VM 在一台机器上运行。每个 VM 都包含一整套操作系统、一个或多个应用、必要的二进制文件和库资源,因此占用大量空间。而且 VM 启动也十分缓慢。

container-vm

安装

准备

首先更新Package索引:

sudo apt-get update

添加Https支持:

sudo apt-get install \
    apt-transport-https \
    ca-certificates \
    curl \
    software-properties-common -y

然后添加Docker官方的GPG key:

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

## 如果上面的地址不能下载,可以使用国内镜像
curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg  | sudo apt-key add -

添加Docker-CE稳定版仓储地址:

sudo add-apt-repository \
   "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \
   $(lsb_release -cs) \
   stable"

由于Docker官方仓储download.docker.com的访问较慢,故使用了中科大镜像源替代。

安装

最后,便可以直接安装了:

sudo apt-get update
sudo apt-get install docker-ce

我们可以运行一下Hello Word来验证一下是否安装成功:

sudo docker run hello-world

默认情况下,Docker需要使用root身份来访问,每次都使用sudo命令较为麻烦,我们可以将当前用户添加到docker用户组来实现非root用户访问:

sudo usermod -aG docker $USER

重新登录一下,便可以不使用sudo命令来操作docker了。

镜像加速

默认情况下,Docker镜像是从Docker官方市场store.docker.com来拉取的,同样非常缓慢,好在Docker官方提供了国内镜像库,可使用如下命令来配置:

docker --registry-mirror=https://registry.docker-cn.com daemon

为了永久性保留更改,可以修改/etc/docker/daemon.json文件并添加上 registry-mirrors 键值:

{
  "registry-mirrors": ["https://registry.docker-cn.com"]
}

修改保存后重启 Docker 以使配置生效:

sudo systemctl restart docker

安装Docker Compose

Docker Compose 是一个用来定义和运行复杂应用的Docker工具。我们的应用通常会由多个容器组成,使用Docker Compose可以非常容易的将一组容器当成一个整体来配置部署。

curl -L https://github.com/docker/compose/releases/download/1.23.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

可以在 https://github.com/docker/compose/releases 查看具体的发布列表。

常用命令

运行容器(run)

run是我们最常用的命令:

docker run nginx

如上,便启动了一个nginx容器。

端口映射(-p)

此时,我们还无法通过访问宿主机的IP来访问刚才部署的Nginx,需要先进行端口映射:

docker run -p 8080:80 nginx

后台运行(-d)

默认情况下,当我们推出命令行时,容器也会被关闭。我们可以使用-d参数使容器保持后台运行:

docker run -d <image-name>

然后访问宿主机的IP:8080,便可以看到“Welcome to nginx!”。

指定名称(-n)

docker run --name <container-name> <image-name>

docker run --name myredis redis

如上,创建了一个名称为redis的容器。

持久化数据(-v)

容器被设计为无状态的,当我们删除一个容器时,保存在其中的数据也会随之删除。如果我们希望某些数据不随着容器的删除而删除,则可以使用目录绑定(通常称为卷),将容器中的某个文件夹于主机上的文件夹绑定,来实现数据的持久化。

docker run -v <host-dir>:<container-dir> <image-name>

除此之外,我们还可以使用Data Containers来实行数据的持久化,数据容器(Data Containers)唯一的职责就是存储和管理数据:

docker create -v /config --name dataContainer busybox

如上,我们使用busybox镜像创建了一个数据容器,并使用-v参数来指定容器存储和管理数据的目录位置。

然后我们可以将文件拷贝到容器中:

docker cp config.conf dataContainer:/config/

接下来,我们就可以在新的容器中引用该数据容器了:

docker run --volumes-from dataContainer ubuntu

新创建的ubuntu容器挂载了数据容器的/config目录。

重启策略(--restart)

通过--restart选项,可以设置容器的重启策略,以决定在容器退出时Docker守护进程是否重启刚刚退出的容器。

docker run -d --restart=always <image-name>

有如下4种重启策略:

  • no,默认策略,在容器退出时不重启容器
  • on-failure,在容器非正常退出时(退出状态非0),才会重启容器
    • on-failure:3,在容器非正常退出时重启容器,最多重启3次
  • always,在容器退出时总是重启容器
  • unless-stopped,在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器

进入交互模式(-it)

docker run -it [image-name] /bin/bash
  • -i interact 进入交互模式。
  • -t tty 分配一个伪终端。

执行之后,可以看到命令行的主机名已经变成了容器的Id,表示成功进入到了容器中,可以使用exit命令退出容器。

其他

# 启动一个SQLServer容器
docker run -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=Qwer1234' -p 1433:1433 -d --restart=unless-stopped microsoft/mssql-server-linux

管理容器

查看容器(ps)

docker ps

通过ps命令可以看到当前运行的容器,添加-a参数,则可以看到停止的容器。

我们可以使用docker inspect <friendly-name|container-id>来查看某个容器的详细信息:

dokcer inspect redis

附加容器(attach)

ttach可以附加到一个已经运行的容器的stdin中。

docker attach [containerid]

进入容器(exec)

docker exec -it [containerid] /bin/bash

是需要注意的是,对于attach,如果从这个stdin中exit,会导致容器的停止。而exec则不会,推荐使用exec

停止容器(stop)

docker stop [containerid]

删除容器(rm)

docker rm [containerid]

如果要删除的容器正在运行,则无法删除,可以添加-f参数来强制删除,也可以先停止容器再删除:

如果我们想删除所有的容器,可以使用如下命令:

docker rm $(docker ps -a -q) -f

镜像管理

Docker把应用程序及其运行环境等打包在 image 文件里面,相当于容器的模板。

搜索镜像

我们可以在 registry.hub.docker.com 查找镜像,也可以使用 dokcer search <name> 命令来搜索,如:我们使用如下命令来搜索redis镜像。

docker search redis

查看镜像

# 查看镜像列表
docker images

# 查看所有镜像(包括中间层镜像)
docker image -a

# 查看所有镜像的ID
docker images -q

# 查看所有的虚悬镜像(-f 显示满足条件的镜像)
docker images -f "dangling=true"

# 按仓库名过滤
docker images [REPOSITORY]

# 按仓库名和标签过滤
docker images [REPOSITORY:TAG]

镜像列表输出如下:

REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest e38bc07ac18e 2 weeks ago 1.85kB

每列含义:

  • REPOSITORY:仓储名
  • TAG:标签, 一个镜像可以有多个标签
  • IMAGE ID:镜像的唯一标识,通常在删除镜像时使用
  • CREATED:创建时间
  • SIZE:所占用的空间,展开后的各层所占空间的总和。

删除镜像

# 删除镜像
docker rmi [imageid]

docker image rm [imageid]

# 删除所有镜像
docker image rm $(docker images -q) -f

# 删除虚悬镜像(dangling image)
docker image prune

仓库名和标签均为<none>,这类无标签、无仓储名的镜像被称为dangling image

拉取推送

# 拉取镜像
docker pull [imagename]

# 构建镜像
docker build

# 推送镜像
docker push [imagename]

其他

# 查看镜像、容器、卷占用的空间
docker system df

Dockerfile

Dcoker镜像是从一个基础镜像开始的,基础镜像包括应用程序所需的平台依赖项, 例如, 安装了JVMCLR等。

镜像的定义是使用dockerfile文件来表达的。dockerfile是描述如何部署应用的列表。一个简单的Dockerfile文件如下:

FROM nginx:alpine
COPY . /usr/share/nginx/html

如上,我们的基础镜像是一个alpine版本的nginx,从而拥有了一个安装了nginx的linux环境。

接下来,我们可以通过定义的dockerfile文件来构建镜像:

docker build -t webserver-image:v1 .

-t参数为镜像指定一个友好的名字和标记,.则表示使用当前目录的dockerfile文件。

OnBuild

通常,dockerfile文件的执行顺序是从上到下,但我们可以使用ONBUILD指令来延后执行(在子镜像构建时执行)。

如下,我们定义一个经典的Node应用程序基础镜像:

FROM node:10
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
ONBUILD COPY package.json /usr/src/app/
ONBUILD RUN npm install
ONBUILD COPY . /usr/src/app
CMD [ "npm", "start" ]

当我们构建该镜像时,ONBUILD指令包含的内容将不会执行,然后我们定义一个该镜像的子镜像:

FROM node:10-onbuild
EXPOSE 3000

当我们构建该镜像时,上面的ONBUILD才会被执行。这样做的优势是可以在多个镜像中共享一份基础镜像,大大减少构建的速度。

Ignore File

为了防止将一个不必要或者敏感的数据打包到镜像中,可以使用.dockerignore文件进行配置。

下面的命令将passwords.txt文件加到了忽略中,确保它不会意外的被打包到镜像中发布出去。

echo passwords.txt >> .dockerignore

我们可以将.dockerignore文件存储在源代码管理中,保持团队间的一致。

总结

Docker是革命性的,干净利落的UX俘获了技术人员的芳心,ASP.NET Core 也是全面拥抱Docker,我们也要紧跟时代的步伐。

本文主要介绍docker的一些基本用法,可作为一个docker使用笔记来参考,并不断的补充完善,但不会涉及到比较深入的介绍,后续在其他文章中会详细介绍一些具体的用法。

posted @ 2018-05-01 12:49  雨夜朦胧  阅读(4516)  评论(5编辑  收藏  举报