docker学习笔记(阳哥版)正在更新中

基础篇

1.docker介绍

容器虚拟化技术,解决了运行环境和配置问题的软件容器

镜像文件:image文件生成容器实例,本身也是一个文件,称为镜像文件

容器实例:一个容器运行一种服务,当我们需要的时候,就可以通过docker客户端创建一个对应的运行实例,也就是我们的容器仓库。

2.docker安装

docker安装方法

3.常用命令

3.1 帮助启动类命令

启动docker:systemctl start docker
停止docker:systemctl stop docker
重启docker:systemctl restart docker
查看docker状态:systemctl status docker
开机启动docker:systemctl enable docker
查看docker概要信息:docker info
查看docker总体帮助文档:docker --help
查看docker命令帮助文档:docker 具体命令 --help

3.2 镜像命令

1.列出本地主机上的镜像:docker images
option说明: -a 列出本地所有的镜像
-q 只显示镜像ID
2.搜索docker镜像:docker search 镜像名
option说明:–limit N 只列出N个镜像
docker search --limit 5 redis 只列出前五个redis镜像
3.下载镜像:docker pull 镜像名[:TAG]
option说明:没有TAG就是最新版
4.查看镜像/容器/数据卷所占的空间:docker system df
5.删除某个镜像:docker rmi 镜像ID
option说明:-f 强制删除

  • 面试题:docker虚玄镜像是什么?
    仓库名、标签名都是<none>的镜像,俗称虚玄镜像
3.3 容器指令
1.新建+启动容器:

docker run [OPTIONS] IMAGE [COMMAND] [ARG...] 启动交互式容器
option说明:
–name=“容器新名字” 为容器指定一个名称
-d 后台运行容器并返回容器ID,也即启动守护式容器(后台运行)
docker run -d 容器名

-i 以交互模式运行容器,通常与-t同时使用
-t 为容器重新分配一个伪输入终端,通常与-i同时使用,也即启动交互式容器(前台有伪终端,等待交互)
-P 随机端口映射,大写P
-p 指定端口映射,小写p
pl: docker run -it ubuntu bash 启动交互式ubuntu,要退出终端,使用exit

2.列出当前正在运行的容器:

docker ps [OPTIONS]
option说明(常用):
-a 列出当前所有正在运行的容器+历史上运行过的
-l 显示最近创建的容器
-n 显示最近n个创建的容器
-q 静默模式,只显示容器编号

3.退出容器

两种退出方式:
exit:run进去容器,exit退出,容器停止
ctrl+p+q:run进去容器,ctrl+p+q退出,容器不停止

4.启动已经停止运行的容器

docker start 容器ID或容器名

5.重启容器

docker restart 容器ID或容器名

6.停止容器

docker stop 容器ID或容器名

7.强制停止容器

docker kill 容器ID或容器名

8.删除已经停止运行的容器

docker rm 容器ID

9.查看容器日志

docker logs 容器ID

10.查看容器内运行的进程

docker top 容器ID

11.查看容器内部细节

docker inspect 容器ID

12.进入正在运行的容器并以命令行交互

1.docker exec -it 容器ID bash
2.docker attach 容器ID
推荐使用docker exec 命令,因为退出容器终端不会导致容器的停止
而使用docker attach会导致容器的停止

13.从容器中拷贝文件到主机上

容器->主机docker cp 容器ID:容器内路径 目的主机路径

14.导入和导出容器

1.export导出容器的内容作为一个tar归档文件[对应import命令]
2.import从tar包中的内容创建一个新的文件系统再导入为镜像[对应export命令]
docker export 容器ID > 文件名.tar
cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号

15.为容器重命名

docker rename 原名称 新名称

4.Docker镜像

docker镜像层都是只读的。
容器层是可写的,当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。

4.1 commit命令

docker commit提交容器副本使之成为一个新的镜像
docker commit -m = "提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]

4.2 本地镜像发布到阿里云

阿里云开发者平台
创建仓库镜像:
1.选择控制台,进入容器镜像服务
2.选择个人实例
3.创建命名空间
4.创建镜像仓库
5.进入管理界面获得脚本

