Service 对外暴露与应用

Service 对外暴露与应用

Service

Kubernetes Service定义了这样一种抽象:逻辑上的一组 Pod,一种能够访问它们的策略 —— 一般被称为微服务。这一组 Pod 可以被 Service 访问到,一般是经过 selector实现的。

举例:考虑一个图片处理 backend,它运行了3个副本。这些副本是可互换的 —— frontend 不需要关心它们调用了哪一个 backend 副本。 然而组成这一组 backend 程序的 Pod 实际上可能会发生变化,frontend 客户端不必知道,并且也不需要跟踪这一组 backend 的状态。Service 定义的抽象可以解耦这种关联。

Service能够提供负载均衡的能力,可是使用上存在以下限制:

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

如web访问的service服务示例图:

在这里插入图片描述

VIP和Service代理

在 Kubernetes 集群中,每一个 Node 运行一个 kube-proxy 进程。kube-proxy 负责为 Service 实现了一种 VIP(虚拟 IP)的形式,而不是 ExternalName 的形式。后端

从Kubernetes v1.0开始,已经可使用 userspace代理模式。Kubernetes v1.1添加了 iptables 代理模式,在 Kubernetes v1.2 中kube-proxy 的 iptables 模式成为默认设置。Kubernetes v1.8添加了 ipvs 代理模式。

为何不使用 DNS 轮询?

缘由以下:

  • DNS 实现的历史由来已久,它不遵照记录 TTL,而且在名称查找到结果后会对其进行缓存。

  • 有些应用程序仅执行一次 DNS 查找,并没有限期地缓存结果。

  • 即便应用和库进行了适当的从新解析,DNS 记录上的 TTL 值低或为零也可能会给 DNS 带来高负载,从而使管理变得困难。

由于有缓存,所以不合适。

userspace代理模式

这种模式,kube-proxy 会监视 Kubernetes master 对 Service 对象和 Endpoints 对象的添加和移除。 对每一个 Service,它会在本地 Node 上打开一个端口(随机选择)。 任何链接到“代理端口”的请求,都会被代理到 Service 的backend Pods 中的某个上面(如 Endpoints 所报告的同样)。 使用哪一个 backend Pod,是 kube-proxy 基于 SessionAffinity 来肯定的。网络

最后,它配置 iptables 规则,捕获到达该 Service 的 clusterIP(是虚拟 IP)和 Port 的请求,并重定向到代理端口,代理端口再代理请求到 backend Pod。

默认状况下,userspace模式下的kube-proxy经过循环算法选择后端。

默认的策略是,经过 round-robin 算法来选择 backend Pod。

在这里插入图片描述

iptables 代理模式

这种模式,kube-proxy 会监视 Kubernetes 控制节点对 Service 对象和 Endpoints 对象的添加和移除。 对每一个 Service,它会配置 iptables 规则,从而捕获到达该 Service 的 clusterIP 和端口的请求,进而将请求重定向到 Service 的一组 backend 中的某个上面。对于每一个 Endpoints 对象,它也会配置 iptables 规则,这个规则会选择一个 backend 组合。

默认的策略是,kube-proxy 在 iptables 模式下随机选择一个 backend。

使用 iptables 处理流量具备较低的系统开销,由于流量由 Linux netfilter 处理,而无需在用户空间和内核空间之间切换。 这种方法也可能更可靠。

若是 kube-proxy 在 iptables模式下运行,而且所选的第一个 Pod 没有响应,则链接失败。 这与userspace模式不一样:在这种状况下,kube-proxy 将检测到与第一个 Pod 的链接已失败,并会自动使用其余后端 Pod 重试。

咱们可使用 Pod readiness 探测器 验证后端 Pod 是否能够正常工做,以便 iptables 模式下的 kube-proxy 仅看到测试正常的后端。这样作意味着能够避免将流量经过 kube-proxy 发送到已知已失败的Pod。
在这里插入图片描述

IPVS 代理模式

