docker学习笔记

Docker笔记

1.和传统虚拟机的区别

  • size小
  • 速度快
  • 复杂度

2.安装

借机生蛋

window - virtual machine - docker

docker 的基本组成

  • 镜像 image 以Java来举例的话就是 Java类的类模板,只是一个只读的模板。镜像可以用来创建docker容器,一个镜像可以创建很多很多容器。
  • 容器 contain 以Java来举例的话就是new Java类的实体, 容器里面是 需要的linux环境建议版本,包括root用户权限,进程,用户空间,网络空间 还有就是运行的程序
  • 仓库 repository 存放镜像的地方,暂时把它称为集合

安装配置

  1. 确定你是centos7

  2. 卸载旧版本

  3. yum安装gcc相关

    # gcc
    yum -y install gcc
    yum -y install gcc-c++
    # yum-utils
    yum -y install yum-utils
    
  4. 设置stable仓库

    yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
  5. 然后更新一下 yum makecache fast

  6. 安装docker引擎

    sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
    
  7. 启动测试

    systemctl start docker
    docker version
    docker run hello-world
    
  8. 如果你遇到以下 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
    
  9. 然后配置阿里云的加速器

    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
    
  10. 卸载

    #停止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 容器iddocker stop 容器iddocker 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出来一个对象

docker镜像的样子


看一下图

当你下载镜像的时候,里面就包括了 bootfsrootfs

在bootfs 上有 基础的镜像,然后当你的镜像run之后在镜像的顶部会有一个容器,容器时可读可写的。

小栗子:

当我们想在这个 ubuntu容器上装一个vim工具的时候发现了很傻逼的问题,但是百度上面搜出来的答案都是无用的

apt-get出错截图

因为什么呢?就是因为网络,但是我们尝试了在 /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":[]}


  1. 运行你的ubuntu

       docker run -it --name="myubuntu" ubuntu /bin/bash 
    
       apt-get update
       apt-get install -y net-tools  #安装net-tools
    
  2. 然后 ctrl+q+p也好 exit 也好

  3. 然后commit 把这个镜像上传

       docker commit -m 'ubuntu with ifconfig' -a 'fyeeware' 容器的id 别名:tag
    
  4. 然后按照他需要的格式采取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

docker挂载


特别提示如果你的容器的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主从复制的原理 自己去了解 主从复制原理
步骤章节

  1. 新建一个主服务器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
    
  2. 主服务器的 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
    
  3. 修改完成主数据库master的配置后重启容器
    docker restart mysql-master

  4. 进入mysql-master容器

    1. 执行命令

         docker exec -it mysql-master /bin/bash
         mysql -uroot -p 密码
      
    2. 问题
      如果你遇到docker启动不了mysql的时候,请及时看到日志
      docker logs container-name然后你就可以看到报错日志,我这里是因为
      多了空格造成识别不了。。

    3. 在主机上创建一个salve

         ## 建立一个用户
         CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
         ## 授权
         GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
      
  5. 新建从服务器3308

    1. 命令

         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
      
    2. 创建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
      
    3. 重启mysql-slave

  6. 查看主服务器状态

          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

  7. 进入从服务器中 docker exec -it mysql-slave /bin/bash mysql-uroot -p

  8. 在从数据库配置主从复制

       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;
    
  9. 查看并开启主从复制

       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  ## 注意这个 是未开启的   
    
    
  10. 在从库里开启 start slave

    1. 补充怎么关闭slave
      就是stop slave
  11. 真的是错一步步步错!!!

   mysql> select * from t1;
      +------+------+
      | id   | name |
      +------+------+
      |    1 | jack |
      +------+------+
      1 row in set (0.00 sec)

分布式存储之哈希算法

哈希取余运算

  1. key / 3(主机数) 扩充和收缩的时候

一致性哈希算法分区

哈希槽分区

主从redis集群配置

  1. 新建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
    
  2. 解释一下命令

    • docker run--name--privileged=true -v 不用解释了
    • --net host 主机网络
    • --appendonly yes 表示只能追加
    • --cluster-enabled yes 集群打开
  3. 进入 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
      
  4. 进入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
      redis集群检查

    • 关于主从服务器如果我的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集群扩容

  1. 需求就是增加一个主从,那么增加一个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
    
  2. 然后就是拜码头 - 认识一下集群第一个老大

       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
    

    7号机加入群成功


    检查节点是否加入成功 redis-cli --cluster check 192.168.1.102:6381
    7号机加入集群检查

    • 注意没有槽位 虽然加入了但是没有重新分配

         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
      

      所以这个是怎么分配的?是重新打散还是每个人施舍一点呢?是后者,每个人匀一点

  3. 把自己的奴隶招进来

    
       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集群缩容

  1. 这个主要就是解放奴隶

    命令: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.
    
  2. 依然是重新分配

    命令: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 已经没有槽位了
    
    
  3. 解除从机关系

    命令: 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清单 - 一条条构建镜像的指令和参数构成的脚本

