kubectl 的三种操作方式

kubectl 的三种操作方式

kubectl 的核心功能在于通过 API Server 操作 Kubernetes 的各种资源对象

  1. 直接命令
  2. 命令式对象配置
  3. 声明式对象配置
  1. 直接通过 kubectl 命令及相关的选项创建资源对象的方式,即为直接命令式操作
1
2
3
4
5
# 创建名为nginx-deploy的Deployment控制器资源对象
kubectl run nginx-deploy --image=nginx:1.12 --replicas=2

# 创建名为nginx-svc的Service资源对象
kubectl expose deployment/nginx --name=nginx-svc --port=80
  1. 用户也可以根据资源清单创建资源对象,即命令式对象配置文件。假设存在定义了 Deployment 对象的 nginx-deploy.yaml 文件,和定义了 Service 对象的 nginx-svc.yaml 文件。
1
kubectl create -f nginx-deploy.yaml -f nginx-svc.yaml
  1. 可以将创建交由kubectl自行确定,用户只需要声明期望的状态,即为声明式对象配置。假设存在定义了Deployment对象的nginx-deploy.yaml文件,以及定义了Service对象的nginx-svc.yaml文件
1
kubectl apply -f nginx-deploy.yaml -f nginx-svc.yaml

可以简单地理解为,kubectl replace 的执行过程,是使用新的 YAML 文件中的 API 对象,替换原有的 API 对象;而 kubectl apply,则是执行了一个对原有 API 对象的 PATCH 操作.

kube-apiserver 在响应命令式请求(比如,kubectl replace)的时候,一次只能处理一个写请求,否则会有产生冲突的可能。而对于声明式请求(比如,kubectl apply),一次能处理多个写操作,并且具备 Merge 能力。

istio

istio
是一个基于 Kubernetes 项目的微服务治理框架。它的架构非常清晰.

Istio 最根本的组件,是运行在每一个应用 Pod 里的 Envoy 容器(高性能 C++ 网络代理)。Istio 项目的核心,就是由无数个运行在应用 Pod 中的 Envoy 容器组成的服务代理网格

Istio 项目,则把这个代理服务以 sidecar 容器的方式,运行在了每一个被治理的应用 Pod 中。Pod 里的所有容器都共享同一个 Network Namespace。所以,Envoy 容器就能够通过配置 Pod 里的 iptables 规则,把整个 Pod 的进出流量接管下来。

Istio 的控制层(Control Plane)里的 Pilot 组件,就能够通过调用每个 Envoy 容器的 API,对这个 Envoy 代理进行配置,从而实现微服务治理。

假设这个 Istio 架构图左边的 Pod 是已经在运行的应用,而右边的 Pod 则是我们刚刚上线的应用的新版本。这时候,Pilot 通过调节这两 Pod 里的 Envoy 容器的配置,从而将 90% 的流量分配给旧版本的应用,将 10% 的流量分配给新版本应用,并且,还可以在后续的过程中随时调整。这样,一个典型的“灰度发布”的场景就完成了。比如,Istio 可以调节这个流量从 90%-10%,改到 80%-20%,再到 50%-50%,最后到 0%-100%,就完成了这个灰度发布的过程。

Istio 项目使用的,是 Kubernetes 中的一个非常重要的功能,叫作 Dynamic Admission Control (也叫做Initializer)。

pod.yaml

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']

注入 envoy 容器:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
- name: envoy
image: lyft/envoy:845747b88f102c0fd262ab234308e9e22f693a1
command: ["/usr/local/bin/envoy"]
...

Istio 要做的,就是编写一个用来为 Pod “自动注入” Envoy 容器的 Initializer

Initializer 要做的工作,就是把这部分 Envoy 相关的字段,自动添加到用户提交的 PodAPI 对象里。可是,用户提交的 Pod 里本来就有 containers 字段和 volumes 字段,所以 Kubernetes 在处理这样的更新请求时,就必须使用类似于 git merge 这样的操作,才能将这两部分内容合并在一起(正是声明式 API 最主要的能力。)