文章目录

对象管理

本节介绍对象的相关概念和管理机制。只有了解了这些机制,我们才能轻松的对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原理


  1. 工作负载Pod

1.1 Pod结构

k8s企业级应用系列(二):对象管理及Pod原理-LMLPHP

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生命周期

k8s企业级应用系列(二):对象管理及Pod原理-LMLPHP

Pod在其生命周期中所处的状态:

1.6 外部访问Pod容器的应用程序

curl -ivh -k https://${POD_IP}:${CONTAINER_PORT}/path -w %{http_code}
04-09 08:45