云原生架构实战07 Kubernetes的核心实战 下
  dBFTbkVLMBge 2023年11月19日 18 0

7、存储抽象

pod如果挂掉,在其他的机器启动新pod,原来pod的数据是无法迁移到新机器的;所以使用单独的存储层来解决。

将节点上的文件或目录挂载到pod上,此时该目录会变成持久化存储目录,即使Pod被删除后重启,也可以重新加载到该目录,该目录下的文件不会丢失。

云原生架构实战07 Kubernetes的核心实战 下_redis

云原生架构实战07 Kubernetes的核心实战 下_docker_02

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


环境准备

1、所有节点

#所有机器安装
yum install -y nfs-utils

云原生架构实战07 Kubernetes的核心实战 下_docker_03

2、主节点

#nfs主节点
echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports

mkdir -p /nfs/data
systemctl enable rpcbind --now
systemctl enable nfs-server --now
#配置生效
exportfs -r
exportfs

云原生架构实战07 Kubernetes的核心实战 下_redis_04


3、从节点

showmount -e 192.168.183.134 #master的ip地址

#执行以下命令挂载 nfs 服务器上的共享目录到本机路径 /root/nfsmount
mkdir -p /nfs/data
#挂载到主节点的目录
mount -t nfs 192.168.183.134:/nfs/data /nfs/data

云原生架构实战07 Kubernetes的核心实战 下_nginx_05

在master节点执行

# 写入一个测试文件
echo "hello nfs server" > /nfs/data/test.txt

云原生架构实战07 Kubernetes的核心实战 下_docker_06

然后看从节点,已经看到了同步过来的文件text.txt

云原生架构实战07 Kubernetes的核心实战 下_docker_07

4、原生方式数据挂载

云原生架构实战07 Kubernetes的核心实战 下_docker_08

先创建目录/nfs/data/nginx-pv

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-pv-demo
  name: nginx-pv-demo
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx-pv-demo
  template:
    metadata:
      labels:
        app: nginx-pv-demo
    spec:
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
        - name: html
          nfs:
            server: 192.168.183.134
            path: /nfs/data/nginx-pv
kubectl apply -f nfs-mount.yaml #执行

云原生架构实战07 Kubernetes的核心实战 下_redis_09

云原生架构实战07 Kubernetes的核心实战 下_redis_10

发现挂载的pod

/usr/share/nginx/html/index.html 内容和外面/nfs/data/nginx-pv/index.html 一模一样

5、HostPath的使用

apiVersion: v1
kind: Pod
metadata:
  name: test-volume-pd
spec:
  containers: 
  - image: nginx
    name: nginx-volume
    volumeMounts: 
    - mountPath: /test-pd
      name: test-volume
  volumes: 
  - name: test-volume
    hostPath:
      path: /data
      type: DirectoryOrCreate

kubectl apply -f test-volume-pd.yaml #执行

云原生架构实战07 Kubernetes的核心实战 下_docker_11

在work1 的/data目录下创建touch index.html  ,内容为空

kubectl exec -it test-volume-pd -- sh #主节点进入到pod中

云原生架构实战07 Kubernetes的核心实战 下_docker_12

云原生架构实战07 Kubernetes的核心实战 下_docker_13

从主节点写入,然后去work1看下/data目录下的内容,已经同步过来了

云原生架构实战07 Kubernetes的核心实战 下_nginx_14

然后work1写入

云原生架构实战07 Kubernetes的核心实战 下_redis_15

再去主节点的pod内看下内容,发现内容也同步过来了

云原生架构实战07 Kubernetes的核心实战 下_docker_16

6、EmptyDir

主要用于一个pod中不同的Container共享数据使用的,由于只是在pod内部使用,因此与其他volume比较大的区别是,当pod如果被删除了,那么emnptyDir也会被删除。不能做持久化存储

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

云原生架构实战07 Kubernetes的核心实战 下_nginx_17


云原生架构实战07 Kubernetes的核心实战 下_redis_18



1、PV&PVC

上面挂载的方式有一个问题 :

1.pod如果删除,那么外面目录/nfs/data目录下的内容并不会被清理掉

2.pod使用的存储空间没有限制

PV:持久卷(Persistent Volume),将应用需要持久化的数据保存到指定位置

