クラウド ネイティブでのエンタープライズ レベルのフロントエンド構築の実践

序文

コンテナ、k8s、クラウドネイティブがますます普及している昨今、クラウドネイティブ時代のフロントエンドプロジェクトの構築・リリースにどのような変化があったのでしょうか?従来のビルドおよびデプロイ プラットフォームと比較して、クラウド ネイティブの違いは何ですか? 従来の構築および展開プラットフォームでのエンタープライズ レベルのプロジェクト構築に興味がある場合は、まず [統合展開プラットフォームでのエンタープライズ レベルのフロントエンド構築の実践] を参照してください。

今日は主に、オープンソースの車輪 (docker/k8s/rancher/gitlab ci) に基づくクラウドネイティブな構築ソリューションについて話します。

完全なプロセス

完全なプロセスを次の図に示します。

1. コードは gitlab でホストされており、gitlab の ci cd を借用しています。

2. gitlab の ci は、主にプロジェクト自体のビルド パッケージと、docker イメージ build-docker のパッケージを担当します。

3. パッケージ化された Docker イメージをプライベート ソース ハーバーにプッシュします。

4. 環境を微分し、rancher の http インターフェースを呼び出し、ハーバーに docker イメージをダウンロードして、指定したクラスターの指定したプロジェクトをデプロイします。Rancher は、kubectl を介して k8s クラスターも制御します。

    ┌──────────────┐ ┌────────────────┐ 
    │ │ │ 
    │ 港 ├────────── ────▲│ ランチャー │ 
    │ │▼──────────────┤ ├──────────────┐ 
    │ │ docker pull │ │ 
    └ ──────────────┘ └───────────────┘ kubectl│ 
           ▲ ▲ │ 
           │ │ 
           │ │ │ 
           │ │ 
           │build-docker deploy-test1 │
           │ deploy-release │ 
           │ ...... │ 
           │ │ │ 
     build │ │ │                          
           │ │ 
┌──────────┴────────────┐ │ ┌ ────────────┴─────────────┐ 
│ │ │ │ 
│ │ │ 
│ │ │ │ 
│ gitlab ├─────────────── ───┘ │ k8sクラスタ │ 
│ │ │ 
│ │ 
│ │ │ 
└────────────────── ────────┘ └──────────────────────────┘

CI と CD の完全なプロセス

あるプロジェクトのgitlab ci ymlファイルを例に詳細を紹介します。

1. まず、rancher と Harbor を含む必要な変数を定義します。

2. pre-script before_script を実行して、ブランチを介して環境変数とパッケージ化されたイメージの名前を決定します. 通常のブランチのイメージ名にはハッシュが含まれません. これは、基本的にテスト環境をロールバックする必要がないためです. 環境変数は RUNTIME_ENV で、後続の docker ビルドによってコンテナーに取り込まれます。

3. ステージ全体が build、build-docker、deploy-test1、deploy-online に分かれていることを定義します。プロジェクトのパッケージ化、イメージのパッケージ化、展開テスト環境、オンライン環境の展開をそれぞれ行います。

4. 各段階で実行されるジョブを定義します. たとえば、展開は rancher インターフェースを呼び出し、さまざまな変数を渡します.

image: docker:18.06
 
 
variables:
  # rancher 变量
  RANCHER_NAMESPACE: kef2e
  RANCHER_PROJECT: kef2e
  RANCHER_WORKLOAD: ke-cms
  # harbor 变量
  PROJECT: kef2e
  IMAGE_NAME: ke-cms
  # 部署重要变量
  RANCHER_URL: https://someurl
  RANCHER_URL_ONLINE: https://someurl
  RANCHER_TOKEN: yourtoken
  RANCHER_TOKEN_ONLINE: yourtoken
  RANCHER_PROJECT_ID: yourid
  RANCHER_PROJECT_ID_ONLINE: yourid

 
services:
  - name: docker:18.06-dind
    alias: docker
 
