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: [email protected]m
        - 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)即可登录进入到首页:

 

六、Gitlab CI持续集成

参考:https://www.qikqiak.com/k8s-book/docs/65.Gitlab%20CI.html

Gitlab 8.0 开始,Gitlab CI 就已经集成在 Gitlab 中,我们只要在项目中添加一个.gitlab-ci.yml文件,然后添加一个Runner,即可进行持续集成

 

 

 

 

七、CI/CD部署k8s应用

https://www.qikqiak.com/k8s-book/docs/66.devops.html

流程:

1、开发人员提交代码到 Gitlab 代码仓库

2、通过 Gitlab 配置的 Jenkins Webhook 触发 Pipeline 自动构建

3、Jenkins 触发构建构建任务,根据 Pipeline 脚本定义分步骤构建

4、先进行代码静态分析,单元测试

5、然后进行 Maven 构建(Java 项目)

6、根据构建结果构建 Docker 镜像

7、推送 Docker 镜像到 Nexus 仓库

8、触发更新服务阶段,使用 Helm 安装/更新 Release

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

 

 

 

 

 

猜你喜欢

转载自www.cnblogs.com/weavepub/p/10957972.html