配置管理

ConfigMap

创建

使用 kubectl create configmap -h 查看实例,构建 configmap对象

Examples:
  # Create a new config map named my-config based on folder bar
  kubectl create configmap my-config --from-file=path/to/bar
  
  # Create a new config map named my-config with specified keys instead of file basenames on disk
  kubectl create configmap my-config --from-file=key1=/path/to/bar/file1.txt --from-file=key2=/path/to/bar/file2.txt
  
  # Create a new config map named my-config with key1=config1 and key2=config2
  kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2
  
  # Create a new config map named my-config from the key=value pairs in the file
  kubectl create configmap my-config --from-file=path/to/bar
  
  # Create a new config map named my-config from an env file
  kubectl create configmap my-config --from-env-file=path/to/foo.env --from-env-file=path/to/bar.env

在config/test 目录下创建 两个文件

# db.properties
username=root
password=root

# redis.properties
host=127.0.0.1:3379
indexDB=2

# 创建 方式一

kubectl create configmap my-config --from-file=test/

# 查看 cm 是缩写 configmap
kubectl get configmap

# 结果
NAME               DATA   AGE
kube-root-ca.crt   1      6d11h
my-config          2      30s

# 查看配置信息
kubectl describe cm my-config

# 结果
Name:         my-config
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
db.properties:
----
username=root
password=root
redis.properties:
----
host=127.0.0.1:3379
indexDB=2


BinaryData
====


# 创建 方式二
# application.yml
spring:
  application:
    name: test
server:
  port: 8080

# 创建
kubectl create cm spring-boot-test-yaml --from-file=/root/config/application.yml

# 查看
kubectl describe cm spring-boot-test-yaml

# 结果
Name:         spring-boot-test-yaml
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
application.yml:
----
spring:
  application:
    name: test
server:
  port: 8080


BinaryData
====
# 创建 方式三 别名
kubectl create cm spring-boot-test-alises-yaml --from-file=app.yml=/root/config/application.yml

# 查看
kubectl describe cm spring-boot-test-alises-yaml

# 结果
Name:         spring-boot-test-alises-yaml
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
app.yml:
----
spring:
  application:
    name: test
server:
  port: 8080

# 创建 方式四 直接创建
kubectl create cm test-key-value-config --from-literal=username=root --form-literal=admin
kubectl create cm test-env-config --from-literal=JAVE_OPTS_TEST='-Xms512m -Xms512m' --from-literal=APP_NAME=srping-boot





创建一个po使用 配置的环境变量

env-test-cm.yaml

apiVersion: v1
kind: Pod
metadata:
  name: env-test-cm
spec:
  containers:
    - name: env-test
      image: alpine
      command: ["/bin/sh", "-c", "env && sleep 3600"]
      imagePullPolicy: IfNotPresent
      env:
        - name: JAVA_VM_OPTS
          valueFrom:
            configMapKeyRef:
              name: test-env-config # Name of the ConfigMap
              key: JAVE_OPTS_TEST # 表示从 ConfigMap 中获取 key 为 JAVE_OPTS_TEST 的值,并赋值给 JAVA_VM_OPTS
        - name: APP
          valueFrom:
            configMapKeyRef:
              name: test-env-config
              key: APP_NAME

测试是否能用

# 创建po
kubectl create -f env-test-po.yaml

# 查看日志
kubectl logs -f  env-test-po


# 结果
NGINX_SVC_SERVICE_HOST=10.107.108.13
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=env-test-po
SHLVL=1
HOME=/root
JAVA_VM_OPTS=-Xms512m -Xmx512m  #新增的
NGINX_SVC_SERVICE_PORT=80
NGINX_SVC_PORT=tcp://10.107.108.13:80
NGINX_SVC_SERVICE_PORT_WEB=80
NGINX_SVC_PORT_80_TCP_ADDR=10.107.108.13
APP=srping-boot #新增的
NGINX_SVC_PORT_80_TCP_PORT=80
NGINX_SVC_PORT_80_TCP_PROTO=tcp
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
NGINX_SVC_PORT_80_TCP=tcp://10.107.108.13:80
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/

k8s查看pod日志报错