4.3 本地镜像发布到私有库

1.下载镜像Docker Registry
docker pull registry

2.运行私有库Registry,相当于本地有个私有Docker hub
docker run -d -p 5000:5000 -v /zzyyuse/myregistry/:/tmp/registry --privileged=true registry
-v /zzyyuse/myregistry/:/tmp/registry --privileged=true
-v 表示指定容器卷,左侧/zzyyuse/myregistry/表示宿主机上路径
右侧/tmp/registry表示容器内路径,实现宿主机和容器内部数据的互通

3.案例演示创建一个新镜像,ubuntu安装ifconfig命令
apt-get update
apt-get install net-tools

4.curl验证私服库上有什么镜像
curl -XGET http://192.168.10.147:5000/v2/_catalog

5.将新镜像修改符合私服规范的Tag
docker tag lonelyubuntu:1.1 192.168.10.147:5000/lonelyubuntu:1.1

6.修改配置文件使之支持http
cat /etc/docker/daemon.json
vi /etc/docker/daemon.json
在这里插入图片描述

7.push推送到私服库
docker push 192.168.10.147:5000/lonelyubuntu:1.1
8.curl验证私服库上有什么镜像
curl -XGET http://192.168.10.147:5000/v2/_catalog
在这里插入图片描述
9.pull到本地并运行
docker pull 192.168.10.147:5000/lonelyubuntu:1.1

5.docker容器数据卷

容器卷记得加入 --privileged=true
有点类似redis中的aof和rdb文件
将docker容器内的数据保存进宿主机的磁盘中
运行一个带有容器卷存储功能的容器实例
docker run -d -p 5000:5000 -v /宿主机绝对路径目录:容器内目录 --privileged=true 镜像名
特点:

  • 数据卷可在容器之间共享或重用数据
  • 卷中的更改可以直接实时生效
  • 数据卷中的更改不会包含在镜像的更新中
  • 数据卷的生命周期一直持续到没有容器使用它为止
5.1 宿主vs容器之间映射添加容器卷

docker run -d -v /宿主机绝对路径目录:/容器内目录 --privileged=true 镜像名
pl:docker run -it --privileged=true -v /tmp/myHostData:/tmp/myDockerData ubuntu /bin/bash
查看数据卷是否挂载成功
docker inspect 容器ID
在这里插入图片描述

5.2 读写规则映射添加说明

1.读写(默认):
docker run -it --privileged=true -v /宿主机绝对路径:/容器内目录:rw 镜像名
rw表示容器内和宿主机都可以读写
2.只读:(要使容器内部只能读,不能写)
docker run -it --privileged=true -v /宿主机绝对路径:/容器内目录:ro 镜像名
ro表示容器内只读,宿主机可读可写

5.3 卷的继承和共享

容器1完成和宿主机的映射
docker run -it --privileged=true -v /mydocker/u:/tmp/u --name u1 ubuntu
容器2继承容器1的卷规则
docker run -it --privileged=true --volumes-from 父类 --name u2 ubuntu
–volumes-from 父类 ,父类这里为u1(容器1的名称)

6.Docker常规安装

6.1 总体步骤
  1. 搜索镜像
  2. 拉取镜像
  3. 查看镜像
  4. 启动镜像
  5. 停止容器
  6. 移除容器
6.2 安装mysql

1.拉取镜像文件:docker pull mysql:5.7
2.启动mysql:docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
3.重新进入mysql容器:docker exec -it mysql容器ID bash
4.登入mysql:mysql -uroot -p123456
5.(实际工作中使用)挂容器数据卷,使mysql数据可以持久化

docker run -d -p 3306:3306 --privileged=true 
-v /lonely/mysql/log:/var/log/mysql 
-v /lonely/mysql/data:/var/lib/mysql 
-v /lonely/mysql/conf:/etc/log/conf
-e MYSQL_ROOT_PASSWORD=123456 --name mysql mysql:5.7

进入宿主机:cd /lonely/mysql/conf/
vi my.cnf
并将如下内容写入文件

