当前位置: 首页 > article >正文

【Ubuntu24.04】服务部署(Docker)

目录

  • 0 背景
  • 1 安装和配置Docker
  • 2 配置服务环境
    • 2.1 安装MySQL
    • 2.2 安装Redis
  • 3 部署服务
  • 4 总结

0 背景

    你的多个服务都部署在了虚拟电脑上,并且它们运行得好好的,没有任何问题。现在你的计算机的状态是:一个Windows操作系统,Windows操作系统上安装了VirtualBox或者VMware之类的虚拟机软件,在虚拟机软件的帮助下,你安装了多台虚拟电脑,有些虚拟电脑上你只安装了数据库等组件,有些虚拟电脑上部署了你的微服务,这些虚拟电脑组合在一起形成了你的整个服务。
    当你的服务运行了一段时间之后,你发现好像哪里不对劲。有的虚拟电脑上的服务或组件被频繁地使用,不过也不是什么坏事,这正是你需要的。但是有的虚拟电脑上的服务却被访问得很少,甚至几乎没被访问过。
    这时你又开始思考,似乎用一个虚拟机给那些不被经常访问的服务来用有点浪费资源了,有没有更经济一点的方法呢?不对,被不被经常访问好像并不是你看不惯的原因,你看不惯的应该是这些虚拟机占用你的资源而没有被充分利用
    你终于明白了是什么地方不对劲了:这一个虚拟机上只部署一个服务太浪费资源了,一个虚拟电脑在安装时需要让你指定资源(内存,CPU,磁盘等),你最少得指定操作系统占用的空间,而一个操作系统要占几个G的磁盘,你的服务只是一个简单的服务,运行时峰值也就几百兆,而你需要使用到的操作系统的功能也不多,你就会想,怎么才能将这些用不到的功能去掉啊?
    另外,纵观整个服务,它们都运行在Linux系统上,尽管这些Linux系统发行版不同,但是它们的内核是一样的。如果有一种“提取公因式”的技术,它能让所有这些虚拟机内核都集中在一起,然后将提取了“公因式”后的服务或组件成为一种“插件”,当把“插件”插入有内核的系统上,它就可以工作,那就好了。
    还真有,于是你开始做接下来的事。

1 安装和配置Docker

    同样,一个脚本搞定

#!/bin/bash
sudo apt update
sudo apt upgrade -y
# 安装必要工具
sudo apt install apt-transport-https
# 配置apt下载源
# 使用阿里源
aliyun_src="https://mirrors.aliyun.com/docker-ce/linux/ubuntu/"
# curl是自带的,没必要安装
curl -fsSL "${aliyun_src}gpg" | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] ${aliyun_src} $(. /etc/os-release && echo "${VERSION_CODENAME}") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 刷新源,这一步很重要
sudo apt update
# 通过apt安装docker
sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# 添加镜像源
# 创建目录
sudo mkdir -p /etc/docker

# 写入配置文件
sudo tee /etc/docker/daemon.json <<-'EOF'
{
    "registry-mirrors": [
    	"https://hub.crdz.gq",
        "https://hub.littlediary.cn",
        "https://docker.1panel.live",
        "https://hub.xdark.top",
        "https://docker.m.daocloud.io",
        "https://docker.kejilion.pro",
        "https://registry.dockermirror.com",
        "https://docker.unsee.tech"
    ]
}
EOF

# 配置不加sudo使用docker
sudo usermod -aG docker "${USER}"
# 重启docker服务
sudo systemctl daemon-reload && sudo systemctl restart docker

2 配置服务环境

    使用Docker安装组件,就比在操作系统上直接安装要方便多了,而且又便于管理。下面仍然是以JDKMySQLRedis举例,实际上在Docker中,无论你想安装什么都是一样的命令,只需要给个组件名和版本号即可(当然还得有真实存在的镜像才行),非常方便,不过瓶颈往往在于镜像源。
    在上面的脚本中,笔者给出了写文章时还存活的镜像地址。不保证一直可用,失效的时候再去网上找找看,修改配置文件即可。

2.1 安装MySQL

    直接run即可,注意备份实例中的数据和配置,备份数据所在的文件夹需要保证存在

# 建立数据和备份文件所在的目录
sudo mkdir -p /data/mysql/data
sudo mkdir -p /data/mysql/conf
# 指定mysql实例运行的名字,端口号映射等
docker run --name mysql-8.4 \
-e MYSQL_ROOT_PASSWORD=your_own_password \
-v /data/mysql/data:/var/lib/mysql \
-v /data/mysql/conf:/etc/mysql/conf.d \
-d -p 3306:3306 mysql:8.4
# 需要进入

    MySQL8.4似乎不需要写任何配置文件就可正常使用。

2.2 安装Redis

    直接run即可

sudo mkdir -p /data/redis/data
sudo mkdir -p /data/redis/conf

docker run --name redis-7.0.15 \
-v /data/redis/data:/data \
-v /data/redis/conf/redis.conf:/usr/local/etc/redis/redis.conf \
-d -p 6379:6379 redis:7.0.15

    其中,redis.conf的内容就是之前在操作系统上直接安装Redis时的配置文件,去掉注释后如下:

# bind 127.0.0.1 -::1
protected-mode no
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
pidfile /run/redis/redis-server.pid
loglevel notice
logfile /var/log/redis/redis-server.log
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 /var/lib/redis
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

# 注意这里换成你自己的密码
requirepass {your_own_password}

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

    在运行实例之前需要在/data/redis/conf/中创建这个文件,并取名为redis.conf