PVC:持久卷声明(Persistent Volume Claim),申明需要使用的持久卷规格

云原生架构实战07 Kubernetes的核心实战 下_nginx_19

云原生架构实战07 Kubernetes的核心实战 下_nginx_20

当用户创建一个pvc对象洪湖,主节点会检测新的pvc对象,并且寻找与之匹配的pv卷,找到pv卷后将二者绑定在一起

如果找不到对应的pv,则需要看pvc是否设置storageClass来决定是否动态创建pv,若没有配置,pvc就会一直处于未绑定状态,直到有与之匹配的pv后才会申领绑定关系。pod没绑定之前是无法启动的。

pod一旦使用pvc绑定pv后,为了保护数据,避免数据丢失问题,pv对象会受到保护,在系统内无法被删除。

1、创建pv池

静态供应

#nfs主节点
mkdir -p /nfs/data/01
mkdir -p /nfs/data/02
mkdir -p /nfs/data/03

云原生架构实战07 Kubernetes的核心实战 下_docker_21

创建PV

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv01-10m
spec:
  capacity:
    storage: 10M
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  nfs:
    path: /nfs/data/01
    server: 192.168.183.134
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv02-1gi
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  nfs:
    path: /nfs/data/02
    server: 192.168.183.134
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv03-3gi
spec:
  capacity:
    storage: 3Gi
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  nfs:
    path: /nfs/data/03
    server: 192.168.183.134

kubectl apply -f pv.yaml执行

云原生架构实战07 Kubernetes的核心实战 下_docker_22

云原生架构实战07 Kubernetes的核心实战 下_docker_23


2、PVC创建与绑定

云原生架构实战07 Kubernetes的核心实战 下_nginx_24

创建PVC  

vi pvc.yaml

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: nginx-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 200Mi
  storageClassName: nfs

 发现申请成功

云原生架构实战07 Kubernetes的核心实战 下_docker_25

还可以删除pvc 再重新申请

云原生架构实战07 Kubernetes的核心实战 下_redis_26

云原生架构实战07 Kubernetes的核心实战 下_docker_27

云原生架构实战07 Kubernetes的核心实战 下_docker_28

创建Pod绑定PVC   vi pod-pvc.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-deploy-pvc
  name: nginx-deploy-pvc
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-deploy-pvc
  template:
    metadata:
      labels:
        app: nginx-deploy-pvc
    spec:
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
        - name: html
          persistentVolumeClaim:
            claimName: nginx-pvc

云原生架构实战07 Kubernetes的核心实战 下_docker_29

云原生架构实战07 Kubernetes的核心实战 下_nginx_30

kubectl exec -it nginx-deploy-pvc-64747758f9-4sxnf -- /bin/ba

云原生架构实战07 Kubernetes的核心实战 下_nginx_31

StorageClass

云原生架构实战07 Kubernetes的核心实战 下_docker_32

云原生架构实战07 Kubernetes的核心实战 下_nginx_33



2、ConfigMap

抽取应用配置,并且可以自动更新

1、redis示例

1、把之前的配置文件创建为配置集

vi redis.conf

appendonly yes
# 创建配置,redis保存到k8s的etcd;
kubectl create cm redis-conf --from-file=redis.conf

云原生架构实战07 Kubernetes的核心实战 下_docker_34

这个配置集configmap,存储在k8s的etcd中;这样就把刚才的配置文件做成了k8s的配置集

kubectl get cm redis-conf -oyaml

云原生架构实战07 Kubernetes的核心实战 下_docker_35

精简后如下

apiVersion: v1
data:    #data是所有真正的数据,key:默认是文件名   value:配置文件的内容
  redis.conf: |
    appendonly yes
kind: ConfigMap
metadata:
  name: redis-conf
  namespace: default

只要增加immutable:true  就把这个configMap设置为不可变

云原生架构实战07 Kubernetes的核心实战 下_nginx_36

云原生架构实战07 Kubernetes的核心实战 下_redis_37

2、创建Pod

vi redis.yaml

apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: redis
    command:
      - redis-server
      - "/redis-master/redis.conf"  #指的是redis容器内部的位置
    ports:
    - containerPort: 6379
    volumeMounts:
    - mountPath: /data
      name: data
    - mountPath: /redis-master
      name: config
  volumes:
    - name: data
      emptyDir: {}
    - name: config
      configMap:
        name: redis-conf
        items:
        - key: redis.conf
          path: redis.conf

