k8s的使用

构建和运行镜像

编写一个go程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package main

import (
"io"
"log"
"net/http"
)

func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "[v1] Hello, Kubernetes!")
})

log.Printf("v1 access http://localhost:3000\n")
panic(http.ListenAndServe(":3000", nil))
}

编写Dockerfile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 引入golang的环境,并设置别名
FROM golang:1.20-alpine AS builder
# 工作目录
WORKDIR /project
# 把当前文件夹的内容都添加到镜像的/project文件夹下
ADD . .
# 编译golang源代码
# 设置代理、操作系统、CPU架构、禁用cgo编译
# 设置mod为自动模式,防止因为没有设置go.mod而编译报错
RUN GOPROXY=https://goproxy.cn,direct GOOS=linux GOARCH=amd64 CGO_ENABLED=0 GO111MODULE=auto go build -o main -ldflags "-w -extldflags -static"

# 引入alpine系统环境
FROM alpine as prod
# 从上面的build镜像复制编译好的文件/project/main到当前目录
COPY --from=builder /project/main .
# 暴露3000端口
EXPOSE 3000
# 启动main程序
ENTRYPOINT ["/main"]

打包镜像

docker build . -t derobukal/hellok8s:v1

执行镜像,并把3000端口暴露出来

docker run --rm -p 3000:3000 derobukal/hellok8s:v1

之后可以用curl访问3000端口,结果正常显示了

~ curl 127.0.0.1:3000[v1] Hello, Kubernetes!%   

之后可以把这个镜像推送到镜像仓库

docker logindocker push derobukal/hellok8s:v1

使用Pod

编写pod.yaml

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Pod # 资源类型为pod
metadata:
name: go-http # 名称,需要在当前命名空间中唯一
labels:
app: go
version: v1
spec:
containers: # pod内的容器组
- name: go-http
image: derobukal/hellok8s:v1 # 镜像默认来源 DockerHub

之后创建pod

~ kc apply -f pod.yamlpod/go-http created~ kc get podsNAME      READY   STATUS    RESTARTS   AGEgo-http   1/1     Running   0          65s

然后临时开启端口转发,就可以访问相应的服务了

~ kc port-forward go-http 3000:3000Forwarding from 127.0.0.1:3000 -> 3000Forwarding from [::1]:3000 -> 3000~ curl http://127.0.0.1:3000[v1] Hello, Kubernetes!%

在进行以上测试的时候,如果出现pod启动不了的情况,可能是因为防火墙的原因,可以开启网络代理之后再试。

使用Deployment

一般来说,pod不会被直接的使用,而是用Deployment来进行相关的操作。

编写deployment.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: apps/v1
kind: Deployment
metadata:
# deployment 唯一名称
name: hellok8s-go-http
spec:
replicas: 2 # 副本数量
selector:
matchLabels:
app: hellok8s # 管理template下所有 app=hellok8s的pod,(要求和template.metadata.labels完全一致!!!否则无法部署deployment)
template: # template 定义一组容器
metadata:
labels:
app: hellok8s
spec:
containers:
- image: derobukal/hellok8s:v1
name: hellok8s

部署deployment

~ kc apply -f deployment.yaml deployment.apps/hellok8s-go-http created~ kc get deploymentsNAME               READY   UP-TO-DATE   AVAILABLE   AGEhellok8s-go-http   2/2     2            2           79s

kc get pod -o wide可以查看更详细的pod信息。我们可以把配置中的副本数改为3,之后重新执行部署命令,然后查看详细的pod信息如下,可以看到又新增了一个pod

NAME                                READY   STATUS    RESTARTS   AGE     IP           NODE       NOMINATED NODE   READINESS GATESgo-http                             1/1     Running   0          14m     10.244.0.6   minikube   <none>           <none>hellok8s-go-http-6db476b8cb-4n2nx   1/1     Running   0          4m35s   10.244.0.7   minikube   <none>           <none>hellok8s-go-http-6db476b8cb-s76jr   1/1     Running   0          4m35s   10.244.0.8   minikube   <none>           <none>hellok8s-go-http-6db476b8cb-tjqs9   1/1     Running   0          8s      10.244.0.9   minikube   <none>           <none>

我们选取任意一个pod进行端口转发,随后请求可以看到结果正常

~ kc port-forward hellok8s-go-http-6db476b8cb-4n2nx 3000:3000 Forwarding from 127.0.0.1:3000 -> 3000Forwarding from [::1]:3000 -> 3000Handling connection for 3000

