1. K8S 资源
k8s中,所有的内容都被抽象为资源,资源实例化后,称为对象
集群资源分类:
- 名称空间级别: 只在本名称空间下可见
- 集群级别: role, 不管在什么名称空间小,均可见
- 元数据级别: HPA(可以CPU利用率平滑扩展)
1.1 工作负载 (workload)
- Pod: 最小资源,共享网络栈、存储卷等
- ReplicaSet:调度器,管理Pod的创建,通过标签的选择去控制Pod的副本数
- Deployment: 控制器,通过控制RS的创建,去创建Pod
- StatefulSet:有状态服务管理器
- DaemonSet:可在每个节点都运行一个Pod组件
- Job: 批量工作
- CronJob: 定时或轮训工作
1.2 服务发现及负载均衡
1.3 配置与存储
1.4 集群
不指定名称空间,所有节点均能访问:role
- Namespace
- Node
- Role
- ClusterRole
- RoleBinding
- ClusterRoleBinding
1.5 元数据
- HPA
- PodTemplate
- LimitRange
1.6 用法查询
1 2 3
| kubectl explain pod
kubectl explain pod.spec
|
2. Pod 生命周期

1)kubectl –> apiserver –> CRI –> kubelet 环境初始化
2)启动Pause容器: 初始化网络和数据卷
3)init C初始化。多个initC时,必须串行执行,且每个必须执行成功才向下走
4)Main C,开始运行时,启动Start命令/脚本;结束时,执行Stop命令(做哪些清理操作等)
5)Readiness 就绪检测:若干秒后,进行是否就绪的探测。只有当Readiness成功后,Pod才会显示Ready状态
6)Liveness 生存检测:探测Main C中的进程是否正常,不正常则执行重启、删除等命令
2.1 InitC 容器
即 Infra 容器,其镜像是一个用汇编写成,永远处于“pause”状态的容器,解压后大小100~200KB,运行时占用极小的资源
作用:
initC 容器可作为 Pod 中其他容器的初始化工具
出于安全考虑,将应用容器中的某些实用工具(python, awk等)单独拆开放入initC容器
应用容器的启动是并行的,而 initC 容器可阻塞应用容器的启动,直到满足一些先决条件
实例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| apiVersion: v1 kind: Pod metadata: name: test-initc labels: app: myapp spec: initContainers: - name: init-myservice image: busybox:1.28.4 command: ['sh','-c','until nslookup myservice;do echo waiting for myservice;sleep 2; done;'] - name: init-mydb image: busybox:1.28.4 command: ['sh','-c','until nslookup mydb;do echo waiting for mydb;sleep 2;done;'] containers: - name: mypod image: busybox:1.28.4 command: ['sh','-c','echo The app is running!&& sleep 3600'] --- apiVersion: v1 kind: Service metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 9001 --- apiVersion: v1 kind: Service metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 9002
|
2.2 容器探针
健康状态探针:
- ReadinessProbe: 判断容器服务是否可用,成功显示ready, 失败不触发重启
- LivenessProbe: 判断容器是否存活,如果探测到不健康,将触发重启策略。如果未配置该探针,则永远返回成功.
探针的三种实现方式:
- ExecAction: 容器内执行命令,返回码等于0则认为成功
- TCPSocketAction: 在指定端口上的容器IP地址进行TCP检查,如果端口打开,则认为成功
- HTTPGetAction: 在指定端口和路径的容器IP地址执行HTTP GET请求,状态码在 [200, 399] 表示成功
探测结果:
- success
- failed:失败,按策略处理
- unknown:诊断失败,但不会采取任何行动
2.2.1 就绪检测
检测失败,状态非Ready,但不会重启容器
spec.containers[].readinessProbe.httpGet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| apiVersion: v1 kind: Pod metadata: name: readiness-httpget-pod spec: containers: - name: readiness-httpget-container image: nginx imagePullPolicy: IfNotPresent readinessProbe: httpGet: port: 80 path: /index1.html initialDelaySeconds: 1 periodSeconds: 3
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| $ kubectl create -f readiness-probe-httpget.yaml
$ kubectl get pod NAME READY STATUS RESTARTS AGE readiness-httpget-pod 0/1 Running 0 9s
$ kubectl describe pod readiness-httpget-pod Warning Unhealthy 1s (x3 over 7s) kubelet, k8s-node01 Readiness probe failed: HTTP probe failed with statuscode: 404
$ kubectl exec readiness-httpget-pod -it -- /bin/sh
total 8 drwxr-xr-x 2 root root 40 Aug 14 00:36 . drwxr-xr-x 3 root root 18 Aug 14 00:36 .. -rw-r--r-- 1 root root 494 Aug 11 14:50 50x.html -rw-r--r-- 1 root root 612 Aug 11 14:50 index.html
$ kubectl get pod NAME READY STATUS RESTARTS AGE readiness-httpget-pod 1/1 Running 0 2m57s
|
2.2.2 存活检测
检测失败,直接重启Pod
spec.containers[].livenessProbe.exec
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| apiVersion: v1 kind: Pod metadata: name: liveness-exec-pod spec: containers: - name: liveness-exec-container image: busybox imagePullPolicy: IfNotPresent command: ["/bin/sh", "-c", "touch /tmp/abc.txt; sleep 60; rm -f /tmp/abc.txt; sleep 3600"] livenessProbe: exec: command: ["test", "-e", "/tmp/abc.txt"] initialDelaySeconds: 1 periodSeconds: 3
|
1 2 3 4 5 6 7 8 9
| $ kubectl create -f liveness-prob-exec.yaml
$ kubectl get pod -w NAME READY STATUS RESTARTS AGE liveness-exec-pod 1/1 Running 0 26s liveness-exec-pod 1/1 Running 1 2m58s liveness-exec-pod 1/1 Running 2 3m35s liveness-exec-pod 1/1 Running 3 5m15s
|
spec.containers[].livenessProbe.httpGet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| apiVersion: v1 kind: Pod metadata: name: liveness-httpget-pod spec: containers: - name: liveness-httpget image: nginx imagePullPolicy: IfNotPresent livenessProbe: httpGet: port: 80 path: /index.html initialDelaySeconds: 1 periodSeconds: 3 timeoutSeconds: 10
|
spec.containers[].livenessProbe.tcpSocket
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| apiVersion: v1 kind: Pod metadata: name: tcpsocket-pod spec: containers: - name: redis image: redis livenessProbe: tcpSocket: port: 6379 initialDelaySeconds: 5 periodSeconds: 3 timeoutSeconds: 1
|
2.3 启动 & 退出
spec.containers[].lifecycle.postStart|preStop
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| apiVersion: v1 kind: Pod metadata: name: lifecycle-demo spec: containers: - name: lifecycle-demo-container image: nginx lifecycle: postStart: exec: command: ["/bin/sh", "-c", "echo Hello postStart > /tmp/hello.txt"] preStop: exec: command: ["/usr/sbin/nginx", "-s", "quit"]
|
2.4 Pod 状态值
- Pending:Pod已被k8s系统接受,但有一个或多个镜像容器尚未创建。等待时间包括调度Pod的时间和通过网络下载镜像的时间。
- Running: Pod已经绑定到一个节点上了,Pod中的所有容器已被创建
- Succeeded: Pod中的所有容器都被成功终止,且不会再重启
- Failed: Pod中的所有容器都已终止,但至少有一个容器以非0返回值退出
- Unknown: 未知原因无法获取Pod状态,通常是因为与Pod所在主机的通信失败
3. 注入卷
Projected Volume: 不是为了存放容器里的数据,也不是用于容器和宿主机之间的数据交换,而是为了给容器提供预先定义好的数据
常见的 Projected Volume:
- Secret
- ConfigMap
- Downward API
- ServiceAccountToken
3.1 Secret
作用:把 Pod 想要访问的加密数据放入 etcd 中
类型:
内置类型 |
用法 |
Opaque |
用户定义的任意数据 |
kubernetes.io/service-account-token |
服务账号令牌 |
kubernetes.io/dockercfg |
~/.dockercfg 文件的序列化形式 |
kubernetes.io/dockerconfigjson |
~/.docker/config.json 文件的序列化形式 |
kubernetes.io/basic-auth |
用于基本身份认证的凭据 |
kubernetes.io/ssh-auth |
用于 SSH 身份认证的凭据 |
kubernetes.io/tls |
用于 TLS 客户端或者服务器端的数据 |
bootstrap.kubernetes.io/token |
启动引导令牌数据 |
3.1.1 Opaque
创建 secret:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| $ kubectl apply -f - <<EOF apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque stringData: user: root pass: "123456" EOF
$ kubectl create secret generic my-secret --from-literal=user=root --from-literal=pass=123456
|
使用 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: pod-secret-volume spec: containers: - name: secret-volume image: busybox args: - sleep - "86400" volumeMounts: - name: mysql-cred mountPath: "/projected-volume" readOnly: true volumes: - name: mysql-cred secret: secretName: mysecret items: - key: user path: cred/user - key: pass path: cred/pass
|
检查数据挂载:
1 2
| $ kubectl exec -it pod-secret-volume -- cat /projected-volume/cred/pass 123456
|
3.1.2 TLS
1 2 3 4 5 6 7 8 9 10
| apiVersion: v1 kind: Secret metadata: name: secret-tls type: kubernetes.io/tls data: tls.crt: | MIIC2DCCAcCgAwIBAgIBATANBgkqh ... tls.key: | MIIEpgIBAAKCAQEA7yn3bRHQ5FHMQ ...
|
3.2 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 25 26 27 28 29 30 31 32 33 34 35
| apiVersion: v1 kind: ConfigMap metadata: name: special-config data: special.how: very --- apiVersion: v1 kind: ConfigMap metadata: name: env-config data: log_level: INFO --- apiVersion: v1 kind: Pod metadata: name: pod-configmap spec: containers: - name: cm-container image: busybox command: ["/bin/sh", "-c", "env"] env: - name: SPECIAL_LEVEL_KEY valueFrom: configMapKeyRef: name: special-config key: special.how - name: LOG_LEVEL valueFrom: configMapKeyRef: name: env-config key: log_level restartPolicy: Never
|
3.3 DownwardAPI
作用:让 Pod 中的容器,能够直接获取该 Pod API 对象本身的信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| apiVersion: v1 kind: Pod metadata: name: downward-api-volume labels: zone: china-standard-time cluster: taos-1 rack: rack-22 annotations: version: "1.2" builder: gopher spec: containers: - name: busybox image: busybox command: ["sh", "-c"] args: - while true; do if [[ -e /etc/podinfo/labels ]]; then echo -en '\n\n'; cat /etc/podinfo/labels; fi; if [[ -e /etc/podinfo/annotations ]]; then echo -en '\n\n'; cat /etc/podinfo/annotations; fi; sleep 5; done; volumeMounts: - name: podinfo mountPath: /etc/podinfo volumes: - name: podinfo downwardAPI: items: - path: "labels" fieldRef: fieldPath: metadata.labels - path: "annotations" fieldRef: fieldPath: metadata.annotations
|
环境变量方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| apiVersion: v1 kind: Pod metadata: name: downward-api-env spec: containers: - name: busybox image: busybox command: ["/bin/sh", "-c", "env"] env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP
|
3.4 ServiceAccountToken
Service Account 是 k8s 的一种内置”服务账户“,它绑定了一个特殊的 Secret,即 ServiceAccountToken, 保存了授权信息等内容。任何在 k8s 集群上运行的应用,都必须使用 ServiceAccountToken 中的授权信息,才能合法访问 API Server.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| $ kubectl describe pod nginx Containers: nginx: ... Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-stqtv (ro) Volumes: kube-api-access-stqtv: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: <nil> DownwardAPI: true
$ kubectl exec -it nginx -- ls /run/secrets/kubernetes.io/serviceaccount ca.crt namespace token
|