重生之我爱上了k8s!

news2024/10/19 0:33:19
内容不全,待补充中...... 

目录

一、k8s的部署

1.1.集群环境初始化

1.1.1.所有主机禁用swap

1.1.2.安装k8s部署工具

1.1.2.所有节点安装cri-docker

1.1.3.在master节点拉取K8S所需镜像

1.1.4.集群初始化

1.1.5.其他两台主机加入集群

1.1.6.安装flannel网络插件

1.1.7.查看所有node的状态

三、pod的管理和优化

3、pod的生命周期

(1)、INIT容器

2、探针

四、控制器

1、replicaset

2、deployment控制器

3、daemonset控制器

4、job控制器

5、cronjob控制器

k8s的存储

1、Configmap

(1)、congifmap的创建方式

(2)、configmap的使用方式

使用configmap 填充环境变量

通过数据卷使用configmap

利用configmap填充pod的配置文件

 2、secrets

(1)、secrets的创建

(2)、secrets的应用

挂载卷

向指定路径映射 secret 密钥

将secrets设置为环境变量

 存储docker registry的认证信息

3、volumes

(1)、emptyDir卷

(2)、hostpath卷

(3)、nfs卷

(4)、持久卷

4、存储类


 

准备工作:

1、准备一台主机为harbor镜像仓库

搭建私人镜像仓库

2、新建三台主机连接到该镜像仓库

实验环境:

主机名ip
k8s-master172.25.254.100
k8s-node1172.25.254.10
k8s-node2172.25.254.20
docker-harbor(reg.gaoyingjie.org)172.25.254.250

操作:

(1)、配置三台主机的解析

vim /etc/hosts

内容:
172.25.254.100  k8s-master
172.25.254.10   k8s-node1
172.25.254.20   k8s-node2
172.25.254.250  reg.gaoyingjie.org

(2)、检查三台主机的软件仓库

(3)、三台主机安装docker

(4)、从harbor主机将认证证书传输给三台主机

[root@k8s-master docker]# mkdir -p  /etc/docker/certs.d/reg.gaoyingjie.org

[root@docker-harbor ~]# scp /data/certs/gaoyingjie.org.crt root@172.25.254.100:/etc/docker/certs.d/reg.gaoyingjie.org/ca.crt

(5)、设置镜像源

[root@k8s-master reg.gaoyingjie.org]# vim /etc/docker/daemon.json
内容;

{
        "registry-mirrors":["https://reg.gaoyingjie.org"]
}

(6)、传输

将100主机的所有文件传输给10、20主机

[root@k8s-master ~]# scp *.rpm root@172.25.254.10:/root
[root@k8s-master ~]# scp *.rpm root@172.25.254.20:/root
[root@k8s-node1 ~]# dnf install *.rpm -y
[root@k8s-node2 ~]# dnf install *.rpm -y


[root@k8s-master ~]# scp -r /etc/docker/ root@172.25.254.10:/etc/
[root@k8s-master ~]# scp -r /etc/docker/ root@172.25.254.20:/etc/

(7)、登录

三台主机都可以登录仓库reg.gaoyingjie.org

docker login reg.gaoyingjie.org

一、k8s的部署

1.1.集群环境初始化

1.1.1.所有主机禁用swap

[root@k8s- ~]# systemctl mask dev-nvme0n1p3.swap
[root@k8s- ~]# swapoff -a
[root@k8s- ~]# systemctl status dev-nvme0n1p3.swap
[root@k8s- ~]# vim /etc/fstab 

内容:
注释swap

1.1.2.安装k8s部署工具

[root@k8s-master ~]# dnf install kubelet-1.30.0 kubeadm-1.30.0 kubectl-1.30.0 -y

#设置kubectl命令自动补全功能
[root@k8s-master ~]# dnf install bash-completion -y
[root@k8s-master ~]# echo "source <(kubectl completion bash)" >> ~/.bashrc
[root@k8s-master ~]# source  ~/.bashrc

1.1.2.所有节点安装cri-docker

[root@k8s-master ~]# dnf install libcgroup-0.41-19.el8.x86_64.rpm \
> cri-dockerd-0.3.14-3.el8.x86_64.rpm -y

[root@k8s-master ~]# vim /lib/systemd/system/cri-docker.service

编辑内容:

#指定网络插件名称及基础容器镜像
ExecStart=/usr/bin/cri-dockerd --container-runtime-endpoint fd:// --network-plugin=cni --pod-infra-container-image=reg.timinglee.org/k8s/pause:3.9

[root@k8s-master ~]# systemctl daemon-reload
[root@k8s-master ~]# systemctl start cri-docker
[root@k8s-master ~]# ll /var/run/cri-dockerd.sock

将该配置文件拷贝给其他两台主机:

[root@k8s-master ~]# scp /lib/systemd/system/cri-docker.service root:/172.25.254.10:/lib/systemd/system/cri-docker.service
[root@k8s-master ~]# scp /lib/systemd/system/cri-docker.service root:/172.25.254.20:/lib/systemd/system/cri-docker.service

1.1.3.在master节点拉取K8S所需镜像

#拉取k8s集群所需要的镜像
[root@k8s-master ~]# kubeadm config images pull --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.30.0 --cri-socket=unix:///var/run/cri-dockerd.sock​

#上传镜像到harbor仓库
[root@k8s-master ~]# docker images | awk '/google/{ print $1":"$2}' \| awk -F "/" '{system("docker tag "$0" reg.gaoyingjie.org/k8s/"$3)}'​

[root@k8s-master ~]# docker images  | awk '/k8s/{system("docker push "$1":"$2)}'  

1.1.4.集群初始化

[root@k8s-master ~]# systemctl enable --now  kubelet.service
[root@k8s-master ~]# systemctl status kubelet.service

#执行初始化命令
[root@k8s-master ~]# kubeadm init --pod-network-cidr=10.244.0.0/16 \
--image-repository reg.gaoyingjie.org/k8s \
--kubernetes-version v1.30.0 \
--cri-socket=unix:///var/run/cri-dockerd.sock

#指定集群配置文件变量[root@k8s-master ~]# echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile​

#当前节点没有就绪,因为还没有安装网络插件,容器没有运行
[root@k8s-master ~]# kubectl get node

[root@k8s-master ~]# kubectl get pod -A

1.1.5.其他两台主机加入集群

在此阶段如果生成的集群token找不到了可以重新生成

[root@k8s-master ~]#   kubeadm token create --print-join-command kubeadm join 172.25.254.100:6443 --token 5hwptm.zwn7epa6pvatbpwf --discovery-token-ca-cert-hash 
[root@k8s-node1 ~]# kubeadm reset --cri-socket=unix:///var/run/cri-dockerd.sock
[root@k8s-node1 ~]# kubeadm join 172.25.254.100:6443 --token baujlw.w4xhwevafprh8uk9 --discovery-token-ca-cert-hash sha256:f05eb014ffdee15265806a1bc7a54270d8b28cccf90b88cb2b2910fe3aaab05f --cri-socket=unix:///var/run/cri-dockerd.sock


