Kubernetes+Jenkins+Nexus+Gitlab進行CI/CD集成


 前面已經完成了 二進制部署Kubernetes集群,下面進行CI/CD集成。

一、流程說明

應用構建和發布流程說明:

1、用戶向Gitlab提交代碼,代碼中必須包含Dockerfile;

2、將代碼提交到遠程倉庫;

3、用戶在發布應用時需要填寫git倉庫地址和分支、服務類型、服務名稱、資源數量、實例個數,確定后觸發Jenkins自動構建;

4、Jenkins的CI流水線自動編譯代碼並打包成docker鏡像推送到Nexus鏡像倉庫;

5、Jenkins的CI流水線中包括了自定義腳本,根據我們已准備好的kubernetes的YAML模板,將其中的變量替換成用戶輸入的選項;

6、生成應用的kubernetes YAML配置文件;

7、更新Ingress的配置,根據新部署的應用的名稱,在ingress的配置文件中增加一條路由信息;

8、更新PowerDNS,向其中插入一條DNS記錄,IP地址是邊緣節點的IP地址。關於邊緣節點,請查看邊緣節點配置;

9、Jenkins調用kubernetes的API,部署應用;

 

二、 安裝NFS

部署時候會使用PVC對象,進行掛載,需要有遠程存儲,這里安裝nfs。master1作為nfs服務端,其余node作為nfs客戶端。

2.1 安裝nfs

在所有的節點上安裝

yum install -y nfs-utils rpcbind

 

2.2 配置nfs

只需在master1上配置和啟動,客戶端上安裝即可不用啟動。

mkdir /opt/nfs

vim /etc/exports

/opt/nfs *(rw,sync,no_root_squash)

注意:后期要是修改了/etc/exports這個配置文件,可以使用exportfs -arv命令加載不需重啟。

 

2.3 設置固定端口

只需設置master1防火牆即可,客戶端不用設置

vim /etc/sysconfig/nfs               //在最后添加

RQUOTAD_PORT=4001
LOCKD_TCPPORT=4002
LOCKD_UDPPORT=4002
MOUNTD_PORT=4003
STATD_PORT=4004

#重啟

systemctl enable rpcbind

systemctl enable nfs

systemctl restart rpcbind && systemctl restart nfs

 

2.4 配置防火牆

vim /etc/sysconfig/iptables

-A INPUT -p tcp -m state --state NEW -m tcp --dport 111 -j ACCEPT
-A INPUT -p udp -m state --state NEW -m udp --dport 111 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 2049 -j ACCEPT
-A INPUT -p udp -m state --state NEW -m udp --dport 2049 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 4001:4004 -j ACCEPT
-A INPUT -p udp -m state --state NEW -m udp --dport 4001:4004 -j ACCEPT

#重啟防火牆

service iptables restart && service iptables save

 

2.5 客戶端驗證

showmount -e 172.31.50.170

 

三、 集成Jenkins

參考:https://www.kancloud.cn/huyipow/kubernetes/716441

3.1 流程說明

利用jenkins kubernetes plugin實現動態分配資源構建,Jenkins Master 和 Jenkins Slave 以 Pod 形式運行在 Kubernetes 集群的 Node 上,Master 運行在其中一個節點,並且將其配置數據存儲到一個 Volume 上去,Slave 運行在各個節點上,並且它不是一直處於運行狀態,它會按照需求動態的創建並自動刪除。

這種方式的工作流程大致為:當 Jenkins Master 接受到 Build 請求時,會根據配置的 Label 動態創建一個運行在 Pod 中的 Jenkins Slave 並注冊到 Master 上,當運行完 Job 后,這個 Slave 會被注銷並且這個 Pod 也會自動刪除,恢復到最初狀態。

 

那么我們使用這種方式帶來了哪些好處呢?

1、服務高可用,當 Jenkins Master 出現故障時,Kubernetes 會自動創建一個新的 Jenkins Master 容器,並且將 Volume 分配給新創建的容器,保證數據不丟失,從而達到集群服務高可用。

