环境: 基于Drone+Gitea+Docker对go项目进行CI/CD
目标: 把原来由docker run起来的进程交给k8s去进行调度编排
前提: 熟悉k8s的基本使用

1.kubectl环境打包

这里把用户目录下的.kube目录和kubectl程序放到当前目录,打包成镜像,上传到私有仓库

Dockerfile

FROM alpine:3.10
COPY .kube /root/.kube
COPY kubectl /bin/

build.sh

image=192.168.41.34/pub/kubectl
ver=v1
docker build -t $image:$ver .
# 可能需要docker login
docker push $image:$ver
# 测试
docker run --rm 192.168.41.34/pub/kubectl:$ver kubectl get nodes

执行

./build.sh

2.项目代码

├── .drone.yml
├── deployment.yaml
├── deploy.sh
├── Dockerfile
├── go.mod
├── go.sum
└── main.go

main.go

package main

import (
	"fmt"
	"net/http"

	"github.com/rs/xid"
)

var port = ":8080"

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) {
		id := xid.New().String()
		s := fmt.Sprintf("你好, id: %s", id)
		fmt.Fprintf(w, "%v\n", s)
	})
	if err := http.ListenAndServe(port, nil); err != nil {
		fmt.Println(err)
	}
}

.drone.yml


kind: pipeline
name: default

clone:
  depth: 10

steps:
  # 开发版
  - name: docker-${DRONE_BRANCH}
    image: plugins/docker:18.09
    settings:
      username: drone
      password:
        from_secret: DOCKER_PASSWORD
      registry: 192.168.41.34
      repo: 192.168.41.34/test/demo
      insecure: true
      debug: true
      dockerfile: Dockerfile
      tags:
        - canary
    when:
      branch:
        - master
        - dev
      event:
        - push

  # 稳定版
  - name: docker-release
    image: plugins/docker:18.09
    settings:
      username: drone
      password:
        from_secret: DOCKER_PASSWORD
      registry: 192.168.41.34
      repo: 192.168.41.34/test/demo
      insecure: true
      dockerfile: Dockerfile
      tags:
        - ${DRONE_TAG}
        - latest
    when:
      event:
        - tag

  # 开发版部署
  - name: k8s-deploy-${DRONE_BRANCH}
    image: 192.168.41.34/pub/kubectl:v1
    commands:
      - namespace=dev
      - version=canary
      - sh deploy.sh $namespace $version
    when:
      branch:
        - master
        - dev
      event:
        - push

  # 稳定版部署
  - name: k8s-deploy-release
    image: 192.168.41.34/pub/kubectl:v1
    commands:
      - namespace=test
      - version=${DRONE_TAG}
      - sh deploy.sh $namespace $version
    when:
      event:
        - tag

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo
  namespace: NAMESPACE
  labels:
    env: NAMESPACE
    app: demo
spec:
  selector:
    matchLabels:
      env: NAMESPACE
      app: demo
  replicas: 1
  template:
    metadata:
      labels:
        env: NAMESPACE
        app: demo
    spec:
       containers:
        - name: demo
          image: 192.168.41.34/test/demo:VERSION
          imagePullPolicy: Always
          ports:
          - name: http
            containerPort: 8080
            protocol: TCP

deploy.sh

namespace=$1
version=$2
name=demo
image=192.168.41.34/test/demo

sed -ie "s/VERSION/$version/g" deployment.yaml
sed -ie "s/NAMESPACE/$namespace/g" deployment.yaml
cat deployment.yaml
# 没有则创建Deployment对象,有则更新镜像
kubectl get deployments/$name -n $namespace || kubectl apply -f deployment.yaml
kubectl set image deployments/$name $name="$image:$version" -n $namespace

Dockerfile

FROM 192.168.41.34/pub/golang:1.12 as builder
WORKDIR /build
COPY . .
RUN  CGO_ENABLED=0 GOPROXY=http://192.168.40.131:4000 go build -o demo
FROM alpine:3.10 as runner
LABEL description="the image is a demo"
WORKDIR /app
COPY --from=builder /build/demo /app/
EXPOSE 8080
ENTRYPOINT ["./demo"]

3.总结

golang项目提交代码到gitea,然后触发drone做ci/cd
drone做了以下两步,每一步都是在容器里进行,容器用完即删:

  • 把项目编译打包成docker上传到私有仓库
  • 运行kubectl客户端,创建Deployment对象或者更新对象的image字段值
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