一文熟练掌握Docker使用

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 做开发的应该很多人都知道Docker,就算是没有用过,应该也有所耳闻。这款开源于2013年的工具一经问世,便迅速火爆起来,在微服务、项目迁移、云等方面备受欢迎。如今它的github项目已经达到54k个star。Docker到底是什么?它有什么优点使得它如此受欢迎?到底该怎么使用?本文就从以上几点进行阐述,希望通过这篇文章能够让大家对Docker有一个清晰的认识。

什么是Docker?


13.png


Docker是由dotCloud公司发起并与2013年开源的一个项目,一径开源就备受欢迎,其主要项目至今在github已经54k个star。它是使用Go语言开发实现,基于Linux内核cgroup、namespace以及AUFS类等技术对进程进行封装隔离,属于一种操作系统层面的虚拟化技术。此后,进一步开发开始使用runC和containerd,进一步封装,从文件系统到网路互联,再到进行都进行隔离,极大的简化了容器的创建和维护,使得Docker比虚拟机更为轻便、快捷。

为什么要用Docker?

Docker与传统虚拟机一样,同属于虚拟化技术,但是它拥有众多虚拟机无法比拟的优势:

  • 持续交付和部署
  • 更快的迁移
  • 更高效的利用系统资源
  • 更快的启动时间
  • 一致的运行环境
  • 更轻松的维护和扩展

容器与虚拟机的对比详情如下:

14.png

对于大多数开发人员感受最为就是前两点:持续交付和部署更快的迁移

我想这对于很多开发人员都是一个很头疼的问题,在开发过程中会遇到这种抱怨:“在我电脑上可以运行啊?为什么换一台电脑就不行了?”

虽然诸如maven、nodejs的package.json、Python的requirement的出现使得迁移变得简单,但是它们更多的是使得在第三方工具包的迁移方面变得简单方面,但是在系统和开发环境方面却没有什么作用。docker确保了直行环境的一致性,可以在多平台上运行,使得应用迁移更加容易。此外,docker使用分层存储以及镜像技术,使得应用重复部分的复用更加容易,可以基于基础镜像做更多的扩展,使得系统的维护变得更加简单。

基本概念

使用docker接触最多的就是以下3个概念,

  • 镜像:image
  • 容器:container
  • 仓库:repository

了解这三个概念,对容器的整个生命周期便有了认识。在这里,我用简单的语言对上述3个概念进行描述

镜像:进行就相当于一个精简化的文件系统,例如官方提供的Ubuntu镜像,就只包含了最小化的root文件系统。

容器:容器是一个拥有自己root文件系统、自己网络配置、自己命名空间的进程。镜像和容器就像是编程中的实例,镜像时静态的定义,而镜像运行时的实体是容器。什么是类和实例?举一个编程的例子阐述一下,

# 类

classHelloWorld:

def__init__(self, x, y):

self.x = x

self.y = y


defadd(self):

returnself.x + self.y


# 实例

hello_world = HelloWorld(2, 3)

print(hello_world.add())


# 输出

>>> 5

其中HelloWorld是类,hello_world是实例,类比一下,就能够理解容器和镜像之间的关系。

仓库:docker镜像仓库就如同github代码仓库一样,当一个人构建一个项目,想在其他其他电脑上运行这个项目,那么就去从代码仓库把这个项目克隆下来。docker镜像仓库也是这样,当构建一个镜像之后,想在其他服务器上使用这个镜像,就需要一个集中的存储、分发服务,仓库就是这样的服务。官方的镜像仓库是DockerHub,它存储了丰富的镜像,但是国内拉取镜像速度缓慢,因此可以使用国内镜像仓库进行替代,例如阿里云镜像仓库、网易云镜像仓库、DaoCloud镜像市场等。

15.jpg

安装配置

docker目前支持Linux、Windows 10、macOS,下面就一个Linux安装为例,

APT方式安装

首先安装HTTPS软件包和CV证书,

$ sudo apt-get update

$ sudo apt-get install \

   apt-transport-https \

   ca-certificates \

   curl \

   software-properties-common

添加软件源GPG密钥,

$ curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add

添加docker软件源,

$ sudo add-apt-repository \

   "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \

   $(lsb_release -cs) \

   stable"

安装docker ce,

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

添加用户组

docker命令会使用Unix socket与docker引擎通讯,因此每次使用时会需要root权限,也就是需要在命令前加sudo比较麻烦,为了避免这个麻烦可以把建立docker组并把当前用户加入docker用户组,

$ sudo groupadd docker
$ sudo usermod -aG docker $USER

启动、退出、重启docker

$ systemctl start docker
$ systemctl stop docker
$ systemctl restart docker

