Kubernetes 高级特性集锦

来源:互联网 发布:python 运维框架 编辑:程序博客网 时间:2024/06/05 04:11

1.前言

kubernetes 项目发展至今,社区出现了很多非常优秀的特性,这些特性极大地扩展了Kubernetes的能力。目前很多公司基于Google Kubernetes 和 Docker 打造各自的私有化PaaS平台,这些高级特性往往是PaaS平台需要的,深入了解这些特性能够帮助架构设计人员快速确定技术方案,达到事半功倍的效果。目前很多PaaS平台都通过开放Kubernetes 特性,获得了很好的效果。

2.特性介绍

1)集群联邦

用户在生产环境部署微服务时有一个非常明确的需求,那就是希望服务部署能够跨zone、跨区域、跨集群甚至跨云边界。相对于单个集群的服务部署模式,跨集群服务能够提供按地域分布的服务,支持混合云、多云场景,全面提升服务的高可用等级。服务使用者希望服务无论在集群内部还是外部,都有稳定、一致的连接。

从Kubernetes的角度来说,以前只针对一个集群进行管理即可,加入集群联邦特性之后,就需要一个"集群控制器",通过这个控制器控制各个集群。各个集群在集群控制器中有相应的标识,发送的命令通过集群控制器进行转发。


从上图可以看出,用户通过UI、CLI、API发起的请求,最终汇集到集群联邦控制面板,集群控制面板负责与各个集群进行交互。更为详细信息请查看:

http://blog.kubernetes.io/2016/07/cross-cluster-services.html

2) 有状态应用

众所周知,Pod在Kubernetes中是会发生漂移的。比如节点出现故障,应用会迁移到正常节点。对于无状态应用,这是没有问题的,但是针对有状态应用,这种方式则不可取,因为迁移之后,应用的状态(比如写在节点上的临时文件)不会随着应用迁移,会引起状态不一致的问题。比如Mysql,Mongodb,Zookeeper等引用,必须挂载数据卷并且支持稳定的访问。

无状态的概念,就是只负责运算,不负责任何数据的存储,这样就能很轻松地做到水平扩展。对于无状态应用,如何做到水平扩展呢?谷歌提出了解决方案,Pod负责运行无状态应用,PetSet负责有状态应用。

PetSet 作为运行有状态应用的基础,需要具体以下条件:

* 有唯一的编号

* 在网络上有一个不会改变的标识,k8s是通过域名实现的。pod则是名字后面还有随机数,所以需要有service来做转发

* 每个有状态服务,都需要有自己的卷,这样就能保证数据可靠存储

PetSet.yaml 如下:

# A headless service to create DNS recordsapiVersion: v1kind: Servicemetadata:  name: nginx  labels:    app: nginxspec:  ports:  - port: 80    name: web  # *.nginx.default.svc.cluster.local  clusterIP: None  selector:    app: nginx---apiVersion: apps/v1alpha1kind: PetSetmetadata:  name: webspec:  serviceName: "nginx"  replicas: 2  template:    metadata:      labels:        app: nginx      annotations:        pod.alpha.kubernetes.io/initialized: "true"    spec:      terminationGracePeriodSeconds: 0      containers:      - name: nginx        image: gcr.io/google_containers/nginx-slim:0.8        ports:        - containerPort: 80          name: web        volumeMounts:        - name: www          mountPath: /usr/share/nginx/html  volumeClaimTemplates:  - metadata:      name: www      annotations:        volume.alpha.kubernetes.io/storage-class: anything    spec:      accessModes: [ "ReadWriteOnce" ]      resources:        requests:          storage: 1Gi
从yaml中可以看出,Service以PetSet中的Pet作为后端Pod,并且PetSet挂载了持久化存储。同时,PetSet支持以下功能:

* Peer discovery

* PetSet Update

* PetSet 扩容

* 镜像升级

* PetSet删除(仅仅删除PetSet不会删除挂载的持久化存储,如果要在删除PetSet同时删除PVC,需要使用--cascade=false参数)

Kubernetes Petset 官方文档:

http://kubernetes.io/docs/user-guide/petset/

3)Init-Container

在Pod真正运行起来之前,通常有一些初始化的动作需要做,比如初始化本地数据(可能是一些配置)。Pod里面的多个Container(至少一个),在挂载volume之后,并行地进行初始化。

K8S 为了解决Container在运行之前的初始化工作,引入了init-container的概念。一个Init container的定义如下:

apiVersion: v1kind: Podmetadata:  name: kubectl  annotations:    pod.alpha.kubernetes.io/init-containers: '[        {            "name": "download",            "image": "busybox",            "command": [                "wget",             "-O",                 "/work-dir/kubectl",                 "http://storage.googleapis.com/kubernetes-release/release/v1.2.4/bin/linux/amd64/kubectl"            ],            "volumeMounts": [                {                    "name": "workdir",                    "mountPath": "/work-dir"                }            ]        },        {            "name": "chmod",            "image": "busybox",            "command": ["chmod", "755", "/work-dir/kubectl"],            "volumeMounts": [                {                    "name": "workdir",                    "mountPath": "/work-dir"                }            ]        }    ]'spec:  containers:  - name: kubectl    image: busybox    command:    - /bin/sleep    - "36000"    volumeMounts:    - name: workdir      mountPath: /usr/local/bin  dnsPolicy: Default  volumes:  - name: workdir    emptyDir: {}
这里的init container包含两个容器,一个负责下载,另一个负责修改权限。在busybox加载之前完成所有操作,这非常符合init container的设计意图。

这个应用场景是将kubectl容器化处理,首先现在kubectl二进制,然后切换执行权限,一旦Kubectl二进制有版本变更,仅需要升级二进制,重启pod即可。使用方式如下:

kubectl exec -t -i kubectl kubectl versionClient Version: version.Info{Major:"1", Minor:"2", GitVersion:"v1.2.4", GitCommit:"3eed1e3be6848b877ff80a93da3785d9034d0a4f", GitTreeState:"clean"}Server Version: version.Info{Major:"1", Minor:"3+", GitVersion:"v1.3.0-beta.2", GitCommit:"caf9a4d87700ba034a7b39cced19bd5628ca6aa3", GitTreeState:"clean"}

官方设计文档在此:
https://github.com/kubernetes/kubernetes/blob/master/docs/proposals/container-init.md

4)configmap

应用通常需要很多配置参数,这些配置参数通常都以Container环境变量的形式传入容器内部,能够有一个k8s对象,保存通用的配置参数呢?

k8s提供了configmap对象,这个对象存储了map(key、value)形式的参数。一个configmap定义如下:

kind: ConfigMapapiVersion: v1metadata:  creationTimestamp: 2016-02-18T19:14:38Z  name: example-config  namespace: defaultdata:  example.property.1: hello  example.property.2: world  example.property.file: |-    property.1=value-1    property.2=value-2    property.3=value-3
configmap使用场景如下:

* ConfigMap 作为环境变量使用

configmap:

apiVersion: v1kind: ConfigMapmetadata:  name: special-config  namespace: defaultdata:  special.how: very  special.type: charm
Pod:

apiVersion: v1kind: Podmetadata:  name: dapi-test-podspec:  containers:    - name: test-container      image: gcr.io/google_containers/busybox      command: [ "/bin/sh", "-c", "env" ]      env:        - name: SPECIAL_LEVEL_KEY          valueFrom:            configMapKeyRef:              name: special-config              key: special.how        - name: SPECIAL_TYPE_KEY          valueFrom:            configMapKeyRef:              name: special-config              key: special.type  restartPolicy: Never
* 作为命令行参数

configmap:

apiVersion: v1kind: ConfigMapmetadata:  name: special-config  namespace: defaultdata:  special.how: very  special.type: charm
pod:

apiVersion: v1kind: Podmetadata:  name: dapi-test-podspec:  containers:    - name: test-container      image: gcr.io/google_containers/busybox      command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]      env:        - name: SPECIAL_LEVEL_KEY          valueFrom:            configMapKeyRef:              name: special-config              key: special.how        - name: SPECIAL_TYPE_KEY          valueFrom:            configMapKeyRef:              name: special-config              key: special.type  restartPolicy: Never
* 挂载卷

configmap:

apiVersion: v1kind: ConfigMapmetadata:  name: special-config  namespace: defaultdata:  special.how: very  special.type: charm
pod:

apiVersion: v1kind: Podmetadata:  name: dapi-test-podspec:  containers:    - name: test-container      image: gcr.io/google_containers/busybox      command: [ "/bin/sh", "-c", "cat /etc/config/special.how" ]      volumeMounts:      - name: config-volume        mountPath: /etc/config  volumes:    - name: config-volume      configMap:        name: special-config  restartPolicy: Never

官方资料在此:http://kubernetes.io/docs/user-guide/configmap/

3. Template

在kubernetes中,创建应用涉及到的对象比较多,通常需要很多参数。用户如果没有模版,每次都需要配置很多参数。在反复创建过程中,效率很低。

K8S 提供了模版能力,开放该能力能够帮助用户快速创建应用。一个应用模版实例如下:

MySql:

https://github.com/openshift/origin/blob/master/examples/db-templates/mysql-persistent-template.json

Jekins:

https://github.com/openshift/origin/blob/master/examples/jenkins/jenkins-persistent-template.json

目前主要使用PodTemplate,里面主要涉及Pod的定义(镜像、挂卷等等)

// PodSpec is a description of a podtype PodSpec struct {Volumes []Volume `json:"volumes"`// List of initialization containers belonging to the pod.InitContainers []Container `json:"-"`// List of containers belonging to the pod.Containers    []Container   `json:"containers"`RestartPolicy RestartPolicy `json:"restartPolicy,omitempty"`// Optional duration in seconds the pod needs to terminate gracefully. May be decreased in delete request.// Value must be non-negative integer. The value zero indicates delete immediately.// If this value is nil, the default grace period will be used instead.// The grace period is the duration in seconds after the processes running in the pod are sent// a termination signal and the time when the processes are forcibly halted with a kill signal.// Set this value longer than the expected cleanup time for your process.TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"`// Optional duration in seconds relative to the StartTime that the pod may be active on a node// before the system actively tries to terminate the pod; value must be positive integerActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty"`// Required: Set DNS policy.DNSPolicy DNSPolicy `json:"dnsPolicy,omitempty"`// NodeSelector is a selector which must be true for the pod to fit on a nodeNodeSelector map[string]string `json:"nodeSelector,omitempty"`// ServiceAccountName is the name of the ServiceAccount to use to run this pod// The pod will be allowed to use secrets referenced by the ServiceAccountServiceAccountName string `json:"serviceAccountName"`// NodeName is a request to schedule this pod onto a specific node.  If it is non-empty,// the scheduler simply schedules this pod onto that node, assuming that it fits resource// requirements.NodeName string `json:"nodeName,omitempty"`// SecurityContext holds pod-level security attributes and common container settings.// Optional: Defaults to empty.  See type description for default values of each field.SecurityContext *PodSecurityContext `json:"securityContext,omitempty"`// ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec.// If specified, these secrets will be passed to individual puller implementations for them to use.  For example,// in the case of docker, only DockerConfig type secrets are honored.ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty"`// Specifies the hostname of the Pod.// If not specified, the pod's hostname will be set to a system-defined value.Hostname string `json:"hostname,omitempty"`// If specified, the fully qualified Pod hostname will be "<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>".// If not specified, the pod will not have a domainname at all.Subdomain string `json:"subdomain,omitempty"`}
3.总结

kubernetes 发展迅速,增加了很多新特性,本篇的总结仅作为开端,后续会介绍其他更多特性。









0 0
原创粉丝点击