个人随笔
目录
当前位置: 首页 云计算 k8s实战
k8s实战
2023-02-23 22:14:53

下面进行k8s的实战,主要是pod,service,ingress,pv,pvc,configmap,secret这些,下面开始。

一、环境如下

就按我上一篇帖子搭建的环境来操作:k8s集群环境搭建

  1. k8s-new-master:192.168.192.8
  2. k8s-new-node1:192.168.192.9
  3. k8s-new-node2:192.168.192.10

用户密码:root/forever
控制台:https://192.168.192.8:30110
登录token:

  1. eyJhbGciOiJSUzI1NiIsImtpZCI6IkVRZGZRRm52ZlJwcWRlc040dURELTluQ1daZjV2M3o2dnBzaEhReDBZbTAifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi11c2VyLXRva2VuLXRqbXJwIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQubmFtZSI6ImFkbWluLXVzZXIiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJmN2M3OGJkZi0xN2YzLTQxY2UtYmVhNS1lYzA0MDY4ZDgxYTQiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6a3ViZXJuZXRlcy1kYXNoYm9hcmQ6YWRtaW4tdXNlciJ9.tUEW6nt4KvoV48eoAShBFqGUQx4e5KHb8nB8X24JhNf9vGhAfgAKgLo1S4HEgmqPkM1FUsMxxeNZMvRvjOI7Ju9AVUQkG7bz3skd1I_yZSoiOlcc6_woCXZ0az_nOGwvjjYeE8s8TuBT0nGkiKyZBiruyjyluHJyvv_wYex4DsyGUTKytX7ab0ndSz67JdVvzsfKjOrHmvSc_93D_mWvPwuboma-22qtdH5B-OZ3LOtj-15jRdSd3B4fTsZkw8Sijjgda5ltfncYvg-MJbAq0BEOhYYzmLL5p6CfD5Nq9rnDC1NcrMQfkUu3FblekDfWasHqRvM7iEBr_G0dvuh_Pg

相关命令

  1. #查看节点
  2. kubectl get nodes
  3. #查看pod
  4. kubectl get pods -A
  5. 查看podip
  6. kubectl get pods -owide

二、开始实战(pod,service,ingress)

1、资源创建方式

我们创建资源可以通过命令行直接创建,也可以通过YAML文件来创建

● 命令行
● YAML

2、Namespace

名称空间用来隔离资源

用命令行的模式建立

  1. #创建
  2. kubectl create ns hello
  3. #查看
  4. kubectl get ns
  5. #删除
  6. kubectl delete ns hello

下面是用yaml的方式建立

建立文件helo-ns.yaml

  1. apiVersion: v1
  2. kind: Namespace
  3. metadata:
  4. name: hello

执行命令创建

  1. kubectl apply -f helo-ns.yaml

3、Pod

运行中的一组容器,Pod是kubernetes中应用的最小单位.

用命令行的模式建立

  1. kubectl run mynginx2 --image=nginx

因为之前搭建环境的时候已经建立过mynginx了,所以这里用mynginx2

运行如下命令进行相关操作

  1. kubectl run mynginx --image=nginx
  2. # 查看default名称空间的Pod
  3. kubectl get pod
  4. # 描述
  5. kubectl describe pod Pod名字
  6. # 查看Pod的运行日志
  7. kubectl logs Pod名字
  8. # 每个Pod - k8s都会分配一个ip
  9. kubectl get pod -owide
  10. # 使用Pod的ip+pod里面运行容器的端口
  11. curl 10.244.245.193
  12. # 删除
  13. kubectl delete pod Pod名字

集群中的任意一个机器以及任意的应用都能通过Pod分配的ip来访问这个Pod

我之前就是这个ping不通很奔溃才重新搭建,修改了pod的ip才行的,不然跟我的虚拟机有点冲突了。

如果是用yaml的话也很简单,如下面的一个nginx一个tomcat对应的yaml文件

nginx

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. labels:
  5. run: mynginx3
  6. name: mynginx3
  7. # namespace: default
  8. spec:
  9. containers:
  10. - image: nginx
  11. name: mynginx3

tomcat/nginx,这个相当于一个pod里面有两个容器,端口不通,nginx是80,tomcat是8080

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. labels:
  5. run: myapp
  6. name: myapp
  7. spec:
  8. containers:
  9. - image: nginx
  10. name: nginx
  11. - image: tomcat:8.5.68
  12. name: tomcat

执行命令都是

  1. kubectl apply -f yaml文件名

