k8s阶段05 Operator, DaemonSet, Job, CronJob, Ingress和Ingress Controller(蓝绿/恢复发布), helm
基本要求: 需要给每个实例惟一且固定的标识,依赖于一个专用的Headless Service; 需要给每个实例一个专用的PVC卷,该卷要来自volumeTemplateClaim,卷的标识 “template_name-pod_name”; Pod Management Policy: OrderedReady:按顺序,依次 Parallel:并行 StatefulSet仅负责为有状态应用的编排,提供一个基础框架;
Operator Framework: #go开发框架 声明式API 自定义的资源类型: 外置、独立的API Server; #通过k8s的api server调到自己开发的API Server CRD: #K8S里自定义资源类型 自定义Controller #自己开发控制器 基于专用的Operator编排运行某有状态应用的逻辑: 1、部署Operator及其专用的资源类型; 2、使用专用的资源类型,来声明一个有状态应用的编排需求; #社区中心网站 https://operatorhub.io/ #示例(通过Operator安装es) #参考文档: https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-deploy-eck.html #1.部署crd (就会拥有crd资源对象) [root@master01 ~]#kubectl create -f https://download.elastic.co/downloads/eck/2.15.0/crds.yaml #查看crd [root@master01 ~]#kubectl get crd #生成的资源类型 [root@master01 ~]#kubectl explain Elasticsearch #2.基于RBAC规则部署operator (也就是执行上面资源对象的控制器) [root@master01 ~]#kubectl apply -f https://download.elastic.co/downloads/eck/2.15.0/operator.yaml [root@master01 ~]#kubectl get pods -n elastic-system NAME READY STATUS RESTARTS AGE elastic-operator-0 1/1 Running 0 91s #3.定义es集群(注意内存,每个节点4g) [root@master01 eck-operator]#vim elasticsearch-myes-cluster.yaml apiVersion: elasticsearch.k8s.elastic.co/v1 kind: Elasticsearch metadata: name: namespace: mall spec: version: 8.13.0 #es集群版本 nodeSets: #每个实例设定 - name: default #这个配置叫default count: 3 config: node.store.allow_mmap: false #是否启用内存映射 volumeClaimTemplates: #卷请求模板 - metadata: name: elasticsearch-data spec: accessModes: - ReadWriteOnce resources: requests: storage: 5Gi #storageClassName: nfs-csi storageClassName: openebs-hostpath #存储类 [root@master01 eck-operator]#kubectl create namespace mall #会创建pod,service,statefulset [root@master01 eck-operator]#kubectl apply -f elasticsearch-myes-cluster.yaml [root@master01 eck-operator]#kubectl get all -n mall NAME READY STATUS RESTARTS AGE pod/myes-es-default-0 1/1 Running 0 18m pod/myes-es-default-1 1/1 Running 0 18m pod/myes-es-default-2 1/1 Running 0 18m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/myes-es-default ClusterIP None <none> 9200/TCP 18m service/myes-es-http ClusterIP 10.106.251.132 <none> 9200/TCP 18m service/myes-es-internal-http ClusterIP 10.107.141.153 <none> 9200/TCP 18m service/myes-es-transport ClusterIP None <none> 9300/TCP 18m NAME READY AGE statefulset.apps/myes-es-default 3/3 18m #获取es首次登陆密码 [root@master01 eck-operator]#kubectl get secret -n mall myes-es-elastic-user Opaque 1 24m [root@master01 eck-operator]#kubectl get secret myes-es-elastic-user -o yaml -n mall elastic: MTdZMU1YN2RNOG4zcDlWeFRmcjA4TGEw #base64解码 ]#echo MTdZMU1YN2RNOG4zcDlWeFRmcjA4TGEw | base64 -d 17Y1MX7dM8n3p9VxTfr08La0 #访问es服务(通过service/myes-es-http服务) ]#curl -u "elastic:17Y1MX7dM8n3p9VxTfr08La0" -k https://10.106.251.132:9200 #也可生成一个交互式pod来访问,这样可以通过服务名地址访问 ]#kubectl run client-$RANDOM --image ikubernetes/admin-box:v1.2 -it --rm --restart=Never --command -- /bin/bash root@client-17621 /# curl -u "elastic:17Y1MX7dM8n3p9VxTfr08La0" -k https://myes-es-http.mall:9200 #定义kibana [root@master01 eck-operator]#vim kibana-myes.yaml apiVersion: kibana.k8s.elastic.co/v1 kind: Kibana metadata: name: kibana namespace: mall spec: version: 8.13.0 count: 1 elasticsearchRef: #应用es集群名 name: "myes" http: tls: #使用tls通讯 selfSignedCertificate: disabled: true service: spec: type: LoadBalancer #会创建kibana的pod,deployment和service [root@master01 eck-operator]#kubectl apply -f kibana-myes.yaml #直接有一个kibana的资源对象 (当前为red是因为要下载pod并运行) [root@master01 eck-operator]#kubectl get kibana -n mall NAME HEALTH NODES VERSION AGE kibana red 8.13.0 25s [root@master01 eck-operator]#kubectl get all -n mall NAME READY STATUS RESTARTS AGE pod/kibana-kb-dfc656fdc-snrth 1/1 Running 0 6m ... NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kibana-kb-http LoadBalancer 10.97.83.49 10.0.0.53 5601:31706/TCP 6m ... #浏览器输入,访问kibana,用户名/密码:elastic/17Y1MX7dM8n3p9VxTfr08La0 10.0.0.53:5601 #定义filebeat(上面Operator创建crd已包含filebeat) [root@master01 eck-operator]#vim beats-filebeat.yaml apiVersion: beat.k8s.elastic.co/v1beta1 kind: Beat metadata: name: filebeat namespace: mall #把整个文件中的namespace都改成mall,下面还有 spec: type: filebeat version: 8.13.0 elasticsearchRef: #引用的es name: "myes" kibanaRef: #引用的kibana name: "kibana" ... #下面有排除一些名称空间下的pod(和系统有关,防止敏感信息泄露) #会用daemonset部署filebeat [root@master01 eck-operator]#kubectl apply -f beats-filebeat.yaml #会有filebeat的资源类型 [root@master01 eck-operator]#kubectl get beat -n mall NAME HEALTH AVAILABLE EXPECTED TYPE VERSION AGE filebeat red 3 filebeat 37s #查看daemonset [root@master01 eck-operator]#kubectl get ds -n mall #扩容,升级等操作只要修改配置文件并应用即可,升级会用内置的滚动更新策略,eck operator 会自动完成
#DaemonSet用于确保所有或选定的工作节点上都运行有一个Pod副本 DaemonSet:编排系统级应用 资源规范: selector: {} template:{} 系统级存在共享宿主信息或资源需要: 1、hostNet/hostPid/hostUser 2、hostPath volume 更新: updateStrategy rollingUpdate: #默认滚动更新 maxSurge #默认0,一般都设置为0,否则就有2个冲突了 maxUnavailable #默认1 #默认如下设定,也比较合理 updateStrategy: rollingUpdate: maxSurge: 0 maxUnavailable: 1 type: RollingUpdate #示例 [root@master01 daemonsets]#vim daemonset-demo.yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: daemonset-demo namespace: prom labels: app: prometheus component: node-exporter spec: selector: matchLabels: app: prometheus component: node-exporter template: metadata: name: prometheus-node-exporter labels: app: prometheus component: node-exporter spec: containers: - image: prom/node-exporter:v1.5.0 name: prometheus-node-exporter ports: - name: prom-node-exp containerPort: 9100 hostPort: 9100 livenessProbe: tcpSocket: port: prom-node-exp initialDelaySeconds: 3 readinessProbe: httpGet: path: '/metrics' port: prom-node-exp scheme: HTTP initialDelaySeconds: 5 hostNetwork: true #共享宿主机网络 hostPID: true [root@master01 daemonsets]#kubectl create namespace prom [root@master01 daemonsets]#kubectl apply -f daemonset-demo.yaml -n prom #查看(这里3个是因为集群节点3个) [root@master01 daemonsets]#kubectl get ds -n prom NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE daemonset-demo 3 3 0 3 0 <none> 58s [root@master01 daemonsets]#kubectl get ds -n prom -o wide NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE CONTAINERS IMAGES SELECTOR daemonset-demo 3 3 3 3 3 <none> 101s prometheus-node-exporter prom/node-exporter:v1.5.0 app=prometheus,component=node-exporter #查看pod(因为共享宿主机网络,所以ip显示的是节点地址) [root@master01 daemonsets]#kubectl get pods -n prom -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES daemonset-demo-cfdbq 1/1 Running 0 5m24s 10.0.0.154 node03 <none> <none> daemonset-demo-nggp7 1/1 Running 0 5m24s 10.0.0.152 node01 <none> <none> daemonset-demo-zhqrd 1/1 Running 0 5m24s 10.0.0.153 node02 <none> <none> #查看随便一台的指标 [root@master01 daemonsets]#curl 10.0.0.154:9100/metrics #升级 [root@master01 daemonsets]#vim daemonset-demo.yaml ... spec: containers: - image: prom/node-exporter:v1.6.0 #修改版本 #更新 [root@master01 daemonsets]#kubectl apply -f daemonset-demo.yaml #可以看到是逐一更新的 ]#kubectl get pods -n prom -w
#一次性任务用job,周期性任务用cronjob #本质是cronjob是不断创建一个新job来实现 #注:Job和CronJob类型重启策略应该设置为OnFailure或Never,OnFailure最合适(可设重启次数,默认6) #有时候有些服务pod会使用job来做环境初始化
Job负责编排运行有结束时间的“一次性”任务,而前面的Deployment和DaemonSet主要负责编排始终运行的守护进程类应用;
◼ 控制器要确保Pod内的进程“正常(成功完成任务)”地退出
◼ 非正常退出的Pod可以根据需要重启,并在重试一次的次数后终止
◼ 有些Job是单次任务,也有些Job需要运行多次(次数通常固定)
◼ 有些任务支持同时创建及并行运行多个Pod以加快任务处理速度,Job控制器还允许用户自定义其并行度
需要周期性运行的Job,则由CronJob控制器负责编排
◼ CronJob建立在Job的功能之上,是更高层级的控制器
◼ 它以Job控制器完成单批次的任务编排,而后为这种Job作业提供需要运行的周期定义
Job资源同样需要标签选择器和Pod模板,但它不需要指定replicas,而是应该给定completions,即需要完成的作业数,默认为1次; ◼ Job资源会为其Pod对象自动添加“job-name=JOB_NAME”和“controller-uid=UID”标签,并使用标签选择器完成对controller-uid标签的关联,因此,selector并非必选字段 ◼ Pod的命名格式:`$(job-name)-$(index)-$(random-string),其中的$(index)字段取值与completions和completionMode有关 ◼ 注意 ◆ Job资源所在群组为“batch/v1” ◆ Job资源中,Pod的RestartPolicy的取值 只能为Never或OnFailure #示例模板 apiVersion: batch/v1 # API群组及版本; kind: Job # 资源类型特有标识; metadata: name <string> # 资源名称,在作用域中要惟一; namespace <string> # 名称空间;Job资源隶属名称空间级别; spec: selector <object> # 标签选择器,必须匹配template字段中Pod模板中的标签;(可不设,Job自动生成标签够用) suspend <boolean> # 是否挂起当前Job的执行,挂起作业会重置StartTime字段的值; template <object> # Pod模板对象; completions <integer> #期望的成功完成的作业次数,成功运行结束的Pod数量;(要运行几次) completionMode <string> # 追踪Pod完成的模式,支持Indexed和NonIndexed(默认)两种; ttlSecondsAfterFinished <integer> # 终止状态作业的生存时长,超期将被删除; parallelism <integer> # 作业的最大并行度,默认为1;(不超过completions运行次数,否则无意义) backoffLimit <integer> # 将作业标记为“Failed”之前的重试次数,默认为6; activeDeadlineSeconds <integer> # 作业启动后可处于活动状态的时长;
#下面模拟一个简单Job(串行运行) [root@master01 jobs_and_cronjobs]#vim job-demo.yaml apiVersion: batch/v1 kind: Job metadata: name: job-demo spec: template: spec: containers: - name: myjob image: ikubernetes/admin-box:v1.2 imagePullPolicy: IfNotPresent command: ["/bin/sh", "-c", "sleep 15"] #执行命令 restartPolicy: Never completions: 2 #要运行2次 ttlSecondsAfterFinished: 3600 backoffLimit: 3 activeDeadlineSeconds: 300 #运行并观察,启动一个完成后再启动一个 ]#kubectl apply -f job-demo.yaml && kubectl get pods -w #完成后查看pods,都是Completed状态 [root@master01 ~]#kubectl get pods NAME READY STATUS RESTARTS AGE job-demo-2rpxh 0/1 Completed 0 114s job-demo-ct2xk 0/1 Completed 0 38s #查看job [root@master01 jobs_and_cronjobs]#kubectl get jobs -o wide #下面模拟一个简单Job(并行运行) [root@master01 jobs_and_cronjobs]#vim job-para-demo.yaml apiVersion: batch/v1 kind: Job metadata: name: job-para-demo spec: template: spec: containers: - name: myjob image: ikubernetes/admin-box:v1.2 imagePullPolicy: IfNotPresent command: ["/bin/sh", "-c", "sleep 15"] restartPolicy: Never completions: 6 #运行6次 parallelism: 2 #并行数改为2 ttlSecondsAfterFinished: 3600 backoffLimit: 3 activeDeadlineSeconds: 1200 #运行,同一时间有2个pod执行,至于在哪个节点上是调度器决定的 [root@master01 jobs_and_cronjobs]#kubectl apply -f job-para-demo.yaml &&kubectl get pods -w #job一般不存在更新的需求
#每隔一段时间根据job模板创建job CronJob控制器用于管理Job资源的运行时间,它允许用户在特定的时间或以指定的间隔运行Job CronJob控制器的功能类似于linux操作系统的周期性任务作业计划(crontab),用于控制作业运行的时间点及周期性运行的方式: ◼ 仅在未来某时间点将指定的作业运行一次 ◼ 在指定的周期性时间点重复运行指定的作业 CronJob资源也是标准的API资源类型 注意: ◼ 在CronJob中,通配符“?”和“*”的意义相同,它们都表示任何可用的有效值 #示例模板 apiVersion: batch/v1 # API群组及版本; kind: CronJob # 资源类型特有标识; metadata: name <string> # 资源名称,在作用域中要惟一; namespace <string> # 名称空间;CronJob资源隶属名称空间级别; spec: jobTemplate <Object> # job作业模板,必选字段; metadata <object> # 模板元数据; spec <object> # 作业的期望状态; schedule <string> # 调度时间设定,必选字段; #前一job没结束,后一job开始了,允许吗?allow允许,forbid禁止,Replace替换(后job替换前job) concurrencyPolicy <string> # 并发策略,可用值有Allow、Forbid和Replace; failedJobsHistoryLimit <integer> # 失败作业的历史记录数,默认为1; successfulJobsHistoryLimit <integer> # 成功作业的历史记录数,默认为3; startingDeadlineSeconds <integer> #因错过时间点而未执行的作业的可超期时长;(因快到下一个执行点了) suspend <boolean> # 是否挂起后续的作业,不影响当前作业,默认为false; #Cronjob说明: #每两小时执行一次 0 */2 * * * #分钟不能用*,不然就会变成没隔2小时每分钟执行 0 7,10,16 * * * #7,10,16点各执行一次 0 8-18 * * * #8点到18点,每小时执行一次 #示例 [root@master01 jobs_and_cronjobs]#vim cronjob-demo.yaml apiVersion: batch/v1 kind: CronJob metadata: name: cronjob-demo namespace: default spec: schedule: "* * * * *" #每分钟执行一次 jobTemplate: metadata: labels: #标签加不加都可以 controller: cronjob-demo spec: parallelism: 1 #并行度为1 completions: 1 #运行1次 ttlSecondsAfterFinished: 600 backoffLimit: 3 activeDeadlineSeconds: 60 template: spec: containers: - name: myjob image: ikubernetes/admin-box:v1.2 command: - /bin/sh - -c - date; echo Hello from CronJob, sleep a while...; sleep 10 restartPolicy: OnFailure startingDeadlineSeconds: 300 [root@master01 jobs_and_cronjobs]#kubectl apply -f cronjob-demo.yaml #查看,每分钟会执行job (job和pod保留最近3个,设置可改) [root@master01 jobs_and_cronjobs]#kubectl get cronjob,job,pods NAME SCHEDULE TIMEZONE SUSPEND ACTIVE LAST SCHEDULE AGE cronjob.batch/cronjob-demo * * * * * <none> False 0 31s 44s NAME STATUS COMPLETIONS DURATION AGE job.batch/cronjob-demo-28882640 Complete 1/1 13s 31s NAME READY STATUS RESTARTS AGE pod/cronjob-demo-28882640-llz5p 0/1 Completed 0 31s #查看日志,里面会显示几点执行的 [root@master01 jobs_and_cronjobs]#kubectl logs cronjob-demo-28882640-llz5p Sat Nov 30 09:20:00 UTC 2024 Hello from CronJob, sleep a while... #避免一直运行,这里删除cronjob,对应的job和pod也会被删除 [root@master01 jobs_and_cronjobs]#kubectl delete -f cronjob-demo.yaml
将服务类应用暴露至集群外部的方法: NodePort Service LoadBalancer Service 使用专用NodePort来暴露服务 Service with ExternalIP 使用专用的ExternalIP来暴露服务 以上四层代理 通过 Ingress + Ingress Controller 转为七层代理,统一管理流量 #Ingress Controller直接把请求打到service下的pod上,进行负载均衡(不需要service负载均衡了)。 #service的负载均衡功能不需要了,但是需要pod发现功能,把pod信息发给Ingress Controller Ingress及其它相关的资源类型 + Ingress Controller 资源类型: Ingress IngressClass #告诉哪个Ingress Controller可以加载解析Ingress资源 IngressGateway #更高阶的功能,流量网关,业务网关(目前属于alpha特性,后续版本会提供) Ingress Controller: #有如下几种可以选择 Ingress-Nginx: kubernetes-sigs #用的最多 registry.k8s.io Kong Traefik #用的较多 Contour Gloo Cilium #各主流Ingress Controller对比图: https://blog.palark.com/wp-content/uploads/2019/10/kubernetes-ingress-comparison.png 七层代理多个服务的方式: 虚拟主机: port ip host: 基于主机名的虚拟主机 基于单一虚拟主机开放多服务: scheme://host:port/PATH{1,2,3, ...} 最终可用的方式:基于主机名的虚拟主机; SSL虚拟主机:SNI Ingress的类型: 简单扇出:基于单一虚拟主机使用不同的Path开放多服务 http://magedu.com/blog/ --> wordpress:80/blog/ #会访问wordpress下的blog url rewrite #可以通过rewrite跳转到wordpress/下 --annotation nginx.ingress.kubernetes.io/rewrite-target="/" 基于主机名的虚拟主机 SSL
类型一:Simple fanout
#主机一样,路径不同
#每一个服务使用一个独立的主机名 #例: service1.magedu.com service2.magedu.com
#把其中一个主机名配置为https
部署Ingress-Nginx
#官网 https://github.com/kubernetes/ingress-nginx #注意表中Ingress-NGINX版本对k8s版本的适配 https://kubernetes.github.io/ingress-nginx/deploy/ #部署Ingress-Nginx ]#kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.12.0-beta.0/deploy/static/provider/cloud/deploy.yaml #查看资源对象(会创建在ingress-nginx的名称空间中) [root@master01 ~]#kubectl get all -n ingress-nginx ...#因为部署了metallb,这里ingress-nginx-controller服务自动分配了EXTERNAL-IP service/ingress-nginx-controller LoadBalancer 10.96.135.77 10.0.0.52 80:32563/TCP,443:30464/TCP 12m [root@master01 ~]#kubectl get pods -n ingress-nginx NAME READY STATUS RESTARTS AGE ingress-nginx-admission-create-sx2t8 0/1 Completed 0 3h ingress-nginx-admission-patch-4djcx 0/1 Completed 0 3h ingress-nginx-controller-7d56585cd5-6jdp5 1/1 Running 0 3h #浏览器可以尝试访问ingress-nginx-controller服务,会报404 nginx,因为还没有主机 10.0.0.52 #部署Ingress-Nginx时,会自动创建叫nginx的ingressclass (部署controller都会创建一个对应ingressclass) [root@master01 ~]#kubectl get ingressclass NAME CONTROLLER PARAMETERS AGE nginx k8s.io/ingress-nginx <none> 76m
把服务开放到外部去访问
创建使用Ingress资源: kubectl create ingress NAME --rule=host/path=service:port[,tls[=secret]] [options] --class #指定ingressclass是谁 注意事项: (1) Ingress是名称空间级别的资源,它仅应该引用同一个名称空间下的Service; (2) 主机名不是集群上的资源对象,因而其作用范围为集群级别; #实际操作示例(把demoapp服务通过ingress-nginx对外暴露): #如果没有service,先创建一个service ]#kubectl create service clusterip demoapp --tcp=80:80 [root@master01 ~]#kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/demoapp ClusterIP 10.107.218.150 <none> 80/TCP 14s #创建Ingress资源(主机:demoapp.magedu.com;路径:/表示起始路径/*起始与所有路径,加''防止*被shell解析) #ingress要开发sevice通常在同一名称空间 #先测试输出看看效果 ]#kubectl create ingress demoapp --rule='demoapp.magedu.com/*'=demoapp:80 --class=nginx --dry-run -o yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: creationTimestamp: null name: demoapp spec: ingressClassName: nginx rules: - host: demoapp.magedu.com http: paths: - backend: service: name: demoapp port: number: 80 path: / pathType: Prefix #/*就是Prefix;如果是/就是Exact,精确匹配/(不会代理/abc) status: loadBalancer: {} ]#kubectl create ingress demoapp --rule='demoapp.magedu.com/*'=demoapp:80 --class=nginx #也可以使用下面声明式对象配置 ]#kubectl create ingress demoapp --rule='demoapp.magedu.com/*'=demoapp:80 --class=nginx --dry-run=client -o yaml > ingress-demoapp.yaml ]#kubectl apply -f ingress-demoapp.yaml #查看ingress资源 [root@master01 ~]#kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE demoapp nginx demoapp.magedu.com 80 10s #查看详情(底下Reason为sync,Scheduled for sync表示ingress已经被Ingress-Nginx加载并生效了) [root@master01 ~]#kubectl describe ingress demoapp ... Rules: Host Path Backends ---- ---- -------- demoapp.magedu.com / demoapp:80 (10.244.1.145:80,10.244.2.125:80,10.244.3.91:80) Annotations: <none> Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Sync 4m10s (x2 over 4m51s) nginx-ingress-controller Scheduled for sync #测试,主机host文件配置 ingress-nginx-controller的EXTERNAL-IP给对应主机名 10.0.0.52 demoapp.magedu.com #浏览器访问即可返回,刷新会自动跳转到各个pod demoapp.magedu.com #进入nginx的pod中查看,nginx的conf中上游通过lua脚本实现上游怎么发现,使用什么balance代理(如删除ingress资源,nginx会自动把对应配置删除) #ingress-nginx会读取ingress资源变动,并将其映射为自己配置文件上的配置,并让niginx随时动态按需重载 #示例(把wordpress暴露到外面) #创建ingress ]#kubectl create ingress wordpress --rule='blog.magedu.com/*'=wordpress:80 --class=nginx -n blog #查看ingress ]#kubectl describe ingress wordpress -n blog #把blog.magedu.com配入宿主机host文件中,访问测试
Annotation(了解, 早期使用)
Annotation:#可以给ingress-nginx配置更多参数 注解信息;添加到资源对象上的kv类型的数据; 键标识:[prefix/]key 不适用于标签选择器来过滤资源对象; 常用于为资源提供注释信息,该信息还可以被特定的控制器解读为应用的配置的信息 #yaml中使用格式 metadata: labels: ... annotations: ... 命令:kubectl annotate #使用方式和label相同 #ingress-nginx配置参数参考 https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/ #例: #url重写路径 nginx.ingress.kubernetes.io/enable-rewrite-log "true" or "false"
把ingress配置为ssl的类型
SSL Ingress: 准备secret 创建Ingress,指明要加载secret中的证书和私钥 kubectl create ingress NAME --rule=host/path=service:port[,tls[=secret]] [options] #示例 #创建私钥 [root@master01 ~]#(umask 011;openssl genrsa -out demoapp.key 2048) #基于demoapp.key创建自签证书(subj指定证书持有者信息) [root@master01 ~]#openssl req -new -x509 -key ./demoapp.key -out ./demoapp.crt -days=3655 -subj="/CN=demoapp.magedu.com" #创建成secret(类型tls,名称demoapp-ssl) [root@master01 ~]#kubectl create secret tls demoapp-ssl --key=./demoapp.key --cert=./demoapp.crt #查看 [root@master01 ~]#kubectl get secrets #删除前面的ingress,重新建简单些 [root@master01 ~]#kubectl delete ingress demoapp #创建ingress ]#kubectl create ingress demoapp --rule='demoapp.magedu.com/*'=demoapp:80,tls=demoapp-ssl --class=nginx #查看是否完成同步(Scheduled for sync说明完成了同步) [root@master01 ~]#kubectl describe ingress demoapp ... Normal Sync 23s nginx-ingress-controller Scheduled for sync #浏览器访问(点高级,继续访问即可) https://demoapp.magedu.com/
简单扇出:基于单一虚拟主机使用不同的Path开放多服务(用的比较少)
#注意: 把www.magedu.com/demoapp/路径映射出去,demoapp也需要/demoapp/路径,没有可以用rewrite做url重写 简单扇出:基于单一虚拟主机使用不同的Path开放多服务 http://magedu.com/blog/ --> wordpress:80/blog/ #会访问wordpress下的blog url rewrite #可以通过rewrite跳转到wordpress/下 --annotation nginx.ingress.kubernetes.io/rewrite-target="/" #创建ingress ]#kubectl create ingress www --rule='www.magedu.com/demoapp/*'=demoapp:80 --class=nginx --annotation nginx.ingress.kubernetes.io/rewrite-target="/" #修改host文件,浏览器访问测试 http://www.magedu.com/demoapp/
基于Ingress Nginx的灰度发布
Ingress-Nginx支持配置Ingress Annotations来实现不同场景下的灰度发布和测试,它能够满足金丝雀发
布、蓝绿部署与A/B测试等不同的业务场景
https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/ #ingress-nginx配置参数canary,true:当前ingress规则发新版本,false或没设:接入流量发给旧版本(相当于发布开关) nginx.ingress.kubernetes.io/canary "true" or "false" #如果上面的发布开关canary为true,流量怎么在新旧版本之间做调整,通过下面参数 nginx.ingress.kubernetes.io/canary-by-header string nginx.ingress.kubernetes.io/canary-by-header-value string nginx.ingress.kubernetes.io/canary-by-header-pattern string nginx.ingress.kubernetes.io/canary-by-cookie string nginx.ingress.kubernetes.io/canary-weight number nginx.ingress.kubernetes.io/canary-weight-total number Ingress Nginx Annotations支持的Canary规则 ◼ nginx.ingress.kubernetes.io/canary-by-header:基于该Annotation中指定Request Header进行流量切分,适用于灰度发布以及A/B测试 ◆在请求报文中,若存在该Header且其值为always时,请求将会被发送到Canary版本 ◆若存在该Header且其值为never时,请求将不会被发送至Canary版本 ◆对于任何其它值,将忽略该Annotation指定的Header,并通过优先级将请求与其他金丝雀规则进行优先级的比较 ◼ nginx.ingress.kubernetes.io/canary-by-header-value:基于该Annotation中指定的Request Header的值进行流量切分,标头名称则由前一个Annotation(nginx.ingress.kubernetes.io/canary-by-header)进行指定 ◆请求报文中存在指定的标头,且其值与该Annotation的值匹配时,它将被路由到Canary版本 ◆对于任何其它值,将忽略该Annotation ◼ nginx.ingress.kubernetes.io/canary-by-header-pattern ◆同canary-by-header-value的功能类似,但该Annotation基于正则表达式匹配Request Header的值 ◆若该Annotation与canary-by-header-value同时存在,则该Annotation会被忽略 Ingress Nginx Annotations支持的Canary规则(续) ◼ nginx.ingress.kubernetes.io/canary-weight:基于服务权重进行流量切分,适用于蓝绿部署,权重范围0 - 100按百分比将请求路由到Canary Ingress中指定的服务 ◆权重为 0 意味着该金丝雀规则不会向Canary入口的服务发送任何请求 ◆权重为100意味着所有请求都将被发送到 Canary 入 ◼ nginx.ingress.kubernetes.io/canary-by-cookie:基于 cookie 的流量切分,适用于灰度发布与 A/B 测试 ◆cookie的值设置为always时,它将被路由到Canary入口 ◆cookie的值设置为 never时,请求不会被发送到Canary入口 ◆对于任何其他值,将忽略 cookie 并将请求与其他金丝雀规则进行优先级的比较 规则的应用次序 ◼ Canary规则会按特定的次序进行评估 ◼ 次序:canary-by-header -> canary-by-cookie -> canary-weight #如果没匹配到就发给旧版本 工作负载型控制器的高级实现(了解):#支持高级发布功能(金丝雀,蓝绿发布) Argo Rollouts,可取代Deployment的全部功能 OpenKruise Kruise Rollouts
实际操作示例(各种发布规则)
#把当前default名称空间下的资源都删了,免得干扰 ]#kubectl delete deployments,service,statefulset --all ]#kubectl delete ingress --all #创建demoapp的Deployment和service [root@master01 ingress-canary-demo]#kubectl apply -f deploy-demoap-v1_0.yaml #创建ingress [root@master01 ingress-canary-demo]#vim 01-ingress-demoapp.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: demoapp annotations: #改字段已经被废,能用,用ingressClassName代替 kubernetes.io/ingress.class: nginx spec: rules: - host: demoapp.magedu.com http: paths: - backend: service: name: demoapp-v10 port: number: 80 path: / pathType: Prefix [root@master01 ingress-canary-demo]#kubectl apply -f 01-ingress-demoapp.yaml #浏览器输入,测试 demoapp.magedu.com #创建新版本对应的Deployment和service [root@master01 ingress-canary-demo]#kubectl apply -f deploy-demoap-v1_1.yaml #ingress上加配置,迁一部分流量到新版本 [root@master01 ingress-canary-demo]#vim 02-canary-by-header.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/canary: "true" #启动canary功能 nginx.ingress.kubernetes.io/canary-by-header: "X-Canary" #有该标头发给新版本 name: demoapp-canary-by-header spec: ingressClassName: nginx rules: - host: demoapp.magedu.com http: paths: - backend: service: name: demoapp-v11 #新版本服务 port: number: 80 path: / pathType: Prefix [root@master01 ingress-canary-demo]#kubectl apply -f 02-canary-by-header.yaml #查看,现在有2个ingress [root@master01 ingress-canary-demo]#kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE demoapp <none> demoapp.magedu.com 10.0.0.52 80 39m demoapp-canary-by-header nginx demoapp.magedu.com 10.0.0.52 80 7m56s #在另一台机器上配置host做测试 [root@node01 ~]#curl demoapp.magedu.com #请求老版本 iKubernetes demoapp v1.0 !! ClientIP: 10.244.2.138, ServerName: demoapp-v10-7895f997b5-spljs, ServerIP: 10.244.1.158! #加入请求头X-Canary: always, 请求新版 [root@node01 ~]#curl -H "X-Canary: always" demoapp.magedu.com iKubernetes demoapp v1.1 !! ClientIP: 10.244.2.138, ServerName: demoapp-v11-559fc44c47-27ncl, ServerIP: 10.244.1.159! [root@node01 ~]#curl -H "X-Canary: a" demoapp.magedu.com #请求老版本(因为不是always) iKubernetes demoapp v1.0 !! ClientIP: 10.244.2.138, ServerName: demoapp-v10-7895f997b5-spljs, ServerIP: 10.244.1.158! #把02的发布规则删掉 [root@master01 ingress-canary-demo]#kubectl delete -f 02-canary-by-header.yaml #在02基础上追加了自定义规则值 ]#vim 03-canary-by-header-value.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-by-header: "IsVIP" #存在这个标头,且值为false,就发给canary nginx.ingress.kubernetes.io/canary-by-header-value: "false" name: demoapp-canary-by-header-value spec: ingressClassName: nginx rules: - host: demoapp.magedu.com http: paths: - backend: service: name: demoapp-v11 port: number: 80 path: / pathType: Prefix [root@master01 ingress-canary-demo]#kubectl apply -f 03-canary-by-header-value.yaml [root@master01 ingress-canary-demo]#kubectl get ingress NAME CLASS HOSTS ADDRESS PORTS AGE demoapp <none> demoapp.magedu.com 10.0.0.52 80 44m demoapp-canary-by-header-value nginx demoapp.magedu.com 10.0.0.52 80 35s #测试 [root@node01 ~]#curl -H "IsVIP: false" demoapp.magedu.com iKubernetes demoapp v1.1 !! ClientIP: 10.244.2.138, ServerName: demoapp-v11-559fc44c47-27ncl, ServerIP: 10.244.1.159! [root@node01 ~]#curl demoapp.magedu.com iKubernetes demoapp v1.0 !! ClientIP: 10.244.2.138, ServerName: demoapp-v10-7895f997b5-spljs, ServerIP: 10.244.1.158! [root@node01 ~]#curl -H "IsVIP: always" demoapp.magedu.com iKubernetes demoapp v1.0 !! ClientIP: 10.244.2.138, ServerName: demoapp-v10-7895f997b5-spljs, ServerIP: 10.244.1.158! #把新的发布规则删掉,以免干扰 [root@master01 ingress-canary-demo]#kubectl delete -f 03-canary-by-header-value.yaml [root@master01 ingress-canary-demo]#vim 04-canary-by-header-pattern.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-by-header: "Username" #正则表达式匹配 nginx.ingress.kubernetes.io/canary-by-header-pattern: "(vip|VIP)_.*" name: demoapp-canary-by-header-pattern spec: rules: - host: demoapp.magedu.com http: paths: - backend: service: name: demoapp-v11 port: number: 80 path: / pathType: Prefix [root@master01 ingress-canary-demo]#kubectl apply -f 04-canary-by-header-pattern.yaml #测试 [root@node01 ~]#curl demoapp.magedu.com iKubernetes demoapp v1.0 !! ClientIP: 10.244.2.138, ServerName: demoapp-v10-7895f997b5-spljs, ServerIP: 10.244.1.158! [root@node01 ~]#curl -H "Username: vip_aaa" demoapp.magedu.com iKubernetes demoapp v1.1 !! ClientIP: 10.244.2.138, ServerName: demoapp-v11-559fc44c47-27ncl, ServerIP: 10.244.1.159! [root@master01 ingress-canary-demo]#kubectl delete -f 04-canary-by-header-pattern.yaml #注意:上面3种方式,使用其中的任意一种 [root@master01 ingress-canary-demo]#vim 05-canary-by-weight.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "50" #新版本权重50% name: demoapp-canary-by-weight spec: rules: - host: demoapp.magedu.com http: paths: - backend: service: name: demoapp-v11 port: number: 80 path: / pathType: Prefix [root@master01 ingress-canary-demo]#kubectl apply -f 05-canary-by-weight.yaml #测试,查看返回比例 [root@node01 ~]#while true; do curl demoapp.magedu.com; sleep .2; done #删除,避免后续测试干扰 [root@master01 ingress-canary-demo]#kubectl delete -f 05-canary-by-weight.yaml [root@master01 ingress-canary-demo]#vim 06-canary-by-cookie.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true" #有cookie,且vip_user=always就发给新版 nginx.ingress.kubernetes.io/canary-by-cookie: "vip_user" name: demoapp-canary-by-cookie spec: rules: - host: demoapp.magedu.com http: paths: - backend: service: name: demoapp-v11 port: number: 80 path: / pathType: Prefix [root@master01 ingress-canary-demo]#kubectl apply -f 06-canary-by-cookie.yaml #测试 [root@node01 ~]#curl demoapp.magedu.com iKubernetes demoapp v1.0 !! ClientIP: 10.244.2.138, ServerName: demoapp-v10-7895f997b5-spljs, ServerIP: 10.244.1.158! [root@node01 ~]#curl -b "vip_user=always" demoapp.magedu.com iKubernetes demoapp v1.1 !! ClientIP: 10.244.2.138, ServerName: demoapp-v11-559fc44c47-27ncl, ServerIP: 10.244.1.159! #删除,避免后续测试干扰 [root@master01 ingress-canary-demo]#kubectl delete -f 06-canary-by-cookie.yaml #模拟蓝绿发布 #蓝绿发布,实际就是通过权重控制 [root@master01 ingress-canary-demo]#vim 05-canary-by-weight.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "0" #新版本权重为0 name: demoapp-canary-by-weight spec: rules: - host: demoapp.magedu.com http: paths: - backend: service: name: demoapp-v11 port: number: 80 path: / pathType: Prefix [root@master01 ingress-canary-demo]#kubectl apply -f 05-canary-by-weight.yaml #测试,查看返回比例,全是旧版本 [root@node01 ~]#while true; do curl demoapp.magedu.com; sleep .2; done #等部署完新版本,新版本上线,手动测试能用,立即编辑05 apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/canary: "true" nginx.ingress.kubernetes.io/canary-weight: "100" #调整为100 name: demoapp-canary-by-weight spec: rules: - host: demoapp.magedu.com http: paths: - backend: service: name: demoapp-v11 port: number: 80 path: / pathType: Prefix [root@master01 ingress-canary-demo]#kubectl apply -f 05-canary-by-weight.yaml #测试,查看返回比例,全是新版本 [root@node01 ~]#while true; do curl demoapp.magedu.com; sleep .2; done
Helm: 包管理器: rpm/rpm, deb/dpkg, ... yum/dnf, apt/apt-get, ... helm, Chart: 包格式:Chart, tgz打包格式 管理工具:Helm Chart仓库: http/https helm: 命令行客户端 Chart仓库 API Server (kubeconfig文件) 仓库的位置: 项目自身维护仓库 公共仓库: oci:// Chart中的yaml文件格式: 模板文件 --> 向模板字串赋值 --> 完成模板渲染 赋值方式: 命令行选项:helm --set KEY=VALUE --set ... 值文件:helm -f /PATH/TO/YAML_FILE Chart通常会附带默认的值文件(values.yml) 部署的实例: Release helm程序组件: v2: helm --> Tiller (部署运行在Kubernetes集群上) --> API Server v3: helm --> API Server
Helm是一款简化安装和管理Kubernetes应用程序的工具
◼ 可用于Kubernetes之上的应用程序管理的资源配置文件需要以特定的结构组织为Chart
◆Chart代表着可由Helm管理的有着特定格式的程序包
◆Chart中的资源配置文件通常以模板(go template)形式定义,在部署时,用户可通过向模板参数赋值实现定制化安装
的目的
◆各模板参数通常也有默认值,这些默认值定义在Chart包里一个名为values.yml的文件中
◼ 类似于kubectl,Helm也是Kubernetes API Server的命令行客户端工具
◆支持kubeconfig认证文件
◆需要事先从仓库或本地加载到要使用目标Chart,并基于Chart完成应用管理
◆Chart可缓存于Helm本地主机上
◼ 支持仓库管理和包管理的各类常用操作,例如Chart仓库的增、删、改、查,以及Chart包的制作、发布、搜索、下载等
#官网 https://artifacthub.io/ Artifact Hub ◼ 由Helm社区维护的一个名为Artifact Hub的Web应用,旨在便于Chart的共享与分发 ◼ 支持查询、安装和发布Kubernetes应用程序包
部署helm
#根据官网,可以下载自己所需要的版本 https://helm.sh/docs/intro/install/ #我这里选v3.16.3最新版本, Linux amd64版本 (go开发,静态编译,放在/usr/local/bin或/usr/bin下可直接使用) #下载 [root@master01 ~]#curl -LO https://get.helm.sh/helm-v3.16.3-linux-amd64.tar.gz [root@master01 ~]#tar xf helm-v3.16.3-linux-amd64.tar.gz [root@master01 ~]#cd linux-amd64/ [root@master01 linux-amd64]#mv helm /usr/local/bin [root@master01 linux-amd64]#cd #可以使用helm了 #搜索chart,搜本地配置的仓库是repo, 搜Artifact Hub用hub #搜本地仓库,这里因为没配本地仓库 ]#helm search repo mysql Error: no repositories configured #搜Artifact Hub中包含mysql的 [root@master01 wordpress]#helm search hub mysql URL CHART VERSION APP VERSION DESCRIPTION ...
使用helm部署mysql示例
#Artifact Hub上搜mysql (bitnami是一个很大的开源组织) 可以参看默认参数 https://artifacthub.io/packages/helm/bitnami/mysql #注意:helm install下dockerhub镜像,要网络代理,推荐使用环境变量的方法 ]#export https_proxy="http://10.0.0.1:7890" ]#export http_proxy="http://10.0.0.1:7890" ]#export no_proxy="127.0.0.0/8,10.244.0.0/16,192.168.0.0/16,10.96.0.0/12,magedu.com,cluster.local" #基于dockerhub上的oci仓库部署,创建mysql的release(下面没设的参数采用默认值) helm install mysql \ --set auth.rootPassword='MageEdu' \ --set global.storageClass=nfs-csi \ #可改为openebs-hostpath本地卷,提升性能 --set architecture=replication \ #架构类型 --set auth.database=wpdb \ --set auth.username=wpuser \ --set auth.password='magedu.com' \ --set secondary.replicaCount=1 \ #从服务器几个实例 --set auth.replicationPassword='replpass' \ #从服务器连主服务区使用的密码 oci://registry-1.docker.io/bitnamicharts/mysql \ -n wordpress --create-namespace #create-namespace如果名称空间不存在就创建 #自动到dockerhub上下载指定的chart,创建出一个release(部署主从复制的mysql) #返回 NAME: mysql LAST DEPLOYED: Tue Dec 3 04:36:34 2024 NAMESPACE: wordpress STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: CHART NAME: mysql CHART VERSION: 12.1.0 APP VERSION: 8.4.3 #mysql版本 #获取密码(用户root) 获取的其实就是设置的MageEdu MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace wordpress mysql -o jsonpath="{.data.mysql-root-password}" | base64 -d) 2. To connect to primary service (read/write): mysql -h mysql-primary.wordpress.svc.cluster.local -uroot -p"$MYSQL_ROOT_PASSWORD" 3. To connect to secondary service (read-only): mysql -h mysql-secondary.wordpress.svc.cluster.local -uroot -p"$MYSQL_ROOT_PASSWORD" #查看创建的东西 [root@master01 ~]#kubectl get all -n wordpress NAME READY STATUS RESTARTS AGE pod/mysql-primary-0 1/1 Running 0 17m pod/mysql-secondary-0 1/1 Running 0 17m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/mysql-primary ClusterIP 10.103.149.119 <none> 3306/TCP 17m service/mysql-primary-headless ClusterIP None <none> 3306/TCP 17m service/mysql-secondary ClusterIP 10.108.47.42 <none> 3306/TCP 17m service/mysql-secondary-headless ClusterIP None <none> 3306/TCP 17m NAME READY AGE statefulset.apps/mysql-primary 1/1 17m statefulset.apps/mysql-secondary 1/1 17m #查看刚刚部署的实例 [root@master01 wordpress]#helm list -n wordpress NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION mysql wordpress 1 2024-12-03 04:36:34.261136708 +0000 UTC deployed mysql-12.1.0 8.4.3 #修改刚刚部署的实例参数(把要修改的参数换好直接提交) helm upgrade mysql --set ... #卸载 helm uninstall mysql #查看状态(返回的就是刚刚部署返回的信息) [root@master01 ~]#helm status mysql -n wordpress
使用helm部署wordpress示例
#artifacthub搜wordpress项目,可查看参数 https://artifacthub.io/packages/helm/bitnami/wordpress #里面会内置mariadb解决依赖关系,但也是配置自己搭的mysql数据库,这里用上面的mysql主从架构 #基于dockerhub上的oci仓库部署 #使用已经部署完成的现有MySQL数据库,支持Ingress,且外部的MySQL是主从复制架构。注意修改如下命令中各参数值,以正确适配到自有环境。 helm install wordpress \ --set mariadb.enabled=false \ #内置mariadb设为false --set externalDatabase.host=mysql-primary.wordpress.svc.cluster.local \ --set externalDatabase.user=wpuser \ --set externalDatabase.password='magedu.com' \ --set externalDatabase.database=wpdb \ --set externalDatabase.port=3306 \ --set persistence.storageClass=nfs-csi \ --set ingress.enabled=true \ #自动创建ingress --set ingress.ingressClassName=nginx \ --set ingress.hostname=wordpress.magedu.com \ --set ingress.pathType=Prefix \ --set wordpressUsername=admin \ #管理员用户 --set wordpressPassword='magedu.com' \ oci://registry-1.docker.io/bitnamicharts/wordpress \ -n wordpress --create-namespace #返回 echo "WordPress URL: http://wordpress.magedu.com/" 3. Login with the following credentials below to see your blog: echo Username: admin echo Password: $(kubectl get secret --namespace wordpress wordpress -o jsonpath="{.data.wordpress-password}" | base64 -d) #查看release [root@master01 wordpress]#helm list -n wordpress NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION mysql wordpress 1 2024-12-03 04:36:34.261136708 +0000 UTC deployed mysql-12.1.0 8.4.3 wordpress wordpress 1 2024-12-03 08:21:00.881921331 +0000 UTC deployed wordpress-24.0.8 6.7.1 #查看pvc [root@master01 wordpress]#kubectl get pvc -n wordpress NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE data-mysql-primary-0 Bound pvc-294397e1-666d-4c94-9f8d-93f008f08d4f 8Gi RWO nfs-csi <unset> 3h49m data-mysql-secondary-0 Bound pvc-10cc3453-0fc9-4271-9c0b-7d3e77d6220b 8Gi RWO nfs-csi <unset> 3h49m wordpress Bound pvc-2071ac90-0a6b-4dc5-aacb-e5d17438c097 10Gi RWO nfs-csi <unset> 4m43s #查看ingress,外部IP地址10.0.0.52 [root@master01 wordpress]#kubectl get ingress -n wordpress NAME CLASS HOSTS ADDRESS PORTS AGE wordpress nginx wordpress.magedu.com 10.0.0.52 80 8m52s #等待wordpress的pod启动完成 [root@master01 ~]#kubectl get pods -n wordpress #在windows上host配置wordpress.magedu.com,测试 #登录 admin/magedu.com http://wordpress.magedu.com/wp-login.php
helm部署harbor示例
#artifacthub上官方的用的最多 https://artifacthub.io/packages/helm/harbor/harbor #需要先添加仓库,名称为harbor helm repo add harbor https://helm.goharbor.io #查看本地仓库repo [root@master01 ingress-canary-demo]#helm repo list NAME URL harbor https://helm.goharbor.io #本地仓库repo搜索harbor,左侧仓库名,右侧chart名 [root@master01 ingress-canary-demo]#helm search repo harbor NAME CHART VERSION APP VERSION DESCRIPTION harbor/harbor 1.16.0 2.12.0 An open source trusted cloud native registry th... #查看chart值文件 [root@master01 ingress-canary-demo]#helm show values harbor/harbor #准备部署harbor所用参数值文件 [root@master01 harbor]#vim harbor-values.yaml expose: type: ingress tls: #使用内置tls enabled: true certSource: auto #自动生成自签证书 ingress: hosts: core: registry.magedu.com className: "nginx" annotations: ingress.kubernetes.io/ssl-redirect: "true" ingress.kubernetes.io/proxy-body-size: "0" nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/proxy-body-size: "0" ipFamily: ipv4: #只支持ipv4 enabled: true ipv6: enabled: false #外部访问必须通过该地址(这里指定主机名,ip地址访问不进来的) externalURL: https://registry.magedu.com # 持久化存储配置部分 persistence: enabled: true resourcePolicy: "keep" #删除实例,对应存储还是保留下来 persistentVolumeClaim: # 定义Harbor各个组件的PVC持久卷 registry: # registry组件(持久卷) storageClass: "nfs-csi" # 前面创建的StorageClass,其它组件同样配置 accessMode: ReadWriteMany # 卷的访问模式,需要修改为ReadWriteMany size: 5Gi chartmuseum: # chartmuseum组件(持久卷) 保存chart的仓库 storageClass: "nfs-csi" accessMode: ReadWriteMany size: 5Gi jobservice: jobLog: storageClass: "nfs-csi" accessMode: ReadWriteOnce size: 1Gi #scanDataExports: # storageClass: "nfs-csi" # accessMode: ReadWriteOnce # size: 1Gi database: # PostgreSQl数据库组件 storageClass: "nfs-csi" accessMode: ReadWriteMany size: 2Gi redis: # Redis缓存组件 storageClass: "nfs-csi" accessMode: ReadWriteMany size: 2Gi trivy: # Trity漏洞扫描 storageClass: "nfs-csi" accessMode: ReadWriteMany size: 5Gi harborAdminPassword: "magedu.com" #部署harbor (harbor仓库下/harbor的chart) ]#helm install harbor -f harbor-values.yaml harbor/harbor -n harbor --create-namespace #查看harbor release [root@master01 harbor]#helm list -n harbor NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION harbor harbor 1 2024-12-03 10:01:23.556792261 +0000 UTC deployed harbor-1.16.0 2.12.0 [root@master01 harbor]#kubectl get ingress -n harbor NAME CLASS HOSTS ADDRESS PORTS AGE harbor-ingress nginx registry.magedu.com 10.0.0.52 80, 443 3m49s #等待pod启动完成 [root@master01 harbor]#kubectl get pods -n harbor #windows下hosts中添加 10.0.0.52 registry.magedu.com #浏览器输入测试(关掉vpn就可以了,可能需要修改环境变量no_proxy) admin/magedu.com https://registry.magedu.com #显示出当时部署时的自定义值文件内容 [root@master01 harbor]#helm get values harbor -n harbor #显示所有渲染出的资源配置文件 [root@master01 harbor]#helm get manifest harbor -n harbor ##显示出当时部署时的自定义值文件内容,命令行参数也可以 [root@master01 harbor]#helm get values mysql -n wordpress USER-SUPPLIED VALUES: architecture: replication auth: database: wpdb password: magedu.com replicationPassword: replpass rootPassword: MageEdu username: wpuser global: storageClass: nfs-csi secondary: replicaCount: 1 #显示创建完成后的提示信息,helm get notes也可以显示 [root@master01 harbor]#helm get notes mysql -n wordpress
部署Helm ◼ 使用操作系统包管理器安装,支持Homebrew、Chocolatey、Scoop、GoFish和Snap等包管理器 ◼ 直接下载适合目标平台的二进制Helm程序包,展开并放置于合适的位置即可使用 ◆https://github.com/helm/helm/releases 常用的helm命令 ◼ Repostory管理 #仓库里的元数据比较旧了,通过update更新元数据,可以下更新的数据(和apt update一样) ◆repo命令,支持repository的add、list、remove、update和index等子命令 ◼ Chart管理 ◆create、 package、pull、 push、dependency、search、show和verify等操作 ◼ Release管理 ◆install、upgrade、get、list、history、status、rollback和uninstall等操作