轻量化的业务部署 -- Docker指北

222100209李炎东 2024-06-03 00:54:34
这个作业属于哪个课程2302软件工程社区
这个作业要求在哪里软件工程实践总结&个人技术博客
这个作业的目标个人技术总结
其他参考文献《构建之法》

目录

目录

  • 目录
  • 技术概述
  • 技术详述
  • Docker的基本构成
  • Docker安装
  • Docker命令
  • 帮助命令
  • 镜像命令
  • 容器命令
  • Docker镜像
  • 镜像是什么
  • Docker镜像加载原理
  • 分层理解
  • commit镜像
  • 容器数据卷
  • 什么是容器数据卷
  • 使用数据卷
  • 具名挂载/匿名挂载
  • Dockerfile
  • DockerFile介绍
  • DockerFile构建过程
  • DockerFile指令
  • 一个Dockerfile样例
  • docker compose
  • 安装docker compose
  • docker-compose.yml文件样例
  • 如何使用
  • 问题和解决过程
  • 网络通信问题
  • 总结
  • 参考文献/博客

技术概述

​ Docker是一种容器化技术,用于打包、部署和运行应用程序。同时也是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。它在需要快速部署、跨平台运行和隔离环境的情况下使用。学习Docker可提高开发效率和部署一致性。难点包括镜像构建、容器网络配置和资源管理。

img

技术详述

Docker的基本构成

img

镜像(image):

​ docker镜像好比一个模板,开源通过这个模板来创建容器服务,tomcat镜像 ===> run ===> tomcat01容器(提供服务器),通过这个镜像开源创建多个容器

容器(container):

​ Docker利用容器技术,独立运行一个或一个组应用,通过镜像来创建。

​ 启动,停止,删除,基本命令

​ 目前就可以把这个容器理解为一个建议的linux系统

仓库(repository):

​ 仓库就是存放镜像的地方

​ 仓库分为公有仓库和私有仓库

​ Docker Hub是国外的,需要配置镜像加速

Docker安装

环境准备

1、需要一点linux基础

2、CentOs 7

3、使用SSH工具连接远程服务器

环境查看

使用uname -r命令,查看系统内核版本,系统内核版本在3.10以上就可以使用Docker了

正式安装Docker

  1. 卸载老版本Docker

    yum remove docker docker-common container-selinux docker-selinux docker-engine
    
  2. 更新yum

    yum update
    
  3. 安装 yum-utils,它提供了 yum-config-manager,可用来管理yum源

     yum install -y yum-utils
    
  4. 添加yum源

    yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
  5. 更新索引

    yum makecache fast
    
  6. 安装docker

    1. 获取rpm

      wget https://download.docker.com/linux/centos/7/x86_64/edge/Packages/containerd.io-1.2.6-3.3.el7.x86_64.rpm
      
    2. 安装

      yum -y install containerd.io-1.2.6-3.3.el7.x86_64.rpm
      
    3. yum install -y docker-ce
      
  7. 启动docker

    systemctl start docker
    
  8. 测试是否成功

    docker --version
    

感受Docker

​ 如果你之前没有用过docker,你可以使用docker run hello-world命令,快速拉取并运行一个官方提供的hello-world镜像体验一下,或许你能初步感受到docker的便捷。

img

Docker命令

img

帮助命令

$ docker version         # 显示docker版本信息
$ docker info             # 显示docker的系统信息(包括镜像和容器信息)
$ docker 命令 --help    # 万能命令 (基本docker中的什么命令,在后面加上--help都能够查看更加详细的参数和说明,最常用的命令)

帮助文档:Docker run reference | Docker Documentation

镜像命令

docker的基础是一个类似于一个操作系统的镜像。我们可以通过docker镜像命令对镜像进行一些操作。以下操作的结果就不做详细说明了,只简单列出命令和他的作用。

$ docker images  # 查看所有本地主机上的镜像
$ docker search mysql    # 搜索镜像 (默认从dockerhub官方镜像仓库中搜索)
$ docker pull mysql        # 拉取镜像 (默认从dockerhub官方镜像仓库中拉取)
$ docker rmi -f 容器id [容器id 容器id 容器id .....]        #删除指定镜像
$ docker rmi -f $(docker images -aq)                     #删除所有镜像

容器命令

tips:有了镜像才可以创建容器

接下来我们下载一个centos来测试学习

docker pull centos

新建容器并启动

docker run [可选参数] image

# 参数说明
--name="Name"        # 容器名字
-d                    # 以后台方式运行
-it                    # 使用交互方式运行(可进入容器查看)
-p                    # 指定容器端口 -p 8080:8080
    -p ip:主机端口:容器端口
    -p 主机端口:容器端口    # 常用!
    -p 容器端口
    容器端口
-P                    # 随机指定端口

