分享Docker的各种部署(亲测可行)

本文的所有资料是我查阅各类博客亲测可用后借鉴和记录下来的,大家如果想要快速搭建的话可以参考,避免踩坑



Docker部署Nacos


  1. docker拉取镜像
docker pull nacos/nacos-server:v2.1.0
  1. 创建目录(目的是为了后面进行挂载)
mkdir -p /home/nacos/logs/ #新建logs目录
mkdir -p /home/nacos/conf/ #新建conf目录
  1. 启动nacos并复制文件到宿主机,关闭容器
# 启动容器
docker run -p 8848:8848 --name nacos -d nacos/nacos-server

# 复制文件 (前面的路径是容器的,后面的是linux本地的)
docker cp nacos:/home/nacos/logs/ /home/nacos/
docker cp nacos:/home/nacos/conf/ /home/nacos/

# 关闭容器
docker rm -f nacos


这一步启动nacos是为了将nacos里面的文件拷贝出到挂载目录中,这样我们就可以直接修改挂载目录中文件来映射到容器里面去了


4. 重新启动nacos

多行表示:

docker run -d
--name nacos
-p 8848:8848 -p 9848:9848 -p 9849:9849
--privileged=true
-e JVM_XMS=256m
-e JVM_XMX=256m
-e MODE=standalone
-v /home/nacos/logs/:/home/nacos/logs
-v /home/nacos/conf/:/home/nacos/conf/
--restart=always
nacos/nacos-server:v.2.1.0 (不行就直接用镜像ID)

一行表示:

docker run -d --name nacos -p 8848:8848 -p 9848:9848 -p 9849:9849 --privileged=true -e JVM_XMS=256m -e JVM_XMX=256m -e MODE=standalone -v /home/nacos/logs/:/home/nacos/logs -v /home/nacos/conf/:/home/nacos/conf/ --restart=always nacos/nacos-server:v.2.1.0 (不行就直接用镜像ID)


docker run -d : 启动容器 -d是后台启动并返回容器id的意思
–name nacos :为容器指定一个名称
-p 8848:8848 -p 9848:9848 -p 9849:9849 : 指定端口映射,注意这里的p不能大写,大写是随机端口映射
–privileged=true : 扩大容器内的权限,将容器内的权限变为root权限,不加的话就是普通用户权限,可能会出现cannot open directory
-e JVM_XMS=256m : 为jvm启动时分配的内存
-e JVM_XMX=256m : 为jvm运行过程中分配的最大内存
-e MODE=standalone : 使用 standalone模式(单机模式),MODE值有cluster(集群)模式/standalone模式两种,MODE必须大写
-v /mydata/nacos/logs/:/home/nacos/logs : 将容器的/home/nacos/logs目录挂载到 /mydata/nacos/logs
-v /mydata/nacos/conf/:/home/nacos/conf/: 将容器的/home/nacos/conf目录挂载到 /mydata/nacos/conf
–restart=always :重启docker时,自动启动相关容器



注意事项


  1. 需要开放防火墙
## 开放端口8848 9848 9849
firewall-cmd --zone=public --add-port=8848/tcp --permanent
firewall-cmd --zone=public --add-port=9848/tcp --permanent
firewall-cmd --zone=public --add-port=9849/tcp --permanent

## 重启防火墙
firewall-cmd --reload

## 查看所有开启的端口
firewall-cmd --zone=public --list-ports
  1. 重启docker
## 重启docker
systemctl restart docker
  1. 访问页面
http://ip:8848/nacos/index.html



补充



nacos默认使用的数据库不是MySQL,如果想要使用MySQL实现数据持久化到数据库,可以自行更改。






Docker部署ElasticSearch


1.拉取ES镜像


docker pull elasticsearch:7.17.9



2.安装临时ES容器,用于拷贝挂载文件


docker run --name es -d -e ES_JAVA_OPTS="-Xms512m -Xmx512m" -e "discovery.type=single-node" -p 9200:9200 -p 9300:9300 elasticsearch:7.17.9



3.拷贝挂载目录下的文件


docker cp -a es:/usr/share/elasticsearch/config/ /home/es