[root@k8s-node2 ~]# kubeadm reset --cri-socket=unix:///var/run/cri-dockerd.sock
[root@k8s-node2 ~]# kubeadm join 172.25.254.100:6443 --token baujlw.w4xhwevafprh8uk9 --discovery-token-ca-cert-hash sha256:f05eb014ffdee15265806a1bc7a54270d8b28cccf90b88cb2b2910fe3aaab05f --cri-socket=unix:///var/run/cri-dockerd.sock

1.1.6.安装flannel网络插件

#注意关闭防火墙,并且seinux的状态都是disabled

#现在镜像:
[root@k8s-master ~]# docker pull docker.io/flannel/flannel:v0.25.5
[root@k8s-master ~]# docker pull docker.io/flannel/flannel-cni-plugin:v1.5.1-flannel1

​#上传镜像到仓库[root@k8s-master ~]# docker tag flannel/flannel:v0.25.5 reg.gaoyingjie.org/flannel/flannel:v0.25.5
[root@k8s-master ~]# docker push reg.gaoyingjie.org/flannel/flannel:v0.25.5

​#编辑kube-flannel.yml 修改镜像下载位置
[root@k8s-master ~]# vim kube-flannel.yml

#需要修改以下几行
[root@k8s-master ~]# grep -n image kube-flannel.yml
146:        image: reg.timinglee.org/flannel/flannel:v0.25.5
173:        image: reg.timinglee.org/flannel/flannel-cni-plugin:v1.5.1-flannel1
184:        image: reg.timinglee.org/flannel/flannel:v0.25.5

#安装flannel网络插件
[root@k8s-master ~]# kubectl apply -f kube-flannel.yml

1.1.7.查看所有node的状态

都是ready说明k8s集群已经完成。

三、pod的管理和优化

3、pod的生命周期

(1)、INIT容器

init容器可以独立于Pod应用容器运行,init容器必须在应用容器启动前完成,它可以检测某个自定义任务是否完成,若没有完成,则会一直检测直到完成为止,若该任务完成后,init容器则会启动,当init容器启动后应用容器才会并行启动。也就是说,因此 Init 容器提供了一种机制来阻塞或延迟应用容器的启动,直到满足了一组先决条件。一旦前置条件满足,Pod内的所有的应用容器会并行启动。

[root@k8s-master ~]# vim pod.yml
[root@k8s-master ~]# kubectl apply -f pod.yml
pod/initpod created
[root@k8s-master ~]# kubectl get pods
NAME      READY   STATUS     RESTARTS      AGE
initpod   0/1     Init:0/1   0             43s     #可以看到status没有running
nginx1    1/1     Running    1 (40h ago)   2d
[root@k8s-master ~]# kubectl logs pod/initpod init-myservice 
wating for myservice
wating for myservice
wating for myservice
wating for myservice
wating for myservice
wating for myservice
wating for myservice
wating for myservice
[root@k8s-master ~]# kubectl exec -it pods/initpod -c init-myservice -- /bin/sh
/ # 
/ # touch testdfile
/ # ls
bin        etc        lib        proc       sys        tmp        var
dev        home       lib64      root       testdfile  usr
/ # exit
[root@k8s-master ~]# kubectl get pods
NAME      READY   STATUS     RESTARTS      AGE
initpod   0/1     Init:0/1   0             2m47s     #建立文件后init容器已经running
nginx1    1/1     Running    1 (40h ago)   2d

2、探针

(1)、存活探针

配置文件内容:

apiVersion: v1
kind: Pod
metadata:
  labels:
    name: initpod
  name: initpod
spec:
  containers:
    - image: myapp:v1
      name: myapp
      livenessProbe:
        tcpSocket:                ##检测端口存在性
          port: 8080
        initalDelaySeconds: 3        #容器启动后要等待多少秒后就探针开始工作,默认是 0
        periodSeconds: 1             #执行探测的时间间隔,默认为 10s 如果监测成功,每1s检测一次
        timeoutSeconds: 1            #探针执行检测请求后,如果检测失败,等待响应的超时时间,默认为1s

(2)、就绪探针

四、控制器

1、replicaset

  • ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行

  • 虽然 ReplicaSets 可以独立使用,但今天它主要被Deployments 用作协调 Pod 创建、删除和更新的机制

#生成yml文件
[root@k8s-master ~]# kubectl create deployment replicaset --image myapp:v1 --dry-run=client -o yaml > replicaset.yml​

配置文件内容:

apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: replicaset		#指定pod名称,一定小写,如果出现大写报错
spec:
  replicas: 2			#指定维护pod数量为2
  selector:				#指定检测匹配方式
    matchLabels:		#指定匹配方式为匹配标签
      app: myapp		#指定匹配的标签为app=myapp

  template:				#模板,当副本数量不足时,会根据下面的模板创建pod副本
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - image: myapp:v1
        name: myapp

2、deployment控制器

  • Deployment控制器并不直接管理pod,而是通过管理ReplicaSet来间接管理Pod

  • Deployment管理ReplicaSet,ReplicaSet管理Pod

  • 主要用来:创建Pod和ReplicaSet、滚动更新和回滚、扩容和缩容、暂停与恢复

#生成yaml文件
[root@k8s-master ~]# kubectl create deployment deployment --image myapp:v1  --dry-run=client -o yaml > deployment.yml

配置文件内容:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment
spec:
  replicas: 4
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - image: myapp:v1
        name: myapp

 查看:

版本升级:

  

版本回滚:

版本滚动更新策略:

 

版本更新暂停:

[root@k8s2 pod]# kubectl rollout pause deployment deployment-example

查看:还是原来的版本

 版本更新恢复:

[root@k8s2 pod]# kubectl rollout resume deployment deployment-example

3、daemonset控制器

DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。当有节点加入集群时, 也会为他们新增一个 Pod ,当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod

master有污点:

设置对污点容忍后:master被控制器分配pod

4、job控制器

Job,主要用于负责批量处理(一次要处理指定数量任务)短暂的一次性(每个任务仅运行一次就结束)任务。

Job特点如下:

  • 当Job创建的pod执行成功结束时,Job将记录成功结束的pod数量

  • 当成功结束的pod达到指定的数量时,Job将完成执行

前提:上传perl镜像到harbor:用来计算。

[root@k8s-master ~]# kubectl create job testjob --image perl:5.34.0 --dry-run=client -o yaml > job.yml

配置文件内容: 

apiVersion: batch/v1
kind: Job
metadata:
  creationTimestamp: null
  name: testjob
spec:
  completions: 6        #一共完成任务数为6
  parallelism: 2        #每次并行完成2个
  backoffLimit: 4        #运行失败后尝试4重新运行
  template:
    spec:
      containers:
      - image: perl:5.34.0
        name: testjob
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never        #关闭后不自动重启

 可以看到并行任务数两个,一共开启6个pod进行运算:

查看任务完成后的日志结果:

