笔记列表:
目录
- 144、k8s网络-为什么要使用Ingress网络_1
- 145、k8s网络-Ingress网络架构_1
- 146、k8s网络-部署Ingress-nginx_1
- 147、k8s网络-Ingress示例_1
- 148、k8s网络-Ingress细节配置-默认服务_1
- 149、k8s网络-nginx-ingress的全局配置_1
- 150、k8s网络-ingress限流等示例_1
- 151、k8s网络-ingress-nginx部署特点_1
- 152、k8s网络-ingress-路径重写示例_1
- 153、k8s网络-ingress-基于Cookie的会话保持技术_1
- 154、k8s网络-ingress-安全连接_1
- 155、k8s网站-ingress-几种证书的区别_1
- 156、k8s网络-ingress-金丝雀_1
- 157、k8s网络-networkpolicy-网络隔离策略_1
- 158、k8s网络-k8s网络小结_1
- 159、k8s网络-kube-proxy来控制节点直接网络_1
- 160、k8s存储-卷的基本概念_1
- 161、k8s存储-Secret的创建_1
- 162、k8s存储-secret使用Pod.env进行获取-不会热更新_1
- 163、k8s存储-secret挂载的方式使用_1
- 164、k8s存储-secret挂载默认只读_1
- 165、k8s存储-cm结合SpringBoot做到生产配置无感知_1
- 166、k8s存储-卷挂载-hostPath、emptyDir方式_1
- 167、k8s存储-nfs文件系统环境搭建_1
- 168、k8s存储-nfs进行挂载_1
- 169、k8s存储-pv与pvc与Pod的使用_1
- 170、k8s存储-pv的回收策略等细节
- 171、k8s存储-动态供应原理与流程_1
- 172、k8s存储-动态供应完成_1
144、k8s网络-为什么要使用Ingress网络_1
144.1、为什么需要Ingress?
- Service可以使用NodePort暴露集群外访问端口,但是性能低下,并不安全
- Ingress可以负载均衡、限流等
- Ingress 公开了从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由被Ingress 资源上定义的规则控制。
- 我们使用Ingress作为整个集群统一的入口,配置Ingress规则转到对应的Service
144.2、整体框架图
145、k8s网络-Ingress网络架构_1
146、k8s网络-部署Ingress-nginx_1
146.1、获取安装yaml文件
首先点击Ingress查看官方文档
然后我们需要看一下ingress-nginx
如何安装,在上面的文档中我们能找到如下内容点击下图红色方框中的蓝色链接就好,如下:
之后就进入了ingress-nginx的Installation Guide,然后往下滑动屏幕,之后就可以点击下面的Bare-metal进行安装了,如下:
然后就可以看到安装命令,但是在国内我们不能这样安装,我们把下图中的链接复制出来,在浏览器上访问就可以得到ingress-nginx的对应yaml文件
146.2、安装ingress-nginx
146.2.1、导入镜像
直接使用docker load -i 镜像tar包名称
即可导入,镜像在下面
链接:https://pan.baidu.com/s/1ofsKDRWXuvhTFWmqlvHG1Q?pwd=uycg
提取码:uycg
146.2.2、修改yaml文件
我的文件在下面
1、修改service的type
2、修改kind类型
3、修改上图DaemonSet下面的网络为主机网络,即80和443端口直接占据的就是虚拟机的80和443端口;另外还修改了镜像地址,原因是那个镜像我们无法下载
4、修改节点选择方式,之前那种节点相当于是选择所有的节点,修改之后的节点选择器只会选择部分打标签的节点
146.2.3、执行yaml文件
所需yaml文件在下面,然后通过kubectl apply -f XXX.yaml
命令执行就是了
apiVersion: v1
kind: Namespace
metadata:
name: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
---
# Source: ingress-nginx/templates/controller-serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx
namespace: ingress-nginx
automountServiceAccountToken: true
---
# Source: ingress-nginx/templates/controller-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
data:
---
# Source: ingress-nginx/templates/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
name: 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:
- extensions
- networking.k8s.io # k8s 1.14+
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ''
resources:
- events
verbs:
- create
- patch
- apiGroups:
- extensions
- networking.k8s.io # k8s 1.14+
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- networking.k8s.io # k8s 1.14+
resources:
- ingressclasses
verbs:
- get
- list
- watch
---
# Source: ingress-nginx/templates/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
name: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ingress-nginx
subjects:
- kind: ServiceAccount
name: ingress-nginx
namespace: ingress-nginx
---
# Source: ingress-nginx/templates/controller-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx
namespace: ingress-nginx
rules:
- apiGroups:
- ''
resources:
- namespaces
verbs:
- get
- apiGroups:
- ''
resources:
- configmaps
- pods
- secrets
- endpoints
verbs:
- get
- list
- watch
- apiGroups:
- ''
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io # k8s 1.14+
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- networking.k8s.io # k8s 1.14+
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- networking.k8s.io # k8s 1.14+
resources:
- ingressclasses
verbs:
- get
- list
- watch
- apiGroups:
- ''
resources:
- configmaps
resourceNames:
- ingress-controller-leader-nginx
verbs:
- get
- update
- apiGroups:
- ''
resources:
- configmaps
verbs:
- create
- apiGroups:
- ''
resources:
- events
verbs:
- create
- patch
---
# Source: ingress-nginx/templates/controller-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx
namespace: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: ingress-nginx
subjects:
- kind: ServiceAccount
name: ingress-nginx
namespace: ingress-nginx
---
# Source: ingress-nginx/templates/controller-service-webhook.yaml
apiVersion: v1
kind: Service
metadata:
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller-admission
namespace: ingress-nginx
spec:
type: ClusterIP
ports:
- name: https-webhook
port: 443
targetPort: webhook
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
---
# Source: ingress-nginx/templates/controller-service.yaml:不要
apiVersion: v1
kind: Service
metadata:
annotations:
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
type: ClusterIP ## 改为clusterIP
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
---
# Source: ingress-nginx/templates/controller-deployment.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
selector:
matchLabels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
revisionHistoryLimit: 10
minReadySeconds: 0
template:
metadata:
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
spec:
dnsPolicy: ClusterFirstWithHostNet ## dns对应调整为主机网络
hostNetwork: true ## 直接让nginx占用本机80端口和443端口,所以使用主机网络
containers:
- name: controller
image: ingress-nginx-controller:v0.46.0
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
exec:
command:
- /wait-shutdown
args:
- /nginx-ingress-controller
- --election-id=ingress-controller-leader
- --ingress-class=nginx
- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
runAsUser: 101
allowPrivilegeEscalation: true
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: LD_PRELOAD
value: /usr/local/lib/libmimalloc.so
livenessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 5
readinessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
ports:
- name: http
containerPort: 80
protocol: TCP
- name: https
containerPort: 443
protocol: TCP
- name: webhook
containerPort: 8443
protocol: TCP
volumeMounts:
- name: webhook-cert
mountPath: /usr/local/certificates/
readOnly: true
resources:
requests:
cpu: 100m
memory: 90Mi
nodeSelector: ## 节点选择器
node-role: ingress #以后只需要给某个node打上这个标签就可以部署ingress-nginx到这个节点上了
#kubernetes.io/os: linux ## 修改节点选择
serviceAccountName: ingress-nginx
terminationGracePeriodSeconds: 300
volumes:
- name: webhook-cert
secret:
secretName: ingress-nginx-admission
---
# Source: ingress-nginx/templates/admission-webhooks/validating-webhook.yaml
# before changing this value, check the required kubernetes version
# https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#prerequisites
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
name: ingress-nginx-admission
webhooks:
- name: validate.nginx.ingress.kubernetes.io
matchPolicy: Equivalent
rules:
- apiGroups:
- networking.k8s.io
apiVersions:
- v1beta1
operations:
- CREATE
- UPDATE
resources:
- ingresses
failurePolicy: Fail
sideEffects: None
admissionReviewVersions:
- v1
- v1beta1
clientConfig:
service:
namespace: ingress-nginx
name: ingress-nginx-controller-admission
path: /networking/v1beta1/ingresses
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: ingress-nginx-admission
annotations:
helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
namespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: ingress-nginx-admission
annotations:
helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
rules:
- apiGroups:
- admissionregistration.k8s.io
resources:
- validatingwebhookconfigurations
verbs:
- get
- update
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ingress-nginx-admission
annotations:
helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ingress-nginx-admission
subjects:
- kind: ServiceAccount
name: ingress-nginx-admission
namespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: ingress-nginx-admission
annotations:
helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
namespace: ingress-nginx
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- create
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ingress-nginx-admission
annotations:
helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
namespace: ingress-nginx
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: ingress-nginx-admission
subjects:
- kind: ServiceAccount
name: ingress-nginx-admission
namespace: ingress-nginx
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: ingress-nginx-admission-create
annotations:
helm.sh/hook: pre-install,pre-upgrade
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
namespace: ingress-nginx
spec:
template:
metadata:
name: ingress-nginx-admission-create
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
spec:
containers:
- name: create
image: docker.io/jettech/kube-webhook-certgen:v1.5.1
imagePullPolicy: IfNotPresent
args:
- create
- --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.$(POD_NAMESPACE).svc
- --namespace=$(POD_NAMESPACE)
- --secret-name=ingress-nginx-admission
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
restartPolicy: OnFailure
serviceAccountName: ingress-nginx-admission
securityContext:
runAsNonRoot: true
runAsUser: 2000
---
# Source: ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: ingress-nginx-admission-patch
annotations:
helm.sh/hook: post-install,post-upgrade
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
namespace: ingress-nginx
spec:
template:
metadata:
name: ingress-nginx-admission-patch
labels:
helm.sh/chart: ingress-nginx-3.30.0
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.46.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: admission-webhook
spec:
containers:
- name: patch
image: docker.io/jettech/kube-webhook-certgen:v1.5.1
imagePullPolicy: IfNotPresent
args:
- patch
- --webhook-name=ingress-nginx-admission
- --namespace=$(POD_NAMESPACE)
- --patch-mutating=false
- --secret-name=ingress-nginx-admission
- --patch-failure-policy=Fail
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
restartPolicy: OnFailure
serviceAccountName: ingress-nginx-admission
securityContext:
runAsNonRoot: true
runAsUser: 2000
146.2.4、修改节点的标签,让ingress-nginx部署到对应节点
只要执行下面的命令之后,对应的节点上就会部署ingress-nginx
kubectl label node 节点名称 node-role=ingress
可以通过kubectl get ds -A
去查看部署情况,可以看到有一台机器上部署了ingress-nginx
146.2.5、如何从浏览器访问ingress-nginx
一图胜千言,根据节点选择,可以让ingress-nginx
部署到部分节点中,然后我们说一下流量走向,从外部访问的流量到达F5硬件层面的负载均衡器,之后流量就会被打到部署ingress-nginx的节点上(直接使用ingress-nginx
所在节点的ip进行负载均衡即可,另外ingress-nginx用的80和443端口是节点所在虚拟机的主机ip),然后ingress-nginx
在根据规则将流量达到service中,只有service在将流量打到具体执行业务的Pod中
147、k8s网络-Ingress示例_1
首先先说下面的yaml文件,it666.com
是我随意起的名字,pathType: Prefix
代表按照前缀匹配,path: /
代表前缀是/
就行,backend.service.name: canary-service-test
代表到达ingress-nginx
的流量会分配到canary-service-test
这个service里面,并且对应的service端口是80
,我们只需要在windows中的hosts文件中配置上node2节点的虚拟机ip和it666.com的关联关系就可以了,例如:192.168.139.134 it666.com
,之后我们在浏览器中直接访问http://it666.com(访问之后,链接后面会默认带/
)就可以看到nginx的结果页了,并且也能看到负载均衡的效果
既然已经提到了匹配方式,那就大致介绍一下吧
- Prefix:前缀匹配
- Exact:精确匹配
这些匹配方式的详细解释,以及详细用法都可以通过官网去学习
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: it666-ingress
namespace: default
spec:
rules:
- host: it666.com
http:
paths:
- path: /
pathType: Prefix
backend: ## 指定需要响应的后端服务
service:
name: canary-service-test ## kubernetes集群的svc名称
port:
number: 80 ## service的端口号
148、k8s网络-Ingress细节配置-默认服务_1
记得在hosts文件中配置192.168.139.134 it672.com
,基本情况不需要解释了,说一下效果吧,我们访问http://it672.com/abc看到的是下图效果
如果访问http://it672.com,那么看到的是下图效果
所以如果访问的内容不匹配,那就会访问默认服务,其中defaultBackend.service.name
访问的是默认服务的名称,而defaultBackend.service.port.number
访问的是默认服务service中的端口
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: it672-ingress
namespace: default
spec:
defaultBackend: ## 指定所有未匹配的默认后端
service:
name: php-apache
port:
number: 80
rules:
- host: it672.com
http:
paths:
- path: /abc
pathType: Prefix
backend:
service:
name: canary-service-test
port:
number: 80
149、k8s网络-nginx-ingress的全局配置_1
首先我们需要知道可以修改哪些全局配置,点击ConfigMaps就可以去查看了,然后还给了配置示例,如下:
data:
map-hash-bucket-size: "128"
ssl-protocols: SSLv2
具体配置效果是这样的,如下:
我们可以通过下面的命令去进行配置,保存就可以更新配置了,如果配置没有更新,那就把那两个ingress-nginx
的Pod删除了,让它自己生成就可以应用最新配置了
kubectl edit cm ingress-nginx-controller -n ingress-nginx
150、k8s网络-ingress限流等示例_1
正常访问http://it777.com/abc都是没问题的,但是我们持续点击F5
按键,那就会出现下面内容:
原因就是被限流拦截了
既然已经看完了效果,那就来看一下yaml文件吧,其实我们只添加了一个metadata.annotations.nginx.ingress.kubernetes.io/limit-rps: "1"
,这个作用就是限制1s中之内只能访问一次
想了解更多注解用法的,请看:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: it777-ingres
namespace: default
annotations: ##注解
nginx.ingress.kubernetes.io/limit-rps: "1" ### 限流的配置
spec:
rules:
- host: it777.com
http:
paths:
- path: /abc
pathType: Prefix
backend:
service:
name: canary-service-test
port:
number: 80
151、k8s网络-ingress-nginx部署特点_1
在安装ingress-nginx的yaml文件中,我们看到默认的标签选择节点的方式是可以给每一个机器部署ingress-nginx,但是后来我们更改之后就会让只有特定标签的节点才会安装ingress-nginx
152、k8s网络-ingress-路径重写示例_1
下面就是yaml文件,我们直接访问http://it888.com/api/hello,看到的内容如下:
从上面可以看出/api
已经被截取掉了,只留下了/hello
,所以达到了截串的目的
想了解更多注解用法的,请看:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2 ### 访问service的时候只会留下/api/后面的部分,官方链接:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#rewrite
name: it888-rewrite-ingress
namespace: default
spec:
rules:
- host: it888.com
http:
paths:
- backend:
service:
name: php-apache
port:
number: 80
path: /api(/|$)(.*)
pathType: Prefix
153、k8s网络-ingress-基于Cookie的会话保持技术_1
想了解更多注解用法的,请看:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: it999-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/affinity: "cookie" # 官方链接:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#cookie-affinity
nginx.ingress.kubernetes.io/session-cookie-name: "atguigu-session" # 如果不写该注解,那么默认名称是INGRESSCOOKIE
spec:
rules:
- host: it999.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: canary-service-test
port:
number: 80
154、k8s网络-ingress-安全连接_1
154.1、生成密钥文件
具体命令是:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ${KEY_FILE_NAME} -out ${CERT_FILE_NAME} -subj "/CN=${公司域名}/O=${公司域名}"
例如:
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.cert -subj "/CN=it666.com/O=it666.com"
说明:
其中${XXX}
中的名称都是可以改变的,上面例子的含义是生成遵守x509
规范的密钥,有效期是365
天,加密算法是rsa:2048
,生成的密钥key
文件名称是tls.key
,而密钥value
的文件名称是tls.cert
,然后公司的域名是it666.com
154.2、生成secret
具体命令是:
kubectl create secret tls ${secret名称} --key ${KEY_FILE_NAME} --cert ${CERT_FILE_NAME}
例子:
kubectl create secret tls it666-tls --key tls.key --cert tls.cert
说明:
其中kubectl create secret tls
是定死的,而it666-tls
是我们自己起的secret名称,而tls.key
和tls.cert
和上一步生成的两个文件名称一一对应
拓展:
如果想看secret在哪里,我们可以通过命令kubectl get secret
去查看
154.3、使用说明
对应yaml
文件就在下面了,在浏览器上可以访问https://it666.com/abcd就可以了,可以看到效果就是有证书(虽然证书无效,但是证书依然使用上了)
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: it100-ingress
namespace: default
spec:
tls:
- hosts:
- it666.com # 公司域名
secretName: it666-tls # secret名称
rules:
- host: it666.com
http:
paths:
- path: /abcd
pathType: Prefix
backend:
service:
name: canary-service-test
port:
number: 80
155、k8s网站-ingress-几种证书的区别_1
证书分级(安全性从上往下依次增强):
- DV:域名验证型证书
- OV:企业验证型证书
- EV:增强验证型证书
详细分级请看:科普:SSL证书中DV证书,OV证书和EV证书的特点与区别
156、k8s网络-ingress-金丝雀_1
156.1、service和ingress金丝雀版本对比
-
service金丝雀灰度发布版本(请看:129.2、金丝雀部署示例):service通过标签labels选择Pod来完成灰度发布
-
ingress金丝雀灰度发布版本:使用不同ingress选择不同service,进而选择不同Pod来完成灰度发布
156.2、ingress金丝雀版本部署示例
156.2.1、service和deployment示例(先执行)
说明:
用于生成两个service,2个deployment,并且service和其中一个deployment对应,未来我们的ingress来把流量达到service中,进而把流量分配到Pod中
其中访问canary-v1-service
的结果是nginx默认页
,而canary-v2-service
的结果是111111111
首先:
直接使用docker load -i 镜像tar包名称
即可导入,镜像在下面
链接:https://pan.baidu.com/s/1CBOrbuTBBJSa15xl7lMlsQ?pwd=kqgx
提取码:kqgx
其次执行yaml文件:
apiVersion: v1
kind: Service
metadata:
name: canary-v1-service
namespace: default
spec:
selector:
app: canary-v1-pod
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: canary-v1-deploy
namespace: default
labels:
app: canary-v1-deploy
spec:
selector:
matchLabels:
app: canary-v1-pod
replicas: 1
template:
metadata:
labels:
app: canary-v1-pod
spec:
containers:
- name: nginx
image: nginx
---
apiVersion: v1
kind: Service
metadata:
name: canary-v2-service
namespace: default
spec:
selector:
app: canary-v2-pod
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 80
protocol: TCP
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: canary-v2-deploy
namespace: default
labels:
app: canary-v2-deploy
spec:
selector:
matchLabels:
app: canary-v2-pod
replicas: 1
template:
metadata:
labels:
app: canary-v2-pod
spec:
containers:
- name: nginx
image: nginx-test:env-msg
156.2.2、ingress普通版本示例(中间执行)
说明:
普通版本对应canary-v1-service
这个service
操作:
执行kubectl apply -f XXX.yaml
即可,其中yaml文件就在下面
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: canary-v1-ingress
namespace: default
spec:
rules:
- host: it110.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: canary-v1-service
port:
number: 80
156.2.3、ingress金丝雀版本示例(最后执行)
- 想了解金丝雀版本的更多用法,请看:https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#canary
- 注解nginx.ingress.kubernetes.io/canary的作用:在上面ingress普通版本示例中,我们看到这两个spec中的内容都是相同的,不过我们执行下面yaml文件的时候没有报错,原因是我们通过
nginx.ingress.kubernetes.io/canary: "true"
注解指明了当前ingress版本是金丝雀版本,用以完成灰度发布功能,所以执行过程中不会报错 - 三个注解的优先级对比:分别是nginx.ingress.kubernetes.io/canary-by-header
>
nginx.ingress.kubernetes.io/canary-by-cookie>
nginx.ingress.kubernetes.io/canary-weight,对于这三个注解而言,虽然多个优先级的可以并存,但是高优先级注解执行之后就不会执行低优先级的注解了 - 注解nginx.ingress.kubernetes.io/canary-by-header:如果我们这样写,那么流量都会到ingress金丝雀版本中,不会到ingress普通版本中,postman中访问方式如下。如果你认为value值不想用always或者never判断,那就可以用
nginx.ingress.kubernetes.io/canary-by-header-value
来指定你认可的值,当value中是该值的时候,流量就会全部打到ingress金丝雀版本中
- 注解nginx.ingress.kubernetes.io/canary-by-cookie:如果我们这样写,那么流量都会到ingress金丝雀版本中,不会到ingress普通版本中,postman中访问方式如下
- 注解nginx.ingress.kubernetes.io/canary-weight:如果我们这样写,那么流量的80%都会到ingress金丝雀版本中,另外20%会到ingress普通版本中,postman中访问方式如下
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: canary-v2-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/canary: "true" # 值为true表示当前ingress是金丝雀版本
nginx.ingress.kubernetes.io/canary-by-header: "v2_header" # canary-by-header方式,如果对应值是always,那么始终将流量分配到这,如果值为never,那么作用相反
nginx.ingress.kubernetes.io/canary-by-cookie: "v2_cookie" # canary-by-cookie方式,如果对应值是always,那么始终将流量分配到这,如果值为never,那么作用相反
nginx.ingress.kubernetes.io/canary-weight: "80" # canary-weight方式,使用比率来控制分配到该ingress中的流量,其中0~100之间都是可用的
spec:
rules:
- host: it110.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: canary-v2-service
port:
number: 80
157、k8s网络-networkpolicy-网络隔离策略_1
157.1、网络隔离策略的简介
- 概念:既可以用入站规则限制别人访问Pod,也可以用出站规则限制Pod访问别人
- 网络隔离策略是名称空间下的资源吗?:是
- 标识符:全名称是
NetworkPolicy
,缩写是netpol
- 适用资源:Pod
- 出入站规则:
- 入站规则:限制别人访问Pod
- 出站规则:限制Pod访问别人
- 策略分类(适用于入站规则和出站规则):
- 基于Pod的标签
- 基于名称空间的标签
- 基于网络范围
157.2、使用示例
使用的yaml就在下面,先把里面的标签选择规则改成自己的,在用kubectl apply -f XXX.yaml
执行就是了,然后按照下面的例子我们说一下测试方式,就测试一个入站规则吧,我们找到标签中app=busybox
的Pod,然后进入该Pod。之后找到标签中app=nginx
的Pod,复制下该Pod的ip,然后在上面busybox的容器中进行访问就好了;下面我们对yaml文件中的属性进行说明,如下所示:
- podSelector:根据Pod的标签选中需要应用网络隔离策略的Pod
- policyTypes:说明使用的是入站规则还是出站规则,默认是Ingress入站规则
- ingress:定义入站白名单,也就是谁可以访问该Pod。然后可以通过ip范围、名称空间标签、Pod标签3种方式进行限制,3种方式可以并存,下面说一下3种网络隔离策略使用方式
- 任何一个成立都行:下面例子中的写法,属于或者的关系,也就是任何一个成立都是可以访问的
- 必须全满足:如果我们把
namespaceSelector
、podSelector
中的-
去掉,那就变成了交集,也就是必须满足这3种网络隔离策略才能访问nginx
- egress:定义出站白名单,也就是该Pod可以访问谁。然后可以通过ip范围、名称空间标签、Pod标签3种方式进行限制,3种方式可以并存,上面已经说了3种网络隔离策略使用方式,这里不再赘述
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: network-policy-test
namespace: default
spec:
podSelector: ## 根据标签选中Pod,一旦这些Pod被选中,它们的网络策略将由下面出入站规则policyTypes控制
matchLabels:
app: nginx # app是标签键,而nginx是标签值
policyTypes: ## 定义上面Pod的入站出站规则,默认值是Ingress;其中Ingress代表入站规则,Egress代表出站规则,可以只写一个
- Ingress
- Egress
ingress: ## 定义入站白名单,也就是限制谁可以访问该Pod
- from:
- ipBlock: # ip方式
cidr: 10.101.0.0/16 # 允许的范围,范围是10.101.0.0~10.101.255.255
except: # 不被允许的IP范围,范围是10.101.1.0~10.101.1.255
- 10.101.1.0/24
- namespaceSelector: # 名称空间的标签选择方式,查看标签名称是kubectl get ns --show-labels
matchLabels:
kubernetes.io/metadata.name: default # kubernetes.io/metadata.name是名称空间的标签键,而default是名称空间的标签值
- podSelector: # Pod的标签选择方式
matchLabels:
app: busybox # app是Pod的标签键,而busybox是Pod的标签值
ports: # 设置可以访问的端口和协议
- protocol: TCP
port: 80
egress: ## 定义出站白名单,也就是限制该Pod可以访问谁
- to: # 下面同样可以配置ipBlock、namespaceSelector、podSelector三种网络隔离策略,不过上面已经介绍过了,这里不再赘述
- ipBlock:
cidr: 10.101.0.0/16
ports: # 设置可以访问的端口和协议
- protocol: TCP
port: 80
158、k8s网络-k8s网络小结_1
158.1、访问架构图
流程解释:
流量从客户端出发,经过DNS到达我们的负载均衡器(比如F5硬件负载均衡器),之后根据负载均衡规则,流量到达安装有Ingress的虚拟机上,Ingress根据规则把流量打到Service中,然后Service在根据自己的负载均衡策略将流量打到对应的Pod中,最终由Pod中的容器进行请求处理
158.2、访问流程
上面用文字做了简单解释,下面在用图来解释一下
158.3、网络互通原理
158.3.1、容器——>容器
解释: 一个Pod内部直接使用本地回路(loopback)通信
158.3.2、Pod——>Pod(同节点)
解释: Pod1访问Pod2,从Pod1的网卡出发到虚拟机的网卡,两者存在一个绑定关系,虚拟机的网卡当然也不能处理,那就通过网桥进行转发,网桥根据CIDR(网络范围)将请求转换到另外一个Pod了
158.3.3、Pod——>Pod(跨节点)
解释: Pod1访问Pod4,它们在不同的虚拟机上,从Pod1的网卡触发到VM1虚拟机的网卡,然后网卡把请求转给VM1虚拟机的网桥,网桥根据CIDR(网络范围)发现自己不能处理,然后它就去把请求发送到能处理它的另外一个虚拟机VM2,然后VM2接收之后通过网桥》虚拟机网卡,最终把流量送到了Pod4
158.3.4、Pod——>Service
解释: Pod1通过Pod网卡到虚拟机网卡,然后虚拟机网卡把请求转到网桥,网桥去查询IPtables/ipvs,找到合适的Ip之后在去把请求传给Pod
158.3.5、Service——>Pod
解释: 也是需要IPtables/ipvs的介入才能把请求转到对应的Pod
158.3.6、Pod——>Internet
158.3.7、Pod——>Internet(负载均衡,4层模型)
158.3.8、Pod——>Internet(Ingress,7层模型)
159、k8s网络-kube-proxy来控制节点直接网络_1
kubeproxy负载将所有节点的IP信息进行同步,所以我们访问任何一个节点都是OK的
160、k8s存储-卷的基本概念_1
160.1、卷挂载含义
- 概念:容器说自己需要把一些东西挂到外边,Pod帮它来实现这个构思,最终完成卷挂载
- 精髓:容器声明卷挂载,也就是哪些位置需要挂载出去;Pod声明卷详情,也就是说卷的位置到底在哪里。这些精髓都是可以落脚到yaml文件中
- 绘图说明:下图可以来说明,其中volumeMounts对应容器中的卷挂载声明,而volumes对应Pod的卷详情说明,这两个属性就是yaml文件中用到的属性
161.2、卷挂载类型概览
- 配置信息
- Secret:用来保存敏感配置信息。Base64加密配置信息,一般是用户名、密码之类的敏感信息,比如我们阿里云连接信息就可以是Secret类型的
- ConfigMap:用来保存普通配置信息。根据云原生12要素中所说,配置应该和应用分离,比如我们的微服务应用的application.properties配置就可以放在ConfigMap中,然后随时修改随时生效
- 临时存储
- emptyDir:绝对临时存储;随Pod而生,随Pod而死,在Pod中随便找的一个空目录
- hostPath:相对临时存储;内容会存储到虚拟机本地,但是即使Pod死了,也不会删除hostPath的内容,不过如果Pod在别的虚拟机上拉起,这些数据也肯定找不到,毕竟其他机器上没有这些内容
- 持久化存储
- glusterFS
- nfs
- cephfs
- ……
更多卷挂载信息请看:https://kubernetes.io/docs/concepts/storage/volumes/
161、k8s存储-Secret的创建_1
161.1、基本介绍
- Secret对象类型用来保存敏感信息,例如密码、OAuth 令牌和 SSH 密钥。 将这些信息放在 secret 中比放在 Pod 的定义或者 容器镜像 中来说更加安全(他人不可见)和灵活(修改很方便)。
- Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象。用户可以创建 Secret,同时系统也创建了一些 Secret。
- 官方文档:https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/
161.2、secret种类
161.2.1、普通划分方法
- docker-registry:创建一个给 Docker registry 使用的 secret。在配置连接阿里云镜像仓库密钥的时候用过,详情请看:
104.2、如何从私有镜像仓库下载镜像
- tls:创建一个 TLS secret。在配置ingress安全连接的时候用过,详情请看:
154.2、生成secret
- generic:从本地 file, directory 或者 literal value 创建一个 secret。这个下面会讲到
161.2.2、细致划分方法
说明: 可以通过kubectl get secrets 资源名称 -oyaml
查看详情类型type,比如kubectl get secrets my-aliyun -oyaml
,例如:
更多内置类型请看下面表格:
161.3、创建secret用法
说明: docker-registry
、tls
类型的情况之前都已经讲过了,这里不再赘述,所以下面只说明generic
的用法
161.3.1、普通字符串
命令方式:
# kubectl create secret generic是定死的,而mysql-secret是secret的名称
# username是key,value是root,并且password是key,value是123456,用命令创建的方式中的value值都是明文
kubectl create secret generic mysql-secret \
--from-literal=username='root' \
--from-literal=password='123456'
yaml文件方式:
注意:username
和password
的值都是经过Base64加密算法进行加密过后的写法
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
data:
username: cm9vdA==
password: MTIzNDU2
161.3.2、文件内容
161.3.2.1、默认键名(键名是文件名称)
命令方式:
# 首先新建两个文件,分别是username.txt和password.txt,并且里面放置的内容分别是root、123456
kubectl create secret generic mysql_secret_file \
--from-file=./username.txt \
--from-file=./password.txt
yaml文件方式:
注意:username.txt
和password.txt
的值都是经过Base64加密算法进行加密过后的写法
apiVersion: v1
kind: Secret
metadata:
name: mysql_secret_file
data:
username.txt: cm9vdAo=
password.txt: MTIzNDU2Cg==
161.3.2.1、指定键名
命令方式:
# kubectl create secret generic是定死的,而mysql_secret_file_02是secret的名称
# username是key,value是username.txt内容,并且password是key,value是password.txt内容
kubectl create secret generic mysql_secret_file_02 \
--from-file=username=./username.txt \
--from-file=password=./password.txt
yaml文件方式:
注意:username
和password
的值都是经过Base64加密算法进行加密过后的写法
apiVersion: v1
kind: Secret
metadata:
name: mysql_secret_file_02
data:
username: cm9vdAo=
password: MTIzNDU2Cg==
162、k8s存储-secret使用Pod.env进行获取-不会热更新_1
以下yaml
文件中包含3种可以动态获取配置的方式,分别是secretKeyRef
(从secret资源中获取键值)、fieldRef
(从yaml文件中动态获取属性值)、resourceFieldRef
(从yaml文件的pod资源配置中获取resource资源信息)
测试的时候我们需要进入busybox
容器,命令是:kubectl exec -it pod-use-secret-test -- /bin/sh
,如下所示:
我们即使更新了secret资源中的键值,但是也不会更改已经运行的容器中的变量值,所以这也被称作不会热更新
下面是测试用的yaml文件:
apiVersion: v1
kind: Pod
metadata:
name: "pod-use-secret-test"
namespace: default
labels:
app: "pod-use-secret-test"
spec:
containers:
- name: pod-use-secret-test
image: "busybox"
command: ['/bin/sh', '-c', 'sleep 3600']
resources:
limits:
cpu: 200m
memory: 500Mi
requests:
cpu: 100m
memory: 200Mi
env:
- name: username # 在容器中可以用$username方式调用
valueFrom:
secretKeyRef: # 1、secret
name: mysql-secret # secret资源名称
key: username # 键名称
- name: namespace # 在容器中可以用$namespace方式调用
valueFrom:
fieldRef: # 2、field
fieldPath: metadata.namespace # 来自上面属性字段的全路径
- name: limitcpu # 在容器中可以用$limitcpu方式调用
valueFrom:
resourceFieldRef: # 3、resource
containerName: pod-use-secret-test # 上面pod的名称
resource: limits.cpu # 上面pod资源的一些限制信息,可以填写的内容比如有:limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu, requests.memory and requests.ephemeral-storage
上面那几种配置方式都来自于kubectl explain
命令所得,如下所示:
163、k8s存储-secret挂载的方式使用_1
163.1、将secret中的所有键值都以文件的方式挂载进去,其中键为文件名,值为文件内容
apiVersion: v1
kind: Pod
metadata:
name: "pod-secret-volume-all-test"
namespace: default
labels:
app: "pod-secret-volume-all-test"
spec:
containers:
- name: pod-secret-volume-all-test
image: "busybox"
command: ['/bin/sh', '-c', 'sleep 3600']
volumeMounts: # 在容器中声明挂载信息
- name: app
mountPath: /app
volumes: # 指定挂载详情
- name: app
secret: # 以secret方式挂载,这只是其中一种,还可以是configMap、cephfs、nfs、hostPath等
secretName: mysql-secret # secret资源名称,下面不加items属性,这种会挂载所有文件(键为名,值为文件内容)到容器指定位置
进入busybox看一下效果吧,如下:
163.2、将secret中的部分键值以文件的方式挂载进去,其中键名是我们自己指定的,值为文件内容
apiVersion: v1
kind: Pod
metadata:
name: "pod-secret-volume-items-test"
namespace: default
labels:
app: "pod-secret-volume-items-test"
spec:
containers:
- name: pod-secret-volume-items-test
image: "busybox"
command: ['/bin/sh', '-c', 'sleep 3600']
volumeMounts: # 在容器中声明挂载信息
- name: app
mountPath: /app
volumes: # 指定挂载详情
- name: app
secret: # 以secret方式挂载,这只是其中一种,还可以是configMap、cephfs、nfs、hostPath等
secretName: mysql-secret # secret资源名称
items:
- key: username # secret中的键名
path: info/username.txt # 必须是相对路径,否则会报错
进入busybox看一下效果吧,如下:
164、k8s存储-secret挂载默认只读_1
secret资源挂载到容器内部默认是只读的,不能从容器内部进行修改。如果真的想从容器内部修改,那就需要考虑我们进入容器时的权限问题,其中挂载到容器内部的secret资源的权限值得是Pod外部的用户权限,即使我们在容器内部是root用户,但是依然无法修改容器内的secret挂载资源
165、k8s存储-cm结合SpringBoot做到生产配置无感知_1
165.1、创建ConfigMap
165.1.1、普通字符串
命令方式:
kubectl create configmap my-config \
--from-literal=username=root \
--from-literal=password=123456
yaml方式:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
data:
username: root
password: "123456"
165.1.2、类似文件
165.1.2.1、默认键名(键名是文件名称)
命令方式:
kubectl create configmap my-config-file \
--from-file=username.txt \
--from-file=password.txt
yaml方式:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config-file
data:
username.txt: | # 键名就是文件名称,键值是文件内容
root
password.txt: |
123456
165.1.2.2、指定键名
命令方式:
kubectl create configmap my-config-file-1 \
--from-file=username=username.txt \
--from-file=password=password.txt
yaml方式:
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config-file-1
data:
username: | # 键名是我们指定的名称,键值是文件内容
root
password: |
123456
165.2、使用ConfigMap
165.2.1、Pod中env环境变量
apiVersion: v1
kind: Pod
metadata:
name: "pod-use-configmap-test"
namespace: default
labels:
app: "pod-use-configmap-test"
spec:
containers:
- name: pod-use-configmap-test
image: "busybox"
command: ['/bin/sh', '-c', 'sleep 3600']
env:
- name: username # 在容器中可以用$username方式调用
valueFrom:
configMapKeyRef: # configMap类型,可以对比之前说过的secret(加密信息)、fieldRef(字段属性)、resourceFieldRef(Pod中的resource资源)
name: my-config # configMap资源名称
key: username # 键名称
进入busybox看一下效果吧,如下:
165.2.2、将ConfigMap中的配置信息挂载到容器内部
165.2.2.1、挂载ConfigMap中的全部键值
apiVersion: v1
kind: Pod
metadata:
name: "pod-configmap-volume-all-test"
namespace: default
labels:
app: "pod-configmap-volume-all-test"
spec:
containers:
- name: pod-configmap-volume-all-test
image: "busybox"
command: ['/bin/sh', '-c', 'sleep 3600']
volumeMounts: # 在容器中声明挂载信息
- name: app
mountPath: /app
volumes: # 指定挂载详情
- name: app
configMap: # 以configmap方式挂载,这只是其中一种,还可以是secret、cephfs、nfs、hostPath等
name: my-config # configMap资源名称,下面不加items属性,这种会挂载所有文件(键为名,值为文件内容)到容器指定位置
进入busybox看一下效果吧,如下:
165.2.2.2、挂载ConfigMap中的部分键值
apiVersion: v1
kind: Pod
metadata:
name: "pod-configmap-volume-items-test"
namespace: default
labels:
app: "pod-configmap-volume-items-test"
spec:
containers:
- name: pod-configmap-volume-items-test
image: "busybox"
command: ['/bin/sh', '-c', 'sleep 3600']
volumeMounts: # 在容器中声明挂载信息
- name: app
mountPath: /app # app会被当做目录
volumes: # 指定挂载详情
- name: app
configMap: # 以configMap方式挂载,这只是其中一种,还可以是secret、cephfs、nfs、hostPath等
name: my-config # configMap资源名称
items:
- key: username # configMap中的键名
path: info/username.txt # 必须是相对路径,否则会报错
- key: password # configMap中的键名
path: info/password.txt # 必须是相对路径,否则会报错
进入busybox看一下效果吧,如下:
165.2.3、spec.containers.volumeMounts.subPath的使用
具体用法大家看一下就知道了,官方不建议使用subPath,原因是:
configMap、hostPath外边的内容更新的时候不会更新容器里面的内容,而不用subPath的情况会进行热更新
apiVersion: v1
kind: Pod
metadata:
name: "pod-configmap-volume-items-test-2"
namespace: default
labels:
app: "pod-configmap-volume-items-test-2"
spec:
containers:
- name: pod-configmap-volume-items-test-2
image: "busybox"
command: ['/bin/sh', '-c', 'sleep 3600']
volumeMounts: # 在容器中声明挂载信息
- name: username
mountPath: /app/username.txt # 下面写subPath,这必须写上username.txt,不然app会被当成文件,然后把username.txt放在app文件中
subPath: username.txt # 和上面的username.txt一致即可;可用于指定所引用的卷内的子路径,而不是其根路径。
volumes: # 指定挂载详情
- name: username
configMap: # 以configMap方式挂载,这只是其中一种,还可以是secret、cephfs、nfs、hostPath等
name: my-config # configMap资源名称
items:
- key: username # configMap中的键名
path: username.txt # 必须是相对路径,否则会报错
165.3、公司使用configMap示例
先说一下configMap的创建结果:
在来看我们在项目的yaml文件中如何使用他们呢,如下:
以下截图是和上面containers
同级的volumes
的内容:
165.4、configMap和secret的区别
- secret可以创建的种类多,而configMap可以创建的种类少:
secret
可以创建的种类分别有tls
(创建一个 TLS secret;例如:ingress安全连接的密钥创建)、docker-registry
(创建一个给 Docker registry 使用的 secret;例如连接阿里云私有镜像仓库的用户名和密码配置)、generic
(从本地 file, directory 或者 literal value 创建一个 secret;这就是上面讲解的最常用的要求);而configMap
只相当于拥有generic
这一个 - secret的内容是Base64加密存储的,而configMap中的内容是明文存储的
- secret用的次数比较少,而configMap比较常用一点
166、k8s存储-卷挂载-hostPath、emptyDir方式_1
166.1、emptyDir
161.1.1、概念
- emptyDir方式挂载的目录随Pod而生,随Pod而死,所以数据一般不妨在它里面
- 卷最开始是空的
- 存储空间来自于本地kubelet根目录(通常是根磁盘)或者内存,这个可以通过参数进行设置;其中
pod.spec.volumes.emptyDir.medium
默认值是空串,那么将存储在kubelet根目录中,而pod.spec.volumes.emptyDir.medium
的值为Memory
的时候,那就会把数据存储在内存中了 - Pod中的所有容器都可以使用这个空目录,下面例子就是最好的证明
161.1.2、示例
下面的例子是113、k8s工作负载-Pod的多容器协同
中的例子
apiVersion: v1
kind: Pod
metadata:
name: "multi-container-pod"
namespace: default
labels:
app: "multi-container-pod"
spec:
containers:
- name: nginx-container
image: "nginx"
volumeMounts:
- name: common-vol
mountPath: /usr/share/nginx/html
- name: alpine-container
image: "alpine"
command: ["/bin/sh", "-c", "while true; do sleep 1; date > /app/index.html; done;"]
volumeMounts:
- name: common-vol
mountPath: /app
volumes:
- name: common-vol
emptyDir: {
} # docker匿名挂载
166.2、hostPath
166.2.1、概念
作用: 将主机上的目录/文件挂载到容器内
如果主机上的目录/文件不存在,但是我们还想让它在挂载的时候自动生成,那就可以使用spec.volumes.name.hostPath.type
属性,可用值列表如下:
详细信息请看:https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#hostpath
然后给个示例吧,如下:
166.2.1、示例
166.2.1.1、将主机时间文件挂载到容器内部
作用: 这样容器内部的时间就是正常的,这个很重要
apiVersion: v1
kind: Pod
metadata:
name: "pod-hostpath-test"
namespace: default
labels:
app: "pod-hostpath-test"
spec:
containers:
- name: pod-hostpath-test
image: "busybox"
command: ['sleep', '3600']
volumeMounts:
- name: localtime
mountPath: /etc/localtime # 接收主机上的时间文件
volumes:
- name: localtime
hostPath: # 将主机的时间文件挂载到容器内部
path: /usr/share/zoneinfo/Asia/Shanghai
进入busybox
容器查看结果,如下:
说明:虽然两个都是文件,但是依然挂载成功了
166.2.2、configMap和hostPath的区别
- 相同
- subPath使用之后,容器中的内容不会热更新
- 不同
- mountPath挂载方式不同:如果仅仅使用
spec.containers.volumeMounts.mountPath
,而不使用spec.containers.volumeMounts.subPath
;configMap
会把该路径当做目录,然后把相关文件放在它下面;而hostPath
会根据spec.volumes.hostPath.path
的类型来决定spec.containers.volumeMounts.mountPath
的类型,两者是相等的 - subPath挂载方式不同:如果
spec.containers.volumeMounts.mountPath
和spec.containers.volumeMounts.subPath
都使用;configMap
会把mountPath
当成文件,hostPath的不咋会
- mountPath挂载方式不同:如果仅仅使用
167、k8s存储-nfs文件系统环境搭建_1
在85、k8s-集群创建完成
已经搭建完成了
168、k8s存储-nfs进行挂载_1
yaml
文件直接就在下面,yaml
文件的作用是把index.html
文件放在nfs
的共享目录中,我们直接通过修改nfs
共享目录下test
目录中的index.html
,那就可以修改访问pod
的返回结果
apiVersion: v1
kind: Pod
metadata:
name: "pod-nginx-nfs-direct"
namespace: default
labels:
app: "pod-nginx-nfs-direct"
spec:
containers:
- name: pod-nginx-nfs-direct
image: "nginx"
ports:
- containerPort: 80
name: http
volumeMounts:
- name: localtime
mountPath: /etc/localtime
- name: html
mountPath: /usr/share/nginx/html # 这也是已经存在的一个目录,用来存储访html文件,比如index.html
volumes:
- name: localtime
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
- name: html
nfs: # 采用nfs方式进行挂载
server: 192.168.139.133 # 这是nfs所在虚拟机的浏览器访问地址,不是nfs服务的内网地址
path: /nfs/data/test # 这也是已经存在的一个目录,其中/nfs/data目录是nfs的存储目录,目前里面存放的是index.html
169、k8s存储-pv与pvc与Pod的使用_1
169.1、pv、pvc、storageClass
- pv(PersistentVolume):真正落地存储,和物理存储目录关联,每一个pv都位于pv池中
- pvc(PersistentVolumeClaim):申请pv的一个说明,里面需要写用什么存储类、容量大小、删除策略等信息
- storageClass:这是存储类,相当于pv的一个分类,用来区分不同种类的pv,pv池中虽然含有很多pv,但是每一个pv都有不同的类别,比如存储类可以是我们自己命名的一个名称,或者是nfs的动态存储
169.2、手动创建PV,实现PVC静态供应
说明: 下面举例中静态供应使用的是nfs中的目录,其中静态供应中的目录没有任何的限制,只要是目录就是可以的
169.2.1、手动创建PV
下面创建了3个pv,分别是10m、100m、1g的pv,如下图所示:
创建10m的pv:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-10m-test
namespace: default
labels:
app: pv-10m-test
spec:
storageClassName: my-self-storage # 存储类名称,每一个pod都隶属于一个存储类
capacity:
storage: 10m # 标明容量
accessModes:
- ReadWriteOnce # 访问模式
nfs:
server: 192.168.139.133 # nfs所在的虚拟机路径
path: /nfs/data/a # /nfs/data是nfs的主目录,目录a是已经创建好的目录
创建100m的pv:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-100m-test
namespace: default
labels:
app: pv-100m-test
spec:
storageClassName: my-self-storage # 存储类名称,每一个pod都隶属于一个存储类
capacity:
storage: 100m # 标明容量
accessModes:
- ReadWriteOnce # 访问模式
nfs:
server: 192.168.139.133 # nfs所在的虚拟机路径
path: /nfs/data/b # /nfs/data是nfs的主目录,目录b是已经创建好的目录
创建1g的pv:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-1gi-test
namespace: default
labels:
app: pv-1gi-test
spec:
storageClassName: my-self-storage # 存储类名称,每一个pod都隶属于一个存储类
capacity:
storage: 1Gi # 标明容量
accessModes:
- ReadWriteOnce # 访问模式
nfs:
server: 192.168.139.133 # nfs所在的虚拟机路径
path: /nfs/data/c # /nfs/data是nfs的主目录,目录c是已经创建好的目录
169.2.2、手动创建PVC去申请PV
在下面的yaml
文件中我们创建了一个20m
的申请书,并且使用的存储类就是创建上面pv
时用到的存储类,所以k8s会在该存储类下面的所有pv中选择一个容量最合适的pv,然后将该pv和pvc绑定,我们上面创建了10m、100m、1g的pv,那最合适的肯定是100m的pv了,所以pvc和100m的pv进行绑定,如下所示:
该pvc
本次在该存储类下面的pv
列表中找到了合适的pv
,如果找不到的话,那么pvc的状态会一直是pending
这种做法的坏处就是需要提前去创建PV,这样会增加运维工程师的工作量,所以最好是自动根据申请书的容量去创建PV,这样既可以减轻运维工程师的工作量,还可以按需获取PV,不会浪费存储空间,后续我们会说到nfs动态挂载,它的出现就是为了解决上述两个问题的
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-20m-test
namespace: default
labels:
app: pvc-20m-test
spec:
storageClassName: my-self-storage # 说明使用那个存储类,只能使用该存储类下的pv
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20m # 说明pvc申请书的容量
169.3、创建Pod去使用PVC
上面已经创建了pvc,并且pvc已经和pv进行了绑定,下面这个yaml文件的作用就是使用这个pvc,我们此处看一下pod的状态,如下:
然后我们创建一个index.html放在pv里面,并且修改index.html的内容,直接访问pod的ip,发现输出的正是index.html中的内容,如下:
yaml文件如下:
apiVersion: v1
kind: Pod
metadata:
name: "pod-nginx-static-pvc-test"
namespace: default
labels:
app: "pod-nginx-static-pvc-test"
spec:
containers:
- name: pod-nginx-static-pvc-test
image: "nginx"
ports:
- containerPort: 80
name: http
volumeMounts:
- name: localtime
mountPath: /etc/localtime
- name: html
mountPath: /usr/share/nginx/html # 这也是已经存在的一个目录
volumes:
- name: localtime
hostPath:
path: /usr/share/zoneinfo/Asia/Shanghai
- name: html
persistentVolumeClaim: # 使用存储卷声明方式
claimName: pvc-20m-test # pvc名称
170、k8s存储-pv的回收策略等细节
170.1、回收策略类型
- Retain:默认值,即使删除了pvc,pvc对应的目录也不会删除,里面的内容更不会删除,并且pv的状态就从
Bound
变成Released
,虽然看起来是释放了,但是以后不能被任何PVC绑定,即使是原来的PVC也不行,这个我已经尝试过了 - Recycle:即使删除了pvc,pvc对应的目录也不会删除,但是目录里面的东西会自动删除,并且PV的type从
Bound
变成Available
,那以后就可以被其他PVC挂载,NFS和HostPath支持该用法 - Delete:诸如AWS EBS、GCE PD、Azure Disk或OpenStack Cinder卷这类的关联资产也会被删除;
- 如果静态供应中的NFS使用这种方案,当删除PVC之后,PV的type从
Bound
变成Failed
,说明回收失败了,pv对应目录以及目录中的内容也不会被删除,但是以后不能被任何PVC绑定,即使是原来的PVC也不行,这个我已经尝试过了 - 如果动态供应中的NFS使用这种方案,那是可以奏效的,并且可以通过设置注解来完成删除pv之前将pv备份的功能,然后在删除pv,这一点在创建动态供应nfs的时候已经设置过了,如下图所:
- 如果静态供应中的NFS使用这种方案,当删除PVC之后,PV的type从
拓展:
既然提到了pv中的type,那我们再说一下pvc中的type,其中pvc中type的默认值是Delete
,另外两种是Retain、Recycle,所以pvc中的type和pv中的一样,对于NFS动态供应来说,我们直接通过NFS动态供应的存储类创建的pv的type和pvc的type一致
如果使用85、k8s-集群创建完成
中搭建的那一套NFS动态供应,并且创建存储类的时候设置了自动删除备份功能,也就是上图红色框中框选的部分,那我们删除pvc的时候也会同步删除pv,并且在删除pv之前将pv的内容部分好,备份文件夹名称是archived-名称空间-pvc名称-pv名称
,例如:archived-test-image-pvc-5eb7d15c-c81e-4074-803b-2c691542a37a
170.2、PV、PVC如何设置回收策略
PV:
PVC:
170.3、Pod、PVC、PV删除所产生的影响
- Pod:Pod删除不会删除PVC
- PVC:Pod没有删除的时候pvc不能删除,PVC删除之后会对PV产生影响
- PV:PV删除的时候可能会备份,其中NFS动态供应中在存储类中设置相关注解才行,如下:
171、k8s存储-动态供应原理与流程_1
171.1、PV和PVC访问模式
下面这几种访问模式,PV和PVC都是支持的,如果是静态供应的情况,我们需要手动设置PV的访问模式;如果是NFS动态供应的话,我们只需要设置PVC的访问模式,然后就可以间接设置PV的访问模式
- ReadWriteOnce:卷可以被一个节点以读写方式挂载。 ReadWriteOnce 访问模式也允许运行在同一节点上的多个 Pod 访问卷。
- ReadOnlyMany:卷可以被多个节点以只读方式挂载。
- ReadWriteMany:卷可以被多个节点以读写方式挂载。
上述3种方式,NFS都是支持的
PV示例如下:
PVC示例如下:
171.2、动态供应图
换一种表示方式:
172、k8s存储-动态供应完成_1
说明: 85、k8s-集群创建完成
已经讲过了
172.1、使用NFS动态供应创建PVC
下面这个例子就是PVC使用NFS动态供应的例子
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-pvc-2
namespace: default
labels:
app: nginx-pvc-2
spec:
storageClassName: managed-nfs-storage ## NFS动态供应的存储类名字,按照你自己的填写,如果设置了默认存储类,就可以不设置该值,默认也会使用默认存储类
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100m