3 部署服务

    在将你的服务打成jar包之前,你应该在配置文件中将MySQLRedis的配置项写成环境变量的形式,这既保证信息不泄露,又方便配置管理

# 其它配置省略
spring:
  datasource:
    url: jdbc:mysql://${MYSQL_HOST}:3306/cl_db?useSSL=false&serverTimezone=UTC
    username: ${MYSQL_USER}
    password: ${MYSQL_PASSWORD}
  data:
    redis:
      host: ${REDIS_HOST}
      port: 6379
      password: ${REDIS_PASSWORD}

    使用Docker的时候,部署服务往往使用Dockerfile,而Dockerfile往往是以某个JDK为基础镜像的,你可以想象成JDK和服务是绑定在一起的,一个服务对应一个JDK,下面给出一个Dockerfile示例:

# 从openjdk17开始构建
FROM openjdk:17
# 镜像信息
# LABEL author="XXX"
# LABEL date=""
# LABEL maintainer=""
# LABEL version="1.0.0-SNAPSHOT"
# LABEL description=""
# 跑一些命令
RUN mkdir -p /app
# 设置环境变量,这里也可以设置服务中具体会使用到的环境变量
ENV PATH="/app:${PATH}"
ENV MYSQL_HOST=mysql-8.4
ENV MYSQL_USER=root
ENV MYSQL_PASSWORD=your_password
ENV REDIS_HOST=redis-7.0.15
ENV REDIS_PASSWORD=your_password
# 指定工作目录
WORKDIR /app
# 将jar包复制进来(<src>相对于Dockerfile所在目录,<dest>相对于工作目录)
COPY your_service.jar .
# 暴露端口,记得加上你的服务的端口
EXPOSE 80 22 443 8080
# 入口
ENTRYPOINT ["java", "-jar", "/app/your_service.jar"]

    将jar包和Dockerfile放到同一个目录下,然后在这个目录下执行下面的命令将jar包打成镜像

docker build -t your_images_name:tag .

    新建Docker网络,将服务要使用到的组件连接到这个网络

docker network create your_network
docker network connect your_network mysql-8.4
docker network connect your_network redis-7.0.15

    然后将实例运行在这个网络上,这一步可以配置在配置文件中需要用到的环境变量,注意修改成自己的,而且不要忘了端口号,不然外部访问不了。这里指定的环境变量可以将Dockerfile中的环境变量覆盖掉。

docker run -p 65535:65535 \
--name your_service_name \
--network your_network \
-e MYSQL_HOST=mysql-8.4 \
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=your_password \
-e REDIS_HOST=redis-7.0.15 \
-e REDIS_PASSWORD=your_password \
-d your_images_name:tag

    至此,服务部署成功。

4 总结

    本文介绍了Docker的安装以及使用Docker来部署服务。如果有多个服务,只需要先将jar包打成镜像,然后根据镜像创建实例即可。不过,美中不足的一点是JDK17镜像有点大,有471MB,有兴趣的可以自己尝试优化。(笔者拉了一个78MBubuntu:24.04的镜像,然后下载jdk17的安装包传到实例里面安装,最后将这个实例打成镜像,有580MB。。。)
    部署服务到这里就结束了,可以看到比起最初的手动安装,Docker简化了很多操作,并且使服务和环境方便维护了,当然还有很多很强大的部署和管理服务的工具,比如docker-composek8s等,但笔者认为作为一个开发者无需去走一遍这些服务部署的实操,只需要在开发中会使用命令即可(当然还得看具体的开发有没有用到这些工具)。
    这样,就可以只使用一个虚拟电脑,然后在上面安装Docker来部署和管理你的服务了。当然关于Docker还有很多细节这篇文章没有提到,不过部署服务的模式和基本操作差不多就这样。


http://www.kler.cn/a/413737.html

相关文章:

  • Linux应用开发————进程
  • springboot336社区物资交易互助平台pf(论文+源码)_kaic
  • Neo4j图形数据库-Cypher中常用指令
  • 矩阵重构——sortrows函数
  • spark 写入mysql 中文数据 显示?? 或者 乱码
  • Spring-Mybatis测试
  • 实验二 系统响应及系统稳定性
  • 【11-20期】Java面试进阶:深入解析核心问题与实战案例
  • Linux基础学习--vi与vim
  • 读《Effective Java》笔记 - 条目10
  • 化工行业 FMEA 与安全生产的关系
  • Java使用反射记录操作日志
  • 23省赛区块链应用与维护(房屋租凭【下】)
  • json object转x-www-form-urlencoded
  • ShuffleNet V2:高效卷积神经网络架构设计的实用指南
  • 计算机视觉中的距离变换:经典案例与Python代码解析
  • 无人机产业发展如何?如何进行产业分析?
  • 视觉感知与处理:解密计算机视觉的未来
  • MySQL子查询介绍和where后的标量子查询
  • yarn 任务 beyond the ‘PHYSICAL‘ memory limit 报错处理
  • 半导体、晶体管、集成电路、芯片、CPU、单片机、单片机最小系统、单片机开发板-概念串联辨析
  • 【网络安全设备系列】12、态势感知
  • Z2400023基于Java+Servlet+jsp+mysql的酒店管理系统的设计与实现 源码 调试 文档
  • 在Manjaro Gnome桌面的基础上安装Budgie桌面环境
  • 【入门篇】小游戏——多语言求解版
  • 希尔排序:一个“跳房子游戏”