5、cronjob控制器

  • Cron Job 创建基于时间调度的 Jobs。

  • CronJob控制器以Job控制器资源为其管控对象,并借助它管理pod资源对象。

  • CronJob可以以类似于Linux操作系统的周期性任务作业计划的方式控制其运行时间点及重复运行的方式。

  • CronJob可以在特定的时间点(反复的)去运行job任务。

生成cronjob的yml文件
[root@k8s-master ~]# kubectl create cronjob testcronjob --image busyboxplus:latest --schedule="* * * * *" --restart Never --dry-run=client -o yaml > cronjob.yml

配置文件内容:

apiVersion: batch/v1
kind: CronJob
metadata:
  creationTimestamp: null
  name: testcronjob
spec:
  schedule: '* * * * *'
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - image: busyboxplus:latest
            name: testcronjob
            command: ["/bin/sh","-c","date;echo Hello from the Kubernetes cluster"]
          restartPolicy: Never

查看:是否每分钟建立一个pod并且输出一句话

[root@k8s-master ~]# watch -n 1 kubectl get pods

ClusterIP

直接解析到service的虚拟ip上

无头模式:

 

nodeport

ingress1

基于域名

https加密

用户加密

重定向

金丝雀

基于header

基于权重

k8s的存储

1、Configmap

(1)、congifmap的创建方式

通过字面值创建

[root@k8s-master storage]# kubectl create  configmap userlist  --from-literal name=gyj --from-literal age=23
configmap/userlist created
[root@k8s-master storage]# kubectl describe cm userlist 
Name:         userlist
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
age:
----
23
name:
----
gyj

BinaryData
====

Events:  <none>
[root@k8s-master storage]# 

通过文件创建

[root@k8s-master storage]# kubectl create cm configmap2 --from-file /etc/resolv.conf 
configmap/configmap2 created
[root@k8s-master storage]# kubectl describe cm configmap2 
Name:         configmap2
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
resolv.conf:
----
# Generated by NetworkManager
nameserver 114.114.114.114


BinaryData
====

Events:  <none>

通过目录创建

[root@k8s-master storage]# mkdir test
[root@k8s-master storage]# cp /etc/hosts /etc/rc.d/rc.local /root/storage/test/
[root@k8s-master storage]# kubectl create cm configmap2 --from-file test/
configmap/configmap2 created
[root@k8s-master storage]# kubectl describe cm configmap2 
Name:         configmap2
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.254.100  k8s-master
172.25.254.10   k8s-node1
172.25.254.20   k8s-node2
172.25.254.250  reg.gaoyingjie.org

rc.local:
----
#!/bin/bash
# THIS FILE IS ADDED FOR COMPATIBILITY PURPOSES
#
# It is highly advisable to create own systemd services or udev rules
# to run scripts during boot instead of using this file.
#
# In contrast to previous versions due to parallel execution during boot
# this script will NOT be run after all other services.
#
# Please note that you must run 'chmod +x /etc/rc.d/rc.local' to ensure
# that this script will be executed during boot.

touch /var/lock/subsys/local
mount /dev/cdrom /rhel9/


BinaryData
====

Events:  <none>

通过yaml文件创建

[root@k8s-master storage]# kubectl create cm configmap3 --from-literal db_host=172.25.254.100 --from-literal db_port=3306 --dry-run=client -o yaml > configmap3.yaml
[root@k8s-master storage]# vim configmap3.yaml 
[root@k8s-master storage]# kubectl apply -f configmap3.yaml 
configmap/configmap3 created
[root@k8s-master storage]# kubectl describe configmaps configmap3 
Name:         configmap3
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
db_port:
----
3306
db_host:
----
172.25.254.100

BinaryData
====

Events:  <none>

(2)、configmap的使用方式

  • 使用configmap 填充环境变量
[root@k8s-master storage]# vim testpod1.yml 
[root@k8s-master storage]# kubectl apply -f testpod1.yml 
pod/configmap-pod created
[root@k8s-master storage]# kubectl get pods
NAME            READY   STATUS      RESTARTS   AGE
configmap-pod   0/1     Completed   0          7s
test            1/1     Running     0          5m51s
[root@k8s-master storage]# kubectl logs pods/configmap-pod 
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=configmap-pod
SHLVL=1
HOME=/
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
key1=172.25.254.100
key2=3306
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
PWD=/
KUBERNETES_SERVICE_HOST=10.96.0.1
[root@k8s-master storage]# 
[root@k8s-master storage]# vim testpod1.yml 

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: configmap-pod
  name: configmap-pod
spec:
  containers:
  - image: busyboxplus:latest
    name: configmap-pod
    command:
    - /bin/sh
    - -c
    - env
    envFrom:
    - configMapRef:
        name: configmap3
  restartPolicy: Never

[root@k8s-master storage]# kubectl apply -f testpod1.yml 
pod/configmap-pod created
[root@k8s-master storage]# kubectl logs pods/configmap-pod 
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=configmap-pod
SHLVL=1
HOME=/
db_port=3306
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
PWD=/
KUBERNETES_SERVICE_HOST=10.96.0.1
db_host=172.25.254.100
#在pod命令行中使用变量
[root@k8s-master ~]# vim testpod3.yml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: testpod
  name: testpod
spec:
  containers:
  - image: busyboxplus:latest
    name: testpod
    command:
    - /bin/sh
    - -c
    - echo ${db_host} ${db_port}		#变量调用需
    envFrom:
    - configMapRef:
        name: lee4-config
  restartPolicy: Never

#查看日志
[root@k8s-master ~]# kubectl logs pods/testpod
172.25.254.100 3306
  • 通过数据卷使用configmap

声明一个卷并挂载,把configmap里的键变为挂载目录下的文件名字、把值变为文件内容。

[root@k8s-master storage]# vim testpod2.yml 

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: testpod
  name: testpod
spec:
  containers:
  - image: busyboxplus:latest
    name: testpod
    command:
    - /bin/sh
    - -c
    - sleep 1000000
    volumeMounts:
    - name: config-volume
      mountPath: /config
  volumes:
  - name: config-volume
    configMap:
      name: configmap3       #配置文件
  restartPolicy: Never

  • 利用configmap填充pod的配置文件

举例:当容器运行nginx时,nginx的配置文件可以放在configmap(通过文件创建configmap),修改配置时可以直接修改configmap文件内容,就不用修改每个pod的nginx配置文件

#建立配置文件模板
[root@k8s-master ~]# vim nginx.conf
server {
  listen 8000;
  server_name _;
  root /usr/share/nginx/html;
  index index.html;
}
#利用nging模板文件生成cm(通过文件创立cm)
root@k8s-master ~]# kubectl create cm nginx-conf --from-file nginx.conf     #通过nginx.conf 这个文件创建名为nginx-conf的cm
configmap/nginx-conf created
[root@k8s-master ~]# kubectl describe cm nginx-conf
Name:         nginx-conf
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
nginx.conf:                           #该cm的键
----
server {                              #该cm的值
  listen 8000;
  server_name _;
  root /usr/share/nginx/html;
  index index.html;
}


BinaryData
====

