一次镜像,处处运行(配置文件不一样,版本缺失,第三方引入依赖包不同导致的各种发布上线的错误)
为了解决运行环境和配置问题的软件容器 ,方便做持续集成并有助于整体发布的容器虚拟化技术
传统虚拟机和容器虚拟化技术的区别?
1.
传统虚拟机
2.容器虚拟化技术
官网: https://www.docker.com/
docker hub — 安装docker镜像的仓库 https://hub.docker.com/
镜像:类似java的类模板
容器:通过java类模版new出来的一个个实例对象
仓库:存放镜像的地方
Book book1 = new Book(); // 等号左边Book是镜像,右侧new Book()是DOCKER容器
Book book2 = new Book();
Book book3 = new Book();
Client:客户端
DOCKER_HOST:宿主机
Docker daemon:后台服务线程
Registry:仓库
docker工作原理
https://docs.docker.com/engine/install/centos/#uninstall-old-versions
1、确定你是CentOS7及以上版本
cat /etc/redhat-release
2、卸载旧版本
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
3、yum安装gcc相关
3.1 CentOS7能上外网
3.2 yum -y install gcc
3.3 yum -y install gcc-c++
4、安装需要的软件包
4.1 、官网要求
4.2 、执行命令 : html yum install -y yum-utils
5、设置stable镜像仓库
5.1、推荐
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
6、更新yum软件包索引
yum makecache fast
7、安装DOCKER CE
yum -y install docker-ce docker-ce-cli containerd.io
8、启动docker
systemctl start docker
查看状态 ps -ef | grep docker
9、测试
docker version
docker run hello-world
10、卸载
systemctl stop docker
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
11、 配置阿里云镜像加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://wxu2xpb9.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
启动docker: systemctl start docker
停止docker: systemctl stop docker
重启docker: systemctl restart docker
查看docker状态: systemctl status docker
开机启动: systemctl enable docker
查看docker概要信息: docker info
查看docker总体帮助文档: docker --help
linux 命令 : man xxx
查看docker命令帮助文档: docker 具体命令 --help
列出本地主机上的镜像
各个选项说明:
REPOSITORY:表示镜像的仓库源
TAG:镜像的标签版本号
IMAGE ID:镜像ID
CREATED:镜像创建时间
SIZE:镜像大小
同一仓库源可以有多个 TAG版本,代表这个仓库源的不同个版本,我们使用 REPOSITORY:TAG 来定义不同的镜像。
如果你不指定一个镜像的版本标签,例如你只使用 ubuntu,docker 将默认使用 ubuntu:latest 镜像
OPTIONS说明:
-a :列出本地所有的镜像(含历史映像层)
-q :只显示镜像ID。
网站 : https://hub.docker.com
命令: docker search [OPTIONS] 镜像名字
案例
##
OPTIONS说明:
–limit : 只列出N个镜像,默认25个
docker search --limit 5 redis
下载镜像
1、docker pull 镜像名字[:TAG]
2、docker pull 镜像名字
没有TAG就是最新版
等价于
docker pull 镜像名字:latest
docker pull ubuntu
查看linux硬盘空间 df -h
删除镜像
删除单个
docker rmi -f 镜像ID
删除多个
docker rmi -f 镜像名1:TAG 镜像名2:TAG
删除全部
docker rmi -f $(docker images -qa)
面试题:谈谈docker虚悬镜像是什么?
是什么
仓库名、标签都是的镜像,俗称虚悬镜像dangling image
docker run [OPTIONS] IMAGE [COMMAND] [ARG…]
OPTIONS说明(常用):
-a :列出当前所有正在运行的容器+历史上运行过的
-l :显示最近创建的容器。
-n:显示最近n个创建的容器。
-q :静默模式,只显示容器编号。
启动交互式命令:
docker ps [OPTIONS]
OPTIONS说明(常用):
-a :列出当前所有正在运行的容器+历史上运行过的
-l :显示最近创建的容器。
-n:显示最近n个创建的容器。
-q :静默模式,只显示容器编号。
两种退出方式:
1.exit — run进去容器,exit退出,容器停止
2.ctrl+p+q — run进去容器,ctrl+p+q退出,容器不停止
docker start 容器ID或者容器名
docker restart 容器ID或者容器名
docker stop 容器ID或者容器名
docker kill 容器ID或容器名
docker rm 容器ID/容器名称
docker rm -f 容器ID/容器名称
一次性删除多个容器实例:
docker rm -f $(docker ps -a -q) / docker ps -a -q | xargs docker rm
有镜像才能创建容器,这是根本前提(下载一个Redis6.0.8镜像演示)
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
前台交互式启动
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 attach 容器ID
二、案例演示,用centos或者unbuntu都可以
上述两个区别:
attach 直接进入容器启动命令的终端,不会启动新的进程。用exit退出,会导致容器的停止。
exec 是在容器中打开新的终端,并且可以启动新的进程,用exit退出,不会导致容器的停止。
三、推荐大家使用 docker exec 命令,因为退出容器终端,不会导致容器的停止。
四、用之前的redis容器实例进入试试
1.进入redis服务
2.docker exec -it 容器ID /bin/bash
3.docker exec -it 容器ID redis-cli
4.一般用-d后台启动的程序,再用exec进入对应容器实例
容器→主机
docker cp 容器ID:容器内路径 目的主机路径
export 导出容器的内容留作为一个tar归档文件[对应import命令]
import 从tar包中的内容创建一个新的文件系统再导入为镜像[对应export]
案例 :
docker export 容器ID > 文件名.tar
cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号
以我们的pull为例,在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
镜像分层最大的一个好处就是共享资源,方便复制迁移,就是为了复用。
比如说有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;
同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
Docker镜像层都是只读的,容器层是可写的
当容器启动时,一个新的可写层被加载到镜像的顶部。
这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
1、docker commit提交容器副本使之成为一个新的镜像
2、docker commit -m=“提交的描述信息” -a=“作者” 容器ID 要创建的目标镜像名:[标签名]
3、案例演示ubuntu安装vim
3.1、从Hub上下载ubuntu镜像到本地并成功运行
3.2、原始的默认Ubuntu镜像是不带着vim命令的
3.3、外网连通的情况下,安装vim
docker容器内执行上述两条命令:
apt-get update
apt-get -y install vim
3.4、安装完成后,commit我们自己的新镜像
3.5、启动我们的新镜像并和原来的对比
1 官网是默认下载的Ubuntu没有vim命令
2 我们自己commit构建的镜像,新增加了vim功能,可以成功使用。
1 官方Docker Hub地址:https://hub.docker.com/,中国大陆访问太慢了且准备被阿里云取代的趋势,不太主流。
2 Dockerhub、阿里云这样的公共镜像仓库可能不太方便,涉及机密的公司不可能提供镜像给公网,所以需要创建一个本地私人仓库供给团队使用,基于公司内部项目构建镜像。
Docker Registry是官方提供的工具,可以用于构建私有镜像仓库
docker pull registry
docker run -d -p 5000:5000 -v /zzyyuse/myregistry/:/tmp/registry --privileged=true registry
默认情况,仓库被创建在容器的/var/lib/registry目录下,建议自行用容器卷映射,方便于宿主机联调
1.从Hub上下载ubuntu镜像到本地并成功运行
2.原始的Ubuntu镜像是不带着ifconfig命令的
3.外网连通的情况下,安装ifconfig命令并测试通过
docker容器内执行上述两条命令:
apt-get update
apt-get install net-tools
4.安装完成后,commit我们自己的新镜像
公式:
docker commit -m=“提交的描述信息” -a=“作者” 容器ID 要创建的目标镜像名:[标签名]
命令:在容器外执行,记得
docker commit -m=“ifconfig cmd add” -a=“zzyy” a69d7c825c4f zzyyubuntu:1.2
5.启动我们的新镜像并和原来的对比
1 官网是默认下载的Ubuntu没有ifconfig命令
2我们自己commit构建的新镜像,新增加了ifconfig功能,可以成功使用。
curl -XGET http://192.168.111.162:5000/v2/_catalog
按照公式: docker tag 镜像:Tag Host:Port/Repository:Tag
自己host主机IP地址,填写同学你们自己的,不要粘贴错误,O(∩_∩)O
使用命令 docker tag 将zzyyubuntu:1.2 这个镜像修改为192.168.111.162:5000/zzyyubuntu:1.2
docker tag zzyyubuntu:1.2 192.168.111.162:5000/zzyyubuntu:1.2
别无脑照着复制,registry-mirrors 配置的是国内阿里提供的镜像加速地址,不用加速的话访问官网的会很慢。
2个配置中间有个逗号 ','别漏了,这个配置是json格式的。
2个配置中间有个逗号 ','别漏了,这个配置是json格式的。
2个配置中间有个逗号 ','别漏了,这个配置是json格式的。
vim命令新增如下红色内容:vim /etc/docker/daemon.json
{
“registry-mirrors”: [“https://aa25jngu.mirror.aliyuncs.com”],
“insecure-registries”: [“192.168.111.162:5000”]
}…
docker push 192.168.111.162:5000/zzyyubuntu:1.2
docker run -d -p 5000:5000 -v /zzyyuse/myregistry/:/tmp/registry --privileged=true registry
curl -XGET http://192.168.111.162:5000/v2/_catalog
docker pull 192.168.111.162:5000/zzyyubuntu:1.2
docker run -it 镜像ID /bin/bash
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名
Docker容器产生的数据,如果不备份,那么当容器实例删除后,容器内的数据自然也就没有了。
为了能保存数据在docker中我们使用卷。
特点:
1:数据卷可在容器之间共享或重用数据
2:卷中的更改可以直接实时生效,爽
3:数据卷中的更改不会包含在镜像的更新中
4:数据卷的生命周期一直持续到没有容器使用它为止
宿主vs容器之间映射添加容器卷
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名
容器和宿主机之间数据共享
1 docker修改,主机同步获得
2 主机修改,docker同步获得
3 docker容器stop,主机修改,docker容器重启看数据是否同步。
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:rw 镜像名
默认同上案例,默认就是rw
容器实例内部被限制,只能读取不能写
/容器目录:ro 镜像名 就能完成功能,此时容器自己只能读取不能写
ro = read only
此时如果宿主机写入内容,可以同步给容器内,容器可以读取到。
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
1、容器1完成和宿主机的映射
docker run -it --privileged=true -v /mydocker/u:/tmp --name u1 ubuntu
2、容器2继承容器1的卷规则
docker run -it --privileged=true --volumes-from 父类 --name u2 ubuntu
1、搜索镜像
2、拉取镜像
3、查看镜像
4、启动镜像
4.1、服务端口映射
5、停止容器
6、移除容器
1、docker hub上面查找tomcat镜像
docker search tomcat
2、从docker hub上拉取tomcat镜像到本地
docker pull tomcat
3、docker images查看是否有拉取到的tomcat
4、使用tomcat镜像创建容器实例(也叫运行镜像)
docker run -it -p 8080:8080 tomcat
-p 小写,主机端口:docker容器端口
-P 大写,随机分配端口
i:交互
t:终端
d:后台
5、访问猫首页
1.问题
2.解决
可能没有映射端口或者没有关闭防火墙
把webapps.dist目录换成webapps
先成功启动tomcat
查看webapps 文件夹查看为空
6、免修改版说明
docker pull billygoo/tomcat8-jdk8
docker run -d -p 8080:8080 --name mytomcat8 billygoo/tomcat8-jdk8
一、简单版
1.使用mysql镜像
docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
docker ps
docker exec -it 容器ID /bin/bash
mysql -uroot -p
2.建库建表插入数据
3.外部Win10也来连接运行在dokcer上的mysql容器实例服务
4.问题
1.插入中文数据试试
为什么报错?
docker上默认字符集编码隐患
docker里面的mysql容器实例查看,内容如下:
SHOW VARIABLES LIKE 'character%'
2.删除容器后,里面的mysql数据如何办
容器实例一删除,你还有什么?
二、实战版
1.新建mysql容器实例
docker run -d -p 3306:3306 --privileged=true -v /zzyyuse/mysql/log:/var/log/mysql -v /zzyyuse/mysql/data:/var/lib/mysql -v /zzyyuse/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7
2.新建my.cnf(在主机上)
通过容器卷同步给mysql容器实例
[client]
default_character_set=utf8
[mysqld]
collation_server = utf8_general_ci
character_set_server = utf8
3.重新启动mysql容器实例再重新进入并查看字符编码
4.再新建库新建表再插入中文测试
结论
之前的DB 无效
修改字符集操作+重启mysql容器实例,之后的DB 有效,需要新建
结论:docker安装完MySQL并run出容器后,建议请先修改完字符集编码后再新建mysql库-表-插数据
假如将当前容器实例删除,再重新来一次,之前建的db01实例还有吗?trytry
1.建目录
mkdir -p /app/redis
2 拷贝配置文件
将准备好的redis.conf文件放进/app/redis目录下
3 /app/redis目录下修改redis.conf文件
3.1 开启redis验证 可选
requirepass 123
3.2 允许redis外地连接 必须
注释掉 # bind 127.0.0.1
3.3 daemonize no
将daemonize yes注释起来或者 daemonize no设置,因为该配置和docker run中-d参数冲突,会导致容器一直启动失败…
docker run -p 6379:6379 --name myr3 --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 exec -it 运行着Rediis服务的容器ID redis-cli
修改前:我们用的配置文件,数据库默认是16个
修改后: 宿主机的修改会同步给docker容器里面的配置。
记得重启服务