在 ipvs 模式下,kube-proxy监视Kubernetes服务(Service)和端点(Endpoints),调用 netlink 接口相应地建立 IPVS 规则, 并按期将 IPVS 规则与 Kubernetes服务(Service)和端点(Endpoints)同步。该控制循环可确保 IPVS 状态与所需状态匹配。访问服务(Service)时,IPVS 将流量定向到后端Pod之一。

IPVS代理模式基于相似于 iptables 模式的 netfilter 挂钩函数,可是使用哈希表做为基础数据结构,而且在内核空间中工做。 这意味着,与 iptables 模式下的 kube-proxy 相比,IPVS 模式下的 kube-proxy 重定向通讯的延迟要短,而且在同步代理规则时具备更好的性能。与其余代理模式相比,IPVS 模式还支持更高的网络流量吞吐量。

IPVS提供了更多选项来平衡后端Pod的流量。分别是:

  • rr: round-robin
  • lc: least connection (smallest number of open connections)
  • dh: destination hashing
  • sh: source hashing
  • sed: shortest expected delay
  • nq: never queue

注意:要在 IPVS 模式下运行 kube-proxy,必须在启动 kube-proxy 以前使 IPVS Linux 在节点上可用。 当 kube-proxy 以 IPVS 代理模式启动时,它将验证 IPVS 内核模块是否可用。 若是未检测到 IPVS 内核模块,则 kube-proxy 将退回到以 iptables 代理模式运行。

在这里插入图片描述

Service服务类型

Kubernetes 中Service有如下4中类型:

  • ClusterIP:默认类型,自动分配一个仅Cluster内部能够访问的虚拟IP

  • NodePort:经过每一个 Node 上的 IP 和静态端口(NodePort)暴露服务。以ClusterIP为基础,NodePort 服务会路由到 ClusterIP 服务。经过请求 <NodeIP>:<NodePort>,能够从集群的外部访问一个集群内部的 NodePort 服务。

  • LoadBalancer:使用云提供商的负载均衡器,能够向外部暴露服务。外部的负载均衡器能够路由到 NodePort 服务和 ClusterIP 服务。

  • ExternalName:经过返回 CNAME 和它的值,能够将服务映射到 externalName 字段的内容(例如,foo.bar.example.com)。没有任何类型代理被建立。
    须要注意的是:Service 可以将一个接收 port 映射到任意的 targetPort。默认状况下,targetPort 将被设置为与 port 字段相同的值。

Service域名格式:$(service name).$(namespace).svc.cluster.local,其中 cluster.local 为指定的集群的域名

主机名IPOS
master192.168.58.110Centos
node01192.168.58.111Centos
node02192.168.58.125Centos
ClusterIP:

默认类型,自动分配一个仅Cluster内部能够访问的虚拟IP

# 编写network.yaml资源清单文件

[root@master ~]# vi network.yaml 
apiVersion: apps/v1 
kind: Deployment 
metadata: 
  name: myapp-deploy 
  namespace: default 
spec: 
  replicas: 2 
  selector: 
    matchLabels: 
      app: myapp 
      release: v1
  template:
    metadata: 
      labels: 
        app: myapp 
        release: v1 
    spec: 
      containers: 
      - name: myapp
        image: xm17671855780/httpd:v1.0
        imagePullPolicy: IfNotPresent
---
apiVersion: v1 
kind: Service 
metadata: 
  name: myapp-nodeport
  namespace: default
spec: 
  type: ClusterIP
  selector: 
    app: myapp
    release: v1
  ports: 
  - name: httpd
    port: 80
    targetPort: 80

# 应用资源清单文件,创建资源
[root@master ~]# kubectl apply -f network.yaml   
deployment.apps/myapp-deploy created
service/myapp-nodeport created

# 查看pod,service运行情况
[root@master ~]# kubectl get pods,svc
NAME                                READY   STATUS    RESTARTS   AGE
pod/myapp-deploy-667bd747b6-6mkmq   1/1     Running   0          6m30s
pod/myapp-deploy-667bd747b6-wp65f   1/1     Running   0          6m30s

