前面已经完成了 二进制部署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=
LOCKD_TCPPORT=
LOCKD_UDPPORT=
MOUNTD_PORT=
STATD_PORT=

#重启

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  -j ACCEPT
-A INPUT -p udp -m state --state NEW -m udp --dport -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport -j ACCEPT
-A INPUT -p udp -m state --state NEW -m udp --dport -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport : -j ACCEPT
-A INPUT -p udp -m state --state NEW -m udp --dport : -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:
serviceAccountName: jenkins
containers:
- name: jenkins
image: jenkins/jenkins:lts
imagePullPolicy: IfNotPresent
ports:
- containerPort:
name: web
protocol: TCP
- containerPort:
name: agent
protocol: TCP
resources:
limits:
cpu: 2000m
memory: 4Gi
requests:
cpu: 1000m
memory: 2Gi
livenessProbe:
httpGet:
path: /login
port:
initialDelaySeconds:
timeoutSeconds:
failureThreshold:
readinessProbe:
httpGet:
path: /login
port:
initialDelaySeconds:
timeoutSeconds:
failureThreshold:
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= -Dhudson.slaves.NodeProvisioner.MARGIN= -Dhudson.slaves.NodeProvisioner.MARGIN0=0.85 -Duser.timezone=Asia/Shanghai
securityContext:
fsGroup:
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:
targetPort: web
- name: agent
port:
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:

最后创建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:
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:
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:
targetPort:
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:
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:
volumeMounts:
- mountPath: /var/lib/redis
name: data
livenessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds:
timeoutSeconds:
readinessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds:
timeoutSeconds:
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:
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:
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:
volumeMounts:
- mountPath: /var/lib/postgresql
name: data
livenessProbe:
exec:
command:
- pg_isready
- -h
- localhost
- -U
- postgres
initialDelaySeconds:
timeoutSeconds:
readinessProbe:
exec:
command:
- pg_isready
- -h
- localhost
- -U
- postgres
initialDelaySeconds:
timeoutSeconds:
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:
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.
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: ""
- name: GITLAB_SSH_PORT
value: ""
- 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: :
- name: DB_TYPE
value: postgres
- name: DB_HOST
value: postgresql
- name: DB_PORT
value: ""
- 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: ""
ports:
- name: http
containerPort:
- name: ssh
containerPort:
volumeMounts:
- mountPath: /home/git/data
name: data
livenessProbe:
httpGet:
path: /
port:
initialDelaySeconds:
timeoutSeconds:
readinessProbe:
httpGet:
path: /
port:
initialDelaySeconds:
timeoutSeconds:
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:
targetPort: http
- name: ssh
port:
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

Kubernetes+Jenkins+Nexus+Gitlab进行CI/CD集成的更多相关文章

  1. 物联网架构成长之路(47)-利用GitLab实现CI持续集成

    0.前言 前段时间,考虑到要练习部署一套CI/CD的系统.一开始考虑到Jenkins,随着这两天的了解,发现最新版的GitLab已经提供有CI/CD集成了.所以本次博客,干脆一步到位,直接用GitLa ...

  2. 【补充】Gitlab 部署 CI 持续集成

    上一篇:<劈荆斩棘:Gitlab 部署 CI 持续集成> 上一篇所配置的.gitlab-ci.yml: stages: - build - test before_script: - ec ...

  3. [转] gitlab 的 CI/CD 配置管理

    [From] http://blog.51cto.com/flyfish225/2156602 gitlab 的 CI/CD 配置管理 (二) 标签(空格分隔):运维系列 一:gitlab CI/CD ...

  4. Docker 集成 Jenkins Gitlab 实现 CI/CD

    首先介绍下环境部分,文章中共涉及到三台服务器,分别用 Gitlab,Jenkins,Deploy 三个名称代替,部署在内网环境,同时因为政策原因,服务器无法直接连通外网.下载 Jenkins 插件时需 ...

  5. Gitlab的CI/CD初尝试

    初衷:今天公司的前端和测试人员吵起来了.原因是测试埋怨前端人员把Bug的状态更改为已解决,结果代码根本没提交,而前端人员埋怨测试测的太频繁了,需要打几个环境的包不方便.又要改东西又要频繁打包费时间.凡 ...

  6. 使用Jenkins+Docker+Gitlab+Maven搭建持续集成环境

    继使用Docker搭建Gitlab后 大致的步骤如下: 开发人员通过IDE工具(IntelliJ IDEA)将代码推送到gitlab. jenkins从gitlab中获取到源码,并使用maven编译. ...

  7. 劈荆斩棘:Gitlab 部署 CI 持续集成

    阅读目录: install configue gitlab-ci-multi-runner restore nuget packages bulid .sln run unit tests confi ...

  8. 一种使用gitlab的CI/CD功能实现Nginx配置更新的方法

    至于nginx的docker制作,前面已介绍过. 现在使用gitlab在线编辑的方式,可实现Nginx的自定义配置并更新. .gitlab-ci.yml内容如下: variables: project ...

  9. Jenkins+git+gitlab实现持续自动集成部署

    1  实验环境 三台服务器 gitlab        192.168.7.139 Jenkins    192.168.7.140 java          192.168.7.141 [root ...

随机推荐

  1. Permutations II

    Given a collection of numbers that might contain duplicates, return all possible unique permutations ...

  2. 执行openstack命令报错【You must provide a username via either -...】

    openstack环境搭建好后,openstack的服务都启动了,当执行openstack命令时如nova service list报如下错误 You must provide a username ...

  3. C# DataGridView显示行号的三种方法

    方法一: 网上最常见的做法是用DataGridView的RowPostPaint事件在RowHeaderCell中绘制行号: private void dgGrid_RowPostPaint( obj ...

  4. Python—进程、线程、协程

    一.线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务 方法: ...

  5. Invisible or disabled control cannot be activated

    在WPF 应用程序下出现:Invisible or disabled control cannot be activated(不见的或禁用的控件不能被激活)错误. System.ArgumentExc ...

  6. Paxos算法(转)

    Paxos算法的难理解与算法的知名度一样令人敬仰,从我个人的经历而言,难理解的原因并不是该算法高深到大家智商不够,而在于Lamport在表达该算法时过于晦涩且缺乏一个完整的应用场景.如果大师能换种思路 ...

  7. mongodb安装服务

    一.准备工作 1:下载:  http://www.mongodb.org/downloads 2:解压到ZIP到 D:\Mongodb   ,在此目录下再建立2个目录  D:\Mongodb\db和D ...

  8. strlen源码剖析

      学习高效编程的有效途径之一就是阅读高手写的源代码,CRT(C/C++ Runtime Library)作为底层的函数库,实现必然高效.恰好手中就有glibc和VC的CRT源代码,于是挑了一个相对简 ...

  9. weui复选框无法传值

    //原来的反了 function changeState (ele) { if(ele.checked){ ele.setAttribute('checked','checked') console. ...

  10. java maven打包jar 方法参数名变var1,var2之类的无意义参数名怎么办

    这是idea 对.class反编译的结果.要想看完整源码,可以使用maven-source-plugin,在pom.xml里配置: <plugin> <groupId>org. ...