Docker基础篇(很详细)

一、简单介绍

(一)为什么用docker

开发人员发开完成就发布一个jar或者war包,其他的都交给运维人员来做;而现在,开发即运维,打包部署上线一套流程走完:开发人员会将项目及其附带的环境一起打包jar+(Redis
Jdk ES MySQL)成一整套发布,称为镜像,这样就不再需要再配置环境,直接执行一整套即可,省去环境配置的麻烦且保证了一致性;

Docker的出现就是为了解决以上问题,

  • 更轻量:基于容器的虚拟化。仅包含业务运行所需的runtime环境,Centos、Ubuntu基础镜像仅170M;宿主机可部署100~1000个容器
  • 更高效:无操作系统虚拟化开销
    • 计算:清亮,无额外开销
    • 存储:系统盘aufs/dm/overlayfs;数据盘volume
    • 网络:宿主机网络,NS隔离
  • 更敏捷、更灵活:
    • 分层的存储和包管理,devops理念
    • 支持多种网络配置

二、看待容器的不同角度

1、从面向对象角度
Docker利用容器(Container)独立运行的一个或一组应用,应用程序或服务运行在容器里面,容器就类似于一个虚拟化的运行环境,容器是用镜像创建的运行实例。就是是java中的类和实例对象一样,镜像是静态的定义,容器是镜像运行时的实体。容器为镜像提供了一个标准的和隔离的运行环境,他可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台
2、从镜像容器角度
可以把容器看做是一个简易版的Linux环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

(一)与虚拟化技术对比

Docker 和 虚拟机技术 的不同:
(1)docker有着比逊尼基更少的抽象层
(2)docker、利用的是宿主机的内核,而不需要加载操作系统OS内核

  • 传统虚拟机技术,虚拟出一套硬件,运行一个完整的操作系统,在这个系统上安装和运行软件

  • 容器内的应用直接运行在宿主机的内核上,容器没有自己的内核,也没有虚拟硬件,轻便快速,

  • 每个容器互相隔离,每个容器都有一个自己的文件系统,互不影响

     虚拟机缺点:
     	1、资源占用十分大
     	2、冗余步骤多
     	3、启动慢
     	
     docker优点:
     	1、更高效的利用系统资源
     	2、更快速的启动时间
     	3、一致的运行环境
     	4、持续交付和部署
     	5、更轻松的迁移
     	6、更轻松的维护和扩展
    

三、docker的三大核心

(一)镜像(image)

  1. 镜像就是一个只读的模板,可以通过这个模板创建容器服务,一个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中)

(二)容器(container)

  1. Docker利用容器技术,独立运行的一个或一组应用。容器是用镜像创建的运行实例。

  2. 它可以被启用,开始,停止,删除。每个容器都是相互隔离的,保证安全的平台。

  3. 可以把容器看作是一个简易版的Linux系统(包括root用户权限,进程空间,用户空间和网络空间等)和运行在其中的应用程序。

  4. 容器的定义和镜像几乎一摸一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的

(三)仓库(repository)

  1. 仓库是集中存放镜像文件的场所。

  2. 仓库和仓库注册服务器(Registry)是有区别的,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签

  3. 仓库分为公开仓库(public)和私有仓库(private)两种形式

  4. 最大的开放仓库是国外的 Docker Hub,存放了数量庞大的镜像供用户下载。

  5. 国内的公开仓库包括阿里云,网易云都有容器服务器(需要配置镜像加速)等

四、安装

官网安装教程十分详细,可参照此教程:https://docs.docker.com/engine/install/centos/

要安装Docker Engine,您需要CentOS 7或8的维护版本。不支持或未测试存档版本。
docker必须部署在Linux内核的系统上。如果其他系统想部署docker就必须安装一个虚拟Linux环境

uname -r					#查看系统内核
cat /etc/os-release			#查看Linux服务器系统版本
cat /etc/redhad-replease	#查看centos版本

1、卸载旧版本

sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine

2、安装gcc相关

yum -y install gcc
yum -y install gcc-c++

3、安装Docker需要软件包

sudo yum install -y yum-utils

4、设置stable镜像仓库

用国外的会报连接超时等错误,推荐用国内镜像

# 默认是国外的
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
    
# 换成阿里云镜像地址
sudo yum-config-manager \
    --add-repo \
    http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

