Kubernetes资源对象的管理-创新互联

Kubernetes概述

Kubernetes是Google开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以便对应用请求进行负载均衡。

创新互联建站长期为成百上千客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为柏乡企业提供专业的做网站、成都做网站柏乡网站改版等技术服务。拥有十年丰富建站经验和众多成功案例,为您定制开发。

在Kubernetes中,我们可以创建多个容器,每个容器里面运行一个应用实例,然后通过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需要运维人员去进行复杂的手工配置和处理。

Kubernetes 特点

可移植: 支持公有云,私有云,混合云,多重云(multi-cloud)

可扩展: 模块化,插件化,可挂载,可组合

自动化: 自动部署,自动重启,自动复制,自动伸缩/扩展

在K8s中创建资源的方式有两种:命令行和YAML文件,本次博文主要介绍使用YAML文件的方式,如需使用命令行创建资源请参考K8s资源对象的基本管理

Kubernetes中的YAML文件与配置清单是一样的,根据个人习惯。本次博文统称为YAML文件!

一、YAML文件基础

YAML是专门用来配置文件的语言,非常简洁和强大。与了解的properties、XML、json等数据格式,习惯之后就会发现越来越好用。其实YAML就是结合了大部分的标记语言的特性,整合新开发的。

YAML文件的特点:

  • 层次分明、结构清晰;
  • 使用简单、上手容易;
  • 功能强大、语义丰富;
    需要特别注意的是:
  • 大小写敏感;
  • 严格要求缩进;

二、YAML文件使用

1)YAML文件的组成

Kubernetes中的YAML文件主要由五个一级字段组成,分别是:

  • apiVersion:api版本信息;
  • kind:指定创建资源对象的类型;
  • metadata:元数据内部的嵌套字段,定义了资源对象的名称、名称空间等;
  • spec:规范定义资源应该拥有什么样的特性,依靠控制器确保性能可以满足,满足用户期望的状态。
  • status:显示资源的当前状态,K8s就是确保当前状态向目标状态无限靠近从而满足用户期望。代表资源当前的状态;

2)获取编写YAML文件的帮助

虽然知道了YAML文件中的一级字段都是什么,但是还是不知道应该怎么写。可以借助以下命令来获取一些帮助信息。

[root@master ~]# kubectl api-versions      
//获取当前集群支持的 apiserver版本
[root@master ~]# kubectl api-resources 
//获取全部的api资源对象
[root@master ~]# kubectl explain deployment
//查看k8s某个对象的配置清单格式,应该包含哪些字段及使用方法
[root@master ~]# kubectl explain deployment.spec
//这个命令是非常重要的,它可以一级一级来获取帮助

3)YAML文件的基本格式

[root@master ~]# cat web.yaml 
kind: Deployment           //指定要创建的资源对象
apiVersion: extensions/v1beta1     //指定deployment所对应的API版本信息
metadata:
  name: web          //定义deployment的名称
spec:
  replicas: 2          //指定副本数量
  template:
   metadata:
    labels:             //指定pod的标签
     app: web_server
   spec:
    containers:
    - name: nginx      //指定pod运行的容器的名称
     image: nginx      //指定运行容器所需的镜像

4)apply创建或更新

[root@master ~]# kubectl apply -f web.yaml
//使用“-f”来指定yaml文件,根据yaml文件中定义的内容生成所需的资源

apply可以指定多次,如果发现文件不同,则更新

5)delete删除

[root@master ~]# kubectl delete -f web.yaml
//删除yaml文件中定义的资源

6)验证

[root@master ~]# kubectl get deployments. web
//查看web控制器所产生的pod
NAME  READY  UP-TO-DATE  AVAILABLE  AGE
web   2/2   2       2      5m50s
[root@master ~]# kubectl describe deployments. web
//查看web控制器的详细信息

返回的结果如下:
Kubernetes资源对象的管理

这样一来,Kubernetes已经根据YAML文件生成了我们所需的pod资源!

