本文所实验的Pod:
configmap,Downward API,Service Account,容器健康检查,PodPreset
实例:
# cat mysql.yaml
apiVersion: v1
kind: Pod
metadata:
name: mysql
spec:
containers:
- name: mymap
image: mysql:5.7
args:
- sleep
- "86400"
volumeMounts:
- name: mycfmap
mountPath: "/etc/mysql"
volumes:
- name: mycfmap
configMap:
name: mycfmap
#cat my.cnf
a=1
b=2
#创建configmap
kubectl create configmap mycfmap --from-file=./my.cnf
使用configmap进行的挂载,mountPath所指的路径有就覆盖,没有就创建。因此,在容器中的/etc/mysql/里只有my.cnf,其余的文件都被覆盖
1 从普通文件创建
kubectl create configmap mysql-cnf --from-file=my-cnf=./my.cnf
2 从 yaml 文件创建
# ./kustomization.yaml
configMapGenerator:
- name: mysql-cnf
files:
- my-cnf=./my.cnf
kubectl apply -f ./kustomization.yaml
Pod使用
- 更新
更新 Etcd 中配置数据
apiVersion: v1
kind: Pod
metadata:
name: test-configmap
spec:
containers:
- name: test-configmap-volume
image: busybox
args:
- sleep
- "86400"
volumeMounts:
- name: mysqlcfmap
mountPath: "/etc/config" # 挂载到容器中目录,这个目录会自动创建
volumes:
- name: mysqlcfmap
configMap:
name: mycnf # 创建 configmap 对象的名称
items:
- key: my-cnf # 创建 configmap 对象时指定的 key
path: my.cnf # 容器 a 目录中的文件名
/etc/config/my.cnf # 软链接
不更新
apiVersion: v1
kind: Pod
metadata:
name: test-configmap
spec:
containers:
- name: test-configmap-volume
image: busybox
args:
- sleep
- "86400"
volumeMounts:
- name: mysqlcfmap
mountPath: "/etc/my.cnf" # 挂载到容器中目录,这个目录会自动创建
subPath: my.cnf
volumes:
- name: mysqlcfmap
configMap:
name: mycnf # 创建 configmap 对象的名称
items:
- key: my-cnf # 创建 configmap 对象时指定的 key
path: my.cnf # 容器 a 目录中的文件名
/etc/my.cnf # 普通文件
Ps:当然如果mountPath后面的路径不存在,那么就会在容器中创建该目录,要映射的文件也不会映射进去;如果存在,那么就会将原来的备份,并将文件映射到指定位置
Downward API
作用:让 Pod 里的容器能够直接获取到这个 Pod API 对象本身的信息。
实例:
apiVersion: v1
kind: Pod
metadata:
name: test-downwardapi-volume
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
spec:
containers:
- name: client-container
image: busybox
command: ["sh", "-c"]
args:
- while true; do
if [[ -e /etc/podinfo/labels ]]; then
echo -en '\n\n'; cat /etc/podinfo/labels;cat; echo -en '\n' ; cat /etc/podinfo/rourou; fi;
sleep 5;
done;
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
readOnly: false
volumes:
- name: podinfo
projected:
sources:
- downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "rourou"
fieldRef:
fieldPath: metadata.name
验证:
kubectl logs test-downwardapi-volume
得到结果:
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"
test-downwardapi-volume
Service Account
集群验证的信息位于:/vat/run/secrets/kubernetes.io/serviceaccount目录下
ca.crt
namespace
token
三个文件
容器健康检查和恢复机制
在 Kubernetes 中,你可以为 Pod 里的容器定义一个健康检查“探针”(Probe)。这样,kubelet 就会根据这个 Probe 的返回值决定这个容器的状态,而不是直接以容器进行是否运行(来自 Docker 返回的信息)作为依据。这种机制,是生产环境中保证应用健康存活的重要手段
基础实例
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness
spec:
containers:
- name: liveness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
#通过查看/tmp/healthy文件是否存在确定容器运行状态,initialDelaySeconds(容器启动后几秒后开始检查),periodSeconds(每几秒检查一次)。可以看到 RESTARTS的数字发生了变化
需要注意的是:Kubernetes 中并没有 Docker 的 Stop 语义。所以虽然是 Restart(重启),但实
际却是重新创建了容器.这个功能就是 Kubernetes 里的Pod 恢复机制,也叫 restartPolicy。它是 Pod 的 Spec 部分的一个标准字段(pod.spec.restartPolicy),默认值是 Always,即:任何时候这个容器发生了异常,它一定会被重新创建
Pod 的恢复过程,永远都是发生在当前节点上,而不会跑到别的节点上去。事实上,一旦一个 Pod 与一个节点(Node)绑定,除非这个绑定发生了变化(pod.spec.node 字段被修改),否则它永远都不会离开这个节点。这也就意味着,如果这个宿主机宕机了,这个 Pod 也不会主动迁移到其他节点上去,而如果你想让 Pod 出现在其他的可用节点上,就必须使用 Deployment 这样的“控制器”来管理
Pod
而作为用户,你还可以通过设置 restartPolicy,改变 Pod 的恢复策略。除了 Always,它还有OnFailure 和 Never 两种情况:
Always:在任何情况下,只要容器不在运行状态,就自动重启容器;
OnFailure: 只在容器 异常时才自动重启容器;
Never: 从来不重启容器。
通过TCP或HTTP监听状态
监听HTTP端口
apiVersion: v1
kind: Pod
metadata: # pod 的源数据信息,可以写多个
name: nginx-http # pod 的名字
spec:
containers:
- name: nginx # 容器的名字
image: nginx:alpine # 镜像的名字
ports:
- containerPort: 80
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 3
periodSeconds: 3
监听TCP端口
livenessProbe
tcpSocket:
port: 8080
initialDelaySeconds: 3
periodSeconds: 3
综合练习
#default.conf
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location /nginx-status {
stub_status on;
access_log off;
}
}
#挂载文件并监听
apiVersion: v1
kind: Pod
metadata: # pod 的源数据信息,可以写多个
name: nginx-status # pod 的名字
spec:
containers:
- name: nginx # 容器的名字
image: nginx:alpine # 镜像的名字
ports:
- containerPort: 80
volumeMounts:
- name: nginx
mountPath: "/etc/nginx/conf.d/default.conf"
subPath: default.conf
livenessProbe:
httpGet:
path: /nginx-status/
port: 80
initialDelaySeconds: 3
periodSeconds: 3
volumes:
- name: nginx
configMap:
name: nginx
在宿主机可以通过curl访问得到nginx-status
PodPreset
其作用在于用一个已经编写好的yaml文件填充需要的yaml文件
实例:
# dev.yaml
apiVersion: v1
kind: Pod
metadata: # pod 的源数据信息,可以写多个
name: dev # pod 的名字
labels:
disktype: ssd
spec:
containers:
- name: dev # 容器的名字
image: nginx:alpine # 镜像的名字
ports:
- containerPort: 80
#ops.yaml
apiVersion: settings.k8s.io/v1alpha1
kind: PodPreset
metadata:
name: ops
spec:
selector:
matchLabels:
disktype: ssd
volumeMounts:
- mountPath: /etc/nginx/conf.d/default.conf
name: nginx
subPath: default.conf
volumes:
- name: nginx
configMap:
name: nginx
本实验的环境: server与client均为v1.16.1版本
值的注意的是:kubenet中PodPerset默认为关闭的。因此,需要自己打开。
vim /etc/kubernetes/manifests/kube-apiserver.yaml
添加下面的行
- --runtime-config=settings.k8s.io/v1alpha1=true
修改下面的行
- --enable-admission-plugins=NodeRestriction,PodPreset