k8s day11 vuejs+docker+kubernates+github actions实现自动部署
打算把个人博客部署在k8s上面,记录下过程。
博客是由vuepress搭建的
目前的部署方式见CD
简单说就是执行npm run build
把生成的静态资源扔到我自己服务器的nginx站点目录中
我们要实现的是 每次提交到master分支,打包一个docker镜像 -> 推到docker hub -> 登录 google cloud 的k8s集群简称(GKE) -> 每个节点拉镜像实现分布式
- 首先项目根目录添加
Dockerfile
和.dockerignore
Dockerfile
# build stage
FROM node:lts-alpine as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/docs/.vuepress/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
.dockerignore
node_modules
.git
- 打包docker镜像并推到docker hub仓库
docker build . --file Dockerfile -t finleyma/blog-vuepres
docker push
打开 hub.docker.com/r/finleyma/… 更新时间变了,搞定了第一步
- 项目根目录创建kubernates.yaml
注意:我们已经提前在google cloud上建立好了包含3个工作节点的k8s集群
其中Deployment的replicas为3,因为我们的k8s集群有三个工作节点
Service的类型为LoadBalancer,这样google cloud会自动帮我们创建负载均衡器并分配IP
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-blog-vuepress
labels:
app: blog-vuepress
spec:
replicas: 3
selector:
matchLabels:
app: blog-vuepress
template:
metadata:
labels:
app: blog-vuepress
spec:
containers:
- name: blog-vuepress
image: finleyma/blog-vuepress:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: service-blog-vuepress
spec:
type: LoadBalancer
selector:
app: blog-vuepress
ports:
# 默认情况下,为了方便起见,`targetPort` 被设置为与 `port` 字段相同的值。
- protocol: TCP
## service暴露在cluster ip上的端口
port: 80
## targetPort是pod上的端口,Dockerfile中指定了80
targetPort: 80
- 稍等片刻,查看刚刚创建的service
kubectl describe svc service-blog-vuepress
注意LoadBalancer Ingress就是暴露出来的可以外部访问的IP啦,浏览器打开这个IP就是我们的网站了
以上基本功能已经完成,接下来我们实现自动化
- 提交代码后自动创建镜像
项目根目录创建
.github/workflows/cloud.yaml
注意:这个文件目前在完善中,不保证是最新的
# This is a basic workflow to help you get started with Actions
name: CI
# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
push:
branches: [ master ]
env:
CI: true
NODE: 14.x
# google cloud kubernates cluser (GKE)
PROJECT_ID: ivory-strategy-313903
GKE_CLUSTER: cluster-1 # Add your cluster name here.
GKE_ZONE: asia-east1-a # Add your cluster zone here.
DEPLOYMENT_NAME: deployment-blog-vuepress # Add your deployment name here.
IMAGE: finleyma/blog-vuepress
IMAGE_TAG: $GITHUB_SHA
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"
build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
- uses: actions/checkout@v2
- name: Install Node.js
uses: actions/setup-node@v1
with:
node-version: "${{ env.NODE }}"
# calculate some variables that are used later
- name: github branch
run: |
BRANCH=${GITHUB_REF##*/}
if [ "$BRANCH" == "master" ]; then
TAGS="latest,$(date +'%Y%m%d')"
else
TAGS="$BRANCH"
fi
TAGS="${TAGS},${BRANCH}-${{ github.run_number }},${GITHUB_SHA:0:7}"
echo "TAGS=${TAGS}" >> $GITHUB_ENV
echo "GITHUB_BRANCH=${BRANCH}" >> $GITHUB_ENV
- name: Install npm dependencies
run: npm ci
- name: Run build task
run: npm run build --if-present
- name: Build the Docker image
run: docker build --file Dockerfile .
- name: publish docker image to dockerhub
uses: elgohr/Publish-Docker-Github-Action@master
with:
name: ${{ env.IMAGE }}
username: finleyma
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
tags: ${{ env.TAGS }}
# - name: Deploy to Server Cloud 2
# uses: easingthemes/ssh-deploy@v2.1.5
# env:
# SSH_PRIVATE_KEY: ${{ secrets.PRIVATE_KEY2 }}
# ARGS: "-rltgoDzvO --delete"
# SOURCE: "docs/.vuepress/dist/"
# REMOTE_PORT : ${{ secrets.PORT2 }}
# REMOTE_HOST: ${{ secrets.HOST2 }}
# REMOTE_USER: ${{ secrets.USERNAME }}
# TARGET: "/home/ubuntu/blog"
# Setup gcloud CLI
- uses: google-github-actions/setup-gcloud@94337306dda8180d967a56932ceb4ddcf01edae7
with:
service_account_key: ${{ secrets.GKE_SA_KEY }}
project_id: ${{ env.PROJECT_ID }}
# Configure docker to use the gcloud command-line tool as a credential helper
- run: |-
gcloud --quiet auth configure-docker
# Get the GKE credentials so we can deploy to the cluster
- uses: google-github-actions/get-gke-credentials@fb08709ba27618c31c09e014e1d8364b02e5042e
with:
cluster_name: ${{ env.GKE_CLUSTER }}
location: ${{ env.GKE_ZONE }}
credentials: ${{ secrets.GKE_SA_KEY }}
# Deploy the Docker image to the GKE cluster
# kubectl set image deployment deployment-blog-vuepress blog-vuepress=finleyma/blog-vuepress:master-87 --record
# ./kustomize edit set image gcr.io/PROJECT_ID/IMAGE:TAG=gcr.io/$PROJECT_ID/$IMAGE:$GITHUB_SHA
# ./kustomize build . | kubectl apply -f -
- name: Deploy
run: |-
kubectl get services -o wide
kubectl set image deployment deployment-blog-vuepress blog-vuepress=finleyma/blog-vuepress:${GITHUB_SHA:0:7} --record
kubectl rollout history deployment deployment-blog-vuepress
# Slack Notification
- name: Slack Notification
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
fields: repo,message,commit,author,action,eventName,ref,workflow,job,took # selectable (default: repo,message)
env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # optional
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} # required
if: always() # Pick up events even if the job fails or is canceled.
- google cloud部分可以参考
转载自:https://juejin.cn/post/6996514086536085534