2、動態伸縮,合理使用資源,每次運行 Job 時,會自動創建一個 Jenkins Slave,Job 完成后,Slave 自動注銷並刪除容器,資源自動釋放,而且 Kubernetes 會根據每個資源的使用情況,動態分配 Slave 到空閑的節點上創建,降低出現因某節點資源利用率高,還排隊等待在該節點的情況。

3、擴展性好,當 Kubernetes 集群的資源嚴重不足而導致 Job 排隊等待時,可以很容易的添加一個 Kubernetes Node 到集群中,從而實現擴展。

 

3.2 創建命名空間

kubectl create namespace kube-ops

  

3.3 創建PV/PVC

將容器的 /var/jenkins_home 目錄掛載到了一個名為 opspvc 的 PVC 對象上面,所以我們同樣還得提前創建一個對應的 PVC 對象,當然我們也可以使用我們前面的 StorageClass 對象來自動創建:(jenkins-pvc.yaml)

vim jenkins-pvc.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: opspv
spec:
  capacity:
    storage: 200Gi
  accessModes:
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Delete
  nfs:
    server: 172.31.50.170
    path: /opt/nfs/jenkins

---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: opspvc
  namespace: kube-ops
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 200Gi

#在master1上的nfs共享目錄里創建jenkins目錄,並賦予權限

mkdir -p /opt/nfs/jenkins

cd /opt/nfs/

chown 1000 jenkins/

 

#創建 PVC 對象

kubectl create -f jenkins-pvc.yaml

 

3.4 配置RBAC權限

給 jenkins 賦予了一些必要的權限,當然如果你對 serviceAccount 的權限不是很熟悉的話,我們給這個 sa 綁定一個 cluster-admin 的集群角色權限也是可以的,當然這樣具有一定的安全風險

vim jenkins-rbac.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: jenkins
  namespace: kube-ops

---

kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: jenkins
  namespace: kube-ops
rules:
  - 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"]

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
  name: jenkins
  namespace: kube-ops
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: jenkins
subjects:
  - kind: ServiceAccount
    name: jenkins
    namespace: kube-ops

#創建 rbac 相關的資源對象:

kubectl create -f jenkins-rbac.yaml

 

3.5 部署Jenkins

mkdir /opt/jenkins -p

cd /opt/jenkins/

#創建部署文件

vim jenkins-deployment.yaml

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: jenkins
  namespace: kube-ops
spec:
  template:
    metadata:
      labels:
        app: jenkins
    spec:
      terminationGracePeriodSeconds: 10
      serviceAccountName: jenkins
      containers:
      - name: jenkins
        image: jenkins/jenkins:lts
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080
          name: web
          protocol: TCP
        - containerPort: 50000
          name: agent
          protocol: TCP
        resources:
          limits:
            cpu: 2000m
            memory: 4Gi
          requests:
            cpu: 1000m
            memory: 2Gi
        livenessProbe:
          httpGet:
            path: /login
            port: 8080
          initialDelaySeconds: 60
          timeoutSeconds: 5
          failureThreshold: 12
        readinessProbe:
          httpGet:
            path: /login
            port: 8080
          initialDelaySeconds: 60
          timeoutSeconds: 5
          failureThreshold: 12
        volumeMounts:
        - name: jenkinshome
          subPath: jenkins
          mountPath: /var/jenkins_home
        env:
        - name: LIMITS_MEMORY
          valueFrom:
            resourceFieldRef:
              resource: limits.memory
              divisor: 1Mi
        - name: JAVA_OPTS
          value: -Xmx$(LIMITS_MEMORY)m -XshowSettings:vm -Dhudson.slaves.NodeProvisioner.initialDelay=0 -Dhudson.slaves.NodeProvisioner.MARGIN=50 -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85 -Duser.timezone=Asia/Shanghai
      securityContext:
        fsGroup: 1000
      volumes:
      - name: jenkinshome
        persistentVolumeClaim:
          claimName: opspvc