NAME                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/kubernetes       ClusterIP   10.96.0.1       <none>        443/TCP   5d22h
service/myapp-nodeport   ClusterIP   10.98.209.123   <none>        80/TCP    6m30s

# 查看iptables,规则

[root@master ~]# iptables -t nat -nvL | grep 'myapp-nodeport'
    0     0 KUBE-MARK-MASQ  all  --  *      *       10.244.2.173         0.0.0.0/0            /* default/myapp-nodeport:httpd */
    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/myapp-nodeport:httpd */ tcp to:10.244.2.173:80
    0     0 KUBE-MARK-MASQ  all  --  *      *       10.244.1.126         0.0.0.0/0            /* default/myapp-nodeport:httpd */
    2   120 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/myapp-nodeport:httpd */ tcp to:10.244.1.126:80
    2   120 KUBE-SVC-UJB7KAYNZVW7NK6H  tcp  --  *      *       0.0.0.0/0            10.98.209.123        /* default/myapp-nodeport:httpd cluster IP */ tcp dpt:80
    2   120 KUBE-MARK-MASQ  tcp  --  *      *      !10.244.0.0/16        10.98.209.123        /* default/myapp-nodeport:httpd cluster IP */ tcp dpt:80
    2   120 KUBE-SEP-WXLK2WHO6A3V7JDH  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/myapp-nodeport:httpd */ statistic mode random probability 0.50000000000
    0     0 KUBE-SEP-BXPFXJRGQ62K7TWT  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/myapp-nodeport:httpd */


# 访问测试
[root@master ~]# curl 10.98.209.123
This is V1!

NodePort

nodePort的原理在于在node上开了一个端口,将向该端口的流量导入到kube-proxy,然后由 kube-proxy进一步到给对应的pod。若是将 type 字段设置为 NodePort,则 Kubernetes 控制层面将在 --service-node-port-range 标志指定的范围内分配端口(默认值:30000-32767)。

# 修改资源定义文件

[root@master ~]# vi network.yaml 
apiVersion: apps/v1 
kind: Deployment 
metadata: 
  name: myapp-deploy 
  namespace: default 
spec: 
  replicas: 2 
  selector: 
    matchLabels: 
      app: myapp 
      release: v1
  template:
    metadata: 
      labels: 
        app: myapp 
        release: v1 
    spec: 
      containers: 
      - name: myapp
        image: xm17671855780/httpd:v1.0
        imagePullPolicy: IfNotPresent
---
apiVersion: v1 
kind: Service 
metadata: 
  name: myapp-nodeport
  namespace: default
spec: 
  type: NodePort  // 指定NodePort类型
  selector: 
    app: myapp
    release: v1
  ports: 
  - name: httpd
    port: 80
    targetPort: 80
    nodePort: 30002   //指定对外端口

# 应用修改后的资源定义文件,重启pods
[root@master ~]# kubectl apply -f network.yaml 
deployment.apps/myapp-deploy unchanged
service/myapp-nodeport configured

# 查看pods,service状态
[root@master ~]# kubectl get pod,svc
NAME                                READY   STATUS    RESTARTS   AGE
pod/myapp-deploy-667bd747b6-6mkmq   1/1     Running   0          30m
pod/myapp-deploy-667bd747b6-wp65f   1/1     Running   0          30m

NAME                     TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
service/kubernetes       ClusterIP   10.96.0.1       <none>        443/TCP        5d23h
service/myapp-nodeport   NodePort    10.98.209.123   <none>        80:30002/TCP   30m

