DevOps-持续集成持续部署一

DevOps-持续集成持续部署一_第1张图片

JDK 官网: https://www.oracle.com/java/technologies/downloads/#java8-linux

安装JDk

root@vms81:~# cd /opt/
root@vms81:/opt# tar xf jdk-8u333-linux-x64.tar.gz
root@vms81:/opt/jdk1.8.0_333# vim ~/.bashrc
export JAVA_HOME=/opt/jdk1.8.0_333
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.

root@vms81:/opt/jdk1.8.0_333# source ~/.bashrc
root@vms81:/opt/jdk1.8.0_333# java -version
java version "1.8.0_333"
Java(TM) SE Runtime Environment (build 1.8.0_333-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.333-b02, mixed mode)

部署jenkins

war包方式

Jenkins war包:http://mirrors.jenkins.io/war-stable/
java -jar jenkins.war --httpPort=28080

nohup java -jar jenkins.war --httpPort=28080 &

官网:https://www.jenkins.io/zh/download/

容器方式

设置权限

[root@master jenkins]# vim jenkins-clusterRoleBinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: jenkins-clusterRoleBinding
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: jenkins-clusterRole
subjects:
  - kind: ServiceAccount
    name: jenkins-sa
    namespace: jenkins # 默认命名空间下也需要添加此行

[root@master jenkins]# more  jenkins-clusterRole.yaml 
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: jenkins-clusterRole
rules:
  - apiGroups: ["extensions", "apps"]
    resources: ["deployments"]
    verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
  - apiGroups: [""]
    resources: ["services"]
    verbs: ["create", "delete", "get", "list", "watch", "patch", "update"]
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["create","delete","get","list","patch","update","watch"]
  - apiGroups: [""]
    resources: ["pods/exec"]
    verbs: ["create","delete","get","list","patch","update","watch"]
  - apiGroups: [""]
    resources: ["pods/log"]
    verbs: ["get","list","watch"]
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get"]

[root@master jenkins]# more jenkins-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins-sa
  namespace: jenkins
  

挂载

[root@master jenkins]# more jenkins-pvc.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name:  jenkins
  namespace: jenkins
spec:
  resources:
    requests:
      storage: 5Gi
  accessModes:
    - ReadWriteMany
  storageClassName: mysc1       # 提前设置了sc

设置deployment

[root@master jenkins]# more jenkins-deploy.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jenkins-deploy         #deployment名称
  namespace: jenkins
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jenkins
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      terminationGracePeriodSeconds: 10     #优雅停止pod
      serviceAccount: jenkins-sa            #后面还需要创建服务账户
      containers:
      - name: jenkins
        image: jenkins/jenkins:2.346.1-jdk8 #镜像版本(2.346.1默认安装的jdk11版本,如果想安装jdk8可以指定version:2.346.1-jdk8)
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080                #外部访问端口
          name: web
          protocol: TCP
        - containerPort: 50000              #jenkins save发现端口
          name: agent
          protocol: TCP
        resources:
          limits:
            cpu: 2
            memory: 1Gi
          requests:
            cpu: 1
            memory: 512Mi
        livenessProbe:
          httpGet:
            path: /login
            port: 8080
          initialDelaySeconds: 30          #容器初始化完成后,等待30秒进行探针检查
          timeoutSeconds: 5
          failureThreshold: 12          #当Pod成功启动且检查失败时,Kubernetes将在放弃之前尝试failureThreshold次。放弃生存检查意味
着重新启动Pod。而放弃就绪检查,Pod将被标记为未就绪。默认为3.最小值为1
        readinessProbe:
          httpGet:
            path: /login
            port: 8080
          initialDelaySeconds: 30
          timeoutSeconds: 5
          failureThreshold: 12
        volumeMounts:                       #需要将jenkins_home目录挂载出来
        - name: jenkins-home
          mountPath: /var/jenkins_home
        env:
        - name: LIMITS_MEMORY
          valueFrom:
            resourceFieldRef:
              resource: limits.memory
              divisor: 1Mi
        - name: JAVA_OPTS # -Dhudson.model.DownloadService.noSignatureCheck=true 关闭源配置检查,否则换源后可能无法使用
          value: -Xmx$(LIMITS_MEMORY)m -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvis
ioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85 -Duser.timezone=Asia/Shanghai -Dhudson.model.DownloadService.noSignat
ureCheck=true -Dhudson.model.UpdateCenter.updateCenterUrl=https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/
      securityContext:
        fsGroup: 1000
      volumes:
      - name: jenkins-home
        persistentVolumeClaim: 
          claimName: jenkins

设置svc