---
apiVersion: v1
kind: Service
metadata:
  name: jenkins
  namespace: kube-ops
  labels:
    app: jenkins
spec:
  selector:
    app: jenkins
  ports:
  - name: web
    port: 8080
    targetPort: web
  - name: agent
    port: 50000
    targetPort: agent

使用默認的官方鏡像就行。一切准備的資源准備好過后,我們直接創建 Jenkins 服務:

kubectl create -f jenkins-deployment.yaml

 

創建完成后,要去拉取鏡像可能需要等待一會兒,然后我們查看下 Pod 的狀態:

kubectl get svc,pod -n kube-ops -o wide

 

如果報錯:

Can not write to /var/jenkins_home/copy_reference_file.log. Wrong volume permissions?

touch: cannot touch '/var/jenkins_home/copy_reference_file.log': Permission denied

參考解決:http://www.voidcn.com/article/p-dkiuxvuo-bpy.html

 

3.6 配置Ingress

最后為了方便我們測試,我們這里通過 ingress的形式來訪問Jenkins 的 web 服務,Jenkins 服務端口為8080,50000 端口為agent,這個端口主要是用於 Jenkins 的 master 和 slave 之間通信使用的。

vim jenkins-ingress.yaml

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: jenkins-ingress
  namespace: kube-ops
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: jenkins.weave.pub
    http:
      paths:
      - backend:
          serviceName: jenkins
          servicePort: 8080

最后創建ingress 路由服務,需等創建jenkins服務后再創建

kubectl apply -f jenkins-ingress.yaml

kubectl get ingress -o wide -n kube-ops

 

3.7 訪問Jenkins UI

需要在win機器hosts里指定ingress地址到該域名:

172.31.55.50 jenkins.weave.pub

然后瀏覽器訪問jenkins.weave.pub,如下:

進入容器查看密碼:

kubectl exec jenkins-66598b574-gfjbt -n kube-ops -- cat /var/jenkins_home/secrets/initialAdminPassword

也可以直接在 nfs 的共享數據目錄中查看:

cat /opt/nfs/jenkins/secret/initAdminPassword

 

然后粘貼繼續,最后選擇推薦的插件安裝即可。

 

3.8 配置Jenkins Slave

接下來我們就需要來配置 Jenkins,讓他能夠動態的生成Slave的Pod。jenkins依賴插件清單:kubernetes、managed scripts。

第1步: 我們需要安裝kubernetes plugin, 點擊 系統管理 -> 插件管理 -> Available -> Kubernetes勾選安裝即可。

 

 

第2步: 安裝完畢后,點擊 系統管理 -> 系統設置 -> (拖到最下方)新增一個雲 -> 選擇 Kubernetes,然后填寫 Kubernetes 和 Jenkins 配置信息。

說明:

1)Kubernetes 地址:https://kubernetes.default.svc.cluster.local,

2)Kubernetes 命名空間填 kube-ops,然后點擊連接測試,如果出現 Connection test successful 的提示信息證明Jenkins 已經可以和 Kubernetes 系統正常通信了。

3)Jenkins URL地址:http://jenkins2.kube-ops.svc.cluster.local:8080 這里的格式為:服務名.namespace.svc.cluster.local:8080,根據上面創建的jenkins的服務名填寫。

 

第3步: 配置 Pod Template,其實就是配置 Jenkins Slave 運行的 Pod 模板,命名空間我們同樣是用kube-ops,Labels 這里也非常重要,對於后面執行 Job 的時候需要用到該值,然后我們這里使用的是 cnych/jenkins:jnlp 這個鏡像,這個鏡像是在官方的 jnlp 鏡像基礎上定制的,加入了 kubectl 等一些實用的工具。

 

還需要在下面掛載一個主機目錄,一個是 /var/run/docker.sock,該文件是用於 Pod 中的容器能夠共享宿主機的 Docker,這就是大家說的 docker in docker 的方式,Docker二進制文件我們已經打包到上面的鏡像中了。

 

