Docker

1. 什么是Docker

一条小鲸鱼上面有些集装箱,比较形象的说明了 Docker 的特点,以后见到这个图标等同见到了 Docker

2. 容器技术

  1. Docker 是一个开源的应用容器引擎,它基于Go语音开发,并遵从Apache2.0开源协议
  2. 使用 Docker 可以让开发者封装他们的应用以及依赖包到一个可移植的容器中,然后发布到任意
  3. Linux机器上,也可以实现虚拟化
  4. Docker 容器完全使用沙箱机制,相互之间不会有任何接口,这保证了容器之间的安全性
  5. Docker 诞生于 2013 年初,目前有两个版本: Community Edition(CE ,社区版 ) 和 EnterpriseEdition(EE,企业版 )

3. 容器与虚拟机区别

  1. 虚拟机是在一台物理机上,利用虚拟化技术,虚拟出来多个操作系统,每个操作系统之间是隔离的。
  2. Docker 是开源的应用容器引擎,依然需要先在电脑上安装操作系统,然后安装 Docker 容器管理器。

4. Docker特点

  1. 更高效的利用系统资源:Docker 对系统资源的利用率很高,无论是应用执行速度,内存损耗或者文件存储速度,都要比传统虚拟 机技术更高效。
  2. 更快速的启动时间:传统的虚拟化技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级,甚至毫秒级的启动时间,大大节约了开发测试,部署的时间。
  3. 一致的运行环境:Docker 是一个采用集装箱思想出现技术,把相关依赖及运行代码打到一起,达到开发环境,测试环境,部署环境一样,减少由于环境不一致而出现问题
  4. 持续支付和部署:对开发和运维人员来说,最希望就是一次创建和部署,可以在任意地方运行。
  5. 更轻松的迁移:Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本、其运行结果是一致的。
  6. 更轻松的维护和扩展:Docker 使用的分层存储以及镜像技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得十分简单。

5. Docker客户端和服务器

  1. Docker 是一个客户端 – 服务器( C/S )架构程序。
  2. Docker 客户端只需要向 Docker 服务器或者守护进程发出请求,服务器或者守护进程将完成所有工作并返回结果。
  3. Docker 提供了一个命令行工具 Docker 以及一整套 RESTful API 。
  4. 你可以在同一台宿主机上运行 Docker 守护进程和客户端,也可以从本地的 Docker 客户端连接到运 行在另一台宿主机上的远程 Docker 守护进程。

6. Docker镜像

  1. 镜像是构建 Docker 的基石。
  2. 用户基于镜像来运行自己的容器。
  3. 镜像也是 Docker 生命周期中的 “ 构建 ” 部分。
  4. 镜像是基于联合文件系统的一种层式结构,由一系列指令一步一步构建出来。
  5. 例如:添加一个文件;执行一个命令;打开一个窗口。也可以将镜像当作容器的 “ 源代码 ” 。
  6. 镜像体积很小,非常 “ 便携 ” ,易于分享、存储和更新。

7. Registry(注册中心/镜像仓库)

  1. Docker 用 Registry 来保存用户构建的镜像。
  2. Registry 分为公共和私有两种。
  3. Docker 公司运营公共的 Registry 叫做 Docker Hub 。
  4. 用户可以在 Docker Hub 注册账号,分享并保存自己的镜像
  5. 说明:在 Docker Hub 下载镜像巨慢,可以自己构建私有的 Registry

8. Docker容器

  1. Docker 可以帮助你构建和部署容器,你只需要把自己的应用程序或者服务打包放进容器即可。
  2. 容器是基于镜像启动起来的,容器中可以运行一个或多个进程。
  3. 我们可以认为,镜像是 Docker 生命周期中的构建或者打包阶段,而容器则是启动或者执行阶段。
  4. 容器基于镜像启动,一旦容器启动完成后,我们就可以登录到容器中安装自己需要的软件或者服务。

9. 安装Docker

#安装最新版本的Docker
sudo apt install docker-ce docker-ce-cli containerd.io
#等待安装完成

#查看Docker版本
sudo docker version

#查看Docker运行状态
sudo systemctl status docker

#docker 命令补全工具
sudo apt-get install bash-completion

sudo curl -L https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker -o /etc/bash_completion.d/docker.sh

source /etc/bash_completion.d/docker.sh

#启动docker
sudo systemctl start docker

#查看 Docker 是否成功
docker info

#注意:通过tar包安装的Go,注意解压到/usr/local/这个目录再配置环境变量

