05-Ingress基础、Helm和物理卷

ingress

理论

回顾暴露端口

05-Ingress基础、Helm和物理卷

假如没有ingress,自己来做https方案:

05-Ingress基础、Helm和物理卷

Nginx-Ingress

05-Ingress基础、Helm和物理卷

Ingress-Nginx github 地址:https://github.com/kubernetes/ingress-nginx
Ingress-Nginx 官方网站:https://kubernetes.github.io/ingress-nginx/

Ingress可以解决什么问题
1.动态配置服务:如果按照传统方式, 当新增加一个服务时, 我们可能需要在流量入口加一个反向代理指向我们新的k8s服务. 而如果用了Ingress, 只需要配置好这个服务, 当服务启动时, 会自动注册到Ingress的中, 不需要额外的操作.
2.减少不必要的端口暴露

Ingress 工作原理

1.ingress controller通过和kubernetes api交互,动态的去感知集群中ingress规则变化,

2.然后读取它,按照自定义的规则,规则就是写明了哪个域名对应哪个service,生成一段nginx配置,

3.再写到nginx-ingress-control的pod里,这个Ingress controller的pod里运行着一个Nginx服务,控制器会把生成的nginx配置写入/etc/nginx.conf文件中,

4.然后reload一下使配置生效。以此达到域名分配置和动态更新的问题。

ingress和pod的关系

05-Ingress基础、Helm和物理卷

pod和ingress通过service关联,ingress作为统一入口,由service关联一组pod

ingress工作流程

05-Ingress基础、Helm和物理卷

通过ingress管理不同业务的域名,从而分发流量到不同的service

使用ingress

05-Ingress基础、Helm和物理卷

操作:通过ingress对外暴露应用,通过域名访问

创建nginx应用,对外暴露端口使用NodePort

kubectl create deployment web --image=nginx
kubectl expose deployment web --port=80 --target-port=80 --type=NodePort

05-Ingress基础、Helm和物理卷

部署ingress controller,多加一层ingress

参考链接:
https://www.cnblogs.com/hailun1987/p/14162278.html
https://segmentfault.com/a/1190000040618813

直接部署

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.0/deploy/static/provider/baremetal/deploy.yaml

sed -i 's@k8s.gcr.io/ingress-nginx/controller:v1.0.0\(.*\)@willdockerhub/ingress-nginx-controller:v1.0.0@' deploy.yaml
sed -i 's@k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.0\(.*\)$@hzde0128/kube-webhook-certgen:v1.0@' deploy.yaml

kubectl apply -f deploy.yaml

部署文件介绍:

namespace.yaml
创建一个独立的命名空间 ingress-nginx

configmap.yaml
ConfigMap是存储通用的配置变量的,类似于配置文件,使用户可以将分布式系统中用于不同模块的环境变量统一到一个对象中管理;而它与配置文件的区别在于它是存在集群的“环境”中的,并且支持K8S集群中所有通用的操作调用方式。从数据角度来看,ConfigMap的类型只是键值组,用于存储被Pod或者其他资源对象(如RC)访问的信息。这与secret的设计理念有异曲同工之妙,主要区别在于ConfigMap通常不用于存储敏感信息,而只存储简单的文本信息。

ConfigMap可以保存环境变量的属性,也可以保存配置文件。创建pod时,对configmap进行绑定,pod内的应用可以直接引用ConfigMap的配置。相当于configmap为应用/运行环境封装配置。

pod使用ConfigMap,通常用于:设置环境变量的值、设置命令行参数、创建配置文件。

default-backend.yaml
如果外界访问的域名不存在的话,则默认转发到default-http-backend这个Service,其会直接返回404:

rbac.yaml
负责Ingress的RBAC授权的控制,其创建了Ingress用到的ServiceAccount、ClusterRole、Role、RoleBinding、ClusterRoleBinding

with-rbac.yaml
是Ingress的核心,用于创建ingress-controller。ingress-controller的作用是将新加入的Ingress进行转化为Nginx的配置

优化 ingress-nginx

使用 hostNetwork
修改 Deployment 下面的 spec

05-Ingress基础、Helm和物理卷

修改负载均衡问题
把 kind: Deployment 改为 kind: DaemonSet 模式,这样每台 node 上都有 ingress-nginx-controller pod 副本。

05-Ingress基础、Helm和物理卷

修改 ingressClass 问题
如果不关心 ingressClass 或者很多没有 ingressClass 配置的 ingress 对象,
添加参数 ingress-controller --watch-ingress-without-class=true 。

...
args:
  - /nginx-ingress-controller
  - --publish-service=$(POD_NAMESPACE)/ingress-nginx-dev-v1-test-controller
  - --election-id=ingress-controller-leader
  - --controller-class=k8s.io/ingress-nginx
  - --configmap=$(POD_NAMESPACE)/ingress-nginx-dev-v1-test-controller
  - --validating-webhook=:8443
  - --validating-webhook-certificate=/usr/local/certificates/cert
  - --validating-webhook-key=/usr/local/certificates/key
  - --watch-ingress-without-class=true  # 新增
...

应用yaml文件
kubectl apply -f deploy.yaml

!如果安装失败先删除命名空间:
kubectl delete ns ingress-nginx --force --grace-period=0

查看部署ingress状态
kubectl get pods -n ingress-nginx -o wide

05-Ingress基础、Helm和物理卷

创建nginx应用:

创建ingress规则

ingress-network.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx" #声名需要使用nginx方式解析ingress
spec:
  rules: # 一个Ingress可以配置多个rules
  - host: example.ingredemo.com # 域名配置,可以不写(不建议),支持匹配,一般写法:*.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path 例如“/”或“/abc”
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80
05-Ingress基础、Helm和物理卷
(此图yaml配置格式为1.23.0之前的版本)

通过servicename来匹配
kubectl apply -f ingress-network.yaml

kubectl get svc -n ingress-nginx -o wide

05-Ingress基础、Helm和物理卷

32671端口为ingress访问端口

测试规则是否生效,部署在了哪台机器上
kubectl get ing

05-Ingress基础、Helm和物理卷

修hosts文件(本地macbook测试方式,windows或线上环境根据实际情况自行修改)

05-Ingress基础、Helm和物理卷

查看(查看80端口即可)

05-Ingress基础、Helm和物理卷

创建一个多域名ingress

cat ingress-mulDomain.yaml 
apiVersion: networking.k8s.io/v1beta1 # networking.k8s.io/v1 / extensions/v1beta1 
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: "nginx"
  name: example
spec:
  rules: # 一个Ingress可以配置多个rules
  - host: foo.bar.com # 域名配置,可以不写,匹配*, *.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path / /abc
      - backend:
          serviceName: nginx-svc 
          servicePort: 80
        path: /
  - host: foo2.bar.com # 域名配置,可以不写,匹配*, *.bar.com
    http:
      paths: # 相当于nginx的location配合,同一个host可以配置多个path / /abc
      - backend:
          serviceName: nginx-svc-external
          servicePort: 80
        path: /

给 ingress-nginx 配置 HTTPS 访问(属于secret)

创建自签证书文件
openssl req -x509 -nodes -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginx/O=nginx"
创建后会生成两个文件
tls.crt tls.key

创建 secret
kubectl create secret tls tls-secret --key tls.key --cert tls.crt

修改ingress-network.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:
  - hosts:
    - example.ingredemo.com
    secretName: tls-secret
  rules:
  - host: example.ingredemo.com
    http:
      paths:
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80

kubectl apply -f ingress-network.yaml

访问:

05-Ingress基础、Helm和物理卷

nginx添加BasicAuth

yum -y install httpd-tools
htpasswd -c auth testuser
kubectl create secret generic basic-auth --from-file=auth

生成一个基于base64加密的字符串

05-Ingress基础、Helm和物理卷
05-Ingress基础、Helm和物理卷

修改ingress
ingress-network.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/auth-type: basic
    nginx.ingress.kubernetes.io/auth-secret: basic-auth
    nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - foo'
spec:
  rules:
  - host: example.ingredemo.com
    http:
      paths:
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80

输入用户名和密码

05-Ingress基础、Helm和物理卷

此功能常用在ELK 网页端

Nginx 进行重写

rewrite.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
    nginx.ingress.kubernetes.io/rewrite-target: https://www.baidu.com:443
spec:
  tls:
  - hosts:
    - example.ingredemo.com
    secretName: tls-secret
  rules:
  - host: example.ingredemo.com
    http:
      paths:
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: web
            port:
              number: 80
名称描述
nginx.ingress.kubernetes.io/rewrite-target必须重定向流量的目标URI
nginx.ingress.kubernetes.io/ssl-redirect指示位置部分是否仅可访问SSL(当Ingress包含证书时默认为True)
nginx.ingress.kubernetes.io/force-ssl-redirect即使Ingress未启用TLS,也强制重定向到HTTPS
nginx.ingress.kubernetes.io/app-root定义Controller必须重定向的应用程序根,如果它在'/'上下文中
nginx.ingress.kubernetes.io/use-regex指示Ingress上定义的路径是否使用正则表达式

tomcat部署练习:

创建应用yaml
vim tomcat.yaml

apiVersion: apps/v1 
kind: Deployment   
metadata:             
  name: tomcat-deployment     
  labels:       
    app: tomcat  
spec:          
  replicas: 2 
  selector:      
    matchLabels: 
      app: tomcat
  minReadySeconds: 1
  progressDeadlineSeconds: 60
  revisionHistoryLimit: 2
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:        
    metadata:  
      labels:  
        app: tomcat
    spec:         
      containers:     
      - name: tomcat     
        image: wenlongxue/tomcat:tomcat-demo-62-8fe6052    
        imagePullPolicy: Always          
        ports:
        - containerPort: 8080
        resources:
          requests:
            memory: "2Gi"
            cpu: "80m"
          limits: 
            memory: "2Gi" 
            cpu: "80m"
        readinessProbe:
          httpGet:
            path: /
            port: 8080
          initialDelaySeconds: 180
          periodSeconds: 5
          timeoutSeconds: 3
          successThreshold: 1
          failureThreshold: 30
---
apiVersion: v1
kind: Service
metadata:      
  name: tomcat-service
  labels:      
    app: tomcat 
spec:        
  selector:   
    app: tomcat  
  ports:
  - name: tomcat-port 
    protocol: TCP      
    port: 8080         
    targetPort: 8080   
  type: ClusterIP 

kubectl apply -f tomcat.yaml

创建 ingress yaml
vim tomcat-ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tomcat
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
  - host: tomcat.cnsre.cn
    http:
      paths:
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: tomcat-service
            port:
              number: 8080

kubectl apply -f tomcat-ingress.yaml

在 hosts 文件最后追加 ingress 节点的 IP 地址
192.168.1.11 tomcat.cnsre.cn

访问

05-Ingress基础、Helm和物理卷

给 ingress-tomcat 配置 HTTPS 访问

创建自签证书文件
openssl req -x509 -nodes -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginx/O=nginx"
创建后会生成两个文件
tls.crt tls.key

创建 secret
kubectl create secret tls tls-secret --key tls.key --cert tls.crt

修改ingress-network.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tomcat
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:                      # 新增
  - hosts:                  # 新增
    - tomcat.cnsre.cn       # 新增
    secretName: tls-secret  # 新增
  rules:
  - host: tomcat.cnsre.cn
    http:
      paths:
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name: tomcat-service
            port:
              number: 8080

kubectl apply -f ingress-network.yaml

访问:

05-Ingress基础、Helm和物理卷

helm

什么是 Helm

在没使用 helm 之前,向 kubernetes 部署应用,我们要依次部署 deployment、svc 等,步骤较繁琐。况且随着很多项目微服务化,复杂的应用在容器中部署以及管理显得较为复杂,helm 通过打包的方式,支持发布的版本管理和控制,很大程度上简化了 Kubernetes 应用的部署和管理

Helm 本质就是让 K8s 的应用管理(Deployment,Service 等 ) 可配置,能动态生成。通过动态生成 K8s 资源清单文件(deployment.yaml,service.yaml)。然后调用 Kubectl 自动执行 K8s 资源部署

Helm 是官方提供的类似于 YUM 的包管理器,是部署环境的流程封装。Helm 有两个重要的概念:chart 和 release

helm引入原因

之前部署方式

通过导出的方式修改编写yaml文件
kubectl create deployment web --image=nginx --dry-run=client -o yaml > web.yaml

暴露端口
kubectl expose deployment web --port=80 --type=NodePort --target-port=80 --name=web1 -o yaml > web-expose.yaml
kubectl expose deployment web --port=80 --target-port=80 --type=NodePort

检查
初级部署方式
检查pods
kubectl get pods -o wide
检查网络
kubectl get svc

ingress部署方式
通过yaml文件指定对外暴露端口和域名
kubectl apply -f ingress-network.yaml
kubectl get ing
kubectl get pods -n ingress-nginx -o wide

之前的缺陷
如果使用之前方式部署的那一应用,少数服务的应用,比较合适
但是部署微服务项目,可能有几十个服务,每个服务都有一套yaml文件,需要维护大量yaml文件,版本管理特别不方便

Helm介绍

使用helm可以解决哪些问题?

05-Ingress基础、Helm和物理卷

Helm 是一个 Kubernetes 的包管理工具,就像 Linux 下的包管理器,如 yum/apt 等,可以很方便的将之前打包好的 yaml 文件部署到 kubernetes 上。

Helm 有 3 个重要概念:
(1)helm:一个命令行客户端工具,主要用于 Kubernetes 应用 chart 的创建、打包、发布和管理。
(2)Chart:应用描述,一系列用于描述 k8s 资源相关文件(yaml文件)的集合。
(3)Release:基于 Chart 的部署实体,一个 chart 被 Helm 运行后将会生成对应的一个release;将在 k8s 中创建出真实运行的资源对象。应用级别版本管理

Helm v3 的第一个稳定版本
1、最明显的变化是 Tiller 的删除
2、Release 名称可以在不同命名空间重用
3、支持将 Chart 推送至 Docker 镜像仓库中
4、使用 JSONSchema 验证 chart values

Helm架构变化

05-Ingress基础、Helm和物理卷

helm安装过程(v3)

helm安装文档:

https://helm.sh/docs/intro/install/

Helm 命令客户端命令下载地址:https://github.com/helm/helm/releases  解压移动到/usr/bin/目录即可

05-Ingress基础、Helm和物理卷

wget https://get.helm.sh/helm-v3.2.1-linux-amd64.tar.gz
tar zxvf helm-v3.2.1-linux-amd64.tar.gz
mv linux-amd64/helm /usr/bin/

配置国内 chart 仓库
微软仓库(http://mirror.azure.cn/kubernetes/charts/)这个仓库推荐,基本上官网有的 chart 这里都有。
阿里云仓库(https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts )
官方仓库(https://hub.kubeapps.com/charts/incubator)官方 chart 仓库,国内有点不好使。

添加存储库
添加微软仓库
helm repo add stable http://mirror.azure.cn/kubernetes/charts

可以继续添加阿里仓库
helm repo add aliyun https://kubernetes.oss-cn-hangzhou.aliyuncs.com/charts

更新源仓库
helm repo update

05-Ingress基础、Helm和物理卷

搜索源内容
helm search repo 名称

05-Ingress基础、Helm和物理卷

如果想要删除阿里源
helm repo remove aliyun

helm命令补全:
source <(helm completion bash)
echo "source <(helm completion bash)" >> ~/.bash_profile
helm completion bash > /usr/share/bash-completion/completions/helm

使用helm快速部署应用

过程

05-Ingress基础、Helm和物理卷

一键安装(部署weave)

helm search repo weave

05-Ingress基础、Helm和物理卷

helm install ui stable/weave-scope

05-Ingress基础、Helm和物理卷

这个创建过程相当于自己联网从stable库中下载了一个部署weave-scope的yaml文件组在chart中,创建应用之后名称为ui,然后把应用跑起来

通过安装之后的名称查看应用
helm status ui

05-Ingress基础、Helm和物理卷

查看pods
kubectl get pods

05-Ingress基础、Helm和物理卷

暴露端口
kubectl get svc 默认不会暴露端口,需要将ClusterIP修改成NodePort

05-Ingress基础、Helm和物理卷

编写yaml文件
kubectl edit svc ui-weave-scope

05-Ingress基础、Helm和物理卷

kubectl get svc

05-Ingress基础、Helm和物理卷

web查看

05-Ingress基础、Helm和物理卷

helm安装dashboard

tips:非helm安装dashboard方式:
https://github.com/kubernetes/dashboard

进入helm官网,选择charts
https://helm.sh/docs/intro/install/
https://artifacthub.io/

05-Ingress基础、Helm和物理卷

搜索kubernetes-dashboard

05-Ingress基础、Helm和物理卷

安装带有release名称的chart:my-release
添加仓库并安装
helm repo add kubernetes-dashboard https://kubernetes.github.io/dashboard/
helm repo update
helm install kubernetes-dashboard kubernetes-dashboard/kubernetes-dashboard --namespace kube-system

05-Ingress基础、Helm和物理卷

helm list -n kube-system

05-Ingress基础、Helm和物理卷

修改svc为NodePort模式提供对完访问端口

kubectl edit svc kubernetes-dashboard -n kube-system

05-Ingress基础、Helm和物理卷

kubectl get svc -n kube-system

05-Ingress基础、Helm和物理卷

访问
https://192.168.1.10:31321

05-Ingress基础、Helm和物理卷

填写token(如果遇到异常可以跳过)
kubectl -n kube-system describe $(kubectl get secret -n kube-system -o name | grep namespace) | grep token
kubectl -n kube-system get secret | grep dashboard-token
kubectl describe secrets kubernetes-dashboard-token-4bhsn -n kube-system
这里有些问题。使用这里的token无法编辑dashboard

创建一个SA管理员权限:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kube-system

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kube-system

获取token:
kubectl -n kube-system get secret $(kubectl -n kube-system get sa/admin-user -o jsonpath="{.secrets[0].name}") -o go-template="{{.data.token | base64decode}}"

05-Ingress基础、Helm和物理卷

登入:

05-Ingress基础、Helm和物理卷

自定义一个chart部署一个自定义应用

创建一个chart模板
helm create mychart

查看生成的mychart目录

05-Ingress基础、Helm和物理卷

创建自己的应用
cd mychart/templates
rm -rf *
kubectl create deployment web1 --image=wangyanglinux/myapp:v1 --dry-run=client -o yaml > deployment.yaml
先把服务跑起来,在进行端口暴露的yaml创建,然后再把服务删掉
kubectl create -f deployment.yaml
kubectl expose deployment web1 --port=80 --target-port=80 --type=NodePort --dry-run=client -o yaml > service.yaml
kubectl delete deployment web1
当前目录成功创建了两个yaml文件deployment.yaml service.yaml

安装mychart
helm install web1 mychart

05-Ingress基础、Helm和物理卷

kubectl get pods,svc

05-Ingress基础、Helm和物理卷

应用升级

05-Ingress基础、Helm和物理卷

比如说修改了mychart中的yaml文件进行升级
将mychart2下的templete下的yaml文件进行修改

05-Ingress基础、Helm和物理卷

升级操作
helm upgrade web1 mychart

05-Ingress基础、Helm和物理卷

使用helm实现高效复用

实现方式讲解:

05-Ingress基础、Helm和物理卷

修改操作:

05-Ingress基础、Helm和物理卷

修改处:

05-Ingress基础、Helm和物理卷

具体操作:

1:在values.yaml定义变量和值
vim values

05-Ingress基础、Helm和物理卷

2:在templetes的yaml文件使用values.yaml定义变量

vim deployment.yaml

05-Ingress基础、Helm和物理卷

Release可以变化版本名称

vim service.yaml

05-Ingress基础、Helm和物理卷

这里".svc注意"不能用“.”需要用横杠

生成yaml文件

测试
helm install --dry-run web2 mychart

05-Ingress基础、Helm和物理卷

创建
helm install web3 mychart
kubectl get pods

05-Ingress基础、Helm和物理卷

kubectl get svc

05-Ingress基础、Helm和物理卷

测试

05-Ingress基础、Helm和物理卷

优化模版样例(deployment+service+ingress(tls证书版)):

目录结构

05-Ingress基础、Helm和物理卷

values.yaml

deployment:
  label: nginx-label
  replicas: 3
  image: wangyanglinux/myapp:v1
  imagename: nginx

service:
  label: nginx-svc-label
  port: 80
  targetport: 80
  porttype: NodePort

ingress:
  hostname: example.ingredemo.com
  port: 80
  secret: tls-secret

templates:

deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: {{.Values.deployment.label}}
  name: {{.Release.Name}}-deploy
spec:
  replicas: {{.Values.deployment.replicas}}
  selector:
    matchLabels:
      app: {{.Values.deployment.label}}
  template:
    metadata:
      labels:
        app: {{.Values.deployment.label}}
    spec:
      containers:
      - image: {{.Values.deployment.image}}
        name: {{.Values.deployment.imagename}}

service.yaml

apiVersion: v1
kind: Service
metadata:
  labels:
    app: {{.Values.service.label}}
  name: {{.Release.Name}}-svc
spec:
  ports:
  - port: {{.Values.service.port}}
    protocol: TCP
    targetPort: {{.Values.service.targetport}}
  selector:
    app: {{.Values.deployment.label}}
  type: {{.Values.service.porttype}}

ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{.Release.Name}}-ingress
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  tls:                      
  - hosts:                  
    - {{.Values.ingress.hostname}}      
    secretName: {{.Values.ingress.secret}}
  rules:
  - host: {{.Values.ingress.hostname}}
    http:
      paths:
      - path: "/"
        pathType: Prefix
        backend:
          service:
            name:  {{.Release.Name}}-svc
            port:
              number: 80

helm install myapp mychart/

访问https://example.ingredemo.com/:

05-Ingress基础、Helm和物理卷

20230823更新:最近推荐使用helm安装ingress

使用helm安装ingress:https://kubernetes.github.io/ingress-nginx/deploy/#using-helm

添加 ingress-nginx 官方helm仓库

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx

下载ingress的helm包至本地

helm pull ingress-nginx/ingress-nginx --version=4.0.1
tar -xvf ingress-nginx-4.0.1.tgz

更改对应的配置

cd ingress-nginx && vim values.yaml

修改 ingress-nginx-controller 的镜像仓库地址,默认是 k8s.gcr.io 国内无法访问,这里用到github上一个同步 ingress-nginx-controller 的仓库 docker.io/willdockerhub/ingress-nginx-controller(最近貌似这个仓库也g了=-=,自行寻找国内文档吧)

05-Ingress基础、Helm和物理卷

修改 hostNetwork 的值为 true(建议使用专有宿主机单独去跑ingress):

05-Ingress基础、Helm和物理卷

dnsPolicy的值改为: ClusterFirstWithHostNet (修改 hostNetwork 的值为 true后必须跟着修改,否则内部无法解析)

05-Ingress基础、Helm和物理卷

nodeSelector 添加标签: ingress: "true",用于部署 ingress-controller 到指定节点

05-Ingress基础、Helm和物理卷

kind类型更改为:DaemonSet nodeSelector+DaemonSet方式可以更方便的进行nginx的扩容和缩容

05-Ingress基础、Helm和物理卷

kube-webhook-certgen的镜像地址改为国内仓库地址 registry.aliyuncs.com/google_containers/kube-webhook-certgen

05-Ingress基础、Helm和物理卷

type: LoadBalancer 如果非公有云部署修改成ClusterIP

05-Ingress基础、Helm和物理卷

执行安装

先创建一个名称空间
kubectl create ns ingress-nginx

给需要部署ingress的节点上打标签(k8s默认集群中,出于安全考虑,默认配置下Kubernetes不会将Pod调度到Master节点。可以选择执行“kubectl taint node master1 node-role.kubernetes.io/master-”命令去除master的污点,这里使用node进行打标签了)
kubectl label node k8s-node01 ingress=true

进入chart目录(ingress-nginx目录)进行helm安装
helm install ingress-nginx -n ingress-nginx .

安装后结果展示:

05-Ingress基础、Helm和物理卷

kubectl get all -n ingress-nginx

05-Ingress基础、Helm和物理卷

因为node01有ingress=true标签,所以部署到了node01,在扩容缩容ingress所部属的节点数量时,一定要先把前面的负载均衡后端的node先摘除掉

05-Ingress基础、Helm和物理卷

使用宿主机开启nginx监听可以避免使用kube-proxy进行代理,使用NodePort会影响服务器性能

05-Ingress基础、Helm和物理卷

数据卷

概念:

容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器崩溃时,kubelet 会重启它,但是容器中的文件将丢失——容器以干净的状态(镜像最初的状态)重新启动。其次,在 Pod 中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes 中的 Volume 抽象就很好的解决了这些问题

Kubernetes 支持以下类型的卷

  • awsElasticBlockStore azureDisk azureFile cephfs csi downwardAPI emptyDir
  • fc flocker gcePersistentDisk gitRepo glusterfs hostPath iscsi local nfs
  • persistentVolumeClaim projected portworxVolume quobyte rbd scaleIO secret
  • storageos vsphereVolume

emptyDir

当 Pod 被分配给节点时,首先创建 emptyDir 卷,并且只要该 Pod 在该节点上运行,该卷就会存在。正如卷的名字所述,它最初是空的。Pod 中的容器可以读取和写入 emptyDir 卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同路径上。当出于任何原因从节点中删除 Pod 时,emptyDir 中的数据将被永久删除

emptyDir 的用法有:
- 暂存空间,例如用于基于磁盘的合并排序、用作长时间计算崩溃恢复时的检查点
- Web服务器容器提供数据时,保存内容管理器容器提取的文件

jobs-empty.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: jobs-empty
spec:
  template:
    spec:
      restartPolicy: Never
      initContainers:
        - name: job-1
          image: busybox:1.34.1
          command:
            - 'sh'
            - '-c'
            - >
              for i in 1 2 3;
              do
                echo "job-1 `date`";
                sleep 1s;
              done;
              echo job-1 GG > /srv/input/code
          volumeMounts:
            - mountPath: /srv/input/
              name: input
        - name: job-2
          image: busybox:1.34.1
          command:
            - 'sh'
            - '-c'
            - >
              for i in 1 2 3;
              do
                echo "job-2 `date`";
                sleep 1s;
              done;
              cat /srv/input/code &&
              echo job-2 GG  > /srv/input/output/file
          resources:
            requests:
              cpu: 3
          volumeMounts:
            - mountPath: /srv/input/
              name: input
            - mountPath: /srv/input/output/
              name: output
      containers:
        - name: job-3
          image: busybox:1.34.1
          command:
            - 'sh'
            - '-c'
            - >
              echo "job-1 and job-2 completed";
              sleep 3s;
              cat /srv/output/file
          volumeMounts:
            - mountPath: /srv/output/
              name: output
      volumes:
        - name: input
          emptyDir: {}
        - name: output
          emptyDir: {}

查看:

kubectl describe pods jobs-empty-g7cqc

05-Ingress基础、Helm和物理卷

kubectl logs jobs-empty-g7cqc -c job-1
kubectl logs jobs-empty-g7cqc -c job-2
kubectl logs jobs-empty-g7cqc

05-Ingress基础、Helm和物理卷

hostPath

卷将主机节点的文件系统中的文件或目录挂载到集群中

hostPath的用途如下:

  • 运行需要访问 Docker 内部的容器;使用 /var/lib/dockerhostPath
  • 在容器中运行 cAdvisor;使用 /dev/cgroupshostPath
  • 允许 pod 指定给定的 hostPath 是否应该在 pod 运行之前存在,是否应该创建,以及它应该以什么形式存在

除了所需的 `path` 属性之外,用户还可以为 `hostPath` 卷指定 `type`

05-Ingress基础、Helm和物理卷

使用这种卷类型请注意,因为:
由于每个节点上的文件都不同,具有相同配置(例如从 podTemplate 创建的)的 pod 在不同节点上的行为可能会有所不同*
当 Kubernetes 按照计划添加资源感知调度时,将无法考虑 hostPath 使用的资源
在底层主机上创建的文件或目录只能由 root 写入。您需要在特权容器中以 root 身份运行进程,或修改主机上的文件权限以便写入 hostPath

hostPath案例:

test-pd.yaml

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: wangyanglinux/myapp:v1
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # directory location on host
      path: /data
      # this field is optional
      type: Directory

kubectl apply -f test-pd.yaml

kubectl get pods

05-Ingress基础、Helm和物理卷

kubectl describe pod test-pd

05-Ingress基础、Helm和物理卷

两台node上操作:
mkdir /data
echo $(hostname) > /data/index.html

进入容器查看:

05-Ingress基础、Helm和物理卷

nfs网络存储

pod重启,数据还会存在

安装nfs
重新找一台机器(192.168.1.14)安装nfs
yum -y install nfs-utils rpcbind
mkdir -p /data/nfs
vim /etc/exports
/data/nfs *(rw,no_root_squash,no_all_squash,sync)

将node节点服务器安装nfs
yum -y install nfs-utils

nfs服务端开启nfs
systemctl start nfs
touch /data/nfs/aaa

master节点在k8s集群部署应用使用nfs持久网络存储
mkdir pv
cd pv

nfs-nginx.yaml

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
        ports:
        - containerPort: 80
      volumes:
        - name: wwwroot
          nfs:
            server: 192.168.1.14
            path: /data/nfs
05-Ingress基础、Helm和物理卷

kubectl apply -f nfs-nginx.yaml

05-Ingress基础、Helm和物理卷

kubectl get pods

05-Ingress基础、Helm和物理卷

如果nfs开启的是匿名用户权限,补充(可忽略)
node节点授权
vim /etc/kubernetes/kubelet.conf

05-Ingress基础、Helm和物理卷

在master节点上,添加认证用户,直接使用下列命令实现
kubectl create clusterrolebinding system:anonymous --clusterrole=cluster-admin --user=system:anonymous

进入pod进行查看是否挂载了nfs的共享目录

kubectl get pods

05-Ingress基础、Helm和物理卷

kubectl describe pod nginx-dep1-64d699cc8c-d4l8s

05-Ingress基础、Helm和物理卷

kubectl exec -it nginx-dep1-64d699cc8c-d4l8s bash
cd /usr/share/nginx/html/;ls

05-Ingress基础、Helm和物理卷

暴露端口并测试

kubectl expose deployment nginx-dep1 --port=80 --target-port=80 --type=NodePort

kubectl get svc

05-Ingress基础、Helm和物理卷

修改nfs挂载目录文件(14端操作)
echo successful > /data/nfs/index.html

05-Ingress基础、Helm和物理卷

PV,PVC

存储分类:

文件存储:一些数据可能需要被多个节点使用,比如用户的头像、用户上传的文件等,实现方式:NFS、NAS、FTP、CephFS等。

块存储:一些数据只能被一个节点使用,或者是需要将一块裸盘整个挂载使用,比如数据库、Redis等,实现方式:Ceph、GlusterFS、公有云。

对象存储:由程序代码直接实现的一种存储方式,无需挂载,云原生应用无状态化常用的实现方式,实现方式:一般是符合S3协议的云存储,比如AWS的S3存储、Minio、七牛云等(IO、吞吐量性能可能相对差一些)。

概念:

05-Ingress基础、Helm和物理卷

PersistentVolume(PV)
是由管理员设置的存储,它是群集的一部分。就像节点是集群中的资源一样,PV 也是集群中的资源。 PV 是 Volume 之类的卷插件,但具有独立于使用 PV 的 Pod 的生命周期。此 API 对象包含存储实现的细节,即 NFS、iSCSI 或特定于云供应商的存储系统

PersistentVolumeClaim(PVC)
是用户存储的请求。它与 Pod 相似。Pod 消耗节点资源,PVC 消耗 PV 资源。Pod 可以请求特定级别的资源(CPU 和内存)。声明可以请求特定的大小和访问模式(例如,可以以读/写一次或 只读多次模式挂载)

静态 pv
集群管理员创建一些 PV。它们带有可供群集用户使用的实际存储的细节。它们存在于 Kubernetes API 中,可用于消费

动态pv
当管理员创建的静态 PV 都不匹配用户的 PersistentVolumeClaim 时,集群可能会尝试动态地为 PVC 创建卷。此配置基于 StorageClasses:PVC 必须请求 [存储类],并且管理员必须创建并配置该类才能进行动态创建。声明该类为 "" 可以有效地禁用其动态配置

要启用基于存储级别的动态存储配置,集群管理员需要启用 API server 上的 DefaultStorageClass [准入控制器] 。例如,通过确保 DefaultStorageClass 位于 API server 组件的 --admission-control 标志,使用逗号分隔的有序值列表中,可以完成此操作

PV 绑定到 PVC
master 中的控制环路监视新的 PVC,寻找匹配的 PV(如果可能),并将它们绑定在一起。如果为新的 PVC 动态调配 PV,则该环路将始终将该 PV 绑定到 PVC。否则,用户总会得到他们所请求的存储,但是容量可能超出要求的数量。一旦 PV 和 PVC 绑定后,PersistentVolumeClaim 绑定是排他性的,不管它们是如何绑定的。 PVC 跟 PV 绑定是一对一的映射

持久化卷声明的保护
PVC 保护的目的是确保由 pod 正在使用的 PVC 不会从系统中移除,因为如果被移除的话可能会导致数据丢失(当 pod 状态为 Pending 并且 pod 已经分配给节点或 pod 为 Running 状态时,PVC 处于活动状态)
当启用PVC 保护 alpha 功能时,如果用户删除了一个 pod 正在使用的 PVC,则该 PVC 不会被立即删除。PVC 的删除将被推迟,直到 PVC 不再被任何 pod 使用

持久化卷类型
PersistentVolume 类型以插件形式实现。Kubernetes 目前支持以下插件类型:

  • GCEPersistentDisk AWSElasticBlockStore AzureFile AzureDisk FC (Fibre Channel)
  • FlexVolume Flocker NFS iSCSI RBD (Ceph Block Device) CephFS
  • Cinder (OpenStack block storage) Glusterfs VsphereVolume Quobyte Volumes
  • HostPath VMware Photon Portworx Volumes ScaleIO Volumes StorageOS

访问模式限制:

05-Ingress基础、Helm和物理卷

回收策略(可以通过persistentVolumeReclaimPolicy: Recycle字段配置)

  • Retain(保留)——手动回收
  • Recycle(回收)——基本擦除(rm -rf /thevolume/*
  • Delete(删除)——删除,如果Volume插件支持,删除PVC时会同时删除PV,动态卷默认为Delete,目前支持Delete的存储后端包括AWS EBS, GCE PD, Azure Disk, or OpenStack Cinder等

当前,只有 NFS(旧版) 和 HostPath 支持回收策略(这种策略没啥优点)。AWS EBS、GCE PD、Azure Disk 和 Cinder 卷支持删除策略(省钱)

PV的几种状态

  • Available:可用,没有被PVC绑定的空闲资源。
  • Bound:已绑定,已经被PVC绑定。
  • Released:已释放,PVC被删除,但是资源还未被重新使用。
  • Failed:失败,自动回收失败。

本实验将会讲解并验证StatefulSet相关知识点: 

匹配 Pod name ( 网络标识 ) 的模式为:$(statefulset名称)-$(序号),比如上面的示例:web-0,web-1,web-2

statefulSet 为每个 Pod 副本创建了一个 DNS 域名,这个域名的格式为: $(podname).(headless server name),也就意味着服务间是通过Pod域名来通信而非 Pod IP,因为当Pod所在Node发生故障时, Pod 会被飘移到其它 Node 上,Pod IP 会发生变化,但是 Pod 域名不会有变化

StatefulSet 使用 Headless 服务来控制 Pod 的域名,这个域名的 FQDN 为:$(service name).$(namespace).svc.cluster.local,其中,“cluster.local” 指的是集群的域名

根据 volumeClaimTemplates,为每个 Pod 创建一个 pvc,pvc 的命名规则匹配模式:(volumeClaimTemplates.name)-(pod_name),比如上面的 volumeMounts.name=www, Pod name=web-[0-2],因此创建出来的 PVC 是 www-web-0、www-web-1、www-web-2

删除 Pod 不会删除其 pvc,手动删除 pvc 将自动释放 pv

Statefulset的启停顺序
有序部署:部署StatefulSet时,如果有多个Pod副本,它们会被顺序地创建(从0到N-1)并且,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态
有序删除:当Pod被删除时,它们被终止的顺序是从N-1到0
有序扩展:当对Pod执行扩展操作时,与部署一样,它前面的Pod必须都处于Running和Ready状态

StatefulSet使用场景
稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于 PVC 来实现
稳定的网络标识符,即 Pod 重新调度后其 PodName 和 HostName 不变
有序部署,有序扩展,基于 init containers 来实现
有序收缩

PV和PVC实现过程

05-Ingress基础、Helm和物理卷

nfs服务器如果一旦变化,所有nodeIP都要发生改变,实际应用不方便,如果直接调用接口则可以简化工作量

05-Ingress基础、Helm和物理卷

实现流程

05-Ingress基础、Helm和物理卷

生产环境具体情况:

05-Ingress基础、Helm和物理卷

可以实现应用通过pvc绑定pv,以及通过存储容量和匹配模式进行绑定

实验一:nfs基于刚才的pv,pvc的升级操作

删除刚才的实验
kubectl delete -f nfs-nginx.yaml

首先了解一个PV全配置样例模版:
pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv0003
spec:
  capacity: # 容量配置
    storage: 5Gi
  volumeMode: Filesystem
 # volumeMode:卷的模式,目前支持Filesystem(文件系统) 和 Block(块),其中Block类型需要后端存储支持,默认为文件系统
  accessModes: # accessModes:该PV的访问模式
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: slow # storageClassName:PV的类,一个特定类型的PV,只能绑定到特定类别的PVC
  mountOptions: # 非必须,新版本中已弃用
    - hard
    - nfsvers=4.1
  nfs: # nfs:NFS服务配置,包括1、path:NFS上的共享目录
 2、server:NFS的IP地址
    path: /tmp
    server: 172.17.0.2

该PV的访问模式补充(https://kubernetes.io/docs/concepts/storage/persistent-volumes/#reclaim-policy):
ReadWriteOnce(RWO):读写权限,但是只能被单个节点挂载
ReadOnlyMany(ROX):只读权限,可以被多个节点挂载
ReadWriteMany(RWX):读写权限,可以被多个节点挂载

05-Ingress基础、Helm和物理卷

下面做自己的实验:
pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-pv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  nfs:
    path: /data/nfs
    server: 192.168.1.14
05-Ingress基础、Helm和物理卷

主要定义服务IP和路径,专业人士提供即可,如通过容量5G和读写模式的进行匹配
kubectl apply -f pv.yaml

pvc.yaml

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

---

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
05-Ingress基础、Helm和物理卷

主要负责创建nginx并连接pvc,根据存储容量,读写匹配

kubectl apply -f pvc.yaml

kubectl get pv,pvc

05-Ingress基础、Helm和物理卷

kubectl get pods

05-Ingress基础、Helm和物理卷

进入容器
kubectl exec -it nginx-dep1-69f5bb95b-dzsrj bash
ls /usr/share/nginx/html/

05-Ingress基础、Helm和物理卷

实验二 基于statefuset+PV(nfs),PVC实现有状态服务:

安装 NFS 服务器

yum install -y nfs-common nfs-utils  rpcbind
mkdir /nfs && cd /nfs
mkdir {1..10}
for i in {1..10};do echo $i > $i/index.html; done
chmod -R 777 /nfs
systemctl start nfs
systemctl enable rpcbind
systemctl enable nfs

vi /etc/exports

05-Ingress基础、Helm和物理卷
/nfs/1 *(rw,no_root_squash,no_all_squash,sync)
/nfs/2 *(rw,no_root_squash,no_all_squash,sync)
/nfs/3 *(rw,no_root_squash,no_all_squash,sync)
/nfs/4 *(rw,no_root_squash,no_all_squash,sync)
/nfs/5 *(rw,no_root_squash,no_all_squash,sync)
/nfs/6 *(rw,no_root_squash,no_all_squash,sync)
/nfs/7 *(rw,no_root_squash,no_all_squash,sync)
/nfs/8 *(rw,no_root_squash,no_all_squash,sync)
/nfs/9 *(rw,no_root_squash,no_all_squash,sync)
/nfs/10 *(rw,no_root_squash,no_all_squash,sync)

systemctl start rpcbind
systemctl restart nfs

所有node:

yum install -y nfs-common nfs-utils  rpcbind
systemctl start nfs
systemctl enable rpcbind
systemctl enable nfs

测试可用性(nfs切记要关闭防火墙):
mount -t nfs 192.168.1.13:/nfs/1 /test

升级成PV(存储工程师去做):
vi nfspv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfspv1
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs
  nfs:
    path: /nfs/1
    server: 192.168.1.13
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfspv2
spec:
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs
  nfs:
    path: /nfs/2
    server: 192.168.1.13

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfspv3
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs1
  nfs:
    path: /nfs/3
    server: 192.168.1.13

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfspv4
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs
  nfs:
    path: /nfs/4
    server: 192.168.1.13

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfspv5
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs
  nfs:
    path: /nfs/5
    server: 192.168.1.13

kubectl apply -f nfspv.yaml
kubectl  get pv

05-Ingress基础、Helm和物理卷

创建服务并声明PVC:

myweb.yaml

apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: wangyanglinux/myapp:v1
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "nfs"
      resources:
        requests:
          storage: 1Gi
05-Ingress基础、Helm和物理卷
05-Ingress基础、Helm和物理卷

statefuset特性:角标,顺序扩容缩

kubectl  get pvc,pv

05-Ingress基础、Helm和物理卷

pv3 storageClassName不满足, pv4读写策略不满足

继续创建两个pv

vi nfspv2.yaml

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfspv6
spec:
  capacity:
    storage: 2Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs
  nfs:
    path: /nfs/6
    server: 192.168.1.13

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfspv7
spec:
  capacity:
    storage: 1.5Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs
  nfs:
    path: /nfs/7
    server: 192.168.1.13

存储容量为2个g和1.5个g

kubectl get pv

05-Ingress基础、Helm和物理卷

预选和优选

kubectl edit statefulsets.apps web
修改 replicas: 4
kubectl  get pv,pvc

05-Ingress基础、Helm和物理卷

5G空间的PV被剩下来,由此可知:
1:当请求策略不同时,PV和PVC不能匹配
2:当预选都满足时(预选所有条件必须都满足),则按照服务创建顺序进行优选(注意PVC从上到下排列顺序从最优->匹配)

验证网站搭建成功:

05-Ingress基础、Helm和物理卷

验证数据持久化:
输入一部分数据到pod中作为验证数据

05-Ingress基础、Helm和物理卷

验证稳定的网络标识:

kubectl get svc -n kube-system
dig -t A web-0.nginx.default.svc.cluster.local. @10.96.0.1

05-Ingress基础、Helm和物理卷

kubectl delete pod web-0
ingress固定了域名后端的访问

05-Ingress基础、Helm和物理卷

kubectl exec -it web-0 -- sh

05-Ingress基础、Helm和物理卷

测试PV的数据稳定性

只要PVC没有被删除,PV不会随着pod的删除而删除
kubectl delete statefulsets.apps web
删除之后PV依然绑定

05-Ingress基础、Helm和物理卷

重跑服务:
kubectl apply -f myweb.yaml

kubectl exec -it web-0 -- sh

05-Ingress基础、Helm和物理卷

如果pvc被删除,PV将会进入release状态;

kubectl delete -f myweb.yaml

05-Ingress基础、Helm和物理卷

首先先直接挂上来备份数据,然后可以选择edit方式将released变成为可用状态

处理方式1:
kubectl edit pv nfspv1
删除:

05-Ingress基础、Helm和物理卷

kubectl get pv

05-Ingress基础、Helm和物理卷

处理方式2:
批量删除pv,重新创建pv

05-Ingress基础、Helm和物理卷

其他PV配置

PV配置示例-HostPath

kind: PersistentVolume
apiVersion: v1
metadata:
  name: task-pv-volume
  labels:
    type: local
spec:
  storageClassName: hostpath
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  hostPath:
    path: "/mnt/data"

PV配置示例-ceph

apiVersion: v1
kind: PersistentVolume
metadata:
  name: ceph-rbd-pv
spec:
  capacity:
    storage: 1Gi
  storageClassName: ceph-fast
  accessModes:
    - ReadWriteOnce
  rbd:
    monitors:
      - 192.168.1.123:6789
      - 192.168.1.124:6789
      - 192.168.1.125:6789
    pool: rbd
    image: ceph-rbd-pv-test
    user: admin
    secretRef:
      name: ceph-secret
    fsType: ext4
    readOnly: false
  • monitors:Ceph的monitor节点的IP
  • pool:所用Ceph Pool的名称,可以使用ceph osd pool ls查看
  • image:Ceph块设备中的磁盘映像文件,可以使用rbd create POOL_NAME/IMAGE_NAME --size 1024创建,使用rbd list POOL_NAME查看
  • user:Rados的用户名,默认是admin
  • secretRef:用于验证Ceph身份的密钥
  • fsType:文件类型,可以是ext4、XFS等
  • readOnly:是否是只读挂载

PVC创建和挂载失败的原因

PVC一直Pending的原因:

  • lPVC的空间申请大小大于PV的大小
  • lPVC的StorageClassName和PV不一致
  • lPVC的accessModes和PV的不一致

挂载PVC的Pod一直处于Pending(使用describe查看):

  • PVC没有创建成功/PVC不存在
  • PVC和Pod不在同一个Namespace

发布者:LJH,转发请注明出处:https://www.ljh.cool/8277.html

(0)
上一篇 2022年9月23日 上午2:27
下一篇 2022年9月26日 上午2:23

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注