对象管理
本节介绍对象的相关概念和管理机制。只有了解了这些机制,我们才能轻松的对k8s资源进行编排。
1 对象 Object
由于许多资源类型需要用作DNS子域名的名称,所以,对象命名需遵守RFC 1035定义的DNS标签标准。
2 命名空间 namespace
绝大多数的k8s对象都属于某一命名空间,但是也有一些资源(如:命名空间本身,节点,持久化卷
)不属于任何命名空间。
2.1 查看命名空间中的资源
# 查看 位于命名空间中的资源
kubectl api-resources --namespaced=true
# 查看 不在命名空间中的资源
kubectl api-resources --namespaced=false
2.2 创建命名空间
# Source: /myworkdir/myns.yaml
apiVersion: v1
kind: NameSpace
metadata:
name: myns
# 通过资源描述文件创建命名空间
kubectl create -f /myworkdir/myns.yaml
# 通过命令创建命名空间
kubectl create namespace myns
# 查看/删除命名空间
kubectl get ns
kubectl delete namespace myns
2.3 设置当前默认的命名空间
kubectl config set-context --current --namespace=<名字空间名称>
# 验证
kubectl config view --minify | grep namespace:
2.4 DNS解析
3 标签 labels
3.1 标签键:
由前缀
+名称
两段组成,用斜杠/
分割,前缀是可选的,名称是必需的。如kubernetes.io/master
。
3.2 标签值:
3.3 标签语法
# json格式
"metadata": {
"labels": {
"key1" : "value1",
"key2" : "value2"
}
}
# yaml格式
metadata:
labels:
key1: value1
key2: value2
3.4 示例:
apiVersion: v1
kind: Pod # 资源类型
metadata:
name: label-demo # 定义资源名称,在同类资源中唯一。
labels:
environment: production # 定义私有标签environment:production
app: nginx # 定义私有标签app:nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2 # 引用镜像版本。
ports:
- containerPort: 80
4 标签选择器 selector
4.1 在REST客户端 kubeclt
中使用
# 基于等值:支持'='、'=='和'!='
kubectl get pods -l environment=production,tier=frontend # 查找标签为environment=production,tier=frontend的pod。
kubectl get pods -l environment!=production,tier==frontend
# 基于集合:支持'in' 'notin'
kubectl get pods -l 'environment in (production),tier in (frontend)'
kubectl get pods -l 'environment in (production, qa)' # 查看标签environment的值在(production, qa)中的pod。
kubectl get pods -l 'environment,environment notin (frontend)'
# 混合使用
kubectl get pods -l 'partition in (customerA, customerB),environment!=qa'
4.2 在k8s对象
中引用
# 基于等值
---
"selector": { # json格式
"component" : "redis",
"type": "Cluster"
}
selector: # yaml格式
component: redis
type: Cluster
nodeSelector: # 节点选择器 spec.nodeSelector
accelerator: nvidia-tesla-p100 # 选择带有该标签的节点。
# 基于集合
---
selector:
# 集合形式,由{key,value}对组成的映射。类似于matchExpressions的In操作。
matchLabels:
component: redis
# 列表形式,支持运算符:In NotIn Exists DoesNotExist。
matchExpressions:
- { key: tier, operator: In, values: [cache] }
- { key: environment, operator: NotIn, values: [dev] }
4.3 根据标签查找
# 使用-L key查看所有具有key标签的pod。
$ kubectl get pods -Lapp -Ltier -Lrole
NAME READY STATUS RESTARTS AGE APP TIER ROLE
guestbook-fe-4nlpb 1/1 Running 0 1m guestbook frontend <none>
guestbook-redis-master-5pg3b 1/1 Running 0 1m guestbook backend master
guestbook-redis-replica-2q2yf 1/1 Running 0 1m guestbook backend replica
guestbook-redis-replica-qgazl 1/1 Running 0 1m guestbook backend replica
my-nginx-divi2 1/1 Running 0 29m nginx <none> <none>
# 指定标签键值
$ kubectl get pods -lapp=guestbook,role=replica
NAME READY STATUS RESTARTS AGE
guestbook-redis-replica-2q2yf 1/1 Running 0 3m
guestbook-redis-replica-qgazl 1/1 Running 0 3m
4.4 更新标签
# 根据"app=nginx"过滤所有的Pod,然后用打上"tier=fe"标签
$ kubectl label pods -l app=nginx tier=fe
pod/my-nginx-2035384211-j5fhi labeled
pod/my-nginx-2035384211-u2c7e labeled
# 查看刚设置了标签的Pod
$ kubectl get pods -l app=nginx -L tier # -L 表示查看所有键为tier的pod。
NAME READY STATUS RESTARTS AGE TIER
my-nginx-2035384211-j5fhi 1/1 Running 0 23m fe
my-nginx-2035384211-u2c7e 1/1 Running 0 23m fe
5 注解 annotations
标签
和注解
都是为k8s对象
附加元数据。但是,标签
可以用来选择对象
和查找
满足某些条件的对象集合。注解
附加的是非标识
元数据,不用于标识
和选择
对象。
5.1 注解语法
# json格式
"metadata": {
"annotations": {
"key1" : "value1",
"key2" : "value2"
}
# yaml格式
metadata:
annotations:
key1: value1
key2: value2
5.2 示例
apiVersion: v1
kind: Pod
metadata:
name: annotations-demo
annotations:
imageregistry: "https://hub.docker.com/" # 定义注解内容
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
6 字段选择器
# 筛选出status.phase字段值为Running的所有Pod
$ kubectl get pods --field-selector status.phase=Running
# 使用不支持的字段,选择器报错
$ kubectl get ingress --field-selector foo.bar=baz
Error from server (BadRequest): Unable to find "ingresses" that match label selector "", field selector "foo.bar=baz": "foo.bar" is not a known field selector: only "metadata.name", "metadata.namespace"
# 支持'='、'=='和'!='
$ kubectl get services --all-namespaces --field-selector metadata.namespace!=default # 筛选非defualt命名空间的svc
# 链式选择器,同标签选择器一样,可以使用逗号分隔的列表组成一个选择链。
kubectl get pods --field-selector=status.phase!=Running,spec.restartPolicy=Always
# 查看多种资源类型
kubectl get statefulsets,services --all-namespaces --field-selector metadata.namespace!=default
7 属主与附属机制
7.1 基本概念
7.2 属主引用
7.3 垃圾回收
7.4 级联删除
7.5 与标签选择器不同
Pod原理
- 工作负载Pod
1.1 Pod
结构
1.2 Infra/Pause容器
容器之间是通过命名空间
进行隔离的,为了让Pod
中的容器共享资源,就需要打破命名空间
的隔离。所以,在Pod
初始化时会首先创建一个Infra容器
,然后再将创建的应用容器
加入到Infra容器
中,这样它们就共享同一套资源了。
1.2 应用容器及回调
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
spec:
dnsPolicy: Default
containers:
- name: myapp-container
image: busybox:1.28
lifecycle:
postStart:
exec:
# command: ["/bin/sh", "-c", "do_postStart.sh"]
command: ["/bin/sh", "-c", "echo Hello postStart> /usr/share/message"]
preStop:
exec:
# command: ["/bin/sh", "-c", "do_preStop.sh"]
command: ["/bin/sh","-c","while killall -0 myapp; do sleep 1; done"]
1.3 Init容器
# Source: /myworkdir/mypod.yaml
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app.kubernetes.io/name: MyApp
spec:
# 应用容器定义
containers:
- name: myapp-container
image: busybox:1.28
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
initContainers:
# init容器定义
- name: init-myservice
image: busybox:1.28
command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
# init容器定义
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
1.4 Sidecar容器
apiVersion: apps/v1
kind: Pod
metadata:
name: myapp
labels:
app: myapp
spec:
# 应用容器定义
containers:
- name: myapp
image: alpine:latest
command: ['sh', '-c', 'echo "logging" > /opt/logs.txt']
volumeMounts:
- name: data
mountPath: /opt
# 通过initContainers字段定义Sidecar容器
initContainers:
- name: logshipper
image: alpine:latest
restartPolicy: Always # Pod整个生命周期
command: ['sh', '-c', 'tail /opt/logs.txt'] # tail命令保持进程不退出。
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
emptyDir: {}
1.5 Pod生命周期
Pod在其生命周期中所处的状态:
1.6 外部访问Pod容器的应用程序
curl -ivh -k https://${POD_IP}:${CONTAINER_PORT}/path -w %{http_code}