5、更新yum软件包索引

提高安装软件的速度

sudo yum makecache fast

6、安装docker ce

sudo yum install docker-ce docker-ce-cli containerd.io

7、启动docker

systemctl start docker

8、测试

docker daemon要执行一个镜像,如果本地有,直接转换成容器实例运行;如果本地没有这个镜像,则从远程库(docker hub)去拉取到本地,再形成容器实例;如果远程库(docker hub)也找不到,则返回失败错误,查不到该镜像

ps -ef |grep docker 	#查看是否启动
docker version			#查看docker版本
docker run hello-world	#会报找不到镜像的错误,但是代表正常

9、卸载

systemctl stop docker
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
rm -rf /var/lib/containerd

五、阿里云镜像加速

防止发布、交互以及编排时超时

地址:https://promotion.aliyun.com/ntms/act/kubernetes.html
注册一个属于自己的阿里云账户(可复用淘宝账号)
获得加速器地址连接
粘贴脚本直接执行
重启服务器

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

六、docker常用命令

(一)帮助启动类命令

systemctl start docker			#启动docker
systemctl stop docker			#停止docker
systemctl restatrt docker		#重启docker
systemctl status docker			#查看docker状态
systemctl enable docker			#开启启动
docker info						#查看docker概要信息
docker --help					#查看docker总体帮助文档
docker 具体命令 --help			#查看docker命令帮助文档

(二)镜像命令

docker images
	列出本地主机上的镜像
		REPOSITORY:表示镜像的仓库源
		TAG:镜像的标签版本号
		IMAGE ID:镜像ID
		CREATED:创建镜像的时间
		SIZE:镜像大小
			#同一仓库源可以有多个TAG版本,代表这个仓库源的不同个版本,我们使用REPOSITORY:TAG来定义不同的镜像。
			#如果你不指定一个镜像的版本标签,例如你只使用Ubuntu,docker将默认使用ubuntu:latest镜像
	OPTIONS说明:
		-a:列出本地所以的镜像(包含历史映像层)
		-q:只显示镜像ID

docker search 某个xxx镜像名字
	网站:
		http://hub.docker.com
	命令:
		docker search [OPTIONS]镜像名字
		案例
			NAME:镜像名称
			DESCRIPTION:镜像说明
			STARS:点赞数量
			OFFICIAL:是否是官方的
			AUTOMATED:是否是自动构建的
		OPTIONS说明:
			--limit:只列出N个镜像,默认25个
			docker search --limit 5 redis(要查询的镜像名称)
	
docker pull 某个xxx镜像名字
	下载镜像
	docker pull 镜像名字[:TAG]
	docker pull 镜像名字
		没有TAG就是最新版
		等价于(docker pull 镜像名字:latest)latest是默认标签,可以不写
		docker pull ubuntu
		docker pull redis:6.0.8(冒号后面跟什么版本就拉取相对应的版本)

docker system df 查看镜像/容器/数据卷所占的空间
	类型		总计		活跃数		大小		可伸缩性
	TYPE		TOTAL		ACTIVE		SIZE		RECLAIMABLE
	Images
	Containers
	Local Volumes
	Build Cache
		Images:镜像
		Containers:容器
		Local Volumes:本地卷
		Build Cache:构建的缓存
docker rmi 某个xxx镜像名字/ID	#-f代表强制删除
	删除镜像
	删除单个
		docker rmi -f 镜像ID
	删除多个
		docker rmi -f 镜像名1:TAG 镜像名2:TAG
	删除全部
		docker rmi -f $(docker images -qa)
docker虚悬镜像是什么?
	是什么:
		仓库名、标签都是<none>的镜像,俗称虚悬镜像dangling image
	长什么样:
		docker images	#查看
		REPOSITORY		TAG		IMAGE ID 	CREATED		SIZE	
		<none>			<none>
		#有ID,有大小并且仓库名、标签都是<none>,建议删除

镜像传输
	docker save -o abc.tar xxx:v1.0		# 将镜像保存成压缩包
	docker load -i abc.tar				# 别的机器加载这个镜像

(三)容器命令