docker cp -a es:/usr/share/elasticsearch/data/ /home/es

docker cp -a es:/usr/share/elasticsearch/logs/ /home/es


docker cp -a es:/usr/share/elasticsearch/plugins/ /home/es




4 停止es服务,并删除临时容器


docker stop es
docker rm es


5 创建正式es容器


docker run -p 9200:9200 -p 9300:9300 \
--privileged=true --name es \
--net mynet \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms300m -Xmx300m" \
-v /home/es/plugins:/usr/share/elasticsearch/plugins \
-v /home/es/data:/usr/share/elasticsearch/data \
-v /home/es/logs:/usr/share/elasticsearch/logs \
-v /home/es/config:/usr/share/elasticsearch/config \
-d elasticsearch:7.17.9
上面的这种是使用了自定义网络 mynet,大家可以自行创建;下面是使用了host网络,连通linux本地,可以根据具体情况采用不同的网络形式。



docker run -p 9200:9200 -p 9300:9300 \
--privileged=true --name es \
--net host \
-e "discovery.type=single-node" \
-e ES_JAVA_OPTS="-Xms300m -Xmx300m" \
-v /home/es/plugins:/usr/share/elasticsearch/plugins \
-v /home/es/data:/usr/share/elasticsearch/data \
-v /home/es/logs:/usr/share/elasticsearch/logs \
-v /home/es/config:/usr/share/elasticsearch/config \
-d elasticsearch:7.17.9



说明

1 privileged=true 允许访问挂载目录

2 "discovery.type=single-node" 单机版

3 ES_JAVA_OPTS="-Xms256m -Xmx256m" 设置内存,如果服务器内存不是很大,这里设置小点,否则服务将起不来



6 设置允许跨域 (这一步可选做)


打开es配置文件 elasticsearch.yml,添加如下,这样head插件就可以访问 es服务器了

http.cors.enabled: true
http.cors.allow-origin: "*"
http.cors.allow-headers: Authorization,X-Requested-With,Content-Length,Content-Type



7 kibana远程访问


如果你本地已经安装了kibana就无需在远程服务器上安装kibana了,只要做如下的设置就可以通过本地的kibana访问远程的es,打开本地的kibana的配置文件 kibana.yml,添加如下语句

elasticsearch.hosts: ["<此处填写自己的远程服务器ip:9200>"]


下面是提供的DSL用于测试分词器

GET _search
{
"query": {
"match_all": {}
}
}


POST _analyze
{
"analyzer": "ik_max_word",
"text": "你好我是人"
}


PUT /yingzisou_post
{
"settings": {
"analysis": {
"analyzer": {
"text_analyzer": {
"tokenizer": "ik_smart",
"filter": "py"
},
"completion_analyzer": {
"tokenizer": "keyword",
"filter": "py"
}
},
"filter": {
"py": {
"type": "pinyin",
"keep_full_pinyin": false,
"keep_joined_full_pinyin": true,
"keep_original": true,
"limit_first_letter_length": 16,
"remove_duplicated_term": true,
"none_chinese_pinyin_tokenize": false
}
}
}
},
"mappings": {
"properties": {
"id": {
"type": "long"
},
"title": {
"type": "text",
"analyzer": "text_analyzer",
"search_analyzer": "ik_smart"
},
"content": {
"type": "text",
"analyzer": "text_analyzer",
"search_analyzer": "ik_smart"
},
"thumbNum": {
"type": "long"
},
"favourNum": {
"type": "long"
},
"userId": {
"type": "long"
},
"suggestion":{
"type": "completion",
"analyzer": "completion_analyzer"
}
}
}
}


GET /yingzisou_post/_search


8 记录一次尝试修复elasticsearch Data too large问题


如果说kibana启动不起来,看看是不是es设置的堆栈内存太小了







Docker部署MySQL


1.拉取镜像


在线拉取镜像
命令:docker pull mysql


2.创建持久化存储,日志,配置文件目录


第一步:创建存储目录,日志目录,配置文件目录
命令:mkdir -p /home/mysql/{conf,data,log}

