docker详解

初识docker

主机级虚拟化分为两类:第一种是安装再host之上,另一只是直接再硬件上安装一个虚拟化系统
主机级虚拟化与容器级虚拟化异同:
	目的相同:都是为了实现进程隔离
	主机级虚拟化隔离:为了实现隔离运行进程需要创建一个系统,代价太大
	容器级虚拟化隔离:因为进程是在用户空间运行,所以只隔离用户空间

容器级虚拟化的实现lxc核心为以下三部分:
	chroot
	namespaces名称空间:
		域名、主机名(UTS);
		文件树(mount)
		进程间通信(IPC)
		进程树(PID)				
		用户和组(user)
		网络(net)
	cgroups(系统级资源分配)
		把系统级资源分成多个组,然后把每个组内资源量指派给用户空间		

在这里插入图片描述
在这里插入图片描述

docker:
	docker是lxc的增强版或二次发行版,是内核容器技术的前端工具,老版本的docker是把lxc作为其引擎,极大简化了lxc创建用户空间时通过定制模板进行安装的复杂过程,docker是通过将整个调试部署好的运行环境打包成镜像直接运行镜像进行创建用户空间,优化了批量创建管理功能,后来docker已经抛弃lxc引擎,采用libcontainer引擎,再到目前容器运行时的环境标准化的实现runC引擎
	docker底层通过分层构建联合挂载的机制实现,每一底层镜像都是只读和共享的,最上层才是私有的可读写的,这样极大方便了分发效率、过程,程序数据会保存到外挂盘中,这样可以方便迁移,脱离容器实现持久存储
	遵循一个容器一个进程的原则:
	 	 弊端:但是会占用更大的空间,每个容器都需要自带调试查看工具
	  	 优势:极大的方便了开发人员,可以跨平台、系统和开发语言,真正实现了一次编写到处运行,部署方便配置好镜像一条命令就可以运行
编排工具:
	作用:实现程序编排(解决程序间依赖关系和启动顺序等)和底层资源调用
	docker与k8s都是用go语言研发
	实现:
		machine+swarm+compose		docker自带
		mesos+marathon	底层资源编排
		kubernetes/k8s	主流编排工具
docker架构:C/S,由三部分组成:
	Daemon:docker主机运行的守护进程
		Containers
		Images	本地镜像仓库
	Client:通过http或https协议传输
	Registries :注册表,远程镜像仓库,默认为 docker hub(或可以选择一些国内镜像仓库),通过http或https协议传输,默认是https
		功能:认证、索引、镜像仓库,不同于yum仓库,Registries里每个不同的应用程序都有一个单独的仓库,仓库名就是应用程序名,镜像名字是仓库名+tag并且一个镜像可以有多个标签,如果下载镜像时不给标签,默认下载最新版镜像(latest标签的镜像),一般下载时可以选在稳定版(stable标签)镜像
		
镜像与容器的关系:类似于执行命令,执行命令需要加载本地文件并启动一个进程,而本地文件可以看作镜像,进程可以看作容器,当命令执行完之后进程就会停止,而本地文件还在,同理容器中应用程序停止后容器也会停止,而镜像还在。

docer对象:因为在docer上都是静态风格的接口,所以每一组件都会被当做对象来管理,可单独支持增删改查,对象分别有:
		images
		containers	
		networks
		volumes	存储卷,一般在外部的网络存储之上
		plugins	

docker安装

清华大学开元镜像版本较新所以配置yum源
	cd /etc/yum.repos.d/
	wget  https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
	sed s@https://download.docker.com/@https://mirrors.tuna.tsinghua.edu.cn/docker-ce/@g   docker-ce.repo
	yum repolist 查看是否有包
	yum install -y docker-ce
或者
  	curl -fsSL get.docker.com -o get-docker.sh
	sudo sh get-docker.sh --mirror Aliyun


docker配置文件
	/etc/docker/daemon.json(启动前可以手动创建)
docker镜像加速配置:可以用以下三种
	docker cn
	阿里云加速器
	中国科技大学 
	
	cn 配置:
		 {
				 "registry-mirrors": ["https://registry.docker-cn.com"]
		 }

 查看:
 	 docker version 查看docker相关版本信息
 	 docker info  查看详细信息如(容器、镜像等)  

docker基础命令的使用
在这里插入图片描述