更新deployment

我们将golang程序中的v1修改为v2,之后打包新版本镜像并上传

docker build . -t derobukal/hellok8s:v2docker push derobukal/hellok8s:v2

之后我们修改deployment.yaml中的镜像为derobukal/hellok8s:v2,然后更新部署

~ kc apply -f deployment.yaml deployment.apps/hellok8s-go-http configured

可以看到pod都重新部署了

~ kc get pod -o wide                                         NAME                               READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATESgo-http                            1/1     Running   0          25m   10.244.0.6    minikube   <none>           <none>hellok8s-go-http-8b44d58c5-5bmx7   1/1     Running   0          34s   10.244.0.12   minikube   <none>           <none>hellok8s-go-http-8b44d58c5-djfcd   1/1     Running   0          35s   10.244.0.11   minikube   <none>           <none>hellok8s-go-http-8b44d58c5-rt29z   1/1     Running   0          58s   10.244.0.10   minikube   <none>           <none>

之后选取一个Pod进行端口转发,并请求发现返回结果发生了变化

~ kc port-forward hellok8s-go-http-8b44d58c5-5bmx7 3000:3000 Forwarding from 127.0.0.1:3000 -> 3000Forwarding from [::1]:3000 -> 3000Handling connection for 3000~ curl http://127.0.0.1:3000[v2] Hello, Kubernetes!%

回滚deployment

查看版本信息

~ kc rollout history deployment/hellok8s-go-httpdeployment.apps/hellok8s-go-http REVISION  CHANGE-CAUSE1         <none>2         <none>

查看具体版本2

~ kc rollout history deployment/hellok8s-go-http --revision=2deployment.apps/hellok8s-go-http with revision #2Pod Template:Labels:app=hellok8s    pod-template-hash=8b44d58c5Containers:hellok8s:    Image:derobukal/hellok8s:v2    Port:<none>    Host Port:<none>    Environment:<none>    Mounts:<none>Volumes:<none>

查看具体版本1

~ kc rollout history deployment/hellok8s-go-http --revision=1deployment.apps/hellok8s-go-http with revision #1Pod Template:Labels:app=hellok8s    pod-template-hash=6db476b8cbContainers:hellok8s:    Image:derobukal/hellok8s:v1    Port:<none>    Host Port:<none>    Environment:<none>    Mounts:<none>Volumes:<none>

回退到版本1

~ kc rollout undo deployment/hellok8s-go-http --to-revision=1deployment.apps/hellok8s-go-http rolled back

此时查看pod可以发现pod已经发生了改变,访问服务返回的也是v1版本信息了。

部署失败

我们构建一个如下的程序

1
2
3
4
5
package main

func main() {
panic("something went wrong")
}

之后打包一个新版本镜像:docker build . -t derobukal/hellok8s:v_error
并对这个镜像进行push:docker push derobukal/hellok8s:v_error

之后可以简单地使用命令而不修改deployment.yaml文件来重新部署deployment,通过命令修改镜像:

~ kc set image deployment/hellok8s-go-http hellok8s=derobukal/hellok8s:v2_error  deployment.apps/hellok8s-go-http image updated~ kc get podsNAME                                READY   STATUS              RESTARTS        AGEgo-http                             1/1     Running             1 (7m34s ago)   54mhellok8s-go-http-55669566cb-l69hx   0/1     ContainerCreating   0               41shellok8s-go-http-6db476b8cb-dlr2z   1/1     Running             1 (7m34s ago)   22mhellok8s-go-http-6db476b8cb-glx7h   1/1     Running             1 (7m34s ago)   22mhellok8s-go-http-6db476b8cb-sfxnr   1/1     Running             1 (7m34s ago)   22m

重新部署之后我们查看pod可以发现,之前的pod仍然在正常运行,而新启动的pod则处于ContainerCreating状态。我们可以直接回退到上一个版本

~ kc rollout undo deployment/hellok8s-go-http --to-revision=2deployment.apps/hellok8s-go-http rolled back~ kc get podsNAME                                READY   STATUS        RESTARTS      AGEgo-http                             1/1     Running       1 (12m ago)   58mhellok8s-go-http-55669566cb-l69hx   0/1     Terminating   0             5m17shellok8s-go-http-8b44d58c5-74mhw    1/1     Running       0             22shellok8s-go-http-8b44d58c5-hfpjj    1/1     Running       0             20shellok8s-go-http-8b44d58c5-lzwfm    1/1     Running       0             19s