快速、可预测地部署服务
拥有即时扩展服务的能力
滚动升级,完成新功能发布
优化硬件资源,降低成本
Pipeline:Gitlab CI 里的流水线,每一次代码的提交触发 GitLab CI 都会产生一个 Pipeline。
Stage:每个 Pipeline 由多个 Stage 组成,并且每个 Stage 是有先后顺序的。
Job:GitLab CI 里的最小任务单元,负责完成具有一件事情,例如编译、测试、构建镜像等。每个 Job 都需要指定 Stage ,所以 Job 的执行顺序可以通过制定不同的 Stage 来实现。
GitLab Runner:是具体执行 Job 的环境,每个 Runner 在同一时间只能执行一个 Job。
Executor:每个 Runner 在向 GitLab 注册的时候需要指定 Executor,来决定通过何种类型的执行器来完成 Job。
shared:所有项目使用
group:group下项目使用
specific:指定项目使用
yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install docker-ce -y
systemctl start docker
systemctl enable docker
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
sudo yum install gitlab-runner -y
gitlab-runner start
gitlab-runner register --non-interactive \
--url "http://git.xxxx.cn" \
--registration-token "xxxxxxxxxxx" \
--executor "docker" \
--docker-image alpine:latest \
--description "base-runner-docker" \
--tag-list "base-runner" \
--run-untagged="true" \
--docker-privileged="true" \
--docker-pull-policy "if-not-present" \
--docker-volumes /etc/docker/daemon.json:/etc/docker/daemon.json \
--docker-volumes /etc/gitlab-runner/key/docker-config.json:/root/.docker/config.json \
--docker-volumes /etc/gitlab-runner/find_diff_files:/usr/bin/find_diff_files \
--docker-volumes /etc/gitlab-runner/key/id_rsa:/root/.ssh/id_rsa \
--docker-volumes /etc/gitlab-runner/key/test-kube-config:/root/.kube/config
{ "insecure-registries" : ["http://docker.vpgame.cn"] }
gitlab-runner restart
按照一定规则自动构建镜像,可以快速便捷地新建和更新镜像
根据规则可以找到镜像对应的 Dockerfile,明确镜像的具体组成
团队成员可以通过提交 Merge Request 自由地构建自己需要的镜像
运行时基础镜像:提供各个语言运行时必须的工具和相应的 package。
CI 镜像:基于运行时基础镜像,添加单元测试、lint、静态分析等功能,用在 CI/CD 流程中的 test 环节。
打包上线镜像:用在 CI/CD 流程中的 build 和 deploy 环节。
php/
├── 1.0
│ ├── Dockerfile
│ ├── ci-1.0
│ │ └── Dockerfile
│ ├── php.ini
│ ├── read-zk-config
│ ├── start_service.sh
│ └── www.conf
└── nginx
├── Dockerfile
├── api.vpgame.com.conf
└── nginx.conf
FROM php:7.1.16-fpm-alpine3.4
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories\
&& apk upgrade --update && apk add --no-cache --virtual build-dependencies $PHPIZE_DEPS \
tzdata postgresql-dev libxml2-dev libmcrypt libmcrypt-dev libmemcached-dev cyrus-sasl-dev autoconf \
&& apk add --no-cache freetype libpng libjpeg-turbo freetype-dev libpng-dev libjpeg-turbo-dev libmemcached-dev \
&& cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone \
&& docker-php-ext-configure gd \
--with-gd \
--with-freetype-dir=/usr/include/ \
--with-png-dir=/usr/include/ \
--with-jpeg-dir=/usr/include/ \
&& docker-php-ext-install gd pdo pdo_mysql bcmath opcache \
&& pecl install memcached apcu redis \
&& docker-php-ext-enable memcached apcu redis \
&& apk del build-dependencies \
&& apk del tzdata \
&& rm -rf /var/cache/apk/* \
&& rm -rf /tmp/* \
&& rm -rf /working/* \
&& rm -rf /usr/local/etc/php-fpm.d/*
COPY start_service.sh /usr/local/bin/start_service.sh
COPY read-zk-config /usr/local/bin/read-zk-config
COPY php.ini /usr/local/etc/php/php.ini
COPY www.conf /usr/local/etc/php-fpm.d/www.conf
WORKDIR /work
CMD ["start_service.sh"]
FROM docker.vpgame.cn/infra/php-1.0
ENV PATH="/root/.composer/vendor/bin:${PATH}"
ENV COMPOSER_ALLOW_SUPERUSER=1
RUN mkdir -p /etc/ssh && echo "StrictHostKeyChecking no" >> /etc/ssh/ssh_config
RUN apk --update add --no-cache make libc-dev autoconf gcc openssh-client git bash &&\
echo "apc.enable_cli=1" >> /usr/local/etc/php/conf.d/docker-php-ext-apcu.ini
RUN pecl install xdebug && docker-php-ext-enable xdebug &&\
echo -e "\nzend_extension=xdebug.so" >> /usr/local/etc/php/php.ini
RUN wget https://vp-infra.oss-cn-beijing.aliyuncs.com/gitlab-ci/software/download/1.6.5/composer.phar -O /bin/composer && \
chmod +x /bin/composer && \
composer config -g -q repo.packagist composer https://packagist.laravel-china.org
RUN composer global require -q phpunit/phpunit:~5.0 squizlabs/php_codesniffer:~3.0
WORKDIR /
CMD ["/bin/bash"]
for FILE in `bash ./find_diff_files|grep Dockerfile|sort`;
do
DIR=`dirname "$FILE"`;
IMAGE_NAME=`echo $DIR | sed -e 's/\//-/g'`;
echo $CI_REGISTRY/$HARBOR_DIR/$IMAGE_NAME;
docker build -t $CI_REGISTRY/$HARBOR_DIR/$IMAGE_NAME -f $FILE $DIR;
docker push $CI_REGISTRY/$HARBOR_DIR/$IMAGE_NAME;
done
Alpine Linux Package Management(APK)镜像地址:http://mirrors.aliyun.com
一些海外软件下载会比较慢,可以先下载下来上传至阿里云 OSS 后下载。Dockerfile 使用阿里云 OSS 作为下载源,减少构建镜像时间。
stages:
- build
- test
- deploy
首先,所有 build 里的 Job 会并行执行;
当 build 里所有 Job 执行成功, test 里所有 Job 会并行执行;
如果 test 里所有 Job 执行成功, deploy 里所有 Job 会并行执行;
如果 deploy 里所有 Job 执行成功, 当前 Pipeline 会被标记为 passed;
当某个 stage 的 Job 执行失败, Pipeline 会标记为为 failed,其后续stage 的 Job 都不会被执行。
unittest:
stage: test
image: docker.vpgame.cn/infra/php-1.0-ci-1.1
services:
- name: docker.vpgame.cn/infra/mysql-5.6-multi
alias: mysql
- name: redis:4.0
alias: redis_default
script:
- mv .env.tp .env
- composer install --no-dev
- phpunit -v --coverage-text --colors=never --coverage-html=coverage --stderr
artifacts:
when: on_success
paths:
- vendor/
- coverage/
expire_in: 1 hour
coverage: '/^\s*Lines:\s*\d+.\d+\%/'
only:
- branches
- tags
tags:
- base-runner
dependencies:
- unittest
job:
only:
- /^issue-.*$/
except:
- branches
# Build stage
.build-op:
stage: build
dependencies:
- unittest
image: docker.vpgame.cn/infra/docker-kubectl-1.0
services:
- name: docker:dind
entrypoint: ["dockerd-entrypoint.sh"]
script:
- echo "Image name:" ${DOCKER_IMAGE_NAME}
- docker build -t ${DOCKER_IMAGE_NAME} .
- docker push ${DOCKER_IMAGE_NAME}
tags:
- base-runner
build-test:
extends: .build-op
variables:
DOCKER_IMAGE_NAME: ${DOCKER_REGISTRY_PREFIX}/${CI_PROJECT_PATH}:${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHORT_SHA}
only:
- /^testing/
- master
build-prod:
extends: .build-op
variables:
DOCKER_IMAGE_NAME: ${DOCKER_REGISTRY_PREFIX}/${CI_PROJECT_PATH}:${CI_COMMIT_TAG}
only:
- tags
# Deploy stage
.deploy-op:
stage: deploy
image: docker.vpgame.cn/infra/docker-kubectl-1.0
script:
- echo "Image name:" ${DOCKER_IMAGE_NAME}
- echo ${APP_NAME}
- sed -i "s~__NAMESPACE__~${NAMESPACE}~g" deployment.yml service.yml
- sed -i "s~__APP_NAME__~${APP_NAME}~g" deployment.yml service.yml
- sed -i "s~__PROJECT_NAME__~${CI_PROJECT_NAME}~g" deployment.yml
- sed -i "s~__PROJECT_NAMESPACE__~${CI_PROJECT_NAMESPACE}~g" deployment.yml
- sed -i "s~__GROUP_NAME__~${GROUP_NAME}~g" deployment.yml
- sed -i "s~__VERSION__~${VERSION}~g" deployment.yml
- sed -i "s~__REPLICAS__~${REPLICAS}~g" deployment.yml
- kubectl apply -f deployment.yml
- kubectl apply -f service.yml
- kubectl rollout status -f deployment.yml
- kubectl get all,ing -l app=${APP_NAME} -n $NAMESPACE
# Deploy test environment
deploy-test:
variables:
REPLICAS: 2
VERSION: ${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHORT_SHA}
extends: .deploy-op
environment:
name: test
url: http://example.com
only:
- /^testing/
- master
tags:
- base-runner
# Deploy prod environment
deploy-prod:
variables:
REPLICAS: 3
VERSION: ${CI_COMMIT_TAG}
extends: .deploy-op
environment:
name: prod
url: http://example.com
only:
- tags
tags:
- pro-deploy
定义 Deployment 来创建 Pod 和 ReplicaSet
滚动升级和回滚应用
扩容和缩容
暂停和继续 Deployment
apiVersion 为当前配置格式的版本
kind 指定了资源类型,这边当然是 Deployment
metadata 是该资源的元数据,其中 name 是必需的数据项,还可以指定 label 给资源加上标签
spec 部分是该 Deployment 的规格说明
spec.replicas 指定了 Pod 的副本数量
spec.template 定义 Pod 的基本信息,通过 spec.template.metadata 和 spec.template.spec 指定
spec.template.metadata 定义 Pod 的元数据。至少需要定义一个 label 用于 Service 识别转发的 Pod, label 是通过 key-value 形式指定的
spec.template.spec 描述 Pod 的规格,此部分定义 Pod 中每一个容器的属性,name 和 image 是必需项
apiVersion: apps/v1beta2
kind: Deployment
metadata:
labels:
app: __APP_NAME__
group: __GROUP_NAME__
name: __APP_NAME__
namespace: __NAMESPACE__
Kubernetes 中运行的 Service 以及 Deployment 名称由 GitLab 中的 groupname 和 projectname 组成,即 {{groupname}}-{{projectname}},例:microservice-common。此名称记为 app_name,作为每个服务在 Kubernetes 中的唯一标识。这些变量可以通过 GitLab-CI 的内置变量中进行获取,无需对每个 project 进行特殊的配置。
Lables 中用于识别服务的标签与 Deployment 名称保持一致,统一设置为 app:{{app_name}}。
...
spec:
...
template:
...
spec:
...
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: group
operator: In
values:
- __GROUP_NAME__
...
...
spec:
...
template:
...
spec:
...
containers:
- name: fpm
livenessProbe:
httpGet:
path: /__PROJECT_NAME__
port: 80
initialDelaySeconds: 3
periodSeconds: 5
readinessProbe:
httpGet:
path: /__PROJECT_NAME__
port: 80
initialDelaySeconds: 3
periodSeconds: 5
...
...
...
spec:
...
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
...
...
spec:
...
template:
...
spec:
...
containers:
- name: fpm
env:
- name: aliyun_logs_vpgame
value: stdout
- name: aliyun_logs_vpgame_tags
value: topic=__APP_NAME__
...
...
...
spec:
...
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "80"
prometheus.io/path: /{{ project_name }}/metrics
...
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/alicloud-loadbalancer-address-type: intranet
labels:
app: __APP_NAME__
name: __APP_NAME__
namespace: __NAMESPACE__
spec:
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: __APP_NAME__
type: LoadBalancer
转载:https://blog.csdn.net/M2l0ZgSsVc7r69eFdTj/article/details/102387428