kubernetes介绍

一、Kubernetes管理文件介绍

Kubernetes最常用的配置文件格式为yaml格式,yaml因为支持注释,可以很好的表示复杂的数据格式,正在越来越多地被其它程序作为配置文件来使用。

Yaml(发音/ˈjæməl/)格式介绍

缩进

Yaml只支持空格作为缩进,不支持tab作为缩进。可以使用两个空格或者四个空格表示一层,但是整个yaml文件必须统一,要么全部使用两个空格作为缩进要么全部使用四个空格作为缩进,不允许混合使用。

注释

Yaml使用#作为一行的注释,当yaml碰到以#开头的行时将作为注释对待。

字典数据结构

字典数据结构使用key:value格式,例如:

apiVersion: v1
kind: ConfigMap
metadata:
  name: dns

解释为: 键值 apiVersion值为 v1, 键值 kind值为 ConfigMap, 键值 metadata值又为一个字典数据结构。

数组数据结构

例如:

favAnimals:
  - cat
  - dog
  - elephant

键值favAnimals的值为一个数组,这个数组值为 cat, dog, elephant。

一个更复杂的yaml结构解释

apiVersion: v1
kind: Service
metadata:
  name: sms
spec:
  selector:
    run: deployment-sms
  ports:
  - protocol: TCP
    name: http
    port: 18000
    targetPort: 8000

键值apiVersion值为 v1,键值kind值为Service,键值metadata值为 name: sms,键值 spec值为

selector:
    run: deployment-sms
  ports:
  - protocol: TCP
    name: http
    port: 18000
    targetPort: 8000

键值 ports值为一个数组,这个数组有一个值,值为

    protocol: TCP
    name: http
    port: 18000
    targetPort: 8000

多个yaml文件合并为一个

Kubernetes支持多个yaml文件合为一个文件编写,每个yaml块使用 --- 分隔。合并的yaml文件有先后顺序之分,如果有依赖关系的话,被依赖的yaml文件必须放在前面。

二、Kubernetes简介

Kubernetes优势

Kubernetes是一个集中的容器container管理环境,它提供一种更加方便的资源管理办法,方便服务快捷地做到扩展和伸缩以满足业务量的变化需求。

Kubernetes架构

Kubernetes是master+node节点架构,我们业务系统的容器只运行在node上面。
Master节点用于kubernetes任务分配调度,运行的组件有:kube-apiserver, etcd, kube-scheduler, cloud-controller-manager。
Node机器运行的组件有:kubelet, kube-proxy, 以及运行时的容器Container Runtime。


Kubernetes api

Kubernetes api完整地定义了kubernetes使用的对象参数,v1.12版本api定义地址:
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.12/

Kubectl客户端

Kubectl是最常用到的命令,它用于跟apiServer通讯,把yaml里配置的对象在kubernetes集群里生效。它也用于查看kubernetes对象的状态。

三、业务系统进kubernetes

业务系统一般比较关心,配置文件如何解决,日志如何解决,如何运行镜像,现在就这些比较关心的问题进行讨论。

定义配置文件

Kubernetes的ConfigMap对象用于把配置参数映射到kubernetes集群里的方式,这些业务参数或者environment环境变量都将定义在yaml文件里,以原子最小单位的形式供其它要使用它们的系统重复使用。

Y_DNS解决

Openresty需要使用resolver xxx.xxx.xxx.xxx; 指令来指定DNS服务器用来解析域名。一般我们在run.sh里定义Y_DNS环境变量的方式把DNS传入使用start.lua来生成resolver.conf的方式来定义openresty的resolver。解决办法,把Y_DNS作为ConfigMap定义到kubernetes系统。

dns-config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: dns
data:
  Y_DNS: 172.0.0.1

解释:
第1行,定义apiVersion,apiVersion是kubernetes api必须的元素。
第2行,定义类别kind,这是一个ConfigMap类别,用于定义配置参数。
第3行,定义ConfigMap的一些基本元数据,其中name是metadata里必须定义的,给这个ConfigMap起一个名字为dns,后续在其它yaml里可以使用这个名字来引用我们定义的配置信息。所以定义名字时应该具有唯一性。
第5行,data后面的将是该dns ConfigMap的具体内容。
第6行,我们定义了一个ConfigMap变量YBS_DNS,它的值是 172.0.0.1,这是一个kubernetes集群DNS。