如果在slave agent中想要訪問kubernetes 集群中其他資源,我們還需要綁定之前創建的Service Account 賬號:jenkins,點擊高級可以看到Service Account選項。

到這里我們的 Kubernetes 插件就算配置完成了。點擊保存即可。

 

3.9 測試構建

Kubernetes 插件的配置工作完成了,接下來我們就來添加一個 Job 任務,看是否能夠在 Slave Pod 中執行,任務執行完成后看 Pod 是否會被銷毀。

1) Jenkins 首頁點擊新建任務,輸入任務名稱haimaxy-jnlp-slave-demo,然后我們選擇:構建一個自由風格的軟件項目。點擊確定

 

注意:在下面的 標簽表達式 這里要填入haimaxy-jnlp,就是前面我們配置的 Slave Pod 中的 Label,這兩個地方必須保持一致。

 

2)然后往下拉,在 構建 區域選擇執行shell,輸入如下:

echo "測試 Kubernetes 動態生成 jenkins slave"
echo "==============docker in docker==========="
docker info
 
echo "=============kubectl============="
kubectl get pods -n kube-ops

 

3)點擊保存,直接在頁面點擊 立即構建 觸發構建即可。

 

4)然后觀察 Kubernetes 集群中增加了jnlp名字的pod

kubectl get pods -n kube-ops -o wide

同樣也可以查看到對應的控制台信息:

 

5)任務已經構建完成后,然后這個時候我們再去集群查看我們的 Pod 列表,發現 kube-ops 這個 namespace 下面已經沒有之前的 Slave 這個 Pod 了。

到這里我們就完成了使用 Kubernetes 動態生成 Jenkins Slave 的方法。

  

3.10 安裝BlueOcean

BlueOcean 是 Jenkins 團隊從用戶體驗角度出發,專為 Jenkins Pipeline 重新設計的一套 UI 界面,仍然兼容以前的 fressstyle 類型的 job,BlueOcean 具有以下的一些特性:

1)連續交付(CD)Pipeline 的復雜可視化,允許快速直觀的了解 Pipeline 的狀態

2)可以通過 Pipeline 編輯器直觀的創建 Pipeline

3)需要干預或者出現問題時快速定位,BlueOcean 顯示了 Pipeline 需要注意的地方,便於異常處理和提高生產力

4)用於分支和拉取請求的本地集成可以在 GitHub 或者 Bitbucket 中與其他人進行代碼協作時最大限度提高開發人員的生產力。

 

BlueOcean 可以安裝在現有的 Jenkins 環境中,也可以使用 Docker 鏡像的方式直接運行,我們這里直接在現有的 Jenkins 環境中安裝 BlueOcean 插件:登錄 Jenkins Web UI -> 點擊左側的 Manage Jenkins -> Manage Plugins -> Available -> 搜索查找 BlueOcean -> 點擊下載安裝並重啟

 

 

 

四、 部署Nexus

參考:https://www.jianshu.com/p/cc4817e014df

4.1 創建命名空間

為了方便Kubernetes中的資源管理,通常針對項目將各種資源划分布到不同的Namespace中,所以我們創建一個名為repo-nexus的命名空間。

mkdir /opt/nexus

cd /opt/nexus 

cat >repo-nexus-ns.yaml <<EOF
apiVersion: v1
kind: Namespace
metadata:
   name: repo-nexus
   labels:
     name: repo-nexus
EOF

#使用命令,應用配置

kubectl apply -f repo-nexus-ns.yaml

  

4.2 創建PV/PVC

在Kubernetes中,數據存儲方式有很多,這里選擇了PV/PVC的形式,然后將實際產生的數據保存在單獨的一台NFS機器上。創建PV/PVC的配置文件:

cat >repo-nexus-data.yaml <<EOF
---
# pv

apiVersion: v1
kind: PersistentVolume
metadata:
  name: repo-nexus-pv