有镜像才能创建容器,这是根本前提(下载一个centos或者Ubuntu镜像演示)
	说明:左侧是拉取的centos,右侧是拉取的ubuntu(从上往下看,别从左到右看)
		centos7.5						ubuntu5
		Docker							Docker
		Centos7							Centos7
		VMware							VMWare
		Win10操作系统					win10操作系统
		笔记本电脑硬件					笔记本电脑硬件
	docker pull centos
	docker pull ubuntu
	本次演示用ubuntu
新建+启动容器
	docker run [OPIONS] IMAGE [COMMAND] [ARG...]
		OPTIONS说明
			OPIONS说明(常用):有些事一个减号,有些事两个减号
			--name="容器新名字"		为容器指定一个名称(可以不加等号或者引号);
			-d:后台运行容器并返回容器ID,也即启动守护式容器(后台运行)。
			
			-i:以交互模式运行容器,通常与-t同时使用;
			-t:为容器重新分配一个伪输入终端,通常与-i同时使用;
			也即启动交互式容器(前台有伪终端,等待交互)。
			
			-P:随机端口映射,大写P
			-p:指定端口映射,小写p
			参数								说明
			-P hostPort:ContainerPort			端口映射 -p 8080:80
			-p ip:hostPort:ContainerPort		配置监听地址 -p 10.0.0.100:8080:80
			-p ip::containerPort				随机分配端口 -p 10.0.0.100::80
			-p hostPort:containerPort:udp		指定协议 -p 8080:80:tcp
			-p 81:80 -p 443:443					指定多个
		启动交互式容器(前台命令行)
			docker run -it ubuntu /bin/bash或者bash或者/sh(默认会自动加命令行)
			#使用镜像ubuntu:latest以交互模式启动一个容器,在容器内执行/bin/bash命令
			-i:交互式操作;	
			-t:终端;
			ubuntu:ubuntu镜像;
			/bin/bash:放在镜像名后的是命令,这里我们希望有个交互式shell,因此用的是/bin/bash;
			要退出终端,直接输入exit。
列出当前所有正在运行的容器
	docker ps [OPTIONS]
		OPTIONS说明
			-a:列出当前所有正在运行的容器+历史上运行过的
			-l:显示最近创建的容器
			-n:显示最近n个创建的容器(后面跟几就查几条)
			-q:静默模式,只显示容器ID
			容器ID			镜像	命令		创建时间	状态		对外是否暴露端口		容器名称
			CONTAINER ID	IMAGE	COMMAND		CREATED		STATUS		PORTS				NAMES
退出容器(两种方式)
	exit
		run进去容器,exit退出,容器停止
	ctrl+p+q
		run进去容器,ctrl+p+q退出,容器不停止
启动已停止运行的容器
	docker start 容器ID或者容器名
重启容器
	docker restart 容器ID或者容器名
停止容器
	docker stop 容器ID或者容器名(可以跟多个)
强制停止容器
	docker kill	容器ID或者容器名(谨慎使用)
删除已停止的容器
	docker rm 容器ID或者容器名(-f强制删除,不管启动还是停止)
		一次性删除多个容器实例(谨慎使用)
			docker rm -f $(docker ps -a -q)
			docker ps -a -q | xargs docker rm
