docker

docker 运行环境标准化、可复制化、可迁移化

容器 : 共享宿主机内核 轻量 容器间隔离

Docker 核心概念:

  1. Image:镜像,应用模板
  2. Container:容器,镜像运行后的实例
  3. Registry:仓库,存放镜像
  4. Engine:引擎,负责管理镜像、容器、网络、存储
  5. Volume:数据卷,负责持久化
  6. Network:网络,负责容器通信

1.安装

使用的环境为ro cky linux 9.5

docker文档官网 : https://docs.docker.com/

1.1 使用yum在线进行安装

// 添加gcc编译环境
yum -y install gcc
yum -y install gcc-c++
// 添加yum版本控制工具
yum -y install  yum-utils

// 添加阿里云镜像源
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 

// 安装docker
yum -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

// 启动docker
systemctl start docker
// 开机自启
systemctl enable docker 
systemctl is-enabled docker

1.2 卸载

systemctl stop docker
yum remove docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
rm -rf /var/lib/docker
rm -rf /var/lib/containerd

1.2 使用压缩包进行安装

下载安装包地址:https://download.docker.com/linux/static/stable/
# tgz 是 tar.gz
tar xzvf FILE.tgz

cp docker/* /usr/bin/

docker version

# 创建docker的systemd服务文件

touch /etc/systemd/system/docker.service

cat > /etc/systemd/system/docker.service <<'EOF'
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service containerd.service
Wants=network-online.target

[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s

[Install]
WantedBy=multi-user.target
EOF

mkdir -p /var/lib/docker
mkdir -p /etc/docker

systemctl daemon-reload

// 启动docker
systemctl start docker
// 开机自启
systemctl enable docker 
systemctl is-enabled docker

2.配置加速器

蠢的连docker都墙,每次还得从阿里云上边往下爬 蛋疼吗?
# /etc/docker/daemon.json

cat > /etc/docker/daemon.json << 'EOF'
{
"registry-mirrors": 
    ["https://docker.m.daocloud.io",
    "https://huecker.io",
    "https://dockerhub.timeweb.cloud",
    "https://noohub.ru"]
}
EOF


systemctl daemon-reload
systemctl restart docker


# 使用国内轩辕hub库
echo $password | docker login -u $id --password-stdin docker.xuanyuan.run

docker pull docker.xuanyuan.run/library/xxx1.1

3. docker命令

3.1 帮助启动类命令

  • systemctl start docker
  • systemctl stop docker
  • systemctl restart docker
  • systemctl status docker
  • systemctl enable docker
  • systemctl disable docker
  • docker info
  • systemctl daemom-reload

3.2 镜像命令

  • docker images
  • docker search --limit 5 redis
  • docker pull xxx[:v1]
  • docker system df
  • docker rmi $id

3.3 容器命令

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
  • docker run

    • --name
    • -d 后台运行
    • -i (interactive)
    • -t (tty)
    • -P 随机端口映射
    • -p 指定端口映射
  • docker rm (-f)

    • docker ps -qa | xargs docker rm 删除所有容器
  • docker ps
  • docker restart
  • docker stop
  • docker kill
  • docker logs
  • docker top
  • docker inspect
  • docker port
  • docker rename 源容器名称 新容器名称
  • docker exec -it ID /bin/bash docker attach 直接进入容器启动的终端 exit会使容器停止
  • docker cp ID:容器内路径 目的主机地址
  • docker export ID > xxx.tar 将容器备份
  • docker import xxx.tar name:V1.1 恢复备份
  • docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名

4.镜像

  • docker commit -m="提交的信息" -a="作者" 容器ID 要创建的目标镜像名:V1.1
  • docker tag 容器ID(源镜像名) regionID/name/xxx:V1.1(新镜像名)
  • docker pull
  • docker push
  • docker inspect
  • docker save -o 文件名.tar 镜像名:标签

5.仓库

5.1阿里云仓库

参考阿里云容器镜像服务

aliyun.com

5.2本地仓库

`Docker挂载主机目录访问如果出现cannot open directory .: Permission denied
解决办法:在挂载目录后多加一个--privileged=true参数即可
如果是CentOS7安全模块会比之前系统版本加强,不安全的会先禁止,所以目录挂载的情况被默认为不安全的行为,在SELinux里面挂载目录被禁止掉了额,如果要开启,我们一般使用--privileged=true命令,扩大容器的权限解决挂载目录没有权限的问题,也即使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限。`


docker pull registry 

docker run --name=registry -d -p 5000:5000 -v /huan/myRegistry/:/tmp/registry --privileged=true 镜像ID

curl -XGET http://127.0.0.1:5000/v2/_catalog

docker tag rocky01:v2 127.0.0.1:5000/huanhuan:v1.1

# /etc/docker/daemon.json 中添加
"insecure-registries":["127.0.0.1:5000"]

docker push 127.0.0.1:5000/huanhuan:v1.1

curl -XGET http://127.0.0.1:5000/v2/_catalog

docker pull 127.0.0.1:5000/huanhuan:v1.1

6.容器数据卷

6.1 容器挂载数据卷

#使用rocky镜像创建容器测试    
docker run --name=rocky01 -d -it -v /huan/docker/rocky01Mount/:/huan/test:rw --privileged=true rocky:latest /bin/bash

docker inspect 容器ID  查看mount 可以查看到容器挂载的详细信息

# 在容器中创建文件进行测试, /huan/test/下的文件会持久化到宿主机目录中

# :rw 默认是读写权限,可不写  :ro 为只读

6.2 继承数据卷

docker run -it --privileged=true --volumes-from 父类 --name xx 镜像ID

7.进阶

7.1 mysql主从复制

## 创建master
docker run -p 3306:3306 --name 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=root -d docker.xuanyuan.run/mysql/mysql-server:5.7

## 配置conf /mydata/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


## 在主数据库中创建数据同步用户
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
show master status;


## 创建slave
docker run -p 3307:3307 --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 docker.xuanyuan.run/mysql/mysql-server:5.7

## 配置conf /mydata/mysql-slave/conf/my.cnf
## 设置server_id,同一局域网中需要唯一
[mysqld]
server_id=102
## 指定不需要同步的数据库名称
binlog-ignore-db=mysql  
## 开启二进制日志功能
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


## 在从数据库中配置
change master to master_host='192.168.233.186',master_user='slave',master_password='123456',master_port=3306,master_log_file='mall-mysql-bin.000001',master_log_pos=617,master_connect_retry=30;

show slave status \G ;

## 在主数据中开启主从同步
start slave;


## 测试同步
create database db01;
use db01;
create table t1(id int,name varchar(20));
select * from t1;

7.2 配置redis集群

7.2.1 基础配置

## 创建六个redis容器 
for i in {1..6};do docker run -d --name redis-node-$i --net host --privileged=true -v /mydata/redis/share/redis-node-$i:/data redis:latest --cluster-enabled yes --appendonly yes --port 638$i;done

## 随便进入一个redis容器  ip自行替换   创建哈希槽
redis-cli --cluster create 192.168.233.186:6381 192.168.233.186:6382 192.168.233.186:6383 192.168.233.186:6384 192.168.233.186:6385 192.168.233.186:6386 --cluster-replicas 1

redis-cli -p 6381
cluster info
cluster nodes


# -c 使用集群模式进行简单的测试
redis-cli -p 6381 -c 
FLUSHALL
set k1 v1
set k2 v2
get k1 
get k2

## 检查集群详细信息
redis-cli --cluster check 192.168.233.186:6381

## 模拟宕机  stop docker查看 clsuter nodes 状态变更情况
自己玩......

7.2.2 模拟扩容

# 创建一个主备的docker redis容器
for i in {7,8};do docker run -d --name redis-node-$i --net host --privileged=true -v /mydata/redis/share/redis-node-$i:/data redis:latest --cluster-enabled yes --appendonly yes --port 638$i;done

#添加主节点
redis-cli --cluster add-node 192.168.233.186:6387 192.168.233.186:6381
# 删除主节点
#步骤1:迁移该主节点所有槽位到其他主节点
redis-cli --cluster reshard <集群节点> --cluster-from <待删主节点ID> --cluster-to <目标主节点ID> --cluster-slots <槽数量> --cluster-yes
# 步骤2:确认槽位已清空(检查 cluster nodes 输出中该节点无 [xxx-yyy] 标识)
redis-cli -h <待删节点IP> -p <端口> cluster nodes | grep <节点ID>
# 步骤3:删除节点
redis-cli --cluster del-node <集群节点> <待删主节点ID>

#添加从节点
redis-cli --cluster add-node --cluster-slave --cluster-master-id <主节点ID> <新从节点IP:端口> <集群中任一节点IP:端口>

#删除从节点
redis-cli --cluster del-node <集群中任一节点IP:端口> <要删除的从节点ID>

#重新分派哈希槽号
redis-cli --cluster reshard id:port
# 按提示输入:
#   slots to move: 例如 1000
#   destination node ID: 新节点ID
#   source node IDs: all(或指定源节点)
#   yes 确认