搭建GitLab服务

        业务管理平台需要将本地的代码上传并进行版本管理,选择搭建gitlab私服较为合理,下面就介绍下在已有kubernetes集群上如何搭建gitlab私服及配置域名提供服务过程。

镜像准备

        选择gitlab-ce镜像,登录dockerhub 搜索 gitlab/gitlab-ce,选择合适版本,这里需要注意的是,由于我们后续要使用gitlab的api集成,在使用api中需要用到access_token,而据官方文档说明,创建永久token能力在15.4之后已不推荐使用,并计划在16.0删除。我们考虑集成的方便性,可能要用到永久的token能力,所以这里选择了15.11.6-ce.0 。可以直接使用dockerhub,考虑拉取速度也可以pull到本地并上传harbor私库。在从dockerhub拉取本地时,如果速度过慢,可以注册阿里云账号,添加加速器,详情参考 Docker镜像加速
        准备好镜像之后,就可以编写kubernetes脚本了,我们要把gitlab的数据和配置进行持久化保存,所以需要创建两个持久卷PVC,分别为gitlab-data和gitlab-config。

数据卷脚本

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: gitlab-data
  namespace: gitlab
  annotations:
    kubesphere.io/creator: aaaaaa
    pv.kubernetes.io/bind-completed: 'yes'
    pv.kubernetes.io/bound-by-controller: 'yes'
    volume.beta.kubernetes.io/storage-provisioner: dev-nfs-storage
  finalizers:
    - kubernetes.io/pvc-protection
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
  volumeName: pvc-15d9ceca-0416-4fa0-a78c-72cc349ff4ea
  storageClassName: managed-nfs-storage
  volumeMode: Filesystem
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: gitlab-config
  namespace: gitlab
  annotations:
    kubesphere.io/creator: aaaaaa
    pv.kubernetes.io/bind-completed: 'yes'
    pv.kubernetes.io/bound-by-controller: 'yes'
    volume.beta.kubernetes.io/storage-provisioner: dev-nfs-storage
  finalizers:
    - kubernetes.io/pvc-protection
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  volumeName: pvc-d7a420ff-6220-49ff-863b-8dfc04cee692
  storageClassName: managed-nfs-storage
  volumeMode: Filesystem

部署脚本

创建部署时,把容器中gitlab的数据(/var/opt/gitlab)和配置(/etc/gitlab)分别挂载到卷 gitlab-data 和 gitlab-config上。同时需要注意的是通过环境变量 GITLAB_ROOT_PASSWORD 来指定默认的root账号登录密码,密码不能含有常见词汇及连续数字,否则创建会失败。gitlab比较耗内存,建议使用8G。

kind: Deployment
apiVersion: apps/v1
metadata:
  name: gitlab15
  namespace: gitlab
  labels:
    app: gitlab15
  annotations:
    deployment.kubernetes.io/revision: '32'
    kubesphere.io/creator: aaaaaa
    kubesphere.io/description: 15.11.6-ce.0
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gitlab15
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: gitlab15
      annotations:
        kubesphere.io/restartedAt: '2023-07-28T02:45:21.829Z'
    spec:
      volumes:
        - name: gitlab-data
          persistentVolumeClaim:
            claimName: gitlab-data
        - name: gitlab-config
          persistentVolumeClaim:
            claimName: gitlab-config
      containers:
        - name: container-rc2xwo
          image: gitlab/gitlab-ce:15.11.6-ce.0 # 这里可以指定上边准备的harbor私库
          ports:
            - name: http-1
              containerPort: 80
              protocol: TCP
          env:
            - name: GITLAB_ROOT_PASSWORD
              value: Xxx@12axxfadfafeetx  #这里是默认密码
          resources:
            limits:
              cpu: '4'
              memory: 8Gi
              nvidia.com/gpu: '0'
            requests:
              nvidia.com/gpu: '0'
          volumeMounts:
            - name: gitlab-data
              mountPath: /var/opt/gitlab
            - name: gitlab-config
              mountPath: /etc/gitlab
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      serviceAccountName: default
      serviceAccount: default
      securityContext: {}
      imagePullSecrets:
        - name: harbor-secret
      schedulerName: default-scheduler
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 25%
      maxSurge: 25%
  revisionHistoryLimit: 10
  progressDeadlineSeconds: 600