查看pod的IP

  1. [root@k8s-new-master ~]# kubectl get pod -owide
  2. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  3. myapp 2/2 Running 0 2m41s 10.244.245.194 k8s-new-node1 <none> <none>
  4. mynginx 1/1 Running 1 14h 10.244.53.2 k8s-new-node2 <none> <none>
  5. mynginx2 1/1 Running 0 42m 10.244.245.193 k8s-new-node1 <none> <none>
  6. mynginx3 1/1 Running 0 2m50s 10.244.53.3 k8s-new-node2 <none> <none>

访问下myapp

  1. curl 10.244.245.194:80
  2. curl 10.244.245.194:8080

发现是可以正常访问的。

此时创建的应用是还不能外部访问的,需要后面的service才行。

4、Deployment

控制Pod,使Pod拥有多副本,自愈,扩缩容等能力

4-1、自愈能力

用deployment创建的pod,等pod删掉后,会自动启动,下面来验证下

  1. kubectl create deployment mytomcat --image=tomcat:8.5.68

启动后,执行删除pod的命令

  1. kubectl delete pod mytomcat-6f5f895f4f-ppz46

过一会发现又创建了,但是如果我们不是用Deployment方式创建的pod,删除后将不会再创建。

  1. [root@k8s-new-master ~]# kubectl get pod
  2. NAME READY STATUS RESTARTS AGE
  3. mytomcat-6f5f895f4f-9dx2n 1/1 Running 0 13s
  4. mytomcat-6f5f895f4f-ppz46 0/1 Terminating 0 2m21s

得把所有pod删掉先,不然怕内存不够

  1. kubectl delete pod myapp
  2. kubectl delete pod mynginx
  3. kubectl delete pod mynginx2
  4. kubectl delete pod mynginx3
  5. #查看部署
  6. kubectl get deployments
  7. #删除部署
  8. kubectl delete deployment mytomcat

部署只能删除部署,如果只删除pod会自愈的。

4-2、多副本

可以用命令行

  1. kubectl create deployment my-dep --image=nginx --replicas=3

或者使用yaml创建多副本

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. labels:
  5. app: my-dep
  6. name: my-dep
  7. spec:
  8. replicas: 3
  9. selector:
  10. matchLabels:
  11. app: my-dep
  12. template:
  13. metadata:
  14. labels:
  15. app: my-dep
  16. spec:
  17. containers:
  18. - image: nginx
  19. name: nginx

执行命令当然是

  1. kubectl apply -f yaml文件名

查看可以知道

  1. [root@k8s-new-master ~]# kubectl get pods
  2. NAME READY STATUS RESTARTS AGE
  3. my-dep-5b7868d854-495hg 0/1 ContainerCreating 0 22s
  4. my-dep-5b7868d854-cz48b 1/1 Running 0 22s
  5. my-dep-5b7868d854-fs78l 1/1 Running 0 22s

创建了三个副本,查看更加详细的内容

  1. [root@k8s-new-master ~]# kubectl get pods -owide
  2. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  3. my-dep-5b7868d854-495hg 1/1 Running 0 107s 10.244.53.5 k8s-new-node2 <none> <none>
  4. my-dep-5b7868d854-cz48b 1/1 Running 0 107s 10.244.245.198 k8s-new-node1 <none> <none>
  5. my-dep-5b7868d854-fs78l 1/1 Running 0 107s 10.244.53.4 k8s-new-node2 <none> <none>

发现有一个是在节点1,那我们尝试把节点1,关闭,看看如何

  1. [root@k8s-new-master ~]# kubectl get nodes
  2. NAME STATUS ROLES AGE VERSION
  3. k8s-new-master Ready control-plane,master 17h v1.20.9
  4. k8s-new-node1 NotReady <none> 16h v1.20.9
  5. k8s-new-node2 Ready <none> 16h v1.20.9

我们可以每隔一秒看看节点一的pod情况

  1. watch -n 1 kubectl get pods -owide

等了大概十分钟,节点1的副本就被停止了,重新在节点2启动了

  1. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  2. my-dep-5b7868d854-495hg 1/1 Running 0 9m35s 10.244.53.5 k8s-new-node2 <none> <none>
  3. my-dep-5b7868d854-9zsmh 1/1 Running 0 39s 10.244.53.6 k8s-new-node2 <none> <none>
  4. my-dep-5b7868d854-cz48b 1/1 Terminating 0 9m35s 10.244.245.198 k8s-new-node1 <none> <none>
  5. my-dep-5b7868d854-fs78l 1/1 Running 0 9m35s 10.244.53.4 k8s-new-node2 <none> <none>
4-3、扩缩容