docker 
	search  imagename 搜索远端镜像
	-H, --host list       远程管理所指定的主机,需修改配置文件
		示例:
			docker -H 10.0.0.2:2347 image ls 
	login  登录registry
		Usage:  docker login [OPTIONS] [SERVER]
		Options:
		 -p, --password string   Password
		 -u, --username string   Username
	**image 	镜像相关命令**
		pull   [registry][:port] /[<namespace>/]<name>:<tag>  拉取镜像,[registry][:port}省略时默认为Hub registry,端口省略时默认为https(443端口),[<namespace>/]省略时默认为顶级仓库 
			示例:
				docker image pull quay.io/coreos/flannel:v0.10.0-amd64
		push  推送本地镜像到registry,注意本地标签一定要与所推送的registry信息一致,并且需要先登录registry才能push
			Usage:  docker image push [OPTIONS] NAME[:TAG]
			示例:
				docker image push cuijian/httpd
		save	打包导出镜像
        	Usage:  docker image save [OPTIONS] IMAGE [IMAGE...]  可一次打包多个
        	Options:
			  -o, --output string   Write to a file, instead of STDOUT  指定打包的文件
			 示例:
			 	docker image save -o nginx.gz cuijian/nginx:v0.1 cuijian/nginx:v0.2
		load	 镜像导入
        	Usage:  docker image load [OPTIONS]
        	Options:
				-i, --input string   Read from tar archive file, instead of STDIN
			示例:
				docker image load -i  nginx.gz	
		ls  [REPOSITORY[:TAG]] 列出本地镜像,
		inspect 查看镜像详细信息,其中CMD内容为镜像的默认启动的第一个进程命令
		rm 	
		tag	添加标签,一个镜像可以有多个标签
			Usage:  docker image tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
			示例:
				docker image tag  4996f4623cd5 cuijian/nginx:v0.1-1				
				docker image tag  cuijian/nginx:v0.1-1  cuijian/nginx:latest	
		build  制作镜像
			Usage:  docker image build [OPTIONS] PATH | URL | -
			Options:
				-t, --tag list  打标签
				--build-arg list          设置构建时的变量
			

	**container  容器相关命令**
		inspect  查看容器详细信息
		exec  Usage:  docker container exec [OPTIONS] CONTAINER COMMAND [ARG...] 
			绕过容器边界,在容器中执行外部命令,并顶替和取代ID为1的进程,但为保障容器中ID为1的进程不变依然能接收容器启动停止等信号,容器内默认又进行exec				
			-it  附加终端并交互式登录		
			示例:
				 docker container  exec -it ngx1 /bin/sh	
		create
		start
			-ai	附加交互式接口
		stop
		kill
		port  查看指定容器中的端口映射
		log  日志直接保存在控制台中
		run  [OPTIONS] IMAGE [COMMAND] [ARG...] 创建并启动容器; [COMMAND] [ARG...] 指定启动时的命令和参数
		在容器中跑任何程序不能运行在后台,否则容器任务程序不存在而终止容器
			-t, --tty  附加一个终端
			-i  交互式访问
			--name string  容器名称				
				示例:注意因为busybox默认运行/bin/bash为主进程,shell有交互接口且必须要附加终端进行交互才能使进程在前台运行,否则容器运行即推出,如果默认进程非/bin/bash 可以用exec /bin/bash 替换默认进程进行交互
					docker run --name b1 -it busybox:latest 
			-d  启动后挂载到后台,与容器外的当前系统的终端剥离
			--rm  容器停止即删除
			--network [bridge/host/none/container:CONTAINER]  选择一个网络模型,默认为bridge
				示例:
					创建联盟式网络模型web2,共享web1的网络相关名称空间
					docker	--name web2  -d --network container:web1 cuijian/nginx:v0.1			
			-h, --hostname string 从容器外注入主机名
			--add-host list(host:ip) 添加本地解析
			--dns list 设置自定义的dns列表
			-p   [ip:][port:]<port> 暴漏容器的指定端口,可以使用多次(bridge网络模型使用的是nat桥模式,所以需要主动把桥内部容器暴露出来,外部主机才能进行访问内部容器,所以一共有4中暴露方式)
				示例:
					暴漏容器web1的80端口,映射到物理机所有网卡的随机端口上
					docker run --name web1 -p 80 cuijian/httpd:v0.2
					暴漏容器web1的80端口,映射到物理机所有网卡的8080端口上
					docker run --name web1 -p 8080:80 cuijian/httpd:v0.2
					暴漏容器web1的80端口,映射到物理机172.16.0.67网卡的随机端口上
					docker run --name web1 -p 172.16.0.67::80 cuijian/httpd:v0.2
					暴漏容器web1的80端口,映射到物理机172.16.0.67网卡的8080端口上
					docker run --name web1 -p 172.16.0.67:8080:80 cuijian/httpd:v0.2
			-P 暴漏所有端口	
			--volumes-from  复制另一个容器的存储卷,可以与共享网络同时用
			-e, --env list           启动容器时设置变量值				
		pause  暂停
		unpause  取消暂停
		top	显示资源消耗情况
		ls  显示运行中的容器
			-a 显示所有容器,包括停止的
		commit  制作镜像
			Usage:  docker container commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]  
			Options:
        		-a, --author string    Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")
	        	-p, --pause	创建时使容器出于暂停状态
        		-c, --change list    :修改容器内部默认启动时命令
        	示例:(-f 为运行在前台 -h 为指定根目录)
        		docker container commit  -a "cuijian <cuijian@163.com>" -c 'CMD ["/bin/httpd","-f","-h","/date/nginx"]' -p box1 cuijian/httpd:v0.3
        		
	network	网络相关命令
		inspect 查看网络详细信息
			Usage:  docker network inspect [OPTIONS] NETWORK [NETWORK...]
			示例:
				docker network inspect bridge
		ls

镜像管理