# 测试    启动并进入容器
[root@Lear /]# docker run -it centos /bin/bash
[root@73efe585932d /]# ls        # 查看容器内的centos,很多版本,内部命令不完善
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

# 从容器中退回主机
[root@73efe585932d /]# exit
exit

其他容器命令

$ docker ps     // 列出所有容器
    -a        # 列出当前正在运行的容器+历史运行过的容器
    -n=?    # 显示最近创建的容器(显示个数)
    -q        # 只显示容器id
    
$ exit            # 停止容器并退出
ctrl + P + Q    # 退出但容器不停止运行

$ docker rm 容器id                   # 删除指定容器
$ docker rm -f $(docker ps -aq)    # 删除所有容器
$ docker ps -a -q|xargs docker rm    # 删除所有的容器

$ docker start 容器id        # 启动容器
$ docker restart 容器id        # 重启容器
$ docker stop 容器id        # 停止当前正在运行的容器
$ docker kill 容器id        # 强制停止当前容器

$ docker logs -f -t --tail 显示行数 容器id # 查看日志

$ docker top 容器id     # 查看容器进程信息

$ docker inspect 容器id         # 查看镜像元数据

# 进入正在运行的容器 (/bin/bash不行就改为sh)
$ docker exec -it 容器id /bin/bash        # 进入容器后开启一个新的终端
$ docker attach 容器id /bin/bash            # 进入正在执行的命令行

$ docker cp 容器id:容器内路径 目的主机路径        # 从容器拷贝文件

Docker镜像

镜像是什么

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量、配置文件。

所有的应用直接打包为镜像,即可直接跑起来

如何获取镜像:

  • 远程仓库拉取
  • 加载已有文件
  • 自己制作DockerFile

Docker镜像加载原理

UnionFS(联合文件系统)

联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来只能看到一个文件系统。联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。

image-20220723172606514

镜像加载原理

Docker的镜像实际由一层一层的文件系统组成:

bootfs(boot file system)主要包含bootloader和kernel。bootloader主要是引导加载kernel,完成后整个内核就都在内存中了。此时内存的使用权已由bootfs转交给内核,系统卸载bootfs。可以被不同的Linux发行版公用。
rootfs(root file system),包含典型Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件。rootfs就是各种不同操作系统发行版(Ubuntu,Centos等)。因为底层直接用Host的kernel,rootfs只包含最基本的命令,工具和程序就可以了。

分层理解

所有的Docker镜像都起始于一个基础镜像层,当进行修改或增加新的内容时,就会在当前镜像层之上,创建新的容器层。
容器在启动时会在镜像最外层上建立一层可读写的容器层(R/W),而镜像层是只读的(R/O)。

img

img

img

commit镜像

docker commit     # 提交容器为一个新的副本
# 和git类似
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]

可以将自己diy的容器打包为一个镜像

容器数据卷

什么是容器数据卷

如果数据都在容器中,删除容器 -> 数据丢失

所以我们有时需要将容器内的数据同步到宿主机上。

容器数据卷:即一种容器间数据共享技术

简单来说,就是将容器内的目录挂载在宿主机上

也就是容器的持久化和同步操作,容器间也可以数据共享

img

使用数据卷

直接使用命令挂载 -v

docker run -it -v 主机目录:容器内目录

# 测试
docker run -it -v /home/ceshi:/home centos /bin/bash
# 查看是否挂载成功
docker inspect 容器id

具名挂载/匿名挂载

# 匿名挂载
-v 容器内路径
docker run -d -P --name nginx01 -v /etc/nginx nginx

# 查看所有的 volume 情况
docker volume ls

# 具名挂载
docker run -d -P --name nginx02 -v juming-nginx:/etc/nginx nginx

所有的docker容器内的卷,在没有指定目录的情况下都是在/var/lib/docker/volumes/xxxx/_data

通过具名挂载可以方便的找到一个卷,大多数使用具名挂载

Dockerfile

DockerFile介绍

DockerFIle 就是构建 docker 镜像的构建文件!本质是一个命令脚本,用于生成镜像。

构建步骤:

  • 编写一个 dockerfile 文件
  • docker build 构建成为一个镜像
  • docker run 运行镜像
  • docker push 发布镜像 (DockerHub、阿里云镜像仓库)

查看centos官方镜像学习

img

dockerhub上的镜像90%都源自 scratch

img

官方镜像都是基础包,缺少很多功能,我们通常构建自己的镜像使用

DockerFile构建过程

基础知识:

1、每个保留关键字(指令)都必须是大写字母

2、从上到下顺序执行

3、#表示注释

4、每一个指令都会创建提交一个新的镜像层并提交

img

dockerfile是面向开发的,以后要发布项目,做镜像,就需要编写dockerfile

docker镜像逐渐成为企业交付的标准,必须要掌握

步骤:开发、部署、上线、运维。。。

DockerFile : 构建文件,定义了一切的步骤,源代码

