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

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

1、流程說明

應用構建和發佈流程說明:node

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

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

三、用戶在發佈應用時須要填寫git倉庫地址和分支、服務類型、服務名稱、資源數量、實例個數,肯定後觸發Jenkins自動構建;github

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

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

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

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

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

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

 

2、 安裝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

 

3、 集成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 也會自動刪除,恢復到最初狀態。

 

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

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

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

三、擴展性好,當 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 -> 點擊下載安裝並重啓

 

 

 

4、 部署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 查看日誌。

  

說明:

一、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的設置要與其一致

二、Service相關說明

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

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

3)注意namespace爲repo-nexus

三、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倉庫被分爲了三種:

一、hosted:託管倉庫,私有倉庫,能夠push和pull;

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

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

由於jenkins須要push鏡像,故建立hosted私有倉庫。

 

一、配置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對應的文件夾的大小。

 

二、配置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/

 

 

5、 部署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/

 

一、建立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

 

二、部署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

一、建立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

 

二、部署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

一、建立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

 

二、部署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)便可登陸進入到首頁:

 

  

6、CI/CD部署k8s應用

6.1 流程

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

二、經過 Gitlab 配置的 Jenkins Webhook 觸發 Pipeline 自動構建

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

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

五、而後進行 Maven 構建(Java 項目)

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

七、推送 Docker 鏡像到 Nexus 倉庫

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

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

 

6.2 CI/CD

具體實現參考以下:

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

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

 

 

 

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

相關文章
相關標籤/搜索