# 查看日志
kubectl logs -f  env-test-po


# 日志报错
Error from server: Get "https://192.168.10.104:10250/containerLogs/default/env-test-po/env-test?follow=true": dial tcp 192.168.10.104:10250: connect: no route to host

# 解决方案

[root@localhost ~]# iptables -F
或者
[root@localhost ~]# systemctl stop firewalld

测试文件挂载 file-test-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: env-configfile-po
spec:
  containers:
    - name: env-test
      image: alpine
      command: ["/bin/sh", "-c", "env;sleep 3600"]
      imagePullPolicy: IfNotPresent
      env:
        - name: JAVA_VM_OPTS
          valueFrom:
            configMapKeyRef:
              name: test-env-config # Name of the ConfigMap
              key: JAVE_OPTS_TEST # 表示从 ConfigMap 中获取 key 为 JAVE_OPTS_TEST 的值,并赋值给 JAVA_VM_OPTS
        - name: APP
          valueFrom:
            configMapKeyRef:
              name: test-env-config
              key: APP_NAME
      volumeMounts:
        - name: db-config # 表示加载volumes 属性中的那一个数据卷
          mountPath: "/usr/local/mysql/conf" # 想要将数据卷挂载到那个目录下
          readOnly: true # 是否只读
  volumes: # 数据卷挂载 configmap secret
    - name: db-config # 数据卷的名字,随意设置
      configMap: # 数据卷类型为configMap
        name: my-config # configmap的名字,必须跟想要加载的configmap相同
        items: # 对configmap中的key进行映射,如果不指定,默认会将 configmap中所有的key全部转化为一个个同名的文件
          - key: db.properties # configmap中的key
            path: db.properties # 将该key的值转为文件名为db.properties的文件
  restartPolicy: Never

创建pod+测试

kubectl create -f file-test-pod.yaml 

kubectl exec -it env-configfile-po -- sh

# 结果如下

[root@k8s-master config]# kubectl exec -it env-configfile-po -- sh
/ # cd /usr/local/mysql/conf/
/usr/local/mysql/conf # ls
db.properties
/usr/local/mysql/conf # 

Secret 创建存在编码的情况

# 创建
kubectl create secret generic orig-secret  --from-literal=username=root --from-literal=password=root

# 查看 
kubectl describe secret/orig-secret

# 结果

Name:         orig-secret
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  4 bytes
username:  4 bytes

SubPath 的使用

volumeMounts:
  - mountPath:/etc/nginx/nginx.conf # 挂载到哪里
    name: config-volume # 使用那个confgmap或是secret
    subPath: /etc/nginx/nginx.conf

配置热更新

通过edit命令直接修改 configmap

# 编辑
kubectl edit cm my-config


[root@k8s-master config]# kubectl exec -it env-configfile-po -- sh
/ # cd /usr/local/mysql/conf/
/usr/local/mysql/conf # ls
db.properties
/usr/local/mysql/conf # 

通过replace 替换

kubectl create cm test-dir-config --from-file=./test/ --dry-run -o yaml | kubectl replace -f-

不可变的Secret和configMap

配置configMap 可以设置 immutable:true 来禁止修改

持久化存储

volumes

# volume-test-po.yaml
apiVersion: v1
kind: Pod
metadata:
  name: volume-test
spec:
  containers:
    - name: volume-test
      image: nginx
      volumeMounts:
        - name: test-volume # 挂载到容器的那个目录
          mountPath: /test-pd # 挂载那个 volume
  volumes:
    - name: test-volume
      hostPath: # 与主机共享目录,加载主机中的指定目录到容器中
        path: /data # 节点中的目录
        type: DirectoryOrCreate # 如果不存在则创建

HostPath

  • 空字符串:默认类型,不做任何检查
  • DirectoryOrCreate: 如果给定的path不存在,就创建一个755的空目录
  • Directory: 这个目录必须存在
  • FileCreate: 如果给定的文件不存在,则创建一个644的空文件
  • File: 这个文件必须存在
  • Socket: UNIX套接子,必须存在
  • CharDeivce: 字符设备,必须存在
  • BlockDevice 块设备,必须存在

测试

# master创建容器
kubectl create -f volume-test-po.yaml

