Docker系统
Docker系统有两个程序:docker服务端和docker客户端
docker服务端:是一个服务进程,管理着所有的容器。也叫docker engine
docker客户端:扮演着docker服务端的远程控制器,可以用来控制docker的服务端进程。
大部分情况下,docker服务端和客户端运行在一台机器上
Docker三大核心组件:
Docker 镜像 - Docker images
Docker 仓库 - Docker registeries
Docker 容器 - Docker containers
容器的三大组成要素:
名称空间 namespace 容器隔离(pid,net,mnt,user,)
资源限制 cgroups 资源(内存,cpu)
文件系统 overlay2(UnionFS)
docker 仓库:
用来保存镜像,可以理解为代码控制中的代码仓库。同样的,Docker 仓库也有公有和私有的概念。
公有的 Docker 仓库名字是 Docker Hub。Docker Hub 提供了庞大的镜像集合供使用。这些镜像可以是自己创建,或者在别人的镜像基础上创建。
仓库(registry) -->Repository-->镜像(按版本区分)
docker.io/centos:7
registry/repository:tag
repository:存储库
docker 国内仓库
ali
网易蜂巢
daocloud
=========================
docker公有仓库
docker.io -------docker官方库也叫docker-hub
类似于github一样,面向全球的一个docker镜像的公共仓库。如果在国内使用速度太慢。
===============================
docker私有仓库
个人或者公司部署的非公开库
Docker 镜像
Docker 镜像是 Docker 容器运行时的只读模板,每一个镜像由一系列的层 (layers) 组成。Docker 使用 UnionFS 来将这些层联合到单独的镜像中。正因为有了这些层的存在,Docker 是如此的轻量。当你改变了一个 Docker 镜像,比如升级到某个程序到新的版本,一个新的层会被创建。因此,不用替换整个原先的镜像或者重新建立(在使用虚拟机的时候你可能会这么做),只是一个新的层被添加或升级了。
在 Docker 的术语里,一个只读层被称为镜像,一个镜像是永久不会变的。由于 Docker 使用一个统一文件系统,由于镜像不可写,所以镜像是无状态的。
镜像由三部分组成:
镜像名称:仓库名称+镜像分类+tag名称(镜像版本)
1.存储对象:images
2.格式:库名/分类:tag
3.tag:表示镜像版本
镜像的大体分类方式:这不是规定
1.以操作系统名字
centos的docker镜像:
centos5
centos6
centos7
-----------------
2.以应用的名字
nginx的docker镜像
tomcat的docker镜像
mysql的docker镜像
镜像名字:
完整镜像名称示例:
docker.io/library/nginx:v1
docker.io/library/nginx:latest
daocloud.io/library/nginx
镜像ID:
所有镜像都是通过一个 64 位十六进制字符串来标识的。 为简化使用,前 12 个字符可以组成一个短ID,可以在命令行中使用。短ID还是有一定的碰撞机率,所以服务器总是返回长ID。
镜像ID:64位的id号,一般我们看到的是12位的我们称之为短ID,只要我们每个ID号不冲突就可以了
镜像本身:是由一层一层的镜像合在一起的,最底层的镜像我们称为基础镜像,在这个基础镜像的基础上还可以在做镜像,在做的镜像称为子镜像,对于子镜像来讲在谁的基础之上做的就是父镜像。
基础镜像:一个没有任何父镜像的镜像,谓之基础镜像。
centos7 镜像
centos7+nginx 镜像
Docker 容器
Docker 容器和文件夹很类似,一个Docker容器包含了所有的某个应用运行所需要的环境。每一个 Docker 容器都是从 Docker 镜像创建的。Docker 容器可以运行、开始、停止、移动和删除。每一个 Docker 容器都是独立和安全的应用平台,Docker 容器是 Docker 的运行部分。
docker镜像命名解析
Docker镜像命名解析
镜像是Docker最核心的技术之一,也是应用发布的标准格式。无论你是用docker pull image,或者是在
Dockerfile里面写FROM image,从Docker官方Registry下载镜像应该是Docker操作里面最频繁的动作之一
了。那么docker镜像是如何命名的,这也是Docker里面比较容易令人混淆的一块概念:Registry,Repository, Tag and Image。
那么Registry又是什么呢?Registry存储镜像数据,并且提供拉取和上传镜像的功能。Registry中镜像是通过
Repository来组织的,而每个Repository又包含了若干个Image。
下面是在本地机器运行docker images的输出结果:
常说的"ubuntu"镜像其实不是一个镜像名称,而是代表了一个名为ubuntu的Repository,同时在这个Repository下面有一系列打了tag的Image,Image的标记是一个GUID,为了方便也可以通过Repository:tag来引用。
Image[:tag]
当一个镜像的名称不足以分辨这个镜像所代表的含义时,你可以通过tag将版本信息添加到run命令中,以执行特
定版本的镜像。
例如:docker run ubuntu:14.04
docker镜像和容器的区别
一、Docker镜像
要理解Docker镜像和docker容器之间的区别,确实不容易。。
一个Docker镜像可以构建于另一个Docker镜像之上,这种层叠关系可以是多层的。第1层的镜像层我们称之为基础镜像(Base Image),其他层的镜像(除了最顶层)我们称之为父层镜像(Parent Image)。这些镜像继承了他们的父层镜像的所有属性和设置。
Docker镜像通过镜像ID进行识别。镜像ID是一个64字符的十六进制的字符串。但是当我们运行镜像时,通常我们不会使用镜像ID来引用镜像,而是使用镜像名来引用。
要列出本地所有有效的镜像,可以使用命令
# docker images
镜像可以发布为不同的版本,这种机制我们称之为标签(Tag)。
可以使用pull命令加上指定的标签:
# docker pull ubuntu:14.04
# docker pull ubuntu:12.04
二、Docker容器
Docker容器可以使用命令创建:
# docker run -it imagename /bin/bash
它会在所有的镜像层之上增加一个可写层。这个可写层有运行在CPU上的进程,而且有两个不同的状态:运行态
(Running)和退出态 (Exited)。这就是Docker容器。当我们使用docker run启动容器,Docker容器就进
入运行态,当我们停止Docker容器时,它就进入退出态。
当我们有一个正在运行的Docker容器时,从运行态到停止态,我们对它所做的一切变更都会永久地写到容器的文
件系统中。要切记,对容器的变更是写入到容器的文件系统的,而不是写入到Docker镜像中的。
我们可以用同一个镜像启动多个Docker容器,这些容器启动后都是活动的,彼此还是相互隔离的。我们对其中一
个容器所做的变更只会局限于那个容器本身。如果对容器的底层镜像进行修改,那么当前正在运行的容器是不受影响的,不会发生自动更新现象。
名字空间--namespace
namespace 空间隔离
cgroup 资源限制
名字空间是 Linux 内核一个强大的特性。每个容器都有自己单独的名字空间,运行在其中的应用都像是在独立的操作系统中运行一样。名字空间保证了容器之间彼此互不影响。
- pid 名字空间
不同用户的进程就是通过 pid 名字空间隔离开的,且不同名字空间中可以有相同 pid。所有的 LXC 进程在 Docker中的父进程为Docker进程,每个 LXC 进程具有不同的名字空间。同时由于允许嵌套,因此可以很方便的实现嵌套的 Docker 容器。
-
net 名字空间 ----做网络接口隔离的
有 了 pid 名字空间, 每个名字空间中的 pid 能够相互隔离,但是网络端口还是共享 host 的端口。网络隔离是通过 net 名字空间实现的, 每个 net 名字空间有独立的 网络设备, IP 地址, 路由表, /proc/net 目录。这样每个容器的网络就能隔离开来。
ipc 名字空间
容器中进程交互还是采用了 Linux 常见的进程间交互方法(interprocess communication - IPC), 包括信号量、消息队列和共享内存、socket、管道等。
面试题:linux系统里面ipc通信有几种方式
socket:网络进程间的通信
管道:本地进程间的通信:echo hello | grep e
信号: kill -9 PID 这种我们叫信号量级,也是本地进程间的通信
共享内存:每个操作系统里面共享内存多大,是物理内存的一半
- mnt名字空间
mnt 名字空间允许不同名字空间的进程看到的文件结构不同,这样每个名字空间 中的进程所看到的文件目录就被隔离开了。
- uts 名字空间
UTS("UNIX Time-sharing System") 名字空间允许每个容器拥有独立的 hostname 和 domain name, 使其在网络上可以被视作一个独立的节点而非主机上的一个进程。
- user 名字空间
每个容器可以有不同的用户和组 id, 也就是说可以在容器内用容器内部的用户执行程序而非主机上的用户。