spec:
  capacity:
    storage: 100Gi
  accessModes:
    - ReadWriteMany
  nfs:
       server: 172.31.50.170
       path: "/opt/nfs/repo-nexus"

---
# pvc

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: repo-nexus-pvc
  namespace: repo-nexus
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: ""
  resources:
    requests:
      storage: 100Gi
EOF

在master1上的nfs共享目錄里創建repo-nexus目錄,並賦予權限(無論使用任何存儲方式,只要使用nexus3的官方鏡像,都要將最后的實際存儲目錄進行授權操作,否則pod啟動會報錯目錄無權限或無法寫入文件的錯誤。)

mkdir -p /opt/nfs/repo-nexus

cd /opt/nfs/

chown -R 200 repo-nexus/

 

#創建 PVC 對象

kubectl create -f repo-nexus-data.yaml

 

#查看

kubectl get pv,pvc --all-namespaces

 

4.3 部署Nexus

我們需要創建Deployment、Service和Ingress三部分資源來進行部署。首先我們創建配置文件:

cat >repo-nexus.yaml <<EOF
---
# deployment

kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    app: repo-nexus
  name: repo-nexus
  namespace: repo-nexus
spec:
  replicas: 1
  selector:
    matchLabels:
      app: repo-nexus
  template:
    metadata:
      labels:
        app: repo-nexus
    spec:
      containers:
        - name: repo-nexus
          image: sonatype/nexus3:latest
          imagePullPolicy: IfNotPresent
          resources:
            limits:
              memory: "4Gi"
              cpu: "1000m"
            requests:
              memory: "2Gi"
              cpu: "500m"
          ports:
          - containerPort: 8081
            protocol: TCP
          volumeMounts:
          - name: repo-nexus-data
            mountPath: /nexus-data
      volumes:
        - name: repo-nexus-data
          persistentVolumeClaim:
            claimName: repo-nexus-pvc

---
# service

kind: Service
apiVersion: v1
metadata:
  labels:
    app: repo-nexus
  name: repo-nexus
  namespace: repo-nexus
spec:
  ports:
    - port: 8081
      targetPort: 8081
  selector:
    app: repo-nexus

---
# ingress

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: repo-nexus
  namespace: repo-nexus
spec:
  rules:
  - host: nexus.weave.pub
    http:
      paths:
      - path: /
        backend:
          serviceName: repo-nexus
          servicePort: 8081
EOF

注意:更加詳細的yaml文件,參考:https://github.com/travelaudience/kubernetes-nexus/blob/master/kubernetes/nexus-statefulset.yaml

 

#部署應用

kubectl apply -f repo-nexus.yaml

 

#查看

kubectl get svc,pod,ingress -n repo-nexus -o wide

如果報錯,可以執行 kubectl logs -n repo-nexus repo-nexus-674ff69854-j7spt 查看日志。

  

說明:

1、Deployment相關說明

1)在這里使用官方鏡像,sonatype/nexus3:latest,如果拉取失敗可以先手動拉取。

2)參考官方docker鏡像說明文檔(https://hub.docker.com/r/sonatype/nexus3/),我們可以看出映射出來的端口號是8081,所以我們在這里將containerPort設置為8081。

3)同樣,因為官方文檔中指出,鏡像所使用的數據全部掛載了運行時容器的/nexus-data目錄下,所以我們將template/spec/containers/volumeMounts/mountPath設置成了/nexus-data

4)因為我們在上一步驟中,創建的PVC名稱為repo-nexus-pvc,所以這里要注意template/spec/volumes/persistentVolumeClaim/claimName的設置要與其一致

2、Service相關說明

1)注意spec/port/targetPort要設置成8081,與容器實際端口保持一致

2)這里為了方便記憶,將service的port也設置成了8081

3)注意namespace為repo-nexus

3、Ingress相關說明

這里我直接使用了域名host做區分,所以path設置成了/,你也可以根據自身的實際情況進行設置

 

4.4 訪問Nexus UI