也可以使用,

$ service docker start

$ service docker stop

$ service docker restart

Dockerfile

理解docker中一些基本概念,并完成docker安装下一步就是学习docker的使用。对于大多数开发人员来说,docker使用过程中最为核心的部分就是Dockerfile。

Dockerfile是一个文本文件,它包含了一些指令,docker镜像的构建就是通过Dockerfile中的这一条一条的指令完成的。也就是说,要构建一个镜像,就需要一个Dockerfile,然后根据自己的需求配置一些指令集合,下面就看一下Dockerfile中使用的一些指令。

FROM:指定基础镜像

定制我们的镜像,是需要以一个镜像为基础的,就是基础镜像,例如Ubuntu、 nginx、postgres、mysql等,例如,FROM Ubuntu: 16.04,如果本地有Ubuntu基础镜像则使用本地基础镜像,如果没有则会到官方镜像仓库拉取,16.04是镜像版本号,如果不指定则会拉取lastest。

RUN:执行命令

RUN指定我们在构建镜像时需要执行的命令,比如apt-get install安装某个软件,pip install安装Python依赖包,配置软件源,配置时区等, 例如,RUN apt-get install python3

ADD和COPY:文件操作

ADD和COPY是两个功能类似的指令,一般优先使用COPY,它比ADD更透明,它的功能是将本地文件拷贝到容器中,例如,COPY ./ /home/jackpop

WORKDIR:指定工作路径

指定镜像的运行时的工作路径,例如,WORKDIR /home/jackpop

ENTRYPOINT:设置镜像主命令

