docker基本概念
一 容器的概念
1. 什么是容器:
容器是在隔离的环境里面运行的一个进程,这个隔离的环境有自己的系统目录文件,有自己的ip地址,主机名等。也可以说:容器是一种轻量级虚拟化的技术。
2. 容器相对于kvm虚拟机的优势:
1. 容器能提供接近宿主机的性能,而kvm虚拟机会损害一部分宿主机的性能 2. 若宿主机最多能启动10虚拟机,那么它可以启动100+容器 3. 启动一台kvm虚拟机,可以能需要20秒,容器只需要1秒 4. kvm需要硬件cpu的支持,容器不需要
3.docker容器是什么?
Docker是通过内核虚拟化技术(namespaces及cgroups)来提供容器的资源隔离与资源限制。
由于Docker通过操作系统层的虚拟化实现隔离(对操作系统的内核有要求),所以Docker容器在运行时,不需要类似虚拟机(VM)额外的操作系统开销,从而比kvm虚拟机更轻量。
- Docker是一个开源的应用容器引擎,基于 GO 语言,并遵循 Apache2.0协议。
- docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的linux服务器,也可以实现虚拟化。
- 容器是完全使用沙箱机制,相互之间不会有任何接口(类iphone的app),并且容器开销极其低。
- Docker 是世界领先的软件容器平台。
- Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核 的cgroup,namespace,以及AUFS类的UnionFS等技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。 由于隔离的进程独立于宿主和其它的隔离的进
程,因此也称其为容器。Docke最初实现是基于 LXC. - Docker 能够自动执行重复性任务,例如搭建和配置开发环境,从而解放了开发人员以便他们专注在真正重要的事情上:构建杰出的软件。
- 用户可以方便地创建和使用容器,把自己的应用放入容器。容器还可以进行版本管理、复制、分享、修改,就像管理普通的代码一样。
二 docker相关概念
docker是一种软件的打包技术。
1. docker的理念
docker的主要目标是"Build,Ship and Run any App,Angwhere",构建,运输,然后处处运行
构建:制作docker镜像,打包容器的所有系统目录文件 运输:上传,下载,共享docker镜像 运行:基于docker镜像提供的rootfs,启动容器
Docker 主要用途#
- 简化环境搭建,提高开发生命周期效率,资源利用更出色。
- 自动迁移,可以制作镜像,迁移使用自定义的镜像即可迁移,不会出现什么问题,管理更加方便了。
- 微服务利器。
只要能运行docker容器,那么docker镜像中已经安装好的软件也可以运行,所以说docker是一种软件的打包技术。
2. docker的优点:
解决了操作系统和软件运行环境的依赖 对于开发人员来说,再也不用担心不会部署开发环境 开发环境,测试环境和生产环境高度一致。 让用户体验产品新特性的又一种思路。
2.1、容器化越来越受到欢迎,因为容器是:#
- 灵活:即使是最复杂的应用也可以集装箱化。
- 轻量级:容器利用并共享主机内核。
- 可互换:您可以即时部署更新和升级。
- 便携式:您可以在本地构建,部署到云,并在任何地方运行。
- 可扩展:您可以增加并自动分发容器副本。
- 可堆叠:您可以垂直和即时堆叠服务。
2.1、镜像和容器(contalners)#
- 通过镜像启动一个容器,一个镜像是一个可执行的包,其中包括应用程序所需要的所有内容,包含代码,运行时间间,库、环境变量和配置文件。
- 容器是镜像的运行实例,当被运行时有镜像转台和用户进程,可以使用
docker ps
查看。
2.2、容器和虚拟机区别#
- 容器在Linux 本机上运行,并于其他容器共享主机的内核,它运行的一个独立的进程,不占用任何其他的可执行文件的内存,十分轻量。
- 虚拟机运行时的是一个完成的操作系统,通过虚拟机管理程序对主机资源的访问进行虚拟访问,相比之下需要的资源更多。
3. docker的架构和组件
docker是一个cs架构:通过docker version来查看
docker最重要的三大组件:镜像,容器,仓库
Docker 版本#
- Docker Community Edition(CE)社区版。
- Enterprise Edition(EE) 商业版。
三 镜像名和标签
1. 镜像名称说明
标准镜像名由四部分组成: 1. 仓库地址/项目名/镜像名:标签,如 daocloud.io/library/nginx:latest 2. docker官方仓库的官方镜像可省略仓库地址和项目名,即:镜像名:标签 3. docker官方仓库的第三方镜像可省略仓库地址,即:项目名/镜像名:标签 4. 第三方仓库的镜像必须包含所有信息,即:仓库地址/项目名/镜像名:标签
2. 镜像标签
同一个镜像可以有多个便签,一个标签也可以对应多个镜像 标签常用来区分版本号,如centos:7,centos:7.4,centos:latest 如果未指明使用哪个标签,将使用默认的标签latest
3. Docker 三个重要概念#
-
image 镜像
Docker 镜像(Image)就是一个只读模板。他是一个可运行的软件(MySQL,Tomcat),也可以是一个系统(Centos),镜像可以用来创建 Docker 容器,一个容器可以创建很多个镜像。
-
container 容器
Docker 利用容器来运行应用,容器是从镜像创建的运行实例,它可以被启动、开始、停止、删除、每个容器之间都是相互隔离的,保证安全的平台,可以把容器看作是一个简易版的 Linux 环境 (包括 Root 用户权限、镜像空间、用户空间和网络空间等)和运行在其中的应用程序。
-
repository 仓库
- 仓库是集中镜像文件的仓库,registry 是仓库的主从服务器,实际上是参考注册服务器上存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
- 仓库分为两种,公有仓库和私有仓库,最大的公开仓库是docker Hub,存放了数量庞大的镜像供用户下周,国内的docker pool,这里仓库的概念与Git类似,registry可以理解为github这样的托管服务。
镜像与容器的关系类似于面向对象编程中的对象和类:
Docker | 面向对象 |
---|---|
容器 | 对象 |
镜像 | 类 |
四 镜像的分层概念
docker镜像是分层存储的,最上面一层为可写层,下面所有层都是只读层,这要做的好处是:
1. 多个镜像可以共用底层镜像,减小仓库容量 2. 制作镜像时可以使用底层镜像缓存,加快制作速度 3. 启动镜像时不用加载重复镜像,提高启动速度 4. 每一个只读层都可以单独作为镜像加载,制方便排查作镜像时的问题
五 Docker DNS Server
从 Docker 1.10 版本开始,docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过“容器名”通信。
方法很简单,只要在启动时用 --name
为容器命名就可以了。
使用 docker DNS 有个限制:只能在 user-defined 网络中使用。也就是说,默认的 bridge 网络是无法使用 DNS 的。下面验证一下:
# 创建自定义网络 docker network create --driver bridge noah_net# 启动基于自定义的网络的容器并测试 docker run -d --network=noah_net --name=bbox1 busybox sleep 900 docker run -it --network=noah_net --name=bbox2 busybox ping -c1 bbox1# 启动默认网络的容器并测试。 docker run -d --name=bbox3 busybox sleep 900docker run -it --name=bbox4 busybox ping -c1 bbox3
bbox4 无法 ping 到 bbox3。
END docker组件间关系图
六、Docker基本原理
Docker核心解决的问题是利用其自研的libcontainer [8-9]来实现类似虚拟机(VM)的功能,从而利用尽可能少的硬件资源给用户提供尽可能好的服务。与VM不同, libcontainer并不是一套硬件虚拟化方法,而是操作系统级的虚拟化。这理解起来可能并不像VM那样直观,所以可以从Docker要解决的问题出发,看看它是怎么满足用户虚拟化需求的。
Docker是一个开放源代码的应用容器引擎,能够自动化部署应用封装到一个程序库打包的一部分,然后在任何所选的系统上发布。
Docker的基本原理可以概括为:
-
镜像(Image):Docker镜像是一个只读的模板,用来创建Docker容器。
-
容器(Container):容器是从Docker镜像启动的实例,在容器中可以运行应用。容器是镜像的运行实例。
-
仓库(Repository):Docker仓库用来保存镜像。Docker仓库可以是公有的,也可以是私有的。
-
Dockerfile:Dockerfile是一个文本文件,包含了创建Docker镜像所需的所有命令。
-
-
这个Dockerfile定义了一个Python应用的Docker镜像,包括设置工作环境、复制文件、安装依赖以及定义容器启动时执行的命令。
# 使用官方Python运行时作为父镜像 FROM python:3.8-slim# 设置工作目录 WORKDIR /app# 将当前目录内容复制到位于/app中的容器 COPY . /app# 安装requirements.txt中指定的任何所需包 RUN pip install --no-cache-dir -r requirements.txt# 在容器启动时运行app.py CMD ["python", "./app.py"]
-
Docker的基本命令:
-
docker run
:创建一个新的容器并运行一个应用。 -
docker ps
:查看正在运行的容器。 -
docker stop
:停止运行的容器。 -
docker build
:从Dockerfile构建一个镜像。 -
docker push
:将本地的镜像上传到仓库。 -
docker pull
:从仓库获取镜像到本地。
Docker前世:
1.chroot实现切根,隔离操作系统。
2.namespaces实现进程、挂载、网络等的隔离UTS、MOUNT、TCP、PID、USER、NETWORK
3.ccgroup实现资源调度、销毁等Docker今生:
LXC---->Dcoker
LinuXContainer:封装上述常用功能用于调用,便于容器的创建、使用、销毁。Docker:EE企业版、CE社区版Docker 是 Docker.Inc 公司开源的一个基于 LXC技术之上构建的Container容器引擎, 源代码托管在 GitHub 上, 基于Go语言并遵从Apache2.0协议开源。
Docker是通过内核虚拟化技术(namespaces及cgroups等)来提供容器的资源隔离与安全保障等。由于Docker通过操作系统层的虚拟化实现隔离,所以Docker容器在运行时,不需要类似虚拟机(VM)额外的操作系统开销,提高资源利用率。Docker 包括三个基本概念镜像(Image)容器(Container)仓库(Repository)
Image(镜像):
那么镜像到底是什么呢?Docker 镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。
Container(容器)
容器(Container)的定义和镜像(Image)几乎一模一样,也是一堆层统一视角,唯一区别在于容器最上面那一层是可读可写的。
Repository(仓库)
镜像仓库是 Docker 用来集中存放镜像文件的地方,类似于我们之前常用的代码仓库。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本 。
我们可以通过<仓库名>:<标签>的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 Latest 作为默认标签。
用户需要考虑虚拟化方法,尤其是硬件虚拟化方法,需要借助其解决的问题主要是以下4个:
隔离性 - 每个用户实例之间相互隔离, 互不影响。 硬件虚拟化方法的方案是VM;libcontainer的方案是容器,具体而言是namespace。其中的pid, net, ipc, mnt, uts 等将容器的进程, 网络, 消息, 文件系统和主机隔离开。
可配额/可度量 - 每个用户实例可以按需提供其计算资源,所使用的资源可以被计量。硬件虚拟化方法因为虚拟了CPU和内存,可以方便实现;libcontainer则主要是利用cgroups来控制资源。cgroups 实现了对资源的配额和度量,提供了类似文件的接口。在 /cgroup目录下新建一个文件夹即可新建一个group,在此文件夹中新建task文件,并将pid写入该文件,即可实现对该进程的资源控制。
移动性 - 用户的实例可以很方便地复制、移动和重建。硬件虚拟化方法通过snapshot和image来实现;Docker主要通过AUFS实现。AUFS (AnotherUnionFS) 是一种联合文件系统, 就是支持将不同目录挂载到同一个虚拟文件系统下的文件系统。它具有节省存储空间、快速部署、节省内存、升级方便、允许在不更改base-image的同时修改其目录中的文件的特点。
安全性 - 这个讨论范围较大,这里强调是host主机的角度尽量保护容器。硬件虚拟化的方法因为虚拟化的水平比较高,用户进程都是在KVM等虚拟机中运行的;然而对于libcontainer, 其中运行的进程应当是事先静态编译完成的。用户提供的参数也是通过exec系统调用提供给用户进程。通常情况下容器中也没有长进程存在。
七、Docker平台架构
Docker平台由以下部分组成:
Docker守护进程(Docker daemon):Docker采用 C/S架构 [3]。Docker daemon 作为服务端接受来自客户端的请求 [4-5],并进行处理(创建、运行、分发容器) [4] [6]。
Docker客户端(Docker client):Docker 客户端则用于与 Docker 守护进程通信,发送命令以管理容器。Docker采用 C/S架构。客户端和服务端既可以运行在一个机器上,也可通过 socket 或者RESTful API 来进行通信。
Docker daemon一般在宿主主机后台运行,等待接收来自客户端的消息。 Docker 客户端则为用户提供一系列可执行命令,用户用这些命令实现跟 Docker daemon交互。
Docker镜像(Docker images):Docker 镜像是用于构建 Docker 容器的静态文件,它包含了应用程序运行所需的所有文件、依赖项和配置信息。Docker 镜像可以从 Docker Hub 或其他镜像仓库中获取,也可以通过 Dockerfile 自定义构建。
Docker容器(Docker container):Docker 容器是 Docker 镜像的运行实例,它包含了应用程序及其依赖项,并在隔离的环境中运行。每个容器都是一个独立的进程,拥有自己的文件系统、网络空间和进程空间。
Docker容器通过Docker镜像来创建。容器与镜像的关系类似于面向对象编程中的对象与类。
Docker | 面向对象的编程 |
容器 | 对象 |
镜像 | 类 |
Docker仓库(Docker Registry):Docker仓库是用于存储和管理Docker镜像的集中存储库 [7]。其中最常见的是Docker Hub,它是一个公共的Docker镜像仓库,包含了大量的官方和社区维护的镜像。除了Docker Hub外,还可以搭建私有的 Docker 仓库来管理自己的镜像。
平台工具
Docker Compose是一个用于定义和运行多容器Docker应用程序的工具 [10]。它只需一个命令,便可使用YAML格式文件去配置应用程序的服务并执行所有容器的创建和启动过程。docker-compose 命令行允许用户一次性在多个容器上运行命令;例如,构建镜像、 缩放容器、运行已停止的容器等 [11]。与镜像或与用户操作相关的命令在Docker Compose中不相关,因为它们指向一个容器。docker-compose.yml文件用于定义应用程序的服务,并包括各种配置选项。例如,build选项定义了配置选项,如Dockerfile路径,command选项允许覆盖默认的Docker命令等 [10]。Docker Compose的第一个公测版(版本0.0.1)于2013年12月21日发布。第一个用于生产的版本(1.0)于2014年10月16日发布 [12]。
Docker Swarm为Docker容器提供本机集群功能,它将一组Docker引擎变成一个虚拟Docker引擎。在Docker 1.12及更高版本中,Swarm模式与Docker引擎集成 [13]。Docker swarm CLI [14]实用程序允许用户运行Swarm容器,创建发现令牌,在集群中列出节点等 [13]。docker nodeCLI实用程序允许用户运行各种命令来管理群中的节点,例如,列出群中的节点,更新节点和从群中删除节点 [15]。Docker使用Raft共识算法管理蜂群。据Raft称,要执行更新,大多数Swarm节点需要就更新达成一致 [16]。
Docker Volume促进了数据的独立持久性,即使在容器被删除或重新创建后,数据仍可保留。
八、Docker功能特性
技术特性
在Docker的网站上提到了这一技术的典型场景:
-
使应用的打包与部署自动化
-
创建轻量、私密的PAAS环境
-
实现自动化测试和持续的集成/部署
部署与扩展webapp、数据库和后台服务
基于libcontainer的轻量级虚拟化,Docker相比KVM之类最明显的特点就是启动快,资源占用小。因此可以构建隔离的标准化的运行环境,轻量级的PaaS(如dokku), 构建自动化测试和持续集成环境,以及一切可以横向扩展的应用(尤其是需要快速启停来应对峰谷的web应用)。
- 1.
构建标准化的运行环境,现有的方案大多是在一个baseOS上运行一套puppet/chef,或者一个image文件,其缺点是前者需要baseOS许多前提条件,后者几乎不可以修改(因为copy on write的文件格式在运行时rootfs是read only的)。并且后者文件体积大,环境管理和版本控制本身也是一个问题。
- 2.
PaaS环境是不言而喻的,其设计之初和dotcloud的案例都是将其作为PaaS产品的环境基础
- 3.
因为其标准化构建方法(buildfile)和良好的REST API,使其能够很好地集成自动化测试和持续集成/部署。
- 4.
得益于libcontainer的轻量化,以及Docker能够只加载每个容器变化的部分,Docker在单机环境下与KVM之类的虚拟化方案相比能够更加快速和占用更少资源。
技术局限
Docker并不是全能的,设计之初也不是KVM之类虚拟化手段的替代品,简单总结几点:
- 1.
Docker是基于64位Linux的,无法在32位的linux/Windows/unix环境下使用
- 2.
libcontainer利用了cgroup等linux kernel功能,因此容器的guest系统只能是linux base的
- 3.
隔离性相比KVM之类的虚拟化方案有所欠缺,所有容器公用一部分的运行库
- 4.
网络管理相对简单,主要是基于namespace隔离
- 5.
cgroup的cpu和cpuset提供的cpu功能相比KVM的等虚拟化方案相比难以度量
- 6.
Docker对disk的管理比较有限
- 7.
容器随着用户进程的停止而销毁,容器中的log等用户数据不便收集
Docker在本质上是一个附加系统。使用分层架构构建一个应用是可行的。每个组件被添加到之前已经创建的组件之上;另一方面,分层架构带来另一方面的效率提升,当重建存在变化的Docker镜像时,不需要重建整个Docker镜像,只需要重建变化的部分。
可能更为重要的是,Docker旨在用于弹性计算。每个Docker实例的运营生命周期有限,实例数量根据需求增减。在一个管理适度的系统中,这些实例生而平等,不再需要时便各自消亡了。
针对Docker环境存在的不足,意味着在开始部署Docker前需要考虑如下几个问题。首先,Docker实例是无状态的。这意味着它们不应该承载任何交易数据,所有数据应该保存在数据库服务器中。
其次,开发Docker实例并不像创建一台虚拟机、添加应用然后克隆那样简单。为成功创建并使用Docker基础设施,管理员需要对系统管理的各个方面有一个全面的理解,包括Linux管理、编排及配置工具比如Puppet、Chef以及Salt。这些工具生来就基于命令行以及脚本。
Docker的应用场景
在软件开发过程中,Docker允许开发人员将应用程序、其依赖项和运行时环境打包到一个称为容器的独立单元中。这样的容器具有一致的运行环境,可以在开发、测试和生产环境中轻松地部署和交付,并且无需担心环境差异。
另外,在微服务架构中,开发者可以使用Docker将各个服务打包为独立的容器,从而实现服务的解耦和独立部署,以及不同服务之间资源的隔离。提高了系统的灵活性、可伸缩性和可维护性。
Docker容器可以与持续集成和持续部署工具(如Jenkins、Travis CI等)集成,实现自动化构建、测试和部署流程,从而加速软件交付周期。
开发团队可以使用Docker容器来创建标准化的开发环境,对齐团队中每个开发者的环境,避免了“仅在我这里可以工作”的问题。
总的来说,Docker的应用场景涵盖了软件开发的各个阶段,从开发到部署再到运维,都能够提供便利和效率。在不远的将来,Docker还会为AI开发赋能。随着生成式AI与大语言模型的广泛应用,曾经完全属于AI领域开发者的任务如今也需要由其他相关领域的开发者完成。这一变化涵盖了金融、安全、医疗等领域。Docker为开发者提供了构建、测试、运行和部署NVIDIA AI Enterprise软件平台的理想方式——一个端到端的云原生软件平台,为每个企业提供生成式AI [23]。该平台可用于Docker容器,并可作为微服务部署。这使团队能够专注于开发前沿人工智能应用程序,并保证程序性能。
安装docker软件
1. 添加yum源
# 添加阿里云的docker源 curl -o /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo # 清除yum缓存 yum makecache fast
2. 安装docker
# 安装系统必要的工具依赖 yum install -y yum-utils device-mapper-persistent-data lvm2 # 安装docker软件 yum install -y docker-ce
3. 配置docker镜像加速
docker的镜像默认都从docker-hub上拉取,然而由于不可描述的原因,国内访问速度很很慢,因此会采用镜像加速的方式拉取镜像,常用的有四个地址,分别是daocloud,七牛,docker-cn,阿里云,阿里云的要注册后才能使用专用地址,使用使用方法如下
# 方法1:DaoCloud+七牛+docker-cn加速 mkdir /etc/docker cat >/etc/docker/daemon.json <<EOF { "registry-mirrors": ["https://ms14dndh.mirror.aliyuncs.com", "http://hub-mirror.c.163.com", "https://registry.docker-cn.com"] } EOF docker cn的加速效果很一般,如果不用阿里云的话,推荐用发放DaoCloud# 方法2:阿里云加速器 注册阿里云账号,才能获取专用加速器地址,获得路径: https://cr.console.aliyun.com/#/accelerato
4. 启动docker
systemctl daemon-reload systemctl start docker systemctl enable docker
5. 启动第一个docker容器
docker run -itd -p 80:80 nginx
输出结果:
Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
743f2d6c1f65: Pull complete
6bfc4ec4420a: Pull complete
688a776db95f: Pull complete
Digest: sha256:23b4dcdf0d34d4a129755fc6f52e1c6e23bb34ea011b315d87e193033bcd1b68
Status: Downloaded newer image for nginx:latest
46030b32068a344d66e8437ff7b9ccca3b593b1d43b679f781b4ef23d35e82c6
输出结果解释:
1. 本地未发现镜像文件 2. 从仓库library/nginx分层下载镜像 3. 下载完成后校验哈希值 4. 新镜像命令并输出ID
docker基础操作命令
一 命令格式
docker的命令分老版命令格式和新版命令格式,新版命令主要是更直观了,添加了镜像[image]和容器[container]来区分命令,简单举例对比:
# 显示容器命令 老版命令:docker ps 新版命令:docker container ls# 显示镜像命令 老版命令: docker images 新版命令: docker image ls# 删除镜像命令 老版命令: docker rmi centos:latest 新版命令: docker image rm centos:latest
二 镜像相关命令
1. 搜索镜像:
docker search xxx
选镜像的建议:优先考虑官方镜像,然后是starts数量多的镜像
2.拉取/推送镜像
# 拉取镜像到本地 docker image pull centos# 推送centos镜像到仓库 docker image push centos
3. 镜像加速器
cat >/etc/docker/daemon.json <<EOF { "registry-mirrors": ["https://ms14dndh.mirror.aliyuncs.com"] } EOF
4. 查看/删除镜像
# 查看镜像 docker image ls# 删除镜像 docker image rm centos
5. 导入/导出镜像
# 导出镜像 docker image save centos > docker-centos7.4.tar.gz# 导入镜像 docker image load -i docker-centos7.4.tar.gz
三 容器相关命令
1. 创建启动容器
# 创建并启动容器 docker container run -d -p 80:80 nginx:latest {cmd}#单独创建容器 docker container create -p 80:80 nginx# 单独启动容器 docker container start -d 容器ID|容器名
常规参数:
参数名 | 功能 | 不带此参数时 |
---|---|---|
-d | 将容器放在后台运行 | 前台运行,会占用终端 |
-p | 进行端口映射 | 有些复杂,单独说明 |
-it | 分配新终端并进入容器 | 不会进入容器内部 |
--name | 指定容器的名字 | 随机命名 |
cmd | 覆盖容器的初始命令 | 使用容器的初始命令 |
--cpus | 限定cpu的权重 | 不限制 |
-memory | 限定内存的大小 | 不限制 |
-h | 指定容器的主机名 | 以容器端ID命名 |
2. 停止删除容器
# 停止容器 docker container stop 容器ID|容器名# 杀死容器 docker container kill 容器ID|容器名# 删除容器 docker container rm 容器ID|容器名# 批量删除容器 docker container rm -f $(docker container ls -a -q)
3. 查看容器
1. 查看容器 #查看运行中的容器 docker container ls #查看所有容器 docker container ls -a2. 查看指定容器详细信息 以下命令可以查看容器的超详细信息,以json格式显示 docker container inspect 容器ID|容器名
4. 进入容器的方法
进入容器的目的:排错,调试
# attach 方法[不常用] docker container attach [OPTIONS] 容器ID|容器名 此方法会是进入容器当前终端,会实时打印容器的输出信息,退出很麻烦[Ctrl+p Ctrl+q ],容易按成[Ctrl+c]导致容器被关闭# exec方法 docker container exec [OPTIONS] 容器ID|容器名 {命令} 常用docker exec -it xxx /bin/bash的方法打开新终端进入容器
四 端口映射
1.docker容器为什么要使用端口映射
默认情况下,容器使用的ip网段是172.17.0.0/16,外界的用户只能访问宿主机的10.0.0.0/24网段,无法访问172.17.0.0/16网段。
而我们运行容器的目的,是希望运行在容器中的服务,能够被外界访问,这里就涉及到了外网10.0.0.0/24到容器内网172.17.0.0/16网段的转换,所以需要做端口映射。
2.docker容器端口映射的方法
docker 的端口映射是通过自动添加一条iptables规则实现的
指定映射端口
语法 | 举例 | 说明 |
---|---|---|
-p hPort:cPort | -p 8800:80 | 主机8800映射容器80 |
同上,指定多个-p | -p 81:80 -p 443:443 | 一次映射多个端口 |
-p ip:hPort:cPort | -p 10.0.0.11:8800:80 | 指定主机IP |
-p crPort | -p 80 | 随机端口映射容器80 |
-p ip::crPort | -p 10.0.11::80 | IP指定,主机端口随机 |
-p hPort:cPort:udp | -p 8800:80:udp | 默认tcp映射,改为UDP |
完全随机映射
docker run -P 将dockerfile创建镜像时指定的,需要映射出来的内网端口,做外网随机映射
五 docker资源限额
一个 docker host 上会运行若干容器,每个容器都需要 CPU、内存和 IO 资源,Docker 提供了资源限制的机制避免某个容器因占用太多资源而影响其他容器乃至整个 host 的性能。
A. 内存限额
与操作系统类似,容器可使用的内存包括两部分:物理内存和 swap。
1. -m 或 --memory:设置内存的使用限额,例如 100M, 2G。 2. --memory-swap:设置 内存+swap 的使用限额。 3. 默认情况下都为为 -1,即对容器内存和 swap 的使用没有限制。 4. 如果只指定 -m 参数,那么 --memory-swap 默认为 -m 的两倍
命令案例:
docker run -m 200M --memory-swap=300M ubuntu
允许该容器最多使用 200M 的内存和 100M 的 swap。
A1 动态修改内存限额
动态修改运行中的容器内存限额,需要用到update参数 并且不能只修改内存限制,需要同步修改swap限制,否则会报错,报错详见:
docker update --memory 2048m --memory-swap -1 gitlab
B. cpu限额
通过 -c 设置的 cpu share 并不是 CPU 资源的绝对数量,而是一个相对的权重值。 某个容器最终能分配到的 CPU 资源取决于它的 cpu share 占所有容器 cpu share 总和的比例。
默认所有容器可以平等地使用 host CPU 资源 ,并且没有限制。 通过 -c 或 --cpu-shares 设置容器使用 CPU 的权重。 如果不指定,默认值为 1024。 通过 cpu share 可以设置容器使用 CPU 的优先级。
案例:在 host 中启动了两个容器:
docker run --name "container_A" -c 1024 ubuntu docker run --name "container_B" -c 512 ubuntu
container_A 的 cpu share 1024,是 container_B 的两倍。 当两个容器都需要 CPU 资源时,container_A 可以得到的 CPU 是 container_B 的两倍。
这种按权重分配 CPU 只会发生在 CPU 资源紧张的情况下。如果 container_A 处于空闲状态,这时,为了充分利用 CPU 资源,container_B 也可以分配到全部可用的 CPU。
C. 磁盘限额
Block IO 指的是磁盘的读写,docker 可通过设置权重、限制 bps 和 iops 的方式控制容器读写磁盘的带宽。
目前 Block IO 限额只对 direct IO(不使用文件缓存)有效。
1. block IO 权重
默认情况所有容器能平等地读写磁盘,可以通过设置 --blkio-weight 参数来改变容器 block IO 的优先级。 --blkio-weight 与 --cpu-shares 类似,设置的是相对权重值,默认为 500
在下面的例子中,container_A 读写磁盘的带宽是 container_B 的两倍。
docker run -it --name container\_A --blkio-weight 600 ubuntu docker run -it --name container\_B --blkio-weight 300 ubuntu
2. 限制 bps 和 iops
bps 是 byte per second,每秒读写的数据量。 iops 是 io per second,每秒 IO 的次数--device-read-bps,限制读某个设备的 bps。--device-write-bps,限制写某个设备的 bps。--device-read-iops,限制读某个设备的 iops。--device-write-iops,限制写某个设备的 iops。
下面这个例子限制容器写 /dev/sda 的速率为 30 MB/s
# 创建一个数据卷 docker volume create xxx# 查看数据卷列表 docker volume ls# 删除一个数据卷 docker volume rm# 查看一个数据卷的属性 docker volume inspect
六 数据卷与挂载
常见的docker数据卷命令
# 创建一个数据卷 docker volume create xxx# 查看数据卷列表 docker volume ls# 删除一个数据卷 docker volume rm# 查看一个数据卷的属性 docker volume inspect
数据卷与容器卷挂载
# 绑定卷 docker run -d -p 80:80 -v /data/test/:/usr/share/nginx/html nginx# 容器管理卷 docker run -d -p 180:80 -v /usr/share/nginx/html nginx docker run -d -p 380:80 -v noah-v1:/usr/share/nginx/html nginx# 容器卷 docker volume create noah-v2 docker run -d -p 801:80 --volumes-from vc_data nginx
列出镜像列表
我们可以使用 docker images 来列出本地主机上的镜像。
runoob@runoob:~$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 14.04 90d5884b1ee0 5 days ago 188 MB php 5.6 f40e9e0f10c8 9 days ago 444.8 MB nginx latest 6f8d099c3adc 12 days ago 182.7 MB mysql 5.6 f2e8d6c772c0 3 weeks ago 324.6 MB httpd latest 02ef73cf1bc0 3 weeks ago 194.4 MB ubuntu 15.10 4e3b13c8a266 4 weeks ago 136.3 MB hello-world latest 690ed74de00f 6 months ago 960 B training/webapp latest 6fae60ef3446 11 months ago 348.8 MB
各个选项说明:REPOSITORY:表示镜像的仓库源TAG:镜像的标签IMAGE ID:镜像IDCREATED:镜像创建时间SIZE:镜像大小
同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本, 如 ubuntu 仓库源里,有 15.10、14.04 等多个不同的版本, 我们使用 REPOSITORY:TAG 来定义不同的镜像。 所以,我们如果要使用版本为15.10的ubuntu系统镜像来运行容器时,命令如下:
runoob@runoob:~$ docker run -t -i ubuntu:15.10 /bin/bash root@d77ccb2e5cca:/#
参数说明:-i: 交互式操作。-t: 终端。ubuntu:15.10: 这是指用 ubuntu 15.10 版本镜像为基础来启动容器。/bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。
如果要使用版本为 14.04 的 ubuntu 系统镜像来运行容器时,命令如下:
runoob@runoob:~$ docker run -t -i ubuntu:14.04 /bin/bash root@39e968165990:/#
如果你不指定一个镜像的版本标签 例如你只使用 ubuntu,docker 将默认使用 ubuntu:latest 镜像。
获取一个新的镜像
当我们在本地主机上使用一个不存在的镜像时 Docker 就会自动下载这个镜像。 如果我们想预先下载这个镜像,我们可以使用 docker pull 命令来下载它。
Crunoob@runoob:~$ docker pull ubuntu:13.10 13.10: Pulling from library/ubuntu 6599cadaf950: Pull complete 23eda618d451: Pull complete f0be3084efe9: Pull complete 52de432f084b: Pull complete a3ed95caeb02: Pull complete Digest: sha256:15b79a6654811c8d992ebacdfbd5152fcf3d165e374e264076aa435214a947a3 Status: Downloaded newer image for ubuntu:13.10
下载完成后,我们可以直接使用这个镜像来运行容器。
查找镜像
我们可以从Docker Hub网站来搜索镜像,网址为: https://hub.docker.com/
我们也可以使用 docker search 命令来搜索镜像。 比如我们需要一个 httpd 的镜像来作为我们的 web 服务。 我们可以通过 docker search 命令搜索 httpd 来寻找适合我们的镜像。
runoob@runoob:~$ docker search httpd
: 镜像仓库源的名称 : 镜像的描述 : 是否 docker 官方发布 : 类似 Github 里面的 star,表示点赞、喜欢的意思。 : 自动构建。
拖取镜像
我们决定使用上图中的 httpd 官方版本的镜像,使用命令 docker pull 来下载镜像。
runoob@runoob:~$ docker pull httpd Using default tag: latest latest: Pulling from library/httpd 8b87079b7a06: Pulling fs layer a3ed95caeb02: Download complete 0d62ec9c6a76: Download complete a329d50397b9: Download complete ea7c1f032b5c: Waiting be44112b72c7: Waiting
下载完成后,我们就可以使用这个镜像了。
runoob@runoob:~$ docker run httpd
删除镜像
镜像删除使用 docker rmi 命令,比如我们删除 hello-world 镜像:
$ docker rmi hello-world
创建镜像
当我们从 docker 镜像仓库中下载的镜像不能满足我们的需求时,我们可以通过以下两种方式对镜像进行更改。
1、从已经创建的容器中更新镜像,并且提交这个镜像 2、使用 Dockerfile 指令来创建一个新的镜像
更新镜像
更新镜像之前,我们需要使用镜像来创建一个容器。
runoob@runoob:~$ docker run -t -i ubuntu:15.10 /bin/bash root@e218edb10161:/#
在运行的容器内使用 apt-get update 命令进行更新。 在完成操作之后,输入 exit 命令来退出这个容器。 此时 ID 为 e218edb10161 的容器,是按我们的需求更改的容器。 我们可以通过命令 docker commit 来提交容器副本。
runoob@runoob:~$ docker commit -m="has update" -a="runoob" e218edb10161 runoob/ubuntu:v2 sha256:70bf1840fd7c0d2d8ef0a42a817eb29f854c1af8f7c59fc03ac7bdee9545aff8
各个参数说明:-m: 提交的描述信息-a: 指定镜像作者e218edb10161:容器 IDrunoob/ubuntu:v2: 指定要创建的目标镜像名
我们可以使用 docker images 命令来查看我们的新镜像 runoob/ubuntu:v2:
runoob@runoob:~$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE runoob/ubuntu v2 70bf1840fd7c 15 seconds ago 158.5 MB ubuntu 14.04 90d5884b1ee0 5 days ago 188 MB php 5.6 f40e9e0f10c8 9 days ago 444.8 MB nginx latest 6f8d099c3adc 12 days ago 182.7 MB mysql 5.6 f2e8d6c772c0 3 weeks ago 324.6 MB httpd latest 02ef73cf1bc0 3 weeks ago 194.4 MB ubuntu 15.10 4e3b13c8a266 4 weeks ago 136.3 MB hello-world latest 690ed74de00f 6 months ago 960 B training/webapp latest 6fae60ef3446 12 months ago 348.8 MB
使用我们的新镜像 runoob/ubuntu 来启动一个容器
runoob@runoob:~$ docker run -t -i runoob/ubuntu:v2 /bin/bash root@1a9fbdeb5da3:/#
构建镜像
我们使用命令 docker build , 从零开始来创建一个新的镜像。 为此,我们需要创建一个 Dockerfile 文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像。
runoob@runoob:~$ cat Dockerfile FROM centos:6.7 MAINTAINER Fisher "fisher@sudops.com" RUN /bin/echo 'root:123456' |chpasswd RUN useradd runoob RUN /bin/echo 'runoob:123456' |chpasswd RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local EXPOSE 22 EXPOSE 80 CMD /usr/sbin/sshd -D
每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。 第一条FROM,指定使用哪个镜像源 RUN 指令告诉docker 在镜像内执行命令,安装了什么。。。 然后,我们使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像。
runoob@runoob:~$ docker build -t runoob/centos:6.7 . Sending build context to Docker daemon 17.92 kB Step 1 : FROM centos:6.7 ---> d95b5ca17cc3 Step 2 : MAINTAINER Fisher "fisher@sudops.com" ---> Using cache ---> 0c92299c6f03 Step 3 : RUN /bin/echo 'root:123456' |chpasswd ---> Using cache ---> 0397ce2fbd0a Step 4 : RUN useradd runoob ......
参数说明:-t :指定要创建的目标镜像名. :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径
使用docker images 查看创建的镜像已经在列表中存在,镜像ID为860c279d2fec
runoob@runoob:~$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE runoob/centos 6.7 860c279d2fec About a minute ago 190.6 MB runoob/ubuntu v2 70bf1840fd7c 17 hours ago 158.5 MB ubuntu 14.04 90d5884b1ee0 6 days ago 188 MB php 5.6 f40e9e0f10c8 10 days ago 444.8 MB nginx latest 6f8d099c3adc 12 days ago 182.7 MB mysql 5.6 f2e8d6c772c0 3 weeks ago 324.6 MB httpd latest 02ef73cf1bc0 3 weeks ago 194.4 MB ubuntu 15.10 4e3b13c8a266 5 weeks ago 136.3 MB hello-world latest 690ed74de00f 6 months ago 960 B centos 6.7 d95b5ca17cc3 6 months ago 190.6 MB training/webapp latest 6fae60ef3446 12 months ago 348.8 MB
我们可以使用新的镜像来创建容器
runoob@runoob:~$ docker run -t -i runoob/centos:6.7 /bin/bash [root@41c28d18b5fb /]# id runoob uid=500(runoob) gid=500(runoob) groups=500(runoob)
从上面看到新镜像已经包含我们创建的用户 runoob。
设置镜像标签
我们可以使用 docker tag 命令,为镜像添加一个新的标签。
runoob@runoob:~$ docker tag 860c279d2fec runoob/centos:dev
docker tag 镜像ID,这里是 860c279d2fec ,用户名称、镜像源名(repository name)和新的标签名(tag)。 使用 docker images 命令可以看到,ID为860c279d2fec的镜像多一个标签。
runoob@runoob:~$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE runoob/centos 6.7 860c279d2fec 5 hours ago 190.6 MB runoob/centos dev 860c279d2fec 5 hours ago 190.6 MB runoob/ubuntu v2 70bf1840fd7c 22 hours ago 158.5 MB ubuntu 14.04 90d5884b1ee0 6 days ago 188 MB php 5.6 f40e9e0f10c8 10 days ago 444.8 MB nginx latest 6f8d099c3adc 13 days ago 182.7 MB mysql 5.6 f2e8d6c772c0 3 weeks ago 324.6 MB httpd latest 02ef73cf1bc0 3 weeks ago 194.4 MB ubuntu 15.10 4e3b13c8a266 5 weeks ago 136.3 MB hello-world latest 690ed74de00f 6 months ago 960 B centos 6.7 d95b5ca17cc3 6 months ago 190.6 MB training/webapp latest 6fae60ef3446 12 months ago 348.8 MB