需要在win機器hosts里指定ingress地址到該域名:

172.31.55.50 nexus.weave.pub

然后瀏覽器訪問 nexus.weave.pub 登入,默認賬號密碼:admin/admin123(我修改為Admin123),界面如下:

  

4.5 創建Docker倉庫

在Nexus中Docker倉庫被分為了三種:

1、hosted:托管倉庫,私有倉庫,可以push和pull;

2、proxy:代理和緩存遠程倉庫,如maven中央倉庫,只能pull;

3、group:將proxy和hosted倉庫添加到一個組,只訪問一個組地址即可,如配置maven依賴倉庫組,只能pull。

因為jenkins需要push鏡像,故創建hosted私有倉庫。

 

1、配置Blob Stores

依次點擊管理BUTTON -> Repository ->Blob Stores-> Create blob stores

容器啟動的nexus,這樣Path就是對應容器里面的路徑/nexus-data/blobs/docker,而容器的路徑我是做了nfs持久化存儲,這樣就是在nfs主機上的/opt/nfs/repo-nexus/blobs/docker目錄了。

#在nfs主機上查看

一旦創建了blob store,就不可修改類型和名稱。而且,該blob store被倉庫或者倉庫組使用后,都不可以被刪除。一個倉庫只可以使用一個Blob Store,一個Blob Store可以對應多個倉庫。Blob store的大小為Path對應的文件夾的大小。

 

2、配置Repositories

依次點擊管理BUTTON -> Repository -> Repositories -> Create Repository -> Docker(hosted), 然后在彈出的頁面中填寫如下信息。

這樣就創建好了一個私有倉庫。訪問地址即 為nexus.weave.pub:6000

  

4.6 測試倉庫可用

參考:https://www.hifreud.com/2018/06/05/02-nexus-docker-repository/

 

 

五、 部署Gitlab

本節將 Gitlab 安裝到 Kubernetes 集群中,參考:https://www.qikqiak.com/k8s-book/docs/64.Gitlab.html

Gitlab官方提供了 Helm 的方式在 Kubernetes 集群中來快速安裝,但是在使用的過程中發現 Helm 提供的 Chart 包中有很多其他額外的配置,所以這里使用自定義的方式來安裝,也就是自己來定義一些資源清單文件。

Gitlab主要涉及到3個應用:Redis、Postgresql、Gitlab 核心程序,實際上我們只要將這3個應用分別啟動起來,然后加上對應的配置就可以很方便的安裝 Gitlab 了。如果已經有可使用的 Redis 或 Postgresql 服務的話,那么直接配置在 Gitlab 環境變量中即可,如果沒有的話就單獨部署。

 

5.1 部署Redis

參考:https://github.com/dotbalo/k8s/tree/master/gitlab,資源清單文件

mkdir /opt/gitlab

cd /opt/gitlab/

 

1、創建PV/PVC的配置文件:

cat >gitlab-redis-pv.yaml <<EOF
---
# pv

apiVersion: v1
kind: PersistentVolume
metadata:
  name: gitlab-redis-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
       server: 172.31.50.170
       path: "/opt/nfs/gitlab-redis"

---
# pvc

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: gitlab-redis-pvc
  namespace: kube-ops
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: ""
  resources:
    requests:
      storage: 10Gi
EOF

#在master1上的nfs共享目錄里創建gitlab-redis目錄

mkdir -p /opt/nfs/gitlab-redis

#創建 PVC 對象

kubectl create -f gitlab-redis-pv.yaml

 

2、部署gitlab-redis

vim gitlab-redis.yaml

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: redis
  namespace: kube-ops
  labels:
    name: redis
spec:
  template:
    metadata:
      name: redis
      labels:
        name: redis
    spec:
      containers:
      - name: redis
        image: sameersbn/redis
        imagePullPolicy: IfNotPresent
        ports:
        - name: redis
          containerPort: 6379
        volumeMounts:
        - mountPath: /var/lib/redis
          name: data
        livenessProbe:
          exec:
            command:
            - redis-cli
            - ping
          initialDelaySeconds: 30
          timeoutSeconds: 5
        readinessProbe:
          exec:
            command:
            - redis-cli
            - ping
          initialDelaySeconds: 5
          timeoutSeconds: 1
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: gitlab-redis-pvc

