1. 概述
1.1 基本介绍
集群统一入口,以restful方式,交个etcd存储
- scheduler
节点调度,选择node节点应用部署
- controller-manager
处理集群中常规后台任务,一个资源对应一个控制器
- etcd
存储系统,用于保存集群相关的数据
node 组件
- kube let
master排到node节点代表,管理本机容器
- kube-proxy
1.3 k8s核心概念
Pod
- 最小部署单元
- 一组容器(如Docker容器)的集合
- 共享网络,一个pod中的网络共享
- 声明周期是短暂的
- 一个Pod有一个特殊的被称为“根容器”的Pause容器
Controller
- 定期检查系统中存活的Pod,确保预期的pod数量和Replication Controller(RC)提交的一致
- 支持无状态应用部署
- 支持有状态应用部署
- 确保所有的node运行同一个pod
- 定义一次性任务和定时任务
Service
kubectl [common] [TYPE] [NAME] [flags]
[root@master1 ~]# kubectl get nodes node2
帮助命令
kubectl --help
具体查看某个操作
kubectl get --help
目前使用到的命令
#部署一个服务
kubectl create deployment nginx --image=nginx
#开放服务端口
kubectl expose deployment nginx --port=80 --type=NodePort
#查看已经部署服务
kubectl get pod,svc
#通过yaml文件部署服务
kubectl apply -f
#查看controller服务
kubectl get cs
#查看node节点
kubectl get nodes
3.2 如何快速编写yaml文件
# 第一种:使用kubectl create 命令生成yaml文件,新建一条yaml文件
kubectl create deployment web1 --image=nginx --dry-run -o yaml > deployment.yaml
第二种:使用kubectl get 命令导出yaml文件,用已经创建好的pod来生成yaml文件
kubectl get deploy
kubectl get deploy nginx -o=yaml --export > de.yaml
4. POD 最小单元
4.1 Pod节本概念
- 最小部署的单元
- 包含多个容器(一组容器(如Docker容器)的集合)
- 一个pod中容器共享网络命名空间
-
4.2 Pod存在的意义
创建容器使用docker,一个docker对应一个容器,一个容器有进程,一个容器运行一个应用程序
- Pod是多进程设计,运行多个应用程序(一个Pod 有多个容器,一个容器里面运行一个应用程序)
- Pod存在为了亲密性应用
- 两个应用之间进行交互
- 网络之间调用
- 两个应用需要频繁调用
4.3 共享网络
共享网络
通过Pause容器(每个pod默认都包含有一个Pause容器),把其他容器加入到Pause容器里面,让所有业务容器在同一个名称空间中,可以实现网络共享
共享存储
引入数据卷概念Volumn,使用数据卷进行持久化存储4.4 Pod镜像拉取策略
pod提供三种镜像拉取策略
IfNotPresent: 默认值,镜像在宿主机上不存在时才拉取
Always:每次创建Pod 都会重新拉取一次镜像
Never: Pod 永远不会主动拉取这个镜像4.5 Pod资源限制
pod提供对节点主机资源的上限和下限限制resources:
requests:
memory: "64Mi" #对内存最小调度限制
cpu: "250m" #对cpu最小调度限制
limits:
memory: "128Mi" #对内存最大调度限制
cpu: "500m" #对cpu最大调度限制
4.6 Pod重启策略
yaml文件中用restartPolicy:Never 表示重启机制,提供三种重启机制
Always:当容器终止退出后,总是重启容器,默认策略
OnFailure:当容器异常退出(退出状态码非0)时,才重启容器
Never:当容器终止退出,从不重启容器4.7 Pod健康检查
```yamllivenessProbe (存活检查)
如果检查失败,将杀死容器,根据Pod的restartPolicy来操作
readinessProbe (就绪检查)
如果检查失败,Kubernetes会把Pod从service endpoints中剔除
```yaml
# Probe 支持以下三种检查方式
## httpGet
### 发送HTTP请求,返回200-400范围状态码为成功
## exec
### 执行Shell命令返回状态码是0为成功
## tcpSocket
### 发起TCP Socket建立成功
4.8 Pod创建流程
说明:
master节点
- createpod — apiserver — etcd
- scheduler — apiserver — etcd — 调度算法,把pod调度某个node节点上
node节点
- kubelet — apiserver — 读取etcd拿到分配给当前节点pod — docker 创建容器
4.9 Pod调度节点亲和性
硬亲和性: 约束条件必须满足spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- nodeSelectorTerms:
- key: env role
operator: In
values:
- dev
- test
软亲和性: 尝试满足,不保证一定满足
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
-key: group
operator: In
values:
- otherprod
4.10 Pod调度节点选择器
Pod资源限制对Pod调用产生影响
resources:
requests:
memory: "64Mi"
cpu: "250m"
节点选择器标签影响Pod调度
spec:
nodeSelector:
env_role: dev
4.11 Pod调度污点和污点容忍
- 基本介绍
nodeSelector和nodeAffinity:Pod调度到某些节点上,Pod属性调度时候实现
Taint污点:节点不做普通分配调度,是节点属性
- 使用场景
- 专用节点
- 配置特点硬件节点
- 基于Taint驱逐
- 查看节点污点情况
#kubectl describe node [节点名称] | grep Taint
kubectl describe node k8smaster | grep Taint
污点有三个值
NoSchedule:一定不被调用
PreferNoSchdule: 尽量不被调度
NoExecute:不会调度,并且还会驱逐Node已有Pod
为节点添加污点
#kubectl taint node [节点名称] key=value:[污点的三个值]
kubectl taint node master1 key=value:NoSchedule
删除污点
kubectl taint node master1 env_role:NoSchedule-node/master1 untainted
污点容忍
spec:
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
4.12 常用命令
查看已经部署的pod
kubectl get deployment
删除pod
kubectl delete deployment nginx-dep
查看pvc
kubectl get pvc -A
删除pvc
#删除pvc
kubectl delete pvc XXX
#强制删除
kubectl delete pvc XXX --force --grace-period=0
5. Controller控制器
5.1 什么是Controller
Controller是一个在集群上管理和运行容器的对象,通俗的说就是用来管理Pod的
5.2 Pod和Controller的关系
- Pod是通过Controller 实现应用的运维,比如伸缩,滚动升级等等
- Pod和Controller 之间通过label标签建立关系
spec:
selector:
matchLabels:
app: filebeat #和labels app保持一致
template:
metadata:
labels:
app: filebeat #和selector app保持一致
5.3 deployment 应用场景
- 部署无状态应用
- 管理Pod和ReplicaSet
- 部署,滚动升级等功能
- 应用场景:web服务,微服务
5.4 使用deployment部署应用
- 导出yaml文件
通过镜像拉去创建yaml文件
kubectl create deployment web --image=nginx --dry-run -o yaml > web.yaml
通过已经创建的pod生成yaml文件
[root@master1 kubernetes]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 5h4m
[root@master1 kubernetes]# kubectl get deploy nginx -o=yaml --export > web1.yaml
使用yaml部署应用
kubectl apply -f web.yaml
对外暴露发布端口
生成yaml文件
kubectl expose deployment web --port=80 --type=NodePort --target-port=80 --name=web -o yaml > web.yaml
部署应用
kubectl apply -f web.yaml
查看访问端口
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.1.0.1 <none> 443/TCP 5h31m
nginx NodePort 10.1.8.108 <none> 80:30499/TCP 5h9m
web NodePort 10.1.181.210 <none> 80:30942/TCP 103s
5.5 应用升级回滚和弹性伸缩
- 应用升级
kubectl set image deployment web nginx=nginx:1.15
kubectl rollout status deployment web
查看升级版本
[root@master1 kubernetes]# kubectl rollout history deployment web
deployment.apps/web
REVISION CHANGE-CAUSE
1 <none>
2 <none>
3 <none>
回滚到上一个版本
kubectl rollout undo deployment web
回滚到指定的版本
kubectl rollout undo deployment web --to-revision=3
查看升级状态
kubectl rollout status deployment web
Waiting for deployment "web" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "web" rollout to finish: 1 old replicas are pending termination...
deployment "web" successfully rolled out
弹性伸缩
kubectl scale deployment web --replicas=10
6. Service
6.1 Service 存在的意义
- 防止Pod 失联(起到服务发现的作用)
-
6.2 Pod和Service关系
通过selector.app.nginx 和 labels.app.nginx关联
6.3 常用Service 类型
ClusterIP: 集群内部使用
- NodePort:对外访问应用使用
- LoadBalancer:对外访问应用使用,公有云
说明:node 内网部署应用时,外网是不可以访问的。可以通过一台可以访问外网的服务器,部署nginx做反向代理。手动把可以访问的节点添加到nginx里面
7. 配置管理
8. 集群安全机制
8.1 概述
- 访问k8s集群的时候,需要经过三个步骤完成具体操作
- 第一步 认证
- 第二步 鉴权(授权)
- 第三部 准入控制
- 进行访问的时候,过程中都需要经过apiserver,apiserver 做统一协调,比如门卫。
- 传输安全
对外不暴露8080端口,只能内部访问,对外使用端口6443
- 认证
客户端身份证方式:
role:特定命名空间访问权限
ClusterRole:所有命名空间访问权限
- 角色绑定
roleBinding:角色绑定到主体
ClusterRoleBinding:集群角色绑定到主体
- 主体
user:用户
group:用户组
serviceAccount:服务账号
8.6 rbac实现鉴权
创建命名空间
kubectl create ns roledemo
在新建的命名空间创建pod
kubectl run nginx --image=nginx -n roledemo
创建角色
新建rbac-role.yaml文件,文件名可以随意
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: ctnrs
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
执行yaml文件
kubectl apply -f rbac-role.yaml
查看角色
kubectl get role -n roledemo
- 创建角色绑定
新建rbac-rolebinding.yaml文件
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: roletest
subjects:
- kind: User
name: lucy # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role #this must be Role or ClusterRole
name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
执行yaml文件
kubectl apply -f rbac-rolebinding.yaml
查看角色和角色绑定
kubectl get role,rolebinding -n roledemo
9. Ingress
9.1 为什么引入Ingress
- 把端口号对外暴露,通过ip+端口号进行访问
使用Service里面的NodePort实现
- NodePort缺陷
- 在每个节点上都会起到端口,在访问时候通过任何节点,通过节点ip+暴露端口实现访问
- 这意味着每个端口只能使用一次,一个端口号对应着一个应用
- 实际访问中都是用域名,根据不同域名跳转到不同端口对应的服务中
9.2 Ingress和Pod关系
- pod和ingress通过service关联的
-
9.3 使用Ingress对外暴露应用
部署ingress Controller
这里选择官方维护的nginx控制器实现部署 创建nginx应用
kubectl create deployment web2 --image=nginx
对外暴露端口使用NodePort
kubectl expose deployment web2 --port=80 --target-port=80 --type=NodePort
部署Ingress controller
新建ingress-con.yaml文件,文件名可以随意
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-configuration
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: tcp-services
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
kind: ConfigMap
apiVersion: v1
metadata:
name: udp-services
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
name: nginx-ingress-clusterrole
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- "extensions"
- "networking.k8s.io"
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- "extensions"
- "networking.k8s.io"
resources:
- ingresses/status
verbs:
- update
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
name: nginx-ingress-role
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
rules:
- apiGroups:
- ""
resources:
- configmaps
- pods
- secrets
- namespaces
verbs:
- get
- apiGroups:
- ""
resources:
- configmaps
resourceNames:
# Defaults to "<election-id>-<ingress-class>"
# Here: "<ingress-controller-leader>-<nginx>"
# This has to be adapted if you change either parameter
# when launching the nginx-ingress-controller.
- "ingress-controller-leader-nginx"
verbs:
- get
- update
- apiGroups:
- ""
resources:
- configmaps
verbs:
- create
- apiGroups:
- ""
resources:
- endpoints
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
name: nginx-ingress-role-nisa-binding
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: nginx-ingress-role
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: nginx-ingress-clusterrole-nisa-binding
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: nginx-ingress-clusterrole
subjects:
- kind: ServiceAccount
name: nginx-ingress-serviceaccount
namespace: ingress-nginx
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
annotations:
prometheus.io/port: "10254"
prometheus.io/scrape: "true"
spec:
hostNetwork: true
# wait up to five minutes for the drain of connections
terminationGracePeriodSeconds: 300
serviceAccountName: nginx-ingress-serviceaccount
nodeSelector:
kubernetes.io/os: linux
containers:
- name: nginx-ingress-controller
image: lizhenliang/nginx-ingress-controller:0.30.0
args:
- /nginx-ingress-controller
- --configmap=$(POD_NAMESPACE)/nginx-configuration
- --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
- --udp-services-configmap=$(POD_NAMESPACE)/udp-services
- --publish-service=$(POD_NAMESPACE)/ingress-nginx
- --annotations-prefix=nginx.ingress.kubernetes.io
securityContext:
allowPrivilegeEscalation: true
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
# www-data -> 101
runAsUser: 101
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
ports:
- name: http
containerPort: 80
protocol: TCP
- name: https
containerPort: 443
protocol: TCP
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 10
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 10
lifecycle:
preStop:
exec:
command:
- /wait-shutdown
---
apiVersion: v1
kind: LimitRange
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
limits:
- min:
memory: 90Mi
cpu: 100m
type: Container
执行yaml文件
kubectl apply -f ingress-con.yaml
查看ingress controller状态
kubectl get pods -n ingress-nginx
- 创建ingress规则
新建ingressy.yaml规则文件
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: example-ingress
spec:
rules:
- host: example.ingredemo.com
http:
paths:
- path: /
backend:
serviceName: web
servicePort: 80
执行yaml文件
kubectl apply -f ingress.yaml
查看部署应用在哪个节点上
kubectl get pods -n ingress-nginx -o wide
查看域名映射端口
kubectl get ing
10. Helm
10.1 Helm介绍
Helm是一个Kubernetes的包管理工具,就像Linux 下的包管理器,如yum/apt等,可以很方便的将之前打包好的yaml文件部署到kubernetes上
10.2 使用helm 可以解决哪些问题?
- 使用helm可以把这些yaml作为一个整体管理
- 实现yaml高效复用
-
10.3 Helm三个重要概念
helm 是一个命令行客户端工具
- Chart 把yaml打包,是yaml集合
- Release 基于chart部署实体,应用级别的版本管理
10.4 Helm常用命令
创建一个chart并制定名字
helm create mchart
管理chart依赖
helm dependency
下载一个 release。 可用子命令: all、 hooks、 manifest、 notes、 values
获取 release 历史
安装一个 chart
#helm install 安装之后名称 应用名称或创建的chart名称
helm install ui stable/weave-scope
列出 release
helm list
将 chart 目录打包到 chart 存档文件中
从远程仓库中下载 chart 并解压到本地
helm pull stable/mysql -- untar
添加, 列出, 移除, 更新和索引 chart 仓库。 可用子命令: add、 index、 list、 remove、 update
#添加仓库 helm repo add [仓库名称] [仓库地址]
helm repo add stable http://mirror.azure.cn/kubernetes/charts
#仓库列表
helm repo list
#更新仓库
helm repo update
#索引
helm repo index
#移除 helm repo remove [仓库名称]
helm repo remove aliyun
从之前版本回滚
helm rollback
根据关键字搜索 chart。 可用子命令: hub、 repo ```shell helm search repo mysql
helm search hub mysql
11. 查看 chart 详细信息。 可用子命令: all、 chart、 readme、 values
```shell
show
显示已命名版本的状态
#helm status [应用名称]
helm status web3
本地呈现模板
template
卸载一个release
helm release web3
更新一个release
helm upgrade web3
查看helm客户端版本
helm version
10.5 Helm安装(v3版本)
- 下载离线压缩文件
解压helm压缩文件
tar -zxvf helm-v3.0.0-linux-amd64.tar.gz
把解压缩之后的helm目录复制(移动)到Linux服务器的/usr/bin目录下
mv help /usr/bin
10.6 helm仓库管理
添加仓库
#helm repo add 仓库名称 仓库地址
helm repo add stable http://mirror.azure.cn/kubernetes/charts
查看仓库地址
helm repo list
更新仓库地址
helm repo update
删除仓库地址
helm repo remove aliyun
10.7 使用helm快速部署应用
根据helm命令搜索应用
#helm search repo [应用名称]
[root@master1 bin]# helm search repo weave
NAME CHART VERSION APP VERSION DESCRIPTION
stable/weave-cloud 0.3.9 1.4.0 DEPRECATED - Weave Cloud is a add-on to Kuberne...
stable/weave-scope 1.1.12 1.12.0 DEPRECATED - A Helm chart for the Weave Scope c...
根据helm搜索内容选择安装
#helm install 安装之后名称 搜索之后应用名称
helm install ui stable/weave-scope
查看通过helm安装的应用列表
helm list
查看通过helm安装的应用状态
#helm status [应用名称]
helm status ui
10.8 如何使用Chart
- 使用命令创建chart
# 创建mchart
helm create mchart
# 进入mchart文件夹
[root@master1 mchart]# ls
charts Chart.yaml templates values.yaml
文件说明
Chart yaml:当前Chart属性配置信息
templates:编写yaml文件放到这个目录中
values.yaml:yaml文件可以使用全局变量
在templates文件夹下创建两个yaml文件
可以通过 导出yaml的方式导出文件生成deployment.yaml文件
kubectl create deployment web3 --image=nginx --dry-run -o yaml > deployment.yaml
生成service.yaml文件
kubectl expose deployment web3 --port=80 --target-port=80 --type=NodePort --dry-run -o yaml > service.yaml
安装chart(要回到mchart的上级目录下)
helm install web3 mchart/
10.9 复用yaml文件
待完善
11. 持久存储
数据卷emptydir 是本地存储,当pod重启后数据就不存在了,需要对数据持久化存储
NFS是一个网络存储,当pod重启后,数据还是存在的
11.1 NFS安装
安装NFS
找一台nfs存储服务器yum install -y nfs-utils
设置挂载路径
vi /etc/exports
/data/nfs *(rw,no_root_squash)
注意:挂载路径需要手动创建出来
11.2 在k8s集群node节点中安装nfs
yum install -y nfs-utils
11.3 在nfs服务器中启动nfs服务
#启动nfs服务
systemctl start nfs
#查看nfs服务是否启动
ps -ef | grep nfs
11.4 在k8s集群部署应用使用nfs持久网络存储
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-dep1
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: wwwroot
mountPath: /usr/share/nginx/html # k8s集群中目录,nfs目录中的文件会同步到这个文件夹
ports:
- containerPort: 80
volumes:
- name: wwwroot
nfs:
server: 192.168.44.134 # nfs服务器ip
path: /data/nfs # nfs 挂载目录
这样nfs服务器中/data/nfs目录中的文件就可以同步到/usr/share/nginx/html文件夹中了
11.5 PV和PVC
nfs存储,需要制定nfs服务器的ip,这在实际生产项目中有诸多的不变为了解决这个问题引入pv和pvc,在yaml文件中指定nfs的别名,根据容量来匹配nfs服务器
- PV:持久化存储,对存储资源进行抽象,对外提供可以调用的地方(生产者)
- PVC:用于调用,不需要关心内部实现细节(消费者)
11.6 PV和PVC的使用
- 在master节点中安装服务
新建pvc.yaml文件,在文件中指定nfs别名
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-dep1
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: wwwroot
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
volumes:
- name: wwwroot
persistentVolumeClaim:
claimName: my-pvc #通过别名的方式指定nfs服务器
---
# 声明nfs服务器别名
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteMany #匹配模式,pv和pvc是根据容量来匹配的
resources:
requests:
storage: 5Gi
安装pvc服务
kubectl apply -f pvc.yaml
查看pvc服务
kubectl get pvc
- 安装pv服务
新建pv.yaml文件
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
nfs:
path: /k8s/nfs
server: 192.168.242.150 # 这个是nfs服务的ip
安装pv服务
kubectl get pv