# 查看iptables 规则
[root@master ~]# iptables -t nat -nvL | grep 'myapp-nodeport'
    1    60 KUBE-SVC-UJB7KAYNZVW7NK6H  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/myapp-nodeport:httpd */ tcp dpt:30002
    0     0 KUBE-MARK-MASQ  all  --  *      *       10.244.2.173         0.0.0.0/0            /* default/myapp-nodeport:httpd */
    0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/myapp-nodeport:httpd */ tcp to:10.244.2.173:80
    0     0 KUBE-MARK-MASQ  all  --  *      *       10.244.1.126         0.0.0.0/0            /* default/myapp-nodeport:httpd */
    1    60 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/myapp-nodeport:httpd */ tcp to:10.244.1.126:80
    0     0 KUBE-SVC-UJB7KAYNZVW7NK6H  tcp  --  *      *       0.0.0.0/0            10.98.209.123        /* default/myapp-nodeport:httpd cluster IP */ tcp dpt:80
    0     0 KUBE-MARK-MASQ  tcp  --  *      *      !10.244.0.0/16        10.98.209.123        /* default/myapp-nodeport:httpd cluster IP */ tcp dpt:80
    1    60 KUBE-MARK-MASQ  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/myapp-nodeport:httpd */ tcp dpt:30002
    1    60 KUBE-SEP-WXLK2WHO6A3V7JDH  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/myapp-nodeport:httpd */ statistic mode random probability 0.50000000000
    0     0 KUBE-SEP-BXPFXJRGQ62K7TWT  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/myapp-nodeport:httpd */

# 访问测试
[root@master ~]# curl 192.168.58.110:30002
This is V1!

LoadBalancer

LoadBalancer 可以将来自客户端的请求分发到不同的服务器(阿里云、腾讯云、AWS),通过将一系列的请求转发到不同的服务器可以提高服务器的性能,并可以自动地寻找最优的服务器转发请求,这样不仅提高了系统性能,同时达到了负载均衡的目的,满足了用户需求,因此 LoadBalancer 在应用场景中一般处于 web 服务器的前端,用来均衡发到 web 服务器的请求量,均衡负载,提高系统性能。LoadBalancer 可以连接多个 web server,从而将多个 web server 组成一个集群(cluster),集群中负载的分配通过 loadBalancer 进行控制和管理。当然为了更好地进行负载均衡,LoadBalancer 也可以构建为一个集群,使用 LoadBalancer 构建的 web server cluster。
在这里插入图片描述

LoadBalancer示例,需要使用到相关云厂商服务支持,这里就不表述了。

ExternalName类型示例

这种类型的Service经过返回CNAME和它的值,能够将服务映射到externalName字段的内容(例如:my.k8s.example.com;能够实现跨namespace名称空间访问)。ExternalName Service是Service的特例,它没有selector,也没有定义任何的端口和Endpoint。相反的,对于运行在集群外部的服务,它经过返回该外部服务的别名这种方式提供服务。

# 修改netwoek.yanl资源定义文件

[root@master ~]# vi network.yaml 
apiVersion: apps/v1 
kind: Deployment 
metadata: 
  name: myapp-deploy 
  namespace: default 
spec: 
  replicas: 2 
  selector: 
    matchLabels: 
      app: myapp 
      release: v1
  template:
    metadata: 
      labels: 
        app: myapp 
        release: v1 
    spec: 
      containers: 
      - name: httpd
        image: xm17671855780/file_httpd:v0.2  //此处将镜像,更换为基于contos编译的httpd镜像
        imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata: 
  name: myapp-externalname
  namespace: default
spec: 
  type: ExternalName  //指定类型
  externalName: my.k8s.example.com

# 使用修改过后的资源定义文件,重启pods
[root@master ~]# kubectl apply -f network.yaml 
deployment.apps/myapp-deploy configured
service/myapp-externalname unchanged


# 查看pod,service状态
[root@master ~]# kubectl get pod,svc
NAME                               READY   STATUS    RESTARTS   AGE
pod/myapp-deploy-6768948cc-4tp9j   1/1     Running   0          9m8s
pod/myapp-deploy-6768948cc-x5ncr   1/1     Running   0          9m6s

NAME                         TYPE           CLUSTER-IP   EXTERNAL-IP          PORT(S)   AGE
service/kubernetes           ClusterIP      10.96.0.1    <none>               443/TCP   6d
service/myapp-externalname   ExternalName   <none>       my.k8s.example.com   <none>    32m