Events:  <none>
#建立nginx控制器文件
[root@k8s-master ~]# kubectl create deployment nginx --image nginx:latest --replicas 1 --dry-run=client -o yaml > nginx.yml

#设定nginx.yml中的卷
[root@k8s-master ~]# vim nginx.yml
[root@k8s-master ~]# cat nginx.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:latest
        name: nginx
        volumeMounts:
        - name: config-volume
          mountPath: /etc/nginx/conf.d     #挂载目录,在该目录下cm的键成为文件名,值成为文件内容

      volumes:
        - name: config-volume
          configMap:
            name: nginx-conf               #cm名字

测试:

测试可以访问该pod;

在该pod的nginx的目录下也有挂载的配置文件:

通过cm热更新修改配置:

所以当想要修改nginx的配置时,比如修改端口,只需要修改cm的配置,不用一个一个pod去修改。

[root@k8s-master storage]# kubectl edit cm nginx-conf   #修改cm

#配置文件内容

apiVersion: v1
data:
  nginx.conf: "server{\n\tlisten 80;\n\tserver_name _;\n\troot /usr/share/nginx/html;\n\tindex
    index.html;\n}\n"
kind: ConfigMap
metadata:
  creationTimestamp: "2024-09-15T08:21:02Z"
  name: nginx-conf
  namespace: default
  resourceVersion: "188837"
  uid: 15396d74-0151-4d02-8509-3f3234fb8a9e

#修改配置后,原有的pod的配置并不会修改,所以删除pod,pod会重启,重启后的pod遵循修改后的配置

[root@k8s-master storage]# kubectl delete pods nginx-8487c65cfc-9st6s 
pod "nginx-8487c65cfc-9st6s" deleted
[root@k8s-master storage]# kubectl get pods 
\NAME                     READY   STATUS    RESTARTS   AGE
nginx-8487c65cfc-d8kqd   1/1     Running   0          3s

测试:端口改为80,是nginx的默认端口,所以可以直接访问

 2、secrets

  • Secret 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 ssh key。

  • 敏感信息放在 secret 中比放在 Pod 的定义或者容器镜像中来说更加安全和灵活

  • Pod 可以用两种方式使用 secret:

    • 作为 volume 中的文件被挂载到 pod 中的一个或者多个容器里。

    • 当 kubelet 为 pod 拉取镜像时使用。

  • Secret的类型:

    • Service Account:Kubernetes 自动创建包含访问 API 凭据的 secret,并自动修改 pod 以使用此类型的 secret。

    • Opaque:使用base64编码存储信息,可以通过base64 --decode解码获得原始数据,因此安全性弱。

    • kubernetes.io/dockerconfigjson:用于存储docker registry的认证信息

(1)、secrets的创建

从文件创建

[root@k8s-master secrets]# echo -n gaoyingjie > username.txt
[root@k8s-master secrets]# echo -n gyj > username.txt
[root@k8s-master secrets]# kubectl create secret generic userlist --from-file username.txt --from-file ^C
[root@k8s-master secrets]# echo -n gaoyingjie > username.txt
[root@k8s-master secrets]# echo -n gaoyingjie > password.txt
[root@k8s-master secrets]# kubectl create secret generic userlist --from-file username.txt --from-file password.txt 
secret/userlist created
[root@k8s-master secrets]# kubectl get secrets userlist -o yaml
apiVersion: v1
data:
  password.txt: Z2FveWluZ2ppZQ==           #username已加密
  username.txt: Z2FveWluZ2ppZQ==           #password已加密
kind: Secret
metadata:
  creationTimestamp: "2024-09-15T11:54:24Z"
  name: userlist
  namespace: default
  resourceVersion: "200519"
  uid: 4a144911-0b46-4e1e-95b1-13b403cac262
type: Opaque

编写yml文件建立

#将要存储的username和password用base64加密
[root@k8s-master secrets]# echo -n gaoyingjie | base64
Z2FveWluZ2ppZQ==
[root@k8s-master secrets]# echo -n gyj | base64
Z3lq

#生成secrets配置文件
[root@k8s-master secrets]# kubectl create secret generic userlist --dry-run=client -o yaml > userlist.yml
[root@k8s-master secrets]# vim userlist.yml 

#配置文件内容
apiVersion: v1
kind: Secret
metadata:
  creationTimestamp: null
  name: userlist
type: Opaque
data:
  username: Z2FveWluZ2ppZQ==
  password: Z3lq


[root@k8s-master secrets]# kubectl apply -f userlist.yml 
secret/userlist created
[root@k8s-master secrets]# kubectl get secrets 
NAME           TYPE                             DATA   AGE
docker-login   kubernetes.io/dockerconfigjson   1      4d9h
userlist       Opaque                           2      10s
#查看
[root@k8s-master secrets]# kubectl describe secrets userlist 
Name:         userlist
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
username:  10 bytes
password:  3 bytes

[root@k8s-master secrets]# kubectl get secrets userlist -o yaml
apiVersion: v1
data:
  password: Z3lq
  username: Z2FveWluZ2ppZQ==
kind: Secret
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"password":"Z3lq","username":"Z2FveWluZ2ppZQ=="},"kind":"Secret","metadata":{"annotations":{},"creationTimestamp":null,"name":"userlist","namespace":"default"},"type":"Opaque"}
  creationTimestamp: "2024-09-15T12:02:45Z"
  name: userlist
  namespace: default
  resourceVersion: "201277"
  uid: 3ef997b4-aed7-4b2a-b05d-15064df95bae
type: Opaque

(2)、secrets的应用

  • 挂载卷
[root@k8s-master secrets]# vim pod1.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: nginx
  name: nginx
spec:
  containers:
  - image: nginx
    name: nginx
    volumeMounts:
    - name: secrets                 #卷的名字
      mountPath: /secret            #挂载路径
      readOnly: true                #卷为只读类型
#声明卷
  volumes:
  - name: secrets                    #声明卷的名字为secrets
    secret:
      secretName: userlist           #卷内的数据是secrets,名为userlist的sercrets也是以键值对的形式存储,
                                     #userlist里有两个键,那么挂载目录secret下就有两个文件名,userlist内键值对的两个值就是这两个文件的内容

[root@k8s-master secrets]# kubectl apply -f userlist.yml 
secret/userlist created
[root@k8s-master secrets]# kubectl apply -f pod1.yml
pod/nginx created
[root@k8s-master secrets]# kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          4s
[root@k8s-master secrets]# kubectl describe pod nginx
[root@k8s-master secrets]# kubectl exec pods/nginx -it -- /bin/bash      #进入容器查看

可以看到secret挂载点下有userlist的两个键,分别是两个文件username和password: 

集群资源的唯一凭证是建立k8s的时候自动建立的,删除后pod就不能使用集群资源了。

  • 向指定路径映射 secret 密钥
[root@k8s-master secrets]# vim pod2.yml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: nginx1
  name: nginx1
