04Kubernetes-网络服务Service

Service服务介绍

通过前面的实验我们已经掌握了使用Pod控制器来管理Pod,我们也会发现,Pod的生命周期非常短暂,每次镜像升级都会销毁以及创建,而我们知道每个Pod都拥有自己的IP地址,并且随着Pod删除和创建,这个IP是会变化的。
当我们的Pod数量非常多的时候前端的入口服务该怎么知道后面都有哪些Pod呢?
为了解决这个问题k8s提供了一个对象Service和三种IP,创建的Service资源通过标签可以动态的知道后端的Pod的IP地址,在PodIP之上设计一个固定的IP,也就是ClusterIP,然后使用NodePort来对外暴露端口提供访问。
接下来我们先认识一下K8s里的三种IP及其作用。

Service的三种资源

NodePort
节点对外提供访问的IP

ClusterIP
用来动态发现和负载均衡POD的IP

PodIP
提供POD使用的IP

file

Cluster IP资源配置

资源配置清单

[root@db01 php-apache]# cat cluster_ip.yaml
apiVersion: v1
kind: Service
metadata:
  name: php-apache
  namespace: default
spec:
  selector:
    run: php-apache
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  type: ClusterIP

# 配置解释:
  ports:
  - name: http
    port: 80        # clusterIP的端口号
    protocol: TCP   # 协议类型
    targetPort: 80  # POD暴露的端口号
  type: ClusterIP   # service类型

# 创建镜像
[root@db01 php-apache]# kubectl apply -f cluster_ip.yaml

# 查看ClusterIP
[root@db01 php-apache]# kubectl get service
[root@db01 php-apache]# kubectl get svc
NAME         TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.1.0.1      <none>        443/TCP   3d
php-apache   ClusterIP   10.1.187.11   <none>        80/TCP    14s

## 查看cluster ip的详细信息
[root@db01 php-apache]# kubectl describe svc php-apache
Name:              php-apache
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          run=php-apache
Type:              ClusterIP
IP:                10.1.187.11
Port:              http  80/TCP
TargetPort:        80/TCP
Endpoints:         10.2.2.67:80
Session Affinity:  None
Events:            <none>

通过Cluster IP名字即可访问到POD原理

file

NodePort资源配置

资源配置清单

[root@db01 php-apache]# cat node-port.yaml
apiVersion: v1
kind: Service
metadata:
  name: php-nodeport
  namespace: default
spec:
  selector:
    run: php-apache
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
    nodePort: 30000
  type: NodePort

#配置解释:
  ports:
  - name: http
    port: 80             #clusterIP的端口号
    protocol: TCP        #协议类型
    targetPort: 80       #POD暴露的端口
    nodePort: 30000      #Nodeport的端口号,也就是对外用户访问的端口号
  type: NodePort         #service类型

service 服务发现

在k8s中,一个service对应的"后端""由Pod的IlP和容器端口号组成,即一个完整的"IP:Port"访问地址,这在k8s里叫做Endpoint。通过查看Service的详细信息可以看到后端Endpoint的列表。

[ root@node1 ~]# kubectl describe svc my-nginx
..............
Endpoints:     10.2.1.24:80,10.2.1.26:80,10.2.1.27:80+2...

我们也可以使用DNS域名的形式访问Service,如果在同一个命名空间里甚至可以直接使用service名来访问服务。

servicename.namespace.svc.cluster. local
Servicename.namespace
servicename

file

ingress网络

NodePort缺点

1.没有ingress之前,pod对外提供服务只能通过NodeIP:NodePort的形式,但是这种形式有缺点,一个节点上的PORT不能重复利用。比如某个服务占用了80,那么其他服务就不能在用这个端口了。
2.NodePort是4层代理,不能解析7层的http,不能通过域名区分流量
3.为了解决这个问题,我们需要用到资源控制器叫Ingress,作用就是提供一个统一的访问入口。工作在7层
4.虽然我们可以使用nginx/haproxy来实现类似的效果,但是传统部署不能动态的发现我们新创建的资源,必须手动修改配置文件并重启。
5.适用于k8s的ingress控制器主流 的有nginx-ingress和traefik