# 此处Type,改为 ExternalName模式了

宿主机dig命令安装

# 进入pods中的某个容器中

[root@master ~]# kubectl exec -it myapp-deploy-6768948cc-4tp9j /bin/sh  
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
sh-4.4# /bin/bash

[root@myapp-deploy-6768948cc-4tp9j src]# ls
apr-1.7.0  apr-util-1.6.1  debug  httpd-2.4.48  kernels
[root@myapp-deploy-6768948cc-4tp9j src]# cd
[root@myapp-deploy-6768948cc-4tp9j ~]# yum install -y bind-utils    // 安装包组

coredns记录信息如下

# 经过 nslookup 访问

[root@myapp-deploy-6768948cc-4tp9j ~]# nslookup myapp-externalname.default.svc.cluster.local
Server:         10.96.0.10
Address:        10.96.0.10#53

myapp-externalname.default.svc.cluster.local    canonical name = my.k8s.example.com.
** server can't find my.k8s.example.com: NXDOMAIN

# 其中  10.96.0.10 为 coredns IP
# myapp-externalname.default.svc.cluster.local 为Service域名。格式为:$(service name).$(namespace).svc.cluster.local,其中 cluster.local 指定的集群的域名

# 经过 dig 访问
[root@myapp-deploy-6768948cc-4tp9j ~]# dig -t A myapp-externalname.default.svc.cluster.local.@10.96.0.10

; <<>> DiG 9.11.26-RedHat-9.11.26-6.el8 <<>> -t A myapp-externalname.default.svc.cluster.local.@10.96.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 24780
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 1293df4bb1831323 (echoed)
;; QUESTION SECTION:
;myapp-externalname.default.svc.cluster.local.\@10.96.0.10. IN A

;; Query time: 1012 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: Sat Dec 25 04:08:21 UTC 2021
;; MSG SIZE  rcvd: 97


ExternalIP示例

若是外部的 IP 路由到集群中一个或多个 Node 上,Kubernetes Service 会被暴露给这些 externalIPs。经过外部 IP(做为目的 IP 地址)进入到集群,打到 Service 端口上的流量,将会被路由到 Service 的 Endpoint 上。

externalIPs 不会被 Kubernetes 管理,它属于集群管理员的职责范畴。

根据 Service 的规定,externalIPs 能够同任意的 ServiceType 来一块儿指定。在下面的例子中,my-service 能够在【模拟外网IP】“10.0.0.240”(externalIP:port) 上被客户端访问。

# 编写 network.yaml资源定义文件

[root@master ~]# vi network.yaml 
apiVersion: apps/v1 
kind: Deployment 
metadata: 
  name: myapp-deploy 
  namespace: default 
spec: 
  replicas: 2 
  selector: 
    matchLabels: 
      app: myapp 
      release: v1
  template:
    metadata: 
      labels: 
        app: myapp 
        release: v1 
    spec: 
      containers: 
      - name: httpd
        image: xm17671855780/file_httpd:v0.2
        imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata: 
  name: myapp-externalip
  namespace: default
spec: 
  selector: 
    app: myapp
    release: v1
  ports: 
  - name: httpd
    port: 80
    targetPort: 80
  externalIPs: 
    - 10.0.0.240


# 应用资源定义文件,部署资源
[root@master ~]# kubectl apply -f network.yaml 
deployment.apps/myapp-deploy unchanged
service/myapp-externalip created

# 查看pods,service状态
[root@master ~]# kubectl get svc -o wide
NAME                 TYPE           CLUSTER-IP      EXTERNAL-IP          PORT(S)   AGE     SELECTOR
kubernetes           ClusterIP      10.96.0.1       <none>               443/TCP   6d3h    <none>
myapp-externalip     ClusterIP      10.99.109.176   10.0.0.240           80/TCP    13s     app=myapp,release=v1
myapp-externalname   ExternalName   <none>          my.k8s.example.com   <none>    3h45m   <none>