定镜像运行是运行的命令,例如, ENTRYPOINT  ["python", "-m, "main"]

LABEL:添加标签

可以为镜像添加标签来帮助组织镜像、记录许可信息、辅助自动化构建等。

CMD:执行目标镜像中包含的软件

如果创建镜像的目的是为了部署某个服务,可能会执行某种形式的命令,可以包含参数。

EXPOSE:指定监听端口

给外部访问指定访问端口。

ENV:环境变量

为了方面程序运行,有时需要更新环境变量。

VOLUME:暴露数据库存储文件

USER:指定当前用户

其中常用的命令就是FROMCOPYWORKDIRENTRYPOINTRUN

常用命令

了解了Dockerfile的常用指令,我们该怎么对镜像和容器进行操作呢?下面就来学习一下docker常用的一些命令,

备注:由于我已经把当前用户加入到docker用户组,所以下面命令没有加sudo,如果没有加用户组需要使用sudo docker。

查看本地镜像

$ docker image ls

REPOSITORY TAG IMAGE ID CREATED SIZE

ubuntu 16.04 ****** 10 days ago 119MB

查看容器

$ docker ps -a

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

*** *** *** *** *** *** *** ***

启动、停止、重启容器

$ docker start $container_id

$ docker stop $container_id

$ docker restart $container_id

退出和进入镜像

$exit

$ docker exec$container_id /bin/bash

启动镜像

$ docker run $image_id

可以用--p和--dns指定端口和dns来配置网络。

container_id是容器ID,image_id是镜像ID。

拉取镜像

$ docker image pull ubuntu

从Dockerfile创建镜像

$ docker build

从一个修改的容器创建镜像

$ docker commit

容器与本地之间复制文件

$ docker cp

推送镜像

$ docker push

为镜像打标签

$ docker tag

重命名容器

$ docker rename

删除容器

$ docker rm

删除镜像

$ docker rmi

搜索镜像

$ docker search

Docker常用命令概括:

16.jpg


动手实践

创建项目

Test/
├── Dockerfile
└── main.py

写一个简单的测试程序

# main.py
import logging
from time import sleep
import numpy as np
logging.basicConfig(level=logging.DEBUG,
          format="'%(asctime)s - "
               "%(filename)s[line:%(lineno)d] - "
               "%(levelname)s: %(message)s")
def main():
  for i in range(10):
    logging.debug(np.random.randint(0, 5))
    sleep(0.1)
if __name__ == '__main__':
  main()

Dockerfile

这是构建镜像中的重点部分,

FROM ubuntu:16.04
COPY ./ /home/Test_docker
WORKDIR /home/Test_docker
RUN apt-get update && apt-get install -y python3 python3-pip \
&& ln -s pip3 /usr/bin/pip \
&& ln -sf /usr/bin/python3 /usr/bin/python \
&& rm -rf ls /var/cache/apt/* \
ENTRYPOINT ["python3", "-m", "main"]

进入项目根目录

$cd Test

开始创建镜像

$ docker build test:v1.0 .

test是指定构建镜像的名称,v1.0指定镜像标签,如果不指定,镜像名称和标签会显示为<none>。

运行镜像

$ docker run $image_id
'2019-06-29 12:26:38,298 - main.py[line:13] - DEBUG: 0
'2019-06-29 12:26:38,399 - main.py[line:13] - DEBUG: 2
'2019-06-29 12:26:38,499 - main.py[line:13] - DEBUG: 1
'2019-06-29 12:26:38,599 - main.py[line:13] - DEBUG: 3
'2019-06-29 12:26:38,699 - main.py[line:13] - DEBUG: 0
'2019-06-29 12:26:38,799 - main.py[line:13] - DEBUG: 4
'2019-06-29 12:26:38,900 - main.py[line:13] - DEBUG: 4
'2019-06-29 12:26:39,000 - main.py[line:13] - DEBUG: 4
'2019-06-29 12:26:39,100 - main.py[line:13] - DEBUG: 4
'2019-06-29 12:26:39,200 - main.py[line:13] - DEBUG: 2

当然,也可以在基础镜像的基础上进行修改来创建我们的镜像,例如,我们拉取一个Ubuntu基础镜像,可以启动镜像后安装我们需要的软件和环境,然后利用docker commit [OPTIONS] CONTAINER [REPO [:TAG]]来创建一个新镜像。

延伸阅读

除了基础的docker之外,还有一些高级的docker开源工具,比较知名的有如下3项,

  • docker compose
  • docker machine
  • docker swarm

其中docker compose是官方编排项目之一,用于快速在集群中部署分布式应用。docker machine同样是官方编排项目之一,负责在多种平台上快速安装docker环境。docker swarm提供docker容器集群服务,是docker官方对容器云生态进行支持的核心方案。

除此之外,还有一些比较知名的集群管理系统,例如,

17.png

  • Mesos
  • Kubernetes

其中Mesos是来自UC Berkeley的集群资源管理开源项目,它可以让用户很容易实现分布式应用的自动化调度。Kubernetes是由Google团队发起并维护的给予docker的开源容器集群管理系统,应用比较广泛,它不仅支持场景的云平台,而且支持内部数据中心。

相关实践学习
通过容器镜像仓库与容器服务快速部署spring-hello应用
本教程主要讲述如何将本地Java代码程序上传并在云端以容器化的构建、传输和运行。
Kubernetes极速入门
Kubernetes(K8S)是Google在2014年发布的一个开源项目,用于自动化容器化应用程序的部署、扩展和管理。Kubernetes通常结合docker容器工作,并且整合多个运行着docker容器的主机集群。 本课程从Kubernetes的简介、功能、架构,集群的概念、工具及部署等各个方面进行了详细的讲解及展示,通过对本课程的学习,可以对Kubernetes有一个较为全面的认识,并初步掌握Kubernetes相关的安装部署及使用技巧。本课程由黑马程序员提供。 &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
相关文章
|
Shell Docker 容器
docker使用记录一
docker使用记录一
133 0
docker使用记录一
|
NoSQL Shell Redis
docker的使用
docker的使用
148 0
|
Docker 容器
docker使用阿里云加速
安装完docker引擎后,默认使用的docker仓库,拉取镜像速度比较慢,需要修改daemon.json来进行加速。
1057 0
docker使用阿里云加速
|
应用服务中间件 Linux Shell
|
Linux Docker 容器
docker使用
docker run -t -i --mount type=bind,source=/c/workspace/gopath,target=/go -p 8080:8080 golang:1.11-stretch docker start -i CONTAINER ID docker exec -i -t CONTAINER ID /bin/bash volumes写dockerfile的时候无法挂载本地目录,使用 --volumes-from=容器id 来做基于volume互联 基于link互联,跨主机用connectable,实际应用不多。
1493 0
|
关系型数据库 PHP 数据库
docker学习系列16 使用过程的一些经验总结
COPY 和 ADD 命令具有相同的特点:只复制目录中的内容而不包含目录自身。 比如 backend 目录的结构如下: --- backend -- model -- controller 如果执行 WORKDIR /app COPY backend . 容器内app底下会是model和controller目录,并不是backend目录。
1289 0
|
Linux Shell 数据安全/隐私保护
|
应用服务中间件 Linux nginx
|
数据库 Docker 容器
《Docker生产环境实践指南》——1.3 使用Docker的多种方式
过去的几年时间,科技发生了巨大变化,从物理服务器到虚拟服务器,再到拥有PaaS环境的云计算。不论是否采用了全新架构,Docker镜像都可以在当前环境中很容易地被使用。要使用Docker,并不需要立即从单体应用程序迁移到面向服务架构。有很多用例允许在不同层次上集成Docker。
2631 0
下一篇
无影云桌面