device配置文件解决

device配置文件有两层目录,一层在/sms目录下,一层在/device/status目录下,一层目录下的配置文件放在一个yaml文件里,这样才能够后续映射到不同的目录里。

下面截取了device-config.yaml部分代码

  ---
 apiVersion: v1
 kind: ConfigMap
 metadata:                                                                                                                                                                                    
   name: device-conf
 data:
   addr.ini: |
     [addr]
     sms_url = http://sms.default.svc.cluster.local:18000/sms/print
 ---
 apiVersion: v1
 kind: ConfigMap
 metadata:
   name: device-status-conf
 data:
   device_status.ini: |
     [status]
     1 = ok

解释:
第1行,因为把device两个yaml配置放在了一个文件里,使用---分隔表示一个文件的内容。
第2行,同样的,定义了apiVersion
第3行,定义kind的,为ConfigMap类别
第4,5行,定义metadata,主要定义了name名字,注意该名字的唯一性。
第7行开始为ConfigMap的数据data,注意这儿跟dns-config.yaml里不同,它定义了一个配置文件样式, addr.ini : | 前面addr.ini为配置文件的名字,后续在其它yaml文件里引用映射到一个目录下,那么该文件名就是addr.ini,后面的 | 表示后续的内容为addr.ini文件的数据。
同理,从10行以后是定义的/device/status目录下的配置文件内容。

sms配置文件

 ---
 apiVersion: v1
 kind: ConfigMap
 metadata:
   name: configmap-sms
 data:
   client.ini: |
     [jpush]
     key=aa
     secret=76basdt                                                                                                                                                      
   mysql.ini: |
     [config]
     host=mysql.ws.com
     port=3306

定义模块运行参数

Kubertnetes的一大优势就是能够定义业务系统的运行份数,动态伸缩,下面我们来看下定义sms运行状态的一种新kubernetes类型Deployment。

sms Deployment

sms-deployment.yaml

 ---
 apiVersion: apps/v1beta1
 kind: Deployment
 metadata:
   name: deployment-sms
 spec:
   replicas: 2
   template:
     metadata:
       labels:
         run: deployment-sms
     spec:
       containers:
       - name: deployment-sms
         image: registry:5000/sms:20210101
         env:
           - name: Y_DNS
             valueFrom:
               configMapKeyRef:
                 name: dns
                 key : Y_DNS
         ports:
         - containerPort: 8000
         volumeMounts:
         - name: volume-sms
           mountPath: /home/openresty/openresty/nginx/sms/conf
           readOnly: true
 
         - name: volume-log
           mountPath: /data/log
       volumes:
      
       - name: volume-sms
         configMap: 
           name: configmap-sms
 
       - name: volume-log
         hostPath:
           path: /data/log

解释:
第1行,yaml内容分隔符。
第2行,定义apiVersion。
第3行,该对象的类别为Deployment,Deployment对象用于定义业务系统的运行状态信息。
第4,5行,定义该对象的一些metadata,其中我们定义了该对象的名字。
第6行,spec定义该Deployment的一些规范。
第7行,replicas定义该业务系统将要运行的份数,我们定义为运行2份。
第8行,template内容定义要运行的业务系统的模板信息。
第11行,定义运行的container名字,这儿的名字在14行定义。
第13行,定义运行的container数组,这儿数组里定义了一个container。
第14行,该container的名字是deployment-sms,第11行填的名字就是这儿定义的名字。
第15行,要启动container的镜像名称。
第16至21行,前面dns-config.yaml里定义的dns ConfigMap变量。
第22,23行,定义container启动的端口。
第24至37行,定义mount挂载的卷。
我们先看30至37行,我们定义了两个volume,32行至34行volume的名字为 volume-sms,它引用的是前面sms ConfigMap的配置参数。35行至37行volume的名字为volume-log,它引用的是一个物理路径 /data/log。
我们再来看24至29行,这儿我们来使用下面定义的volume,第25至27行,我们使用下面定义的volume-sms,也就是使用了一个ConfigMap,我们把这个ConfigMap内容挂载到到container容器的路径/home/openresty/openresty/nginx/sms/conf,这样我们就把ini的配置文件挂到了该目录下,并且设置了只读权限。第28,29行,我们使用了下面定义的volume-log,这是一个物理路径,我们把它挂载到container里的/data/log。
总结:我们在sms Deployment里定义了sms要运行的份数,使用的环境变量,配置文件要挂载的目录,日志文件的目录这些关键的信息。