云原生架构实战07 Kubernetes的核心实战 下_docker_38

执行上面的redis配置

kubectl apply -f redis.yaml

已经创建好了redis的pod

云原生架构实战07 Kubernetes的核心实战 下_redis_39

进到redis的pod里面看配置内容

云原生架构实战07 Kubernetes的核心实战 下_redis_40

也可以在外面编辑配置集内容

kubectl edit configmap redis-conf

增加了一行

云原生架构实战07 Kubernetes的核心实战 下_redis_41

云原生架构实战07 Kubernetes的核心实战 下_docker_42

此时再进入容器看,增加的配置已经同步

云原生架构实战07 Kubernetes的核心实战 下_redis_43

3、检查默认配置

kubectl exec -it redis -- redis-cli

127.0.0.1:6379> CONFIG GET appendonly
127.0.0.1:6379> CONFIG GET requirepass

云原生架构实战07 Kubernetes的核心实战 下_nginx_44

requirepass的配置 需要等重启后才能生效

4、修改ConfigMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: example-redis-config
data:
  redis-config: |
    maxmemory 2mb
    maxmemory-policy allkeys-lru

5、检查配置是否更新

kubectl exec -it redis -- redis-cli

127.0.0.1:6379> CONFIG GET maxmemory
127.0.0.1:6379> CONFIG GET maxmemory-policy

检查指定文件内容是否已经更新

修改了CM。Pod里面的配置文件会跟着变


配置值未更改,因为需要重新启动 Pod 才能从关联的 ConfigMap 中获取更新的值。

原因:我们的Pod部署的中间件自己本身没有热更新能力

3、Secret

Secret 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 SSH 密钥。 将这些信息放在 secret 中比放在 Pod 的定义或者 容器镜像 中来说更加安全和灵活。

kubectl create secret docker-registry leifengyang-docker \
--docker-username=leifengyang \
--docker-password=Lfy123456 \
--docker-email=xxxxxxx@qq.
##命令格式
kubectl create secret docker-registry regcred \
  --docker-server=<你的镜像仓库服务器> \
  --docker-username=<你的用户名> \
  --docker-password=<你的密码> \
  --docker-email=<你的邮箱地址>

云原生架构实战07 Kubernetes的核心实战 下_docker_45

apiVersion: v1
kind: Pod
metadata:
  name: private-nginx
spec:
  containers:
  - name: private-nginx
    image: leifengyang/guignginx:v1.0
  imagePullSecrets:
  - name: leifengyang-docker

4、CronJob 高级调度

在k8s中周期性运行计划任务,与linux中的crontab相同

注意点:cronjob执行的时间是controller-manager的时间,所以一定要确保controller-manager的时间是准确的

创建一个 名为my-cronjob的Kubernetes CronJob定时任务,使用 busybox 镜像作为容器镜像,执行每分钟一次的定时任务,任务是打印当前日期和休眠10秒钟

apiVersion: batch/v1
kind: CronJob
metadata:
  creationTimestamp: null
  name: my-cronjob
spec:
  jobTemplate:
    metadata:
      creationTimestamp: null
      name: my-cronjob
    spec:
      template:
        metadata:
          creationTimestamp: null
        spec:
          terminationGracePeriodSeconds: 0
          containers:
          - command:
            - sh
            - -c
            - date;sleep 10
            image: busybox
            imagePullPolicy: IfNotPresent
            name: my-cronjob
            resources: {}  
          restartPolicy: OnFailure        
  schedule: '*/1 * * * *'
status: {}
kubectl apply -f crontab.yaml #执行

云原生架构实战07 Kubernetes的核心实战 下_docker_46

可以看到每分钟都启动一个cronjob的pod执行,执行完成后变成completed

云原生架构实战07 Kubernetes的核心实战 下_docker_47

5、初始化容器 initContainer

云原生架构实战07 Kubernetes的核心实战 下_docker_48

云原生架构实战07 Kubernetes的核心实战 下_nginx_49

云原生架构实战07 Kubernetes的核心实战 下_docker_50

云原生架构实战07 Kubernetes的核心实战 下_nginx_51

云原生架构实战07 Kubernetes的核心实战 下_docker_52

