Kubernetes 部署 Gitlab
1. 部署 Redis
[root@k8s-master01 gitlab]# cat > namespace.yaml <<EOF
apiVersion: v1
kind: Namespace
metadata:
name: dev-ops
EOF
[root@k8s-master01 gitlab]# cat > gitlab-redis-pvc.yaml <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gitlab-redis-pvc
namespace: dev-ops
spec:
storageClassName: "nfs-provisioner-storage"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
EOF
[root@master01 redis]# cat > gitlab-redis.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: dev-ops
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
initContainers:
- name: system-init
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/library/busybox:1.32 # 加速镜像
image: docker.io/library/busybox:1.32 # 源镜像
imagePullPolicy: IfNotPresent
command:
- "/bin/sh"
- "-c"
- |
echo "调整内存大页"
echo 2048 > /proc/sys/net/core/somaxconn && echo never > /sys/kernel/mm/transparent_hugepage/enabled
securityContext:
privileged: true
runAsUser: 0
volumeMounts:
- name: sys
mountPath: /sys
containers:
- name: redis
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/redis:6.2.7 # 加速镜像
image: docker.io/redis:6.2.7 # 源镜像
imagePullPolicy: IfNotPresent
ports:
- name: redis
containerPort: 6379
protocol: TCP
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 500m
memory: 500Mi
# 存活探针
livenessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 30
timeoutSeconds: 5
# 就绪性探针
readinessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 30
timeoutSeconds: 1
volumeMounts:
- name: host-time
mountPath: /etc/localtime
readOnly: true
- name: redis-data
mountPath: /data
volumes:
- name: host-time
hostPath:
path: /etc/localtime
- name: sys
hostPath:
path: /sys
- name: redis-data
persistentVolumeClaim:
claimName: gitlab-redis-pvc
restartPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: dev-ops
labels:
app: redis
spec:
ports:
- name: redis
port: 6379
targetPort: 6379
selector:
app: redis
EOF2. 部署 PgSQL
[root@master01 postgres]# cat > gitlab-postgresql-pvc.yaml <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gitlab-postgresql-pvc
namespace: dev-ops
spec:
storageClassName: "nfs-provisioner-storage"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 30Gi
[root@master01 postgres]# cat > gitlab-postgresql.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgresql
namespace: dev-ops
labels:
app: postgresql
spec:
replicas: 1
selector:
matchLabels:
app: postgresql
template:
metadata:
labels:
app: postgresql
spec:
containers:
- name: postgresql
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/sameersbn/postgresql:14-20230628 # 加速镜像
image: docker.io/sameersbn/postgresql:14-20230628 # 源镜像
imagePullPolicy: IfNotPresent
ports:
- name: postgres
containerPort: 5432
env:
- name: DB_USER
value: gitlab
- name: DB_PASS
value: passw0rd
- name: DB_NAME
value: gitlab_production
- name: DB_EXTENSION
value: 'pg_trgm,btree_gist'
resources:
requests:
cpu: 2
memory: 2Gi
limits:
cpu: 2
memory: 2Gi
livenessProbe:
exec:
command:
- "/bin/bash"
- "-c"
- |
if psql -U gitlab -d gitlab_production -c 'SELECT 1;' > /dev/null 2>&1; then
exit 0
else
exit 1
fi
initialDelaySeconds: 30
timeoutSeconds: 5
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
readinessProbe:
exec:
command:
- "/bin/bash"
- "-c"
- |
if psql -U gitlab -d gitlab_production -c 'SELECT 1;' > /dev/null 2>&1; then
exit 0
else
exit 1
fi
initialDelaySeconds: 5
timeoutSeconds: 1
periodSeconds: 10
successThreshold: 1
failureThreshold: 3
volumeMounts:
- name: data
mountPath: /var/lib/postgresql
readOnly: false
- name: host-time
mountPath: /etc/localtime
volumes:
- name: host-time
hostPath:
path: /etc/localtime
- name: data
persistentVolumeClaim:
claimName: gitlab-postgresql-pvc
---
apiVersion: v1
kind: Service
metadata:
name: postgresql
namespace: dev-ops
labels:
app: postgresql
spec:
ports:
- name: postgresql
port: 5432
targetPort: 5432
selector:
app: postgresql
EOF如果 postgresql 使用的存储是 glusterfs,那么 pod 需要修改一下
spec:
securityContext:
fsGroup: 1001 # 确保 NFS 卷的组权限
fsGroupChangePolicy: "OnRootMismatch" # 仅必要时修改卷权限
supplementalGroups:
- 1010 # 额外赋予访问宿主机日志的权限3. 部署 Gitlab
[root@master01 gitlab]# cat > gitlab-pvc.yaml <<EOF
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gitlab-pvc
namespace: dev-ops
spec:
storageClassName: "nfs-provisioner-storage"
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Gi
EOF
[root@master01 gitlab]# cat > gitlab.yaml <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitlab
namespace: dev-ops
labels:
app: gitlab
spec:
replicas: 1
selector:
matchLabels:
app: gitlab
template:
metadata:
labels:
app: gitlab
spec:
containers:
- name: gitlab
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/sameersbn/gitlab:16.10.0 # 加速镜像
image: docker.io/sameersbn/gitlab:16.10.0 # 源镜像
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 # 首次运行时 root 用户的密码。默认为5iveL!fe。GitLab 要求其长度至少为8 个字符
value: "5iveL!fe"
- name: GITLAB_ROOT_EMAIL
value: "2099637909@qq.com"
- name: SMTP_ENABLED
value: "true"
- name: SMTP_HOST
value: "smtp.qq.com"
- name: SMTP_PORT
value: "465"
- name: SMTP_USER
value: "2099637909@qq.com"
- name: SMTP_PASS
value: "xxxxxxx"
- name: SMTP_TLS
value: "true"
- name: GITLAB_HOST
value: "k8s-gitlab.tianxiang.love"
# 开启 https,这个只是你在用 gitlab 的时候,比如打开页面,pull push 走的是 https 了,并不是后端服务真的监听了一个443端口
- name: GITLAB_HTTPS
value: "true"
# 如果证书是自己签的,那么需要把 ca 证书添加到 gitlab 中,我当时的证书是自己签名的,但是没开启这个变量也能用
#- name: SSL_SELF_SIGNED
# value: "false"
# 如果开启 https 的话,把端口换成 443
- name: GITLAB_PORT
value: "443"
# clone 的时候 ssh 端口 30022
- name: GITLAB_SSH_PORT
value: "30022"
- 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: https
containerPort: 443
- name: ssh
containerPort: 22
resources:
limits:
cpu: 4
memory: 8Gi
requests:
cpu: 0.5
memory: 1Gi
livenessProbe:
httpGet:
path: /users/sign_in
port: 80 # 不论是不是 https ,这个端口永远都是80
scheme: HTTP
initialDelaySeconds: 300
timeoutSeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /users/sign_in # GitLab登录页面是常用的健康检查端点
port: 80
scheme: HTTP
initialDelaySeconds: 60 # 可以比liveness probe短一些
timeoutSeconds: 5
periodSeconds: 10
volumeMounts:
- mountPath: /etc/localtime
readOnly: true
name: host-time
- mountPath: /home/git/data
name: data
volumes:
- name: host-time
hostPath:
path: /etc/localtime
- name: data
persistentVolumeClaim:
claimName: gitlab-pvc
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gitlab
namespace: dev-ops
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "0"
labels:
app: gitlab-ingress
spec:
ingressClassName: nginx
tls:
- hosts:
- k8s-gitlab.tianxiang.love
secretName: https-secret
rules:
- host: k8s-gitlab.tianxiang.love
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: gitlab
port:
number: 80
---
apiVersion: v1
kind: Service
metadata:
name: gitlab
namespace: dev-ops
labels:
app: gitlab
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30080
- name: https
port: 443
targetPort: 443
nodePort: 30443
- name: ssh
port: 22
targetPort: 22
nodePort: 30022
selector:
app: gitlab
EOF4. 创建 gitlab https 证书
[root@k8s-master1 tls]# cat script.sh
#!/bin/bash
# 生成 CA 证书
echo "正在生成 CA 证书..."
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -sha512 -days 3650 -subj "/C=CN/ST=Beijing/L=Beijing/O=Example CA/OU=CA/CN=My Root CA" -key ca.key -out ca.crt
echo "✅ CA 证书已生成: ca.crt"
# 获取域名
while true; do
read -e -p "请输入要签发的域名 (支持泛域名,如 *.example.com): " DOMAIN
if [[ -n "$DOMAIN" ]]; then
break
else
echo "❌ 域名不能为空,请重新输入!"
fi
done
# 生成服务器私钥
openssl genrsa -out "${DOMAIN}.key" 4096
# 生成 CSR
openssl req -sha512 -new -subj "/C=CN/ST=Beijing/L=Beijing/O=Example/OU=Server/CN=${DOMAIN}" -key "${DOMAIN}.key" -out "${DOMAIN}.csr"
# 让用户输入多个 IP
read -e -p "请输入服务器的 IP 地址(多个 IP 用空格分隔,留空则不添加 IP): " -a IPS
# 生成 SAN 配置文件
cat > v3.ext <<EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=127.0.0.1
DNS.2=${DOMAIN}
DNS.3=localhost
EOF
# 添加 IP 地址,每个 IP 单独占一行
ip_index=1
for ip in "${IPS[@]}"; do
echo "IP.${ip_index}=${ip}" >> v3.ext
((ip_index++))
done
# 输出 v3.ext 确保格式正确
echo "✅ 生成的 v3.ext 配置文件如下:"
cat v3.ext
# 使用 CA 签发服务器证书
openssl x509 -req -sha512 -days 3650 -extfile v3.ext -CA ca.crt -CAkey ca.key -CAcreateserial -in "${DOMAIN}.csr" -out "${DOMAIN}.crt"
# 生成 PEM 格式证书
openssl x509 -inform PEM -in "${DOMAIN}.crt" -out "${DOMAIN}.cert"
# 验证证书
openssl verify -CAfile ca.crt "${DOMAIN}.crt"
# 显示证书信息
openssl x509 -in "${DOMAIN}.crt" -noout -text
[root@k8s-master1 tls]# ls
ca.crt ca.key ca.srl *.tianxiang.love.cert *.tianxiang.love.crt *.tianxiang.love.csr *.tianxiang.love.key script.sh v3.ext
[root@k8s-master1 tls]# kubectl -n dev-ops create secret tls https-secret --cert=*.tianxiang.love.crt --key=*.tianxiang.love.key5. 启动服务
[root@k8s-master1 tls]# kubectl get pods -n dev-ops
NAME READY STATUS RESTARTS AGE
gitlab-754cb964f6-488z4 1/1 Running 0 27h
postgresql-cb8776fdf-78xwq 1/1 Running 0 26h
redis-5dc466b555-cl44d 1/1 Running 0 26h
License:
CC BY 4.0