docker镜像:
	含有启动容器所需要的文件系统及内容,因此其用于创建并启动docker容器
	采用分层构建机制,最底层为为bootfs,其上层为rootfs(真正用来构建用户空间并运行容器的)
		bootfs:用于系统引导的文件系统,包括bootloader和kernel,容器启动完成后会被卸载以节约内存资源;
		rootfs:位于bootfs之上,表现为docker容器的根文件系统;
			传统模式中,系统启动时,内核挂载rootfs时会首先将其挂载为”只读“模式,完整性自检完成后将其重新挂载为读写模式;
			docker中,rootfs由内核挂在为”只读“模式,而后通过”联合挂载“技术额外挂载一个”可写“层;
	镜像分层:
		基础镜像:docker镜像中最底层
		父镜像:位于下层镜像是上层镜像的父镜像
		可读写层(启动的容器中生成):最上层为”可读写“层,其下的均为只读层
		示例:在一个apache镜像中,底层为bootfs引导层,在上层会有一个非常基础的例如centos系统,在上层是一个vi工具,在上层才是apache,当容器启动完成后会把bootfs从内存中卸载掉,然后在内存中添加一个可读写层(容器删除此层也会被删除包括所有数据),除了读写层是容器私有,其他的相当于本地文件是其他容器可共享的,

	存储镜像文件系统:要实现这种镜像分层和联合挂载技术需要依赖于专有的文件系统
		aufs:联合文件系统,docker早期使用的文件系统
		overlayfs:叠加文件系统,已合并到3.18Linux内核之中,目前为止docker所使用的文件系统驱动,是一种抽象的二级文件系统,需要建构在本地文件系统之上

Docker Registry:用于保存docker镜像,包括镜像的层次结构和元数据
	分类:
		Sponsor Registry:第三方的registry,供客户和docker社区使用
		Mirror	Registry:第三方registry,只让客户使用
		Vendor Registry:由发布Docker镜像的供应商提供的registry
		Private Registry:通过设有防火墙和额外的安全层的私有实体提供的registry,自建registry,可以不消耗网络带宽
	组成:
		Repository:
			由某特定的docker镜像的所有迭代版本组成的镜像仓库
			一个Registry中可以存在多个Repository
				Repository可以分为”顶层仓库“和”用户仓库“
				用户仓库名称格式为”用户名/仓库名“
			每个仓库可以包含多个Tag,每个标签对应一个镜像
		Index
			维护用户账号、镜像的校验以及公共命名空间的信息
			相当于为Registry提供了一个完成用户认证等功能的检索接口
			
	云原生:基于单机系统开发的程序在容器中修改维护配置时有诸多不便,因此就基于云环境或接口而开发的程序,例如可以直接传环境变量修改配置

docker hub:默认Docker Registry  
	功能:	
		镜像仓库:
		自动构建:把更新的文件提交到github中,然后docker hub会获取这文件并进行自动构建为新的镜像
		Webhooks:钩子,与github关联,当github更新时自动触发钩子进行构建镜像
		用户组		

阿里云registry的使用:
	登录阿里云搜索容器镜像服务
	找到镜像加速器根据器上的内容添加到配置文件中并重启
	进入实例列表的个人实例创建命名空间和仓库
	进入仓库中根据其中的操作指南进行上传或拉取代码`在这里插入代码片`
	示例:
		创建镜像或者打标签:
			docker image tag  cuijian/httpd:v0.3  registry.cn-qingdao.aliyuncs.com/cuijian442230/test:v0.1
		登录:
			docker login --username=cuijian442230 registry.cn-qingdao.aliyuncs.com
		推送:
			docker image push registry.cn-qingdao.aliyuncs.com/cuijian442230/test:v0.1		

镜像制作有三种方式:
	dockerfile  然后build成镜像
	基于容器制作(docker commit),会把运行容器中的可写层单独创建一个镜像
	docker Hub automated builds (类似于Docker file),docker Hub上的子自动构建镜像功能				
	(1)基于容器做镜像
			示例:
				创建镜像:docker container commit  -a "cuijian <cuijian@163.com>" -c 'CMD ["/bin/httpd","-f","-h","/date/nginx"]' -p box1 cuijian/httpd:v0.3
				登录registry:docker login -u cuijian -p 123456
				远程推送 :docker image push cuijian/httpd

镜像的导入导出:
	示例:
		导出:
			docker image save -o nginx.gz cuijian/nginx:v0.1
		导入:
			docker image load -i  nginx.gz

容器虚拟化网络概述
补充内容
VMware虚拟机三种网络模式:桥接模式,NAT模式,仅主机模式
brctl命令:网桥管理,安装包:yum install bridge-utils -y
ip netns 配置网络名称空间