[client]
default_character_set=utf8
[mysqld]
collation_server=utf8_general_ci
character_set_server=utf8
6.3 安装redis
  1. 拉取镜像文件:docker pull redis 容器卷记得加入 --privileged=true
  2. 在centos宿主机下新建目录/app/redis mkdir -p /app/redis
  3. 将一个redis.conf文件模板拷贝进/app/redis目录下
    cp /myredis/redis.conf /app/redis/
  4. /app/redis目录下修改redis.conf文件
    1.开启redis验证requirepass 123
    2.允许redis外地连接:必须注释掉#bind 127.0.0.1
    3.daemonize no将daemonize yes注释起来或者daemonize no设置,因为该配置和docker run中-d参数冲突,会导致容器一直启动失败。
    另外,一定要用对应版本的conf文件,否则会导致意想不到的结果。
  5. 运行镜像
    docker run -p 6379:6379 --name lonelyredis --privileged=true -v /app/redis/redis.conf:/etc/redis/redis.conf -v /app/redis/data:/data -d redis redis-server /etc/redis/redis.conf
  6. 测试redis-cli连接上来
    docker exec -it 容器ID bash

高级篇

1.安装mysql主从复制

1.1 新建主服务器容器实例3307
docker run -d -p 3307:3306 --privileged=true 
-v /mysqldata/mysql-master/log:/var/log/mysql 
-v /mysqldata/mysql-master/data:/var/lib/mysql 
-v /mysqldata/mysql-master/conf:/etc/mysql
-e MYSQL_ROOT_PASSWORD=123456 --name mysql-master mysql:5.7
1.2 进入 /mydata/mysql-master/conf目录下新建my.cnf

cd /mydata/mysql-master/conf/
vi 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
1.3 修改完配置后重启master实例

docker restart mysql-master

1.4 进入mysql-master容器

docker exec -it mysql-master /bin/bash
mysql -uroot -p123456 输入用户和密码登录mysql

1.5 master容器实例内创建数据同步用户

1.CREATE USER 'slave'@'%' IDENTIFIED BY '123456'; 创建用户
2.GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%'; 授予权限

1.6 新建从服务器容器实例3308
docker run -d -p 3308:3306 --privileged=true 
-v /mydata/mysql-slave/log:/var/log/mysql 
-v /mydata/mysql-slave/data:/var/lib/mysql 
-v /mydata/mysql-slave/conf:/etc/log/conf 
-e MYSQL_ROOT_PASSWORD=123456 --name mysql-slave mysql:5.7
1.7 进入/mydata/mysql-slave/conf目录下新建my.cnf

cd /mydata/mysql-master/conf/
vi my.cnf
输入内容:

