百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

Go docker环境配置

toyiye 2024-06-21 12:00 9 浏览 0 评论

一.先安装git,用于后续代码拉取:

yum -y install git

二.安装docker:

1.更新yum, 安装依赖

sudo yum update
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

2.将docker源添加到系统中

sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

3.安装docker

sudo yum install docker-ce docker-ce-cli containerd.io

4.启动docker和添加开启自启动

sudo systemctl start docker
sudo systemctl enable docker

5.查看docker版本

docker -v

三、安装go环境

wget wget https://studygolang.com/dl/golang/go1.16.1.linux-amd64.tar.gz
tar -zxvf go1.16.1.linux-amd64.tar.gz
mv go/ /usr/local/

添加环境变量 GOROOT 和将 GOBIN 添加到 PATH 中

vi /etc/profile
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin

配置完毕后,执行命令令其生效

source /etc/profile

在控制台输入go version,若输出版本号则安装成功,如下:

$ go version
go version go1.16.1 linux/amd64

打开module和配置代理

$go env -w GO111MODULE=on
$go env -w GOPROXY=https://goproxy.cn,direct
$go env -w GOPATH=/data/gowork

四、git拉取项目代码

cd /
mkdir -r /data/gowork/src
cd /data/gowork/src
git clone https://gitee.com/xiaoxingeapp/go-blog.git
cd go-blog
go mod tidy

五、将Golang应用部署到Docker

vi Dockerfile

FROM golang:latest

ENV GOPROXY https://goproxy.cn,direct
# 移动到工作目录
WORKDIR /data/gowork/src/go-blog
# 将代码复制到容器中
COPY . /data/gowork/src/go-blog
# 将我们的代码编译成二进制可执行文件
RUN go build .

EXPOSE 8000
ENTRYPOINT ["./go-blog"]

注意 go-blogdocker 容器里编译,并没有在宿主机现场编译

构建镜像

#在go-blog目录下执行
docker build -t go-blog-docker .

#输出:
Sending build context to Docker daemon 96.39 MB
Step 1/6 : FROM golang:latest
 ---> d632bbfe5767
Step 2/6 : WORKDIR $GOPATH/src/github.com/EDDYCJY/go-gin-example
 ---> 56294f978c5d
Removing intermediate container e112997b995d
Step 3/6 : COPY . $GOPATH/src/github.com/EDDYCJY/go-gin-example
 ---> 3b60960120cf
Removing intermediate container 63e310b3f60c
Step 4/6 : RUN go build .
 ---> Running in 52648a431450
go: downloading github.com/gin-gonic/gin v1.3.0
go: downloading github.com/go-ini/ini v1.32.1-0.20180214101753-32e4be5f41bb
go: downloading github.com/swaggo/gin-swagger v1.0.1-0.20190110070702-0c6fcfd3c7f3
...
 ---> 7bfbeb301fea
Removing intermediate container 52648a431450
Step 5/6 : EXPOSE 8000
 ---> Running in 98f5b387d1bb
 ---> b65bd4076c65
Removing intermediate container 98f5b387d1bb
Step 6/6 : ENTRYPOINT ./go-gin-example
 ---> Running in c4f6cdeb667b
 ---> d8a109c7697c
Successfully built aab0b3fdee0a
Successfully tagged go-blog-docker:latest

验证镜像:

docker images
输出:
go-blog-docker latest aab0b3fdee0a About a minute ago 1.37GB
golang latest 73fa8a9cf041 15 hours ago 941MB

创建并运行一个新容器

执行命令 
docker run -p 8000:8000 go-blog-docker

