说说docker这个好玩意 | 青训营

169 阅读7分钟

最近学了docker这个东西,是真的好用啊,学习其他技术的成本直线下降,再也不需要为环境配置而发愁了

一、什么是docker?

Docker是一种容器技术,它可以让开发者和运维人员在一个独立的环境中打包、部署和运行应用程序。

1、什么是容器?

容器是一种沙盒技术,它是一个特殊的进程,可以运行在一个隔离和受限的环境中,与外界和其他容器分开。容器中包含了应用程序和它的依赖库、配置文件等,可以在不同的平台上运行,而不需要修改代码或安装额外的软件。容器可以看作是应用程序的可执行单元,也可以看作是一种虚拟化技术的形式。

2、什么是容器技术?

容器技术是一种轻量级的操作系统虚拟化技术,它可以将应用程序和它的运行环境打包到一个容器中,通过容器引擎提供隔离资源限制的运行环境,实现应用和平台、硬件的解耦,方便应用的移植和部署。容器技术利用操作系统的功能(如名称空间和控制组)来隔离和管理进程,不需要运行额外的操作系统,因此比虚拟机更节省资源和启动更快。

3、docker相比于虚拟机的优势

  • 轻量级:Docker容器与宿主机共享内核,不需要单独的操作系统,占用资源少,启动快。
  • 隔离性:Docker容器之间相互隔离,不会互相影响,提高了安全性和稳定性。
  • 可移植性:Docker容器可以在不同的平台和环境中运行,方便了应用程序的迁移和分发。
  • 可扩展性:Docker容器可以通过编排工具(如Kubernetes)进行水平扩展,提高了应用程序的可伸缩性和负载均衡能力。
  • 可复用性:Docker容器可以通过镜像(image)进行保存和共享,方便了应用程序的复用和更新。

接下来说一下docker中一个重要的概念:镜像

二、什么是镜像?

Docker镜像是一种轻量级可移植自包含的文件系统,它包含了运行一个应用程序所需要的所有内容,如代码、库、环境变量、配置文件等。

Docker镜像是由多个镜像层组成的,每个镜像层对应一个Dockerfile中的一个命令,每个镜像层都是只读的,只有最上层的容器层是可读可写的。

Docker-image-structe-a160887f0c854f298287c9a86865f39b.png

Docker镜像可以从Docker Hub或其他镜像仓库中下载或上传,也可以通过Dockerfile或commit命令自己创建(这个后面会说到)。

好了,概念基本清楚了,接下来进入实操,我会用redis镜像来演示

三、实操

首先根据你的操作系统和需求选择合适的版本。,可以参照这个史上最全Docker环境安装指南

安装 docker 后,你就可以开始制作和运行容器了。容器是由镜像(image)文件创建的,镜像文件包含了应用程序和依赖。

  • 首先,我们从仓库拉取 redis 镜像,可以输入 docker pull redis 命令,这会下载最新版本的 redis 镜像,若需要选择版本,则加上版本号,示例:docker pull redis:7.2-rc3-bookworm
  • 然后,我们可以创建并运行一个名为 redis-server 的容器,可以输入 docker run --name redis-server -d -p 6379:6379 redis 命令,这会在后台运行一个容器,-p 将容器的 6379 端口映射到主机的 6379 端口。
  • 接着,我们可以查看正在运行的容器,可以输入 docker ps 命令,这会显示容器的 ID、名称、状态、端口等信息。
  • 然后,我们可以在运行的容器中执行一个命令,比如查看 redis 的版本,可以输入 docker exec redis-server redis-cli --version 命令,这会输出类似 redis-cli 6.2.6 的结果。
  • 接下来,我们可以进入容器的交互式终端,可以输入 docker exec -it redis-server sh 命令,这会打开一个 shell 环境。在 shell 中,我们可以使用 redis-cli 命令来测试 redis 的功能,比如设置和获取键值对。例如:
# 设置键 name 的值为 Alice
/ # redis-cli set name Alice
OK
# 获取键 name 的值
/ # redis-cli get name
"Alice"
# 退出 shell
/ # exit
  • 接着,我们可以停止容器,可以输入 docker stop redis-server 命令,这会停止运行的容器。
  • 然后,我们可以启动容器,可以输入 docker start redis-server 命令,这会重新启动容器。
  • 接着,我们可以查看容器的日志输出,可以输入 docker logs redis-server 命令,这会显示容器的启动信息、连接信息等。
  • 最后,我们可以删除容器和镜像,可以输入 docker rm redis-server 命令来删除容器,然后输入 docker rmi redis 命令来删除镜像。

接下来讲讲比较重要的dockerfile,会这个就可以自己构建镜像了

四、Dockerfile

  • dockerfile是一种用来描述如何构建 docker 镜像的文本文件,它包含一系列的指令,每一条指令都会创建一个新的镜像层,并对镜像进行修改。dockerfile 可以让我们自定义镜像的内容、结构、依赖、环境等,从而实现更高效和灵活的部署。

  • 以 golang 为例,我们可以使用 dockerfile 来创建一个 golang 的开发环境,并运行一个简单的 web 服务。我们需要以下几个步骤:

    • 在主机上创建一个工作目录,比如 go-docker-demo,并在其中创建一个 main.go 文件,内容如下:
    package main
    
    import (
        "fmt"
        "log"
        "net/http"
    )
    
    func main() {
        http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
            fmt.Fprintf(w, "Hello, Docker!")
        })
        log.Fatal(http.ListenAndServe(":8080", nil))
    }
    
    • 在工作目录中创建一个 Dockerfile 文件,内容如下:
    # 使用官方 golang 镜像作为基础镜像
    FROM golang:alpine
    #在环境中添加PROXY
    ENV GOPROXY https://goproxy.cn,direct
    # 设置工作目录
    WORKDIR /go/src/app
    # 将主机上的 main.go 文件复制到工作目录中
    COPY main.go .
    # 编译并安装程序
    RUN go build -o app .
    # 暴露 8080 端口
    EXPOSE 8080
    # 运行程序
    CMD ["./app"]
    
    • 在工作目录中执行 docker build -t go-docker-demo . 命令,这会根据 Dockerfile 的内容构建一个名为 go-docker-demo 的镜像。
    • 执行 docker run --name go-docker-demo -d -p 8080:8080 go-docker-demo 命令,这会运行一个名为 go-docker-demo 的容器,并将容器的 8080 端口映射到主机的 8080 端口。
    • 在浏览器中访问 http://localhost:8080/ ,就可以看到 Hello, Docker! 的输出。

还有一个比较重要的概念:挂载卷

五、挂载卷

  • 挂载卷是一种在 docker 容器和主机之间共享文件或目录的机制,可以实现数据的持久化和同步。挂载卷有两种类型:绑定挂载命名挂载

  • 绑定挂载是将主机上的一个已存在的文件或目录挂载到容器中的一个指定位置,容器和主机可以双向读写这些文件或目录。绑定挂载的优点是方便快捷,缺点是不利于跨平台和跨主机的移植性。

  • 命名挂载是创建一个 docker 管理的卷,并将其挂载到容器中的一个指定位置,容器和主机可以双向读写这些文件或目录。命名挂载的优点是具有更好的移植性和安全性,缺点是需要额外的管理和配置。

  • 以 centos 镜像为例,我们可以使用以下几种方式来使用挂载卷:

    • 使用 -v 参数来指定绑定挂载,比如将主机上的 /data1 目录挂载到容器中的 /data2 目录:
    docker run -it -v /data1:/data2 centos /bin/bash
    
    • 使用 VOLUME 指令来创建匿名挂载,比如在 Dockerfile 中指定两个匿名卷:
    FROM centos
    VOLUME ["volume01","volume02"]
    CMD echo "----end----"
    CMD /bin/bash
    
    • 使用 --volumes-from 参数来挂载其他容器的数据卷,比如将 mysql01 容器的数据卷挂载到 mysql02 容器:
    docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7 /bin/bash
    docker run -d -p 3311:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7 /bin/bash
    

结束力,虽然还有容器之间的网络连接、发布镜像什么的没有讲但是基本很简单啦,前面的会了的话基本使用也差不多了,如果火力,我就把后面的补充啦