在运行过程中,我们可以随着流量需求对pod进行扩缩容,比如我们一开始只部署了3个pod,因为搞活动导致流量暴增,我们就可以扩容到5个,等活动结束后又改为3个,当然这些扩缩容可以在控制台界面直接修改,也可以用命令或者修改配置文件实现,下面演示使用命令方式实现

扩容到5

  1. kubectl scale --replicas=5 deployment/my-dep

执行完就可以看到

  1. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  2. my-dep-5b7868d854-495hg 1/1 Running 0 36m 10.244.53.5 k8s-new-node2 <none> <none>
  3. my-dep-5b7868d854-4vfps 0/1 ContainerCreating 0 16s <none> k8s-new-node1 <none> <none>
  4. my-dep-5b7868d854-9zsmh 1/1 Running 0 27m 10.244.53.6 k8s-new-node2 <none> <none>
  5. my-dep-5b7868d854-fs78l 1/1 Running 0 36m 10.244.53.4 k8s-new-node2 <none> <none>
  6. my-dep-5b7868d854-pjmkf 0/1 ContainerCreating 0 16s <none> k8s-new-node1 <none> <none>

正在部署两个新的pod

我们可以修改配置文件缩容到2

  1. kubectl edit deployment my-dep
  2. #修改 replicas 到2

wq报错完后就可以看到缩容了,有三个节点Terminating

  1. [root@k8s-new-master ~]# kubectl get pods -owide
  2. NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
  3. my-dep-5b7868d854-495hg 0/1 Terminating 0 39m 10.244.53.5 k8s-new-node2 <none> <none>
  4. my-dep-5b7868d854-4vfps 1/1 Running 0 3m6s 10.244.245.200 k8s-new-node1 <none> <none>
  5. my-dep-5b7868d854-9zsmh 0/1 Terminating 0 30m 10.244.53.6 k8s-new-node2 <none> <none>
  6. my-dep-5b7868d854-fs78l 0/1 Terminating 0 39m 10.244.53.4 k8s-new-node2 <none> <none>
  7. my-dep-5b7868d854-pjmkf 1/1 Running 0 3m6s 10.244.245.199 k8s-new-node1 <none> <none>
4-4、自愈&故障转移

这个在4-2多副本中已经演示了,启动多个副本后,把其中一个节点停机,k8s自动在别的存活的节点启动了。

4-5、滚动跟新

指定新的镜像后,会自动跟新所有容器

  1. kubectl set image deployment/my-dep nginx=nginx:1.16.1 --record
  2. kubectl rollout status deployment/my-dep

也可以修改配置中的镜像版本来更新

  1. kubectl edit deployment/my-dep

可以看到,已经修改位1.16.1的版本了,如果想要升级,修改为其它版本即可自动升级

  1. ...
  2. spec:
  3. containers:
  4. - image: nginx:1.16.1
  5. imagePullPolicy: Always
  6. name: nginx
  7. ...
4-6、版本回退
  1. #历史记录
  2. kubectl rollout history deployment/my-dep
  3. #查看某个历史详情
  4. kubectl rollout history deployment/my-dep --revision=2
  5. #回滚(回到上次)
  6. kubectl rollout undo deployment/my-dep
  7. #回滚(回到指定版本)
  8. kubectl rollout undo deployment/my-dep --to-revision=2

除了Deployment,k8s还有StatefulSet 、DaemonSet Job 等 类型资源。我们都称为工作负载。
有状态应用类似mysql,redis等使用 StatefulSet 部署,无状态应用类似我们的微服务使用Deployment部署,具体可以查看:https://kubernetes.io/zh/docs/concepts/workloads/controllers/

5、Service

将一组 Pods 公开为网络服务的抽象方法。

我们在安装k8s的时候,有执行如下命令

  1. kubeadm init \
  2. --apiserver-advertise-address=192.168.192.8 \
  3. --control-plane-endpoint=k8s-new-master \
  4. --image-repository registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images \
  5. --kubernetes-version v1.20.9 \
  6. --service-cidr=10.96.0.0/16 \
  7. --pod-network-cidr=10.244.0.0/16

这里我们知道,pod的ip是从10.244.0.0/16生成的,service是从10.96.0.0/16生成的,service跟pod的关系就类似于nginx跟应用的关系,我们pod有多个副本,我们可以通过访问service负载均衡到pod,下面我们来测试下。

我们为之前的部署my-dep通过service暴露出去

  1. #暴露Deploy
  2. kubectl expose deployment my-dep --port=8000 --target-port=80
  3. #使用标签检索Pod
  4. kubectl get pod -l app=my-dep

也可以用文件的方式

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. labels:
  5. app: my-dep
  6. name: my-dep
  7. spec:
  8. selector:
  9. app: my-dep
  10. ports:
  11. - port: 8000
  12. protocol: TCP
  13. targetPort: 80

