天天看點

【Kubernetes系列】第7篇 CI/CD之元件部署

前言

應對靈活開發的需求,對CI(持續內建))/CD(持續傳遞)的提出了更高的标準,今天來讨論下,如何基于開源元件(gitlab/jenkins/harbor/kubernetes)使用CI/CD,賦能團隊的開發、運維。

核心元件

元件名稱 版本 備注
kubernetes v1.15.3 10.0.0.182:6443
jenkins 2.176.2 叢集内部署/ namespace: devops
gitlab 11.8 主機部署
harbor v1.7.4 docker-compose部署

基本流程

  1. 在GitLab建立對應的項目。
  2. 開發者将代碼送出到GitLab。
  3. Jenkins建立對應的任務(Job),內建該項目的Git位址和Kubernetes叢集。
  4. 如有配置鈎子,推送(Push)代碼會自動觸發Jenkins建構,如沒有配置鈎子,需要手動建構。
  5. Jenkins控制Kubernetes(使用的是Kubernetes插件)建立Jenkins Slave。
  6. Jenkins Slave根據流水線(Pipeline)定義的步驟執行建構。
    1. 檢出代碼、打包、編譯。
    2. 通過Dockerfile生成鏡像。
    3. 将鏡像提送(Push)到私有Harbor。
    4. Jenkins再次控制Kubernetes進行最新的鏡像部署。

__注__:

  • 上面所述為一般步驟,中間還可能會涉及自動化測試等步驟,可自行根據業務場景添加。
  • 上面流水線步驟一般由應用代碼庫的根目錄下Jenkinsfile決定,Jenkins會自動讀取該檔案;另外如果需要對具體的應用流水線實施強管控,可以獨立管理jenkinsfile模闆,然後根據jenkins API接口即時生成流水線。
  • 預設使用的Dockerfile放置在代碼倉庫的根目錄下。

元件部署

1.Kubernetes

【Kubernetes系列】第3篇 Kubernetes叢集安裝部署
  1. 無忌過招:手把手教你搭建自己的GitLab庫
  2. 安裝配置指南

_注_: 本文主要說明下jenkins的部署及配置,其他元件如果你部署有問題,歡迎留言。

Jenkins 部署及配置

_說明_:

  • 以下的yaml檔案均在 k8s master節點的 /home/jenkins_deploy目錄下,
  • 部署示例的depployment.yaml 的注解
    • nodeName ipaddress

      , ipaddress 請确認其為一個有效的ip.
    • 示例中jenkins的目錄

      /var/jenkins_home

      是直接挂載到host_path, 如果你有條件,建議替換為共享存儲。
    • 因使用的jenkins-master 的基礎鏡像來自公網,需要k8s maste 節點也要可以通路外網,或者你可以将

      jenkins/jenkins:lts-alpine

      推送至自己的内網鏡像倉庫。
  • 部署示例的ingress.yaml 的注解
    • 需要你也需要辦公網(叢集外)通路,請将

      jenkins.dev.hanker.net

      , 改為有效的域名位址,或是你也可以通過

      NodePort

      的形式聲明 service,就可以直接通過

      ip:port

      的形式通路jenkins了。

1. 準備部署yaml

  • deployment.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: devops
  
# Deployment 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: jenkins
  namespace: devops
spec:
  replicas: 1
  revisionHistoryLimit: 3
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      nodeName: 1.1.1.1
      serviceAccountName: jenkins-admin
      containers:
      - image: jenkins/jenkins:lts-alpine
        imagePullPolicy: IfNotPresent
        name: jenkins
        volumeMounts:
        - name: jenkins-volume
          mountPath: /var/jenkins_home
        - name: jenkins-localtime
          mountPath: /etc/localtime
        env:
          - name: JAVA_OPTS
            value: '-Xms256m -Xmx1024m -Duser.timezone=Asia/Shanghai'
          - name: TRY_UPGRADE_IF_NO_MARKER
            value: 'true'
        ports:
        - name: http
          containerPort: 8080
        - name: agent
          containerPort: 50000
        resources:
          requests:
            cpu: 1000m
            memory: 1Gi
          limits:
            cpu: 1200m
            memory: 2Gi
      volumes:
        - name: jenkins-localtime
          hostPath:
            path: /etc/localtime
        - name: jenkins-volume
          hostPath:
            path: /home/jenkins/jenkins_home           
  • 配置service, services.yaml
