博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
kubernetes学习笔记 (二):k8s初体验
阅读量:6437 次
发布时间:2019-06-23

本文共 6424 字,大约阅读时间需要 21 分钟。

本文采用本地k8s v1.10.3版本开发,如果还没有搭建可参照 进行搭建

搭建本地Docker镜像仓库

  1. docker pull docker.io/registry 拉取registry的镜像到本机
  2. docker run -d -p 5000:5000 --name=registry --restart=always --privileged=true --log-driver=none -v /home/data/registrydata:/tmp/registry registry 运行刚刚拉取的registry
  3. 在Docker for Mac中找到Docker -> Preferences -> Daemon,在insecure registries中填入自己刚刚搭建的本地仓库

准备一个Docker镜像

  1. 随意使用什么语言写一个http接口,例如Nodejs:
@Get('whoami')    async whoAmI() {        debug('whoAmI called with %O', {});        return { serverType: Config.SERVER_TYPE };    }复制代码
  1. 编写对应的DockerFile
FROM node:8WORKDIR /rootRUN mkdir -p /root/appCOPY package.json /root/app/COPY dist /root/app/distWORKDIR /root/appRUN npm config set registry https://registry.npm.taobao.org/ ;\    npm config set disturl https://npm.taobao.org/dist/ ;\    npm i --productionCMD [ "node", "/root/app/dist/main.js" ]EXPOSE 80复制代码
  1. 编译、打标签,并推送到本地仓库中
echo 'Building to dits ...'tscecho 'Docker building image ...'docker build --rm -t localhost:5000/gateapp:0.0.1 .echo 'Pushing ...'docker push localhost:5000/gateappecho 'Docker list images ...'docker images复制代码

最后你会看到localhost:5000/gateapp:0.0.1的镜像已经在你的机器中啦,下面会用到

Kubernetes中的重要概念

  1. Cluster: Cluster是计算、存储和网络资源的集合,Kubernetes利用这些资源运行各种基于容器的应用
  2. Master: Master是Kubernetes的大脑,它的主要职责是调度,即决定将应用放在那里运行。
  3. Node: Node的职责是运行容器应用。Node由Master管理,Node负责监控并汇报容器的状态,同时根据Master的要求管理容器的生命周期。
  4. Pod: Pod是Kubernetes中最小工作单元。每个Pod包含一个或多个容器。Pod中的容器会作为一个整体被Master调度到一个Node上运行。
  5. Controller:Kubernetes通常不会直接创建Pod,而是通过Controller来管理Pod。Controller中定义了Pod的部署特性,比如有几个副本、在什么样的Node上运行等。为了满足不同的业务场景,Kubernetes提供了多种Controller,包括Deployment、ReplicaSet、DaemonSet、StatefuleSet、Job等,后面会逐个学习这些Controller
  6. Service:Service定义外界访问一组特定Pod的方式。

创建Deployment部署应用

  1. 新建一个yaml文件,如:
apiVersion: extensions/v1beta1 # kubectl api的版本kind: Deployment # kubernetes的资源类型metadata:    name: gate-deployment-devspec:    replicas: 2 # 运行的Pod副本数量    template:        metadata:            labels:                app: gate-app-dev        spec:            containers:                - name: gateapp                  image: localhost:5000/gateapp:0.0.1 # Docker镜像地址(上面创建的)                  env: # 镜像启动时的环境变量                      - name: NODE_ENV                        value: 'development'                      - name: HTTP_PORT                        value: '80' # 容器http的端口 需要自己代码中实现复制代码
  1. 通过kubectl apply -f xxx.yaml就可以部署上面的Deployment的了,也可以打开Kubernetes的Dashboard点击创建,输入yaml文件中的内容进行创建。经过一段时间后,在Dashboard面板中可以看到,1个部署 gate-deployment-dev,一个副本集 gate-deployment-dev-775d556ffb,两个容器组 gate-deployment-dev-775d556ffb-2tlgn、gate-deployment-dev-775d556ffb-sfqrq,可以点击查看每个资源的信息,大部分内容都是自解释的。

    在部署Deployment后,Kubernetes大致执行了以下几个过程:

    • 用户创建Deployment
    • Deployment创建了一个副本集(ReplicaSet)gate-deployment-dev-775d556ffb
    • ReplicaSet创建了两个Pod,与我们定义的replicas: 2 一致

创建Service

此时上面的镜像提供的接口还不能供外界访问,需要创建一个对应的Service

  1. 新创建一个yaml文件或者在上一个yaml文件中添加 --- 隔开
  2. 编辑以下内容:
apiVersion: v1 # kubectl api的版本kind: Service # kubernetes的资源类型metadata:    name: gate-svc-devspec:    type: NodePort # service的类型 ClusterIp类型 只有Cluster内部节点和Pod可以访问 NodePort Cluster外部可以通过
:
访问 LoadBalancer负载均衡 selector: app: gate-app-dev # 与上面的template中定义的label一致 ports: - protocol: TCP # 只有TCP 或 UDP port: 80 # clusterIp 监听的端口 nodePort: 30000 # Node 监听的端口取值范围 30000-32767 targetPort: 80 # Pod 监听的端口复制代码
  1. kubectl apply -f xxx.yaml 或者在Dashboard中创建

  2. 观察Dashboard面板,会发现多了一个名字叫gate-svc-dev的服务,提供了监听了30000端口

  3. curl http://localhost:30000/whoami 可以看到接口已经可以访问了

    需要注意的是:

    • 为什么需要Service?

      Deployment等其他Controller动态创建和销毁Pod来保证应用的健壮性,也就是Pod是脆弱的,应用是健壮的,我们不该期望Pod的健壮性。每个Pod都有自己的ClusterIp地址,当Pod发生故障被新的Pod替代时,ClusterIp很有可能发生变化,所以如果直接让外界访问Pod就有问题了。

    • Service和Pod如何映射?

      通过上面的yaml定义可以看出,Service通过 label标签选择器选择对应的一堆Pod。当请求被发送到Service上时,Service采用了某种分配策略把流量转发到了某一个Pod上面进行处理。

    • Service有哪些类型?

      1. ClusterIp:Service通过Cluster内部的IP对外提供服务,只有Cluster内的节点和Pod可以访问,这是默认的类型。
      2. NodePort: Service通过Cluster节点的静态端口对外提供服务。Cluster外部可以通过<NodeIp>:<NodePort>访问Service
      3. LoadBalancer: cloud provider特有的对外提供服务,后续线上部署时会讲到

滚动更新

滚动更新是一次只更新一小部分副本,成功后再更新更多的副本,最终完成所有副本的更新。滚动更新最大的好处就是零停机,保证了业务的连续性。

  1. 对本地代码进行一点改动
  2. 编译、打标签,并推送到本地仓库中
echo 'Building to dits ...'tscecho 'Docker building image ...'docker build --rm -t localhost:5000/gateapp:0.0.2 .echo 'Pushing ...'docker push localhost:5000/gateappecho 'Docker list images ...'docker images复制代码

这时候可以看到有0.0.1 和 0.0.2两个版本的镜像

  1. 在Dashboard中编辑Deployment,把image: localhost:5000/gateapp:0.0.1改成image: localhost:5000/gateapp:0.0.2,点击更新

  2. 等待一段时间,再观察所有的Pod都被更新成0.0.2版本的了,是不是很方便!

    反复执行上面的步骤,不难发现更新过程中Kubernets都做了什么:

    • Deployment的镜像被更新为0.0.2版本
    • 新创建了一个名称为gate-deployment-dev-594468997c的ReplicaSet副本集,镜像为0.0.2
    • 新的ReplicaSet增加了一个Pod
    • 旧的ReplicaSet减少了一个Pod
    • 逐渐的新的ReplicaSet接管了所有旧ReplicaSet的Pod,滚动更新完成
  3. 自定义滚动更新行为

