基于 Docker for MAC 的 Kubernetes 本地环境搭建与应用部署

下载最新的 Docker for Mac 或者 Edge 版本,即可以看到内置的 Kubernetes 集群,直接点击安装即可在本地搭建好单节点的 Kubernetes 环境:

安装完毕后,如果我们也勾选了 Show system containers 选项,那么使用如下的 Docker 命令,能看到自动安装的 Kubernetes 相关容器:

➜  ~ docker container ls --format "table{{.Names}}\t{{.Image }}\t{{.Command}}"
NAMES                                                                                                                   IMAGE                                                    COMMAND
k8s_compose_compose-75f8bb4779-stxv9_docker_3c963862-f9f4-11e7-93cc-025000000001_0                                      docker/kube-compose-controller                           "/compose-controller…"
k8s_POD_compose-75f8bb4779-stxv9_docker_3c963862-f9f4-11e7-93cc-025000000001_0                                          gcr.io/google_containers/pause-amd64:3.0                 "/pause"
k8s_sidecar_kube-dns-545bc4bfd4-799pr_kube-system_139bf000-f9f4-11e7-93cc-025000000001_0                                gcr.io/google_containers/k8s-dns-sidecar-amd64           "/sidecar --v=2 --lo…"
k8s_dnsmasq_kube-dns-545bc4bfd4-799pr_kube-system_139bf000-f9f4-11e7-93cc-025000000001_0                                gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64     "/dnsmasq-nanny -v=2…"
k8s_kubedns_kube-dns-545bc4bfd4-799pr_kube-system_139bf000-f9f4-11e7-93cc-025000000001_0                                gcr.io/google_containers/k8s-dns-kube-dns-amd64          "/kube-dns --domain=…"
k8s_kube-proxy_kube-proxy-rrd8t_kube-system_139b00df-f9f4-11e7-93cc-025000000001_0                                      gcr.io/google_containers/kube-proxy-amd64                "/usr/local/bin/kube…"
k8s_POD_kube-dns-545bc4bfd4-799pr_kube-system_139bf000-f9f4-11e7-93cc-025000000001_0                                    gcr.io/google_containers/pause-amd64:3.0                 "/pause"
k8s_POD_kube-proxy-rrd8t_kube-system_139b00df-f9f4-11e7-93cc-025000000001_0                                             gcr.io/google_containers/pause-amd64:3.0                 "/pause"
k8s_kube-scheduler_kube-scheduler-docker-for-desktop_kube-system_972d74c9fc2f4ebd8ab673058e386a65_0                     gcr.io/google_containers/kube-scheduler-amd64            "kube-scheduler --ad…"
k8s_kube-apiserver_kube-apiserver-docker-for-desktop_kube-system_f7a81e8fe624bd46059fc6084e86bb81_0                     gcr.io/google_containers/kube-apiserver-amd64            "kube-apiserver --ad…"
k8s_etcd_etcd-docker-for-desktop_kube-system_56a21c0a5f545c0cca5388c457bb1b3b_0                                         gcr.io/google_containers/etcd-amd64                      "etcd --advertise-cl…"
k8s_kube-controller-manager_kube-controller-manager-docker-for-desktop_kube-system_8d1848c1e562e35a225e402988eadcd1_0   gcr.io/google_containers/kube-controller-manager-amd64   "kube-controller-man…"
k8s_POD_kube-apiserver-docker-for-desktop_kube-system_f7a81e8fe624bd46059fc6084e86bb81_0                                gcr.io/google_containers/pause-amd64:3.0                 "/pause"
k8s_POD_kube-controller-manager-docker-for-desktop_kube-system_8d1848c1e562e35a225e402988eadcd1_0                       gcr.io/google_containers/pause-amd64:3.0                 "/pause"
k8s_POD_kube-scheduler-docker-for-desktop_kube-system_972d74c9fc2f4ebd8ab673058e386a65_0                                gcr.io/google_containers/pause-amd64:3.0                 "/pause"
k8s_POD_etcd-docker-for-desktop_kube-system_56a21c0a5f545c0cca5388c457bb1b3b_0                                          gcr.io/google_containers/pause-amd64:3.0                 "/pause"

关于各个容器的作用,可以参阅 这里。在安装过程中,Docker 也为我们安装了 kubectl 控制命令:

$ kubectl get namespaces
$ kubectl get posts --namespace kube-system

接下来我们可以使用 kubectl 命令来创建简单的 kubernetes-dashboard 服务:

➜  ~ kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
secret "kubernetes-dashboard-certs" created
serviceaccount "kubernetes-dashboard" created
role "kubernetes-dashboard-minimal" created
rolebinding "kubernetes-dashboard-minimal" created
deployment "kubernetes-dashboard" created
service "kubernetes-dashboard" created

服务安装完毕后可以查看部署的容器与服务:

➜  ~ kubectl get deployments --namespace kube-system
NAME                   DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
kube-dns               1         1         1            1           22m
kubernetes-dashboard   1         1         1            0           26s
➜  ~ kubectl get services --namespace kube-system
NAME                   TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
kube-dns               ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP   22m
kubernetes-dashboard   ClusterIP   10.111.242.95   <none>        443/TCP         30s

在 Dashboard 启动完毕后,可以使用 kubectl 提供的 Proxy 服务来访问该面板:

$ kubectl proxy

# 打开如下地址:
# http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/

如果访问报错,可以尝试编辑 kubernetes-dashboard 服务,或者参阅这里

$ kubectl -n kube-system edit service kubernetes-dashboard

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
...
  name: kubernetes-dashboard
  namespace: kube-system
  resourceVersion: "343478"
  selfLink: /api/v1/namespaces/kube-system/services/kubernetes-dashboard-head
  uid: 8e48f478-993d-11e7-87e0-901b0e532516