我们查看service

  1. [root@k8s-new-master ~]# kubectl get svc
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 19h
  4. my-dep ClusterIP 10.96.191.91 <none> 8000/TCP 56s

通过访问10.96.191.91来测试

  1. curl 10.96.191.91:8000

我们验证下有没有负载均衡的效果

先查询容器

  1. [root@k8s-new-master ~]# kubectl get pod -l app=my-dep
  2. NAME READY STATUS RESTARTS AGE
  3. my-dep-5b7868d854-5jrv5 1/1 Running 0 29m
  4. my-dep-5b7868d854-nk9t5 1/1 Running 0 29m

进入容器内部修改index.html

  1. #这里进去设置为1
  2. kubectl exec -ti my-dep-5b7868d854-5jrv5 -n default sh
  3. cd /usr/share/nginx/html
  4. echo '1' > index.html
  5. exit
  6. #这里进去设置为2
  7. kubectl exec -ti my-dep-5b7868d854-nk9t5 -n default sh
  8. cd /usr/share/nginx/html
  9. echo '2' > index.html
  10. exit

尝试多次访问curl 10.96.191.91:8000

发现是有实现负载均衡的

  1. [root@k8s-new-master ~]# curl 10.96.191.91:8000
  2. 2
  3. [root@k8s-new-master ~]# curl 10.96.191.91:8000
  4. 1
  5. [root@k8s-new-master ~]# curl 10.96.191.91:8000
  6. 1
  7. [root@k8s-new-master ~]# curl 10.96.191.91:8000
  8. 2
5-1、ClusterIP

我们上面建的service,type默认是ClusterIP,是不能通过宿主机的ip来访问的

  1. # 等同于没有--type的
  2. kubectl expose deployment my-dep --port=8000 --target-port=80 --type=ClusterIP
  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. labels:
  5. app: my-dep
  6. name: my-dep
  7. spec:
  8. ports:
  9. - port: 8000
  10. protocol: TCP
  11. targetPort: 80
  12. selector:
  13. app: my-dep
  14. type: ClusterIP

如果要宿主机可以访问,需要用NodePort模式

5-2、NodePort

命令版

  1. kubectl expose deployment my-dep --port=8001 --target-port=80 --type=NodePort

yaml版:my-dep2.yaml

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. labels:
  5. app: my-dep2
  6. name: my-dep2
  7. spec:
  8. ports:
  9. - port: 8000
  10. protocol: TCP
  11. targetPort: 80
  12. selector:
  13. app: my-dep
  14. type: NodePort

创建

  1. kubectl apply -f my-dep2.yaml

查看

  1. [root@k8s-new-master ~]# kubectl get svc
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20h
  4. my-dep ClusterIP 10.96.191.91 <none> 8000/TCP 37m
  5. my-dep2 NodePort 10.96.206.61 <none> 8000:31123/TCP 2m20s
  6. [root@k8s-new-master ~]#

我们在浏览器访问任意一个节点

  1. http://192.168.192.8:31123
  2. http://192.168.192.9:31123
  3. http://192.168.192.10:31123

NodePort范围在 30000-32767 之间,所以防火墙或者工作组要放开这些端口

6、Ingress

Kubernetes关于服务的暴露主要是通过NodePort方式,通过绑定宿主机的某个端口,然后进行pod的请求转发和负载均衡,但这种方式下缺陷是:

Service可能有很多个,如果每个都绑定一个node主机端口的话,主机需要开放外围一堆的端口进行服务调用,管理混乱无法应用很多公司要求的防火墙规则。

理想的方式是通过一个外部的负载均衡器,绑定固定的端口,比如80,然后根据域名或者服务名向后面的Service ip转发,Nginx很好的解决了这个需求,但问题是如果有新的服务加入,如何去修改Nginx的配置,并且加载这些配置? Kubernetes给出的方案就是Ingress,Ingress包含了两大主件Ingress Controller和Ingress。

Ingress其实就是对nginx的封装。

6-1、安装
  1. wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.47.0/deploy/static/provider/baremetal/deploy.yaml
  2. #修改镜像
  3. vi deploy.yaml
  4. #将image的值改为如下值:
  5. registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/ingress-nginx-controller:v0.46.0

如果下载不了文件,就用这个https://www.suibibk.com//fileupload/files/ingress.yaml

  1. kubectl apply -f ingress.yaml
  1. # 检查安装的结果
  2. kubectl get pod,svc -n ingress-nginx
  3. # 最后别忘记把svc暴露的端口要放行
