当前位置:   article > 正文

十三、K8s SVC相关操作_svc地址

svc地址

实验环境:

在这里插入图片描述

按照图示部署好了K8s集群,一个Master,两个worker nodes。

一、SVC概述:

所以Kubernetes Service定义了这样一种抽象:一个Pod的逻辑分组,一种可以访问它们的策略 ——通常称为微服务。这一组Pod能够被Service访问到,通常是通过Label Selector。用户仅需要访问 Service,Service能够提供负载均衡的能力,能够将用户流量分配到背后的pod上去。
在这里插入图片描述
Service能够提供负载均衡的能力,但是在使用上有以下限制:

只提供 4 层负载均衡能力,而没有 7 层功能,但有时我们可能需要更多的匹配规则来转发请求,这点上 4 层负载均衡是不支持的。

二、没有SVC的情景,外部应用访问集群内的pods:

创建deployment,部署3个pods:

生成并修改deployment的yaml文件:将端口映射到宿主的33300

kubectl create deployment web1 --image=nginx --dry-run=client -o yaml >web1.yaml

[root@vms201 svc]# cat web1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: web1
  name: web1
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web1
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: web1
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - image: nginx
        name: nginx
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80
          hostPort: 33300
        resources: {}
status: {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

创建并查看deployment:

[root@vms201 svc]# kubectl create -f web1.yaml
deployment.apps/web1 created
[root@vms201 svc]# kubectl create -f web1.yaml
deployment.apps/web1 created
[root@vms201 svc]# kubectl get pods -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP               NODE             NOMINATED NODE   READINESS GATES
web1-7579ff4ffd-rmhmn   1/1     Running   0          5s    10.244.185.124   vms203.rhce.cc   <none>           <none>
web1-7579ff4ffd-xrzkn   1/1     Running   0          5s    10.244.58.249    vms202.rhce.cc   <none>           <none>
[root@vms201 svc]# kubectl get deployments.apps
NAME   READY   UP-TO-DATE   AVAILABLE   AGE
web1   2/2     2            2           10s
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这种情况下,在外部设备访问两个worker nodes上的2个pod:

vms202:
在这里插入图片描述
vms203:
在这里插入图片描述
这种情况虽然能够满足外部设备访问集群中的pod,但是需要修改对应的node的IP地址进行访问,不满足实际的需求。同时,如果一个node上有多个容器映射端口到宿主机的同一个端口号上,会出现端口冲突的故障。

三、创建SVC

部署SVC关联的deployment:

修改deploy的yaml文件并部署:

[root@vms201 svc]# cat web1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: web1
  name: web1
spec:
  replicas: 2
  selector:
    matchLabels:
      app1: web1
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app1: web1
        app2: web2
        app3: web3
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - image: nginx
        name: nginx
        imagePullPolicy: IfNotPresent
        ports:
        resources: {}
status: {}

[root@vms201 svc]# kubectl apply -f web1.yaml
deployment.apps/web1 created
[root@vms201 svc]# kubectl get pods --show-labels
NAME                    READY   STATUS    RESTARTS   AGE     LABELS
web1-54cbfdf7b5-c5r9n   1/1     Running   0          5m49s   app1=web1,app2=web2,app3=web3,pod                                   -template-hash=54cbfdf7b5
web1-54cbfdf7b5-wg2vr   1/1     Running   0          5m49s   app1=web1,app2=web2,app3=web3,pod                                   -template-hash=54cbfdf7b5
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

yaml文件中定义了2个副本,并且每个pod有3个标签。

创建SVC的方式:

  1. 直接使用命令行;(推荐)
  2. 使用yaml文件的方式创建。

举例: 通过命令行的方式创建SVC(建议)

语法:

kubectl expose --name=名字 资源类型/名字 --port=xxx --target-port=yyy --selector=aaa=bbb
  • 1

其中target-port是pod运行的端口,不能随便写。而—port为SVC的端口,可以随意修改。对deployment设置服务:

[root@vms201 svc]# kubectl expose --name=svc1 deployment web1 --port=80 --target-port=80
service/svc1 exposed
[root@vms201 svc]# kubectl get svc svc1 -o wide
NAME   TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE   SELECTOR
svc1   ClusterIP   10.105.219.0   <none>        80/TCP    63s   app1=web1
  • 1
  • 2
  • 3
  • 4
  • 5

可以看到SELECTOR为web1,说明了如果在创建SVC时没有指定哪个标签定位pod时,使用的是和deploy一样的标签。查看SVC关联的后端容器等信息:

[root@vms201 svc]# kubectl describe svc svc1
Name:              svc1
Namespace:         svc
Labels:            app=web1
Annotations:       <none>
Selector:          app1=web1
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.105.219.0
IPs:               10.105.219.0
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.185.125:80,10.244.58.252:80
Session Affinity:  None
Events:            <none>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

Endpoints指明了SVC关联的后端容器的地址。

注意:如果我们再deployment之外重新创建了一个pod,且标签和设置的SVC匹配的标签相同,也会被被SVC关联。

修改deployment中部署pod的主页,查看负载分担的情况:

kubectl exec -it web1-54cbfdf7b5-c5r9n -- sh -c "echo 111 > /usr/share/nginx/html/index.html"
kubectl exec -it web1-54cbfdf7b5-wg2vr -- sh -c "echo 222 > /usr/share/nginx/html/index.html"
  • 1
  • 2

svc的地址为 10.105.219.0,在cluster中都可以访问:

[root@vms201 svc]# while true ; do
> curl 10.105.219.0
> sleep 1
> done
111
111
222
111
111
222
111
111
222
111
222
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

可以看到流量被分配到了SVC关联的两个pod中去。

注意:kube-proxy的模式是iptales(默认),则无法ping通svc的地址,如果为ipvs,则可以ping通svc的地址。

[root@vms201 svc]# ping 10.105.219
PING 10.105.219 (10.105.0.219) 56(84) bytes of data.
  • 1
  • 2

四、服务的发现

我们现在创建的应用比较单一,有时候需要创建多级应用,例如WordPress+mysql。流量访问Wordpress的SVC,被负载到身后的pods中;Wordpress的pod再连接到mysql的pod的SVC上,访问mysqldb。而wordpress如何访问mysql pods的SVC,则就是集群的发现。

服务发现的三种方式:

  1. clusterIP
  2. 变量方式
  3. DNS方法(推荐)

方式1: clusterIP

修改mysql的vim文件:

kubectl run dbpod --image=mysql --image-pull-policy=IfNotPresent --dry-run=client -o yaml > dbpod.yaml

[root@vms201 svc]# cat dbpod.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: dbpod
  name: dbpod
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - image: mysql
    imagePullPolicy: IfNotPresent
    name: dbpod
    resources: {}
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: mysql1
    - name: MYSQL_USER
      value: tom
    - name: MYSQL_PASWORD
      value: mysql1
    - name: MYSQL_DATABASE
      value: wordpress
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

创建并查看mysql的pod:

[root@vms201 svc]# kubectl create -f dbpod.yaml
pod/dbpod created
[root@vms201 svc]# kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
dbpod   1/1     Running   0          6s
  • 1
  • 2
  • 3
  • 4
  • 5

创建mysql pod对应的SVC:

[root@vms201 svc]# kubectl expose --name=dbsvc pod dbpod --port=3306 --target-port=3306
service/dbsvc exposed
[root@vms201 svc]# kubectl get svc
NAME    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
dbsvc   ClusterIP   10.111.190.70   <none>        3306/TCP   27s
  • 1
  • 2
  • 3
  • 4
  • 5

创建wordpress的pod,yaml文件如下:

[root@vms201 svc]# cat blogpod.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: blogpod
  name: blogpod
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - image: wordpress
    imagePullPolicy: IfNotPresent
    name: blogpod
    resources: {}
    env:
    - name: WORDPRESS_DB_HOST
      value: 10.111.190.70
    - name: WORDPRESS_DB_USER
      value: root
    - name: WORDPRESS_DB_PASSWORD
      value: mysql1
    - name: WORDPRESS_DB_NAME
      value: wordpress
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

其中WORDPRESS_DB_HOST为mysql SVC的cluster IP,WORDPRESS_DB_USER、WORDPRESS_DB_PASSWORD、WORDPRESS_DB_NAME分别是mysqldb的账号密码和数据库。

[root@vms201 svc]# kubectl apply -f blogpod.yaml
pod/blogpod created
[root@vms201 svc]# kubectl get pods -o wide
NAME      READY   STATUS    RESTARTS   AGE     IP               NODE             NOMINATED NODE   READINESS GATES
blogpod   1/1     Running   0          2m23s   10.244.185.66    vms203.rhce.cc   <none>           <none>
dbpod     1/1     Running   0          8m10s   10.244.185.126   vms203.rhce.cc   <none>           <none>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

可以看到,blogpod运行在vms203.rhce.cc宿主机上。接着创建wordpress的SVC:

[root@vms201 svc]# kubectl expose --name=blogsvc pod blogpod --port=80 --target-port=80 --type=NodePort
service/blogsvc exposed
[root@vms201 svc]# kubectl get svc
NAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
blogsvc   NodePort    10.105.201.27   <none>        80:32726/TCP   5s
dbsvc     ClusterIP   10.111.190.70   <none>        3306/TCP       8m21s
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

type=NodePort会在后续补充。现在可以使用宿主机vms203.rhce.cc的32726端口访问到wordpress,发现不用创建数据库,说明连接成功。

在这里插入图片描述

方式2: 变量方式

修改blogpod的变量:blogpod会以变量的方式去记录服务的信息。进入pod,输入命令env查看环境变量:

[root@vms201 svc]# kubectl exec -it  blogpod -- bash
root@blogpod:/var/www/html# env | grep SERVICE_HOST
DBSVC_SERVICE_HOST=10.111.190.70
KUBERNETES_SERVICE_HOST=10.96.0.1
root@blogpod:/var/www/html# env | grep SERVICE_PORT
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_PORT=443
DBSVC_SERVICE_PORT=3306
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

其中的几个参数需要注意:

  1. 大写服务名_SERVICE_HOST=服务的IP
  2. 大写服务名_SERVICE_PORT=服务的端口
  3. DBSVC_SERVICE_HOST=dbsec的IP
  4. DBSVC_SERVICE_PORT=dbsec的端口

相关SVC信息如果哎此pod之前创建,会自动被记录,在之后则不会。

重新创建blogpod:

[root@vms201 svc]# kubectl delete -f blogpod.yaml
pod "blogpod" deleted
  • 1
  • 2

修改blogpod的yaml文件:引用为变量的方式。

[root@vms201 svc]# cat blogpod.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: blogpod
  name: blogpod
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - image: wordpress
    imagePullPolicy: IfNotPresent
    name: blogpod
    resources: {}
    env:
    - name: WORDPRESS_DB_HOST
      value: $(DBSVC_SERVICE_HOST)
    - name: WORDPRESS_DB_USER
      value: root
    - name: WORDPRESS_DB_PASSWORD
      value: mysql1
    - name: WORDPRESS_DB_NAME
      value: wordpress
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

同理可以访问到WordPress上,且不用创建数据库。

此方式存在的问题:

  1. 只能获取相同namespace里的变量;
  2. 变量的获取有先后顺序,引用的变量必须要先创建。

方式3: DNS方式

直接通过SVC名称的方式访问服务。可以看到集群中已经存在了一个DNS的SVC:kube-dns 。

[root@vms201 svc]# kubectl get svc -n kube-system -o wide
NAME             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE     SELECTOR
kube-dns         ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP,9153/TCP   7d17h   k8s-app=kube-dns
metrics-server   ClusterIP   10.96.163.225   <none>        443/TCP                  7d15h   k8s-app=metrics-server
  • 1
  • 2
  • 3
  • 4

当我们每创建一个SVC,都会想kube-dns 进行注册,kubedns都会知道这个这个SVC的IP地址。所以在同一个命名空间里面可以直接通过SVC名访问SVC(通过这个SVC名向kube-dns进行查询),如果pod和SVC不是同一个命名空间,需要加上指定SVC命名空间的参数。

重新创建pod,修改WORDPRESS_DB_HOST参数为dbsvc即可:

[root@vms201 svc]# kubectl delete -f blogpod.yaml
pod "blogpod" deleted
[root@vms201 svc]# vim blogpod.yaml
[root@vms201 svc]# cat blogpod.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: blogpod
  name: blogpod
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - image: wordpress
    imagePullPolicy: IfNotPresent
    name: blogpod
    resources: {}
    env:
    - name: WORDPRESS_DB_HOST
      value: dbsvc
    - name: WORDPRESS_DB_USER
      value: root
    - name: WORDPRESS_DB_PASSWORD
      value: mysql1
    - name: WORDPRESS_DB_NAME
      value: wordpress
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
[root@vms201 svc]# kubectl apply -f blogpod.yaml
pod/blogpod created
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

同理可以访问到WordPress上,且不用创建数据库。

五、服务的发布

所谓发布指的是,如何让集群之外的主机能访问服务。Service发布方式在 K8s 中有以下四种类型:

1.ClusterIp:
默认类型,自动分配一个仅 Cluster 内部可以访问的虚拟 IP(service创建一个仅集群内部可访问的ip,集群内部其他的pod可以通过该服务访问到其监控下的pod)
在这里插入图片描述
2.NodePort:
在 ClusterIP 基础上为 Service 在每台机器上绑定一个端口,这样就可以通过NodePort 来访问该服务(在service及各个node节点上开启端口,外部的应用程序或客户端访问node的端口将会转发到service的端口,而service将会依据负载均衡随机将请求转发到某一个pod的端口上。一般暴露服务常用的端口)。NodePort是宿主机的端口,port是Service的端口,target-port为pod的端口。
在这里插入图片描述
创建deploy和服务,type内心为NodePort:

[root@vms201 svc]# kubectl create -f web1.yaml
deployment.apps/web1 created
[root@vms201 svc]# kubectl expose --name=websvc deployment web1 --port=80 --target-port=80 --type=NodePort
service/blogsvc exposed
[root@vms201 svc]# kubectl get svc
NAME      TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
websvc    NodePort   10.103.97.15   <none>        80:32717/TCP   2m12s
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

可以看到,type为NodePort,映射的端口为32717,我们就可以在外部设备访问集群内的任何一个机器(无论是master还是worker nodes),以访问到内部的pod:
在这里插入图片描述
此方式存在的问题,例如在一个集群发布了多个SVC,那么其宿主机上也会映射相应的端,这样会导致2个问题:

  1. 端口越多,漏洞可能性越大;
  2. 维护起来也麻烦。

3.LoadBalancer:
在 NodePort 的基础上,借助cloud provider创建一个外部负载均衡器,并将请求转发到: NodePort(在NodePort基础之上,即各个节点前加入了负载均衡器实现了真正的高可用,一般云供应商提供的k8s集群就是这种)
在这里插入图片描述
每个SVC都有一个私有的地址,只能在集群内部访问,如果我们将一个SVC设置为Loadbalancer,则这个SVC会获取一个外部IP地址(需要一个地址池,由metallb提供)

安装metallb,官网:https://metallb.universe.tf/installation/,根据其中的步骤完成metalib安装。创建命名空间:

[root@vms201 svc]# kubectl create ns metallb-system
namespace/metallb-system created
  • 1
  • 2

下载的yaml文件,地址为:https://raw.githubusercontent.com/metallb/metallb/v0.10.2/manifests/metallb.yaml,下载完成后保存为metallb.yaml文件。修改其文件,在image下设置imagePullPolicy为IfNotPresent。

应用对于的yaml文件创建metallb的pod:

[root@vms201 svc]# kubectl apply -f metallb.yaml
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
podsecuritypolicy.policy/controller created
podsecuritypolicy.policy/speaker created
serviceaccount/controller created
serviceaccount/speaker created
clusterrole.rbac.authorization.k8s.io/metallb-system:controller created
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created
role.rbac.authorization.k8s.io/config-watcher created
role.rbac.authorization.k8s.io/pod-lister created
role.rbac.authorization.k8s.io/controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created
rolebinding.rbac.authorization.k8s.io/config-watcher created
rolebinding.rbac.authorization.k8s.io/pod-lister created
rolebinding.rbac.authorization.k8s.io/controller created
daemonset.apps/speaker created
deployment.apps/controller created

[root@vms201 svc]# kubectl get pods -n metallb-system
NAME                          READY   STATUS    RESTARTS   AGE
controller-6b78bff7d9-shv95   1/1     Running   0          42m
speaker-gcbkh                 1/1     Running   0          42m
speaker-tg2tm                 1/1     Running   0          42m
speaker-v5f7h                 1/1     Running   0          42m
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

创建地组池,yaml文件如下:分配的地址为192.168.0.240-192.168.0.250,与node同网段。

[root@vms201 svc]# cat pool.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.0.240-192.168.0.250
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

应用yaml文件:

[root@vms201 svc]# kubectl apply -f pool.yaml
configmap/config created
  • 1
  • 2

删除之前的SVC,创建新的SVC:

[root@vms201 svc]# kubectl delete svc websvc
service "websvc" deleted
[root@vms201 svc]# kubectl expose --name=websvc deployment web1 --port=80 --target-port=80 --type=LoadBalancer
service/websvc exposed
[root@vms201 svc]# kubectl get svc
NAME     TYPE           CLUSTER-IP       EXTERNAL-IP     PORT(S)        AGE
websvc   LoadBalancer   10.110.232.180   192.168.0.240   80:32010/TCP   45s
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

可以看到,EXTERNAL-IP为地组池分配的地址:192.168.0.240。如果没有安装metallib,服务的状态为pending。外部设备现在可以以192.168.0.240直接访问pod:
在这里插入图片描述

LB方式最大的缺点则是每个service一个LB又有点浪费和麻烦,,并且需要k8s之外的支持。

4.Ingress:(推荐)
ingress(简称ing)则只需要一个NodePort或者一个LB就可以满足所有service对外服务的需求。工作机制大致可以用下图表示:
在这里插入图片描述
实际上,ingress相当于一个7层的负载均衡器,是k8s对反向代理的一个抽象。大概的工作原理也确实类似于Nginx,可以理解成在 Ingress 里建立一个个映射规则 , ingress Controller 通过监听 Ingress这个api对象里的配置规则并转化成 Nginx 的配置(kubernetes声明式API和控制循环) , 然后对外部提供服务。

搭建ingress–nginx控制器过程:

1.首先在nginx上下载对应镜像和yaml文件。
2.在三台设备上加载镜像。
3.应用其yaml文件生成ingress控制器:

[root@vms201 svc]# kubectl apply -f nginx-ingress-controller.yaml
namespace/ingress-nginx created
serviceaccount/ingress-nginx created
configmap/ingress-nginx-controller created
clusterrole.rbac.authorization.k8s.io/ingress-nginx created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx created
role.rbac.authorization.k8s.io/ingress-nginx created
rolebinding.rbac.authorization.k8s.io/ingress-nginx created
service/ingress-nginx-controller-admission created
service/ingress-nginx-controller created
deployment.apps/ingress-nginx-controller created
validatingwebhookconfiguration.admissionregistration.k8s.io/ingress-nginx-admission created
serviceaccount/ingress-nginx-admission created
clusterrole.rbac.authorization.k8s.io/ingress-nginx-admission created
clusterrolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
role.rbac.authorization.k8s.io/ingress-nginx-admission created
rolebinding.rbac.authorization.k8s.io/ingress-nginx-admission created
job.batch/ingress-nginx-admission-create created
job.batch/ingress-nginx-admission-patch created
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

4.查看运行结果: 可以看到,控制器在vms202.rhce.cc node上运行。

[root@vms201 svc]# kubectl get pods -n ingress-nginx -o wide
NAME                                        READY   STATUS      RESTARTS   AGE     IP              NODE             NOMINATED NOD                         E   READINESS GATES
ingress-nginx-admission-create-pc4pd        0/1     Completed   0          2m30s   10.244.185.75   vms203.rhce.cc   <none>                                    <none>
ingress-nginx-admission-patch-phkjj         0/1     Completed   1          2m30s   10.244.185.76   vms203.rhce.cc   <none>                                    <none>
ingress-nginx-controller-59b8bf5fdc-4x4x4   1/1     Running     0          2m30s   192.168.0.202   vms202.rhce.cc   <none>                                    <none>
  • 1
  • 2
  • 3
  • 4
  • 5

5.修改外部设备的host文件,当访问web应用(2个pod)的域名时,都被解析为node2的ip 192.168.0.202。添加内容如下:
192.168.0.202 www1.rhce.cc
192.168.0.202 www2.rhce.cc

6.创建2个nginx的pod:

yaml文件为:

[root@vms201 svc]# cat pod1.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: web1
  name: web1
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: c1
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

创建两个nginx的pod:

[root@vms201 svc]# kubectl apply -f pod1.yaml
pod/web1 created
[root@vms201 svc]# sed 's/web1/web2/' pod1.yaml | kubectl apply -f -
pod/web2 created
[root@vms201 svc]# kubectl get pods
[root@vms201 svc]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE   IP              NODE             NOMINATED NODE   READINESS GATES
web1   1/1     Running   0          16s   10.244.185.69   vms203.rhce.cc   <none>           <none>
web2   1/1     Running   0          15s   10.244.185.70   vms203.rhce.cc   <none>           <none>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

分别将其中主页修改为111和222,方便后续测试观察。

[root@vms201 svc]# kubectl exec -it web1 -- sh -c "echo 111 > /usr/share/nginx/html/index.html"
[root@vms201 svc]# kubectl exec -it web2 -- sh -c "echo 222 > /usr/share/nginx/html/index.html"
  • 1
  • 2

7.分别对于两个pod创建service

[root@vms201 svc]# kubectl expose --name=svc1 pod web1 --port=80
service/svc1 exposed
[root@vms201 svc]# kubectl expose --name=svc2 pod web2 --port=80
service/svc2 exposed
[root@vms201 svc]# kubectl get svc
NAME   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
svc1   ClusterIP   10.104.248.179   <none>        80/TCP    25s
svc2   ClusterIP   10.100.210.160   <none>        80/TCP    14s
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

8.设置ingress规则:

我们需要设置当访问www1.rhce.cc时,流量被发送到web1;当访问www2.rhce.cc时,流量被发送到web2 。注意:配置ingress规则不需要切换到ingress的命名空间。

编辑ingress规则的yaml文件(在官网查找格式:https://kubernetes.io/docs/concepts/services-networking/ingress/):

[root@vms201 svc]# cat ingressrule.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myingress
  #annotations:
  #  nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: www1.rhce.cc
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: svc1
            port:
              number: 80
  - host: www2.rhce.cc
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: svc2
            port:
              number: 80
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

在测试环境中需要注释2句话。

9.创建ingress规则,应用到ingress上,然后测试:

[root@vms201 svc]# kubectl apply -f ingressrule.yaml
ingress.networking.k8s.io/myingress created
[root@vms201 svc]# kubectl get ingress
NAME        CLASS    HOSTS                       ADDRESS         PORTS   AGE
myingress   <none>   www1.rhce.cc,www2.rhce.cc   10.108.154.34   80      29s
  • 1
  • 2
  • 3
  • 4
  • 5

然后在修改了host文件的设备上访问www1.rhce.cc和www2.rhce.cc:测试成功。
在这里插入图片描述

在这里插入图片描述

注意点:
如果在别的命名空间里也创建了和当前命名空间一样的ingress规则,会报错,告知www1.rhce.cc这个域名已经被占用了。

参考资料:
6. 《老段CKA课程》
7. 链接:https://www.jianshu.com/p/fd597312751a
8. 链接:https://blog.csdn.net/yrx420909/article/details/105724292

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号