10. Docker常用命令

  1. docker search 镜像名称 //搜索镜像
  2. docker pull 镜像名称:版本号 //拉取对应版本的镜像
  3. docker pull 镜像名称 //默认拉取最新的镜像
  4. docker images //查看本地已下载的镜像
  5. docker ps //查看正在运行的容器
  6. docker ps -a //查看所有的容器(包括run、stop、exited状态的)
  7. docker container ls //查看正在运行的容器
  8. docker rm 容器ID //只能删除没有在运行的容器
  9. docker rm -f 容器ID //可以删除正在运行的容器
  10. docker run -p 本地主机端口号:容器服务端口号 –name 容器名字 [-e 配置信息修改] -d 镜像名字
  11. docker start 容器ID //启动容器
  12. docker stop 容器ID //终止容器
  13. docker rmi 镜像名称orID //删除镜像
  14. docker rmi 镜像名称orI –force //强制删除镜像

11. Docker部署GO项目

  1. 项目创建
    • mkdir demo_app
    • go mod demo_app
    • touch main.go

package main

import (
        "fmt"
        "net/http"
)

func main() {
        http.HandleFunc("GET /posts/{id}", func(writer http.ResponseWriter, request *http.Request) {
                id := request.PathValue("id")
                fmt.Fprintf(writer, "docker 部署GO :  id: %s", id)
        })

        fmt.Println("Starting server at http://localhost:8080")

        if err := http.ListenAndServe(":8080", nil); err != nil {
                panic(err)
        }
}
~   

2. 运行 go run main.go //运行结果 Starting server at http://localhost:8080

3. 编写Dockerfile

# 使用官方的 Go 语言镜像作为基础镜像
# 这里使用 Go 1.22.6 版本的 Alpine Linux 镜像
FROM golang:1.22.6-alpine AS builder

# 设置工作目录为 /app
# 所有后续操作都会在这个目录下进行
WORKDIR /app

# 将当前项目目录的所有文件拷贝到容器的 /app 目录中
COPY . .

# 设置 Go 模块代理为 https://goproxy.cn(在中国加速模块下载),并下载项目的依赖
RUN go env -w GOPROXY=https://goproxy.cn,direct && go mod download

# 编译 Go 项目,生成可执行文件 demo_app
RUN go build -o demo_app

# 使用一个更小的基础镜像(Alpine)来运行应用程序
# Alpine 是一个极简的 Linux 发行版,适合部署阶段
FROM alpine:latest

# 安装 tzdata 包,确保支持时区的配置
RUN apk add --no-cache tzdata

# 设置工作目录为 /app
WORKDIR /app

# 从编译阶段的镜像中拷贝编译后的二进制文件到运行镜像中
COPY --from=builder /app/demo_app /app/demo_app

# 暴露容器的 8080 端口,用于外部访问
EXPOSE 8080

# 设置容器启动时运行的命令
# 这里是运行编译好的可执行文件 demo_app
CMD ["/app/demo_app"]

4. 构建docker镜像 :

docker build -t demp_app .
docker build:这是 Docker 用于构建镜像的命令。
-t simple-web-app:t 是 --tag 的缩写,用来给构建的 Docker 镜像命名。
.:指定了构建上下文的路径,. 表示当前目录,Docker 引擎会从当前目录读取 Dockerfile 以及所有相关的项目文件并打包进镜像中。

5. 运行docker容器

docker run -p 8080:8080 simple-web-app
docker run:基于指定的 Docker 镜像创建并启动一个容器实例。
-p 8080:8080:将本地主机的 8080 端口映射到容器的 8080 端口,以便你可以通过 localhost:8080 访问容器内的应用。
simple-web-app:基于 simple-web-app 镜像来创建并运行容器。
这样,Go 项目将会在本地的 8080 端口上运行。你可以通过浏览器访问 http://localhost:8080/posts/1,应该会看到 id: 1 的字样。

12. Docker compose

  1. 概述
    • 在前面的 demo_app 项目中,我们只实现了一个简单的 Web 服务,它并没有依赖任何第三方中间件。因此,只需要一个 Docker 容器就可以完成整个项目的部署,过程相对简单。
    • 然而,在实际的项目中,即使是类似的 Web 应用,往往也会需要依赖其他第三方中间件,例如数据库(如 MySQLPostgreSQLMongoDB)、缓存(如 Redis)、或者消息队列(如 Kafka)等。这些依赖服务需要与 Web 应用协同工作,如果我们需要手动启动每个服务的 Docker 容器,并且管理它们之间的启动顺序和网络配置,整个过程会非常繁琐且容易出错。
    • 为了简化这些管理和配置工作,使得多服务应用的部署更加简便和一致,我们可以使用 Docker Compose 工具。Docker ComposeDocker 的一个工具,允许我们通过编写一个简单的 YAML 文件(通常命名为 docker-compose.yml),来描述多服务应用所需的容器、网络配置、卷等资源。借助这个配置文件,我们只需一条命令就可以启动所有相关的服务,使得整个流程更高效且易于管理。
  2. 安装docker compose
    • sudo apt-get update
    • sudo apt-get install docker-compose-plugin
    • docker compose version
    • #更新,重复执行以上命令
  3. 引入 mongo 库
    • go get github.com/chenmingyong0423/go-mongox
  4. main.go
