docker入门知识

简介

Docker是一个开源的应用容器引擎。基于Namspaces、Control Groups和UnionFS,保证容器的轻巧、隔离和易移植。build once, configure once and run anywhere。
Docker的特性:

  • 速度飞快;
  • 优雅的隔离架构;
  • cpu/内存消耗低;
  • 快速启动/关闭/销毁;
  • 开源;

满足 DevOps 的需求:

  • 简化了大规模的集群部署步骤
  • 方便快捷的持续集成和部署 CI/CD
  • 微服务架构
  • 一次性的/定时的任务
  • 一致的开发测试环境
  • 演示、使用环境
  • 解决设备成本,充分利用资源
  • 技术方案快速验证

版本

2017/3/3,Docker版本从1.13.*直接跳入17.03,即17年3月。Docker以后会以CE(Community Edition)和EE(Enterprise Edition)的形式发布。CE版本每个月发布一次,EE三个月发布一次,对应17.03、17.06等。对于发布的每个EE版本,Docker官网都会提供一年的技术支持。docker EE支持各大主流系统和云服务器,但是CE则不是,

docker v.s 虚拟机

传统虚拟化技术的体系架构:
docker入门知识_第1张图片
Docker 技术的体系架构:
docker入门知识_第2张图片
从上面两张图一目了然看到docker相对于虚拟机的优势所在:资源占用少,启动速度快,……。

安全性

容器相比虚拟机更为安全

基本概念

三个基本概念:镜像Image,容器Container,仓库Registry;
Docker镜像
一个只读的模板。镜像可以用来创建 Docker 容器。Docker 提供一个很简单的机制来创建镜像或者更新现有的镜像,用户可以直接从仓库下载一个已经做好的镜像直接使用。利用 Dockerfile 以及 docker build 命令来创建Docker Images镜像。镜像是一种文件结构,Dockerfile中的命令都会在文件系统中创建一个新的层次结构,镜像则构建与这些文件系统之上。

Docker容器
容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看作是一个简易版Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
镜像是只读的,容器在启动的时候创建一层可写层作为最上层。

Docker仓库
仓库是集中存放镜像文件的场所。Repository镜像名和Registry是两回事。Registry 里存放着多个Repository,每个仓库中又包含多个镜像,每个镜像有不同的标签tag。
仓库分为公开仓库和私有仓库两种形式。最大的公开仓库是 Docker Hub,存放数量庞大的镜像供用户下载。 国内的公开仓库包括 Docker Pool等,可以提供大陆用户更稳定快速的访问。企业或者用户可以借助于 Registry (或者Harbor、Portus)在本地网络内创建一个私有仓库。
当用户创建自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以。
不严谨的类比:Docker 仓库的概念跟 Git 类似,注册服务器可以理解为 GitHub 这样的托管服务。

常用命令行

# 前置知识:镜像的 ID 唯一标识镜像,如果两个镜像有相同的镜像ID,即下面的,说明是同一镜像,TAG 信息用来标记来自同一个仓库的不同镜像,不指定tag信息,默认就是LATEST。
 == //:
# 下载镜像images
docker pull //:
docker pull ubuntu:12.04
# 等价于
docker pull registry.hub.docker.com/ubuntu:12.04 命令,即从注册服务器registry.hub.docker.com 中的 ubuntu 仓库来下载标记为 12.04 的镜像。官方仓库在国外,速度慢,从其它仓库(如阿里镜像库)下载时需要指定完整的仓库注册服务器地址,或者在配置文件里面修改。
# 利用 tag,新打一个image
docker tag  localhost:5000/mng-portal:1.5

# 如果pull下载失败,依据提示可能需要登录
docker login 
# 列出本地的镜像
docker images
# 上传镜像images,不仅仅需要登录,还需要push的admin权限
docker push //:
# build 镜像images, 需要在dockerfile所在目录下面执行,注意后面的点
docker build --build-arg http_proxy=http://:--build-arg https_proxy=https://: -t hello-world:1.0 . 
# 删除空悬的images,即 :
docker rmi --force $(docker images -f dangling=true -q)

# 启动容器有两种方式,1. 基于镜像新建一个容器并启动,2. 将终止状态(stopped)的容器重新启动。
# 将镜像run起来,变成container。不带 -it 选项时,启动的容器并不会保留后台进程;-t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i 则让容器的标准输入保持打开。在交互模式下,用户可以通过所创建的终端来输入命令。
docker run -it -p 15432:5432 -v /root:/mount hello-world:1.0 /bin/bash

原理:当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括:
1、检查本地是否存在指定的镜像,不存在就从公有仓库下载;利用镜像创建并启动一个容器
2、分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
3、从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
4、从地址池配置一个 ip 地址给容器
5、执行用户指定的应用程序
6、执行完毕后容器被终止

利用 docker start 命令,直接将一个已经终止的容器启动运行。容器的核心为所执行的应用程序,所需要的资源都是应用程序运行所必需的。除此之外,并没有其它的资源。可以在伪终端中利用 ps 或 top 来查看进程信息。容器中仅运行指定的 bash 应用,这使得 Docker 对资源的利用率极高。

# 保存镜像images为tar包:
docker save -o //*.tar 
# 从导出的本地 tar 文件中再导入到本地镜像库
docker load -i *.tar
# 导入镜像以及其相关的元数据信息(包括标签等)
docker load < ubuntu_14.04.tar
# docker images 列出本地所有镜像,其中很可能会包含有很多中间状态的未打过标签的镜像,大量占据着磁盘空间。
# 删除容器containers
docker rm -f 
# 清理所有未打过标签的本地镜像
docker rmi $(docker images -q/--quiet -f/--filter "dangling=true")
# 在删除镜像之前要先用 docker rm 删掉依赖于这个镜像的所有容器,-f 参数强制删除images,
docker rmi -f 

# kill_running_containers
docker kill `docker ps -q` 
# 从容器拷贝文件到主机host上去
docker cp : 
//示例
docker cp Users.json  /root
# 从主机上拷贝文件到容器内
docker cp    ./xxxx.json       4755137f8c52:/
# list all containers:
docker ps -a
# 进入容器:
docker exec -it  bash

# 查看容器日志
docker logs

# 搜索镜像,按照star排名
docker search nginx

# 用于查看容器/镜像的配置信息,包含容器名、环境变量、运行命令、主机配置、网络配置和数据卷配置等。
docker inspect 

# 其他不常用
# 退出登录Docker registry
docker logout

使用docker启动数据库

docker 形式安装本地的 postgres 数据库,命令:

docker run -d \
  --name postgres-order \
  -e POSTGRES_DB=order \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=1Qaz \
  -p 5432:5432 \
  postgres

上面这个命令会检查本地有没有一个 postgres 镜像,没有的话,则会执行 docker pull postgres从官方仓库拉取一个镜像。
以后比如想要新建一个本地的数据库 bank,则命令为:

docker run -d \
  --name postgres-bank \
  -e POSTGRES_DB=bank \
  -e POSTGRES_USER=postgres \
  -e POSTGRES_PASSWORD=1Qaz \
  -p 5432:5432 \
  postgres

即统一使用本地的 postgres image,container 的名字是 postgres-,数据库名字使用 -e POSTGRES_DB 参数指定,用户名和密码保持不变。container 名字必须变,否则命令执行报错。
然后就可以使用客户端连接工具,如 dbeaver连接。

高级命令行

Docker System

使用过docker的人都知道,磁盘空间特别容易占用100%,虽然docker已经引入层的概念来优化存储卷空间。此时我们需要一个工具或者命令行来检测可以删除或者清理的容器或者镜像等占用的资源;上面讲到一条基本命令:# 删除空悬的images,即 ::docker rmi --force $(docker images -f dangling=true -q)

如果开发或者生产环境一直使用这个命令行,会显得效率低下,并且并不能完全清理其他占用的空间。自Docker 17.03版本以来,docker自带命令docker system用来清理空间。命令df -h可以用来检测磁盘的使用情况;docker system df命令,用于查看Docker的磁盘使用情况,基于Linux自带的命令dfdocker system prune可以用于删除所有停止的容器以及dangling镜像,执行此命令会给出warning:

WARNING! This will remove:
    - all stopped containers
    - all volumes not used by at least one container
    - all networks not used by at least one container
    - all dangling images

