Docker-应用容器
Docker-应用容器
安装 Docker
-
官网
官网
( ①
): https://www.docker.com/centos(
②
): https://docs.docker.com/engine/install/centos/选择 Linux
(①
)选择对应系统安装 ( ②
) -
卸载旧版本
1
2
3
4
5
6
7
8sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine -
下载关于
Docker
的依赖环境 1
yum install -y yum-utils device-mapper-persistent-data lvm2
-
设置镜像仓库
1
2
3yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 选择一个
sudo yum-config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo -
安装
docker
1
2
3
4# 更新 yum 软件包索引
yum makecache fast
# 安装最新版本
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin -
启动
docker
并设置开机自动启动 1
2
3
4
5# 启动
systemctl start docker
# 设置开机自启
systemctl enable docker -
配置镜像加速
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20# 可以通过修改
daemon 配置文件 /etc/docker/daemon.json 来使用加速器
sudo mkdir -p /etc/docker
# 添加国内镜像【sudo开始复制一直到 EOF 结束】
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors":[
"https://eyy45bvx.mirror.aliyuncs.com",
"https://hub-mirror.c.163.com",
"https://registry.aliyuncs.com",
"https://registry.docker-cn.com",
"https://docker.mirrors.ustc.edu.cn"
]
}
EOF
# 重新加载 daemon 配置
sudo systemctl daemon-reload
# 重启 docker
sudo systemctl restart docker-
可以获取自己的阿里云地址
-
登录阿里云
-
进入控制台
-
搜索
[容器镜像服务](https://cr.console.aliyun.com/cn-hangzhou/instances)
获取镜像加速器地址
-
-
-
查看镜像加速是否生效
1
docker info
加速生效 -
测试环境
1
docker run hello-world
-
输出
测试环境
卸载 Docker
-
查看运行状态
1
systemctl status docker
-
停止服务
1
2
3systemctl stop docker
# 出现如下,使用该命令
sudo systemctl stop docker.socket停止 -
查看
yum
安装的 docker
文件包 1
yum list installed | grep docker
已下载列表 -
删除所有安装的
docker
文件包 1
2
3
4# 查看
rpm -qa|grep docker
# 删除列出的文件
yum -y remove xxx删除 -
删除
docker
镜像 1
rm -rf /var/lib/docker
中央仓库
-
Docker
官方的中央仓库: 这个仓库是镜像最全的, 但是下载速度较慢 https://hub.docker.com/
-
国内镜像网站:
网易蜂巢,daoCloud... 1
2https://c.163yun.com/hub#/home
http://hub.daocloud.io (推荐使用,速度加载较快) -
在公司内部会采用私服的方式拉取镜像
( 添加相关配置
)1
2
3
4
5
6
7
8
9
10
11# 编辑 | 新建该配置文件
vim /etc/docker/daemon.json
# 添加如下信息
{
"registry-mirrors": ["https://register.docker-cn.com"],
# 私服
"insecure-registries": ["ip:port"]
}
# 重新启动两个服务
systemctl daemon-reload
systemctl restart docker
镜像的操作
-
拉取环境
1
2
3
4
5
6# http://hub.daocloud.io/ 在此处搜索
# 拉取镜像到本地
docker pull 镜像名称[:tag]
# Eg
docker pull daocloud.io/library/tomcat:8.0.45-
拉取流程
拉取所需环境 -
拉取过程
拉取过程
-
Run-流程
-
流程
docker run 的 run
流程
Docker-常用命令
帮助启动类命令
-
启动
1
systemctl start docker
-
停止
1
systemctl stop docker
-
重启
1
systemctl restart docker
-
查看状态
1
systemctl status docker
-
开机启动
1
systemctl enable docker
-
查看
docker
概要信息 1
docker info
-
查看
docker
总体帮助命令 1
docker --help
-
查看
docker
命令帮助文档 1
docker 具体命令 --help
镜像命令
-
列出本地主机上的镜像
1
2
3
4
5docker images -[options]
options:
-a: 列出本地所有的镜像(含历史映像层)
-q: 只显示镜像 ID查看全部本地的镜像 -
REPOSITORY
: 表示镜像的仓库源 -
TAG
: 镜像的标签版本号 -
IMAGE ID
: 镜像ID
-
CREATED
: 镜像创建时间 -
SIZE
: 镜像大小用一仓库源可以有多个
TAG
版本, 代表这个仓库源的不同个版本,我们使用 REPOSITORY:TAG
来定义不同的镜像 如果你不指定一个镜像的版本标签,
例如你只使用 ubuntu
,docker
将默认使用 ubuntu:latest
镜像
-
-
搜索某个镜像
1
2
3docker search 某个镜像名称
# Eg: 查看排名前 5 的
docker search --limit 5 redis信息 参数 说明 NAME 镜像名称 DESCRIPTION 镜像说明 STARS 点赞数 OFFICIAL 是否是官方的 AUTOMA 是否是自动构建的 -
拉取某个镜像
1
2
3docker pull 某个镜像名称
[:TAG]
# 没有 TAG 就是最新版,等价于如下
docker pull 镜像名称:latest -
查看占用空间
1
docker system df 镜像
/ 容器 / 数据卷所占用的空间 空间信息 -
删除镜像
1
2
3
4
5
6
7
8# 删除单个, -f 参数可以强制删除
docker rmi 某个镜像名字id
# 删除多个
docker rmi -f 镜像名1:TAG 镜像名 2:TAG
# 删除全部
docker rmi -f $(docker images -qa)删除前与删除后 -
镜像导出与导入
1
2
3
4
5
6# 将本地镜像导出
docker save -o 导出的路径 镜像id
# 加载本地的镜像文件
docker load -i 镜像文件
# 修改镜像名称
docker tag 镜像id 新镜像名称: 版本 使用流程 -
面试题: 谈谈
docker
虚悬镜像是什么? -
虚悬镜像指的是
仓库名、标签都是
<none>
的镜像, 俗称 虚悬镜像
(dangling image) -
长什么样
虚悬镜像,需要删除掉
-
容器命令
-
拉取
ubuntu
镜像 1
docler pull ubuntu
-
新建
+ 启动容器 -
启动交互式容器
(前台命令行) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 简单操作
docker run 镜像标识 | 镜像名称[:tag]
# 可以直接拉取并启动
docker run -d -p 宿主机端口:容器端口 --name 容器名称 镜像的标识|镜像名称 [:tag]
# -d: 代表后台运行容器
# --name: 容器名称 =>指定容器的名称
# -i: 以交互模式运行容器,通常与 -t 同时使用
# -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用
docker run -it ubuntu bash
# 退出
exit
# -p: 宿主机端口:容器端口 => 为了映射当前 Linux 的端口和容器的端口
-
-
退出
-
exit
:run
进去容器, exit
退出, 容器停止 容器自动关闭 -
ctrl+p+q
:run
进去容器, ctrl+p+q
退出, 容器不停止 容器未停止
-
-
查看正在运行的
容器
1
2
3docker ps [-qa]
-a: 查看全部的容器,包括没有运行的
-q: 只查看容器的标识测试 -
启动已停止运行的容器
1
docker start 容器
id/ 或者容器名 使用容器 id 进行启动或关闭 -
停止容器
1
docker stop 容器
id/ 或者容器名 -
强制停止容器
1
docker kill 容器
id/ 或者容器名 -
删除已停止的容器
1
2
3
4# 删除单个
docker rm 容器id
# 一次性删除多个容器实例
docker rm -f $(docker ps -qa)删除多个已停止容器 -
查看容器的日志
1
2docker logs -f 容器
id
-f: 可以滚动查看日志的最后几行 -
进入正在运行的容器并以命令行交互
-
方式一
1
2
3
4
5
6docker exec -it 容器
id(CONTAINER ID) bash
# Eg: 进入 Tomcat
docker exec -it fb0 bash
# 退出容器内部
exit进入容器内的 Tomcat
-
方式二
1
docker attach 容器
id -
两者的区别
exec【推荐】
是在容器中打开新的终端,并且可以启动新的进程, 用 exit
退出, 不会导致容器的停止 attach
: 直接进入容器启动命令的终端,不会启动新的进程, 用 exit
退出,会导致容器的停止
-
-
查看容器内部细节
1
docker inspect 容器
id -
从容器内拷贝文件到主机上
-
容器 到 主机
-
命令
1
2
3docker cp 容器
id: 容器内路径 目的主机路径
# Eg: 将 容器 tmp 目录内的文件备份到宿主机
docker cp bc7c957b6662:/tmp ./cp-tmp.txt文件备份
-
-
导入和到导出容器
-
export
: 导出容器的内容六作为一个tar
归档文件 -
import
: 从tar
包中的内容创建一个新的文件系统再导入未镜像 -
案例
1
2# 导出
docker export 容器id > 文件名.tar 1
2
3
4# 导入
cat 文件名.tar | docker import - 镜像用户/ 镜像名: 镜像版本号
# Eg:
cat ubuntu.tar | docker import - coderitl/ubuntu:latest导入与导出
-
Docker-镜像
-
镜像
是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,
我们把应用程序和配置依赖打包形成一个可交付的运行环境 (包括代码、运行时需要的库、环境变量和配置文件), 这个打包好的运行环境就是 image
镜像文件 -
分层的镜像
一个镜像的下载是等待一个一个文件内容的下载 (分层) -
UnionFS(联合文件系统)
UnionFS(联合文件系统)
:Union
文件系统 ( UnionFS
)是一种分层、轻量级并且高性能的文件系统,它支持 对文件系统的修改作为一次提交来一层层的叠加
,同时可以将不同目录挂载到用一个虚拟文件系统下, union
文件系统是 Docker
镜像的基础。 镜像可以通过分层来进行继承
,基于基础镜像 (没有父镜像),可以制作各种具体的应用镜像 特点:一次性同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
-
-
Docker
镜像commit
操作-
docker commit
提交容器副本使之成为一个新的镜像 -
命令
1
docker commit -m="提交的描述信息" -a="作者" 容器
id 要创建的目标镜像名:[标签名] -
案例:
ubuntu
安装 vim
-
从
Hub
上下载 ubuntu
镜像到本地并成功运行 启动,更新容器内部 -
原始的默认
Ubuntu
镜像时不带着 vim
命令的 -
外网联通的情况下,
安装 vim
1
2
3# 容器内部执行
apt-get -y update
apt-get -y install vim -
安装完成后,
commit
我们自己的新镜像 1
2# e50146ce2426: docker ps 获取
docker commit -m="add vim" -a="coder-itl" e50146ce2426 coderitl/ubuntu:1.1 -
启动我们的新镜像并和原来的对比
1
2# ctrl + p + q 【退出,
不关闭容器】
docker run -it coderitl/ubuntu:1.1 bash启动自己制作的镜像
-
-
镜像发布
公服
-
本地镜像发布到阿里云
-
创建阿里云镜像仓库
-
选择控制台,
进入容器镜像服务 (搜索 容器镜像服务
)进入容器镜像服务 -
选择个人实例
点击 个人实例
-
命名空间
创建 命名空间
-
仓库名称
选择命名空间, 创建镜像仓库 填写基本信息 直接选择 本地仓库
-
进入管理界面获得脚本
获取脚本 -
推送到
阿里云
1
2
3
4
5
6# username: 阿里云账号的用户名,
之后输入阿里云账号的密码
$ docker login --username=bin_爱豆 registry.cn-hangzhou.aliyuncs.com
# 如下命令中的 [ImageId] 和 [镜像版本号] 修改为本次推送之远程仓库的信息
$ docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/coder-itl/ubuntu:[镜像版本号]
# [镜像版本号]: 填写版本号
$ docker push registry.cn-hangzhou.aliyuncs.com/coder-itl/ubuntu:[镜像版本号]使用脚本 信息修改 推送到远程
-
-
-
拉取阿里云镜像到本地
-
拉取镜像
1
docker pull registry.cn-hangzhou.aliyuncs.com/coder-itl/ubuntu:[镜像版本号]
拉取自己创建的镜像到本地
-
私服
-
Docker Registry
-
下载镜像
Docker Registry
1
docker pull registry
-
运行私有库
Registry
,相当于本地有个私有Docker hub
1
2
3
4
5
6
7
8
9# 在宿主机创建目录【权限充足时将会自动创建】
mkdir -p /coderitl/myregistry/
# 默认情况,仓库被创建再容器的 /var/lib/registry 目录下, 建议自行用容器卷映射, 方便与宿主机联调
docker run -d -p 5000:5000 -v /coderitl/myregistry/:/tmp/myregistry --privileged=true registry
# -v: 相当于将这两个目录联通共享
/coderitl/myregistry/【宿主机目录】:/tmp/myregistry【容器内目录】
# 默认情况下容器中的root 用户只是 host 主机的一个普通用户,但如果 docker run --privileged=true 就真正的给这个普通用户赋予了和 host 主机 root 用户的特权。 基础操作 -
案例演示创建一个新镜像,
ubuntu
安装 ifconfig
命令 -
进入容器内部
【ubuntu】
1
2
3
4
5
6
7
8# 获取正在运行的容器 id
docker ps
# 进入容器内部
docker exec -it 容器id bash
# 未运行时,可执行如下 registry.cn-hangzhou.aliyuncs.com/coder-itl/ubuntu:1.1【替换】
docker run -it registry.cn-hangzhou.aliyuncs.com/coder-itl/ubuntu:1.1 bash启动容器并进入交互界面 -
执行如下下载
ifconfig
1
2
3
4
5
6
7# 安装
apt-get -y update
apt-get -y install net-tools
# 测试
ifconfig测试命令,使用 ctrl+p+q 退出
-
提交本次镜像
1
2# e50146ce2426: docker ps 获取
docker commit -m="add vim" -a="coder-itl" e50146ce2426 coderitl/ubuntu:1.2镜像提交
-
-
curl
验证私服库上有什么镜像 1
2# ip: 本机
curl -XGET http://192.168.2.3:5000/v2/_catalog私服初始为空 -
将新镜像
coderitl/ubuntu
修改为符合私服规范的 Tag
1
2# 语法: docker tag 镜像:tag Host(ip):Port/Repository:Tag
docker tag coderitl/ubuntu:1.2 192.168.2.3:5000/coderitl/ubuntu:1.2 -
修改配置文件使之支持
http
1
2
3
4
5
6
7
8
9
10
11
12
13# 编辑 daemon.json
vim /etc/docker/daemon.json
# 添加如下
{
... ,
# 在之前内容后补充,使用 "逗号" 分割
"insecure-registries":["192.168.2.3:5000"]
}
# 上述保存退出后,重新加载 daemon
systemctl daemon-reload
systemctl restart docker
# 添加原因: docker 默认不允许 http 方式推送镜像,通过配置选项来取消这个限制 => 修改完如果不生效, 对 docker 进行重启 修改 daemon.json
重启 docker
后, 需要重新启动 registry
-
push
推送到私服库 1
docker push 192.168.2.3:5000/coderitl/ubuntu:1.2
推送时 registry
必须是启动的 -
curl
验证私服库上有什么镜像 1
2# ip: 本机
curl -XGET http://192.168.2.3:5000/v2/_catalog上传成功 -
拉取到本地
1
docker pull 192.168.2.3:5000/coderitl/ubuntu:1.2
拉取镜像
-
容器数据卷
-
是什么
可以将
docker
容器内的数据保存在宿主机的磁盘中 卷: 卷就是一个目录,存在于一个或多个容器中,
由 docker
挂载到容器, 但不属于联合文件系统, 因此能够绕过 Unbion File System
提供的一些用于持续存储或共享数据的特性 卷的设计目的就是
数据的持久化
,完全独立于容器的生命周期,因此 Docker
不会在容器删除时删除其挂载的数据卷 -
权限问题
Docker
挂载目录访问 如果出现 cannout open directory.: Oermission denid
解决方法: 在挂载目录后多加一个
--privileged=true
参数即可 原因: 如果是
Centos7
安全模块会比之前系统版本加强,不安全的会先禁止, 所以目录挂载的情况被默认认为不是安全的行为,在 SELinux
里面挂载目录被禁止掉了,如果要开启,只需要添加 --privileged=true
参数即可,可以扩大容器的权限解决挂载目录没有权限的问题,使用了该参数, 容器 root
将会拥有真正的 root
权限,否则, root
将会只是一个普通 root
用户而已 -
运行一个带有容器数据卷存储功能的容器实例
1
docker run -it --privileged=true -v /
宿主机绝对路径目录:/ 容器内目录 镜像名 -
能做什么
将运行的环境打包成镜像,
run
后形成容器实例运行, 但是我们对数据的要求希望是持久化的 Docker
容器产生的数据,如果我们不备份,那么当容器实例删除后, 容器内的数据自然也就没有了,为了能保存数据在 docker
中我们使用 卷
特点:
- 数据卷可以在容器之间共享或重用数据
- 卷中的更改可以直接试试生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一致持续到没有容器使用它为止
-
创建带有数据卷的
ubuntu
1
2# 权限问题: 默认允许读写
(rw),只读只需要添加配置 /tmp/centos_data:/tmp/docker_dat:ro【read only】
docker run -it --privileged=true -v /tmp/centos_data:/tmp/docker_data --name="cut" ubuntu -
查看数据卷是否挂载成功
1
docker inspect 容器
id 查看挂载目录 容器与宿主机之间实现数据共享 -
卷的继承和共享
1
2
3
4# 父类: cut
docker run -it --privileged=true -v /tmp/centos_data:/tmp/docker_data --name="cut" ubuntu
# name2 获取继承
docker run -it --privileged=true --volumes-from 父类(名称) --name="name2" ubuntu
Docker-常规安装
总体步骤
- 搜索镜像
- 拉取镜像
- 查看镜像
- 启动镜像
- 停止镜像
- 移除镜像
Tomcat
-
搜索
1
docker search --limit 1 tomcat
-
拉取
1
2# Tomcat 10
docker pull tomcat -
启动
1
docker run -d -p 8080:8080 --privileged=true --name="test-tomcat" tomcat
-
新版发生改变
-
首页发生变化
出现如下 -
进入
Tomcat
容器内部 1
docker exec -it 容器
id bash -
主要原因
无法显示首页的原因 -
删除该文件夹
1
rm -r webapps
-
将
webapps.dist
重命名 1
2
3
4# 1. 先进性备份
cp webapps.dist/ -r webapps.dist.back/
# 2. 修改为 webapps
cp -r webapps.dist webapps备份 成功加载首页
-
-
免修该版本下载
1
2# tomcat8
docker run -d -p 8080:8080 --name mytomcat8 billygoo/tomcat8-jdk8
MYSQL
-
安装
1
2
3
4
5
6
7
8# 本机已经安装了 mysql 需要注意端口
docker run -d -p 3306:3306 --privileged=true \
-v /coderitl/mysql/log:/var/log/mysql \
-v /coderitl/mysql/data:/var/lib/mysql \
-v /coderitl/mysql/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=root \
--name mysql \
mysql:5.7-
在目录
/coderitl/mysql/conf
下新建 my.cnf
新建配置文件在数据卷挂载的 conf
目录下 1
2
3
4
5
6
7
8
9
10# 通过容器卷同步给 mysql 容器实例
vim my.cnf
# 添加如下内容
[client]
default-character-set=utf8
[mysqld]
character-set-server=utf8
collation-server=utf8_general_ci1
2
3
4
5
6
7# 添加上下其一即可
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
character-set-server=utf81
2# 查看字符集
show variables like "character_%";字符集 (等待后查看) -
重新启动
mysql
容器实例再重新进入并查看字符集编码 1
docker restart mysql
-
在新建库新建表再插入中文测试
成功显示中文数据
-
-
mysql
最新版 1
2
3
4
5
6
7docker run -d -p 3306:3306 --privileged=true \
-v /coderitl/mysql/log:/var/log/mysql \
-v /coderitl/mysql/data:/var/lib/mysql \
-v /coderitl/mysql/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=root \
--name mysql \
mysql
Redis
-
从
docker hub
上拉取 1
docker pull redis:6.0.8
-
Redis6.0
的配置文件地址 https://raw.githubusercontent.com/redis/redis/6.0/redis.conf
-
修改配置文件
protected-mode no
# bind 127.0.0.1
daemonize no
-
个人已修改使用的配置
获取配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134protected-mode no
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 16
always-show-logo yes
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
dbfilename dump.rdb
rdb-del-sync-files no
dir ./
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-diskless-load disabled
repl-disable-tcp-nodelay no
replica-priority 100
acllog-max-len 128
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
lazyfree-lazy-user-del no
oom-score-adj no
oom-score-adj-values 0 200 800
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
stream-node-max-bytes 4096
stream-node-max-entries 100
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
dynamic-hz yes
aof-rewrite-incremental-fsync yes
rdb-save-incremental-fsync yes
jemalloc-bg-thread yes
-
-
创建容器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 创建目录
mkdir -p /coderitl/redis/conf
# 添加 redis 的配置文件
cd /coderitl/redis/conf
# 将提供的配置文件内容写入 redis.conf 文件中
vim redis.conf
# 注意宿主机是否已经安装 安装需要注意端口
docker run -p 6379:6379 \
--name redis \
--restart=always \
--privileged=true \
-v /coderitl/redis/data/:/data \
-v /coderitl/redis/conf/redis.conf:/etc/redis/redis.conf \
-d redis:6.0.8 redis-server /etc/redis/redis.conf-
拉去镜像后更新添加选项
1
2# 未添加时执行,
作用: 当启动 linux 时跟随启动, 不常用 Redis 时慎用
docker update redis --restart=always
-
NotePad++
-
插件
1
NppFTP
-
使用
SFTP
-
作用
可以直接修改虚拟机内部文件,支持语法高亮
-
文件打开
双击打开的文件
MYSQL-主从复制-Docker
-
步骤
-
新建主服务器容器实例
3307
1
2
3
4
5
6docker run -p 3307: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 mysql:5.7 -
进入
/mydata/mysql-master/conf
目录下新建 my.cnf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16[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 -
修改完配置后重启
master
实例 1
docker restart mysql-master
-
进入
mysql-master
容器 1
2# 进入容器 测试是否可以登录成功
docker exec -it id bash测试是否可以登录成功 -
master
容器实例内创建数据同步用户 1
2
3
4# 创建用户
create user 'slave'@'%' identified by '123456';
# 授权【虚拟机内的 MSQL 没有忽略大小写】
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';windows
忽略大小写 Linux
大小写敏感 -
新建从服务器实例容器
3308
1
2
3
4
5
6docker 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 -
进入
/mydata/mysql-slave/conf
目录下新建 my.cnf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22[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 -
修改完配置后重启
slave
实例 1
docker restart mysql-slave
-
在主数据库中查看主从同步状态
1
show master status;
-
进入
mysql-slave
容器 1
docker exec -it mysql-slave bash
-
在
从数据库
中配置主从复制1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# 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;
# 需要启动的命令
change master to master_host='192.168.2.3', master_user='slave', master_password='123456', master_port=3307, master_log_file='mall-mysql-bin.000002', master_log_pos=154, 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
show slave status\G;
还未开始 -
在
从数据库
中开启主从同步1
start slave;
-
查看
从数据库
状态发现已经同步主从同步已开启 -
主从复制测试
-
主机
新建库-使用库-新建表-插入数据 -
从机使用库-查看记录
主从测试
-
-
安装 Redis 集群-分布式存储案例真题
-
cluster(集群模式)-docker
:哈希槽分区进行亿级数据存储 -
面试题
-
1~2
亿条数据需要缓存,请问如何设计这个存储案例 解决方案如下:
-
哈希取余分区
模型 2
亿条记录就是 2
亿个 k,v
,我们 单机
不行必须要用分布式多机,假设有 3
台机器构成一个集群,用户每次读写操作都是根据公式: hash(key)%N
个机器台数, 计算出哈希值, 用来决定数据映射到哪一个节点上。 -
优点
简单粗暴,
直接有效,只需要预估好数据规划好节点,例如 3
,台、8 台、10 台 就能保证一段时间的数据支撑。使用 Hash
算法让固定的一部分请求落到同一台服务器,这样每台服务器固定处理一部分请求,起到负载均衡和分而治之的作用 -
缺点
原来规划好的节点,进行扩容或者缩容就比较麻烦了,不管扩容、每次数据变动导致节点有变动,映射关系需要重新进行计算,在服务器个数固定不变时没有问题,如果需要弹性扩容或故障停机的情况下,原来的取模公式就会发生变化:
Hash*(key)/3
会变成 Hash(key)/?
.此时地址经过某个 Redis
机器宕机了,由于台数数量变化, 会导致 Hash
取余全部数据重新洗牌
-
-
一致性哈希算法分区
-
背景
一致性算法在
1997
年由麻省理工学院中剔除, 设计目标是为了解决 分布式缓存数据变动和映射问题
,某个机器宕机了,
分母数量改变了,自然取余数就不 OK 了 -
作用
提出一致性
Hash
解决方案,目的是当服务器个数发生变动时,尽量减少影响客户端到服务器的映射关系 -
实现的三大步骤
-
算法构建一致性哈希环
一致性哈希算法必然有个
hash
函数并按照算法产生 hash
值, 这个算法的所有可能哈希值会构成一个全量集,这个集合可以成为一个 hash
空间【 0,2^32-1
】,这个是一个线性空间,但是在算法中,我们通过适当的逻辑控制它首尾相连 ( 0=2^32
),这样让他逻辑上形成了一个环形空间它也是按照使用取模的方法,
前面提到的是对服务器数量进行取模。而一致性 Hash
算法是对 2^32
取模, 简单来说: 一致性 Hash 算法将整个哈希值空间组织成一个虚拟的圆环 如果假设某哈希函数 H
的值空间为 0-2^32-1(即哈希值是一个 32 位无符号整型)
,整个哈希环如下: 整个空间按顺时针方向组织,圆环的正上方的点代表 0
,0
点右侧的第一个点代表 1
,依次类推,直到2^32-1
,也就是说0
点左侧的第一个点代表 2^32-1
,0
和 2^32-1
在零点房中重合,我们把这个由 2^32
个点组成的圆环称为 Hash
环 哈希环 -
服务器
IP
节点映射 将集群中各个
IP
节点映射到环上的某一个位置。 将各个服务器使用
Hash
进行一个 哈希
,具体可以选择服务器的 IP
或主机名作为关键字进行哈希, 这样每台机器就能确定其在哈希环上的位置。假如: 4
个节点 A、B、C、D
经过 IP
地址的 哈希函数计算
,使用(hash(ip)) IP
地址后在环空间的位置如下: 服务器 IP
节点映射 (Eg) -
key
落到服务器的落键规则 当我们需要存储一个
kv
键值对时, 首先计算 key
的 hash
值, hash(key)
,将这个 key
使用相同的函数 Hash
计算出哈希值并确定此数据在环上的位置, 从此位置沿环顺时针"行走" 第一台遇到的服务器就是其应该定位到的服务器, 并将该键值对存储在该节点上。 如果我们有
Object A、B、C、D
四个数据对象, 经过哈希计算后, 在环空间的位置如下: 根据一致性 Hash
算法, 数据 A
会被定位到 Node A
上,… 落键规则
-
-
优点
-
一致性哈希算法的
容错性
假设
Node C
宕机,可以看到此时对象 A、B、D
不会受到影响,只有 C
对象被重定位到 Node D
。一般的,在一致性Hash
算法中,如果一台服务器不可用,则受影响的数据仅仅是此服务器到其环空间中前一台服务器(即沿着逆时针方向行走遇到的第一台服务器)之间数据,其它不会受到影响。简单说,就是 C 挂了,受到影响的只是 B、C 之间的数据,并且这些数据会转移到 D 进行存储。 -
一致性哈希算法的
扩展性
数据量增加了,需要增加一台节点
NodeX,X 的位置在 A 和 B 之间,那收到影响的也就是 A 到 X 之间的数据,重新把 A 到 X 的数据录入到 X 上即可, 不会导致
hash 取余全部数据重新洗牌。
-
-
缺点
一致性
Hash 算法在服务节点太少时,容易因为节点分布不均匀而造成数据倾斜(被缓存的对象大部分集中缓存在某一台服务器上)问题,
-
-
哈希槽分区
-
为什么会出现
是由于
一致性哈希算法中数据倾斜
哈希槽实质上就是一个数组,
数组 [0,2^14-1]
形成一个 hash slot
空间 -
能干什么
解决均匀分配的问题,
在数据和节点之间又加入了一层,
,现在就相当于节点上放的是槽,把这层称为哈希槽 (slot),用于管理数据和节点之间的关系 槽里放的是数据。 槽解决的是粒度问题,相当于把粒度变大了,这样方便于数据移动
哈希解决的是映射问题,
使用 key
的哈希值来计算所在的槽, 便于数据分配 -
多少个
hash
槽 一个集群只能有
16384
个槽,编号 0-16383(0-2^14-1)
。这些槽会分配给集群中的所有主节点,分配策略没有要求。可以指定哪些编号的槽分配给哪个主节点。集群会记录节点和槽的对应关系。解决了节点和槽的关系后,接下来就需要对key
求哈希值,然后对 16384
取余,余数是几 key
就落入对应的槽里。 slot = CRC16(key) % 16384
。以槽为单位移动数据,因为槽的数目是固定的,处理起来比较容易,这样数据移动问题就解决了。 -
哈希槽计算
Redis 集群中内置了 16384 个哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。当需要在 Redis 集群中放置一个 key-value
时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,也就是映射到某个节点上。如下代码,key 之 A 、B 在 Node2, key 之 C 落在 Node3 上 -
3
主 3
从 -
分段
分段
-
创建实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15# --cluster-enabled yes【开启集群】 --appendonly yes【持久化】
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启动查看 -
进入容器
redis-node-1
并为 6
台机器构建集群关系 1
2
3
4
5
6
7
8# 进入 redis-node-1
docker exec -it redis-node-1 bash
# -cluster-replicas 1 表示为每个master 创建一个 slave 节点
redis-cli --cluster create 192.168.2.3:6381 192.168.2.3:6382 192.168.2.3:6383 192.168.2.3:6384 192.168.2.3:6385 192.168.2.3:6386 --cluster-replicas 1
# 之后输入: yes关系构建 (分段)
-
-
链接进入
6381
作为切入点, 查看集群状态 1
2# 在 redis-node-1 容器内部
redis-cli -p 6381整体情况 节点信息 -
主机下挂载从机情况
通过 cluster nodes
查看
-
-
-
-
主从容错切换迁移案例
-
数据读写存储
-
启动
3
主 3
从, 进入 redis-node-1
正常启动 连接 6381
-
连接
6381
,添加2
个 key 添加情况,原因是由于集群分槽导致的,如果在某一个槽超出,将无法插入数据 -
防止路由失效加参数
-c
并再次新增 2 个 key
1
2
3
4# 单机连接方式
redis-cli -p 6381
# 由于现在是集群环境,所以退出单机登录, 添加 -c 参数【集群启动】
redis-cli -p 6381 -c添加情况 -
查看集群信息
1
redis-cli --cluster check 192.168.2.3:6381
集群检查
-
-
-
容错切换迁移
-
主
6381
和 从机切换
,先停止 主机 6381
6381
停止 停止 -
再次查看集群情况
当前情况 从机上位, 对数据未造成影响 -
先还原之前的
3
主 3
从 1
2# 启动 reids-node-1
docker start reids-node-1恢复 -
查看集群状态
当前状态 挂载情况 恢复的主机并不会再次成为
主机
,而是成为其中的一个 从机
-
-
主从扩容
-
新建
6387,6388
两个节点 + 新建后启动 + 查看是否是 8
节点 1
2
3docker 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成功启动 8
台容器 -
进入
6387
容器内部实例 1
docker exec -it redis-node-7 bash
-
将新增的
6387
节点 ( 空槽好
)作为 master
节点加入原集群 1
2
3
4
5
6
7# 将新增的
6387 作为 master 节点加入集群
redis-cli --cluster add-node 自己实际IP 地址:6387 自己实际 IP 地址:6381
redis-cli --cluster add-node 192.168.2.3:6387 192.168.2.3:6381
6387 就是将要作为master 新增节点
6381 就是原来集群节点里面的领路人,相当于6387 拜拜 6381 的码头从而找到组织加入集群 添加节点 -
检查集群情况第一次
1
2# redis-cli --cluster check 真实
ip 地址:6381
redis-cli --cluster check 192.168.2.3:6381成功添加 -
重新分配槽号
1
2# 重新分派槽号 命令: redis-cli --cluster reshard IP
地址: 端口号
redis-cli --cluster reshard 192.168.2.3:6381添加节点后槽位信息为空 16384/master
=4096数 选择分配的容器 id, 后续输入 yes
-
检查集群情况第二次
再次查看槽位信息 (6387 槽位来自于其他三个的分配组成了 4096
)为什么
6387
是 3
个新的区间,以前的还是连续? 重新分配成本太高,所以前
3
家各自匀出来一部分,从 6381/6382/6383
三个旧节点分别匀出 1364
个坑位给新节点 6387
-
为主节点
6387
分配从节点 6388
1
2
3
4
5
6
7
8
9
10# 命令:redis-cli --cluster add-node ip:
新 slave 端口 ip: 新 master 端口 --cluster-slave --cluster-master-id 新主机节点 ID
# 查看 id
redis-cli --cluster check 192.168.2.3:6381
# 364259ffcb88b0f84cc14c1e3686bf94ed3708d4: -------这个是6387 的编号,按照自己实际情况
# 分配
redis-cli --cluster add-node 192.168.2.3:6388 192.168.2.3:6387 --cluster-slave --cluster-master-id 364259ffcb88b0f84cc14c1e3686bf94ed3708d4主节点: 6387
-
检查集群情况第三次
4
主 4 从
-
-
主从缩容
-
目的:
6387
和 6388 下线 -
检查集群情况获得
6388(从机端口)
的节点 ID
1
2redis-cli --cluster check 192.168.2.3:6381
slave: 38829c4b96974ad6002a8c71c55722a6787a14c5 -
将
6388
删除, 从集群中将 4
号从节点 6388 删除 1
2# 命令:redis-cli --cluster del-node ip:
从机端口 从机 6388 节点 ID
redis-cli --cluster del-node 192.168.2.3:6388 38829c4b96974ad6002a8c71c55722a6787a14c5 -
将
6387
的槽号清空, 重新分配, 本例将清出来的槽号都给 6381
1
redis-cli --cluster reshard 192.168.2.3:6381
输入 -
检查集群情况第二次
4 主 3 从 -
将
6387(主)
删除 1
2# 命令:redis-cli --cluster del-node ip:
端口 6387 节点 ID
redis-cli --cluster del-node 192.168.2.3:6387 364259ffcb88b0f84cc14c1e3686bf94ed3708d4 -
检查集群情况第三次
恢复 3
主 3 从
-
Dockerfile
-
是什么
Dockerfile
使用来构建Docker
镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本 -
构建三步骤
- 编写
Dockerfile
文件 docker build
命令构建镜像 docker run
以镜像运行容器实例
- 编写
-
Dockerfile-构建过程解析
-
基础内容
- 每条保留字指令都
必须为大写字母
且后面要跟随至少一个参数 - 指令按照从上到下,顺序执行
#
表示注释- 每条指令都会创建一个新的镜像曾并对镜像进行提交
- 每条保留字指令都
-
大致流程
docker
从基础镜像运行一个容器 - 执行一条指令并对容器做出修改
- 执行类似
docker commit
的操作提交一个新的镜像层 - 执行
dockerfile
中的下一条指令直到所有指令都执行完成
-
-
保留字
-
FROM
: 基础镜像,当前新镜像是基于那个镜像的,指定一个已经存在的镜像作为模板, 第一条必须是 FROM
-
MAINTAINER
: 镜像维护者的姓名和邮箱地址 -
RUN
: 容器构建时需要运行的命令-
shell
格式 1
RUN yum -y install vim
-
exec
格式
-
-
EXPOSE
: 当前容器对外暴露的端口 -
WORKDIR
: 指定在创建容器后,终端默认登录的进来工作目录, 一个落脚点 -
USER
: 指定该镜像以什么样的用户去执行,如果都不指定,默认是 root
-
ENV
: 用来在构建镜像过程中设置环境变量 -
ADD
:将宿主机目录下的文件拷贝进镜像切会自动处理URL
和解压 tar
压缩包 -
COPY
-
VOLUME
: 容器数据卷,用于数据保存和持久化工作 -
CMD
- 指定容器启动后要干的事情,可以有多个,
但只有最有一条生效 - 和
RUN
的区别 CMD
是在 docker run
时运行RUN
是在 docker build
时运行
- 指定容器启动后要干的事情,可以有多个,
-
ENTRYPOINT
- 是用来指定一个容器启动时要运行的命令
- 类似于
CMD
指令, 但是 ENTRYPOINT
不会被 docker run
后面的命令覆盖,而且这些命令行参数 会被当做参数送给 ENTRYPOINT
指令指定的程序 - 优点: 在执行
docker run
的时候可以指定 ENTRYPOINT
运行时所需的参数 - 注意: 如果
Dockerfile
中如果存在多个 ENTRYPOINT
指令, 仅最后一个生效
-
-
实战
-
镜像地址
-
目标: 自定义镜像
- 基础镜像
centos
- 添加
vim
- 添加
net-tools
- 基础镜像
-
步骤
- 编写
Dockerfile
文件名就是 Dockerfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33FROM centos
MAINTAINER coderitl<3327511395@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
# 更新yum
RUN cd /etc/yum.repos.d/
RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*
RUN sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*
RUN yum -y update
RUN yum makecache
#安装 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-8u171-linux-x64.tar.gz /usr/local/java/
#配置java 环境变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
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-
构建
1
2
3
4# 语法: 最后有一个 点
docker build -t 镜像名称:TAG .
# 构建
docker build -t centos-java8:1.0 .构建 -
运行
1
docker run -it 新镜像名称:TAG
测试
- 编写
-
-
虚悬镜像
虚悬镜像 -
查看所有虚悬镜像
1
docker image ls -f dangling=true
-
删除
1
2# 虚悬镜像已经失去存在价值,
可以删除
docker image prune
-
Docker-网络
-
虚拟网桥
docker0
-
查看
docker
网络模式命令 1
docker network ls
网络模式 -
能干什么
- 容器间的互联和通信以及端口映射
- 容器
IP
变动时候可以通过服务名直接网络通信而不受到影响
-
docker0
Docker
服务默认会创建一个 docker0
网桥 (其上有一个 docker0
内部接口), 该桥接网络的名称为 docker0
,它在 内核层
连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到 同一个物理网络
,Docker
默认指定了 docker0
接口的 IP
地址和子网掩码, 让主机和容器之间可以通过网桥相互通信 bridge
模型
Docker-Compose
-
是什么
Docker-Compose
是 Docker
官方的开源项目, 负责实现对 Docker
容器集群的快速编排 -
作用
简化参数,
使用 *.yml
文件易于维护, yml
文件严格要求空格和缩进, 不要使用 tab
-
下载
1
2
3
4
5
6
7# 下载: https://github.com/docker/compose/releases/download/v2.15.1/docker-compose-linux-x86_64(下载地址)
curl -SL https://github.com/docker/compose/releases/download/v2.15.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
# 如果是在 windows 上下载传输到linux, 需要重命名
# 添加可执行权限
chmod 777 docker-compose
# 软连接【不需要再进行后续的环境变量配置】
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose下载 -
测试
docker-compose
环境变量 测试 docker-compose
环境变量 -
核心概念
- 一个文件:
docker-compose.yml
- 两个要素
- 服务: 一个个应用容器实例:
mysql、redis....
- 工程: 由一组关联的应用容器组成的一个
完整业务单元
,在 docker-compose.yml
文件中定义
- 服务: 一个个应用容器实例:
- 一个文件:
-
常用命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15docker-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 # 查看容器输出日志
docker-compose config # 检查配置
docker-compose config -q # 检查配置,有问题才有输出
docker-compose restart # 重启服务
docker-compose start # 启动服务
docker-compose stop # 停止服务
-
docker-compose
管理容器 -
语法
yml
文件以 key:value
方式来指定配置信息 多个配置信息以
换行 + 缩进
的方式来区分 -
管理
Tomcat
和 mysql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25version: '3.1' # docker 版本
services:
mysql: # 服务名称
restart: always # 代表只要 docker 启动,那么这个容器就跟着一起启动
image: daocloud.io/library/mysql:5.7.31 # 指定镜像路径
container_name: mysql # 指定容器名称
ports:
- 3306:3306 # 指定端口号映射 (- 可以映射多个)
environment:
MYSQL_ROOT_PASSWORD: root # 指定 MYSQL 的root 用户登录密码
TZ: Asia/Shanghai # 指定时区
volumes:
- /opt/docker_mysql_tomcat/mysql_data:/var/lib/mysql # 映射数据卷
tomcat:
restart: always # 代表只要 docker 启动,那么这个容器就跟着一起启动
image: daocloud.io/library/tomcat:8.0.45 # 指定镜像路径
container_name: tomcat # 指定容器名称
ports:
- 8080:8080 # 指定端口号映射 (- 可以映射多个)
environment:
TZ: Asia/Shanghai # 指定时区
volumes:
- /opt/docker_mysql_tomcat/tomcat_webapps:/usr/local/tomcat/webapps # war 映射数据卷
- /opt/docker_mysql_tomcat/tomcat_logs:/usr/local/tomcat/logs # 日志映射数据卷 -
使用
docker-compose
命令管理 *.yml
文件 1
2
3
4
5
6
7
8# 先删除之前的 mysql 和 tomcat
docker images
# 1. 停止
docker stop $(docker ps -qa)
# 2. 删除
docker rm $(docker ps -qa)
# 3. 检测
docker images删除之前所有镜像 -
docker-compose
命令启动 1
2
3
4
5
6
7
8
9
10
11
12
13# 后台启动
docker-compose up -d
# 关闭删除容器
docker-compose down
# 开启 | 关闭 | 重启 已经存在的由 docker-compose维护的容器
docker-compose start | stop | restart
# 查看由 docker-compose 管理的容器
docker-compose ps
# 查看日志
docker-compose logs -f-
运行
成功执行 docker-compose.yml
-
-
-
docker-compose
管理自定义镜像 -
文件目录层级
1
2
3
4
5
6
7
8
9
10
11
12➜ cprogram tree /f
Folder PATH listing
Volume serial number is 214A-AF6E
E:.
│ Dockerfile
│ index.html
│
└───docker-compose
docker-compose.yml # docker-compose up -d 在此目录执行
➜ cprogram -
Dockerfile
1
2
3# 容器内部路径需要准确无误
from daocloud.io/library/nginx:1.9.1
copy index.html /usr/share/nginx/html # 如果后面的路径不正确nginx 是不能访问到指定的资源文件, 会启动为 nginx 默认页面 -
docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14version: '3.1'
services:
nginx_show_index:
restart: always
build:
# 构建自定义镜像
context: ../ # 指定 dockerfile 文件的所在路径
dockerfile: Dockerfile # 指定Dockerfile 文件名称
image: myNginxShowIndex:1.0.0 # 自定义镜像名
container_name: nginx_show_index # 容器名称
ports:
- 81:80
environment:
TZ: Asia/Shanghai -
提示
1
2
3
4
5
6
7
8可以直接启动基于 docker-compose.yml 以及 Dockerfiler 文件构建的自定义镜像
docker-compose up -d
如果自定义镜像不存在,会帮助我们构建出自定义镜像, 如果自定义镜像已经存在, 会直接运行这个自定义镜像
重新构建
重新构建自定义镜像
docker-compose build
运行前 重新构建
docker-compose up -d --build
-
-
微服务制作
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47version: "3"
services:
microService:
image: coderitl_docker:1.6
container_name: ms01
ports:
- "6001:6001"
volumes:
- /app/microService:/data
networks:
- coderitl
depends_on:
- redis
- mysql
redis:
image: redis:6.0.8
ports:
- "6379:6379"
volumes:
- /app/redis/redis.conf:/etc/redis/redis.conf
- /app/redis/data:/data
networks:
- coderitl
command: redis-server /etc/redis/redis.conf
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: '123456'
MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
MYSQL_DATABASE: 'db2021'
MYSQL_USER: 'root'
MYSQL_PASSWORD: 'root'
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:
- coderitl
command: --default-authentication-plugin=mysql_native_password #解决外部无法访问
# 配置在同一网段【docker-网络部分学习】
networks:
coderitl:
Docker-轻量级可视化工具 Portainer
-
安装
1
2
3
4
5
6docker run -d -p 8000:8000 -p 9000:9000 \
--name protainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer_data:/data \
portainer/portainer-ce:latest -
通过
ip:9000
访问 -
设置
admin
用户和密码 ( coder-itl
)后首次登录 创建用户 -
登录后选择
local
监控本地
Docker-CI、CD
CI
-
ci
介绍 **CI(continuous intergration)**:持续集成
持续集成: 编写代码时,
完成了一个功能后, 立即提交代码到 Git
仓库中, 将项目重新构建并且测试 - 快速发现错误
- 防止代码偏离主分支
-
搭建
gitlab
1
2
3
4
5
6修改 ssh 默认连接端口
vim /etc/ssh/sshd_config
修改 Port 22 => 其他端口 保存 => 退出 注意下次连接Linux 时, 修改端口
重启 sshd
systemctl restart sshd修改 ssh 端口,为了给 gitlab
使用 -
创建
docker-compose.yml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24version: '3.1'
services:
gitlab:
image: 'coderitl2218/gitlab-ce-zh:11.1.4'
container_name: "gitlab"
restart: always
privileged: true
hostname: 'gitlab'
environment:
TZ: 'Asia/Shanghai'
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://47.104.232.247' # 注意修改
gitlab_rails['time_zone'] = 'Asia/Shanghai'
gitlab_rails['smtp_enable'] = true
gitlab_rails['gitlab_shell_ssh_port'] = 22
ports:
- '80:80' # 注意修改
- '443:443'
- '22:22'
volumes:
- /opt/docker_gitlab/config:/etc/gitlab
- /opt/docker_gitlab/data:/var/opt/gitlab
- /opt/docker_gitlab/logs:/var/log/gitlab -
搭建成功
-
搭建
gitlab-runner
-
创建
docker
卷1
docker volume create gitlab-runner-config
-
使用我们刚刚创建的卷启动
GitLab Runner
容器1
2
3
4
5
6
7docker run -d --name gitlab-runner --restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v gitlab-runner-config:/etc/gitlab-runner \
gitlab/gitlab-runner:latest
-v gitlab-runner-config 本地配置文件查看路径 -
检测是否安装
检测 gitlab-runner
-
添加容器权限,保证容器可以使用宿主机的
docker,
docker exec -it gitlab-runner usermod -aG root gitlab-runner
-
注册
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29docker exec -it gitlab-runner gitlab-runner register
输入 GitLab 地址
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
http://192.168.199.109/
输入 GitLab Token
Please enter the gitlab-ci token for this runner:
1Lxq_f1NRfCfeNbE5WRh
输入 Runner 的说明
Please enter the gitlab-ci description for this runner:可以为空
设置 Tag,可以用于指定在构建规定的 tag 时触发 ci
Please enter the gitlab-ci tags for this runner (comma separated):
deploy
这里选择 true ,可以用于代码上传后直接执行(根据版本,也会没有次选项)
Whether to run untagged builds [true/false]:
true
这里选择 false,可以直接回车,默认为 false(根据版本,也会没有次选项)
Whether to lock Runner to current project [true/false]:
false
选择 runner 执行器,这里我们选择的是 shell
Please enter the executor: virtualbox, docker+machine, parallels, shell, ssh, docker-ssh+machine, kubernetes, docker, docker-ssh:
shell-
按顺序输入
输入指定信息 成功创建 -
进一步设置
点击编辑 选择如下选项
-
-
-
测试
gitlab
推送 -
这里比较麻烦
我的 http
始终是没有测试推送成功过 -
在
windows
下关于 ssh_key
始终也没能验证成功, 为了赶进度, 暂时跳过 -
解决方案
-
使用
Linux
下创建 ssh-keygen -t rsa -C "admin@example.com"
1
2
3gitlab 默认提供的 邮箱也用它,
没能验证成功邮箱,gitlab 注册页面没有在弹出, 也就再没理会该问题
git config --global user.name "Administrator"
git config --global user.email "admin@example.com" -
查看并添加
SSH
到 gitlab
1
2
3
4
5cd ~/.ssh/
ls
cat xxx.pub
复制该文件内容,注意空格 -
修改
linux
下的~/.ssh/
的权限 1
2
3都执行一下
chmod 755 ~/.ssh/
chmod 600 ~/.ssh/id_rsa ~/.ssh/id_rsa.pub #一般执行这条就行了。 -
寻找
SSH
添加位置 添加 ssh_key -
验证是否成功
1
2验证 gitlab 服务器
ssh -T git@47.104.232.247-
输出
验证是否添加成功
-
-
尝试克隆仓库
拉取 gitlab
公共仓库 -
再次测试直接添加
remote
初始化本地仓库-
创建远程仓库
创建远程仓库 -
关联仓库测试推送
( 第一天是没能实现管理的,
)一直报错是关于 not found 关联仓库测试推送 -
windows
再次测试拉取 -
解决方案
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16在 ~/.ssh/config 文件中添加如下信息
gitlab
Host gitlab-服务器ip 不添加端口号
HostName gitlab-服务器ip 不添加端口号
User root
IdentityFile ~/.ssh/cp_id_rsa # 我这里将 linux 的 文件复制下来了
命令行执行
ssh-keygen -R gitlab服务器 IP
输出一下信息
Host 47.104.232.247 found: line 8
C:\Users\coderitl/.ssh/known_hosts updated.
Original contents retained as C:\Users\coderitl/.ssh/known_hosts.old -
测试拉取远程仓库
Windows 拉取远程仓库 -
成功解决在
windows
上的免密推送 Windows
成功推送到 gitlab
仓库
-
-
-
-
-
持续集成
-
创建
maven
项目,并关联 gitlab
远程仓库 -
创建
.gitlab-ci.yml
选择 CI-CD
创建 .gitlab-ci.yml
-
失败
( 进入流水线之后,观察到是使用
)http,而我已经开启了 ssh 日志报错信息 runner 类型 服务器阻塞 本地 centos 成功运行 -
宿主机安装
java 、maven
并配置环境变量 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28先安装 wget
yum -y install wget
创建文件夹管理(Linux 其实和 Windows 安装一样, 位置首先自己得清楚)
mkdir environment
进入该目录
cd environment
下载 maven 需要注意下载的文件里面是否含有 bin 目录 ,下载 3.8.4 没有出现 bin 目录, 这里使用 3.6
wget https://mirrors.tuna.tsinghua.edu.cn/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz
alibaba => Java(github下载很慢, 建议下载到 windows 传输)
wget https://github.com/alibaba/dragonwell8/releases/download/dragonwell-8.8.9_jdk8u302-ga/Alibaba_Dragonwell_8.8.9_x64_linux.tar.gz
解压
tar -zxvf apache-maven-3.6.3-bin.tar.gz
进入解压后的目录
cd apache-maven-3.6.3
获取所在目录
pwd
复制好上述输出的目录
编辑环境变量
vim /etc/profile
进入文件末尾 添加如下,注意匹配
JAVA_HOME=/root/maven_3.6.3/jdk1.8.0_231
MAVEN_HOME=/root/maven_3.6.3/apache-maven-3.6.3
export PATH=$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH
是环境变量生效
source /etc/profile-
检测是否安装成功
检测安装环境是否正常
-
-
http 解决连接
-
创建访问令牌
头像 => 设置 => 左侧
(访问令牌) => 创建访问令牌, 最后添加的是此处的令牌 创建仓库令牌 -
修改连接参数
1
2
3http:oauth:
拥有可读可写的令牌 @gitlab-服务器地址: 端口 / 用户名 / 仓库名.git
Eg
http:oauth2:xxxxxx@192.168.0.128:22/root/coder-itl.git -
测试
修改连接参数
CD(Jenkins)
-
实现持续交付持续部署
-
官网
https:www.jenkins.io
-
docker-compose.yml
1
2
3
4
5
6当前工作目录: /root/data/jenkins
mkdir data
chmod 777 data
user的 uid 为 1000
mkdir -p /var/jenkins_home
chown -R 1000:1000 /var/jenkins_home1
2
3
4
5
6
7
8
9
10
11version: "3.1"
services:
jenkins:
image: jenkins/jenkins
restart: always
container_name: jenkins
ports:
- 8888:8080
- 50000:50000
volumes:
- ./data:/var/jenkins_home -
密码在
jenkins
容器日志中, 访问时输入 1
docker logs -f jenkins
Jenkins
密码 -
访问
1
http://ip:8888/
-
选择插件安装
-
git
系列 git
系列选择 -
ssh
,publish 因为安全问题被下架
-
-
-
配置目标服务器与
Gitlab
免密登录 -
目标服务器
入口 SSH 配置 测试链接 -
免密登录
-
进入
jenkins
容器内创建密钥 1
2
3
4
5
6
7
8
9docker ps
docker exec -it [jenkins | 容器id] bash
三次回车
ssh-keygen -t rsa -C "email"
退出容器
exit
进入容器中显示存放的目录
cd /root/data/jenkins/data/.ssh -
gitlab
添加 SSH
生成的 xxx.pub
的内容
-
-
为
Jenkins
配置 maven、java(添加容器内的路径)
1
2
3
4复制环境中已经存在的文件 到 jenkins 的映射目录中
cp -R maven/ ~/data/jenkins/data/
cp -R java/ ~/data/jenkins/data/
宿主机的映射路径Maven 配置位置,全局配置的下面` 容器内环境位置
-
-
手动拉取
gitlab
项目 -
生成
密钥
1
2
3
4
5
6
7
8
9
10
11
12
13
14ssh-keygen -t rsa -C "admin@example.com"
生成 config 文件
gitlab
Host ip
HostName ip
User root
IdentityFile ~/.ssh/id_rsa
权限
chmod 400 ~/.ssh/id_rsa
IdentityFile ~/.ssh/id_rsa => 这个目录不变,在 jenkins 容器内生成的密钥默认放在容器内的该路径下, -
gitlab
添加密钥 -
测试克隆项目
clone 一次, 输入 yes
,二次拉取就不需要验证了
-
-
Jenkins
创建 maven
任务 -
全局凭证
添加私钥 -
maven
构建选择 maven
-
配置
maven 本地仓库 和 阿里云镜像
-
构建输出
Jenkins 成功实现 -
文件位置
1
2
3
4
5
6
7
8
9[INFO] Copying webapp resources [/var/jenkins_home/workspace/Test-CD/src/main/webapp]
[INFO] Building war: /var/jenkins_home/workspace/Test-CD/target/gitlab-ci-1.0-SNAPSHOT.war
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:20 min
[INFO] Finished at: 2022-02-17T07:40:12Z
[INFO] ------------------------------------------------------------------------
Finished: SUCCESS
-
-
实现持续交付持续部署
-
安装
Git Parameter | Persistent
根据版本可选择, 完成后选择 重启
重启 (过程漫长) -
重新指定构建项目的方式
-
添加参数构建
添加参数构建 配置 -
修改
构建
删除初始的 maven
选择为脚本 shell
-
编写
shell
1
2
3
4
5echo $Tag
cd /var/jenkins_home/workspace/Test-CD
git checkout $Tag
git pull origin $Tag
/var/jenkins_home/maven/apache-maven-3.6.3/bin/mvn clean package容器内 maven
-
-
构建后配置
-
-
构建项目成功后,
需要将内容发布到目标服务器 -
修改程序代码
-
测试
-
GITLAB-删除不需要的远程仓库
-
删除位置路径
1
进入项目 => 点击左侧导航栏设置 => 通用 => Advanced(展开) => 下拉 => 删除 (输入红色标注内容) -
演示
gitlab
仓库删除
-
Docker-快速安装
-
vim docker-install.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44echo -e "\e[1m\e[4m\e[34minto.........................................................\e[0m\n"
echo -e "\e[1m\e[4m\e[34minto remove docker...........\e[0m"
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
echo -e "\e[1m\e[4m\e[34minto download utils...........\e[0m\n"
yum install -y yum-utils device-mapper-persistent-data lvm2
echo -e "\e[1m\e[4m\e[34minto add repo...........\e[0m\n"
sudo yum-config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo
echo -e "\e[1m\e[4m\e[34minto yum makecache...........\e[0m\n"
yum makecache fast
echo -e "\e[1m\e[4m\e[34minto install docker-ce...........\e[0m\n"
sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
echo -e "\e[1m\e[4m\e[34minto config daemon.json...........\e[0m\n"
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors":[
"https://eyy45bvx.mirror.aliyuncs.com",
"https://hub-mirror.c.163.com",
"https://registry.aliyuncs.com",
"https://registry.docker-cn.com",
"https://docker.mirrors.ustc.edu.cn"
]
}
EOF
echo -e "\e[1m\e[4m\e[34minto daemon-reload...........\e[0m\n"
sudo systemctl daemon-reload
echo -e "\e[1m\e[4m\e[34minto restart docker...........\e[0m\n"
sudo systemctl restart docker
echo -e "\e[1m\e[4m\e[34mend.........................................................\e[0m\n"