6、污点和容忍

云原生架构实战07 Kubernetes的核心实战 下_nginx_53

云原生架构实战07 Kubernetes的核心实战 下_nginx_54

污点:是标注在节点上的,在一个节点打上污点以后,k8s会认为尽量不要将pod调度到该节点上,除非该pod上面表示可以容忍该污点,且一个节点可以打多个污点。此时则需要该pod容忍所有污点才会被调度该节点。

kubectl taint node work1 key=value:NoSchedule  #打上污点
kubectl taint node work1 key=value:NoSchedule- #移除污点

NoExecute的含义

云原生架构实战07 Kubernetes的核心实战 下_nginx_55

云原生架构实战07 Kubernetes的核心实战 下_nginx_56

云原生架构实战07 Kubernetes的核心实战 下_redis_57

Equal的用法

云原生架构实战07 Kubernetes的核心实战 下_docker_58

Exists的用法

云原生架构实战07 Kubernetes的核心实战 下_nginx_59

下面实战打污点

kubectl taint node work1 memory=low:NoSchedule

云原生架构实战07 Kubernetes的核心实战 下_redis_60

kubectl describe node work1 #查看work1的详细信息

可以看到node被打上了污点

云原生架构实战07 Kubernetes的核心实战 下_docker_61

master节点原本就打上了污点,所以不能调度

云原生架构实战07 Kubernetes的核心实战 下_redis_62

如果打污点

kubectl taint node work1 memory=low:No

可以看见驱逐的现象,删掉污点后,pod调度运行恢复正常

云原生架构实战07 Kubernetes的核心实战 下_nginx_63

在deployment的yaml配置中,增加容忍的配置,重新执行

云原生架构实战07 Kubernetes的核心实战 下_redis_64

就可以发现node2又开始运行pod了

云原生架构实战07 Kubernetes的核心实战 下_redis_65

如果使用Exists配置,就不需要value了,配置key即可

云原生架构实战07 Kubernetes的核心实战 下_redis_66

7、亲和力

云原生架构实战07 Kubernetes的核心实战 下_redis_67

云原生架构实战07 Kubernetes的核心实战 下_nginx_68

云原生架构实战07 Kubernetes的核心实战 下_redis_69

云原生架构实战07 Kubernetes的核心实战 下_docker_70

下面看一个亲和力的yaml配置

云原生架构实战07 Kubernetes的核心实战 下_docker_71

优先调度到weight:50的

云原生架构实战07 Kubernetes的核心实战 下_nginx_72

pod亲和力:将与指定pod亲和力匹配的pod部署在同一节点

pod反亲和力:根据策略,尽量不部署到一起

云原生架构实战07 Kubernetes的核心实战 下_redis_73

云原生架构实战07 Kubernetes的核心实战 下_docker_74

8、访问控制 认证与鉴权

云原生架构实战07 Kubernetes的核心实战 下_docker_75

云原生架构实战07 Kubernetes的核心实战 下_nginx_76

普通用户应用不多

重点看下Service Account 服务账户

云原生架构实战07 Kubernetes的核心实战 下_nginx_77

云原生架构实战07 Kubernetes的核心实战 下_docker_78

云原生架构实战07 Kubernetes的核心实战 下_nginx_79

云原生架构实战07 Kubernetes的核心实战 下_redis_80

云原生架构实战07 Kubernetes的核心实战 下_redis_81

云原生架构实战07 Kubernetes的核心实战 下_redis_82

云原生架构实战07 Kubernetes的核心实战 下_redis_83

云原生架构实战07 Kubernetes的核心实战 下_nginx_84

云原生架构实战07 Kubernetes的核心实战 下_redis_85



【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月19日 0

暂无评论

推荐阅读
  DF5J4hb0hcmT   2023年11月02日   36   0   0 mysqldocker
  DF5J4hb0hcmT   2023年11月02日   22   0   0 docker
  llt0tXqeaug8   2023年11月26日   23   0   0 ubunturubydocker
  DF5J4hb0hcmT   2023年11月02日   29   0   0 Redisdocker
  DF5J4hb0hcmT   2023年11月02日   45   0   0 javajardocker
  DF5J4hb0hcmT   2023年11月02日   28   0   0 mysqldocker
dBFTbkVLMBge