Kubernetes-提供服务的方式

目录

一. 直接访问Pod的IP地址

二. 通过Service访问

1. ClusterIP类型

2. NodePort类型

3. Ingress类型


一. 直接访问Pod的IP地址

Kubernetes中的最小单位是Pod,所有的应用也是运行在Pod中的

每个Pod都会被分配一个唯一的IP地址

创建一个Pod

cat nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    k8s-app: nginx-pod
  name: nginx-pod
spec:
  containers:
  - image: 172.16.2.100:30050/library/nginx:latest
    imagePullPolicy: Always
    name: nginx
    ports:
    - containerPort: 80
      name: nginx
      protocol: TCP

kubectl create -f nginx-pod.yaml

查看Pod的详细信息

[root@k8s-node1 example]# kubectl get pod -owide
NAME        READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
nginx-pod   1/1     Running   0          26s   172.17.76.14   k8s-node2   <none>           <none>

可以看到该Pod分配一个IP地址,在另一个容器中可以正常访问该地址

[root@k8s-node1 ~]# kubectl --namespace=admin exec -it lnbkobka-session-jzqnd bash
[root@lnbkobka-session-jzqnd ~]# curl 172.17.76.14
<p>Hello Nginx</p>

(这种方式基本上不使用)

Pod的IP地址是一个随机分配的内网地址,只能在容器内部访问

并且正常场景下为了保证服务的可用性会通过deployment(statefulset)等来创建Pod,保证Pod的数量,而不会单独创建Pod

二. 通过Service访问

应为Pod是最小的单元如果在Pod中容器出现异常终止了是不会重启,在实际使用场景下基本不会直接使用Pod而是使用Deployment部署自己的应用

Deployment是对一组Pod集群的管理,可以保证环境中一直存在指定数量的Pod(比如当pod所在的node节点关机,则deployment会在其他节点重新启动Pod)

创建deployment

[root@k8s-node1 example]# cat nginx-dp.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    k8s-app: nginx-dp
  name: nginx-dp
spec:
  replicas: 2  // 表示当前deployment有2个副本
  selector:
    matchLabels:
      k8s-app: nginx-dp
  template:
    metadata:
      labels:
        k8s-app: nginx-dp
    spec:
      containers:
      - image: nginx:latest
        name: nginx
        ports:
        - containerPort: 80
          name: nginx
          protocol: TCP

查看deployment

[root@k8s-node1 example]# kubectl get deployments
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
nginx-dp   2/2     2            2           8s

// 查看Pod信息
[root@k8s-node1 example]# kubectl get pod -owide
NAME                        READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
nginx-dp-78c4f884c8-qwh8m   1/1     Running   0          20s   172.17.86.12   k8s-node1   <none>           <none>
nginx-dp-78c4f884c8-sbvzz   1/1     Running   0          20s   172.17.76.14   k8s-node2   <none>           <none>

可以看到该Deployment下有2个Pod分别运行在两个Node节点上

手动删除一个Pod

[root@k8s-node1 example]# kubectl delete pod nginx-dp-78c4f884c8-qwh8m
pod "nginx-dp-78c4f884c8-qwh8m" deleted

[root@k8s-node1 example]# kubectl get pod -owide
NAME                        READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
nginx-dp-78c4f884c8-n4czv   1/1     Running   0          14s   172.17.86.12   k8s-node1   <none>           <none>
nginx-dp-78c4f884c8-sbvzz   1/1     Running   0          96s   172.17.76.14   k8s-node2   <none>           <none>

可以看到删除Pod后又自动创建了一个Pod(对于Deployment管理还可以进行Pod扩容,升级等操作)

从上面可以看到deployment只负责Pod的管理,本身并没有IP地址,但是deployment下会存在多个Pod,每个Pod的地址都不一样,如果存在扩容等操作后,扩容的Pod的地址也是随机生成的,不可能记住所有的Pod的地址

Kubernete Service 是一个定义了一组Pod的策略的抽象,我们也有时候叫做宏观服务。这些被服务标记的Pod都是(一般)通过label Selector决定的,举个例子,我们假设有一个tomcat的应用,通过deployment部署,有三个副本。对于需要调用tomcat服务的应用(比如nginx)来说,不需要关注这个tomcat有几个pod,而是通过一个固定的地址访问,当tomcat的pod发生变化时,nginx不需要关注,使用固定的地址仍然可用继续访问

Service根据使用方式有几种类型

1. ClusterIP类型

创建一个service

[root@k8s-node1 example]# cat nginx-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  ports:
  - name: nginx
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    k8s-app: nginx-dp
  type: ClusterIP


[root@k8s-node1 example]# kubectl create -f nginx-svc.yaml 
service/nginx-svc created

查看Service信息,可用看到service分配了一个cluster-ip

[root@k8s-node1 example]# kubectl get service nginx-svc 
NAME        TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
nginx-svc   ClusterIP   10.10.207.26   <none>        80/TCP    10s

在其他容器中访问clusterIP

[root@k8s-node1 ~]# kubectl --namespace=admin exec -it lnbkobka-session-jzqnd bash
[root@lnbkobka-session-jzqnd ~]# curl 10.10.207.26
<p>Hello Nginx</p>

可用看到通过clusterip访问也可以正常访问,但是clusterip仍然是内网IP,只能通过容器内部访问(也可以直接通过service-name访问,k8s内部会自动进行域名解析)

这种方式一般适用于不需要对外的服务,比如mysql,redis等

 

2. NodePort类型

nodeport类型的service和clusterip相比多了一个nodeport属性,会在所有的node节点开放nodeport端口,通过访问物理机的端口达到访问容器的效果

创建nodeport类型的service(service yaml中可以手动定义nodeport,范围在30000-32767,不过这种方式容易冲突,不定义的话kubernetes会自动生成一个)

[root@k8s-node1 example]# cat nginx-svc-nodeport.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc-nodeport
spec:
  ports:
  - name: nginx
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    k8s-app: nginx-dp
  type: NodePort

[root@k8s-node1 example]# kubectl create -f nginx-svc-nodeport.yaml 
service/nginx-svc-nodeport created

[root@k8s-node1 example]# kubectl get service nginx-svc-nodeport 
NAME                 TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
nginx-svc-nodeport   NodePort   10.10.133.76   <none>        80:32117/TCP   14s

查看service可以看到多了一个32117的端口,在物理机上查看该端口的状态,可以看到在监听中

[root@k8s-node1 example]# lsof -i:32117
COMMAND     PID USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME
kube-prox 27278 root   33u  IPv6 120151742      0t0  TCP *:32117 (LISTEN)

在物理机上访问物理机IP:NodePort,可以看到在物理机上通过nodeport已经可以访问到容器的服务

[root@k8s-node1 example]# curl 127.0.0.1:32117
<p>Hello Nginx</p>

由于nodeport会在每个节点上进行监听,所以任意一个nodeip+nodeport都可以访问

在实际环境中,我们一般会使用keepalived对node节点做vip,通过vip访问,或者单独搭建一个nginx,通过nginx进行负载均衡

3. Ingress类型

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值