快速、可预测地部署服务
拥有即时扩展服务的能力
滚动升级,完成新功能发布
优化硬件资源,降低成本
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 源:
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
安装 Docker:
yum install docker-ce -y
启动并加入开机启动:
systemctl start docker
systemctl enable docker
Gitlab runner 安装与启动执行下面的命令进行 GitLab Runner 的安装和启动:
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 注册与配置更新
启动 GitLab Runner 后还需要向 GitLab 进行注册,在注册前需要从 GitLab 里查询 token。不同类型的 Runner 对应的 token 获取的路径不同。shared Runner 需要 admin 权限的账号,按如下方式可以获取对应的 token。
其他两种类型在对应的页面下( group 或 project 主页)的 setting—>CI/CD—>Runner 可以获取到 token。Runner 的注册方式分为交互式和非交互式两种。其中交互式注册方式,在输入 gitlab-runner register 命令后,按照提示输入注册所需要的信息,包括 gitlab url、token 和 Runner 名字等。这边个人比较推荐非交互式命令,可以事先准备好命令,完成一键注册,并且非交互式注册方式提供了更多的注册选项,可以满足更多样化的需求。按如下示例即可完成一个 Runner 的注册:
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
我们可以通过 --docker-pull-policy 指定 Executor 执行 Job 时 Dokcer 镜像下载策略。--docker-volumes 指定容器与宿主机(即 Runner 运行的服务器)的文件挂载映射关系。上面挂载的文件主要是用于 Runner 在执行 Job 时,运用的一些 key,包括访问 GitLab、Docker Harbor 和 Kubernetes 集群的 key。当然,如果还有其他文件需要共享给容器,可以通过 --docker-volumes 去指定。/etc/docker/daemon.json 文件主要为了可以以 http 方式访问 docker horbor 所做的设置:
{ "insecure-registries" : ["http://docker.vpgame.cn"] }
完成注册后,重启 Runner 即可:
gitlab-runner restart
部署完成后,可以在 GitLab 的 Web 管理界面查看到不同 Runner 的信息。
此外,如果一台服务需要注册多个 Runner ,可以修改 /etc/gitlab-runner/config.toml 中的 concurrent 值增加 Runner 的并发数,修改完之后同样需要重启 Runner。Docker 基础镜像制作
为了满足不同服务对运行环境的多样化需求,我们需要为不同语言的服务提前准备不同的基础镜像用于构建镜像阶段使用。此外,CI/CD 所需要的工具镜像也需要制作,作为 Runner 执行 Job 时生成容器所需要的 Docker 镜像。所有的镜像都以编写 Dockerfile 的形式通过 GitLab 进行管理,并且我们编写了 .gitlab-ci.yml 文件,使得每次有 Dockerfile 新增或者修改就会触发 Pipeline 进行镜像的构建并上传到 Harbor 上。这种管理方式有以下优点:
按照一定规则自动构建镜像,可以快速便捷地新建和更新镜像
根据规则可以找到镜像对应的 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
该目录下有一个名为 1.0 的文件夹,里面有一个 Dockerfile 用来构建 php fpm 运行时基础进行镜像。主要是在 php:7.1.16-fpm-alpine3.4 加了我们自己定制化的文件,并指定工作目录和容器初始命令。
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"]
在 1.0/ci-1.0 还有一个 Dockerfile,是用来构建 PHP 在进行单元测试和 lint 操作时所使用的 CI 镜像。可以看到它基于上面的基础运行时镜像增加其他工具来进行构建的。
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"]
另外 Nginx 目录下同样有 Dockerfile,来定制化我们 PHP 项目所需要的 Nginx 镜像。在 GitLab 里第一次增加新的 Dockerfile 或者更改 Dockerfile 时,会触动 Pipeline 自动进行镜像的构建并上传的我们私有的 Docker Harbor 上。
镜像自动构建基本原理由于各个镜像通过 Dockerfile 进行管理, Master 分支有新的合并,可以通过 git diff 命令找出合并前后新增或更新的 Dockerfile,然后根据这些 Dockerfile 依据一定的命名规则构建镜像,并上传到 Docker Harbor 上。
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
上面命令中 finddifffiles 基于 git diff 命令找出合并前后有差异的文件。
加速 tips
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
上面的 Job 主要完成了单元测试的功能,在起始行定义了 Job 的名称。下面我们来解释 Job 每个关键字的具体含义。stage,定义了 Job 所处的 stage,值为定义在全局中 stages 里的值。image,指定了 Runner 运行所需要的镜像,这个镜像是我们之前制作的基本镜像。通过该镜像运行的 Docker 即是 Job 运行的环境。services,Runner 所运行的 Docker 所需要的连接依赖,在这边分别定义了 MySQL 和 Redis,在 Job 运行时会去连接这两个镜像生成的 Docker。script,Job 运行的具体的命令 ,通过 Shell 来描述。此 Job 中的 script 主要完成了代码的编译和单元测试。artifacts,主要是将此 Job 中完成的结果打包保存下来,可以通过 when 指定何时保存,path 定义了保存的文件路径, expire_in 指定了结果保存的有效期。与之对应的是 dependencies 参数,如果其他 Job 需要此 Job 的 artifacts ,只需要在 Job 按照如下定义即可。
dependencies:
- unittest
only 关键字指定了 Job 触发的时机,该例子中说明只有分支合并或者打 tag 的情况下,该 Job 才会被触发。与 only 相对还有 except 关键字来排除触发 Job 某些情况。此外 only 还支持正则表达式,比如:
job:
only:
- /^issue-.*$/
except:
- branches
这个例子中,只有以 issue- 开头 tag 标记才会触发 Job。如果不加 except 参数,以 issue- 开头的分支 或者 tag 标记会会触发 Job。tags,tags关键字主要是用来指定运行的 Runner 类型。在我们实际运用中,部署测试环境和生产环境所采用的 Runner 是不一样的,它们是通过不同的 tag 去标识区分。
所以,我们在 Job 定义中,通过 tags 指定 Runner 的值,来指定所需要的 Runner。我们可以看到 Job 的定义非常的清晰和灵活,关于 Job 的使用远不止这些功能,更详细的用法可以参考 GitLab CI/CD 官方文档。
CI/CD 流程编排在清楚了如何描述一个 Job 之后,我们通过定义一个个 Job,并进行编排形成 Pipelines。因为我们可以描述设定 Job 的触发条件,所以通过不同的条件可以触发形成不一样的 Pipelines。在 PHP 项目 Kubernetes 上线过程中,我们规定了合并 Master 分支会进行 lint、unitest、build-test 以及 deploy-test 四个 Job。
在测试环境验证通过之后,我们再通过打 tag 进行正式环境的上线。此处的 Pipelines 包含了 unittest、build-pro 和 deploy-pro 三个 Job。
在 .gitlab-ci.yml 文件中,test 阶段主要完成 lint 和 unitest 两个 Job,不同的语言在进行 Job 定义时会各有不同。我们重点来看一下 build 和 deploy 两个 stage 的 Job 描述。build stage:
# 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
在这边,由于 build 阶段中测试环境和生产环境进行镜像打包时基本操作时是相同的,都是根据 Dockerfile 进行镜像的 build 和镜像仓库的上传。这里用到了一个 extend 参数,可以减少重复的 Job 描述,使得描述更加地简洁清晰。我们先定义一个 .build-op 的 Job,然后 build-test 和 build-prod 都通过 extend 进行继承,可以通过定义关键字来新增或覆盖 .build-op 中的配置。比如 build-prod 重新定义了变量( variables)DOCKER_IMAGE_NAME以及触发条件(only)更改为了打 tag 。这边我们还需要注意到的是在定义 DOCKER_IMAGE_NAME 时,我们引用了 GitLab CI 自身的一些变量,比如 CI_COMMIT_TAG 表示项目的 commit 的 tag 名称。我们在定义 Job 变量时,可能会引用到一些 GitLab CI 自身变量,关于这些变量的说明可以参考 GitLab CI/CD Variables 中文文档。deploy stage:
# 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
与 build 阶段类似,先先定义一个 .deploy-op 的 Job,然后 deploy-test 和 deploy-prod 都通过 extend 进行继承。.deploy-op 主要完成了对 Kubernetes Deployment 和 Service 模板文件的一些变量的替换,以及根据生成的 Deployment 和 Service 文件进行 Kubernetes 服务的部署。deploy-test 和 deploy-prod 两个 Job 定义了不同变量(variables)以及触发条件(only)。除此之外, deploy-prod 通过 tags 关键字来使用不同的 Runner,将部署的目标集群指向给生产环境的 Kubernetes。这里还有一个关键字 environment 需要特别说明,在定义了 environment 之后,我们可以在 GitLab 中查看每次部署的一些信息。除了查看每次部署的一些信息之外,我们还可以很方便地进行重新部署和回滚。
可以看到,通过对 Job 的关键字进行配置,我们可以灵活地编排出我们所需要的 CI/CD 流程,非常好地满足多样化的场景。Deployment 与 Service 配置
在 CI/CD 流程中完成 Docker 镜像的打包任务之后需要将服务所对应的镜像部署到 Kubernetes 集群中。Kubernetes 提供了多种可以编排调度的资源对象。首先,我们简单了解一下 Kubernetes 中的一些基本资源。
Kubernetes 基本资源对象概览
PodPod 作为无状态应用的运行实体是其中最常用的一种资源对象, Kubernetes 中资源调度最小的基本单元,它包含一个或多个紧密联系的容器。这些容器共享存储、网络和命名空间,以及如何运行的规范。在 Kubernetes 中, Pod 是非持久的,会因为节点故障或者网络不通等情况而被销毁和重建。所以我们在 Kubernetes 中一般不会直接创建一个独立的 Pod,而是通过多个 Pod 对外提供服务。
ReplicaSetReplicaSet 是 Kubernetes 中的一种副本控制器,控制由其管理的 Pod,使 Pod 副本的数量维持在预设的个数。ReplicaSets 可以独立使用,但是在大多数场景下被 Deployments 作为协调 Pod 创建,删除和更新的机制。
DeploymentDeployment 为 Pod 和 ReplicaSet 提供了一个声明式定义方法。通过在 Deployment 中进行目标状态的描述,Deployment controller 会将 Pod 和 ReplicaSet 的实际状态改变为所设定的目标状态。Deployment 典型的应用场景包括:
定义 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__
__APPNAME__、__GROUPNAME__ 和 __NAMESPACE__ 这种形式的变量都是在 CI/CD 流程中会被替换成 GitLab 每个 project 所对应的变量,目的是为了多了 project 用相同的 deployment.yml 文件,以便在进行 Kubernetes 迁移时可以快速复制,提高效率。
服务名称
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__
...
资源请求大小,对于一些重要的线上应用,limit 和 request 设置一致,资源不足时 Kubernetes 会优先保证这些 Pod 正常运行。为了提高资源利用率。对一些非核心,并且资源不长期占用的应用,可以适当减少 Pod 的 request,这样 Pod 在调度时可以被分配到资源不是十分充裕的节点,提高使用率。但是当节点的资源不足时,也会优先被驱逐或被 oom kill。
健康检查(Liveness/Readiness)配置Liveness 主要用于探测容器是否存活,若监控检查失败会对容器进行重启操作。Readiness 则是通过监控检测容器是否正常提供服务来决定是否加入到 Service 的转发列表接收请求流量。Readiness 在升级过程可以发挥重要的作用,防止升级时异常的新版本 Pod 替换旧版本 Pod 导致整个应用将无法对外提供服务的情况。每个服务必须提供可以正常访问的接口,在 deployment.yml 文件配置好相应的监控检测策略。
...
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
...
...
升级策略配置升级策略我们选择 RollingUpdate 的方式,即在升级过程中滚动式地逐步新建新版本的 Pod,待新建 Pod 正常启动后逐步 kill 掉老版本的 Pod,最终全部新版本的 Pod 替换为旧版本的 Pod。
我们还可以设置 maxSurge 和 maxUnavailable 的值分别控制升级过程中最多可以比原先设置多出的 Pod 比例以及升级过程中最多有多少比例 Pod 处于无法提供服务的状态。
...
spec:
...
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
...
日志配置采用 log-tail 对容器日志进行采集,所有服务的日志都上报到阿里云日志服务的一个 log-store中。在 deployment.yml 文件里配置如下:
...
spec:
...
template:
...
spec:
...
containers:
- name: fpm
env:
- name: aliyun_logs_vpgame
value: stdout
- name: aliyun_logs_vpgame_tags
value: topic=__APP_NAME__
...
...
通过设置环境变量的方式来指定上传的 Logstore 和对应的 tag,其中 name 表示 Logstore 的名称。通过 topic 字段区分不同服务的日志。
监控配置通过在 Deployment 中增加 annotations 的方式,令 Prometheus 可以获取每个 Pod 的业务监控数据。配置示例如下:
...
spec:
...
template:
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "80"
prometheus.io/path: /{{ project_name }}/metrics
...
其中 prometheus.io/scrape: "true" 表示可以被 Prometheus 获取,prometheus.io/port 表示监控数据的端口,prometheus.io/path 表示获取监控数据的路径。
service.yml 配置service.yml 文件主要对 Service 进行了描述。
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
对 Service 的定义相比于 Deoloyment 要简单的多,通过定义 spec.ports 的相关参数可以指定 Service 的对外暴露的端口已经转发到后端 Pod 的端口。spec.selector 则是指定了需要转发的 Pod 的 label。另外,我们这边是通过负载均衡器类型对外提供服务,这是通过定义 spec.type 为 LoadBalancer 实现的。通过增加 metadata.annotations 为 service.beta.kubernetes.io/alicloud-loadbalancer-address-type: intranet 可以在对该 Service 进行创建的同时创建一个阿里云内网 SLB 作为对该 Service 请求流量的入口。
如上图所示,EXTERNAL-IP 即为 SLB 的 IP。总结
在以上工作的基础上,我们对各个服务划分为几类(目前基本上按照语言进行划分),然后为每一类中的服务通过 .gitlab-ci.yml 制定一套统一的 CI/CD 流程,与此相同的,同一类中的服务共用一个 Deployment 和 Service 模板。这样我们在进行服务迁移到 Kubernetes 环境时可以实现快速高效地迁移。当然,这只是迁移实践路上迈出的第一步,在 Kubernetes 中的服务的稳定性、性能、自动伸缩等方面还需要更深入地探索和研究。Kubernetes实战培训
Kubernetes实战培训将于2019年10月18日在深圳开课,3天时间带你系统掌握Kubernetes,学习效果不好可以继续学习。本次培训包括:云原生介绍、微服务;Docker基础、Docker工作原理、镜像、网络、存储、数据卷、安全;Kubernetes架构、核心组件、常用对象、网络、存储、认证、服务发现、调度和服务质量保证、日志、监控、告警、Helm、实践案例等,点击下方图片或者阅读原文链接查看详情。