[root@master jenkins]# more jenkins-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: jenkins-agent
spec:
  selector:
    app: jenkins
  type: NodePort
  ports:
  - name: agent
    port: 50000
    targetPort: agent
---
apiVersion: v1
kind: Service
metadata:
  name: jenkins-web
spec:
  selector:
    app: jenkins
  ports:
  - name: web
    port: 8080
    targetPort: web

设置ingress

[root@master jenkins]# more jenkins-ingress.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: jenkins-web
  namespace: jenkins
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: 域名  
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: jenkins-web
            port:
              number: 8080

创建(apply)所有所需yaml文件

[root@master jenkins]# kubectl apply -f .
clusterrole.rbac.authorization.k8s.io/jenkins-clusterRole created
clusterrolebinding.rbac.authorization.k8s.io/jenkins-clusterRoleBinding created
deployment.apps/jenkins-deploy created
ingress.networking.k8s.io/jenkins-web created
persistentvolumeclaim/jenkins created
serviceaccount/jenkins-sa created
service/jenkins-agent created
service/jenkins-web created

检查

[root@master jenkins]# kubectl get all
NAME                                  READY   STATUS    RESTARTS   AGE
pod/jenkins-deploy-5654789768-vs9w9   1/1     Running   0          14m

NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)           AGE
service/jenkins-agent   NodePort    10.108.161.246   <none>        50000:30524/TCP   14m
service/jenkins-web     ClusterIP   10.101.34.109    <none>        8080/TCP          14m

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/jenkins-deploy   1/1     1            1           14m

NAME                                        DESIRED   CURRENT   READY   AGE
replicaset.apps/jenkins-deploy-5654789768   1         1         1       14m

访问ingress中设置的域名来访问jenkins
DevOps-持续集成持续部署一_第2张图片
密码保存在运行的jenkins容器中

[root@master jenkins]# kubectl exec -it jenkins-deploy-5654789768-vs9w9 -- bash

jenkins@jenkins-deploy-5654789768-vs9w9:/$ cat /var/jenkins_home/secrets/initialAdminPassword
939257093bc24356a7d53fc617259e7c       --------> 初始管理员密码

安装插件(后期更新插件一定要先备份插件–家目录下的plugins文件)
DevOps-持续集成持续部署一_第3张图片

DevOps-持续集成持续部署一_第4张图片
DevOps-持续集成持续部署一_第5张图片
DevOps-持续集成持续部署一_第6张图片
常用插件选择

Active ChoicesVersion         
参数化构建插件  

Blue Ocean                    
pipeline 的可视化UI插件

Convert To PipelineVersion            
将自由风格项目转换为Pipeline项目

Declarative Pipeline Migration Assistant APIVersion 
Declarative Pipeline Migration AssistantVersion
Delivery PipelineVersion
Pipeline项目相关插件

Git ParameterVersion
git参数化构建

Hidden ParameterVersion
Hidden参数化构建

Kubernetes CLIVersion
Kubernetes Client APIVersion
Kubernetes CredentialsVersion
KubernetesVersion
k8s相关插件

List Git Branches ParameterVersion
查看git branches的插件

Parameterized Remote TriggerVersion
Parameterized Trigger plugin
根据已经完成构建的结果,触发新Job或者传递参数

Pipeline相关插件

安装gitlab

下载地址: https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/

[root@worker-2 ~]# wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-15.1.0-ce.0.el7.x86_64.rpm
[root@worker-2 ~]# rpm -ivh gitlab-ce-15.1.0-ce.0.el7.x86_64.rpm
[root@worker-2 ~]# vim  /etc/gitlab/gitlab.rb
external_url 'http://git.域名.com'
[root@worker-2 ~]# gitlab-ctl reconfigure    
一千年以后

关闭不需要的进程

reconfigure  会自动启动进程,
  * runit_service[gitlab-kas] action restart (up to date)
[2022-07-01T16:50:02+08:00] INFO: directory[/var/opt/gitlab/gitlab-workhorse/sockets] sending restart action to runit_service[gitlab-workhorse] (delayed)
Recipe: gitlab::gitlab-workhorse
  * runit_service[gitlab-workhorse] action restart (up to date)
[2022-07-01T16:50:02+08:00] INFO: env_dir[/opt/gitlab/etc/node-exporter/env] sending restart action to runit_service[node-exporter] (delayed)
Recipe: monitoring::node-exporter
  * runit_service[node-exporter] action restart (up to date)
[2022-07-01T16:50:03+08:00] INFO: env_dir[/opt/gitlab/etc/gitlab-exporter/env] sending restart action to runit_service[gitlab-exporter] (delayed)
Recipe: monitoring::gitlab-exporter
  * runit_service[gitlab-exporter] action restart (up to date)
