Docker基本介绍和操作

Docker基本介绍和操作

Docker基本介绍

什么是Docker

Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。
Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 开始,则进一步演进为使用 runC 和 containerd。
Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。

Docker与传统虚拟化的不同

传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。

为什么使用Docker

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

对比传统虚拟机总结,如下表:

特性 容器 虚拟机
启动 秒级 分钟级
硬盘使用 一般为 MB 一般为 GB
性能 接近原生 弱于
系统支持量 单机支持上千个容器 一般几十个

Docker基本概念

Docker 包括三个基本概念

  • 镜像(Image)
  • 容器(Container)
  • 仓库(Repository)

Docker基本操作

Docker版本介绍

docker-ce-17.09.0.ce
系统环境是linux7.x

Docker服务相关命令

启动docker服务
systemctl start docker
查看docker服务状态
systemctl status docker
关闭docker服务
systemctl stop docker
docker开机自启动
systemctl enable docker

查看Docker信息

查看docker版本
docker version
查看docker系统信息
docker info
查看docker日志信息
docker logs

Docker镜像

镜像拉取

例如以 centos 为关键词进行搜索:
docker search centos
使用公司内部镜像库
docker login dockerhub.datagrand.com
输入账号+密码
docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
实战:如从公司内部镜像库下载CentOS镜像
docker pull dockerhub.datagrand.com/global/centos:7.2.1511
使用第三方镜像仓库,如Docker
实战:如从Docker镜像库下载busybox
docker pull busybox

列出镜像

要想列出已经下载下来的镜像,可以使用 docker image 命令。

REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
busybox                                latest              e1ddd7948a1c        5 days ago          1.16MB
说明:
列表包含了 仓库名、标签、镜像 ID、创建时间 以及 所占用的空间。

镜像推送

推送至公司内部镜像库
登录公司镜像库
docker login dockerhub.datagrand.com
输入账号+密码
如我们需要将 busybox:latest 推送至global项目下,具体操作步骤如下:
docker tag e1ddd7948a1c dockerhub.datagrand.com/global/busybox:v100
其中,e1ddd7948a1c 是镜像ID,可以通过docker images来查看。

操作Docker容器

运行镜像

实战:运行busybox,容器名字是datagrand,启动sh并且将其放到后台运行。

语法:docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
docker run -itd --name=datagrand busybox /bin/sh
其中:
-itd这三个参数分别表示:
-i:交互式操作
-t:终端
-d:后台运行

查看容器运行状态

正在运行的容器
docker ps
查找某个正在运行的容器,如上例中的datagrand
docker ps grep datagrand
查看所有容器状态(包括运行和停止的)
docker ps -a

进入容器内部

语法:docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
docker exec -it b7df818849aa /bin/sh
其中b7df818849aa为容器ID,可通过docker ps来查看。

停止、重启和删除容器

docker stop b7df818849aa 
docker restart b7df818849aa
docker rm b7df818849aa
其中b7df818849aa为容器ID,可通过docker ps来查看。

删除本地镜像

语法:docker rmi [OPTIONS] IMAGE [IMAGE...]
docker rmi e1ddd7948a1c feac5e0dfdb2
其中e1ddd7948a1c和feac5e0dfdb2是镜像ID,可以通过docker images来查看。

请注意:在删除镜像之前,请将使用该镜像的容器停止和删除,否则会有如下报错:

Error response from daemon: conflict: unable to delete e1ddd7948a1c (cannot be forced) - image is being used by running container b7df818849aa
Error response from daemon: conflict: unable to delete e1ddd7948a1c (must be forced) - image is being used by stopped container b7df818849aa

镜像导出和导入

镜像导出
docker save e1ddd7948a1c |gzip > docker_file.tgz
其中,e1ddd7948a1c是镜像ID,可以通过docker images来查看。
镜像导入
docker load < docker_file.tgz 
说明:
也可以使用Export和Import对容器进行导出和导入。
两者区别,这里简单说一下:
使用导出后再导入(exported-imported)的镜像会丢失所有的历史,而保存后再加载(saveed-loaded)的镜像没有丢失历史和层(layer)。这意味着使用导出后再导入的方式,你将无法回滚到之前的层(layer),同时,使用保存后再加载的方式持久化整个镜像,就可以做到层回滚(可以执行docker tag <LAYER ID> <IMAGE NAME>来回滚之前的层)。

