1.安装docker
yum -y update
yum install -y docket
/*************源码安装*************/
下载安装
wget -qO- https://get.docker.com/ | sh
*遇到问题
Delta RPMs disabled because /usr/bin/applydeltarpm not installed.
//解决方案
yum provides '*/applydeltarpm'
yum install deltarpm
**遇到问题
Public key for containerd.io-1.2.4-3.1.el7.x86_64.rpm is not installed
解决方案
rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-*
修改用户组 ,因为docker 默认只允许root用户操作 把当前用户加入docker组 就也可以操作
usermod -aG docker xbf
2.管理docker
启动
service docker start|stop
docker info//查看是否正确安装
3.docker镜像地址修改
//https://www.daocloud.io/
curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io
vi /etc/docker/daemon.json
4.docker查找镜像 安装
docker search nginx
docker pull docker.io/nginx
docker images
5.镜像的导入导出
docker save nginx > /data/nginx.tar.gz
docker load < /data/nginx.tar.gz
docker rmi docker.io/nginx //删除
6.创建并启动容器
docker run -it --name myNginx docker.io/nginx bash //run 启动容器 -it 启动容器后开启一个交互界面 --name 起个名字 bash启动容器 运行bash命令行
docker run -it --name myNginx -p 9000:8080 -p 8666:2111 -v /data/www:/www --privileged docker.io/nginx bash // -p 把容器的8080端口映射到宿主机的9000端口 -v 把宿主机的真是目录映射到容器目录 --privileged 容器对真是目录的权限 【最高权限】
docker pause myNginx 暂停
docker unpause myNginx 继续
docker stop myNginx 停止
docker start -i myNginx
docker rm myNginx 删除容器 前提是容器必须停止
拷贝本地文件进入镜像[临时]
docker cp index.htl 94e814e2efa8:/var/
【固化】
docker commit -m 'fun' 94e814e2efa8 newTag
7.搭建pxc
docker pull percona/percona-xtradb-cluster //安装pxc
docker load < /data/soft/pxc.ter.gzs//本地安装
1).修改名字 名字太长了
docker tag docker.io/percona/percona-xtradb-cluster pxc
//修改后就可以删除掉原来的镜像
docker rmi docker.io/percona/percona-xtradb-cluster
2).处于安全 给pxc集群实例创建内部网段
a.docker network create net1 //docker 内部自带网段172.18.0.1
docker network create --subnet=172.18.0.0/16 net1 //子网掩码是24位的
b.查看创建的网段
docker inspect net1
c.删除网段
docker network rm net1
3).pxc在docker容器中无法使用映射的目录来使用宿主机的文件,故而用docker卷来映射
a.docker volume create --name v1//创建docker卷
b.docker inspect v1 //查看券
[
{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/v1/_data",
"Name": "v1",
"Options": {},
"Scope": "local"
}
]
/var/lib/docker/volumes/v1/_data是宿主机真是的目录
c.删除数据卷
docker volume rm v1
docker volume create --name?v1
docker volume create --name?v2
docker volume create --name?v3
docker volume create --name?v4
docker volume create --name?v5
docker volume create --name backup 用来热备份
4).运行pxc
docker run -d -p 3306:3306 -v v1:/var/lib/mysql
-e MYSQL_ROOT_PASSWORD=root
-e CLUSTER_NAME=PXC
-e XTRABACKUP_PASSWORD=111111
--privileged --name=node1 --net=net1 --ip 172.18.0.2 pxc
//-d 创建出的容器在后台运行 -v 数据卷=>mysql数据目录
//-e 启动参数
MYSQL_ROOT_PASSWORD=mysql密码
CLUSTER_NAME集群的名称
XTRABACKUP_PASSWORD数据库节点之间同步时所用的密码
ClUSTER_JOIN=node1 加入集群跟第一个pxc节点进行同步
//--privileged给它最高的权限
//--name 容器名称
//--net使用的网段
//--ip 此容器指定ip
//pxc 容器名称
//创建五个节点
节点1:docker run -d -p 3306:3306 -v v1:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=111111 --privileged --name=node1 --net=net1 --ip 172.18.0.2 pxc//第一个节点命令执行完成 要用Navicat连接一下mysql数据库看看是否数据库初始化成功 否则之后的容器创建会闪退
连接名: pxc_db1
主机ip:192.168.18.125//宿主机的ip
端口:3306 后边的节点依次是3307~3310
用户名:root
密码:123
节点2:docker run -d -p 3307:3306 -v v2:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=111111 -e CLUSTER_JOIN=node1 --privileged --name=node2 --net=net1 --ip 172.18.0.3 pxc
节点3:docker run -d -p 3308:3306 -v v3:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=111111 -e CLUSTER_JOIN=node1 --privileged --name=node3 --net=net1 --ip 172.18.0.4 pxc
节点4:docker run -d -p 3309:3306 -v v4:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=111111 -e CLUSTER_JOIN=node1 --privileged --name=node4 --net=net1 --ip 172.18.0.5 pxc
节点5:docker run -d -p 3310:3306 -v v5:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=111111 -e CLUSTER_JOIN=node1 --privileged --name=node5 --net=net1 --ip 172.18.0.6 pxc
我是直接删除了node1容器,然后再重新创建容器启动成功,经测试,数据库的数据还在,但是你在重启docker服务之后,所有的容器节点都会被关闭,这时候再次使用docker start node1命令,就启动不了了,经过查看日志,发现要修改数据卷v1里面的文件,具体路径为:/var/lib/docker/volumes/v1/_data,文件名为grastate.dat
vim 进这个文件,修改safe_to_bootstrap: 1,便能成功启动了。其余节点都是关联的node1节点,只要node1节点启动了,在创建其余节点严格按照步骤来的话,应该是能成功启动的。
8.数据库负载均衡
1).Haproxy中间件
a. docker pull haproxy//安装haproxy
b. 创建配置文件
touch /data/soft/haproxy/haproxy.cfg
vi /data/soft/haproxy/haproxy.cfg
c. 启动haproxy容器
hp1:docker run -it -d -p 4001:8888 -p 4002:3306 -v /data/soft/haproxy:/usr/local/etc/haproxy --name hp1 --privileged --net=net1 --ip 172.18.0.7 haproxy
hp2:docker run -it -d -p 4003:8888 -p 4004:3306 -v /data/soft/haproxy:/usr/local/etc/haproxy --name hp2 --privileged --net=net1 --ip 172.18.0.8 haproxy
docker exec -it hp1 bash//进入后台运行的haproxy
haproxy -f /usr/local/etc/haproxy/haproxy.cfg
d.在数据库创建haproxy的账号
create user 'haproxy'@'%' identified by '';无任何权限就是做心跳检测
e. 监控地址
http://192.168.18.125:4001/dbs admin abc123456
f.尝试停止一个pxc节点
docker stop node1
9.双机热备解决但节点haproxy
1).keepalived争抢虚拟ip
架构设计:(docker的虚拟ip不能被外网使用,所以需要借助宿主机的keepalived映射成外网可以访问的虚拟ip)
宿主机虚拟ip=>keepalived=>docker虚拟ip=>容器N[keepalived,haproxy]=>负载均衡=>pxc集群
2).安装keepalived
a.在安装haproxy的容器之内执行
//Ubuntu apt-get更新源替换及加速方法
// (1).cp /etc/apt/sources.list /etc/apt/sources.list.bak
// (2).我把source.list 文件提前编辑好了 放在/usr/local/etc/haproxy/目录下 下一步直接拷贝移动
cp /usr/local/etc/haproxy/sources.list /etc/apt/sources.list
apt-get update
apt-get install keepalived
b.配置keepalived.conf
vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state MASTER //MASTER主动争抢ip 只有一个keepalived可以抢到 未抢到的自动降级为slvae
interface eth0//我自定义虚拟ip 保存到的网卡 eth0(docker的网卡)
virtual_router_id 51 //这一组keepalived的id 0~255
priority 100//权重 硬件配置高的话可以高一点 抢走ip比较优先
advert_int 1//心跳检测间隔 1s
authentication {
auth_type PASS//心跳检测的登录其它keepalived方式
auth_pass 123456
}
virtual_ipaddress {
172.18.0.201//往eth0写入虚拟ip 可以多个ip 每行一个
}
}
d.启动keepalived
service keepalived start [ | systemctl restart keepalived]
e.宿主机测试 ping 172.18.0.201
f.在宿主机安装keepalived
yum install -y keepalived
g.配置keepalived
vi /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state MASTER
interface ens33//在enss33网卡定义一个虚拟的ip 跟docker 虚拟ip做映射
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.18.150
}
}
//为虚拟ip 192.168.18.150设置转发规则
//外部请求到192.168.18.150 8888 经过keepalived映射到docker 172.18.0.201 8888
virtual_server 192.168.18.150 8888 {
delay_loop 3//心跳检测间隔 3s
lb_algo rr //轮训转发
lb_kind NAT//nat模式
persistence_timeout 50//超时时间
protocol TCP
//docker的虚拟ip
real_server 172.18.0.201 8888 {
weight 1
}
}
//数据库的ip映射
virtual_server 192.168.18.150 3306 {
delay_loop 3
lb_algo rr
lb_kind NAT
persistence_timeout 50
protocol TCP
//docker的容器的数据端口
real_server 172.18.0.201 3306 {
weight 1
}
}
10.当系统自动开机关机后 可以自动为docker分配网络服务
1).修改宿主机文件
vi /etc/sysctl.conf
增加
net.ipv4.ip_forward=1
2).systemctl restart network
11.热备份数据
1).LVM Linux自带对分区创建快照的备份方式 可以备份任何数据库
缺点:对数据库加锁 数据库只能读取不能写入
2).XtraBackup 支持全量备份(首次) 增量备份
12.XtraBackup热备份数据
1).创建数据卷
docker volume create backup
2).停止pxc node1节点 加入backup
3).删除node1节点
4).从新创建
docker run -d -p 3306:3306 -v v1:/var/lib/mysql -v backup:/data -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=111111 -e CLUSTER_JOIN=node2 --privileged --name=node1 --net=net1 --ip 172.18.0.2 pxc
5).进入备份所在的容器内部 安装备份工具
root用户进入容器: docker exec -it -u 0 node1 bash
宿主机:cp /data/soft/haproxy/sources.list /var/lib/docker/volumes/backup/_data
docker cp sources.list node1:/data/
a. apt-get update
b. apt-get install percona-xtrabackup-24
6).备份命令
a.全量备份
innobackupex --user=root --password=root /data/backup/full
12.pxc 全量恢复
0).执行测试
a.docker stop node1 node2 node3 node4 node5
b.docker rm node1 node2 node3 node4 node5
c.docker volume rm v1 v2 v3 v4 v5
d.docker volume create --name v1
e.docker run -d -p 3306:3306 -v v1:/var/lib/mysql -v backup:/data -e MYSQL_ROOT_PASSWORD=root -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=111111 --privileged --name=node1 --net=net1 --ip 172.18.0.2 pxc
f.docker exec -it -u 0 node1 bash
1).rm -rf /var/lib/mysql/* //先清空数据目录
2).未提交的事务回滚一下:innobackupex --user=root --password=root --apply-back /data/backup/full/2018-09-25_08-59-55/
3).执行冷还原:innobackupex --user=root --password=root --copy-back /data/backup/full/2018-09-25_08-59-55/
4).exit 退出容器
chmod -R 777 /var/lib/docker/volumes/v/_data/
chmod -R 777 /var/lib/docker/volumes/backup/_data/
重启node1节点
*遇到问题
[ERROR] InnoDB: The innodb_system data file ‘ibdata1’ must be writable
2019-03-15T12:26:08.995417Z 0 [ERROR] InnoDB: The innodb_system data file ‘ibdata1’ must be writable
2019-03-15T12:26:08.995446Z 0 [ERROR] InnoDB: Plugin initialization aborted with error Generic error
2019-03-15T12:26:10.100243Z 0 [ERROR] Plugin ‘InnoDB’ init function returned error.
2019-03-15T12:26:10.168399Z 0 [ERROR] Plugin ‘InnoDB’ registration as a STORAGE ENGINE failed.
2019-03-15T12:26:10.168478Z 0 [ERROR] Failed to initialize builtin plugins.
2019-03-15T12:26:10.168576Z 0 [ERROR] Aborting
13.Redis高速缓存 RedisCluster
1).redis 集群最好有奇数个Master 至少3个 因为他们有选举机制
2).安装redis容器
a. docker pull yyyyttttwwww/redis
如果之前创建了net2网段,现在要删除必须 先解散docker集群
docker swarm leave -f
查看网络
docker network ls
删除 docker_gwbridge
docker network rm docker_gwbridge
创建net2的网络
docker network create --subnet=172.19.0.0/16 net2
b. 创建Redis的容器
节点1:docker run -it -d --name r1 -p 5001:6379 --net=net2 --ip 172.19.0.2 redis bash
节点2:docker run -it -d --name r2 -p 5002:6379 --net=net2 --ip 172.19.0.3 redis bash
节点3:docker run -it -d --name r3 -p 5003:6379 --net=net2 --ip 172.19.0.4 redis bash
节点4:docker run -it -d --name r4 -p 5004:6379 --net=net2 --ip 172.19.0.5 redis bash
节点5:docker run -it -d --name r5 -p 5005:6379 --net=net2 --ip 172.19.0.6 redis bash
节点6:docker run -it -d --name r6 -p 5006:6379 --net=net2 --ip 172.19.0.7 redis bash
c.进入redis容器修改配置文件
docker exec -it r1 bash
vi /usr/redis/redis.conf
daemonize yes #redis 以后台方式运行
cluster-enabled yes #开启集群
cluster-config-file nodes.conf #集群配置文件
cluster-node-timeout 15000 #节点与节点超时时间
appendonly yes #开启AOF模式
bind 0.0.0.0 #允许任何ip访问
d.启动redis
/usr/redis/src/redis-server /usr/redis/redis.conf
/usr/redis/src/redis-cli shutdown #关闭
13.使用redis-trib.rb创建redis集群
redis-trib是基于ruby的redis集群命令工具 所以要提前安装ruby环境
1.copy一份redis-trib.rb
mkdir cluster
cp /usr/redis/src/redis-trib.rb /usr/redis/cluster/
cd /usr/redis/cluster/
apt-get install ruby
apt-get install rubygems
gem install redis
2.创建集群
./redis-trib.rb create --replicas 1 172.19.0.2:6379 172.19.0.3:6379 172.19.0.4:6379 172.19.0.5:6379 172.19.0.6:6379 172.19.0.7:6379
#--replicas 1 为每个主节点创建一个从节点
测试
/usr/redis/src/redis-cli -c
查看节点运行的状况
cluster nodes
14.Nginx 负载均衡
1).创建Nginx容器
docker run -it -d --name n1 -v /data/soft/n1/nginx.conf:/etc/nginx/nginx.conf --net=host --privileged nginx
//--net=host 可以使用宿主机的ip
14-1.云平台搭建mysql集群
参考文章:
https://www.imooc.com/article/48765
安装swarm
docker pull swarm
创建第一个节点
docker swarm init --advertise-addr 172.17.35.204 --listen-addr 172.17.35.204:2377
更新节点参数
docker node update --advertise-addr 172.17.35.204 --listen-addr 172.17.35.204:2377
docker node rm -f host-172.17.35.204
继续加入节点
172.17.12.191
docker swarm join --advertise-addr 172.17.12.191 --listen-addr 172.17.12.191:2377 --token SWMTKN-1-4yr3yrj9owc37e6rhwyq65bd6adqlhllc0ud5bddkgr1uzoapx-etra7a27tbbfvtu4cuz9tqr4x 172.17.35.204
15.Dockerfile
创建Dockerfile
FROM alpine:latest //我要生成的镜像的基础镜像 ,alpine专门针对docker来做的一个极小的Linux环境
MAINTAINER xbf //共享的时候
CMD echo '你还这是第一个docker img' //运行的命令
生成新的images
docker build -t hello_docker ./ //-t 是给images 起一个名字标签 ./指的是当前目录下的文件送给docker——engine来生成images
运行images
docker run hello_docker
实战:创建Nginx镜像
mkdir nginx_df
创建Dockerfile
vi Dockerfile
FROM ubuntu //基于ubuntu基础镜像
MAINTAINER logge
RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list //加速
RUN apt-get update //执行命令 更新Ubuntu的库
RUN apt-get install -y nginx //安装Nginx
COPY index.html /var/www/html //copy一个index.html 到www目录
ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"] //容器的入点 ,最后这个会展开用空格 连接成一条命令执行
EXPOSE 80 //暴露一个端口
创建html
vi index.html
运行images
docker run -d -p 8080:80 my-nginx
测试
curl http://localhost:8080
16.Dockerfile命令
ADD 添加一个文件
WORKDIR 指定路径
ENV 设定环境变量
ENTRYPOINT 容器的入口 如果同时出现CMD时 ,CDM 的参数会变成它的参数
USER 指定用户
VOLUME 挂载卷
17.镜像分层
//每一层都有一个id
FROM alpine:latest //erwetwert343
MAINTAINER xbf //sf5sd4fas54fas
CMD echo '你还这是第一个docker img' /adf4s5fg45sf
//images里的层是只读的
当images运行成为容器之后 每层都是可读可写的
* 分层主要是解决images之间层与层之间重复共享存储 节省空间
18.提供独立于容器之外的持久化存储Volume
例如:
docker run -d --name nginx -v /usr/share/nginx/html nginx
检查
docker inspect nginx
"Mounts": [
{
"Type": "volume",
"Name": "95ff05341bdb2f4e4e41128613e5051fb18bb3f648b6c42db07f2da4ac22a654",
"Source": "/var/lib/docker/volumes/95ff05341bdb2f4e4e41128613e5051fb18bb3f648b6c42db07f2da4ac22a654/_data", //宿主机目录
"Destination": "/usr/share/nginx/html",//挂载的容器目录
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
进入容器
docker exec -it nginx /bin/bash
挂载宿主机目录 到容器目录
docker run -p 8081:80 -d -v $PWD:/use/share/nginx/html nginx
测试
curl http://localhost:8081
创建数据镜像
mkdir vol
cd vol/
mkdir data
数据镜像
docker create -v $PWD/data:/var/mydata --name data_container ubuntu
从另外一个容器挂载数据卷--volumes-from data_container
docker run -it --volumes-from data_container ubuntu /bin/bash
查看挂载的数据卷
mount
/dev/vda1 on /var/mydata type ext4 (rw,relatime,data=ordered)挂载的数据卷
进入数据卷创建文件
cd /var/mydata
touch whatever.txt
进入
vol/data/
19.Registry 注册【镜像仓库】
docker search xxxx
docker run xxximg
创建新的镜像
先登录
docker login
docker tag xxximg longg/newimg
推送
docker push longg/newimg
20.多容器APP docker-composer
安装docker-compose
地址:https://docs.docker.com/compose/install/#install-compose
curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
让所有人都可执行这个文件
chmod a+x /usr/local/bin//docker-compose
测试
docker-compose --version
实战:
博客+nginx+mysql
mkdir boke
cd boke/
mkdir nginx
mkdir boke
mkdir data
cd boke/
vi Dockerfile
FROM ghost
COPY ./config.js /var/lib/ghost/config.js
CMD ["npm","start","--production"]
vi config.js
var path = require('path'),config;
config={
production:{
url:'http://mytestblog.com',
mail:{},
database:{
client:'mysql',
connection:{
host:'db',
user:'ghost',
password:'ghost',
database:'ghost',
port:'3306',
charset:'utf8'
},
debug:false
},
psths:{
contentPath:path.join(process.env.GHOST_CONTENT,'/')
},
server:{
host:'0.0.0.0',
port:'2368'
}
}
};
module.exports=config;
cd ../nginx
vi Dockerfile
FROM nginx
COPY nginx.conf /ect/nginx/nginx.conf
EXPOSE 80
vi nginx.conf
worker processes 4;
events worker connections 1024;
http {
server{
listen 80;
location / {
proxy pass http://ghost-app:2368;
}
}
}
cd ../
vi docker-compose.yml
version: '2'//compose的版本
networks:
ghost://声明网络
services://声明服务
ghost-app:
build: boke//基于谁构建本地镜像
networks:
- ghost
depends_on://声明依赖 连接容器db,必须db服务先启动我才能启动
- db
ports:
- "2368:2368"
nginx:
build: nginx
networks:
- ghost
depends_on:
- ghost-app
ports:
- "8082:80"
db:
image: "mysql:5.7.15"//pull镜像
networks:
- ghost
environment://环境变量
MYSQL_ROOT_PASSWORD: mysqlroot
MYSQL_USER: ghost
MYSQL_PASSWORD: ghost
volumes://声明本地卷
- $PWD/data:/var/lib/mysql
ports:
- "3306:3306"
docker-compose 命令
up 启动服务
stop 停止服务
rm 删除服务中的各个容器
logs 观察各个容器的日志
ps 列出服务相关的容器