strategy:        rollingUpdate: # 滚动更新策略            maxSurge: 10% # 数值越大 滚动更新时新创建的副本数量越多            maxUnavailble: 10% # 数值越大 滚动更新时销毁的旧副本数量越多    replicas: 2 # 运行的Pod副本数量复制代码
- maxSurge:此参数控制滚动更新中副本总数超过DESIRED的数量或最大比例,数值越大 滚动更新时新创建的副本数量越多- maxUnavailble:此参数控制滚动更新中,不可用的副本占DESIRED的最大数量或最大利弊,数值越大 滚动更新时销毁的旧副本数量越多复制代码

那如果更新过程出错了怎么办?请接着往下看

健康检查

Kubernetes有很强大的自愈能力,默认的实现方式是重启发生故障的容器,此外用户可以使用Liveness、 Readiness的探测机制设置更为精细的健康检查,进而真正实现零停机部署、避免部署无效的镜像、更加安全的滚动升级

  1. 编辑之前的Deployment.yaml,例如:
image: localhost:5000/gateapp:0.0.13                  readinessProbe: # 一种健康检查决定是否加入到service 对外服务                      httpGet:                          scheme: HTTP # 支持http https                          path: /healthy                          port: 80 # 与你的pod端口一致                      initialDelaySeconds: 10 # 容器启动多久后开始检查                      periodSecods: 5 # 几秒检查一次复制代码
  • readinessProbe即是使用Readiness健康探测机制,当检查不通过时(例如接口返回的状态码不是200-400之间),Kubernetes就不会把容器添加到Service中供外界访问,观察Pod的状态为Not Ready。 initialDelaySeconds是决定容器启动多久后开始检查,通常要比启动时间再长一些;periodSecods是多久检查一次,连续3次探测失败后,Ready将变成不可用,Kubernets把这个Pod从Service中下线

  • LiveNess的配置项和Readiness的一样,不同之处在于探测失败后的行为。前者会重启容器,后者会设置Pod不可用,并从Service中下线。

  • LiveNess和Readiness的探测是独立使用的,二者没有依赖,可以单独使用也可以同时使用。一般情况下使用LiveNess判断容器是否需要重启实现自愈;Readiness判断容器是否已经准备好对外提供服务。

  1. 自定义健康检查的代码: 自定义/healthy get接口,比如数据库连接等等
@Get('healthy')    async checkHealthy(@Res() res: Response) {        let isHealthy = false;        // some code to check healthy begin        isHealthy = true;        // check end        const data = {            isHealthy,        };        debug('执行健康检查结果 %O', data);        res.status(isHealthy ? HttpStatus.OK : HttpStatus.INTERNAL_SERVER_ERROR).json(data);    }复制代码

一起来学习Kubernetes

相信看完以上的文章,你也会认为Kubernetes真的非常强大,是非常值得学习的。笔者也是小白一个,从0开始学习的,如果你也想一起,可以加入我们的群。

转载地址:http://lnkwo.baihongyu.com/

你可能感兴趣的文章
IT人必须学会的职场四原则
查看>>
Android之剪贴薄实现
查看>>
WPF数据模板和控件模板
查看>>
Sonix SN9P701 OCR点读笔二维码识别源码
查看>>
oracle 单引号 双引号 连接符
查看>>
[golang] implicit assignment of unexported field
查看>>
数据结构 练习 20-查找 算法
查看>>
hadoop集群虚拟机配置
查看>>
如何使用fileupload工具来实现文件上传
查看>>
EZ GUI Button和Checkbox创建
查看>>
指针[收藏]
查看>>
审批流程设计方案-介绍(一)
查看>>
JAVA进阶----主线程等待子线程各种方案比较(转)
查看>>
PowerDesigner(九)-模型文档编辑器(生成项目文档)(转)
查看>>
Python多进程编程
查看>>
使Eclipse下支持编写HTML/JS/CSS/JSP页面的自动提示。
查看>>
IIS_右键点击浏览网站没有反应
查看>>
Struts2的OGNL遍历数组、List、简单的Map
查看>>
POJ训练计划1035_Spell checker(串处理/暴力)
查看>>
Makefile 使用总结【转】
查看>>