学习极客时间上的《深入剖析Kubernetes》
秉持眼过千遍不如手过一遍的原则。动手实践并记录结果
对应章节:15 | 深入解析Pod对象(二):使用进阶
Project Volume
Project Volume(投射数据卷)是为Pod提供事先定义好的一些数据,包括4种:
Secret
ConfigMap
Downward API
ServiceAccountToken
Secret
以文件形式创建secret
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 $ 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
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 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 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对象
创建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
创建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 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使用进阶主要涉及了:
Project Volume的4种类型
健康状况检查和恢复