package main

import (
	"context"
	"fmt"
	"net/http"

	"github.com/chenmingyong0423/go-mongox"
	"github.com/chenmingyong0423/go-mongox/builder/query"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go.mongodb.org/mongo-driver/mongo/readpref"
)

type Post struct {
	mongox.Model `bson:",inline"`
	Title        string `bson:"title"`
	Author       string `bson:"author"`
	Content      string `bson:"content"`
}

// 示例代码,不是最佳的创建方式
func newCollection() *mongo.Collection {
	client, err := mongo.Connect(context.Background(), options.Client().ApplyURI("mongodb://mongo:27017").SetAuth(options.Credential{
		Username:   "test",
		Password:   "test",
		AuthSource: "db-test",
	}))
	if err != nil {
		panic(err)
	}
	err = client.Ping(context.Background(), readpref.Primary())
	if err != nil {
		panic(err)
	}
	collection := client.Database("db-test").Collection("test_post")
	return collection
}

func main() {
	// 创建一个 *mongo.Collection 对象
	mongoColl := newCollection()
	// 使用 Post 结构体作为泛型参数创建一个 collection
	postColl := mongox.NewCollection[Post](mongoColl)

	http.HandleFunc("GET /posts/{id}", func(writer http.ResponseWriter, request *http.Request) {
		id := request.PathValue("id")
		post, err := postColl.Finder().Filter(query.Id(id)).FindOne(context.Background())
		if err != nil {
			fmt.Fprintf(writer, "docker compose error: %s", err.Error())
		} else {
			fmt.Fprintf(writer, "docker compose post: %v", post)
		}
	})

	fmt.Println("Starting server at http://localhost:8080")

	if err := http.ListenAndServe(":8080", nil); err != nil {
		panic(err)
	}
}

5. 编写 MongoDB 脚本

mongosh -- "$MONGO_INITDB_DATABASE" <<EOF
db = db.getSiblingDB('admin')
db.auth('$MONGO_INITDB_ROOT_USERNAME', '$MONGO_INITDB_ROOT_PASSWORD');
db = db.getSiblingDB('$MONGO_INITDB_DATABASE')
db.createUser({
    user: '$MONGO_USERNAME',
    pwd: '$MONGO_PASSWORD',
    roles:[
        {
            role: 'readWrite',
            db: '$MONGO_INITDB_DATABASE'
        }
    ]
});
EOF

6. 编写docker-compose.yaml 文件

version: '3.8'

services:
  # 定义 simple-web-app 服务
  web:
    # 使用 Dockerfile 构建镜像
    build: .
    # 容器启动后暴露的端口,映射宿主机的8080端口到容器的8080端口
    ports:
      - "8080:8080"
    # 依赖于 db 服务,确保 MongoDB 服务在 web 服务之前启动
    depends_on:
      - mongo

  # 定义 MongoDB 服务
  mongo:
    # 使用官方的 MongoDB 镜像
    image: mongo:latest
    # 设置 MongoDB 初始化时的根用户名、密码和默认数据库
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: admin
      MONGO_INITDB_DATABASE: db-test
      MONGO_USERNAME: test  # 应用程序用户的名称
      MONGO_PASSWORD: test  # 应用程序用户的密码
    # 暴露 MongoDB 的默认端口27017,便于外部访问
    ports:
      - "27017:27017"
    # 使用 --auth 命令启动 MongoDB 以启用身份验证
    command:
      - --auth
    # 使用卷来持久化数据库数据,避免容器删除时数据丢失
    volumes:
      - db_data:/data/db
      # 将初始化 MongoDB 用户的脚本挂载到容器中,确保在启动时执行
      - ./script/mongo-init.sh:/docker-entrypoint-initdb.d/mongo-init.sh

# 定义卷,用于持久化存储 MongoDB 的数据,避免数据在容器重启时丢失
volumes:
  db_data:

7. 运行 docker-compose 命令

docker-compose up -d
#
构建 demo_app 的 Docker 镜像。
启动 MongoDB 服务,并通过 mongo-init.sh 初始化数据库、用户和权限。
启动 demo_app 容器。

#访问浏览器
http://192.168.2.32:8080/posts/1 或者 http://localhost:8080/posts/1

#stop服务
docker-compose down

#清除旧镜像和容器
docker-compose down && docker-compose up --build -d

文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