這篇文章應該會很長。php
小說 是我之前寫的一個項目,主要是爲了練手vue,後端用lumen(php框架)寫的。附上碼雲的連接 vue-novel,先後端代碼都很簡單。最近把它遷移到了k8s,配合gitlab-runner和rancher-ui實現了CI/CD,在此記錄一下。附上遷移後的項目地址:html
最開始這個項目是怎麼運行的呢?我在vultr買了個vps,安裝 lnmp 集成環境,項目代碼用FTP傳上去,配置一下nginx就跑起來了。遷移到k8s後,提交和發佈代碼的大體流程以下:前端
能夠看到,咱們要作的僅僅是推送代碼,而後去後臺更新項目的鏡像,項目就上線了。vue
每臺vps都要配置。node
#!/bin/sh
# 1. stop firewalld
systemctl stop firewalld && systemctl disable firewalld
# 2. stop SElinux
sudo sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
# 3. set timezone
timedatectl set-timezone Asia/Shanghai
# 4
yum install vim htop -y
# 5. increase swap
dd if=/dev/zero of=/home/swap bs=1024 count=5120000
/sbin/mkswap /home/swap
/sbin/swapon /home/swap
# 6. install docker
curl -fsSL get.docker.com | sh
systemctl start docker && systemctl enable docker
複製代碼
增長交換內存是由於我機器配置不夠,才1G內存;防火牆和SElinux是必定要關閉的,否則集羣確定搭建不成功;docker也要安裝一下。linux
代碼上容器確定要用鏡像,說一下須要什麼鏡像。nginx
後端用php,那麼須要一個nginx-php鏡像,我在github上找了一個,不過有一點小bug,fork過來稍微改了下,附上連接:nginx-php。 這個鏡像基於alpine,而後源碼安裝了php和nginx,咱們本身擴展和更新比較方便。根據這個Dockerfile打包鏡像,而後推送到 dockerhub,最終獲得一個 nginx-php鏡像。若是不想讓你的基礎鏡像公開,能夠不推到dockerhub,等私有倉庫搭好後放到私有倉庫。至於怎麼打包和推送鏡像,這個比較簡單,就不細說了。git
前端的同理,把Dockerfile裏安裝php相關的部分刪掉,打包並推送鏡像,最終獲得一個 nginx 鏡像。github
使用k3s搭建集羣其實就是幾個命令的事,可是國內服務器不行,由於k8s依賴pause鏡像,這個鏡像你在國內確定下不下來,因此國內搭集羣只能手動。redis
運行官方腳本。
curl -sfL https://get.k3s.io | sh -
複製代碼
看到systemd: Starting k3s就能夠了。修改配置:
vim /etc/systemd/system/multi-user.target.wants/k3s.service
複製代碼
把ExecStar的值改成
/usr/local/bin/k3s server --docker --no-deploy traefik --cluster-secret=hjp
複製代碼
- --docker 用docker作底層容器(默認的是containerd)
- --no-deploy traefik 不安裝traefik組件
- --cluster-secret=hjp 設置密碼,待會添加agent(節點)就不須要去查看token了
而後從新加載配置,重啓k3s。
systemctl daemon-reload
systemctl restart k3s
複製代碼
運行
k3s kubectl get nodes
複製代碼
查看一下節點
有一個master節點,這是安裝server的時候自帶的,這樣其實就已經建立了有一個master節點的k8s集羣。注意這裏有個坑。 按照官方文檔的說法,其實能夠直接運行命令的時候指定配置
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--docker --no-deploy traefik --cluster-secret=hjp" sh -
複製代碼
這樣就不用再修改配置。可是這樣啓動k3s後,後面搭建docker私有倉庫、docker-registry配置ingress會一直顯示initializing,因此仍是安裝後手動修改配置吧。
我是國外的服務器,因此直接用腳本搭建的,k3s的 官方文檔 最下面寫了怎麼手動搭建。其實就是去github上把 k3s 下載,而後上傳到服務器運行。然而國內服務器要多作一步,即在這以前先把pause鏡像手動下載,從新打個tag。dockerhub上有個鏡像谷歌倉庫,附上連接 pause鏡像。
docker pull mirrorgooglecontainers/pause:3.1
docker tag mirrorgooglecontainers/pause:3.1 k8s.gcr.io/pause:3.1
複製代碼
把下載的k3s文件複製到/usr/local/bin/k3s
cp ./k3s /usr/local/bin/k3s
chmod 777 /usr/local/bin/k3s
複製代碼
啓動k3s
k3s server &
複製代碼
以後的操做步驟應該跟自動搭建是同樣的。
k3s命令目錄在/usr/local/bin/
要卸載的話,先運行k3s-killall.sh,再運行k3s-uninstall.sh。
接下來要搭個 rancher 界面來操做集羣,其實也是一個命令的事。進入另外一臺vps,執行
docker run -d -v /var/lib/rancher/:/var/lib/rancher/ --restart=unless-stopped --name rancher-server -p 80:80 -p 443:443 rancher/rancher:stable
複製代碼
注意rancher和k3s不能裝在同一臺機器上,否則這個容器啓動會報錯。k3s V0.8.1版本的時候仍是能夠的,不知道最近更新了什麼,附上
github該問題的連接。把域名(rancher.hjply.com)指向這臺vps的ip,而後瀏覽器訪問rancher.hjply.com。因爲rancher是自簽名證書,會彈出安全警告,直接無視便可。
設置密碼後進入。
搭建完成,右下角能夠切換語言。
把集羣導入rancher後,才能可視化地操做集羣。
在剛纔的頁面點擊 "添加集羣",選擇 「導入現有的Kubernetes集羣」, 名字隨便寫個,點建立
進入這個頁面複製最後一條命令,在k3s server那臺機器上執行
過一會自動跳轉到這個頁面狀態會從waiting變成active,表示導入完成。
若是這個狀態一直沒變化,或者頁面沒有自動跳轉,估計就是防火牆、SElinux沒關,或者k3s和rancher兩臺機器互相ping不通。
導入成功後查看一下集羣。
能夠看到有一個節點,就是k3s server自帶的master節點,若是有須要能夠繼續添加節點。
再開一臺機器,vps配置同上,而後配置一個host
vi /etc/hosts
複製代碼
加一條
127.0.0.1 vultr3
複製代碼
運行命令
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--docker --node-name=vultr3" K3S_URL=https://217.69.8.236:6443 K3S_CLUSTER_SECRET=hjp sh -
複製代碼
再查看一下集羣。
看到有2個節點,表示成功。
直接用rancher搭建私有倉庫比較方便。
先進入集羣頁面,建立一個項目。點擊添加項目,項目名稱隨便寫,系統的這2個項目(Default和System)不要動。
進入這個項目,而後進到應用商店。
點「啓動」,選擇docker-registry,點「查看詳情」進入部署頁面。
部署的時候須要注意2點。
爲何須要啓用https?由於咱們要使用賬號密碼控制私有倉庫的訪問權限,不能誰均可以往裏面push鏡像,而啓用賬號密碼就必須用https(官方文檔要求,如圖)。
直接在阿里雲申請個免費證書,下載到電腦
接下來就是生成賬號密碼。進入k3s server那臺機器(必定要用這臺機器,由於不一樣機器生成的密碼不同),依次執行:
mkdir -p /home/registry/auth
docker run --entrypoint htpasswd registry -Bbn hjp hjp >>/home/registry/auth/htpasswd
cat /home/registry/auth/htpasswd
複製代碼
(賬號hjp,密碼hjp)_
複製一下生成的密碼,填入部署頁面
配置一下負載均衡,使用自定義域名(registry.hjply.com指向k3s server這臺機器)
點擊啓動,就建立了docker倉庫。這裏我沒有作持久化配置,因此容器刪掉后里面的鏡像也會被刪除。最後還差一步配置ssl和賬號密碼。
進入證書頁面
添加證書,把從阿里雲下載的證書導入,點擊保存便可。而後升級一下倉庫的ingress,點擊「升級」,把SSL證書勾選上,保存。
這樣倉庫的https就配置好了,咱們測試一下,打開網頁 registry.hjply.com/v2/_catalog
輸入帳號密碼
看到倉庫是空的,裏面沒有鏡像,到此docker私有倉庫就搭建完了。最後還要把倉庫的帳號密碼保存在集羣,由於待會拉取鏡像須要權限認證。
點擊鏡像庫憑證
把賬號密碼填寫一下,保存便可。
gitlab-runner有3種,即
其中Specific Runners是針對項目的,每一個項目能夠分別配置本身的runner;
Shared Runners是gitlab上別人共享出來的runner,咱們不用,把它禁用掉;
Group Runners是針對項目組的,只要給項目組配置一個runner,組內的全部項目均可以使用這個runner。
新建一個group,把項目都放進去
進入group_hjp的CI/CD配置頁面
能夠看到如今尚未安裝runner。找一下 文檔,裏面有寫怎麼安裝gitlab-runner,咱們直接在vps上安裝,依次運行
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
sudo yum install gitlab-runner
複製代碼
便可。安裝以後須要註冊,運行
gitlab-runner register
複製代碼
這樣就註冊完成了。刷新網頁驗證一下
進入到項目的CI/CD頁面,驗證Groups Runners是否可用。
最後,由於待會要用這個runner打包和推送鏡像到docker私有倉庫,因此還須要配置一下docker。
先把私有倉庫地址加入docker配置文件(新版docker沒有這個文件,直接vim建立便可)
vim /etc/docker/daemon.json
複製代碼
把私有倉庫地址寫入文件,保存退出。
從新加載docker配置
systemctl reload docker
複製代碼
同理,在k3s server上也要把私有倉庫地址加到/etc/docker/daemon.json配置文件裏,由於拉取鏡像須要用。
而後切換到gitlab-runner用戶,登陸registry.hjply.com並保存帳號密碼
若是報 /var/run/docker.sock 沒有權限的錯誤,須要把gitlab-runner這個用戶添加到docker用戶組
usermod -G docker gitlab-runner
複製代碼
到這裏gitlab-runner和docker配置就完成了。
之後端代碼爲例,先把目錄層級改一下。
咱們加個src目錄,把代碼全放進去,而後開始編寫 .gitlab-ci.yml、Dockerfile、nginx.conf文件
server {
listen 80 default_server;
client_max_body_size 5m;
client_body_buffer_size 256k;
client_header_buffer_size 256k;
large_client_header_buffers 4 8k;
set $rootPath '/data/src/public';
root $rootPath;
index index.php index.html index.htm;
server_name localhost;
if (!-e $request_filename) {
rewrite ^/(.*)$ /index.php/$1 last;
}
location ~ ^(.+\.php)(.*)$ {
fastcgi_pass unix:/usr/local/php/var/run/php-fpm.sock;
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_buffer_size 128k;
fastcgi_buffers 256 16k;
client_body_buffer_size 1024k;
include fastcgi_params;
}
}
複製代碼
這就是個很普通的php項目nginx配置,就很少說了。
FROM hongjiapei/nginx-php
COPY nginx.conf /usr/local/nginx/conf.d/nginx.conf
COPY src /data/src
RUN chown -R www-data.www-data /data/src/ && chmod -R 755 /data/src \
&& rm -rf /usr/local/php/etc/php-fpm.d/www.conf
WORKDIR /data/src
EXPOSE 80
CMD sh -c 'nginx && php-fpm -D && tail -f /usr/local/nginx/logs/error.log'
複製代碼
繼承了咱們以前打包的nginx-php鏡像,而後用本身的nginx.conf覆蓋掉默認的配置,最後前臺啓動nginx和php-fpm、打印nginx錯誤日誌。注意這裏不能後臺啓動nginx和php-fpm,否則等你命令執行完了容器就自動退出了。
stages:
- build
- push
build_image:
stage: build
script:
- ls -la
- CI_COMMIT_TAG=`git log | grep -e "^commit.*" | wc -l` && docker build --pull -t registry.hjply.com/group_hjp/xsbe:"$CI_COMMIT_TAG" .
only:
- master
tags:
- abc
push_image:
stage: push
script:
- CI_COMMIT_TAG=`git log | grep -e "^commit.*" | wc -l` && docker push registry.hjply.com/group_hjp/xsbe:"$CI_COMMIT_TAG" && docker rmi registry.hjply.com/group_hjp/xsbe:"$CI_COMMIT_TAG"
only:
- master
tags:
- abc
複製代碼
這裏分爲兩步,第一步打包鏡像,第二步推送鏡像。only:master表示只有master推送的時候才啓動流水線,tags:abc表示使用tag包含abc的runner,因此剛纔註冊gitlab-runner寫的tag是什麼這裏就寫什麼,git log | grep -e "^commit.*" | wc -l 表示git日誌裏帶有commit關鍵字的條數,通常提交一次就多一條,咱們用這個數字做爲鏡像的tag,推送完鏡像後把本機的鏡像刪掉。
到這裏配置就所有完成了,接下來提交代碼測試一下。
在master提交代碼,進入項目頁面查看
能夠看到項目正在執行流水線,點進去看下
等兩個階段都成功就表示執行完成,查看一下鏡像
剛纔提交的代碼鏡像是registry.hjply.com/group_hjp/xsbe:4
進入rancher後臺,第一次須要部署服務,之後只須要更新。
點擊「部署服務」,使用剛纔的鏡像啓動,把80端口暴露出來,部署服務以前要確保兩件事
若是沒配置好,鏡像拉取會失敗的。
等狀態變成active就表示部署完成
而後配置ingress,這樣就能夠經過域名把請求轉發到容器。
進入「負載均衡」,點擊「添加ingress規則」
把域名指向容器的80端口,保存。
初次部署基本完成,打開網頁驗證一下(要提早把這個域名指向k3s server這臺機器)。
剛纔只用了一個pod啓動項目,若是性能不夠,能夠多加幾個pod,點擊那個「+」號便可。
到這裏項目尚未徹底部署完成,還差最後一步,即配置文件。lumen的配置文件爲.env文件,通常數據庫、redis配置都寫在裏面,這個文件確定不會放在git裏,下面說一下怎麼給項目添加配置文件。
點擊「配置映射」
鍵就用配置文件的文件名.env,值就是文件內容,能夠填多行,保存,而後升級項目。
給項目添加一個ConfiMap卷,保存。
等項目自動更新pod。
更新完成,隨便進入一個pod,查看一下是否有.env文件。
有.env文件,打開看一下是否正確
跟剛纔配置的同樣,到這裏初次部署就完成了。
項目更新就比較簡單了,新增一個接口xsbe.hjply.com/test,在master提交代碼,等流水線執行完,而後去看看鏡像的tag是什麼
去rancher後臺更新一下項目
把tag改成剛纔鏡像的tag,保存便可。
等pod更新完後,打開網頁驗證一下
說明代碼更新成功。
流水線失敗不可怕,根據報錯信息去解決便可。之前端項目爲例,提交代碼後發現流水線失敗了
點進去看看報錯信息
發現是npm命令找不到,原來是gitlab-runner這臺機器忘了裝nodejs,安裝一下
yum install nodejs -y
複製代碼
點擊最右邊的刷新按鈕從新執行流水線
成功後去看看鏡像的tag
去rancher後臺部署一下
配置ingress
部署完成,打開網頁測試一下
到這裏就完成了。
最後咱們看一下私有倉庫裏的鏡像
就是咱們剛纔推送的2個鏡像。