[root@master ~]# kubectl get pod -o wide      //查看pod的详细信息
NAME          READY  STATUS   RESTARTS  AGE  IP      NODE   NOMINATED NODE  READINESS GATES
web-d6ff6c799-7jtvd  1/1   Running  0      17m  10.244.2.2  node02        
web-d6ff6c799-7tpdc  1/1   Running  0      17m  10.244.1.2  node01        

K8s集群内部测试访问:
Kubernetes资源对象的管理

三、创建YAML文件使K8s中pod的服务能够被外部访问

[root@master ~]# cat web-svc.yaml 
kind: Service
apiVersion: v1
metadata:
  name: web-svc
spec:
  type: NodePort      //指定类型为NodePort,可以让外部访问,否则默认情况下是cluster IP,仅限集群内部访问
  selector:     
   app: web_server       //必须与deployment资源对象的标签进行关联
  ports:
  - protocol: TCP
   port: 80              //指定要映射到的Cluster  IP的端口
   targetPort: 80         //指定的是要映射pod中的端口
   nodePort: 31000      //指定映射到宿主机的端口,范围是30000~32767
[root@master ~]# kubectl apply -f web-svc.yaml 
//生成service的控制文件(yaml中已经定义其名称为web-svc)
[root@master ~]# kubectl get svc web-svc   //查看service控制器
NAME    TYPE    CLUSTER-IP   EXTERNAL-IP  PORT(S)     AGE
web-svc  NodePort  10.99.32.22       80:31000/TCP  12m
//TYPE:为NodePort,可以使外部访问;
//PORT:映射出的端口与我们定义的一样

测试访问:
Kubernetes资源对象的管理

注意:是访问群集中任意节点都可以访问k8s集群中pod所提供的服务!

四、底层负载均衡实现原理

[root@master ~]# kubectl describe svc web-svc 
//查看service的详细信息

返回的信息如下:
Kubernetes资源对象的管理
既然说到,Endpoints指定的是后端pod的IP地址,那么下面进行验证:

[root@master ~]# kubectl get pod -o wide | awk '{print $6}'
//提取后端pod的IP地址
IP
10.244.2.2
10.244.1.2
//与上述查询的结果一样!

我们知道service是有负载均衡的能力,那么是怎么实现的?

其实,背后的原理并没有那么高大上,kube-proxy通过iptables的转发机制来实现负载均衡的效果的,先定义目标IP是service提供的群集IP,然后使用“-j”选项转发到其他iptables规则,接下来验证一下:

[root@master ~]# kubectl get svc web-svc | awk '{print $3}'
//首先查看service的群集IP地址
CLUSTER-IP
10.99.32.22
[root@master ~]# iptables-save | grep 10.99.32.22
//查看iptables规则中与群集IP地址相关的内容
-A KUBE-SERVICES ! -s 10.244.0.0/16 -d 10.99.32.22/32 -p tcp -m comment --comment "default/web-svc: cluster IP" -m tcp --dport 80 -j KUBE-MARK-MASQ
-A KUBE-SERVICES -d 10.99.32.22/32 -p tcp -m comment --comment "default/web-svc: cluster IP" -m tcp --dport 80 -j KUBE-SVC-3RBUQ3B6P3MTQ3S7
从上述结果中可以看出,当目标地址是群集IP时,就会转发到KUBE-SVC-3RBUQ3B6P3MTQ3S7规则中
[root@master ~]# iptables-save | grep KUBE-SVC-3RBUQ3B6P3MTQ3S7
:KUBE-SVC-3RBUQ3B6P3MTQ3S7 - [0:0]
-A KUBE-NODEPORTS -p tcp -m comment --comment "default/web-svc:" -m tcp --dport 31000 -j KUBE-SVC-3RBUQ3B6P3MTQ3S7
-A KUBE-SERVICES -d 10.99.32.22/32 -p tcp -m comment --comment "default/web-svc: cluster IP" -m tcp --dport 80 -j KUBE-SVC-3RBUQ3B6P3MTQ3S7
-A KUBE-SVC-3RBUQ3B6P3MTQ3S7 -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-E3SP5QDRAUFB55IC
-A KUBE-SVC-3RBUQ3B6P3MTQ3S7 -j KUBE-SEP-3T3LUFAKMOTS5BKN
//从查询结果中可以看出其负载均衡的效果,因为后端只创建了两个pod,所以其概率为0.5

