浅入Kubernetes(7):应用部署据实例,Deployment、Service、Re plicaSet

简介: 浅入Kubernetes(7):应用部署据实例,Deployment、Service、Re plicaSet

在本文之前,你需要阅读:

  • 尝试 kubeadm

https://www.cnblogs.com/whuanle/p/14679590.html

https://www.whuanle.cn/archives/1230

  • CKAD认证中的部署教程

https://www.cnblogs.com/whuanle/p/14679922.html

https://www.whuanle.cn/archives/1231


在此之前,需要使用 kubeadm 部署了 master 节点,然后 最好也部署一个 worker 节点(kubeadm join)。在本篇文章中,我们将部署一个 Nginx 实例,并学会 Deployment 配置、网络映射、副本集。


Deployment


Deployment 是 Kubernetes 提供的一种自我修复机制来解决机器故障维护的问题

当我们单独使用 docker 部署应用时,为了应用挂了后能够重启,我们可以使用 --restart=always 参数,例如:


docker run -itd --restart=always -p 666:80 nginx:latest


但是这种方式只能单纯重启容器,并不具备从机器故障中恢复的能力。

Kubernetes Deployment 是一个配置,它可以指挥 Kubernetes 如何创建和更新你部署的应用实例,创建 Deployment 后,Kubernetes master 会将应用程序调度到集群中的各个节点上。Kubernetes Deployment 提供了一种与众不同的应用程序管理方法。


Deployment 的创建,有两种方法,一种是直接使用命令创建,一种是通过 yaml,后面我们会介绍这两种创建方法。


创建 Deployment


我们来部署一个 Nginx 应用。

kubectl create deployment nginx --image=nginx:latest


在 worker 节点上执行 docker ps,可以看到:

root@instance-2:~# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED          STATUS          PORTS     NAMES
fe7433f906a0   nginx     "/docker-entrypoint.…"   7 seconds ago    Up 6 seconds              k8s_nginx_nginx-55649fd747-wdrjj_default_ea41dcc4-94fe-47f9-a804-5b5b1df703e9_0


获取所有 deployment :

kubectl get deployments


NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   1/1     1            1           2m24s


使用 kubectl describe deployment nginx 可以获得更加详细的信息。

使用 kubectl get events 可以获得创建 Deployment 到部署容器过程的详细事件记录。


Successfully assigned default/nginx-55649fd747-wdrjj to instance-2
Pulling image "nginx:latest"
Successfully pulled image "nginx:latest" in 8.917597859s
Created container nginx
Started container nginx
Created pod: nginx-55649fd747-wdrjj
Scaled up replica set nginx-55649fd747 to 1


我们也可以使用 yaml 文件创建 Deployment:

kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml


导出 yaml

无论哪种部署方式,我们都可以从已经创建的 Deployment 导出 yaml 文件,使用 -o yaml 即可导出(-o json 导出json)。


kubectl get deployment nginx -o yaml
# 保存到文件
# kubectl get deployment nginx -o yaml > mynginx.yaml


然后终端会打印:

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: "2021-04-21T00:37:13Z"
  generation: 1
  labels:
    app: nginx
  name: nginx
  namespace: default
... ...


我们可以尝试把 yaml 导出到 mynginx.yaml 文件中,然后我们删除这个 Deployment。

kubectl delete deployment ngin


然后利用导出的 mynginx.yaml 再创建一个 Deployment。

kubectl apply -f mynginx.yaml


kubectl apply/create


当我们创建一个 deployment 时,kubectl createkubectl apply 效果是一样的,但是 apply 还具有更新(update) 的功能。


kubectl apply 会在以前的配置、提供的输入和资源的当前配置之间 找出三方差异,以确定如何修改资源,kubectl apply 命令将会把推送的版本与以前的版本进行比较,并应用你所做的更改, 但是不会自动覆盖任何你没有指定更改的属性

另外还有 kubectl replacekubectl editkubectl replace 是破坏性更新/替换,容易导致问题;kubectl edit 可以更新 deployment。


根据 Kubernetes 官方的文档,应始终使用 kubectl applykubectl create --save-config 创建资源。


这里再说一下创建 deployment 的区别。


如果使用 create 创建,命令格式:

kubectl create deployment {deployment的名字} --image={镜像名称}


如果使用 apply 命令创建,yaml 中需要指定一些信息:

kind: Deployment
... ...
medatada:
    name:nginx
... ...
    spec:
      containers:
      - image: nginx:latest


然后执行 kubectl apply -f xxx.yaml 文件。


一个是 kubectl create deployment ;另一个是 kubectl apply -f,在 yaml 中指定 kind: Deployment


有时我们不知道我们的创建命令或 yaml 是否正确,可以使用 --dry-run=client--dry-run=client 参数来预览而不真正提交。