重点
	有镜像才能创建容器,这是根本前提(下载一个Redis6.0.8镜像演示)
	启动守护式容器(后台服务器)	#与上面的做对比
		在大部分的场景下,我们希望docker的服务是在后台运行的,我们可以通过-d指定容器的后台运行模式
		docker run -d 容器名
			例如:使用镜像centos:latest以后台模式启动一个容器
			docker run -d centos
			
			问题:然后docker -ps -a进行查看,会发现容器已经退出
			很重要的说明一点:Docker容器后台运行,就必须有一个前台继承
			容器运行的命令如果不是那些一直挂起的命令(比如top,tail),就是会自动退出的。

			这个是docker的机制问题,比如你的web容器,我们以nginx为例,正常情况下,
			我们配置启动服务只需要启动响应的service即可。例如service nginx start
			但是,这样做,nginx为后台进程模式运行,就导致docker前台没有运行的应用,
			这样的容器后台启动后,会立即自杀因为他觉得他没事可做了
			所以,最佳的解决方案是,将你要运行的程序以前台进程的形式运行,
			常见的就是命令行模式,表示我还有交互操作,别中断
		redis前后台启动演示case(像redis,mysql后需要守护式启动,因为你交互式启动万一不小心关了就完蛋了)
			前台交互式启动
				docker run -it redis:6.0.8
			后台守护式启动
				docker run -d redis:6.0.8
	查看容器日志
		docker logs 容器ID
	查看容器内运行的进程
		docker top 容器ID
	查看容器内部细节
		docker inspect 容器ID
	进入正在运行的容器并以命令行交互	#与上面的做对比
		docker exec -it 容器ID bashShell
			docker exec --help
			-d:运行时在后台运行
			-i:交互
			-t:命令伪终端
		重新进入docker attach 容器ID
		案例演示,用cantos或者ubuntu都可以
		上述两个区别
			attach直接进入容器启动命令的终端,不会启动新的进程
			用exit退出,会导致容器的停止。
			
			exec是在容器中打开新的终端,并且可以启动新的进程
			用exec退出,不会导致容器的停止。
		推荐大家使用docker exec命令,因为退出容器终端,不会导致容器的停止。
		用之前的redis容器实例进入试试
			进入redis服务
				docker exec -it 容器ID /bin/bash
					redis-cli -p 6379
					set k1 v1
					get k1
				一般用-d后台启动的程序,再用exec进入对应容器实例
	从容器呢拷贝文件到主机上
		容器->主机
		docker cp 容器ID:容器内路径 目的主机路径
			例如:进入/tmp目录创建a.txt文件
			docker exec -it 容器ID /bin/bash	#以交互式启动
			cd /tmp
			touch a.txt
			exit退出
			docker cp 容器ID:/tmp/a.txt /指定的路径
	导入和导出容器(用作数据的迁移和备份)
		export导出容器的内容留作为一个tar归档文件[对应import命令]
		import从tar包中的内容创建一个新的文件系统再导入为镜像[对应export]
		案例:
			docker export 容器ID > 文件名.tar
			cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号
总结
	attach 	Attach to a running container	#当前shell下attach连接指定运行镜像
	build	Build an image from a Dockerfile	#通过Dockerfile定制镜像
	commit	Create a new image from a container changes	#提交当前容器为新的镜像
	cp		Copy files/folders from the containers filesystem to the host path	#从容器中拷贝指定文件或者目录到宿主机中
	create	Create a new container	#创建一个新的容器,同run,但不启动容器
	diff	Inspect changes on a container's filesystem	#查看docker容器变化
	events 	Get real time events from the server	#从docker服务获取容器实时事件
	exec	Run a command in an existing container	#在已存在的容器上运行命令
	export	Stream the contents of a container as a tar archive	#导出容器的内容留作为一个tar归档文件[对应import]
	history	Show the history of an image	#展示一个镜像形成历史
	images 	List images	#列出系统当前镜像
	import 	Create a new filesystem image from the contents of a tarball	#从tar包中的内容创建一个新的文件系统映射[对应export]
	info	Display system-wide information	#显示系统相关信息
	inspect	Return low-level information on a container	#查看容器详细信息
	kill	Kill a running container	#kill指定docker容器
	load	Load an image from a tar archive	#从一个tar包中加载一个镜像[对应save]
	login	Register or Login to the docker registry server	#注册或登陆一个docker源服务器
	logout	Log out from a Docker registrt server	#从当前Docker registry退出
	logs	Fetch the logs of a container	#输出当前容器日志信息
	port	Lookup the public-facing port which is NAT-ed to PRIVATE_PORT	#查看映射端口对应的容器内部源端口
	pause	Pause all processes within a container	#暂停容器
	ps		List containers	#列出容器列表
	pull	Pull an image or a repositry from the docker registry server	#从docker镜像源服务器拉取指定镜像或者库镜像
	push 	Push an image or a repositry to the docker registry server	#推送指定镜像或者库镜像至docker源服务器
	restart Restatrt a running container	#重启运行的容器
	rm		Remove one or more containers	#移除一个或多个容器
	rmi		Remove one or more images	#移除一个或多个镜像[五容器使用该镜像才可删除,否则需删除相关容器才可继续或-f强制删除]
	run		Run a command in a new container	#创建一个新的容器并运行一个命令
	save	Save an image to a tar archive	#保存一个经纬为一个tar包[对应load]
	search 	Search for an image on the Docker Hub	#在docker hub中搜索镜像
	start	Start a stopped containers	#启动容器
	stop	Stop a running containers	#停止容器
	tag		Tag an image into a repository	#给源中镜像打标签
	top		Lookuo the running processes of a container	#查看容器中运行的进程信息
	unpause Unpause a paused container	#取消暂停容器
	version	Show the docker version information	#查看docker版本号
	wait	Block ubtil a container stops,then print its exit code	#截取容器停止时的退出状态值