6-2、使用
  1. [root@k8s-new-master ~]# kubectl get pod,svc -n ingress-nginx
  2. NAME READY STATUS RESTARTS AGE
  3. pod/ingress-nginx-admission-create-c8gbj 0/1 Completed 0 2m34s
  4. pod/ingress-nginx-admission-patch-f6dvr 0/1 Completed 0 2m34s
  5. pod/ingress-nginx-controller-65bf56f7fc-59gmk 1/1 Running 0 2m34s
  6. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  7. service/ingress-nginx-controller NodePort 10.96.141.189 <none> 80:32276/TCP,443:32488/TCP 2m35s
  8. service/ingress-nginx-controller-admission ClusterIP 10.96.185.85 <none> 443/TCP 2m35s

https://192.168.192.8:32488/
http://192.168.192.8:32276/

6-3、测试

准备好如下test-ingress.yaml

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: hello-server
  5. spec:
  6. replicas: 2
  7. selector:
  8. matchLabels:
  9. app: hello-server
  10. template:
  11. metadata:
  12. labels:
  13. app: hello-server
  14. spec:
  15. containers:
  16. - name: hello-server
  17. image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/hello-server
  18. ports:
  19. - containerPort: 9000
  20. ---
  21. apiVersion: apps/v1
  22. kind: Deployment
  23. metadata:
  24. labels:
  25. app: nginx-demo
  26. name: nginx-demo
  27. spec:
  28. replicas: 2
  29. selector:
  30. matchLabels:
  31. app: nginx-demo
  32. template:
  33. metadata:
  34. labels:
  35. app: nginx-demo
  36. spec:
  37. containers:
  38. - image: nginx
  39. name: nginx
  40. ---
  41. apiVersion: v1
  42. kind: Service
  43. metadata:
  44. labels:
  45. app: nginx-demo
  46. name: nginx-demo
  47. spec:
  48. selector:
  49. app: nginx-demo
  50. ports:
  51. - port: 8000
  52. protocol: TCP
  53. targetPort: 80
  54. ---
  55. apiVersion: v1
  56. kind: Service
  57. metadata:
  58. labels:
  59. app: hello-server
  60. name: hello-server
  61. spec:
  62. selector:
  63. app: hello-server
  64. ports:
  65. - port: 8000
  66. protocol: TCP
  67. targetPort: 9000

上面会产生两个service,一个是nginx-demo端口8000,负载到80端口的nginx-demo pod上,一个是hello-server,端口也是8000,负载到9000端口的hello-server pod上。

执行

  1. kubectl apply -f test-ingress.yaml

查看

  1. [root@k8s-new-master ~]# kubectl get svc -owide
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
  3. hello-server ClusterIP 10.96.189.213 <none> 8000/TCP 69s app=hello-server
  4. nginx-demo ClusterIP 10.96.243.249 <none> 8000/TCP 69s app=nginx-demo

6-3-1、域名访问
我们在本地的host准备如下两个域名
C:\Windows\System32\drivers\etc\hosts

  1. 192.168.192.10 hello.suibibk.com
  2. 192.168.192.10 demo.suibibk.com

因为ingress创建后是在192.168.192.10,所以只能配置这个,不能配置其它节点,这个跟service不同

我们来部署个Ingress:test-ingress2.yaml

  1. apiVersion: networking.k8s.io/v1
  2. kind: Ingress
  3. metadata:
  4. name: ingress-host-bar
  5. spec:
  6. ingressClassName: nginx
  7. rules:
  8. - host: "hello.suibibk.com"
  9. http:
  10. paths:
  11. - pathType: Prefix
  12. path: "/"
  13. backend:
  14. service:
  15. name: hello-server
  16. port:
  17. number: 8000
  18. - host: "demo.suibibk.com"
  19. http:
  20. paths:
  21. - pathType: Prefix
  22. path: "/nginx" # 把请求会转给下面的服务,下面的服务一定要能处理这个路径,不能处理就是404
  23. backend:
  24. service:
  25. name: nginx-demo ## java,比如使用路径重写,去掉前缀nginx
  26. port:
  27. number: 8000

部署

  1. kubectl apply -f test-ingress2.yaml

查看下结果

  1. [root@k8s-new-master ~]# kubectl get ingress
  2. NAME CLASS HOSTS ADDRESS PORTS AGE
  3. ingress-host-bar nginx hello.suibibk.com,demo.suibibk.com 80 9s

上面的部署的意思是,如果我们访问

http://hello.suibibk.com/nginx 会访问到service:hello-server
http://demo.suibibk.com/nginx 会访问到service:nginx-demo

然而,访问却啥报错,进不去,why,后面才发现ingress-controller的官方yaml默认注释了hostNetwork 工作方式,以防止端口的在宿主机的冲突,没有绑定到宿主机 80 端口;

