本篇应用的 goweb demo,页面很简略,性能也是很简略,写代码不是本篇的重点,重点是先体验一下整个流程:开发环境筹备、写代码、提交到仓库、拉取代码构建并打包镜像、推送到镜像仓库,部署到 K8S。
本篇的分享分为上篇和下篇,上篇是手动,打算在下篇再讲主动。只有手动体验过,能力更能深刻的了解外面的流程、细节,前面再把这个流程革新为全程自动化就是信手拈来的事件。如果连手工部署都跑不通,还想谈自动化呢?如果是在企业里,谈自动化之前还得先把标准化流程给落实了,再来谈自动化。
golang 开发环境筹备
- 下载 golang 二进制包
wget https://golang.google.cn/dl/go1.19.3.linux-amd64.tar.gz
tar -zxf go1.19.3.linux-amd64.tar.gz
mv go /usr/local/
- 在 /etc/profile 配置环境变量
export GOROOT="/usr/local/go"
export GOPATH="/data/project/gocode"
export GOPROXY="https://goproxy.cn,direct"
export GO111MODULE="on"
export PATH=$PATH:$GOROOT/bin:$GOPATH
# 使其失效
source /etc/profile
GOPROXY 示意的是 go 的代理设置,当主动下载第三方代码的库地址时,go 默认是国外下载,所以配置代理,加快速度,国内个别应用七牛云的 goproxy.cn
- 进入 $GOPATH 创立 src、pkg、bin 目录
[root@workhost ~]# cd $GOPATH
[root@workhost gocode]# mkdir bin pkg src
写代码
- 一个简略的我的项目构造
[root@workhost goweb]# tree
.
├── go.mod
├── main.go
├── README.md
└── static
└── login.html
- 写一个简略的前端页面
static/login.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<title> 不背锅运维 </title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.staticfile.org/twitter-bootstrap/5.1.1/js/bootstrap.bundle.min.js"></script>
</head>
<body class="bg-dark bg-opacity-76">
<div class="container vh-100">
<div class="row vh-100">
<div class="col-4 m-auto p-5 justify-content-center bg-white rounded">
<form action="/login" method="post">
<div class="mb-3">
<label class="form-label mb-1 text-black-50"> 用户名:</label>
<input type="text" class="form-control" name="account">
</div>
<div class="mb-4">
<label class="form-label mb-1 text-black-50"> 明码:</label>
<input type="password" class="form-control" name="password">
</div>
<div class="mb-1">
<button type="submit" class="form-control btn-primary"> 登录 </button>
</div>
</form>
<div class="container mt-3 justify-content-center">
<div class="container">
<p class="text-danger">{{.Msg}}</p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
- 后端代码
main.go
package main
import (
"log"
"net/http"
"text/template"
)
type Message struct {Msg string}
func home(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {w.Header().Set("Location", "/login")
w.WriteHeader(http.StatusFound)
}
}
func login(w http.ResponseWriter, r *http.Request) {t, _ := template.ParseFiles("./static/login.html")
if r.Method == "GET" {t.Execute(w, nil)
} else {r.ParseForm()
account := r.Form["account"][0]
userPwd := r.Form["password"][0]
if account == "tantianran" {
if userPwd == "1qaz#EDC" {msg := Message{Msg: "祝贺!验证通过 O(∩_∩)O"}
t.Execute(w, msg)
} else {msg := Message{Msg: "明码谬误..."}
t.Execute(w, msg)
}
} else {msg := Message{Msg: "用户名谬误..."}
t.Execute(w, msg)
}
}
}
func main() {http.HandleFunc("/", home)
http.HandleFunc("/login", login)
listenAddr := ":80"
log.Println("ListenAndserve", listenAddr)
err := http.ListenAndServe(listenAddr, nil)
if err != nil {log.Println(err)
}
}
- 看看页面成果
- 提交到 gitab
git add .
git commit -m "add code"
git push
编译和打包镜像
- 编译
[root@workhost src]# git clone http://192.168.11.254:8088/tantianran/goweb.git^C
[root@workhost src]# cd goweb/
[root@workhost goweb]# go build main.go
- 编写 Dockerfile
这个 Dockerfile 的作用是将一个 Golang Web 应用程序打包为一个 Docker 镜像,使其能够在 Docker 容器中运行并通过 80 端口对外提供服务。
FROM golang:latest
WORKDIR /app
COPY static /app/static
COPY main /app
EXPOSE 80
CMD ["./main"]
指令解释:
- 开始构建镜像
依据 Dockerfile 构建一个 Docker 镜像并给镜像打上标签。
docker build -t 192.168.11.254:8081/webdemo/goweb:20230427v1 .
- 启动容器
docker run -d -it --name goweb -p 8090:80 192.168.11.254:8081/webdemo/goweb:20230427v1
- 拜访
- 推送到公有仓库
确保镜像没问题之后,推送到 Harbor
docker push 192.168.11.254:8081/webdemo/goweb:20230427v1
装置 ingress-nginx
这里我打算应用 ingress 的形式来裸露利用,应用比拟支流的 ingress-nginx。
- 部署 ingress-nginx
因为是内网的 K8S 测试集群,为了可能疾速测试,以下 deploy.yaml 中裸露 Controller 的形式是应用 NodePort,这种形式实用于简直所有的集群,但通常会应用 30000-32767 范畴内的端口。
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.7.0/deploy/static/provider/baremetal/deploy.yaml
- 部署完后查看:
tantianran@k8s-b-master:~/nginx-ingress$ kubectl get pod,svc -n ingress-nginx
NAME READY STATUS RESTARTS AGE
pod/ingress-nginx-admission-create-6fp24 0/1 Completed 0 9m54s
pod/ingress-nginx-admission-patch-nvtjv 0/1 Completed 0 9m54s
pod/ingress-nginx-controller-6b87568f97-kpms9 1/1 Running 0 9m54s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/ingress-nginx-controller NodePort 10.96.106.100 <none> 80:31179/TCP,443:30701/TCP 9m55s
service/ingress-nginx-controller-admission ClusterIP 10.106.222.181 <none> 443/TCP 9m55s
tantianran@k8s-b-master:~/nginx-ingress$
手工部署到 K8S
- 部署 Deployment、Service 以及创立 Ingress 规定
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: goweb
name: goweb
spec:
replicas: 1
selector:
matchLabels:
app: goweb
template:
metadata:
labels:
app: goweb
spec:
containers:
- image: 192.168.11.254:8081/webdemo/goweb:20230427v1
name: goweb
---
apiVersion: v1
kind: Service
metadata:
labels:
app: goweb
name: goweb
spec:
ports:
- name: http-port
port: 5678
protocol: TCP
targetPort: 80
selector:
app: goweb
type: ClusterIP
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: goweb
spec:
ingressClassName: nginx
rules:
- host: "test.goweb.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: goweb
port:
number: 5678
- 部署实现后查看
tantianran@k8s-b-master:~/goweb$ kubectl get svc,pod,ingress
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/goweb ClusterIP 10.111.92.32 <none> 5678/TCP 2m4s
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 23h
NAME READY STATUS RESTARTS AGE
pod/goweb-57c44c897d-frxf6 1/1 Running 0 2m4s
pod/nfs-client-provisioner-6685d955d-p9w57 1/1 Running 1 (12m ago) 12h
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress.networking.k8s.io/goweb nginx test.goweb.com 192.168.11.101 80 2m4s
tantianran@k8s-b-master:~/goweb$
- 增加域名映射
举荐大家应用 SwitchHosts 工具来治理 hosts,不便日常测试。
- 测试拜访
本文转载于 WX 公众号:不背锅运维(喜爱的盆友关注咱们):https://mp.weixin.qq.com/s/YGhndR5zR-Ebf8IaKbFZiQ