Kubernetes 演进史

Kubernetes简称K8S(除去结尾的K和结尾的S,两头正好有八个字符,故号称K8S)是谷歌开源的一个全新的基于容器技术的分布式架构计划,同时也是一个全新的容器编排工具。

Kubernetes的前身是谷歌的Borg零碎,始于2003年,它是在谷歌外部应用的一个容器管理系统,它治理着来自数千个不同应用程序的数十万个作业,逾越许多集群,而每个集群领有多达数万台计算机。

2013年,另外一个Omega零碎在谷歌外部利用,Omega能够看作是Borg的延长,在大规模集群治理以及性能方面优于Borg。然而Borg和Omega都是谷歌外部应用的零碎,也就是所谓的闭源零碎。直到2014年,谷歌以开源的模式推出了Kubernetes零碎,同年6月7号在github上实现了第一次提交,随后的7月10号,微软,IBM,Redhat,Docker退出了Kubernetes社区。

在2015年7月Kubernetes正式公布了v1.0版本,直到往年6月19号公布了v1.15版本,而且1.16版本正在缓和开发之中。能够看出短短四年曾经公布了十六个版本,而且速度越来越快。

其实在容器编排畛域除了有Kubernetes,还有Docker Swarm和Mesos,在初期,这三者呈三足鼎立之势,然而当初Kubernetes却一枝独秀,Kubernetes曾经倒退成为一个Kubernetes生态圈,而且以Kubernetes为外围倒退起来的的CloudNative的发展势头也很迅猛。

Kubernetes上部署利用

拜访位于Kubernetes平台上的应用程序,用户申请达到Ingress资源,Ingress会依据配置的策略,找到相应的service,因为service和pod是通过labelSelector来实现映射的,所以申请到了service,自然而然就能找到相应的pod,从而申请就到了最终的目的地:运行应用程序的容器。流程简图如下

Kubernetes平台上"所有皆资源",所以如果要部署一个可对外拜访的应用程序,依据上图所示能够跟着上面的三步曲(deployment(Pod)---> Service---> Ingress)创立出deployment,service,ingress三种资源就能够。

第一步:Deployment(Pod)的创立

Pod是Kubernetes最根本也最重要的概念,它是Kubernetes平台上资源调度的最小也是最根本单元。利用程序运行在容器内,pod治理着容器,而pod是被调度到node下面的,node能够是一个物理机或者虚拟机。容器,pod,node的关系犹如豌豆株,豌豆荚,豌豆的关系。如下图所示。

一个pod外面能够有多个容器,同一个pod内的多个容器共享pod的资源,比方共享卷,网络等。就像一个豌豆荚外面能够有多个豌豆,同一个豌豆荚外面的几个豌豆共用一个豌豆蒂来排汇养分。pod是运行在Kubernetes node节点上的,一个node下面能够运行多个pod,就像一株豌豆下面有多个豌豆荚。一个Kubernetes cluster个别蕴含多个node,就像一亩地外面个别有多株豌豆。

筹备工作

Kubernetes平台上利用程序运行在容器内,容器是用镜像生成的,所以在部署pod之前,咱们先将一个输入 HelloDevOps 的应用程序打包成容器镜像。应用程序的代码如下

package mainimport(    "fmt"    "log"    "net/http"    "os")func get_hostname() string{    hostname, _ := os.Hostname()    return hostname}func get_env_var() string {    version := os.Getenv("VERSION")    return version}func handler(w http.ResponseWriter, r *http.Request) {    fmt.Fprintf(w, "Hello DevOps, pod name is %s, version is %s",get_hostname(), get_env_var())}func main() {    http.HandleFunc("/", handler)    log.Fatal(http.ListenAndServe(":9999", nil))}

接下来编写Dockerfile

FROM golang:1.12.7-alpine3.9MAINTAINER devops008@sina.comWORKDIR /usr/src/appCOPY main.go /usr/src/appEXPOSE 8888CMD ["go","run","main.go"]

而后用命令 docker build-t dllhb/go_demo:v1.0&&docker push dllhb/go_demo:v1.0 将镜像push到dockerhub下面,上面能够用此镜像创立一个pod。

创立Deployment(Pod)

apiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: hello-devops  labels:    app: hello-devopsspec:  replicas: 1  template:    metadata:      labels:        app: hello-devops    spec:      containers:      - name: hello-devops        image: dllhb/go_demo:v1.0        resources:          limits:            cpu: "200m"            memory: "200Mi"          requests:            cpu: "100m"            memory: "50Mi"        imagePullPolicy: IfNotPresent        ports:         - containerPort: 8888

