目录
简介
安装
基础使用
1.帮助启动类命令
启动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
2.镜像命令
列出本地主机上的镜像
docker images
-a 列出本地所有镜像(含历史映象层)
-q 只显示镜像ID
查找某个镜像
docker search 某镜像名称
--limit N 只列出N个镜像(默认25个)
拉取某个镜像
docker pull 某镜像名称/某镜像名称:TAG (docker pull redis:6.0.8)
查看镜像/容器/数据卷所占的空间
docker system df
docker rmi 某镜像ID
-f 强制删除
docker中 删除所有的镜像
docker rmi -f $(docker images -aq)
3.容器命令
新建启动容器
docker run OPTIONS 镜像名:TAG
OPTIONS:
--name 指定容器名称
-d 后台运行容器并返回容器ID,守护式容器
-i 以交互式模型运行容器 通常与-t同时使用
-t 为容器重新分配一个伪输入终端,通常与-i同时使用
(docker run -it centos /bin/bash)
-P 大写P 随机端口映射
-p 小写p 指定端口映射(-p 8080:80)
查看所有运行的容器
docker ps OPTIONS
OPTIONS:
-a 列出当时运行的和历史运行的所有容器
-l 显示最近创建的容器
-n 显示最近n个创建的容器
-q 只显示容器ID
退出容器
docker run -it 进去的容器,
使用exit退出并停止容器
使用ctrl + p + q退出但不停止容器
启动已停止的容器
docker start 容器ID或名称
启动所有容器
docker start $(docker ps -aq)
启动所有状态为exited 的容器
docker start $(docker ps -aq -f status=exited)
重启容器
docker restart 容器ID或名称
停止容器
docker stop 容器ID或名称
停止所有容器
docker stop $(docker ps -aq)
强制停止容器
docker kill 容器ID或名称
删除已停止的容器
docker rm OPTIONS 容器ID
OPTIONS:
-f 强制删除
删除所有容器
docker rm -f $(docker ps -aq)
--------DEMO--------
docker pull redis
docker run -d redis
docker ps
查看容器日志
docker logs 容器ID
查看容器内运行的进程
docker top 容器ID
查看容器内部细节
docker inspect 容器ID
进入正在运行的容器并以命令行交互
docker exec -it 容器ID /bin/bash (exit退出不会停止容器)
docker attach 容器ID (exit退出,会停止容器,不推荐使用)
从容器内拷贝文件到主机上
docker cp 容器ID:容器内路径 目的主机路径
导出容器为tar文件
docker export 容器ID > 文件名.tar
将tar文件导出为镜像
cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号
提交容器副本使之成为一个新的镜像
docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:TAG
4.联合文件系统
联合文件系统UnionFS,分层的轻量级文件系统,加载简单 资源复用
5.发布镜像到云上(略)
拉取阿里云镜像到本地
6.搭建私有docker仓库(略)
docker pull registry
运行私有仓库registry,相当于本地有一个私有Docker hub
7.docker容器数据卷
容器内的数据备份+持久化到本地主机目录
docker run -d -p 8080:80 -v /宿主机路径:/容器内路径 --privileged=true 镜像名
-v 添加自定义容器卷映射
--privileged = true,扩大容器的权限解决挂载目录没有权限的问题。也即使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通的用户权限。
读写规则
默认规则:同时支持读写: -v /宿主机路径:/容器内路径:rw
容器内部实例被限制,只能读不能写: -v /宿主机路径:/容器内路径:ro
新的容器 继承父类容器数据卷 --volumes-from
docker run -it --privileged=true --volumes-from 父类容器名 镜像名
常用软件安装
tomcat
docker run -d -p 8080:8080 tomcat:版本
mysql
docker run -d -p 3306:3306 --privileged=true
-v /lf/mysql/log:/var/log/mysql
-v /lf/mysql/data:/var/lib/mysql
-v /lf/mysql/conf:/etc/mysql
-e MYSQL_ROOT_PASSWORD=123456
--name mysql
mysql:5.7
redis
前提:在宿主机/lf/redis目录下创建redis.conf配置文件
启动命令
docker run -d -p 6379:6379 --privileged=true
-v /lf/redis/data:/data
-v /lf/redis/redis.conf:/etc/redis/redis.conf
--name redis
redis:6.0.8
redis-server /etc/redis/redis.conf
进入redis容器
docker exec -it redis /bin/bash
redis-cli
nginx
docker pull nginx
创建三个空文件夹
/lf/nginx/conf
/lf/nginx/log
/lf/nginx/html
创建一个nginx容器,为了拷贝它的文件
docker run -d --name nginx -p 8888:80 nginx
# 拷贝文件
docker cp nginx:/etc/nginx/nginx.conf /lf/nginx/conf/nginx.conf
# 将容器conf.d文件夹下内容复制到宿主机
docker cp nginx:/etc/nginx/conf.d /lf/nginx/conf/conf.d
# 将容器中的html文件夹复制到宿主机
docker cp nginx:/usr/share/nginx/html /lf/nginx/
# 找到nginx对应的容器id
docker ps -a
# 关闭该容器
docker stop nginx
# 删除该容器
docker rm nginx
# 创建新的容器 匹配文件
docker run -d
-v /lf/nginx/conf/nginx.conf:/etc/nginx/nginx.conf
-v /lf/nginx/conf/conf.d:/etc/nginx/conf.d
-v /lf/nginx/log:/var/log/nginx
-v /lf/nginx/html:/usr/share/nginx/html
--name nginx -p 8888:80 nginx
curl localhost:8888
高级篇
mysql主从复制
1.新建主服务器容器3307
docker run -d -p 3307:3306 --privileged=true
-v /lf/mysql-master/log:/var/log/mysql
-v /lf/mysql-master/data:/var/lib/mysql
-v /lf/mysql-master/conf:/etc/mysql
-e MYSQL_ROOT_PASSWORD=root
--name mysql-master
mysql:5.7
2.进入/lf/mysql-master/conf目录下新建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
docker ps
4.进入mysql-master容器
docker exec -it mysql-master /bin/bash
mysql -uroot -p
5.master容器实例内创建数据同步用户
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'slave'@'%';
6.新建从服务器实例3308
docker run -d -p 3308:3306 --privileged=true
-v /lf/mysql-slave/log:/var/log/mysql
-v /lf/mysql-slave/data:/var/lib/mysql
-v /lf/mysql-slave/conf:/etc/mysql
-e MYSQL_ROOT_PASSWORD=root
--name mysql-slave
mysql:5.7
7.进入/lf/mysql-slave/conf目录下新建my.cnf
[mysqld]
## 设置server_id,同一局域网中需要唯一
server_id=102
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql
## 开启二进制日志功能,以备Slave作为其它数据库实例的Master时使用
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
8.修改完配置重启slave实例
docker restart mysql-slave
docker ps
9.在主数据库中查看主从同步状态
SHOW MASTER STATUS;
10.进入mysql-slave容器
docker exec -it mysql-master /bin/bash
mysql -uroot -p
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 = 154,
master_connect_retry = 30;
# master_log_file、master_log_pos对应上SHOW MASTER STATUS;
12.在从服务器中查看主从同步状态
show slave status;
13.在从数据库中开启主从同步
start slave;
14.查看数据库状态发现已经同步
show slave status;
15.主从复制测试
create database db01;
use db01;
create table t1 (id int,name VARCHAR(20));
insert into t1 VALUES(1,'zs');
redis集群
分布式存储算法
- 哈希取余分区hash(key)/N节点数
使用 Hash 算法让固定的一部分请求落到同一台服务器上,这样每台服务器固定处理一部分请求(并维护这些请求的信息),起到负载均衡+分而治之的作用。
缺点:原来规划好的节点,进行扩容或者缩容就比较麻烦,不管扩或缩,映射关系需要重新进行计算。
- 一致性哈希算法分区
缺点:Hash 环的数据倾斜问题
- 哈希槽分区:
哈希槽实质就是一个数组,数组[0,2^14 -1]形成hash slot 空间。
redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,也就是映射到某个节点上。
安装
//新建6个redis容器
docker run -d --name redis-node-1 --net host --privileged=true -v /lf/redis-node-1/data:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381
docker run -d --name redis-node-2 --net host --privileged=true -v /lf/redis-node-2/data:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382
docker run -d --name redis-node-3 --net host --privileged=true -v /lf/redis-node-3/data:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383
docker run -d --name redis-node-4 --net host --privileged=true -v /lf/redis-node-4/data:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384
docker run -d --name redis-node-5 --net host --privileged=true -v /lf/redis-node-5/data:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385
docker run -d --name redis-node-6 --net host --privileged=true -v /lf/redis-node-6/data:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386
//构建集群关系
docker exec -it redis-node-1 bash
//--cluster-replicas 1 为每个master创建一个slave节点
redis-cli --cluster create 节点ip:6381 节点ip:6382 节点ip:6383 节点ip:6384 节点ip:6385 节点ip:6386 --cluster-replicas 1
//查看集群状态
redis-cli -p 6381
cluster info
cluster nodes
结果===>
master 6381 : slave 6384
master 6382 : slave 6385
master 6383 : slave 6386
//集群环境连接 -c
redis-cli -p 6381 -c
//查看集群信息
redis-cli --cluster check ip:6381
//容错切换迁移
1.停止主机6381
2.查看集群情况
重启redis-node-1,查看集群情况:
主从扩容
master 6384 : slave 6381
master 6382 : slave 6385
master 6383 : slave 6386
扩容:
master 6384 : slave 6381
master 6382 : slave 6385
master 6383 : slave 6386
master 6387 : slave 6388
1.新增redis节点 6387、6388
docker run -d --name redis-node-7 --net host --privileged=true -v /lf/redis-node-7/data:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6387
docker run -d --name redis-node-8 --net host --privileged=true -v /lf/redis-node-8/data:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6388
2.将新增的节点6387节点(空槽) 作为master节点加入原集群
docker exec -it redis-node-7 bash
redis-cli --cluster add-node 节点ip:6387 节点ip:6381
3.检查集群
redis-cli --cluster check 节点ip:6381
4.重新分配槽号
redis-cli --cluster reshard 节点ip:6381
4096 = 16384/4
all
yes
5.检查集群
redis-cli --cluster check 节点ip:6381
之前三个master节点,每个节点分出一些槽给新的master
6.挂载从服务器6388到主服务器6387上 ( --cluster-master-id 主服务器master id )
redis-cli --cluster add-node 节点ip:6388 节点ip:6387 --cluster-slave --cluster-master-id 7f1d4af5569b6becd6b6fb6ad76b80734e28b877
7.检查集群
redis-cli --cluster check 节点ip:6381
主从缩容
1.删从节点6388
redis-cli --cluster del-node 节点ip:6388 b37329dda7bb8414154a89b8c0f90ee1432b0293 //6388节点ID
2.将6387槽号清空,并分配给6382
redis-cli --cluster reshard 节点ip:6382
3.检查集群
redis-cli --cluster check 节点ip:6381
4.删从节点6387
redis-cli --cluster del-node 节点ip:6387 7f1d4af5569b6becd6b6fb6ad76b80734e28b877 //6387节点ID
Dockerfile
https://docs.docker.com/engine/reference/builder/
常用保留字指令
FROM 镜像名 //第一行 基于的基础镜像
MAINTAINER //维护者的姓名、邮箱地址
RUN //容器构建build时,需要执行的命令
EXPOSE //当前容器对外暴露的端口 如果用 -p xxx:xxx 这种方式,Dockerfile 不写 EXPOSE 也不影响服务端口的映射,没有 EXPOSE 的端口,也没有被封锁,依然能够对外提供服务
WORKDIR //指定在容器创建后,终端默认登录进来的工作目录,一共落脚点
USER //指定该镜像以什么用户去执行 默认root
ENV //运行时环境 设置环境变量
ADD //把宿主机目录下的文件拷贝到镜像 且会自动处理URL和解压tar压缩包
COPY //类似ADD:COPY src dest
VOLUME //容器卷
CMD //容器启动后 运行的指令 会被docker run后面的命令覆盖
ENTRYPOINT //容器启动后 运行的指令 不会被docker run后面的命令覆盖
构建镜像
docker build -t 新的镜像名:TAG .
使用Dockerfile发布微服务
1.maven打包jar包
2.创建Dockerfile
FROM java:8
MAINTAINER lf
ENV LANG C.UTF-8
ENV TZ Asia/Shanghai
VOLUME /tmp
ADD jiaXingWaterResource-1.0-SNAPSHOT.jar jiaXingWaterResource-1.0-SNAPSHOT.jar
ENTRYPOINT ["java","-Xms256m","-Xmx256m","-jar","/jiaXingWaterResource-1.0-SNAPSHOT.jar"]
EXPOSE 8091
3.拷贝到服务器
4.构建镜像
docker build -t water_resource:1.0 .
5.运行
docker run -d -p 8091:8091 water_resource:1.0
docker network
docker network ls
网络模式
bridge:为每个容器分配、设置IP等,并将容器连接到一个docker0;虚拟网桥,默认为该模式;
host:容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口; (docker run --network host ...)
none:
container:
自定义网络模式
docker network create test
//新建容器加入网络
docker run -d -p 8081:8080 --network test --name tomcat81 billygoo/tomcat8-jdk8
docker run -d -p 8082:8080 --network test --name tomcat82 billygoo/tomcat8-jdk8
docker exec -it tomcat81 bash
ping tomcat 82
docker exec -it tomcat82 bash
ping tomcat 81
docker compose
安装:https://docs.docker.com/compose/install/
常用命令
docker-compose -h
docker-compose up -d
docker-compose down
docker-compose exec 服务id
docker-compose ps
docker-compose top
docker-compose logs 服务id
docker-compose config //检查docker-compose.yml配置文件是否正确
docker-compose -q
docker-compose restart
docker-compose start
docker-compose stop
docker-compose config -q
docker-compose -f docker-compose.yml up -d
轻量级可视化工具 Portainer
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-ce:latest
登录
http://ip:9000
容器监控CIG
CAdvisor 容器监视 数据收集处理
InfluxDB 数据存储
Granfana 可视化
创建docker-compose.yml
version: '3'
volumes:
grafana_data: {
}
services:
influxdb:
image: tutum/influxdb:0.9
restart: always
environment:
- PRE_CREATE_DB=cadvisor
ports:
- 8083:8083
- 8086:8086
volumes:
- ./data/influxdb:/data
cadvisor:
image: google/cadvisor
links:
- influxdb:influxsrv
command: -storage_driver=influxdb -storage_driver_db=cadvisor -storage_driver_host=influxsrv:8086
restart: always
ports:
- 9090:8080
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
grafana:
user: '104'
image: grafana/grafana
restart: always
links:
- influxdb:influxsrv
ports:
- 3000:3000
volumes:
- grafana_data:/var/lib/grafana
environment:
- HTTP_USER=admin
- HTTP_PASS=admin
- INFLUXDB_HOST=influxsrv
- INFLUXDB_PORT=8086
- INFLUXDB_USER=root
- INFLUXDB_PASS=root
docker-compose config -q
docker-compose -f docker-compose-CIG.yml up -d
访问Grafana:http://ip:3000