深入剖析kubernetes笔记

编排永远是容器云项目的灵魂所在,也是kubernetes社区持久生命力的源泉。

服务类型

IaaS 基础设施服务,Infrastucture-as-a-service
PasS 平台服务,Platform-as-a-service
SaaS 软件服务,Software-as-a-service

1645088256165.png

SaaS 是软件的开发、管理和部署都交给第三方,不需要关心技术问题,拿来即用。普通用户接触到的互联网服务几乎都是SaaS,比如:微信、钉钉、百度云盘等。

PaaS 提供软件部署平台,抽象掉了硬件和操作系统细节,可以无缝的扩展。开发者只需要关注自己的业务逻辑,不需要关注底层.比如Google APP Engine、阿里云轻量应用服务器等。

IaaS 是云服务的最底层,提供一些基础资源。它和PaaS的区别是用户需要自己控制底层,实现基础设施的使用逻辑。比如Amazon EC2、阿里云ECS等。

PaaS项目被大家接纳的主要原因,提供了应用托管的能力。主流的做法就是租用一批虚拟机,像管理物理服务器那样,用脚本或者手工的方式在机器上部署应用。

Cloud Foundry 会调用操作系统的Cgroups和Namespace机制为每个应用单独创建一个沙盒的隔离环境,然后在沙盒中启动这些应用经常。这样就实现了把多个用户的应用互不干涉的在虚拟机里批量和自动的运行起来的目的。

PaaS项目的核心能力就是所谓的容器。

Docker 项目崛起的主要原因就是在于镜像。
所谓的 Docker 镜像,其实就是一个压缩包。但是压缩包直接包含一个完整操作系统的所有文件和目录,所以这个压缩包的内容和本地开发的和测试环境用的操作系统完全一样。

Docker 镜像的精髓就是本地环境和云端环境高度一致。

但是 Docker 项目固然解决了应用打包的问题,但是并不能代替 PaaS 完成大规模部署应用的职责。

Docker 公司为什么要收购 Fig 并发布 Swarm 项目呢?
该公司主要目的还是考虑如何让开发者把应用部署在我的项目上。而 Swarm 项目的最大亮点就是完全使用 Docker 项目原版容器管理 API 来完成集群管理。
而 Fig 项目之所以受欢迎是因为第一次提出了容器编排的概念。编排主要指用户如何通过某些工具或者配置来完成一组虚拟机以及关联资源的定义、配置、创建和删除等工作,然后由云计算平台按照这些指定的逻辑来完成的过程。

Swarm 擅长跟 Docker 生态的无缝集成,而 Mesos 擅长大规模集群的调度和管理。

容器本身没有价值,有价值的是容器编排。

容器的核心功能就是通过约束和修改进程的动态表现,从而为其创造出一个“边界”。对于 Docker 等大多数 Linux 容器来说,Cgroups 技术是用来制造约束的主要手段,而 Namespace 技术是用来修改进程视图的主要方法。

在创建容器进程的时候,指定了这个进程所需要启用的一组 Namespace 参数。这样容器就只能看到当前 Namespace 所限定的资源、文件、设备、状态或者配置。而对于宿主机以及其他不相关的程序就完全看不到了。
容器只是一种特殊的进程。

隔离与限制

虚拟机和容器的对比

敏捷和高性能是容器相对于虚拟机的最大优势,也是它能够在 PaaS 这种细粒度的资源管理平台上大型起到的重要原因。不过,基于 Namespace 的隔离机制相比于虚拟化技术不足的地方就是,隔离的不彻底。

容器只是允许在宿主机上的一种特殊进程,那么多个容器之间使用的就还是一个宿主机的操作系统内核。

Pod

Pod 到底是什么,其实是一组共享了某些资源的容器。

在一个Pod中,infra容器永远是第一个被创建的容器。

状态类型的组成

  1. Pending。这个状态意味着Pod的YAML文件已经提交给了Kubenetes,API对象已经被创建并保存在ETCD中。但是目前该pod中的容器因为某些原因不能正常创建,比如调度不成功。
  2. Running。这个状态下Pod已经调度成功。所包含的容器都已经创建成功,并且至少有一个正在运行中。
  3. Succeeded。这个状态意味着Pod中所有容易都正常运行完毕,并且已经退出。主要常见于一次性的任务。
  4. Failed。这个状态下,至少有一个容器以不正常的状态退出。
  5. Unknown。这是一个异常状态,意味着Pod的状态不能持续被kubelet汇报给apiserver.很可能是主从节点之间的通信出现问题。

特殊的Volume

有这么几种特殊的Volume,存在的意义不是为了存放容器里的数据,也不是用来进行容器和宿主机之间的数据交换,而是为容器提供预先定义好的数据。主要分为以下四种类型:

  1. Secret 把pod想要访问的加密数据存放到etcd中,然后就可以通过在Pod的容器里挂载Volume的方式访问到Secret里保存的信息;
  2. ConfigMap
  3. Dowward API
  4. ServiceAccountToken
Secret

可以用来存放数据库账号密码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

apiVersion: v1
kind: Pod
metadata:
name: test-projected-volume
spec:
containers:
- name: test-secret-volume
image: busybox
args:
- sleep
- "86400"
volumeMounts:
- name: mysql-cred
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: mysql-cred
projected:
sources:
- secret:
name: user
- secret:
name: pass

注意挂载的Volume类型是projected。这里用到的数据库用户名和密码,正是以Secret对象的方式交给Kubenetes保存的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

$ cat ./username.txt
admin
$ cat ./password.txt
c1oudc0w!

$ kubectl create secret generic user --from-file=./username.txt
$ kubectl create secret generic pass --from-file=./password.txt

# 查看的话直接get secrets就行可以了
[root@uat-109 k8s]# kubectl get secrets
NAME TYPE DATA AGE
default-token-s9c4l kubernetes.io/service-account-token 3 157m
pass Opaque 1 10s
user Opaque 1 23s

除了from-file的方式还可以使用yaml的方式,比如:

1
2
3
4
5
6
7
8
9

apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
user: YWRtaW4=
pass: MWYyZDFlMmU2N2Rm

注意Secret对象爼数据必须是经过Base64转码的,以免出现明文密码的安全隐患。

1
2
3
4
$ echo -n 'admin' | base64
dG9t
$ echo -n '1f2d1e2e67df' | base64
dG9t
ConfigMap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# .properties文件的内容
$ cat example/ui.properties
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice

# 从.properties文件创建ConfigMap
$ kubectl create configmap ui-config --from-file=example/ui.properties

# 查看这个ConfigMap里保存的信息(data)
$ kubectl get configmaps ui-config -o yaml
apiVersion: v1
data:
ui.properties: |
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
kind: ConfigMap
metadata:
name: ui-config
...

pod 的恢复策略有三种模式:

  • Always 任何情况下只要容器不在运行状态就一定自动重启容器
  • OnFailure 只有在容器异常是才会自动重启容器
  • Never 从不重启容器

PodPreset 可以实现预定义好部分字段,然后对selector的对象进行自动添加。注意要先创建PodPreset,然后再创建应用Pod。

只适用于1.11以后的版本。

健康检查方式

livenessProbe 和 readinessProbe

  1. 支持http探测
  2. 执行命令command探测
  3. tcp探测端口

Deployment

Deployment是一个两层控制权。首先它通过rs的个数开连上应用的版本,然后再通过rs的属性,比如replicas的值来保证pod的副本数量。

deployment 控制 rs版本,rs 控制pod副本数。

Deployment 控制器实际操纵的是ReplicaSet对象,而不是Pod对象。实际上控制的是ReplicaSet的数目,以及每个ReplicaSet的属性。
而每一个应用的版本,对应的证书一个ReplicaSet,这个版本应用的Pod数量,则有ReplicaSet通过它自己的控制器来保证。
1b6fac0f3400e2e1e7d7fec737d824c6.jpeg

将一个集群中正在允许的多个Pod版本,交替的逐一升级的过程,就是滚动更新。

1661754735804.png

------ 本文结束 ------

版权声明

Medivh's Notes by Medivh is licensed under a Creative Commons BY-NC-ND 4.0 International License.
Medivh创作并维护的Medivh's Notes博客采用创作共用保留署名-非商业-禁止演绎4.0国际许可证
本文首发于Medivh 博客( http://www.mknight.cn ),版权所有,侵权必究。