运维实战 容器部分 Kubernetes存储
Posted 洛冰音
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了运维实战 容器部分 Kubernetes存储相关的知识,希望对你有一定的参考价值。
运维实战 容器部分 Kubernetes存储
CoinfigMap配置管理
在K8S
中, CoinfigMap
被用于保存配置信息.
其主要特点是以键值对方式存储
.
通过CoinfigMap
, K8S
提供了向Pod
中导入配置的方法.
这一操作结局了镜像与配置耦合度高的问题, 实现了镜像与配置的解耦, 同时也大大提高了镜像的复用性和可移植性.
通过导入配置, 镜像可以批量化的进行配置修改和迁移.
可能的应用场景
- 用于向容器内填充环境变量
- 设置容器内的命令行参数
- 作为容器内应用的配置文件存在
- 填充数据卷的配置文件
如何使用
常见的创建ConfigMap
的方式有4种
CLI
交互式创建, 即字面值方式创建- 使用文件进行创建
- 使用目录进行创建(实际就是批量文件创建)
- 通过编写
yaml
资源清单创建
分类实践及其特性
字面值方式创建
##采用CLI方式交互式填写键值对
[root@Server2 YAML]# kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2
configmap/my-config created
##查看创建的ConfigMap
[root@Server2 YAML]# kubectl get cm
NAME DATA AGE
kube-root-ca.crt 1 5h31m
my-config 2 6s
[root@Server2 YAML]# kubectl describe cm my-config
Name: my-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
key1:
----
config1
key2:
----
config2
Events: <none>
##测试完成后清理环境
[root@Server2 YAML]# kubectl delete cm my-config
configmap "my-config" deleted
使用文件创建
默认情况下, 文件的名称会成为Key
, 而文件的内容会成为对应的Value
.
##使用DNS解析文件作为导入文件
[root@Server2 YAML]# kubectl create configmap my-config-2 --from-file=/etc/resolv.conf
configmap/my-config-2 created
##查看创建的ConfigMap
[root@Server2 YAML]# kubectl get cm
NAME DATA AGE
kube-root-ca.crt 1 5h32m
my-config-2 1 5s
[root@Server2 YAML]# kubectl describe cm my-config-2
Name: my-config-2
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
resolv.conf:
----
nameserver 114.114.114.114
Events: <none>
##测试完成后清理环境
[root@Server2 YAML]# kubectl delete cm my-config-2
configmap "my-config-2" deleted
使用目录创建
##创建测试目录并导入用于测试的文件
[root@Server2 mnt]# mkdir configMap
[root@Server2 mnt]# cd configMap/
[root@Server2 configMap]# cp /etc/passwd .
[root@Server2 configMap]# cp /etc/resolv.conf .
[root@Server2 configMap]# cp /etc/hosts .
##通过目录方式创建ConfigMap
[root@Server2 configMap]# kubectl create configmap my-config-3 --from-file=/etc/configMap
##查看创建的ConfigMap
[root@Server2 configMap]# kubectl get cm
NAME DATA AGE
kube-root-ca.crt 1 5h35m
[root@Server2 configMap]# kubectl create configmap my-config-3 --from-file=/mnt/configMap
configmap/my-config-3 created
[root@Server2 configMap]# kubectl get cm
NAME DATA AGE
kube-root-ca.crt 1 5h35m
my-config-3 3 3s
[root@Server2 configMap]# kubectl describe cm my-config-3
Name: my-config-3
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
hosts:
----
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.5.250 foundation4.ilt.example.com
172.25.5.1 Server1 reg.westos.org
172.25.5.2 Server2
172.25.5.3 Server3
172.25.5.4 Server4
172.25.5.5 Server5
172.25.5.6 Server6
172.25.5.7 Server7
172.25.5.8 Server8
passwd:
----
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
polkitd:x:999:998:User for polkitd:/:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
postfix:x:89:89::/var/spool/postfix:/sbin/nologin
tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin
kubeadm:x:1000:1000::/home/kubeadm:/bin/bash
resolv.conf:
----
nameserver 114.114.114.114
Events: <none>
##测试完成后清理环境
[root@Server2 configMap]# kubectl delete cm my-config-3
configmap "my-config-3" deleted
使用资源清单创建
- 使用的
CM1.yaml
文件内容
vim CM1.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: cm1-config
data:
db_host: "172.25.0.250"
db_port: "3306"
- 创建一个简单的
ConfigMap
[root@Server2 configMap]# vim CM1.yaml
##导入资源清单
[root@Server2 configMap]# kubectl apply -f CM1.yaml
configmap/cm1-config created
##查看创建的ConfigMap
[root@Server2 configMap]# kubectl get cm
NAME DATA AGE
cm1-config 2 7s
kube-root-ca.crt 1 5h37m
[root@Server2 configMap]# kubectl describe cm cm1-config
Name: cm1-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
db_host:
----
172.25.0.250
db_port:
----
3306
Events: <none>
如何使用ConfigMap
上文有提到, ConfigMap
的用法之一就是导入Pod
中, 那么如何在Pod
中使用自然也有不同的用法了.
通过环境变量直接传递
Pod1.yaml
内容
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: pod1
image: busybox
command: ["/bin/sh", "-c", "env"]
env:
- name: key1
valueFrom:
configMapKeyRef:
name: cm1-config
key: db_host
- name: key2
valueFrom:
configMapKeyRef:
name: cm1-config
key: db_port
restartPolicy: Never
实现目的
通过使用Pod1.yaml
, 可以创建一个自主式Pod
, 名称为pod1
,并将cm1-config
中的db_host
赋给了容器内的环境变量key1
, db_port
的值赋给了key2
, 在容器运行后采用终端输出环境变量.
相当于只是传递数值而并没有直接引入变量.
- 验证效果
[root@Server2 configMap]# vim Pod1.yaml
[root@Server2 configMap]# kubectl apply -f Pod1.yaml
pod/pod1 created
[root@Server2 configMap]# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod1 0/1 ContainerCreating 0 6s
[root@Server2 configMap]# kubectl logs pod1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=pod1
SHLVL=1
HOME=/root
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
key1=172.25.0.250
KUBERNETES_PORT_443_TCP_PROTO=tcp
key2=3306
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
##进行环境清洁
[root@Server2 configMap]# kubectl delete -f Pod1.yaml
pod "pod1" deleted
env
命令的效果为打印环境变量.
上文代码框中的环境变量含有key1
和key2
, 其内容取自ConfigMap
的键.
另一种方式
当然, 也可以直接传递变量而不是赋值了.
Pod2.yaml
内容
vim pod2.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod2
spec:
containers:
- name: pod2
image: busybox
command: ["/bin/sh", "-c", "env"]
envFrom:
- configMapRef:
name: cm1-config
restartPolicy: Never
- 检查结果
[root@Server2 configMap]# vim Pod2.yaml
[root@Server2 configMap]# kubectl apply -f Pod2.yaml
pod/pod2 created
[root@Server2 configMap]# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod2 0/1 ContainerCreating 0 3s
[root@Server2 configMap]# kubectl logs pod2
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=pod2
SHLVL=1
db_port=3306
HOME=/root
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
db_host=172.25.0.250
[root@Server2 configMap]# kubectl delete -f Pod2.yaml
pod "pod2" deleted
设置命令行参数方式
- 修改过的
Pod2.yaml
内容
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: pod1
image: busybox
command: ["/bin/sh", "-c", "echo $(db_host) $(db_port)"]
envFrom:
- configMapRef:
name: cm1-config
restartPolicy: Never
不难看出, 这里是将变量的值在命令行中直接显示, 实际的实现与上面的方式并无二样.
[root@Server2 configMap]# vim Pod2.yaml
[root@Server2 configMap]# kubectl apply -f Pod2.yaml
pod/pod1 created
[root@Server2 configMap]# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod1 0/1 ContainerCreating 0 3s
[root@Server2 configMap]# kubectl logs pod1
172.25.0.250 3306
通过数据卷挂载进行使用
Pod3.yaml
内容
apiVersion: v1
kind: Pod
metadata:
name: pod3
spec:
containers:
- name: pod3
image: busybox
command: ["/bin/sh", "-c", "cat /config/db_host"]
volumeMounts:
- name: config-volume
mountPath: /config
volumes:
- name: config-volume
configMap:
name: cm1-config
restartPolicy: Never
上面的资源清单
做了以下几件事:
- 将
cm1-config
作为数据卷config-volume
- 将
config-volume
挂载到/config
下 - 在命令行中输出
/config/db_host
的内容, 实际就是读取了db_host
的值
[root@Server2 configMap]# kubectl delete -f Pod2.yaml
pod "pod1" deleted
[root@Server2 configMap]# kubectl apply -f Pod3.yaml
pod/pod3 created
[root@Server2 configMap]# kubectl get pod
NAME READY STATUS RESTARTS AGE
pod3 0/1 Completed 0 10s
[root@Server2 configMap]# kubectl logs pod3
172.25.0.250[root@Server2 configMap]#
数据卷模式下的ConfigMap热更新
- 通过以下实验, 我们可以验证
ConfigMap
热更新相关的问题 - 通过以下
YAML
文件创建控制器并将配置文件作为数据卷挂载
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/conf.d
volumes:
- name: config-volume
configMap:
name: nginxconf
- 使用的
nginx.conf
内容
server
listen 80;
server_name _;
location /
root /usr/share/nginx/html;
index index.html index.htm;
- 创建
ConfigMap
并进行内容检测
[root@Server2 configMap]# kubectl create configmap nginxconf --from-file=nginx.conf
configmap/nginxconf created
[root@Server2 configMap]# kubectl get cm
kNAME DATA AGE
cm1-config 2 15m
kube-root-ca.crt 1 5h53m
nginxconf 1 10s
[root@Server2 configMap]# kubectl describe cm nginxconf
Name: nginxconf
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
nginx.conf:
----
server
listen 80;
server_name _;
location /
root /usr/share/nginx/html;
index index.html index.htm;
Events: <none>
- 不难发现, 此时
nginxconf
中的nginx.conf
的值中端口配置部分为listen 80
- 创建控制器并进行内容检测
[root@Server2 configMap]# kubectl apply -f Pod4.yaml
deployment.apps/my-nginx created
[root@Server2 configMap]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-nginx-86d5ccb8db-zsl8v 0/1 ContainerCreating 0 5s
[root@Server2 configMap]# kubectl exec -it my-nginx-86d5ccb8db-zsl8v -- bash
root@my-nginx-86d5ccb8db-zsl8v:/# cd /etc/nginx/conf.d/
root@my-nginx-86d5ccb8db-zsl8v:/etc/nginx/conf.d# ls
nginx.conf
root@my-nginx-86d5ccb8db-zsl8v:/etc/nginx/conf.d# cat nginx.conf
server
listen 80;
server_name _;
location /
root /usr/share/nginx/html;
index index.html index.htm;
##查看容器内挂载情况(此处节选有用部份)
root@my-nginx-86d5ccb8db-zsl8v:/etc/nginx/conf.d# mount
/dev/mapper/rhel-root on /etc/nginx/conf.d type xfs (ro,relatime,attr2,inode64,noquota)
root@my-nginx-86d5ccb8db-zsl8v:/etc/nginx/conf.d# exit
exit
- 测试
Nginx
服务情况, 通过默认80
端口可以访问
[root@Server2 configMap]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-nginx-86d5ccb8db-zsl8v 1/1 Running 0 94s 10.244.141.201 server3 <none> <none>
[root@Server2 configMap]# curl 10.244.141.201
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
- 修改
nginxconf
中的监听端口部分
[root@Server2 configMap]# kubectl edit cm nginxconf
configmap/nginxconf edited
[root@Server2 configMap]# kubectl exec -it my-nginx-86d5ccb8db-zsl8v -- bash
root@my-nginx-86d5ccb8db-zsl8v:/# cat /etc/nginx/conf.d/nginx.conf
server
listen 80;
server_name _;
location /
root /usr/share/nginx/html;
index index.html index.htm;
root@my-nginx-86d5ccb8db-zsl8v:/# cat /etc/nginx/conf.d/nginx.conf
server
listen 8000;
server_name _;
location /
root /usr/share/nginx/html;
index index.html index.htm;
- 等待一段时间后, 会发现容器内的文件内容也变化了, 即完成了文件的热更新
- 但是稍加测试就会发现, 文件修改了, 服务却没有重载, 访问依旧是
80
端口而不没有变成8000
端口
[root@Server2 configMap]# curl 10.244.141.201
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@Server2 configMap]# curl 10.244.141.201:8000
curl: (7) Failed connect to 10.244.141.201:8000; Connection refused
- 服务重载的正确方式: 打补丁
kubectl patch deployments.apps my-nginx --patch '"spec": "template":"metadata": "annotations": "version/config": "2021051102"'
deployment.apps/my-nginx patched
- 在进行
patch
后,80
端口无法正常访问而8000
畅通
[root@Server2 configMap]# curl 10.244.22.5
curl: (7) Failed connect to 10.244.22.5:80; Connection refused
[root@Server2 configMap]# curl 10.244.22.5:8000
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
- 尝试修改回去
[root@Server2 configMap]# kubectl edit cm nginxconf
configmap/nginxconf edited
[root@Server2 configMap]# kubectl patch deployments.apps my-nginx --patch '"spec": "template":"metadata": "annotations": "version/config": "2021051101"'
deployment.apps/my-nginx patched
[root@Server2 configMap]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-nginx-687ccbd4f6-79cr9 1/1 Terminating 0 88s 10.244.22.5 server4 <none> <none>
my-nginx-759cdbfbdc-f6jx8 1/1 Running 0 4s 10.244.141.202 server3 <none> <none>
[root@Server2 configMap]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-nginx-759cdbfbdc-f6jx8 1/1 Running 0 6s 10.244.141.202 server3 <none> <none>
[root@Server2 configMap]# curl 10.244.141.202
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
- 不难发现, 提交补丁的过程实际上就是控制器完成了一次滚动更新的操作
Secret配置管理
简单概念
- 与
ConfigMap
类似,Secret
也是一种对象存储, 区别在于Secret
对象性质的卷常被用来保存敏感信息, 如密码/OAuth
认证令牌等等 - 比起
CpnfigMap
, 将这些信息存储在Secret
重命更加安全和灵活
常见的两种使用方式
- 作为数据卷中的文件挂载入
Pod
进行使用 - 当作
Pod
从私有仓库拉取镜像时的认证必需品使用
Secret
的类型
类型 | 定义 |
---|---|
Service Account | K8S 会自动创建包含访问 API 凭据的Secret , 并自动修改 pod 以使用此类型的Secret , 如果没有API 凭证则Pod 无法与管理节点交互 |
Opaque | 使用base64 编码存储信息, 可以通过base64 --decode 解码获得原始数据, 因此安全性弱, 常用于文件挂载入Pod 时使用 |
kubernetes.io/dockerconfigjson | 用于存储Docker Registry 的认证信息, 当需要拉取私有仓库的镜像时使用 |
Service Account的默认设置
-
Service Account
创建时Kubernetes
会默认创建对应的Secret
-
对应的
Secret
会自动挂载到Pod
的/run/secrets/kubernetes.io/serviceaccount
目录中
通过describe
方式可以查看Pod
挂载情况
kubectl describe pod my-nginx-759cdbfbdc-f6jx8
可以看到, Mounts
信息中有Service Account
, 挂载位置为/var/run/secrets/kubernetes.io/serviceaccount
进入容器查看其内部内容, 可以看到包含命名空间, CA
证书, token
[root@Server2 ~]# kubectl exec my-nginx-759cdbfbdc-f6jx8 -- ls /var/run/secrets/kubernetes.io/serviceaccount
ca.crt
namespace
token
每个Namespace
下有一个名为default
的默认的Service Account
对象
上方在内部文件中看到的token
起到的作用时, 当Pod
启动后用来协助完成Pod
中的进程访问API Server
时的身份鉴权过程
也就是说, 缺少了这部分文件, Pod
将无法有效的与MASTER
节点进行交互
Opaque Secret
交互式方式此处不列举, 但有一条需要注意的
- 如果密码具有特殊字符, 则需要使用
\\
字符对其进行转义
文件方式创建
[root@Server2 Secret]# echo -n 'westos' > ./Password.txt
[root@Server2 Secret]# echo -n 'NeuWings' > ./Username.txt
[root@Server2 Secret]# ls
Password.txt Username.txt
[root@Server2 Secret]# kubectl create secret generic db-user-pass --from-file=./Username.txt --from-file=./Password.txt
secret/db-user-pass created
[root@Server2 Secret]# kubectl get secrets
NAME TYPE DATA AGE
db-user-pass Opaque 2 13s
default-token-5rnvk kubernetes.io/service-account-token 3 22h
同时可看到了上文所述的default
资源清单方式创建
- 获取编码转化文字内容的方式
echo -n 'admin' | base64
YWRtaW4=
$ echo -n 'westos' | base64
d2VzdG9z
- 使用的
Mysecret.yaml
内容
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: d2VzdG9z
- 操作过程
[root@Server2 Secret]# vim Mysecret.yaml
[root@Server2 Secret]# kubectl delete secrets db-user-pass
secret "db-user-pass" deleted
[root@Server2 Secret]# kubectl apply -f Mysecret.yaml
secret/mysecret created
[root@Server2 Secret]# kubectl get secrets
NAME TYPE DATA AGE
default-token-5rnvk kubernetes.io/service-account-token 3 23h
mysecret Opaque 2 15s
默认情况下kubectl get
和kubectl describe
为了安全是不会显示密码的内容, 只会显示长度
[root@Server2 Secret]# kubectl describe secrets mysecret
Name: mysecret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 6 bytes
username: 5 bytes
如果需要查看内容可以附加-o yaml
参数, 使其以yaml
格式输出.
将Secret挂载到Volume
- 修改后的
Mysecret.yaml
内容
apiVersion: v1
kind: Pod
metadata:
name: mysecret
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: secrets
mountPath: "/secret"
readOnly: true
volumes:
- name: secrets
secret:
secretName: mysecret
- 操作记录
[root@Server2 Secret]# vim Mysecret.yaml
[root@Server2 Secret]# kubectl apply -f Mysecret.yaml
pod/mysecret created
[root@Server2 Secret]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-nginx-759cdbfbdc-f6jx8 1/1 Running 1 17h
mysecret 0/1 ContainerCreating 0 5s
[root@Server2 Secret]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-nginx-759cdbfbdc-f6jx8 1/1 Running 1 17h
mysecret 1/1 Running 0 8s
向指定路径映射Secret密钥
- 使用到的
v2.yaml
文件内容
apiVersion: v1
kind: Pod
metadata:
name: mysecret
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: secrets
mountPath: "/secret"
readOnly: true
volumes:
- name: secrets
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
- 操作流程
[root@Server2 Secret]# kubectl apply -f v2.yaml
pod/mysecret created
[root@Server2 Secret]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-nginx-759cdbfbdc-f6jx8 1/1 Running 1 17h
mysecret 0/1 ContainerCreating 0 5s
[root@Server2 Secret]# kubectl describe pod mysecret
将Secret设置为环境变量
- 使用到的
v3.yaml
文件内容
apiVersion: v1
kind: Pod
metadata:
name: secret-env
spec:
containers:
- name: nginx
image: nginx
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
上面的资源清单做到了
- 从
mysecret
中分别读取两个key
对应的value
存储到两个对应的环境变量中
环境变量读取Secret
是一种很方便好用的方法, 但是其无法动态更新Secret
存储Docker Registry的认证信息
- 创建一个包含私有仓库认证信息的
Secret
, 并创建对应的私有仓库
[root@Server2 Secret]# kubectl create secret docker-registry myregistrykey --docker-server=reg.westos.org --docker-username=admin --docker-password=westos --docker-email=lunarlibrary@foxmail.com
secret/myregistrykey created
- 实验开始前私有仓库
westos
的日志情况
- 实验用到的
TestPod.yaml
文件内容
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: game2048
image: reg.westos.org/westos/game2048
- 由于镜像拖取是从私有仓库, 而上面的资源清单没有做登陆验证, 镜像是无法拉取的
[root@Server2 Secret]# vim TestPod.yaml
[root@Server2 Secret]# kubectl apply -f TestPod.yaml
pod/mypod created
[root@Server2 Secret]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-nginx-759cdbfbdc-f6jx8 1/1 Running 1 17h
mypod 0/1 ImagePullBackOff 0 4s
mysecret 1/1 Running 0 9m46s
secret-env 1/1 Running 0 6m38s
- 修改构建, 增加
imagePullSecrets
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: game2048
image: reg.westos.org/westos/game2048
imagePullSecrets:
- name: myregistrykey
[root@Server2 Secret]# vim TestPod.yaml
[root@Server2 Secret]# kubectl apply -f TestPod.yaml
pod/game2048 created
[root@Server2 Secret]# kubectl get pod
NAME READY STATUS RESTARTS AGE
game2048 1/1 Running 0 6s
my-nginx-759cdbfbdc-f6jx8 1/1 Running 1 17h
mysecret 1/1 Running 0 13m
secret-env 1/1 Running 0 9m58s
- 查看私有仓库日志, 可以看到一条登录后的
pull
, 证明mypod
确实用到了引入的认证
Volumes配置管理
- 默认情况下, 容器中的文件是临时存放在磁盘上的
- 如果容器崩溃,
kubelet
将尝试重启容器, 容器重建后恢复初始状态, 而这将导致容器内的文件丢失 - 而且在生产环境中, 一个
Pod
内经常存在多个容器, 各个容器间还需要共享文件/资源
这些问题该如何解决
K8S
中的卷具有明确的生命周期, 与包裹它的Pod
相同.
这也就意味着, 卷比Pod
中运行的任何容器的存活时间都要长.这样即使容器重建, 数据也不会丢失.
当然, 如果Pod
被摧毁, 卷自然也就不复存在了.
卷不能挂载到其他卷, 也不能与其他卷有硬链接. Pod
中的每个容器必须独立地指定每个卷的挂载位置.
emptyDir卷
Pod
被调度到某一节点后, 首先会创建一个emptyDir
卷- 只要
Pod
不被调度到其他节点, 该emptyDir
卷就会一直存在 - 之所以叫
emptyDir
, 是因为在建立时卷最初是空的以上是关于运维实战 容器部分 Kubernetes存储的主要内容,如果未能解决你的问题,请参考以下文章