输出:
2022/03/03 09:12:39 dial tcp 127.0.0.1:3306: connect: connection refused
[GIN-debug] GET    /swagger/*any             --> github.com/swaggo/gin-swagger.CustomWrapHandler.func1 (3 handlers)
[GIN-debug] GET    /auth                     --> go-blog/routers/api.GetAuth (3 handlers)
[GIN-debug] GET    /api/v1/tags              --> go-blog/routers/api/v1.GetTags (4 handlers)
[GIN-debug] POST   /api/v1/tags              --> go-blog/routers/api/v1.AddTag (4 handlers)
[GIN-debug] PUT    /api/v1/tags/:id          --> go-blog/routers/api/v1.EditTag (4 handlers)
[GIN-debug] DELETE /api/v1/tags/:id          --> go-blog/routers/api/v1.DeleteTag (4 handlers)
[GIN-debug] GET    /api/v1/articles          --> go-blog/routers/api/v1.GetArticles (4 handlers)
[GIN-debug] GET    /api/v1/articles/:id      --> go-blog/routers/api/v1.GetArticle (4 handlers)
[GIN-debug] POST   /api/v1/articles          --> go-blog/routers/api/v1.AddArticle (4 handlers)
[GIN-debug] PUT    /api/v1/articles/:id      --> go-blog/routers/api/v1.EditArticle (4 handlers)
[GIN-debug] DELETE /api/v1/articles/:id      --> go-blog/routers/api/v1.DeleteArticle (4 handlers)

仔细看看控制台的输出了一条错误 dial tcp 127.0.0.1:3306: connect: connection refused

我们研判一下,发现是 Mysql 的问题,接下来第二项我们将解决这个问题。

六、Mysql安装

拉取镜像

Docker 的公共仓库 Dockerhub 下载 MySQL 镜像(国内建议配个镜像)

$ docker pull mysql

创建并运行一个新容器

运行 Mysql 容器,并设置执行成功后返回容器 ID

$ docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:latest
输出:
8c86ac986da4922492934b6fe074254c9165b8ee3e184d29865921b0fef29e64

进入 Mysql容器

#进入mysql容器命令:
docker exec -it mysql bash
#连接mysql
mysql -uroot -p -h localhost

#退出容器命令
exit

Mysql 挂载数据卷

倘若不做任何干涉,在每次启动一个 Mysql 容器时,数据库都是空的。另外容器删除之后,数据就丢失了(还有各类意外情况),非常糟糕!

数据卷

数据卷 是被设计用来持久化数据的,它的生命周期独立于容器,Docker 不会在容器被删除后自动删除 数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的 数据卷。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 docker rm -v 这个命令

数据卷 是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:

  • 数据卷 可以在容器之间共享和重用
  • 对 数据卷 的修改会立马生效
  • 对 数据卷 的更新,不会影响镜像
  • 数据卷 默认会一直存在,即使容器被删除

注意:数据卷 的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会隐藏掉,能显示看的是挂载的 数据卷。

如何挂载

首先创建一个目录用于存放数据卷;示例目录 /data/docker-mysql,注意 --name 原本名称为 mysql 的容器,需要将其删除 docker rm

#删除之前的容器
docker stop mysql
docker rm mysql

#重新运行
docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -v /data/docker-mysql:/var/lib/mysql -d mysql:latest

创建成功,检查目录 /data/docker-mysql,下面多了不少数据库文件

远程连接:

MySQL错误号码 2058

mysql> use mysql;
Database changed
mysql> select host,user,plugin,authentication_string from user where user = 'root';
+-----------+------+-----------------------+------------------------------------------------------------------------+
| host      | user | plugin                | authentication_string                                                  |
+-----------+------+-----------------------+------------------------------------------------------------------------+
| %         | root | caching_sha2_password | $A$005$ru3S) >y(Z3@il]wvVwxn/VoB7KXrDWmV9eQvw2NMFQrbYOKo.WGlhU1M3/ |
| localhost | root | mysql_native_password | *6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9                              |
+-----------+------+-----------------------+------------------------------------------------------------------------+
2 rows in set (0.00 sec)

#发现我们看一下host,这里的host表示的是可以远程连接,但是这个远程连接的密码是加密的方式的,我做的方法是两边切换一下,最后调整如下就可以登录了
UPDATE `user` SET `plugin`='mysql_native_password',authentication_string='*81F5E21E35407D884A6CD4A731AEBFB6AF209E1B' WHERE `host`="%" AND `user`="root" LIMIT 1;
flush privileges;

验证

接下来交由你进行验证,目标是创建一些测试表和数据,然后删除当前容器,重新创建的容器,数据库数据也依然存在(当然了数据卷指向要一致)

七、需要将go容器与mysql容器关联起来

vim conf/app.ini

修改:

HOST = mysql:3306

重新构建镜像

删除之前go-blog镜像

删除原本的有问题的镜像,-f 是强制删除及其关联状态

若不执行 -f,你需要执行 docker ps -a 查到所关联的容器,将其 rm 解除两者依赖关系

docker rmi -f gin-blog-docker

重复先前第五步骤,回到 go-blog 的项目根目录下执行

docker build -t go-blog-docker .

创建并运行一个新容器

Q:我们需要将 Golang 容器和 Mysql 容器关联起来,那么我们需要怎么做呢?

A:增加命令 --link mysql:mysqlGolang 容器与 Mysql 容器互联;通过 --link可以在容器内直接使用其关联的容器别名进行访问,而不通过 IP,但是--link只能解决单机容器间的关联,在分布式多机的情况下,需要通过别的方式容器方式互联进行连接(ambassador)

分布式多机情况使用通过容器方式互联:
#启动ambassador1:
sudo docker run -d --link mysql:mysql --name ambassador1 -p 3306:3306 ambassador  
#启动ambassador2:
sudo docker run -d --name ambassador2 --expose 3306 -e MYSQL_PORT_3306_TCP=tcp://x.x.x.x:3306 ambassador  
#启动go-blog:
sudo docker run -i -t --rm --link ambassador2:mysql go-blog-docker

运行

执行命令 docker run --link mysql:mysql -p 8000:8000 go-blog-docker

$ docker run --link mysql:mysql -p 8000:8000 go-blog-docker
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:    export GIN_MODE=release
 - using code:    gin.SetMode(gin.ReleaseMode)
...
Actual pid is 1

结果

检查启动输出、接口测试、数据库内数据,均正常;我们的 Golang 容器和 Mysql 容器成功关联运行,大功告成 :)


补充另外一个问题:go-block-docker这个镜像占用太大了

创建超小的 Golang 镜像

Q:为什么这么镜像体积这么大?

A:FROM golang:latest 拉取的是官方 golang 镜像,包含 Golang 的编译和运行环境,外加一堆 GCC、build 工具,相当齐全

这是有问题的,我们可以不在 Golang 容器中现场编译的,压根用不到那些东西,我们只需要一个能够运行可执行文件的环境即可

构建 Scratch 镜像

Scratch 镜像,简洁、小巧,基本是个空镜像

修改 Dockerfile

FROM scratch

WORKDIR /data/gowork/src/go-blog
COPY . /data/gowork/src/go-blog

EXPOSE 8000
CMD ["./go-blog"]

编译可执行文件

CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o go-blog 

编译所生成的可执行文件会依赖一些库,并且是动态链接。在这里因为使用的是 scratch 镜像,它是空镜像,因此我们需要将生成的可执行文件静态链接所依赖的库

构建镜像

$ docker build -t go-blog-docker-scratch .

注意,假设你的 Golang 应用没有依赖任何的配置等文件,是可以直接把可执行文件给拷贝进去即可,其他都不必关心

这里可以有好几种解决方案

  • 依赖文件统一管理挂载
  • go-bindata 一下

因此这里如果解决了文件依赖的问题后,就不需要把目录给 COPY 进去了

运行

$ docker run --link mysql:mysql -p 8000:8000 go-blog-docker-scratch


思考:

docker已经发行很多年了为什么最近几年企业才大力使用,得益于k8s

早期cgroups也能实现容器,后来docker出来更方便了,但是生产上不利于维护与部署,之后有了docker-composer再后来k8s技术成熟,运维技术的积累,企业才敢开始大力推广使用。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码