1. Giới Thiệu
Trong bài này sẽ hướng dẫn bạn cách build, deploy và run một Golang web service đơn giản bằng việc sử dụng GitLab và GCP GKE/AWS EKS. Kết hợp sử dụng GitLab CI để quản lý tiến trình CI/CD trở nên dễ dàng hơn.
Trước khi bắt đầu, bạn cần chuẩn bị một số yêu cầu sau:
2. Yêu cầu:
- GitLab Account
- GCP Account (either one)
- AWS Account (either one)
- setup Ingress Controller và Cert-Manager trên k8s
3. Tạo Project
3.1 Tạo Project trên Gitlab thông qua Gitlab Web Portal theo 9 bước sau:
- Tạo một project mới theo link: https://gitlab.com/projects/new
- Đặt tên project
- Thêm mô tả cho project ( không bắt buộc)
- Chọn Visibility Level là Private hay Public.
- Chọn vào “Initialize repository with a README”, ở bước này sẽ sinh ra một file README.md trong project.
- Sau khi thực hiện xong các bước trên, bạn sẽ được chuyển hướng đến trang chứa project vừa tạo.
- Chọn vào “Clone button” và copy đường link https, tiến hành clone project về máy bằng git clone.
$ git clone https://gitlab.com/hounienlin/mysample.git
- Chuyển vào thư mục vừa clone về, và kiểm tra file README.md trên máy của bạn, để đảm bảo là chúng ta có clone source về đúng hay không .
$ ls README.md
- OK, như vậy là chúng ta chuẩn bị xong, sẵn sàng để sang phần tiếp theo.
4. Thêm một Cluster GKE vào GitLab
Ở bước này, chúng ta sẽ thêm Cluster k8s vào Gitlab. Để hiểu hơn về bước này, các bạn có thể tham khảo ở đây:
https://docs.gitlab.com/ee/user/project/clusters/add_existing_cluster.html
for my case, I just type below
$ k get secret |grep gitlab
$ k describe secret gitlab-token
Name: gitlab-token
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account.name: gitlab
kubernetes.io/service-account.uid: b63fb686-cba6-4abc-9f97-cd6aec3c87cc
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1159 bytes
namespace: 7 bytes
token: eyJhbGciOiJSUzthisisafaketokenVpSWFdiTWpKUkhCY0hzSXNCaDdjdDZKbTB1WDVBZTBiWmw0RzgifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImdpdGxhYi10b2tlbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJnaXRsYjdoueljmasdlj;oelkmjkldklje09uOELJIDELJDVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJiNjNmYjY4Ni1jYmE2LTRhYmMtOWY5Ny1jZDZhZWMzYzg3Y2MiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpnaXRsYWIifQ.RMwRA5WlbDtZ4udCijV2pXhll1ZTRnspQkr3_dD6AwxkvEblT4lEd2H2I4LU_hP6PIXRtNyvoaogZn7UEZQXmKfHnQFS334Ttjvg0LQn1mg6a06nVwOStBMxpbSB82EQirRHT2h1nyG8VAimsRYHp67sahZR3Oc79ALBAkr3NSwHrr-sYQSKuxnwLFe9cD1rt6mQZPztq3sgLakASWixyO1_ZiRGQD08VE3VzF5kVLPn2o7xk4V7r6D-pbYvbxCoAYuNiS6AiQfZK9L7sevVvdjlOkYJaBULzFdfH7eLyUGKzTMRiT99m6UbhGCxqZyJXKhACrMqgJZOHgeUpHHQgQ
- Click vào “Add Kubernetes Cluster”
- Add existing GKE cluster
- Điền vào các thông tin Kubernetes cluster name, API URL, CA Certificate, và service token. Click vào button “Add Kubernetes cluster”
- Khi K8S cluster đã sẵn sàng, bạn cần chỉnh lại “base domain”, sau đó save lại.
5. Thêm ingress controller và cert-manager vào GKE cluster
Nếu bạn chưa biết cách, tham khảo tại đây.
5.1 Thêm deploy token
Đây là token dùng cho k8s pull docker image về từ Gitlab repository.
- Kéo xuống phía gần cuối, click vào settings/repository
- Tìm đến mục “Deploy tokens” , click vào nút Expand.
- Ở đây, chúng ta cần tạo thêm một “Deploy token”. Nhập vào Tên và tích vào “read_registry”.
- Click vào “Create deploy token”
- [Lưu ý] Bạn phải lưu lại username, password, vì nó chỉ hiển thị 1 lần. Nếu mất, bạn phải tạo lại.
5.2 Thêm variables
- Click vào settings/CI/CD
- Chọn vào mục “Variables” > “Add Variable”
- Thêm 2 variables ( KUBEPULLPASS là deploy token password, KUBEPULLUSER là deploy token name vừa tạo)
6. Configure application
6.1 git push golang application
6.2 Config Dockerfile
FROM golang:1.12-alpine
RUN apk add --no-cache git
# Set the Current Working Directory inside the container
WORKDIR /app/xff
# We want to populate the module cache based on the go.{mod,sum} files.
COPY go.mod .
#COPY go.sum .
RUN go mod download
COPY . .
# Build the Go app
RUN go build -o ./out/xff .
# This container exposes port 8080 to the outside world
EXPOSE 9000
# Run the binary program produced by `go install`
CMD ["./out/xff"]
6.3 Config main.go
package main
import (
"log"
"net/http"
"strings"
"github.com/sebest/xff"
)
func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
//ips := strings.Split(r.Header.Get("X-Forwarded-For"))
xff := strings.Split(r.Header.Get("X-Forwarded-For"), ", ")
log.Printf("xff: %+v", xff)
w.Write([]byte("(v3) XFF IP is " + strings.Join(xff, ", ") + "\n"))
})
xffmw, _ := xff.Default()
http.ListenAndServe(":8080", xffmw.Handler(handler))
}
6.4 Config k8s.yml
kind: Service
apiVersion: v1
metadata:
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "80"
name: ${APP_NAME}
spec:
selector:
app: ${APP_LABEL}
type: NodePort
ports:
- protocol: TCP
port: 80
targetPort: 8080
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: ${APP_NAME}
labels:
app: ${APP_LABEL}
spec:
replicas: 3
selector:
matchLabels:
app: ${APP_LABEL}
template:
metadata:
labels:
app: ${APP_LABEL}
spec:
imagePullSecrets:
- name: gitlab-auth
containers:
- name: ${APP_NAME}
image: "${DOCKER_IMAGE_TAG}"
ports:
- containerPort: 8080
---
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
name: ${APP_NAME}-cert
spec:
secretName: production-auto-deploy-tls
dnsNames:
- ${DEPLOY_HOST}
acme:
config:
- http01:
ingressClass: nginx
domains:
- ${DEPLOY_HOST}
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ${APP_NAME}-ingress
annotations:
service.beta.kubernetes.io/do-loadbalancer-enable-proxy-protocol: "true"
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: ${DEPLOY_HOST}
http:
paths:
- backend:
serviceName: ${APP_NAME}
servicePort: 80
tls:
- hosts:
- ${DEPLOY_HOST}
secretName: production-auto-deploy-tls
Trong đó, các biến môi trường ${…} sẽ được cấu hình trong file gitlab-ci.yaml
6.5 Config gitlab-ci.yaml
Thay đổi “xxx.yourbasedomain”, phù hợp với domain của bạn.
stages:
- build
- deploy
variables:
DOCKER_IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
build:
stage: build
image: docker:stable
services:
- docker:19-dind
variables:
DOCKER_HOST: tcp://docker:2375/
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
before_script:
- docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
- docker info
script:
- docker build -t $DOCKER_IMAGE_TAG .
- docker push $DOCKER_IMAGE_TAG
deploy:
stage: deploy
variables:
APP_NAME: production-xff
APP_LABEL: production
DEPLOY_HOST: xxx.yourbasedomain
environment:
name: production
url: https://xxx.yourbasedomain
image: roffe/kubectl:v1.13.0
script:
- kubectl delete --ignore-not-found=true secret gitlab-auth
- kubectl create secret docker-registry gitlab-auth --docker-server=$CI_REGISTRY --docker-username=$KUBE_PULL_USER --docker-password=$KUBE_PULL_PASS
- cat k8s.yml | envsubst | kubectl apply -f -
only:
- master
6.6 go.mod and go.sum
$ go mod init main.go
$ go build -o xff
6.7 push code
$ git add .
$ git commit -am "this is my demo"
$ git push
7. Monitoring
- Deploy job sẽ được trigger tự động.
- Kiểm tra Pipepines
- Để xem chi tiết, bạn có thể click vào pipelines để thấy các output.
Nguồn:
Nhấn Subcribe để nhận thêm nhiều bài viết mới Like Facebook
[maxbutton id=”2″ ] [maxbutton id=”3″ ]
Đăng ký liền tay Nhận Ngay Bài Mới
Subscribe ngay
Cám ơn bạn đã đăng ký !
Lỗi đăng ký !
Add Comment