stages:
  - build-spa
  - build-docker
  - deploy
  - deploy_online
 

  before_script:
    - echo exec before_script
    # 现在gitlab版本没有 CI_COMMIT_SHORT_SHA 变量(v>11.7),进行兼容
    - if [ "$CI_COMMIT_SHORT_SHA" = "" ]; then CI_COMMIT_SHORT_SHA=${CI_COMMIT_SHA:0:8} ;fi;
    # 将branch name里的/转换为tag name支持的-
    - CI_COMMIT_REF_SAFE_NAME=$(echo $CI_COMMIT_REF_NAME | sed 's/\//-/')
    # 镜像的仓库地址
    - IMAGE_URL=$DOCKER_REG/$PROJECT/$IMAGE_NAME:$CI_COMMIT_REF_SAFE_NAME
    - if [[ "$CI_COMMIT_REF_SAFE_NAME" != "release" ]]; then RUNTIME_ENV=development ; fi
    - if [[ "$CI_COMMIT_REF_SAFE_NAME" == "release" ]] || [[ "$CI_COMMIT_REF_SAFE_NAME" == "pre" ]]; then IMAGE_URL=$DOCKER_REG/$PROJECT/$IMAGE_NAME:$CI_COMMIT_REF_SAFE_NAME-$CI_COMMIT_SHORT_SHA; fi
    - echo image url:$IMAGE_URL
    - echo image RUNTIME_ENV:$RUNTIME_ENV

.deploy_tpl: &deploy_def
  script:
    - CONTAINER_URL=$RANCHER_URL/v3/projects/$RANCHER_PROJECT_ID/workloads/deployment:$RANCHER_NAMESPACE:$RANCHER_WORKLOAD
    - curl -u $RANCHER_TOKEN -X GET $CONTAINER_URL -o deployment.json -k
    - TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
    - sed -i 's#image\":[^,]*,#image\":\"'$IMAGE_URL'\",#' deployment.json
    - sed -i 's/"cattle.io\/timestamp":"[^"]*"/"cattle.io\/timestamp":"'${TIMESTAMP}'"/g' deployment.json
    - curl -u $RANCHER_TOKEN -XPUT -H "Accept:application/json" -H "Content-Type:application/json" [email protected] $CONTAINER_URL -k
    - echo RANCHER_URL:$RANCHER_URL
    - echo RANCHER_TOKEN:$RANCHER_TOKEN
    - echo RANCHER_PROJECT_ID:$RANCHER_PROJECT_ID
    - echo CONTAINER_URL:$CONTAINER_URL


# 打包spa
build-spa:
  stage: build-spa
  tags:
    - k8s
  image: harbor-registry.inner.youdao.com/ke-test/agent-base:node12
  script:
    - echo "package build directory"
    - yarn config set strict-ssl false
    - yarn config set registry http://f2enpm.inner.youdao.com/
    # https://github.com/cnpm/cnpmjs.org/issues/1246, puppeteer在CI可能install有问题
    - yarn config set puppeteer_download_host https://nexus3.corp.youdao.com/repository/npm-all/
    - yarn config set puppeteer_skip_chromium_download true
    - yarn install
    # 这里为项目线上的构建命令,根据项目自行修改
    - yarn release
  cache:
    key: "$CI_COMMIT_REF_SLUG"
    paths:
      - node_modules/
  artifacts:
    name: "$CI_COMMIT_REF_SLUG"
    paths:
      - dist
    when: always
    expire_in: 6 mos
 
# 构建镜像
build-docker:
  retry: 2
  stage: build-docker
  tags:
    - k8s
  script:
    # 登陆 dockerhub
    - echo $DOCKER_REG_PASSWD | docker login $DOCKER_REG -u $DOCKER_REG_USER --password-stdin
    # 镜像地址
    - echo $IMAGE_URL
    - docker build -t $IMAGE_URL --build-arg RUNTIME_ENV=$RUNTIME_ENV .
    - docker push $IMAGE_URL
    - docker logout $DOCKER_REG
 
 
# 部署rancher
deploy_rancher:
  stage: deploy
  image: $CURL_IMAGE
  tags:
    - k8s
  variables:
    MSG: "正式部署到 $RANCHER_CLUSTER:$RANCHER_NAMESPACE \n部署地址:$RANCHER_URL/p/$RANCHER_PROJECT_ID/workload/deployment:$RANCHER_NAMESPACE:$RANCHER_WORKLOAD-$CI_COMMIT_REF_NAME \n"
  script:
  <<: *deploy_def
  # 手动触发rancher部署
  when: manual
  
# 部署rancher online
deploy_rancher_online:
  stage: deploy_online
  image: $CURL_IMAGE
  tags:
    - k8s
  variables:
    RANCHER_URL: $RANCHER_URL_ONLINE
    RANCHER_PROJECT_ID: $RANCHER_PROJECT_ID_ONLINE
    RANCHER_TOKEN: $RANCHER_TOKEN_ONLINE
    MSG: "正式部署到 $RANCHER_CLUSTER:$RANCHER_NAMESPACE \n部署地址:$RANCHER_URL/p/$RANCHER_PROJECT_ID/workload/deployment:$RANCHER_NAMESPACE:$RANCHER_WORKLOAD-$CI_COMMIT_REF_NAME \n"
  script:
  <<: *deploy_def
  # 手动触发rancher部署
  only:
    - release
  when: manual