七、Docker镜像

(一)是什么

镜像

> 1.是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。
> 2.只有通过这个镜像文件才能生成Docker容器实例(类似Java中new出来一个对象)
分层的镜像
> 以我们的pull为例,在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载

在这里插入图片描述

UnionFS(联合文件系统)
> UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite serveral directories into a single virtual filesystem)。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起啦,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
Docker镜像加载原理
> 1.docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。 bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是引导文件系统bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已有bootfs转交给内核,此时系统也会卸载bootfs。
> 2.rootfs(root file system),在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
> 3.对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供rootfs就行了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs
为什么Docker镜像要采用这种分层结构呢
> 1.镜像分层最大的一个好处就是共享资源,方便复制迁移,就是为了复用。

比如果也有多个镜像都从相同的base镜像构建而来,那么Docker Host只需要在磁盘上保存一份base镜像;
同时内存中也只需加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

(二)重点理解

Docker镜像层都是可读的,容器层是可写的 
当容器启动时,一个新的可写层被加载到镜像的顶部。 
这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。

#当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
#所有对容器的改动-无论添加、删除、还是修改文件都只会发生在容器层中。只有容器层是可写的,容器层下面的所有镜像层都是只读的。

(三)Docker镜像commit操作案例

docker commit 提交容器副本使之成为一个新的镜像
docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
案例演示ubuntu安装vim
	从Hub上下载ubuntu镜像到本地并成功运行
	原始的默认Ubuntu镜像是不带着vim命令的
	外网连通的情况下,安装vim(docker容器内执行以下命令)
		apt-get update				#更新我们的包管理工具
		apt-get -y install vim		#安装我们需要的vim
	安装完成后,commit我们自己的新镜像(记得在容器外执行)
		docker commit -m="add vim cmd ok" -a="xxx" 镜像ID 包名/镜像名:版本号
	启动新镜像并和原来的对比
总结
	Docker中的镜像分层,支持通过扩展现有镜像,创建新的镜像。类似Java继承于一个Base基础类,自己再按需扩展。
	新镜像是从base镜像一层一层叠加生成的。每安装一个软件,就在现有镜像的基础上增加一层

八、本地镜像发布到阿里云

(一)本地镜像发布到阿里云流程

阿里云ECS Docker生态如下图所示:
在这里插入图片描述

(二)镜像的生成方法

基于当前容器创建一个新的镜像,新功能增强
docker commit [OPTIONS] 容器ID [REPOSITORY[:TAG]]
例如:
	docker commit -a xxx -m "new mycentos 1.4 from 1.3" 镜像ID mycentos:1.4
	OPTIONS说明:
		-a:提交的镜像作者
		-m:提交时的说明文字

(三)将本地镜像推送到阿里云(有钱就买企业版,没钱就用免费的个人版)

本地镜像素材原型
阿里云开发者平台
	https://promotion.aliyun.com/ntms/act/kubernetes.html(或者直接写aliyun.com)
创建仓库镜像
	选择控制台,进入容器镜像服务
	选择个人实例
	命名空间(创建命名空间,根据自己需求命名)
	仓库名称
		选择已有的命名空间,创建仓库名称,摘要写上添加了什么功能
		选择本地仓库,创建镜像仓库
	进入管理界面获得脚本
		阿里云会自动生成一些脚本(根据自己所需去粘贴复制即可)
将镜像推送到阿里云
	将镜像推送到阿里云registry
		管理界面脚本(根据自己所需去粘贴复制即可)
		脚本实例(直接复制阿里云的命令即可,手敲容易出错)
			docker login --username=*** registry.cn- beijing.aliyuncs.com	#用户名别写错了
			Password:	#输入自己的密码
			Login Succeeded	#证明成功登陆阿里云
			docker tag 镜像ID registry.cn- beijing.aliyuncs.com/包名/镜像名:镜像版本号
			docker push registry.cn- beijing.aliyuncs.com/包名/镜像名:镜像版本号

(四)将阿里云上的镜像下载到本地