sms Service

在前面我们定义了sms的运行时,那么现在sms运行起来了,是否就可以供device等系统使用了呢?答案是否定的,kubernetes规定内部的HTTP(S)服务要供kubernetes内部系统使用的话,必须把它expose为一个service服务。下面我们来看下一个service要如何定义。

 ---
 apiVersion: v1
 kind: Service
 metadata:
   name: sms
 spec:
   selector:
     run: deployment-sms
   ports:
   - protocol: TCP
     name: http
     port: 18000
     targetPort: 8000

第3行,我们定义了它的种类为service。
第5行,我们定义了该service的名字。
第7,8行,我们使用了selector选择了一个运行时容器,就是前面定义的deployment-sms运行时容器。
第10至13行,我们定义了该service expose的端口,第10,11行说明它是一个http的服务,第13行容器内监听的端口是8000,第12行我们把该服务暴露为18000端口,这样外部使用该sms服务将使用18000端口。

device调用sms的URL配置

device因为需要调用sms,而sms也部署在kubernetes里,前面说到如果kubernetes内部的服务要被其它系统调用的话,必须把被调用的系统expose为一个service,那么这个service的域名也是有一定讲究的,它的域名组成为 service名字.default.svc.cluster.local,这样device配置文件里定义的sms配置实际为 sms.default.svc.cluster.local:18000。

device Deployment

device同理我们要先定义一个运行时来运行它的容器,也即定义一个deployment,同理在该deployment里我们需要定义device运行时使用的环境变量,运行的镜像名称,要挂载的配置文件路径,日志挂载目录等。我们来看下device deployment的定义:

 apiVersion: apps/v1beta1
 kind: Deployment
 metadata:
   name: deployment-device
 spec:
   replicas: 2
   template:
     metadata:
       labels:
         run: deployment-device
     spec:
       containers:                                                                                                                                                                                                                        
       - name: deployment-device
         image: registry:5000/device:20210101
         env:
           - name: Y_DNS
             valueFrom:
               configMapKeyRef:
                 name: dns
                 key : Y_DNS
           - name: Y_CONFIG_URL
             value: http://127.0.0.1:8000/ini/
         ports:
         - containerPort: 8000
         volumeMounts:
         - name: device-conf
           mountPath: /home/openresty/openresty/nginx/ini/device
           readOnly: true
         - name: device-status-conf
           mountPath: /home/openresty/openresty/nginx/ini/device/status
           readOnly: true
         - name: log
           mountPath: /data/log
       volumes:
       - name: device-conf
         configMap:                                                                                                                                                                           
           name: device-conf
       - name: device-status-conf
         configMap:
           name: device-status-conf
       - name: log
         hostPath:
           path: /data/log

第4行,我们给这个deployment定义了一个名字。
第6行,我们定义了device容器运行的复制份数为2份。
第12至43行,我们定义了要运行的容器内容。
第13行,我们给要运行的容器定义名字为deployment-device。第10行这里run运行的就是该容器的名字。
第14行,定义要运行的镜像版本号。
第15行,定义env环境变量到容器里。后面的16至22行都是环境变量的定义。
第16至20行,我们使用了前面dns-config.yaml里的ConfigMap来映射到环境变量Y_DNS。
第21,22行,我们定义了另一个环境变量Y_CONFIG_URL,它的值为http://127.0.0.1:8000/ini/
第23,24行定义了容器里服务使用的端口,也即nginx.conf里面监听的端口。
第34至43行,我们先定义使用的volume。
第25至33行,我们把要使用的volume挂载到容器目录里。
至此device系统也已经运行起来了,前面说kubernetes内部的服务要供内部系统使用要定义一个service,那么kubernetes内部的系统要供kubernetes外部服务调用呢?答案是要定义一个NodePort来供外部调用,或者定义一个Ingress来供外部调用。

device NodePort

 ---
 apiVersion: v1
 kind: Service
 metadata:
   name: device
 spec:
   type: NodePort
   selector:
     run: deployment-device
   ports:
   - protocol: TCP
     name: http
     port: 8000                                                                                                                                                                                
     targetPort: 8000
     nodePort: 30072