第二步:创建MySQL配置文件
命令:touch /home/mysql/conf/my.cnf

第三步:写入以下配置文件内容
命令:vim /home/mysql/conf/my.cnf


[client]
#设置客户端默认字符集utf8mb4
default-character-set=utf8mb4
[mysql]
#设置服务器默认字符集为utf8mb4
default-character-set=utf8mb4
[mysqld]
#配置服务器的服务号,具备日后需要集群做准备
server-id = 1
#开启MySQL数据库的二进制日志,用于记录用户对数据库的操作SQL语句,具备日后需要集群做准备
log-bin=mysql-bin
#设置清理超过30天的日志,以免日志堆积造过多成服务器内存爆满
expire_logs_days=30
#解决MySQL8.0版本GROUP BY问题
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
#允许最大的连接数
max_connections=1000
# 禁用符号链接以防止各种安全风险
symbolic-links=0
# 设置东八区时区
default-time_zone = '+8:00'




第四步:赋予目录权限

chmod 777 /home/mysql/conf/my.cnf /home/mysql/data/ /home/mysql/log


3.启动MySQL镜像


启动镜像命令:

docker run -p 3306:3306 --restart=always --name mysql --privileged=true -v /home/mysql/log:/var/log/mysql -v /home/mysql/data:/var/lib/mysql -v /home/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -d mysql --lower-case-table-names=1


解析:

-p:主机端口:容器端口。

-d:启动的镜像名称。

--name:设置容器名称。

--privileged=true:赋予容器权限修改宿主文件权利。

--restart=always:设置docker启动时,容器跟随自启。

--lower-case-table-names=1:用于指定表名是否进行大小写不敏感的处理。

-e MYSQL_ROOT_PASSWORD=123456:设置MySQL的root用户的密码。

-v /home/mysql/log:/var/log/mysql:挂载容器日志到宿主,方便查看日志。

-v /home/mysql/conf:/etc/mysql/conf.d:挂载容器配置文件到宿主,方便修改配置文件。

-v /home/mysql/data:/var/lib/mysql:挂载容器存储文件到宿主,避免因不小心卸载容器或者容器损坏导致数据丢失不可找回风险。


4.开启防火墙


第一步:开启指定防火墙端口命令:

命令:firewall -cmd --add-list=3306/tcp --permanent


第二步:刷新防火墙

命令:firewall-cmd --reload




Docker修改MySQL的占用内存大小


修改mysql占用内存大小


因为自己部署服务内存比较小,而mysql在docker初始化就占500M,所以可优化其占用内存大小

1.查看运行内存

[root@ ~]# docker stats



CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS



a28d702be74a mysql 0.34% 400.49MiB / 1.694GiB 24.33% 0B / 0B 19.3MB / 14.1MB 38



c8adbf02c7a5 kafka 0.30% 435.7MiB / 1.694GiB 25.11% 1.77MB / 2.93MB 130MB / 86kB 65



92187cc1f68e zookeeper 0.07% 89.78MiB / 1.694GiB 5.18% 2.93MB / 1.77MB 99.5MB / 127kB 19

2.进入mysql容器终端

docker exec -it mysql bash

3.切换进入/etc/mysql/conf.d 目录

cd /etc/mysql/conf.d

4.我们需要进入容器当中进行修改容器里面的配置文件,可能有的服务器是没有安装vim的,所以我们没有的需要安装的

apt-get update

apt-get install vim

5.docker进入mysql容器内,进入/etc/mysql/conf.d 目录执行 vim docker.cnf

vim docker.cnf

6.在对应文件后面添加下面的参数

performance_schema_max_table_instances=400



table_definition_cache=400



performance_schema=off



table_open_cache=64



innodb_buffer_pool_chunk_size=64M



innodb_buffer_pool_size=64M

各参数对应的意义为

[mysqld]



performance_schema_max_table_instances=400



table_definition_cache=400 #缓存



performance_schema=off #用于监控MySQL server在一个较低级别的运行过程中的资源消耗、资源东西



table_open_cache=64 #打开表的缓存