需要在deployment里面加入

  1. hostNetwork: true这个字段值

大概在这个位置,大家搜索dnsPolicy就可定位

  1. ...
  2. spec:
  3. hostNetwork: true
  4. dnsPolicy: ClusterFirst
  5. ...

加上后,重新执行

  1. kubectl replace --force -f ingress.yaml

就可以正常访问了。

6-3-2、路径重写

  1. apiVersion: networking.k8s.io/v1
  2. kind: Ingress
  3. metadata:
  4. annotations:
  5. nginx.ingress.kubernetes.io/rewrite-target: /$2
  6. name: ingress-host-bar
  7. spec:
  8. ingressClassName: nginx
  9. rules:
  10. - host: "hello.suibibk.com"
  11. http:
  12. paths:
  13. - pathType: Prefix
  14. path: "/"
  15. backend:
  16. service:
  17. name: hello-server
  18. port:
  19. number: 8000
  20. - host: "demo.suibibk.com"
  21. http:
  22. paths:
  23. - pathType: Prefix
  24. path: "/nginx(/|$)(.*)" # 把请求会转给下面的服务,下面的服务一定要能处理这个路径,不能处理就是404
  25. backend:
  26. service:
  27. name: nginx-demo ## java,比如使用路径重写,去掉前缀nginx
  28. port:
  29. number: 8000
  1. #一个节点
  2. kubectl exec -ti nginx-demo-7d56b74b84-tfpqt -n default sh
  3. cd /usr/share/nginx/html
  4. echo '1' > 1.html
  5. exit
  6. #另一个节点
  7. kubectl exec -ti nginx-demo-7d56b74b84-xl7vq -n default sh
  8. cd /usr/share/nginx/html
  9. echo '1' > 1.html
  10. exit

当我们访问http://demo.suibibk.com/nginx/1.html,就相当于访问http://demo.suibibk.com/1.html,注意这里并不是说浏览器上面的地址行会变。

6-3-3、流量控制
test-ingress4.yaml

  1. apiVersion: networking.k8s.io/v1
  2. kind: Ingress
  3. metadata:
  4. name: ingress-limit-rate
  5. annotations:
  6. nginx.ingress.kubernetes.io/limit-rps: "1"
  7. spec:
  8. ingressClassName: nginx
  9. rules:
  10. - host: "haha.suibibk.com"
  11. http:
  12. paths:
  13. - pathType: Exact
  14. path: "/"
  15. backend:
  16. service:
  17. name: nginx-demo
  18. port:
  19. number: 8000
  1. kubectl apply -f test-ingress4.yaml

这里需要在本机hosts加上

  1. 192.168.192.10 haha.suibibk.com

我们限制的limit-rps是1,浏览器访问这个:http://haha.suibibk.com ,频率高一点就会报下面的错误

  1. 503 Service Temporarily Unavailable

证明有进行流量控制。

三、存储抽象

我们可以指定容器的挂载目录,统一存储在一个地方,比如ceph,nfs,这里用nfs来举例,后面我们就可以挂载redis,mysql的数据文件到nfs中,对应的pod出问题后,只要在别的节点启动pod数据也不会丢失。

1、NFS

NFS就是Network File System的缩写,它最大的功能就是可以通过网络,让不同的机器、不同的操作系统可以共享彼此的文件。

1-1、所有节点执行如下命令
  1. #所有机器安装
  2. yum install -y nfs-utils
1-2、主节点
  1. #nfs主节点
  2. echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports
  3. mkdir -p /nfs/data
  4. systemctl enable rpcbind --now
  5. systemctl enable nfs-server --now
  6. #配置生效
  7. exportfs -r
1-3、从节点
  1. #这里要写主节点的ip
  2. showmount -e 192.168.192.8
  3. #执行以下命令挂载 nfs 服务器上的共享目录到本机路径 /root/nfsmount
  4. mkdir -p /nfs/data
  5. mount -t nfs 192.168.192.8:/nfs/data /nfs/data
  6. # 写入一个测试文件
  7. echo "hello nfs server" > /nfs/data/test.txt

可以发现,别的节点的/nfs/data目录也有test.txt文件了

1-4、原生方式挂载数据
  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. labels:
  5. app: nginx-pv-demo
  6. name: nginx-pv-demo
  7. spec:
  8. replicas: 2
  9. selector:
  10. matchLabels:
  11. app: nginx-pv-demo
  12. template:
  13. metadata:
  14. labels:
  15. app: nginx-pv-demo
  16. spec:
  17. containers:
  18. - image: nginx
  19. name: nginx
  20. volumeMounts:
  21. - name: html
  22. mountPath: /usr/share/nginx/html
  23. volumes:
  24. - name: html
  25. nfs:
  26. server: 192.168.192.8
  27. path: /nfs/data/nginx-pv

