一、简单介绍
(一)为什么用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)
- 镜像就是一个只读的模板,可以通过这个模板创建容器服务,一个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中)
(二)容器(container)
-
Docker利用容器技术,独立运行的一个或一组应用。容器是用镜像创建的运行实例。
-
它可以被启用,开始,停止,删除。每个容器都是相互隔离的,保证安全的平台。
-
可以把容器看作是一个简易版的Linux系统(包括root用户权限,进程空间,用户空间和网络空间等)和运行在其中的应用程序。
-
容器的定义和镜像几乎一摸一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的
(三)仓库(repository)
-
仓库是集中存放镜像文件的场所。
-
仓库和仓库注册服务器(Registry)是有区别的,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签
-
仓库分为公开仓库(public)和私有仓库(private)两种形式
-
最大的开放仓库是国外的 Docker Hub,存放了数量庞大的镜像供用户下载。
-
国内的公开仓库包括阿里云,网易云都有容器服务器(需要配置镜像加速)等
四、安装
官网安装教程十分详细,可参照此教程: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>,建议删除
(三)容器命令
有镜像才能创建容器,这是根本前提(下载一个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后需要守护式启动,因为你交互式启动万一不小心关了就完蛋了)
前台交互式启动
dcoker 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
dcoker 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 #会发现数据库所以超出范围,就证明是我们自己的配置文件