k8s

https://kubernetes.io/docs/tutorials/kubernetes-basics/

Kubernetes集群包含有节点代理kubelet和Master组件(APIs, scheduler, etc),一切都基于分布式的存储系统

整体结构

 

开发者开发一个应用后,打包Docker镜像,上传到Docker registry;然后编写一个yaml部署描述文件。开发者通过kubectl(或其它应用),将部署描述文件提交到API server,API server将部署需求更新到etcd。etcd在K8s管理结点中的作用相当于数据库,其它组件提交到API server的数据都存储于etcd。API server非常轻量,并不会直接去创建或管理Pod等资源,在多数场景下甚至不会去主动调用其它的K8s组件发出指令。其它组件通过建立和API server的长连接,监视关心的对象,监视到变化后,执行所负责的操作。如图所示,Controller Manager中的控制器监视到新的部署描述后,根据部署描述,创建ReplicaSet、Pod等资源。Scheduler监视到新的Pod资源后,结合集群的资源情况,选定一或多个工作结点运行Pod。工作结点上的Kubelet监视到有Pod被计划在自己的结点后,向Docker等Container runtime发出启动容器的指令,Docker engineer将按照指令从Docker registy拉取镜像,然后启动并运行容器

以下是摘自 凌风探梅的总结

.什么是kubernetes
  首先,他是一个全新的基于容器技术的分布式架构领先方案。Kubernetes(k8s)是Google开源的容器集群管理系统(谷歌内部:Borg)。在Docker技术的基础上,为容器化的应用提供部署运行、资源调度、服务发现和动态伸缩等一系列完整功能,提高了大规模容器集群管理的便捷性。
  Kubernetes是一个完备的分布式系统支撑平台,具有完备的集群管理能力,多扩多层次的安全防护和准入机制、多租户应用支撑能力、透明的服务注册和发现机制、內建智能负载均衡器、强大的故障发现和自我修复能力、服务滚动升级和在线扩容能力、可扩展的资源自动调度机制以及多粒度的资源配额管理能力。同时Kubernetes提供完善的管理工具,涵盖了包括开发、部署测试、运维监控在内的各个环节。
Kubernetes中,Service是分布式集群架构的核心,一个Service对象拥有如下关键特征:
  • 拥有一个唯一指定的名字
  • 拥有一个虚拟IP(Cluster IP、Service IP、或VIP)和端口号
  • 能够体统某种远程服务能力
  • 被映射到了提供这种服务能力的一组容器应用上
  Service的服务进程目前都是基于Socket通信方式对外提供服务,比如Redis、Memcache、MySQL、Web Server,或者是实现了某个具体业务的一个特定的TCP Server进程,虽然一个Service通常由多个相关的服务进程来提供服务,每个服务进程都有一个独立的Endpoint(IP+Port)访问点,但Kubernetes能够让我们通过服务连接到指定的Service上。有了Kubernetes内奸的透明负载均衡和故障恢复机制,不管后端有多少服务进程,也不管某个服务进程是否会由于发生故障而重新部署到其他机器,都不会影响我们队服务的正常调用,更重要的是这个Service本身一旦创建就不会发生变化,意味着在Kubernetes集群中,我们不用为了服务的IP地址的变化问题而头疼了。
  容器提供了强大的隔离功能,所有有必要把为Service提供服务的这组进程放入容器中进行隔离。为此,Kubernetes设计了Pod对象,将每个服务进程包装到相对应的Pod中,使其成为Pod中运行的一个容器。为了建立Service与Pod间的关联管理,Kubernetes给每个Pod贴上一个标签Label,比如运行MySQL的Pod贴上name=mysql标签,给运行PHP的Pod贴上name=php标签,然后给相应的Service定义标签选择器Label Selector,这样就能巧妙的解决了Service于Pod的关联问题。
  在集群管理方面,Kubernetes将集群中的机器划分为一个Master节点和一群工作节点Node,其中,在Master节点运行着集群管理相关的一组进程kube-apiserver、kube-controller-manager和kube-scheduler,这些进程实现了整个集群的资源管理、Pod调度、弹性伸缩、安全控制、系统监控和纠错等管理能力,并且都是全自动完成的。Node作为集群中的工作节点,运行真正的应用程序,在Node上Kubernetes管理的最小运行单元是Pod。Node上运行着Kubernetes的kubelet、kube-proxy服务进程,这些服务进程负责Pod的创建、启动、监控、重启、销毁以及实现软件模式的负载均衡器。
  在Kubernetes集群中,它解决了传统IT系统中服务扩容和升级的两大难题。你只需为需要扩容的Service关联的Pod创建一个Replication Controller简称(RC),则该Service的扩容及后续的升级等问题将迎刃而解。在一个RC定义文件中包括以下3个关键信息。
  • 目标Pod的定义
  • 目标Pod需要运行的副本数量(Replicas)
  • 要监控的目标Pod标签(Label)
  在创建好RC后,Kubernetes会通过RC中定义的的Label筛选出对应Pod实例并实时监控其状态和数量,如果实例数量少于定义的副本数量,则会根据RC中定义的Pod模板来创建一个新的Pod,然后将新Pod调度到合适的Node上启动运行,知道Pod实例的数量达到预定目标,这个过程完全是自动化。
  
 Kubernetes优势:
    - 容器编排
    - 轻量级
    - 开源
    - 弹性伸缩
    - 负载均衡
 

Kubernetes主要由以下几个核心组件组成:

  • etcd保存了整个集群的状态;
  • apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
  • controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
  • scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
  • kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
  • Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
  • kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;
每个API对象都有3大类属性:元数据metadata、规范spec和状态status
pod文件
# yaml格式的pod定义文件完整内容:
apiVersion: v1       #必选,版本号,例如v1
kind: Pod       #必选,Pod
metadata:       #必选,元数据
  name: string       #必选,Pod名称
  namespace: string    #必选,Pod所属的命名空间
  labels:      #自定义标签
    - name: string     #自定义标签名字
  annotations:       #自定义注释列表
    - name: string
spec:         #必选,Pod中容器的详细定义
  containers:      #必选,Pod中容器列表
  - name: string     #必选,容器名称
    image: string    #必选,容器的镜像名称
    imagePullPolicy: [Always | Never | IfNotPresent] #获取镜像的策略 Alawys表示下载镜像 IfnotPresent表示优先使用本地镜像,否则下载镜像,Nerver表示仅使用本地镜像
    command: [string]    #容器的启动命令列表,如不指定,使用打包时使用的启动命令
    args: [string]     #容器的启动命令参数列表
    workingDir: string     #容器的工作目录
    volumeMounts:    #挂载到容器内部的存储卷配置
    - name: volumestring     #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
      mountPath: string    #存储卷在容器内mount的绝对路径,应少于512字符
      readOnly: boolean    #是否为只读模式
    ports:       #需要暴露的端口库号列表
    - name: string     #端口号名称
      containerPort: int   #容器需要监听的端口号
      hostPort: int    #容器所在主机需要监听的端口号,默认与Container相同
      protocol: string     #端口协议,支持TCP和UDP,默认TCP
    env:       #容器运行前需设置的环境变量列表
    - name: string     #环境变量名称
      value: string    #环境变量的值
    resources:       #资源限制和请求的设置
      limits:      #资源限制的设置
        cpu: string    #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
        memory: string     #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
      requests:      #资源请求的设置
        cpu: string    #Cpu请求,容器启动的初始可用数量
        memory: string     #内存清楚,容器启动的初始可用数量
    livenessProbe:     #对Pod内个容器健康检查的设置,当探测无响应几次后将自动重启该容器,检查方法有exec、httpGet和tcpSocket,对一个容器只需设置其中一种方法即可
      exec:      #对Pod容器内检查方式设置为exec方式
        command: [string]  #exec方式需要制定的命令或脚本
      httpGet:       #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
        path: string
        port: number
        host: string
        scheme: string
        HttpHeaders:
        - name: string
          value: string
      tcpSocket:     #对Pod内个容器健康检查方式设置为tcpSocket方式
         port: number
       initialDelaySeconds: 0  #容器启动完成后首次探测的时间,单位为秒
       timeoutSeconds: 0   #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
       periodSeconds: 0    #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
       successThreshold: 0
       failureThreshold: 0
       securityContext:
         privileged:false
    restartPolicy: [Always | Never | OnFailure]#Pod的重启策略,Always表示一旦不管以何种方式终止运行,kubelet都将重启,OnFailure表示只有Pod以非0退出码退出才重启,Nerver表示不再重启该Pod
    nodeSelector: obeject  #设置NodeSelector表示将该Pod调度到包含这个label的node上,以key:value的格式指定
    imagePullSecrets:    #Pull镜像时使用的secret名称,以key:secretkey格式指定
    - name: string
    hostNetwork:false      #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
    volumes:       #在该pod上定义共享存储卷列表
    - name: columestring     #共享存储卷名称 (volumes类型有很多种)
      emptyDir: {}     #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
      hostPath: string     #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
        path: string     #Pod所在宿主机的目录,将被用于同期中mount的目录
      secret:      #类型为secret的存储卷,挂载集群与定义的secre对象到容器内部
        scretname: string  
        items:     
        - key: string
          path: string
      configMap:     #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
        name: string
        items:
        - key: string
          path: string    

Node

  • 每个Node节点都运行着以下一组关键进程
  • kubelet:负责对Pod对于的容器的创建、启停等任务
  • kube-proxy:实现Kubernetes Service的通信与负载均衡机制的重要组件
  • Docker Engine(Docker):Docker引擎,负责本机容器的创建和管理工作

复制控制器(Replication Controller,RC)

Replication Controller用来管理Pod的副本,保证集群中存在指定数量的Pod副本,是实现弹性伸缩、动态扩容和滚动升级的核心。

随后可以通过Label Selector(标签选择器)查询和筛选拥有某些Label的资源对象,Kubernetes通过这种方式实现了类似SQL的简单又通用的对象查询机制

 

 Label Selector在Kubernetes中重要使用场景如下:

 

  1.kube-Controller进程通过资源对象RC上定义Label Selector来筛选要监控的Pod副本的数量,从而实现副本数量始终符合预期设定的全自动控制流程

  2.kube-proxy进程通过Service的Label Selector来选择对应的Pod,自动建立起每个Service岛对应Pod的请求转发路由表,从而实现Service的智能负载均衡

  3.通过对某些Node定义特定的Label,并且在Pod定义文件中使用Nodeselector这种标签调度策略,kuber-scheduler进程可以实现Pod”定向调度“的特性

 

Label

Label是Replication Controller和Service运行的基础,二者通过Label来进行关联Node上运行的Pod。

Service

 Node IP:Node节点的IP地址
 Pod IP: Pod的IP地址
 Cluster IP:Service的IP地址

Service是定义一系列Pod以及访问这些Pod的策略的一层抽象。Service通过Label找到Pod组

2个后台Pod,定义后台Service的名称为‘backend-service’,

lable选择器为(tier=backend, app=myapp)。backend-service 的Service会完成如下两件重要的事情:

1.会为Service创建一个本地集群的DNS入口,因此前端Pod只需要DNS查找主机名为 ‘backend-service’,就能够解析出前端应用程序可用的IP地址。

2.现在前端已经得到了后台服务的IP地址,但是它应该访问2个后台Pod的哪一个呢?Service在这2个后台Pod之间提供透明的负载均衡,会将请求分发给其中的任意一个(如下面的动画所示)。通过每个Node上运行的代理(kube-proxy)完成.

Deployment

Deployment为Pod和Replica Set(下一代Replication Controller)提供声明式更新,只需要在Deployment中描述你想要的目标状态是什么,Deployment controller就会帮你将Pod和Replica Set的实际状态改变到你的目标状态

一个典型的用例如下:

  • 使用Deployment来创建ReplicaSet。ReplicaSet在后台创建pod。检查启动状态,看它是成功还是失败。
  • 然后,通过更新Deployment的PodTemplateSpec字段来声明Pod的新状态。这会创建一个新的ReplicaSet,Deployment会按照控制的速率将pod从旧的ReplicaSet移动到新的ReplicaSet中。
  • 如果当前状态不稳定,回滚到之前的Deployment revision。每次回滚都会更新Deployment的revision。
  • 扩容Deployment以满足更高的负载。
  • 暂停Deployment来应用PodTemplateSpec的多个修复,然后恢复上线。
  • 根据Deployment 的状态判断上线是否hang住了。
  • 清除旧的不必要的ReplicaSet。

Ingress

 service和pod的IP仅可在集群内部访问。集群外部的请求需要通过负载均衡转发到service在Node上暴露的NodePort上,然后再由kube-proxy将其转发给相关的Pod。而Ingress就是为进入集群的请求提供路由规则的集合

Ingress可以给service提供集群外部访问的URL、负载均衡、SSL终止、HTTP路由等。为了配置这些Ingress规则,集群管理员需要部署一个Ingress controller,它监听Ingress和service的变化,并根据规则配置负载均衡并提供访问入口。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test
spec:
  rules:
  - host: foo.bar.com
    http:
      paths:
      - path: /foo
        backend:
          serviceName: s1
          servicePort: 80
      - path: /bar
        backend:
          serviceName: s2
          servicePort: 80

Volume

Secrets

 

 echo -n "root" | base64
cm9vdA==

 

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  password: MWYyZDFlMmU2N2Rm
  username: YWRtaW4=

创建好secret之后,有两种方式来使用它:

  • 以Volume方式
  • 以环境变量方式

将Secret挂载到Volume中


apiVersion: v1
kind: Pod
metadata:
  labels:
    name: db
  name: db
spec:
  volumes:
  - name: secrets
    secret:
      secretName: mysecret  创建的secrect名字
  containers:
  - image: gcr.io/my_project_id/pg:v1
    name: db
    volumeMounts:
    - name: secrets
      mountPath: "/etc/secrets"
      readOnly: true
    ports:
    - name: cp
      containerPort: 5432
      hostPort: 5432

将Secret导出到环境变量中

       env:
        - name: WORDPRESS_DB_USER
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: username
        - name: WORDPRESS_DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: password

 

ConfigMap  容器应用的配置管理

ConfigMap可以通过多种方式在Pod中使用,比如设置环境变量、设置容器命令行参数、在Volume中创建配置文件等。

创建一个配置文件  并将配置引入pod

apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-appvars
data:
  key-serverxml:
    <?xml Version='1.0'encoding='utf-8'?>
    <Server port="8005"shutdown="SHUTDOWN">
    .....
      </service>
    </Server>
  key-loggingproperties:
    "handlers=lcatalina.org.apache.juli.FileHandler,
    ...."
    volumeMounts:
    - name: serverxml                          #引用volume名
      mountPath:/configfiles                       #挂载到容器内部目录
        configMap:
          name: cm-test-appconfigfile                  #使用configmap定义的的cm-appconfigfile
          items:
          - key: key-serverxml                     #将key=key-serverxml
            path: server.xml                           #value将server.xml文件名进行挂载
          - key: key-loggingproperties                 #将key=key-loggingproperties    
            path: logging.properties                   #value将logging.properties文件名进行挂载 

健康检查的三种方式

ExecAction:在容器内部执行一个命令,如果该命令的返回值为0,则表示容器健康
TCPSocketAction:通过容器ip地址和端口号执行TCP检查,如果能够建立tcp连接表明容器健康
HTTPGetAction:通过容器Ip地址、端口号及路径调用http get方法请求资源,如果响应的状态吗大于200且小于400,则认为容器健康
spec:
  containers:
  - name: tomcat
    image: grc.io/google_containers/tomcat
    args:  配置一个命令,健康检查执行
    -/bin/sh
    - -c
    -echo ok >/tmp.health;sleep10; rm -fr /tmp/health;sleep600
    livenessProbe:
      exec:
        command:
        -cat
        -/tmp/health
      initianDelaySeconds:15
      timeoutSeconds:1 
  
  livenessProbe:
      tcpSocket:
        port: 80
      initianDelaySeconds:30
      timeoutSeconds:1

    livenessProbe:
      httpGet:
        path:/_status/healthz
        port: 80
      initianDelaySeconds:30
      timeoutSeconds:1

initialDelaySeconds:启动容器后首次监控检查的等待时间,单位秒
timeouSeconds:健康检查发送请求后等待响应的超时时间,单位秒。当发生超时就被认为容器无法提供服务无,该容器将被重启
健康检查

NodeSelector:定向调度

给node打上标签 kubectl label nodes k8s-node-1 label1=test

nodeSelector:
          label1: test

 

NodeAffinity:亲和性调度
该调度策略是将来替换NodeSelector的新一代调度策略。由于NodeSelector通过Node的Label进行精确匹配,所有NodeAffinity增加了In、NotIn、Exists、DoesNotexist、Gt、Lt等操作符来选择Node。调度侧露更加灵活。
  • 日志收集,比如fluentd,logstash等
  • 系统监控,比如Prometheus Node Exporter,collectd,New Relic agent,Ganglia gmond等
  • 系统程序,比如kube-proxy, kube-dns, glusterd, ceph等

kubectl get namespaces
kubectl create namespace new-namespace
kubectl get pods -l label名 -n namespace名
kubectl scale deployment nginx-deployment --replicas 10 扩容
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 更新镜像部署
kubectl edit deployment/nginx-deployment
kubectl create -f deployment.yaml文件 -n 命名空间
kubectl delete pods pods名称
kubectl get svc -n 名称 -o 样式 | 附加范围
kubectl delete pods,services -l name=myLabel(标签) --include-uninitialized(包含尚未初始化的)
kubectl exec -it pod名 /bin/bash -n 命名空间
kubectl rollout history deployment/deployment名称 -n --revision=版本号 查看提交历史
kubectl rollout history deployment/deployment名称 -n
kubectl rollout undo deployment/deployment名称 --to-revision=版本号 -n

kubectl rolling-update redis-master --image=redis-master:2.0  升级内部镜像

kubectl get pods --show-labels
kubectl rollout status deployment/nginx-deployment 监控回撤状态
kubectl describe deployment 部署名 -n 空间 查看详细
kubectl set resources deployment nginx -c=nginx --limits=cpu=200m,memory=512Mi


kubectl get deployment pod名 -o yaml -n 查看部署文件
创建环境变量 将常量参数写入其中
kubectl create configmap env-config --from-literal=log_level=INFO

kubectl logs volume-pod -c busybox 

posted @ 2018-12-30 12:55  jojoworld  阅读(357)  评论(0编辑  收藏  举报