目录
1./compose/basic目录下的docker-compose.yml文件内容
2./compose/project-root目录下的docker-compose.yml文件内容
前言:
最终方案:
步骤一:物理机上安装docker
步骤二:用docker-compose启动一个最小版本的集群,包含paas服务、hpc上的存储和计算服务以及hpc调度器
步骤三:修改步骤二对应的服务的配置文件和数据库的配置等
步骤四:docker-compose up -d启动所有服务
步骤五:Jenkins自动化执行测试用例流水线配置,解决脚本报错问题
步骤六:配置Jenkins自动化获取代码覆盖率流水线并运行测试环境
步骤七:通过流水线创建固定文件夹,存放生成的覆盖率HTML文件
步骤八:获取代码覆盖率并不断优化已有代码,提升覆盖率
步骤九:docker-compose down关闭所有服务
一、项目目录结构
/basic用于存放各种基础配置
/code目录下存放仓库代码
/conf目录下存放流水线执行需要的各种配置文件
/data目录下用于存放storage数据
/project-root项目目录下存放各个服务,每个服务单独目录下存放
/portainer目录下存放相关配置,用于单独起一个可视化界面
/tools目录下存放需要的工具
二、docker-compose启动微型集群
上面的项目目录结构已经非常清晰啦~
1./compose/basic目录下的docker-compose.yml文件内容
version: '3.0'
services:
mysql:
image: mysql:5.7
container_name: mysql_compose
ports:
- "33306:3306"
environment:
MYSQL_DATABASE: 'mydatabase'
MYSQL_USER: 'mysql'
MYSQL_PASSWORD: 'mysql123'
MYSQL_ROOT_PASSWORD: 'rootmysql'
volumes:
- mysql_data:/var/lib/mysql
redis:
image: "redis:alpine"
container_name: redis_compose
ports:
- "6379:6379"
volumes:
- redis_data:/data
etcd:
image: quay.io/coreos/etcd:v3.4.15
container_name: etcd_compose
environment:
ETCDCTL_API: "3"
command:
- /usr/local/bin/etcd
- --data-dir=/etcd-data
- --name=node1
- --initial-advertise-peer-urls=http://0.0.0.0:2380
- --listen-peer-urls=http://0.0.0.0:2380
- --advertise-client-urls=http://0.0.0.0:2379
- --listen-client-urls=http://0.0.0.0:2379
- --initial-cluster=node1=http://0.0.0.0:2380
ports:
- "2379:2379"
- "2380:2380"
volumes:
- etcd_data:/etcd-data
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.14.0
container_name: elasticsearch
environment:
- discovery.type=single-node
ports:
- "9200:9200"
kibana:
image: docker.elastic.co/kibana/kibana:7.14.0
container_name: kibana
ports:
- "5601:5601"
depends_on:
- elasticsearch
apm-server:
image: docker.elastic.co/apm/apm-server:7.14.0
container_name: apm-server
depends_on:
- elasticsearch
ports:
- "8200:8200"
environment:
- output.elasticsearch.hosts=["elasticsearch:9200"]
zookeeper:
image: 'bitnami/zookeeper:latest'
container_name: zookeeper
ports:
- '2181:2181'
environment:
- ALLOW_ANONYMOUS_LOGIN=yes
kafka:
image: 'bitnami/kafka:latest'
container_name: kafka
ports:
- '9092:9092'
environment:
- KAFKA_BROKER_ID=1
- KAFKA_LISTENERS=PLAINTEXT://:9092
- KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092
- KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
- ALLOW_PLAINTEXT_LISTENER=yes
depends_on:
- zookeeper
volumes:
mysql_data: {}
redis_data: {}
etcd_data: {}
配置了需要用到的各个基础服务,这部分可以直接使用哦~
启动镜像:
docker-compose up -d
启动成功后可以验证是否连通
比如验证mysql,本地连接:输入地址为:你的linux机器的IP地址,输入端口:33306(正常可以使用3306端口,由于小编的linux机器上已经有同事起了一个mysql镜像,3306端口已被占用,改为了33306),输入root用户、密码
2./compose/project-root目录下的docker-compose.yml文件内容
涉及到安全性问题,就简单给出其中一个服务的例子~
比如:job服务
job:
image: job-image #这里我直接用的公司已有的镜像,当然也可以自己build
container_name: job
ports:
- "8894:8899"
- "11214:11211"
restart: always
volumes:
- /home/jenkins/compose/project-root/internal/job/config:/workspace/job/config
environment:
YS_ENV: "test"
LOG_LVL: "debug"
接下来配置好job服务后,可以看到配置的卷映射的地址,切换到具体的目录下,修改里面的配置文件:test.yml和test_custom.yml
mysql:
default:
_startup: true
dsn: "root:rootmysql@tcp(linux机器IP地址:33306)/project_root?charset=utf8"
redis:
default:
_startup: true
addr: linux机器IP地址:6379
etcd:
startup: false
endpoints: ["linux机器IP地址:2379"]
tls: false
apm:
apm_server_url: "http://linux机器IP地址:8200"
上述是配置文件修改的部分内容,其他涉及公司业务不显示,但是逻辑是一样的哦~
配置成功后启动镜像:
docker-compose up -d
上述job服务拉取镜像时提到也可以自己build,那么如何build一个go服务呢?
步骤一、编写Dockerfile文件
# 基础镜像
FROM golang:1.16 as builder
# 设置工作目录
WORKDIR /app
# 复制go module文件
COPY go.mod .
COPY go.sum .
# 下载依赖
RUN go mod download
# 复制项目文件
COPY . .
# 构建你的应用
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o myapp .
# 最终镜像
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
# 从构建者阶段复制已编译的app到当前目录
COPY --from=builder /app/myapp .
# 运行时候的命令
CMD ["./myapp"]
步骤二:编写docker-compose.yml
version: '3.8'
services:
webapp:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080" # 将容器中的8080端口映射到宿主机的8080端口
environment:
- GIN_MODE=release # 设置 Golang 应用的环境变量(如果需要)
步骤三:运行docker-compose
在 docker-compose.yml
文件所在的目录下,运行以下命令启动你的服务
docker-compose up --build
--build
选项表示 docker-compose 需要先构建(或重建)镜像。如果没有修改Dockerfile或不需要重新构建镜像,下次启动可以直接运行 docker-compose up
三、portainer配置可视化界面
查看/compose/portainer目录下的docker-compose.yml文件
version: '3.0'
services:
portainer:
image: 6053537/portainer-ce
restart: always
container_name: portainer
ports:
- "8000:8000"
- "9001:9000"
- "9443:9443"
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
- "portainer_data:/data"
volumes:
portainer_data:
配置成功后启动镜像:
docker-compose up -d
启动成功后,通过浏览器打开:http://linux机器的IP地址:9001,可打开可视化界面,首先设置登录用户名和密码,设置成功后,可看到具体界面。
上述的界面可看作是docker-compos命令行的可视化界面,是轻量级的,请尽情的探索吧~
每个服务之间可能有依赖关系,在启动过程中遇到的问题,大概率就是配置不正确导致的,具体问题具体解决~
四、执行测试用例获取测试覆盖率
我们项目目前是用go语言,采用goc来获取代码覆盖率。
在前面的步骤中已经部署了相应的Go服务,还需要部署Goc server,并确保goc server和其他Go服务在同一网络中,这样他们之间才可以互相通信。
编写docker-compose.yml文件
version: '3'
services:
goc-server:
image: your-goc-server-image
ports:
- "7777:7777" # 确保端口映射匹配你希望goc server监听的端口
networks:
- goc-network
go-service:
build: .
command: sh -c "goc build ./... && ./your-service-binary"
ports:
- "8080:8080"
networks:
- goc-network
environment:
- GOC_SERVER_ADDRESS=goc-server:7777
networks:
goc-network:
driver: bridge
可根据项目具体替换your-service-binary
为你的服务二进制文件名,替换your-goc-server-image
为你的goc
服务器Docker镜像。确保GOC_SERVER_ADDRESS
环境变量指向goc-server
服务。也可以直接在本地goc build ,将构建成功后的二进制文件传到docker-compose集群中。
拿job服务举例:
步骤1:切换到包含main.go的job服务目录下
cd /home/jenkins/compose/code/project-root/cmd/job
步骤2: 执行命令,使用agentport参数确定端口,生成job二进制文件
CGO_ENABLED=0 goc build --center=http://服务IP:port --agentport :12321 .
步骤3:切换到compose对应的job服务目录
cd /home/jenkins/compose/project-root/internal/job
步骤4:复制job二进制文件
cp ../../../code/project-root/cmd/job/job ./
步骤5: 编写Dockerfile
vim Dockerfile
FROM alpine-with-bash
#设置工作目录
WORKDIR /home/job
#复制
COPY ./job /home/job
COPY ./config /home/job/config
# 确保二进制文件可执行
RUN chmod +x /home/job/job
ENV YS_ENV=test
# 当容器启动时运行应用
CMD ["./job"]
步骤6: 构建job服务镜像
docker build -t job-test .
步骤7: 在容器内运行镜像
docker run -it job-test:latest /bin/bash
步骤8:修改之前的compose/project-root/docker-compose.yml文件内容
version: '3.0'
services:
job:
image: job-test:latest
container_name: job
ports:
- "8894:8899"
- "11214:11211"
- "12321:12321" #构建job时的端口,在这里暴露出来
restart: always
volumes:
- /home/jenkins/compose/project-root/internal/job/config:/home/job/config
environment:
YS_ENV: "test"
LOG_LVL: "debug"
GOC_SERVER_ADDRESS: "http://goc-server:7777"
depends_on:
- goc-server # 确保启动顺序
goc-server:
image: goc-server:latest
container_name: goc-server
ports:
- "7788:7777"
restart: always
command: ["sh", "-c", "go install github.com/qiniu/goc@latest && goc server"]
volumes:
- /home/jenkins/compose/code/project-root:/go/src/project-root
working_dir: /go/src/project-root
environment:
- GO111MODULE=on
步骤9:登录9001端口进入到portainer可视化界面,也可以直接进入到goc-server中运行
也可以通过命令进入到容器内的交互界面:
docker exec -it goc-server bash
进入到goc server容器中,将已有的其他Go服务注册进去
goc register -a 服务所在地址 -n 服务名
执行测试:
在Go服务运行时,执行测试。若是手动测试,直接访问服务;若是自动化测试,运行自动化测试脚本。
收集测试覆盖率数据:
收集测试覆盖率:
goc profile --service SERVICE_NAME -o coverage.out
goc profile -o coverage.out
生成覆盖率报告:
go tool cover -html=coverage.out -o coverage.html
gocov convert coverage.out |gocov-html >coverage.html
可查看goc-server服务的日志,可看到列出、注册、获取覆盖率都成功啦~
停止服务:
docker-compose down
五、Jenkins日常发布测试用例&服务
通过上述步骤已经能获取到覆盖率了,但是每次手工执行肯定是比较浪费人力物力的,可通过创建Jenkins流水线实现日常执行测试用例,可实现服务日常发布。
自动化实现测试用例执行这里就不讲解了,每个公司有具体的流水线。
这里简单看一下测试用例自动化执行的流水线:
接下来详细讲解下获取覆盖率的流水线,大概配置如下:
构建选项参数:SERVICE_NAME、MODULE_NAME、PRIORITY
编写jenkins的shell脚本,内容如下:
#!/bin/bash
GOC_SERVER_ADDRESS="goc-server:7788"
export GOC_SERVER_ADDRESS
TestURL="ssh://vcssh@git测试库地址.git"
repoPath="/var/jenkins_work/workspace/${JOB_NAME}/${BUILD_ID}"
ProjectPath="/home/jenkins/compose/code/project-root"
ComposePath="/home/jenkins/compose/project-root"
cov_file="${SERVICE_NAME}_TestCoverage.out"
cov_html="${SERVICE_NAME}_TestCoverage.html"
git clone $TestURL $repoPath
cd $repoPath
cp /home/jenkins/compose/conf/.env ${repoPath}/test
cp /home/jenkins/compose/conf/.env.storage ${repoPath}/test/storage/v1/.env
go mod tidy
#执行测试用例
cd $repoPath
go test -v -timeout 30m ./test/$MODULE_NAME/... -run="^Test"+"/Test"+$PRIORITY
# 由于在Jenkins非交互式环境,移除-it参数用来运行docker exec
docker exec goc-server bash -c "goc list"
# 清除存量覆盖率数据
docker exec goc-server bash -c "goc clear --address=$GOC_SERVER_ADDRESS"
# 收集覆盖率数据
docker exec goc-server bash -c "goc profile --service $SERVICE_NAME -o ${cov_file}"
docker exec goc-server bash -c "go tool cover -func=${cov_file}"
# 生成代码覆盖率报告
docker exec goc-server bash -c "gocov convert ${cov_file} | gocov-html > ${cov_html}"
cd ${repoPath}
# 创建存放覆盖率报告的目录
mkdir -p TestCoverage
# 确保已将报告文件从 docker 容器复制到指定目录
docker cp goc-server:/go/src/project-root/${cov_file} TestCoverage/
docker cp goc-server:/go/src/project-root/${cov_html} TestCoverage/
添加构建后操作:选择Publish HTML reports,配置相关参数如下:
如果想知道每次构建的具体情况,也可以添加构建后操作:企业微信通知
执行此流水线,最后就可以看到覆盖率文件了,在浏览器中打开~
六、问题描述及解决方式
问题1:
go tool cover -func=test.out
问题描述:执行上述命令时报错没有go.mod
解决方式:需将工作目录设置在project-root项目根目录下,问题解决
问题2:
goc profile --service job -o test.out
gocov convert test.out |gocov-html >test.html
问题描述:执行上述命令时提示:gocov、gocov-html不存在,需要安装
解决方式:在之前的Dockerfile中加入以下命令并重新打镜像
RUN go install github.com/axw/gocov/gocov@latest
RUN go install github.com/AlekSi/gocov-xml@latest
RUN go install github.com/matm/gocov-html@latest
问题3:
问题描述:获取到test.out和test.html文件后,想复制到本地通过浏览器打开
解决方式:
1.在本地新建/job文件夹
2.打开本机终端,切换目录到C:/Users/admin/Desktop/job/
3.执行命令:
scp username@服务IP:项目目录/test.html .
4.文件复制成功,可通过浏览器打开查看
问题4:
问题描述:
收集覆盖率时遇到报错:FATA Goc server http://linux机器:7788 return an error: {"error":"no profiles"}
查看goc-server服务日志报错:[GIN] 2024/03/29 - 08:21:15 | 417 | 173.303µs | 127.0.0.1 | POST "/v1/cover/profile"
解决方式:后排查到是因为docker-compose没有将镜像build时的端口暴露出来,添加暴露端口后,问题解决,可获取到覆盖率
七、docker基础知识总结
镜像命令:
-
docker images
: 列出本地的所有镜像。 -
docker pull <image-name>
: 从远程仓库拉取镜像到本地。 -
docker build -t <tag> .
: 根据当前目录的Dockerfile构建一个新镜像。 -
docker rmi <image-id>
: 删除一个镜像。
容器命令:
-
docker ps
: 列出正在运行的容器。 -
docker ps -a
: 列出所有容器,无论状态。 -
docker run <image-name>
: 基于一个镜像创建并启动一个新容器。 -
docker stop <container-id>
: 停止一个容器。 -
docker start <container-id>
: 启动一个已经停止的容器。 -
docker restart <container-id>
: 重启容器。 -
docker rm <container-id>
: 删除一个已经停止的容器。 -
docker exec -it <container-id> /bin/bash
: 进入正在运行的容器内部。
网络命令:
-
docker network ls
: 列出所有的网络。 -
docker network create <network-name>
: 创建一个新的网络。 -
docker network rm <network-name>
: 删除一个网络。
卷命令:
-
docker volume ls
: 列出所有的卷。 -
docker volume create <volume-name>
: 创建一个新的卷。 -
docker volume rm <volume-name>
: 删除一个卷。
日志和进程查看命令:
-
docker logs <container-id>
: 查看容器的输出日志。 -
docker top <container-id>
: 查看容器内的进程信息。
系统命令:
-
docker system df
: 显示 Docker 使用的磁盘空间。 -
docker system prune
: 清理未使用的网络、挂载、镜像和构建缓存。
Docker Compose命令:
docker-compose up
: 启动并运行整个应用。使用-d
标志来后台运行服务。docker-compose down
: 停止并移除所有由docker-compose up
创建的资源,包括网络、容器、卷。docker-compose start
: 启动已经存在的容器。docker-compose stop
: 停止已经运行的服务,不移除容器。docker-compose restart
: 重启服务。docker-compose build
: 构建或重建服务关联的镜像。docker-compose pull
: 拉取服务依赖的镜像。docker-compose push
: 推送服务镜像到镜像仓库。docker-compose logs
: 查看服务的日志输出。使用-f
来跟踪实时日志。docker-compose exec
: 在运行的服务容器中执行命令。docker-compose run
: 运行一个一次性命令。例如:运行一个脚本或者执行一个服务的管理命令。docker-compose ps
: 列出项目中目前的所有容器。docker-compose config
: 验证并查看配置文件的内容。docker-compose rm
: 删除所有(或指定的)停止状态的服务容器。docker-compose top
: 显示运行中的服务容器中的进程。docker-compose pause
: 暂停服务容器。docker-compose unpause
: 恢复服务容器。