#可以将本地的先删除在测试
登陆
docker login --username=*** registry.cn- beijing.aliyuncs.com	#用户名别写错了
拉取
docker pull registry.cn- beijing.aliyuncs.com/包名/镜像名:镜像版本号

九、本地镜像发布到私有库

(一)本地镜像发布到私有库流程

阿里云ECS Docker生态如下图所示:
在这里插入图片描述

(二)是什么

Docker Registry

1.官方Docker Hub地址:https://hub.docker.com/,中国大陆访问太慢了且准备被阿里云取代的趋势,不太主流。
2.Dockerhub、阿里云这样的公共镜像仓库可能不太方便,涉及机密的公司不可能提供镜像给公网,所以需要创建一个本地私人仓库供给团队使用,基于公司内部项目构建镜像。

Docker Registry是官方提供的工具,可以用于构建私有镜像仓库

(三)将本地镜像推送到私有库

1.下载镜像Docker Registry
	docker pull registry
2.运行私有库Registry,相当于本地有个私有Docker hub
	docker run -d -p 5000:5000 -v /xxx/myregistry/:/tmp/registry --privileged=true registry
		-v /xxx/myregistry/:/tmp/registry	#冒号左边是宿主机的路径,冒号右边是容器内的路径
		--privileged=true					#开放权限
	默认情况,仓库被创建在容器的/var/lib/registry目录下,建议自行用容器卷映射,方便与宿主机联调
3.案例演示创建一个新镜像,Ubuntu安装ifconfig命令
	从Hub上下载ubuntu镜像到本地并成功运行
	原始的ubuntu镜像是不带着ifconfig命令的
	外网连通的情况下,安装ifconfig命令并测试通过
		apt-get update
		apt-get install net-tools
	安装完成后,commit我们自己的新镜像(记得在容器外执行)
		docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
	启动新镜像并和原来的对比
4.curl验证私服库上有什么镜像
	curl -XGET http://本机IP:5000/v2/_catalog	#模拟发一个get请求
	{"repositories".[]}	#结果是空的
5.将新镜像(镜像名:版本号)修改符合私服规范的Tag
	按照公式:docker tag 镜像:Tag Host:Port/Repository:Tag	#自己host主机IP地址,不要写错
6.修改配置文件使之支持http
	cat /etc/docker/daemon.json	#cat是查看,配置的话用vim
	{
		"registry-mirrors":["自己的阿里云加速地址"],
		"insecure-registries":["自己本机IP:私服端口"]
	}
	#不配置阿里提供的镜像加速地址的话访问官网会很慢
	上述理由:docker默认不允许http方式推送镜像,通过配置选项来取消这个限制--->修改完后如果不生效,建议重启docker
	修改完之保守起见:建议重启并查看状态
	systemctl restart docker
	systemctl status docker
	重新启动私服库
7.push推送到私服库
	docker push 自己的IP:私服端口/镜像名称:版本号
8.curl验证私服库上有什么镜像2
	curl -XGET http://本机IP:5000/v2/_catalog
	{"repositories".["自己推送的镜像名称"]}
9.pull到本地并运行
	docker pull 主机IP:私服端口/镜像名称:版本号
	docker run -it 镜像ID:版本号 /bin/bash
	输入ifconfig命令验证

十、Docker容器数据卷

(一)坑:容器卷记得加入

--privileged=true	#开启权限
Docker挂载主机目录访问如果出现cannot open directory.:Permission denied
解决办法:在挂载目录后多加一个--privileged=true参数即可

如果是CentOS7安全模块会比之前系统版本加强,不安全的会先禁止,所以目录挂载的情况被默认认为是不安全的行为
在SELinux里面挂载目录被禁止掉了,如果要开启,我们一般使用--privileged=true命令,扩大容器的权限解决挂载目录没有权限的问题,也即使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限。

(二)回顾上面的内容,参数V

docker run -d -p 5000:5000 -v /xxx/myregistry/:/tmp/registry --privileged=true registry
	-v /xxx/myregistry/:/tmp/registry	#冒号左边是宿主机的路径,冒号右边是容器内的路径
	--privileged=true					#开放权限
默认情况,仓库被创建在容器的/var/lib/registry目录下,建议自行用容器卷映射,方便与宿主机联调

(三)是什么

卷就是目录或文件,存在于一个或多个容器中,将docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会再容器删除时删除其挂载的数据卷