# 到对应的节点目录添加内容
[root@k8s-node3 ~]# cd /data
[root@k8s-node3 data]# ls
[root@k8s-node3 data]# touch index.html
[root@k8s-node3 data]# echo "hello" >> index.html
[root@k8s-node3 data]# cat index.html
hello
[root@k8s-node3 data]# iptables -F

# 到master中进入容器
[root@k8s-master volumes]# kubectl exec -it volume-test -- sh
# ls
bin  boot  dev  docker-entrypoint.d  docker-entrypoint.sh  etc  home  lib  media  mnt  opt  proc  root  run  sbin  srv  sys  test-pd  tmp  usr  var
# cd test-pod
# ls
index.html
# cat index.html
hello

EmptyDir

主要用于一个pod中不同container共享数据使用的,由于只是在Pod内部使用,因此与其他volume 比较大的区别是,当pod如果删除了,那么emptyDir也会被删除。

存储介质可以是任意类型,不如 SSD,磁盘或网络存储,可以将emptyDir.medium设置为 Memory,让k8s使用tmpfs (内存支持使用系统),速度比较快,但是重启tmpfs节点时,数据会被清除,且设置的大小会计入到container的内存限制中

demo

# empty-dir-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: empty-dir-pod
spec:
  containers:
    - name: nginx-emptydir1
      image: alpine
      command: ["/bin/sh", "-c", "sleep 3600;"]
      volumeMounts:
        - name: cache-volume # 挂载到容器的那个目录
          mountPath: /cache # 挂载那个 volume
    - name: nginx-emptydir2
      image: alpine
      command: ["/bin/sh", "-c", "sleep 3600;"]
      volumeMounts:
        - name: cache-volume # 挂载到容器的那个目录
          mountPath: /opt # 挂载那个 volume
  volumes:
    - name: cache-volume
      emptyDir: {}

# 创建pod
kubectl create -f empty-dir-pod.yaml

# 进入容器 nginx-emptydir1
kubectl exec -it empty-dir-pod -c nginx-emptydir1 -- sh
/ # ls
bin    cache  dev    etc    home   lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var
/ # cd cache/
/cache # ls
/cache # pwd
/cache
/cache # touch a.txt #第一步
/cache # ls  # 第四部
a.txt  b.txt

# 进入容器 nginx-emptydir2
kubectl exec -it empty-dir-pod -c nginx-emptydir2 -- sh
/ # ls
bin    dev    etc    home   lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var
/ # cd opt/
/opt # ls  # 第二部
a.txt
/opt # touch  b.txt # 第三步


nfs挂载

nfs卷能将NFS(网络文件系统) 挂载到你的Pod中,不行emptyDir那样会在删除容器的时候Pod同时也会被删除,nfs的内容在容器被删除的时候会被报错,卷只是被卸载,这意味着nfs卷可以被预先填充数据,并且这些数据可以在Pod之间共享

安装NFS

# 安装 nfs
yum install nfs-utils -y

# 启动 nfs
systemctl start nfs-server

# 查看 nfs版本
cat /proc/fs/nfsd/versions

# 创建共享目录
mkdir -p /home/nfs

# 设置共享目录 export
vi /etc/exports
/home/nfs/rw 192.168.10.0/24(rw,sync,no_subtree_check,no_root_squash)
/home/nfs/ro 192.168.10.0/24(rw,sync,no_subtree_check,no_root_squash)

# 重新加载
exportfs -f
systemctl reload nfs-server

# 创建一个文件
cd /data/nfs/ro
touch README.md
echo "hello" > README.md


# 到其他测试节点安装nfs-utils 并加载测试 【记得安装 nfs-utils】

mkdir -p /mnt/nfs/rw
mount -t nfs 192.168.10.104:/home/nfs/rw /mnt/nfs/rw
mkdir -p /mnt/nfs/ro
mount -t nfs 192.168.10.104:/home/nfs/ro /mnt/nfs/ro

# 测试
cd /mnt/nfs/ro
ls
# 结果
README.md

POD测试

apiVersion: v1
kind: Pod
metadata:
  name: nfs-test-pd1