[2022-07-01T16:50:03+08:00] INFO: env_dir[/opt/gitlab/etc/redis-exporter/env] sending restart action to runit_service[redis-exporter] (delayed)
Recipe: monitoring::redis-exporter
  * runit_service[redis-exporter] action restart (up to date)
[2022-07-01T16:50:04+08:00] INFO: env_dir[/opt/gitlab/etc/prometheus/env] sending restart action to runit_service[prometheus] (delayed)
Recipe: monitoring::prometheus
  * runit_service[prometheus] action restart (up to date)
[2022-07-01T16:50:04+08:00] INFO: file[Prometheus config] sending run action to execute[reload prometheus] (delayed)
  * execute[reload prometheus] action run[2022-07-01T16:50:05+08:00] INFO: execute[reload prometheus] ran successfully

    - execute /opt/gitlab/bin/gitlab-ctl hup prometheus
[2022-07-01T16:50:05+08:00] INFO: env_dir[/opt/gitlab/etc/alertmanager/env] sending restart action to runit_service[alertmanager] (delayed)
Recipe: monitoring::alertmanager
  * runit_service[alertmanager] action restart (up to date)
[2022-07-01T16:50:05+08:00] INFO: env_dir[/opt/gitlab/etc/postgres-exporter/env] sending restart action to runit_service[postgres-exporter] (delayed)
Recipe: monitoring::postgres-exporter
  * runit_service[postgres-exporter] action restart (up to date)
[2022-07-01T16:50:06+08:00] INFO: env_dir[/opt/gitlab/etc/grafana/env] sending restart action to runit_service[grafana] (delayed)
Recipe: monitoring::grafana
  * runit_service[grafana] action restart (up to date)
[2022-07-01T16:50:06+08:00] INFO: Chef Infra Client Run complete in 169.994230781 seconds
[root@izbp1bllim99f4pkb4xtetz ~]# gitlab-ctl stop prometheus
ok: down: prometheus: 0s, normally up
[root@izbp1bllim99f4pkb4xtetz ~]# gitlab-ctl stop grafana
ok: down: grafana: 1s, normally up
[root@izbp1bllim99f4pkb4xtetz ~]# gitlab-ctl stop gitlab-exporter
ok: down: gitlab-exporter: 1s, normally up

访问网站(默认账号位root)
DevOps-持续集成持续部署一_第7张图片
如果刷新了页面或者忘记设置密码 ----重新设置密码

[root@izbp1bllim99f4pkb4xtetz ~]# gitlab-rails console -e production
--------------------------------------------------------------------------------
 Ruby:         ruby 2.7.5p203 (2021-11-24 revision f69aeb8314) [x86_64-linux]
 GitLab:       15.1.0 (6bea4379525) FOSS
 GitLab Shell: 14.7.4
 PostgreSQL:   13.6
------------------------------------------------------------[ booted in 17.31s ]
Loading production environment (Rails 6.1.4.7)
irb(main):001:0> user = User.where(id: 1).first 
=> #<User id:1 @root>
irb(main):002:0> user.password =  '密码' 
=> "密码"
irb(main):003:0> user.password_confirmation = '密码'
=> "密码"
irb(main):004:0> user.save!
=> true
irb(main):005:0> exit

导入master的公钥
DevOps-持续集成持续部署一_第8张图片
在gitlab中创建组和项目
DevOps-持续集成持续部署一_第9张图片
DevOps-持续集成持续部署一_第10张图片
gitlab 面密登录

[root@master ~]# more  .gitconfig 
[user]
        email = 邮箱@qq.com
        name = 账户
[credential]
        helper = store
[http]
    sslVerify = false

[root@master ~]# more .git-credentials
https://{username}:{password}@github.com

输入命令
[root@master ~]# git config --global credential.helper store

# 上步操作已经添加了ssh密钥,这边就可以免密提交/拉取

gitlab凭据设置

DevOps-持续集成持续部署一_第11张图片

Jenkins pipeline

Jenkins pipeline语法:https://www.jenkins.io/doc/book/pipeline/syntax/
中文文档:https://www.jenkins.io/zh/doc/book/pipeline/syntax/

参数

参数化构建

尝试1
DevOps-持续集成持续部署一_第12张图片
DevOps-持续集成持续部署一_第13张图片

尝试 2

不勾选使用参数化构建过程

pipeline {
    agent any
    parameters {
        string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
    }
    stages {
        stage('Example') {
            steps {
                echo "Hello ${params.PERSON}"
            }
        }
    }
}

DevOps-持续集成持续部署一_第14张图片

input和options 的用法

