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 main
import(
"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.9
MAINTAINER devops008@sina.com
WORKDIR /usr/src/app
COPY main.go /usr/src/app
EXPOSE 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/v1beta1
kind: Deployment
metadata: name: hello-devops
labels:
app: hello-devops
spec:
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 pods
NAME READY STATUS RESTARTS AGE
hello-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: v1
kind: Service
metadata:
name: hello-devops-svc
labels:
app: hello-devops
spec:
ports:
- port: 8888
name: http
selector:
app: hello-devops
而后执行 kubectl-n devops-f service.yaml 在 devops namespace 上面创立出 service
,并查看
$ kubectl -n devops get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-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/v1beta1
kind: Ingress
metadata:
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 ing
NAME HOSTS ADDRESS PORTS AGE
hello-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.com
Hello 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 日,胡贤彬《自动化测试,如何做到「攻防兼备」?》