流程访问图:

file

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: php-apache-ingress
spec:
  rules:
  - host: php.lw.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: php-apache-svc
            port:
              number: 80

安装部署nginx-ingress

我们可以直接使用kubernetes官方自带的nginx-ingress控制清单来部署

wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/baremetal/deploy.yaml -O nginx-ingress.yaml

修改资源配置文件

这里我们主要修改三个地方

1.Deployment类型修改为Demoset类型

2.Pod网络修改为HostPort

ß3.镜像地址修改为阿里云

294 kind: DaemonSet
-------------------
323           image: registry.aliyuncs.com/google_containers/nginx-ingress-controller:v0.48.1
-------------------
377           ports:
378             - name: http
379               containerPort: 80
380               protocol: TCP
381               hostPort: 80
382             - name: https
383               containerPort: 443
384               protocol: TCP
385               hostPort: 443
386             - name: webhook
387               containerPort: 8443
388               protocol: TCP
389               hostPort: 8443

应用资源配置

kubectl apply -f nginx-ingrss.yml

查看创建的资源

[root@node1 nginx-ingress]# kubectl -n ingress-nginx get all  
NAME                                       READY   STATUS      RESTARTS   AGE
pod/ingress-nginx-admission-create-k5rfg   0/1     Completed   0          60m
pod/ingress-nginx-admission-patch-kk2qb    0/1     Completed   0          60m
pod/ingress-nginx-controller-d44bf         1/1     Running     0          114s
pod/ingress-nginx-controller-rkxlm         1/1     Running     0          114s

NAME                                         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)                      AGE
service/ingress-nginx-controller             NodePort    10.1.144.123   <none>        80:31053/TCP,443:30450/TCP   60m
service/ingress-nginx-controller-admission   ClusterIP   10.1.195.159   <none>        443/TCP                      60m

NAME                                      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/ingress-nginx-controller   2         2         2       2            2           kubernetes.io/os=linux   114s

NAME                                       COMPLETIONS   DURATION   AGE
job.batch/ingress-nginx-admission-create   1/1           51s        60m
job.batch/ingress-nginx-admission-patch    1/1           66s        60m

创建测试的服务

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  selector:
    matchLabels:
      app: my-nginx
  template:
    metadata:
      labels:
        app: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  labels:
    app: my-nginx
spec:
  ports:
  - port: 80
    protocol: TCP
    name: http
  selector:
    app: my-nginx

创建Ingress规则

资源配置清单:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-nginx
spec:
  rules:
  - host: nginx.k8s.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: my-nginx
            port:
              number: 80

规则解释:

spec:
  rules:                                            #转发规则
  - host: nginx.k8s.com             #匹配的域名
    http:                                           #基于http协议解析
      paths:                                    #基于路径进行匹配
      - path: /                             #匹配/路径
        pathType: ImplementationSpecific    #路径类型
        backend:                            #匹配后跳转的后端服务
          service:                      #设置后端跳转到Service的配置
            name:my-nginx         #跳转到名为my-nginx的ClusterIP
            port:                           #跳转到的端口
              number: 80            #Service端口号

pathType路径类型支持的类型:

ImplementationSpecific  系统默认,由IngressClass控制器提供
Exact   精确匹配URL路径,区分大小写
Prefix  匹配URL路径的前缀,区分大小写

访问测试

在windows上配置hosts解析:
nginx.k8s.com

部署wordpress

需求: wordpress要运行在k8s中

1.MySQL
mysql-dp.yaml

1.名称空间: blog
2.镜像mysql:5.7
3.环境变量
4.节点选择:disk=ssd上
5.数据持久化:在宿主机的/data/mysql/data

2.mysql-svc
mysql-svc.yaml