---
apiVersion: v1
kind: Service
metadata:
  name: redis
  namespace: kube-ops
  labels:
    name: redis
spec:
  ports:
    - name: redis
      port: 6379
      targetPort: redis
  selector:
    name: redis

#應用部署

kubectl create -f gitlab-redis.yaml

  

5.2 部署Postgresql

1、創建PV/PVC的配置文件:

cat >gitlab-postgresql-pv.yaml <<EOF
---
# pv

apiVersion: v1
kind: PersistentVolume
metadata:
  name: gitlab-postgresql-pv
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteMany
  nfs:
       server: 172.31.50.170
       path: "/opt/nfs/gitlab-postgresql"

---
# pvc

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: gitlab-postgresql-pvc
  namespace: kube-ops
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: ""
  resources:
    requests:
      storage: 10Gi
EOF

#在master1上的nfs共享目錄里創建gitlab-postgresql目錄

mkdir -p /opt/nfs/gitlab-postgresql

#創建 PVC 對象

kubectl create -f gitlab-postgresql-pv.yaml

 

2、部署postgresql

vim gitlab-postgresql.yaml

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: postgresql
  namespace: kube-ops
  labels:
    name: postgresql
spec:
  template:
    metadata:
      name: postgresql
      labels:
        name: postgresql
    spec:
      containers:
      - name: postgresql
        image: sameersbn/postgresql:10
        imagePullPolicy: IfNotPresent
        env:
        - name: DB_USER
          value: gitlab
        - name: DB_PASS
          value: passw0rd
        - name: DB_NAME
          value: gitlab_production
        - name: DB_EXTENSION
          value: pg_trgm
        ports:
        - name: postgres
          containerPort: 5432
        volumeMounts:
        - mountPath: /var/lib/postgresql
          name: data
        livenessProbe:
          exec:
            command:
            - pg_isready
            - -h
            - localhost
            - -U
            - postgres
          initialDelaySeconds: 30
          timeoutSeconds: 5
        readinessProbe:
          exec:
            command:
            - pg_isready
            - -h
            - localhost
            - -U
            - postgres
          initialDelaySeconds: 5
          timeoutSeconds: 1
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: gitlab-postgresql-pvc

---
apiVersion: v1
kind: Service
metadata:
  name: postgresql
  namespace: kube-ops
  labels:
    name: postgresql
spec:
  ports:
    - name: postgres
      port: 5432
      targetPort: postgres
  selector:
    name: postgresql

#應用部署

kubectl create -f gitlab-postgresql.yaml

  

5.3 部署Gitlab

1、創建PV/PVC的配置文件

cat >gitlab-gitlab-pv.yaml <<EOF
---
# pv

apiVersion: v1
kind: PersistentVolume
metadata:
  name: gitlab-gitlab-pv
spec:
  capacity:
    storage: 100Gi
  accessModes:
    - ReadWriteMany
  nfs:
       server: 172.31.50.170
       path: "/opt/nfs/gitlab-gitlab"

---
# pvc

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: gitlab-gitlab-pvc
  namespace: kube-ops
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: ""
  resources:
    requests:
      storage: 100Gi
EOF

在master1上的nfs共享目錄里創建gitlab-gitlab目錄

mkdir -p /opt/nfs/gitlab-gitlab

#創建 PVC 對象

kubectl create -f gitlab-gitlab-pv.yaml

 

2、部署gitlab

vim gitlab-gitlab.yaml

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: gitlab
  namespace: kube-ops
  labels:
    name: gitlab