spec:
  containers:
  - image: nginx
    name: nginx1
    volumeMounts:
    - name: secrets
      mountPath: /secret
      readOnly: true

  volumes:
  - name: secrets
    secret:
      secretName: userlist
      items:                       #指定userlist的个别键放在指定路径下
      - key: username              #将userlist的键username放在my-users/username目录下
        path: my-users/username    #也可以指定别的键或者指定别的路径,比如 -key: password path: auth/password


[root@k8s-master secrets]# kubectl apply -f pod2.yml 
pod/nginx1 created
[root@k8s-master secrets]# kubectl get pods 
NAME     READY   STATUS    RESTARTS   AGE
nginx1   1/1     Running   0          6s
[root@k8s-master secrets]# kubectl exec -it pods/nginx1 -- /bin/bash

可以看到只有username:

  • 将secrets设置为环境变量
[root@k8s-master secrets]# vim pod3.yml
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: busybox
  name: busybox
spec:
  containers:
  - image: busybox
    name: busybox
    command:
    - /bin/sh
    - -c
    - env
    env:
    - name: USERNAME            #将userlist的键username赋给USERNAME
      valueFrom:
        secretKeyRef:
          name: userlist
          key: username
    - name: PASS                #将userlist的键password赋给PASS    
      valueFrom:
        secretKeyRef:
          name: userlist
          key: password
  restartPolicy: Never

[root@k8s-master secrets]# kubectl apply -f pod3.yml 
pod/busybox created

  •  存储docker registry的认证信息

docker registry的私有仓库上传和下载都需要验证,而共有仓库上传需要验证,下载不需要验证。

当k8s集群的某个节点想要下载私有仓库的镜像时,必须要登录认证,所以要进行集群化认证。

登录172.25.254.250(reg.gaoyingjie.org)创建名gyj的私有仓库
#登陆仓库
[root@k8s-master secrets]# docker login  reg.gaoyingjie.org
Authenticating with existing credentials...
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credential-stores

Login Succeeded

#上传镜像
[root@k8s-master secrets]# docker tag nginx:latest reg.gaoyingjie.org/gyj/nginx:latest
[root@k8s-master secrets]# docker push reg.gaoyingjie.org/gyj/nginx:latest
latest: digest: sha256:8a34fb9cb168c420604b6e5d32ca6d412cb0d533a826b313b190535c03fe9390 size: 1364
#建立用于docker认证的secret
[root@k8s-master secrets]# kubectl create secret docker-registry docker-auth --docker-server reg.gaoyingjie.org --docker-username admin --docker-password gyj --docker-email gaoyingjie@gaoyingjie.org 
secret/docker-auth created

#查看secrets
[root@k8s-master secrets]# kubectl get secrets 
NAME           TYPE                             DATA   AGE
docker-auth    kubernetes.io/dockerconfigjson   1      4m53s        #集群拉取镜像需要认证的secrets
docker-login   kubernetes.io/dockerconfigjson   1      4d11h
userlist       Opaque                           2      102m


[root@k8s-master secrets]# vim pod4.yml

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: nginx
  name: nginx
spec:
  containers:
    - image: reg.gaoyingjie.org/gyj/nginx:latest      #从私有仓库下载时要使用绝对路径
    name: nginx
  imagePullSecrets:                #添加创建的集群认证secrets,不设定docker认证时无法下载
  - name: docker-auth

#若没有 imagePullSecrets:- name: docker-auth(不添加集群认证secrtes),那么拉取镜像时会报错
[root@k8s-master secrets]# kubectl get pod
NAME    READY   STATUS         RESTARTS   AGE
nginx   0/1     ErrImagePull   0          35s        #拉取镜像报错errimagepull


#添加secrets后
[root@k8s-master secrets]# kubectl apply -f pod4.yml 
pod/nginx created
[root@k8s-master secrets]# kubectl get pods 
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          7s

3、volumes

  • 容器中文件在磁盘上是临时存放的,这给容器中运行的特殊应用程序带来一些问题

  • 当容器崩溃时,kubelet将重新启动容器,容器中的文件将会丢失,因为容器会以干净的状态重建。

  • 当在一个 Pod 中同时运行多个容器时,常常需要在这些容器之间共享文件。

  • Kubernetes 卷具有明确的生命周期与使用它的 Pod 相同

  • 卷比 Pod 中运行的任何容器的存活期都长,在容器重新启动时数据也会得到保留

  • 当一个 Pod 不再存在时,卷也将不再存在。

  • Kubernetes 可以支持许多类型的卷,Pod 也能同时使用任意数量的卷。

  • 卷不能挂载到其他卷,也不能与其他卷有硬链接。 Pod 中的每个容器必须独立地指定每个卷的挂载位置。

静态卷:emptyDir卷、hostpath卷、nfs卷。都是需要管理员手动指定,不能自动调用

(1)、emptyDir卷

当Pod指定到某个节点上时,首先创建的是一个emptyDir卷,并且只要 Pod 在该节点上运行,卷就一直存在。卷最初是空的。 尽管 Pod 中的容器挂载 emptyDir 卷的路径可能相同也可能不同,但是这些容器都可以读写 emptyDir 卷中相同的文件。 当 Pod 因为某些原因被从节点上删除时,emptyDir 卷中的数据也会永久删除,也就是说,emptyDir的生命周期和pod一样。

emptyDir 的使用场景:

  • 主要作用就是共享,对于所有pod之间的共享资源。
  • 缓存空间,例如基于磁盘的归并排序。

  • 耗时较长的计算任务提供检查点,以便任务能方便地从崩溃前状态恢复执行。

  • 在 Web 服务器容器服务数据时,保存内容管理器容器获取的文件。

[root@k8s-master ~]# mkdir volumes
[root@k8s-master volumes]# vim pod1.yml
apiVersion: v1
kind: Pod
metadata:
  name: vol1    #pod的名字
spec:
  containers:
  - image: busyboxplus:latest        #开启的镜像
    name: vm1                        #名字
    command:                    
    - /bin/sh
    - -c
    - sleep 30000000
    volumeMounts:
    - mountPath: /cache            #挂载目录
      name: cache-vol            #指定的卷的名字
  - image: nginx:latest
    name: vm2
    volumeMounts:
    - mountPath: /usr/share/nginx/html        
#挂载目录,在该目录下存储的内容就是存储到cache-vol卷中,同样,在该目录下存储的内容,可以在busyboxplus的挂载目录/cache下可以看到。
      name: cache-vol
  volumes:                          #声明卷
  - name: cache-vol                 #卷的名字
    emptyDir:                       #卷的类型
      medium: Memory                #卷的设备:内存    
      sizeLimit: 100Mi              #大小


[root@k8s-master volumes]# kubectl describe pod vol1
#进入容器查看
[root@k8s-master volumes]# kubectl exec -it pods/vol1 -c vm1 -- /bin/sh
/ # ls
bin      dev      home     lib64    media    opt      root     sbin     tmp      var
cache    etc      lib      linuxrc  mnt      proc     run      sys      usr
/ # cd cache/
/cache # echo gaoyingjie > index.html
/cache # ls
index.html
/cache # curl localhost        #basybox和nginx在一个pod内,共享网络栈,所以可以curl localhost
gaoyingjie
/cache # 

