在2017年年底之前docker并不支持k8s,因为swarm 和 k8s 是竞争关系,docker在2014年发布第一个版本,2017年年底docker宣布支持k8s。

docker swarm分为manager节点和worker节点,manager节点是管理的功能,维持cluster状态并且提供对外的接口,可以通过manager部署app部署services,stack等等。

同样在k8s里面他的架构和docker swarm类似,或者说分布式的集群大的方向的架构都是类似的。都是有manager和worker,只不过在kubernets中manager成为master节点,worker称之为node,就是普通的node节点。

master对外提供接口,可以对整个kubernets集群进行操作,比如查看cluster节点状态或者把app通过api部署到集群里面去,下面我们分别看一下master和node分别具备哪些功能。

我们先来看master,master是k8s的大脑,master的主要功能有API Server他是暴露给外界访问的,可以通过CLI或者UI去操作API Service然后和整个集群进行交互操作。Scheduler实现调度工作,假设我们通过API下达一个命令部署一个应用,这个应用需要两个容器,那这两个容器到底要运行在那个节点上去,这个就是Scheduler通过一些调度算法来决定运行在哪个节点。Controller是一个控制,比如说容器要做一个负载均衡,要做一个扩展,控制运行个数等等。最底层有一个etcd,他是一个分布式的key-value-store,就是一个存储,就是存储整个k8s的状态和配置。

对于node来讲里面非常重要的一个概念是pod, 在k8s里面来讲pod是容器调度的最小单位,所谓pod他指的是具有相同的name space的一些container的组合。这个name space包含所有的name space, 比如说user-name-space, net-name-space, 其实主要还是network name space。具有相同的network name space组合,这个容器可能有一个也可能有多个,如果是多个的话他们是共享一个network space。关于pod我们后面还是会解释的。

Docker,kubelet,kube-proxy, fluentd. 这里面docker是容器组件,kubelet是master节点控制node节点的代理桥梁。kube-proxy和网络有关主要做端口的代理和转发,负载均衡等功能。fluentd主要是日志的采集,存储和查询。

  1. 集群的安装

minikube可以快速的帮我在本地搭建一个只有一个节点的集群,这个节点既是master又是worker,可以使用他来进行学习。这个工具可以用在linux,macOS,windows都是没有问题的。

kubeadm可以方便的在本地搭建一个真正的k8s集群,有多个节点,至少一个master,一个 workder,节点是可选的。当然节点越多需要的资源也就越多。他的使用要复杂一些。

现在很多云服务商都会提供搭建k8s的服务,只需要简单的UI界面操作就可以了。比如阿里云,谷歌云等等。

  1. 在mac上安装

我们这里使用minikube来演示 https://minikube.sigs.k8s.io/docs/start/, 安装还是比较简单的。按照文档操作就可以了。国内的阿里云上也存在很多的可安装的方式。这里需要注意的是这里需要依赖VBox, 要提前安装好。

minikube version

启动minikube, 这个启动可能会失败,因为服务在国外,可以参考上面的文档设置国内镜像。

minikube start

创建之后会在VBox里面创建一台虚拟机,然后会创建很多的container和镜像,这需要一些时间,耐心等待就可以了。

# 查看状态
minikube status
# 进入到创建的虚拟机里面
minikube ssh
# 查看容器
docker ps

这里有很多的容器,他们就是组成k8s的组件。

创建之后我们就可以用kubectl去链接我们这个单节点的集群了,在开始使用之前我们需要安装kubectl,他是一个客户端,他可以获取集群的运行信息和创建k8s的资源,比如pod,development。安装

# 查看信息
kubectl version
# 查看k8s的pod,这里面展示的都是一些核心的组件,是他们组成了k8s
kubectl get pod --all-namespaces

停止minikube

# 停止
minikube stop
# 删除
minikube delete
# 启动dashboard服务,可以通过网页访问k8s集群
minikube dashboard

Kubernetes中的基本概念和操作

kubectl有一个自动补全的方法completion,可以使用--help查询设置方法

kubectl completion --help

设置之后使用tab按键就会出现提示方法。

