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

  • 尝试 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 参数,例如:

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

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

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

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

创建 Deployment

我们来部署一个 Nginx 应用。

  1. kubectl create deployment nginx --image=nginx:latest

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

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

获取所有 deployment :

  1. kubectl get deployments
  1. NAME READY UP-TO-DATE AVAILABLE AGE
  2. nginx 1/1 1 1 2m24s

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

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

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

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

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

导出 yaml

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

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

然后终端会打印:

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. annotations:
  5. deployment.kubernetes.io/revision: "1"
  6. creationTimestamp: "2021-04-21T00:37:13Z"
  7. generation: 1
  8. labels:
  9. app: nginx
  10. name: nginx
  11. namespace: default
  12. ... ...

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

  1. kubectl delete deployment ngin

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

  1. 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 创建,命令格式:

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

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

  1. kind: Deployment
  2. ... ...
  3. medatada:
  4. name:nginx
  5. ... ...
  6. spec:
  7. containers:
  8. - image: nginx:latest

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

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

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

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

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

  1. 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 文件,

  1. spec:
  2. containers:
  3. - name: nginx
  4. image: nginx:1.14.2
  5. ports:
  6. - containerPort: 80

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

  1. kubectl apply -f mynginx.yaml

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

  1. spec:
  2. containers:
  3. - image: nginx:latest
  4. imagePullPolicy: Always
  5. name: nginx
  6. ports:
  7. - containerPort: 80
  8. protocol: TCP
  9. ... ...
  10. 注:在里面加上了
  11. ports:
  12. - containerPort: 80
  13. protocol: TCP
  14. 这三行。

然后删除两行字段:

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

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

查看 deployment、pod:

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

然后我们创建 service。

  1. kubectl expose deployment nginx

或者指定端口:

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

查看 service:

  1. kubectl get services
  1. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  2. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 24h
  3. nginx ClusterIP 10.101.245.225 <none> 80/TCP 5m57s

查看 端口:

  1. kubectl get ep
  1. NAME ENDPOINTS AGE
  2. kubernetes 10.170.0.2:6443 25h
  3. nginx 192.168.56.24:80 17m

查看 Pod 信息信息:

  1. kubectl describe pod nginx | grep Node:
  1. Node: instance-2/10.170.0.4

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

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

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

  1. curl 192.168.56.24:80
  2. curl 10.101.245.225:80

ReplicaSet

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

  1. NAME READY UP-TO-DATE AVAILABLE AGE
  2. 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 中修改副本数。

  1. kubectl scale deployment nginx --replicas=3

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

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

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

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

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

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

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

  1. NAME ENDPOINTS AGE
  2. kubernetes 10.170.0.2:6443 28h
  3. nginx 192.168.56.24:80,192.168.56.25:80,192.168.56.26:80 3h15m