/cache # dd if=/dev/zero of=bigfile bs=1M count=99        #卷设置了100M 测试
99+0 records in
99+0 records out
/cache # dd if=/dev/zero of=bigfile bs=1M count=100
100+0 records in
99+1 records out
/cache # dd if=/dev/zero of=bigfile bs=1M count=101        #超过100则没有空间
dd: writing 'bigfile': No space left on device
101+0 records in
99+1 records out
/cache # 

(2)、hostpath卷

功能:

hostPath 卷能将主机节点文件系统上的文件或目录挂载到您的 Pod 中,不会因为pod关闭而被删除。也就是将该pod的一些资源存在本机上。

hostPath 的一些用法

  • 运行一个需要访问 Docker 引擎内部机制的容器,挂载 /var/lib/docker 路径。

  • 在容器中运行 cAdvisor(监控) 时,以 hostPath 方式挂载 /sys。

  • 允许 Pod 指定给定的 hostPath 在运行 Pod 之前是否应该存在,是否应该创建以及应该以什么方式存在

hostPath的安全隐患

  • 具有相同配置(例如从 podTemplate 创建)的多个 Pod 会由于节点上文件的不同而在不同节点上有不同的行为。

  • 当 Kubernetes 按照计划添加资源感知的调度时,这类调度机制将无法考虑由 hostPath 使用的资源。

  • 基础主机上创建的文件或目录只能由 root 用户写入。您需要在 特权容器 中以 root 身份运行进程,或者修改主机上的文件权限以便容器能够写入 hostPath 卷。

[root@k8s-master volumes]# vim pod2.yml
apiVersion: v1
kind: Pod
metadata:
  name: vol1
spec:
  containers:
  - image: nginx:latest
    name: vm1                                
    volumeMounts:
    - mountPath: /usr/share/nginx/html         #挂载目录,将主机/data的内容挂载到当前目录
      name: cache-vol
  volumes:
  - name: cache-vol                    #声明卷
    hostPath:                          #卷的类型
      path: /data                      #卷的路径(主机上的路径)
      type: DirectoryOrCreate		   #当/data目录不存在时自动建立


[root@k8s-master volumes]# kubectl apply -f pod2.yml 
pod/vol1 created
[root@k8s-master volumes]# kubectl get -o wide pods 
NAME   READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
vol1   1/1     Running   0          21s   10.244.36.85   k8s-node1   <none>           <none>

#pod在node1上
#node1是pod的主机,node1上有data目录
[root@k8s-node1 ~]# ll /data
总用量 0
[root@k8s-node1 ~]# cd /data
[root@k8s-node1 data]# echo gaoyingjie > index.html    #写入内容
[root@k8s-node1 data]# ls
index.html

[root@k8s-master volumes]# curl 10.244.36.85    #可以看到pod下/usr/share/nginx/html内容
gaoyingjie
#当pod被删除后
[root@k8s-master volumes]# kubectl delete -f pod2.yml --force

#主机hostpath卷不会删除
[root@k8s-node1 data]# ls
index.html
[root@k8s-node1 data]# cat index.html 
gaoyingjie
[root@k8s-node1 data]# 

(3)、nfs卷

NFS 卷允许将一个现有的 NFS 服务器上的目录挂载到 Kubernetes 中的 Pod 中。这对于在多个 Pod 之间共享数据或持久化存储数据非常有用

例如,如果有多个容器需要访问相同的数据集,或者需要将容器中的数据持久保存到外部存储,NFS 卷可以提供一种方便的解决方案。

意义:用另外一台主机做存储,k8s集群和集群数据资源不在同一台主机上,实现了存储分离。

准备工作:

4台主机都要安装nfs,175.25.254.250是nfs服务器,其他主机是为了访问nfs服务器。

[root@docker-harbor ~]# dnf install nfs-utils -y
[root@docker-harbor rhel9]# systemctl enable --now nfs-server.service
[root@docker-harbor rhel9]# systemctl status nfs-server.service 
#编辑策略文件
[root@docker-harbor ~]# vim /etc/exports
/nfsdata   *(rw,sync,no_root_squash)
#rw:读写,sync:数据完完整性同步,async:实时性同步,no_root_squash:设置权限,欣慰nfsdata是需要root权限

[root@docker-harbor ~]# exportfs -rv
exporting *:/nfsdata
#关闭火墙后查看,每台主机都能看到
[root@docker-harbor ~]# showmount -e 172.25.254.250
Export list for 172.25.254.250:
/nfsdata *
[root@k8s-master ~]# showmount -e 172.25.254.250
Export list for 172.25.254.250:
/nfsdata *

部署nfs卷:

[root@k8s-master volumes]# vim pod3.yml
apiVersion: v1
kind: Pod
metadata:
  name: vol1
spec:
  containers:
  - image: nginx:latest
    name: vm1
    volumeMounts:
    - mountPath: /usr/share/nginx/html        #卷挂载目录
      name: cache-vol
  volumes:                                    #声明卷
  - name: cache-vol                           #卷的名称
    nfs:                                      #使用的是nfs卷
      server: 172.25.254.250                  #nfs服务器的ip,就是挂载点ip
      path: /nfsdata                          #nfs共享出来的目录

#pod开启后会将/usr/share/nginx/html下的内容挂载到nfs服务器的/nfsdata目录下

[root@k8s-master volumes]# kubectl apply -f pod3.yml 
pod/vol1 created
[root@k8s-master volumes]# kubectl describe pod vol1 

#nfsdata目录下还没有内容,所以访问nginx的首发目录是403
[root@k8s-master volumes]# curl 10.244.36.87
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.27.1</center>
</body>
</html>
#进入nfsdata的目录下写入内容
[root@docker-harbor ~]# cd  /nfsdata/
[root@docker-harbor nfsdata]# echo gaoyingjie > index.html
[root@docker-harbor nfsdata]# ls
index.html

#再次查看,可以看到网页内容了
[root@k8s-master volumes]# curl 10.244.36.87
gaoyingjie

动态卷:持久卷。就是在使用资源时卷会自动建立。

(4)、持久卷

静态pv卷:

管理员手动建立pv,然后才能建立pvc,pod才能使用pvc申请pv。

[root@k8s-master pvc]# vim pv.yml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv1        #pv的名字
spec:                
  capacity:
    storage: 5Gi        #pv的大小
  volumeMode: Filesystem        #文件系统
  accessModes:
    - ReadWriteOnce        #访问模式:单点读写
  persistentVolumeReclaimPolicy: Retain      #回收模式:保留
  storageClassName: nfs        #存储类为nfs
  nfs:
    path: /nfsdata/pv1           #访问路径,将pv1的存储数据挂载到该目录下
    server: 172.25.254.250

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv2
spec:
  capacity:
    storage: 15Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteMany            #多点读写
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs
  nfs:
    path: /nfsdata/pv2
    server: 172.25.254.250
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv3
spec:
  capacity:
    storage: 25Gi
  volumeMode: Filesystem
  accessModes:
    - ReadOnlyMangy            #多点只读
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs
  nfs:
    path: /nfsdata/pv3
    server: 172.25.254.250