使用-a选项可以做深度清理,docker system prune -a

WARNING! This will remove:
    - all stopped containers
    - all volumes not used by at least one container
    - all networks not used by at least one container
    - all images without at least one container associated to them

这个命令将清理整个系统,并且只会保留真正在使用的镜像,容器,数据卷以及网络,因此需要格外谨慎。比如,不能在生产环境中运行prune -a命令,因为一些备用镜像(用于备份,回滚等)有时候需要用到,如果这些镜像被删除,则运行容器时需要重新下载。
此时,所有未绑定容器的镜像将会被删除。由于第一次prune命令删除所有容器,因此所有镜像(它们没有绑定任何容器)都会被删除。

dockerfile

参考另一篇博客Dockerfile编写总结

搭建镜像服务器

为什么需要搭建镜像服务器:

  1. 服务器部署在国外的 docker hub 对于国内企业/个人用户而言,访问速度慢得一逼;
  2. 主要是:企业用户为了安全和私有化考虑,需要搭建自己内部的私有仓库,类比于nexus,GitLab;

主要有docker registry,Harbor,以及Portus。

docker registry

官网:
旧版:docker-registry
新版:distribution
Docker Registry是一个Docker仓库,用来存储和分享Docker镜像,一般用于局域网或者内网。
创建方式
最简单的方法:
docker run -d -p 5000:5000 --restart=always --privileged=true --name registry -v /root/data:/var/lib/registry registry:2
其他方法,无外乎直接使用代码库的dockerfile构建registry镜像,或者二进制安装。

Harbor

Portus

Docker API

参考sdk
对应于docker ps命令,http方式如下:

$ curl --unix-socket /var/run/docker.sock http:/v1.24/containers/json
[{
  "Id":"ae63e8b89a26f01f6b4b2c9a7817c31a1b6196acf560f66586fbc8809ffcd772",
  "Names":["/tender_wing"],
  "Image":"bfirsh/reticulate-splines",
  ...
}]

那么使用Java呢?引入dependency:

<dependency>
    <groupId>com.github.jnrgroupId>
    <artifactId>jnr-unixsocketartifactId>
    <version>0.20version>
dependency>

使用 UnixSocket 调用Docker API的demo程序:

public static void main(String[] args) {
    // 建立 Unix Socket 连接
    File sockFile = new File("/var/run/docker.sock");
    UnixSocketAddress address = new UnixSocketAddress(sockFile);
    UnixSocketChannel channel = UnixSocketChannel.open(address);
    UnixSocket unixSocket = new UnixSocket(channel);

    // 调用 Docker API
    PrintWriter w = new PrintWriter(unixSocket.getOutputStream());
    w.println("GET /v1.24/containers/json HTTP/1.1");
    w.println("Host: http");
    w.println("Accept: */*");
    w.println("");
    w.flush();
    // 关闭 Output,否则会导致下面的 read 操作一直阻塞
    unixSocket.shutdownOutput();

    // 获取返回结果
    BufferedReader br = new BufferedReader(new InputStreamReader(unixSocket.getInputStream()));
    String line;
    while ((line = br.readLine()) != null){
        System.out.println(line);
    }
    unixSocket.close();
}

Docker Compose

Docker Compose,用来定义和运行多个容器的工具。需要编写 docker-compose.yml 来配置容器,docker compose 解析这个文件,分析其语法,如有错误肯定不能启动成功。推荐一个在线检查 yaml 文件格式的网址yamllint。
一个简单示例:

services:
  jetty:
    images: jetty
    container_name: jetty
      ports:
        - "8881:8080"
        - "22"
  jenkins:
    images: jenkins
    container_name: jenkins
    ports:
      - "8882:8080"
    links:
      jetty

命令docker-compose up -d,docker compose 解析文件之后,会先启动 jetty,然后启动 jenkins;

docker compose安装