以上のプロセスにより、フロントエンド プロジェクトの構築と展開は完了しますが、まだいくつかの問題があります。エンタープライズ レベルの意味は、最高の保守性を追求し、パーソナライズを可能な限り減らすことです。また、20 以上のプロジェクトがある場合、このような構成の yml を 1 つずつ必要としますが、めちゃくちゃになりませんか? したがって、抽象的な統一された構成が不可欠です。

統合構成後の CI と CD

分析を通じて、矛盾している可能性があるビルド フェーズを除いて、ランチャーのプロジェクト ID などの変数名が異なることを除いて、他のフェーズは同じであると結論付けることができます。

統合構成後の yml ファイルは次のとおりです。

ビルド ステージを除いて、他のステージと before_script はリモート管理に抽出され、インクルードによって読み込まれます。

ビルド フェーズで行われたことの一貫性を極端に確保できる場合は、それらをすべて抽出して、変数名の構成のみを残すこともできます。私たちのプロジェクトの数が多いため、パーソナライズされた変換の費用対効果は高くないため、ビルドは一時的に保存されます。

image: docker:18.06
 
 
variables:
  # rancher 变量
  RANCHER_NAMESPACE: kef2e
  RANCHER_PROJECT: kef2e
  RANCHER_WORKLOAD: ke-cms
  # harbor 变量
  PROJECT: kef2e
  IMAGE_NAME: ke-cms
  # 部署重要变量
  RANCHER_URL: https://someurl
  RANCHER_URL_ONLINE: https://someurl
  RANCHER_TOKEN: yourtoken
  RANCHER_TOKEN_ONLINE: yourtoken
  RANCHER_PROJECT_ID: yourid
  RANCHER_PROJECT_ID_ONLINE: yourid

 
services:
  - name: docker:18.06-dind
    alias: docker
 
stages:
  - build
  - build-docker
  - deploy-test1
  - deploy-online

include: 
    - 'https://g.hz.netease.com/api/v4/projects/49427/repository/files/before_script.yml/raw?ref=master&private_token=YOUR_TOKEN&ext=.yml'
    - 'https://g.hz.netease.com/api/v4/projects/49427/repository/files/job.yml/raw?ref=master&private_token=YOUR_TOKEN&ext=.yml'

# 打包spa
build-spa:
  stage: build
  tags:
    - k8s
  image: harbor-registry.inner.youdao.com/ke-test/agent-base:node12
  script:
    - echo "package build directory"
    - yarn config set strict-ssl false
    - yarn config set registry http://f2enpm.inner.youdao.com/
    # https://github.com/cnpm/cnpmjs.org/issues/1246, puppeteer在CI可能install有问题
    - yarn config set puppeteer_download_host https://nexus3.corp.youdao.com/repository/npm-all/
    - yarn config set puppeteer_skip_chromium_download true
    - yarn install
    # 这里为项目线上的构建命令,根据项目自行修改
    - yarn release
  cache:
    key: "$CI_COMMIT_REF_SLUG"
    paths:
      - node_modules/
  artifacts:
    name: "$CI_COMMIT_REF_SLUG"
    paths:
      - dist
    when: always
    expire_in: 6 mos

抽象化された 2 つのリモート スクリプトは次のとおりです。

before_script.yml は、条件に従ってイメージ名を定義するなど、いくつかの事前操作を行うために使用されます。

default:
  before_script:
    - echo exec before_script
    # 现在gitlab版本没有 CI_COMMIT_SHORT_SHA 变量(v>11.7),进行兼容
    - if [ "$CI_COMMIT_SHORT_SHA" = "" ]; then CI_COMMIT_SHORT_SHA=${CI_COMMIT_SHA:0:8} ;fi;
    # 将branch name里的/转换为tag name支持的-
    - CI_COMMIT_REF_SAFE_NAME=$(echo $CI_COMMIT_REF_NAME | sed 's/\//-/')
    # 镜像的仓库地址
    - IMAGE_URL=$DOCKER_REG/$PROJECT/$IMAGE_NAME:$CI_COMMIT_REF_SAFE_NAME
    - if [[ "$CI_COMMIT_REF_SAFE_NAME" != "release" ]]; then RUNTIME_ENV=development ; fi
    - if [[ "$CI_COMMIT_REF_SAFE_NAME" == "release" ]] || [[ "$CI_COMMIT_REF_SAFE_NAME" == "pre" ]]; then IMAGE_URL=$DOCKER_REG/$PROJECT/$IMAGE_NAME:$CI_COMMIT_REF_SAFE_NAME-$CI_COMMIT_SHORT_SHA; fi
    - echo image url:$IMAGE_URL
    - echo image RUNTIME_ENV:$RUNTIME_ENV

