什么是Docker以及如何使用Docker部署Go Web应用和Docker Compose模式

2023年 9月 7日 79.4k 0

 Docker介绍

物理机

在讲docker之前,先介绍一下物理机,发展到虚拟化时代的过程

物理机时代是计算机科学和信息技术的早期阶段,也是计算机系统的基础。在这个时代,计算机应用程序和操作系统都运行在物理硬件上,没有虚拟化或抽象层。每个计算任务都需要运行在单独的物理机上,资源分配和管理比较困难,也容易导致资源浪费。

什么是Docker以及如何使用Docker部署Go Web应用和Docker Compose模式-1

虚拟机

为了克服物理机资源的浪费和管理难题,服务器虚拟化技术开始兴起。VMware 公司在2001年推出了第一个商用虚拟化产品,允许在单个物理机上运行多个虚拟机(VM)。每个虚拟机是一个独立的虚拟操作系统实例,它们共享物理机的资源。这种虚拟化技术极大地提高了资源利用率,并简化了管理。 

什么是Docker以及如何使用Docker部署Go Web应用和Docker Compose模式-1

我们现在在Windows操作系统上安装Linux操作系统都是通过 VMware Workstation 上通过虚拟机的镜像文件来安装虚拟机,这些虚拟机共用我们宿主机的硬件资源,我们就可以在一个宿主机上开启多个虚拟机部署多个app

但是虚拟化也是有局限性的,每一个虚拟机都是一个完整的操作系统,要分配系统资源,虚拟机多道一定程度时,操作系统本身资源也就消耗殆尽,或者说必须扩容。

容器化

为了解决应用部署时减少对硬件资源的浪费,容器化技术如Docker和Kubernetes兴起,它们提供了更轻量级的虚拟化方式,将应用程序和其依赖项打包成容器,以便在任何支持容器的环境中运行。容器与虚拟机相比更轻量级,它们共享主机操作系统的内核,只包含应用程序及其依赖项,因此更加节省资源。

什么是Docker以及如何使用Docker部署Go Web应用和Docker Compose模式-1

Docker是实现容器化的一种方式,我们只需要使用相应的镜像文件,也就是将业务代码运行的环境,整体打包为单个的文件,就可以开启一个容器。下图是docker镜像分层结构