[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id = 102
## 指定不需要同步的数据库名称
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
## relay_log配置中继日志
relay_log=mall-mysql-relay-bin
## log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1
## slave设置为只读(具有super权限的用户除外)
read_only=1

1.8 修改完配置后重启slave实例

docker restart mysql-slave

1.9 在主数据库中查看主从同步状态

show master status;
在这里插入图片描述

1.10 进入mysql-slave容器

docker exec -it mysql-slave /bin/bash 进入mysql-slave容器
mysql -uroot -p123456 登入mysql

1.11 在从数据库中配置主从复制

change master to master_host = '宿主机ip' , master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-bin.000001', master_log_pos=617, master_connect_retry=30;
参数说明:
master_host:主数据库的IP地址
master_port:主数据库的运行端口
master_user:在主数据库创建的用于同步数据的用户账号
master_password:在主数据库创建的用于同步数据的用户密码
master_log_file:指定从数据库要复制数据的日志文件,通过查看主数据的状态,获取File参数
master_log_pos:指定从数据库从哪个位置开始复制数据,通过查看主数据的状态获取Position参数
master_connect_retry:连接失败重试的时间间隔,单位为秒

1.12 在从数据库中查看主从同步状态

show slave status \G;
在这里插入图片描述

1.13 在从数据库中开启主从同步

start slave;

1.14 查看从数据库状态发现已经同步

show slave status \G;
在这里插入图片描述

1.15 主从同步测试

主机添加数据:
在这里插入图片描述
从机同步数据:
在这里插入图片描述

2.安装redis集群(大厂面试题第四季-分布式存储案例真题)

2.1 1~2亿条数据需要缓存,请问如何设计这个存储案例(本章建议直接看原视频)

分布式存储

哈希取余分区

在这里插入图片描述

        2亿条数据就是2亿个k,v,单机处理不太行,需要分布式多机,假设有3台机器构成一个集群,用户每次读写操作都是根据公式:hash(key)%N个机器台数,计算出哈希值,用来决定数据映射到哪一个节点上。
        优点:简单,直接有效,只需要预估好数据规划好节点,就能保证一段时间的数据支撑。使用hash算法让固定的一部分请求落在同一台服务器上,这样没台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡+分而治之的作用。
        缺点:原来规划好的节点,进行扩容或者容缩就比较麻烦了,不管扩缩,每次数据变动导致节点有变动,映射关系需要重新进行计算,在服务器个数固定不变时没有问题,如果需要弹性扩容或故障停机的情况下,原来的取模公式就会发生变化:hash(key)%3会变成hash(key)%?。此时地址经过取余运算的结果将会发生很大变化,根据公式获取的服务器也会变得不可控。
某个redis机器宕机了,由于台数数量变化,会导致hash取余全部数据重新洗牌。

一致性哈希算法分区

        设计目标是为了解决分布式缓存数据变动和映射问题,提出一致性hash解决方案,目的是当服务器个数发生变动时,尽量减少影响客户端到服务器的映射关系。
        3大步骤:1.算法构建一致性哈希环
                         2.服务器IP节点映射
                         3.key落到服务器的落键规则
优点:容错性,扩展性
缺点:一致性哈希算法的倾斜问题

哈希槽分区

1.为什么会出现:一致性哈希算法的数据倾斜问题,哈希槽实质就是一个数组,数组[0,2^14-1]形成hash slot空间。
2.解决均匀分配的问题,在数据和节点之间又加入了一层,把这层称为哈希槽(slot),用于管理数据和节点之间的关系,现在就相当于节点上放的是槽,槽里放的是数据。
3.多少个hash槽,一个集群只能有16384个槽(0~16383),这些槽会分配给集群中的所有主节点,分配策略没有要求。可以指定哪些编号的槽分配给那个主节点。集群会记录节点和槽的对应关系。解决了节点和槽关系后,接下来就需要对key求hash值,然后对16384取余,余数是几就落入对应的槽里。slot=CRC16(key)%16384。以槽为单位移动数据,因为槽的数目是固定的,处理起来比较容易,这样数据移动问题就解决了。

2.2 三主三从redis集群扩缩容

1.端口及主从说明(内部分配应该是随机的)

在这里插入图片描述

2.redis集群配置
1.关闭防火墙+启动docker服务

service iptables stop 关闭防火墙
systemctl start docker 启动docker服务

2.新建6个docker容器实例

1.docker run -d --name redis-node-1 --net host --privileged=true -v /data/redis/share/redis-node-1:/data redis:7.0.9 --cluster-enabled yes --appendonly yes --port 6381
2.docker run -d --name redis-node-2 --net host --privileged=true -v /data/redis/share/redis-node-2:/data redis:7.0.9 --cluster-enabled yes --appendonly yes --port 6382
3.docker run -d --name redis-node-3 --net host --privileged=true -v /data/redis/share/redis-node-3:/data redis:7.0.9 --cluster-enabled yes --appendonly yes --port 6383
4.docker run -d --name redis-node-4 --net host --privileged=true -v /data/redis/share/redis-node-4:/data redis:7.0.9 --cluster-enabled yes --appendonly yes --port 6384
5.docker run -d --name redis-node-5 --net host --privileged=true -v /data/redis/share/redis-node-5:/data redis:7.0.9 --cluster-enabled yes --appendonly yes --port 6385
6.docker run -d --name redis-node-6 --net host --privileged=true -v /data/redis/share/redis-node-6:/data redis:7.0.9 --cluster-enabled yes --appendonly yes --port 6386
参数说明:
–cluster-enabled 表示是否开启集群
–appendonly 表示是否开启持久化
运行以上命令以后使用docker ps查看一下:
在这里插入图片描述

3.进入容器redis-node-1并为6台机器构建集群关系(以一台主机为例)
进入容器:docker exec -it redis-node-1 /bin/bash
构建主从关系:

进入docker容器后才能执行以下命令,注意要改成自己的IP地址
redis-cli --cluster create 192.168.10.149:6381 192.168.10.149:6382 192.168.10.149:6383 192.168.10.149:6384 192.168.10.149:6385 192.168.10.149:6386 --cluster-replicas 1
–cluster-replicas 1 表示为每个master创建一个slave节点
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.3 主从容错迁移案例

1.数据读写存储

启动6机构成的集群并通过exec进入
docker exec -it redis-node-1 /bin/bash
对6381新增两个key
redis-cli -p 6381 连上6381机器
set k1 v1 新增key-value
在这里插入图片描述
防止路由失效加参数-c并新增两个key
redis-cli -p 6381 -c
-c 表示以集群环境打开redis
在这里插入图片描述
查看集群信息
redis-cli --cluster check 192.168.10.149:6381
在这里插入图片描述

2.容错切换迁移

在这里插入图片描述

1.主机6381和从机切换,先停止主机6381

docker stop redis-node-1

2.再次查看集群信息

docker exec -it redis-node-2 /bin/bash 进入2号主机容器
redis-cli -p 6382 -c 进入redis集群
cluster nodes 查看节点信息
在这里插入图片描述

3.先还原之前的三主三从

docker start redis-node-1 启动已经关闭的redis主机1容器
docker exec -it redis-node-2 /bin/bash 进入redis集群
cluster nodes 查看集群状态(发现原来宕机的redis主机1已经变成了从机)
在这里插入图片描述
一般重启原来的主机以后还是要让原来宕机的主机作为主机而不是从机
先启动redis主机1(6381)docker start redis-node-1
再停掉原来的redis从机(6384)docker stop redis-node-4
再启动6384 docker start redis-node-4

4.查看集群状态

在这里插入图片描述
此时发现主机1(6381)再次成为了主机
重启6384
在这里插入图片描述
发现6384又变成了从机
总结:主机1宕机,从机4上位成为主机,主机1开机成为了从机,想要使原来的主机1还是主机,4号机继续做从机,需要关闭4号机,再开启4号机。

2.4 主从扩容需求分析

三主三从不够用,需要再添加一主一从。

1.新建6387、6388两个节点,新建后启动,查看是否8节点

1.docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/share/redis-node-7:/data redis:7.0.9 --cluster-enabled yes --appendonly yes --port 6387
2.docker run -d --name redis-node-8 --net host --privileged=true -v /data/redis/share/redis-node-8:/data redis:7.0.9 --cluster-enabled yes --appendonly yes --port 6388

2.进入6387容器实例内部

docker exec -it redis-node-7 bash

3.将新增的6387节点(空槽号)作为master节点加入原集群

容器内容运行命令:
redis-cli --cluster add-node 192.168.10.149:6387 192.168.10.149:6381
将新增的6387作为master节点加入集群
redis-cli --cluster add-node 自己实际IP地址:6387 自己实际IP地址:6381
6387就是将要作为master新增节点
6381就是原来集群节点里面的领路人,相当于6387拜拜6381的码头从而找到组织加入集群
在这里插入图片描述

4.检查集群情况

redis-cli --cluster check 192.168.10.149:6381
在这里插入图片描述

5.重新分派槽号

redis-cli --cluster reshard IP地址:端口号
redis-cli --cluster reshard 192.168.10.149:6381
在这里插入图片描述
输入4096(因为槽位从0~16383也就是16384个槽位,除以4得到4096)
在这里插入图片描述
ID要填入新加入节点的ID
在这里插入图片描述
最后填入all
在这里插入图片描述

6.检查集群情况

redis-cli --cluster check 192.168.10.149:6381
在这里插入图片描述
重新分配后单个节点的槽位号不一定是一整块连续的,可能分为几个区间

7.为主节点6387分配从节点6388

redis-cli --cluster add-node ip:新slave端口 ip:新master端口 --cluster-slave --cluster-master-id 新主机节点ID
根据自己实际ID和IP及端口号修改即可
redis-cli --cluster add-node 192.168.10.149:6388 192.168.10.149:6387 --cluster-slave --cluster-master-id d0e707592e93ce68aa915fd1d261be134e962048

8.检查集群情况

redis-cli --cluster check 192.168.10.149:6382
在这里插入图片描述
可以看到6387对应的从机也添加成功

2.5 主从缩容案例

删除6387主机和6388从机,恢复3主3从。

1.先删除6388从机

redis容器内执行以下命令:
redis-cli --cluster del-node IP:端口 6388节点ID
根据自己情况修改即可
redis-cli --cluster del-node 192.168.10.149:6388 1278a9ac9cde8dbf2e62368093cbf7a241aafc00
在这里插入图片描述

2.清出来的槽位重新分配

redis-cli --cluster reshard 192.168.10.149:6381
与扩容时槽位分配类似,但有所不同
在这里插入图片描述
查看集群情况
redis-cli --cluster check 192.168.10.149:6381
在这里插入图片描述

3.再删除6387

redis-cli --cluster del-node IP:端口 6388节点ID
在这里插入图片描述

4.恢复成3主3从

在这里插入图片描述

3.DockerFile

DockerFile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的文本。
DockerFile官网
构建三步骤:
1.编写DockerFile文件
2.docker build命令构建镜像
3.docker run依照镜像运行容器实例

1.DockerFile内容基础知识

1.每条保留字指令都必须为大写字母且后面要跟随至少一个参数
2.指令按照从上到下,顺序执行
3.#表示注释
4.每条指令都会创建一个新的镜像层并对镜像进行提交

2.Docker执行DockerFile的大致流程

1.docker从基础镜像运行一个容器
2.执行一条指令并对容器作出修改
3.执行类似docker commit的操作提交一个新的镜像层
4.docker再基于刚提交的镜像运行一个新容器
5.执行dockerfile中的下一条指令直到所有指令都执行完成

3.DockerFile常用保留字指令
1.FROM

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

2.MAINTAINER

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

3.RUN

容器构建时需要运行的命令
两种格式:

  • shell格式:RUN shell命令
  • exec格式:RUN ["可执行文件","参数1","参数2"]
    RUN是在docker build时运行
4.EXPOSE

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

5.WORKDIR

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

6.USER

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

7.ENV

用来在构建镜像过程中设置环境变量

8.ADD

将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包

9.COPY

类似ADD,拷贝文件和目录到镜像中。将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>

10.VOLUME

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

11.CMD

指定容器启动后的要干的事情
CMD指令的格式和RUN类似,也是两种格式:

  • shell格式:CMD <命令>
  • exec格式:CMD ["可执行文件","参数1","参数2"]
  • 参数列表格式:CMD ["参数1","参数2"]。在指定了ENTRYPOINT指令后,用CMD指定具体的参数
    注意:Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换
12.ENTRYPOINT

也是用来指定一个容器启动时要运行的命令
类似于CMD指令,但是ENTRYPOINT不会被docker run后面的指令覆盖,而且这些命令行参数会被当做参数送给ENTRYPOINT指令指定的程序
命令格式:ENTRYPOINT ["<executeable>","<param1>","<param2>"]
ENTRYPOINT可以和CMD一起用,一般是变参才会使用CMD,这里的CMD等于是在给ENTRYPOINT传参。
当指定了ENTRYPOINT后,CMD的含义就发生了变化,不再是直接运行其命令而是将CMD的内容作为参数传递给ENYRYPOINT指令,他两个组合会变成<ENTRYPOINT>“<CMD>”
案例如下:假设已通过DockerFile构建了nginx:test镜像:

  FROM nginx
  ENTRYPOINT ["nginx","-c"]  #定参
  CMD ["/etc/nginx/nginx.conf"] #变参
是否传参按照dockerfile编写执行传参运行
Docker命令docker run nginx:testdocker run nginx:test -c /etc/nginx/new.conf
衍生出的实际命令nginx -c /etc/nginx/nginx.confnginx -c /etc/nginx/new.conf
4.自定义镜像mycentosgo1.19

要求:Centos镜像具备vim+ifconfig+go1.19(不想用java,只能用go来代替)
1.新建文件夹myfile
2.编写Dockerfile文件
vim Dockerfile

FROM centos:7
MAINTAINER lonely<2925028830@qq.com>

ENV MYPATH /usr/local
WORKDIR $MYPATH

# 安装vim编辑器
RUN yum -y install vim
RUN yum -y install net-tools

# 安装go1.19及lib库
RUN yum -y install glibc.i686
RUN mkdir /usr/local/go1.19
# ADD 是相对路径,把go1.19.linux-amd64.tar.gz添加到容器中,而且会自动解压压缩包,安装包必须要和DockerFile文件在同一位置
ADD go1.19.linux-amd64.tar.gz /usr/local/go1.19
#配置go环境变量
ENV GOROOT=/usr/local/go1.19/go
RUN mkdir /usr/local/goprojects
ENV GOPATH=/usr/local/goprojects
ENV PATH=$PATH:$GOROOT/bin
ENV GO111MODULE=on
ENV GOPROXY=https://goproxy.cn,direct
EXPOSE 80
CMD echo $MYPATH
CMD echo "success-------ok"
CMD /bin/bash

3.构建
docker build -t 新镜像名字:TAG .
注意,上面TAG后面有个空格,有个点
在这里插入图片描述
进入容器并运行相关命令测试,发现已经可用
在这里插入图片描述
虚玄镜像:在Dockerfifile中编写
vim Dockerfile

FROM ubuntu
CMD echo "action is success"

docker build .
docker images查看镜像
在这里插入图片描述

查看虚玄镜像docker image ls -f dangling=true
在这里插入图片描述
删除虚玄镜像:docker image prune
在这里插入图片描述

5.新建微服务并发布部署到docker容器

1.编写微服务程序
用go随便写了个接口

package main

import (
	"fmt"
	"time"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()
	r.GET("/home", func(ctx *gin.Context) {
		ctx.String(200, "you can access it")
	})
	r.GET("/timestamp", func(ctx *gin.Context) {
		timestamp := time.Now()
		ctx.JSON(200, map[string]interface{}{
			"success": true,
			"msg":     timestamp,
		})
	})
	fmt.Println("正在监听")
	r.Run()  //默认在8080上运行
}

2.编写Dockerfile

FROM golang:1.19

RUN go env -w GO111MODULE=on
RUN go env -w GOPROXY=https://goproxy.cn,direct

MAINTAINER lonely
WORKDIR /home/workspace
ADD . /home/workspace
RUN go mod init gin_microservice
RUN go mod tidy
RUN go get -u github.com/gin-gonic/gin
RUN cd ./gin_microservice
RUN go build -o app ./gin_microservice/main/main.go
EXPOSE 8899

ENTRYPOINT ["./gin_microservice/app"]

3.构建容器
docker build -t gin_micro:1.19 .
在这里插入图片描述
4.运行容器
docker run -d -p 8080:8080 gin_micro
在这里插入图片描述

5.访问测试
访问成功,获取到结果
在这里插入图片描述

4.network

network能干吗?
容器间的互联和通信以及端口映射
容器IP变动时候可以通过服务名直接网络通信而不受到影响

1.network是什么?

docker不启动:默认网络情况
在这里插入图片描述
docker启动后,网络情况
在这里插入图片描述

2.network常用命令

查看docker network命令帮助信息:docker network --help
在这里插入图片描述

查看docker网络:docker network ls
创建一个网络:docker network create net_name
删除一个网络:docker network rm net_name
查看网络数据源:docker network inspect net_name

3.网络模式
网络模式简介
bridge为每一个容器分配、设置IP等,并将容器连接到一个docker0
虚拟网桥,默认为该模式
host容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口
none容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair和网桥连接,IP等
container新创建的容器不会创建自己的网卡和配置自己的IP,而是和一个指定的容器共享IP、端口范围等

bridge模式:--network bridge,默认使用docker0
host模式:--network host指定
none模式:--network none指定
container模式:--network container:Name或容器ID
自定义网络模式:--network 自定义网络名,自定义网络本身就维护好了主机名和ip的对应关系(ip和域名都能通)

4.network底层和容器映射变化

启动两个ubuntu
docker run -it --name u1 ubuntu bash
docker run -it --name u2 ubuntu bash
查看它们的ip
在这里插入图片描述
在这里插入图片描述
我们发现u1的ip为172.17.0.2,u2的ip为172.17.0.3,如果我们把u2移除docker rm -f u2
再新建一个容器:docker run -it --name u3 ubuntu bash
查看u3的ipdocker inspect u3 |tail -n 20
在这里插入图片描述
发现其ip地址也为172.17.0.3,仿佛和u2冲突,但u2已经被删除,说明docker容器内部的ip是有可能发生改变的

5.Docker-compose容器编排

docker-compose是docker官方的开源项目,负责实现对docker容器集群的快速编排。需要定义一个YAML格式的配置文件,docker-compose.yml,写好多个容器之间的调用关系,然后,只要一个命令,就能同时启动/关闭这些容器。
compose允许用户通过一个单独的docker-compose.yml模板文件来定义一组相关联的应用容器为一个项目。

1.compose下载

官网
官网下载
1.对于Ubuntu 和Debian, 运行:

sudo apt-get update
sudo apt-get install docker-compose-plugin

2.对于以RPM为基础的发行版本(如centos), 运行:

 sudo yum update
 sudo yum install docker-compose-plugin

看看compose是否安装成功:docker compose version
当然,如果你想手动安装,可以去官网查看安装方法

2.compose核心概念

一文件:docker-compose.yml
两要素:

  • 服务(service)一个个应用容器实例,比如订单微服务,mysql容器,nginx容器
  • 工程(project)由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml文件中定义
3.docker-compose使用的三个步骤
  • 编写Dockerfile定义各个微服务应用并构建出对应的镜像文件
  • 使用docker-compose.yml定义一个完整业务单元,安排好整体应用中的各个容器服务
  • 最后,执行docker-compose up命令来启动并运行整个应用程序,完成一键部署上线
4.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 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 停止服务

5.compose编排微服务

编写docker-compose.yml文件

version:"3" #版本

services:
 microService:
  image:zzyy_docker:1.6 #指定镜像名
  container_name:ms01   #容器名
  ports:    #运行容器时的端口映射
  - "6001:6001"
  volumes:  #容器运行时指定容器数据卷
  - /app/microService:/data
  networks:  # 指定网络
  - lonely_net
  depends_on:   #依赖
  - redis
  - mysql
 redis:
  image:redis:7.0.9
  ports:
   - "6379:6379"
  volumes:
   - /app/redis/redis.conf:/etc/redis/redis.conf
   - /app/redis/data:/data
  networks:
   - lonely_net
 command: redis-server /etc/redis/redis.conf
 mysql:
  image:mysql:5.7
  envieonment:
   MYSQL_ROOT_PASSWORD:'292502'
   MYSQL_ALLOW_EMPTY_PASSWORD :'no'
   MYSQL_DATABASE:'lonely_db'
   MYSQL_USER:'lonely'
   MYSQL_PASSWORD:'292502'
  ports:
   - "3306:3306"
  volumes:
   - /app/mysql/db:/var/lib/mysql
   - /app/mysql/conf/my.cnf:/etc/my.cnf
   - /app/mysql/init:/docker-entrypoint-initdb.d
  networks:
   - lonely_net
  command:
   --default-authentication-plugin=mysql_native_password  #解决外部无法访问

networks:    #创建一个网络,lonely_net
  lonely_net:

持续学习中。。。

  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值