【K8S实战】-超详细教程(二)

环境这块的这里我就不过多描述了,需要了解的可以看这篇文章【k8s搭建(超详细,保姆级教程)】。

1、Deployment

Deployment其他功能我上一篇文章已写,有兴趣的可以移步这里【K8S实战】-超详细教程(一)
nginx-tmp.yaml文件内容如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-tmp
  name: nginx-tmp
spec:
  replicas: 2 #副本数量
  selector:
    matchLabels:
      app: nginx-tmp
  template:
    metadata:
      labels:
        app: nginx-tmp
    spec:
      containers:
      - image: nginx
        imagePullPolicy: IfNotPresent #如果存在则不重新拉取镜像
        name: nginx
      restartPolicy: Always

1.1、滚动更新

K8S初始运行状态
[root@master nginx]# kubectl get pod -A -owide
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE     IP                NODE     NOMINATED NODE   READINESS GATES
default       nfs-client-provisioner-846cc9c4-4687x      1/1     Running   0          135m    192.168.166.129   node1    <none>           <none>
default       nginx-tmp-f4bb75fc8-npcw7                  1/1     Running   0          122m    192.168.166.130   node1    <none>           <none>
default       nginx-tmp-f4bb75fc8-wn2t5                  1/1     Running   0          122m    192.168.166.131   node1    <none>           <none>
......
kube-system   kube-scheduler-master                      1/1     Running   0          3h56m   172.168.200.130   master   <none>           <none>

滚动更新“--record”这个是记录本次升级记录
[root@master nginx]# kubectl set image deployment nginx-tmp nginx=nginx:1.16.1 --record
deployment.apps/nginx-tmp image updated

查看版本滚动更新状态,这里会先一个pod停掉启动成功,再去停掉另一个pod。
[root@master nginx]# kubectl rollout status deployment nginx-tmp
Waiting for deployment "nginx-tmp" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx-tmp" rollout to finish: 1 old replicas are pending termination...
deployment "nginx-tmp" successfully rolled out
[root@master nginx]# 
[root@master nginx]# 
查看历史版本,发现版本2已经更改为1.16.1了
[root@master nginx]# kubectl rollout history deployment nginx-tmp
deployment.apps/nginx-tmp 
REVISION  CHANGE-CAUSE
1         <none>
2         kubectl set image deployment nginx-tmp nginx=nginx:1.16.1 --record=true

1.2、版本回退

继续【1.1、滚动更新】我弄了几个版本,目前最新的是版本4。

[root@master nginx]# kubectl rollout history deployment nginx-tmp
deployment.apps/nginx-tmp 
REVISION  CHANGE-CAUSE
1         <none>
2         kubectl set image deployment nginx-tmp nginx=nginx:1.16.1 --record=true
3         kubectl set image deployment nginx-tmp nginx=nginx:1.17.6 --record=true
4         kubectl set image deployment nginx-tmp nginx=nginx:1.17.5 --record=true

1.2.1、回退上一个版本
当前版本撤销,回退上一个版本。
[root@master nginx]# kubectl rollout undo deployment nginx-tmp

查看历史版本记录发现,目前版本5是最新的
[root@master nginx]# kubectl rollout history deployment nginx-tmp 
deployment.apps/nginx-tmp 
REVISION  CHANGE-CAUSE
1         <none>
2         kubectl set image deployment nginx-tmp nginx=nginx:1.16.1 --record=true
4         kubectl set image deployment nginx-tmp nginx=nginx:1.17.5 --record=true
5         kubectl set image deployment nginx-tmp nginx=nginx:1.17.6 --record=true

1.2.2、回退指定版本

继续【1.2.1、回退上一个版本】。

查看某个版本历史记录,这里查看了版本4的,如下是版本4的相关信息
[root@master nginx]# kubectl rollout history deployment/nginx-tmp --revision=4
deployment.apps/nginx-tmp with revision #4
Pod Template:
  Labels:	app=nginx-tmp
	pod-template-hash=768b4b54bd
  Annotations:	kubernetes.io/change-cause: kubectl set image deployment nginx-tmp nginx=nginx:1.17.5 --record=true
  Containers:
   nginx:
    Image:	nginx:1.17.5
    Port:	<none>
    Host Port:	<none>
    Environment:	<none>
    Mounts:	<none>
  Volumes:	<none>

回退到版本1
[root@master nginx]# kubectl rollout undo deployment/nginx-tmp --to-revision=1
deployment.apps/nginx-tmp rolled back

查看版本历史记录,目前最新的是版本6,
[root@master nginx]# kubectl rollout history deployment/nginx-tmp 
deployment.apps/nginx-tmp 
REVISION  CHANGE-CAUSE
2         kubectl set image deployment nginx-tmp nginx=nginx:1.16.1 --record=true
4         kubectl set image deployment nginx-tmp nginx=nginx:1.17.5 --record=true
5         kubectl set image deployment nginx-tmp nginx=nginx:1.17.6 --record=true
6         <none>

还有一种是有状态服务,大家可以去官网自行了解【有状态服务】,这里就不过多赘述了。

2、Service

K8S的service主要作用是为了解决多个副本的访问负载及服务发现。service访问类型主要有个2种一种是ClusterIP(外网不能访问)一种是NodePort(外网能访问)。
这里以【5.1.2】的nginx-tmp.yaml进行演示。

初始运行信息
[root@k8s-m dpm]#  kubectl get pod -A -owide
NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE    IP                NODE     NOMINATED NODE   READINESS GATES
default       nginx-tmp-f4bb75fc8-b6r6f                  1/1     Running   0          3m21s   192.168.166.141   node1    <none>           <none>
default       nginx-tmp-f4bb75fc8-wdv27                  1/1     Running   0          3m23s   192.168.166.140   node1    <none>           <none>

......
kube-system   kube-scheduler-k8s-m                       1/1     Running   3          4d6h   200.168.88.130    k8s-m    <none>           <none>

2.1、命令方式暴露Service

暴露ClusterIP一个服务
[root@k8s-m dpm]# kubectl expose deployment nginx-tmp --port=8000 --target-port=80 --type=ClusterIP
service/nginx-tmp exposed

查看暴露的服务
[root@k8s-m dpm]# kubectl get svc -A
NAMESPACE     NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE
default       kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP                  4d6h
default       nginx-tmp    ClusterIP   10.96.225.90    <none>        8000/TCP                 34s
kube-system   kube-dns     ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP,9153/TCP   4d6h

先修改下2个节点(node1,node2)的nginx主页,这样才能更好的观察。
[root@k8s-m dpm]# kubectl exec -it nginx-tmp-f4bb75fc8-b6r6f -- bash
root@nginx-tmp-f4bb75fc8-7zcl4:/# 
root@nginx-tmp-f4bb75fc8-7zcl4:/# echo node1 > /usr/share/nginx/html/index.html 
root@nginx-tmp-f4bb75fc8-7zcl4:/# cat /usr/share/nginx/html/index.html 
node1
root@nginx-tmp-f4bb75fc8-7zcl4:/# exit
exit
command terminated with exit code 127
修改节点2的主页信息
[root@k8s-m dpm]# kubectl exec -it nginx-tmp-f4bb75fc8-wdv27 -- bash
root@nginx-tmp-f4bb75fc8-t79j5:/# 
root@nginx-tmp-f4bb75fc8-t79j5:/# echo node2 > /usr/share/nginx/html/index.html
root@nginx-tmp-f4bb75fc8-t79j5:/# cat /usr/share/nginx/html/index.html
node2
root@nginx-tmp-f4bb75fc8-t79j5:/# exit
exit

通过服务访问2个节点的nginx主页,这里个发现节点2可以访问,但是节点1有问题,这里其实是我在做【5.3故障转移、自愈】时实验遗留的问题,我重启过node1,那么防火墙也会运行,所以这里关掉节点1的防火墙即可。
[root@k8s-m dpm]# curl 10.96.225.90:8000
node2
[root@k8s-m dpm]# curl 10.96.225.90:8000
curl: (7) Failed connect to 10.96.225.90:8000; 没有到主机的路由

去节点1机器执行如下命令关闭防火墙
[root@k8s-n1 ~]# service firewalld stop
Redirecting to /bin/systemctl stop firewalld.service

回到主节点再次通过服务访问,发现已经可以访问2台nginx的服务了。
在浏览器使用任意节点的IP进行访问,发现是无法访问集群内的服务的。
[root@k8s-m dpm]# curl 10.96.225.90:8000
node2
[root@k8s-m dpm]# curl 10.96.225.90:8000
node1

删除该暴露的服务
[root@k8s-m dpm]# kubectl delete service nginx-tmp 
service "nginx-tmp" deleted

暴露一个NodePort的服务。
[root@k8s-m dpm]# kubectl expose deployment nginx-tmp --port=8000 --target-port=80 --type=NodePort
service/nginx-tmp exposed

查看重新暴露后的服务信息,发现多了一个端口
[root@k8s-m dpm]# kubectl get svc
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP          4d6h
nginx-tmp    NodePort    10.96.32.123   <none>        8000:32617/TCP   22s

在浏览器使用任意节点的IP+暴露的端口访问即可…

2.2、Yaml方式暴露Service

暴露一个服务
[root@k8s-m svc]# kubectl apply -f nginx-svc.yaml 
service/nginx-tmp created

删除一个服务
[root@k8s-m svc]# kubectl delete-f nginx-svc.yaml 
service/nginx-tmp created

nginx-svc.yaml文件内容如下:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-tmp
  name: nginx-tmp
spec:
  ports:
   - protocol: TCP
     port: 8000
     targetPort: 80
  selector:
    app: nginx-tmp
  type: NodePort #这里的值也可以是ClusterIP

3、Ingress

Ingress 公开从集群外部到集群内服务的 HTTP 和 HTTPS 路由。 流量路由由 Ingress 资源上定义的规则控制。
Ingress 可为 Service 提供外部可访问的 URL、负载均衡流量、终止 SSL/TLS,以及基于名称的虚拟托管。 Ingress 控制器 通常负责通过负载均衡器来实现 Ingress,尽管它也可以配置边缘路由器或其他前端来帮助处理流量。
Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的 Service。

3.1、安装

下载yaml资源文件
[root@master nginx]# wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.47.0/deploy/static/provider/baremetal/deploy.yaml

先把deploy.yaml这里的镜像替换成这个ingress-nginx-controller:v0.49.1
......
spec:
  dnsPolicy: ClusterFirst
  containers:
    - name: controller
      #image: k8s.gcr.io/ingress-nginx/controller:v0.46.0@sha256:52f0058bed0a17ab0fb35628ba97e8d52b5d32299fbc03cc0f6c7b9ff036b61a
      image: liangjw/ingress-nginx-controller:v0.49.1
      imagePullPolicy: IfNotPresent
      lifecycle:
......


创建资源
[root@master nginx]# kubectl create -f deploy.yaml

查看创建请求,发现已经成功运行
[root@master nginx]# kubectl get pod,svc -n ingress-nginx
NAME                                            READY   STATUS      RESTARTS   AGE
pod/ingress-nginx-admission-create-nvvwt        0/1     Completed   0          12s
pod/ingress-nginx-admission-patch-kj4dh         0/1     Completed   1          12s
pod/ingress-nginx-controller-76cccff97f-mvxcr   0/1     Running     0          12s

NAME                                         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             NodePort    10.96.170.144   <none>        80:30171/TCP,443:31647/TCP   12s
service/ingress-nginx-controller-admission   ClusterIP   10.96.24.13     <none>        443/TCP                      12s


浏览器进行访问
http://172.168.200.130:30702/
https://172.168.200.130:30854/

在这里插入图片描述

3.2、使用

准备一个nginx-tmp.yaml(如果之前有的先停止掉)。

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-tmp
  name: nginx-tmp
spec:
  replicas: 2 #副本数量
  selector:
    matchLabels:
      app: nginx-tmp
  template:
    metadata:
      labels:
        app: nginx-tmp
    spec:
      containers:
      - image: nginx
        imagePullPolicy: IfNotPresent
        name: nginx
      restartPolicy: Always

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

创建2个pod以及暴露服务

[root@master nginx]# kubectl get pod,svc 
NAME                                        READY   STATUS    RESTARTS   AGE
pod/nfs-client-provisioner-846cc9c4-4687x   1/1     Running   0          3h21m
pod/nginx-tmp-f4bb75fc8-2lx5p               1/1     Running   0          19s
pod/nginx-tmp-f4bb75fc8-hjr2g               1/1     Running   0          19s

NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE
service/kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP    5h2m
service/nginx-tmp    ClusterIP   10.96.42.140   <none>        8000/TCP   19s

3.2.1、域名访问

继续【3.2、使用】的实战,还需准备一个ingress-test.yaml文件。

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

创建一个ingress

[root@master nginx]# kubectl apply -f ingress-test.yaml 
ingress.networking.k8s.io/ingress-host created

[root@master nginx]# kubectl get ingress
NAME           CLASS   HOSTS              ADDRESS           PORTS   AGE
ingress-host   nginx   demo.test.com   172.168.200.131   80      65s

在浏览器上使用demo.test.com:30171/nginx进行访问。注需要配置宿主机的hosts文件。

172.168.200.130 demo.test.com

在这里插入图片描述

3.2.2、路径重写

继续【3.2.1、域名访问】,把ingress-test.yaml作如下修改。继续深入学习可以看这里【ingress-nginx】。

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: "demo.test.com"
    http:
      paths:
      - pathType: Prefix
        path: "/nginx(/|$)(.*)"  # 把请求会转给下面的服务,下面的服务一定要能处理这个路径,不能处理就是404。/nginx(/|$)(.*)意思是会把nginx这个前缀去掉。
        backend:
          service:
            name: nginx-tmp  ## java,比如使用路径重写,去掉前缀nginx
            port:
              number: 8000

直接这样即可。

[root@master nginx]# kubectl apply -f ingress-test.yaml 
ingress.networking.k8s.io/ingress-host configured

浏览器再次请求。
在这里插入图片描述

3.2.3、流量控制

继续【 3.2.2、路径重写】,ingress-test.yaml做如下调整。深入学习请移步【ingress-nginx】。

apiVersion: networking.k8s.io/v1
kind: Ingress  
metadata:
  annotations:
  	  nginx.ingress.kubernetes.io/rewrite-target: /$2
      nginx.ingress.kubernetes.io/limit-rps: "1" #每秒只能有一个请求
  name: ingress-host
spec:
  ingressClassName: nginx
  rules:
  - host: "demo.test.com"
    http:
      paths:
      - pathType: Prefix
        path: "/nginx(/|$)(.*)"  # 把请求会转给下面的服务,下面的服务一定要能处理这个路径,不能处理就是404
        backend:
          service:
            name: nginx-tmp  ## java,比如使用路径重写,去掉前缀nginx
            port:
              number: 8000

执行如下命令:

[root@master nginx]# kubectl apply -f ingress-test.yaml 
ingress.networking.k8s.io/ingress-host configured

然后在浏览器上每秒点击多次即可出现如下页面。
在这里插入图片描述

上一篇:【K8S实战】超详细教程(一)
下一篇:【K8S实战】超详细教程(三)

资源参考:

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