而后用 kubectl-n devops create-f devops.yaml 在devops namespace上面创立出deployment,并查看pod的状态。

$ kubectl -n devops get podsNAME                            READY     STATUS    RESTARTS   AGEhello-devops-78dd67d9cc-klxlm   1/1       Running   0          17s

应用程序在容器外面运行,而后pod负责管理,每个pod在创立胜利后会被调配给一个IP,其余pod能够通过这个IP来跟它进行通信,然而pod的IP在pod重启当前就会发生变化,这样导致了其余pod无奈跟它进行通信。在此状况下,形象一个叫做Service的资源,Service具备一个惟一指定的名字,一旦创立便不会扭转,直到被删除。艰深来讲,Service是一组具备雷同label的pod所提供服务的一种形象。这样Service和pod就造成了映射。以Service name之不变而解决了pod IP的常变之大问题。

第二步:Service的创立

apiVersion: v1kind: Servicemetadata:  name: hello-devops-svc  labels:    app: hello-devopsspec:  ports:  - port: 8888    name: http  selector:    app: hello-devops

而后执行 kubectl-n devops-f service.yaml 在devops namespace上面创立出service,并查看

$ kubectl -n devops get svcNAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGEhello-devops-svc   ClusterIP   172.21.246.13   <none>        8888/TCP   71s

部署利用的目标是为了可能给用户提供可用的服务,也就是说服务要可能对外拜访,这就波及到了服务裸露这个话题。Kubernetes服务裸露的模式有三种:NodeIP+Port, LoadBalancer,Ingress。

如果要通过NodeIP+Port的形式裸露服务,须要在Kubernetes节点下面关上相应的端口,对于生产线上的利用,这种形式存在肯定的安全隐患;另外,云厂商提供的Kubernetes cluster中的node如果因为降级等起因重启之后NodeIP很可能产生扭转。所以NodeIP+Port是Kubernetes晚期广泛应用的服务裸露形式。

LoadBalancer个别是云厂商提供的一种服务裸露形式,如果要本人搭建,会显得费时费力,所以咱们抉择用Ingress来对服务进行裸露。Ingress的实现是通过Ingress策略定义和一个具体的Ingress Controller实现联合起来,实现服务裸露。

本文的目标在于实际,能够依据Ingress资源的定义形式间接创立Ingress资源来实现服务裸露。

第三步:Ingress的创立

Ingress 如果开启了TLS,那么须要对应的创立一个secret资源,Kubernetes的secret资源次要用来寄存一些敏感信息,比方明码,token等。能够先用openssl命令生成tls.cert和tls.key文件。

$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /tmp/tls.key -out /tmp/tls.crt -subj "/CN=devops.test.com"

而后用这两个文件来创立secret

$ kubectl -n devops create secret tls test-tls --key=/tmp/tls.key --cert=/tmp/tls.crt

将下述内容写入一个ingress.yaml文件

apiVersion: extensions/v1beta1kind: Ingressmetadata:  name: hello-devops-ingress  annotations:    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"spec:  tls:  -hosts:    - hello-devops.test.com    secretName: test-tls  rules:  - host: hello-devops.test.com    http:      paths:      - path: /        backend:          serviceName: hello-devops-svc          servicePort: 8888

而后应用命令 kubectl-n devops create-f ingress.yaml 在devops namespace上面创立Ingress资源并查看

$ kubectl -n devops get ingNAME                   HOSTS             ADDRESS        PORTS     AGEhello-devops-ingress   devops.test.com   10.208.70.22   80, 443   100s

用curl命令查看 curl-k-s https://devops.test.com 能够看到如下内容

$ curl -k -s https://devops.test.comHello DevOps, pod name is hello-devops-78dd67d9cc-klxlm

至此,通过创立deployment,service,ingress资源实现了Hello DevOps的利用部署。简略的demo能够依照这种简略的几个步骤在Kubernetes下面实现部署,然而当微服务的数量减少,资源的管理文件也将是海量的,不仅仅只有下面的deployment,service,ingress,还将会有secret,configmap,pvc等。

起源:DevSecOps SIG
作者:小马哥
申明:文章取得作者受权在IDCF社区公众号(devopshub)转发。优质内容共享给思否平台的技术伙伴,如原作者有其余思考请分割小编删除,致谢。

7月每周四晚8点,【冬哥有话说】研发效力工具专场,公众号留言“研发效力”可获取地址

  • 7月8日,周文洋《微软DevOps工具链的 "爱恨情仇"(Azure DevOps)》
  • 7月15日,待定
  • 7月22日,张扬《基础设施即代码的⾃动化测试摸索》
  • 7月29日,胡贤彬《自动化测试,如何做到「攻防兼备」?》