网络名称空间:主要用于实现协议栈、网络设备等的隔离	
docker*安装完成之后会自动生成一个bridge(nat桥,可以用docker network ls 查看)网络和一个docker0接口,它既可以当交换机使用又可以当网卡使用,每当创建一个容器时就会自动生成一对虚拟网卡,其中一段在容器中,另一端就在docker0这个交换机上。(docker0和与交换机相连的虚拟接口可以ifconfig查看,网桥可以用brctl show 查看),所以同一台主机上的创建的容器都在同一个bridge上时是可以直接通信的,而所在的物理机是直接把docker0这个虚拟交换机直接当网卡用了,默认IP为172.17.0.1,所以也可以直接跟容器通信,但是在创建容器时因为是nat'桥,默认进行了地址伪装(SNAT,可以在物理机iptables -nL 查看),所以其他外部主机是访问不到此物理机上的容器的,想要被访问需要主动暴漏发布端口(DNAT),但是用这种网络模型,如果有多个容器都使用80端口,并且物理机上只有一个网卡,就导致只能有一个容器在对外暴漏时的端口是80,其他的需要选择其他端口,并且如果双方都是容器都要经过nat转换导致通信效率低下。解决方法:叠加网络。当然还有物理桥桥接,不过这种在大型环境上容易出现网络风暴
Overlay Network(叠加网络):基于隧道,在原有IP报文之上在封装一层IP报文,通信时首先外层IP报文通信,在找到对应主机后,在通过内层IP报文找到真正要访问的物理主机之上的虚拟主机服务器,因此容器可以直接暴漏端口不在需要DNAT映射

docker中有4种网络模型
	bridge(默认)  使用虚拟网卡nat桥到虚拟交换机docker0上
	开放式容器(host):  共享物理网卡(容器共享主机的网络相关的名称空间),对容器中的网络有修改权限,在容器中创建的进程可以直接通过物理机网卡接口网访问
 	封闭式容器(none):  无网络只有一个lo(本地回环)接口
 	(bridge/host/none 网络模型启动时可以直接用 run --network 指定 )
 	
	联盟式网络:一台物理机的多个容器其中6个名称空间的User、PID、Mount为私有,但是UTS、IPC、NETWORK共享一个名称空间,lo本地回环接口可以直接访问共享一个网络相关名称空间的所有容器,启动时需要docker run container:CONTAINER参数
		例如:docker  container run --name b2 	--network container:b1  busybox:latest	


自定义docker0桥的网络属性信息
核心选项为bip,即bridge ip之意,用于指定docker0桥自身的IP地址;其它选项可通过此地址计算得出。
	vim /etc/docker/daemon.json文件
	{
	"bip": "192.168.1.5/24",
	"fixed-cidr": "10.20.0.0/16",
	"fixed-cidr-v6": "2001:db8::/64",
	"mtu": 1500,
	"default-gateway": "10.20.1.1",
	"default-gateway-v6": "2001:db8:abcd::89",
	"dns": ["10.20.1.2","10.20.1.3"]
	} 
	
远程管理
	dockerd守护进程的C/S,其默认仅监听Unix SOcket格式的地址,/var/run/docker.sock(只监听在本地),如果想要守护进程监听在TCP套接字上需要修改配置文件并重启docker:
		vim	/etc/docker/daemon.json
			"hosts": ["tcp://0.0.0.0:2375", "unix:///var/run/docker.sock"]
	配置完成之后可以远程连接命令测试示例:
		docker -H 10.0.0.2:2347 image ls 

创建虚拟桥
docker network create:
	Usage:  docker network create [OPTIONS] NETWORK
	Options:
				-d, --driver [bridge/host/ipvlan/macvlan/null/overlay] 选择网络模型/驱动,默认为bridge
				--subnet  子网掩码
				--gateway  
	示例:
		docker network  create -d bridge --subnet "172.16.0.0/16" --gateway "172.16.0.1" bridge2
			查看网络: docker network ls
			查看接口:ifconfig
			改接口名: ifdown br-34a62d88abbe && ip link set dev br-34a62d88abbe name  eth1
	补充:想在同一个docker中的两个网络(网桥)内的容器进行通信只需要打开宿主机的网络转发并且开通自动生成的防火墙规则即可					

Docker 存储卷

读写层:
	Docker镜像由多个只读层叠加而成,启动容器时docker会加载只读镜像层并在镜像栈顶部(内存中)添加一个读写曾
写实复制:
	如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制该文件到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏,此即“写实复制”机制
	缺点,I/O效率低下,在对I/O要求较高的服务例如:mysql、redis ,满足不了其对性能的需求
		解决实现技术:存储卷

存储卷:docker容器的文件系统是分层构建联合挂在,因为结构的复杂使得io效率很慢,这时就可以把宿主机或NFS服务器等的一个目录挂在到容器中读写层的一个目录中从而绕过容器的文件系统提高io效率
	优点:
		可以实现脱离容器的生命周期而使数据持久
		易于容器间数据共享
		宿主机访问数据方便		
	docker的存储卷目前默认是本机的文件系统,容器只能在同一台主机上才能调度存储卷,如果有状态分布式服务想要实现跨主机存储就需要找到之前的持久数据,这个docker本身无法实现需要运维人员通过NFS等共享存储和编排工具等实现
	
