1. 在 Kubernetes 上安裝 Gitlab
Gitlab官方提供了 Helm 的方式在 Kubernetes 叢集中來快速安裝,但是在使用的過程中發現 Helm 提供的 Chart 包中有很多其他額外的配置,所以我們這裡使用自定義的方式來安裝,也就是自己來定義一些資源清單檔案。
Gitlab主要涉及到3個應用:Redis、Postgresql、Gitlab 核心程式,實際上我們只要將這3個應用分別啟動起來,然後加上對應的配置就可以很方便的安裝 Gitlab 了,我們這裡選擇使用的映象不是官方的,而是 Gitlab 容器化中使用非常多的一個第三方映象:sameersbn/gitlab,基本上和官方保持同步更新,地址:http://www.damagehead.com/docker-gitlab/
安裝
如果我們已經有可使用的 Redis 或 Postgresql 服務的話,那麼直接配置在 Gitlab 環境變數中即可,如果沒有的話就單獨部署。
首先部署需要的 Redis 服務,對應的資源清單檔案如下:(gitlab-redis.yaml)
apiVersion: apps/v1 kind: Deployment metadata: name: redis namespace: kube-ops labels: name: redis spec: replicas: 1 selector: matchLabels: name: redis 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 emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: redis namespace: kube-ops labels: name: redis spec: ports: - name: redis port: 6379 targetPort: redis selector: name: redis
然後是資料庫 Postgresql,對應的資源清單檔案如下:(gitlab-postgresql.yaml)
apiVersion: apps/v1 kind: Deployment metadata: name: postgresql namespace: kube-ops labels: name: postgresql spec: replicas: 1 selector: matchLabels: name: postgresql 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 emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: postgresql namespace: kube-ops labels: name: postgresql spec: ports: - name: postgres port: 5432 targetPort: postgres selector: name: postgresql
然後就是我們最核心的 Gitlab 的應用,對應的資源清單檔案如下:(gitlab.yaml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitlab
namespace: kube-ops
labels:
name: gitlab
spec:
replicas: 1
selector:
matchLabels:
name: gitlab
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: admin321
- name: GITLAB_ROOT_EMAIL
value: [email protected]
- name: GITLAB_HOST
value: git.qikqiak.com
- 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
emptyDir: {}
---
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: traefik # 注意這個,需要事先安裝好traefik,若是使用的nginx-ingress,則需要刪除這兩行
spec:
rules:
- host: git.qikqiak.com
http:
paths: /
- backend:
serviceName: gitlab
servicePort: http
要注意我們這裡應用資料沒有做資料持久化,只是使用的emptyDir: {}型別的 volume,Pod 掛掉後,對應的資料也就沒有了,所以要在正式的環境中使用一定要做資料的持久化,比如新增 PV/PVC 或者 StorageClass。
要注意的是其中 Redis 和 Postgresql 相關的環境變數配置,另外,我們這裡添加了一個 Ingress 物件,來為我們的 Gitlab 配置一個域名git.qikqiak.com,這樣應用部署完成後,我們就可以通過該域名來訪問了,然後直接部署即可:
可以事先把gitlab的映象給拉取下來:
docker pull sameersbn/gitlab:11.8.1
kubectl create -f gitlab-redis.yaml
kubectl create -f gitlab-postgresql.yaml
kubectl create -f gitlab.yaml
建立完成後,檢視 Pod 的部署狀態:
# kubectl get pods -n kube-ops
NAME READY STATUS RESTARTS AGE
gitlab-75f4f976f-5nldw 1/1 Running 0 3m28s
postgresql-6bdfc9f845-4bfh5 1/1 Running 0 140m
redis-644479576f-7jx9p 1/1 Running 0 141m
可以看到都已經部署成功了,然後我們可以通過 Ingress 中定義的域名git.qikqiak.com(需要做 DNS 解析或者在本地 /etc/hosts 中新增對映)來訪問 Portal:
本機環境:用的是windows系統的主機,然後安裝一個vmware ,然後安裝倆虛擬機器,一個master,一個worker組成的k8s
需要在本機windows上和workerz主機上新增如下域名解析:192.168.75.11為worker主機ip
192.168.75.11 git.qikqiak.com
(以下這倆錯誤是上面實際操作過程中遇到的,上面的程式碼都已經處理過了,可以直接執行)
執行常見錯誤解決:
1.error: error validating "gitlab-redis.yaml": error validating data: ValidationError(Deployment.spec): missing required field "selector" in io.k8s.api.apps.v1.DeploymentSpec; if you choose to ignore these errors, turn validation off with --validate=false
報錯意思:部署驗證錯誤,在deploymentspec模組中必須指定 selector引數。
在 Deployment.spec 模組中,除了指定 replicas 副本數量,還需要指定副本標籤與 Deployment控制器進行匹配
解決辦法:寫全 spec的 selector標籤引數,與Pod和deployment相匹配
2.error: unable to recognize "gitlab-redis.yaml": no matches for kind "Deployment" in version "apps/v1beta1"
Deployment中使用的apps介面版本不一致。
查詢當前所有的版本:
# kubectl api-versions
admissionregistration.k8s.io/v1
admissionregistration.k8s.io/v1beta1
apiextensions.k8s.io/v1
apiextensions.k8s.io/v1beta1
apiregistration.k8s.io/v1
apiregistration.k8s.io/v1beta1
apps/v1
authentication.k8s.io/v1
authentication.k8s.io/v1beta1
authorization.k8s.io/v1
authorization.k8s.io/v1beta1
autoscaling/v1
autoscaling/v2beta1
autoscaling/v2beta2
batch/v1
batch/v1beta1
certificates.k8s.io/v1beta1
coordination.k8s.io/v1
coordination.k8s.io/v1beta1
crd.projectcalico.org/v1
discovery.k8s.io/v1beta1
events.k8s.io/v1beta1
extensions/v1beta1
kuboard.cn/v1
metrics.k8s.io/v1beta1
networking.k8s.io/v1
networking.k8s.io/v1beta1
node.k8s.io/v1beta1
policy/v1beta1
rbac.authorization.k8s.io/v1
rbac.authorization.k8s.io/v1beta1
scheduling.k8s.io/v1
scheduling.k8s.io/v1beta1
storage.k8s.io/v1
storage.k8s.io/v1beta1
v1
使用
使用使用者名稱 root,和部署的時候指定的超級使用者密碼GITLAB_ROOT_PASSWORD=admin321即可登入進入到首頁:
Gitlab 執行後,我們可以註冊為新使用者並建立一個專案,還可以做很多的其他系統設定,比如設定語言、設定應用風格樣式等等。
點選Create a project建立一個新的專案,和之前 Github 使用上沒有多大的差別:
建立完成後,我們可以新增本地使用者的一個SSH-KEY,這樣我們就可以通過 SSH 來拉取或者推送程式碼了。SSH 公鑰通常包含在~/.ssh/id_rsa.pub 檔案中,並以ssh-rsa開頭。如果沒有的話可以使用ssh-keygen命令來生成,id_rsa.pub裡面的內容就是我們需要的 SSH 公鑰,然後新增到 Gitlab 中。
由於平時使用的 ssh 預設是 22 埠,現在如果用預設的 22 埠去連線,是沒辦法和 Gitlab 容器中的 22 埠進行對映的,因為我們只是通過 Service 的 22 埠進行了對映,要想通過節點去進行 ssh 連結就需要在節點上一個埠和容器內部的22埠進行繫結,所以這裡我們可以通過 NodePort 去對映 Gitlab 容器內部的22埠,比如我們將環境變數設定為GITLAB_SSH_PORT=30022,將 Gitlab 的 Service 也設定為 NodePort 型別:
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
nodePort: 30022
type: NodePort
selector:
name: gitlab
注意上面 ssh 對應的 nodePort 埠設定為 30022,這樣就不會隨機生成了,重新更新下 Deployment 和 Service,更新完成後,現在我們在專案上面 Clone 的時候使用 ssh 就會帶上埠號了:
修改後的gitlab.yaml檔案內容:
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: gitlab
namespace: kube-ops
labels:
name: gitlab
spec:
replicas: 1
selector:
matchLabels:
name: gitlab
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: admin321
- name: GITLAB_ROOT_EMAIL
value: [email protected]
- name: GITLAB_HOST
value: git.qikqiak.com
- name: GITLAB_PORT
value: "80"
- 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: 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
emptyDir: {}
---
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
nodePort: 30022 # 新增的這行
type: NodePort # 新增的這行
selector:
name: gitlab
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: gitlab
namespace: kube-ops
annotations:
kubernetes.io/ingress.class: traefik # 注意這個,需要事先安裝好traefik,若是使用的nginx-ingress,則需要刪除這兩行
spec:
rules:
- host: git.qikqiak.com
http:
paths: /
- backend:
serviceName: gitlab
servicePort: http
然後在執行:kubectl apply -f gitlab.yaml
現在就可以使用Clone with SSH的地址了,由於上面我們配置了 SSH 公鑰,所以就可以直接訪問上面的倉庫了:
$ git clone ssh://[email protected]:30022/root/gitlab-demo.git
Cloning into 'gitlab-demo'...
warning: You appear to have cloned an empty repository.
Checking connectivity... done.
然後隨便在該專案下面新增一些資源:
$ echo "# hello world" > README.md
$ git add .
$ git commit -m 'hello world'
[master (root-commit) 63de7cb] hello world
1 file changed, 1 insertion(+)
create mode 100644 README.md
$ git push origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 224 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To ssh://[email protected]:30022/root/gitlab-demo.git
* [new branch] master -> master
然後重新整理瀏覽器,就可以看到剛剛建立的 Git 倉庫中多了一個 README.md 的檔案:
到這裡就表明我們的 Gitlab 就成功部署到了 Kubernetes 叢集當中了。
附錄:安裝nginx-ingress教程
# vim nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
# vim nginx-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-service
labels:
app: nginx
spec:
selector:
app: nginx
ports:
- name: nginx-port
protocol: TCP
port: 80
nodePort: 32600
targetPort: 80
type: NodePort
# vim nginx-ingress.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: my-ingress-for-nginx # Ingress 的名字,僅用於標識
spec:
rules: # Ingress 中定義 L7 路由規則
- host: a.demo.kuboard.cn # 根據 virtual hostname 進行路由(請使用您自己的域名)
http:
paths: # 按路徑進行路由
- path: /
backend:
serviceName: nginx-service # 指定後端的 Service 為之前建立的 nginx-service
servicePort: 80
執行命令
kubectl apply -f nginx-deployment.yaml
kubectl apply -f nginx-service.yaml
kubectl apply -f nginx-ingress.yaml
檢查執行結果
kubectl get ingress -o wide
可檢視到名稱為 my-ingress-for-nginx 的 Ingress。
從網際網路訪問
# 請使用您自己的域名
curl git.qikqiak.com