kubectl create deployment testnginx --image=nginx:latest --dry-run=client


在一些 k8s 认证中,我们没时间一点点写 yaml ,但是又需要定制,此时可以使用 --dry-run=client -o yaml ,既可以不生效 Deployment,又可以导出 yaml 文件。


kubectl create deployment testnginx --image=nginx:latest --dry-run=client -o yaml


除了 deployment,其它 kubernetes 对象也可以使用这种方法,格式是 kubectl {对象} {参数} --dry-run=client -o yaml


kubernetes 对象/资源,有 deployment、job、role、namespace 等。

还有一个地方也说一下,kubectl get xxx 时,带不带 s 都没关系,例如 kubectl get nodes / kubectl get node 都是一样的。


不过,一般从语义上,我们获取全部对象时,可以使用 kubectl get nodes,获取具体的对象时,可以使用 kubectl get node nginx。类似的,kubectl describe nodeskubectl describe node nginx。实际上加不加 s 都一样。


网络端口映射和更新 Deployment


对于 docker,我们要映射端口时,可以使用 docker ... -p 6666:80 ,那么对于 deployment 部署容器应用,我们怎么处理呢?


我们可以看一下 https://k8s.io/examples/controllers/nginx-deployment.yaml 文件,

spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80


这里我们不直接使用这个 yaml 文件,继续使用之前的 yaml 文件,我们首先部署一个 nginx。

kubectl apply -f mynginx.yaml


然后修改 mynginx.yaml 文件,找到 image: nginx:latest,在后面加上端口映射。

spec:
      containers:
      - image: nginx:latest
        imagePullPolicy: Always
        name: nginx
        ports:
        - containerPort: 80
          protocol: TCP
... ...
注:在里面加上了
        ports:
        - containerPort: 80
          protocol: TCP
          这三行。


然后删除两行字段:

resourceVersion: "109967"
  uid: e66201e3-a740-4c1c-85f5-a849db40a0fd


因为这两个字段限定了版本和 uid ,这样替换或更新的时候,可以对 nginx 的 deployment 直接操作。


查看 deployment、pod:

kubectl get deployment,pod


NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx   1/1     1            1           5m44s
NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-55649fd747-9vfrx   1/1     Running   0          5m44s


然后我们创建 service。

kubectl expose deployment nginx


或者指定端口:

kubectl expose deployment nginx --port=80 --target-port=8000


查看 service:

kubectl get services


NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   24h
nginx        ClusterIP   10.101.245.225   <none>        80/TCP    5m57s


查看 端口:

kubectl get ep


NAME         ENDPOINTS          AGE
kubernetes   10.170.0.2:6443    25h
nginx        192.168.56.24:80   17m


查看 Pod 信息信息:

kubectl describe pod nginx | grep Node:


Node:         instance-2/10.170.0.4

因为 deployment 部署的 应用/pod ,不会在 master 上,不同 Node 是不能访问的。

使用 kubectl get serviceskubectl get ep 查询的 ip ,我们可以在 worker 节点上直接访问。


例如笔者查询出来的 ip,可以在 worker 中这样访问。

curl 192.168.56.24:80
curl 10.101.245.225:80


ReplicaSet


我们执行 kubectl get deployments 命令,输出:

NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   1/1     1            1           38m
  • NAME 列出了集群中 Deployment 的名称。
  • READY 显示应用程序的可用的 副本 数。显示的模式是“就绪个数/期望个数”。
  • UP-TO-DATE 显示为了达到期望状态已经更新的副本数。
  • AVAILABLE 显示应用可供用户使用的副本数。
  • AGE 显示应用程序运行的时间。


副本

因为容器化应用中,根据云原生12因素的方法论和核心思想,一个 Processes 应当是无状态的,任何持久化的数据都要存储在后端服务中。因此,A 镜像,启动 N 个 docker 容器,端口为 801、802、803...,他们其实都是一样的,我们访问哪个容器,最终提供的服务都是一致的。


但是,如果我们把这些容器放到不同 Node 中,再通过 k8s ,就可以为多个实例之间分配流量,即负载均衡。


在 Deployment 中,可以通过指定 yaml 文件的 .spec.replicas 字段或者以命令参数 --replicas= 设置副本数量。


ReplicaSet


“ReplicaSet 的目的是维护一组在任何时候都处于运行状态的 Pod 副本的稳定集合。 因此,它通常用来保证给定数量的、完全相同的 Pod 的可用性。”


感兴趣的读者可以看文档:https://kubernetes.io/zh/docs/concepts/workloads/controllers/replicaset/

在前面,我们已经创建了 nginx ,接下来我们在这个 deployment 中修改副本数。


kubectl scale deployment nginx --replicas=3


然后等几秒后执行 kubectl get deployments 查看结果。

NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   3/3     3            3           3h15m


执行 kubectl get pod -o wide 可以输出信息的 pod 信息 。

NAME       READY   STATUS   ESTARTS   AGE     IP              NODE     NOMINATED NODE   READINESS GATES
nginx-581   1/1     Running   0     3h11m   192.168.56.24   instance-2   <none>           <none>
nginx-582   1/1     Running   0     3m30s   192.168.56.25   instance-2   <none>           <none>
nginx-583   1/1     Running   0     3m30s   192.168.56.26   instance-2   <none>           <none>
# 注,笔者删除了Name的部分名称


可以看到 这几个 pod 都分配在 instance-2 这个节点上,因为我只有一台 worker 节点服务器,如果多创建几台节点服务器,k8s 会自动分配到不同的节点中。什么的输出也可以看到,每个 pod 都有自己的 ip 地址。


当我们使用 kubectl delete xxx 删除 pod 时,Deployment 会自动保持三个副本集,所以会自动启用新的 pod 。


执行 kubectl get ep 可以看到不同 pod 暴露的 端口。


NAME         ENDPOINTS                                            AGE
kubernetes   10.170.0.2:6443                                      28h
nginx        192.168.56.24:80,192.168.56.25:80,192.168.56.26:80   3h15m
相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
相关文章
|
21天前
|
Kubernetes 网络协议 应用服务中间件
K8S二进制部署实践-1.15.5
K8S二进制部署实践-1.15.5
31 0
|
29天前
|
存储 运维 Kubernetes
容器服务ACK常见问题之修改service的名字失败如何解决
容器服务ACK(阿里云容器服务 Kubernetes 版)是阿里云提供的一种托管式Kubernetes服务,帮助用户轻松使用Kubernetes进行应用部署、管理和扩展。本汇总收集了容器服务ACK使用中的常见问题及答案,包括集群管理、应用部署、服务访问、网络配置、存储使用、安全保障等方面,旨在帮助用户快速解决使用过程中遇到的难题,提升容器管理和运维效率。
|
22天前
|
Kubernetes 流计算 Perl
在Rancher K8s上部署Flink时,TaskManager连接不上并不断重启可能是由多种原因导致的
在Rancher K8s上部署Flink时,TaskManager连接不上并不断重启可能是由多种原因导致的
33 7
|
6天前
|
Kubernetes 监控 Cloud Native
构建高效云原生应用:基于Kubernetes的微服务治理实践
【4月更文挑战第13天】 在当今数字化转型的浪潮中,企业纷纷将目光投向了云原生技术以支持其业务敏捷性和可扩展性。本文深入探讨了利用Kubernetes作为容器编排平台,实现微服务架构的有效治理,旨在为开发者和运维团队提供一套优化策略,以确保云原生应用的高性能和稳定性。通过分析微服务设计原则、Kubernetes的核心组件以及实际案例,本文揭示了在多变的业务需求下,如何确保系统的高可用性、弹性和安全性。
11 4
|
7天前
|
JSON Kubernetes Go
无缝集成:在IntelliJ IDEA中利用Kubernetes插件轻松管理容器化应用
无缝集成:在IntelliJ IDEA中利用Kubernetes插件轻松管理容器化应用
16 0
无缝集成:在IntelliJ IDEA中利用Kubernetes插件轻松管理容器化应用
|
5天前
|
Kubernetes 搜索推荐 Docker
使用 kubeadm 部署 Kubernetes 集群(二)k8s环境安装
使用 kubeadm 部署 Kubernetes 集群(二)k8s环境安装
38 17
|
17天前
|
Kubernetes Ubuntu 应用服务中间件
Ubuntu 22.04 利用kubeadm方式部署Kubernetes(v1.28.2版本)
Ubuntu 22.04 利用kubeadm方式部署Kubernetes(v1.28.2版本)
80 0
|
18天前
|
消息中间件 Kubernetes Kafka
Terraform阿里云创建资源1分钟创建集群一键发布应用Terraform 创建 Kubernetes 集群
Terraform阿里云创建资源1分钟创建集群一键发布应用Terraform 创建 Kubernetes 集群
14 0
|
20天前
|
人工智能 监控 Serverless
如何基于ACK Serverless快速部署AI推理服务
通过上述步骤,可以在ACK Serverless上快速部署AI推理服务,实现高可用、弹性扩展的服务架构。
19 1
|
26天前
|
Kubernetes Java Nacos
nacos常见问题之k8s上部署需要自动扩缩容如何解决
Nacos是阿里云开源的服务发现和配置管理平台,用于构建动态微服务应用架构;本汇总针对Nacos在实际应用中用户常遇到的问题进行了归纳和解答,旨在帮助开发者和运维人员高效解决使用Nacos时的各类疑难杂症。
28 0