有点类似我们Redis里面的rdb和aof文件
将docker容器内的数据保存进宿主机的磁盘中
运行一个带有容器卷存储功能的容器实例
	docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 --name=自定义名字 镜像名 	#公式(目录不存在会自动创建)

(四)能干嘛

* 将运用于运行的环境打包镜像,run后形成容器实例运行,但是我们对数据的要求希望是持久化的

Docker容器产生的数据,如果不备份,那么当容器实例删除后,容器内的数据自己也就没有了。
为了能保存数据在docker中我们使用卷。

特点:
	1:数据卷可在容器之间共享或重用数据
	2:卷中更改可以直接实时生效
	3:数据卷中的更改不会包含在镜像的更新中
	4:数据卷的生命周期一直持续到没有容器使用它为止

(五)数据卷案例

1.宿主机vs容器之间映射添加容器卷
	命令:docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 --name=自定义名字 镜像名 
	查看数据卷是否挂载成功
		docker inspect 容器ID
		找到Mounts "TYPE":"类型为绑定"	"Source":"源地址" "Destination":"目的地址"	#参考跟自己定义的是否一致
	容器和宿主机之间数据共享
		1 docker修改,主机同步获得
		2 主机修改,docker同步获得
		3 docker容器stop,主机修改,docker容器重启数据依旧是同步
		#双方无论创建什么数据都是实时共享的,可以开两个终端,自己测试一下
2.读写规则映射添加说明
	读写(默认)
		docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:rw --name=自定义名字 镜像名
		默认都是有rw权限的
	只读
		容器实例内部被限制,只能读取不能写
		docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:ro --name=自定义名字 镜像名
			ro=read only	#此时如果宿主机写入内容,可以同步给容器给,容器可以读取到
3.卷的继承和共享
	容器1完成和宿主机的映射
		docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 --name=自定义名字 镜像名
	容器2继承容器1的卷规则
		docker run -it --privileged=true --volumes-from 父类 --name=自定义名字 镜像名
		#就算父类停止,照样可以实现与宿主机数据共享
		#父类启动,还可以恢复容器2与宿主机的数据

十一、Docker常规安装简介

(一)总体步骤

搜索镜像
拉取镜像
查看镜像
启动镜像--->服务端口映射
停止容器
移除容器

(二)安装tomcat

docker hub上面查找tomcat镜像
	docker search tomcat
从docker hub上拉取tomcat镜像到本地
	docker pull tomcat
docker images查看是否有拉取到的tomcat
	docker images tomcat
使用tomcat镜像创建容器实例(也叫运行镜像)
	docker run -it -p 8080:8080 --name=t1 tomcat
		-p:小写,主机端口:docker容器端口
		-P:大写,随机分配端口
			例如:docker run -it -P tomcat	
				#docker ps 查看随机分配端口映射;外部端口随机:容器端口:8080
				#外部访问就通过随机端口访问docker内部8080端口的tomcat
		-i:交互
		-t:终端
		-d:后台
	docker ps	#查看是否启动
访问猫首页(localhost:8080)
	问题	#最后访问报404请情况:HTTP状态404 - 未找到
	解决
		可能没有映射端口或者没有关闭防火墙
		把webapps.dist目录换成webapps
			docker exec -it 镜像ID /bin/bash	#进入tomcat
			ls -l #查看文件
			cd webapps	#切换文件夹
			ls -l #会发现是空的
			rm -r webapps	#将这个空的删掉
			mv webapps.dist webapps	#将文件重命名
	再访问就出现猫了	
免修改版说明
	docker pull billygoo/tomcat8-jdk8
	docker run -d -p 8080:8080 --name mytomcat8 billygoo/tomcat8-jdk8

(三)安装mysql

docker hub上面找mysql镜像
	docker search mysql
从docker hub上(阿里云加速器)拉取mysql镜像到本地标签为5.7
	docker pull mysql:5.7
	docker images mysql:5.7