[root@k8s-master pvc]# kubectl apply -f pv.yml 
persistentvolume/pv1 unchanged
persistentvolume/pv2 unchanged
persistentvolume/pv3 created
[root@k8s-master pvc]# kubectl get pv
\NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   VOLUMEATTRIBUTESCLASS   REASON   AGE
pv1    5Gi        RWO            Retain           Available           nfs            <unset>                          37s
pv2    15Gi       RWX            Retain           Available           nfs            <unset>                          37s
pv3    25Gi       ROX            Retain           Available           nfs            <unset>  
[root@k8s-master pvc]# vim pvc.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc1               #名字可以随机,只看pvc的访问模式和请求大小这两个是否有匹配的pv
spec:
  storageClassName: nfs
  accessModes:
    - ReadWriteOnce            #pv和pvc的方式必须一致
  resources:
    requests:
      storage: 1Gi             #pvc1的请求大小比pv小,不能超过pv的大小

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc2
spec:
  storageClassName: nfs
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc3
spec:
  storageClassName: nfs
  accessModes:
    - ReadOnlyMany
  resources:
    requests:
      storage: 15Gi

[root@k8s-master pvc]# kubectl apply -f pvc.yml 
persistentvolumeclaim/pvc1 created
persistentvolumeclaim/pvc2 created
persistentvolumeclaim/pvc3 created
[root@k8s-master pvc]# kubectl get pvc
NAME   STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   VOLUMEATTRIBUTESCLASS   AGE
pvc1   Bound    pv1      5Gi        RWO            nfs            <unset>                 10s
pvc2   Bound    pv2      15Gi       RWX            nfs            <unset>                 10s
pvc3   Bound    pv3      25Gi       ROX            nfs            <unset>                 10s
[root@k8s-master pvc]# vim pod1.yml
apiVersion: v1
kind: Pod
metadata:
  name: gaoyingjie
spec:
  containers:
  - image: nginx
    name: nginx
    volumeMounts:
    - mountPath: /usr/share/nginx/html      #pv1挂载到该目录下,该目录最终访问的就是pv1的内容
      name: vol1
  volumes:                #声明卷
  - name: vol1
    persistentVolumeClaim:       #持久卷请求,用请求使用卷pv1
      claimName: pvc1


[root@k8s-master pvc]# kubectl apply -f pod1.yml 
pod/gaoyingjie created
[root@k8s-master pvc]# kubectl get pods 
NAME         READY   STATUS    RESTARTS   AGE
gaoyingjie   1/1     Running   0          10s
[root@k8s-master pvc]# kubectl describe pods gaoyingjie 
#pv1中没有内容时,访问不到
[root@k8s-master pvc]# kubectl get pods -o wide
NAME         READY   STATUS    RESTARTS   AGE    IP             NODE        NOMINATED NODE   READINESS GATES
gaoyingjie   1/1     Running   0          6m8s   10.244.36.88   k8s-node1   <none>           <none>
[root@k8s-master pvc]# curl 10.244.36.88 
<html>
<head><title>403 Forbidden</title></head>
<body>
<center><h1>403 Forbidden</h1></center>
<hr><center>nginx/1.27.1</center>
</body>
</html>

#在pv1中写入内容
[root@docker-harbor nfsdata]# echo gaoyingjie > pv1/index.html
#可以看到写入的内容
[root@k8s-master pvc]# curl 10.244.36.88 
gaoyingjie
#也可以进入容器中,看到pv1的内容已挂载到/usr/share/nginx/html/目录下
[root@k8s-master pvc]# kubectl exec -it pods/gaoyingjie -- /bin/bash
root@gaoyingjie:/# cd /usr/share/nginx/html/
root@gaoyingjie:/usr/share/nginx/html# ls
index.html
root@gaoyingjie:/usr/share/nginx/html# cat index.html 
gaoyingjie

4、存储类

动态pv

创建pvc的时候会调用存储类去自动创建目录,如果没有指定存储类则调用默认存储类(前提是有默认存储类,没有则pvc状态显示pending)

1、集群授权

[root@k8s-master storageclass]# vim rbac.yml
apiVersion: v1
kind: Namespace
metadata:
  name: nfs-client-provisioner        #名命空间
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  namespace: nfs-client-provisioner
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: nfs-client-provisioner
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  namespace: nfs-client-provisioner
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  namespace: nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: nfs-client-provisioner
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io


[root@k8s-master storageclass]# kubectl apply -f rbac.yml 
namespace/nfs-client-provisioner created
serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created

#查看rbac信息
[root@k8s-master storageclass]# kubectl -n nfs-client-provisioner get sa
NAME                     SECRETS   AGE
default                  0         18s
nfs-client-provisioner   0         19s

自动创建卷是由存储分配器来做,存储分配器用pod工作。

2、存储分配器所用的控制器

[root@k8s-master storageclass]# vim deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  namespace: nfs-client-provisioner            #命名空间
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: sig-storage/nfs-subdir-external-provisioner:v4.0.2
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner        #标签
            - name: NFS_SERVER
              value: 172.25.254.250
            - name: NFS_PATH                    #通过该变量识别nfs的地址和内容
              value: /nfsdata
      volumes:
        - name: nfs-client-root
          nfs:
            server: 172.25.254.250            #nfs服务器的ip
            path: /nfsdata                    #nfs的共享目录

#上传镜像到镜像仓库
[root@docker-harbor ~]# docker load  -i nfs-subdir-external-provisioner-4.0.2.tar 
1a5ede0c966b: Loading layer  3.052MB/3.052MB
ad321585b8f5: Loading layer  42.02MB/42.02MB
Loaded image: registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2

[root@docker-harbor ~]# docker tag registry.k8s.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2 reg.gaoyingjie.org/sig-storage/nfs-subdir-external-provisioner:v4.0.2

[root@docker-harbor ~]# docker push reg.gaoyingjie.org/sig-storage/nfs-subdir-external-provisioner:v4.0.2
The push refers to repository [reg.gaoyingjie.org/sig-storage/nfs-subdir-external-provisioner]
ad321585b8f5: Pushed 
1a5ede0c966b: Pushed 
v4.0.2: digest: sha256:f741e403b3ca161e784163de3ebde9190905fdbf7dfaa463620ab8f16c0f6423 size: 739


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2218113.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微积分复习笔记 Calculus Volume 1 - 2.5 Precise Definition of a Limit

2.5 The Precise Definition of a Limit - Calculus Volume 1 | OpenStax

Python基础——类与对象

类与对象的理解&#xff1a; 在程序中我们将类看作是设计图纸&#xff0c;对象则是根据这个图纸生产的产品。面向对象编程就是使用对象编程&#xff0c;在类中我们定义成员属性和方法。 来看下面这个例子&#xff0c;创建student类&#xff0c;定义对象并对属性赋值。 class S…

Golang | Leetcode Golang题解之第480题滑动窗口中位数