记得nfs server要输入主节点的ip
创建

  1. kubectl apply -f nginx-pv-demo.yaml

查看创建情况

  1. kubectl get pods -owide

发现一直在创建中:ContainerCreating
查看创建详情

  1. kubectl describe pod nginx-pv-demo-5f6ccc5f79-d29tr
  1. Output: mount.nfs: mounting 192.168.192.8:/nfs/data/nginx-pv failed, reason given by server: No such file or directory

喵的,忘记创建挂载文件夹

  1. cd /nfs/data/
  2. mkdir nginx-pv

再等等查看就发现已经创建了。去/nfs/data/nginx-pv 目录下面创建个index.html

  1. curl 10.244.53.16:80

返回了预期结果。

1-5、PV&PVC模式

PV:持久卷(Persistent Volume),将应用需要持久化的数据保存到指定位置
PVC:持久卷申明(Persistent Volume Claim),申明需要使用的持久卷规格

1-5-1、创建pv池
静态供应

  1. #nfs主节点
  2. mkdir -p /nfs/data/01
  3. mkdir -p /nfs/data/02
  4. mkdir -p /nfs/data/03

创建pv

  1. apiVersion: v1
  2. kind: PersistentVolume
  3. metadata:
  4. name: pv01-10m
  5. spec:
  6. capacity:
  7. storage: 10M
  8. accessModes:
  9. - ReadWriteMany
  10. storageClassName: nfs
  11. nfs:
  12. path: /nfs/data/01
  13. server: 192.168.192.8
  14. ---
  15. apiVersion: v1
  16. kind: PersistentVolume
  17. metadata:
  18. name: pv02-1gi
  19. spec:
  20. capacity:
  21. storage: 1Gi
  22. accessModes:
  23. - ReadWriteMany
  24. storageClassName: nfs
  25. nfs:
  26. path: /nfs/data/02
  27. server: 192.168.192.8
  28. ---
  29. apiVersion: v1
  30. kind: PersistentVolume
  31. metadata:
  32. name: pv03-3gi
  33. spec:
  34. capacity:
  35. storage: 3Gi
  36. accessModes:
  37. - ReadWriteMany
  38. storageClassName: nfs
  39. nfs:
  40. path: /nfs/data/03
  41. server: 192.168.192.8

注意server要修改为自己的主节点ip

  1. kubectl apply -f pv.yaml

查看

  1. [root@k8s-new-master ~]# kubectl get pv
  2. NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
  3. pv01-10m 10M RWX Retain Available nfs 26s
  4. pv02-1gi 1Gi RWX Retain Available nfs 26s
  5. pv03-3gi 3Gi RWX Retain Available nfs 26s

1-5-2、PVC创建与绑定
创建PVC

  1. kind: PersistentVolumeClaim
  2. apiVersion: v1
  3. metadata:
  4. name: nginx-pvc
  5. spec:
  6. accessModes:
  7. - ReadWriteMany
  8. resources:
  9. requests:
  10. storage: 200Mi
  11. storageClassName: nfs

创建Pod绑定PVC

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. labels:
  5. app: nginx-deploy-pvc
  6. name: nginx-deploy-pvc
  7. spec:
  8. replicas: 2
  9. selector:
  10. matchLabels:
  11. app: nginx-deploy-pvc
  12. template:
  13. metadata:
  14. labels:
  15. app: nginx-deploy-pvc
  16. spec:
  17. containers:
  18. - image: nginx
  19. name: nginx
  20. volumeMounts:
  21. - name: html
  22. mountPath: /usr/share/nginx/html
  23. volumes:
  24. - name: html
  25. persistentVolumeClaim:
  26. claimName: nginx-pvc

执行完后再查看pv

  1. [root@k8s-new-master ~]# kubectl get pv
  2. NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
  3. pv01-10m 10M RWX Retain Available nfs 2m57s
  4. pv02-1gi 1Gi RWX Retain Bound default/nginx-pvc nfs 2m57s
  5. pv03-3gi 3Gi RWX Retain Available nfs 2m57s

发现pv02-1gi已被使用。我们pod申请的是200M,所以最靠近且满足的就是pv02-1gi

2、ConfigMap

抽取应用配置,并且可以自动更新

2-1、redis示例

2-1-1、把之前的配置文件创建为配置集

  1. # 创建配置,redis保存到k8s的etcd;这个需要先有redis.conf文件
  2. kubectl create cm redis-conf --from-file=redis.conf