spec:
  template:
    metadata:
      name: gitlab
      labels:
        name: gitlab
    spec:
      containers:
      - name: gitlab
        image: sameersbn/gitlab:11.8.1
        imagePullPolicy: IfNotPresent
        env:
        - name: TZ
          value: Asia/Shanghai
        - name: GITLAB_TIMEZONE
          value: Beijing
        - name: GITLAB_SECRETS_DB_KEY_BASE
          value: long-and-random-alpha-numeric-string
        - name: GITLAB_SECRETS_SECRET_KEY_BASE
          value: long-and-random-alpha-numeric-string
        - name: GITLAB_SECRETS_OTP_KEY_BASE
          value: long-and-random-alpha-numeric-string
        - name: GITLAB_ROOT_PASSWORD
          value: Admin123
        - name: GITLAB_ROOT_EMAIL
          value: weavepub@gmail.com
        - name: GITLAB_HOST
          value: gitlab.weave.pub
        - name: GITLAB_PORT
          value: "80"
        - name: GITLAB_SSH_PORT
          value: "22"
        - name: GITLAB_NOTIFY_ON_BROKEN_BUILDS
          value: "true"
        - name: GITLAB_NOTIFY_PUSHER
          value: "false"
        - name: GITLAB_BACKUP_SCHEDULE
          value: daily
        - name: GITLAB_BACKUP_TIME
          value: 01:00
        - name: DB_TYPE
          value: postgres
        - name: DB_HOST
          value: postgresql
        - name: DB_PORT
          value: "5432"
        - name: DB_USER
          value: gitlab
        - name: DB_PASS
          value: passw0rd
        - name: DB_NAME
          value: gitlab_production
        - name: REDIS_HOST
          value: redis
        - name: REDIS_PORT
          value: "6379"
        ports:
        - name: http
          containerPort: 80
        - name: ssh
          containerPort: 22
        volumeMounts:
        - mountPath: /home/git/data
          name: data
        livenessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 180
          timeoutSeconds: 5
        readinessProbe:
          httpGet:
            path: /
            port: 80
          initialDelaySeconds: 5
          timeoutSeconds: 1
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: gitlab-gitlab-pvc

---
apiVersion: v1
kind: Service
metadata:
  name: gitlab
  namespace: kube-ops
  labels:
    name: gitlab
spec:
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: ssh
      port: 22
      targetPort: ssh
  selector:
    name: gitlab

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: gitlab
  namespace: kube-ops
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: gitlab.weave.pub
    http:
      paths:
      - backend:
          serviceName: gitlab
          servicePort: http

注意:標黃為root賬戶的初始密碼,郵箱,訪問主機。

#應用部署

kubectl create -f gitlab-gitlab.yaml

  

5.4 訪問Gitlab UI

需要在win機器hosts里指定ingress地址到該域名:

172.31.55.50 gitlab.weave.pub

然后瀏覽器訪問 gitlab.weave.pub,如下:

 

使用用戶名 root,和部署的時候指定的超級用戶密碼GITLAB_ROOT_PASSWORD=Admin123(默認密碼是admin321)即可登錄進入到首頁:

 

  

六、CI/CD部署k8s應用

6.1 流程

1、開發人員提交代碼到 Gitlab 代碼倉庫

2、通過 Gitlab 配置的 Jenkins Webhook 觸發 Pipeline 自動構建

3、Jenkins 觸發構建構建任務,根據 Pipeline 腳本定義分步驟構建

4、先進行代碼靜態分析,單元測試

5、然后進行 Maven 構建(Java 項目)

6、根據構建結果構建 Docker 鏡像

7、推送 Docker 鏡像到 Nexus 倉庫

8、觸發更新服務階段,使用 Helm 安裝/更新 Release

9、查看服務是否更新成功。

 

6.2 CI/CD

具體實現參考如下:

Rancher 構建 CI/CD 自動化流程 - 動態配置 Jenkins-slave(一)

Rancher 構建 CI/CD 自動化流程 - 動態配置 Jenkins-slave(二)

 

 

 

本文參考:https://www.qikqiak.com/k8s-book/docs/66.devops.html 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM