认识Kubernetes

1 为什么使用Kubernetes

1)从单机走向集群已成为必然趋势。

2)Kubernetes可以全面拥抱微服务架构。

3)可以随时随地将系统整体“搬迁”到公有云上。

        华为云(CCE)、阿里云(ACK)和腾讯云(TKE)先后宣布支持Kubernetes集群,基于Service的虚拟IP地址(Cluster IP)的设计思路让架构与底层的硬件拓扑无关,我们无须改变运行期的配置文件,就能将系统从现有的物理机环境无缝迁移到公有云上。

4)Kubernetes内在的服务弹性扩容机制可以让我们轻松应对突发流量。

5)Kubernetes系统架构具有超强的横向扩容能力。

        利用Kubernetes提供的工具,不用修改代码,就能将一个Kubernetes集群从只包含几个Node的小集群平滑扩展到拥有上百个Node的大集群。

2 K8s使用案例

功能:JSP页面通过JDBC直接访问MySQL数据库并展示数据。

此应用需要启动两个容器:Web App容器和MySQL容器,并且Web App容器需要访问MySQL容器。

在Docker时代,我们在一个宿主机上启动了这两个容器,需要把MySQL容器的IP地址通过环境变量注入Web App容器里;同时,需要将WebApp容器的8080端口映射到宿主机的8080端口,以便在外部访问。

k8s的时代,实现方法如下:

首先,为MySQL服务创建一个RC定义文件mysql-rc.yaml:

        apiVersion: v1
        kind: ReplicationController                 # 副本控制器RC
        metadata:
          name: mysql                                  # RC的名称,全局唯一
        spec:
          replicas: 1                                  # Pod副本的期待数量
          selector:
            app: mysql                                 # 符合目标的Pod拥有此标签
          template:                                    # 根据此模板创建Pod的副本(实例)
            metadata:
              labels:
              app: mysql                             # Pod副本拥有的标签,对应RC的Selector
            spec:
              containers:                              # Pod内容器的定义部分
              - name: mysql                            # 容器的名称
              image: mysql                           # 容器对应的Docker Image
              ports:
              - containerPort: 3306                # 容器应用监听的端口号
              env:                                    # 注入容器内的环境变量
              - name: MYSQL_ROOT_PASSWORD
                value: "123456"

在Master上执行命令:

# kubectl create -f mysql-rc.yaml
# kubectl get rc
# kubectl get pods 

通过docker ps指令查看正在运行的容器,发现提供MySQL服务的Pod容器已经创建并正常运行了,此外还多创建了一个来自谷歌的pause容器,这就是Pod的“根容器”。
最后,创建一个与之关联的Kubernetes Service——MySQL的定义文件(文件名为mysql-svc.yaml)

apiVersion: v1       
kind: Service                        # 表明是Kubernetes Service
        metadata:
          name: mysql                        # Service的全局唯一名称
        spec:
          ports:
            - port: 3306                     # Service提供服务的端口号
          selector:                           # Service对应的Pod拥有这里定义的标签
            app: mysql

运行kubectl命令,创建Service:

# kubectl create -f mysql-svc.yaml
# kubectl get svc
# kubectl get endpoints
# kubectl get svc mysql-svc -o yaml

MySQL服务会被分配Cluster IP地址。随后,Kubernetes集群中其他新创建的Pod就可以通过Service的Cluster IP+端口号3306来连接和访问它了。
接下来按照上面方式启动tomcat ,创建对应的RC文件myweb-rc.yaml,内容如下:

        apiVersion: v1
        kind: ReplicationController
        metadata:
          name: myweb
        spec:
          replicas: 2
          selector:
           app: myweb
          template:
            metadata:
              labels:
              app: myweb
            spec:
              containers:
              - name: myweb
                image: kubeguide/tomcat-app:v1
                  ports:
                  - containerPort: 8080
         env:
           - name: MYSQL_SERVICE_HOST
           value: 'mysql'
           - name: MYSQL_SERVICE_PORT
           value: '3306'

最后,创建对应的Service。以下是完整的YAML定义文件(myweb-svc.yaml):

        apiVersion: v1
        kind: Service
        metadata:
          name: myweb
        spec:
          type: NodePort
          ports:
            - port: 8080
              nodePort: 30001
          selector:
            app: myweb

type=NodePort和nodePort=30001的两个属性表明此Service开启了NodePort方式的外网访问模式。在Kubernetes集群之外,比如在本机的浏览器里,可以通过30001这个端口访问myweb(对应到8080的虚端口上)。

3 k8s基础概念

Kubernetes具有完备的集群管理能力,包括多层次的安全防护和准入机制多租户应用支撑能力、透明的服务注册和服务发现机制、内建的智能负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制,以及多粒度的资源配额管理能力。

3.1 Service

在Kubernetes中,Service是分布式集群架构的核心,一个Service对象拥有如下关键特征。

  • ◎ 拥有唯一指定的名称(比如mysql-server)。
  • ◎ 拥有一个虚拟IP(Cluster IP、Service IP或VIP)和端口号。
  • ◎ 能够提供某种远程服务能力。
  • ◎ 被映射到提供这种服务能力的一组容器应用上。

一个Service通常由多个相关的服务进程提供服务,可以通过Service(虚拟Cluster IP +Service Port)连接到指定的Service。

每个Service其实就是我们经常提起的微服务架构中的一个微服务,Service定义了一个服务的访问入口地址,前端的应用(Frontend Pod)通过这个入口地址访问其背后的一组由Pod副本组成的集群实例,Service与其后端Pod副本集群之间则是通过Label Selector来实现无缝对接的。RC的作用实际上是保证Service的服务能力和服务质量始终符合预期标准。

Kubernetes中的IP

  • ◎ Node IP:Node的IP地址。
  • ◎ Pod IP:Pod的IP地址。Docker Engine根据docker0网桥的IP地址段进行分配的,通常是一个虚拟的二层网络。
  • ◎ Cluster IP:Service的IP地址。

4.2 Pod

容器提供了强大的隔离功能,所以有必要把为Service提供服务的这组进程放入容器中进行隔离。为此,Kubernetes设计了Pod对象,将每个服务进程都包装到相应的Pod中,使其成为在Pod中运行的一个容器(Container)。为了建立Service和Pod间的关联关系,Kubernetes首先给每个Pod都贴上一个标签(Label)。

通常在一个Node节点上可运行几百个Pod。在每个Pod中都运行着一个特殊的被称为Pause的根容器,其他容器则为业务容器,这些业务容器共享Pause容器的网络栈和Volume挂载卷。

Kubernetes为每个Pod都分配了唯一的IP地址,称之为Pod IP,一个Pod里的多个容器共享Pod IP地址。Pod的IP加上这里的容器端口(containerPort),组成了一个新的概念——Endpoint,它代表此Pod里的一个服务进程的对外通信地址。

3.3 master和node

1)master - 控制平⾯
控制平⾯的组件对集群做出全局决策,为了稳定⼀般不会在上⾯部署应用。

API server 是 k8s 控制⾯的前端,也是⽤户唯⼀可以直接交互的 k8s 组件内部系统组件以及外部⽤户组件都通过相同的API进⾏通信。

kube-scheduler 监听 apiserver,发现有待调度的 pod,就按照⼀定的调度策略绑定到合适的 Node 上,并把信息写⼊到 etcd。

kube-controller-manager 控制器的作⽤是从API Server获得所需状态。它检查要控制的节点的当前状态,确定是否与所需状态存在任何差异,并解决它们。

2)node - 计算节点(⼯作节点)
维护运⾏的pod,提供 kubernetes 运⾏环境

Node作为集群中的工作节点,在Node上运行着Kubernetes的kubelet、kube-proxy、Docker Engine(docker)服务进程,负责Pod的创建、启动、监控、重启、销毁,以及实现软件模式的负载均衡器。

通过kubectl describe node <node_name>查看某个Node的详细信息:

3.4  服务扩容

在Kubernetes集群中,只需为需要扩容的Service关联的Pod创建一个RC(Replication Controller),在一个RC定义文件中包括以下3个关键信息。

  • ◎ 目标Pod的定义。
  • ◎ 目标Pod需要运行的副本数量(Replicas)。
  • ◎ 要监控的目标Pod的标签。

3.5 Label

Label是用来资源管理的。一些常用的Label示例如下:

◎ 版本标签:"release" : "stable"、"release" : "canary"。

◎ 环境标签:"environment":"dev"、"environment":"qa"、"environment":"production"。

◎ 架构标签:"tier" : "frontend"、"tier" : "backend"、"tier" : "middleware"。

◎ 分区标签:"partition" : "customerA"、"partition" : "customerB"。

◎ 质量管控标签:"track" : "daily"、"track" : "weekly"。

Label标签会再其他pod的Label Selector里查询到,Label Selector可以被类比为SQL语句中的where查询条件,

name=redis-slave,env!=production

name notin (php-frontend),env!=production

其次,matchLabels用于定义一组Label,与直接写在Selector中的作用相同;matchExpressions用于定义一组基于集合的筛选条件,包括In 、 NotIn 、 Exists和DoesNotExist。       

selector:
   matchLabels:
     app: myweb
   matchExpressions:
     - {key: tier, operator: In, values: [frontend]}
     - {key: environment, operator: NotIn, values: [dev]}

3.6 Replication Controller 资源对象

声明某种Pod的副本数量在任意时刻都符合某个预期值,RC的定义包括如下几个部分。

◎ Pod期待的副本数量。

◎ 用于筛选目标Pod的Label Selector。

◎ 当Pod的副本数量小于预期数量时,用于创建新Pod的Pod模板(template)。

可以使用如下命令定义副本数量

kubectl scale rc redis-slave --replicas=3 scaled

注意:Replica Set与Deployment这两个重要的资源对象逐步替代了之前RC的作用。

3.7 Deployment 资源对象

创建namespace:kubectl create ns test

创建Deployment:kubectl create deployment nginx-manual --image=nginx:alpine -n test

创建Deployment:kubectl apply -f nginx.yaml -n test

查看信息:kubectl get deploy -n test

动态扩缩容:kubectl scale deployment nginx-deployment -n test --replicas=0

3.8 Horizontal Pod Autoscaler 资源对象

通过追踪分析指定RC控制的所有目标Pod的负载变化情况,来确定是否需要有针对性地调整目标Pod的副本数量。

HPA有以下两种方式作为Pod负载的度量指标。

◎ CPUUtilizationPercentage。

◎ 应用程序自定义的度量指标,比如服务在每秒内的相应请求数(TPS或QPS)。

apiVersion: 
    autoscaling/v1
        kind: HorizontalPodAutoscaler
        metadata:
          name: php-apache
          namespace: default
        spec:
          maxReplicas: 10
          minReplicas: 1
          scaleTargetRef:
            kind: Deployment
            name: php-apache
          targetCPUUtilizationPercentage: 90

当这些Pod副本的CPUUtilizationPercentage的值超过90%时会触发自动动态扩容行为,在扩容或缩容时必须满足的一个约束条件是Pod的副本数为1~10。

3.9 StatefulSet 资源对象

StatefulSet从本质上来说,可以看作Deployment/RC的一个特殊变种,它有如下特性。

◎ StatefulSet里的每个Pod都有稳定、唯一的网络标识,可以用来发现集群内的其他成员。

◎ StatefulSet控制的Pod副本的启停顺序是受控的,操作第n个Pod时,前n-1个Pod已经是运行且准备好的状态。

◎ StatefulSet里的Pod采用稳定的持久化存储卷,通过PV或PVC来实现,删除Pod时默认不会删除与StatefulSet相关的存储卷(为了保证数据的安全)。

3.10 Job 资源对象

批处理任务通常并行(或者串行)启动多个计算进程去处理一批工作项(work item),在处理完成后,整个批处理任务结束。Job就是用来并行处理的。

(1)Job所控制的Pod副本是短暂运行的,可以将其视为一组Docker容器,其中的每个Docker容器都仅仅运行一次。

(2)Job所控制的Pod副本的工作模式能够多实例并行计算。

3.11 Volume

Volume(存储卷)是Pod中能够被多个容器访问的共享目录。

先在Pod上声明一个Volume,然后在容器里引用该Volume并挂载(Mount)到容器里的某个目录上。      

       template:
            metadata:
              labels:
                app: app-demo
                tier: frontend
            spec:
              volumes:
                - name: datavol
                emptyDir: {}
              containers:
              - name: tomcat-demo
                image: tomcat
                volumeMounts:
                - mountPath: /mydata-data
                  name: datavol
                imagePullPolicy: IfNotPresent

Kubernetes提供了非常丰富的Volume类型,下面逐一进行说明。

1.emptyDir

一个emptyDir Volume是在Pod分配到Node时创建的。当Pod从Node上移除时,emptyDir中的数据也会被永久删除。

2.hostPath

hostPath为在Pod上挂载宿主机上的文件或目录。

3.NFS

使用NFS网络文件系统提供的共享目录存储数据时,我们需要在系统中部署一个NFS Server。

4. 其他公有云存储

3.12 Persistent Volume

Volume是被定义在Pod上的,属于计算资源的一部分,而实际上,网络存储是相对独立于计算资源而存在的一种实体资源。

在使用虚拟机的情况下,我们通常会先定义一个网络存储,然后从中划出一个“网盘”并挂接到虚拟机上。Persistent Volume(PV)和与之相关联的Persistent Volume Claim(PVC)也起到了类似的作用。

◎ PV只能是网络存储,不属于任何Node,但可以在每个Node上访问。

◎ PV并不是被定义在Pod上的,而是独立于Pod之外定义的。

3.13 namespace

Namespace在很多情况下用于实现多租户的资源隔离。如果不特别指明Namespace,则用户创建的Pod、RC、Service都将被系统创建到这个默认的名为default的Namespace中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值