また、job.yml はいくつかのパブリック タスクを格納するために使用されます。

.deploy_tpl: &deploy_def
  script:
    - CONTAINER_URL=$RANCHER_URL/v3/projects/$RANCHER_PROJECT_ID/workloads/deployment:$RANCHER_NAMESPACE:$RANCHER_WORKLOAD
    - curl -u $RANCHER_TOKEN -X GET $CONTAINER_URL -o deployment.json -k
    - TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
    - sed -i 's#image\":[^,]*,#image\":\"'$IMAGE_URL'\",#' deployment.json
    - sed -i 's/"cattle.io\/timestamp":"[^"]*"/"cattle.io\/timestamp":"'${TIMESTAMP}'"/g' deployment.json
    - curl -u $RANCHER_TOKEN -XPUT -H "Accept:application/json" -H "Content-Type:application/json" [email protected] $CONTAINER_URL -k
    - echo RANCHER_URL:$RANCHER_URL
    - echo RANCHER_TOKEN:$RANCHER_TOKEN
    - echo RANCHER_PROJECT_ID:$RANCHER_PROJECT_ID
    - echo CONTAINER_URL:$CONTAINER_URL

variables: 
  RANCHER_URL: 
  RANCHER_URL_ONLINE: 
  RANCHER_TOKEN: 
  RANCHER_TOKEN_ONLINE: 

# 构建镜像
build-docker:
  retry: 2
  stage: build-docker
  tags:
    - k8s
  script:
    # 登陆 dockerhub
    - echo $DOCKER_REG_PASSWD | docker login $DOCKER_REG -u $DOCKER_REG_USER --password-stdin
    # 镜像地址
    - echo $IMAGE_URL
    - docker build -t $IMAGE_URL --build-arg RUNTIME_ENV=$RUNTIME_ENV .
    - docker push $IMAGE_URL
    - docker logout $DOCKER_REG
 
 

# 部署rancher
deploy_rancher_test1:
  stage: deploy-test1
  image: $CURL_IMAGE
  tags:
    - k8s
  variables:
    MSG: "正式部署到 $RANCHER_CLUSTER:$RANCHER_NAMESPACE \n部署地址:$RANCHER_URL/p/$RANCHER_PROJECT_ID/workload/deployment:$RANCHER_NAMESPACE:$RANCHER_WORKLOAD-$CI_COMMIT_REF_NAME \n"
  script:
  <<: *deploy_def
  # 手动触发rancher部署
  when: manual

  # 部署rancher online
deploy_rancher_online:
  stage: deploy-online
  image: $CURL_IMAGE
  tags:
    - k8s
  variables:
    RANCHER_URL: $RANCHER_URL_ONLINE
    RANCHER_PROJECT_ID: $RANCHER_PROJECT_ID_ONLINE
    RANCHER_TOKEN: $RANCHER_TOKEN_ONLINE
    MSG: "正式部署到 $RANCHER_CLUSTER:$RANCHER_NAMESPACE \n部署地址:$RANCHER_URL/p/$RANCHER_PROJECT_ID/workload/deployment:$RANCHER_NAMESPACE:$RANCHER_WORKLOAD-$CI_COMMIT_REF_NAME \n"
  script:
  <<: *deploy_def
  # 手动触发rancher部署
  only:
    - release
  when: manual

要約する

上記の統合構成を完了した後、各プロジェクトは、ci プロセスを作成してフロントエンドのビルドとリリースを完了するときに、独自のプロジェクトと独自のビルド フェーズ タスクの一意のパラメーターを構成するだけで済みます。

将来、新しい環境とクラスターが追加された場合、それらは同じ構成のスクリプトで維持するだけでよく、プロジェクトはステージと対応する変数を追加するだけで済みます。

おすすめ

転載: blog.csdn.net/weixin_44786530/article/details/130424880
おすすめ