首页 > 代码库 > petset翻译
petset翻译
Terminology
通过这个文档,你将会看到一些术语,有时候他们在别的地方交叉使用,这可能会引起一些困惑。这一节的
是帮助你理清楚他们。
- Node: 一个简单的虚拟或物理机在你的一个k8s集群中
- Cluster: 一组在 single failure domain中的Node, 除非另有说明。
- Persistent Volume Claim(PVC): 一个对存储的请求, 譬如一个持久存储
- Host name: hostname附属于pod的UTS namespace,也就是pod输出的hotname
- DNS/Domain name: 使用标准方法解析集群本地域名
- Ordinality: the proprety of being “ordinal”, 占据序列中的一个位置
- Pet: 在一个Pet Set中的一个简单成员。更通俗的说法的是, 一个有状态的应用
- Peer: 一个运行服务的进程,该进程有能力和其他进程通讯
What is a Pet Set
在k8s中, 绝大部分的pod管理都是把pod抽象成微服务的一次性工作单元。 例如 Replication constrollers, 使用一个弱保证来设计的 - 对于特定的pod模板,应该有N个副本。pod会被作为无状态的单元对待, 如果其中一个pod不健康了或者需要被新版本替代了, 系统仅仅需要重新部署或者替换pod
foo.default.svc.cluster.local
|service|
/ \
| pod-asdf | | pod-zxcv |
一个Pet set, 通过对比,是一组有状态的pod,有状态的pod需要更健壮的身份概念。 在这篇文档中,把他认为是“成堆的应用( clustered applications)”
*.foo.default.svc.cluster.local
| mysql-0 | <-> | mysql-1 |
[pv 0] [pv 1]
集群应用的协调部署是出了名的难,他们需要更强壮的身份和资格概念,他们使用不透明度网络协议,而且还特别容易产生竞争条件和死锁
传统的管理员部署这些应用,是利用这些节点上稳定的,有这持久化存储和固定IP的长时间存活的实体。
Pet Set的目标是通过给一个有效的application实例指定个人身份来解耦这些依赖,不依赖底层物理基础设备( that are not anchored to the underlying physical infrastructure)。这个文档的剩余部分,我们会将这些实体定义为"Pets" Our use of this term is predated by the “Pets vs Cattle” analogy
。
Pets和Pods的关系: PetSet要求这里有0到N-1个Pets, 每一个Pets有一个确定的名称- PetSet名称-序数, 它是一个唯一的名称。 每一个Pet最多有一个Pod, 每一个Pet Sets最多有一个给定身份的Pet
When to user Pet Set?
一个Pet Set 确保任何指定时间内,有固定数目个带唯一身份标识的pets在运行。 一个Pet的身份是由以下三条因素定义的:
- 一个稳定的hostname, 在DNS中是有效的
- 一个序数索引
- 稳定的存储: 和hostanme和序数索引有关联的。
这些属性对部署有状态的应用都是有用的。 大部分有状态的应用都是成堆出现的,这就意味着他们通过依赖于存储状态的严格的资格要求进行结组。
Pet Sets对这种应用在管理过程中遇到的两个特别普遍的问题是很有帮助的:
- discovery of peers for quorum
- startup/teardown ordering
当你的应用需要一些或者全部这样的特性的时候,使用Pet Sets就够了。 把pod作为无状态的副本管理是很简单的
Pet Sets的工作场景为:
- 像Mysql或者Postgresql这种一个实例在任何时候都需要一个持久化的存储卷的数据库
- 像Zookeeper,Etcd或者Elasticsearch这些需要稳定关系的集群应用
Alpha limitations
当你使用Pet Sets开始部署应用的时候,你需要明白,这里有一些局限性
- Pet Sets是一个 alpha resource, 在k8s 1.3之前的任何release版本都是不可以用的
- 在所有的alpha/beta中,都可以使用--runtime-config选项来传递给apiserver,从而禁用, 事实上,最有可能是在被托管的k8s上禁用
- 在Pet Sets中,唯一可更新的就是replicas
- 一个给定的Pet的存储,必须由基于要求的storage class的动态存储提供者提供(pv需要自己创建),或者由管理员预先提供。需要注意的是,动态提供存储卷的功能 也是在alpha中
- 删除Pet Set不能删除任何Pet, 你必须首先手动的将Pet Set配置中Pet规模缩放到0,或者删除Pet自己
- 删除Pet Set或将Pet Set配置中Pet数量缩小,并不会删除与Pet Set关联的存储卷。首先这是为了确保安全,毕竟你的数据比那些所有和Pet Set关联的可以被自动清洗的要有价值 ( your data is more valuable than an auto purge of all related Pet Set resources)
- 删除持久性存储卷的请求将会导致一个关联的存储卷删除
- 所有的Pet Set要求一个 "governing service",或者一个负责所有Pet的网络标识服务, 而用户负责此服务
- 更新一个已经存在的Pet Set就目前而言是一个手动的过程,这需要你重新使用新版本的镜像部署一个Pet Set 或者,把Pet一个一个孤立起来,更新他们的镜像,然后把它们添加回集群
Example Pet Set
我们将会创建一个基础的Pet Set 来演示,Pets如何来指定一个唯一的、"sticky"的身份
# A headless service to create DNS records
# A headless service to create DNS records
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- port: 80
name: web
# *.nginx.default.svc.cluster.local
clusterIP: None
selector:
app: nginx
---
apiVersion: apps/v1alpha1
kind: PetSet
metadata:
name: web
spec:
serviceName: "nginx"
replicas: 2
template:
metadata:
labels:
app: nginx
annotations:
pod.alpha.kubernetes.io/initialized: "true"
spec:
terminationGracePeriodSeconds: 0
containers:
- name: nginx
image: gcr.io/google_containers/nginx-slim:0.8
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
annotations:
volume.alpha.kubernetes.io/storage-class: anything
spec:
accessModes: [ "ReadWriteOnce" ]
resources:
requests:
storage: 1Gi
把这个配置文件保存为petset.yaml,然后把它提交给负责创建Pet Set和管理Pet的k8s的集群
$ kubectl create -f petset.yaml
service "nginx" created
petset "nginx" created
Pet Identity
不论Pet是由哪一个node调度 ,pet的身份信息会一直跟随者他。我们可以查看刚刚创建的pet的身份信息
Ordinal Index
你可以通过 $(petset name)-$(ordinal index assigned by petset controller) 这样的命令查看两个pod预先设置的名称
$ kubectl get po
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 10m
web-1 1/1 Running 0 10m
Stable storage
两个pod,对应着两个持久存储卷。 这是Pet Set基于volumeTemplate字段自动创建的
$ kubectl get pv
NAME CAPACITY ACCESSMODES STATUS CLAIM REASON AGE
pvc-90234946-3717-11e6-a46e-42010af00002 1Gi RWO Bound default/www-web-0 11m
pvc-902733c2-3717-11e6-a46e-42010af00002 1Gi RWO Bound default/www-web-1 11m
Network identity
网络标示由两部分组成。第一,我们创建一个headless Service来控制我们创建Pet Set时所在的域名。这个域名通过 $(service name).$(namespace).svc.cluster.local
这样的方式来被Server管理,"cluster.local"是集群的域名
每一个Pet被创建,都会得到一个匹配的DNS子域名,使用的方法为: $(petname).$(governing service domain),governing service是由Pet Set中的serviceName字段定义的。
这里有一些选择Cluster Domain,Service name, Pet Set name, 如何影响Pets的DNS names,Pet中的pod的hostname的例子
Cluster Domain | Service (ns/name) | Pet Set (ns/name) | Pet Set Domain | Pet DNS | Pet Hostname |
---|---|---|---|---|---|
cluster.local | default/nginx | default/web | nginx.default.svc.cluster.local | web-{0..N-1}.nginx.default.svc.cluster.local | web-{0..N-1} |
cluster.local | foo/nginx | foo/web | nginx.foo.svc.cluster.local | web-{0..N-1}.nginx.foo.svc.cluster.local | web-{0..N-1} |
kube.local | foo/nginx | foo/web | nginx.foo.svc.kube.local | web-{0..N-1}.nginx.foo.svc.kube.local | web-{0..N-1} |
需要注意的是, Cluster Domain将会被设置为cluster.local除非重写了配置信息
下面让我们用一个简单的测试来校验我们的断言
$ kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx None <none> 80/TCP 12m
...
首先PetSet提供了一一稳定的hostname
$ for i in 0 1; do kubectl exec web-$i -- sh -c ‘hostname‘; done
web-0
web-1
hostname是和集群中的DNS地址相关联的
$ kubectl run -i --tty --image busybox dns-test --restart=Never /bin/sh
dns-test # nslookup web-0.nginx
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-0.nginx
Address 1: 10.180.3.5
dns-test # nslookup web-1.nginx
Server: 10.0.0.10
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
Name: web-1.nginx
Address 1: 10.180.0.9
容器里运行了一个nginx web服务器, 他默认在会寻找 /usr/share/nginx/html/index.html文件
这个目录依靠Pet Set中的PersistentVolume字段来创建,现在,让我们在该文件中写下我们的hostname
$ for i in 0 1; do
kubectl exec web-$i -- sh -c ‘echo $(hostname) > /usr/share/nginx/html/index.html‘;
done
验证每一个web服务的服务器有它自己的hostname
$ for i in 0 1; do kubectl exec -it web-$i -- curl localhost; done
web-0
web-1
现在删除Pet Set中所有的pod
$ kubectl delete po -l app=nginx
pod "web-0" deleted
pod "web-1" deleted
等执行完成后, try to retrieve the previously written hostname through the DNS name of the peer。 能匹配他们 ,是因为存储,DNS name, hostname一直跟随这Pet,不论Pet在哪里调度。
$ kubectl exec -it web-1 -- curl web-0.nginx
web-0
$ kubectl exec -it web-0 -- curl web-1.nginx
web-1
Peer discovery
一个Pet可以把它自己的表示都组合到一块
- 使用 downward api发现他的pod name
- 使用 hostname 命令来发现DNS name
- 使用 mount或者df命令发现他的存储卷(通常,这不是必须的)
发现一个Pet Set的governing Service不是必须的,因为你可以通过一个有效的环境变量把它传递下去
通常pet需要找到他自己的peer,在前面的nginx例子中, 我们仅仅使用kubectl发现已存在的pod的名称,作为人,我们可以说明哪个pod属于指定的Pet Set,
另一个发现peer的方法是通过API Service,就像使用kubectl,但是这有一些缺点(你需要在你的应用容器中运行一个k8s指定的初始化系统,该系统的pid需要为1)
Pet Set为你提供了使用DNS记录发现peer的方法。为了阐述这个方法,我们是用先前的例子( note: one usually doesn’t
apt-get
in a container)$ kubectl exec -it web-0 /bin/sh
web-0 # apt-get update && apt-get install -y dnsutils
...
web-0 # nslookup -type=srv nginx.default
Server: 10.0.0.10
Address: 10.0.0.10#53
nginx.default.svc.cluster.local service = 10 50 0 web-1.ub.default.svc.cluster.local.
nginx.default.svc.cluster.local service = 10 50 0 web-0.ub.default.svc.cluster.local.
Updating a Pet Set
你可以不能更新PetSet的任何字段除了spec.replicas。 你可以通过使用标准的kubectl更新命令更新replicas字段,比如:path和edit。 Pet Set目前不支持更新image,这在limitations那一段已经作为标注指出来了。
Scaling a Pet Set
你可以通过更新"replicas"来对Pet Set进行缩放。需要注意的是,这个控制仅仅只能:
- 从0到N-1开始,在同一时间只能创建一个Pet,在创建下一个Pet之前,会等到前一个变成Runing and Ready
- 从N-1到0,同一时间只能删除一个,删除下一个之前需要等待前一个完全停止 (past its terminationGracePeriodSeconds)
$ kubectl get po
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 30s
web-1 1/1 Running 0 36s
$ kubectl patch petset web -p ‘{"spec":{"replicas":3}}‘"web" patched
$ kubectl get po
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 40s
web-1 1/1 Running 0 46s
web-2 1/1 Running 0 8s
Deleting a Pet Set
清除一个Pet Set 需要一点手工,就像在limiitations阶段标注的一样。 你可以使用Kubectl 删除一个Pet Set,但是它不会把Pet Set中的Pod缩减到0(貌似不能通过这种方式删除Pod)
$ kubectl delete -f petset.yaml
petset "web" deleted
$ kubectl get po -l app=nginx
NAME READY STATUS RESTARTS AGE
web-0 1/1 Running 0 21h
web-1 1/1 Running 0 21h
$ kubectl delete po -l app=nginx
pod "web-0" deleted
pod "web-1" deleted
删除Pod也不会删除存储卷。 这需要管理员去删除这些存储卷。有一点可以肯定的是,你可以在删除存储卷之前有机会复制存储卷里的数据
Simply deleting the PVC after the pods have left the terminating state should trigger deletion of the backing Persistent Volumes
pod离开terminating state后,删除PVC,会引发备份持久化存储的删除
注意:一旦PVC删除,你将会失去你所有的数据, 请小心操作
$ kubectl get po -l app=nginx
$ kubectl get pvc -l app=nginx
NAME STATUS VOLUME CAPACITY ACCESSMODES AGE
www-web-0 Bound pvc-62d271cd-3822-11e6-b1b7-42010af00002 0 21h
www-web-1 Bound pvc-62d6750e-3822-11e6-b1b7-42010af00002 0 21h
$ kubectl delete pvc -l app=nginx
$ kubectl get pv
如果你想清除上述所有,那么使用:
$ grace=$(kubectl get po web-0 --template ‘{{.spec.terminationGracePeriodSeconds}}‘)
$ kubectl delete petset,po -l app=nginx
$ sleep $grace
$ kubectl delete pvc -l app=nginx
Troubleshooting
你可能注意到了在上面Pet Set的展示用都出现了annotations字段
annotations:
pod.alpha.kubernetes.io/initialized: "true"
这个字段是一个调试钩子,它会暂停所有的Pet Set的缩小,扩大(规模的变化), 如果你想在每创建或删除一个pet的时候暂停petset,在模板中把他设置成false,等每一个pet创建之后,可以验证它是否被正确的初始化,然后在pet中使用kubectl edit把它设置成true, 在任一个pet中把它设置为false , 可以暂停Pet Set. 如果你不需要它,就像上面显示的一样,把它设置为true后再创建Pet Set. 这个在调试 debugging bootstrapping race conditions的时候是非常好用的
petset翻译
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。