一篇Docker带你入门爱不释手
1、本博客主要参考尚硅谷的尚硅谷Docker实战教程(docker教程天花板)
视频教程,整理不易,还请读者见谅。
2、尚硅谷的有些视频还不错(PS:不是广告,毕竟看了人家比较好的教程,得给人家打个call)
3、视频地址:尚硅谷Docker实战教程(docker教程天花板)
什么是Docker
Docker是一种由Docker Inc.(以前称为DotCloud)开发的容器虚拟化工具,是一个"轻量级容器类型虚拟化环境"
Docker是基于Go语言实现的云开源项目。
Docker的主要目标是 “Build Ship and Run Any App Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期
的管理,使用户的APP (可以是一个WEB应用或数据库应用等等)及其运行环境能够做到“一次镜像,处处运行”
docker官网:https://www.docker.com/
dockerhud官网:https://hub.docker.com/
docker有什么作用
- 替代虚拟机(VM)
Docker可以在很多情况下替代虚拟机。如果用户只关心应用程序而不是操作系统,可以用Docker替代虚拟机,把操作系统交给其他人去考虑
- 软件原型
如果想快速体验软件,同时避免干扰目前的设置或配备一台虚拟机带来的麻烦,Docker可以在几毫秒内提供一个沙盒环境
- 打包软件
因为对Linux用户而言,Docker镜像实际上没有依赖,所以非常适合用于打包软件。用户可以构建镜像,并确保它可以运行在任何现代Linux机器上——就像Java一样,但不需要JVM
- 让微服务架构成为可能
Docker 有助于将一个复杂系统分解成一系列可组合的部分,这让用户可以用更离散的方式来思考其服务。用户可以在不影响全局的前提下重组软件,使其各部分更易于管理和可插拔
- 启用持续交付
容器和虚拟机有什么区别
- 虚拟机
虚拟机的大小为数GB。在虚拟服务器上运行单个应用程序意味着还要运行Guest OS以及Guest OS运行所需的所有硬件的虚拟副本。这样很快就增加了很多RAM和CPU资源消耗
- 容器
容器只是运行在宿主机上的一种特殊的进程,多个容器之间使用的还是同一个宿主机的操作系统内核。
Docker容器 | 虚拟机(VM) | |
---|---|---|
操作系统 | 与宿主机共享OS | 宿主机OS上运行虚拟机OS |
存储大小 | 镜像小,便于存储与传输 | 镜像庞大(vmdk、vdi等) |
运行性能 | 几乎无额外性能损失 | 操作系统额外的CPU、内存消耗 |
移植性 | 轻便、灵活,适应于Linux | 笨重, 与虚拟化技术耦合度高 |
硬件亲和性 | 面向软件开发者 | 面向硬件运维者 |
部署速度 | 快速,秒级 | 较慢,10s以上 |
docker安装
前提
Docker并非是一个通用的容器工具,它依赖于已存在并运行的Linux内核环境。
Docker实质上是在已经运行的Linux下制造了一个隔离的文件环境,因此它执行的效率几乎等同于所部署的Linux主机。
因此,Docker 必须部署在Linux内核的系统上。如果其他系统想部署Docker就必须安装一个虚拟Linux环境。
安装
- 虚拟机(VMware Workstation Pro16)
- CentOS7 / 阿里云CentOS7镜像下载位置(http://mirrors.aliyun.com/centos/7/isos/x86_64/)
- 官网安装地址 https://docs.docker.com/engine/install/centos/
卸载旧版本
sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine
yun安装gcc相关的
yum -y install gcc&gcc-c++
yum -y install gcc-c++
安装
yum-utils
包
sudo yum install -y yum-utils
设置存储库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装 Docker 引擎
sudo yum -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin
启动
sudo systemctl start docker
测试
docker ps
停止
sudo systemctl start docker
卸载
yum remove docker-ce docker-ce-cli containerd.io
rm -rf /var/lib/docker
rm -rf /var/lib/containerd
docker的基本组成
image文件可以看作是容器的模板。Docker 根据image文件生成容器的实例。同一个image文件,可以生成多个同时运行的容器
实例。
- 镜像(image)
Docker镜像(Image)就是一个只读的模板。镜像可以用来创建Docker容器,个镜像可以创建很多容器
Docker镜像文件类似于Java的类模板,而docker容器实例类似于Java中new出来的实例对象。image 文件生成的容器实例,本身也是一个文件,称为镜像文件。
- 容器(container)
Docker利用容器(Container) 独立运行的一个或-组应用,应用程序或服务运行在容器里面,容器就类似于一个虚拟化的运行环
境,容器是用镜像创建的运行实例。就像是Java中的类和实例对象-样,镜像是静态的定义,容器是镜像运行时的实体。
容器为镜像提供了一个标准的和隔离的运行环境,它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台一个容器运行一种服务,当我们需要的时候,就可以通过docker客户端创建一 个对应的运行实例,也就是我们的容器
- 仓库(repositoy)
就相当于GitHub一样存放各种的Git的项目的地方
仓库分为公开仓库(Public) 和私有仓库(Private) 两种形式,最大的公开仓库是Docker Hub
存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云、网易云等就是放一堆镜像的地方,我们可以把镜像发布到仓库中,需要的时候再从仓库中拉下来就可以了。
阿里云镜像加速器
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<- 'EOF'
{"registry-mirrors": ["https://aa25jngu.mirror.alijuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
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
查看docker命令帮助文档
docker 具体命令-help
镜像命令
列出本地主机上的镜像
docker images
参数
列出本地所有的镜像( -a )
docker images -a
只显示镜像ID ( -q )
docker images -q
组合使用
docker images -aq
[root@rocketmq-node3 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE |
---|
REPOSITORY:表示镜像的仓库源 |
TAG:镜像的标签版本号 |
IMAGE ID:镜像ID |
CREATED: 镜像创建时间 |
SIZE:镜像大小 |
去搜索远程仓库中的这个镜像
docker search 镜像名字
[root@rocketmq-node3 ~]# docker search redis NAME DESCRIPTION STARS OFFICIAL AUTOMATED |
---|
NAME:镜像名称 |
DESCRIPTION:镜像说明 |
STARS:点赞数量 |
OFFICIAL:是否是官方的 |
AUTOMATED:是否是自动构建的 |
参数
只列出N个镜像,默认25个( limit )
docker search --limit 5 redis
下载镜像,同一个仓库源可以有多个tag版本,代表这个仓库源的不同个版本
docker pull 镜像名字
参数
最新的
docker pull mysql = docker pull mysql:latest
指定版本的
docker pull mysql:8.0.27
查看镜像/容器/数据卷所占的空间
docker system df
删除
docker rmi 镜像名字/ID
参数
强制删除 ( -f )
docker rmi -f redis
删除多个
docker rmi -f 镜像名1:TAG 镜像名2:TAG
删除全部
docker rmi -f $(docker images -qa)
容器命令
run的话就是现在本地看一下,如果本地没有就会去到远程仓库进行下载在启动
docker run 镜像名称
参数
为容器指定一个名称 ( --name=“容器新名字” )
docker run mysql --name="mysql8"
后台运行容器并返回容器ID,也即启动守护式容器(后台运行)( -d )
docker run mysql -d
以交互模式运行容器,通常与-t同时使用( -i )
docker run mysql -it 或者 docker run mysql -i
为容器重新分配一个伪输入终端,通常与-i同时使用 也即启动交互式容器(前台有伪终端,等待交互)( -t )
docker run mysql -it 或者 docker run mysql -t
-P:随机端口映射,大写P ( -P )
docker run mysql -P
-p:指定端口映射,小写p( -p )
docker run mysql -p 3306:3306
交互式说明
docker run -it mysql /bin/bash
-i:交互式操作 -t:终端 mysql:mysql镜像 /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式Shell,因此用的是/bin/bash 要退出终端,直接输入exit
列出当前所有正在运行的容器
docker ps
参数(这些参数也是可以组合使用的)
列出当前所有正在运行的容器+历史上运行过的( -a )
docker ps -a
显示最近创建的容器( -l )
docker ps -l
显示最近n个创建的容器( -n )
docker ps -n 2
静默模式, 只显示容器编号( -q )
docker ps -q
退出容器
run进去容器,exit退出, 容器停止
exit
run进去容器,ctrl+p+q退出, 容器不停止
这个是用键盘的,Ctrl+p+q
启动已经停止的容器
docker start 容器ID 或者 容器名
重启容器
docker restart 容器ID 或者 容器名
停止容器
docker stop 容器ID 或者 容器名
强制停止容器
docker kill 容器ID 或 容器名
删除已停止的容器
docker rm 容器ID
强制删除全部
docekr rm -f $(docker ps -aq)
查看容器日志
docker logs 容器ID
查看容器内运行的进程
docker top 容器ID
查看容器内部的细节
docker inspect 容器ID
进入正在运行的容器并以命令交互
重新进入容器
docker attach 容器ID /bin/bash
- attach直接进入容器启动命令的终端,不会启动新的进程
- 用exit退出,会导致容器的停止
进入容器
docker exec -it 容器ID /bin/bash
区别
- exec是在容器中打开新的终端,并且可以启动新的进程
- 用exit退出,不会导致容器的停止
容器拷贝文件到主机
docker cp 容器ID:容器内路径 目的主机路径
导入和导出容器
导出容器的内容留作为一个tar归档文件( export )
docker export 容器ID > 名字.tar
实例
docker export 容器ID > a.tar
导入从tr包中的内容创建- -个新的文件系统再导入为镜像( import )
cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号
实例
cat a.tar | docker import - abc/redis:5.0.14
当前 shell 下 attach 连接指定运行镜像
attach
通过 Dockerfile 定制镜像
build
提交当前容器为新的镜像
commit
创建一个新的容器,同 run,但不启动容器
create
查看 docker 容器变化
diff
从 docker 服务获取容器实时事件
events
展示一个镜像形成历史
history
kill 指定 docker 容器
kill
从一个 tar 包中加载一个镜像[对应 save]
load
注册或者登陆一个 docker 源服务器
login
从当前 Docker registry 退出
logout
查看映射端口对应的容器内部源端口
port
暂停容器
pause
推送指定镜像或者库镜像至docker源服务器
push
重启运行的容器
restart
保存一个镜像为一个 tar 包[对应 load]
save
取消暂停容器
unpause
截取容器停止时的退出状态值
wait
镜像分层的概念
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS
- docker镜像为什么要用采用这种分层的结构
镜像分层最大的一个好处就是共享资源,方便复制迁移,就是为了复用
docker镜像commit操作
commit
docker commit 提交容器副本使之成为一个新的镜像
docker commit 容器ID
docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
实例
docker commit -m="hello commit" -a="dockers" 容器ID hello:1.3
本地镜像发布到阿里云
第一步就是创建一个镜像
第二步就是登录阿里云
- 创建一个命名空间,填写名字,设置私有还是公有
- 创建一个镜像仓库,填写名字,设置私有还是公有,选择好代码源
- 进入管理界面,哪里有自动生成的脚本
在docker中登录
docker login --username=阿里云用户名 registry.cn-hangzhou.aliyuncs.com
docker tag 镜像ID registry.cn-hangzhou.aliyuncs.com/monster/myredis:版本号
docker push registry.cn-hangzhou.aliyuncs.com/monster/myredis:版本号
从阿里云上面拉取我上传的镜像(注意你上传的版本号)
docker pull registry.cn-hangzhou.aliyuncs.com/monster/myredis:版本号
本地镜像发布到私有库
Dockerhub、阿里云这样的公共镜像仓库可能不太方便,涉及机密的公司不可能提供镜像给公网,所以需要创建一个本地私人仓库供给团队使用,基于公司内部项目构建镜像
docker下载 registry
docker pull registry
运行私有库
默认情况,仓库被创建在容器的/var/lib/registry目录下,建议自行用容器卷映射,方便于宿主机联调
docker run --name="registry" -d -p 5000:5000 -v /home/myregistry/:/tmp/registry --privileged=true registry
设置容器自启动
docker update --restart=always registry
验证私有库是否有没有镜像
curl -XGET http://服务器IP:5000/v2/_catalog
如果是这样的,那就是你没有上传过镜像
{"repositories":[]}
修改成符合私服规范的tag
docker tag 镜像:Tag Host:Port/Repository:Tag
实例
docker tag helloredis:1.3 服务器ID:5000/helloredis:1.3
修改docker配置文件
docker默认不允许http方式推送镜像,通过配置选项来取消这个限制,修改完后如果不生效,建议重启docker
vim /etc/docker/daemon.json
默认是 JSON的格式,记得在上一行的末尾加 英文逗号
"insecure-registries": ["服务器IP:5000"]
重启一下,我还是保守一下
systemctl restart docker
推送镜像到私服库
将那个之前符合私服库的镜像推送
docker push 服务器IP:5000/helloredis:1.3
验证是否上传
curl -XGET http://服务器IP:5000/v2/_catalog
拉取私有库的镜像
docker pull 服务器IP:5000/helloredis:1.3
容器数据卷
将运用与运行的环境打包镜像,run后形成容器实例运行 ,但是我们对数据的要求希望是持久化的
Docker容器产生的数据,如果不备份,那么当容器实例删除后,容器内的数据自然也就没有了
为了能保存数据在docker中我们使用卷
介绍特点
- 数据卷可在容器之间共享或重用数据
- 卷中的更改可以直接实时生效,爽
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
docker指令
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像:tag
功能说明
参数
-volumes 缩写 -v
宿主vs容器之间映射添加容器卷
启动一个容器
docker run -it --privileged=true -v /home/docker/ubuntu1:/tmp/docker_data --name="ubuntu1" ubuntu:14.04
跳转到那个挂载的文件夹中
cd /tmp/docker_data
新建文件,随便你输入什么记得保存
vi hello.txt
退出容器,去到宿主机中的挂载文件夹中,并查看
cd /home/docker/ubuntu1
修改宿主机挂载文件夹中的文件,容器中挂载的文件夹,文件也会改变
就算是容器停止了,我们在宿主机挂载文件夹中在次添加或者修改,容器一旦启动,它也会和宿主机保存同步
读写规则映射添加说明
默认就是rw,就是读写
docker run -it --privileged=true -v /home/docker/ubuntu1:/tmp/docker_data --name="ubuntu1" ubuntu:14.04
或者
docker run -it --privileged=true -v /home/docker/ubuntu1:/tmp/docker_data:rw --name="ubuntu1" ubuntu:14.04
设置只能读取,但是不能写
docker run -it --privileged=true -v /home/docker/ubuntu1:/tmp/docker_data:ro --name="ubuntu1" ubuntu:14.04
卷的继承和共享
命令
docker run -it --privileged=true --volumes-from 父类 --name ubuntu2 镜像:tag
- 实例
docker run -it --privileged=true --volumes-from ubuntu1 --name ubuntu2 ubuntu:14.04
测试,可以先去到父类的那个挂载文件夹中查看一下
查看挂载的目录
docker inspect 容器ID
找到 Mounts
"Mounts": [{"Type": "bind","Source": "/home/docker/ubuntu1", // 挂载宿主机的目录"Destination": "/tmp/docker_data", // 挂载容器里目录"Mode": "","RW": true,"Propagation": "rprivate"}],
docker常用安装
基本步骤
- 搜索镜像
- 拉取镜像
- 查看镜像
- 启动镜像
- 服务端映射
- 停止容器
- 移除容器
安装Tomcat9.0
docker hub上面查找tomcat镜像
docker search tomcat
拉取tomcat
docker pull tomcat:9.0
运行tomcat9.0
docker run -d -p 8080:8080 --name="tomcat9.0" tomcat:9.0
去到容器内部
docker exec -it 容器ID /bin/bash
删除文件夹
rm -rf webapps
修改文件夹
mv webapps.dist webapps
访问,可以不做以上两部,但是出现的会是404但是也没有问题,做了这两部可以看到一只猫的
服务器IP:8080
停止tomcat
docker stop tomcat9.0
删除tomcat
docker rm tomcat9.0
一步到位
docker rm -f tomcat9.0
安装MySQL5.7
去到dockerHud(https://hub.docker.com/)上传搜索
拉取和直接跑MySQL5.7版本的,并且挂载目录
docker run -d -p 3306:3306 --privileged=true \
-v /home/docker/mysql/log:/var/log/mysql \
-v /home/docker/mysql/data:/var/lib/mysql \
-v /home/docker/mysql/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 --name mysql5.7 mysql:5.7
添加配置文件
cd /home/docker/mysql/conf
添加配置文件
vim my.cnf
将配置copy进去
[client]
default_character_set=utf8
[mysqld]
collation_server = utf8_general_ci
character_set_server = utf8
lower_case_table_names= 1
max_allowed_packet=1024M
sql_mode="ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"
[client]
default_character_set=utf8
[mysqld]
collation_server = utf8_general_ci
character_set_server = utf8
lower_case_table_names= 1
max_allowed_packet=1024M
sql_mode="ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"重启MySQL
docker restart mysql5.7
进入MySQL5.7容器实例
docker exec -it mysql5.7 /bin/bash
登录MySQL5.7
mysql -u root -p123456
查看MySQL5.7的字符集
SHOW VARIABLES LIKE 'character%';
远程连接
- 首先打开将服务器的对应端口放开或者安全组放行
- 要知道服务器的IP地址
如果把MySQL5.7容器删除了,数据是否还存在
- 还是在的
安装Redis6.0.8
还是去到dockerhud上查看
拉取redis6.0.8
docker pull redis6.0.8
添加配置文件和文件夹
mkdir /home/docker/redis
cd /home/docker/redis
vim redis.conf
去找一个redis配置文件放在,/home/docker/redis目录下
复制我的配置文件
bind 0.0.0.0protected-mode no# 端口号 port 6379tcp-backlog 511timeout 0tcp-keepalive 300loglevel noticelogfile ""databases 16# 设置密码 requirepass 123456789always-show-logo yessave 900 1save 300 10save 60 10000stop-writes-on-bgsave-error yesrdbcompression yesrdbchecksum yesdbfilename dump6379.rdbdir ./replica-serve-stale-data yesreplica-read-only yesrepl-diskless-sync norepl-diskless-sync-delay 5repl-disable-tcp-nodelay noreplica-priority 100lazyfree-lazy-eviction nolazyfree-lazy-expire nolazyfree-lazy-server-del noreplica-lazy-flush noappendonly noappendfilename "appendonly.aof"appendfsync everysecno-appendfsync-on-rewrite noauto-aof-rewrite-percentage 100auto-aof-rewrite-min-size 64mbaof-load-truncated yesaof-use-rdb-preamble yeslua-time-limit 5000slowlog-log-slower-than 10000slowlog-max-len 128latency-monitor-threshold 0notify-keyspace-events ""hash-max-ziplist-entries 512hash-max-ziplist-value 64list-max-ziplist-size -2list-compress-depth 0set-max-intset-entries 512zset-max-ziplist-entries 128zset-max-ziplist-value 64hll-sparse-max-bytes 3000stream-node-max-bytes 4096stream-node-max-entries 100activerehashing yesclient-output-buffer-limit normal 0 0 0client-output-buffer-limit replica 256mb 64mb 60client-output-buffer-limit pubsub 32mb 8mb 60hz 10dynamic-hz yesaof-rewrite-incremental-fsync yesrdb-save-incremental-fsync yes
启动并且挂载
docker run -d -p 6379:6379 --privileged=true \
-v /home/docker/redis/redis.conf:/etc/redis/redis.conf \
-v /home/docker/data:/data \
--name redis6.0.8 redis:6.0.8 redis-server /etc/redis/redis.conf
进入容器
docker exec -it redis6.0.8 /bin/bash
启动客户端
redis-cli
登录redis,因为设置密码了
auth 123456789
使用命令
set key1 value1
get key1
远程连接,和MySQL差不多
MySQL主从复制
主
run一个MySQL5.7容器
docker run -d -p 3307:3306 --privileged=true \
-v /home/docker/mysql-master/log:/var/log/mysql \
-v /home/docker/mysql-master/data:/var/lib/mysql \
-v /home/docker/mysql-master/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 --name mysql5.7-master mysql:5.7
编写配置文件
cd /home/docker/mysql-master/conf
复制并copy
vim my.cnf
[mysqld]
## 设置端口号
port = 3307
## 设置server_id,同一局域网中需要唯一
server_id=101
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能
log-bin=mall-mysql-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
重启MySQL5.7,因为修改了配置文件
docker restart mysql5.7-master
登录MySQL5.7
docker exec -it mysql5.7-master /bin/bash
mysql -u root -p123456
授权可以给可以同步的用户
CREATE USER 'slave' @'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave' @'%';
查看状态
show master status;
从
run一个MySQL5.7容器
docker run -d -p 3308:3306 --privileged=true \
-v /home/docker/mysql-slave/log:/var/log/mysql \
-v /home/docker/mysql-slave/data:/var/lib/mysql \
-v /home/docker/mysql-slave/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 --name mysql5.7-slave mysql:5.7
进入文件夹,新建文件,copy配置
cd /home/docker/mysql-slave/conf
vim my.cnf
[mysqld]
## 设置端口号
port = 3308
## 设置server_id,同一局域网中需要唯一
server_id=102
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能,以备Slave作为其它数据库实例的Master时使用
log-bin=mall-mysql-slave1-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
expire_logs_days=7
## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。
## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致
slave_skip_errors=1062
## relay_log配置中继日志
relay_log=mall-mysql-relay-bin
## log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1
## slave设置为只读(具有super权限的用户除外)
read_only=1
重启
docker restart mysql5.7-slave
进入容器,并且登录
docker exec -it mysql5.7-slave /bin/bash
mysql -u root -p123456
配置主从
change master to master_host='宿主机ip', master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-bin.000003', master_log_pos=774, master_connect_retry=30;
查看主从状态
show slave status \G
- 参数说明
master_host:主数据库的IP地址;
master_port:主数据库的运行端口;
master_user:在主数据库创建的用于同步数据的用户账号;
master_password:在主数据库创建的用于同步数据的用户密码;
master_log_file:指定从数据库要复制数据的日志文件,通过查看主数据的状态,获取File参数;
master_log_pos:指定从数据库从哪个位置开始复制数据,通过查看主数据的状态,获取Position参数;
master_connect_retry:连接失败重试的时间间隔,单位为秒。
在从库开始主从配置
start slave;
Redis集群
3主3从redis集群配置
启动
启动六个服务之后,记得查看一下容器是否存在
docker run -d --name redis-node-1 --net host --privileged=true -v /data/redis/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381docker run -d --name redis-node-2 --net host --privileged=true -v /data/redis/share/redis-node-2:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382docker run -d --name redis-node-3 --net host --privileged=true -v /data/redis/share/redis-node-3:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383docker run -d --name redis-node-4 --net host --privileged=true -v /data/redis/share/redis-node-4:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384docker run -d --name redis-node-5 --net host --privileged=true -v /data/redis/share/redis-node-5:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385docker run -d --name redis-node-6 --net host --privileged=true -v /data/redis/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386
- 参数详解
docker run | 创建并运行docker容器实例 |
---|---|
–name redis-node-6 | 容器名字 |
–net host | 使用宿主机的IP和端口,默认 |
–privileged=true | 获取宿主机root用户权限 |
-v /data/redis/share/redis-node-6:/data | 容器卷,宿主机地址:docker内部地址 |
redis:6.0.8 | redis镜像和版本号 |
–cluster enabled yes | 开启redis集群 |
–appendonly yes | 开启持久化 |
–port 6386 | redis端口号 |
配置主从关系
进入容器
docker exec -it redis-node-1 /bin/bash
进入docker容器后才能执行一下命令,且注意自己的真实IP地址(192.168.56.102)
redis-cli --cluster create 192.168.56.102:6381 192.168.56.102:6382 192.168.56.102:6383 192.168.56.102:6384 192.168.56.102:6385 192.168.56.102:6386 --cluster-replicas 1# --cluster-replicas 1 表示为每个master创建一个slave节点
输入 yes,如果没有看到 绿色的ok,那应该是出现问题了,先看一下是不是你的 IP出现问题了
查看节点状态
如果我们没有退出刚刚的容器,就直接使用以下的命令
redis-cli -p 6381
集群信息
cluster info
127.0.0.1:6381> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:1
cluster_stats_messages_ping_sent:258
cluster_stats_messages_pong_sent:265
cluster_stats_messages_sent:523
cluster_stats_messages_ping_received:260
cluster_stats_messages_pong_received:258
cluster_stats_messages_meet_received:5
cluster_stats_messages_received:523
集群节点
cluster nodes
127.0.0.1:6381> cluster nodes
7aca3c351f34327c9d1c77ee002028ae657a7f82 192.168.56.102:6385@16385 slave cc5320a4018ccdcf11c31877ef99103744263077 0 1663489028185 1 connected
00b616f9afed040fdba4553e1f8d74e69313809c 192.168.56.102:6382@16382 master - 0 1663489027000 2 connected 5461-10922
cc5320a4018ccdcf11c31877ef99103744263077 192.168.56.102:6381@16381 myself,master - 0 1663489025000 1 connected 0-5460
837b33de6cb66cad9549a83803c14afaf6e9455a 192.168.56.102:6384@16384 slave 503f8fb4bcdc095938b6f33cce6f709428a71939 0 1663489026000 3 connected
503f8fb4bcdc095938b6f33cce6f709428a71939 192.168.56.102:6383@16383 master - 0 1663489024000 3 connected 10923-16383
76cc1acba168a91b33b1f3ec7825552233eb7001 192.168.56.102:6386@16386 slave 00b616f9afed040fdba4553e1f8d74e69313809c 0 1663489027183 2 connected
如果在写入的时候出现了这个错误
127.0.0.1:6381> set key1 value1
(error) MOVED 9189 192.168.56.102:6382
重新输入命令,在启动时加入 -c 来启动集群模式
exit
redis-cli -c -p 6381
查看集群,输入你的IP地址,而不是我的
redis-cli --cluster check 192.168.56.102:6381
root@rocketmq-node3:/data# redis-cli --cluster check 192.168.56.102:6381
192.168.56.102:6381 (cc5320a4...) -> 0 keys | 5461 slots | 1 slaves.
192.168.56.102:6382 (00b616f9...) -> 1 keys | 5462 slots | 1 slaves.
192.168.56.102:6383 (503f8fb4...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 1 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.56.102:6381)
M: cc5320a4018ccdcf11c31877ef99103744263077 192.168.56.102:6381slots:[0-5460] (5461 slots) master1 additional replica(s)
S: 7aca3c351f34327c9d1c77ee002028ae657a7f82 192.168.56.102:6385slots: (0 slots) slavereplicates cc5320a4018ccdcf11c31877ef99103744263077
M: 00b616f9afed040fdba4553e1f8d74e69313809c 192.168.56.102:6382slots:[5461-10922] (5462 slots) master1 additional replica(s)
S: 837b33de6cb66cad9549a83803c14afaf6e9455a 192.168.56.102:6384slots: (0 slots) slavereplicates 503f8fb4bcdc095938b6f33cce6f709428a71939
M: 503f8fb4bcdc095938b6f33cce6f709428a71939 192.168.56.102:6383slots:[10923-16383] (5461 slots) master1 additional replica(s)
S: 76cc1acba168a91b33b1f3ec7825552233eb7001 192.168.56.102:6386slots: (0 slots) slavereplicates 00b616f9afed040fdba4553e1f8d74e69313809c
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
主从容错切换迁移
先停止一下容器,然后在等一下,因为会发送心跳
docker stop redis-node-1
进入容器
docker exec -it redis-node-2 /bin/bash
redis-cli -c -p 6382
查看容器信息
cluster nodes
在让之前那一台启动
docker start redis-node-1
回来之后,发现 node-1 不是主,而是从
cluster nodes
主从扩容
新增两个redis
docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/share/redis-node-7:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6387docker run -d --name redis-node-8 --net host --privileged=true -v /data/redis/share/redis-node-8:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6388
进入容器
docker exec -it redis-node-7 /bin/bash
将新增的6387作为master节点加入集群
redis-cli --cluster add-node 自己实际IP地址:6387 自己实际IP地址:6381
实例
redis-cli --cluster add-node 192.168.56.102:6387 192.168.56.102:6381
说明
6387 就是将要作为master新增节点
6381 就是原来集群节点里面的领路人,相当于6387拜拜6381的码头从而找到组织加入集群
查看集群情况
redis-cli --cluster check 192.168.56.102:6381
root@rocketmq-node3:/data# redis-cli --cluster check 192.168.56.102:6381
192.168.56.102:6382 (00b616f9...) -> 1 keys | 5462 slots | 1 slaves.
192.168.56.102:6385 (7aca3c35...) -> 0 keys | 5461 slots | 1 slaves.
192.168.56.102:6387 (d6232596...) -> 0 keys | 0 slots | 0 slaves.
192.168.56.102:6383 (503f8fb4...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 1 keys in 4 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.56.102:6381)
S: cc5320a4018ccdcf11c31877ef99103744263077 192.168.56.102:6381slots: (0 slots) slavereplicates 7aca3c351f34327c9d1c77ee002028ae657a7f82
S: 76cc1acba168a91b33b1f3ec7825552233eb7001 192.168.56.102:6386slots: (0 slots) slavereplicates 00b616f9afed040fdba4553e1f8d74e69313809c
M: 00b616f9afed040fdba4553e1f8d74e69313809c 192.168.56.102:6382slots:[5461-10922] (5462 slots) master1 additional replica(s)
M: 7aca3c351f34327c9d1c77ee002028ae657a7f82 192.168.56.102:6385slots:[0-5460] (5461 slots) master1 additional replica(s)
M: d6232596bd20c15c3513603c83c5653105221ad8 192.168.56.102:6387slots: (0 slots) master
M: 503f8fb4bcdc095938b6f33cce6f709428a71939 192.168.56.102:6383slots:[10923-16383] (5461 slots) master1 additional replica(s)
S: 837b33de6cb66cad9549a83803c14afaf6e9455a 192.168.56.102:6384slots: (0 slots) slavereplicates 503f8fb4bcdc095938b6f33cce6f709428a71939
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
发现加入的没有槽位
192.168.56.102:6387 (d6232596...) -> 0 keys | 0 slots | 0 slaves.
重新分配槽位
redis-cli --cluster reshard 192.168.56.102:6381
第一个参数填写的是:16384/master总数
第二个参数填写的是:RedisID(d6232596bd20c15c3513603c83c5653105221ad8)
第三个参数填写的是:all
然后这个分配的是,每个master节点都分一点给这个的
给新的,添加一个从
redis-cli --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id 新主机节点ID
实例
redis-cli --cluster add-node 192.168.56.102:6388 192.168.56.102:6387 --cluster-slave --cluster-master-id d6232596bd20c15c3513603c83c5653105221ad8
- 说明
- d6232596bd20c15c3513603c83c5653105221ad8 == 这个是6387的编号(RedisID)
查看集群情况
redis-cli --cluster check 192.168.56.102:6382
root@rocketmq-node3:/data# redis-cli --cluster check 192.168.56.102:6382
192.168.56.102:6382 (00b616f9...) -> 1 keys | 4096 slots | 1 slaves.
192.168.56.102:6387 (d6232596...) -> 0 keys | 4096 slots | 1 slaves.
192.168.56.102:6385 (7aca3c35...) -> 0 keys | 4096 slots | 1 slaves.
192.168.56.102:6383 (503f8fb4...) -> 0 keys | 4096 slots | 1 slaves.
[OK] 1 keys in 4 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.56.102:6382)
M: 00b616f9afed040fdba4553e1f8d74e69313809c 192.168.56.102:6382slots:[6827-10922] (4096 slots) master1 additional replica(s)
S: cc5320a4018ccdcf11c31877ef99103744263077 192.168.56.102:6381slots: (0 slots) slavereplicates 7aca3c351f34327c9d1c77ee002028ae657a7f82
S: d9748596d99ebfd5380c1ae25f905722c8c938db 192.168.56.102:6388slots: (0 slots) slavereplicates d6232596bd20c15c3513603c83c5653105221ad8
M: d6232596bd20c15c3513603c83c5653105221ad8 192.168.56.102:6387slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master1 additional replica(s)
M: 7aca3c351f34327c9d1c77ee002028ae657a7f82 192.168.56.102:6385slots:[1365-5460] (4096 slots) master1 additional replica(s)
S: 76cc1acba168a91b33b1f3ec7825552233eb7001 192.168.56.102:6386slots: (0 slots) slavereplicates 00b616f9afed040fdba4553e1f8d74e69313809c
S: 837b33de6cb66cad9549a83803c14afaf6e9455a 192.168.56.102:6384slots: (0 slots) slavereplicates 503f8fb4bcdc095938b6f33cce6f709428a71939
M: 503f8fb4bcdc095938b6f33cce6f709428a71939 192.168.56.102:6383slots:[12288-16383] (4096 slots) master1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
主从缩容
检查集群情况1获得6388的节点ID
redis-cli --cluster check 192.168.56.102:6382
root@rocketmq-node3:/data# redis-cli --cluster check 192.168.56.102:6382
192.168.56.102:6382 (00b616f9...) -> 1 keys | 4096 slots | 1 slaves.
192.168.56.102:6387 (d6232596...) -> 0 keys | 4096 slots | 1 slaves.
192.168.56.102:6385 (7aca3c35...) -> 0 keys | 4096 slots | 1 slaves.
192.168.56.102:6383 (503f8fb4...) -> 0 keys | 4096 slots | 1 slaves.
[OK] 1 keys in 4 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.56.102:6382)
M: 00b616f9afed040fdba4553e1f8d74e69313809c 192.168.56.102:6382slots:[6827-10922] (4096 slots) master1 additional replica(s)
S: cc5320a4018ccdcf11c31877ef99103744263077 192.168.56.102:6381slots: (0 slots) slavereplicates 7aca3c351f34327c9d1c77ee002028ae657a7f82
S: d9748596d99ebfd5380c1ae25f905722c8c938db 192.168.56.102:6388slots: (0 slots) slavereplicates d6232596bd20c15c3513603c83c5653105221ad8
M: d6232596bd20c15c3513603c83c5653105221ad8 192.168.56.102:6387slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master1 additional replica(s)
M: 7aca3c351f34327c9d1c77ee002028ae657a7f82 192.168.56.102:6385slots:[1365-5460] (4096 slots) master1 additional replica(s)
S: 76cc1acba168a91b33b1f3ec7825552233eb7001 192.168.56.102:6386slots: (0 slots) slavereplicates 00b616f9afed040fdba4553e1f8d74e69313809c
S: 837b33de6cb66cad9549a83803c14afaf6e9455a 192.168.56.102:6384slots: (0 slots) slavereplicates 503f8fb4bcdc095938b6f33cce6f709428a71939
M: 503f8fb4bcdc095938b6f33cce6f709428a71939 192.168.56.102:6383slots:[12288-16383] (4096 slots) master1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
redis-cli --cluster del-node ip:从机端口 从机6388节点ID
redis-cli --cluster del-node 192.168.56.102:6388 d9748596d99ebfd5380c1ae25f905722c8c938db
查看
redis-cli --cluster check 192.168.56.102:6382
root@rocketmq-node3:/data# redis-cli --cluster check 192.168.56.102:6382
192.168.56.102:6382 (00b616f9...) -> 1 keys | 4096 slots | 1 slaves.
192.168.56.102:6387 (d6232596...) -> 0 keys | 4096 slots | 0 slaves.
192.168.56.102:6385 (7aca3c35...) -> 0 keys | 4096 slots | 1 slaves.
192.168.56.102:6383 (503f8fb4...) -> 0 keys | 4096 slots | 1 slaves.
[OK] 1 keys in 4 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.56.102:6382)
M: 00b616f9afed040fdba4553e1f8d74e69313809c 192.168.56.102:6382slots:[6827-10922] (4096 slots) master1 additional replica(s)
S: cc5320a4018ccdcf11c31877ef99103744263077 192.168.56.102:6381slots: (0 slots) slavereplicates 7aca3c351f34327c9d1c77ee002028ae657a7f82
M: d6232596bd20c15c3513603c83c5653105221ad8 192.168.56.102:6387slots:[0-1364],[5461-6826],[10923-12287] (4096 slots) master
M: 7aca3c351f34327c9d1c77ee002028ae657a7f82 192.168.56.102:6385slots:[1365-5460] (4096 slots) master1 additional replica(s)
S: 76cc1acba168a91b33b1f3ec7825552233eb7001 192.168.56.102:6386slots: (0 slots) slavereplicates 00b616f9afed040fdba4553e1f8d74e69313809c
S: 837b33de6cb66cad9549a83803c14afaf6e9455a 192.168.56.102:6384slots: (0 slots) slavereplicates 503f8fb4bcdc095938b6f33cce6f709428a71939
M: 503f8fb4bcdc095938b6f33cce6f709428a71939 192.168.56.102:6383slots:[12288-16383] (4096 slots) master1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
重新分配槽位
redis-cli --cluster reshard 192.168.56.102:6381
第一个填写:4096
第二个填写:7aca3c351f34327c9d1c77ee002028ae657a7f82(接收的master的节点ID)
第三个填写:d6232596bd20c15c3513603c83c5653105221ad8(6387那个的)
第四个填写:done
第五个填写:yes
再次查看
redis-cli --cluster check 192.168.56.102:6382
root@rocketmq-node3:/data# redis-cli --cluster check 192.168.56.102:6382
192.168.56.102:6382 (00b616f9...) -> 1 keys | 4096 slots | 1 slaves.
192.168.56.102:6387 (d6232596...) -> 0 keys | 0 slots | 0 slaves.
192.168.56.102:6385 (7aca3c35...) -> 0 keys | 8192 slots | 1 slaves.
192.168.56.102:6383 (503f8fb4...) -> 0 keys | 4096 slots | 1 slaves.
[OK] 1 keys in 4 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.56.102:6382)
M: 00b616f9afed040fdba4553e1f8d74e69313809c 192.168.56.102:6382slots:[6827-10922] (4096 slots) master1 additional replica(s)
S: cc5320a4018ccdcf11c31877ef99103744263077 192.168.56.102:6381slots: (0 slots) slavereplicates 7aca3c351f34327c9d1c77ee002028ae657a7f82
M: d6232596bd20c15c3513603c83c5653105221ad8 192.168.56.102:6387slots: (0 slots) master
M: 7aca3c351f34327c9d1c77ee002028ae657a7f82 192.168.56.102:6385slots:[0-6826],[10923-12287] (8192 slots) master1 additional replica(s)
S: 76cc1acba168a91b33b1f3ec7825552233eb7001 192.168.56.102:6386slots: (0 slots) slavereplicates 00b616f9afed040fdba4553e1f8d74e69313809c
S: 837b33de6cb66cad9549a83803c14afaf6e9455a 192.168.56.102:6384slots: (0 slots) slavereplicates 503f8fb4bcdc095938b6f33cce6f709428a71939
M: 503f8fb4bcdc095938b6f33cce6f709428a71939 192.168.56.102:6383slots:[12288-16383] (4096 slots) master1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
192.168.56.102:6387 (d6232596…) -> 0 keys | 0 slots | 0 slaves. 为空了
删除 6387节点
命令:redis-cli --cluster del-node ip:端口 6387节点ID
redis-cli --cluster del-node 192.168.56.102:6387 d6232596bd20c15c3513603c83c5653105221ad8
再次查看
redis-cli --cluster check 192.168.56.102:6382
root@rocketmq-node3:/data# redis-cli --cluster check 192.168.56.102:6382
192.168.56.102:6382 (00b616f9...) -> 1 keys | 4096 slots | 1 slaves.
192.168.56.102:6385 (7aca3c35...) -> 0 keys | 8192 slots | 1 slaves.
192.168.56.102:6383 (503f8fb4...) -> 0 keys | 4096 slots | 1 slaves.
[OK] 1 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.56.102:6382)
M: 00b616f9afed040fdba4553e1f8d74e69313809c 192.168.56.102:6382slots:[6827-10922] (4096 slots) master1 additional replica(s)
S: cc5320a4018ccdcf11c31877ef99103744263077 192.168.56.102:6381slots: (0 slots) slavereplicates 7aca3c351f34327c9d1c77ee002028ae657a7f82
M: 7aca3c351f34327c9d1c77ee002028ae657a7f82 192.168.56.102:6385slots:[0-6826],[10923-12287] (8192 slots) master1 additional replica(s)
S: 76cc1acba168a91b33b1f3ec7825552233eb7001 192.168.56.102:6386slots: (0 slots) slavereplicates 00b616f9afed040fdba4553e1f8d74e69313809c
S: 837b33de6cb66cad9549a83803c14afaf6e9455a 192.168.56.102:6384slots: (0 slots) slavereplicates 503f8fb4bcdc095938b6f33cce6f709428a71939
M: 503f8fb4bcdc095938b6f33cce6f709428a71939 192.168.56.102:6383slots:[12288-16383] (4096 slots) master1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
又成为了三主三从
DockerFile
Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜 像所需的指令和参数构成的脚本
- 构建三步骤
- 编写Dockerfile文件
- docker build命令构建镜像
- docker run依镜像运行容器实例
DockerFile官网 -> https://docs.docker.com/engine/reference/builder/
DockerFile构建过程解析
- Dockerfile内容基础知识
- 每条保留字指令都必须为大写字母且后面要跟随至少-个参数
- 指令按照从上到下,顺序执行
- #表示注释
- 每条指令都会创建一个新的镜像层并对镜像进行提交
- Docker执行Dockerfile的大致流程
- docker从基础镜像运行一个容器
- 执行一 条指令并对容器作出修改
- 执行类似docker commit的操作提交-个新的镜像层
- docker再基 于刚提交的镜像运行一-个新容器
- 执行dockerfile中的下一 条指令直到所有指令都执行完成
从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,
* Dockerfile是软件的原材料
* Docker镜像是软件的交付品
* Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。
- Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;
- Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时会真正开始提供服务;
- Docker容器,容器是直接提供服务的。
DockerFile常用保留字指令
FROM
- 基础镜像,当前新镜像是基于哪个镜像的,指定一一个已经存在的镜像作为模板,第一条必须是from
MAINTAINEF
- 镜像维护者的姓名和邮箱地址
RUN
容器构建时需要运行的命令
RUN是在docker build时运行
两种格式
exec格式
RUN ["可执行文件”,"参数1", “参数2"] #例如: # RUN ["./test. php","dev","offline"] 等价于RUN ./test. php dev offline
shell格式
RUN <命令行命令> # <命令行命令>等同于,在终端操作的shell命令
EXPOSE
- 当前容器对外暴 露出的端口
WORKDIR
- 指定在创建容器后,终端默认登陆的进来工作目录,-个落脚点
USER
- 指定该镜像以什么样的用户去执行,如果都不指定,默认是root
ENV
用来在构建镜像过程中设置环境变量
ENV MY_PATH /usr/mytest这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;也可以在其它指令中直接使用这些环境变量,比如:WORKDIR $MY_PATH
ADD
- 将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包
COPY
- 类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置
COPY src dest
COPY [“src”, “dest”]
<src源路径>:源文件或者源目录
<dest目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建
- 类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置
VOLUME
- 容器数据卷,用于数据保存和持久化工作
CMD
指定容器启动后的要干的事情
注意
- Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换
- 命令是有覆盖性的
它和前面RUN命令的区别
CMD是在docker run时运行。
RUN是在docker build时运行。
ENTRYPOINT
也是用来指定一个容器启动时要运行的命令
类似于CMD指令,但是ENTRYPOINT不会被docker run后面的命令覆盖,而且这些命令行参数会被当作参数送给ENTRYPOINT指令指定的程序
命令:
命令格式:ENTRYPOINT ["<executeable>" , "<param1>" , "<param2>",...]
ENTRYPOINT可以和CMD一起用,一般是变参才会使用CMD,这里的CMD等于是在给ENTRYPOINT传参。 当指定了ENTRYPOINT后,CMD的含义就发生了变化,不再是直接运行其命令而是将CMD的内容作为参数传递给 ENTRYPOINT指令,他两个组合会变成x<ENTRYPOINT> "<CMD>"
优点,在执行docker run的时候可以指定ENTRYPOINT运行所需的参数。
注意,如果Dockerfile中如果存在多个ENTRYPOINT指令,仅最后一个生效。
BUILD | Both | RUN |
---|---|---|
FROM | WORKDIR | CMD |
MAINTAINER | USER | ENV |
COPY | EXPOSE | |
ADD | VOLUME | |
RUN | ENTRYPOINT | |
ONBULLD | ||
.dockerignore |
DockerFile案例
自定义镜像 myCentos7java8
要求
- Centos7镜像 具备 vim + ifconfig + jdk8
- JDK的下载镜像地址
- 官网:https://www.oracle.com/java/technologies/downloads/#java8
- https://mirrors.yangxingzhen.com/jdk/
编写
下载镜像
docker pull centos:7
下载jdk
# 新建文件夹 mkdir mydockerfile#进入文件夹 cd /mydockerfile# 下载 wget https://mirrors.yangxingzhen.com/jdk/jdk-8u171-linux-x64.tar.gz
在mydockerfile文件夹下 准备编写Dockerfile文件,注意大写字母D
新建文件
vim Dockerfile
编写Dockerfile
FROM centos:7 MAINTAINER youname<youemaill@126.com>ENV MYPATH /usr/local WORKDIR $MYPATH#安装vim编辑器 RUN yum -y install vim #安装ifconfig命令查看网络IP RUN yum -y install net-tools #安装java8及lib库 RUN yum -y install glibc.i686 RUN mkdir /usr/local/java #ADD 是相对路径jar,把jdk-8u171-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置 ADD jdk-8u171-linux-x64.tar.gz /usr/local/java/ #配置java环境变量 ENV JAVA_HOME /usr/local/java/jdk1.8.0_171 ENV JRE_HOME $JAVA_HOME/jre ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH ENV PATH $JAVA_HOME/bin:$PATHEXPOSE 80CMD echo $MYPATH CMD echo "success--------------ok" CMD /bin/bash
文件同级
[root@izwz9h3jjs3azrqaqdw90gz mydockerfile]# ll total 186428 -rw-r--r-- 1 root root 190890122 Sep 5 14:58 jdk-8u171-linux-x64.tar.gz -rw-r--r-- 1 root root 744 Sep 20 17:38 Dockerfile
构建
- docker build -t 新镜像名字:TAG .
docker build -t centosjava8:1.5 .
查看
[root@izwz9h3jjs3azrqaqdw90gz mydockerfile]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centosjava8 1.5 ca66485f12e1 32 seconds ago 920MB mysql 8.0.28 f2ad9f23df82 5 months ago 521MB tomcat 9.0 b8e65a4d736d 9 months ago 680MB redis 5.0.14 c5da061a611a 9 months ago 110MB mysql 5.7 c20987f18b13 9 months ago 448MB registry latest b8604a3fe854 10 months ago 26.2MB centos 7 eeb6ee3f44bd 12 months ago 204MB ubuntu 14.04 13b66b487594 18 months ago 196MB
运行 centosjava8镜像
docker run -it 镜像ID /bin/bash
发现可以使用 vim 和 config
虚悬镜像
一仓库名、 标签都是的镜像,俗称dangling image,这本来就是一种缺陷
- 新建文件夹和Dockerfile
#
mkdir test#
cd test#
vim Dockerfile
- 编写Dockerfile
FROM centos:7
CMD echo ' action is success'
- 执行
docker build .
- 查看 docker images
[root@izwz9h3jjs3azrqaqdw90gz test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 4eff1f01c448 19 seconds ago 204MB
centosjava8 1.5 ca66485f12e1 23 minutes ago 920MB
coturn latest 9d82e3d4f50a 5 weeks ago 220MB
mysql 8.0.28 f2ad9f23df82 5 months ago 521MB
tomcat 9.0 b8e65a4d736d 9 months ago 680MB
redis 5.0.14 c5da061a611a 9 months ago 110MB
mysql 5.7 c20987f18b13 9 months ago 448MB
coturn/coturn latest 8403619f32d4 9 months ago 135MB
registry latest b8604a3fe854 10 months ago 26.2MB
centos 7 eeb6ee3f44bd 12 months ago 204MB
ubuntu 14.04 13b66b487594 18 months ago 196MB
- 查看docker的虚悬镜像
docker image ls -f dangling=true
[root@izwz9h3jjs3azrqaqdw90gz test]# docker image ls -f dangling=true
REPOSITORY TAG IMAGE ID CREATED SIZE
<none> <none> 4eff1f01c448 About a minute ago 204MB
- 删除虚悬镜像
虚悬镜像已经失去存在价值,可以删除
docker image prune
[root@izwz9h3jjs3azrqaqdw90gz test]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centosjava8 1.5 ca66485f12e1 25 minutes ago 920MB
coturn latest 9d82e3d4f50a 5 weeks ago 220MB
mysql 8.0.28 f2ad9f23df82 5 months ago 521MB
tomcat 9.0 b8e65a4d736d 9 months ago 680MB
redis 5.0.14 c5da061a611a 9 months ago 110MB
mysql 5.7 c20987f18b13 9 months ago 448MB
coturn/coturn latest 8403619f32d4 9 months ago 135MB
registry latest b8604a3fe854 10 months ago 26.2MB
centos 7 eeb6ee3f44bd 12 months ago 204MB
ubuntu 14.04 13b66b487594 18 months ago 196MB
Docker实战Jar
Dockerfile发布Jar到docker容器中
- 先把一个Java应用打包成 Jar包
- 上传到服务器上面
[root@izwz9h3jjs3azrqaqdw90gz software]# ll
-rw-r--r-- 1 root root 20083216 Aug 17 15:09 vi.jar
- 编写Dockerfile
vim Dockerfile
copy
# 基础镜像使用java
FROM java:8# 作者
MAINTAINER youname# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp# 将jar包添加到容器中并更名为zzyy_docker.jar
ADD vi.jar vi_docker.jar# 运行jar包
RUN bash -c 'touch /vi_docker.jar'ENTRYPOINT ["java","-jar","/vi_docker.jar"]#暴露3082端口作为微服务
EXPOSE 3082
- 构建镜像
打包镜像文件
docker build -t vi_docker:1.6 .
[root@izwz9h3jjs3azrqaqdw90gz software]# ll
total 19620
-rw-r--r-- 1 root root 434 Sep 21 18:52 Dockerfile
-rw-r--r-- 1 root root 20083216 Aug 17 15:09 vi.jar
[root@izwz9h3jjs3azrqaqdw90gz software]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
vi_docker 1.6 282e45a1fb66 42 seconds ago 683MB
centosjava8 1.5 ca66485f12e1 25 hours ago 920MB
mysql 8.0.28 f2ad9f23df82 5 months ago 521MB
tomcat 9.0 b8e65a4d736d 9 months ago 680MB
redis 5.0.14 c5da061a611a 9 months ago 110MB
registry latest b8604a3fe854 10 months ago 26.2MB
centos 7 eeb6ee3f44bd 12 months ago 204MB
ubuntu 14.04 13b66b487594 18 months ago 196MB
java 8 d23bdf5b1b1b 5 years ago 643MB
- 运行打包的镜像文件
docker run -d -p 3082:3082 (镜像ID)
- 查看
[root@izwz9h3jjs3azrqaqdw90gz software]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bb08f835b178 282e45a1fb66 "java -jar /vi_docke…" 20 seconds ago Up 19 seconds 0.0.0.0:6001->6001/tcp busy_dijkstra
418f64d79786 registry "/entrypoint.sh /etc…" 10 days ago Up 5 hours 0.0.0.0:5000->5000/tcp registry
- 访问
IP:port
Docker网络(network)
是什么
docker不启动,默认网络情况
- ens33
- lo
- virbr0
docker启动,默认网络情况
会产生一个名为docker0的虚拟网桥
默认创建3大网络模式
[root@izwz9h3jjs3azrqaqdw90gz software]# docker network ls NETWORK ID NAME DRIVER SCOPE 7e24847a18ee bridge bridge local 89926dfbcecf host host local 643857ddfabe none null local
容器间的互联和通信以及端口映射
容器IP变动时候可以通过服务名直接网络通信而不受到影响
常用基本命令
- 命令
[root@izwz9h3jjs3azrqaqdw90gz software]# docker network --helpUsage: docker network COMMANDManage networksCommands:connect Connect a container to a networkcreate Create a networkdisconnect Disconnect a container from a networkinspect Display detailed information on one or more networksls List networksprune Remove all unused networksrm Remove one or more networksRun 'docker network COMMAND --help' for more information on a command.
- 查看网络
docker network ls
- 查看网络源数据
docker network inspect 网络名字(NAME)
- 删除网络
docker network rm 网络名字(NAME)
- 新建一个网络
docker network create (name)实例:docker network create two_network
网络模式
- 总体介绍
- bridge模式:使用-- network bridge指定,默认使用docker0
- host模式:使用–network host指定
- none模式:使用–network none指定
- container模式:使用-- network container:NAME或者容器ID指定
网络模式 | 简介 |
---|---|
bridge | 为每一一个容器分配、设置IP等,并将容器连接到一个docker0虚拟网桥,默认为该模式。 |
host | 容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。 |
none | 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair和网桥连接,IP等。 |
container | 新创建的容器不会创建自己的网卡和配置自己的IP,而是和一个指定的容器共享IP、端口范围等。 |
docker network inspect 网络模式
[root@izwz9h3jjs3azrqaqdw90gz software]# docker network inspect host
[{"Name": "host","Id": "89926dfbcecfd8bcce514846023277d87b8c5c9a66bcdb0e8cdef2c82c48d290","Created": "2022-03-26T21:50:29.01086899+08:00","Scope": "local","Driver": "host","EnableIPv6": false,"IPAM": {"Driver": "default","Options": null,"Config": []},"Internal": false,"Attachable": false,"Ingress": false,"ConfigFrom": {"Network": ""},"ConfigOnly": false,"Containers": {},"Options": {},"Labels": {}}
]
容器实例内默认网络IP生产规则
说明
- 启动容器查看
docker inspect 容器ID or 容器名字
"Networks": {"bridge": {"IPAMConfig": null,"Links": null,"Aliases": null,"NetworkID": "7e24847a18eeae93115028212060ff27416f44bcecff16cccae63f7060f9e216","EndpointID": "e2e6749470e30d8412245de4743e1f5fe1709771ca73b6e41fe98ff4a9c1c811","Gateway": "172.17.0.1","IPAddress": "172.17.0.3","IPPrefixLen": 16,"IPv6Gateway": "","GlobalIPv6Address": "","GlobalIPv6PrefixLen": 0,"MacAddress": "02:42:ac:11:00:03","DriverOpts": null}}
结论
- docker容器内部的ip是有可能会发生改变的
bridge
Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),该桥接网络的名称为docker0,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信
- 查看 bridge 网络的详细信息,并通过 grep 获取名称项
docker network inspect bridge | grep name
案例
1 Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。
2 docker run 的时候,没有指定network的话默认使用的网桥模式就是bridge,使用的就是docker0。在宿主机ifconfig,就可以看到docker0和自己create的network(后面讲)eth0,eth1,eth2……代表网卡一,网卡二,网卡三……,lo代表127.0.0.1,即localhost,inet addr用来表示网卡的IP地址
3 网桥docker0创建一对对等虚拟设备接口一个叫veth,另一个叫eth0,成对匹配。
3.1 整个宿主机的网桥模式都是docker0,类似一个交换机有一堆接口,每个接口叫veth,在本地主机和容器内分别创建一个虚拟接口,并让他们彼此联通(这样一对接口叫veth pair);
3.2 每个容器实例内部也有一块网卡,每个接口叫eth0;
3.3 docker0上面的每个veth匹配某个容器实例内部的eth0,两两配对,一一匹配。
通过上述,将宿主机上的所有容器都连接到这个内部网络上,两个容器在同一个网络下,会从这个网关下各自拿到分配的ip,此时两个容器的网络是互通的。
host
直接使用宿主机的 IP 地址与外界进行通信,不再需要额外进行NAT 转换。
容器将不会获得一个独立的Network Namespace, 而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡而是使用宿主机的IP和端口。
代码
警告
docker run -d -p 8083:8080 --network host --name tomcat9 tomcat:9.0
[root@izwz9h3jjs3azrqaqdw90gz software]# docker run -d -p 8083:8080 --network host --name tomcat9 tomcat:9.0
WARNING: Published ports are discarded when using host network mode
346e0350557ea4ccf31c37fda677320acae7abe5e3b3cf645706a2011acb0cbc
问题:
- docke启动时总是遇见标题中的警告
原因:
- docker启动时指定–network=host或-net=host,如果还指定了-p映射端口,那这个时候就会有此警告,并且通过-p设置的参数将不会起到任何作用,端口号会以主机端口号为主,重复时则递增。
解决:
- 解决的办法就是使用docker的其他网络模式,例如–network=bridge,这样就可以解决问题,或者直接无视
正确
docker run -d --network host --name tomcat9 tomcat:9.0
因为此时容器的IP借用主机的,所以容器共享宿主机网络IP,这样的好处是外部主机与容器可以直接通信
none
在none模式下,并不为Docker容器进行任何网络配置。
也就是说,这个Docker容器没有网卡、IP、路由等信息,只有一个lo
需要我们自己为Docker容器添加网卡、配置IP等。
进入一个可以使用 ip addr命令的容器禁用网络功能,只有Io标识(就是127.0.0.1表示本地回环)
container
新建的容器和已经存在的一个容器共享一个网络ip配置而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。
案例
Alpine Linux 是一款独立的、非商业的通用 Linux 发行版,专为追求安全性、简单性和资源效率的用户而设计。 可能很多人没听说过这个 Linux 发行版本,但是经常用 Docker 的朋友可能都用过,因为他小,简单,安全而著称,所以作为基础镜像是非常好的一个选择,可谓是麻雀虽小但五脏俱全,镜像非常小巧,不到 6M的大小,所以特别适合容器打包
- 启动
docker run -it --name alpine1 alpine /bin/sh
[root@izwz9h3jjs3azrqaqdw90gz software]# docker run -it --name alpine1 alpine /bin/sh
Unable to find image 'alpine:latest' locally
latest: Pulling from library/alpine
59bf1c3509f3: Pull complete
Digest: sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300
Status: Downloaded newer image for alpine:latest
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
20: eth0@if21: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ffinet 172.17.0.4/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft forever
/ #
用另一个启动
docker run -it --network container:alpine1 --name alpine2 alpine /bin/sh
[root@izwz9h3jjs3azrqaqdw90gz ~]# docker run -it --network container:alpine1 --name alpine2 alpine /bin/sh
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft forever
20: eth0@if21: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ffinet 172.17.0.4/16 brd 172.17.255.255 scope global eth0valid_lft forever preferred_lft forever
/ #
一旦关闭 alpine1 ,alpine2就只有本地回环了
自定义网络
自定义桥接网络,自定义网络默认使用的是桥接网络bridge
before(没有使用)
问题
通过 ip 可以 ping 通
通过 服务名 不可以 ping通
after(使用)
- 创建
docker network create tomcat_network
- 选择
docker run -d -p 8082:8080 --network tomcat_network --name tomcat82 billygoo/tomcat8-jdk8
- 问题
- 自定义网络本身就维护好了主机名和ip的对应关系(ip和域名都能通)
Docker平台架构
从其架构和运行流程来看,Docker 是一个 C/S 模式的架构,后端是一个松耦合架构,众多模块各司其职
Docker 运行的基本流程为:
- 1 用户是使用 Docker Client 与 Docker Daemon 建立通信,并发送请求给后者。
- 2 Docker Daemon 作为 Docker 架构中的主体部分,首先提供 Docker Server 的功能使其可以接受 Docker Client 的请求。
- 3 Docker Engine 执行 Docker 内部的一系列工作,每一项工作都是以一个 Job 的形式的存在。
- 4 Job 的运行过程中,当需要容器镜像时,则从 Docker Registry 中下载镜像,并通过镜像管理驱动 Graph driver将下载镜像以Graph的形式存储。
- 5 当需要为 Docker 创建网络环境时,通过网络管理驱动 Network driver 创建并配置 Docker 容器网络环境。
- 6 当需要限制 Docker 容器运行资源或执行用户指令等操作时,则通过 Execdriver 来完成。
- 7 Libcontainer是一项独立的容器管理包,Network driver以及Exec driver都是通过Libcontainer来实现具体对容器进行的操作。
Docker-compose容器编排
Compose 是 Docker 公司推出的一个工具软件,可以管理多个 Docker 容器组成一个应用。你需要定义一个 YAML 格式的配置文件docker-compose.yml,写好多个容器之间的调用关系。然后,只要一个命令,就能同时启动/关闭这些容器
Docker-Compose是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。
可以干什么
docker建议我们每一个容器中只运行一个服务,因为docker容器本身占用资源极少,所以最好是将每个服务单独的分割开来但是这样我们又面临了一个问题?
如果我需要同时部署好多个服务,难道要每个服务单独写Dockerfile然后在构建镜像,构建容器,这样累都累死了,所以docker官方给我们提供了docker-compose多服务部署的工具
例如要实现一个Web微服务项目,除了Web服务容器本身,往往还需要再加上后端的数据库mysql服务容器,redis服务器,注册中心eureka,甚至还包括负载均衡容器等等
Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。
可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose 解决了容器与容器之间如何管理编排的问题。
下载
官网:https://docs.docker.com/compose/compose-file/compose-file-v3/
官网下载:https://docs.docker.com/compose/install/
- 下载
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
- 设置权限
chmod +x /usr/local/bin/docker-compose
- 查看版本
docker-compose --version
- 卸载
如果您使用curl以下方式安装,则卸载Docker Compose
sudo rm /usr/local/bin/docker-compose
Compose核心概念
- 文件
docker-compose. yml
- 两要素
- 服务(service)
- 一个个应用容器实例,比如订单微服务、库存微服务、mysq|容器、 nginx容器或者redis容器
- 工程(project)
- 由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml文件中定义。
- 服务(service)
Compose使用的三个步骤
编写Dockerfile定义各个微服务应用并构建出对应的镜像文件
使用docker-compose.yml,定义一个完整业务单元,安排好整体应用中的各个容器服务
最后,执行docker compose up命令来启动并运行整个应用程序,完成-键部署上线
Compose常用命令
Compose常用命令 | |
---|---|
docker-compose -h | 查看帮助 |
docker-compose up | 启动所有docker-compose服务 |
docker-compose up -d | 启动所有docker-compose服务并后台运行 |
docker-compose down | 停止并删除容器、网络、卷、镜像。 |
docker-compose exec yml里面的服务id |
进入容器实例内部 docker-compose exec docker-compose.yml文件中写的 服务id /bin/bash |
docker-compose ps | 展示当前docker-compose编排过的运行的所有容器 |
docker-compose top | 展示当前docker-compose编排过的容器进程 |
docker-compose logs yml里面的服务id | 查看容器输出日志 |
docker-compose config | 检查配置 |
docker-compose config -q | 检查配置,有问题才有输出 |
docker-compose restart | 重启服务 |
docker-compose start | 启动服务 |
docker-compose stop | 停止服务 |
Compose编排服务
注意
# 在springboot yml 文件 配置中设置成这样#spring.datasource.url=jdbc:mysql://192.168.111.169:3306/db2021 不可取#spring.datasource.url=jdbc:mysql://mysql:3306/db2021 可取#spring.redis.host=192.168.111.169 不可取#spring.redis.host=redis 可取# 我在复制的时候总是出现空格的问题,在复制完之后,看一下有没有对齐,我就是出现了没有对齐的错误 # 我们在使用的时候 docker-compose up -d 或者 docker-compose stop 的时候要注意是不是在docker-compose.yml文件的目录里,如果不在可能会出现问题
编写 docker-compose.yml 文件
vim docker-compose.yml
version: "3" # 版本services: # 服务容器实例microService: # 这个名字随便取image: vi_docker:1.6 # 容器名字+版本号container_name: vi # 运行的镜像名称ports: # 端口号- "6001:6001"volumes: # 挂载数据- /app/microService:/datanetworks: # 网络自定义- name_netdepends_on: # 依赖- redis- mysqlredis: # 注意看 可取的那里,名字是不是redisimage: redis:6.0.8ports:- "6379:6379"volumes:- /app/redis/redis.conf:/etc/redis/redis.conf- /app/redis/data:/datanetworks:- name_netcommand: redis-server /etc/redis/redis.confmysql: # 注意看 可取的那里,名字是不是mysqlimage: mysql:5.7environment:MYSQL_ROOT_PASSWORD: '123456' # root的密码MYSQL_ALLOW_EMPTY_PASSWORD: 'no'MYSQL_DATABASE: 'db2021' #创建一个数据库MYSQL_USER: 'zzyy' # 创建一个用户MYSQL_PASSWORD: 'zzyy123' # 用户的密码ports:- "3306:3306"volumes:- /app/mysql/db:/var/lib/mysql- /app/mysql/conf/my.cnf:/etc/my.cnf- /app/mysql/init:/docker-entrypoint-initdb.dnetworks:- name_netcommand: --default-authentication-plugin=mysql_native_password #解决外部无法访问networks: # 创建一个自定义的网络name_net:
- 查看
[root@izwz9h3jjs3azrqaqdw90gz software]# ll
total 19624
-rw-r--r-- 1 root root 1231 Sep 23 15:31 docker-compose.yml
-rw-r--r-- 1 root root 433 Sep 21 18:59 Dockerfile
-rw-r--r-- 1 root root 20083216 Aug 17 15:09 vi.jar
- 构建镜像
docker build -t vi_docker:1.6 .
- 启动
docker-compose up
or
docker-compose up -d
[root@izwz9h3jjs3azrqaqdw90gz software]# ll
total 19624
-rw-r--r-- 1 root root 1231 Sep 23 15:31 docker-compose.yml
-rw-r--r-- 1 root root 433 Sep 21 18:59 Dockerfile
-rw-r--r-- 1 root root 20083216 Aug 17 15:09 vi.jar
[root@izwz9h3jjs3azrqaqdw90gz software]# docker-compose up
- 查看
docker network ls
[root@izwz9h3jjs3azrqaqdw90gz ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
7e24847a18ee bridge bridge local
89926dfbcecf host host local
643857ddfabe none null local
1a5dddab40f5 software_name_net bridge local# 之所以会有 software_这个前缀,是因为编排规则
docker ps
[root@izwz9h3jjs3azrqaqdw90gz ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0cda46df9d94 vi_docker:1.6 "java -jar /vi_docke…" 3 minutes ago Up 3 minutes 3082/tcp, 0.0.0.0:6001->6001/tcp vi
bf752f53f75f redis:6.0.8 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 0.0.0.0:6379->6379/tcp software_redis_1
a8fd436ced77 mysql:5.7 "docker-entrypoint.s…" 3 minutes ago Up 3 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp software_mysql_1# 之所以会有 software_这个前缀,是因为编排规则
- 进入一个容器
[root@izwz9h3jjs3azrqaqdw90gz ~]# docker exec -it a8fd436ced77 /bin/bash
root@a8fd436ced77:/# mysql -uzzyy -pzzyy123
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.36 MySQL Community Server (GPL)Copyright (c) 2000, 2021, Oracle and/or its affiliates.Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql>
- 停止
docker-compose stop
[root@izwz9h3jjs3azrqaqdw90gz software]# docker-compose stop
Stopping vi ... done
Stopping software_redis_1 ... done
Stopping software_mysql_1 ... done
Docker轻量级可视化Portainer
Portainer 是一款轻量级的应用,它提供了图形化界面,用于方便地管理Docker环境,包括单机环境和集群环境。
安装
官网
- https://www.portainer.io/
- https://docs.portainer.io/v/ce-2.9/start/install/server/docker/linux
步骤
- docker安装
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
- 访问
IP:9000
- 默认用户是 admin,密码只要满足 8位 就行了
- 选择 load这个图标即可
- 实战还是看自己
在我看来他的全部,只不过是将所以docker命令进行一个图形化了
Docker容器监控之CAvisor+InfIuxDB+Granfana
CAdvisor监控收集+InfluxDB存储数据+Granfana展示图表
CAdvisor
CAdvisor是一个容器资源监控I具,包括容器的内存,CPU,网络IO,磁盘I0等监控,同时提供了-一个
WEB页面用于查看容器的实时运行状态。CAdvisor默认存储2分钟的数据 且只是针对单物理机。
不过, CAdvisor提供了很多数据集成接口,支持InfluxDB, Redis,Kafka,Elasticsearch等集成,可以加
上对应配置将监控数据发往这些数据库存储起来。
CAdvisor功能主要有两点:
展示Host和容器两个层次的监控数据。
展示历史变化数据。
InfluxDB
InfluxDB是用Go语言编写的一个开源分布式时序事件和指标数据库无孺外部依赖。
CAdvisor默认只在本机保存最近2分钟的数据,为了持久化存储数据和统一收集展示监控
数据,需要将数据存储到InfluxDB中。InfluxDB是- -个时序数据库,专[用于存储时序相关数据,很
适给存储CAdvisor的数据。且, CAdvisor本身已经提供了InfluxDB的集成方法,丰启动容器时
指定配置即可。
InfluxDB主要功能:
基于时间列,支持与时间有关的相关函数(如最大、最小、求和等);
可度量性:你可以实时对大量数据进行计算;
基于事件:它支持任意的事件数据;
Granfana
Grafana是一个开源的数据监控分析可视化平 台,支持多种数据源配置(支持的数据源包括
InfluxDB,MySQL, Elasticsearch,OpenTSDB,Graphite等)和丰富的插件及模板功能,支持图表权限控
制和报警。
Grafan主要特性:
灵活丰富的图形化选项
可以混合多种风格
支持白天和夜间模式
多个数据源
compose容器编排一套起
记得开启端口
8080
8083
8086
3000
新建目录
[root@izwz9h3jjs3azrqaqdw90gz /]# mkdir cig
[root@izwz9h3jjs3azrqaqdw90gz /]# cd cig/
[root@izwz9h3jjs3azrqaqdw90gz cig]# pwd
/cig
新建 vim docker-compose.yml
vim docker-compose.yml
version: '3.1'volumes:grafana_data: {}services:influxdb:image: tutum/influxdb:0.9restart: alwaysenvironment:- PRE_CREATE_DB=cadvisorports:- "8083:8083"- "8086:8086"volumes:- ./data/influxdb:/datacadvisor:image: google/cadvisorlinks:- influxdb:influxsrvcommand: -storage_driver=influxdb -storage_driver_db=cadvisor -storage_driver_host=influxsrv:8086restart: alwaysports:- "8080:8080"volumes:- /:/rootfs:ro- /var/run:/var/run:rw- /sys:/sys:ro- /var/lib/docker/:/var/lib/docker:rografana:user: "104"image: grafana/grafanauser: "104"restart: alwayslinks:- influxdb:influxsrvports:- "3000:3000"volumes:- grafana_data:/var/lib/grafanaenvironment:- HTTP_USER=admin- HTTP_PASS=admin- INFLUXDB_HOST=influxsrv- INFLUXDB_PORT=8086- INFLUXDB_NAME=cadvisor- INFLUXDB_USER=root- INFLUXDB_PASS=root
检查
docker-compose config -q
如果没有任何的东西输出,那就表示我们编写的没有问题
[root@izwz9h3jjs3azrqaqdw90gz cig]# ll
total 4
-rw-r--r-- 1 root root 977 Sep 23 16:24 docker-compose.yml
[root@izwz9h3jjs3azrqaqdw90gz cig]# docker-compose config -q
[root@izwz9h3jjs3azrqaqdw90gz cig]#
后台启动,运行的时候记得查看一下端口有没有被占用
docker-compose up -d
查看
[root@izwz9h3jjs3azrqaqdw90gz cig]# docker-compose up -d
Starting cig_influxdb_1 ... done
Starting cig_grafana_1 ... done
Starting cig_cadvisor_1 ... done
[root@izwz9h3jjs3azrqaqdw90gz cig]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
360d13628ca3 google/cadvisor "/usr/bin/cadvisor -…" 4 minutes ago Up 24 seconds 0.0.0.0:8080->8080/tcp cig_cadvisor_1
44443549d4cc grafana/grafana "/run.sh" 4 minutes ago Up 24 seconds 0.0.0.0:3000->3000/tcp cig_grafana_1
26b1dd326ff4 tutum/influxdb:0.9 "/run.sh" 4 minutes ago Up 25 seconds 0.0.0.0:8083->8083/tcp, 0.0.0.0:8086->8086/tcp cig_influxdb_1
测试
CAdvisor收集服务
查看
端口:8080
InfluxDB存储服务
查看
端口:8083
默认创建一个数据库,cadvisor,用户/密码 都是 root
Granfana展现服务
查看
端口:3000
默认用户/密码都是 admin,然后会让你设置新的密码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i67Qu9BE-1663922929348)(C:\Users\luoch\AppData\Roaming\Typora\typora-user-images\image-20220923164722821.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zI3CB68c-1663922929349)(C:\Users\luoch\AppData\Roaming\Typora\typora-user-images\image-20220923164749354.png)]
需要将数据存储到InfluxDB中。InfluxDB是- -个时序数据库,专[用于存储时序相关数据,很
适给存储CAdvisor的数据。且, CAdvisor本身已经提供了InfluxDB的集成方法,丰启动容器时
指定配置即可。
InfluxDB主要功能:
基于时间列,支持与时间有关的相关函数(如最大、最小、求和等);
可度量性:你可以实时对大量数据进行计算;
基于事件:它支持任意的事件数据;
Granfana
Grafana是一个开源的数据监控分析可视化平 台,支持多种数据源配置(支持的数据源包括
InfluxDB,MySQL, Elasticsearch,OpenTSDB,Graphite等)和丰富的插件及模板功能,支持图表权限控
制和报警。
Grafan主要特性:
灵活丰富的图形化选项
可以混合多种风格
支持白天和夜间模式
多个数据源
compose容器编排一套起
记得开启端口
8080
8083
8086
3000
新建目录
[root@izwz9h3jjs3azrqaqdw90gz /]# mkdir cig
[root@izwz9h3jjs3azrqaqdw90gz /]# cd cig/
[root@izwz9h3jjs3azrqaqdw90gz cig]# pwd
/cig
新建 vim docker-compose.yml
vim docker-compose.yml
version: '3.1'volumes:grafana_data: {}services:influxdb:image: tutum/influxdb:0.9restart: alwaysenvironment:- PRE_CREATE_DB=cadvisorports:- "8083:8083"- "8086:8086"volumes:- ./data/influxdb:/datacadvisor:image: google/cadvisorlinks:- influxdb:influxsrvcommand: -storage_driver=influxdb -storage_driver_db=cadvisor -storage_driver_host=influxsrv:8086restart: alwaysports:- "8080:8080"volumes:- /:/rootfs:ro- /var/run:/var/run:rw- /sys:/sys:ro- /var/lib/docker/:/var/lib/docker:rografana:user: "104"image: grafana/grafanauser: "104"restart: alwayslinks:- influxdb:influxsrvports:- "3000:3000"volumes:- grafana_data:/var/lib/grafanaenvironment:- HTTP_USER=admin- HTTP_PASS=admin- INFLUXDB_HOST=influxsrv- INFLUXDB_PORT=8086- INFLUXDB_NAME=cadvisor- INFLUXDB_USER=root- INFLUXDB_PASS=root
检查
docker-compose config -q
如果没有任何的东西输出,那就表示我们编写的没有问题
[root@izwz9h3jjs3azrqaqdw90gz cig]# ll
total 4
-rw-r--r-- 1 root root 977 Sep 23 16:24 docker-compose.yml
[root@izwz9h3jjs3azrqaqdw90gz cig]# docker-compose config -q
[root@izwz9h3jjs3azrqaqdw90gz cig]#
后台启动,运行的时候记得查看一下端口有没有被占用
docker-compose up -d
查看
[root@izwz9h3jjs3azrqaqdw90gz cig]# docker-compose up -d
Starting cig_influxdb_1 ... done
Starting cig_grafana_1 ... done
Starting cig_cadvisor_1 ... done
[root@izwz9h3jjs3azrqaqdw90gz cig]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
360d13628ca3 google/cadvisor "/usr/bin/cadvisor -…" 4 minutes ago Up 24 seconds 0.0.0.0:8080->8080/tcp cig_cadvisor_1
44443549d4cc grafana/grafana "/run.sh" 4 minutes ago Up 24 seconds 0.0.0.0:3000->3000/tcp cig_grafana_1
26b1dd326ff4 tutum/influxdb:0.9 "/run.sh" 4 minutes ago Up 25 seconds 0.0.0.0:8083->8083/tcp, 0.0.0.0:8086->8086/tcp cig_influxdb_1
测试
CAdvisor收集服务
查看
端口:8080
InfluxDB存储服务
查看
端口:8083
默认创建一个数据库,cadvisor,用户/密码 都是 root
Granfana展现服务
查看
端口:3000
默认用户/密码都是 admin,然后会让你设置新的密码
完结了吧…
一篇Docker带你入门爱不释手相关推荐
- 不懂java,这篇文章带你入门起飞
文章目录 Java入门 什么是Java Java能做什么 为什么学Java 怎么学Java Java开发环境安装 JDK下载 Jdk安装 win版安装 Linux版本安装 Mac版本安装 开发工具选择 ...
- 一篇详文带你入门 Redis
作者:QQ 音乐前端团队 本文将会从:Redis 使用场景与介绍 -> 数据结构与简单使用 -> 小功能大用处 -> 持久化.主从同步与缓存设计 -> 知识拓展 来书写,初学的 ...
- 10篇论文带你入门深度学习图像分类(附下载)
来源:计算机视觉联盟 本文约7600字,建议阅读10+分钟. 本文将介绍10篇最佳论文供初学者阅读. 前言 计算机视觉是将图像和视频转换成机器可理解的信号的主题.利用这些信号,程序员可以基于这种高级理 ...
- 深度学习到底有多难?这篇文章带你入门!
随着2020年的到来,人类进入了一个崭新的十年.回顾过去10年,深度学习领域取得了巨大进步,解决了许多以前难以解决的问题. 从自动驾驶到Deepfake,深度学习正在改变世界.随着深度学习在各个领域井 ...
- 如何写单片机的寄存器,这篇文章带你入门。
单片机在电学里面,属于很简单的一种器件,外表看,就是一个芯片,长着很多的脚.内部,就是一堆寄存器.不同的单片机,外部表现就是形状和引脚数量和引脚名称可能不一样,内部,就是寄存器名称不一样. 我们要做的 ...
- 带你入门GeoSpark系列之三【空间查询篇】
系列目录 带你入门GeoSpark系列之一[环境篇] 带你入门GeoSpark系列之二[Spatial RDD篇] 带你入门GeoSpark系列之三[空间查询篇] 1.空间范围查询( Spatial ...
- 手把手带你入门 Docker Compose
前言 在上一篇Docker入门介绍 不搞虚的!快速把你拉入Docker 的门里 博客中介绍了如何将 SpringBoot 项目 Docker化.这篇博客将继续带你了解 Docker Compose 用 ...
- 15分钟带你入门sklearn与机器学习——分类算法篇
作者 | 何从庆 本文转载自AI算法之心(ID:AIHeartForYou) [导读]众所周知,Scikit-learn(以前称为scikits.learn)是一个用于Python编程语言的免费软件机 ...
- 这38篇原创文章,带我入门深度学习!
这38篇原创文章带我入门卷积神经网络,循环神经网络和强化学习,希望对您有帮助. 37. 深度学习算法(第37期)----如何用强化学习玩游戏? 36. 深度学习算法(第36期)----强化学习之时 ...
最新文章
- ASP.NET MVC 控制器激活(二)
- python中关键字参数含义_python中接受任意关键字的参数
- JavaScript入门(part10)--作用域
- django 按钮的样式_【实战演练】Python+Django网站开发系列11-成绩查询与成绩录入...
- jvm gc阻塞时长 占比_jvm进行转义分析需要多长时间? 可能比您想象的要长。
- jOOQ类型安全数据库查询教程
- AAS的完整形式是什么?
- python3的输出函数_教女朋友学Python3(二)简单的输入输出及内置函数查看
原创...
- [卷积核]空洞卷积(转)
- 《恋上数据结构第1季》二叉树代码实现
- Notepad++-第一篇命令行语句执行之编译、运行Java
- 真心推荐8个高质量Java学习网站,一起从入门到精通java语言,大厂java面试真题分享,建议码住!
- python能当黑客吗_如何成为一名黑客?(转)
- 从零开始学写脚本(大麦网抢票 上)【第二天】
- 米家扫地机器人充满电需要多长时间_【米家扫地机器人使用总结】充电|APP|清扫_摘要频道_什么值得买...
- excel打开html非常慢,打开excel很慢
- 高级货!Django实现基于人脸识别的门禁管理系统【源码】
- world 字体 选取高亮_Word2003选取文字的N种方法
- linux服务器性能阈值,linux – 如何根据可用内核的数量选择最大负载阈值?
- Java的GUI编程---AWT介绍
热门文章
- 计算机二级Python 操作题知识点及例题总结
- vivo的originos和华为的鸿蒙,originos适配机型_vivo新系统originos升级名单
- 被面试:sharepoint 是什么?优势是什么?
- 关于MySQL : CREATE TABLE if not exists xxx/ALTER TABLE xxx ADD COLUMN IF NOT EXISTS xxx语法使用注意
- netty 大端小端_深入浅出: 大小端模式
- dfa算法 java_DFA算法的实现与最小化
- Jenkins 设置中文显示方式
- 七夕趣味玩法,用 MMGeneration 生成心仪的 TA
- Oracle中ROWID详解
- 电脑调用 iPhone 摄像头全过程(iVCam)