1.名称空间:blog

3.wordpress
wordpress-dp.yaml
wordpress-svc.yaml
wordpress-ingress.yaml

1.副本数为2
2.数据库地址:cluster ip
3.数据库名称:wordpress
4.用户:wordpress
5.使用NFS持久化数据,宿主机:/data/wordpress/data

1.mysql-dp.yaml

 - root密码:123
      - 数据库:wordpress
      - 用户:wordpress
           - 参数:字符集
## node打标签
[root@db01 ~]# kubectl label node db03 disk=ssd

## 查看标签
[root@db01 wordpress]# kubectl get node --show-labels

## 创建名称空间清单
[root@db01 wordpress]# cat ns-blog.yaml 
apiVersion: v1
kind: Namespace
metadata:
   name: blog

## 创建mysql-dp清单
[root@db01 wordpress]# cat mysql-dp.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql57-dp
  labels:
    app: mysql57
  namespace: blog
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql57-dp
  template:
    metadata:
      name: mysql57-dp
      labels:
        app: mysql57-dp
    spec:
      volumes:
      - name: mysql-data
        hostPath:
          path: /data/mysql/data

      nodeSelector:
        disk: ssd
      containers:
      - name: mysql57
        image: mysql:5.7
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 3306
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "123"
        - name: MYSQL_DATABASE
          value: "wordpress"
        - name: MYSQL_USER
          value: "wordpress"
        - name: MYSQL_PASSWORD
          value: "wordpress"
        args:
        - --character-set-server=utf8
        - --collation-server=utf8_general_ci
        volumeMounts:
        - name: mysql-data
          mountPath: /var/lib/mysql

# 给mysql创建clusterIP,mysql-svc
[root@db01 ~]# cat mysql-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: mysql57-svc
  namespace: blog
spec:
  selector:
    app: mysql57-dp
  ports:
  - name: mysql
    port: 3306
    protocol: TCP
    targetPort: 3306
  type: ClusterIP

2.wordpress-dp.yaml

[root@db01 wordpress]# cat wordpress-dp.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wp-dp
  labels:
    app: wp
  namespace: blog

spec:
  replicas: 1
  selector:
    matchLabels:
      app: wp-dp
  template:
    metadata:
      name: wp-dp
      labels:
        app: wp-dp
    spec:
      containers:
      - name: wp
        image: wordpress
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
        env:
        - name: WORDPRESS_DB_HOST
          value: mysql57-svc
        - name: WORDPRESS_DB_NAME
          value: "wordpress"
        - name: WORDPRESS_DB_USER
          value: "wordpress"
        - name: WORDPRESS_DB_PASSWORD
          value: "wordpress"

# 给wp创建clusterIP,wp-svc
[root@db01 wordpress]# cat wp-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: wp-svc
  namespace: blog
spec:
  selector: 
    app: wp-dp
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 80
  type: ClusterIP

3.wp-ingress.yaml

## wp-ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: wp-ingress
  namespace: blog
spec:
  rules:
  - host: blog.drz.com
    http:
      paths:
      - path: /
        pathType: ImplementationSpecific
        backend:
          service:
            name: wp-svc
            port:
              number: 80

文件详情

[root@db01 wordpress]# ll
-rw-r--r-- 1 root root  55 Nov 29 10:03 1_ns-blog.yaml
-rw-r--r-- 1 root root 988 Nov 29 10:11 mysql-dp.yaml
-rw-r--r-- 1 root root 213 Nov 29 10:14 mysql-service.yaml
-rw-r--r-- 1 root root 882 Nov 29 10:51 wordpress-dp.yaml
-rw-r--r-- 1 root root 317 Nov 29 10:29 wp-ingrees.yaml
-rw-r--r-- 1 root root 198 Nov 29 10:27 wp-svc.yaml

until nslookup mysql; do echo waiting for mysql service; sleep 2; done;

山林不向四季起誓 荣枯随缘