美文网首页
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