创建存储卷有两种方式,用docker run -v 实现:
	第一种:只需要指定容器中的一个路径即可,容器驱动会根据规则自动关联到宿主机目录
		示例:
			docker container run -it --name t1 -v data busybox
	第二种:需要指定宿主机目录和容器中目录(甚至可以两个容器共享一个宿主机目录)
		docker container run -it -v HOSTDIR:VOLUMEDIR --name t1 busybox
	查看命令:
		docker container inspect CONTAINERNAME
		docker container  inspect  -f {{.Mounts}} web2  用go模板进行过滤
			查看Volumes值和Mounts值

启动容器并复制另一个容器的存储卷
	前置:生产中经常把一个容器不启动当作底层支撑容器(模板),让其他容器复制它的配置
	示例:
	docker run --name bbox2 --volumes-from bbox1 busybox

Dockerfile基础

dockerfile:是构建镜像的文本文件,在用镜像启动容器时会先启动另一个程序用来读取dockerfile的配置和传递的参数,然后再用容器中的进程替换此程序实现按需配置启动
	优点:可以一次编写多节点传递参数并生效
格式:
	#注释
	from指令(第一个非注释行为form指令来指定做当前镜像是用哪个基础镜像)
	指令  + 参数 :从上往下顺序执行,因此如果有依赖关系,被依赖的指令应该在上面行
要求:
 	找一个专门的dockerfile目录
 	dockerfile文件名首字母必须大写
 	如果要给镜像加入工具包,必须把相关文件或者包放在dockefile目录的当前目录或子目录中	
dockeringore(隐藏文件):所有写在这个文件中的路径,打包时都不会被包含进来

docker build 进行镜像构建镜像,构建时执行的命令是基于镜像中程序的命令而不是宿主机上的命令 
	Usage:  docker build [OPTIONS] PATH | URL | -
	Options:
		-t, --tag list
支持的环境变量,用法与bash中类似:以下两种特殊用法
	${NAME:-tom}:设置变量默认值,若变量为空则值为tom
	${NAME:+tom}:若变量有值则赋值为tom

dockerfile 指令:
注意:dockerfile中每一条命令都会生成一个镜像层,所以尽量简化命令

from: 
	FROM指令是最重的一个且必须为Dockerfile文件开篇的第一个非注释行,用于为映像文件构建过程指定基准镜像,后续的指令运行于此基准镜像所提供的运行环境
	实践中,基准镜像可以是任何可用镜像文件,默认情况下,docker build会在docker主机上查找指定的镜像文件,在其不存在时,则会从Docker Hub Registry上拉取所需的镜像文件
		如果找不到指定的镜像文件,docker build会返回一个错误信息

	 Syntax:
		FROM <repository>[:<tag>] 或
		FROM <repository>@<digest>	(@<哈希码>)
			<repository>:指定作为base image的名称;
			<tag>:base image的标签,为可选项,省略时默认为latest;
label:标签指令向镜像添加元数据
	syntax:LABLE <key>=<value>  <key>=<value>	<key>=<value>...
	示例:
		LABLE maintainer="cuijian<cuijian@163.com>"

copy:用于从Docker主机复制文件至创建的新映像文件
	Syntax
	COPY <src> ... <dest> 或
	COPY ["<src>",... "<dest>"] 
		<src>:要复制的源文件或目录,支持使用通配符
		<dest>:目标路径,即正在创建的image的文件系统路径;建议为<dest>使用绝对路径,否则,COPY指定则以WORKDIR为其起始路径;
		注意:在路径中有空白字符时,通常使用第二种格式
	文件复制准则
		<src>必须是build上下文中的路径,不能是其父目录中的文件
		如果<src>是目录,则其内部文件或子目录会被递归复制,但<src>目录自身不会被复制
		如果指定了多个<src>,或在<src>中使用了通配符,则<dest>必须是一个目录,且必须以/结尾
		如果<dest>事先不存在,它将会被自动创建,这包括其父目录路径

	示例:把当前yum.repos.d目录下的文件复制到镜像中
		COPY yum.repos.d	  /etc/yum.repos.d/  
ADD:ADD指令类似于COPY指令,ADD支持使用TAR文件和URL路径
	Syntax
		ADD <src> ... <dest> 或
		ADD ["<src>",... "<dest>"] 
	操作准则
	同COPY指令
		如果<src>为URL且<dest>不以/结尾,则<src>指定的文件将被下载并直接被创建为<dest>;如果<dest>以/结尾,则文件名URL指定的文件将被直接下载并保存为<dest>/<filename>
		如果<src>是一个本地系统上的压缩格式的tar文件,它将被展开为一个目录,其行为类似于“tar -x”命令;然而,通过URL获取到的tar文件将不会自动展开;
		如果<src>有多个,或其间接或直接使用了通配符,则<dest>必须是一个以/结尾的目录路径;如果<dest>不以/结尾,则其被视作一个普通文件,<src>的内容将被直接写入到<dest>;

WORKDIR:
	用于为Dockerfile中所有的RUN、CMD、ENTRYPOINT、COPY和ADD指定设定工作目录
	Syntax
		WORKDIR <dirpath>
	在Dockerfile文件中,WORKDIR指令可出现多次,其路径也可以为相路径,不过其是相对此前一个WORKDIR指令指定的路径,另外WORKDIR也可调用由ENV指定定义的变量
	例如
		WORKDIR /var/log
		WORKDIR $STATEPATH