kubectl默认会查看.kube下面的config文件来操作k8s, 我们也可以自己设置这个config中的设置来管理k8s的操作。我们可以通过config命令查看。

kubectl config current-context
kubectl config get-contexts

切换context, 可以将不同的cluster配置到config中,然后通过切换来设置不同的操作。

kubectl config use-context [kubeadm]
  1. 节点和标签

master节点上会运行核心的功能,比如调度器,在node节点运行的是部署应用。

# 查询当前有哪些节点
kubectl get node
# 查询指定节点
kubectl get node k8s-master
# 查询指定节点的详细信息
kubectl describe node k8s-master

一般很少查看node的详细信息,可以通过-o 添加参数,输出更多的信息。 wide或者yaml,json

kubectl get node -o wide

node中有个东西叫做label,标签。用于分组, 可以使用下面的命令查看label,label一般是键值对类型。

# 查看label
get node --show-labels
# 设置label
kubectl label node k8s-master env=test
# 删除label,name-
kubectl label node k8s-master env-

ROLES是角色,默认只有master具有角色,node不存在角色,这个是不对的,roles是一种特殊的label,我们也可以设置他。

# 设置node1的roles
kubectl label node k8s-node1 node-role.kubernetes.io/worker=
  1. pod

一个或者一组应用容器,他们分享资源比如volume,分享相同的命名空间的容器,如网络空间。POD是k8s里面的最小调度单位,在k8s里面我们不会直接操作container,而是操作pod,一个pod可能包含多个container。因为pod共享一个name space, 所以它里面的container可以直接localhost通信。

创建pod要通过yml文件,类似下面的方式, 这里的king是Pod, 这个spec里面要声明展示几个container。这里启动了nginx和busybox两个container,他们是可以互相通信的。

apiVersion: v1
kind: Pod
metadata:
    name: nginx-busybox
spec:
    containers:
    - name: nginx
        image: nginx
        ports:
        - containerPort: 80
    - name: busybox
        image: busybox
        command: ["/bin/sh"]
        args: ["-c", "while true; do echo hello; sleep 10; done"]

有了这个文件我们就可以通过kubectl创建Pod了。-f指定配置文件,

kubectl create -f nginx_busybox.yml

创建之后我们可以对pod进行操作。

# 查看pod, 会显示pod的状态和里面container的状态
kubectl get pods
# 获取pod的详细信息
kubectl describe pod nginx-busybox
# 返回更多的信息,ip地址等
kubectl get pods nginx-busybox -o wide
# 进入到pod里面的container里,如果有多个container默认会进入到第一个里面
kubectl exec nginx-busybox -it sh
# 可以通过-c参数指定进入那个container
kubectl exec nginx-busybox -c nginx -it sh
# 删除掉pod
kubectl delete -f nginx_busybox.yml
  1. mamespace命名空间

namespace命名空间用于不同team,不同project之间的隔离,在不同的命名空间中,各种资源的名字是相互独立,比如可以具有相同名称的pod存在。

我们可以通过kubectl获取到当前系统与有那些namespace, 默认情况下会有default,public、system、lease四个namespace

kubectl get namespace

如果要创建namespace可以直接通过create就可以了。

kubectl create namespace demo

有了namespace就可以非常方便的根据namespace对资源进行过滤。

kubectl get pod --namespace kube-system

我们可以在yml中指定创建的pod所在的namespace, 通过namespace关键字,如果不指定系统会默认把namespace放在default里面。

metadata:
    name: nginx
    namespace: demo

查看所有的namespace

kubectl get pod --all-namespaces
  1. 创建自己的context

可以通过设置改变当前默认的namespace, 这就可以通过context去实现,其实他就是kubectl的config。

# 创建
kubectl config set-context demo --user=minikube --cluster=minikube --namespace=demo
# 设置
kubectl config use-context demo
# 查看
kubectl config get-contexts
# 删除,要保证不在当前要删除的context中
kubectl config delete=context demo
  1. Deployment

我们知道k8s的架构中有master节点和node节点,master节点中有API Server,Scheduler,etcd,和controller manager。