Docker 数据管理

为什么需要数据卷

  • 当该容器不再运行时,数据将不会持久存在,并且如果另一个进程需要,则可能很难从容器中获取数据。
  • 容器的可写层紧密耦合到运行容器的主机。无法轻松地将数据移动到其他位置。
  • 写入容器的可写层需要 存储驱动程序来管理文件系统。存储驱动程序使用Linux内核提供联合文件系统。与使用直接写入主机文件系统的数据卷相比,这种额外的抽象降低了性能 。

Docker将数据从Docker主机安装到容器中三种方式:

  • 数据卷(Volumes)
  • 挂载主机目录 (Bind mounts)
  • tmpfs卷

容器中管理数据三种方式区别:

  • Volumes 存储在由Docker(/var/lib/docker/volumes/在Linux上)管理的主机文件系统的一部分中。非Docker进程不应修改文件系统的这一部分。卷是在Docker中保留数据的最佳方式。
  • Bind mounts 可以存储在主机系统的任何位置。它们甚至可能是重要的系统文件或目录。Docker主机或Docker容器上的非Docker进程可以随时修改它们。
  • tmpfs 挂载仅存储在主机系统的内存中,永远不会写入主机系统的文件系统。

什么是数据卷

数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:

  • 可以在容器之间共享和重用
  • 对数据卷的修改会立马生效
  • 对数据卷的更新,不会影响镜像
  • 数据卷默认会一直存在,即使容器被删除

注意:
数据卷的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的 数据卷。

创建和管理卷

创建一个卷
docker volume create my-vol
查看创建的卷
docker volume ls
查看卷详细信息
docker volume inspect my-vol
删除卷
docker volume rm my-vol

启动具有卷的容器

如果启动具有尚不存在的卷的容器,Docker会自动创建卷。
docker run -d \
  -it \
  --name datatest \
  --mount source=myvol2,target=/app \
  busybox
使用docker inspect devtest验证创建卷并安装正确。寻找Mounts部分:
"Mounts": [
            {
                "Type": "volume",
                "Name": "myvol2",
                "Source": "/data/sys/var/docker/volumes/myvol2/_data",
                "Destination": "/app",
                "Driver": "local",
                "Mode": "z",
                "RW": true,
                "Propagation": ""
            }
        ],
说明:mount是一个卷,它显示正确的源和目标,并且mount是可读写的。
停止容器并移除卷:
docker stop datatest
docker rm datatest
docker volume rm myvol2

使用只读卷

docker run -d \
  -it \
  --name=nginxtest \
  --mount source=nginx-vol,destination=/usr/share/nginx/html,readonly \
  nginx:latest

使用绑定挂载(Bind mounts)

与卷相比,绑定装载具有有限的功能。使用绑定装入时,主机上的文件或目录将装入容器中。文件或目录由其在主机上的完整路径或相对路径引用。相反,当你使用卷时,会在主机上的Docker存储目录中创建一个新目录,Docker会管理该目录的内容。
该文件或目录不需要已存在于Docker主机上。如果它尚不存在,则按需创建。绑定挂载非常高效,但它们依赖于具有特定目录结构的主机文件系统。

创建source路径文件target
mkdir /tmp/target
docker run -d \
  -it \
  --name devtest \
  --mount type=bind,source=/tmp/target,target=/app \
  busybox

使用docker inspect devtest验证绑定安装正确创建。寻找Mounts部分:

"Mounts": [
            {
                "Type": "bind",
                "Source": "/tmp/target",
                "Destination": "/app",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
说明:
这表明mount是一个bindmount,它显示了正确的源和目标,它表明mount是读写的,并且传播设置为rprivate。

停止容器:

docker stop devtest
docker rm devtest

注意:
如果将bind-mount绑定到容器上的非空目录中,则绑定装置将隐藏目录的现有内容。

使用只读绑定挂载
docker run -d \
  -it \
  --name devtest \
  --mount type=bind,source="$(pwd)"/target,target=/app,readonly \
  nginx:latest

Docker容器网络

默认网络

安装Docker时,它会自动创建三个网络。可以使用以下docker network ls命令列出这些网络:

docker network ls

NETWORK ID          NAME                DRIVER
7fca4eb8c647        bridge              bridge
9f904ee27bf5        none                null
cf03ee007fb4        host                host

说明:

  • 这三个网络内置于Docker中。运行容器时,可以使用该--network标志指定容器应连接到的网络。
  • bridge所有Docker主机上都存在默认网络。如果未指定其他网络,则新容器将自动连接到默认bridge网络。

创建网络

创建了桥接网络
docker network create --driver bridge datagrand
docker network create datatest
查看创建的网络
docker network ls
NETWORK ID          NAME                   DRIVER              SCOPE
3bf08b12e820        datagrand              bridge              local
0e155373e305        datatest               bridge              local
说明:
默认创建的是bridge网络
删除网络
docker network rm datatest datagrand

网络端口映射

-P(大写)

创建容器时,使用 -P 标志用于自动将其中的任何网络端口映射到Docker主机上临时端口范围内的随机高端口。
实战:运行一个ngin容器,将容器中的端口80 和 443 绑定到主机上的随机高端口。

docker run -itd --name nginxtest -P nginx:1.7.9 /bin/bash
查看nginx容器运行情况:
docker ps
CONTAINER ID        IMAGE                                      COMMAND                  CREATED             STATUS              PORTS                                           NAMES
09cc5e292f7d        nginx:1.7.9                                "/bin/bash"              4 seconds ago       Up 2 seconds        0.0.0.0:32770->80/tcp, 0.0.0.0:32769->443/tcp   nginxtest
-p(小写)

说明:-p 可以多次使用该标志来配置多个端口。

  • 创建容器时,使用该-p标志将容器的端口绑定到特定端口。

实战:运行一个ngin容器,将主机的端口8080映射到容器的端口80.

docker run -itd --name nginxtest -p 8080:80  nginx:1.7.9 /bin/bash
查看nginx容器运行情况:
docker ps
CONTAINER ID        IMAGE                                      COMMAND                  CREATED             STATUS              PORTS                           NAMES
89469d564c89        nginx:1.7.9                                "/bin/bash"              3 seconds ago       Up 3 seconds        443/tcp, 0.0.0.0:8080->80/tcp   nginxtest
  • 创建容器时,使用该-p标志将容器的端口绑定到一定范围内随机端口。

实战:运行一个ngin容器,将容器中的端口80绑定到主机上8000到9000之间的随机可用端口。

docker run -itd --name nginxtest -p 8000-9000:80  nginx:1.7.9 /bin/bash
查看nginx容器运行情况:
docker ps
CONTAINER ID        IMAGE                                      COMMAND                  CREATED             STATUS              PORTS                           NAMES
dbaeeba59908        nginx:1.7.9                                "/bin/bash"              3 seconds ago       Up 3 seconds        443/tcp, 0.0.0.0:8000->80/tcp   nginxtest
  • 默认情况下,该-p标志将指定的端口绑定到主机上的所有接口。但您也可以指定绑定到特定接口,例如仅指定localhost。

实战:运行一个ngin容器,将容器中的端口80绑定到主机127.0.0.1:8080上

docker run -itd --name nginxtest -p 127.0.0.1:8080:80  nginx:1.7.9 /bin/bash
查看nginx容器运行情况:
docker ps
CONTAINER ID        IMAGE                                      COMMAND                  CREATED             STATUS              PORTS                             NAMES
205dd2ed1640        nginx:1.7.9                                "/bin/bash"              3 seconds ago       Up 3 seconds        443/tcp, 127.0.0.1:8080->80/tcp   nginxtest

或者,要将容器的端口80绑定到动态端口,但只能在其上 localhost。

docker run -itd --name nginxtest -p 127.0.0.1::80  nginx:1.7.9 /bin/bash
查看nginx容器运行情况:
docker ps
CONTAINER ID        IMAGE                                      COMMAND                  CREATED             STATUS              PORTS                              NAMES
ba506a445ccc        nginx:1.7.9                                "/bin/bash"              2 seconds ago       Up 2 seconds        443/tcp, 127.0.0.1:32769->80/tcp   nginxtest
  • 可以通过添加尾部来绑定UDP端口/udp
docker run -d -p 127.0.0.1:80:5000/udp training/webapp python app.py

猜你喜欢

转载自blog.51cto.com/wutengfei/2156381