docker参考
docker-compose参考
选择安装版本,以 linux 的 centos 为例访问docker官网 、点击docker for linux:
选择centos版本
先决条件:要安装Docker Engine,您需要一个CentOS 7的维护版本。不支持或未测试存档版本
卸载旧版本
$ sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
如果yum
报告未安装这些软件包, 说明无需关注、可以直接走下一步安装。
设置存储库:首次安装Docker Engine之前,需要设置Docker存储库
安装yum-utils
软件包(提供yum-config-manager
实用程序)并设置稳定的存储库
$ sudo yum install -y yum-utils
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
安装docker引擎,我们这里安装最新版, 需要特定版本可参考官网
$ sudo yum install docker-ce docker-ce-cli containerd.io
启动Docker
$ sudo systemctl start docker
通过运行hello-world
映像来验证是否正确安装了Docker Engine
sudo docker run hello-world
会输出hello word信息 即代表成功。
设置docker开启自启动
# 允许开机启动
$ sudo systemctl enable docker
# 状态检查
$ sudo systemctl status docker
前提条件:Docker Compose依靠Docker Engine进行有意义的工作,请确保有安装Docker Engine
安装版本选择
直接使用crul方式安装 卸载方便
sudo curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
给docker-compose添加可执行权限
sudo chmod +x /usr/local/bin/docker-compose
卸载:(通过curl方式安装卸载)
sudo rm /usr/local/bin/docker-compose
version: "2"
services:
runner:
image: gitlab/gitlab-runner:latest
container_name: gitlab-runner
restart: always
environment:
TZ: Asia/Shanghai
volumes:
- /docker/gitlab-runner/config:/etc/gitlab-runner
- /var/run/docker.sock:/var/run/docker.sock
注意:如果runner executor 为docker 、必须挂载 /var/run/docker.sock:/var/run/docker.sock
配置runner参考
example
安装前准备
mkdir /root/docker
将上述docker-compose.yaml文件拷贝到/root/docker目录下
运行gitlab-runner
docker-compose up -d
查看日志
docker logs gitlab-runner
注册gitlab-runner到gitlab、先查看gitlabrunner 的token
获取token和注册需要的域名或者ip都可
注册gitlab-runner
$ docker exec -it gitlab-runner gitlab-runner register
Runtime platform arch=amd64 os=linux pid=35 revision=ce065b93 version=12.10.1
Running in system-mode.
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
# https://gitlab.com # 你的gitlab的域名或ip
Please enter the gitlab-ci token for this runner:
# 89Gz************ # 上面从项目中获取的token值
Please enter the gitlab-ci description for this runner:
[9e4cbb00ddf2]: # my-runner # 自定义的runner描述
Please enter the gitlab-ci tags for this runner (comma separated):
# demo # 自定义的tag ci可以根据tag执行任务,可在ci中设置 默认启用tag 如果任务未添加tag 会pending
Registering runner... succeeded runner=89GziSKQ
Please enter the executor: docker, docker-ssh, shell, kubernetes, docker+machine, docker-ssh+machine, custom, parallels, ssh, virtualbox:
# docker # 选择executor类型 这里采用docker
Please enter the default Docker image (e.g. ruby:2.6):
# golang:1.14.2 # 默认的镜像 因为是go所以选择go的
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
再次查看日志 现在未继续报错了
Configuration loaded builds=0
gitlab-runner设置
如果允许未设置tag的任务运行 需要在runner里面设置
允许没有tag的任务运行、否则没有tag的任务会 进入pending 状态
配置文件路径 与在yaml文件路径下 /docker/gitlab-runner/config/config.toml
# cat config.toml
concurrent = 1
check_interval = 0
[session_server]
session_timeout = 1800
[[runners]]
name = "my-runner"
url = "https://gitlab.****.com"
token = "dWza**********"
executor = "docker"
[runners.custom_build_dir]
[runners.cache]
[runners.cache.s3]
[runners.cache.gcs]
[runners.docker]
tls_verify = false
image = "golang:1.14.2"
privileged = false
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache", "/root/docker/gitlab-runner/gztar/.tar:/root/.tar","/root/.ssh:/root/.ssh:ro"]
pull_policy = "if-not-present"
shm_size = 0
这里volumes挂载了cache目录以及设置了默认拉取的镜像文件
# 配置从本地获取镜像 加快ci & cd速度
volumes = ["/root/docker/gitlab-runner/gztar/.tar:/root/.tar"]
# 会首先从本地获取镜像 本地没有才会从hub上拉取镜像
pull_policy = "if-not-present"
# --------------
# 可选 映射本机的秘钥到docker里面的docker里面、 可用于ssh 部署之类
volumes = ["/root/.ssh:/root/.ssh:ro"] # ro只读 不允许修改宿主机的秘钥信息
ssh部署可参考
gitlab-yaml
注意:
url = "https://gitlab.****.com" # gitlab的地址
token = "dWza**********" # gitlab的token
附:docker镜像导入导出命令
# 导出镜像
docker save -o /root/docker/gitlab-runner/gztar/golang.tar golang:latest
# 导入镜像
docker load -i /root/docker/gitlab-runner/gztar/golang.tar
# 另外一种方式
docker save golang:latest > /root/docker/gitlab-runner/gztar/golang.tar
docker load < /root/docker/gitlab-runner/gztar/golang.tar
config.toml
文件的check_interval
字段会决定这个时间间隔,它的默认值是3秒(注意当你把它设为0时依然采用的是默认值3秒,而不是0秒)
要解释它的意义,首先我们先来定义worker,在config.toml
文件中定义了很多runner,它们可能executor类型不同,可能注册地址不同,但都是由GitLab Runner这个服务来管理的,为了与GitLab Runner区分开,我们将config.toml
文件中定义的runner称为worker。
对于不同的worker,worker之间(如worker A ---> worker B)的间隔为check_interval / worker_nums,但是对于worker A本身来说它下次去检查是否有job的时间间隔仍为check_interval
。
举个简单例子:config.toml
定义了3个worker—— worker A, worker B 和 worker C,check_interval
采用默认值为3秒,第0秒时worker A会去检查是否有属于自己的job,第1秒时worker B会去检查,第2秒时worker C去检查,第3秒时worker A再检查……这个过程中worker A到worker B的间隔为3 / 3 = 1秒,而对于worker A下次检查job时的时间间隔为check_interval
,即3秒。
官方文档对check_interval
的解释:https://docs.gitlab.com/runner/configuration/advanced-configuration.html#how-check_interval-works。
config.toml
里的concurrent
字段的意义concurrent
限制了整个GitLab Runner能并发处理job的数量。特别注意concurrent
与worker数量无任何关系,所有worker的工作是受GitLab Runner控制的,如果concurrent
值为1并且有一个worker已经在工作了,那么即使其他worker达到了可以工作的条件也只能“pending”。
参考https://docs.gitlab.com/ee/ci/caching/#where-the-caches-are-stored
注意cache是没有过期时间的,而且每一次新的push触发的pipeline,都会重新生成cache,重新生成的cache的名字为“-”,其中num是随着push数量递增的。如果不去清除cache,cache会永久保留在Runner上,日积月累会填满存储空间的,因此最好隔一段时间进行一次清除,清除方法请参考https://docs.gitlab.com/ee/ci/caching/#clearing-the-cache,或者使用clear_volumes.sh 这个简单脚本来处理它, 清除cache的原理是将相关的volume移除,当然,docker也有自带的清除命令,推荐将docker system prune -f --volumes
加入到定时任务中。
参考https://docs.gitlab.com/ee/ci/variables/#priority-of-environment-variables
参考https://docs.gitlab.com/ee/ci/variables/#predefined-variables-environment-variables
这是个dind(docker in docker)
问题,一般pipeline会报如下错误:
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
time="2018-12-17T11:12:33Z" level=error msg="failed to dial gRPC: cannot connect to the Docker daemon. Is 'docker daemon' running on this host?: dial unix
可以将本地的docker socket绑定到container里来解决
在配置文件config.toml
里添加volumes = ["/var/run/docker.sock:/var/run/docker.sock"]
可参考https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-in-docker-executor。
git clone
命令如果想在job运行期间clone代码(如shell或python的脚本),首先要确保你的宿主机有权限clone代码,然后将将你的secret挂载到container里。
例如,通过git/ssh的方式克隆代码,若ssh目录为/root/.ssh
,可以在config.toml
文件里添加如下配置:
volumes = ["/root/.ssh:/root/.ssh:ro"]
ro表示容器只有可读权限 避免修改秘钥。
名称 | 说明 |
---|---|
$CI_PROJECT_NAME | 项目名称 |
$CI_PROJECT_NAMESPACE | 组名称 |
$CI_PROJECT_PATH | 项目相对路径 |
$CI_PROJECT_URL | 项目URL地址 |
$GITLAB_USER_NAME | 用户名称 |
$GITLAB_USER_EMAIL | 用户邮箱 |
$CI_PROJECT_DIR | 项目绝对路径 |
$CI_PIPELINE_ID | 流水线ID |
$CI_COMMIT_REF_NAME | 当前分支 |
通过Makefile简单集成单元测试 覆盖率测试 及覆盖率报告
.PHONY: clean test coverage coverhtml build help lint
PROJECT_NAME := "code"
PKG_LIST := $(shell go list ./... | grep -v /vendor/)
all: build
test: ## Run unittests
@go test -v ${PKG_LIST}
race: ## Run data race detector
@go test -race -short ${PKG_LIST}
coverage: ## Generate global code coverage report
coverage_test
coverhtml: ## Generate global code coverage report in HTML
coverage_test html
build: ## Build the binary file
@go build -i -v -o _${PROJECT_NAME} ./...
lint: ## Lint the files
@golint -set_exit_status ${PKG_LIST}
clean:
rm -rf _${PKG_LIST}
help: ## Display this help screen
@grep -h -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'
SHELL=bash
define BASH_FUNC_coverage_test%%
() {
# Code coverage generation
COVERAGE_DIR="${COVERAGE_DIR:-coverage}"
# Create the coverage files directory
mkdir -p "$COVERAGE_DIR";
# Create a coverage file for each package
for package in ${PKG_LIST}; do
go test -covermode=count -coverprofile "./${COVERAGE_DIR}/${package##*/}.cov" "$$package" ;
done ;
# Merge the coverage profile files
echo 'mode: count' > "./${COVERAGE_DIR}"/coverage.cov ;
tail -q -n +2 "./${COVERAGE_DIR}"/*.cov >> "./${COVERAGE_DIR}"/coverage.cov ;
# Display the global code coverage
go tool cover -func="./${COVERAGE_DIR}"/coverage.cov ;
# If needed, generate HTML report
if [ "$1" == "html" ]; then
go tool cover -html="./${COVERAGE_DIR}"/coverage.cov -o coverage.html ;
fi
# Remove the coverage files directory
rm -rf "$COVERAGE_DIR";
}
endef
export BASH_FUNC_coverage_test%%
image: golang:1.14.2
variables:
PROJECT_NAME: "_code"
DEV_HOST: "测试机器ip"
DEV_PATH: "部署路径"
PRD_HOST: "线上机器ip"
PRD_PATH: "部署路径"
stages:
- test
- build
- deploy
before_script:
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- eval $(ssh-agent -s)
- mkdir -p /go/src/$GITLAB_USER_NAME /go/src/_/builds
- cp -r $CI_PROJECT_DIR /go/src/$GITLAB_USER_NAME/$CI_PROJECT_NAME
- ln -s /go/src/$GITLAB_USER_NAME /go/src/_/builds/$GITLAB_USER_NAME
unit_tests:
stage: test
script:
- make test
tags:
- demo
race_detector:
stage: test
script:
- make race
code_coverage:
stage: test
script:
- make coverage
code_coverage_report:
stage: test
script:
- make coverhtml
only:
- master
build:dev:
stage: build
script:
- go build -i -v -o ${PROJECT_NAME} ./...
artifacts:
expire_in: 1 week
paths:
- $PROJECT_NAME
only:
- dev
build:master:
stage: build
script:
- go build -i -v -o ${PROJECT_NAME} ./...
artifacts:
expire_in: 1 week
paths:
- $PROJECT_NAME
only:
- master
deploy:dev:
stage: deploy
script:
- echo "=====start dev deploy======"
- scp -r $PROJECT_NAME root@$DEV_HOST:$DEV_PATH
- ssh root@$DEV_HOST "cd $DEV_PATH; ./$PROJECT_NAME >> dev.log"
- echo "=====end dev deploy======"
only:
- dev
when: manual
environment: test
dependencies:
- build:dev
deploy:master:
stage: deploy
script:
- echo "=====start deploy======"
- scp -r $PROJECTNAME root@$DEV_HOST:$DEV_PATH
- ssh root@$DEV_HOST "cd $DEV_PATH; ./$PROJECT_NAME >> master_test.log"
- echo "=====end deploy======"
only:
- master
when: manual
environment: production
dependencies:
- build:master
验证.gitlab-ci.yml文件的内容:进入项目仓库->CI/CD->作业->CI Lint,示例如下: