分享免费的编程资源和教程

网站首页 > 技术教程 正文

k8s实战

goqiw 2025-05-28 17:11:59 技术教程 10 ℃ 0 评论

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

一、环境如下

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

k8s-new-master:192.168.192.8
k8s-new-node1:192.168.192.9
k8s-new-node2:192.168.192.10

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

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

相关命令

#查看节点
kubectl get nodes
#查看pod
kubectl get pods -A
查看pod的ip
kubectl get pods -owide

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

1、资源创建方式

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

● 命令行
● YAML

2、Namespace

名称空间用来隔离资源

用命令行的模式建立

#创建
kubectl create ns hello
#查看
kubectl get ns
#删除
kubectl delete ns hello

下面是用yaml的方式建立

建立文件helo-ns.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: hello

执行命令创建

kubectl apply -f helo-ns.yaml

3、Pod

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

用命令行的模式建立

kubectl run mynginx2 --image=nginx

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

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

kubectl run mynginx --image=nginx

# 查看default名称空间的Pod
kubectl get pod 
# 描述
kubectl describe pod Pod名字

# 查看Pod的运行日志
kubectl logs Pod名字

# 每个Pod - k8s都会分配一个ip
kubectl get pod -owide

# 使用Pod的ip+pod里面运行容器的端口
curl 10.244.245.193

# 删除
kubectl delete pod Pod名字

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

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

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

nginx

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: mynginx3
  name: mynginx3
#  namespace: default
spec:
  containers:
  - image: nginx
    name: mynginx3

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

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: myapp
  name: myapp
spec:
  containers:
  - image: nginx
    name: nginx
  - image: tomcat:8.5.68
    name: tomcat

执行命令都是

kubectl apply -f yaml文件名

查看pod的IP

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

访问下myapp

curl 10.244.245.194:80
curl 10.244.245.194:8080

发现是可以正常访问的。

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

4、Deployment

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

4-1、自愈能力

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

kubectl create deployment mytomcat --image=tomcat:8.5.68

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

kubectl delete pod mytomcat-6f5f895f4f-ppz46

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

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

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

kubectl delete pod myapp
kubectl delete pod mynginx
kubectl delete pod mynginx2
kubectl delete pod mynginx3
#查看部署
kubectl get deployments
#删除部署
kubectl delete deployment mytomcat

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

4-2、多副本

可以用命令行

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

或者使用yaml创建多副本

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: my-dep
  name: my-dep
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-dep
  template:
    metadata:
      labels:
        app: my-dep
    spec:
      containers:
      - image: nginx
        name: nginx

执行命令当然是

kubectl apply -f yaml文件名

查看可以知道

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

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

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

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

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

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

watch -n 1 kubectl get pods -owide

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

NAME                      READY   STATUS        RESTARTS   AGE     IP               NODE            NOMINATED NODE   READINESS GATES
my-dep-5b7868d854-495hg   1/1     Running       0          9m35s   10.244.53.5      k8s-new-node2   <none>           <none>
my-dep-5b7868d854-9zsmh   1/1     Running       0          39s     10.244.53.6      k8s-new-node2   <none>           <none>
my-dep-5b7868d854-cz48b   1/1     Terminating   0          9m35s   10.244.245.198   k8s-new-node1   <none>           <none>
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

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

执行完就可以看到

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

正在部署两个新的pod

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

kubectl edit deployment my-dep

#修改 replicas 到2

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

[root@k8s-new-master ~]# kubectl get pods -owide
NAME                      READY   STATUS        RESTARTS   AGE    IP               NODE            NOMINATED NODE   READINESS GATES
my-dep-5b7868d854-495hg   0/1     Terminating   0          39m    10.244.53.5      k8s-new-node2   <none>           <none>
my-dep-5b7868d854-4vfps   1/1     Running       0          3m6s   10.244.245.200   k8s-new-node1   <none>           <none>
my-dep-5b7868d854-9zsmh   0/1     Terminating   0          30m    10.244.53.6      k8s-new-node2   <none>           <none>
my-dep-5b7868d854-fs78l   0/1     Terminating   0          39m    10.244.53.4      k8s-new-node2   <none>           <none>
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、滚动跟新

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

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

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

kubectl edit deployment/my-dep

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

...
spec:
      containers:
      - image: nginx:1.16.1
        imagePullPolicy: Always
        name: nginx
...

4-6、版本回退

#历史记录
kubectl rollout history deployment/my-dep


#查看某个历史详情
kubectl rollout history deployment/my-dep --revision=2

#回滚(回到上次)
kubectl rollout undo deployment/my-dep

#回滚(回到指定版本)
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的时候,有执行如下命令

kubeadm init \
--apiserver-advertise-address=192.168.192.8 \
--control-plane-endpoint=k8s-new-master \
--image-repository registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images \
--kubernetes-version v1.20.9 \
--service-cidr=10.96.0.0/16 \
--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暴露出去

#暴露Deploy
kubectl expose deployment my-dep --port=8000 --target-port=80

#使用标签检索Pod
kubectl get pod -l app=my-dep

也可以用文件的方式

apiVersion: v1
kind: Service
metadata:
  labels:
    app: my-dep
  name: my-dep
spec:
  selector:
    app: my-dep
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 80

我们查看service

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

通过访问10.96.191.91来测试

curl 10.96.191.91:8000

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

先查询容器

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

进入容器内部修改index.html

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

尝试多次访问curl 10.96.191.91:8000

发现是有实现负载均衡的

[root@k8s-new-master ~]# curl 10.96.191.91:8000
2
[root@k8s-new-master ~]# curl 10.96.191.91:8000
1
[root@k8s-new-master ~]# curl 10.96.191.91:8000
1
[root@k8s-new-master ~]# curl 10.96.191.91:8000
2

5-1、ClusterIP

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

# 等同于没有--type的
kubectl expose deployment my-dep --port=8000 --target-port=80 --type=ClusterIP
apiVersion: v1
kind: Service
metadata:
  labels:
    app: my-dep
  name: my-dep
spec:
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 80
  selector:
    app: my-dep
  type: ClusterIP

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

5-2、NodePort

命令版

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

yaml版:my-dep2.yaml

apiVersion: v1
kind: Service
metadata:
  labels:
    app: my-dep2
  name: my-dep2
spec:
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 80
  selector:
    app: my-dep
  type: NodePort

创建

kubectl apply -f my-dep2.yaml

查看

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

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

http://192.168.192.8:31123
http://192.168.192.9:31123
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、安装

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

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

kubectl apply -f ingress.yaml
# 检查安装的结果
kubectl get pod,svc -n ingress-nginx

# 最后别忘记把svc暴露的端口要放行

6-2、使用

[root@k8s-new-master ~]# kubectl get pod,svc -n ingress-nginx
NAME                                            READY   STATUS      RESTARTS   AGE
pod/ingress-nginx-admission-create-c8gbj        0/1     Completed   0          2m34s
pod/ingress-nginx-admission-patch-f6dvr         0/1     Completed   0          2m34s
pod/ingress-nginx-controller-65bf56f7fc-59gmk   1/1     Running     0          2m34s

NAME                                         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             NodePort    10.96.141.189   <none>        80:32276/TCP,443:32488/TCP   2m35s
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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: hello-server
  template:
    metadata:
      labels:
        app: hello-server
    spec:
      containers:
      - name: hello-server
        image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/hello-server
        ports:
        - containerPort: 9000
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-demo
  name: nginx-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-demo
  template:
    metadata:
      labels:
        app: nginx-demo
    spec:
      containers:
      - image: nginx
        name: nginx
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-demo
  name: nginx-demo
spec:
  selector:
    app: nginx-demo
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: hello-server
  name: hello-server
spec:
  selector:
    app: hello-server
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 9000

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

执行

kubectl apply -f test-ingress.yaml

查看

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

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

192.168.192.10 hello.suibibk.com
192.168.192.10 demo.suibibk.com

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

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

apiVersion: networking.k8s.io/v1
kind: Ingress  
metadata:
  name: ingress-host-bar
spec:
  ingressClassName: nginx
  rules:
  - host: "hello.suibibk.com"
    http:
      paths:
      - pathType: Prefix
        path: "/"
        backend:
          service:
            name: hello-server
            port:
              number: 8000
  - host: "demo.suibibk.com"
    http:
      paths:
      - pathType: Prefix
        path: "/nginx"  # 把请求会转给下面的服务,下面的服务一定要能处理这个路径,不能处理就是404
        backend:
          service:
            name: nginx-demo  ## java,比如使用路径重写,去掉前缀nginx
            port:
              number: 8000

部署

kubectl apply -f test-ingress2.yaml

查看下结果

[root@k8s-new-master ~]# kubectl get ingress
NAME               CLASS   HOSTS                                ADDRESS   PORTS   AGE
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里面加入

hostNetwork: true这个字段值

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

...
spec:
      hostNetwork: true
      dnsPolicy: ClusterFirst
...

加上后,重新执行

kubectl replace --force -f ingress.yaml

就可以正常访问了。

6-3-2、路径重写

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

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

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

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-limit-rate
  annotations:
    nginx.ingress.kubernetes.io/limit-rps: "1"
spec:
  ingressClassName: nginx
  rules:
  - host: "haha.suibibk.com"
    http:
      paths:
      - pathType: Exact
        path: "/"
        backend:
          service:
            name: nginx-demo
            port:
              number: 8000
kubectl apply -f test-ingress4.yaml

这里需要在本机hosts加上

192.168.192.10 haha.suibibk.com

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

503 Service Temporarily Unavailable

证明有进行流量控制。

三、存储抽象

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

1、NFS

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

1-1、所有节点执行如下命令

#所有机器安装
yum install -y nfs-utils

1-2、主节点

#nfs主节点
echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports

mkdir -p /nfs/data
systemctl enable rpcbind --now
systemctl enable nfs-server --now
#配置生效
exportfs -r

1-3、从节点

#这里要写主节点的ip
showmount -e 192.168.192.8

#执行以下命令挂载 nfs 服务器上的共享目录到本机路径 /root/nfsmount
mkdir -p /nfs/data

mount -t nfs 192.168.192.8:/nfs/data /nfs/data
# 写入一个测试文件
echo "hello nfs server" > /nfs/data/test.txt

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

1-4、原生方式挂载数据

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-pv-demo
  name: nginx-pv-demo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-pv-demo
  template:
    metadata:
      labels:
        app: nginx-pv-demo
    spec:
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
        - name: html
          nfs:
            server: 192.168.192.8
            path: /nfs/data/nginx-pv

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

kubectl apply -f nginx-pv-demo.yaml

查看创建情况

kubectl get pods -owide

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

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

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

cd /nfs/data/
mkdir nginx-pv

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

curl 10.244.53.16:80

返回了预期结果。

1-5、PV&PVC模式

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

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

#nfs主节点
mkdir -p /nfs/data/01
mkdir -p /nfs/data/02
mkdir -p /nfs/data/03

创建pv

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv01-10m
spec:
  capacity:
    storage: 10M
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  nfs:
    path: /nfs/data/01
    server: 192.168.192.8
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv02-1gi
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  nfs:
    path: /nfs/data/02
    server: 192.168.192.8
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv03-3gi
spec:
  capacity:
    storage: 3Gi
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  nfs:
    path: /nfs/data/03
    server: 192.168.192.8

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

kubectl apply -f pv.yaml

查看

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

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

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: nginx-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 200Mi
  storageClassName: nfs

创建Pod绑定PVC

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-deploy-pvc
  name: nginx-deploy-pvc
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-deploy-pvc
  template:
    metadata:
      labels:
        app: nginx-deploy-pvc
    spec:
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
        - name: html
          persistentVolumeClaim:
            claimName: nginx-pvc

执行完后再查看pv

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

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

2、ConfigMap

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

2-1、redis示例

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

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

也可以用yaml创建

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

查看cm

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

2-1-2、创建redis

apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: redis
    command:
      - redis-server
      - "/redis-master/redis.conf"  #指的是redis容器内部的位置
    ports:
    - containerPort: 6379
    volumeMounts:
    - mountPath: /data
      name: data
    - mountPath: /redis-master
      name: config
  volumes:
    - name: data
      emptyDir: {}
    - name: config
      configMap:
        name: redis-conf
        items:
        - key: redis.conf
          path: redis.conf

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

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

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

2-1-3、修改配置

#找到配置名
kubectl get cm
#修改
kubectl edit configmap redis-conf

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

apiVersion: v1
data:
  redis.conf: |
    appendonly yes
    maxmemory 2mb
    maxmemory-policy allkeys-lru
kind: ConfigMap
metadata:
  creationTimestamp: "2023-02-23T20:44:43Z"
  name: redis-conf
  namespace: default
  resourceVersion: "57788"
  uid: f99aea5f-41da-4755-aed0-7e4a66e2adac

检查配置是否更新

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

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

3、Secret

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

kubectl create secret docker-registry leifengyang-docker \
--docker-username=leifengyang \
--docker-password=Lfy123456 \
--docker-email=534096094@qq.com

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

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

apiVersion: v1
kind: Pod
metadata:
  name: private-nginx
spec:
  containers:
  - name: private-nginx
    image: leifengyang/guignginx:v1.0
  imagePullSecrets:
  - name: leifengyang-docker

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

kubectl describe pod private-nginx

可以看到密码不对的提示

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/

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表