VOLUME:
用于在image中创建一个挂载点目录,以挂载Docker host上的卷或其它容器上的卷
只能指定image中的目录,但在宿主机或其他容器上的关联目录会通过docker驱动自动选择生成无法自定义
Syntax
	VOLUME <mountpoint> 或
	VOLUME ["<mountpoint>"] 
如果挂载点目录路径下此前有文件存在,docker run命令会在卷挂载完成后将此前的所有文件复制到新挂载的卷中

EXPOSE:
	用于为容器打开指定要监听的端口以实现与外部通信
	只能指定暴露的端口,容器动态绑定宿主机的随机端口和所有地址
	注意:EXPOSE只是指定待暴漏端口,制作镜像运行容器后并没有真正暴漏,需要启动容器时的选项-P配合,会自动暴漏镜像中指明的要暴漏的端口
	Syntax
		EXPOSE <port>[/<protocol>] [<port>[/<protocol>] ...]
			<protocol>用于指定传输层协议,可为tcp或udp二者之一,默认为TCP协议
			EXPOSE指令可一次指定多个端口,例如
			EXPOSE 11211/udp 11211/tcp
ENV:
	用于为镜像定义所需的环境变量,并可被Dockerfile文件中位于其后的其它指令(如ENV、ADD、COPY等)所调用
	调用格式为$variable_name或${variable_name}
	Syntax
		ENV <key> <value> 或
		ENV <key>=<value> ...
		第一种格式中,<key>之后的所有内容均会被视作其<value>的组成部分,因此,一次只能设置一个变量;
		第二种格式可用一次设置多个变量,每个变量为一个"<key>=<value>"的键值对,如果<value>中包含空格,可以以反斜线(\)或引号进行转义,也可通过对<value>加引号进行标识;另外,反斜线也可用于续行;定义多个变量时,建议使用第二种方式,以便在同一层中完成所有功能
	可以启动镜像容器时直接赋值,但只是在启动过程中赋予变量值,已经编译好的镜像无法改变,示例:
		docker container run --name web -e DIR="/usr/src/" cuijian/nginx:v0.1
		
CMD与RUN:		
	补充知识:
		(1)shell进程:只有运行在shell子进程下的程序才能使用shell相关命令【例如:通配符*  管道|】,这些进程都与终端相关联,终端退出shell就会退出,其中运行在shell子进程下的程序也会停止,所以可以使用nohup把父进程shell替换成init从而脱离终端限制
		(2)守护进程:与终端无关,由父进程ini管理并且都会存在于/etc/rc.d下可以由system启动的进程
		注意:json数组中,要使用双引号
		
 	RUN:
 		当基于Dockerfile制作镜像时执要运行的命令(注意必须在基础镜像中支持这个命令)有多个命令可以用&&符号,将在docker build时运行 ,注意:CMD是设置镜像的默认启动命令,启动时给run传递启动命令参数可以把CMD覆盖;
 		Syntax
			RUN <command> 或
			RUN ["<executable>", "<param1>", "<param2>"]
			第一种格式中,<command>通常是一个shell命令,且以“/bin/sh -c”来运行它,这意味着此进程在容器中的PID不为1,不能接收Unix信号,因此,当使用docker stop <container>命令停止容器时,此进程接收不到SIGTERM(启停)信号,(如果要设置容器PID为1可以在/bin/sh 下直接执行exec <command>)而这种格式启动的容器,为了能接收容器外的停启信号会在启动时自动在容器中执行exec命令,所以在容器外能查看到是/bin/sh启动的子进程,容器中只能看到启动的程序PID为1的进程是子进程本身,而不能看到/bin/bash这个父进程
			第二种语法格式中的参数是一个JSON格式的数组,其中<executable>为要运行的命令,后面的<paramN>为传递给命令的选项或参数;然而,此种格式指定的命令不会以“/bin/sh -c”来发起,因此常见的shell操作如变量替换以及通配符(?,*等)替换将不会进行;不过,如果要运行的命令依赖于此shell特性的话,可以将其替换为类似下面的格式。RUN ["/bin/bash", "-c", "<executable>", "<param1>"]
			
 	
 	 CMD
 	 	是用于定义把镜像启动为容器时指定默认要运行的程序或命令,可以启动时使用命令docker container run  后加启动命令来取代默认运行命令
		在Dockerfile中可以存在多个CMD指令,但仅最后一个会生效
		Syntax
			CMD <command> 或
			CMD ["<executable>", "<param1>", "<param2>"]或
			CMD ["<param1>","<param2>"]
			前两种语法格式的意义同RUN
			第三种则用于为ENTRYPOINT指令提供默认参数


