docker学习笔记
Docker笔记
1.和传统虚拟机的区别
- size小
- 速度快
- 复杂度
2.安装
借机生蛋
window - virtual machine - docker
docker 的基本组成
- 镜像 image 以Java来举例的话就是 Java类的类模板,只是一个只读的模板。镜像可以用来创建docker容器,一个镜像可以创建很多很多容器。
- 容器 contain 以Java来举例的话就是new Java类的实体, 容器里面是 需要的linux环境建议版本,包括root用户权限,进程,用户空间,网络空间 还有就是运行的程序
- 仓库 repository 存放镜像的地方,暂时把它称为集合
安装配置
-
确定你是centos7
-
卸载旧版本
-
yum安装gcc相关
# gcc yum -y install gcc yum -y install gcc-c++ # yum-utils yum -y install yum-utils
-
设置stable仓库
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
-
然后更新一下
yum makecache fast
-
安装docker引擎
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
-
启动测试
systemctl start docker docker version docker run hello-world
-
如果你遇到以下
reset by peer
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://yxzrazem.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker
-
然后配置阿里云的加速器
sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://majf0tj8.mirror.aliyuncs.com"] } EOF sudo systemctl daemon-reload sudo systemctl restart docker sudo systemctl daemon-reload sudo systemctl restart docker
-
卸载
#停止docker systemctl stop docker sudo yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras sudo rm -rf /var/lib/docker sudo rm -rf /var/lib/containerd
命令篇章
启动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
注意 这个image可以用私服的链接
保存 docker save image > xx.tar
如果更小使用
docker save myimage:latest | gzip > myimage_latest.tar.gz
docker images
[root@hadoop102 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest feb5d9fea6a5 20 months ago 13.3kB
#
REPOSITORY:表示镜像的仓库源
TAG:表示标签版本号
IMAGE ID:镜像ID
CREATED:镜像创建时间
SIZE:镜像大小
docker search xx
可以加 docker search --limit 5 redis
docker pull 镜像名字[:TAG]
docker images -a
所有
docker images -q
只显示id
docker system df
查看镜像/容器/数据卷所占空间
[root@hadoop102 ~]# docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 3 1 176.9MB 176.9MB (99%)
Containers 1 0 0B 0B
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0B
#
TYPE 类型
TOTAL 总计
ACTIVE 活跃数
SIZE 大小
RECLAIMABLE 可伸缩性
docker rmi -f ${docker images -qa}
删除全部
什么是虚悬镜像就是 repo和tag 都是none的 需要删除的
容器
前面说了在java中怎么创建一个对象呢,就是实现一个类。怎么实现就是new 一个 Class
那么在docker里就是 docker run [options] IMAGE [COMMAND] [ARG..]
run一个image
option参数说明
--name="容器新名字" 给容器指定一个名字 其实更像 Image ubuntu01 = new Image();
-d: 后台运行返回值是一个long类型的id
-i:交互模式运行容器,通常与-t同时使用
-t:为容器重新分配一个伪输入终端跟 -i同时使用。 启动交互性容器
-P 随机端口
-p指定端口 写法 -p 8080:80
例子
启动Ubuntu
docker run -it ubuntu /bin/bash
docker 退出容器方式
exit
ctrl+q+p
docker 启动已经停止的容器
1.先查找 docker ps -n number
number 为显示几个
2.拿到容器id然后 docker start 容器id
3.相同的还有docker restart 容器id
,docker stop 容器id
,docker kill 容器id
4.删除已经停止的容器 docker rm 容器id
注意:先停止再删除
5.一次性删除多个容器 危险不演示
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm
6.后台运行一个容器,如果容器不支持的话,那只能使用 -it 下面演示运行redis
docker images; //查看自己的镜像版本
docker run -d redis:xx.xx.xx
7.查看容器运行日志 进入到某个集装箱看日志
docker logs 容器id
8.查看运行情况 top
docker top 容器id
9.查看容器内部情况
docker inspect 容器id
10.重新进入容器
注意 在工作中我们怎么退出容器呢 ctrl + q + p
如果我们不想 exit 直接退出那么就选择 exec
docker exec -it 容器id bashshell
docker attach 容器id
## 例子
docker exec -it 容器id /bin/bash
root@6d58c550ca57:/data# redis-cli -p 6379
redis-cli -p 6379
127.0.0.1:6379> set name jack
OK
127.0.0.1:6379> get name
从容器上取点东西到主机上
docker cp cf7b07ccd04d/opt/a.txt /opt/module/
导入和导出命令
docker export 容器id > a.tar
cat a.tar | docker import - fykinng/ubuntu:3.7
Docker镜像
什么是镜像?就是打包好的代码,运行时需要的库,环境变量和配置文件,这个打包好的运行环境就是镜像,只有通过这个镜像文件才能生成docker容器实例。类似java中new出来一个对象
看一下图
当你下载镜像的时候,里面就包括了 bootfs
和 rootfs
在bootfs 上有 基础的镜像,然后当你的镜像run之后在镜像的顶部会有一个容器,容器时可读可写的。
小栗子:
当我们想在这个 ubuntu容器上装一个vim工具的时候发现了很傻逼的问题,但是百度上面搜出来的答案都是无用的
因为什么呢?就是因为网络,但是我们尝试了在 /etc/resolve.conf文件中添加修改内容。
echo "nameserver 150.236.34.180" | tee /etc/resolv.conf > /dev/null
这个办法是没用的
最后是 是在启动docker的时候加载 网络
docker run -it --name testUbuntu --net=host Ubuntu
然后就是安装vim工具 apt-get -y install vim
然后制作自己已经安装好的镜像 退出容器
docker commit -m 'with vim ubuntu' -a 'fyeeware' 容器id myubuntu:0.0.1
阿里云镜像上传
![阿里云上传]: (http://static.runoob.com/images/runoob-logo.png)
镜像生成的集中方式 仓库拉,Dockerfile构建,容器commit
进入阿里云容器镜像服务
然后根据他上面提示的东西 先登录然后拉取 然后在上传
![步骤截图]: (https://img2023.cnblogs.com/blog/2656161/202306/2656161-20230623133033598-1292106655.png)
本地registry 怎么操作呢
先拉去镜像下来
docker pull registry
然后运行脚本
docker run -d -p 5000:5000 -v /fyeeware/myregistry/:/tmp/registry --privileged registry
docker run -d -p 5000:5000 ##后台运行 500
-v /fyeeware/myregistry/:/tmp/registry ## 数据卷 host主机到哪里
--privileged registry ## 特权 加 images
#然后就是进入你的ubuntu下载 net-tools
# 然后查看你的registry有多少个
> curl -XGET http://192.168.1.102:5000/v2/_catalog
> {"repositories":[]}
-
运行你的ubuntu
docker run -it --name="myubuntu" ubuntu /bin/bash apt-get update apt-get install -y net-tools #安装net-tools
-
然后 ctrl+q+p也好 exit 也好
-
然后commit 把这个镜像上传
docker commit -m 'ubuntu with ifconfig' -a 'fyeeware' 容器的id 别名:tag
-
然后按照他需要的格式采取tag
[root@hadoop102 ~]# docker images;
REPOSITORY TAG IMAGE ID CREATED SIZE
myubuntu 0.0.2 8d0f7162033d 13 seconds ago 209MB
registry.cn-shanghai.aliyuncs.com/fykinghz/myubuntu 0.0.1 fe86e115fca0 3 days ago 185MB
tomcat latest fb5657adc892 18 months ago 680MB
registry latest b8604a3fe854 19 months ago 26.2MB
ubuntu latest ba6acccedd29 20 months ago 72.8MB
hello-world latest feb5d9fea6a5 21 months ago 13.3kB
redis 6.0.2 33c654ea77ff 3 years ago 104MB
[root@hadoop102 ~]# docker tag myubuntu:0.0.2 192.168.1.102:5000/myubuntu:0.0.2
docker tag myubuntu:0.0.2 192.168.1.102:5000/myubuntu:0.0.2
这个是你的本地commit上传的版本加上version 然后host本机ip/本地commit上传版本+version
然后配置http 安全需要同意我们的地址
在 /etc/docker/daemon.json中
加上 insecure-registries: ["192.168.1.102:5000"]
注意我上图 少加了一个" 请注意奥
docker push 192.168.1.102:5000/myubuntu:0.0.2
推送如果完成了请查看
curl -XGET 'http://192.168.1.102:5000/v2/_catalog'
然后就是拉取这个了
docker pull 192.168.1.102:5000/ubuntu:0.0.3
docker容器数据卷
坑关于 permission denied
有什么用呢? 就是数据的持久化。宿主机和容器之间的数据映射添加容器卷
docker run -it --privileged=true -v /宿主机绝对路径:/容器内目录 镜像名
实战
docker run -it --privileged=true -v /tmp/host_data:/tmp/docker_data -name=u1 镜像名
查看是否挂载成功?
docker inspect 容器id
特别提示如果你的容器的ubuntu宕机了,你在宿主机上创建的文件还是可以在它启动后加载进来。
如果你不想让自己容器内部的系统被写入使用以下命令
docker run -it --privileged=true -v /tmp/host:/tmp/docker:ro ubuntu
docker容器2继承docker容器1的宿主机映射怎么操作?
这个父类就是名字 u1
docker run -it --privileged=true -volunmes-from 父类 --name u2 ubuntu
docker常规安装简介
- 安装tomcat
docker hub上查找tomcat镜像
从dockerhub上拉去tomcat镜像到本地
docker images查看是否有拉取到的tomcat
使用tomcat镜像创建容器实例 - 运行镜像
访问tomcat 首页
开始安装tomcat
docker search tomcat
或者去官网看 tag
docker pull tomcat:[tag]
直接运行
docker run -d -p 8080:8080 --name t1 tomcat
但是会显示404
解决 进入这个容器中 使用exec的命令 这个命令是进入 /usr/local/tomcat中
docker exec -it d168899624ff /bin/bash
在新版的tomcat中 webapp中已经没有东西了,我们需要的就是把tomcat中的webapp删除,然后同目录下有 webapp.dist 改名为 webapp就可以访问了
mv webapp.dist/ webapp
但是这样很麻烦 删来删去万一删错了怎么办
我们使用的是修改版的
docker pull billygoo/tomcat8-jdk8
然后直接运行就可以了怎么运行?
docker run -d -p 8080:8080 --name btomcat1 billygoo/tomcat8-jdk8
开始安装mysql
拉取mysql 5.7
docker pull mysql:5.7
运行mysql
docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
docker exec -it 容器id /bin/bash
以上的步骤都是最简单的版本,不采纳
生产版本的该怎么运用呢? 先stop rm你的容器
然后就是运行下面的命令
-v就是加数据卷,然后还有一个 -volume-from 就是继承
docker run -d -p 3306:3306 --privileged=true
-v /fyeeware/mysql/log:/var/log/mysql
-v /fyeeware/mysql/data:/var/lib/mysql
-v /fyeeware/mysql/conf:/etc/mysql/conf.d
-e MYSQL_ROOT_PASSWORD=123456 --name mysql1 mysql:5.7
然后就是配置
my.cnf 配置编码格式 然后��除后在运行还是没问题的
安装redis
这里只是粗浅的安装
将你的宿主机上面的redis.conf 找到并放在 /app/redis/ 下面然后注释127.0.0.1
docker run -p 6379:6379 --name myredis --privileged=true
-v /app/redis/redis.conf:/etc/redis/redis.conf
-v /app/redis/data:/data -d redis:6.0.2 redis-server
/etc/redis/redis.conf
启动完成
安装nginx
先拉一个nginx 我这里使用的nginx:1.21.6
然后创建挂在目录
创建挂载目录
mkdir -p /fyeeware/nginx/conf
mkdir -p /fyeeware/nginx/log
mkdir -p /fyeeware/nginx/html
容器中的
nginx.conf
文件和conf.d
文件夹复制到宿主机
# 生成容器 如果占用就结束
docker run --name nginx -p 80:80 -d nginx
# 将容器nginx.conf文件复制到宿主机
docker cp nginx:/etc/nginx/nginx.conf /fyeeware/nginx/conf/nginx.confm
# 将容器conf.d文件夹下内容复制到宿主机
docker cp nginx:/etc/nginx/conf.d /fyeeware/nginx/conf/conf.d
# 将容器中的html文件夹复制到宿主机
docker cp nginx:/usr/share/nginx/html /fyeeware/nginx/
删除你刚才利用的容器nginx
# 直接执行docker rm nginx或者以容器id方式关闭容器
# 找到nginx对应的容器id
docker ps -a
# 关闭该容器
docker stop nginx
# 删除该容器
docker rm nginx
# 删除正在运行的nginx容器
docker rm -f nginx
执行就是运行和挂载了
docker run \
-p 80:80 --name nginx \
--privileged=true \
-v /fyeeware/nginx/conf/nginx.conf:/etc/nginx/conf \
-v /fyeeware/nginx/conf/conf.d/:/etc/nginx/conf.d \
-v /fyeeware/nginx/log:/var/log/nginx \
-v /fyeeware/nginx/html/:/usr/share/nginx/html -d nginx:1.21.6
如果你修改了nginx 但是又不想重新启动 nginx容器该怎么办呢?
docker exec 容器id nginx -s reload
docker高级篇章
MySQL主从复制章节
关于MySQL主从复制的原理 自己去了解 主从复制原理
步骤章节
-
新建一个主服务器mysql-master
命令
docker run -p 3307:3306 --name --privileged=true mysql-master \ -v /mydata/mysql-master/log:/var/log/mysql \ -v /mydata/mysql-master/data:/var/lib/mysql \ -v /mydata/mysql-master/conf:/etc/mysql \ -e MYSQL_ROOT_PASSWORD=123123 -d mysql:5.7
-
主服务器的
my.cnf
文件的配置[mysqld] ## 设置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
-
修改完成主数据库master的配置后重启容器
docker restart mysql-master
-
进入mysql-master容器
-
执行命令
docker exec -it mysql-master /bin/bash mysql -uroot -p 密码
-
问题
如果你遇到docker启动不了mysql的时候,请及时看到日志
docker logs container-name
然后你就可以看到报错日志,我这里是因为
多了空格造成识别不了。。 -
在主机上创建一个salve
## 建立一个用户 CREATE USER 'slave'@'%' IDENTIFIED BY '123456'; ## 授权 GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
-
-
新建从服务器3308
-
命令
docker run -p 3308:3306 --name mysql-slave \ -v /mydata/mysql-slave/log:/var/log/mysql \ -v /mydata/mysql-slave/data:/var/lib/mysql \ -v /mydata/mysql-slave/conf:/etc/mysql \ -e MYSQL_ROOT_PASSWORD=root \ -d mysql:5.7
-
创建my.cnf 文件
[mysqld] ## 设置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 ## 特别注意 如果你的从数据库进不去的时候!!注解掉下面的 ## skip-grant-tables
-
重启mysql-slave
-
-
查看主服务器状态
mysql> show master status; +-----------------------+----------+--------------+------------------+-------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set | +-----------------------+----------+--------------+------------------ +-------------------+ | mall-mysql-bin.000001 | 617 | | mysql | | +-----------------------+----------+--------------+------------------ +-------------------+ 1 row in set (0.00 sec)
show master status
请注意这个命令是会显示position
的所以你下面的 master_log_pos 也应该改为154 -
进入从服务器中
docker exec -it mysql-slave /bin/bash mysql-uroot -p
-
在从数据库配置主从复制
change master to master_host='192.168.1.102', master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-bin.000001', master_log_pos=617, master_connect_retry=30;
-
查看并开启主从复制
show slave status \G; *************************** 1. row *************************** Slave_IO_State: Master_Host: 192.169.1.102 Master_User: slave Master_Port: 3307 Connect_Retry: 30 Master_Log_File: mall-mysql-bin.000001 Read_Master_Log_Pos: 154 Relay_Log_File: 08f45592d575-relay-bin.000001 Relay_Log_Pos: 4 Relay_Master_Log_File: mall-mysql-bin.000001 Slave_IO_Running: No ## 注意这个 是未开启的 Slave_SQL_Running: No ## 注意这个 是未开启的
-
在从库里开启
start slave
- 补充怎么关闭slave
就是stop slave
- 补充怎么关闭slave
-
真的是错一步步步错!!!
mysql> select * from t1;
+------+------+
| id | name |
+------+------+
| 1 | jack |
+------+------+
1 row in set (0.00 sec)
分布式存储之哈希算法
哈希取余运算
- key / 3(主机数) 扩充和收缩的时候
一致性哈希算法分区
哈希槽分区
主从redis集群配置
-
新建6个docker容器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 6381 docker 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 6382 docker 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 6383 docker 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 6384 docker 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 6385 docker 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
,--name
,--privileged=true -v
不用解释了--net host
主机网络--appendonly yes
表示只能追加--cluster-enabled yes
集群打开
-
进入
redis-node-1
redis容器-
运行命令 ip地址改为你的宿主机ip
redis-cli --cluster create 192.168.1.102:6381 192.168.1.102:6382 \ 192.168.1.102:6383 192.168.1.102:6384 192.168.1.102:6385 192.168.1. \ 102:6386 --cluster-replicas 1
-
-
进入
redis-cli -p 6381
-
执行以下命令
cluster info; ## 查看集群信息 cluster nodes; ## 查看集群节点 包括master 1,2,3 分别下面挂载有谁
-
执行结果 master为你的机器是master还是slave
myself 为你进入的时候的端口redis-cli -p 6381
127.0.0.1:6381> cluster nodes bc111b1002f25c28d2a63d774357725fd79ee719 192.168.1.102:6386@16386 slave a6d85aa032edd56a5bbe99aac39a361fadfc8a31 0 1687759951497 2 connected 7207a344048e5eab3ccb1f6cf2bd7241f1037daa 192.168.1.102:6383@16383 master - 0 1687759952000 3 connected 10923-16383 8fad5af22de9b978f5118af16be950f43f2c74a8 192.168.1.102:6385@16385 slave 259f4e003138fdfe6725e77033cbf35b17b6aea3 0 1687759952504 1 connected a6d85aa032edd56a5bbe99aac39a361fadfc8a31 192.168.1.102:6382@16382 master - 0 1687759950000 2 connected 5461-10922 9f9d6944a8a3227d291d296c83b2d18e97d9736c 192.168.1.102:6384@16384 slave 7207a344048e5eab3ccb1f6cf2bd7241f1037daa 0 1687759951000 3 connected 259f4e003138fdfe6725e77033cbf35b17b6aea3 192.168.1.102:6381@16381 myself,master - 0 1687759948000 1 connected 0-5460 M S 1 - 5 2 - 6 3 - 4
-
你会发现一个error问题,因为是集群环境所有有些key存不进去
127.0.0.1:6381> set k1 v1 (error) MOVED 12706 192.168.1.102:6383
-
解决方案,启动redis-cli的时候
redis-cli -p 6381 -c
127.0.0.1:6381> set k1 v1 -> Redirected to slot [12706] located at 192.168.1.102:6383 OK
发现了什么了吗? 没错他的
slot
值是 #12706# 自动重定向到 2 号机了
因为我们是三个集群,两个两个对应,总共是 16383,2的14次方,分成三段
第一段也就是1号机 master所拥有的,[0-5460,5461-10922,10923-16383] -
经常用到的命令
redis-cli --cluster check 192.168.1.102:6381
-
关于主从服务器如果我的1号机器我的奴隶4号机会这么样呢?答案是4号机上位
docker stop redis-node-1 cluster nodes ## 但是想把1号机重新变成老大怎么办呢? 答案是 docker restart redis-node-1 ## 这个时候 一号机进入是 slave docker stop redis-node-4 ## 这个时候 1号机已从 slave变成 master docker restart redis-node-4 ## 从fail 变成 slave
-
redis集群扩容
-
需求就是增加一个主从,那么增加一个7号机作为master
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 6387 docker 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 bash redis-cli --cluster add-node 自己实际IP地址:6387 本集群:6381 redis-cli --cluster add-node 192.168.1.102:6387 192.168.1.102:6381
检查节点是否加入成功
redis-cli --cluster check 192.168.1.102:6381
-
注意没有槽位 虽然加入了但是没有重新分配
redis-cli --cluster reshard 192.168.1.102:6381 how many > 4096 16384 / 4 1364 * 3 = 4092 > 然后是你的 6387的id > yes redis-cli --cluster check 192.168.1.102:6381
所以这个是怎么分配的?是重新打散还是每个人施舍一点呢?是后者,每个人匀一点
-
-
把自己的奴隶招进来
redis-cli --cluster add-node 192.168.1.102:6388 192.168.1.102:6387 --cluster-slave --cluster-master-id f467dc87a9dfc408385685b50c75aeef539cae8b ##6387的id
然后
redis-cli --cluster check 192.168.1.102:6381
检查一下出现4M4S才是正确的
redis集群缩容
-
这个主要就是解放奴隶
命令:redis-cli --cluster del-node ip:从机端口 从机6388节点ID
redis-cli --cluster del-node 192.168.1.102:6388 d57a630b67ffdca9b7a9a06333bed3e1b2bb47bb ## 然后检查以下 > redis-cli --cluster check 192.168.1.102:6381 > 192.168.1.102:6387 (f467dc87...) -> 1 keys | 4096 slots | 0 slaves.
-
依然是重新分配
命令:redis-cli --cluster reshard 192.168.1.102:6381
> 需要给多少槽位 4096 > 需要谁来接受? 6381的槽位id > 需要谁来放血? 6387的槽位id > done > yes > redis-cli --cluster check 192.168.1.102:6381 > M: f467dc87a9dfc408385685b50c75aeef539cae8b 192.168.1.102:6387 slots: (0 slots) master > 我们发现 6387 已经没有槽位了
-
解除从机关系
命令: redis-cli --cluster del-node ip:从机端口 6387的节点id
root@hadoop102:/data# redis-cli --cluster del-node 192.168.1.102:6387 f467dc87a9dfc408385685b50c75aeef539cae8b >>> Removing node f467dc87a9dfc408385685b50c75aeef539cae8b from cluster 192.168.1.102:6387 >>> Sending CLUSTER FORGET messages to the cluster... >>> Sending CLUSTER RESET SOFT to the deleted node.
再次执行 redis-cli --cluster check 192.168.1.102:6387
发现已经没有 6387了 而6381的 已经变成 8092
Dockerfile简介
简介:以前我们也自己制作过镜像,例如我们的ubuntu容器不含有vim/ifconfig等工具的时候,我们是怎么做的?人工添加功能然后
docker commit
然后变成一个新的镜像,现在dockerfile是给你一个list清单 - 一条条构建镜像的指令和参数构成的脚本
解析
-
每条保留字指令都必须为大写字母且后面要跟随至少一个参数
-
指令按照从上到下,顺序执行
-
表示注释
-
每条指令都会创建一个新的镜像层并对镜像进行提交
大致流程
总结就是千层饼
-
docker从基础镜像运行一个容器
-
执行一条指令并对容器作出修改
-
执行类似docker commit的操作提交一个新的镜像层
-
docker再基于刚提交的镜像运行一个新容器
-
执行dockerfile中的下一条指令直到所有指令都执行完成
总结:
从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,
- Dockerfile是软件的原材料
- Docker镜像是软件的交付品
- Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。
关键字
前面说了docker里面的关键字都是纯大写,跟大部分语言一样都有保留关键字
-
FROM
基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是from -
MAINTAINER
镜像维护者的姓名和邮箱地址 -
RUN
容器构建时需要运行的命令,两种格式-
shell格式
RUN yum -y install vim
-
exec格式
命令 RUN['可执行文件','参数一','参数二']
等同于 RUN ./test.php dev offline
RUN是在 docker build时运行
-
-
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目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。 -
VOLUME
容器数据卷,用于数据保存和持久化工作 -
CMD
指定容器启动后的要干的事情
注意
Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换
参考官网Tomcat的dockerfile演示讲解
docker run -it -p 8080:8080 容器id /bin/bash 这样就不会运行了,因为覆盖了 ## 它和前面RUN命令的区别 ## CMD是在docker run 时运行。 ## RUN是在 docker build时运行。
-
ENTRYPOINT
- 也是用来指定一个容器启动时要运行的命令
- 类似于 CMD 指令,但是ENTRYPOINT不会被docker run后面的命令覆盖, 而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序
- 命令格式和案例说明
命令:ENTRYPOINT['
',' ',' ',...]
案例
这次的目的是centos vim jdk8 ifconfig jdk需要自己去网站下载要么去oracle官网要么去mirrors镜像网站
-
编写
# 宿主机上面 mkdir myfile # 把你下载的jdk包放在这个文件夹下 vim Dockerfile
Dockerfile文件内容
# 因为单纯写 centos可能会下载不了 FROM centos:7 MAINTAINER fyeeware<fyking0318@gmail.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-8u371-linux-i586.tar.gz /usr/local/java/ # 配置java环境变量 ENV JAVA_HOME /usr/local/java/jdk1.8.0_371 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:$PATH EXPOSE 80 CMD echo $MYPATH CMD echo "success--------------ok" CMD /bin/bash
宿主
# 注意最后一个点 docker build --network host -t centosjava8:1.5 . # 进入容器 docker run -it 2696dd4936dc /bin/bash # 查看你的 vim和ifconfig还有局势jdk8 java -version
-
补充如果出现虚悬镜像怎么办
命令:docker images ls -f dangling=true docker images prune
微服务jar包上传
-
自己建一个项目
- 基本的springboot项目,server-port端口是 6001 然后两个接口
-
打成jar包上传到服务器上
# 基础镜像使用java FROM java:8 # 作者 MAINTAINER fyeeware<fyking0318@gmail.com> # VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp VOLUME /tmp # 将jar包添加到容器中并更名为fyeeware_docker.jar ADD docker_boot-0.0.1-SNAPSHOT.jar fyeeware_docker.jar # 运行jar包 这是一个新建 也不知道再干嘛 # RUN bash -c 'touch /fyeeware_docker.jar' ENTRYPOINT ["java","-jar","/fyeeware_docker.jar"] #暴露6001端口作为微服务 EXPOSE 6001
-
打包运行
docker build -t fyeeware_docker:1.6 . docker run -d -p 6001:6001 fyeeware_docker:1.6
-
但是你如果直接访问的话,会超时 然后你自己运行
telnet xxx.xxx.xx.xx 6001
你会发现是超时,那就去出战/入站规则把6001端口打开
Docker网络
简介
-
在docker启动后会生成一个 docker0的虚拟网桥
systemctl start docker ifconfig [root@hadoop102 ~]# ifconfig docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255 inet6 fe80::42:96ff:fe88:d4a6 prefixlen 64 scopeid 0x20<link> ether 02:42:96:88:d4:a6 txqueuelen 0 (Ethernet) RX packets 37 bytes 3859 (3.7 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 55 bytes 8263 (8.0 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
常用命令
-
查看所有的网桥
[root@hadoop102 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 94b6a6035514 bridge bridge local 4fb807883379 host host local c99f8cbb6224 none null local
-
docker network inspect
详细信息 -
docker network create xx_network
新建 -
docker network rm xx_network
移除
能干嘛?
-
容器间的互联和通信以及端口映射
-
容器IP变动时候可以通过服务名直接网络通信而不受到影响
网络模式
-
bridge模式:使用--network bridge指定,默认使用docker0
-
host模式:使用--network host指定
-
none模式:使用--network none指定
-
container模式:使用--network container:NAME或者容器ID指定
# 创建两个ubuntu实例 docker run -it --name u1 ubuntu bash docker run -it --name u2 ubuntu bash #如果我的u2宕机了那么u2的ip会自动给到u3 docker run -it --name u3 ubuntu bash
bridge模式
你可以理解成插槽模式 宿主机上是 28 -27 那么容器就是 27-28
host本地模式
默认占用一个 自己看 和宿主机共享
docker run -d [-p 8081:8080] --name tomcat1 billygoo/tomcat8-jdk8
# 运行一次是有结果的 但是运行第二次就失败了 端口占用
none模式
自闭模式 只有lo 也就是 127.0.0.1 跟docker失去通信 需要自己去添加网卡,配置ip
container模式
寄生于已经存在的容器,和容器共享同个ip,端口范围。但是文件系统和进程都隔离的 结论限制太多,而且下方的命令运行失败,总结就是不可以
docker run -d -p 8086:8080 --network container:tomcat85 --name tomcat86 billygoo/tomcat8-jdk8
自定义模式
自定义模式就是 docker network create xxx_network
docker network create fyeeware_network
docker run -d -p 8081:8080 --network fyeeware_network --name tomcat1 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080 --network fyeeware_network --name tomcat2 billygoo/tomcat8-jdk8
docker exec -it tomcat1 bash
ping tomcat2
root@3735a95e0294:/usr/local/tomcat# ping tomcat2
PING tomcat2 (172.18.0.3) 56(84) bytes of data.
64 bytes from tomcat2.fyeeware_network (172.18.0.3): icmp_seq=1 ttl=64 time=0.093 ms
64 bytes from tomcat2.fyeeware_network (172.18.0.3): icmp_seq=2 ttl=64 time=0.072 ms
64 bytes from tomcat2.fyeeware_network (172.18.0.3): icmp_seq=3 ttl=64 time=0.081 ms
64 bytes from tomcat2.fyeeware_network (172.18.0.3): icmp_seq=4 ttl=64 time=0.063 ms
compose容器编排章节
简介就是控制容器的启动停止 跟spring容器一样,ApplicationContext.xml 是对bean对象管理而compose是对容器管理
概念
-
文件
docker-compose.yml
文件 -
两个要素
-
一个个容器实例,比如微服务容器,
mysql
容器,redis
容器 -
由一组关联应用容器组成的一个完整业务单元,在
docker-compose.yml
文件中定义
-
命令
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 # 查看容器输出日志
dokcer-compose config # 检查配置
dokcer-compose config -q # 检查配置,有问题才有输出
docker-compose restart # 重启服务
docker-compose start # 启动服务
docker-compose stop # 停止服务
使用步骤
- 编写Dockerfile 定义微服务便成为镜像
- 使用docker-compose.yml 定义一个完整单元,安排好整体应用中各个容器
- 执行 docker-compose up命令 启动,一键部署
至于你目前使用的
-
先把你的springboot 服务打包成 jar包,然后使用
docker build -t fyeeware_docker:1.7 .
-
在你的docker-compose.yml文件中写上一下内容
version: "3" services: microService: image: fyeeware_docker:1.7 container_name: ms01 ports: - "6001:6001" volumes: - /fyeeware/microService:/data networks: - atguigu_net depends_on: - redis - mysql redis: image: redis:6.0.8 ports: - "6379:6379" volumes: - /fyeeware/redis/redis.conf:/etc/redis/redis.conf - /fyeeware/redis/data:/data networks: - atguigu_net command: redis-server /etc/redis/redis.conf mysql: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: '123123' MYSQL_ALLOW_EMPTY_PASSWORD: 'no' MYSQL_DATABASE: 'db2023' MYSQL_USER: 'fyeeware' MYSQL_PASSWORD: 'fyeeware123' ports: - "3306:3306" volumes: - /fyeeware/mysql/db:/var/lib/mysql - /fyeeware/mysql/conf/my.cnf:/etc/my.cnf - /fyeeware/mysql/init:/docker-entrypoint-initdb.d networks: - atguigu_net command: --default-authentication-plugin=mysql_native_password #解决外部无法访问 networks: atguigu_net:
-
执行 docker compose config 查看是否合规
-
执行 docker compose up -d 表示后台启动
portainer 监控容器
-
下载
docker pull portainer/portainer-ce:latest docker run -d -p 8000:8000 -p 9000:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce
-
主页
命令就是 docker system df
CIG监控CAdvisor+InfluxDB+Granfana 懒得做了 以后做的着再补充把
-
在 mydocker下面建立目录 cig
-
新建一个 docker-compose.yml 用来让三个容器一起启动
-
修改 docker-compose.yml
3.架构
- c/s架构
- 用户使用
client
与docker daemon
建立通信,并发请求 docker daemon
作为主体部分,提供server
功能给接受client
请求docker engine
执行docker内部的一系列工作,每个工作都是job的形式