对于Win/Mac系统,安装docker的时候附带安装;
Linux安装:
curl https://github.com/docker/compose
下载文件到(>)/usr/local/bin/docker-compose,在下载地址中使用 ( u n a m e − s ) 是 获 取 u n m a e − s 命 令 的 输 出 加 到 路 径 中 。 ‘ c u r l − L h t t p s : / / g i t h u b . c o m / d o c k e r / c o m p o s e / r e l e a s e s / d o w n l o a d / 1.9.0 / d o c k e r − c o m p o s e − (uname -s)是获取 unmae -s 命令的输出加到路径中。 `curl -L https://github.com/docker/compose/releases/download/1.9.0/docker-compose- (unames)unmaescurlLhttps://github.com/docker/compose/releases/download/1.9.0/dockercompose(uname -s)-$(uname -m) > /usr/local/bin/docker-compose`

docker容器集群管理

系统如果是分布式或者微服务的,docker 化之后,容器肯定也不止一个,此时就需要集群编排管理工具,主流就三种 docker swarm、Kubernetes、Mesos。

docker swarm

Swarm,可以把多个主机变成一个虚拟的Docker主机来管理,Go语言开发,源码在[swarm](https://github.com/docker/swarm)上。Swarm使用标准的Docker API,给Docker用户带来无缝的集群使用体验。2016年7月, Swarm已经被整合进入Docker Engine。
Docker Swarm提供API 和CLI来在管理运行Docker的集群,它的功能和使用本地的Docker并没有本质的区别。但是可以通过增加Node带来和好的扩展性。理论上,你可以通过增加节点Node的方式拥有一个无限大的Docker主机。Swarm并不提供UI,需要UI的话,可以安装收费的UCP。
架构图:
docker入门知识_第3张图片

kubernetes

简介参考另一篇博客kubernetes基础入门总结

对比
docker入门知识_第4张图片
图片来源于网络。

docker管理工具

Shipyard

一个基于 Web 的 Docker 管理工具,支持多 host,可以把多个 Docker host 上的 containers 统一管理;可以查看 images,甚至 build images;并提供 RESTful API 等。
GitHub:https://github.com/shipyard/shipyard
官方文档:https://shipyard-project.com/
安装:curl -s https://shipyard-project.com/deploy | bash -s
展示所有参数:curl -s https://shipyard-project.com/deploy | bash -s -- -h
访问 http://localhost:8080,输入账号/密码:admin/shipyard即可访问Shipyard。

Portainer

一个轻量级的管理界面,可以让您轻松地管理不同的Docker环境(Docker主机或Swarm集群)。Portainer 提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作、事件日志显示、容器控制台操作、Swarm集群和服务等集中管理和操作、登录用户管理和控制等功能。功能十分全面,基本能满足中小型单位对容器管理的全部需求。
GitHub:https://github.com/portainer/portainer
官方文档:https://portainer.readthedocs.io/en/latest/deployment.html
使用
docker run -d --privileged -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v /opt/portainer:/data portainer/portainer
如开启SELinux,可执行如下命令启动:
docker run -d --privileged -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock -v /opt/portainer:/data portainer/portainer

docker-gc

官网:https://github.com/spotify/docker-gc
docker-gc用于清理不需要的容器和镜像。可以删除存在一小时以上的容器、没有容器的镜像。docker-gc可以被当做脚本,也可以被视为容器。容器方法运行:docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -e DRY_RUN=1 spotify/docker-gc
安装Docker socket文件,以便和Docker API进行交互。设置环境变量DRY_RUN=1,用于删除前的确认。不带此参数,docker-gc将直接删除它们。确认需要删除的容器和镜像之后,再次运行docker-gc来进行删除清理。

ctop

官网:https://github.com/bcicen/ctop
定位为容器的顶层界面工具,ctop可以为多个容器提供实时显示的数据视图。Mac安装:brew install ctop,安装后配置DOCKER_HOST环境变量即可使用。运行ctop命令,可以查看所有容器的状态。运行ctop -a命令,可以仅查看当前运行的容器。

docker-slim

官网:https://github.com/docker-slim/docker-slim
镜像瘦身工具,可以通过静态和动态分析。在releases下载二进制文件,添加到路径PATH即可使用,支持Linux & Mac系统。命令docker-slim build --http-probe 即可对镜像进行分析,进行压缩。

Watchtower

官网:https://github.com/v2tec/watchtower
Watchtower监视容器运行过程,并且能够捕捉到容器中的变化。当Watchtower检测到有镜像发生变化,会自动使用新镜像重启容器。Watchtower本身就像一个Docker镜像,所以它启动容器的方式和别的镜像无异。运行Watchtower的命令如下:docker run -d --name watchtower --rm -v /var/run/docker.sock:/var/run/docker.sock v2tec/watchtower --interval 30
安装文件/var/run/docker.sock主要用来使Watchtower与Docker后台API交互。 interval 30秒的选项主要用来定义Watchtower的轮询间隔时间。
开启一个容器,用Watchtower来监控:docker run -p 4000:80 --name ,Watchtower会开始监控指定的容器,并且可以分析得到image来源于哪个registry,检测是否有新镜像。检测到新镜像,则会关掉容器,然后用新镜像重启容器。容器会在4000:80 公共端口选项上开启。默认情况下,Watchtower会轮询Dockder Hub注册表查找更新的镜像。你也可以通过在环境变量REPO_USER和REPO_PASS中添加指定注册表证书,来设置Watchtower轮询私有注册表。

Dry

官网:
GitHub
Dry 是一个可管理并监控 Docker 容器和镜像的命令行工具,与 Docker 官方自带的命令行工具相比 Dry 提供交互式操作界面。Dry 可以更方便和直观的管理容器相关的信息,包括对应镜像、容器名称、网络、容器中运行的命令及容器状态。运行在 Docker Swarm 中的Dry进程还会给出 Swarm 集群的各种状态信息。Dry 不仅可以管理本地 Docker 守护进程,也可以管理远程的 Docker 守护进程。前者Docker 主机显示为unix:///var/run/docker.sock;后者Docker 主机显示为 tcp://IP Address:Port Numbertcp://Host Name:Port Number
安装

# 使用预编译的二进制包安装
curl -sSf https://moncho.github.io/dry/dryup.sh | sudo sh
sudo chmod 755 /usr/local/bin/dry
# 参考官网可知,mac下可使用 brew 进行安装,Arch Linux 下可使用 yaourt 进行安装。

使用
命令行下输入dry命令,便可启动一个 Dry进程。 Dry 默认会连接本地的 Docker 守护进程;默认运行界面会显示容器的一些基本信息,与 docker ps 命令相比 Dry 体验上会更加友好。
快捷键命令:dry-keybinds

监控容器
在 Dry 的运行界面中按下 m 键即可打开监控模式,与 docker stats 命令相比 Dry 具有更加详细并且彩色的输出。Dry 还有一个额外的 NAME 列,方便你很容易的区分容器。
管理容器
如果你在 Dry 主界面选中的容器上单击回车键,你就可以管理该容器。Dry 对容器管理提供查看日志、查看/杀死/删除容器、停止/启动/重启容器、查看容器状态及镜像历史记录等操作。
查看全部容器
在 Dry 主界面按下 F2 键即可列出全部容器,包括运行中和已关闭的容器。
监控容器资源利用率
在容器管理界面,点击 Stats+Top 选项查看指定容器的资源利用率。你也可以按下快捷键 s 来打开容器资源利用率界面。
查看容器、镜像及本地卷的磁盘使用情况
在 Dry 主界面按下 F8 键即可查看容器、镜像及本地卷的磁盘使用情况。该界面明确地给出容器、镜像和卷的总数,哪些处于使用状态,以及整体磁盘使用情况、可回收空间大小的详细信息。
管理镜像
在 Dry 主界面中按下 2 键即可列出全部的已下载镜像。如果你想删除一个镜像,只需从界面中选择它,然后按 Ctrl + E。对于强制删除,你可以使用 Ctrl + F。
查看 Docker 网络列表
在 Dry 主界面按下 3 键即可查看全部网络及网关。
其它操作
如果你需要对列表项目进行排序,可按下 F1 键来实现。
Dry 也支持 Docker 的 Services、Stacks 管理,你可以在 Dry 主界面中按下 5 键或 6 键切换到相应管理界面。

Kitematic

Kitematic是一个Docker GUI。
GitHub:https://github.com/docker/kitematic

参考
Docker终极指南

你可能感兴趣的:(docker)