innodb_buffer_pool_chunk_size=64M #InnoDB缓冲池大小调整操作的块大小



innodb_buffer_pool_size=64M #InnoDB 存储引擎的表数据和索引数据的最大内存缓冲区大小

7.退出

exit

8.重启mysql容器

docker stop mysql

docker start mysql

9.观察修改后的内存情况

docker stats









Docker部署Nginx


1 创建挂载目录

mkdir nginx
mkdir nginx/nginx.conf
mkdir nginx/html



2 拉取镜像

docker pull nginx


3 启动容器

坑:

对于nginx的nginx.conf 文件夹是没办法跟它挂载的,因为它是一个文件,最好是先启动一个容器,把里面的nginx.conf拷贝到外面先





然后目录得是这样的:





docker run --restart=always --name nginx -p 80:80 -p 443:443 -v /mydata/nginx/conf/nginx.conf/nginx.conf:/etc/nginx/nginx.conf -v /mydata/nginx/html:/usr/share/nginx/html -v /mydata/nginx/logs:/var/log/nginx -v /mydata/nginx/conf/my.conf:/etc/nginx/conf.d -d nginx




挂载分析
-v /mydata/nginx/conf/nginx.conf/nginx.conf:/etc/nginx/nginx.conf 是挂载nginx的默认配置
-v /mydata/nginx/html:/usr/share/nginx/html 挂载它的前端静态目录
-v /mydata/nginx/logs:/var/log/nginx 挂载它的日志
-v /mydata/nginx/conf/my.conf:/etc/nginx/conf.d 挂载它的自定义配置




红色部分说明nginx.conf是包含在conf.d文件夹下的*.conf的配置




小demo:





在my.conf下写自己的配置


server {
listen 80;
server_name localhost;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}




然后写一个测试index.html放在html中


<!DOCTYPE html>
<html>
<head>
<title>My Web Page</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<h1>Welcome to my web page!</h1>
<p>This is a paragraph of text.</p>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
<img src="image.jpg" alt="An image">
</body>
</html>