spec:
  containers:
    - name: nfs-test-po
      image: nginx
      volumeMounts:
        - mountPath: /usr/share/nginx/html # 挂载那个 volume
          name: nfc-volume-test # 挂载到容器的那个目录
  volumes:
    - name: nfc-volume-test
      nfs:
        server: 192.168.10.104 # NFS 服务器地址
        path: /home/nfs/rw/nginx/html # NFS 服务器地址和共享目录
        readOnly: false
# 测试结果

[root@k8s-master volumes]# kubectl get po -o wide
NAME           READY   STATUS        RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
nfs-test-pd1   1/1     Running       0          15s   10.244.122.108   k8s-node4   <none>           <none>
nginx-pod      0/1     Terminating   0          41h   <none>           k8s-node3   <none>           <none>
[root@k8s-master volumes]# curl 10.244.122.108
hello

PV与PVC

生命周期

构建

静态构建

动态构建

如果集群中已经有的PV无法满足PVC的需求,那么集群会根据PVC自动构架一个PV,该操作是通过StorageClass实现的,要想实现该操作,前提是PVC必须设置StorageClass,否则会无法动态构建PV,可以通过启用DefaultStorageClass来实现PV的构建

绑定

当用户创建一个PVC对象后,主节点会监测新的PVC对象,并且寻找预支匹配的PV卷,找到PV卷后将其绑定在一起。如果找不到对应的PV,则需要看PVC是否设置了StorageClass来决定是否动态创建PV,若没有配置,PVC就会一直处于未绑定状态,直到与之匹配的PV后才处于绑定状态

使用

Pod将PVC当做存储卷来使用,集群会通过PVC找到绑定的PV,并未POD挂载该卷

Pod一旦使用PVC绑定PV之后,为了保护数据,避免数据丢失问题,PV对象将会受到保护,在系统中无法被删除

回收策略

  • Retain 保留
  • Delete 删除
  • Recycle 回收

PV

状态

  • Available 空闲,未被绑定
  • Bound 已被PVC绑定
  • Released PVC被删除,资源已回收,但PV未被重新使用
  • Failed 自动回收失败

配置文件

test-pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0001
spec:
  capacity:
    storage: 2Gi
  volumeMode: Filesystem # 储存类型为文件系统
  accessModes: # 访问模式 ReadWriteOnce 读写一次 ReadWriteMany 读写多次 ReadOnlyMany 只读多次
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Recycle # 回收策略
  storageClassName: slow # 创建PV的储存类名,需要与PVC的储存类名一致
  mountOptions: # 加载配置
    - hard
    - nfsvers=4.1
  nfs:
    path: /home/nfs/rw/test-pv
    server: 192.168.10.104

创建pv

# 创建
kubectl create -f pv-nfs.yaml

# 查看
kubectl get pv

# 结果
NAME      STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
nfs-pvc   Pending                                      slow           67s

PVC

test-pvc.yaml

# https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/
apiVersion: v1
kind: PersistentVolumeClaim # 资源类型为 pvc
metadata:
  name: nfs-pvc # pvc 名称
spec:
  resources:
    requests:
      storage: 2Gi # 请求存储大小
  volumeMode: Filesystem # 储存类型为文件系统
  accessModes: # 访问模式 ReadWriteOnce 读写一次 ReadWriteMany 读写多次 ReadOnlyMany 只读多次
    - ReadWriteMany
  storageClassName: slow # 创建PV的储存类名,需要与PVC的储存类名一致
  # mountOptions: # 加载配置
  #   - hard
  #   - nfsvers=4.1
  # nfs:
  #   path: /home/nfs/rw/test-pv
  #   server: 192.168.10.104

创建PVC

# 创建pvc
kubectl create -f pvc-nfs.yaml

# 查看pvc
kubectl get pvc

# 结果
NAME      STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
nfs-pvc   Pending                                      slow           6s

POD绑定PVC

创建pvc-test-pd.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pvc-test-pd
spec:
  containers:
    - name: pvc-test-pd
      image: nginx
      volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: nfs-pvc
  volumes:
    - name: nfs-pvc
      persistentVolumeClaim:
        claimName: nfs-pvc

配置文件

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