lqshow / notes

Cheat Sheet
10 stars 2 forks source link

k8s 使用 Deployment 管理应用 #40

Open lqshow opened 6 years ago

lqshow commented 6 years ago

在生成环境中,线上的每个服务不能受单个节点故障的影响,同时我们还要根据负载均衡动态调整节点的数量。所以不大可能逐个的通过 Pod 来部署管理应用, k8s 通过 Deployment 能够创建指定数量的 Pod 部署到不同的 Node 上,并且能够很方便的对应用进行升级和回滚操作。

这里以部署一个 Golang 应用为例,来看下一个高可用服务在生产环境常用到的一些操作

创建 Golang 应用

准备代码文件

创建一个名为 server.go 的文件,代码如下

package main

import (
    "fmt"
    "log"
    "net/http"
    "os"
)

func homePage(w http.ResponseWriter, r *http.Request) {
    host, err := os.Hostname()
    check(err)
    fmt.Fprintf(w, "Welcome to the HomePage! \n\nHostname is %s", host)

    fmt.Println("Endpoint Hit: homePage")
}

func check(err error) {
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    }
}

func handleRequests() {
    http.HandleFunc("/", homePage)
    log.Fatal(http.ListenAndServe(":3000", nil))
}

func main() {
    handleRequests()
}

启动应用

go run server.go

查看应用效果

image

生成镜像

Dockerfile 文件

FROM golang:alpine

WORKDIR /data/project
COPY ./ ./

RUN go build -o server .
CMD ["./server"]

通过以上代码文件以及 Dockerfile文件构建一个镜像,镜像名为 lqshow/golang-app:0.0.1

k8s 管理应用

创建 Deployment

首先定义 deploy.yml 文件

apiVersion: v1
kind: Service

metadata:
  name: golang-app-svc
  labels:
    app: golang-app

spec:
  ports:
  - port: 3000
    nodePort: 30081

  selector:
    app: golang-app

  type: NodePort

---

apiVersion: extensions/v1beta1
kind: Deployment

metadata:
  name: golang-app-deploy
  labels:
    app: golang-app

spec:
  replicas: 3

  template:
    metadata:
      labels:
        app: golang-app
    spec:
      containers:
      - name: golang-app-container
        image: lqshow/golang-app:0.0.1
        ports:
          - containerPort: 3000

执行以下命令部署应用

kubectl create -f deploy.yml --record

查看部署情况

deploy4

横向扩展

根据实际运营情况,一个服务扩容和缩容是经常碰到的问题,有两种方法可以实现该操作

# 通过kubectl scale指令来扩容和缩容
kubectl scale deploy/golang-app-deploy --replicas=4

# 通过更改 deploy.yml 中的 replicas 值来扩容
# replicas: 4
kubectl apply -f deployment.yaml --record

滚动更新

假设我们对项目做了更新,比如加了一个新的接口,这时候就要发布一个新版本,需要构建一个新的镜像 lqshow/golang-app:0.0.2。

如果我们只是更新一个镜像版本,可通过如下命令实现

kubectl set image deploy/golang-app-deploy golang-app-container=lqshow/golang-app:0.0.2

验证新加的接口是否生效

image

如果我们既要更新镜像版本,又要扩容,还是通过更新配置文件方便些

kubectl apply -f deploy_rolling_update.yml --record

查看发布状态

kubectl rollout status deployment golang-app-deploy

版本回滚

查看更新的历史

➜  kubernetes git:(master) ✗ kubectl rollout history deployment golang-app-deploy
deployments "golang-app-deploy"
REVISION  CHANGE-CAUSE
1         kubectl apply --filename=deploy.yml --record=true
2         kubectl set image deploy/golang-app-deploy golang-app-container=lqshow/golang-app:0.0.2
3         kubectl apply --filename=deploy_rolling_update.yml --record=true

查看某个具体版本

➜  kubernetes git:(master) ✗ kubectl rollout history deployment golang-app-deploy --revision=3
deployments "golang-app-deploy" with revision #3
Pod Template:
  Labels:       app=golang-app
        pod-template-hash=3862271339
  Annotations:  kubernetes.io/change-cause=kubectl apply --filename=deploy_rolling_update.yml --record=true
  Containers:
   golang-app-container:
    Image:      lqshow/golang-app:0.0.2
    Port:       80/TCP
    Host Port:  0/TCP
    Environment:        <none>
    Mounts:     <none>
  Volumes:      <none>

如果发布后发现重大 Bug,需要回滚到老版本,可执行以下命令

# 回滚到指定版本
kubectl rollout undo deployment/golang-app-deploy --to-revision=1

rollouting

References