Pod 基础
基本概念
Pod 的实质只是一个逻辑概念, k8s 真正处理的还是 Linux 容器的 Namspace 和 Cgroup.
Pod 可以类比于操作系统
Container 则类比于应用程序
Pod 创建过程
Pod, 其实是一组共享可某些资源的容器
- 创建中间容器, infra 容器
占用资源极少, 仅用来控制 Namspace 和 Cgroup
整个Pod只有一个 ip 地址
Pod 内的容器 A B可以直接使用 localhosts 进行通信, 他们共用一份的资源
Pod 的生命周期只跟 infra 容器一致 - 其他定义的容器通过 Join Network Namespace 的方式, 与 infra 容器关联在一起
Pod 中重要字段
- NodeSelector
是一个供用户将 pod 与 node 进行绑定的字段。
这样的一个配置限定了该 pod 只能运行在 'disktype: ssd' 标签的节点上。
apiVersion: v1
kind: Pod
...
spec:
nodeSelector:
disktype: ssd
-
NodeName
用户设置时用于测试或调试,一般由调度器负责设置
-
HostAliases
定义了 Pod 的 host 文件
apiVersion: v1
kind: Pod
...
spec:
hostAliases:
‐ ip: "10.1.2.3"
hostnames:
‐ "foo.remote"
‐ "bar.remote"
...
-
ImagePullPolicy
定义镜像拉取的策略,默认是 Always(每次创建 pod 都要重新拉取一次)
Nerver/isNotPresent 不主动拉取/宿主机不存在时拉取 -
Lifecycle
定义 Container Lifecycle Hooks.
spec:
containers:
‐ name: lifecycle‐demo‐container
image: nginx
lifecycle:
postStart:
exec:
command: ["/bin/sh", "‐c", "echo Hello from the postStart handler > /usr/share/message"]
preStop:
exec:
command: ["/usr/sbin/nginx","‐s","quit"]
postStart, 在容器启动后立即执行一个指定的操作。
preStop, 在容器被杀死之前执行一个指定的操作。
容器的设计模式
- sidecar
sidecar 指的就是我们可以在一个 Pod 中,启动一个辅助容器,来完成一些独立于主进
程(主容器)之外的工作。
比如,在我们的这个应用 Pod 中,Tomcat 容器是我们要使用的主容器,而 WAR 包容器的存在,
只是为了给它提供一个 WAR 包而已。所以,我们用 Init Container 的方式优先运行 WAR 包容器,
扮演了一个 sidecar 的角色。
apiVersion: v1
kind: Pod
metadata:
name: javaweb‐2
spec:
initContainers:
‐ image: geektime/sample:v2
name: war
command: ["cp", "/sample.war", "/app"]
volumeMounts:
‐ mountPath: /app
name: app‐volume
containers:
‐ image: geektime/tomcat:7.0
name: tomcat
command: ["sh","‐c","/root/apache‐tomcat‐7.0.42‐v2/bin/start.sh"]
volumeMounts:
‐ mountPath: /root/apache‐tomcat‐7.0.42‐v2/webapps
name: app‐volume
ports:
‐ containerPort: 8080
hostPort: 8001
volumes:
‐ name: app‐volume
emptyDir: {}
Pod 进阶
Projected Volume
投射数据卷,是为容器提供预先定义好的数据。
- Secret;
- ConfigMap;
- Downward API;
- ServiceAccountToken。
Secret
它的作用,是帮你把 Pod 想要访问的加密数据,存放到 Etcd 中
典型的使用场景(存放数据库的 Credential 信息):
apiVersion: v1
kind: Pod
metadata:
name: test‐projected‐volume
spec:
containers:
‐ name: test‐secret‐volume
image: busybox
args:
‐ sleep
‐ "86400"
volumeMounts:
‐ name: mysql‐cred
mountPath: "/projected‐volume"
readOnly: true
volumes:
‐ name: mysql‐cred
projected:
sources:
‐ secret:
name: user
‐ secret:
name: pass
上面 pod 中用到的数据库的用户名、密码
正是以 Secret 对象的方式交给 Kubernetes 保存的
$ kubectl create secret generic user ‐‐from‐file=./username.txt
$ kubectl create secret generic pass ‐‐from‐file=./password.tx
也可以使用 YAML 文件的方式创建 Secret 对象
这种方式可以只保存一个 Secret 对象,包含两份 Secret 数据
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
user: YWRtaW4=
pass: MWYyZDFlMmU2N2Rm
注意01: 为了避免明文风险, Secret对象保存的数据必须是经过 Base64 转码的
$ echo ‐n 'admin' | base64
YWRtaW4=
$ echo ‐n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm
注意02: 生产环境中,还应开启 Secret 的加密插件
ConfigMap
可以从文件或者目录创建 ConfigMap, 也可以直接编写 ConfigMap 对象的 YAML 文件
# 配置文件
cat example/ui.properties
# 保存
$ kubectl create configmap ui‐config ‐‐from‐file=example/ui.properties
# 查看
$ kubectl get configmaps ui‐config ‐o yaml
Downward API
Downward API 能够获取到的信息,一定是 Pod 里的容器进程启动之前就能够确定下来的信息
volumes:
‐ name: podinfo
projected:
sources:
‐ downwardAPI:
items:
‐ path: "labels"
fieldRef:
fieldPath: metadata.labels
ServiceAccountToken
Service Account
解决 API Server 的授权问题
Service Account 对象的作用是 Kubernetes 进行权限分配的对象
比如:
Service Account A,可以只被允许对 Kubernetes API 进行 GET 操作
Service Account B,则可以有 Kubernetes API 的所有操作的权限
ServiceAccountToken
像这样的 Service Account 的授权信息和文件,实际上保存在它所绑定的一个特殊的 Secret 对象里的。这个特殊的 Secret 对象,就叫作ServiceAccountToken
k8s 为每个 pod 都提供了一个默认的服务账户
$ kubectl describe pod nginx‐deployment‐5c678cfb6d‐lg9lw
pod 健康检查与恢复机制
- 恢复机制
pod.spec.restartPolicy
- Always
- OnFailure
- Never
- 健康检查机制
livenessProbe
可定义执行命令,发起 http/tcp 请求
# http
livenessProbe:
httpGet:
path: /healthz
port: 8080
httpHeaders:
‐ name: X‐Custom‐Header
value: Awesome
initialDelaySeconds: 3
periodSeconds: 3
# tcp
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
# command
livenessProbe:
exec:
command:
‐ cat
‐ /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
PodPreset(Pod 预配置)
preset.yaml
apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: allow‐database
spec:
selector:
matchLabels:
role: frontend
env:
‐ name: DB_PORT
value: "6379"
volumeMounts:
‐ mountPath: /cache
name: cache‐volume
volumes:
‐ name: cache‐volume
emptyDir: {}
pod.yaml
pod.yaml 定义了 role: frontend 标签
会被自动添加 preset.yaml 中的内容
apiVersion: v1
kind: Pod
metadata:
name: website
labels:
app: website
role: frontend
spec:
containers:
‐ name: website
image: nginx
ports:
‐ containerPort: 80
$ kubectl create ‐f preset.yaml
$ kubectl create ‐f pod.yaml