# curl访问,经过ClusterIP
[root@master ~]# curl 10.99.109.176
<html><body><h1>It works!</h1></body></html>


# curl访问,经过ExternalIP
[root@master ~]# curl 10.0.0.240
<html><body><h1>It works!</h1></body></html>

综合案例

创建一个deployment副本数为3,然后滚动更新镜像版本,并记录这个更新记录,最后再回滚到上一个版本

[root@master ~]# vi test.yaml 
apiVersion: apps/v1
kind: Deployment
metadata: 
  name: web
spec: 
  replicas: 3  //副本数量
  revisionHistoryLimit: 5  //版本留存数量
  strategy: 
    rollingUpdate: 
      maxSurge: 50%
      maxUnavailable: 50%
    type: RollingUpdate
  selector: 
    matchLabels: 
      app: httpd
  template: 
    metadata: 
      labels: 
        app: httpd
    spec: 
      containers: 
      - name: httpd
        image: xm17671855780/httpd:v1.0
        imagePullPolicy: IfNotPresent
 
[root@master ~]# kubectl apply -f test.yaml 
deployment.apps/web created

[root@master ~]# kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
web-66dc445c66-99pn4   1/1     Running   0          6s
web-66dc445c66-rm8nk   1/1     Running   0          6s
web-66dc445c66-xzbwm   1/1     Running   0          6s

[root@master ~]# kubectl rollout history deployment/web  //查看历史,历史版本被保留
deployment.apps/web 
REVISION  CHANGE-CAUSE
1         <none>


[root@master ~]# vi test.yaml 
......
containers: 
      - name: httpd
        image: xm17671855780/httpd:v2.0  //更改镜像
        imagePullPolicy: IfNotPresent
 ......
[root@master ~]# kubectl apply -f test.yaml   //应用部署,更新到版本2
deployment.apps/web configured 

[root@master ~]# kubectl get pods
NAME                   READY   STATUS        RESTARTS   AGE
web-66dc445c66-99pn4   1/1     Terminating   0          3m9s
web-66dc445c66-rm8nk   1/1     Terminating   0          3m9s
web-66dc445c66-xzbwm   1/1     Terminating   0          3m9s
web-689dbd69c9-5szrd   1/1     Running       0          9s
web-689dbd69c9-pmgjc   1/1     Running       0          10s
web-689dbd69c9-zgn99   1/1     Running       0          10s

[root@master ~]# kubectl rollout history deployment/web  //看到有两个版本
deployment.apps/web 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

# 回滚至版本1
[root@master ~]# kubectl rollout undo deployment/web --to-revision=1
deployment.apps/web rolled back

# 当前处于版本1,但是只使用了两个镜像,所以被覆盖,替换了。
[root@master ~]# kubectl rollout history deployment/web
deployment.apps/web 
REVISION  CHANGE-CAUSE
2         <none>
3         <none>


给一个应用扩容副本为4

[root@master ~]# kubectl scale --replicas 4 deployment/web
deployment.apps/web scaled

[root@master ~]# kubectl get pods
NAME                   READY   STATUS    RESTARTS   AGE
web-66dc445c66-lkxb5   1/1     Running   0          4m30s
web-66dc445c66-qgsjn   1/1     Running   0          4m30s
web-66dc445c66-sj7bw   1/1     Running   0          4m29s
web-66dc445c66-tfv6n   1/1     Running   0          2s

创建一个pod,其中运行着nginx、redis、memcached3个容器

# 编写hostwork.yaml资源定义文件

[root@master ~]# vi hostwork.yaml 
apiVersion: v1
kind: Pod   //定义pod类型
metadata:
  name: test  //定义pod名
  labels:
    app: who-are-you   //打标签
spec:
  containers:             //定义镜像
  - image: nginx
    name: nginx
  - image: redis
    name: redis
  - image: memcached
    name: memcached

# 应用资源定义文件,创建资源
[root@master ~]# kubectl apply -f hostwork.yaml 
pod/test created

