美文网首页
Docker 体验及总结(6) - Kubernetes(待续)

Docker 体验及总结(6) - Kubernetes(待续)

作者: 千反田爱瑠爱好者 | 来源:发表于2018-09-13 21:05 被阅读24次
    https://www.docker.com/
    • Master-Node,Master对外提供交互API
    • Master:
      • API Server:与整个集群交互
      • Scheduler:调度模块(如容器创建、所运行的节点)
      • Controller:控制模块(负载均衡、横向扩展)
      • ETCD:存储集群状态和配置
    • Node:
      • Pod:调度的最小单位,具有相同Namespace的Container组合
      • Docker:容器运行的技术
      • Kubelet:负责在Node上创建Container、Volume等
      • Kube-proxy:端口代理转发、负载均衡
      • Fluentd:日志采集存储查询
      • Image Registry
      • Optional:DNS,UI...
    Kubernetes架构

    简介:http://www.imooc.com/article/23476

    搭建

    先看看Kelsey Hightower大佬的GitHub:https://github.com/kelseyhightower

    搭建方法:

    以通过Minikube搭建集群为例:需要先安装Minikube和kubectl(连接K8S的客户端):https://github.com/kubernetes/minikube

    minikube start    # 创建一个单节点K8S集群(下载Minikube ISO和localkube binary)
    kubectl version
    kubectl config view    
    kubectl config get-contexts    # 查看Minikube上下文(每个集群对应一个上下文)
    kubectl cluster-info    # 查看集群情况
    
    minikube ssh    # 连接到minikube的虚拟机,查看docker版本
        docker version
    

    使用kubectl自动补全脚本

    source <(kubectl completion zsh)>
    kubectl  completion zsh
    

    Pods

    Pods
    • K8S基本调度单位(K8S不直接对Container操作),包括一或多个Container;
    • Pod中的Container共享Namespace(用户、网络、存储),Container中的通信直接通过localhost。

    实例:以Nginx为例,创建一个pod

    vim pod_nginx.yml
        apiVersion: v1
        kind: Pod
        metadata:
          name: nginx
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx
            ports:
            - containerPort: 80
    kubectl create -f pod_nginx.yml    # 指定yml文件创建并启动pod
    kubectl delete -f pod_nginx.yml    # 删除pod
    kubectl get pods    # 查看集群中有哪些pod
    kubectl get pods -o wide            # 查询Pod中的Container信息
    

    操作pod中的container:

    方法1:通过docker命令控制

    minikube ssh    # 先进入minikube虚拟机
        docker ps    # 查看运行了哪些container
        docker exec -it container_id sh
            xxx
        docker network ls    # 查看minikube的bridge
        docker network inspect bridge    # 查看bridge网络详细信息
    

    方法2:通过K8S命令控制

    kubectl exec -it nginx sh               # 默认进入Pod中的第一个Container(也可以通过-c选项指定)
    
    kubectl describe nginx pods nginx    # 查看某个pod的详细信息
    kubectl port-forward nginx 8080:80      # 端口映射(把pod的80端口映射到minikube的8080端口供本地访问,但在终端中保持运行)
    kubectl delete -f pod_nginx.yml    # 删除pod
    

    ReplicationController

    通过ReplicationController创建pod可维持指定数量的副本(Down以后自动创建)

    vim rc_nginx.yml
        apiVersion: v1
        kind: ReplicationController 
        metadata:
          name: nginx
        spec:
          replicas: 3
          selector:
            app: nginx
          template:
            metadata:
              name: nginx
              labels:
                app: nginx
            spec:
              containers:
              - name: nginx
                image: nginx
                ports:
                - containerPort: 80
    kubectl create -f rc_nginx.yml    # 创建3副本的Nginx pod
    kubectl get rc
    kubectl get pods
    kubectl delete pods pod_name    # 删除其中一个副本(会发现自动恢复一个,维持3个)
    
    kubectl scale rc nginx --replicas=2    # 改为维持2个副本
    kubectl get pods -o wide    # 查看pod运行在哪些节点
    kubectl delete -f rc_nginx.yml
    

    ReplicaSet

    新一代的ReplicationController,支持new set-based
    selector

    vim rs_nginx.yml    # 注意配置与ReplicationController不同
        apiVersion: apps/v1
        kind: ReplicaSet
        metadata:
          name: nginx
          labels:
            tier: frontend
        spec:
          replicas: 3
          selector:
            matchLabels:
              tier: frontend
          template:
            metadata:
              name: nginx
              labels:
                tier: frontend
            spec:
              containers:
              - name: nginx
                image: nginx
                ports:
                - containerPort: 80
    kubectl create -f rs_nginx.yml    
    kubectl get rs
    kubectl get pods
    kubectl scale rs nginx --replicas=2
    

    Deployment

    • 提供ReplicaSets和Pods的声明和实现(副本数、服务版本);
    • 通过Deployment创建的ReplicaSets和Pods不能直接操作,而需要对Deployment操作。
    vim deployment_nginx.yml
        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: nginx-deployment
          labels:
            app: nginx
        spec:
          replicas: 3
          selector:
            matchLabels:
              app: nginx
          template:
            metadata:
              labels:
                app: nginx
            spec:
              containers:
              - name: nginx
                image: nginx:1.12.2
                ports:
                - containerPort: 80
    kubectl create -f deployment_nginx.yml
    kubectl get deployment  -o wide  # 列出所有deployment
    kubectl get rs
    kubectl get pods
    
    # deployment升级
    kubectl set image deployment nginx-deployment nginx=nginx:1.13    # 升级deployment版本
    kubectl get rs
    kubectl get pods
    kubectl rollout history deployment nginx-deployment    # 查看deployment历史版本
    kubectl rollout undo deployment nginx-deployment    # 回滚deployment版本
    

    端口映射

    kubectl get node -o wide    
    kubectl delete services nginx-deployment    # 删除services
    kubectl expose deployment nginx-deployment --type=NodePort    # 把deployment的端口暴露到本地
    kubectl get svc    # 查看deployment的端口映射关系
    

    多节点环境部署

    使用CoreOS的Tectonic-Kubernetes的Sandbox部署多节点环境(基于VirtualBox + Vagrant + SandBox,收费,提供免费试用):https://coreos.com/tectonic/

    下载文件到本地,创建K8S虚拟化环境:

    # https://github.com/yipwinghong/FileRepository/tree/master/kubernetes/tectonic-sandbox-1.7.5-tectonic.1
    cd tectonic-sandbox-1.7.5-tectonic.1
    vagrant up
    

    多集群管理:使得kubectl兼容minikube和tectonic的context

    kubectl config get-clusters
    kubectl config get-contexts
    kubectl config use-context tectonic    # 使用tectonic的context
    kubectl get node
    

    接下来的测试都要使用这个多节点环境。

    K8S网络

    https://kubernetes.io/docs/concepts/cluster-administration/networking/

    多机通信:通过flannel插件实现Overlay网络,集群中默认所有的pods之间、主机与pods之间都可以ping通:

    # 创建两个pods并查看运行情况
    kubectl create -f pod_busybox.yml
    kubectl create -f pod_nginx.yml
    kubectl get pods -o wide
    
    # pods之间可以ping通
    kubectl exec -it busybox-pod sh    # 进入busybox pod
        ip a
        ping 10.0.2.51    # 尝试ping通nginx pod
    
    # 主机与pods也可以ping通
    vagrant status    # 有两台虚拟机w1和c1,假设两个pod都运行在w1,则c1没有pod运行
    vagrant ssh c1    # 进入c1
        ping 10.0.2.51    # 在c1也可以ping通两个pod
        ping 10.0.2.50
    

    网络插件应该满足要求:

    • 所有容器可以互相通信,不需要经过NAT;
    • 所有节点可以与所有容器互相通信(哪怕不在一个节点上),不需要经过NAT;
    • 容器自身ip可供其他(节点、容器)访问。

    Service

    不建议直接使用和管理Pods(网络):

    1. 使用ReplicaSet或ReplicationController水平伸缩scale时,Pods可能会被terminated;
    2. 使用Deployment时,更新Docker Image Version,旧的Pods会被Terminated,然后创建新的Pods。

    Services管理:

    • kubectl exposes命令,会给我们的pod创建一个Service,供外部访问;
    • Service主要类型:ClusterIP,NodePort,LoadBalancer(需要结合云服务商使用),ExternalName(需要DNS支持);
    • 另外也可以使用DNS,但需要DNS的add-on。

    ClusterIP

    • ClusterIP只能供内部访问,不能在互联网上提供服务;
    • 为pods、deployment等创建service时,默认为ClientIP,如需要指定其他,要添加--type选项。

    接上,使用测试网路时创建的busybox pod和nginx pod

    kubectl get pods -o wide    # busybox pod和nginx pod(pod的ip会因重启而变化)
    kubectl expose pods nginx-pod    # 对外提供nginx pod
    kubectl get svc    # 查看对外提供服务的pod使用的ip(services的ip不会因重启而变化)
    
    vagrant ssh c1
        curl  10.3.248.3    # services的ip
    

    使用service的deployment会自动做负载均衡和滚动升级:

    kubectl create -f xxx.yml    # 创建deployment
    kubectl get deployment    # 查看deployment名称
    kubectl expose deployment service-test   # 创建service
    kubectl get svc
    
    # 直接编辑deployment的yml,保存退出后暂时中止,过后自动恢复并升级。
    kubectl edit deployment service-test
    

    NodePort

    • NodePort Service把端口映射到整个Cluster上的每个节点,所以访问任意一个节点都可以请求到服务;
    • 可以绑定NodeIP为公网IP(端口有范围限制),则可以对外提供服务;
    • 存在问题:当启动一个服务,需要占用所有节点的相同端口,对于端口是一种浪费。

    通过yml创建pods再创建service

    vim pod_nginx.yml
        apiVersion: v1
        kind: Pod
        metadata:
          name: nginx-pod
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx-container
            image: nginx
            ports:
            - name: nginx-port
              containerPort: 80
    kubectl create -f pod_nginx.yml
    kubectl get pods -o wide
    
    kubectl expose pods nginx-pod --type=NodePort    # 给pods创建nodeport service
    kubectl get svc
    kubectl describe node c1.xxx
    

    直接通过yml创建service

    vim service_nginx.yml
        apiVersion: v1
        kind: Service
        metadata:
          name: nginx-service
        spec:
          ports:
          - port: 8080
            nodePort: 8080
            targetPort: nginx-port
            protocol: TCP
          selector:
            app: nginx
          type: NodePort
    kubectl create -f service_nginx.yml
    

    Label

    如一个pod(或其他对象)的yml中定义了nodeSelector参数,可以指定其运行在具备某个Label的节点上:

    apiVersion: v1
    kind: Pod
    metadata:
      name: busybox-pod
      labels:
        app: busybox
    spec:
      nodeSelector:
        hardware: good
      containers:
      - name: busybox-container
        image: busybox
        command:
          - sleep
          - "360000"
    

    以上pod就只允许允许运行在hardware=good的节点了,没有的话会一直Pending:

    kubectl get nodes --show-labels
    
    # 为节点指定Label,稍后pod就会运行在w1节点上
    kubectl label node w1 hardware=good
    

    相关文章

      网友评论

          本文标题:Docker 体验及总结(6) - Kubernetes(待续)

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