美文网首页编程开发
2. kubernetes 快速入门

2. kubernetes 快速入门

作者: 升职哦 | 来源:发表于2022-08-15 21:01 被阅读0次

    2. kubernetes 快速入门

    前言

    以下命令以kubernetes v2.3.8 为例

    dashboard 版本: v2.5.1+0.g520013042

    实践出真知,每个版本的kubernetes 改动都比较大。坑也比较多

    文档仅供参考,具体请查看官方文档

    下面我们简单介绍下 k8s中一些常用的命令和概念。

    一、nameSpace

    1. 简介

    nameSpace,中文名称:命名空间。 你可以认为namespaces是你kubernetes集群中的虚拟化集群。在一个Kubernetes集群中可以拥有多个命名空间,它们在逻辑上彼此隔离。 可以为你提供组织,安全甚至性能方面的帮助!

    Namespace是对一组资源和对象的抽象集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的pods, services, replication controllers和deployments等都是属于某一个namespace的(默认是default),而node, persistentVolumes等则不属于任何namespace。

    大多数的Kubernetes中的集群默认会有一个叫default的namespace。实际上,应该是4个:

    • default:用户创建的pod默认在此命名空间。

    • kube-system:kubernetes系统组件使用。

    • kube-node-lease: kubernetes集群节点租约状态,v1.13加入

    • kube-public:公共资源使用,不需要认证也可访问。但实际上现在并不常用。

        这个默认(default)的namespace并没什么特别,但你不能删除它。这很适合刚刚开始使用kubernetes和一些小的产品系统。但不建议应用于大型生产系统。因为,这种复杂系统中,团队会非常容易意外地或者无意识地重写或者中断其他服务service。相反,请创建多个命名空间来把你的service(服务)分割成更容易管理的块。
      

    作用:多租户情况下,实现资源隔离
    属于逻辑隔离
    属于管理边界
    不属于网络边界
    可以针对每个namespace做资源配额

    2. 常用命令

    查看 nameSpace

    # 查看所有namespace
    kubectl get namespace
    # 简写
    kubectl get ns
    
    NAME                   STATUS   AGE
    default                Active   22h
    kube-node-lease        Active   22h
    kube-public            Active   22h
    kube-system            Active   22h
    kubernetes-dashboard   Active   20h
    
    # 查询所有pod的命名空间资源
    kubectl get pod --all-namespaces
    # 简写
    kubectl get pod -A
    
    NAMESPACE              NAME                                         READY   STATUS    RESTARTS   AGE
    kube-system            calico-kube-controllers-7bc6547ffb-2bnbh     1/1     Running   0          21h
    kube-system            calico-node-9cjvj                            1/1     Running   0          4h11m
    kube-system            calico-node-q789c                            1/1     Running   0          3h36m
    kube-system            calico-node-rnhcv                            1/1     Running   0          21h
    kube-system            coredns-6d8c4cb4d-5bjmr                      1/1     Running   0          22h
    kube-system            coredns-6d8c4cb4d-7w72l                      1/1     Running   0          22h
    kube-system            etcd-k8s-master01                            1/1     Running   0          22h
    kube-system            kube-apiserver-k8s-master01                  1/1     Running   0          22h
    kube-system            kube-controller-manager-k8s-master01         1/1     Running   0          22h
    kube-system            kube-proxy-4hsmj                             1/1     Running   0          3h36m
    kube-system            kube-proxy-56nrq                             1/1     Running   0          4h11m
    kube-system            kube-proxy-rcsfg                             1/1     Running   0          22h
    kube-system            kube-scheduler-k8s-master01                  1/1     Running   0          22h
    kubernetes-dashboard   dashboard-metrics-scraper-799d786dbf-j85zw   1/1     Running   0          5h53m
    kubernetes-dashboard   kubernetes-dashboard-fb8648fd9-qcrzk         1/1     Running   0          5h53m
    

    创建 nameSpace

    # 创建nameSpace
    kubectl create namespace curyu
    # 简写
    kubectl create ns curyu
    
    $ namespace/curyu created
    

    删除 nameSpace

    # 删除nameSpace
    kubectl delete namespace curyu
    # 简写
    kubectl delete ns curyu
    
    $ namespace "curyu" deleted
    

    二、pod 与 deployment

    1. 简介

    pod 网络只在 k8s 内部可以访问,外部无法访问。如果需要外部访问我们需要借入 service来实现。

    pod是非永久性资源

    Pod是kubernetes集群能够调度的最小单元。Pod是容器的封装 。

    在Kubernetes集群中,Pod是所有业务类型的基础,也是K8S管理的最小单位级,它是一个或多个容器的组合。这些容器共享存储、网络和命名空间,以及如何运行的规范。在Pod中,所有容器都被统一安排和调度,并运行在共享的上下文中。对于具体应用而言,Pod是它们的逻辑主机,Pod包含业务相关的多个应用容器。

    pod的特点:

    • 网络

    每一个Pod都会被指派一个唯一的Ip地址,在Pod中的每一个容器共享网络命名空间,包括Ip地址和网络端口。在同一个Pod中的容器可以和localhost进行互相通信。当Pod中的容器需要与Pod外的实体进行通信时,则需要通过端口等共享的网络资源。

    • 存储

    Pod能够被指定共享存储卷的集合,在Pod中所有的容器能够访问共享存储卷,允许这些容器共享数据。存储卷也允许在一个Pod持久化数据,以防止其中的容器需要被重启。

    pod的工作方式

    K8s一般不直接创建Pod。 而是通过控制器和模版配置来管理和调度。

    • Pod模版

    • Pod重启

    在Pod中的容器可能会由于异常等原因导致其终止退出,Kubernetes提供了重启策略以重启容器。重启策略对同一个Pod的所有容器起作用,容器的重启由Node上的kubelet执行。Pod支持三种重启策略,在配置文件中通过restartPolicy字段设置重启策略:

    1. Always:只要退出就会重启。
    2. OnFailure:只有在失败退出(exit code不等于0)时,才会重启。
    3. Never:只要退出,就不再重启
      注意,这里的重启是指在Pod的宿主Node上进行本地重启,而不是调度到其它Node上。
    • 资源限制

    Kubernetes通过cgroups限制容器的CPU和内存等计算资源,包括requests(请求,调度器保证调度到资源充足的Node上)和limits(上限)等。

    我们要知道的是: pod是k8s中的最小单元,一个pod中有可能包含多个docker,他们共享网络(ip),共享存储空间。每个pod的ip都是独立的。

    一般情况下,我们并不直接创建 Pod,而是通过 Deployment 来创建 Pod由 Deployment 来负责创建、更新、维护其所管理的所有 Pods

    一旦我们通过 Deployment 创建 Pod,会有一个 Deployment 控制器不断监控所有 Pod 的状态。例如,如果 Pod 运行的机器宕机了,那么 Deployment 控制器会在另一台机器上重新启动一个 Pod。

    2. 常用命令

    注意,不同版本的k8s 命令是由一定区别的。 比如 1.7 和 2.3 版本的deployment 命令就有一些区别。我们这里都是以2.3.8版本为例

    kubernetes 1.8 开始 kubectl run 命令在运行pod的同时不会再创建 deployment。

    版本变更后的办法还是用kubectl apply + yaml 文件

    查看 pod

    # 查看 `default` namespace 下的pods
    kubectl get pods
    # 如果没有找到资源则展示
    $ No resources found in default namespace.
    
    # 查看 `kube-system` namespace 下的pods
    kubectl get pods -n kube-system
    
    NAME                                       READY   STATUS    RESTARTS   AGE
    calico-kube-controllers-7bc6547ffb-2bnbh   1/1     Running   0          21h
    calico-node-9cjvj                          1/1     Running   0          4h39m
    calico-node-q789c                          1/1     Running   0          4h3m
    calico-node-rnhcv                          1/1     Running   0          21h
    coredns-6d8c4cb4d-5bjmr                    1/1     Running   0          23h
    coredns-6d8c4cb4d-7w72l                    1/1     Running   0          23h
    etcd-k8s-master01                          1/1     Running   0          23h
    kube-apiserver-k8s-master01                1/1     Running   0          23h
    kube-controller-manager-k8s-master01       1/1     Running   0          23h
    kube-proxy-4hsmj                           1/1     Running   0          4h3m
    kube-proxy-56nrq                           1/1     Running   0          4h39m
    kube-proxy-rcsfg                           1/1     Running   0          23h
    kube-scheduler-k8s-master01                1/1     Running   0          23h
    
    # 查看所有 namespace 下的 pods
    kubectl get pod --all-namespaces
    # 简写
    kubectl get pod -A
    
    NAMESPACE              NAME                                         READY   STATUS    RESTARTS   AGE
    kube-system            calico-kube-controllers-7bc6547ffb-2bnbh     1/1     Running   0          21h
    kube-system            calico-node-9cjvj                            1/1     Running   0          4h40m
    kube-system            calico-node-q789c                            1/1     Running   0          4h4m
    kube-system            calico-node-rnhcv                            1/1     Running   0          21h
    kube-system            coredns-6d8c4cb4d-5bjmr                      1/1     Running   0          23h
    kube-system            coredns-6d8c4cb4d-7w72l                      1/1     Running   0          23h
    kube-system            etcd-k8s-master01                            1/1     Running   0          23h
    kube-system            kube-apiserver-k8s-master01                  1/1     Running   0          23h
    kube-system            kube-controller-manager-k8s-master01         1/1     Running   0          23h
    kube-system            kube-proxy-4hsmj                             1/1     Running   0          4h4m
    kube-system            kube-proxy-56nrq                             1/1     Running   0          4h40m
    kube-system            kube-proxy-rcsfg                             1/1     Running   0          23h
    kube-system            kube-scheduler-k8s-master01                  1/1     Running   0          23h
    kubernetes-dashboard   dashboard-metrics-scraper-799d786dbf-j85zw   1/1     Running   0          6h21m
    kubernetes-dashboard   kubernetes-dashboard-fb8648fd9-qcrzk         1/1     Running   0          6h21m
    

    创建 deployment

    pod 的创建 node 是随机的,因此我们在创建pod 时要确保 所有 node 的 docker image 里 都有同样的基础环境'tomcat'

    我们可以通过kubectl get pods -o wide命令得知 pod 的创建 node 及 访问ip

    以下所有示例我们都使用默认的 nameSpace,即default,如果要指定nameSpace 请在命令中加入-n your nameSpace

    通常我们不会直接操作pod,而是通过deployment 去管控 pod。

    # 为了方便整理,我们把 所有与的yaml文件都放到 master 节点的 /opt/yaml/路径下
    
    mkdir /opt/yaml # 如果存在则忽略
    cd /opt/yaml/
    vim deployment_nginx.yaml
    #--------------------------------------
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-app
    spec:
      selector:                                    #定义标签选择器
        matchLabels:                                #定义匹配的标签,必须要设置
          app: nginx                                 #匹配的目标标签
      replicas: 3                                  #开启Pod的数量
      template:                                    #定义模板,必须定义,模板是起到描述要创建的pod的作用
        metadata:                                   #定义模板元数据
          labels:                                   #定义模板label,Deployment.spec.template.metadata.labels
            app : nginx                              #定义标签,必须等于 matchLabels 定义的标签
        spec:
          containers:
            - image: nginx    #docker 镜像名,我们使用的是官方的nginx
              name: nginx                                 #镜像名称
              ports:
                - containerPort: 80                         #定义容器使用的端口
    #--------------------------------------
    
    # 而后我们创建deployment 并启动pod
    kubectl apply -f /opt/yaml/deployment_nginx.yaml
    
    $ deployment.apps/nginx-app created
    
    # 查看 deployment
    kubectl get deployment
    
    NAME               READY   UP-TO-DATE   AVAILABLE   AGE
    my-tomcat9-test3   1/1     1            1           110m
    nginx-app          0/3     3            0           14s
    
    # 查看 deployment wide
    kubectl get deployment -o wide
    
    NAME               READY   UP-TO-DATE   AVAILABLE   AGE    CONTAINERS   IMAGES   SELECTOR
    my-tomcat9-test3   1/1     1            1           111m   tomcat       tomcat   app=my-tomcat9-test3
    nginx-app          3/3     3            3           45s    nginx        nginx    app=nginx
    
    # 查看pod wide
    kubectl get pods -o wide
    
    NAME                               READY   STATUS    RESTARTS   AGE    IP               NODE          NOMINATED NODE   READINESS GATES
    my-tomcat9-test                    1/1     Running   0          123m   10.244.211.201   k8s-slave03   <none>           <none>
    my-tomcat9-test3-f9d57988f-xhxhg   1/1     Running   0          111m   10.244.211.202   k8s-slave03   <none>           <none>
    nginx-app-74d589986c-fkwx5         1/1     Running   0          63s    10.244.211.203   k8s-slave03   <none>           <none>
    nginx-app-74d589986c-k67b2         1/1     Running   0          63s    10.244.220.197   k8s-slave02   <none>           <none>
    nginx-app-74d589986c-mzpq9         1/1     Running   0          63s    10.244.220.196   k8s-slave02   <none>           <none>
    tomcat-test2                       1/1     Running   0          23h    10.244.211.194   k8s-slave03   <none>           <none>
    
    # 我们随便找一条进行测试,我们以`nginx-app-74d589986c-mzpq9`为例
    # 查看 pod 节点 logs
    kubectl logs nginx-app-74d589986c-mzpq9
    #--------------------------------------
    /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
    /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
    /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
    10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
    10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
    /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
    /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
    /docker-entrypoint.sh: Configuration complete; ready for start up
    2022/06/30 07:27:00 [notice] 1#1: using the "epoll" event method
    2022/06/30 07:27:00 [notice] 1#1: nginx/1.21.5
    2022/06/30 07:27:00 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
    2022/06/30 07:27:00 [notice] 1#1: OS: Linux 3.10.0-1160.el7.x86_64
    2022/06/30 07:27:00 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
    2022/06/30 07:27:00 [notice] 1#1: start worker processes
    2022/06/30 07:27:00 [notice] 1#1: start worker process 31
    #--------------------------------------
    
    # 测试访问nginx
    curl 10.244.220.196:80
    #--------------------------------------
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    html { color-scheme: light dark; }
    body { width: 35em; margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif; }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    [root@localhost yaml]# curl 10.244.220.196:80
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
    html { color-scheme: light dark; }
    body { width: 35em; margin: 0 auto;
    font-family: Tahoma, Verdana, Arial, sans-serif; }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    #--------------------------------------
    
    # 查看nginx 日志
    kubectl logs nginx-app-74d589986c-mzpq9
    #--------------------------------------
    ...
    10.244.32.128 - - [30/Jun/2022:07:28:07 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
    10.244.32.128 - - [30/Jun/2022:07:28:54 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
    10.244.32.128 - - [30/Jun/2022:07:28:55 +0000] "GET / HTTP/1.1" 200 615 "-" "curl/7.29.0" "-"
    ...
    #--------------------------------------
    
    # 我们还可以使用`describe` 命令来查看详细的描述信息
    kubectl describe deploy nginx
    #--------------------------------------
    Name:                   nginx-app
    Namespace:              default
    CreationTimestamp:      Thu, 30 Jun 2022 15:26:44 +0800
    Labels:                 <none>
    Annotations:            deployment.kubernetes.io/revision: 1
    Selector:               app=nginx
    Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
    StrategyType:           RollingUpdate
    MinReadySeconds:        0
    RollingUpdateStrategy:  25% max unavailable, 25% max surge
    Pod Template:
      Labels:  app=nginx
      Containers:
       nginx:
        Image:        nginx
        Port:         80/TCP
        Host Port:    0/TCP
        Environment:  <none>
        Mounts:       <none>
      Volumes:        <none>
    Conditions:
      Type           Status  Reason
      ----           ------  ------
      Available      True    MinimumReplicasAvailable
      Progressing    True    NewReplicaSetAvailable
    OldReplicaSets:  <none>
    NewReplicaSet:   nginx-app-74d589986c (3/3 replicas created)
    Events:
      Type    Reason             Age   From                   Message
      ----    ------             ----  ----                   -------
      Normal  ScalingReplicaSet  14m   deployment-controller  Scaled up replica set nginx-app-74d589986c to 3
    #--------------------------------------
    
    #有时候我们需要在pod 中执行命令
    kubectl exec -it nginx-app-74d589986c-mzpq9 bash
    #--------------------------------------
    root@nginx-app-74d589986c-mzpq9:/#
    root@nginx-app-74d589986c-mzpq9:/# ls -l
    total 12
    drwxr-xr-x.   2 root root 4096 Dec 20  2021 bin
    drwxr-xr-x.   2 root root    6 Dec 11  2021 boot
    drwxr-xr-x.   5 root root  360 Jun 30 07:27 dev
    drwxr-xr-x.   1 root root   41 Dec 29 19:28 docker-entrypoint.d
    -rwxrwxr-x.   1 root root 1202 Dec 29 19:28 docker-entrypoint.sh
    drwxr-xr-x.   1 root root   19 Jun 30 07:27 etc
    drwxr-xr-x.   2 root root    6 Dec 11  2021 home
    drwxr-xr-x.   1 root root   45 Dec 20  2021 lib
    drwxr-xr-x.   2 root root   34 Dec 20  2021 lib64
    drwxr-xr-x.   2 root root    6 Dec 20  2021 media
    drwxr-xr-x.   2 root root    6 Dec 20  2021 mnt
    drwxr-xr-x.   2 root root    6 Dec 20  2021 opt
    dr-xr-xr-x. 148 root root    0 Jun 30 07:27 proc
    drwx------.   1 root root   27 Jun 30 07:48 root
    drwxr-xr-x.   1 root root   38 Jun 30 07:27 run
    drwxr-xr-x.   2 root root 4096 Dec 20  2021 sbin
    drwxr-xr-x.   2 root root    6 Dec 20  2021 srv
    dr-xr-xr-x.  13 root root    0 Jun 29 01:09 sys
    drwxrwxrwt.   1 root root    6 Dec 29 19:28 tmp
    drwxr-xr-x.   1 root root   66 Dec 20  2021 usr
    drwxr-xr-x.   1 root root   19 Dec 20  2021 var
    #--------------------------------------
    
    # 使用`ctrl + d` 退出pod 终端
    

    删除 deployment

    # 通过pods `NAME` 删除 pod
    kubectl delete deploy tomcat-test
    $ pod "tomcat-test" deleted
    
    # 除了通过`NAME` 删除,我门也可以通过 yaml 来删除
    kubectl delete -f deployment_nginx.yaml
    

    扩容缩容 pod

    这里要注意的是:我在使用dashboard 进行 扩容、缩容操作时操作失败

    image.png

    dashboard 提示操作的命令:

    kubectl scale -n default replicaset nginx-app-74d589986c --replicas=10
    

    将此命令复制到 命令行中执行后,发现也失败。

    现象是: 执行后确实进行了数量的缩减,但是由于异常马上又回滚了。

    对比两条命令,我们发现 dashboard在缩容时 使用的 deployment 名称是nginx-app-74d589986c 而非 nginx-app

    原因:dashboard为非官方提供的组件,有可能是bug 或 兼容性问题,因为k8s 每个版本的更新改动比较大。 这里我们做到心中有数就行了。

    # dashboard [错误]
    kubectl scale -n default replicaset nginx-app-74d589986c --replicas=10
    # cmd [正确]
    kubectl scale deployment nginx-app --replicas=10
    
    # 我们可以通过命令去调整 pod 的数量
    # 语法:  kubectl scale deployment `你的doployment名称` --replicas=`数量`
    kubectl scale deployment nginx-app --replicas=10
    
    # 查看deployment信息
    kubectl get deployment -o wide
    
    NAME        READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES   SELECTOR
    nginx-app   10/20   20           10          68m   nginx        nginx    app=nginx
    
    # 查看pods信息
    
    NAME                         READY   STATUS    RESTARTS   AGE
    my-tomcat9-test              1/1     Running   0          3h12m
    nginx-app-74d589986c-4tvmd   1/1     Running   0          7m41s
    nginx-app-74d589986c-8gjlj   1/1     Running   0          7m41s
    nginx-app-74d589986c-bdf66   1/1     Running   0          7m41s
    nginx-app-74d589986c-c4bhm   1/1     Running   0          7m41s
    nginx-app-74d589986c-cq69z   1/1     Running   0          80s
    nginx-app-74d589986c-d6rjk   1/1     Running   0          80s
    nginx-app-74d589986c-f4g9v   1/1     Running   0          80s
    nginx-app-74d589986c-gfmsd   1/1     Running   0          7m41s
    nginx-app-74d589986c-gtqkd   1/1     Running   0          80s
    nginx-app-74d589986c-kdq6r   1/1     Running   0          7m41s
    nginx-app-74d589986c-l9m44   1/1     Running   0          80s
    nginx-app-74d589986c-nffkb   1/1     Running   0          5m40s
    nginx-app-74d589986c-p4mbl   1/1     Running   0          22m
    nginx-app-74d589986c-p9mss   1/1     Running   0          80s
    nginx-app-74d589986c-slszp   1/1     Running   0          7m41s
    nginx-app-74d589986c-vb8zg   1/1     Running   0          7m41s
    nginx-app-74d589986c-vgpgh   1/1     Running   0          80s
    nginx-app-74d589986c-vtbzh   1/1     Running   0          80s
    nginx-app-74d589986c-xszpf   1/1     Running   0          80s
    nginx-app-74d589986c-xtc49   1/1     Running   0          80s
    tomcat-test2                 1/1     Running   0          24h
    

    滚动更新

    滚动更新我们在后面的部分再讲解

    三、service

    1. 简介

    kubernetes service 有以下几个作用:

    • 提供固定的 IP。由于 Pod 可以随时启停,Pod IP 可能随时都会变化,例如上面 nginx pod 重启之后 IP 可能不再是 10.244.32.128。Service 为 Pods 提供的固定 IP,其他服务可以通过 Service IP 找到提供服务的 Pods。
    • 提供负载均衡。Service 由多个 Pods 组成,kubernetes 对组成 Service 的 Pods 提供的负载均衡方案,例如随机访问、基于 Client IP 的 session affinity。
    • 服务发现。集群中其他服务可以通过 Service 名字访问后端服务(DNS),也可以通过环境变量访问。

    2. 常用命令

    创建 service

    # 为了方便整理,我们把 所有与的yaml文件都放到 master 节点的 /opt/yaml/路径下
    mkdir /opt/yaml # 如果存在则忽略
    cd /opt/yaml/
    vim service_nginx.yaml
    #--------------------------------------
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-app-service # service 名称
      labels:
        app: nginx-app
    spec:
      selector:                 # 选择器,将service 和 pod 相关联
        app: nginx          # 对应pod 的name(deployment name)
      ports:
      - port: 8001                # service针对内部请求监听的端口
        name: nginx-service-80
        protocol: TCP
        targetPort: 80          # pod应用的端口
        nodePort: 32001         # 针对外部请求的监听端口
      type: NodePort            # service type 类型: ClusterIP、NodePort、LoadBalancer、ExternalName
    #--------------------------------------
    
    # 创建service
    kubectl apply -f /opt/yaml/service_nginx.yaml
    
    $ service/nginx-app-service created
    
    # 查看服务信息
    kubectl get service -o wide
    #----------------------------------------
    NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE     SELECTOR
    kubernetes          ClusterIP   10.222.0.1       <none>        443/TCP          2d19h   <none>
    nginx-app-service   NodePort    10.222.191.172   <none>        8001:32001/TCP   6m48s   app=nginx
    #----------------------------------------
    
    # 这里要注意的是 selector 的匹配, 如果匹配不到 通过 `get service` 信息是看不出来的;后面我们会详细了解一下如何查找是否创建一个"成功"的service
    # 我们查看service describe 详情
    kubectl describe service nginx-app-service
    #----------------------------------------
    Name:                     nginx-app-service
    Namespace:                default
    Labels:                   app=nginx-app
    Annotations:              <none>
    Selector:                 app=nginx
    Type:                     NodePort
    IP Family Policy:         SingleStack
    IP Families:              IPv4
    IP:                       10.222.191.172
    IPs:                      10.222.191.172
    Port:                     nginx-service-80  8001/TCP
    TargetPort:               80/TCP
    NodePort:                 nginx-service-80  32001/TCP
    Endpoints:                10.244.211.208:80,10.244.211.209:80,10.244.211.211:80 + 2 more...
    Session Affinity:         None
    External Traffic Policy:  Cluster
    Events:                   <none>
    #----------------------------------------
    

    服务创建成功了!我们访问测试下:

    image.png image.png image.png

    这里有个疑问:为什么通过三个NODE 都能访问到nginx 呢?kube proxy 如何做的负载?每个节点都能访问到我们创建的5个pod吗?

    这个问题我们通过ipvs,得到了解答(需将iptable 升级为 ipvs)

    我们运行ipvsadm 命令(在master和node节点上):

    # 在192.168.56.105节点上查看ipvs
    ipvsadm -ln
    #------------------------------
    IP Virtual Server version 1.2.1 (size=4096)
    Prot LocalAddress:Port Scheduler Flags
      -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
    ...
    TCP  192.168.56.105:32001 rr
      -> 10.244.211.208:80            Masq    1      0          0
      -> 10.244.211.209:80            Masq    1      0          0
      -> 10.244.211.211:80            Masq    1      0          0
      -> 10.244.211.212:80            Masq    1      0          0
      -> 10.244.220.201:80            Masq    1      0          0
    ...
    #------------------------------
    
    # 在192.168.56.106节点上查看ipvs
    ipvsadm -ln
    #------------------------------
    IP Virtual Server version 1.2.1 (size=4096)
    Prot LocalAddress:Port Scheduler Flags
      -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
    ...
    TCP  192.168.56.106:32001 rr
      -> 10.244.211.208:80            Masq    1      0          0
      -> 10.244.211.209:80            Masq    1      0          0
      -> 10.244.211.211:80            Masq    1      0          0
      -> 10.244.211.212:80            Masq    1      0          0
      -> 10.244.220.201:80            Masq    1      0          0
    ...
    #------------------------------
    

    通过查询出来的记录我们能很明确的知道:

    访问k8s集群任意节点,都会将请求负载给deployment创建的所有pod上。

    删除 service

    kubectl delete -n default service nginx-app-service
    

    3. service type

    service 可以定义不同的type,最常用的是 ClusterIPNodePortLoadBalancer;

    下面我们针对四种service type 进行了解

    ClusterIP

    类型为ClusterIP的service,这个service有一个Cluster-IP,其实就一个VIP。具体实现原理依靠kubeproxy组件,通过iptables或是ipvs实现。

    这种类型的service 只能在<font color=red>集群内访问</font>。

    image.png image.png

    NodePort

    我们的场景不全是集群内访问,也需要<font color=red>集群外访问</font>。那么ClusterIP就满足不了了。NodePort当然是其中的一种实现方案。

    在集群内部IP的基础上,在集群的每一个节点(NODE)端口上开放这个服务

    image.png image.png

    此时我们可以通过http://4.4.4.1:30080或http://4.4.4.2:30080 对pod-python访问

    LoadBalancer

    LoadBalancer类型的service 是可以实现<font color=red>集群外部访问</font>服务的另外一种解决方案。不过并不是所有的k8s集群都会支持,大多是在公有云托管集群中会支持该类型。

    在使用一个集群内部IP地址和在NodePort上开放一个Service的基础上,还可以向云提供者申请一个负载均衡器,将流量转发到已经以NodePort形式开放的Service上。

    在那些支持外部负载均衡器的云提供者上面,将type字段设置为"LoadBalancer"会为你的Service设置好一个负载均衡器。该负载均衡器的实际的创建是异步进行的,并且该设置好均衡器会在该Service的status.loadBalancer字段中显示出来

    image.png image.png

    ExternalName

    类型为 ExternalName 的service将服务映射到 DNS 名称,而不是典型的选择器。

    image.png

    4. port、nodePort、targetPort、containerPort的区别

    port

    对内

    k8s 集群内部访问 service的端口,即 通过 ClusterIP : port 去访问某个 Service

    nodePort

    对外

    外部如果要访问 k8s 的 service,使用nodePort;即 通过NODE IP : nodePort 访问到某个Service

    targetPort

    对内

    pod的端口,可理解为:"dockerfile 中的 expose"

    一个请求 -> 经过 service -> service 根据 selector name匹配 -> 转到pod name : targetPort

    containerPort

    对内

    containerPort 是pod k8s对象yaml文件中 配置 暴露的端口。

    通常情况下 可以认为:

    containerPort == pod port;

    containerPort == targetPort;

    附录

    参考资料

    github kube-ladder

    详解k8s的4种Service类型

    相关文章

      网友评论

        本文标题:2. kubernetes 快速入门

        本文链接:https://www.haomeiwen.com/subject/ammlgrtx.html