0%

k8s服务部署

kubernetes的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。目的是实现资源管理的自动化,主要提供了如下的主要功能:

  • 自我修复:一旦某一个容器崩溃,能够在1秒中左右迅速启动新的容器
  • 弹性伸缩:可以根据需要,自动对集群中正在运行的容器数量进行调整
  • 服务发现:服务可以通过自动发现的形式找到它所依赖的服务
  • 负载均衡:如果一个服务起动了多个容器,能够自动实现请求的负载均衡
  • 版本回退:如果发现新发布的程序版本有问题,可以立即回退到原来的版本
  • 存储编排:可以根据容器自身的需求自动创建存储卷

k8s根据官网指引学习Kubernetes 文档 | Kubernetes

在 Kubernetes 上部署第一个应用程序

Deployment 处于 master 节点上,通过发布 Deployment,master 节点会选择合适的 worker 节点创建 Container(即图中的正方体),Container 会被包含在 Pod (即蓝色圆圈)里。

module_02_first_app.25e902c4

部署 nginx Deployment

在k8s中,通过发布 Deployment,可以创建应用程序 (image) 的实例 (container),这个实例会被包含在称为 Pod 的概念中,Pod 是 k8s 中最小可管理单元。

在 k8s 集群中发布 Deployment 后,Deployment 将指示 k8s 如何创建和更新应用程序的实例,master 节点将应用程序实例调度到集群中的具体的节点上。

创建应用程序实例后,Kubernetes Deployment Controller 会持续监控这些实例。如果运行实例的 worker 节点关机或被删除,则 Kubernetes Deployment Controller 将在群集中资源最优的另一个 worker 节点上重新创建一个新的实例。这提供了一种自我修复机制来解决机器故障或维护问题。

在容器编排之前的时代,各种安装脚本通常用于启动应用程序,但是不能够使应用程序从机器故障中恢复。通过创建应用程序实例并确保它们在集群节点中的运行实例个数,Kubernetes Deployment 提供了一种完全不同的方式来管理应用程序

1、创建文件 nginx-deployment.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: apps/v1	#与k8s集群版本有关,使用 kubectl api-versions 即可查看当前集群支持的版本
kind: Deployment #该配置的类型,我们使用的是 Deployment
metadata: #译名为元数据,即 Deployment 的一些基本属性和信息
name: nginx-deployment #Deployment 的名称
labels: #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组,目前不需要理解
app: nginx #为该Deployment设置key为app,value为nginx的标签
spec: #这是关于该Deployment的描述,可以理解为你期待该Deployment在k8s中如何使用
replicas: 1 #使用该Deployment创建一个应用程序实例
selector: #标签选择器,与上面的标签共同作用,目前不需要理解
matchLabels: #选择包含标签app:nginx的资源
app: nginx
template: #这是选择或创建的Pod的模板
metadata: #Pod的元数据
labels: #Pod的标签,上面的selector即选择包含标签app:nginx的Pod
app: nginx
spec: #期望Pod实现的功能(即在pod中部署)
containers: #生成container,与docker中的container是同一种
- name: nginx #container的名称
image: nginx:latest #使用镜像nginx:latest创建container,该container默认80端口可访问
imagePullPolicy: IfNotPresent

2、应用 YAML 文件,并查看状态

1
2
3
4
5
6
7
8
[root@k8s-master nginx]# kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment created
[root@k8s-master nginx]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 1/1 1 1 23m
[root@k8s-master nginx]# kubectl get po
NAME READY STATUS RESTARTS AGE
nginx-deployment-7f7499b7f6-nfnj4 1/1 Running 0 23m

创建service,用于外部访问

Service是一个抽象层,它通过 LabelSelector 选择了一组 Pod(容器组),把这些 Pod 的指定端口公布到到集群外部,并支持负载均衡和服务发现。

  • 公布 Pod 的端口以使其可访问
  • 在多个 Pod 间实现负载均衡
  • 使用 Label 和 LabelSelector

下图中有两个服务Service A(黄色虚线)和Service B(蓝色虚线) Service A 将请求转发到 IP 为 10.10.10.1 的Pod上, Service B 将请求转发到 IP 为 10.10.10.2、10.10.10.3、10.10.10.4 的Pod上。

module_04_services.11cdc7bc

Service 将外部请求路由到一组 Pod 中,它提供了一个抽象层,使得 Kubernetes 可以在不影响服务调用者的情况下,动态调度容器组(在容器组失效后重新创建容器组,增加或者减少同一个 Deployment 对应容器组的数量等)。

