0%

K8s学习笔记——Pod使用进阶

学习极客时间上的《深入剖析Kubernetes》

秉持眼过千遍不如手过一遍的原则。动手实践并记录结果

对应章节:15 | 深入解析Pod对象(二):使用进阶

Project Volume

Project Volume(投射数据卷)是为Pod提供事先定义好的一些数据,包括4种:

  1. Secret
  2. ConfigMap
  3. Downward API
  4. ServiceAccountToken

Secret

  1. 以文件形式创建secret
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 先创建两个文件,username.txt和password.txt
$ cat username.txt
secuser
$ cat password.txt
secPassword
$ kubectl create secret generic user --from-file=./username.txt
secret/user created
$ kubectl create secret generic pass --from-file=./password.txt
secret/pass created
$ kubectl get secret
NAME TYPE DATA AGE
default-token-nlz8h kubernetes.io/service-account-token 3 36d
pass Opaque 1 6s
user Opaque 1 38s
# 可以看到default-token-nlz8h,实际上是k8s的默认token
  1. Pod
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: v1
kind: Pod
metadata:
name: test-pv-secret
spec:
containers:
- name: test-secret
image: busybox
imagePullPolicy: Never
stdin: true
tty: true
volumeMounts:
- name: sec-test
mountPath: "/pv"
readOnly: true
volumes:
- name: sec-test
projected:
sources:
- secret:
name: user
- secret:
name: pass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ kubectl describe pod test-pv-secret
Name: test-pv-secret
...
Volumes:
sec-test:
Type: Projected (a volume that contains injected data from multiple sources)
SecretName: user
SecretOptionalName: <nil>
SecretName: pass
SecretOptionalName: <nil>
default-token-nlz8h:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-nlz8h
Optional: false
...

可以看到,pod的Volumes中有两个:

  • sec-test,即为yaml文件中的volume
  • default-token-nlz8h,k8s默认的token
  1. 容器层面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ docker inspect a77ad18a7a2a
