中间件服务部署-Docker版

目录

0、注意事项

1、权限回收(rabbitmq建议使用命令方式创建用户等信息)

2、严禁使用localhost

3、生产环境常见问题:没有网络、没有yum命令等

1、MySQL

docker pull mysql:5.7
docker pull redis:7.0.0
docker pull rabbitmq:management
docker pull elasticsearch:7.2.0
docker pull nginx:1.19.10-alpine
# 创建目录
mkdir /docker/mysql/{etc,data,logs} -p 
# 如果已经存在,清空
rm -rf /docker/mysql/{etc,data,logs}/*

# 创建配置文件
vim /docker/mysql/etc/mysqld.cnf
[mysqld]
pid-file	= /var/run/mysqld/mysqld.pid
socket		= /var/run/mysqld/mysqld.sock
datadir		= /var/lib/mysql
#log-error	= /var/log/mysql/error.log
# By default we only accept connections from localhost
#bind-address	= 127.0.0.1
# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# mysql日志时间跟随系统时间
log_timestamps=system
character-set-server=utf8

vim /docker/mysql/etc/mysql.cnf
[mysql]
default-character-set=utf8

# 启动日志
docker run -d -p 3306:3306 --name=mysql -v "/docker/mysql/etc/mysqld.cnf":"/etc/mysql/mysql.conf.d/mysqld.cnf" --mount type=bind,src=/docker/mysql/data,dst=/var/lib/mysql \
	-v mysql-logs:/var/log/mysql/ \
    -e TZ=Asia/Shanghai \
    -e MYSQL_ROOT_PASSWORD=Geray@2022 \
    --restart always  mysql:5.7

-v:挂载配置文件到容器中

–mount:将数据文件从容器中映射到本地

-e TZ=Asia/Shanghai:设置容器中的系统时区

-e MYSQL_ROOT_PASSWORD=Geray@2022:设置mysql密码

–restart always :设置容器的重启策略

修改mysql数据库编码:

# 查看编码
docker exec -it mysql mysql -uroot -p 
mysql> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | latin1                     |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

mysql> 

# 修改编码:(修改配置文件mysqld : character-set-server=utf8)
# 添加mysql的[mysql]组文件挂载并重新配置容器启动查看
[mysql]
default-character-set=utf8

# 启动日志
docker run -d -p 3306:3306 --name=mysql -v "/docker/mysql/etc/mysqld.cnf":"/etc/mysql/mysql.conf.d/mysqld.cnf" -v "/docker/mysql/etc/mysql.cnf":"/etc/mysql/conf.d/mysql.cnf" --mount type=bind,src=/docker/mysql/data,dst=/var/lib/mysql \
    -e TZ=Asia/Shanghai \
    -e MYSQL_ROOT_PASSWORD=Geray@2022 \
    --restart always  mysql:5.7
    
mysql> show variables like '%char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | utf8                       |
| character_set_connection | utf8                       |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | utf8                       |
| character_set_server     | utf8                       |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)

创建用户并授权

CREATE USER 'username'@'host' IDENTIFIED BY 'password';

# 创建用户
CREATE USER 'ump'@'%' IDENTIFIED BY 'Gsww_2022';

FLUSH PRIVILEGES;
  • username:你将创建的用户名
  • host:指定该用户在哪个主机上可以登陆,如果是本地用户可用localhost,如果想让该用户可以从任意远程主机登陆,可以使用通配符%
  • password:该用户的登陆密码,密码可以为空,如果为空则该用户可以不需要密码登陆服务器
GRANT privileges ON databasename.tablename TO 'username'@'host'

# 授权
GRANT ALL ON *.* TO 'ump'@'%';

FLUSH PRIVILEGES;
  • privileges:用户的操作权限,如SELECTINSERTUPDATE等,如果要授予所的权限则使用ALL
  • databasename:数据库名
  • tablename:表名,如果要授予该用户对所有数据库和表的相应操作权限则可用*表示,如*.*

更简单的Podman

podman run --name mysql-server -t \
      -e MYSQL_DATABASE="zabbix" \
      -e MYSQL_USER="aa" \
      -e MYSQL_PASSWORD="cc" \
      -e MYSQL_ROOT_PASSWORD="cc" \
      -v /data/zabbix/:/var/lib/mysql/:Z \
      --restart=always \
      --pod=zabbix \
      -d mysql:8.0 \
      --character-set-server=utf8 --collation-server=utf8_bin \
      --default-authentication-plugin=mysql_native_password

修改为Docker版本,以及优化

docker run -d -p 3306:3306 --name mysql-server \
	  -e MYSQL_ROOT_PASSWORD="root@123" \
      -e MYSQL_DATABASE="test" \
      -e MYSQL_USER="test" \
      -e MYSQL_PASSWORD="test@123" \
	  -e TZ=Asia/Shanghai \
      -v mysql8-data:/var/lib/mysql/:Z \
	  -v mysql8-logs:/var/log/mysql/ \
	  -v mysql8-conf:/etc/mysql/conf.d/ \
      --restart=always \
      mysql:8.0 \
      --character-set-server=utf8 --collation-server=utf8_bin \
      --default-authentication-plugin=mysql_native_password

修改配置文件,使日志时间跟随系统 建议直接挂载修改后的日志文件

2、Redis

redis.conf(7.0.0模板)

#删除注释行和空行
sed -i '/^#/d;/^$/d' redis.conf
cat > /docker/redis/conf/redis.conf << EOF
#bind 127.0.0.1 -::1 # 注释掉
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile ""
databases 16
always-show-logo no
set-proc-title yes
proc-title-template "{title} {listen-addr} {server-mode}"
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
rdb-del-sync-files no
dir ./
replica-serve-stale-data yes
replica-read-only yes
repl-diskless-sync yes
repl-diskless-sync-delay 5
repl-diskless-sync-max-replicas 0
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
lazyfree-lazy-user-flush no
oom-score-adj no
oom-score-adj-values 0 200 800
disable-thp yes
appendonly no
appendfilename "appendonly.aof"
appenddirname "appendonlydir"
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
aof-timestamp-enabled no
 
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-listpack-entries 512
hash-max-listpack-value 64
list-max-listpack-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-listpack-entries 128
zset-max-listpack-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
requirepass Gsww_2022
EOF
mkdir -p /docker/redis/{conf,data}

# 通过docker inspect redis命令查看镜像中的redis版本和使用的软件包来下载获取对应版本的配置文件

# 修改配置文件
requirepass Gsww_2022 		#密码
#bind 127.0.0.1    			#注释掉(或者修改为0.0.0.0)
protected-mode yes			#启用保护模式
# 添加域名解析
vim /etc/hosts
# GitHub Start
52.74.223.119 github.com
192.30.253.119 gist.github.com
54.169.195.247 api.github.com
185.199.111.153 assets-cdn.github.com
151.101.76.133 raw.githubusercontent.com
151.101.108.133 user-images.githubusercontent.com
151.101.76.133 gist.githubusercontent.com
151.101.76.133 cloud.githubusercontent.com
151.101.76.133 camo.githubusercontent.com
151.101.76.133 avatars0.githubusercontent.com
151.101.76.133 avatars1.githubusercontent.com
151.101.76.133 avatars2.githubusercontent.com
151.101.76.133 avatars3.githubusercontent.com
151.101.76.133 avatars4.githubusercontent.com
151.101.76.133 avatars5.githubusercontent.com
151.101.76.133 avatars6.githubusercontent.com
151.101.76.133 avatars7.githubusercontent.com
151.101.76.133 avatars8.githubusercontent.com
# GitHub End
docker run -d -v /docker/redis/conf/:/etc/redis/ -v /docker/redis/data:/data --privileged=true -p 6379:6379 --restart always -e TZ=Asia/Shanghai --name redis redis:7.0.0 redis-server /etc/redis/redis.conf --appendonly yes

包含您的文件/docker/redis/conf/的本地目录在哪里。redis.conf使用这种方法意味着您不需要为您的 redis 容器提供 Dockerfile。

映射目录应该是可写的,因为根据配置和操作模式,Redis 可能需要创建额外的配置文件或重写现有的配置文件。

# 测试
docker exec -it redis redis-cli

3、Rabbitmq

配置文件:

cat > /docker/rabbitmq/conf/rabbitmq-env.conf << EOF
RABBITMQ_NODENAME=rabbitmq001
#RABBITMQ_NODE_IP_ADDRESS=192.168.6.21
RABBITMQ_NODE_PORT=5672
#RABBITMQ_MNESIA_BASE=/opt/rabbitmq/data
#RABBITMQ_LOG_BASE=/var/log
EOF

cat > /docker/rabbitmq/conf/rabbitmq.config <<EOF
[
 {rabbit,
   [
     {tcp_listeners, [5672]},
     {dump_log_write_threshold, [1000]},
     {vm_memory_high_watermark, 0.5},
     {disk_free_limit, "200MB"},
     {hipe_compile,true}
   ]
  }
].
EOF
mkdir -p /docker/rabbitmq/{conf,data,logs}
rm -rf /docker/rabbitmq/{data,logs}/*

docker run -d --name rabbitmq -p 15672:15672 -p 5672:5672 -v /docker/rabbitmq/conf:/opt/rabbitmq/etc/rabbitmq -v /docker/rabbitmq/data:/var/lib/rabbitmq -e RABBITMQ_DEFAULT_USER=admin -e RABBITMQ_DEFAULT_PASS=Geray@2022 -v /etc/localtime:/etc/localtime:ro --restart always rabbitmq:management

docker exec -it rabbitmq bash

配置账号密码

# 创建账号和密码(用户存在可以跳过改步骤)
docker exec -it rabbitmq rabbitmqctl add_user admin Geray_2022

# 设置用户角色
docker exec -it rabbitmq rabbitmqctl set_user_tags admin administrator

# 设置用户权限
# 用户 user_admin 具有/vhost1 这个 virtual host 中所有资源的配置、写、读权限
# 格式:set_permissions [-p <vhostpath>] <user> <conf> <write> <read>
# 给/这个vhost设置了admin权限
docker exec -it rabbitmq rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*"

# 更改密码
docker exec -it rabbitmq rabbitmqctl change_password admin Gsww_2022

# 当前用户和角色
docker exec -it rabbitmq rabbitmqctl list_users

追加启动策略

# 查看容器启动时间
docker inspect  -f "" rabbitmq

# 重启次数
docker inspect  -f "" rabbitmq

# 重启策略
docker inspect rabbitmq | grep -i -A 3 restartPolicy

# 重新设置容器的重启策略
docker container update --restart=always rabbitmq

4、ES

1. 优化系统:

# 设置虚拟内存大小,Elasticsearch使用了 NioFs(非阻塞文件系统)和 MMapFs(内存映射文件系统)。
# 配置最大映射数量,以便有足够的虚拟内存可用于mmapped文件
echo "vm.max_map_count=262144" >> /etc/sysctl.conf
# 禁止内存与硬盘交换
echo "vm.swappiness=1" >> /etc/sysctl.conf
# 是配置生效
sysctl -p

es至少需要的内存权限为:262144,默认用户的内存权限为:65530

修改该配置是为了防止es在启动时出现下面的错误

max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

创建es账号

es不能使用root账号启动

useradd es
passwd es

2. 启动

docker pull elasticsearch:7.2.0

#启动镜像
docker run -d --name es \
    -v es-conf:/usr/share/elasticsearch/config/ \
    -v es-data:/usr/share/elasticsearch/data/ \
    -v es-log:/usr/share/elasticsearch/logs/ \
    -v es-plugins:/usr/share/elasticsearch/plugins/ \
    -v /etc/localtime:/etc/localtime:ro \
    -e ES_JAVA_OPTS="-Xms512m -Xmx512m" \
    -e "discovery.type=single-node" \
    -e TZ=Asia/Shanghai \
    -p 9200:9200 -p 9300:9300 \
    --restart=always \
    elasticsearch:7.2.0

ES_JAVA_OPTS设置了ES的启动内存,自己按需修改 discovery.type=single-node表示该es为单节点,不加这个的话,你的es健康状态会显示为黄色

3. 修改配置文件

# 添加配置文件
cat > /var/lib/docker/volumes/es-conf/_data/elasticsearch.yml << EOF
# 集群名
cluster.name: docker-cluster-es
# 节点名
node.name: node
# 监听ip
network.host: 0.0.0.0
# 开启x-pack插件,用于添加账号密码
xpack.security.enabled: true
EOF

修改JVM内存参数(本地环境资源有限)

生产环境建议配置物理内存的50%,但不要超过32G

sed -i "s/Xms1g/Xms512m/g" /var/lib/docker/volumes/es-conf/_data/jvm.options

sed -i "s/Xmx1g/Xmx512m/g" /var/lib/docker/volumes/es-conf/_data/jvm.options

4. 重启容器

docker restart es

5. 设置密码

# 交互式配置密码
docker exec -it es elasticsearch-setup-passwords interactive

根据提示,先输入y,然后输入密码,这里会要求输入多次,主要是需要给好几个系统添加密码,用户默认elastic(Gsww_2022)

测试访问:http://192.168.6.22:9200

5、Nginx

docker pull nginx:1.19.10-alpine

docker run -d --name nginx \
	-p 80:80 \
	-v nginx-conf:/etc/nginx/ \
	-v nginx-data:/usr/share/nginx/  \
	-e TZ=Asia/Shanghai \
	--restart=always \
	nginx:1.19.10-alpine

6、Dockerfile

1. jdk

FROM alpine:latest

#MAINTAINER "Geray <1690014753@qq.com>"

# 打标签
LABEL version="1.0" \
    description="alpine:latest" \
    maintainer="geray<1690014753@qq.com>"
    
# 配置apk包加速镜像为阿里
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories

RUN apk update \
    # && apk add s6 \
    # && apk add nghttp2-dev \
    && apk add ca-certificates \
    && apk add wget \
    # && apk add curl \
    # && apk add tcpdump \
    # && apk add bash-completion \
    # && apk add iputils \
    # && apk add iproute2 \
    && apk add libc6-compat \
    && apk add -U tzdata \
    && rm -rf /var/cache/apk/* \
    
    # 设置操作系统时区
	&& rm -rf /etc/localtime \
 	&& ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
 	
# 设置时区变量
ENV TIME_ZONE Asia/Shanghai

# 设置 语言支持
ENV LANG=zh_CN.UTF-8

# 配置 应用工作目录
WORKDIR /data/

VOLUME /data/

COPY jdk1.8.0_281/ /data/

# 设置jdk环境变量
ENV JAVA_VERSION=1.8.0_281 \
	JAVA_HOME=/data/jdk1.8.0_281 \
	JRE_HOME=$JAVA_HOME/jre \
	CLASSPATH=.:${JAVA_HOME}/jre/lib/rt.jar:${JAVA_HOME}/lib/dt.jar:${JAVA_HOME}/lib/tools.jar \
	PATH=$PATH:${JAVA_HOME}/bin

# 配置 对外端口
#EXPOSE 11000

# 设置启动时预期的命令参数, 可以被 docker run 的参数覆盖掉.
#CMD ["bash", "sleep 20m"]

zip glibc 是GNU发布的libc库,即c运行库。. glibc 是linux系统中最底层的api,几乎其它任何运行库都会依赖于 glibc, 在制作docker alpine镜像可以需要用到他.(docker官方推荐java是基于glibc库,而alpine默认只提供mini libc,故需要安装glibc库)

下载glibc安装包glibc-2.29-r0.apkglibc-bin-2.29-r0.apkglibc-i18n-2.29-r0.apk到文件夹下,下载地址:

https://github.com/sgerrand/alpine-pkg-glibc/releases

构建:

docker build -t jdk:1.8-alpine .
名称 说明 实例
s6 s6是一个unix服务管理器(更像runit和supervisord)。
虽然Docker容器应该有一个明确的焦点,但通常情况下,您需要在容器中运行多个进程。
consur就是一个很好的例子;您需要consur代理来加入consur集群和主服务.
如Nginx或js节点. 日志管理也是可能需要运行另一个进程的一个关键考虑因素。
iputils iputils软件包是Linux环境下一些实用的网络工具的集合  
iproute2 iproute2是linux下管理控制TCP/IP网络和流量控制的新一代工具包,旨在替代老派的工具链net-tools,即大家比较熟悉的ifconfig,arp,route,netstat等命令。  
libc6-compat 这个包提供了一个轻量级的glibc兼容层。对于简单的应用程序,这可能就足够了。  
ca-certificates 我们在构建 docker 镜像时一般使用的是 alpine linux 系统,默认是不带 ca-certificates 根证书的,导致无法识别外部 https 携带的数字证书。  

附件:镜像加速

cat > /etc/docker/daemon.json  << EOF
{
  "registry-mirrors": [
    "https://hub-mirror.c.163.com",
    "https://mirror.baidubce.com",
    "https://docker.mirrors.ustc.edu.cn",
    "https://3fc19s4g.mirror.aliyuncs.com"
  ]
}
EOF