服务脚本

        服务中通过标签gitlab15选择上述部署。

kind: Service
apiVersion: v1
metadata:
  name: gitlab-service
  namespace: gitlab
  labels:
    app: gitlab-service
  annotations:
    kubesphere.io/creator: aaaaaa
spec:
  ports:
    - name: http-1
      protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: gitlab15
  clusterIP: xx.xx.xxx.xx  #会自动生成
  clusterIPs:
    -  xx.xx.xxx.xx
  type: ClusterIP
  sessionAffinity: None
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack

路由脚本

        创建Ingress,关联上述服务及端口,Ingress中指定域名为your-host.com.cn。配置之后登陆时即访问该域名。

kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
  name: ai-gitlab
  namespace: gitlab
  annotations:
    kubesphere.io/creator: aaaaaa
    nginx.ingress.kubernetes.io/proxy-body-size: 60M
    nginx.ingress.kubernetes.io/proxy-connect-timeout: '300'
    nginx.ingress.kubernetes.io/proxy-read-timeout: '300'
    nginx.ingress.kubernetes.io/proxy-send-timeout: '300'
spec:
  rules:
    - host: your-host.com.cn  #你的域名
      http:
        paths:
          - path: /
            pathType: ImplementationSpecific
            backend:
              service:
                name: gitlab-service
                port:
                  number: 80

        由于your-host.com.cn是本地域名,需要配置hosts(C:\Windows\System32\drivers\etc\hosts)文件才能访问。hosts文件中添加 集群节点ip和域名的对应关系,如:10.10.5.5 your-host.com.cn

        另外Ingress中要指定请求的body-size,否则上传文件时会报错(Error writing request body to server)。

登录及配置

        上述脚本运行后,正常启动,就可以访问域名http://your-host.com.cn/来登录gitlab了。输入默认用户root和部署时指定的默认密码,即可登录。
在这里插入图片描述
        登录后,我们创建项目,发现项目的clone地址为服务名+部署pod名,而不是我们指定的域名,这时我们需要修改gitlab的配置,登录到docker内部,这里我们直接从集群连接终端即可。找到/etc/gitlab下的gitlab.rb文件,vi gitlab.rb 进行编辑,找到 external_url 取消注释并修改值为 我们的域名 http://your-host.com.cn。这样再次查看项目的下载地址,就已经变更为我们指定的域名了。至此我们在本地(配置了hosts)和gitlab交互(clone,pull,push)都已OK。

GitLab接口及业务微服务上传代码

GitLab接口注意事项

        业务微服务需要通过接口在gitlab上创建用户、组、项目等,需要调用gitlab的API。这里主要注意的是:

  1. 所有api都要使用access_token进行认证。

  2. 创建用户的时候,必须要管理员账号才有权限。(详情参考官网 Users API
    | GitLab

  3. access_token 有有效期,且在16.0及以后的版本,不支持永久有效。(详情参考官网 Project
    access tokens | GitLab

  4. api的地址为域名/api/version/xxx, 如
    http://your-host.com.cn/api/v4/projects (详情参考官网 REST API | GitLab)

业务微服务上传代码注意事项

        上述我们讲到过在本地(即配置了hosts的机器)可以正常操作gitlab本地私库(your-host.com.cn),但是我们在微服务上传和下载代码时,实际是在微服务后端,即微服务所在的pod容器中,那么问题也就来了,这个容器会识别your-host.com.cn吗,肯定是不会的(实际验证也报了错误 java.net.UnknownHostException: your-host.com.cn),那我们怎么让容器能识别呢,也就是怎么能类似在容器的etc/hosts中添加 your-host.com.cn呢?这里我们可以通过kubernetes中的 HostAliases 来添加。在与container同级下增加 HostAliases属性。

在这里插入图片描述

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