由此可以看出service实现负载均衡的效果:默认情况下使用iptables规则,当然还可以使用其他的方法,这里就不介绍了!

查看负载均衡的详细信息需根据cluster ip为切入口!

实现负载均衡最根本的原理就是:iptables规则根据random(随机数)实现的负载均衡!

五、服务回滚到指定的版本

通过K8s资源对象的基本管理之使用命令行的方式可以了解到kubernetes版本升级、回滚的操作与docker swarm几乎是一样的。回滚操作只能回滚到上一个版本。

搭建私有仓库,使用镜像制作自定义镜像(三个版本),根据主页内容进行区分,将自定义镜像上传到私有仓库中,由于过于简单,过程略……

kubernetes还可以回滚到指定的版本,方法如下:

[root@master yaml]# cat httpd01.deployment.yaml 
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: httpd
spec:
  revisionHistoryLimit: 10                //记录历史版本信息为10个
  replicas: 3
  template:
   metadata:
    labels:
     app: httpd-server
   spec:
    containers:
    - name: httpd
     image: 192.168.1.1:5000/httpd:v1          //三个版本根据镜像进行区分
     ports:                             //这个只是一个声名没有任何作用
     - containerPort: 80
[root@master yaml]# cat httpd02.deployment.yaml 
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: httpd
spec:
  revisionHistoryLimit: 10
  replicas: 3
  template:
   metadata:
    labels:
     app: httpd-server
   spec:
    containers:
    - name: httpd
     image: 192.168.1.1:5000/httpd:v2          //三个版本根据镜像进行区分
     ports:
     - containerPort: 80
[root@master yaml]# cat httpd03.deployment.yaml 
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: httpd
spec:
  revisionHistoryLimit: 10
  replicas: 3
  template:
   metadata:
    labels:
     app: httpd-server
   spec:
    containers:
    - name: httpd
     image: 192.168.1.1:5000/httpd:v3          //三个版本根据镜像进行区分
     ports:
     - containerPort: 80
[root@master yaml]# kubectl apply -f httpd01.deployment.yaml --record
//--record的作用就是记录历史版本信息
[root@master yaml]# kubectl rollout history deployment httpd
//查看历史的版本信息
deployment.extensions/httpd 
REVISION  CHANGE-CAUSE
1     kubectl apply --filename=httpd01.deployment.yaml --record=true
//1,表示版本对应的编号,也可以看出其对应的yaml
[root@master yaml]# kubectl apply -f httpd02.deployment.yaml --record
[root@master yaml]# kubectl apply -f httpd03.deployment.yaml --record
//根据yaml文件进行两次升级
[root@master yaml]# kubectl rollout history deployment httpd 
deployment.extensions/httpd 
REVISION  CHANGE-CAUSE
1     kubectl apply --filename=httpd01.deployment.yaml --record=true
2     kubectl apply --filename=httpd02.deployment.yaml --record=true
3     kubectl apply --filename=httpd03.deployment.yaml --record=true
//确认升级的版本信息已经记录
[root@master yaml]# vim httpd-svc.yaml
kind: Service
apiVersion: v1
metadata:
  name: httpd-svc
spec:
  type: NodePort
  selector:
   app: httpd-server
  ports:
  - protocol: TCP
   port: 80
   targetPort: 80
   nodePort: 31000
[root@master yaml]# kubectl apply -f httpd-svc.yaml
//创建一个svc便于访问测试
[root@master yaml]# curl 127.0.0.1:31000 

hello lvzhenjiang:v3

