前面已经完成了 二进制部署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、查看服务是否更新成功。