K8S 部署应用镜像

784 阅读3分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

一、前言

上节中,我们使用 Github Actions 的简单 CI 流程搭建实现了自动打包上传镜像功能。本节中,我们在 mac 本地环境搭建一个简易的 K8S 测试集群,将镜像部署到集群中,对外提供服务。

二、安装本地 K8S 集群

常见本地搭建 K8S 集群的工具: MinikubeMircroK8SK3dDesktop Docker 等,这些工具都可以快速运行一个本地集群。但我们本文的主题是 QuickStart,即尽可能简易拉通一个完整的应用部署流程,所以我们选用的是 Desktop Docker 工具,可视化、快速的搭建环境。有兴趣的盆友可以自行尝试~ ~ ~

1. 安装 Docker for macOS

下载最新的Docker for Mac,安装并运行,稍后会在顶部的工具栏出现一个鲸鱼图标。

2. 配置镜像加速地址

国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。国内很多云服务商都提供了国内加速器服务,例如:

由于本文使用 mac 本地环境,在任务栏点击 Docker Desktop 应用图标(小鲸鱼) -> Perferences,在左侧导航菜单选择 Docker Engine,在右侧像下边一样编辑 json 文件。修改完成之后,点击 Apply & Restart 按钮,Docker 就会重启并应用配置的镜像地址了。

{
    "registry-mirrors": [
        "https://hub-mirror.c.163.com",
        "https://mirror.baidubce.com"
    ]
}

3. 验证 docker 本地环境

在命令行执行 docker --versiondocker-compose --version 命令来验证是否安装成功

$ docker --version
Docker version 20.10.11, build dea9396
$ docker-compose --version
docker-compose version 1.29.2, build 5becea4c

4. 搭建 K8S 环境

再次在任务栏点击 Docker Desktop 应用图标(小鲸鱼) -> Perferences,在左侧导航菜单选择 Kubernetes,在右侧开启 Enable Kubernetes 开关,这时会自动拉取镜像并安装。

image.png

稍等片刻,就会出现 Kubernetes is running 的标识,K8S 安装完成~

image.png

5. 验证 K8S 本地环境

命令行执行 kubectl get nodeskubectl get nodes,如下图即安装成功

$ kubectl get nodes
NAME                 STATUS    ROLES                   AGE       VERSION
docker-for-desktop   Ready     control-plane,master    4d19h     v1.21.4
$ kubectl cluster-info
Kubernetes control plane is running at https://kubernetes.docker.internal:6443
CoreDNS is running at https://kubernetes.docker.internal:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

三、部署应用

1. 编写 Deploymentyaml 文件

创建名为 common-mail.yaml 的类型为 Deployment 文件

作为最常用的 Kubernetes 对象,Deployment 经常会用来创建 ReplicaSet 和 Pod,一般 Deployment yaml 文件包含四个部分:

  • apiVersion: 表示版本
  • kind: 表示资源
  • metadata: 表示元信息
  • spec: 资源规范字段
apiVersion: apps/v1 # 1.9.0 之前的版本使用 apps/v1beta2,可通过命令 kubectl api-versions 进行查看
kind: Deployment    # 指定创建资源的角色/类型
metadata:           # 资源的元数据/属性
  name: common-mail-service-node # 资源的名字,在同一个 namespace 中必须唯一
  labels:           
    app: common-mail-service 
spec:
  replicas: 2       # 副本数量2
  selector:         # 定义标签选择器
    matchLabels:
      app: common-mail-service
  template:         
    metadata:       # Pod 的定义
      labels:       # Pod 的标签
        app: common-mail-service
    spec:           # 指定该资源的内容
      containers:   
        - name: common-mail-service  # 容器名字
          image: 'xxx/candy-common-mail-service:master-2022-01-10-13-42-32' # 容器镜像地址
          ports:    # 容器对外的端口
            - containerPort: 80

2. 执行创建 Deployment

执行 kubectl create -f common-mail.yaml 命令,创建 Deployment

$ kubectl get pods -o wide
NAME                                        READY   STATUS    RESTARTS   AGE    IP          NODE             NOMINATED NODE   READINESS GATES
common-mail-service-node-6858687c48-85psg   1/1     Running   0          4d5h   10.1.0.11   docker-desktop   <none>           <none>
common-mail-service-node-6858687c48-kpffs   1/1     Running   0          4d5h   10.1.0.10   docker-desktop   <none>           <none>

FAQ:为何出现 Pods 的状态为 ImagePullBackOff?原因是 K8S 不支持拉取私有镜像仓库。需要使用 kubectl create secret 命令,在客户端手动创建 secret,再将其加入 yamlimagePullSecrets 配置,再次拉取镜像,此处不再详细展开。

其他常用命令:

  • 修改命令 kubectl edit deployments/xxx
  • 删除命令 kubectl delete deployments/xxx

3. 编写 Serviceyaml 文件

Service 可以看作一组提供相同服务的 Pods 的对外访问接口,Service 作用于哪些 Pods 是通过 label selector 来定义的,这些 Pods 能被 Service 访问,Pod之间的发现和路由自动由 Kubernetes Service 来处理。

常见的 Service 有四种类型: ClusterIP(默认)NodePortLoadBalancerExternalName. 其中 NodePortLoadBalancer 两类型的 Services 可以对外提供服务。

本文中,使用 NodePort 类型提供对外服务,创建名为 common-mail-service.yaml 的类型为 Service 文件,如下:

apiVersion: v1
kind: Service
metadata:
  name: common-mail-service
  labels:
    app: common-mail-service
spec:
  type: NodePort    # NodePort 类型的
  ports:
  - port: 80        # 对应集群内部的访问端口
    targetPort: 80  # 此端口为 container 暴露出来端口,与 Dockerfile 文件中一致
    protocol: TCP
    nodePort: 30000 # 此端口供外部调用
  selector:
    app: common-mail-service

4. 执行创建 Service

执行 kubectl create -f service.yaml 命令,创建 Service,之后列出所有的 Service

$ kubectl get services
NAME                  TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
common-mail-service   NodePort    10.111.125.205   <none>        80:30000/TCP   8m56s
kubernetes            ClusterIP   10.96.0.1        <none>        443/TCP        5d3h

5. 验证服务可访问性

# 外部访问
$ curl localhost:30000/mail/demo
Send mail success

# 集群访问
$ curl 10.111.125.205/mail/demo (80 端口缺省)
Send mail success

到此我们已经成功将应用部署到 K8S 集群中,并对外提供服务 ~

小结

本节中,我们在 mac 本地环境搭建一个简易的 K8S 测试集群,并将上节创建的镜像部署到该集群中,对外提供服务。

下节预告

本文中我们通过 Service 通过 NodePort 类型提供对外服务,下节我们使用 LoadBalancer 类型来对外提供服务,并说明 Service 对外访问流程。