[
{
"Id": "a77ad18a7a2aad64fba15bf1dcef8b3f2fa803aa3da3cab5def23b40a0aa5b21",
...
HostConfig": {
"Binds": [
"/var/lib/kubelet/pods/cba17e39-f12d-416b-a9d1-6390b590d754/volumes/kubernetes.io~projected/sec-test:/pv:ro",
"/var/lib/kubelet/pods/cba17e39-f12d-416b-a9d1-6390b590d754/volumes/kubernetes.io~secret/default-token-nlz8h:/var/run/secrets/kubernetes.io/serviceaccount:ro",
...
"Mounts": [
{
"Type": "bind",
"Source": "/var/lib/kubelet/pods/cba17e39-f12d-416b-a9d1-6390b590d754/volumes/kubernetes.io~projected/sec-test",
"Destination": "/pv",
"Mode": "ro",
"RW": false,
"Propagation": "rprivate"
},
...

从上面的信息可以看出,/var/lib/kubelet/pods/cba17e39-f12d-416b-a9d1-6390b590d754/volumes/kubernetes.io~projected/sec-test目录以只读方式挂载到了容器上

1
2
3
4
5
6
$ ls /var/lib/kubelet/pods/cba17e39-f12d-416b-a9d1-6390b590d754/volumes/kubernetes.io~projected/sec-test/
password.txt username.txt
$ cat /var/lib/kubelet/pods/cba17e39-f12d-416b-a9d1-6390b590d754/volumes/kubernetes.io~projected/sec-test/username.txt
secuser
$ cat /var/lib/kubelet/pods/cba17e39-f12d-416b-a9d1-6390b590d754/volumes/kubernetes.io~projected/sec-test/password.txt
secPassword
  1. 查看结果
1
2
3
4
5
6
7
$ kubectl exec test-pv-secret -- ls /pv
password.txt
username.txt
$ kubectl exec test-pv-secret -- cat /pv/username.txt
secuser
$ kubectl exec test-pv-secret -- cat /pv/password.txt
secPassword

secret对象

  1. 创建secret对象

Secret 对象要求这些数据必须是经过 Base64 转码的,以免出现明文密码的安全隐患

1
2
3
4
$ echo -n 'secuser' | base64
c2VjdXNlcg==
$ echo -n 'secPassword' | base64
c2VjUGFzc3dvcmQ=
1
2
3
4
5
6
7
8
apiVersion: v1
kind: Secret
metadata:
name: sec-obj-test
type: Opaque
data:
username: c2VjdXNlcg==
password: c2VjUGFzc3dvcmQ=
1
2
3
4
5
6
$ kubectl apply -f secret-obj.yaml
secret/sec-obj-test created
$ kubectl get secret
NAME TYPE DATA AGE
default-token-nlz8h kubernetes.io/service-account-token 3 36d
sec-obj-test Opaque 2 45s
  1. 创建pod
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: v1
kind: Pod
metadata:
name: sec-obj-test
spec:
containers:
- name: test-secobj
image: busybox
imagePullPolicy: Never
stdin: true
tty: true
volumeMounts:
- name: secobj-test
mountPath: "/pv"
readOnly: true
volumes:
- name: sec-test
projected:
sources:
- secret:
name: sec-obj-test
1
2
3
4
5
6
7
8
9
10
11
12
13
$ kubectl describe pod sec-obj-test
Name: sec-obj-test
...
Mounts:
/pv from secobj-test (ro)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-nlz8h (ro)
...
Volumes:
secobj-test:
Type: Projected (a volume that contains injected data from multiple sources)
SecretName: sec-obj-test
SecretOptionalName: <nil>
...
  1. 检查容器上的内容
1
2
3
4
5
6
7
8
9
$ kubectl exec sec-obj-test -- ls /pv
password
username
$ kubectl exec sec-obj-test -- cat /pv/username
secuser
# 注:这里没有换行
$ kubectl exec sec-obj-test -- cat /pv/password
secPassword
# 注:这里没有换行

ConfigMap

创建configMap

以如下配置文件为例

1
2
APP_NAME = "demo"
APP_PORT = 80
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ kubectl create configmap flask-config --from-file=config.py
$ kubectl describe configmaps
Name: flask-config
Namespace: default
Labels: <none>
Annotations: <none>

Data
====
config.py:
----
APP_NAME = "demo"
APP_PORT = 80

Events: <none>

创建pod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: v1
kind: Pod
metadata:
name: configmap-test
spec:
containers:
- name: configmap-test-container
image: busybox
imagePullPolicy: Never
stdin: true
tty: true
volumeMounts:
- name: flask-config
mountPath: "/flask_config"
readOnly: true
volumes:
- name: flask-config
projected:
sources:
- configMap:
name: flask-config

查看容器内的结果

1
2
3
4
5
$ kubectl exec configmap-test -- ls /flask_config
config.py
$ kubectl exec configmap-test -- cat /flask_config/config.py
APP_NAME = "demo"
APP_PORT = 80

DownwardAPI

创建pod

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: downward-api-test
labels:
arch: amd64
spec:
containers:
- name: downward-api-container
image: busybox
imagePullPolicy: Never
stdin: true
tty: true
volumeMounts:
- name: pod-label
mountPath: /pod_label
readOnly: true
volumes:
- name: pod-label
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels

说明:在volumes中声明了downwardAPI,将metadata.labels挂载到容器中的/pod_label

注:我当前的k8s环境中,downwardAPI可以不用定义在projected之下,当然也可以定义在之下

查看结果

1
2
3
4
$ kubectl exec downward-api-test -- ls /pod_label
labels
$ kubectl exec downward-api-test -- cat /pod_label/labels
arch="amd64"

尝试一个其他filed

如将metadata.labels换成metadata.namespace

1
2
$ kubectl exec downward-api-test -- cat /pod_label/labels
default

ServiceAccountToken

其实之前查看pod信息的时候已经看到了相关内容

1
2
3
4
5
6
7
8
9
10
11
12
$ kubectl describe pod xxxxxx
...
Mounts:
/pod_label from pod-label (ro)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-nlz8h (ro)
...
Volumes:
default-token-nlz8h:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-nlz8h
Optional: false
...
1
2
3
4
5
6
$ kubectl exec downward-api-test -- ls /var/run/secrets/kubernetes.io/serviceaccount
ca.crt
namespace
token
$ kubectl exec downward-api-test -- cat /var/run/secrets/kubernetes.io/serviceaccount/token
eyJhbGciOiJSUzI1NiIsImtpZCI6IlhTSnlXMUhXTlNnUmd4MlVMTzdtbm14YVdiSzNUdjk4UnVoZ3RRbUFXZGsifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tbmx6OGgiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjU1MDAxNDE1LWU5N2MtNDVmNS04ZTNlLThkMzZhNGE5ZmYxMSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.wPr9cO6ySUGV65jjA4WxheIk5mpDkim9jYNSN9hmDOOitOkKrC1qj5fg5eF_GnETUZbS7xaf7sitJgIWmNZfA9YJDMn_nY7a6TLGMMRlhRx3ZXhYg6XFheFCQkCwHLJt2FGNlBtf6WpRGBFVZK_bNbjrcxkBAE-tzz7wYFuA4L1zK3UQfZoie11F8NeEWVOliuMXlVT31GZeMG5MCsuSYk_c-S2c2eTT4ru1k74uH7W1nUi9P5O2CzQPjKHTIRcP3HSBuA1CQYxuBk8Av0eE6vQB41tYMIlpIavzljpd-_jWngPkZAUnQbislaXWZhzzKkGkGqsxsFGb0P57sX4Dyg

查看帮助

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$ kubectl explain pod.spec.volumes.projected.sources
KIND: Pod
VERSION: v1

RESOURCE: sources <[]Object>

DESCRIPTION:
list of volume projections

Projection that may be projected along with other supported volume types

FIELDS:
configMap <Object>
information about the configMap data to project

downwardAPI <Object>
information about the downwardAPI data to project

secret <Object>
information about the secret data to project

serviceAccountToken <Object>
information about the serviceAccountToken data to project

容器健康检查及恢复

创建pod

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: v1
kind: Pod
metadata:
name: liveness-test
labels:
test: liveness
spec:
containers:
- name: liveness
image: busybox
imagePullPolicy: Never
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm /tmp/healthy; sleep 600
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
1
2
3
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
liveness-test 1/1 Running 0 21s

可以看到,在21s的时候,pod的运行状态正常,RESTARTS字段为0

给他一会儿时间

查看pod详情

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$ ubectl describe pod liveness-test
Name: liveness-test
Namespace: default
Priority: 0
Node: node2/10.160.18.181
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 75s default-scheduler Successfully assigned default/liveness-test to node2
Normal Pulled 74s kubelet, node2 Container image "busybox" already present on machine
Normal Created 74s kubelet, node2 Created container liveness
Normal Started 74s kubelet, node2 Started container liveness
Warning Unhealthy 32s (x3 over 42s) kubelet, node2 Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
Normal Killing 32s kubelet, node2 Container liveness failed liveness probe, will be restarted
Warning Unhealthy 30s (x3 over 40s) kubelet, node2 Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
Normal Killing 30s kubelet, node2 Container liveness failed liveness probe, will be restarted
Normal Started 2s (x2 over 74s) kubelet, node2 Started container liveness
Normal Pulled 2s (x2 over 74s) kubelet, node2 Container image "busybox" already present on machine
Normal Created 2s (x2 over 74s) kubelet, node2 Created container liveness

当pod运行了一会儿后,/tmp/healthy被删除,随后,Container liveness failed liveness probe, will be restarted

查看pod重启状况

1
2
3
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
liveness-test 1/1 Running 5 6m19s

podPresets是一个需要开启的选项,在我当前环境中没有开启,暂不学习

小结

Pod使用进阶主要涉及了:

  1. Project Volume的4种类型
  2. 健康状况检查和恢复