//访问测试页面效果 [root@master yaml]# kubectl  rollout undo deployment httpd  --to-revision=1 //回滚到版本1,使用--to-revision=1表示,1表示查看历史版本的第一列编号 [root@master yaml]# curl 127.0.0.1:31000    //测试访问

hello lvzhenjiang:v1

六、用label控制pod的位置

如果不指定pod的位置的话,默认情况下,是由K8s中scheduler这个组件来完成的,不能人为的干预。如果是业务需要手动指定的话,那么就需要以下方法:

[root@master yaml]# kubectl label nodes node02 disk=ssd
//手动给node02打上一个 disk=ssd的标签
[root@master yaml]# kubectl get nodes --show-labels | grep disk=ssd
//查看集群中各个节点的标签(包含disk=ssd)
node02  Ready     5d22h  v1.15.0  beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,disk=ssd,kubernetes.io/arch=amd64,kubernetes.io/hostname=node02,kubernetes.io/os=linux
//从结果中可以可看出只有node02包含这个标签
[root@master yaml]# vim httpd.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: httpd
spec:
  revisionHistoryLimit: 10
  replicas: 3
  template:
   metadata:
    labels:
     app: httpd-server
   spec:
    containers:
    - name: httpd
     image: 192.168.1.1:5000/httpd:v1
     ports:
     - containerPort: 80
    nodeSelector:         //指定标签选择器
     disk: ssd 
[root@master yaml]# kubectl apply -f httpd.yaml 
//根据yaml文件生成所需的pod资源
[root@master yaml]# kubectl get pod -o wide
NAME           READY  STATUS   RESTARTS  AGE  IP       NODE   NOMINATED NODE  READINESS GATES
httpd-5895f5548b-6lb97  1/1   Running  0      12s  10.244.2.8   node02        
httpd-5895f5548b-gh8br  1/1   Running  0      10s  10.244.2.10  node02        
httpd-5895f5548b-llxh7  1/1   Running  0      12s  10.244.2.9   node02        
//从查询结果中可以看出三个pod资源都运行在node02节点上

上述需求已经实现,但是只要有人为干预的地方就会错误的产生,不得不考虑以下这种情况!倘若将node02的标签进行删除的话,看一下会发生什么情况!

[root@master yaml]# kubectl label nodes node02 disk-
//将node02的disk=ssd的标签进行删除
[root@master yaml]# kubectl get nodes --show-labels | grep disk=ssd
//验证,标签已经被删除
[root@master yaml]# kubectl delete -f httpd.yaml 
//将原本的pod资源进行删除
[root@master yaml]# kubectl apply -f httpd.yaml 
//重新生成pod资源(yaml文件中依然指定了标签)
[root@master yaml]# kubectl get pod -o wide
NAME           READY  STATUS   RESTARTS  AGE  IP    NODE   NOMINATED NODE  READINESS GATES
httpd-5895f5548b-7w26q  0/1   Pending  0      65s            
httpd-5895f5548b-c6p6s  0/1   Pending  0      65s            
httpd-5895f5548b-v4s5c  0/1   Pending  0      65s            
//但是查看pod的状态为Pending,显然这种状态的pod是不正常的

即使标签的不存在的,yaml文件中也指定了标签,创建pod资源时,不会出现错误,但是pod的状态为Pending(等待的状态),解决方法如下:

[root@master yaml]# kubectl describe pod httpd-5895f5548b-7w26q
//查看pod的详细信息

返回的结果如下:
Kubernetes资源对象的管理

从结果中就已经看出了是因为标签选择器与集群中node的标签不匹配导致的!

如果以上没有发现错误的信息,还需进行以下操作:

[root@master yaml]# kubectl logs -n kube-system kube-scheduler-master
//查看Scheduler组件所产生的日志信息
[root@master yaml]# less /var/log/messages | grep kubelet
//查看系统日志中包含kubelet组件的信息
//因为kubelet是负责管理pod的

有关K8s的详细介绍还是建议参考K8s中文文档

另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


新闻名称:Kubernetes资源对象的管理-创新互联
标题链接:http://ybzwz.com/article/cecepi.html