题目&#xff1a; 题解&#xff1a; type hp struct {sort.IntSlicesize int } func (h *hp) Push(v interface{}) { h.IntSlice append(h.IntSlice, v.(int)) } func (h *hp) Pop() interface{} { a : h.IntSlice; v : a[len(a)-1]; h.IntSlice a[:len(a)-1]; return v }…

十大云手机排行榜:哪个云手机更好用?

近些年&#xff0c;市场上涌现出许多云手机产品&#xff0c;不同产品适合的应用场景也各不相同。在选用云手机之前&#xff0c;企业和个人用户需要了解它们的功能、特点以及适用的场景。本文将对当前主流的云手机进行对比&#xff0c;帮助大家挑选出最适合的云手机产品。 1. 红…

200Kg大载重多旋无人机价格高昂技术分析

200Kg大载重多旋无人机作为一种高度专业化的航空工具&#xff0c;其价格相较于普通无人机显著较高&#xff0c;这主要是由于其在技术设计和生产过程中所需的高要求所致。以下是对其价格高昂的技术分析&#xff1a; 一、高性能材料与结构设计 1. 高强度轻量化材料&#xff1a;…

KafKa 集群【docker compose】

文章目录 主机准备部署编辑 docker-compose.ymlcontrollerbroker生成cluster_id 一篇完整的 docker-compose.yml 文件查看集群状态使用 kafka-ui 查看拉取 kafka-ui添加集群查看集群状态 使用命令行查看 配置讲解controllerbroker 主机准备 IPcontroller idbroker id192.168.1…

FreeRTOS的队列管理

“队列”提供了一种任务到任务、任务到中断和中断到任务的通信机制。 队列特性 数据存储 队列可以容纳有限数量的固定大小的数据项。队列可以容纳的最大项目数称为其“长度”。每个数据项的长度和大小都是在创建队列时设置的。 队列通常用作先进先出&#xff08;FIFO&#xf…

游戏逆向基础-跳出游戏线程发包

附加游戏后下断点 bp ws2_32.send send函数断下后&#xff0c;可以看到数据地址每次都一样 可以说明这个游戏是线程发包&#xff0c;所以直接在数据窗口中转到这个地址&#xff0c;然后对这个地址下硬件写入断点。 下了硬件写入断点后可以一层一层往上面跟&#xff0c;确定写…

RHCE--at,crontab例行性工作

一&#xff1a;安装at &#xff08;1&#xff09;配置yum仓库&#xff1a;以配置网络源举例&#xff1a; 先在/etc/yum.repos.d/ 目录下创建一个以.repo结尾的文件 vim /etc/yum.repos.d/aliyun.repo 写入可以在阿里云镜像站查找appstream和baseos的地址阿里巴巴开源镜像站…

tensorflow案例2--猴痘病识别,一道激活函数的bug

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 文章目录 1、bug2、模型构建1、数据处理1、导入库2、查看数据目录3、加载数据4、数据展示 2、内存优化3、模型构建4、模型训练1、超参数设置2、模型训练 5、结…

通过前端UI界面创建VUE项目

通过前端UI界面创建VUE项目&#xff0c;是比较方面的一种方式&#xff0c;下面我们详细分析一下流程&#xff1a; 1、找到合适目录 右键鼠标&#xff0c;点击在终端打开 2、开始创建 输入 vue ui 浏览器弹出页面 3、点击Create项目 显示已有文件列表&#xff0c;另外可以点击…

Docker部署一款小巧又强大的的自托管网站监控工具Uptime Kuma

文章目录 前言1.关于Uptime Kuma2.安装Docker3.本地部署Uptime Kuma4.使用Uptime Kuma5.cpolar内网穿透工具安装6.创建远程连接公网地址7.固定Uptime Kuma公网地址 &#x1f4a1; 推荐 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#…

CVE-2024-36971漏洞修复----Debian 10.13 内核升级

CVE-2024-36971漏洞修复---Debian 10.13 内核升级 1. 下载内核2. 安装依赖包3. 二进制安装3.1 上传3.2 解压3.3 修改配置文件3.4 编译3.5 安装内核及模块 4. 重启服务器并确认升级成功 1. 下载内核 到kernel.org下载新版的Kernel 由于开发那边不想让Kernel跨大版本,所以就升级…

【优选算法】——双指针(上篇)!

&#x1f308;个人主页&#xff1a;秋风起&#xff0c;再归来~&#x1f525;系列专栏&#xff1a;C刷题算法总结&#x1f516;克心守己&#xff0c;律己则安 目录 前言&#xff1a;双指针 1. 移动零&#xff08;easy&#xff09; 2. 复写零&#xff08;easy&#xff09; 3…

VSCode C/C++跳转到定义、自动补全、悬停提示突然失效

昨天像往常一样用vscode连接云服务器写代码&#xff0c;突然发现跳转到定义、自动补全、悬停提示功能全部不能正常使用了&#xff0c;今天折腾了一上午&#xff0c;看了一大堆教程&#xff0c;最后可算是解决了&#xff0c;因为大家说不定会遇到和我一样的问题&#xff0c;所以…

【工具篇】MLU运行XInference部署手册

文章目录 前言一、平台环境准备二、代码下载三、安装部署1.正常pip 安装 四、运行结果展示1.如果界面404或没有东西请这样做2.运行效果 前言 Xorbits Inference&#xff08;Xinference&#xff09;是一个功能强大、用途广泛的库&#xff0c;旨在为语言、语音识别和多模态模型提…

自监督学习:引领机器学习的新革命

引言 自监督学习&#xff08;Self-Supervised Learning&#xff09;近年来在机器学习领域取得了显著进展&#xff0c;成为人工智能研究的热门话题。不同于传统的监督学习和无监督学习&#xff0c;自监督学习通过利用未标注数据生成标签&#xff0c;从而大幅降低对人工标注数据…

数据库-01MYSQL-001MySQL知识点查漏补缺

MySQL知识点查漏补缺 数据库常识不常见知识点&#xff1a; 数据库常识 知识点001&#xff1a; between…and … 包含临界值。 知识点002&#xff1a;任何内容与null相加等于null。 知识点003&#xff1a;模糊查询涉及的函数有&#xff1a;like&#xff0c;between…and…, in/…

机器的“眼睛“:计算机视觉技术背后的魔法

计算机视觉&#xff0c;作为人工智能领域中的一颗璀璨明珠&#xff0c;正逐步改变着我们的生活方式。它赋予了机器“看”的能力&#xff0c;使得计算机能够从图像和视频中提取信息并进行分析&#xff0c;就像人类用眼睛和大脑来理解世界一样。本文将带你走进计算机视觉的世界&a…

解决linux服务器磁盘占满问题(详细,有效,100%解决)

应用场景&#xff1a; 在我们的日常开发中&#xff0c;我们的服务器总是在不知不觉中磁盘莫名奇妙少了很多空间&#xff0c;或者被占满了&#xff0c;如果这时候要想要存储什么文件&#xff0c;突然发现空间不够了。但我们通常也不知道那些文件占用的空间大&#xff0c;这时候…