0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
影子
作者分享
终于拿到鱼厂周边啦! 记录一下😃
18
面试题 | 02 | 非面经,纯分享,辩证看待答案。 #面试题# 压力山大的问题: 可以讲下API签名认证的流程吗? (感觉这种流程题,如果是线下面试,是不是拿出纸,画出流程图给面试官看更好些) 找工作的我: 好的,那其实签名认证的话,它主要是为了保证接口的安全性,防止一些需要成本的,例如使用到AI的API的这种的,万一被攻击,会导致资源被大量消耗。 那API签名认证的话,它涉及到五个参数,首先两个是accessKey和secretKey,它们类似于公钥和密钥,那这个的信息的话,只能让对应的用户看到。 第三个参数的话是sign,标签,我在项目中是采用实现一个工具类去制作的,是用的secretKey 、请求参数和签名算法(MD5)然后生成一个sign1,然后客户端会把这个accessKey 和请求参数一起发送到服务端,那服务端会根据accessKey去数据库查询这个secretKey,接着还是利用刚才提到的工具类去生成sign2,最后比较sign1和sign2是否相同,相同,则说明请求参数没有被篡改。 那其实一般到这里就算基本的流程了,但是为了防止被攻击重放,还需要第四个参数,nonce,我们会在每次请求中生成一个随机的nonce,将这个nonce存入redis中,并设置好TTL,那么往后的请求过来的时候,跟redis中的nonce进行比较,如果一样的话则拒绝请求,如果不存在,才放行请求,那这样的话就可以解决重放的问题。 但是如果说这个攻击者它等到redis中的nonce过期后再进行重放,那它又可以请求成功。对于这种情况,就得使用到第五个参数,timestamp时间戳,假设我们定义的时间戳是一分钟,那服务器只能接收一分钟内的时差请求,那我们在redis设置的nonce的TTL略大于一分钟即可。这样请求重放过来,如果在一分钟内的,因为nonce存在,无法放行。如果请求大于一分钟的,因为超过了一分钟时差的规定,也无法放行。至此,API签名认证所有流程就算完毕了。
13
面试题打卡 | 01 #面试题# 分享 大家好,我是影子。 最近在准备面试题的东西,之前也不断的了解过八股的记忆方式。 个人感觉比较好的方法如下: 1. 通过先了解原理或者答案,同时实践一遍,正所谓好记性不如烂笔头,实践一遍的时候,对于很多细节也能把控住。 2. 对于一个问题,不要仅限于表面,当问题问到A的时候,试想自己是面试官的话,接下来会怎么问这个问题相关的,而不是,对于一个问题,背完就结束,那么稍微问深一点九接不住了。 3. 也是我个人比较喜欢的。 对于多个相关的问题,学习后,整理为一整篇答案,因为很多问题,其实还是可以联系起来的,后面就是通过上下联系的方式,将全部梳理出来,类似于跟别人讲解,当自己能讲出来的时候,这个题,百分之80已经掌握了,剩下的就是偶尔多看看,加深记忆。 本次,以Redis的问题作为分享,因为基本都是自己的口语化方式,模拟跟面试官的对话,当然,如果是大厂的深度拷问,肯定不够用,纯属打卡分享,哪里有误还望大家指出。 压力山大的问题: redisson实现的分布式锁能解决主从一致性的问题吗? 如果业务非要保证数据的强一致性,这个该怎么解决呢? 能介绍一下redis的分布式锁的相关知识吗? .....| 自行补充 找工作的我: 好的,因为在分布式的场景下,一个服务被部署到多个服务器上,那么在并发的情况下,可能导致一个任务被多次执行。那像我们在单机使用的锁,例如syscornized lock锁,就没法解决这个问题。那么,就需要使用到分布式锁。 分布式锁的实现有很多方式,例如redis的setnx命令,这个命令是存入一个key value,如果存入成功,则返回一个1。如果已经有这个key了,那么返回0,存入失败,并且结合lua脚本去实现。但是通过这个方式实现会有很多问题。第一个是流程会比较复杂,成本高。第二个是它的不可重入问题,第三个是它的不可重试问题,第四个是它的超时无法自动续期问题,第五个是主从一致问题。 那基于这些问题,我在项目中采用的是redisson。redisson很好的基于redis去解决了很多分布式的问题,例如分布式限流 分布式锁等等。 首先是不可重入的问题,因为它的底层是一个可重入锁,底层的流程是如果有请求过来,先判断是否已经存入线程号,如果没有,则直接获取锁,如果有,那么判断是否是同一个线程号,如果不是,则直接拒绝。如果是,则给redis中的value值加一,然后重置TTL。那么释放锁的话同样的,给value值减一,直到value为0释放锁,让其他的线程去获取锁。 那第二个的话是不可重试问题,我们使用Redisson的时候,可以定义一个时间,当一个线程获取不到锁的时候,让它不断的自旋进行尝试,直到时间到了,才停止尝试获取。 那第三个的话是不可自动续期问题,redisson中有一个看门狗机制,我们可以在代码中将trylock这个方法中将参数设置为-1,则算开启了这个看门狗机制,那这个机制的话,可以保证我们的业务完整执行,不会说因为当TTL结束后,锁就自动释放了,那具体的话我在实践中看到的是,给的时间是默认30秒,当到达三分之二的时间的时候,就会自动续期。直到我们的业务完整的执行完再释放锁。 那最后的话是主从一致的问题。因为我们底层使用的setnx的命令,那当我们获取到锁的时候,它是写入主节点的,但是因为主节点是异步复制到从节点,那如果说此时主节点宕机了,而线程一获取到锁后又没有释放锁,从节点也没有同步信息。 同时,从节点中会选举一个作为主节点。此时线程二来获取锁,则会获取成功,最终导致出现了一把锁两个线程获取,这是不合理的。 那解决的方式的话,我们可以使用mulitlock这个多重锁,使用这个锁的话,必须保证所有节点都成功的写入获取锁的线程信息后,才算获取成功,那这样就避免了因为redis多节点信息不一致导致的多个线程获取同一把锁的情况。
14
手写 RPC 框架 笔记
11
手写 RPC 框架 笔记
18
下载 APP