pipeline {
    agent any
    options {             # 可以加一行超时参数 单位可以是时分秒(复数)
        timeout(time: 10, unit: 'SECONDS') 
    }
    stages {
        stage('Example') {
            input {
                message "Should we continue?"
                ok "Yes, we should."
                submitter "alice,bob"
                parameters {
                    string(name: 'PERSON', defaultValue: 'Mr Jenkins', description: 'Who should I say hello to?')
                }
            }
            steps {
                echo "Hello, ${PERSON}, nice to meet you."
            }
        }
    }
}

DevOps-持续集成持续部署一_第15张图片
DevOps-持续集成持续部署一_第16张图片
DevOps-持续集成持续部署一_第17张图片

when

内置条件

branch
    当正在构建的分支与模式给定的分支匹配时,执行这个阶段, 例如: when { branch 'master' }。注意,这只适用于多分支流水线。
environment
    当指定的环境变量是给定的值时,执行这个步骤, 例如: when { environment name: 'DEPLOY_TO', value: 'production' }
expression
    当指定的Groovy表达式评估为true时,执行这个阶段, 例如: when { expression { return params.DEBUG_BUILD } }
not
    当嵌套条件是错误时,执行这个阶段,必须包含一个条件,例如: when { not { branch 'master' } }
allOf
    当所有的嵌套条件都正确时,执行这个阶段,必须包含至少一个条件,例如: when { allOf { branch 'master'; environment name: 'DEPLOY_TO', value: 'production' } }
anyOf
    当至少有一个嵌套条件为真时,执行这个阶段,必须包含至少一个条件,例如: when { anyOf { branch 'master'; branch 'staging' } }
在进入 stage 的 agent 前评估 when

默认情况下, 如果定义了某个阶段的代理,在进入该`stage` 的 agent 后该 stage 的 when 条件将会被评估。但是, 可以通过在 when 块中指定 beforeAgent 选项来更改此选项。 如果 beforeAgent 被设置为 true, 那么就会首先对 when 条件进行评估 , 并且只有在 when 条件验证为真时才会进入 agent 。

并行

声明式流水线的阶段可以在他们内部声明多隔嵌套阶段, 它们将并行执行。 注意,一个阶段必须只有一个 steps 或 parallel 的阶段。 嵌套阶段本身不能包含进一步的 parallel 阶段, 但是其他的阶段的行为与任何其他 stage 相同。任何包含 parallel 的阶段不能包含 agent 或 tools 阶段, 因为他们没有相关 steps。

另外, 通过添加 failFast true 到包含 parallel``stage 中, 当其中一个进程失败时,你可以强制所有的 parallel 阶段都被终止。
示例
pipeline {
    agent any
    stages {
        stage('Non-Parallel Stage') {
            steps {
                echo 'This stage will be executed first.'
            }
        }
        stage('Parallel Stage') {
            when {
                branch 'master'
            }
            failFast true
            parallel {                  // parallel下的stage属于同一级的,同时进行
                stage('Branch A') {
                    agent {
                        label "for-branch-a"
                    }
                    steps {
                        echo "On Branch A"
                    }
                }
                stage('Branch B') {
                    agent {
                        label "for-branch-b"
                    }
                    steps {
                        echo "On Branch B"
                    }
                }
            }
        }
    }
}

BlueOcean

用blueocean 创建流水线
DevOps-持续集成持续部署一_第18张图片
选择git仓库后会生成一串ssh密钥,放入gitlab的ssh中,jenkins就可以拉取gitlab的代码
DevOps-持续集成持续部署一_第19张图片
设置流水线
DevOps-持续集成持续部署一_第20张图片
提交到matser
DevOps-持续集成持续部署一_第21张图片
配置jenkins使用jenkinsfile
DevOps-持续集成持续部署一_第22张图片

script 步骤需要 [scripted-pipeline]块并在声明式流水线中执行。 对于大多数用例来说,应该声明式流水线中的“脚本”步骤是不必要的, 但是它可以提供一个有用的"逃生出口"。 非平凡的规模和/或复杂性的 script 块应该被转移到 共享库 。
示例

pipeline {
    agent any
    stages {
        stage('Example') {
            steps {
                echo 'Hello World'

                script {
                    def browsers = ['chrome', 'firefox']
                    for (int i = 0; i < browsers.size(); ++i) {
                        echo "Testing the ${browsers[i]} browser"
                    }
                }
            }
        }
    }
}

jenkins实践

实践(多job调用)

DevOps-持续集成持续部署一_第23张图片
修改jenkinsfile已支持调用job(gitlab-test)
DevOps-持续集成持续部署一_第24张图片
DevOps-持续集成持续部署一_第25张图片
DevOps-持续集成持续部署一_第26张图片
调用成功
DevOps-持续集成持续部署一_第27张图片

你可能感兴趣的:(devops,ci,jenkins)