ENTRYPOINT:
	类似CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一个单独的可执行程序与CMD不同的是,由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定指定的程序不过,docker run命令的--entrypoint选项的参数可覆盖ENTRYPOINT指令指定的程序
	Syntax
		ENTRYPOINT <command>
		ENTRYPOINT ["<executable>", "<param1>", "<param2>"]
		docker run命令传入的命令参数会覆盖CMD指令的内容并且附加到ENTRYPOINT命令最后做为其参数使用
		Dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅有最后一个会生效

	注意:如果CMD与ENTRYPOINT同时存在,那么CMD会被当做ENTRYPOINT的默认参数,如果这时在命令行传递参数会覆盖CMD
	示例1:
		CMD ["/bin/httpd","-f","-h" ${WEB_ROOT}]
		ENTRYPOINT ["/bin/sh","-c"]			
			实际启动容器的进程为:
			/bin/sh -c "/bin/httpd -f -h /date/root/"
	
	示例2:设置一个模板并可以在启动时传变量
		先准备一个可以生成配置文件的脚本
		vim entrypoint.sh
			#!/bin/bash
			cat > /etc/nginx/conf.d/www.conf << EOF
			server {
						server_name ${HOSTNAME};
						listen ${IP:-0.0.0.0}:${port:-80};
						root ${ROOT:-/usr/share/nginx/html};
				}
				EOF

			exec "$@"

		再准备一个静态页面
			echo "HELLOW" >index.html
		然后开始编写Dockerfile
		vim Dockerfile
			FROM  nginx:1.14-alpine
			LABEL maintainer='CJ <cj@163.com>'
			ENV ROOT='/data/web/html/'
			ADD index.html ${ROOT}
			ADD entrypoint.sh /bin/
			CMD ["/usr/sbin/nginx","-g","daemon off;"]
				(注释:-g为global:全局变量   daemon off 为放在前台)
			ENTRYPOINT  ["/bin/entrypoint.sh"]

		 最后编译成镜像然后启动时赋予变量参数
		 	docker image build  -t myweb:v0.1-1 ./
		 	docker run --name myweb --rm -P -e "PORT=8080" myweb:v0.1-1

USER
	用于指定运行image时的或运行Dockerfile中任何RUN、CMD或ENTRYPOINT指令指定的程序时的用户名或UID默认情况下,container的运行身份为root用户
	Syntax
		USER <UID>|<UserName>
		需要注意的是,<UID>可以为任意数字,但实践中其必须为/etc/passwd中某用户的有效UID,否则,docker run命令将运行失败

HEALTHCHECK  健康状态检测
	HEALTHCHECK可以定义一个CMD用来检查容器是否仍然正常运行。	
	HEALTHCHECK指令有两种形式:
		HEALTHCHECK [OPTIONS] CMD命令(通过在容器内运行一个命令来检查容器健康状况,可以定义时间间隔)
		HEALTHCHECK NONE(禁止健康状态检测)
		options:
			--interval=DURATION (default: 30s)
			--timeout=DURATION (default: 30s) 
			--start-period=DURATION (default: 0s) 容器启动后多长时间(容器初始化完成后)开始进行健康状态检测
			--retries=N (default: 3) 检测多少次失败后触发失败操作
		返回状态:
			0: success 
			1: unhealthy  不健康的
		For example
			HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ I| exit 1

SHELL 
	设置运行shell时的解释器,Linux系统默认为["/bin/sh", "-c"],Windows系统默认为["cmd", "/S", "/C"]
	SHELL在Dockefile中必须写成JSON格式
		Syntax: SHELL ["executable", "parameters"]
		可以多次,会覆盖之前的SHELL并影响后续指令

STOPSIGNAL
	修改容器的停止信号
	Syntax:STOPSIGNAL signal

ARG
	ARG定义了一个变量类似于ENV,区别在于可以通过构建镜像命令参数--build-arg <varname>=<value> flag在构建时传递变量
	示例:默认maintainer="MageEdu <mage@magedu. com>",传参后maintainer="CJ <CJ@163.com>"
	vim Dockefile
		ARG author="MageEdu <mage@magedu. com>"
		LABEL maintainer=$uthor
	 docker image build --build-arg author="CJ <CJ@163.com>"  -t nginx:v0.1-1 ./ 

ONBUILD
	用于在Dockerfile中定义一个触发器,当Dockerfile中定义了ONBUILD,自己在构建镜像时不会被执行,但是当我们编写一个新的Dockerfile文件来基于A镜像构建一个镜像(比如为B镜像)时,这时构造A镜像的Dockerfile文件中的ONBUILD指令就生效了,在构建B镜像的过程中,首先会执行ONBUILD指令指定的指令,然后才会执行其它指令。
	Syntax
		ONBUILD <INSTRUCTION>
	尽管任何指令都可注册成为触发器指令,但ONBUILD不能自我嵌套,且不会触发FROM和MAINTAINER指令
	使用包含ONBUILD指令的Dockerfile构建的镜像应该使用特殊的标签,例如ruby:2.0-onbuild
	在ONBUILD指令中使用ADD或COPY指令应该格外小心,因为新构建过程的上下文在缺少指定的源文件时会失败

Private Registry

Docker Distribution (比较简陋)
	yum  -y install docker-registry
	修改registry配置(也可以用默认配置)
		vim /etc/docker-distribution/registry/config.yml
	启动
		systemctl start docker-distribution
	客户端(docker配置文件)配置为可以使用不安全的registry,因为默认只能使用https协议,配置为可以使用不安全的registry后可以支持http协议
		vim /etc/docker/daemon.json
			{
				"insecure-registries":  ["10.0.0.2:5000"]
			}
		修改完需重启服务
			systemctl restart docker
					
	打标签
		docker image tag nginx:v0.3-11 10.0.0.2:5000/nginx:v0.3-11
	推送:
		docker image push nginx:v0.3-11 10.0.0.2:5000/nginx