DockerImages : 通过 DockerFile 构建生成的镜像 (最终要发布和运行的产品)

Docker容器 : 容器就是镜像运行起来提供服务的

DockerFile指令

FROM            # 基础镜像 (一切从这里开始构建) (一般用centos)
MAINTAINER        # 镜像是谁写的 (姓名+邮箱)
RUN                # 镜像构建时需要运行的命令
ADD                # 步骤:添加内容(比如说jdk压缩包)
WORKDIR            # 镜像工作目录
VOLUME            # 挂载目录
EXPOSE            # 暴露端口
CMD                # 指定容器启动时运行的命令 (只有最后一个会生效,可被替代)
ENTRYPOINT        # 指定容器启动时运行的命令 (可以追加命令)
ONBUILD            # 当构建一个被继承 DockerFile 这个时候会执行 ONBUILD 的命令
COPY            # 类似ADD命令 将文件拷贝到镜像中
ENV                # 构建时设置环境变量

img

一个Dockerfile样例

FROM openjdk:17-jdk-alpine as builder

LABEL author="lear" \
    email="362664609@qq.com"

ADD ./noop-gateway-*.jar /app.jar

RUN sh -c 'touch /app.jar'

EXPOSE 10001

CMD ["--server.port=10001"]

ENV JAVA_OPTS="-server -Xms256m -Xmx256m"
#ENTRYPOINT ["java", "-jar","/app.jar"]
ENTRYPOINT exec java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar /app.jar

docker compose

docker compose简单来说就是一个docker的插件,可以支持高效地管理、定义多个容器。

也可以说他是一种脚本的写法,通过docker-compose.yml脚本来管理、定义多个容器的网络、挂载、命令、环境等等操作。

当你在苦恼于如何同时运行多个容器,比如mysql和你的业务服务时,或许你需要学习docker compose。

安装docker compose

$ curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose         // 下载github上的release

$ chmod +x /usr/local/bin/docker-compose    // 给文件授权

$ docker-compose -v        // 测试是否安装成功

docker-compose.yml文件样例

(是我们软工实践项目中生产环境的容器管理)

version: "3"
services:
  # nacos
  nacos:
    image: nacos/nacos-server:v2.2.0
    hostname: nacos-server
    restart: always
    container_name: noop-nacos
    environment:
      - PREFER_HOST_MODE=hostname
      - MODE=standalone
      - JVM_XMS=128m
      - JVM_XMX=128m
      - JVM_XMN=64m
    privileged: true
    ports:
      - "18848:8848"
      - "19848:9848"
      - "19849:9849"

  # mysql
  mysql:
    container_name: noop-mysql
    hostname: mysql-server
    restart: always
    image: mysql:5.7
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_ROOT_HOST: '%'
    ports:
      - "13306:3306"
    volumes:
      - ./data/config-init/sql/init.sql:/docker-entrypoint-initdb.d/init.sql
      - ./data/mysql/:/var/lib/mysql/
    command:
      [
        --character-set-server=utf8mb4,
        --collation-server=utf8mb4_unicode_ci
      ]

  # redis
  redis:
    image: "library/redis:alpine"
    environment:
      - TZ=Asia/Shanghai
    ports:
      - "16379:6379"
    command: redis-server --requirepass 123456
    restart: always

如何使用

​ 使用起来非常简单,只需要编写好docker-compose.yml脚本,然后通过docker-conpose up命令就能一键启动所有容器了,使用--build参数可以使发生百变的镜像重新build,-d参数可以让你在后台启动这些容器。

问题和解决过程

网络通信问题

  • 描述
    • 众所周知,在同一个docker网络下的容器可以通过容器名来互相进行内网通信。但是在两个不同docker-compose文件中进行通信存在一些困难
  • 解决方法
    • 在外部定义了一个docker network,并且让两个docker compose指定使用外部network,并且辅以.env环境变量文件进行辅助。

总结

​ Docker就像是一个魔法盒子,可以帮助开发人员把软件打包成一个小容器,方便在不同地方快速运行。学习Docker就像学会了一种魔法技能,可以让开发更快更顺利。在工作中,掌握Docker技术就像有了一把神奇的钥匙,可以打开更多便利和效率的大门。

​ 在当下的大多数开发工作中,我们项目交付也不可或缺地要学习docker技术,docker现在不仅仅是运维需要学习的必备技术了,更是每一个开发需要掌握的技术之一。

参考文献/博客

【狂神说Java】Docker最新超详细版教程通俗易懂 - 当初学习Docker时候的入门视频,比较简单,跟着学很快能学会

Docker: Accelerated Container Application Development

Docker Docs

Docker Hub Container Image Library | App Containerization

...全文
84 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

122

社区成员

发帖
与我相关
我的任务
社区描述
FZU-SE
软件工程 高校
社区管理员
  • LinQF39
  • 助教-吴可仪
  • 一杯时间
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