浅入Kubernetes(7):应用部署实例,Deployment、Service、ReplicaSet的更多相关文章

  1. 浅入Kubernetes(6):CKAD认证中的部署教程

    目录 预设网络 kubeadm 安装 k8s 配置 calico 自动补全工具 状态描述 目前为止,笔者已经写了 5 篇关于 k8s 的文章,这一篇笔者将介绍 CKAD 认证官方课程中,如何部署 k8 ...

  2. 浅入Kubernetes(8):外网访问集群

    目录 查询 Service Service 外部服务类型 配置 ServiceType 伸缩数量 阶段总结 在前面几篇文章中,我们学习了 kubeadm .kubectl 的一些命令,也学会了 Dep ...

  3. 浅入Kubernetes(11):了解 Service 和 Endpoint

    目录 Srevice Service 的创建及现象 Service 定义 Endpoint slices 创建 Endpoint.Service Service 创建应用 创建 Endpoint 浅入 ...

  4. 浅入Kubernetes(12):Deployment 的升级、回滚

    目录 更新 上线 会滚 缩放 Deployment 直接设置 Pod 水平自动缩放 比例缩放 暂停 Deployment 上线 本篇内容讨论 Pod 的更新和回滚,内容不多. 更新 打开 https: ...

  5. 浅入kubernetes(2):Kubernetes 的组成

    目录 说明 Kubernetes集群的组成 What are containerized applications? What are Kubernetes containers? What are ...

  6. 浅入Kubernetes(10):控制节点的部署,选择器、亲和性、污点

    目录 标签和nodeSelector 标签选择 亲和性和反亲和性 污点和容忍度 系统默认污点 容忍度 DaemonSet 在前面的学习中,我们学到了 Deployment 部署,以及副本数(Repli ...

  7. 浅入kubernetes(1):Kubernetes 入门基础

    目录 Kubernetes 入门基础 Introduction basic of kubernetes What Is Kubernetes? Components of Kubernetes Kub ...

  8. 浅入kubernetes(5):尝试kubeadm

    本篇介绍利用 kubernetes 的命令行工具,快速创建集群实例,完成 hello world 实践. 上一篇试用 minikube 去搭建集群,这一篇将介绍通过 kubeadm 去操作. 命令行工 ...

  9. kubernetes发布tomcat服务,通过deployment,service布署

    1.制作tomcat镜像 参考docker tomcat镜像制作 此处直接拉取 查看已有可镜像 先设置docker阿里源,即添加 "registry-mirrors": [&quo ...

随机推荐

  1. c/c++ 之静态库

    静态库 编译成目标文件(未链接) g++ -c a.cc b.cc c.cc d.cc #生成 a.o b.o c.o d.o 将目标文件打包为静态库 ar rs libxxx.a a.o b.o c ...

  2. @RestController和@Controller

    1.使用@Controller 注解,在对应的方法上,视图解析器可以解析return 的jsp,html页面,并且跳转到相应页面 若返回json等内容到页面,则需要加@ResponseBody注解 2 ...

  3. SpringBoot文件上传与POI的使用

    1.使用springboot上传文件 本文所要源码在一个项目中,源码:https://github.com/zhongyushi-git/springboot-upload-download.git. ...

  4. (嘎吧)--微软的 C# , IL,CLR, Cup 之间关系以及扩展联想

    还是啰嗦下:文章短并不代表文章质量不高.我最喜欢用干货性的以及总结性的语言 让大家明白文章要表达的内容.这一切,都是来自多年对.NET 的一些领悟以及一些理解. 不长篇大论,一本人也没时间,二本人也不 ...

  5. SpringBoot(八):SpringBoot中配置字符编码 Springboot中文乱码处理

    SpringBoot中配置字符编码一共有两种方式 方式一: 使用传统的Spring提供的字符编码过滤器(和第二种比较,此方式复杂,由于时间原因这里先不介绍了,后续补上) 方式二(推荐使用) 在appl ...

  6. 【转载】markdown数学常用公式箭头符号

    来源1:https://www.jianshu.com/p/3f01c5658356 来源2:https://blog.csdn.net/smstong/article/details/4434063 ...

  7. 从零搭建一个IdentityServer——单页应用身份验证

    上一篇文章我们介绍了Asp.net core中身份验证的相关内容,并通过下图描述了身份验证及授权的流程: 注:改流程图进行过修改,第三方用户名密码登陆后并不是直接获得code/id_token/acc ...

  8. 修饰符static和abstract

    修饰符static和abstract static static可以修饰类中的方法,属性等,被修饰后的方法和属性可以通过类名直接调用也可以通过对象调用.普通的变量只能通过对象进行调用. 静态方法直接可 ...

  9. 【H264】视频编码发展简史

    一.常见视频编码格式 编码格式有很多,如下图: 目前比较常用的编码有: H26x系列:由ITU(国际电传视讯联盟)主导,侧重网络传输 MPEG系列:由ISO(国际标准组织机构)下属的MPEG(运动图象 ...

  10. linux软件deb打包及开机管理员自启动

    环境:Ubuntu 18.04/16.04  Qt:5.12.6 一 deb打包 1.建立目录结构 2.目录内容 1) 子目录DC520: Get以上内容步骤: (1)   创建目录DC520(自己软 ...