spec:
  clusterIP: 10.100.124.90
  externalTrafficPolicy: Cluster
  ports:
  - port: 443
    protocol: TCP
    targetPort: 8443
  selector:
    k8s-app: kubernetes-dashboard
  sessionAffinity: None
  type: ClusterIP ->> NodePort
status:
  loadBalancer: {}

访问上述地址,我们可以看到登录界面:

此时可暂时直接跳过,进入到控制面板中:

Docker 同样为我们提供了简单的应用示范,可以直接使用如下的 Docker Compose 配置文件:

version: '3.3'

services:
  web:
    build: web
    image: dockerdemos/lab-web
    volumes:
     - "./web/static:/static"
    ports:
     - "80:80"

  words:
    build: words
    image: dockerdemos/lab-words
    deploy:
      replicas: 5
      endpoint_mode: dnsrr
      resources:
        limits:
          memory: 16M
        reservations:
          memory: 16M

  db:
    build: db
    image: dockerdemos/lab-db

然后使用 stack 命令创建应用栈:

$ docker stack deploy --compose-file stack.yml demo

Stack demo was created
Waiting for the stack to be stable and running...
 - Service web has one container running

应用栈创建完毕后,可以使用 kubectl 查看创建的 Pods:

$ kubectl get pods

NAME                     READY     STATUS    RESTARTS   AGE
db-7f99cc64b7-cbd9t      1/1       Running   0          2m
web-758c6998f8-tmxfm     1/1       Running   0          2m
words-54bf6c5d57-8bxc8   1/1       Running   0          2m
words-54bf6c5d57-dzxm8   1/1       Running   0          2m
words-54bf6c5d57-k2448   1/1       Running   0          2m
words-54bf6c5d57-mhh4p   1/1       Running   0          2m
words-54bf6c5d57-w2q82   1/1       Running   0          2m

也可以来查看部署的集群与服务:

$ kubectl get deployments
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
db        1         1         1            1           3m
web       1         1         1            1           3m
words     5         5         5            5           3m

$ kubectl get services
NAME         TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
db           ClusterIP      None           <none>        55555/TCP      3m
kubernetes   ClusterIP      10.96.0.1      <none>        443/TCP        52m
web          LoadBalancer   10.97.154.28   <pending>     80:30577/TCP   3m
words        ClusterIP      None           <none>        55555/TCP      3m

可以看到这里的 web 有所谓的 LoadBalancer 类型,即可以对外提供服务。最后我们还可以用 stack 与 kubectl 命令来删除应用:

$ docker stack remove demo
$ kubectl delete deployment kubernetes-dashboard --namespace kube-system

ISTJ 检查员型——细致、谨慎地执行好现有规则

一、基本描述

才储分析:您的性格类型倾向为“ ISTJ ”(内向 实感 思维 判断 倾向度: I57 S71 T57 J71  不假思索指数:6)

沉静,认真;贯彻始终、得人信赖而取得成功。讲求实际,注重事实和有责任感。能够合情合理地去决定应做的事情,而且坚定不移地把它完成,不会因外界事物而分散精神。以做事有次序、有条理为乐—不论在工作上, 家庭上或者生活上。重视传统和忠诚。

ISTJ型的人是严肃的、有责任心的和通情达理的社会坚定分子。他们值得信赖,他们重视承诺,对他们来说,言语就是庄严的宣誓。 ISTJ型的人工作缜密,讲求实际,很有头脑也很现实。他们具有很强的集中力、条理性和 准确性。无论他们做什么,都相当有条理和可靠。他们具有坚定不移、深思熟虑的思想,一旦他们着手自己相信是最好的行动方法时,就很难转变或变得沮丧。ISTJ型的人特别安静和勤奋,对于细节有很强的记忆和判断。 他们能够引证准确的事实支持自己的观点,把过去的经历运用到现在的决策中。他们重视和利用符合逻辑、客观的分析,以坚持不懈的态度准时地完成工作,并且总是安排有序,很有条理。他们重视必要的理论体系和传统 惯例,对于那些不是如此做事的人则很不耐烦。ISTJ型的人总是很传统、谨小甚微。他们聆听和喜欢确实、清晰地陈述事物。ISTJ型的人天生不喜欢显露,即使危机之时,也显得很平静。他们总是显得责无旁贷、坚定不变 、但是在他们冷静的外表之下,也许有强烈却很少表露的反应。

二、气质类型

根据大卫.凯尔西(David Keirsey)气质与性情理论,你属于“传统主义者”,下面是对“传统主义者”的描述:

“传统主义者”相信事实、已证实的数据、过去的经验和“五官”所带给他们的信息,喜欢有结构有条理的世界,喜欢做决定,是一 种既现实又有明确目标的人。

“传统主义者”是最传统的一类人,他们坚定、可靠、可信。他们重视法律、秩序、安全、得体、规则和本分。他们被一种 为社会服务的动机所驱使。他们尊重权威、等级制度和权力,而且一般具有保守的价值观。他们很有责任感,而且经常努力去做正确 的事情,这使他们可以信赖和依靠。

“传统主义者”需要有归属感,需要服务于别人,需要做正确的事情。他们注重安稳、秩序、合作、前后一致和可靠,而且他们严肃 认真,工作努力。“传统主义者”在工作中对自己要求十分严格,而且他们希望别人也是如此。“传统主义者”喜欢那些与他们一样 具有奉献精神、尊重权威和尽自己的本分的同事。

“传统主义者”往往是组织机构的主要支持者,不论他们是在领导层还是处于被领导的位置上。他们最常扮演的角色就是“稳定器” ——传统和现状的维护者。 大多数“传统主义者”(不论他们是属于什么判断偏好)最喜欢的是组织结构稳定、清楚、目标明确 的岗位,不喜欢处在不断变化和杂乱状况之中的职位或组织。

“传统主义者”包括思维型传统主义者和情感型传统主义者,这两种传统主义者之间又有很明显的不同。情感型传统主义者常常不象 思维型传统主义者那样明显地表现出传统主义者的一般特征。在做决定时,情感型传统主义者把与别人的关系和人放在首要位置,本 能地努力寻求与他人更和睦的关系,同时不断寻找着使他们能够通过有形的方式帮助他人的机会。

对于不同的性格类型而言,没有“好”与“坏”之分,每一个人都是一个独一无二的个体,都有其特别的优势和劣势,但问题的关键 在于如何认识这些优势和劣势。基于MBTI模型职业规划的核心法则是:“扬长避短”,学会了这一点将会影响到你的成败及你对工作的正确选择。

对你的总体描述

1. 实际,有条理,认真仔细。
2. 注重规则、政策、契约、例行习惯和时间要求。
3. 一旦他们承诺一件事情,总会坚持完成它。
4. 在跟进、规范方面做得很好。
5. 以第一次和每一次都做了正确的事情为荣。
6. 对需要注意的事情有敏锐的洞察力。
7. 善于尽可能有效地利用现有资源完成工作。

你潜在的弱点 

1. 容易只看到事情有黑和白两种情况,而看不到中间的灰色地带。
2. 可能不能很快地做出改变和适应。
3. 有些此类型成员不擅长变通、缺乏想象力。

三、优势与劣势

ISTJ的特质: 检查员型——细致、谨慎地执行好现有规则

优势:

你是一个认真而严谨的人,勤奋而负有责任感,认准的事情很少会改变或气馁,做事深思熟虑,信守承诺并值得信赖。

你依靠理智的思考来做决定,总是采取客观、合乎逻辑的步骤,不会感情用事,甚至在遇到危机时都能够表现得平静。

你谨慎而传统,重视稳定性、合理性;你天生独立,需要把大量的精力倾注到工作中,并希望其它人也是如此,善于聆听并喜欢将事情清晰而条理的安排好。

你喜欢先充分收集各种信息,然后根据信息去综合考虑实际的解决方法,而不是运用理论去解决。你对细节非常敏感,有很实际的判断力,决定时能够运用精确的证据和过去的经验来支持自己的观点,并且非常系统有条不紊,对那些不这样做的人没有耐心。

劣势:

你非常固执,一旦决定的事情,会对其他的观点置之不理,并经常沉浸于具体的细节和日常的操作中。

你看问题有很强的批判性,通常持怀疑态度,你需要时常的换位思考,更广泛的收集信息,并理智的评估自己的行为带来的可能后果。

你非常独立,我行我素,不能理解不合逻辑的事情,忽视他人的情感,并对与你风格不同的人不能理解,非常挑剔;你要学会欣赏他人的优点并及时表达出来。

你非常有主见,时常会将自己的观点和标准强加给别人,而且无视那些不自信的人的建议。在处理问题时,强求别人按照自己的想法来做,对于未经检验或非常规的方法不加考虑。若能在以后多尝试和接受新颖的、有创造性的方法,你就能做出更有效的决策。

Kubernetes天然适合微服务

三大容器平台之争尘埃落定,Kubernetes成为各家公司做微服务支撑的首选平台。Kubernetes的胜出有社区运营的原因所在,但仅仅从技术角度来讲,Kubernetes相对于其他容器平台来讲,是有微服务基因的,这也是网易云为什么从一开始就选择Kubernetes作为容器平台的原因。很多有IT架构背景的公司,站在IT运维的角度来讲,可能会选择其他容器平台,但是网易云的初创架构团队,是从事博客应用层开发的,站在应用层的角度出发,选择Kubernetes就变成自然而然的事情了。最近在反思,为什么在支撑容器平台和微服务的竞争中,Kubernetes会取得最终的胜出。因为在很多角度来讲三大容器平台从功能角度来说,最后简直是一摸一样,具体的比较可以参考本人前面的两篇文章。

经过一段时间的思索,并采访了从早期就开始实践Kubernetes的网易云架构师们,从而有了今天的分享。一、从企业上云的三大架构看容器平台的三种视角

一切都从企业上云的三大架构开始。

640

如图所示,企业上的三大架构为IT架构,应用架构和数据架构,在不同的公司,不同的人,不同的角色,关注的重点不同。
对于大部分的企业来讲,上云的诉求是从IT部门发起的,发起人往往是运维部门,他们关注计算,网络,存储,试图通过云计算服务来减轻CAPEX和OPEX。
有的公司有ToC的业务,因而累积了大量的用户数据,公司的运营需要通过这部分数据进行大数据分析和数字化运营,因而在这些企业里面往往还需要关注数据架构。
从事互联网应用的企业,往往首先关注的是应用架构,是否能够满足终端客户的需求,带给客户良好的用户体验,业务量往往会在短期内出现爆炸式的增长,因而关注高并发应用架构,并希望这个架构可以快速迭代,从而抢占风口。
在容器出现之前,这三种架构往往通过虚拟机云平台的方式解决。
当容器出现之后,容器的各种良好的特性让人眼前一亮,他的轻量级、封装、标准、易迁移、易交付的特性,使得容器技术迅速被广泛使用。

640

然而一千个人心中有一千个哈姆雷特,由于原来工作的关系,三类角色分别从自身的角度看到了容器的优势给自己带来的便捷。
对于原来在机房里面管计算、网络、存储的IT运维工程师来讲,容器更像是一种轻量级的运维模式,在他们看来,容器和虚拟机的最大的区别就是轻量级,启动速度快,他们往往引以为豪的推出虚拟机模式的容器。
对于数据架构来讲,他们每天都在执行各种各样的数据计算任务,容器相对于原来的JVM,是一种隔离性较好,资源利用率高的任务执行模式。
从应用架构的角度出发,容器是微服务的交付形式,容器不仅仅是做部署的,而是做交付的,CI/CD中的D的。
所以这三种视角的人,在使用容器和选择容器平台时方法会不一样。二、Kubernetes才是微服务和DevOps的桥梁

640

Swarm:IT运维工程师

640

从IT运维工程师的角度来看:容器主要是轻量级、启动快。而且自动重启,自动关联。弹性伸缩的技术,使得IT运维工程师似乎不用再加班。
Swarm的设计显然更加符合传统IT工程师的管理模式。
他们希望能够清晰地看到容器在不同机器的分布和状态,可以根据需要很方便地SSH到一个容器里面去查看情况。
容器最好能够原地重启,而非随机调度一个新的容器,这样原来在容器里面安装的一切都是有的。
可以很方便的将某个运行的容器打一个镜像,而非从Dockerfile开始,这样以后启动就可以复用在这个容器里面手动做的100项工作。
容器平台的集成性要好,用这个平台本来是为了简化运维的,如果容器平台本身就很复杂,像Kubernetes这种本身就这么多进程,还需要考虑它的高可用和运维成本,这个不划算,一点都没有比原来省事,而且成本还提高了。
最好薄薄得一层,像一个云管理平台一样,只不过更加方便做跨云管理,毕竟容器镜像很容易跨云迁移。
Swarm的使用方式比较让IT工程师以熟悉的味道,其实OpenStack所做的事情它都能做,速度还快。

640

Swarm的问题
然而容器作为轻量级虚拟机,暴露出去给客户使用,无论是外部客户,还是公司内的开发,而非IT人员自己使用的时候,他们以为和虚拟机一样,但是发现了不一样的部分,就会很多的抱怨。
例如自修复功能,重启之后,原来SSH进去手动安装的软件不见了,甚至放在硬盘上的文件也不见了,而且应用没有放在Entrypoint里面自动启动,自修复之后进程没有跑起来,还需要手动进去启动进程,客户会抱怨你这个自修复功能有啥用?
例如有的用户会ps一下,发现有个进程他不认识,于是直接kill掉了,结果是Entrypoint的进程,整个容器直接就挂了,客户抱怨你们的容器太不稳定,老是挂。
容器自动调度的时候,IP是不保持的,所以往往重启原来的IP就没了,很多用户会提需求,这个能不能保持啊,原来配置文件里面都配置的这个IP的,挂了重启就变了,这个怎么用啊,还不如用虚拟机,至少没那么容易挂。
容器的系统盘,也即操作系统的那个盘往往大小是固定的,虽然前期可以配置,后期很难改变,而且没办法每个用户可以选择系统盘的大小。有的用户会抱怨,我们原来本来就很多东西直接放在系统盘的,这个都不能调整,叫什么云计算的弹性啊。
如果给客户说容器挂载数据盘,容器都启动起来了,有的客户想像云主机一样,再挂载一个盘,容器比较难做到,也会被客户骂。
如果容器的使用者不知道他们在用容器,当虚拟机来用,他们会觉得很难用,这个平台一点都不好。
Swarm上手虽然相对比较容易,但是当出现问题的时候,作为运维容器平台的人,会发现问题比较难解决。
Swarm内置的功能太多,都耦合在了一起,一旦出现错误,不容易debug。如果当前的功能不能满足需求,很难定制化。很多功能都是耦合在Manager里面的,对Manager的操作和重启影响面太大。
Mesos:数据运维工程师

640

从大数据平台运维的角度来讲,如何更快的调度大数据处理任务,在有限的时间和空间里面,更快的跑更多的任务,是一个非常重要的要素。
所以当我们评估大数据平台牛不牛的时候,往往以单位时间内跑的任务数目以及能够处理的数据量来衡量。
从数据运维的角度来讲,Mesos是一个很好的调度器,既然能够跑任务,也就能够跑容器,Spark和Mesos天然的集成,有了容器之后,可以用更加细粒度的任务执行方式。
在没有细粒度的任务调度之前,任务的执行过程是这样的。任务的执行需要Master的节点来管理整个任务的执行过程,需要Worker节点来执行一个个子任务。在整个总任务的一开始,就分配好Master和所有的Work所占用的资源,将环境配置好,等在那里执行子任务,没有子任务执行的时候,这个环境的资源都是预留在那里的,显然不是每个Work总是全部跑满的,存在很多的资源浪费。
在细粒度的模式下,在整个总任务开始的时候,只会为Master分配好资源,不给Worker分配任何的资源,当需要执行一个子任务的时候,Master才临时向Mesos申请资源,环境没有准备好怎么办?好在有Docker,启动一个Docker,环境就都有了,在里面跑子任务。在没有任务的时候,所有的节点上的资源都是可被其他任务使用的,大大提升了资源利用效率。
这是Mesos的最大的优势,在Mesos的论文中,最重要阐述的就是资源利用率的提升,而Mesos的双层调度算法是核心。
原来大数据运维工程师出身的,会比较容易选择Mesos作为容器管理平台。只不过原来是跑短任务,加上marathon就能跑长任务。但是后来Spark将细粒度的模式deprecated掉了,因为效率还是比较差。
Mesos的问题

640

调度在大数据领域是核心中的核心,在容器平台中是重要的,但是不是全部。所以容器还需要编排,需要各种外围组件,让容器跑起来运行长任务,并且相互访问。Marathon只是万里长征的第一步。
所以早期用Marathon + Mesos的厂商,多是裸用Marathon和Mesos的,由于周边不全,因而要做各种的封装,各家不同。大家有兴趣可以到社区上去看裸用Marathon和Mesos的厂商,各有各的负载均衡方案,各有各的服务发现方案。
所以后来有了DCOS,也就是在Marathon和Mesos之外,加了大量的周边组件,补充一个容器平台应有的功能,但是很可惜,很多厂商都自己定制过了,还是裸用Marathon和Mesos的比较多。
而且Mesos虽然调度牛,但是只解决一部分调度,另一部分靠用户自己写framework以及里面的调度,有时候还需要开发Executor,这个开发起来还是很复杂的,学习成本也比较高。
虽然后来的DCOS功能也比较全了,但是感觉没有如Kubernetes一样使用统一的语言,而是采取大杂烩的方式。在DCOS的整个生态中,Marathon是Scala写的,Mesos是C++写的,Admin Router是Nginx+lua,Mesos-DNS是Go,Marathon-lb是Python,Minuteman是Erlang,这样太复杂了吧,林林总总,出现了Bug的话,比较难自己修复。
Kubernetes

640

而Kubernetes不同,初看Kubernetes的人觉得他是个奇葩所在,容器还没创建出来,概念先来一大堆,文档先读一大把,编排文件也复杂,组件也多,让很多人望而却步。我就想创建一个容器玩玩,怎么这么多的前置条件。如果你将Kubernetes的概念放在界面上,让客户去创建容器,一定会被客户骂。
在开发人员角度,使用Kubernetes绝对不是像使用虚拟机一样,开发除了写代码,做构建,做测试,还需要知道自己的应用是跑在容器上的,而不是当甩手掌柜。开发人员需要知道,容器是和原来的部署方式不一样的存在,你需要区分有状态和无状态,容器挂了起来,就会按照镜像还原了。开发人员需要写Dockerfile,需要关心环境的交付,需要了解太多原来不了解的东西。实话实说,一点都不方便。
在运维人员角度,使用Kubernetes也绝对不是像运维虚拟机一样,我交付出来了环境,应用之间互相怎么调用,我才不管,我就管网络通不通。在运维眼中做了过多他不该关心的事情,例如服务的发现,配置中心,熔断降级,这都应该是代码层面关心的事情,应该是Spring Cloud和Dubbo关心的事情,为什么要到容器平台层来关心这个。
Kubernetes + Docker,却是Dev和Ops融合的一个桥梁。
Docker是微服务的交付工具,微服务之后,服务太多了,单靠运维根本管不过来,而且很容易出错,这就需要研发开始关心环境交付这件事情。例如配置改了什么,创建了哪些目录,如何配置权限,只有开发最清楚,这些信息一方面很难通过文档的方式,又及时又准确的同步到运维部门来,就算是同步过来了,运维部门的维护量也非常的大。
所以,有了容器,最大的改变是环境交付的提前,是每个开发多花5%的时间,去换取运维200%的劳动,并且提高稳定性。
而另一方面,本来运维只管交付资源,给你个虚拟机,虚拟机里面的应用如何相互访问我不管,你们爱咋地咋地,有了Kubernetes以后,运维层要关注服务发现,配置中心,熔断降级。
两者融合在了一起。在微服务化的研发的角度来讲,Kubernetes虽然复杂,但是设计的都是有道理的,符合微服务的思想。
三、微服务化的十个设计要点

640

微服务有哪些要点呢?第一张图是Spring Cloud的整个生态。

640

第二张图是微服务的12要素以及在网易云的实践。

640

第三张图是构建一个高并发的微服务,需要考虑的所有的点。

640

接下来细说微服务的设计要点。
设计要点一:API网关

640

在实施微服务的过程中,不免要面临服务的聚合与拆分,当后端服务的拆分相对比较频繁的时候,作为手机App来讲,往往需要一个统一的入口,将不同的请求路由到不同的服务,无论后面如何拆分与聚合,对于手机端来讲都是透明的。
有了API网关以后,简单的数据聚合可以在网关层完成,这样就不用在手机App端完成,从而手机App耗电量较小,用户体验较好。
有了统一的API网关,还可以进行统一的认证和鉴权,尽管服务之间的相互调用比较复杂,接口也会比较多,API网关往往只暴露必须的对外接口,并且对接口进行统一的认证和鉴权,使得内部的服务相互访问的时候,不用再进行认证和鉴权,效率会比较高。
有了统一的API网关,可以在这一层设定一定的策略,进行A/B测试,蓝绿发布,预发环境导流等等。API网关往往是无状态的,可以横向扩展,从而不会成为性能瓶颈。
设计要点二:无状态化,区分有状态的和无状态的应用

640

影响应用迁移和横向扩展的重要因素就是应用的状态,无状态服务,是要把这个状态往外移,将Session数据,文件数据,结构化数据保存在后端统一的存储中,从而应用仅仅包含商务逻辑。
状态是不可避免的,例如ZooKeeper、DB、Cache等,把这些所有有状态的东西收敛在一个非常集中的集群里面。
整个业务就分两部分,一个是无状态的部分,一个是有状态的部分。
无状态的部分能实现两点,一是跨机房随意地部署,也即迁移性,一是弹性伸缩,很容易的进行扩容。
有状态的部分,如DB、Cache、ZooKeeper有自己的高可用机制,要利用到他们自己的高可用的机制来实现这个状态的集群。
虽说无状态化,但是当前处理的数据,还是会在内存里面的,当前的进程挂掉数据,肯定也是有一部分丢失的,为了实现这一点,服务要有重试的机制,接口要有幂等的机制,通过服务发现机制,重新调用一次后端的服务的另一个实例就可以了。
设计要点三:数据库的横向扩展

640

数据库是保存状态,最重要的也是最容易出现瓶颈的。有了分布式数据库可以使得数据库的性能可以随着节点的增加线性的增加。
分布式数据库最最下面是RDS,是主备的,通过MySQL的内核开发能力,我们能够实现主备切换数据零丢失,所以数据落在这个RDS里面,是非常放心的,哪怕是挂了一个节点,切换完了以后,你的数据也是不会丢的。
再往上就是横向怎么承载大的吞吐量的问题,上面有一个的负载均衡NLB,用LVS、HAProxy、Keepalived,下面接了一层Query Server。Query Server是可以根据监控的数据进行横向的扩展的,如果出现了故障,可以随时进行替换的修复的,对于业务层是没有任何感知的。
另外一个就是双机房的部署,DDB这面开发了一个数据运河NDC的组件,可以使得不同的DDB之间在不同的机房里面进行同步,这时候不但在一个数据中心里面是分布式的,在多个数据中心里面也会有一个类似双活的一个备份,高可用性有非常好的保证。
设计要点四:缓存、缓存

640

在高并发场景下缓存是非常重要的。要有层次的缓存,使得数据尽量靠近用户。数据越靠近用户能承载的并发量也越大,响应时间越小。
在手机客户端App上就应该有一层缓存,不是所有的数据都每时每刻都从后端拿,而是只拿重要的,关键的,时常变化的数据。
尤其是对于静态数据,可以过一段时间去取一次,而且也没必要到数据中心去取,可以通过CDN,将数据缓存在距离客户端最近的节点上,进行就近的下载。
有的时候CDN里面没有,还是要回到数据中心去下载,称为回源,在数据中心的最外层,我们称为接入层,可以设置一层缓存,将大部分的请求拦截,从而不会对后台的数据库造成压力。
如果是动态数据,还是需要访问应用,通过应用中的商务逻辑生成,或者去数据库中读取,为了减轻数据库的压力,应用可以使用本地的缓存,也可以使用分布式缓存,如Memcached或者Redis,使得大部分的请求读取缓存即可,不必访问数据库。
当然动态数据还可以做一定的静态化,也即降级成静态数据,从而减少后端的压力。
设计要点五式:服务拆分和服务发现

640

当系统扛不住,应用变化快的时候,往往要考虑将比较大的服务拆分为一系列小的服务。
这样首先的好处就是开发比较独立,当非常多的人在维护同一个代码仓库的时候,往往对代码的修改就会相互影响,常常会出现,我没改什么测试就不通过了,而且代码提交的时候,经常会出现冲突,需要进行代码合并,大大降低了开发的效率。
另外一个好处就是上线独立,物流模块对接了一家新的快递公司,需要连同下单一起上线,这是非常不合理的行为,我没改还要我重启,我没改还让我发布,我没改还要我开会,都是应该拆分的时机。
另外再就是高并发时段的扩容,往往只有最关键的下单和支付流程是核心,只要将关键的交易链路进行扩容即可,如果这时候附带很多其他的服务,扩容即使不经济的,也是很有风险的。
再就是容灾和降级,在大促的时候,可能需要牺牲一部分的边角功能,但是如果所有的代码耦合在一起,很难将边角的部分功能进行降级。
当然拆分完毕以后,应用之间的关系就更加复杂了,因而需要服务发现的机制,来管理应用相互的关系,实现自动的修复,自动的关联,自动的负载均衡,自动的容错切换。
设计要点六:服务编排与弹性伸缩

640

当服务拆分了,进程就会非常的多,因而需要服务编排,来管理服务之间的依赖关系,以及将服务的部署代码化,也就是我们常说的基础设施即代码。这样对于服务的发布、更新、回滚、扩容、缩容,都可以通过修改编排文件来实现,从而增加了可追溯性,易管理性,和自动化的能力。
既然编排文件也可以用代码仓库进行管理,就可以实现一百个服务中,更新其中五个服务,只要修改编排文件中的五个服务的配置就可以,当编排文件提交的时候,代码仓库自动触发自动部署升级脚本,从而更新线上的环境,当发现新的环境有问题的时候,当然希望将这五个服务原子性的回滚,如果没有编排文件,需要人工记录这次升级了哪五个服务。有了编排文件,只要在代码仓库里面revert,就回滚到上一个版本了。所有的操作在代码仓库里面都是可以看到的。
设计要点七:统一配置中心

640

服务拆分以后,服务的数量非常的多,如果所有的配置都以配置文件的方式,放在应用本地的话,非常难以管理,可以想象当有几百上千个进程中,有一个配置出现了问题,你很难将它找出来,因而需要有统一的配置中心,来管理所有的配置,进行统一的配置下发。
在微服务中,配置往往分为几类,一类是几乎不变的配置,这种配置可以直接打在容器镜像里面,第二类是启动时就会确定的配置,这种配置往往通过环境变量,在容器启动的时候传进去,第三类就是统一的配置,需要通过配置中心进行下发,例如在大促的情况下,有些功能需要降级,哪些功能可以降级,哪些功能不能降级,都可以在配置文件中统一的配置。
设计要点八:统一的日志中心

640

同样是进程数目非常多的时候,很难对成千上百个容器,一个一个登录进去查看日志,所以需要统一的日志中心来收集日志,为了使收集到的日志容易分析,对于日志的规范,需要有一定的要求,当所有的服务都遵守统一的日志规范的时候,在日志中心就可以对一个交易流程进行统一的追溯。例如在最后的日志搜索引擎中,搜索交易号,就能够看到在哪个过程出现了错误或者异常。
设计要点九:熔断、限流、降级

640

服务要有熔断,限流,降级的能力,当一个服务调用另外一个服务,出现超时的时候,应及时的返回,而非阻塞在那个地方,从而影响其他用户的交易,可以返回默认的托底数据。
当一个服务发现被调用的服务,因为过于繁忙,线程池满,连接池满,或者总是出错,则应该及时熔断,防止因为下一个服务的错误或繁忙,导致本服务的不正常,从而逐渐往前传导,导致整个应用的雪崩。
当发现整个系统的确负载过高的时候,可以选择降级某些功能或某些调用,保证最重要的交易流程的通过,以及最重要的资源全部用于保证最核心的流程。
还有一种手段就是限流,当既设置了熔断策略,也设置了降级策略,通过全链路的压力测试,应该能够知道整个系统的支撑能力,因而就需要制定限流策略,保证系统在测试过的支撑能力范围内进行服务,超出支撑能力范围的,可拒绝服务。当你下单的时候,系统弹出对话框说“系统忙,请重试”,并不代表系统挂了,而是说明系统是正常工作的,只不过限流策略起到了作用。
设计要点十:全方位的监控

640

当系统非常复杂的时候,要有统一的监控,主要两个方面,一个是是否健康,一个是性能瓶颈在哪里。当系统出现异常的时候,监控系统可以配合告警系统,及时的发现,通知,干预,从而保障系统的顺利运行。
当压力测试的时候,往往会遭遇瓶颈,也需要有全方位的监控来找出瓶颈点,同时能够保留现场,从而可以追溯和分析,进行全方位的优化。四、Kubernetes本身就是微服务架构

640

基于上面这十个设计要点,我们再回来看Kubernetes,会发现越看越顺眼。
首先Kubernetes本身就是微服务的架构,虽然看起来复杂,但是容易定制化,容易横向扩展。

640

如图黑色的部分是Kubernetes原生的部分,而蓝色的部分是网易云为了支撑大规模高并发应用而定制化的部分。

640

Kubernetes的API Server更像网关,提供统一的鉴权和访问接口。
众所周知,Kubernetes的租户管理相对比较弱,尤其是对于公有云场景,复杂的租户关系的管理,我们只要定制化API Server,对接Keystone,就可以管理复杂的租户关系,而不用管其他的组件。

640

在Kubernetes中几乎所有的组件都是无状态化的,状态都保存在统一的etcd里面,这使得扩展性非常好,组件之间异步完成自己的任务,将结果放在etcd里面,互相不耦合。
例如图中Pod的创建过程,客户端的创建仅仅是在etcd中生成一个记录,而其他的组件监听到这个事件后,也相应异步的做自己的事情,并将处理的结果同样放在etcd中,同样并不是哪一个组件远程调用kubelet,命令他进行容器的创建,而是发现etcd中,Pod被绑定到了自己这里,方才拉起。
为了在公有云中实现租户的隔离性,我们的策略是不同的租户,不共享节点,这就需要Kubernetes对于IaaS层有所感知,因而需要实现自己的Controller,Kubernetes的设计使得我们可以独立创建自己的Controller,而不是直接改代码。

640

API-Server作为接入层,是有自己的缓存机制的,防止所有的请求的压力直接到后端的数据库上。但是当仍然无法承载高并发请求的时候,瓶颈依然在后端的etcd存储上,这和电商应用一摸一样。当然能够想到的方式也是对etcd进行分库分表,不同的租户保存在不同的etcd集群中。

640

有了API Server做API网关,后端的服务进行定制化,对于client和kubelet是透明的。
如图是定制化的容器创建流程,由于大促和非大促期间,节点的数目相差比较大,因而不能采用事先全部创建好节点的方式,这样会造成资源的浪费,因而中间添加了网易云自己的模块Controller和IaaS的管理层,使得当创建容器资源不足的时候,动态调用IaaS的接口,动态的创建资源。这一切对于客户端和kubelet无感知。

640

为了解决超过3万个节点的规模问题,网易云需要对各个模块进行优化,由于每个子模块仅仅完成自己的功能,Scheduler只管调度,Proxy只管转发,而非耦合在一起,因而每个组件都可以进行独立的优化,这符合微服务中的独立功能,独立优化,互不影响。而且Kubernetes的所有组件的都是Go开发的,更加容易一些。所以Kubernetes上手慢,但是一旦需要定制化,会发现更加容易。五、Kubernetes更加适合微服务和DevOps的设计

640

好了,说了Kubernetes本身,接下来说说Kubernetes的理念设计,为什么这么适合微服务。

640

前面微服务设计的十大模式,其中一个就是区分无状态和有状态,在Kubernetes中,无状态对应deployment,有状态对应StatefulSet。
deployment主要通过副本数,解决横向扩展的问题。
而StatefulSet通过一致的网络ID,一致的存储,顺序的升级,扩展,回滚等机制,可以保证有状态应用,很好地利用自己的高可用机制。因为大多数集群的高可用机制,都是可以容忍一个节点暂时挂掉的,但是不能容忍大多数节点同时挂掉。而且高可用机制虽然可以保证一个节点挂掉后回来,有一定的修复机制,但是需要知道刚才挂掉的到底是哪个节点,StatefulSet的机制可以让容器里面的脚本有足够的信息,处理这些情况,实现哪怕是有状态,也能尽快修复。

640

在微服务中,比较推荐使用云平台的PaaS,例如数据库,消息总线,缓存等。但是配置也是非常复杂的,因为不同的环境需要连接不同的PaaS服务。
Kubernetes里面的headless service是可以很好的解决这个问题的,只要给外部的服务创建一个headless service,指向相应的PaaS服务,并且将服务名配置到应用中。由于生产和测试环境分成Namespace,虽然配置了相同的服务名,但是不会错误访问,简化了配置。

640

微服务少不了服务发现,除了应用层可以使用Spring Cloud或者Dubbo进行服务发现,在容器平台层当然是用Service了,可以实现负载均衡,自修复,自动关联。

640

服务编排,本来Kubernetes就是编排的标准,可以将yml文件放到代码仓库中进行管理,而通过deployment的副本数,可以实现弹性伸缩。

640

对于配置中心,Kubernetes提供了configMap,可以在容器启动的时候,将配置注入到环境变量或者Volume里面。但是唯一的缺点是,注入到环境变量中的配置不能动态改变了,好在Volume里面的可以,只要容器中的进程有reload机制,就可以实现配置的动态下发了。

640

统一日志和监控往往需要在Node上部署Agent,来对日志和指标进行收集,当然每个Node上都有,daemonset的设计,使得更容易实现。

640

当然目前最最火的Service Mesh,可以实现更加精细化的服务治理,进行熔断,路由,降级等策略。Service Mesh的实现往往通过sidecar的方式,拦截服务的流量,进行治理。这也得力于Pod的理念,一个Pod可以有多个容器,如果当初的设计没有Pod,直接启动的就是容器,会非常的不方便。
所以Kubernetes的各种设计,看起来非常的冗余和复杂,入门门槛比较高,但是一旦想实现真正的微服务,Kubernetes是可以给你各种可能的组合方式的。实践过微服务的人,往往会对这一点深有体会。六、Kubernetes的常见的使用方式

640

下面我们来看一下,微服务化的不同阶段,Kubernetes的使用方式。
第一阶段:使用公有云虚拟机
也即没有微服务化的阶段,基本上一个进程就能搞定,两个进程做高可用,不需要使用容器,虚拟机就非常好。
第二阶段:容器作为持续集成工具

640

当微服务开始拆分了,如何保证拆分后功能的一致性,需要持续集成作为保证,如前面的论述,容器是非常好的持续集成工具,是解决CI/CD中D的,所以一开始用host网络就可以,这样可以保证部署方式和原来兼容。

640

如果想用私有云进行部署,直接部署在物理机上,在性能要求没有很高,但是又要和其他物理机很好的通信的情况下,可以用bridge打平网络的方式比较好。通过创建网桥,将物理网卡,容器网卡都连接到一个网桥上,可以实现所有的容器和物理机在同样的一个二层网络里面。

640

如果性能要求比较高,例如要部署类似缓存,则可以使用sr-iov网卡。

640

如果想实现租户的简单隔离,则往往使用各种Overlay的网络模式,这是最常用的部署方式。图中的数据来自网络。Flannel、Calico都是非常好的网络插件,虽然Flannel一开始使用用户态的模式性能不好,后来使用内核态,性能大大改善,使用gw模式后,和Calico性能相当。

640

网易云采用了Kubernetes和IaaS深度融合的方式,类似AWS的Fargate的模式,一方面可以使得原来使用虚拟机的用户平滑地迁移到容器,另一方面可以实现公有云的租户隔离。

640

如图是融合的网易云容器服务的架构,这个管理OpenStack和Kubernetes的管理平台,也是用的微服务架构,有API网关,熔断限流功能,拆分成不同的服务,部署在Kubernetes上的,所以处处是微服务。

针对小型团队能力提升方案

以下以搬凳子为案例进行讲解

一、愿景

1、概述:描述整个愿景及目标

晚会要求,需要1万张凳子搬到万人坑,并做好排列,按班级分配,需在1月15日至1月16号完成,此由社联宣传部门完成;

2、方向:建设方向和长远目标

团队成长和熟悉合作流程;

二、前置条件

1、组织机构:当前组织情况

社联宣传部,负责社联的宣传对外工作;

2、人力资源:当前人员配置

宣传部长1名(有一定的管理经验,入会2年)、

宣传副部长1名(有一定的管理经验,但办事拖拉)、

理事4名(无经验,入会3个月)

3、团队情况:团队内部情况,找出缺陷,进行补救,以配合目标建议

暂时无成功共事经验,理事成员对事不上心,副部能力跟不上,凝聚力不足

4、团队建设:

内部讨论(形成统一意识)

人员培训(经验交流,外部人员培训等,定期培训,坚定意识统一)

试点合作(尝试可控项目的试点管理,进行团队磨合)

4、成本管理:资源及资本情况

经费预算1万,其实包括团队建设费用2千,奖励奖金2千,其它计划支持6千;

三、计划

1、前期计划

团队磨合,风险评估

2、中期计划

正式计划执行,项目落地,过程梳理和学习

3、后期计划

团队总结和能力提升,任务交换等

四、方案

1、前期方案

组织合作培训,尝试团队磨合,增加讨论风气;

组织一次聚餐(或者小活动),进一步整合团队,加强磨合;

2、中期方案

部长联系搬运人员,并与搬家公司联系,建议反馈机制及基本执行条件;

副部跟进搬家公司沟通情况,并做好理事工作分工,做好安排有,向部长江报;

理事按副部的计划进行执行,并向副部汇报,如有紧急情况,向部长汇报;

3、后期方案

项目总结;

五、风险

1、人员资源风险

过程人员请假或者无法坚持,根据前期表现,适当增加人员,如找兼职;

2、资源偏差值风险

节点过程与计划偏差,做好预计值评估,如有异常,及时与组办方沟通;

3、人为风险

过程破坏,或者刻意破坏的情况,沟通不顺利及不愿意执行,由部长进行深入沟通,了解具体原因,解决困难;

4、费用风险

根据情况适当调整活动及资源调配,如培训邀请一般专家即可

5、不可控风险

具体情况,具体分配

五、持久

1、岗位交接

暂无;

2、流程梳理

暂无;

3、过程管理

暂无;

4、人员培养

暂无;

5、团队培养

暂无;