使用mysql5.7镜像创建容器(也叫运行镜像)
	简单版
		使用mysql镜像
			docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
				#-e MYSQL_ROOT_PASSWORD=123456      设置 MySQL 服务 root 用户的密码
			docker ps
			docker exit -it 容器ID /bin/bash
			mysql -uroot -p
		建库建表插入数据
			show databases;
			create database db01;
			use db01;
			create table t1(id int,name varchar(20));
			insert into t1 values(1,'xxx');
			select * from t1;
		外部win10也来连接运行在docker上的mysql容器实例服务
			ifconfig	#查询虚拟机IP
			用navicat或者别的工具连接docker上的mysql
			在客户端连接创建数据与docker上的数据是互通的
		问题
			插入中文数据为什么会报错?
				docker上默认的字符集编码隐患
					进入docker容器里面的mysql:SHOW VARIABLES LIKE'character%';	#查询结果都是拉丁
			删除容器后,里面的mysql数据怎么办?
				没办法,丢了☹☹☹
	实战版
		新建mysql容器实例
			docker run -d -p 3306:3306 --privileged=true -v /xxx/mysql/log:/var/log/mysql -v /xxx/mysql/data:/var/lib/mysql -v /xxx/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7	#添加数据卷,防止数据丢失
		新建my.cnf
			通过容器卷同步给mysql容器实例
				cd /xxx/mysql/conf/
				vim my.cnf(添加一下字符编码)
					[client]
					default_character_set=utf8
					[mysqld]
					collation_server=utf8_general_ci
					character_set_server=utf8
				cat my.cnf(别忘了查看)
		重新启动mysql容器实例再重新进入并查看字符编码
			docker restart mysql
			docker exec -it mysql /bin/bash
			mysql -uroot -p		#回车后输入密码
			SHOW VARIABLES LIKE 'character%';
		再新建库新建表再插入中文测试
			show databases;
			create database db01;
			use db01;
			create table t1(id int,name varchar(20));
			insert into t1 values(1,'张三');
			select * from t1;
		结论(以容器内部的字符集编码为准)
			之前插入的中文的数据无效
			修改字符集操作+重启mysql容器实例
			之后新建的库,插入的中文数据有效
			docker安装完MySQL并run出容器后,建议先修改完字符集编码后再新建mysql库-表-查数据
		假如将当前容器实例删除,再重新来一次,之前的数据还有吗?
			可以试一试,重新启动,重新进入数据库查看,发现数据还在(不过别轻易删库)

(四)安装redis

从docker hub上(阿里云加速器)拉取redis镜像到本地标签为6.0.8
	docker pull redis:6.0.8
	docker images
入门命令
	docker run -d -p 6379:6379 redis:6.0.8
	docker exec -it 容器ID /bin/bash
	redis-cli
	set k1 v1
	get k1
	ping
命令提醒:容器卷记得加入--privileged=true
	Docker挂载主机目录访问如果出现cannot open directory.:Permission denied
	解决办法:在挂载目录后多加一个--privileged=true参数即可
在CentOS宿主机下新建目录/app/redis
	mkdir -p /app/redis
将一个redis.conf文件模板拷贝进/app/redis目录下
	cp /myredis/redis.conf /app/redis/
	cd /app/redis/
	ls -l
/app/redis目录下修改redis.conf文件
	默认出厂的原始redis.conf
		1.开启redis验证	#可选
			requirepass 123
		2.允许redis外地连接	#必须
			注释掉#bind 127.0.0.1	#允许redis外地连接(有的都注释掉)
		3.daemonize no
			将daemonize yes注释起来或者daemonize no设置,因为该配置和dockerrun中-d参数冲突,会导致容器一直启动失败
		4.开启redis数据持久化 appendonly yes	#可选
		5.protected- mode no	#(不放心的话这个也可以设置)
使用redis6.0.8镜像创建容器(也叫运行镜像)
	docker run -p 6379:6379 --name myredis --privileged=true -v /app/redis/redis.conf:/etc/redis/redis.conf -v /app/redis/data:/data -d redis:6.0.8 redis-server /etc/redis/redis.conf
	docker ps
测试redis-cli连接上来
	docker exec -it myredis /bin/bash
	redis-cli
	set k1 v1
	get k1
	ping
	select 10	#正常
	select 15	#正常
	select 18	#数据库索引超出范围
	exit
请证明docker启动使用了我们自己指定的配置文件
	将database 16改成15	#因为我们用的配置文件,数据库默认是16个
测试redis-cli连接上来第2次
	docker exec -it myredis /bin/bash
	redis-cli
	get k1
	select 15	#会发现数据库所以超出范围,就证明是我们自己的配置文件
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值