一.资源利用率的概述
k8s容器创建的时候是随机分配的,如果随机分配时,有一个节点分配得比较多时,则会出现卡顿等等的事情;
1.metrics是什么
metrics是一个监控系统资源使用的插件,可以监控node节点上的CPU,内存的使用率,或pod对资源的占用率,通过对资源占用的了解,可以更加合理的部署容器应用
metrics从Kubernetes 1.8开始,资源使用情况的监控可以通过Metrics API的形式获取,具体的组件为Metrics Server,用来替换之前的heapster,heapster从1.11开始逐渐被废弃
2.查看资源占用情况
~]# kubectl top node error: Metrics API not available # 注意要先打开api并安装插件才能查看
metric-server是扩展的apiserver,依赖于kube-aggregator,因此需要在apiserver中开启相关参数,开启聚合API (也就是中继路由)
enable-aggregator-routing=true
二.部署metrics-server
1.开启apiserver聚合服务(中继路由)
1)开启聚合服务
# 添加参数 ~]# vim /etc/kubernetes/manifests/kube-apiserver.yaml #apiserver启动文件 # spec.containers.command 最下面手动添加如下一行(注意对对齐,否则所有查询会报错) - --enable-aggregator-routing=true ...... ~]# systemctl restart kubelet # 验证 ~]# kubectl -n kube-system get pod kube-apiserver-master -o yaml |grep enable-aggregator-routing
2)证书的申请与签发
注:如果没有证书是无法查看节点状态的
linux的用户k8s的用户的用户区别
linux用户存储在password
k8s用户,证书的签发机构,签发证书可信(在k8s内只记录一小时,一小时后删除记录,但是只要k8s签发过的就可以在k8s内用),所以在k8s内有用户的概念,但是不能查找用户,只要用户带有签发的证书就可以登录k8s;所以node节点想要查询就要有证书
metrics使用证书,为kubelet签发证书
在文件var/lib/kubelet/config.yaml的配置文件中添加
~]# vim /var/lib/kubelet/config.yaml serverTLSBootstrap: true
重启kubelet服务,等待几分钟就能看到了
包括master在内的所有节点都需要做
# 默认情况下是没有开启证书签发的(在master操作) ~]# kubectl get csr No resources found # 申请证书示例(在所有节点操作) ~]# vim /var/lib/kubelet/config.yaml # 在文件的最后一行添加申请证书;注:改错节点服务会起不来 serverTLSBootstrap: true # 重启kubelet(在所有节点操作) ~]# systemctl restart kubelet # 查看(master操作) ~]# kubectl get csr NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION csr-6fbtl 91s kubernetes.io/kubelet-serving system:node:node1 <none> Pending csr-bctqw 11m kubernetes.io/kubelet-serving system:node:master <none> Pending csr-bz6hx 2m14s kubernetes.io/kube-apiserver-client-kubelet system:node:vm-0-114-centos <none> Pending csr-gk7tx 62s kubernetes.io/kubelet-serving system:node:vm-0-142-centos <none> Pending # ----------------签发证书必须在 master 上执行 ------------------------- # 看到Pending的状态我们就可以签发证书了(每台都签发一下) ~]# kubectl get csr | awk '{print $1}'| grep -v NAME| xargs -i kubectl certificate approve {} ~]# kubectl get csr NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION csr-6fbtl 91s kubernetes.io/kubelet-serving system:node:node1 <none> Approved,Issued csr-bctqw 11m kubernetes.io/kubelet-serving system:node:master <none> Approved,Issued csr-bz6hx 2m14s kubernetes.io/kube-apiserver-client-kubelet system:node:vm-0-114-centos <none> Approved,Issued csr-gk7tx 62s kubernetes.io/kubelet-serving system:node:vm-0-142-centos <none> Approved,Issued # Approved,Issued则是签发成功 # 申请的多余证书可以使用 (kubectl delete certificatesigningrequests 证书名称) 删除;如果误删了证书删除也不需要再申请,因为已经有记录了
2.安装mertics插件
1)官网
2)下载镜像和资源文件,并导入私有仓库
rbac.yaml 授权控制器
pdb.yaml 中断控制器
deployment.yaml 主进程metrics(修改镜像地址)
service.yaml 后端metrics主进程服务
apiservice.yaml 注册集群API
## 先导入镜像然后操作(这里我找了一些资料暂时没找到国内的镜像,所以如果要安装部署metrics的话要跨网) ~]# docker load -i metrisc-server.tar.gz ~]# docker tag gcr.io/k8s-staging-metrics-server/metrics-server:master 172.17.0.98:5000/metrics-server:master ~]# docker push 172.17.0.98:5000/metrics-server:master ## 第一步安装授权控制器 # 手动书写文件或官方下载 ~]# vim rbac.yaml --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: system:aggregated-metrics-reader labels: rbac.authorization.k8s.io/aggregate-to-view: "true" rbac.authorization.k8s.io/aggregate-to-edit: "true" rbac.authorization.k8s.io/aggregate-to-admin: "true" rules: - apiGroups: ["metrics.k8s.io"] resources: ["pods", "nodes"] verbs: ["get", "list", "watch"] --- apiVersion: v1 kind: ServiceAccount metadata: name: metrics-server namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: metrics-server-auth-reader namespace: kube-system roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: extension-apiserver-authentication-reader subjects: - kind: ServiceAccount name: metrics-server namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: metrics-server:system:auth-delegator roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:auth-delegator subjects: - kind: ServiceAccount name: metrics-server namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: system:metrics-server rules: - apiGroups: - "" resources: - pods - nodes - nodes/stats - namespaces - configmaps verbs: - get - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: system:metrics-server roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:metrics-server subjects: - kind: ServiceAccount name: metrics-server namespace: kube-system # 安装授权控制器 ~]# kubectl apply -f rbac.yaml clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created serviceaccount/metrics-server created rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created clusterrole.rbac.authorization.k8s.io/system:metrics-server created clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created ## 第二步安装中断控制器 # 官方下载文件或手动书写 ~]# vim pdb.yaml --- apiVersion: policy/v1beta1 kind: PodDisruptionBudget metadata: name: metrics-server namespace: kube-system labels: k8s-app: metrics-server spec: minAvailable: 100% selector: matchLabels: k8s-app: metrics-server # 安装中断控制器 ~]# kubectl apply -f pdb.yaml Warning: policy/v1beta1 PodDisruptionBudget is deprecated in v1.21+, unavailable in v1.25+; use policy/v1 PodDisruptionBudget poddisruptionbudget.policy/metrics-server created ## 第三安装主进程 # 官方下载文件或手动书写 ~]# vim deployment.yaml --- apiVersion: apps/v1 kind: Deployment metadata: name: metrics-server namespace: kube-system labels: k8s-app: metrics-server spec: selector: matchLabels: k8s-app: metrics-server strategy: rollingUpdate: maxUnavailable: 0 template: metadata: name: metrics-server labels: k8s-app: metrics-server spec: serviceAccountName: metrics-server volumes: # mount in tmp so we can safely use from-scratch images and/or read-only containers - name: tmp-dir emptyDir: {} containers: - name: metrics-server image: gcr.io/k8s-staging-metrics-server/metrics-server:master imagePullPolicy: IfNotPresent args: - --cert-dir=/tmp - --secure-port=4443 - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname - --kubelet-use-node-status-port # - --kubelet-insecure-tls ports: - name: main-port containerPort: 4443 protocol: TCP readinessProbe: httpGet: path: /healthz port: main-port scheme: HTTPS securityContext: readOnlyRootFilesystem: true runAsNonRoot: true runAsUser: 1000 volumeMounts: - name: tmp-dir mountPath: /tmp nodeSelector: kubernetes.io/os: linux # 安装主进程 ~]# kubectl apply -f deployment.yaml deployment.apps/metrics-server created ## 第四安装service服务 # 官方下载文件或手动书写 ~]# vim service.yaml --- apiVersion: v1 kind: Service metadata: name: metrics-server namespace: kube-system labels: kubernetes.io/name: "Metrics-server" kubernetes.io/cluster-service: "true" spec: selector: k8s-app: metrics-server ports: - port: 443 protocol: TCP targetPort: main-port # 装service服务 ~]# kubectl apply -f service.yaml service/metrics-server created ## 最后安装集群api # 官方下载文件或手动书写 ~]# vim apiservice.yaml --- apiVersion: apiregistration.k8s.io/v1beta1 kind: APIService metadata: name: v1beta1.metrics.k8s.io spec: service: name: metrics-server namespace: kube-system group: metrics.k8s.io version: v1beta1 insecureSkipTLSVerify: true groupPriorityMinimum: 100 versionPriority: 100 # 安装集群api ~]# kubectl apply -f apiservice.yaml apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created #-------------------------------- 查询验证 ---------------------------------------------- ~]# kubectl -n kube-system get pod NAME READY STATUS RESTARTS AGE metrics-server-78dfb54777-4dcjl 1/1 Running 0 116s ~]# kubectl -n kube-system get apiservices | grep metrics NAME SERVICE AVAILABLE AGE v1beta1.metrics.k8s.io kube-system/metrics-server True 2m20s # 如果安装成功了就可以查看节点资源了 ~]# kubectl top node NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% master 95m 4% 840Mi 48% node-0001 24m 1% 266Mi 15% node-0002 24m 1% 270Mi 15% node-0003 26m 1% 280Mi 16% #CPU(cores):毫核 1000分之95秒(把每个执行的周期分为1000,那么一个周期就是95毫秒) #CPU% CPU / 内核数:(两内核就是2000) # HPA就是根据资源占用情况来做的
## 监控容器的示例 # 安装之前写的myapache创建一个容器 ~]# kubectl apply -f myapache.yaml deployment.apps/myapache created # 查看pod容器的资源 ~]# kubectl top pod error: metrics not available yet # 等待大约 30 秒 ~]# kubectl top pod NAME CPU(cores) MEMORY(bytes) myapache-7d689bf8f-lfr5h 1m 6Mi # 设置访问次数来实验pod ~]# curl http://10.244.2.17/info.html?id=5000000 <pre> Array ( [REMOTE_ADDR] => 10.244.0.0 [REQUEST_METHOD] => GET [HTTP_USER_AGENT] => curl/7.29.0 [REQUEST_URI] => /info.php?id=5000000 [id] => 5000000 ) php_host: myapache-7d689bf8f-lfr5h ~]# kubectl top pod NAME CPU(cores) MEMORY(bytes) myapache-7d689bf8f-w4rtt 1000m 8Mi
三.同一个pod运行多容器
类似于容器之间同一个网络,这里是同一个名称空间,也就是一个pod多个容器,那么他们的网卡,主机名等都是共用的
~]# vim webnginx.yaml --- kind: Deployment apiVersion: apps/v1 metadata: name: webnginx spec: selector: matchLabels: myapp: nginx replicas: 1 template: metadata: labels: myapp: nginx spec: volumes: - name: nginx-php configMap: name: nginx-conf containers: - name: nginx image: 172.17.0.98:5000/myos:nginx2 volumeMounts: - name: nginx-php subPath: nginx.conf mountPath: /data/nginx/conf/nginx.conf ports: - protocol: TCP containerPort: 80 - name: php # 在containers字段中添加一个容器 image: 172.17.0.98:5000/myos:nginx2 ports: # 开放端口(可以不写,运用内部io传递的) - protocol: TCP containerPort: 80 restartPolicy: Always # 先当于在文件中添加一个容器
# 创建 ~]# kubectl apply -f webnginx.yaml # 查看验证 ]# kubectl get pods NAME READY STATUS RESTARTS AGE webnginx-7567f4f8d7-rbv9r 2/2 Running 1 (2s ago) 4s # 查看日志 ~]# kubectl describe pods -n default webnginx-7567f4f8d7-rbv9r ]# kubectl logs webnginx-7567f4f8d7-rbv9r error: a container name must be specified for pod webnginx-7567f4f8d7-rbv9r, choose one of: [nginx php] # 此时就不能直接logs查看了,要指定容器 ~]# kubectl logs webnginx-7567f4f8d7-rbv9r -c nginx ~]# kubectl logs webnginx-7567f4f8d7-rbv9r -c php # 进入容器也要指定容器 ~]# kubectl exec -it webnginx-7567f4f8d7-rbv9r -c nginx -- /bin/bash ~]# kubectl exec -it webnginx-7567f4f8d7-rbv9r -c php -- /bin/bash # 测试 ~]# kubectl exec -it webnginx-7567f4f8d7-rbv9r -c nginx -- /bin/bash ~]# ss -ltun Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port tcp LISTEN 0 128 *:80 *:* tcp LISTEN 0 128 127.0.0.1:9000 *:* /]# exit ~]# curl http://10.244.2.25/info.php <pre> Array ( [REMOTE_ADDR] => 10.244.0.0 [REQUEST_METHOD] => GET [HTTP_USER_AGENT] => curl/7.29.0 [REQUEST_URI] => /info.php ) php_host: webnginx-6c9f6fd675-7rmzk 1229
四.存储卷
1.临时卷的概述
1)存储卷的用途
-容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一-些问题。首先,当容器崩溃时,kubelet会重启它,但是容器中的文件将丢失------容器以干净的状态(镜像最初的状态)重新启动。其次,在Pod中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes中的Volume抽象就很好的解决了这些问题。
2)存储卷的简介
-存储卷分为临时与持久,按照时间的长短决定存储卷的类别
-如果不使用存储卷的话则要进入容器修改,维护起来不方便
-docker是使用外挂的存储卷,首先在外部修改完要的配置,然后通过存储卷的方式挂载到容器内部,从而达到修改容器内的配置
-k8s使用的就是ConfigMap(储存在内存的数据,临时的,启动的时候有,退出之后消失)
-目前k8s支持的Volume卷类型(1.17)
awsElasticBlockStore downwardAPI glusterfs projected azureDisk emptyDir hostPath quobyte azureFile fc iscsi rbd cephfs flexVolume nfs scalelO cinder flocker persistentVolumeClaim secret configMap gcePersistentDisk photonPersistentDisk storageos csi gitRepo portworxVolume vsphereVolume
4)临时的用途
有些应用程序需要额外的存储,但不关心数据在重启仍然可用,既是否被持久地保存,例如:缓存服务经常受限于内存大小,将不常用的数据转移到比内存慢,但对总体性能的影响很小的存储中
5)常见的临时卷
emptyDir,configMap,downwardAPI,secret
2.ConfigMap临时卷的概述
ConfigMap的作用
ConfigMap是在Pod中映射(文件/目录)的一种方式,允许你将配置文件与镜像文件分离,以使容器化的应用程序具有可移植性,在内存中运行,所以不适合大的文件(>10M),最好是明文的,比如配置文件
为什么要用Configmap
在日常工作中经常要修改各种配置文件的参数,数据库的地址,用户名密码等,这些操作在容器内容非常麻烦,POD在重启或者迁移的时候又会恢复到初始的状态,使用ConfigMap就可以解决这样的问题
ConfigMap配置
cionfigmap可以映射单一文件,也可以映射一个目录
创建configmap
kubectl create configmap [名称] --from-file=文件路径(文件夹/目录)
## 示例 #先创建一个目录用来存放配置文件 ~]# mkdir web # 创建nginx容器并放入后台运行 ~]# docker run -itd --name mynginx 172.17.0.98:5000/myos:nginx2 # 拷贝配置文件到本地 ~]# docker cp mynginx:/data/nginx/conf/nginx.conf /root/web # 删除容器 ~]# docker stop mynginx && docker rm mynginx # 把下载下来的文件修改(使其支持php) ~]# vim nginx.conf .... location ~ \.php$ { root html; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name; include fastcgi.conf; } ..... # 创建configmap ]# kubectl create configmap nginx-conf --from-file=/root/web/nginx.conf configmap/nginx-conf created # 查看 ~]# kubectl get configmap NAME DATA AGE nginx-conf 1 26s # 以yaml格式查看 ~]# kubectl get configmap nginx-conf -o yaml
注:1.由于 apache 与 nginx 都使用 80 端口,把之前的实验容器全部删除
2.configMap可以映射单一文件,也可以映射一目录
3.使用ConfigMap创建资源文件
# 使用configmap资源示例 ~]# vim webnginx.yaml --- # 资源文件的开始--- kind: Deployment # 定义资源类型 apiVersion: apps/v1 # 该类型的版本 metadata: # 该资源的元数据 name: webnginx # 资源名 spec: # 资源的详细信息 selector: # 以标签来控制容器 matchLabels: # 定义标签组 myapp: nginx # 标签名 replicas: 1 # 启动的副本数 template: # pod的模板 metadata: # pod的元数据 labels: # 定义pod标签 myapp: nginx # 标签名 spec: # pod的详细信息 volumes: # 定义卷的格式 - name: nginx-php # 卷的名字(这里自定义) configMap: # 定义加载类型(configmap) name: nginx-conf # 定义加载的名字(必须与之前创建的名字相同) containers: # 容器的定义 - name: nginx # 容器名 image: 172.17.0.98:5000/myos:nginx2 # 镜像 volumeMounts: # 卷加载的路径 - name: nginx-php # 加载的名字需和上面定义的名字相同 subPath: nginx.conf # 本地的文件路径 mountPath: /data/nginx/conf/nginx.conf # 要加载的路径 ports: # 开放端口 - protocol: TCP # 端口类型 containerPort: 80 # 端口号 restartPolicy: Always # 支持滚动升级 # 添加 ~]# kubectl apply -f webnginx.yaml deployment.apps/webnginx created ~]# kubectl get pod NAME READY STATUS RESTARTS AGE webnginx-844859695b-5s7m7 1/1 Running 0 10s ~]# kubectl exec -it webnginx-844859695b-5s7m7 -- /bin/bash # 查看配置文件是否改变了 /]# cat /usr/local/nginx/conf/nginx.conf /]# ss -ltun Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port tcp LISTEN 0 128 *:80 *:*
注:创建完configmap之后就会加入etcd数据库中,当kubelet收到要创建的configmap时就会从etcd中拿取,发到内存地址里,然后创建容器时会把configmap加入到容器内部,所以在任意节点加入容器都可以用
4.emptyDir临时卷的概述
emptyDir是最基础的Volume类型,用于存储临时数据的简单空目录,如果Pod设置了emptyDir类型Volume,Pod被分配到Node上时候,会创建emptyDir,只要Pod运行在Node上,emptyDir都会存在(容器挂掉不会导致emptyDir丢失数据),但如果Pod从Node上被删除(Pod被删除,或Pod发生迁移),emptyDir也会被删除,并且永久丢失。
emptyDir可以实现同一个pod中数据的共享
emptydir 存储卷(空文夹)临时卷示例
~]# vim webcache.yaml --- kind: Deployment apiVersion: apps/v1 metadata: name: webcache spec: selector: matchLabels: myapp: cache replicas: 1 template: metadata: labels: myapp: cache spec: volumes: # 新添加 - name: empty-data # 新添加 emptyDir: {} # 新添加 containers: - name: apache image: 192.168.1.100:5000/myos:httpd stdin: false tty: false volumeMounts: # 新添加 - name: empty-data # 新添加 mountPath: /var/cache # 新添加 ports: - protocol: TCP containerPort: 80 restartPolicy: Always ~]# kubectl apply -f webcache.yaml deployment.apps/webcache created ~]# kubectl exec -it webcache-c58847c54-qw9lh -- /bin/bash \]# df -h Filesystem Size Used Avail Use% Mounted on /dev/vda1 40G 2.9G 35G 8% /var/cache ... ...
5.持久卷的概述
1)持久卷的用途
-容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题,首先,当容器崩溃时,kubelet会重启它,但是容器中的文件将丢失——容器以干净的状态(镜像最初的状态)重新启动,其次,在Pod中同时运行多个容器时,这些容器之间通常需要共享文件,Kuberbetes中的Volume 抽象就很好的解决了这些问题。
6.hostpath 持久存储卷
-hostPath类型则是映射node文件系统中的文件或者目录到pod里,在使用hostPath类型的存储时,也可以设置type字段,支持类型文件,目录,file,Sochet,CharDevice和BlockDevice
-注意事项:配置相同的pod,可能在不同的Node上表现不同,因为不同节点上映射的文件内容不同
-hostPath里的数据不会随着Pod的结束二结束而消失
-就是docker -v
以apache为例
当客户端来访问,通过service负载均摊给后端服务,后端的pod利用本地的共享目录存储数据
hostpath 存储卷示例
hostPath的规则类型(可到官网查询)
~]# vim webcache.yaml --- kind: Deployment apiVersion: apps/v1 metadata: name: webcache spec: selector: matchLabels: myapp: cache replicas: 1 template: metadata: labels: myapp: cache spec: volumes: - name: empty-data emptyDir: {} - name: log-data # 日志文件名 hostPath: # 映射类型 path: /var/weblog # 要映射的目录 type: DirectoryOrCreate # 定义规则,当该文件不存在时自动创建 containers: - name: apache image: 172.17.0.98:5000/myos:httpd stdin: false tty: false volumeMounts: - name: empty-data mountPath: /var/cache - name: log-data # 挂载的名字(上面创建的) mountPath: /var/log/httpd # 挂载到容器的文件里 ports: - protocol: TCP containerPort: 80 restartPolicy: Always
# 创建 ~]# kubectl apply -f webcache.yaml deployment.apps/webcache created # 查看 ~]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE webcache-75588b9cc5-xzkvc 1/1 Running 0 4s 10.244.2.30 node-0002 ~]# curl http://10.244.2.30/ this is apache # 远程到node节点上 ~]# ssh 192.168.1.32 # 查看共享文件日志 ~]# ls -l /var/weblog/ total 16 -rw-r--r-- 1 root root 86 Apr 26 13:12 access_log -rw-r--r-- 1 root root 489 Apr 26 13:12 error_log ~]# cat /var/weblog/access_log 10.244.0.0 - - [26/Apr/2021:05:12:59 +0000] "GET / HTTP/1.1" 200 15 "-" "curl/7.29.0"
7.NFS共享卷
在生产环境中经常需要多个Pod或在多个APP中共享数据,二这些应用又在不同的机器的不同Pod里面,同网络文件系统经常用来解决这一问题
Kubernetes中通过简单地配置就可以挂载NFS到Pod中,而NFS中的数据是可以永久保存的,同时NFS支持并发写操作
注:cephfs.glusterfs等都能很好的解决这些个问题,我们以NFS为例
1)搭建NFS服务器
# 在仓库节点上搭建nfs服务器 ~]# yum install -y nfs-utils ~]# mkdir -m 777 /var/webroot ~]# vim /etc/exports /var/webroot *(rw) ~]# systemctl enable --now nfs #---------------------------------所有节点都需要 nfs模块 软件包------------------------- ~]# yum install -y nfs-utils #-------------------------------下面在任意其他节点测试------------------------------ ~]# showmount -e 192.168.1.100 Export list for 192.168.1.100: /var/webroot *
2)手工配置
~]# vim nfsapache.yaml --- kind: Deployment apiVersion: apps/v1 metadata: name: webcache spec: selector: matchLabels: myapp: cache replicas: 1 template: metadata: labels: myapp: cache spec: volumes: - name: empty-data emptyDir: {} - name: log-data hostPath: path: /var/weblog type: DirectoryOrCreate - name: web-site # 起一个名字下面调用 nfs: # 添加类型 server: 172.17.0.98 # 主机ip path: /var/webroot # 挂载本地的路径 containers: - name: apache image: 172.17.0.98:5000/myos:httpd stdin: false tty: false volumeMounts: - name: empty-data mountPath: /var/cache - name: log-data mountPath: /var/log/httpd - name: web-site # 挂载的名字(上面创建的) mountPath: /var/www/html # 容器内部挂载点 ports: - protocol: TCP containerPort: 80 restartPolicy: Always ~]# kubectl apply -f nfsapache.yaml ~]# kubectl exec -it [容器名] -- /bin/bash # 查看挂载 ~]# df -h | grep "172.17.0.98"
2)PV/PVC的配置
PV/PVC的概述
-PersistentVolume(持久卷,简称PV)
-PV是资源的提供者,根据集群的基础设施变化二变化,由k8s集群管理员配置
-Persistent VolumeClaim(持久声明,简称PVC)
-PVC是资源的使用者,根据业务服务的需求而变化来配置(不需要理解底层)
PV/PVS的引用使k8s集群具备了存储的 逻辑抽象能力
配置PV(NFS资源)
# 定义pv ~]# vim mypv.yaml --- kind: PersistentVolume apiVersion: v1 metadata: name: pv-nfs spec: volumeMode: Filesystem # 支持的模式文件夹 capacity: # 支持的空间 storage: 30Gi # 30G accessModes: # 支持的模式 - ReadWriteOnce # 单人模式(读写) - ReadOnlyMany # 多人只读 - ReadWriteMany # 多人读写 persistentVolumeReclaimPolicy: Retain # 数据回收方式(手工或自动) nfs: # 类型nfs server: 172.17.0.98 # 服务器ip path: /var/webroot # 文件 官网查看支持的模式持久卷 | Kubernetes ~]# kubectl apply -f mypv.yaml persistentvolume/pv-nfs created ~]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS AGE pv-nfs 30Gi RWO,ROX,RWX Retain Available 3s
创建 pvc
# 声明pv ~]# vim mypvc.yaml --- kind: PersistentVolumeClaim apiVersion: v1 metadata: name: pvc-nfs spec: volumeMode: Filesystem # 支持文件系统 accessModes: # 支持的类型 - ReadWriteMany # 多人读写 resources: # 存储需求 requests: # 最大支持 storage: 25Gi # 25G ~]# kubectl apply -f mypvc.yaml ~]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM pv-nfs 30Gi RWX Retain Bound default/pvc-nfs ~]# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc-nfs Bound pv-nfs 30Gi RWO,ROX,RWX 27s
应用持久卷
~]# vim webnginx.yaml --- kind: Deployment apiVersion: apps/v1 metadata: name: webnginx spec: selector: matchLabels: myapp: nginx replicas: 1 template: metadata: labels: myapp: nginx spec: volumes: - name: nginx-php configMap: name: nginx-conf - name: website # 添加名字(下面好调用) persistentVolumeClaim: # 卷的类型 claimName: pvc-nfs # 声明的pvc名 containers: - name: nginx image: 192.168.1.100:5000/myos:nginx volumeMounts: - name: nginx-php subPath: nginx.conf mountPath: /usr/local/nginx/conf/nginx.conf - name: website # 上面创建的名字(调用) mountPath: /usr/local/nginx/html # 本地路径 ports: - protocol: TCP containerPort: 80 - name: php-backend image: 192.168.1.100:5000/myos:php-fpm volumeMounts: # 容器挂载点 - name: website # 于上面声明的名字一样 mountPath: /usr/local/nginx/html # 容器内挂载点 restartPolicy: Always
# 删除旧的创建 ~]# kubectl delete -f webnginx.yaml deployment.apps "webnginx" deleted ~]# kubectl apply -f webnginx.yaml deployment.apps/webnginx created ~]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE webnginx-d488b9447-t62cl 2/2 Running 0 7s 10.244.2.32 node-0002 # 访问测试 ~]# curl http://10.244.2.32/ # 在 nfs 上创建修改页面,然后在容器端访问测试