侧边栏壁纸
  • 累计撰写 51 篇文章
  • 累计创建 23 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

K8s Pod 和 Service 11

zhanjie.me
2020-11-16 / 0 评论 / 0 点赞 / 0 阅读 / 0 字

11.1 LoadBalancer Service 简介

之前介绍了 NodePort Service,我们知道了通过任意一个 NodeIP:NodePort 就可以访问集群服务,假如集群有多个 Node 节点,比如 10 个、20 个,如何分配对于这些节点的访问请求呢?这个时候最好是有一个负载均衡器,外部的客户端请求只需要访问负载均衡器的 IP 地址,然后由外部负载均衡器分配转发流量到后端 Node 的 NodePort 上,具体如下图所示:

image-pxbdhmjz.png

LoadBalancer Service 实例

LoadBalancer 组件一般是独立于 Kubernetes 集群之外的,大部分的时候是一个硬件的负载均衡器,也可以用软件方式实现,比如:HAProxy 或是 Nginx。对于每个服务都需要配置一个与之对应的 LoadBalancer 实例,这样会增加工作量和出错的概率。

使用 nginx 软件手动实现负载均衡

新建 tomcat-deployment.yaml,并向其中写入如下内容:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tomcat
spec:
  selector:
    matchLabels:
      app: tomcat
  replicas: 2
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      containers:
        - name: tomcat
          image: kubeguide/tomcat-app:v1
          ports:
            - containerPort: 8080

执行创建:

$ kubectl create -f tomcat-deployment.yaml
deployment.apps/tomcat created

新建 tomcat-svc.yaml 文件,并向其中写入如下内容:

apiVersion: v1
kind: Service
metadata:
  name: tomcat-svc
spec:
  type: NodePort
  ports:
  - port: 80 # 设置 ClusterIP 对应的端口为 80
    targetPort: 8080 # Pod 开放的端口为 8080
    nodePort: 30001 # 设置在 Node 上开放的端口为 30001
  selector:
    app: tomcat

执行创建:

$ kubectl create -f tomcat-svc.yaml
service/tomcat-svc created
$ kubectl get svc
NAME         TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
tomcat-svc   NodePort   10.96.112.206   <none>        80:30001/TCP   21s
$ curl 192.168.0.31:30001
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>Apache Tomcat/8.0.35</title>
        <link href="favicon.ico" rel="icon" type="image/x-icon" />
        <link href="favicon.ico" rel="shortcut icon" type="image/x-icon" />
        <link href="tomcat.css" rel="stylesheet" type="text/css" />
    </head>
...

接下来安装并配置 nginx 作为负载均衡器进行模拟。

# 准备环境中已经安装 nginx,查看版本信息:
$ nginx -v
nginx version: nginx/1.19.0

# 向nginx配置文件中添加内容:
$ cat >/etc/nginx/nginx.conf<<EOF
user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    # 添加 k8s 集群所有可用的 nodeIP:nodePort
    upstream k8snode {
        server 192.168.0.31:30001;
        server 192.168.0.32:30001;
        server 192.168.0.33:30001;
    }

    # 设置虚拟主机
    server {
        # 监听 80 端口
        listen 80;
        location / {
            # 反向代理指令,将所有的请求都发送给 k8snode 机器组中的机器
            proxy_pass http://k8snode;
        }
    }
}
EOF

# 检查配置文件是否正确并使之生效
$ nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
$ nginx -s reload

直接通过浏览器访问地址 http://localhost:80:

image-cshbfqno.png


11.2 ExternalName Service 简介

ExternalName Service 是一种特殊类型的 Service,主要用于访问位于集群外部的服务。它没有选择器 Selector,也没有定义任何端口 Port 或是 Endpoints。它的作用是返回集群外服务的域名。

通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段对应的内容(比如:api.github.com)。使用这种类型的服务不会创建任何类型的代理。

新建 externalname-svc.yaml 文件,并向其中写入如下内容:

apiVersion: v1
kind: Service
metadata:
  name: en-svc
  namespace: default
spec:
  type: ExternalName # type 类型需要选择 ExternalName
  externalName: api.github.com # externalName 中填写外部服务对应的域名

执行创建:

$ kubectl create -f externalname-svc.yaml
service/en-svc created
# 查看服务,可以看到 en-svc 服务没有集群 IP,只有一个 EXTERNAL-IP,为:api.github.com
$ kubectl get svc en-svc
NAME     TYPE           CLUSTER-IP   EXTERNAL-IP      PORT(S)   AGE
en-svc   ExternalName   <none>       api.github.com   <none>    23s

先查看api.github.com对应的IP:

$ ping api.github.com
PING api.github.com (13.250.168.23) 56(84) bytes of data.

集群内部通过 DNS 查找 en-svc 服务对应的 IP 地址,这里单独运行一个使用 utils 镜像创建的 pod 执行命令(镜像中已经安装了 dnsutils):

$ kubectl run --generator=run-pod/v1 --rm utils -it --image tutum/dnsutils bash
If you don't see a command prompt, try pressing enter.
root@utils:/# nslookup en-svc
Server:     10.96.0.10
Address:    10.96.0.10#53

en-svc.user-test.svc.cluster.local  canonical name = api.github.com.
Name:   api.github.com
Address: 13.250.168.23

使用 ExternalName Service 可以使集群连接外部服务,在 spec.externalName 字段中定义外部服务的域名即可使用。

0

评论区