Docker基础
官方文档地址:https://www.docker.com/get-started 推荐
中文参考手册:https://docker_practice.gitee.io/zh-cn/中文gitee
什么是Docker
1.官网定义:
我们帮助开发人员和开发团队构建和发布应用
我们为你提供一个完整的容器解决方案,不管你是谁,不管你在哪里,你都可以开始容器的旅程
docker是一个容器技术,docker引擎容器(container)软件(redis mysql tomcat rabbitmq) 构建发布应用
通俗理解为docker是一个软件容器平台|引擎|技术|
早期docker定义:运行你的应用不需要你的环境
容器到底装的是什么?
容器装的就是一个个的软件服务
Docker优势
环境一致,高效迁移
如:我们一个web应用程序涉及很多东西,比如django、mysql、redis、nginx等软件环境,当这些其中某一项版本不一致的时候,可能就会导致应用程序跑不起来的情况,Docker则将程序以及使用软件环境直接绑定在一起,无论在哪个机器上保证的环境的一致。
进程级隔离,容器独立
如:服务器自己的程序挂了,结果发现是别人程序错误把内存吃完了,自己程序因为内存不够就挂掉了,这种也是很常见的情况,如果你的程序的重要性不是非常高的话,公司基本上不可能让你的程序独享一台服务器,这时候你的服务器就会跟公司其他人的程序共享一台服务器,所以不可避免就会受到其他程序的干扰,导致自己的程序出现问题。Docker就能很好的解决环境隔离的问题,别人程序不会影响到自己的程序。
镜像机制,便于部署
公司要弄一个活动,可能会有大量的流量进来,公司需要多部署几十台的服务器,在没有docker的情况下,要在几天内部署几十台服务器,这对运维人员来说非常的折磨,而且每台服务器的环境还不一定一样,就会出现各种问题,用Docker的话,我们只要将程序打包到镜像,你要多少台服务,我就给跑多少个容器,极大地提高了部署效率。
Docker和虚拟机的区别
每一个容器是操作系统之间的隔离
Docker 引擎的安装
安装docker引擎
linux发行版本 centos7+
安装步骤
官网安装步骤:https://docs.docker.com/engine/install/centos/
通用方式安装:跟linux的发行版本无关
Linux平台下Docker的通用方式安装方法
$ curl -fsSL get.docker.com -o get-docker.sh # 执行下载docker引擎的脚本文件
$ sudo sh get-docker.sh --mirror Aliyun # 执行脚本通过脚本下载,设置阿里云镜像下载加速启动docker
$ sudo systemctl enable docker # 将docker加入开机自启动列表
$ sudo systemctl start docker # 启动docker服务(restart重启 status状态 stop停止)创建docker用户组
$ sudo groupadd docker将当前用户加入到docker组
$ sudo usermod -aG docker $USER # 修改过程中会自动创建docker测试docker安装是否正确
$ docker run hello-world查看docker引擎
$ docker info # 查看docker信息
$ docker version # 查看docker版本Docker中的核心概念
镜像(image)
定义:一个镜像代表一个软件
容器 (container)
定义:一个镜像运行一次就会生成一个容器,容器就是一个运行的件服务
仓库(Respostory)
定义: 仓库用来存储所有软件的镜像位置 =====>仓库web界面 docker hub 中心仓库
本地仓库
定义:用于存储在使用docker过程中的相关镜像
Docker中核心架构图
镜像:一个镜像代表一个应用环境,它是一个只读的文件,如:mysql镜像,tomcat镜像,redis镜像,nginx镜像等。容器:镜像每次运行之后就是产生一个容器,就是正在运行的镜像,特点是可读可写。仓库:用来存放镜像的位置,类似与maven仓库,也是镜像下载和上传的位置。dockFile:docker生成镜像配置文件,用来书写自定义镜像的一些配置tar:一个镜像打包的文件,日后可以还原成镜像
镜像加速
docker运行流程
如何拉取官方镜像
$ docker pull tomcat # 拉取最新版本的tomcat
$ docker pull tomcat:8.0 # 拉取指定版本的tomcatDocker如何配置阿里云的镜像加速
- 进入阿里云的官方网站
- 使用账号名和密码进行登录或者扫码登录
- 在控制台搜索镜像加速服务
访问阿里云登录自己账号查看docker镜像加速服务
$ sudo mkdir -p /etc/docker $ sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["<https://xnan2sz4.mirror.aliyuncs.com>"] } EOF $ sudo systemctl daemon-reload $ sudo systemctl restart docker验证docker的镜像加速是否生效
$ docker info ........... 127.0.0.0/8 Registry Mirrors: '<https://lz2nib3q.mirror>,aliyuncs.com' Live Restore Enabled: false Product License: Commounity Engine
概念
- docker中的三个概念
- 仓库
- 远程仓库:docker公司在世界范围内维护的一个中心,用来集中管理docker中的镜像----->搜索仓库 docker hub
- 本地仓库:用来存储自己使用过的镜像,在中心仓库下载镜像存储到本地仓库 /var/lib/docker
- 镜像 image
- 镜像是只读的,不能进行写操作
- 容器 container
- 容器可读可写
- 仓库
docker第一个应用程序
# hello-world
$ docker run hello-world通过docker第一个程序总结docker执行流程
docker run执行镜像 首先去本地仓库去查找,如果本地仓库有,自动对镜像生成一个容器,如果本地仓库没有,它会去中心仓库去下载到本地仓库,然后对镜像生成一个容器。
docker中镜像的相关操作
辅助命令:docker version
功能:用来查看docker客户端引擎和server端引擎版本信息
辅助命令:
docker info功能:用来查看docker引擎
辅助命令:
docker --help功能:帮助信息
镜像 image
查看当前本地仓库存在哪些镜像
docker image ls或者docker images$ docker images # 结果解释 `REPOSITORY` 镜像名称 `TAG` 镜像版本 `IMAGE ID` 镜像ID `CREATED ` 镜像创建时间 `SIZE` 镜像大小 REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest feb5d9fea6a5 10 months ago 13.3kB tomcat 8.0 ef6a7c98d192 3 years ago 356MB注意:以后在使用镜像时,可以使用镜像的ID短名去使用
查看当前本地仓库指定的镜像有哪些版本
docker images 镜像名$ docker images tomcat展示出所有的docker镜像
docker images -a$ docker images -a展示出所有docker镜像的ID
docker images -q$ docker images -q # 展示内容为镜像的ID feb5d9fea6a5 ef6a7c98d192下载一个镜像
docker pull镜像名称 或者docker pull镜像名称:版本$ docker pull tomcat # 获取最新版本 $ docker pull tomcat:9.0 # 获取指定版本搜索镜像
docker search镜像名称$ docker search tomcat # 智能查看当前镜像是否存在,不能列出版本删除镜像
docker image rm镜像名称(name:tag)或者docker image rm镜像ID# 正常删除 $ docker image rmi tomcat:9.0 $ docker image rmi ef6a7c98d192 # 强制删除 $ docker image rmi -f tomcat:9.0 $ docker image rmi -f ef6a7c98d192 # 删除指定镜像名称的所有镜像---->批量删除 $ docker image rmi -f $(docker images tomcat -q) # 删除仓库内的所有镜像 $ docker image rmi -rf $(docker images -q)清理镜像
$ docker image prune支持的子命令
- a 删除所有没有用的镜像,而不仅仅是临时文件。
- f 强制删除镜像文件,无需弹出提示确认。
docker中容器的基本操作1
操作容器的命令格式: docker 命令 [选项]
如何查看docker引擎中运行的容器有哪些?
docker ps查看当前docker引擎中正在运行的容器$ docker ps # 结果解释 `CONTAINER ID` 容器ID `IMAGE` 基于哪个镜像 ` COMMAND` 容器内启动服务的命令 `CREATED` 容器创建时间 `STATUS` 容器状态 `PORTS` 容器服务监听端口 `NAMES` 容器名称 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6f755ceba23c tomcat:8.0 "catalina.sh run" 23 seconds ago Up 22 seconds 8080/tcp infallible_fermat查看所有容器(运行 停止)
docker ps -a查看所有的容器id
docker ps -aq
如何运行一个容器
docker run 镜像名或者docker run 镜像ID$ docker run tomcat:8.0简单运行tomcat镜像
docker run tomcat:8.0|(imageid)运行tomcat容器,同时设置容器与宿主机端口的映射关系
Pdocker run -p 8080(宿主机):8080 tomcat:8.0$ docker run -p 8080:8080 tomcat:8.0注意:可以映射多个端口
运行tomcat,开发端口映射,后台启动该服务
ddocker run -p 8082:8080 -d tomcat:8.0$ docker run -p 8082:8080 -d tomcat:8.0运行tomcat,开放端口映射,后台启动该服务,指定容器名称
-name容器名称docker run -d -p 8083:8080 --name tomcat01 tomcat:8.0$ docker run -d -p 8083:8080 --name tomcat01 tomcat:8.0
停止 重启 暂停 恢复容器
# 停止 $ docker stop 容器id|容器名称 #重启 $ docker restart 容器id|容器名称 #启动 $ docker start 容器id|容器名称 #暂停 $ docker pause 容器id|容器名称 #恢复 $ docker unpause 容器id|容器名称
docker中容器的基本操作2
杀死容器
docker kill id|name
$ docker kill id删除容器
docker rm id|name
$ docker rm id删除一个正在运行的容器
docker rm -f id|name
$docker rm -f id查看容器内部的日志
docker logs id|name
$docker logs id
-t 加入时间戳
-f 跟随最新的日志打印 实时监控容器内服务的日志
--tail 数字显示最后多少条进入容器的内部
容器内部其实是一个linux系统装上了相关的服务
进入容器内部相当于进入了一个新的linux系统里
docker exec -it id|name bash
# -it 表示交互模式
# 先查看一下运行的容器
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aaece9d9ef78 redis "docker-entrypoint.s…" 7 minutes ago Up 7 minutes 0.0.0.0:6379->6379/tcp, :::6379->6379/tcp romantic_jepsen
$ docker exec -it aa bash # 这里的aa指的是aaece9d9ef78 可以缩写为aa退出容器
exit
$ exit容器与宿主机之间的文件拷贝
如何将容器中指定文件和目录拷贝到宿主机
docker cp 容器id|name:容器中文件或目录 主机目录$ docker cp id:/home/index.html /root $ docker cp id:/usr/home/tt /root如何将主机中指定文件和目录拷贝到容器内
docker cp 主机文件和目录 容器id:容器中目录$ docker cp /root/index.html id:/home/
部署项目到docker容器内
- 将项目上传到linux服务器2. 通过
docker cp命令将项目复制到tomcat的webapps目录中即可3. 使用ip+端口进行测试访问
docker cp /root/test.war id:/usr/lcoal/tomcat/webapp
docker中容器的基本操作3
查看容器内运行进程的指令
docker top 容器id或者 docker top 容器name
docker top id|name查看容器内细节指令
docker inspect 容器id或者docker inspect 容器name
docker inspect id|name容器数据卷机制【重点】
数据卷 Data Volume
作用:用来实现容器中的数据与宿主机中数据进行映射的(同步)
注意:数据卷使用时必须在容器首次启动时设置使用:
docker run -v 宿主机目录:容器内目录数据卷的真正意义:在以后使用数据库搭建在容器中的时候,数据库用于存储,如果不使用数据卷的方式,会导致人员把搭建的mysql数据库的容器给删除了,就会导致数据丢失使用数据卷将容器内数据映射到本地,把容器删除了也不会影响本机与数据卷同步的数据
创建方式一:使用绝对路径设置数据卷
$ docker run -v 宿主机绝对路径:容器内路径:(ro) # 注意:这种方式会将容器路径的原始内容全部清空,始终以宿主机路径为主 # ro: ready only 如果在设置数据卷时指定ro,代表以后容器内的路径是只读的 $ docker run -d -p 8081:8080 --name tomcat01 -v /root/apps:/usr/local/tomcat/webapps创建方式二:使用别名方式设置数据卷
$ docker run -v aa:/usr/local/tomcat/webapps ...... # aa 代表docker数据卷中别名,注意:这个别名如果存在docker直接使用 aa不存在直接创建 # 使用别名方式保留容器路径内原始内容,前提别名对应不能存在内容 # 注意:docker根据别名创建目录默认在:/var/lib/docker/volumes/
docker中容器的基本操作4
docker三个核心概念
仓库 repostory
作用:docker 官方维护一个仓库,用来集中存储镜像
镜像 Image
作用:一个镜像代表一个软件服务
特点:只读
容器 container
作用:镜像没运行一次形成一个容器,运行的容器代表一个正在运行的软件服务
特点:可读可写
将容器打包成一个新的镜像
为什么要将容器打包程一个新的镜像?
原因:容器可读可写,基于这个特性我们可以对容器进行我们自己的深度定制
我们可以将修改的容器打包成一个新的镜像,以后基于这个镜像运行成容器存在原始定制特性
目的:可以将项目都放到原始容器后,在进行打包成新的容器,以后可放在多个新的服务器上,做到分布式部署
如何将容器打包成一个新的镜像
docker commit -m "描述信息" 容器id 镜像名:版本或者docker commit -m "描述信息" 容器名称 镜像名:版本$ docker commit -m "描述信息" id 镜像名称:版本镜像的备份和恢复
备份镜像
docker save 镜像名:版本 -o 镜像原始名称-版本.tar$ docker save tomcat:8.0 -o tomcat-8.0.tar # 默认备份到当前目录恢复镜像
docker load -i 镜像原始名称-版本.tar$ docker load -i tomcat-8.0.tar
docker中镜像原理
镜像为什么这么大?
原始 tomcat:10M 镜像 tomcat:356M解释:容器独立操作系统(精简的linux操作系统+软件服务)====>镜像运行====>镜像(操作系统+软件服务)
镜像是一种轻量级的,可独立执行的软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需要的全部内容,包括代码,运行时所需要的库、环境变量和配置文件。
UniFS 联合文件系统 叠加文件系统
Union文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改为一次提交来一层一层的叠加,同时可以将不同目录挂在到同一个虚拟文件系统下。
Union文件系统是docker镜像的基础,这种文件系统特性就是一次同时加载多个文件系统,但从外面看起来只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
原理
docker中的镜像实际是由一层一层文件系统组成的,UnionFS联合文件系统
bootloader引用加载器kwenel内核- bootfs(bot file system)主要包含
bootloader和kernel,bootloader主要引导加载kernel,linux刚启动时会加载bootfs文件系统,在docker镜像的最底层就是botfs。这一层与Linux/Unix系统是一样的,包括boot加载器(bootloader)和内核(kernel)。当boot加载完成之后,整个内核都在内存中,此时内存的使用权已经由bootfs交给内核,此时会卸载bootfs。 - rootfs(root file system)在bootfs之上,包含的就是典型的linux系统的
/dev/proc/bin/etc等标准目录和文件。rootfs就是各种功能不同操作系统的发行版本,比如ubuntu、centos - 我们平时安装进虚拟机的centos都有几个GB,为什么docker这里才只有200MB?对于一个精简的os,rootfs可以很小,只需要包括最基本的命令,工具和程序库就可以了。因为底层直接使用
Host的Kernal,自己只需要提供rootfs就行了,由此可见不同的linux发行版,他们的bootfs一致,rootfs有区别。因此不通的发行版可以共用bootfs。
- bootfs(bot file system)主要包含
为什么docker镜像要使用这种分层结构?
好处:资源共享
- 有多个镜像都是从相同的base镜像构建而来的,那么宿主机只需要在磁盘中保存一份base镜像。同时内存中也主需要加载一份base镜像,就可以为所有容器服务了,而且镜像的每一层都可以被共享。docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层被称为容器层,容器层之下都叫镜像层。
docker 安装mysql服务
建议:使用任何容器参考dockerhub官方网站+搜索引擎(百度google)
下载mysql镜像
- 访问docker hub 官方网站搜索mysql
- 确定版本 5.x (行业流行版本) 8.x(最新版本,引擎更快 特性)
# registry.hub.docker.com $ docker pull mysql:5.6运行mysql
# 启动mysql 开放端口映射(3306) 指定root用户密码 -e代表环境 # 如果本机有mysql不能使用3306端口进行端口映射 $ docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag $ docker yun -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root mysql:5.6启动mysql 开放端口映射(3306) 指定root用户密码 -e MYSQL_ROOT_PASSWORD=xxx 后台运行 -d 指定名称 --name
# 后台启动 $ docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d --name mysql01 mysql:5.6启动mysql 开放端口映射(3306) 指定root用户密码 -e MYSQL_ROOT_PASSWORD=xxx 后台运行 -d 指定名称 --name 总是运行 --restart=always
# 开机自启动 系统重启docker docker容器也跟着启动 #命令 `--restart=always` $ docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d --name mysql02 --restart=always mysql:5.6启动mysql 开放端口映射(3306) 指定root用户密码 -e MYSQL_ROOT_PASSWORD=xxx 后台运行 -d 指定名称 --name 总是运行 --restart=always 数据卷持久化数据到宿主机
重要
推荐使用此方法# 数据同步到宿主机 # -v 宿主机地址:容器地址 $ docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d --name mysql02 --restart=always -v /root/data:/var/lib/mysql mysql:5.6docker 运行mysql容器数据备份
生产服务器:linux centos系统 【宿主机】
内部有:docker引擎
mysql容器在docker引擎之上
在使用mysql容器时数据卷虽然能备份数据
注意:数据卷将数据库底层文件系统进行备份
数据卷只能完成当前宿主机与数据库之间的数据存储,跨机器就实现不了。
不利于诗句迁移和备份,推荐使用sql文件形式去备份数据
如何在mysql中导出sql文件来备份文件
提示: |表示或者的意思,可以使用容器的id
方式一:利用mysql官方命令
mysqldump完成信息的备份备份全部数据
$ mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD" > /root/all-databases.sql # mysql的命令 $ docker exec mysql|容器id sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/all-databases.sql # docker命令备份指定库数据
$ docker exec mysql|容器id sh -c 'exec mysqldump -databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/xx-databases.sql #docker命令备份指定库中的结构,不要数据
$ docker exec mysql|容器id sh -c 'exec mysqldump --no-data -databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > /root/xx-databases.sql #docker命令
使用navicat提供数据备份进行备份
打开软件,连接数据库,找到数据表邮件选择转存储,仅结构
直接在对应库选择备份的表即可,导出即可。
docker安装redis服务
建议:使用任何容器参考dockerhub官方网站+搜索引擎(百度google)
redis支持内存数据持久化
aof持久化redis服务器将所有redis客户端的写操作以命令方式记录到日志文件中aof更安全rdb持久化快照 redis服务器将某一时刻数据以快照文件形式写入到磁盘
下载redis
$ docker pull redis:5.0.12运行redis
$ docker run -p 6379:6379 redis:5.0.12 # 后台运行 映射端口(6379) 后台启动 -d 指定名称 --name 总是启动 --restart=always $ docker run -d -p 6379:6379 --name redis01 --restart=always redis:5.0.12docker 运行redis如何开启持久化
注意只要开启了持久化,持久化文件生成在容器中的/data目录中# 后台运行 映射端口(6379) 后台启动 -d 指定名称 --name 总是启动 --restart=always 开启持久化 --appendonly yes $ docker run -d -p 6379:6379 --name redis01 --restart=always --appendonly yes redis:5.0.12docker 启动redis 开放端口 后台启动 指定名称 总是启动 开启持久化 映射数据文件外部
注意使用此命令后!如果把redis容器删除了,也可以把数据恢复回来$ docker run --name redis03 -d -p 6379:6379 --restart=always -v /root/redisdata:/data redis-server --appendonly yes redis:5.0.12docker 启动redis 使用配置文件启动
- 如何获取redis配置文件
- 第一种方式:下载对应版本找到配置文件,进行修改 使用完整配置文件启动
不推荐 - 第二种方式:创建指定的文件名称,直接书写修改属性即可
推荐
- 第一种方式:下载对应版本找到配置文件,进行修改 使用完整配置文件启动
- 上传配置文件到宿主机指定目录 /root/redisconf/redis.conf
- 数据卷挂载配置启动
$ docker run --name redis03 -d -p 6379:6379 --restart=always -v /root/redisconf:/data redis-server /data/redis.conf --appendonly yes redis:5.0.12- 如何获取redis配置文件
docker 运行 nginx服务
注意 下载nginx时, 先确定下载版本, 按照docker pull nginx:版本号 去下载
下载 nginx
$ docker pull nginx运行 nginx
# 启动nginx 映射端口(80) $ docker run -p 80:80 nginx # 启动nginx 映射端口(80) 后台启动 总是启动 指定名称 $ docker run -p 80:80 -d --restart=always --name nginx01 nginx:版本号 # 启动nginx 映射端口(80) 后台启动 总是启动 指定名称 加载指定nginx配置启动 -v 容器(/etc/nginx/nginx.conf) $ docker run -p 80:80 -d --restart=always --name nginx01 -v /root/nginxconf/nginx.conf:/etc/nginx/nginx.conf nginx:版本号查看nginx容器是否启动成功
$ docker ps实现反向代理 负载均衡
# 拷贝文件 $ docker cp 容器id:/etc/nginx/nginx.conf /root/nginxconf $ docker run -p 80:80 -d --restart=always --name nginx01 -v /root/nginxconf/nginx.conf:/etc/nginx/nginx.conf nginx:版本号nginx作为服务器
$ docker run -p 80:80 -d --restart=always --name nginx01 -v /root/html :/usr/share/nginx/html nginx:版本号nginx作为服务器 又想改配置
注意 -v 可以写多个,没有限制
$ docker run -p 80:80 -d --restart=always --name nginx01 -v /root/html :/usr/share/nginx/html -v /root/nginxconf/nginx.conf:/etc/nginx/nginx.conf nginx:版本号
docker中安装Elasticsearch服务
去docker hub确定版本
下载镜像
docker pull elasticsearch:6.8.10运行es
# 启动 es 映射端口(9200(http) 9300(tcp)) $ docker run -p 9200:9200 -p 9300:9300 elasticsearch:6.8.10 # 启动 es 映射端口(9200(http) 9300(tcp)) 总是启动 指定名称 $ docker run -p 9200:9200 -p 9300:9300 elasticsearch:6.8.10 -d --restart=always --name=es elasticsearch:6.8.10 # 启动 es 映射端口(9200(http) 9300(tcp)) 总是启动 指定名称 通过数据卷映射数据到宿主机 容器内数据存储目录为(/usr/share/elasticsearch/data) $ docker run -p 9200:9200 -p 9300:9300 elasticsearch:6.8.10 -d --restart=always --name=es -v esdata:/usr/share/elasticsearch/data elasticsearch:6.8.10 # 注意:es启动如果没有知名单机方式启动,默认使用集群方式启动,如果使用集群方式启动在启动时会出现如下错误:1. max virtual menory areas vm.max_map_count[65530] is too low, increase to at least[262144] # 解决方案:在宿主机中执行如下操作 # 在centos虚拟机中,修改配置susctl.conf $ vim /etc/sysctl.conf # 加入如下配置 $ vm.max_map_count=262144 # 启动配置, 使配置生效 $ sysctl -p # 启动 es 映射端口(9200(http) 9300(tcp)) 总是启动 指定名称 通过数据卷映射数据到宿主机 通过数据将配置文件映射到宿主机 $ docker run -p 9200:9200 -p 9300:9300 elasticsearch:6.8.10 -d --restart=always --name=es -v esdata:/usr/share/elasticsearch/data -v /root/esconfig/elasticsearch.yml:/usr/share/elasticsearch/config/ elasticsearch:6.8.10
docker中安装MongoDB数据库
去docker hub确定版本
下载镜像
docker pull elasticsearch:6.8.10运行MongoDB
# 运行
$ docker run -d -p 27017:27017 --name mymongo mongo:版本号
# 查看运行日志
$ docker logs -f mymongo
# 进入mongoldb容器
$ docker exec -it mymongo bash
# 常见具有权限的容器
$ docker run --name mymongo -p 27017:27017 -d mongo --auth
# 进入容器配置用户名和密码
$ mongo
$ use admin #选择admin库
$ db.createUser({user:'root',pwd:'root',roles:[{role:'root',db:'admin'}]}) # 创建用户,此用户创建成功,则后续操作都需要用户认证
$ exit
# 将mongodb数据目录映射到宿主机中
$ docker run -d -p 27017:27017 -v /root/mongo/data:/data/db --name mymongo mongodocker中容器之间的通信 -网络使用
容器间通信
说明: 容器之间通过网络相互通信
官方说明:
当docker启动的时候,会自动在主机上创建一个docker0的虚拟网桥,实际上是linux的一个bridge,可以理解为一个软件交换机,它会在挂在到它的网口之间进行转发。
同时,docker随机分配一个本地未占用的私有网段(在RFC1918中定义)中的一个地址给
docker0接口,比如典型的172.17.42.1,掩码为255.255.0.0。伺候启动的容器内的网口也会自动分配一个同一网段(172.17.0.0/16)的地址。当创建一个docker容器的时候,同时会创建一个
veth pair接口(当数据包发送到一个接口时,另外一个接口也可以受到相同的数据包)。这对接口一端在容器内,即etho;另一端在本地并被挂在到docker0网桥,名称以veth开头(例如:vethAQI2QT)。通过这种方式,主机可以跟容器通信,容器之间也可以相互通信,docker就可以创建在主机和所有容器之间的一个虚拟的共享网络。网络总结
- 默认docker在创建容器时,将所有的容器都连接到docker0网桥上。默认在docker0网桥的容器都可以使用容器内ip地址进行通信。
- 默认docker在创建容器时,将所有容器都连接到docker0网桥上,默认在docker0网桥的容器都可以使用容器名字进行通信
自定义网桥实现网桥中一组容器的通信
缺点:没有办法跨桥通信
docker中网桥类型
NETWORK ID NAME DRIVER SCOPE af94280cb29a bridge bridge local 6762fc67bdec host host local 2f9d4d1e4b61 none null localdocker中网络类型:bridge、host、null
创建网络自定义网桥
$ docker network --help # 查看network帮助 $ docker network create -d bridge 网络名 # 创建(默认) 网络名称 $ docker network ls # 查看网络 $ docker network inspect 网络名 # 查看某一个网络细节 $ docker network rm 网络名 # 删除某一个网络 $ docker network prune # 删除所有未被使用的网络名运行多个容器在指定网络中
启动容器时明确指定容器使用哪个网络
$ docker run -d --network 网络名称启动容器之后容器加入某个网络中
$ docker run -d -p 8080:8080 --name tomcat01 --network ems tomcat:8.0 $ docker run 0d -p 8081:8080 --name tomcat01 --network ems tomcat:8.0 $ docker network inspect ems # 查看ems网络下的容器
docker高级数据卷
高级数据卷配置
定义:用来实现宿主机和容器之间文件目录映射同步
数据卷使用 -v 宿主机路径:容器内路径
注意:必须在容器首次启动时指定
使用绝对路径数据卷
$ docker run -v /root/datas:/usr/local/tomcat/webapps :tomcat:8.0使用别名方式数据卷
$ docker run -v bb:/usr/local/tomcat/webapps :tomcat:8.0
别名到底是什么
别名代表一个docker自身维护数据卷
查看所有docker维护数据卷
docker volume ls查看数据卷详细内容
docker insepct 数据卷别名、网桥名称、容器名称 docker network inspect 查看网桥详细 docker volume inspect 查看数据卷详细删除一个数据卷
docker volume rm 数据卷别名创建一个别名数据卷
docker volume create 数据卷别名
Dockerfile 重点
什么是Dockerfile
Dockerfile可以认为是docker镜像的描述文件,是由一系列命令和参数构建成的脚本,主要作用是用来构建docker镜像的构建文件。
作用
通过Dockerfile文件构建一个属于自己的镜像为什么要使用Dockerfile构建镜像的?
官方的镜像确实足够号了,足够适用于大多数应用程序,但是如果我们想自助机属于我们自己的业务镜像,这个时候必须自定义镜像。
如何使用Dockerfile构建自己的镜像
在指定位置创建一个Dockerfile文件
编写dockerfile相关语法通过dockerfile构建镜像
$ docker build -t aa:1.0 .... 指定dockerfile文件所在位置
Dockerfile构建镜像流程
要求: Dockerfile一行只能写一条指令
Dockerfile内容基础知识
1. 每条保留字指定都必须为大写,且后面都要跟至少一个参数。
2. 指领按照从上到下,顺序执行。
3. # 表示注释
4.每条指令都会创建一个新的镜像层,并对镜像进行提交。Dockerfile的保留命令
| 保留字 | 作用 |
|---|---|
| FORM | 当前镜像基于哪个镜像 第一个指令必须是FORM |
| MAINTAINER | 镜像维护者的姓名和邮箱地址 |
| RUN | 构建镜像时需要运行的指令 |
| EXPOSE | 当前容器对外暴露出的端口号 |
| WORKDIR | 指定在创建容器后,终端默认登录进来的工作目录,一个落脚点 |
| ENV | 用来在构建过程中设置环境变量 |
| ADD | 将宿主机目录下的文件拷贝进镜像,且ADD命令会自动处理URL和解压tar包 |
| COPY | 类似于ADD,拷贝文件和目录到镜像中,将从构建上下文目录中<原路径>的文件/目录赋值到新的一层镜像内<目标路径>位置。 |
| VOLUME | 容器数据卷,用于数据保存和持久化工作 |
| CMD | Dockerfile中可以有多个CMD命令,但只有最后一个有效,CMD会被docker run之后的参数替换。 |
| ENTRYPOINT | 指定一个容器启动时要运行的命令,ENTRYPOINT的目的和CMD一样。都是在指定容器启动程序及其参数 |
使用Dockerfile
在宿主机的某一个文件夹里创建一个名称为Dockerfile的文件
使用编辑器工具或者vim去编写Dockerfile文件里内容
小技巧:运行centos容器,直接进入到centos系统中
docker run -it centos:latest$ mkidr docker $ cd docker $ touch DockerfileDockerfile文件内容
FORM centos:latest RUN
FORM命令
基于那个镜像进行构建新的镜像,在构建时会自动从docker hub拉取base镜像,必须作为Dockfile的第一个指令出现
语法
FORM <image> FORM <image>[:<tag>] # 使用版本不写为latest FORM <image>[@<digest>] # 使用摘要
MAINTAINER命令
镜像维护者的姓名和邮箱地址[废弃]
语法
MAINTAINER <name>
RUN命令
RUN命令将在当前映像之上的新层中执行任何命令并提交结果,生成的提交映像将用于Dockerfile中的下一步。
语法
RUN<command> # RUN yum install vim
EXPOSE命令
EXPOSE命令 仅仅使声明当前容器中服务端口是谁
语法
EXPOSE 8808
WORKDIR命令
用不为DOCKERfile中任何RUN、CMD、EXPOSE、ADD指令设置工作目录。如果WORKDIR不存在,即使它没有在任何后续Dockfile指令中使用,它也将被创建。
语法
WORKDIR /path/to/workdir 指定原始镜像存在目录, 不存在目录 WORKDIR /a WORKDIR b WORKDIR c 注意:WORKDIR指令可以在Dockerfile中多次使用,如果提供了相对路径,则该路径将与先前WORKDIR指令的路径相对
ENV命令
用来构建镜像设置环境变量,这个值将出现在构建阶段中所有的后续指令的环境中
语法
ENV <KEY> <VALUE> ENV <KEY> = <VALUE> # 声明变量 ENV A = /home # 如何使用变量 WORKDIR $ A
ADD命令
用来从context上下文复制新文件、目录或远程文件url,并将他们添加到位于指定路径的映像文件系统中。
语法
ADD home* /mydir/ 通配符添加多个文件 ADD hom?.txt /mydir/ 通配符添加 ADD test.txt relativeDir/ 可以指定相对路径
CMD &ENTRYPINT作用
作用:都是用来指定容器启动时默认执行指令
注意:CMD指令可以存在多个,但是存在多个只有最后一个生效
使用语法
CMD &ENTRYPOINT
直接命令方式
java -jar ems.jar
json 数组方式
["java", "-jar", "ems.jar"]
Docker自定义项目镜像
- 创建项目
- 开发项目功能,连接配置数据库,代码生成
- 测试项目代码
- 打包项目
- 编写Dockerfile生成项目【核心步骤】
- 运行镜像
现有docker进行项目部署存在问题
一个项目会存在多个容器, 但是每个容器之间存在着启动的依赖关系。
为了完成一个完整的项目势必用到N个容器配合完成项目中业务开发。
容器的编排至关重要
现在这种方式使用容器,没有办法站在项目的角度将一个项目用到一组容器划分到一起,日后难点在于项目多服务器部署
项目角度管理项目用到一组容器
Docker Compose
作用:给容器进行编排,针对多个容器进行编排,单个容器不需要使用它。
简介
compose项目时Docker官方的开源项目,负责实现对Docker容器集群的快速编排,从功能上看,跟Openstack中的Heat十分类似。其代码目前在https://github.com/docker/compose上开源。
compose定位是【定义和运行多个Docker容器的应用】其前身是开源项目FIG。通过介绍,我们知道使用一个
Dockerfile模板文件,可以让用户很方便的定义一个单独的应用容器,然而在日常工作中,经常会配到需要多个容器相互配合来完成某项任务的情况。例如:要实现一个web项目,除了web服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。
compose刚好满足这样的需求,它允许用户通过一个单独的docker-compose.yml模板文件来定义一组相关联的应用容器为一个项目。compose中有两个重要的概念- 服务:一个应用容器,实际上可以包括若干运行相同镜像的容器实例。
- 项目:由一组关联的应用容器组成一个完整业务单元,在
docker-compose.yml文件中定义。
compose的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷的生命周期管理。compose项目有Python编写,实现上调佣了docker服务提供的API来对容器进行管理。因此,只要所操作的平台支持docker api 就可以在其上利用compose来进行编排管理。安装与卸载
在线安装
从官方github release处直接下载编译好的二进制文件即可,
在linux64位系统中直接下载对应的二进制包
$ sudo curl -L <https://github.com/docker/compose/releases/download/1.25.5/docker-compose-`uname> -s`-`uname -m` > /usr/local/bin/docker-compose $ sudo chmod +x /usr/local/bin/docker-compose
离线安装
# 下载 docker-compose 脚本 # 放入/usr/local/bin # sudo chmod +x /usr/local/bin/docker-compose
docker-compose第一案例
创建第一个项目 mkdir ems
在ems目录创建一个docker-compose.yml模板文件
编辑docker-compose.yml模板文件
启动一个容器写法
version:"3.8" # docker-compose版本和docker 的版本关系,必须对应 services: tomcat: image: tomcat:8.0 # 代表使用哪个镜像,类似于docker run的镜像名称 ports: -8080:8080 # 代表宿主机和容器中端口映射,类似于docker run -p参数 多个参数往下增加启动多个容器写法
tomcat和tomcat01是两个不同的容器
version:"3.8" services: tomcat: container_name: tomcat01 # 代表给容器指定一个名称 类似与docker run --name 参数 推荐使用默认名称 不推荐填写这个配置项 image: tomcat:8.0 # 代表使用哪个镜像, 类似于 docker run 指定的镜像名称 ports: # 代表宿主机和容器中端口映射,类似于docker run -p参数 - 8080:8080 tomcat01: image: tomcat:8.0 ports: - 8081:8081 redis: image: redis:5.0.12 ports: - "6379:6379" mysql: image: mysql:5.6 ports: - "3306:3306" environment: # 代表给当前容器启动指定环境,类似于docker run -e MYSQL_ROOT_PASSWORD=ROOT - "MYSQL_ROOT_PASSWORD=root" volumes: # 代表给当前容器和宿主机指定数据卷,类似于 docker run -v 用于数据持久化存储 注意:docker-compose使用绝对路径必须要有文件夹存在,如果不存在要先创建才能使用。 - /root/mysqldata1:/var/lib/mysql - mysqlData: /var/lib/mysql # 也可以使用别名方式, 但要使用mysqlData必须要声明数据卷,下面就是声明 mysqlData volumes: mysqlData: # 声明mysqlData给上面使用, 创建的时候会给加上项目名_mysqlData启动docker-compose一组服务
$ docker-compose up # 执行运行 $ docker-compose down # 清除缓存
docker-compose 支持的全部命令
# 网址: <https://yeasy.gitbook.io/docker_practice/install>build指令
构建
docker build -t centos7. dockerfile
作用:通过docker-compose 在启动容器之前根据dockerfile构建镜像
使用方法
version: "3.8" # 管理一组服务 services: tomcat: image: tomcat:8.0 ports: -"8080:8080" apps: build: ./ # 指定Dockerfile上下文目录【要求项目和docker-compose.yml和Dockerfile文件要在一起】 它会先找当前目录下的Dockerfile文件里的配置文荣执行完成,在执行docker-compose.yml context: ./ # 用来指定Dockerfile上下文目录 dockerfile: Dockerfile # 指定Dockerfile文件名称 ports: - "8081:8081"
Command指令
作用:覆盖容器启动后默认执行的命令
使用方法
version: "3.8" # 管理一组服务 services: tomcat: image: tomcat:8.0 ports: -"8080:8080" apps: build: ./ # 指定Dockerfile上下文目录【要求项目和docker-compose.yml和Dockerfile文件要在一起】 它会先找当前目录下的Dockerfile文件里的配置文荣执行完成,在执行docker-compose.yml context: ./ # 用来指定Dockerfile上下文目录 dockerfile: Dockerfile # 指定Dockerfile文件名称 ports: - "8081:8081" command:["ls"] # 用来覆盖容器启动后默认指令, 类似于docker image run
container_name指令
作用:用来指定docker-compose启动容器名称 【不推荐指定容器名称】
depends_on指令
作用:解决容器的依赖、启动先后的问题
使用方法
version: "3.8" # 管理一组服务 services: tomcat: image: tomcat:8.0 ports: -"8080:8080" apps: build: ./ # 指定Dockerfile上下文目录【要求项目和docker-compose.yml和Dockerfile文件要在一起】 它会先找当前目录下的Dockerfile文件里的配置文荣执行完成,在执行docker-compose.yml context: ./ # 用来指定Dockerfile上下文目录 dockerfile: Dockerfile # 指定Dockerfile文件名称 ports: - "8081:8081" command:["ls"] # 用来覆盖容器启动后默认指令, 类似于docker run image 覆盖的命令 depends_on: -tomcat # 书写依赖的服务 -mysql -redis
environment指令
作用: 用来给容器启动指定环境变量 相当于docker run -e 选项
env指令
作用:用来给容器启动 指定启动文件, 文件里的内容是容器启动时需要使用的指令
像mysql 的MYSQL_ROOT_PASSWORD: root 指令可以写到指定的配置文件里
使用方法
version: "3.8" # 管理一组服务 services: tomcat: image: tomcat:8.0 ports: -"8080:8080" apps: build: ./ # 指定Dockerfile上下文目录【要求项目和docker-compose.yml和Dockerfile文件要在一起】 它会先找当前目录下的Dockerfile文件里的配置文荣执行完成,在执行docker-compose.yml context: ./ # 用来指定Dockerfile上下文目录 dockerfile: Dockerfile # 指定Dockerfile文件名称 ports: - "8081:8081" command:["ls"] # 用来覆盖容器启动后默认指令, 类似于docker run image 覆盖的命令 depends_on: -tomcat # 书写依赖的服务 -mysql -redis mysql: image: mysql:5.6 ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: root env_file: - ./aa.env
expose指令
作用: 用来指定构建惊喜哪个过程中容器暴露的端口号
使用方法
version: "3.8" # 管理一组服务 services: tomcat: image: tomcat:8.0 ports: -"8080:8080" apps: build: ./ # 指定Dockerfile上下文目录【要求项目和docker-compose.yml和Dockerfile文件要在一起】 它会先找当前目录下的Dockerfile文件里的配置文荣执行完成,在执行docker-compose.yml context: ./ # 用来指定Dockerfile上下文目录 dockerfile: Dockerfile # 指定Dockerfile文件名称 ports: - "8081:8081" command:["ls"] # 用来覆盖容器启动后默认指令, 类似于docker run image 覆盖的命令 depends_on: -tomcat # 书写依赖的服务 -mysql -redis mysql: image: mysql:5.6 ports: - "3306:3306" environment: MYSQL_ROOT_PASSWORD: root env_file: - ./aa.env expore: "8080:8080"image指令
作用:用来指定启动容器使用镜像是谁,相当于 docker run image(镜像名)
label指令
作用: 用来添加元信息,给人看的信息
networks指令
作用: 用来指定容器所使用的网桥是什么,需要配合声明使用
使用方法
# 指定使用网桥 networks: -dangdang # 声明网桥名称为dangdang networks: dangdang:ports指令
作用: 用来指定宿主机和容器的映射端口 相当于docker run -p
使用方法
ports: -"3300" -"8080:8080" -"49100:22" -"127.0.0.1:8001:8001"volumes指令
作用: 用来指定容器中目录和宿主机目录的映射 相当于docker run -v
使用方法
# 使用数据卷 volumes: -mysqlData:/var/lib/mysql # 声明别名数据卷 volumes: mysqlData:restart指令
作用: 用来指定docker容器(服务)总是运行 docker run --restart=always
docker-compose 相关指令
docker-compose 命令 项目|项目中某个服务,注意:没有特殊说明时,默认都是对项目操作语法:
docker-compose -f docker-compose.yml 命令 【选项】【服务id】up [重点]
$ docker-compose up # 对整个项目操作 $ docker-compose up 服务id # 对当前docker-compose中对应服务id容器操作- 该命令十分强大,它将尝试自动完成包括构建镜像,重新创建服务,启动服务,并关联服务相关容器的一系列操作。
- 链接的服务都将会被自动启动,除非已经处于运行状态。
- 大部分的时候都可以直接通过该命令来启动一个项目。
- 默认情况下,
docker-compose up启动的容器都在前台,控制台将会同时打印所有容器的数据信息,可以很方便进行调试。 - 当通过
ctrl+c停止命令时,所有容器将会停止。 - 如果使用
docker-compose up -d,将会在后台启动并运行所有的容器,一般推荐生产环境下使用该选项。 - 默认情况下,如果服务容器已经存在,
docker-compose up将会尝试停止容器,然后重新创建(保持使用volumes-from挂载的卷),以保证新启动的服务匹配docker-compose.yml文件的最新内容。
down[重点]
注意:
docker-compose down 关闭所有容器此命令将会停止
up命令所启动的容器,并移除网络$ docker-compose down # 对整个项目操作 $ docker-compose down 服务id # 对服务id操作有效 并移除网络
exec
$ docker-compose exec 服务id bash # 进入容器ps
$ docker-compose ps # 展示所有运行的服务 $ docker-compose ps -qrestart
$ docker-compose restart # 项目服务重启 $ docker-compose restart 服务id # 对指定项目服务重启 $ docker-compose restart -t 20s 服务id # 在指定时间对指定项目服务重启【20秒之后重启服务】rm
$ docker-compose rm # 删除整个项目 $ docker-compose rm 服务id # 删除指定项目服务 # -f $ docker-compose rm -f 服务id # 强制删除 #-v [谨慎使用] $ docker-compose rm -v 服务id # 删除,会把项目的数据卷删除top
$ docker-compose top # 查看整个项目中所有服务容器内运行进程 $ docker-compose top 服务id # 查看某个服务的运行进程unpause
$ docker-compose unpause # 恢复处于暂停状态的服务 $ docker-compose unpause 服务id # 恢复某个服务pause
$ docker-compose pause # 暂停所有服务 $ docker-compose pause 服务id # 暂停某个服务logs
$ docker-compose logs # 查看整个项目日志 $ docker-compose logs 服务id # 查看某个服务的日志 # -f 实时 $ docker-compose -f #实时查看整个项目日志 $docker-compose -f 服务id #实时查看某个服务日志
Docker可视化界面工具
第三方公司开源portainer项目,用来对docker引擎中运行所有容器进行可视化的展示
使用
安装Portainer
$ docker pull portainer/portainer $ docker volume create portainer_data $ docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer $ docker ps浏览器登录
<https://localhost:9000>
Docker报错
- 第一种报错
[root@VM-16-11-centos ~]# docker run -p 6379:6379 redis
docker: Error response from daemon: driver failed programming external connectivity on endpoint awesome_kare (a692caa9c368942329b345dd4aff29e89cb76644e0298847008c26c1c5af3f68): (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 6379 -j DNAT --to-destination 172.17.0.2:6379 ! -i docker0: iptables: No chain/target/match by that name.原因:
# docker容器底层原理:在启动docker的时候会自动在iptables中注册一个链,通过防火墙的链也可以找到其注册的信息,主要注册这些链,是docker的容器为了暴露端口而使用的。
# 具体原因是:删除了iptables中的链
# 删除连接的方式有很多种
# 重启firewalld防火墙即可对其清除,firewalld是centos7以上,iptables是centos6以下都会有,而firewalld的底层是涉及在iptables上的,在启动firewalld的时候会自动删除iptables链的相关链接
# 删除该链接的其他方式博主暂未遇到有特殊情况的,待发现
# 所以在涉及防火墙firewalld的命令或者是iptables中的命令的时候
# 小心删除其涉及docker的链解决方法:
# 重启防火墙,
$ systemctl restart firewalld
# 重启docker
$ systemctl restart docker
# 查询docker的链
$ iptables -L- 第二种报错
$ docker run -it centos
# 执行上面的命令进入到了docker centos容器系统里
# 进入到centos 在执行下面命令时报错
$ yum update
# 报错
Failed to set locale, defaulting to C.UTF-8
CentOS Linux 8 - AppStream 11 B/s | 38 B 00:03
Error: Failed to download metadata for repo 'appstream': Cannot prepare internal mirrorlist: No URLs in mirrorlist解决方案
$ cd /etc/yum.repos.d
$ mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
curl -o /etc/yum.repos.d/CentOS-Base.repo <https://mirrors.aliyun.com/repo/Centos-8.repo>