vmware harbor
Harbor官方网站:http://vmware.github.io/harbor/
Harbor源码地址:https://github.com/vmware/harbor


	Harbor简介
		Harbor是一个用于存储和分发Docker镜像的企业级Registry服务器,通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源Docker Distribution。作为一个企业级私有Registry服务器,Harbor提供了更好的性能和安全。提升用户使用Registry构建和运行环境传输镜像的效率。Harbor支持安装在多个Registry节点的镜像资源复制,镜像全部保存在私有Registry中, 确保数据和知识产权在公司内部网络中管控。另外,Harbor也提供了高级的安全特性,诸如用户管理,访问控制和活动审计等。
	Harbor的功能
		基于角色的访问控制:用户与Docker镜像仓库通过“项目”进行组织管理,一个用户可以对多个镜像仓库在同一命名空间(project)里有不同的权限。
		镜像复制:镜像可以在多个Registry实例中复制(同步)。尤其适合于负载均衡,高可用,混合云和多云的场景。
		图形化用户界面:用户可以通过浏览器来浏览,检索当前Docker镜像仓库,管理项目和命名空间。
		AD/LDAP:-Harbor可以集成企业内部已有的AD/LDAP,用于鉴权认证管理。
		审计管理:所有针对镜像仓库的操作都可以被记录追溯,用于审计管理。
		国际化:已拥有英文、中文、德文、日文和俄文的本地化版本。更多的语言将会添加进来。
		RESTful API: 提供给管理员对于Harbor更多的操控, 使得与其它管理软件集成变得更容易。
		部署简单:提供在线和离线两种安装工具, 也可以安装到vSphere平台(OVA方式)虚拟设备。	
	vmware harbor 需要基于docker单机编排工具 docker compose	

	安装:
		下载并解压包
			wget https://github.com/goharbor/harbor/releases/download/v2.5.2/harbor-offline-installer-v2.5.2.tgz
			tar -xvf harbor-offline-installer-v2.5.2.tgz
			cd harbor
		编辑配置文件
			vim harbor.cfg
		安装并启动
			yum -y install docker-compose
			./install.sh
		访问页面
			初始密码 admin/Harbor12345
		同Distribution
			docker 配置非安全端口并重启
			镜像打tag
			登录: docker login
			推送
		停止/启动  
			docker-compose --help 查看	
				需要在docker-compose.yml 所在目录中执行

Docker 资源限制

docker容器默认没有资源限制,可以使用宿主机上所有资源
	memory:
		调整了docker daemon 的OOM优先级但未调整容器的,这就导致主机内存耗尽时可能会kill占用内存较多的容器,可以在容器启动时限制容器资源:
		docker container run
			Options:
				内存限制:
					-m, --memory bytes                   Memory limit
					--memory-swap bytes  要限制swap使用大小前提必须先限制内存使用大小
					--memory与--memory-swap 结合起来用有四种情况:
						--memory-swap为正数S;--memory为正数M;则容器可用总空间为S,其中ram(可用物理内存)为M,swap为S-M,若S=M则无可用swap
						--memory-swap为0;--memory为正数M;相当于未设置swap(unset)
						--memory-swap为unset;--memory为正数M;若主机(Docker Host)启用了swap,则容器可用swap为2*M
						--memory-swap为-1(无限大);--memory为正数M;若主机(Docker Host)启用了swap,则容器可使用主机上的所有swap资源
						注意:容器内使用free命令显示的swap没有意义
					--oom-kill-disable True 在主机内存耗尽时禁止kill此容器,提前需要有-m选项
					--oom-score-adj int              Tune host's OOM preferences (-1000 to 1000)
						(补充:Docker host系统内存资源不足时。OOM killer 给进程打分,把 oom_score 最大的进程先杀死,打分主要有两部分组成:
								一是系统根据该进程的内存占用情况打分,进程的内存开销是变化的,所以该值也会动态变化。
								二是用户可以设置的 oom_score_adj,范围是 -1000到 1000,所以数值越小越不容易被杀死,默认为0设定成 -1000,表示禁止OOM killer 杀死该进程
						)

				cpu限制
				(补充:
					优先级NICE:
						进程的优先级为100-139,默认NICE为0也就是优先级为120,可以把NICE在-20,19直接进行调整
						内核优先级为0,99  
						)
					-c, --cpu-shares int                 CPU shares (relative weight)  设置CPU弹性共享比例,例如一个容器配置为512,另一个为1024,他们所分配的cpu资源为1比2,当然是弹性的:例如如果一个容器在空闲中,另一个容器就可以使用所有资源
					--cpus=<value>  数值可以是正数也可以是小数
					--cpuset-cpus string             CPUs in which to allow execution (0-3, 0,1)  限制容器用在哪个cpu核心上
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值