# 查看pod状态
[root@master ~]# kubectl get pods
NAME   READY   STATUS              RESTARTS   AGE
test   0/3     ContainerCreating   0          8s
[root@master ~]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
test   3/3     Running   0          2m32s

# 查看pod详细信息
[root@master ~]# kubectl describe pods test
Name:         test
Namespace:    default
Priority:     0
Node:         node01/192.168.58.111
Start Time:   Sun, 26 Dec 2021 09:25:26 +0800
Labels:       app=who-are-you
Annotations:  <none>
Status:       Running
IP:           10.244.1.144
IPs:
  IP:  10.244.1.144
Containers:
  nginx:
    Container ID:   docker://f6c9ce6e38827bed062054821858762debc661da25f84bcab5dc9866534dff46
    Image:          nginx
    Image ID:       docker-pullable://nginx@sha256:18d4060f8c221c35cde8153e9cb05b225ea8e05ed750514e9271bbcc36c61bae
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Sun, 26 Dec 2021 09:25:44 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-7wm92 (ro)
  redis:
    Container ID:   docker://1d5f6aa03233a1aefd2dd2eda2d86cbf8618395764380aeaf56a34accf2be534
    Image:          redis
    Image ID:       docker-pullable://redis@sha256:db485f2e245b5b3329fdc7eff4eb00f913e09d8feb9ca720788059fdc2ed8339
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Sun, 26 Dec 2021 09:26:00 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-7wm92 (ro)
  memcached:
    Container ID:   docker://036568cf2275901d2808f666fe6eb6a507df45c47b675a59b925d011f1dcf288
    Image:          memcached
    Image ID:       docker-pullable://memcached@sha256:a7895a53299404c294de9d8b0627c2585e924c389783f77c30df0cf6a316750c
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Sun, 26 Dec 2021 09:26:16 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-7wm92 (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  kube-api-access-7wm92:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  2m40s  default-scheduler  Successfully assigned default/test to node01
  Normal  Pulling    2m39s  kubelet            Pulling image "nginx"
  Normal  Pulled     2m23s  kubelet            Successfully pulled image "nginx" in 15.889668022s
  Normal  Created    2m23s  kubelet            Created container nginx
  Normal  Started    2m22s  kubelet            Started container nginx
  Normal  Pulling    2m22s  kubelet            Pulling image "redis"
  Normal  Created    2m7s   kubelet            Created container redis
  Normal  Pulled     2m7s   kubelet            Successfully pulled image "redis" in 15.557081559s
  Normal  Started    2m6s   kubelet            Started container redis
  Normal  Pulling    2m6s   kubelet            Pulling image "memcached"
  Normal  Pulled     111s   kubelet            Successfully pulled image "memcached" in 15.555695122s
  Normal  Created    111s   kubelet            Created container memcached
  Normal  Started    110s   kubelet            Started container memcached


给一个pod创建service,并可以通过ClusterIP/NodePort

#  编写hostwork.yaml资源定义文件
[root@master ~]# vi hostwork.yaml 
apiVersion: apps/v1 
kind: Deployment 
metadata: 
  name: myapp-deploy 
  namespace: default 
spec: 
  replicas: 1
  selector: 
    matchLabels: 
      app: myapp 
      release: v1
  template:
    metadata: 
      labels: 
        app: myapp 
        release: v1 
    spec: 
      containers: 
      - name: myapp
        image: xm17671855780/file_httpd:v0.2
        imagePullPolicy: IfNotPresent
---
apiVersion: v1 
kind: Service 
metadata: 
  name: myapp-nodeport
  namespace: default
spec: 
  type: NodePort  
  selector: 
    app: myapp
    release: v1
  ports: 
  - name: httpd
    port: 80
    targetPort: 80
    nodePort: 31960   

# 指定资源定义文件,部署资源
[root@master ~]# kubectl apply -f hostwork.yaml 
deployment.apps/myapp-deploy created
service/myapp-nodeport created

# 查看pods,service状态
[root@master ~]# kubectl get pod,svc
NAME                               READY   STATUS    RESTARTS   AGE
pod/myapp-deploy-79b6dccb8-h7mlh   1/1     Running   0          12s

NAME                         TYPE           CLUSTER-IP      EXTERNAL-IP          PORT(S)        AGE
service/kubernetes           ClusterIP      10.96.0.1       <none>               443/TCP        6d4h
service/myapp-externalname   ExternalName   <none>          my.k8s.example.com   <none>         4h26m
service/myapp-nodeport       NodePort       10.99.153.177   <none>               80:31960/TCP   12s

# 使用CLUSTER-IP访问
[root@master ~]# curl 10.99.153.177
<html><body><h1>It works!</h1></body></html>

# 使用NodePort访问
[root@master ~]# curl 192.168.58.110:31960
<html><body><h1>It works!</h1></body></html>

创建deployment和service,使用centos容器Nslookup解析service

# 创建一个pod,service
[root@master ~]# vi hostwork.yaml 
apiVersion: apps/v1 
kind: Deployment 
metadata: 
  name: myapp-deploy 
  namespace: default 
spec: 
  replicas: 1
  selector: 
    matchLabels: 
      app: myapp 
      release: v1
  template:
    metadata: 
      labels: 
        app: myapp 
        release: v1 
    spec: 
      containers: 
      - name: myapp
        image: xm17671855780/file_httpd:v0.2
        imagePullPolicy: IfNotPresent
---
apiVersion: v1
kind: Service
metadata: 
  name: myapp-externalname
  namespace: default
spec: 
  type: ExternalName 
  externalName: web.test.example.com

# 查看现有资源
[root@master ~]# kubectl get pods(无)
No resources found in default namespace.

# 部署
[root@master ~]# kubectl apply -f hostwork.yaml 
deployment.apps/myapp-deploy created

# 查看pods,service状态
[root@master ~]# kubectl get pod,svc
NAME                               READY   STATUS    RESTARTS   AGE
pod/myapp-deploy-79b6dccb8-95ckd   1/1     Running   0          3m19s

NAME                         TYPE           CLUSTER-IP   EXTERNAL-IP            PORT(S)   AGE
service/kubernetes           ClusterIP      10.96.0.1    <none>                 443/TCP   6d4h
service/myapp-externalname   ExternalName   <none>       web.test.example.com   <none>    4h45m

# 辨析一个busybox资源定义文件
[root@master ~]# vibusybox.yaml 
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: busybox-pod
  name: test-busybox
spec:
  containers:
  - command:
    - sleep
    - "3600"
    image: busybox
    imagePullPolicy: Always
    name: test-busybox

# 部署
[root@master ~]# kubectl apply -f busybox.yaml 
pod/test-busybox created

# 查看pods,svc的状态
[root@master ~]# kubectl get pod,svc
NAME                               READY   STATUS              RESTARTS        AGE
pod/myapp-deploy-79b6dccb8-95ckd   1/1     Running             1 (2m30s ago)   3h37m
pod/test                           3/3     Running             3 (3m31s ago)   4h12m
pod/test-busybox                   0/1     ContainerCreating   0               9s

NAME                         TYPE           CLUSTER-IP      EXTERNAL-IP            PORT(S)        AGE
service/kubernetes           ClusterIP      10.96.0.1       <none>                 443/TCP        7d1h
service/myapp-externalname   ExternalName   <none>          web.test.example.com   <none>         25h
service/myapp-nodeport       NodePort       10.97.233.242   <none>                 80:31960/TCP   3h46m

# 使用exec -it对test-busybox进行交互
[root@master ~]# kubectl exec -it test-busybox /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # nslookup myapp-externalname.default.svc.cluster.local  
Server:         10.96.0.10
Address:        10.96.0.10:53

myapp-externalname.default.svc.cluster.local    canonical name = web.test.example.com

*** Can't find myapp-externalname.default.svc.cluster.local: No answer

# myapp-externalname.default.svc.cluster.local 为Service域名。格式为:$(service name).$(namespace).svc.cluster.local,其中 cluster.local 指定的集群的域名
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值