解析

  1. 每条保留字指令都必须为大写字母且后面要跟随至少一个参数

  2. 指令按照从上到下,顺序执行

  3. 表示注释

  4. 每条指令都会创建一个新的镜像层并对镜像进行提交

大致流程

总结就是千层饼

  1. docker从基础镜像运行一个容器

  2. 执行一条指令并对容器作出修改

  3. 执行类似docker commit的操作提交一个新的镜像层

  4. docker再基于刚提交的镜像运行一个新容器

  5. 执行dockerfile中的下一条指令直到所有指令都执行完成

总结
从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,
- Dockerfile是软件的原材料
- Docker镜像是软件的交付品
- Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。
img

关键字

前面说了docker里面的关键字都是纯大写,跟大部分语言一样都有保留关键字

  1. FROM
    基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是from

  2. MAINTAINER
    镜像维护者的姓名和邮箱地址

  3. RUN
    容器构建时需要运行的命令,两种格式

    • shell格式

         RUN yum -y install vim
      
    • exec格式

      命令 RUN['可执行文件','参数一','参数二']
      等同于 RUN ./test.php dev offline
      RUN是在 docker build时运行

  4. EXPOSE
    当前容器对外暴露出的端口

  5. WORKDIR
    指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点

  6. USER
    指定该镜像以什么样的用户去执行,如果都不指定,默认是root

  7. ENV
    用来在构建镜像过程中设置环境变量
    注意

    ENV MY_PATH /usr/mytest
    这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;
    也可以在其它指令中直接使用这些环境变量,

    比如:WORKDIR $MY_PATH

  8. ADD
    将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包 一般用这个

  9. COPY
    类似ADD,拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置
    COPY src dest
    COPY ["src", "dest"]
    <src源路径>:源文件或者源目录
    <dest目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。

  10. VOLUME
    容器数据卷,用于数据保存和持久化工作

  11. CMD
    指定容器启动后的要干的事情
    img
    注意
    Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换
    参考官网Tomcat的dockerfile演示讲解
    img

       docker run -it -p 8080:8080 容器id /bin/bash
       这样就不会运行了,因为覆盖了
       ## 它和前面RUN命令的区别
       ## CMD是在docker run 时运行。
       ## RUN是在 docker build时运行。
    
  12. ENTRYPOINT
    - 也是用来指定一个容器启动时要运行的命令
    - 类似于 CMD 指令,但是ENTRYPOINT不会被docker run后面的命令覆盖, 而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序
    - 命令格式和案例说明

命令:ENTRYPOINT['','','',...]

entrypoint截图

案例

这次的目的是centos vim jdk8 ifconfig jdk需要自己去网站下载要么去oracle官网要么去mirrors镜像网站

  1. 编写

       # 宿主机上面
       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
    
  2. 补充如果出现虚悬镜像怎么办

    命令:docker images ls -f dangling=true docker images prune

微服务jar包上传

  1. 自己建一个项目

    • 基本的springboot项目,server-port端口是 6001 然后两个接口
  2. 打成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
    
  3. 打包运行

       docker build -t fyeeware_docker:1.6 .
       docker run -d -p 6001:6001 fyeeware_docker:1.6
    
  4. 但是你如果直接访问的话,会超时 然后你自己运行 telnet xxx.xxx.xx.xx 6001 你会发现是超时,那就去出战/入站规则把6001端口打开

Docker网络

简介

  1. 在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
    

常用命令

  1. 查看所有的网桥

    [root@hadoop102 ~]# docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    94b6a6035514   bridge    bridge    local
    4fb807883379   host      host      local
    c99f8cbb6224   none      null      local
    
  2. docker network inspect 详细信息

  3. docker network create xx_network 新建

  4. 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

img

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是对容器管理

概念

  1. 文件 docker-compose.yml 文件

  2. 两个要素

    • 一个个容器实例,比如微服务容器,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      # 停止服务

使用步骤

  1. 编写Dockerfile 定义微服务便成为镜像
  2. 使用docker-compose.yml 定义一个完整单元,安排好整体应用中各个容器
  3. 执行 docker-compose up命令 启动,一键部署

至于你目前使用的

  1. 先把你的springboot 服务打包成 jar包,然后使用docker build -t fyeeware_docker:1.7 .

  2. 在你的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:
    
  3. 执行 docker compose config 查看是否合规

  4. 执行 docker compose up -d 表示后台启动

portainer 监控容器

  1. 下载

    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
    
  2. 主页

命令就是 docker system df
img

CIG监控CAdvisor+InfluxDB+Granfana 懒得做了 以后做的着再补充把

  1. 在 mydocker下面建立目录 cig

  2. 新建一个 docker-compose.yml 用来让三个容器一起启动

  3. 修改 docker-compose.yml

3.架构

  1. c/s架构
  2. 用户使用clientdocker daemon 建立通信,并发请求
  3. docker daemon 作为主体部分,提供server功能给接受client请求
  4. docker engine 执行docker内部的一系列工作,每个工作都是job的形式
posted @ 2023-06-23 13:36  周三周四  阅读(15)  评论(0)    收藏  举报