Kubernetes微服务DevOps

DevOps 环境搭建

在这里插入图片描述

Gitlab

GitLab 是一个用于仓库管理系统的开源项目,使用 Git 作为代码管理工具,并在此基础上搭建起来的 Web 服务。
Gitlab 是被广泛使用的基于 git 的开源代码管理平台, 基于 Ruby on Rails 构建, 主要针对软件开发过程中产生的代码和文档进行管理, Gitlab 主要针对 group 和 project 两个维度进行代码和文档管理, 其中 group 是群组, project 是工程项目, 一个 group 可以管理多个project , 可以理解为一个群组中有多项软件开发任务, 而一个 project 中可能包含多个 branch, 意为每个项目中有多个分支, 分支间相互独立, 不同分支可以进行归并。

  1. 安装 Gitlab
# 下载安装包
wget https://packages.gitlab.com/gitlab/gitlab-ce/packages/el/7/gitlab-ce-15.3.3-ce.0.el7.x86_64.rpm/download.rpm

# 安装
mv download.rpm gitlab-ce-15.3.3-ce.0.el7.x86_64.rpm
rpm -i gitlab-ce-15.3.3-ce.0.el7.x86_64.rpm

# 编辑 /etc/gitlab/gitlab.rb 文件
# 修改 external_url 访问路径 http://<ip>:<port>
# 其他配置修改如下
gitlab_rails['time_zone'] = 'Asia/Shanghai'
puma['worker_processes'] = 2
sidekiq['max_concurrency'] = 8
postgresql['shared_buffers'] = "128MB"
postgresql['max_worker_processes'] = 4
prometheus_monitoring['enable'] = false

# 更新配置并重启
gitlab-ctl reconfigure
gitlab-ctl restart

# 默认为80端口访问
  1. 页面配置
# 查看默认密码
cat /etc/gitlab/initial_root_password
# 登录后修改默认密码 > 右上角头像 > Perferences > Password

# 修改系统配置:点击左上角三横 > Admin
# Settings > General > Account and limit > 取消 Gravatar enabled > Save changes

# 关闭用户注册功能
# Settings > General > Sign-up restrictions > 取消 Sign-up enabled > Save changes

# 开启 webhook 外部访问
# Settings > Network > Outbound requests > Allow requests to the local network from web hooks and services 勾选

# 设置语言为中文(全局)
# Settings > Preferences > Localization > Default language > 选择简体中文 > Save changes

# 设置当前用户语言为中文
# 右上角用户头像 > Preferences > Localization > Language > 选择简体中文 > Save changes
  1. 为项目配置 Webhook
    进入项目点击侧边栏设置 > Webhooks 进入配置即可

URL:在 jenkins 创建 pipeline 项目后
触发来源:

  • 推送事件:表示收到新的推送代码就会触发
  • 标签推送事件:新标签推送才会触发
  • 评论:根据评论决定触发
  • 合并请求事件:创建、更新或合并请求触发

添加成功后,可以在下方点击测试按钮查看 jenkins 是否成功触发构建操作

  1. 卸载
# 停止服务
gitlab-ctl stop

# 卸载 rpm 软件(注意安装的软件版本是 ce 还是 ee)
rpm -e gitlab-ce

# 查看进程
ps -ef|grep gitlab 
# 干掉第一个 runsvdir -P /opt/gitlab/service log 进程

# 删除 gitlab 残余文件
find / -name *gitlab* | xargs rm -rf
find / -name gitlab | xargs rm -rf

Harbor

  1. 下载harbor离线安装包:https://github.com/goharbor/harbor/releases
    解压缩:
tar -zxvf harbor-offline-installer-v2.14.1.tgz
  1. 复制模板并编辑配置文件
cp harbor.yml.tmpl harbor.yml
vim harbor.yml

关键配置项说明:

# 主机名(必须设置为你的服务器域名或 IP)
hostname: harbor.example.com

# HTTPS 配置(推荐启用)
https:
  port: 443
  certificate: /your-path/harbor.example.com.crt
  private_key: /your-path/harbor.example.com.key

# 如果不使用 HTTPS,可注释掉 https 部分,保留 http(默认端口 80)
# http:
#   port: 80

# 数据库密码(可自定义)
database:
  password: your_strong_password

# Harbor 管理员初始密码(默认是 Harbor12345)
harbor_admin_password: YourAdminPass123!

# 数据持久化路径
data_volume: /data/harbor

# 可选:启用 Trivy 扫描器、Notary、ChartMuseum 等
trivy:
  enabled: true
  1. 运行安装脚本
    确保已安装 Docker 和 Docker Compose
./install.sh

SonarQube

使用 docker run(简单测试)

docker run -d  --name sonarqube  -p 9000:9000  -p 9092:9092 sonarqube:community

访问 http://<服务器IP>:9000,默认账号密码:admin / admin

使用 Docker Compose(含 PostgreSQL)

  1. 创建 docker-compose.yml 文件
version: '3'

services:
  sonarqube:
    image: sonarqube:community
    container_name: sonarqube
    depends_on:
      - db
    environment:
      - SONAR_JDBC_URL=jdbc:postgresql://db:5432/sonarqube
      - SONAR_JDBC_USERNAME=sonar
      - SONAR_JDBC_PASSWORD=sonarpass
    volumes:
      - ./data:/opt/sonarqube/data
      - ./logs:/opt/sonarqube/logs
      - ./extensions:/opt/sonarqube/extensions
    ports:
      - "9000:9000"
      - "9092:9092"  # 用于调试或插件通信(可选)
    networks:
      - sonarnet
    restart: unless-stopped

  db:
    image: postgres:15
    container_name: sonarqube_db
    environment:
      - POSTGRES_USER=sonar
      - POSTGRES_PASSWORD=sonarpass
      - POSTGRES_DB=sonarqube
    volumes:
      - ./postgres_data:/var/lib/postgresql/data
    networks:
      - sonarnet
    restart: unless-stopped

networks:
  sonarnet:
    driver: bridge
  1. 启动服务
docker-compose up -d

Jenkins

  1. 创建持久化目录
sudo mkdir -p /jenkins_home
  1. 启动 Jenkins 容器
docker run -d \
  --name jenkins \
  -p 8080:8080 \
  -p 50000:50000 \
  -v /jenkins_home:/var/jenkins_home \
  --restart unless-stopped \
  jenkins/jenkins:lts

K8S CICD 案例

使用springboot写一个最简单的功能,只有一个Restful接口
Dockerfile:

## 基础镜像
## AdoptOpenJDK 停止发布 OpenJDK 二进制,而 Eclipse Temurin 是它的延伸,提供更好的稳定性
FROM eclipse-temurin:8-jre

## 作者
LABEL org.opencontainers.image.authors="daiwuliang@126.com"

## 定义参数

## 创建并进入工作目录
RUN mkdir -p /works
WORKDIR /works

## maven 插件构建时得到 buildArgs 种的值
COPY target/*.jar app.jar

## 设置 TZ 时区
## 设置 JAVA_OPTS 环境变量,可通过 docker run -e "JAVA_OPTS=" 进行覆盖
ENV TZ=Asia/Shanghai JAVA_OPTS="-Xms256m -Xmx256m"

## 暴露端口
EXPOSE 5001

## 容器启动命令
## CMD 第一个参数之后的命令可以在运行时被替换
CMD java ${JAVA_OPTS} -Djava.security.egd=file:/dev/./urandom -jar app.jar

k8s yaml

---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: k8s-cicd-demo
    component: daiwuliang-devops
    tier: backend
  name: k8s-cicd-demo
  namespace: k8s-cicd
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  selector:
    matchLabels:
      app: k8s-cicd-demo
      component: daiwuliang-devops
      tier: backend
  strategy:
    rollingUpdate:
      maxSurge: 100%
      maxUnavailable: 100%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: k8s-cicd-demo
        component: daiwuliang-devops
        tier: backend
    spec:
      imagePullSecrets:
        - name: harbor-secret
      containers:
        - name: k8s-cicd-demo
          image: REGISTRY/DOCKERHUB_NAMESPACE/APP_NAME:TAG_NAME
          readinessProbe:
            httpGet:
              path: /users
              port: 8080
            timeoutSeconds: 10
            failureThreshold: 30
            periodSeconds: 5
          imagePullPolicy: Always
          ports:
            - containerPort: 8080
              protocol: TCP
          resources:
            limits:
              cpu: 300m
              memory: 600Mi
            requests:
              cpu: 100m
              memory: 100Mi
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: k8s-cicd-demo
    component: daiwuliang-devops
  name: k8s-cicd-demo
  namespace: k8s-cicd
spec:
  ports:
    - name: http
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    app: k8s-cicd-demo
    component: daiwuliang-devops
    tier: backend
  sessionAffinity: None
  type: NodePort

Jenkinsfile

pipeline {
    agent {
        kubernetes {
            label 'maven'
        }
    }

    parameters {
        gitParameter name: 'BRANCH_NAME', branch: '', branchFilter: '.*', defaultValue: 'origin/master', description: '请选择要发布的分支', quickFilterEnabled: false, selectedValue: 'NONE', tagFilter: '*', type: 'PT_BRANCH'
        string(name: 'TAG_NAME', defaultValue: 'snapshot', description: '标签名称,必须以 v 开头,例如:v1、v1.0.0')
    }

    environment {
        DOCKER_CREDENTIAL_ID = 'harbor-user-pass'
        GIT_REPO_URL = 'git-url'
        GIT_CREDENTIAL_ID = 'git-user-pass'
        GIT_ACCOUNT = 'gitlab-account' 
        KUBECONFIG_CREDENTIAL_ID = ''
        REGISTRY = 'harbor-address'
        DOCKERHUB_NAMESPACE = '' 
        APP_NAME = 'k8s-cicd-demo'
        SONAR_CREDENTIAL_ID = 'sonarqube-token'
    }

    stages {

        stage('checkout scm') {
            steps {
                checkout scmGit(branches: [[name: "$BRANCH_NAME"]], extensions: [], userRemoteConfigs: [[credentialsId: "$GIT_CREDENTIAL_ID", url: 'url']])
            }
        }

        stage('unit test') {
            steps {
                sh 'mvn clean test'
            }
        }

        stage('sonarqube analysis') {
            steps {
                withCredentials([string(credentialsId: "$SONAR_CREDENTIAL_ID", variable: 'SONAR_TOKEN')]) {
                    withSonarQubeEnv('sonarqube') {
                        sh 'mvn sonar:sonar -Dsonar.projectKey=$APP_NAME'
                    }
                }
                timeout(time: 1, unit: 'HOURS') {
                    waitForQualityGate abortPipeline: true
                }
            }
        }

        stage('build & push') {
            steps {
                sh 'mvn clean package -DskipTests'
                sh 'docker build -f Dockerfile -t $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER .'
                withCredentials([usernamePassword(passwordVariable: 'DOCKER_PASSWORD', usernameVariable: 'DOCKER_USERNAME', credentialsId: "$DOCKER_CREDENTIAL_ID",)]) {
                    sh 'echo "$DOCKER_PASSWORD" | docker login $REGISTRY -u "$DOCKER_USERNAME" --password-stdin'
                    sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER'
                }
            }
        }

        stage('push latest') {
            steps {
                sh 'docker tag $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:latest'
                sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:latest'
            }
        }

        stage('deploy to dev') {
            steps {
                input(id: 'deploy-to-dev', message: 'deploy to dev?')
                sh '''
                    sed -i'' "s#REGISTRY#$REGISTRY#" deploy/cicd-demo-dev.yaml
                    sed -i'' "s#DOCKERHUB_NAMESPACE#$DOCKERHUB_NAMESPACE#" deploy/cicd-demo-dev.yaml
                    sed -i'' "s#APP_NAME#$APP_NAME#" deploy/cicd-demo-dev.yaml
                    sed -i'' "s#BUILD_NUMBER#$BUILD_NUMBER#" deploy/cicd-demo-dev.yaml
                    kubectl apply -f deploy/cicd-demo-dev.yaml
                '''
            }
        }
        stage('push with tag') {
            when {
                expression {
                    return params.TAG_NAME =~ /v.*/
                }
            }
            steps {
                input(id: 'release-image-with-tag', message: 'release image with tag?')
                withCredentials([usernamePassword(credentialsId: "$GIT_CREDENTIAL_ID", passwordVariable: 'GIT_PASSWORD', usernameVariable: 'GIT_USERNAME')]) {
                    sh 'git config --global user.email "daiwuliang@126.com" '
                    sh 'git config --global user.name "daiwl" '
                    sh 'git tag -a $TAG_NAME -m "$TAG_NAME" '
                    sh 'git push http://$GIT_USERNAME:$GIT_PASSWORD@$GIT_REPO_URL/$GIT_ACCOUNT/k8s-cicd-demo.git --tags --ipv4'
                }
                sh 'docker tag $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:SNAPSHOT-$BUILD_NUMBER $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$TAG_NAME'
                sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$TAG_NAME'
            }
        }
        stage('deploy to production') {
            when {
                expression {
                    return params.TAG_NAME =~ /v.*/
                }
            }
            steps {
                input(id: 'deploy-to-production', message: 'deploy to production?')
                sh '''
                    sed -i'' "s#REGISTRY#$REGISTRY#" deploy/cicd-demo.yaml
                    sed -i'' "s#DOCKERHUB_NAMESPACE#$DOCKERHUB_NAMESPACE#" deploy/cicd-demo.yaml
                    sed -i'' "s#APP_NAME#$APP_NAME#" deploy/cicd-demo.yaml
                    sed -i'' "s#TAG_NAME#$TAG_NAME#" deploy/cicd-demo.yaml
                    kubectl apply -f deploy/cicd-demo.yaml
                '''
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值