zoukankan      html  css  js  c++  java
  • K8S(二)-创建一个pod应用

     Pod是可以创建和管理Kubernetes计算的最小可部署单元。pod可以理解为容器的外壳,给容器做了一层抽象封装。一个Pod代表着集群中运行的一个进程,每个pod都有一个唯一的ip。

    一个pod类似一个豌豆荚,包含一个或多个容器(通常是docker),这多个容器间共享IPC、Network和UTC,和存储卷,存储卷不再属于容器,而属于pod。

    Pod分为两类:

    1. 自主式Pod
    2. 控制器管理的Pod 
      • ReplicationController
      • ReplicaSet
      • Deployment   管理无状态的
      • StatefulSet    管理有状态的
      • Job, Ctonjob

     Deployment为Pod和ReplicaSet提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController来方便的管理应用。典型的应用场景包括:

    • 定义Deployment来创建Pod和ReplicaSet
    • 滚动升级和回滚应用
    • 扩容和缩容
    • 暂停和继续Deployment

    创建一个pod应用

    kubectl  run -h  查看run命令的用法

    master01 # kubectl run nginx-deploy --image=nginx:1.14-alpine --port=80 --replicas=1  --record
                  控制器名称 容器镜像           容器的端口  pod的数量 在Deployment revision中可以查看到执行的历史命令

    查看

    # kubectl get deployment -o wide   #查看deployment控制器
      NAME         READY UP-TO-DATE AVAILABLE AGE   CONTAINERS   IMAGES            SELECTOR
      nginx-deploy 1/1 1 1 2m38s nginx-deploy nginx:1.14-alpine run=nginx-deploy
    [master01 ]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-deploy-55d8d67cf-kckf9 1/1 Running 0 2m55s 10.244.1.2 node01 <none> <none>
    可以看到pod已经运行在一个工作节点上, 这里的ip是cni0桥的ip
    [node01] # ifconfig
    cni0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
            inet 10.244.1.1  netmask 255.255.255.0  broadcast 0.0.0.0 
    # curl 10.244.1.2 可以访问到nginx。在集群中间的任意一个节点都可以访问到pod

     在集群内部任意的节点可以访问pod 。集群外部无法直接访问pod

     删除pods     查看会看到自动起来另一个,因为 replicas个数为1,控制器会另外再启动一个pod

    # kubectl delete pod nginx-deploy-55d8d67cf-kckf9
    pod "nginx-deploy-55d8d67cf-kckf9" deleted
    # kubectl get pods -o wide
    NAME                           READY   STATUS    RESTARTS   AGE     IP           NODE     NOMINATED NODE   READINESS GATES
    nginx-deploy-55d8d67cf-lf5xb   1/1     Running   0          2m55s   10.244.1.3   node01   <none>           <none>

     会看到容器已经被重建了,且pod的ip发生变化了。

    service 

    service是一个抽象概念,定义了一个服务的多个pod逻辑合集和访问pod的策略,一般把service称为微服务。

    举个例子:a服务运行3个pod,b服务怎么访问a服务的pod,pod的ip都不是持久化的重启之后就会有变化。
    这时候b服务可以访问跟a服务绑定的service,service信息是固定的提前告诉b就行了,service通过Label Selector跟a服务的pod绑定,无论a的pod如何变化对b来说都是透明的。

     客户端的请求到service,由service代理至后端的pod。service并不是一个具体的应用程序,而是相当于一条ipvs或iptables规则。

    kubectl  expose  -h  查看命令的用法

    kubectl expose (-f FILENAME | TYPE NAME)  [--port=port]  [--protocol=TCP|UDP|SCTP]  [--target-port=number-or-name]  [--name=name] [--external-ip=external-ip-of-service] [--type=type] [options]

    创建service 

    # kubectl expose deployment nginx-deploy --name=nginx80 --port=80 --target-port=80 --protocol=TCP
    service_name service_port pod_port service
    /nginx exposed

    查看service

    # kubectl get svc -o wide
    NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE     SELECTOR
    kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP          26d     <none>
    nginx80      ClusterIP   10.105.125.134   <none>        80/TCP           118s    run=nginx-deploy
    # curl 10.105.125.134:80 在集群内部节点上可以访问到pod

     在集群节点可以使用 service_ip:service_port 访问pod。  node访问 -> service_ip:service_port -> pod_ip:pod:port。

      在pod客户端可以通过 service_name:service_ip 访问到pod,这依赖于coredns解析

    [master01 ] # cat /etc/resolv.conf

    nameserver 114.114.114.114       # 节点上的dns服务器不是指向的coredns的地址,所以无法直接通过server_name:service_ip 访问pod

    # kubectl get svc -n kube-system   #可以看到coredns的地址
    NAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
    kube-dns   ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   6d3h

    在pod客户端访问

    # kubectl run client --image=busybox --replicas=1 -it --restart=Never

    / # cat /etc/resolv.conf
    nameserver 10.96.0.10
    search default.svc.cluster.local svc.cluster.local cluster.local

     # wget -O - -q http://nginx80     可以访问到  #  pod客户端可以通过 server_name:server_ip 访问到pod 

     kubectl describe svc nginx80    查看service详细信息

     

    • selector    标签选择器
    • endpoints可以看到后端pod资源

    pod被删除掉之后会创建一个新pod,访问nginx:80依然能访问到,因为service通过selector标签选择器跟pod建立了绑定,service可以为pod提供固定访问端点。

    # kubectl get pods --show-labels   # 查看标签
    NAME READY STATUS RESTARTS AGE LABELS
    client 1/1 Running 0 19m run=client
    nginx-deploy-54d6d94f75-b2kxf 1/1 Running 0 165m pod-template-hash=54d6d94f75,run=nginx-deploy

    实践:

    创建两个pod

    # kubectl run myapp --image=ikubernetes/myapp:v1 --replicas=2
    # kubectl get deployment -w # -w 监控deployment状态
    # kubectl get pods -o wide 

     

    创建一个service

    # kubectl expose deployment myapp --port=8000 --target-port=80

    查看svc

    # kubectl describe svc myapp
    Name:              myapp
    Namespace:         default
    Labels:            run=myapp
    Annotations:       <none>
    Selector:          run=myapp
    Type:              ClusterIP
    IP:                10.99.71.37       
    Port:              <unset>  8000/TCP
    TargetPort:        80/TCP
    Endpoints:         10.244.1.35:80,10.244.1.36:80  #service后端的两个pod
    Session Affinity:  None
    Events:            <none>

     创建一个pod客户端访问 service_name:service_port,可以看到service是随机的将请求分发到后端的两个pod的

    # kubectl run client --image=busybox -it 

    / # wget -O - -q http://myapp:8000/hostname.html

      

    动态扩容缩容

      kubectl scale --replicas=5 deployment  nginx-deploy     # replicas指定pod数即可扩容缩容

    升级镜像

     将镜像升级为1.16-alpine:

    # kubectl set image deployment nginx-deploy nginx-deploy=nginx:1.16-alpine  --record
    deployment.extensions/nginx-deploy image updated

    另开一个窗口监控升级过程:
    # kubectl get pod -w

      升级完成后查看:

    # kubectl get pods
    NAME                            READY   STATUS    RESTARTS   AGE
    nginx-deploy-56457775df-ptx9f   1/1     Running   0          2m25s
    # kubectl get deployment
    -o wide NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR nginx-deploy 1/1 1 1 23d nginx-deploy nginx:1.16-alpine run=nginx-deploy

    # kubectl describe pod nginx-deploy-56457775df-ptx9f

      

    回滚操作

    # kubectl rollout undo deployment/nginx-deploy
    deployment.extensions/nginx-deploy rolled back

    --to-revision 参数可以指定回退的版本

    # kubectl rollout undo deploy/nginx-deploy --to-revision=1

    # kubectl rollout history deployment/nginx-deploy     #查看历史版本

    这里CHANGE-CAUSE显示为空是因为操作deployment的时候没有加--record。如果加上应该显示:

    外部客户端访问pod

    k8s中的三种网络:

    Node Network: 与外部网络接口
    Service Network:又叫集群网络,与pod不在一个网段,只存在于iptables或ipvs规则中,是虚拟的
    Pod Network: 节点当中pod的内部网络,可以ping通

    如果端口暴露类型为NodePort,那么外部客户端可以通过集群内任意一台主机ip加暴露的端口进行访问

    1. #  kubectl edit svc myapp   修改service的type为NodePort

      ClusterIP: 默认类型,自动分配一个仅集群内部可以访问的虚拟IP
      NodePort: 在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过  NodeIP:NodePort 来访问该服务

    2. 也可以在创建service时指定type

     kubectl expose deployment nginx-deploy  --name=nginx   --port=80 --target-port=80 --type=NodePort

     # kubectl get svc -o wide

    NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE   SELECTOR
    kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP        26d   <none>
    nginx80      NodePort    10.105.125.134   <none>        80:32441/TCP   35m   run=nginx-deploy

    使用集群外客户端访问,需要使用集群任意一个节点的IP地址加上暴露的端口号

  • 相关阅读:
    Spring Cloud:第四章:Hystrix断路器
    Spring Cloud:第五章:Zuul服务网关
    Spring Cloud:第六章:Config分布式配置
    ES使用org.elasticsearch.client.transport.NoNodeAvailableException: No node available
    for循环使用后contains方法失去效果
    我的分享:第二章:SpringCould专栏
    Spring Cloud:第二章:eureka服务发现
    java程序员怎么创建自己的网站:第四章:做个网站引入广告赚点小钱
    php函数
    each与list的用法
  • 原文地址:https://www.cnblogs.com/xiaobaozi-95/p/11607834.html
Copyright © 2011-2022 走看看