6 Star 72 Fork 28

JustryDeng / notebook

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
[11]kubesphere部署应用到k8s.md 11.61 KB
一键复制 编辑 原始数据 按行查看 历史
JustryDeng 提交于 2023-10-31 11:04 . kubesphere部署应用到k8s

kubesphere使用devOps部署应用到k8s

devOps部署应用到k8s

声明1:本文内容基于kubesphere-v3.3.1

声明2:本文中的配置示例,都是比较简单的入门级配置示例。正式使用时,根据项目进行更多配置即可

第一步:准备应用源码及Dockerfile文件、k8s部署文件

项目结构

image-20230306190329993

注:这两个文件,放在项目下的任意位置都行,只需要在边界Jenkinsfile指定对应路径即可

其中有个API长这样(此api用于部署后的测试验证)

image-20230306191031481

准备Dockerfile

FROM openjdk:8-jdk
MAINTAINER JustryDeng<13548417409@163.com>
ADD target/*.jar /app.jar
ENTRYPOINT [ "java", "-jar", "/app.jar" ]

k8s部署文件

################################################# Deployment 部署应用
apiVersion: apps/v1 # api版本
kind: Deployment # yml文件类型
metadata: # 元数据
  name: demo-deployment # 本deployment的名称
  # 可以使用kubectl创建命名空间,如果没有的话
  # kubectl create namespace {命名空间}
  # kubectl get namespaces
  namespace: demo-namespace
  labels: # 本deployment具备的标签
    app: demo-deployment
spec:
  # 选择器. 将以被选择器选中的template为模板,拉起pod
  selector:
    matchLabels:
      labelA: labelA_value
  replicas: 1 # 要拉起pod副本的数量
  strategy:
    type: RollingUpdate # 拉起pod的策略
  template: # pod模板设置
    metadata:
      labels:
        labelA: labelA_value
        podLabelB: demo-pod
    spec:
      containers:
        - name: i-am-demo-name # 设置容器名(小写字母 or 数字 or 中划线)
          # 设置拉起容器所使用的镜像, 这里通过占位符,取值到下文Jenkinsfile中相关的值, 此参数可以等Jenkinsfile写好后,再回来补充
          # 注意:docker pull时,默认会先走本地镜像,本地有的话,就不会去远程拉,所以如果是拉取远程同名镜像的话,记得拉取前移除本地旧的镜像
          image: '${IMAGE_REGISTRY}/${IMAGE_PROJECT}/${APPLICATION_NAME}:${BRANCH_NAME}-${BUILD_NUMBER}'
          ports:
            # 请求(直接来着node的请求、ingress转发过来的请求) -> service(service管理pod集群, 将请求分发至pod) ->  pod
            # service的端口:port  ->  pod的端口:targetPort(即:containerPort)
            # 因为一个pod内可能有多个容器,即可能有多个containerPort, 所以 当service要往pod转发请求时, 就需要通过targetPort指定需要跳转到哪个containerPort
            - containerPort: 8080 # pod的ip + 容器端口(containerPort) = Endpoint,代表此pod里的一个服务进程的对外通信地址


---

################################################# Service 暴露服务,使走外网可访问
apiVersion: v1
kind: Service
# 设置当前service的元信息
metadata:
  name: demo-service
  namespace: demo-namespace
  labels:
    app: demo-service
spec:
  ports:
    - name: http
      protocol: TCP
      nodePort: 30862 # 宿主机node的端口(外网访问的话,此端口需要开启才行)
      port: 8080 # 当前service的端口
      targetPort: 8080 # 对应上面容器暴露的端口, 不填则默认值为port
  # NodePort模式下,请求依次"经过"的端口:节点机器的的nodePort -> 服务的port -> pod的targetPort
  type: NodePort # 以NodePort的形式暴露service,使得可通过 node的ip + nodePort访问服务
  # 匹配这些pod-template创建出来的pod
  selector:
    labelA: labelA_value
    podLabelB: demo-pod

第二步:创建DevOps项目

较简单,直接参考创建DevOps项目即可

第三步:编辑Jenkinsfile

提示:直接用编辑流水线图形编辑的话,对应生成的Jenkinsfile可能有问题。我们可以直接编辑Jenkinsfile,我们也可以先用图形编辑,然后在图形编辑保存后(会自动生成内容到Jenkinsfile),再去编辑jenkinsfile。

image-20230306185605704

Jenkinsfile内容示例

// 基本上,按照jenkins的语法编写脚本即可
pipeline {
  agent {
    node {
      label 'maven'
    }
  }

  // 参数设置   TODO:根据自己的情况修改
  parameters {
      string(name: 'demoParamA', defaultValue: 'valueA',  description: '参数示例', trim: true)
      choice(name: 'BRANCH_NAME', choices: ['master', 'develop' , 'test', 'prod'],  description: 'git分支名')
  }

  // 设置变量  TODO:根据自己的情况修改
  environment {
      // 项目中dockerfile文件的相对位置
      DOCKERFILE_PATH = 'deploy/Dockerfile'
      // 镜像仓库
      IMAGE_REGISTRY = '10.8.0.101:1180'
      // 镜像所属项目
      IMAGE_PROJECT = 'library'
      // 应用名称
      APPLICATION_NAME = 'demo'
      // 项目中k8s部署文件的相对位置
      K8S_YAML_PATH = 'deploy/k8s-deploy.yml'
  }

  // 步骤
  stages {
    // 参数确认 TODO:根据自己的情况修改
    stage('参数确认') {
      agent none
      steps {
        container('maven') {
          sh """
              echo '您输入的demoParamA的值是:${demoParamA}'
              echo '您选择的BRANCH_NAME的值是:${BRANCH_NAME}'
          """
          //sh 'echo "您选择的BRANCH_NAME的值是:"${BRANCH_NAME}'
          // 在Jenkins文件中,支持Groovy语法的脚本
          script {
              def tmpParamX = "${params.demoParamA}"
              println "tmpParamX的值为:" + tmpParamX
              tmpParamY = ''
              if("${params.demoParamA}".trim() == "valueA"){
                    tmpParamY = '一二三四五'
              } else if("${params.demoParamA}".trim() != "valueA"){
                    tmpParamY = '上山打老虎'
              }
              println "tmpParamY的值为:" + tmpParamY
              // jenkinsfile中对变量进行引用一般用$,如:$currBranchName, 更多可去搜索引擎上查一下 jenkinsfile对groovy的变量引用
          }
        }
      }
    }

    // 拉取代码 TODO:根据自己的情况修改
    stage('拉取代码') {
      agent none
      steps {
        container('maven') {
          // 这里ds-gitee为拉取代码的凭证id。提前在kubesphere的当前devOps项目下创建好. 就可以知道凭证的id了
          git(url: 'https://gitee.com/JustryDeng/demo.git', branch: '${BRANCH_NAME}', credentialsId: 'ds-gitee', changelog: true, poll: false)
          // 执行多个shell指令
          sh """
            pwd
            ls
          """
        }
      }
    }

    // maven打包
    stage('maven打包') {
      agent none
      steps {
        container('maven') {
          // maven打包
          sh 'mvn clean package -Dmaven.test.skip=true '
        }
      }
    }

    // 构建&推送镜像 TODO:根据自己的情况修改
    stage('构建&推送镜像') {
      agent none
      steps {
        container('maven') {
          // 构建raw镜像
          sh 'docker build -f ${DOCKERFILE_PATH} -t ${IMAGE_REGISTRY}/${IMAGE_PROJECT}/${APPLICATION_NAME}:${BRANCH_NAME}-${BUILD_NUMBER} .'
          // 将当前镜像tag为lastest镜像 (lastest镜像就等于当前raw镜像)
          sh 'docker tag  ${IMAGE_REGISTRY}/${IMAGE_PROJECT}/${APPLICATION_NAME}:${BRANCH_NAME}-${BUILD_NUMBER} ${IMAGE_REGISTRY}/${IMAGE_PROJECT}/${APPLICATION_NAME}:latest'
          // harbor-101是登录镜像仓库的凭证id。提前在kubesphere的当前devOps项目下创建好. 就可以知道凭证的id了
          withCredentials([usernamePassword(credentialsId : 'harbor-101' ,usernameVariable : 'DOCKER_USERNAME' ,passwordVariable : 'DOCKER_PASSWORD' ,)]) {
            // 登录镜像仓库
            sh 'echo "${DOCKER_PASSWORD}" | docker login ${IMAGE_REGISTRY} -u "${DOCKER_USERNAME}"  --password-stdin'
            // 推送raw镜像
            sh 'docker push ${IMAGE_REGISTRY}/${IMAGE_PROJECT}/${APPLICATION_NAME}:${BRANCH_NAME}-${BUILD_NUMBER}'
            // 推送lastest镜像
            sh 'docker push ${IMAGE_REGISTRY}/${IMAGE_PROJECT}/${APPLICATION_NAME}:latest'
          }
        }
      }
    }

    // 部署应用到k8s TODO:根据自己的情况修改
    stage('部署应用到k8s') {
      agent none
      steps {
        container('maven') {
          /*
           * admin-kubeconfig是将应用部署至k8s中的操作用户的凭证的id。提前在kubesphere的当前devOps项目下创建好. 就可以知道凭证的id了
           * 注:此kubeconfig凭证对应的用户,应具备k8s操作权限(如:集群管理员,可以admin登录,然后在 集群管理|集群设置|集群成员 这里进行设置),否则此步可能因为权限问题执行失败.
           *     可以用具有【集群管理员】角色的用户登录kubesphere,然后进入当前devOps下创建kubeconfig凭证
           * 注:生成的kubeconfig凭证中,clusters.cluster.server的值可能导致dns解析失败,此时,可以尝试将值里面的域名换成ip地址,最好同时保证/etc/hosts中有对应的地址配置
           * 注:实在不行,可以直接用超级管理员的kubeconfig凭证. 见:/root/.kube/config
           * 
           * 注:当前kubesphere-v3.3.1版本下,这里用的是kubeconfigFile,其余方式可能有bug
           */
          withCredentials([kubeconfigFile(credentialsId : 'admin-kubeconfig' ,variable : 'KUBECONFIG' ,)]) {
           /*
            * envsubst < xxx.yml: 替换xxx.yml文件中的参数引用为对应的参数值。 
            * 注:上面parameters、environment中定义的变量,一次此步骤设置的variable,都可以被作为参数引用
            * kubectl apply -f -: 部署应用至k8s. 即:根据k8s部署配置文件进行部署
            */ 
            sh 'echo k8s部署文件当前拉取的镜像是:${IMAGE_REGISTRY}/${IMAGE_PROJECT}/${APPLICATION_NAME}:${BRANCH_NAME}-${BUILD_NUMBER}'
            sh 'envsubst < ${K8S_YAML_PATH} | kubectl apply -f -'
          }
        }
      }
    }

  }
}

对应的图形界面长这样

image-20230306190724771

第四步:启动流水线,进行部署

image-20230306190847519

image-20230306190900522

第五步:访问测试

image-20230306190927787

修改应用controller代码,Hello改为Hi

image-20230307093648004

推送代码后,触发流水线部署成功后,然后再次访问:

image-20230307093754573

由此可见,使用kubesphere devOps流水线往k8s中部署应用成功!

1
https://gitee.com/JustryDeng/notebook.git
git@gitee.com:JustryDeng/notebook.git
JustryDeng
notebook
notebook
master

搜索帮助