Service使用 Labels、LabelSelector(标签和选择器)匹配一组 Pod。Labels(标签)是附加到 Kubernetes 对象的键/值对,其用途有多种:

  • 将 Kubernetes 对象(Node、Deployment、Pod、Service等)指派用于开发环境、测试环境或生产环境
  • 嵌入版本标签,使用标签区别不同应用软件版本
  • 使用标签对 Kubernetes 对象进行分类

下图体现了 Labels(标签)和 LabelSelector(标签选择器)之间的关联关系

  • Deployment B 含有 LabelSelector 为 app=B 通过此方式声明含有 app=B 标签的 Pod 与之关联
  • 通过 Deployment B 创建的 Pod 包含标签为 app=B
  • Service B 通过标签选择器 app=B 选择可以路由的 Pod

module_04_labels.3255e3d0

1、创建nginx-service.yaml文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1
kind: Service
metadata:
name: nginx-service #Service 的名称
labels: #Service 自己的标签
app: nginx #为该 Service 设置 key 为 app,value 为 nginx 的标签
spec: #这是关于该 Service 的定义,描述了 Service 如何选择 Pod,如何被访问
selector: #标签选择器
app: nginx #选择包含标签 app:nginx 的 Pod
ports:
- name: nginx-port #端口的名字
protocol: TCP #协议类型 TCP/UDP
port: 80 #集群内的其他容器组可通过 80 端口访问 Service
nodePort: 32600 #通过任意节点的 32600 端口访问 Service
targetPort: 80 #将请求转发到匹配 Pod 的 80 端口
type: NodePort #Serive的类型,ClusterIP/NodePort/LoaderBalancer

2、查看状态,并用ip访问

1
2
3
4
[root@k8s-master nginx]# kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d23h <none>
nginx-service NodePort 10.108.169.210 <none> 80:32600/TCP 26m app=nginx

image-20240423110746019

image-20240423110811913

应用扩容缩容

1、修改deployment.yml文件

1
2
spec:	        #这是关于该Deployment的描述,可以理解为你期待该Deployment在k8s中如何使用
replicas: 2 #使用该Deployment创建一个应用程序实例 从1改为2

2、执行命令,可以看到已经变成了两个实例

1
2
3
4
5
6
7
8
9
[root@k8s-master nginx]# kubectl apply -f nginx-deployment.yaml 
deployment.apps/nginx-deployment configured
[root@k8s-master nginx]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 2/2 2 2 41m
[root@k8s-master nginx]# kubectl get po
NAME READY STATUS RESTARTS AGE
nginx-deployment-7f7499b7f6-n7h6n 1/1 Running 0 102s
nginx-deployment-7f7499b7f6-nfnj4 1/1 Running 0 41m

执行滚动更新

Rolling Update滚动更新通过使用新版本的 Pod 逐步替代旧版本的 Pod 来实现 Deployment 的更新,Service 能够监视 Pod 的状态,将流量始终转发到可用的 Pod 上,从而实现零停机。

1、修改 nginx-deployment.yaml 文件

修改文件中 image 镜像的标签,如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.24.0
imagePullPolicy: IfNotPresent

2、执行命令

1
2
[root@k8s-master nginx]# kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deployment configured

3、执行命令,可观察到 pod 逐个被替换的过程(可能有点慢,要先下载镜像)

1
2
3
4
5
6
7
[root@k8s-master nginx]# watch kubectl get pods -l app=nginx
Every 2.0s: kubectl get pods -l app=nginx Tue Apr 23 11:30:15 2024

NAME READY STATUS RESTARTS AGE
nginx-deployment-6b85df66b4-6jftl 0/1 ContainerCreating 0 42s
nginx-deployment-7f7499b7f6-n7h6n 1/1 Running 0 9m23s
nginx-deployment-7f7499b7f6-nfnj4 1/1 Running 0 49m

4、通过查看报错页面的版本号可以看到版本正在替换

image-20240423113132302

image-20240423113143116

image-20240423113310582

5、如果deployment配置没有进行修改也想滚动更新的话就执行下面这句,相当于重启了deployment

1
kubectl rollout restart deploy nginx-deployment

服务回滚

1、查看历史版本

1
2
3
4
5
6
[root@k8s-master nginx]# kubectl rollout history deploy nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
2 <none>
3 <none>

2、回退

命令如果不加--to-revision=x 默认回退到上一版本

1
2
3
4
[root@k8s-master nginx]# kubectl rollout undo deploy nginx-deployment --to-revision=2
deployment.apps/nginx-deployment rolled back
[root@k8s-master nginx]# kubectl rollout status deploy nginx-deployment
deployment "nginx-deployment" successfully rolled out

配置说明

赏口饭吃吧!