第3行,其实这儿定义的类别还是Service类别,但是与前面device service的区别。
第5行,为这个Service定义个名字。
第6至15行,定义该service的spec。
第7行,定义它的类型为NodePort,供kubernetes外部系统调用。
第8,9行,选择前面定义的容器运行时名字。
第10,15行定义该NodePort对外提供服务的端口。
第14行,前面运行时容器nginx.conf监听的端口。
第13行,kubernetes内部系统可以访问的映射端口。
第15行,外部服务访问该服务的外部监听端口。

device Ingress

 ---
 apiVersion: v1
 kind: Service
 metadata:
   name: device-service
   namespace: {{ namespace }}
 spec:
   selector:
     run: device
   ports:
   - protocol: TCP
     name: http
     port: 8000
     targetPort: 8000
 
 ---
 apiVersion: extensions/v1beta1
 kind: Ingress
 metadata:
   name: device-ingress
   namespace: {{ namespace }}
 spec:
   rules:
   - host: k8s.{{ namespace }}.com
     http:
       paths:
       - path: /device
         backend:
           serviceName: device-service
           servicePort: 30072

第7至14行,定义该service的spec,不需要再声明类型为NodePort。
第14行,前面运行时容器nginx.conf监听的端口。
第13行,kubernetes内部系统可以访问的映射端口。
第18行,类别是Ingress类别。
第24行,访问地址。
第27行,待转发的uri。
第29行,转发的Service服务名称,对应第5行的名称。
第30行,外部服务访问该服务的外部监听端口。

四、小结

环境变量env

环境变量的声明有两种方法,方法一在容器运行时Deployment里直接定义,该方法直观,缺点是这样定义的环境变量只能供该Deployment使用。方法二是使用ConfigMap定义,在运行时容器Deployment里引用该ConfigMap作为环境变量,该方法的好处是可以供其它对象统一调用,如果要修改只需要修改一个地方就可以全部生效。

配置文件ConfigMap

配置文件可以使用ConfigMap原样定义,后面在运行时容器Deployment里映射到容器的相应目录即可。

运行时容器Deployment

Deployment定义了一个容器运行时的参数,运行的副本个数,使用的镜像版本,使用的环境变量,映射的目录。

Kubernetes内部调用的Service

一个系统以Deployment的方式把容器运行起来了,如果它要供kubernetes内部系统调用的话,必须暴露端口等参数,以Service的形式定义。Kubernetes其它系统要使用该内部服务的话则以kubernetes内部域名的形式配置在参数里。

外部系统访问Kubernetes内服务

Kubernetes内系统要能够被外部系统调用的话,必须定义一个Service,并且为NodePort的形式把端口映射出去。

五、Kubernetes常用命令

  • 获取所有命名空间上的pod:
    kubectl get pod -o wide --all-namespaces

  • 查看pod IP时使用:
    kubectl get services

  • 查看dsecp-sso-server-w5tx2 日志:
    kubectl describe --namespace=default po ips

  • 通过yaml文件创建:
    kubectl create -f xxx.yaml (不建议使用,无法更新,必须先delete)
    kubectl apply -f xxx.yaml(创建+更新,可以重复使用)

  • 通过yaml文件删除:
    kubectl delete -f xxx.yaml

  • 查看kube-system namespace下面的pod/svc/deployment 等等(-o wide 选项可以查看存在哪个对应的节点):
    kubectl get pod/svc/deployment -n kube-system

  • 查看所有namespace下面的pod/svc/deployment等等:
    kubectl get pod/svc/deployment --all-namcpaces

  • 重启pod(无法删除对应的应用,因为存在deployment/rc之类的副本控制器,删除pod也会重新拉起来):
    kubectl get pod -n kube-system

  • 查看pod描述:
    kubectl describe pod XXX -n kube-system

  • 查看pod 日志 (如果pod有多个容器需要加-c 容器名):
    kubectl logs xxx -n kube-system

  • 删除应用(先确定是由说明创建的,再删除对应的kind):
    kubectl delete deployment xxx -n kube-system

  • 根据label删除:
    kubectl delete pod -l app=flannel -n kube-system

  • 扩容:
    kubectl scale deployment spark-worker-deployment --replicas=8

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,928评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,192评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,468评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,186评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,295评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,374评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,403评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,186评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,610评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,906评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,075评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,755评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,393评论 3 320
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,079评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,313评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,934评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,963评论 2 351

推荐阅读更多精彩内容