也可以用yaml创建

  1. apiVersion: v1
  2. data: #data是所有真正的数据,key:默认是文件名 value:配置文件的内容
  3. redis.conf: |
  4. appendonly yes
  5. kind: ConfigMap
  6. metadata:
  7. name: redis-conf
  8. namespace: default

查看cm

  1. [root@k8s-new-master ~]# kubectl get cm
  2. NAME DATA AGE
  3. kube-root-ca.crt 1 24h
  4. redis-conf 1 39s

2-1-2、创建redis

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: redis
  5. spec:
  6. containers:
  7. - name: redis
  8. image: redis
  9. command:
  10. - redis-server
  11. - "/redis-master/redis.conf" #指的是redis容器内部的位置
  12. ports:
  13. - containerPort: 6379
  14. volumeMounts:
  15. - mountPath: /data
  16. name: data
  17. - mountPath: /redis-master
  18. name: config
  19. volumes:
  20. - name: data
  21. emptyDir: {}
  22. - name: config
  23. configMap:
  24. name: redis-conf
  25. items:
  26. - key: redis.conf
  27. path: redis.conf

2-1-3、检查默认配置

  1. [root@k8s-new-master ~]# kubectl exec -it redis -- redis-cli
  2. 127.0.0.1:6379> CONFIG GET appendonly
  3. 1) "appendonly"
  4. 2) "yes"
  5. 127.0.0.1:6379>

发现就是用的我们创建的配置

2-1-3、修改配置

  1. #找到配置名
  2. kubectl get cm
  3. #修改
  4. kubectl edit configmap redis-conf

加上maxmemory 2mb和maxmemory-policy allkeys-lru

  1. apiVersion: v1
  2. data:
  3. redis.conf: |
  4. appendonly yes
  5. maxmemory 2mb
  6. maxmemory-policy allkeys-lru
  7. kind: ConfigMap
  8. metadata:
  9. creationTimestamp: "2023-02-23T20:44:43Z"
  10. name: redis-conf
  11. namespace: default
  12. resourceVersion: "57788"
  13. uid: f99aea5f-41da-4755-aed0-7e4a66e2adac

检查配置是否更新

  1. [root@k8s-new-master ~]# kubectl exec -it redis -- redis-cli
  2. 127.0.0.1:6379> CONFIG GET maxmemory
  3. 1) "maxmemory"
  4. 2) "0"

配置值未更改,因为需要重新启动 Pod 才能从关联的 ConfigMap 中获取更新的值。
原因:我们的Pod部署的中间件自己本身没有热更新能力

3、Secret

Secret对象类型用来保存敏感信息,例如密码、OAuth 令牌和 SSH 密钥。 将这些信息放在secret 中比放在Pod的定义或者容器镜像中来说更加安全和灵活。

  1. kubectl create secret docker-registry leifengyang-docker \
  2. --docker-username=leifengyang \
  3. --docker-password=Lfy123456 \
  4. --docker-email=534096094@qq.com
  5. ##命令格式
  6. kubectl create secret docker-registry regcred \
  7. --docker-server=<你的镜像仓库服务器> \
  8. --docker-username=<你的用户名> \
  9. --docker-password=<你的密码> \
  10. --docker-email=<你的邮箱地址>
  1. [root@k8s-new-master ~]# kubectl get secret
  2. NAME TYPE DATA AGE
  3. default-token-gqkpn kubernetes.io/service-account-token 3 24h
  4. leifengyang-docker kubernetes.io/dockerconfigjson 1 11s

使用,可以从自己的私有仓库拉起

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: private-nginx
  5. spec:
  6. containers:
  7. - name: private-nginx
  8. image: leifengyang/guignginx:v1.0
  9. imagePullSecrets:
  10. - name: leifengyang-docker

最后执行这个肯定是报错的啦

  1. kubectl describe pod private-nginx

可以看到密码不对的提示

  1. ailed to pull image "leifengyang/guignginx:v1.0": rpc error: code = Unknown desc = Error response from daemon: Head https://registry-1.docker.io/v2/leifengyang/guignginx/manifests/v1.0: unauthorized: incorrect username or password

好了,实战结束。

教程参考:

1、视频教程
https://www.bilibili.com/video/BV13Q4y1C7hS
2、笔记
https://www.yuque.com/leifengyang/oncloud/

 163

啊!这个可能是世界上最丑的留言输入框功能~


当然,也是最丑的留言列表

有疑问发邮件到 : suibibk@qq.com 侵权立删
Copyright : 个人随笔   备案号 : 粤ICP备18099399号-2