什么是Docker以及如何使用Docker部署Go Web应用和Docker Compose模式-1

  • 基础层(Base Layer) - Kernel:

    • 基础层是 Docker 镜像的最底层,通常包含操作系统的内核(Kernel)。内核是操作系统的核心部分,负责管理硬件资源、进程管理和系统调用等底层功能。基础层一般就是我们的宿主机的内核,因此我们下载的docker镜像并不包括操作系统内核,因此文件比虚拟机镜像文件小,因为它只包括发行版,依赖和应用程序。
  • 中间层(Intermediate Layers) - Debian 操作系统:

    • 在基础层之上,可以有一个或多个中间层,代表了对基础层进行的修改和添加。对于 Debian 操作系统来说,这些中间层包含了 Debian 的用户空间组件,如文件系统、系统库、工具等。这些中间层可能包括 Debian 的软件包和配置,用于构建一个完整的 Debian 环境。它就是发行版,我们基于宿主机的Linux内核,就可以通过docker安装不同的发行版(ubuntu,centos...)来使用不同的Linux操作系统。
  • 顶层(Top Layer) - Emacs 应用程序:

    • 顶层是最终的镜像层,包含了您想要在容器中运行的 Emacs 应用程序。这个层包括了 Emacs 的二进制文件、配置文件、插件和用户数据。这是容器的实际文件系统,容器可以在其中修改并运行 Emacs。只有这一层是可以被修改的。
  • 这样,整个 Docker 镜像分层结构就形成了。基础层提供了底层的操作系统内核,中间层添加了操作系统的用户空间组件(Debian),顶层包含了应用程序(Emacs)。每个层都是只读的,只有顶层是可写的,允许容器在其中运行和修改应用程序。

     部署web应用

    在本地开发了应用程序,它很可能有很多的依赖环境或包,甚至对依赖的具体版本都有严格的要求,当开发过程完成后,我们希望将应用程序部署到web服务器。这个时候必须确保所有依赖项都安装正确并且版本也完全相同,否则应用程序可能会崩溃并无法运行。如果想在另一个web服务器上也部署该应用程序,必须从头开始重复这个过程。这种场景就是Docker发挥作用的地方。

    对于运行我们应用程序的主机,不管是笔记本电脑还是web服务器,我们唯一需要做的就是运行一个docker容器平台。从此以后,就不需要担心使用的是MacOS,Ubuntu还是其他。只需定义一次应用,即可随时随地运行。

    我们要用docker部署web应用,就是要自己实现每一层的定制,然后构建成一个镜像文件,通过这个我们自己构建的镜像文件,就可以把我们的web应用部署到容器中。而定制每一层,就是通过写Dockerfile文件来实现。

    Dockerfile

    Dockerfile 是用于定义 Docker 镜像构建过程的文本文件。它包含了一系列命令,用于描述如何构建镜像。以下是 Dockerfile 中常用的一些命令:

  • FROM:指定基础镜像。它是 Dockerfile 的第一个命令,用于指定构建新镜像的起点。例如:

    FROM ubuntu:20.04

  • MAINTAINER:指定镜像的维护者信息。虽然不是必需的,但可以提供有关镜像的相关信息。

  • RUN:在容器内执行命令。它可以用于在构建过程中运行各种命令,例如安装软件包、配置环境等。例如:

    RUN apt-get update && apt-get install -y nginx

  • COPY 和 ADD:用于将文件从主机复制到容器内。COPY 用于简单地复制文件,而 ADD 具有一些额外的功能,如自动解压缩归档文件。例如:

    COPY ./app /app

  • WORKDIR:设置容器内的工作目录。这可以用于指定容器中命令的执行路径。例如:

    WORKDIR /app

  • EXPOSE:声明容器监听的端口。它不会实际打开端口,但可以在运行容器时提供端口映射。例如:

    EXPOSE 80

  • CMD 和 ENTRYPOINT:定义容器启动时执行的命令。CMD 定义了容器的默认命令,可以在运行容器时被覆盖。ENTRYPOINT 也定义了容器的启动命令,但不会被覆盖,除非在运行容器时使用 --entrypoint 参数。例如:

    CMD ["nginx", "-g", "daemon off;"]

  • ENV:设置环境变量。可以用于在容器内定义环境变量,以便应用程序在运行时使用。例如:

    ENV APP_VERSION=1.0

  • 这些是 Dockerfile 中的一些常用命令。Dockerfile 还支持其他命令和更高级的功能,可以根据具体需求进行使用。通过组合这些命令,您可以定义 Docker 镜像的构建过程,使其能够在不同的环境中正确运行您的应用程序。

    简单代码demo 

    通过一个简单的web服务看一下它是怎么通过docker部署的

    package main
    
    import (
    	"fmt"
    	"net/http"
    )
    
    func main() {
    	http.HandleFunc("/", hello)
    	server := &http.Server{
    		Addr: ":8888",
    	}
      fmt.Println("server startup...")
    	if err := server.ListenAndServe(); err != nil {
    		fmt.Printf("server startup failed, err:%vn", err)
    	}
    }
    
    func hello(w http.ResponseWriter, _ *http.Request) {
    	w.Write([]byte("hello world"))
    }
    

    什么是Docker以及如何使用Docker部署Go Web应用和Docker Compose模式-1

    编写Dockerfile

    在demo的同目录下,新建一个Dockerfile,并加入以下内容

    # 基础镜像golang:alpine,这个镜像运行的是alpine Linux发行版,该发行版的大小很小并且内置了Go
    FROM golang:alpine
    
    # 为我们的镜像设置必要的环境变量
    ENV GO111MODULE=on 
        GOPROXY=https://goproxy.cn,direct 
        CGO_ENABLED=0 
        GOOS=linux 
        GOARCH=amd64
    
    # 移动到工作目录:/build
    WORKDIR /build
    
    # 将代码复制到容器中
    COPY . .
    
    # 将我们的代码编译成二进制可执行文件app
    RUN go build -o app .
    
    # 移动到用于存放生成的二进制文件的 /dist 目录
    WORKDIR /dist
    
    # 将二进制文件从 /build 目录复制到这里
    RUN cp /build/app .
    
    # 声明服务端口
    EXPOSE 8888
    
    # 启动容器时运行的命令
    CMD ["/dist/app"]
    

    什么是Docker以及如何使用Docker部署Go Web应用和Docker Compose模式-1

    构建镜像

    在项目目录下,执行下面的命令创建镜像,并指定镜像名称为xx_goweb_app:

    docker build . -t xx_goweb_app
    

    什么是Docker以及如何使用Docker部署Go Web应用和Docker Compose模式-1

    等待构建过程结束,输出如下提示:

    ...
    Successfully built 90d9283286b7
    Successfully tagged xx_goweb_app:latest
    

    什么是Docker以及如何使用Docker部署Go Web应用和Docker Compose模式-1

    现在我们已经准备好了镜像,但是目前它什么也没做。我们接下来要做的是运行我们的镜像,以便它能够处理我们的请求。运行中的镜像称为容器。

    执行下面的命令来运行镜像:

    docker run -p 8888:8888 xx_goweb_app
    

    什么是Docker以及如何使用Docker部署Go Web应用和Docker Compose模式-1

    标志位-p用来定义端口绑定。由于容器中的应用程序在端口8888上运行,我们将其绑定到主机端口也是8888。如果要绑定到另一个端口,则可以使用-p $HOST_PORT:8888。例如-p 5000:8888

    现在就可以测试下我们的web程序是否工作正常,打开浏览器输入http://127.0.0.1:8888就能看到我们事先定义的响应内容如下:

    hello world
    

    什么是Docker以及如何使用Docker部署Go Web应用和Docker Compose模式-1

    Docker Compose模式 

    Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。它允许您使用一个单独的文件(称为 docker-compose.yml)来配置和启动多个 Docker 容器,这些容器可以协同工作以构建完整的应用程序。我在windows安装了Docker Desktop,Docker Compose 已经预安装在Docker Desktop中,所以不需要额外安装,除此情况需要安装Docker Compose,方法自行google

    类似我们写一个商品微服务,它不仅有web服务,还需要使用到mysql和consul注册中心,这个时候我们就需要用到两个容器来协同工作部署这个微服务,通过 Docker Compose 部署包含微服务和 mysql的应用程序是一种常见的做法。

    首先在项目目录下写好dockerfile文件并构建打包成镜像,并且把consul和mysql镜像也下载好

    什么是Docker以及如何使用Docker部署Go Web应用和Docker Compose模式-1

    然后编写docker-compose.yaml文件

    version: '3'
    services:
      go-service:
    #    build:
    #      context: .
    #      dockerfile: Dockerfile
        image: goods_service2
    #    ports:
    #      - 8382:8382
        volumes:
          - ./conf:/conf
        restart: always
        depends_on:
          - mysql
          - consul 
        networks:
          - my-network   
    
      mysql:
        image: mysql:latest
        restart: always
        environment:
          - MYSQL_ROOT_PASSWORD=123456
          - MYSQL_DATABASE=goods_service
          - MYSQL_USER=fengmi
          - MYSQL_PASSWORD=123456
        networks:
          - my-network
    
      consul:
        image: consul:1.10.3
        restart: always
        ports:
          - 8500:8500
        networks:
          - my-network
    networks:
      my-network:
    

    什么是Docker以及如何使用Docker部署Go Web应用和Docker Compose模式-1

    这里我们用文件映射./conf:/conf  ,这样就可以在宿主机的配置文件修改容器内的配置文件,mysql下的environment可以乱填,不需要你去mysql容器中创建数据库用户名密码啥的,他自己帮你完成好了。并且配置一个network,这样可以让三个容器共享一个网络。

    终端运行

    docker-compose up -d
    

    什么是Docker以及如何使用Docker部署Go Web应用和Docker Compose模式-1

    这样容器就部署成功了

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论