docker-1
来源:互联网 发布:js面向对象教程 编辑:程序博客网 时间:2024/06/06 01:45
Docker是什么?
Docker是一个轻量级的(Go语言)开源的应用容器引擎技术(非常方便的发布应用到容器中),容器类似于虚拟机技术(xen、kvm、vmware、virtual)。Docker是直接运行在当前操作系统(Linux)之上,而不是运行在虚拟机中(容器使用宿主操作系统的内核,而虚拟机使用独立的内核,但是它只能用在 64 位的操作系统上),但是也实现了虚拟机技术的资源隔离,性能远远高于虚拟机技术。Docker支持将软件编译成一个镜像(image),在这个镜像里做好对软件的各种配置,然后发布这个镜像,使用者可以运行这个镜像,运行中的镜像称之为容器(container),容器的启动是非常快的,一般都是以秒为单位。这个有点像我们平时安装ghost操作系统,系统安装好后软件都有了,虽然完全不是一种东西,但是思路是类似的。Docker 帮助系统管理员和程序员在容器中开发应用程序,并且可以扩展到成千上万的节点。
目前各大主流云计算平台都支持Docker容器技术,包括阿里云、百度云平台(资源隔离通过Dockert实现)、Cloud Foundry(和Spring一家公司的,目前最成熟也最稳定)、HeroKu、DigitalOcean、OpenShift(JBoss的)、Apache Stratos、Apache MesOS(批处理平台,支持搭建基于Docker的云平台)、Deis(开源PaaS平台);连微软也在Windows Server及其云平台Azure上支持Docker,这样看来Docker大有统一云计算的趋势。
这里的云计算平台一般指的是PaaS(平台即服务),它是一个这样的云计算平台:提供了存储、数据库、网络、负载均衡、自动拓展等功能,你只需将你的程序交给云计算平台就可以了。你的程序可以是用不同的编程语言开发的,而使用的Docker的云计算平台就是用Docker来实现以上功能及不同程序之间的隔离的。
目前主流的软件以及非主流的软件大部分都有人将其封装成Docker镜像,我们只需下载Docker镜像,然后运行镜像就可以快速获得已经做好配置可运行的软件。使用Docker后我们将不用手动下载、安装和配置这些软件(Oracle XE,Redis,MongoDB,ActiveMQ,RabbitMQ)。
特征
面向产品、面向开发、面向测试、面向运维、面向自动化、面向微服务、面向大规模的分布式架构
局限性
基于Linux64位的,不能再32bit环境下运行
GuestOS只能是Linux Base
隔离性相对于KVM等虚拟化技术有所欠缺
采用cgroup的resource control对于cpu的度量很难(内存、硬盘)
container随着用户进程的停止而销毁
dokcer和LXC(ubuntu)的区别
docker更专注部署,而LXC专注于进程的隔离
docker有更好的api方便对于docker容器的管理
dockerfile让image的创建变得容易
通过docker hub 方便image的分享
未来(focus)
网络(容器间通信)
安全性
容器引擎(libcontainer)
Linux FS
第一层:boot file system(bootfs),包含bootloader和kernal,在启动完成后,kernel在内存中,bootfs解除挂载
第二层:root file system(rootfs),包括/bin等目录,这些是和kernel无关,和不同的Linux分发版本有关
Linux FS in Docker
Kernel->BusyBox/Debian->rootfs
FS in Docker
传统Linux启动时,将rootfs设置为readonly并检查完整性,然后设置成read-write
Docker在启动container的时候,也是把rootfs设置为readonly,然后通过aufs把一个readwirte的文件系统挂载到rootfs之上,并且把下层文件系统设置成readonly,这样构成一个完整的操作系统
Layer FS
对于每一层readonly的FS,在docker中称为image
对于顶上read-write的FS,称为container
对于readonly中内容的修改,采用的是COW的技术,把文件复制到read-write层并改写,实际用户看到的是当前container层中的文件,image中的文件不会被影响,通过覆盖文件达到实际效果
Image
除了base image之外,每一层Image 都有一个parent image(单链表)
没有parent iamge的镜像叫做base image(操作系统)
基于COW的技术,image部分是不会被修改的,因此container可以共享image层的FS,提高了存储的效率
lxc,aufs/btrfs:Kernel:bootfs->Debian:Base Image->add emacs:Image(refereces parent)->add Apache:Image->Writeable:Container
Storage driver
除了默认的aufs之外,docker通过对于storage的抽象,可以支持一些其他的storage driver,通过vfs,devicemapper,btrfs
修改docker启动时候的参数设置,增加-storage-driver={storage plugin}在配置文件中
镜像命名和版本管理
base image是docker官方提供的基础镜像
普通镜像的命名规范{namespace}/{repository name}:{tag}
namespace是docker hub的用户名,实际是起到了namespace的作用
repsitoty ,类似与github的项目,例如ubuntu,mysql等
tag,表示版本信息,例如cesc/mysql:5.5,tag是可选的,默认值的latest
Image
对于不存在的Image,Docker会自动去Registry里面下载对应的Image,然后再运行Container
COMMAND
Command标志的是在container中实际运行的首进程
如果Image里面包含了CMD的指令,那么在启动container的时候,不需要指定Command,否则会使用指定的Command来覆盖Image中的CMD
前台运行VS后台运行
默认的Container是在前台运行的,会绑定Command进程的STDIN,STDOUT,STDERR到console上
可以通过-d选项让Container运行在后台
如果是在前台运行,也可以通过指定-a {STDOUT,STDIN,STDERR}选择需要绑定的IO
通过attach命令可以重新attch一个后台运行的container
Container Identification
在后台运行的情况下,RUN命令会返回一个UUID,唯一标示Container
可以通过docker ps来查看container的UUID和运行信息
可以通过指定–name的方式来指定container的名字,name必须唯一
inspect
通过docker inspect{Container ID}来获取container的更多的信息,包括网络,Volume,实际在Host上的进程等信息
Log
通过Logs命令可以看到Container中Command所指向进程的STDOUT,STDERR数据
环境变量
通过-e参数,可以在运行container的时候添加系统环境变量
网路设置
docker使用bridge的方式来实现Container之间以及外部的通信
Network架构:描述:Host:{Bridge docker0{{Container ‘app’,{Tomcat (port 8080)}},{Container ‘app’,{Tomcat (port 8080)}})}
在Host主机上的一个veth{id}的虚拟网卡和一个container里面的eth0网卡一一映射
Host上的bridge负责把数据流在不用的veth间转发,实现网络的IO
bridge(docker0)使用RFC1918私有网络,给每一个container分配IP
通过–net参数来修改container的网络设置,默认是bridge的方式
none 表示关闭container的网络连接
host表示主机的网络栈,这个时候host主机不会创建veth虚拟网卡映射
container:{name|id},使用另外一个container的网络栈
DNS
默认使用Host的DNS配置
可以通过–dns的参数来指定container自己的dns配置
端口映射
Docker通过采用端口映射的方式,允许把内部Container的服务端口暴露到外部
使用-p参数可以指定需要暴露的container的内部端口,在不指定特定的Host的对应端口的情况下,docker会自动分配(49000-49900)在一个Host上的端口与其映射
使用-P参数,表示暴露所有在Image中通过EXPOSE指定的端口,或者随机端口
Volume绑定
通过-v参数,可以把Host上的一个目录绑定到container中,允许container对其进行读写
容器间通信
通过Link参数,把container的端口信息暴露到另一个container中,实现container之间的通信
Dockerfile
Docker通过对于在Dockerfile中的一系列指令的顺序解析实现自动的Image的构建
build命令
通过使用build命令,根据Dockerfile的描述来构建镜像
build的两种方法
通过源代码路径的方式
通过标准输入流的方式
通过源代码路径
Dockerfile需要放置在项目的根目录位置
在构建的时候,Docker Client会把整个Context打包发送到Docker Server端,然后由Server端负责build镜像,在构建成功后,会删除Context目录
docker build -t {镜像名字} {项目的路径,可以是相对路径}
通过标准输入流
通过标准输入流的方式获取Dockerfile的内容
client不会打包上传Context目录,因此对于一些ADD,COPY等涉及Host本地文件复制的操作不够支持
docker build -t {镜像名字}-< Dockerfile路径
build cache
Dockerfile 中的每一个指令执行完毕后,都会提交为一个Image,这样保证了指令之前不会有影响
Docker会尽可能尝试重用之前已经构建的镜像
可以通过在build命令中增加–no-cache的方式来禁用cache
dockerignore
当选择源代码路径的方式构建image的时候,通过在根目录下放置dockerignore文件,来过滤不需要发送到server端的文件
类似于.gitignore的概念
Dockerfile指令
只支持Docker自己定义的一套指令,不支持自定义
大小写不敏感,但是建议全部大写
根据Dockerfile的内容顺序执行
FROM
FROM {base镜像}
必须放在Dockerfile的第一行,表示从哪个BaseImage开始构建
MAINTAINER
可选的,用来标示Image作者
RUN
每一个RUN指令都会是在一个新的Container里面运行,并提交为一个Image作为下一个RUN的Base
一个Dockerfile中可以包含多个RUN,按定义顺序执行
RUN支持两种运行方式
RUN< cmd > 这个会当做/bin/sh -c “cmd”运行
RUN[“executable”,”arg1”,….],Docker把它当做JSON的序列来解析,因此必须用双引号,而且executable需要是完整路径
CMD
CMD的作用是作为执行Container时候的默认行为
当运行Container的时候声明了Command,则不再使用Image中的CMD所定义的命令
一个Dockerfile中只能有一个有效的CMD,当定义多个CMD的时候,只有最后一个才会起作用
CMD定义三种方式
CMD < cmd >这个会当做/bin/sh -c “cmd”来执行
CMD [“executable”,”arg1”,”arg2”]
CMD[“arg1”,”arg2”],这个时候CMD作为ENTRYPOINT的参数
ENTRYPOINT
ENTRYPOINT的作用是,把整个Container变成了一个可执行的文件,这样不能够通过替换CMD的方法来改变创建Container的方式.但是可以通过参数传递的方式影响到Container内部
每个Dockerfile只能够包含一个ENTRYPOINT,多个ENTRYPOINT只有最后一个能有效
当定义了ENTRYPOINT以后,CMD只能够作为参数进行传递
ENTRYPOINT定义方式
ENTRYPOINT[“executable”,”arg1”,”arg2”],这种定义方式下,CMD可以通过JSON序列的方式来定义ENTRYPOINT的参数,可以通过在运行Container的时候通过指定Command的方式传递参数
ENTRYPOINT < cmd >,当做/bin/sh -c “cmd”运行
ADD©
当在源代码构建的方式下,可以通过ADD和COPY的方式,把Host上的文件或者目录复制到Image
ADD©的源必须在context路径下
当src为网络URL的情况下,ADD指令可以把它下载到Dest的指定位置,这个在任何build的方式下都可以work
ENV
ENV key value
用来设置环境变量,后续的RUN可以使用它所创建的环境变量
当创建基于该镜像的Container的时候,会自动拥有设置的环境变量
WORKDIR
用来指定当前工作目录
当使用相对目录的情况下,采用上一个WORKDIR指定的目录作为基准
USER
指定UID或者username,来决定运行RUN指令的用户
ONBUILD
ONBUILD作为一个trigger的标记,可以用来trigger任何Dockerifle中的指令
可以定义多个ONBUILD指令
当下一个镜像B使用镜像A作为Base的时候,在FROM A指令前,会先按照顺序执行在构建A时候定义的ONBUILD指令
ONBUILD < DOCKERFILE指令>< Context>
VOLUME
用来创建一个在image之外的mount point,用来在多个Container之间实现数据共享
运行使用Json array的方式定义多个Volume
VOLUME[“/var/data1”,”/var/data2”]
或者plain text的情况下定义多个VOLUME指定
进入一个容器
sshd
nsenter
exec
sshd
在容器中开启一个SSHD的服务,通过SSH的协议登录到容器中,把容器看成一个VM
安全性不高,需要开启SSHD的服务端口
nsenter
nsenter包含在util-linux包中,用来进入一个进程的Namespace (yum install util-linux)
获取一个容器的进程ID,docker inspect –format “{{.State.Pid}}” < container-id>
nsenter –target $PID –mount –uts –ipc –net –pid
exec
docker 1.3版本引入的一个新的指令,用来进入一个容器中运行指令
Orchestration as a Service
Orchestrate as a Service的目标是协调在不同Host上的Container,把他们有机的组织在一起成为一个统一的系统
OaaS
解决Container的协调管理
单个数据中心单节点/多个节点跨数据中心
Container之间的网络通信
OaaS方案
Fig,非常简单,但是问题是不支持跨主机的Orchestrate
Kubernetes,Google推出的跨云的orchestration as a service的解决方案
Fig
Fig通过对于Docker的封装,从而方便我们构建应用的运行环境
应用运行的所有组件全部运行在Container中,通过服务发现的方式连接在一起
服务发现
Fig使用Docker自带的Link方式来实现服务发现,Fig会负责管理Link的相关信息
fig.yml
fig通过读取当前目录下的fig.yml文件来创建应用的运行环境
fig.yml中需要定义不同的service
Service
Service标示的是一个独立的组件,例如Web应用,MySQL,Redis等都可以定义为一个独立的Service,Service是可以横向拓展的
可以在Service中直接定义Image,也可以通过定义build配置项来运行时创建Image
所有的Service都会被运行为一个或者多个Docker的Container
fig.yum例子
build(.)说明从当前目录来构建Image,需要当前目录有Dockerfile,镜像名称默认是{当前目录名字_ServiceName}
command表示启动Container的CMD
links中的值是service name,这样可以在scale out中把多个container连接到自己
创建环境
fig up 命令会根据当前的fig.yml来启动container,并且根据配置信息把对应的container连接在一起
可以通过fig up{service}的方式,只启动某个Service定义的Container
如果在当前目录下反复运行fig up,会每次都重新创建新的Container,可以通过加参数–no-recreate来防止这个问题产生
检查当前环境
fig ps,类似于docker ps ,用来检查当前fig.yml所定义的service对应的Container的运行情况
水平拓展
fig scale service=Num的方式可以水平拓展service对应的Container的个数
新添加的container如果是link的源头之一,是不会被自动添加到Link的目标Container中的,这个可以通过重新创建目标Container的方式来解决
清除环境
fig stop可以用来停止Container
fig rm可以用来删除Container
调试
可以通过使用fig run{service}CMD的方式来对环境进行调试,比如需要看到实际通过Link注入到某一个Service的环境变量,可以通过fig run web export的方式
fig run也是运行一个Container,如果该Service依赖于其他的Service,并且其他的Service没有被创建,那么也会先创建其他Service的Container,可以通过设定–no-deps来禁止
我为什么要使用Docker?
作为新手,在一台linux机器上安装一些服务可能是麻烦的,而通过Docker已有镜像安装这些是极其方便而高效的,Docker可以减少运维成本而提高资源利用率,在结合已有的开发框架后,项目开发更加迅捷,比如说SpringBoot创建了微服务工程后,直接扔到Docker中运行,或许中间会通过一个持续代码交付平台,。。。。。。。
如何使用Docker?
安装
Centos系统中:(Docker 软件包已经包括在默认的 CentOS-Extras 软件源里;为了方便之后的使用,以管理员权限安装)
sudo yum install docker
卸载
`需要先知道已经安装了哪些docker的功能,然后依次删除掉yum list installed|grep docker复制每一行前面的名称后yum -y remove *删除旧的文件夹rm -rf /var/lib/docker `
配置加速
echo "DOCKER_OPTS=\"\$DOCKER_OPTS --registry-mirror=http://f2d6cb40.m.daocloud.io\"" | sudo tee -a /etc/default/dockerDOCKER_OPTS="$DOCKER_OPTS --registry-mirror=http://f2d6cb40.m.daocloud.io"
通过查看版本号检测是否安装成功
docker -v
启动
systemctl start docker.service(CentOS 7之前)旧式指令为: service docker start
设置为开机启动
systemctl enable docker.service(CentOS 7之前)旧式指令为: chkconfig docker on
*通过查看进程检测是否启动成功*
ps aux|grep docker 通过管道转换进程流输出显示
关闭
systemctl stop docker.service
搜索镜像
在Docker中各种应用或者服务都是一个镜像,如键值对缓存技术Redis,反向代理服务器Nginx,JMS型的消息队列ActiveMQ,AMQP型的消息队列RabbitMQ……….这些都可以通过直接安装而获得服务,可以简化配置,默认仓库是docker hub,按照start量排名
docker search 镜像名
在搜索结果中,列名中OFFICIAL一栏中值为OK的即为官方版
安装镜像
docker pull 镜像名
默认是latest的TAG
通过查看已经安装的全部镜像检测是否安装成功
docker images
其中REPOSITORY一列中表示的是该镜像所在的仓库的名称(默认来自DockerHub),TAG(标签),IMAGE ID(镜像ID):每一个镜像都有一个唯一的镜像ID,CREATED:上次修改的时间,SIZE(大小)
这里的IMAGE ID其实是截断的id,查看完整的id: –no-trunc
删除镜像
docker rmi 镜像名/镜像ID(IMAGE ID)
上传镜像
docker login,登录到docker hub上
把container通过docker commit 容器id 的命令转换成一个image
通过dokcer tag 镜像id 来命名新生成的image
docker push 用名O命名/镜像名称[:tag] 到docker hub中
启动容器
运行一个container的本身就是开启一个具有独立namespace的进程(host中一个普通进程)
运行一个container必须要指定一个image作为初始化的文件系统
sudo docker run [OPTIONS] IMAGE[:TAG]_[COMMAND]-[ARG…]
docker run 镜像名 echo 'hello dokcer' 运行后会立即退出docker run --name custom_name -it 镜像名 bash 启动后进入docker容器中,相当于进入了一台新的机器,进入之后可以通过ls -al 查看所处目录中的文件(linux中包括文件夹),ps aux 查看进程 docker每次只能启动一个进程docker run -d --name custom_name 镜像名 后台模式启动一个镜像,其实也可以不需要先安装就可以启动一个镜像,因为docker会事先pull下来docker start 镜像ID 通过这种方式启动容器可以简便参数的输入镜像名称:标志 默认是启动lasted标志的版本的镜像
查看容器
docker ps -a 所有docker ps -l 当前运行中的容器
停止容器
docker stop [CONTAINTER ID]
但是这样只能停掉一个container,如果想要停掉所有的container:dokcer ps -a -q|xargs docker stop
进入容器
docker exec或者docker attachnsenter --target 容器PID --mount --uts --ipc --net --pid 容器PID如何获取?docker inspect -f {{.State.Pid}} 容器id(部分标示即可不需全部)推荐使用: docker exec -it 容器id /bin/bash
删除容器
docker rm 删除运行中的容器 docker rm -f
但是这样只能删除一个container,如果想要删除所有的container:dokcer ps -a -q|xargs docker rm
查看帮助
docker --help
进入一个已经运行的容器中
dokcer attach 容器id 这样有时候是进不去的而且之后只能ctrl+c退出然后再次查看运行中的容器时会发现该容器已经退出了nsenter 进入容器中(命名空间),如果没有需要安装 :yum install -y util-linuxnseneter --target 进程ID --mount --uts --ipc --net --pid
查看容器的信息
docker inspect --format "{{.State.Pid}}" 容器ID/其中时指定的名称
访问端口映射
随机映射:docker run -P指定映射:-p hostPort:ContainerPort-p ip:hostPort:containerPort-p ip::containerPort-p hostPort:containerPort -p hostPort:containerPort
指定数据卷
docker run -it -v /data redis查看数据卷所在位置:docker inspect -f {{.Volumes}} 容器名指定数据卷在宿主机器中的位置 dokcer run -it -v /dockerData:/dockerData redis只读:docker run -it -v /dockerData:/dockerData:ro redis
数据卷容器
专门的docker容器作为一个数据卷,作为中间人
--volumes-from 其他容器名
构建Docker镜像
FROM:基础镜像MAINTAINER:维护者信息RUN:把命令前面加上RUNADD:COPY文件(同一级),会自动解压WORKDIR:当前工作目录VOLUME:目录挂载EXPOSE:端口RUN:进程要一直运行下去docker make -t 镜像名
Docker核心原理-资源隔离和限制
LXC Kernel
- Docker(1)
- docker(1)
- docker-1
- docker 1
- Docker(1)-- 如何安装Docker
- 深入浅出Docker(1)----Docker核心技术预览
- Docker(1):Virtualbox Install Centos7 & Docker
- Docker学习1 - CentOS7安装docker
- docker【1】docker简介(入门知识)
- docker学习笔记1-docker简介
- Docker学习笔记(1)-初识docker
- 【Docker】-1-Ubuntu下安装配置Docker
- docker源码学习-docker daemon(1 )
- Docker学习(1)------Docker安装
- docker入门1 : 使用docker镜像
- Docker学习笔记1
- Docker学习笔记(1)
- 3.0.1、关于 Docker
- 【转载】Azkaban源码分析
- 一步一步学多线程-synchronized
- Axure RP 8 教程
- canvas实现简单的画图功能
- 美团编程
- docker-1
- 深入浅出TensorFlow(二):TensorFlow解决MNIST问题入门
- web前端知识总结2
- 测试一个大数是否是素数
- RecyclerView第三方开源
- 计算分数加减表达式的值
- cookie 和session 的区别详解
- next数组求解详解
- 虚拟机3种网络模式(桥接、NAT、Host-only)