---
apiVersion: v1
kind: Service
metadata:
  name: jenkins-service
  namespace: devops
spec:
  ports:
  - name: http
    protocol: TCP
    port: 8080
    targetPort: 8080
  - port: 50000
    targetPort: 50000
    name: agent
  selector:
    app: jenkins           
  • 授權jenkins對k8s的通路 rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    k8s-app: jenkins
  name: jenkins-admin
  namespace: devops

---

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
  name: jenkins-rbac
  namespace: devops
rules:
  - apiGroups: ["","extensions","app"]
    resources: ["pods","pods/exec","deployments","replicasets"]
    verbs: ["get","list","watch","create","update","patch","delete"]

---

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: jenkins-admin
  namespace: devops
  labels:
    k8s-app: jenkins
subjects:
  - kind: ServiceAccount
    name: jenkins-admin
    namespace: devops
roleRef:
  kind: ClusterRole
  name: jenkins-rbac
  apiGroup: rbac.authorization.k8s.io           
  • 為了便于辦公網(叢集外)通路,ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: jenkins-ingress
  namespace: devops
spec:
  rules:
  - host: jenkins.dev.hanker.net
    http:
      paths:
      - backend:
          serviceName: jenkins-service
          servicePort: 8080
        path: /           

2. 應用yaml,部署jenkins

$ pwd
$ /home/jenkins_deploy
$ kubectl apply -f *.yaml           

3. 确認jenkins 服務狀态

[root@node0 jenkins_deploy]# kubectl -n devops get deployment jenkins
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
jenkins   1/1     1            1           51d
[root@node0 jenkins_deploy]#            

4. 通路jenkins 安裝插件、設定

注: 步驟1 聲明的域名

jenkins.dev.hanker.net

已經解析至ingress,故可直接通路; 如果你也想通過自定義域名通路jenkins,麻請解析至正确的ingress服務節點,即可。

  1. 确認你也已經安裝了kubernetes/ kubernetes cli 插件

_操作指引_: 【Manage Jenkins】 -> 【Manage Plugins】

你應該可以通過類似的指令擷取jenkins-master的密碼

$ kubectl -n devops exec jenkins-pod-name cat /var/jenkins_home/secrets/initialAdminPassword           
【Kubernetes系列】第7篇 CI/CD之元件部署
  1. 配置Kubernetes 插件

_操作指引_: 【Manage Jenkins】->【Configure System】

【Kubernetes系列】第7篇 CI/CD之元件部署
【Kubernetes系列】第7篇 CI/CD之元件部署

圖中标注:

  1. 請修改為你所在環境對應的k8s master
  2. 聲明jenkins-agent 的指令空間,也可以根據需要調整;
  3. jenkins-master的通路位址,本示例使用的是 service-name的形式通路。
  4. 測試與k8s分享群的連接配接情況。如果你擷取到『

    Connection test successful』,恭喜你可以繼續。

  5. 配置Kubernetes Pod Template
【Kubernetes系列】第7篇 CI/CD之元件部署
  1. 設定基礎的jenkins-agent鏡像;
  2. 指定工作目錄;
    • 如果你需要下載下傳、導出或是緩存建構的話,指定一個為共享存儲的目錄就很有意義了。
  3. 設定目錄挂載
    • 如步驟2如說,你可以将主控端的目錄或是網絡存儲挂載至jenkins-agent.