写点什么

Github 已经 54k 个 star 的 Docker,到底是什么?

作者:Jackpop
  • 2022-11-06
    浙江
  • 本文字数:4556 字

    阅读完需:约 15 分钟

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


程序员宝藏库:https://github.com/Jackpopc/DevWeekly

什么是 Docker?


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

为什么要用 Docker?

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


  • 持续交付和部署

  • 更快的迁移

  • 更高效的利用系统资源

  • 更快的启动时间

  • 一致的运行环境

  • 更轻松的维护和扩展


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



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


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


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

基本概念

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


  • 镜像:image

  • 容器:container

  • 仓库:repository


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


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


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


# 类class HelloWorld:def __init__(self, x, y):self.x = xself.y = y
def add(self):return self.x + self.y
# 实例hello_world = HelloWorld(2, 3)print(hello_world.add())
# 输出>>> 5
复制代码


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


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


安装配置

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 lsREPOSITORY TAG IMAGE ID CREATED SIZEubuntu 16.04 ****** 10 days ago 119MB
复制代码


查看容器


$ docker ps -aCONTAINER 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 常用命令概括:


动手实践

创建项目


Test/├── Dockerfile└── main.py
复制代码


写一个简单的测试程序


# main.py
import loggingfrom time import sleepimport 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_dockerWORKDIR /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 官方对容器云生态进行支持的核心方案。


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



  • Mesos

  • Kubernetes


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

学习资源

上述所讲的常用命令、指令含义等对于日常开发使用已经够用了,如果对 Docker 更深入的内容,例如,数据管理、安全、底层实现、容器与云计算等感兴趣可以选取其他的学习资料。在这里我推荐一份我认为不错的学习资料,就是 yeasy 在 github 开源的一份详细的 docker 教程--docker_practice,目前 docker_practice 项目在 github 已经 13.7k 个 star,想深入学习的可以查看 github 项目,


Docker — 从入门到实践 github.com/yeasy/docker_practice



前言 - Docker - 从入门到实践



也可以查看 gitbooks,


Docker - 从入门到实践 yeasy.gitbook.io/docker_practice/



发布于: 刚刚阅读数: 4
用户头像

Jackpop

关注

还未添加个人签名 2020-09-16 加入

公众号:平凡而诗意,微信:code_7steps,全网粉丝超20万,技术进阶、优质资源、实用工具,欢迎关注!

评论

发布
暂无评论
Github已经54k个star的Docker,到底是什么?_Jackpop_InfoQ写作社区