本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
一、前言
上节中,我们使用 Github Actions 的简单 CI 流程搭建实现了自动打包上传镜像功能。本节中,我们在 mac 本地环境搭建一个简易的 K8S 测试集群,将镜像部署到集群中,对外提供服务。
二、安装本地 K8S 集群
常见本地搭建 K8S 集群的工具: Minikube、MircroK8S、K3d、Desktop 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 --version、 docker-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 开关,这时会自动拉取镜像并安装。
稍等片刻,就会出现 Kubernetes is running 的标识,K8S 安装完成~
5. 验证 K8S 本地环境
命令行执行 kubectl get nodes、kubectl 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. 编写 Deployment 的 yaml 文件
创建名为 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,再将其加入yaml的imagePullSecrets配置,再次拉取镜像,此处不再详细展开。
其他常用命令:
- 修改命令
kubectl edit deployments/xxx - 删除命令
kubectl delete deployments/xxx
3. 编写 Service 的 yaml 文件
Service可以看作一组提供相同服务的Pods的对外访问接口,Service作用于哪些Pods是通过label selector来定义的,这些Pods能被Service访问,Pod之间的发现和路由自动由Kubernetes Service来处理。
常见的 Service 有四种类型: ClusterIP(默认)、NodePort、LoadBalancer、ExternalName. 其中 NodePort 和 LoadBalancer 两类型的 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 对外访问流程。