3.1 安装k8s集群

  1. 使用云厂商提供的k8s服务

  2. kubeadm(https://github.com/kubernetes/kubeadm)

  3. 使用Docker Desktop(mac,win)

  4. 使用minikube(http://github.com/kubernetes/minikube)

    1
    2
    3
    4
    5
    6
    7
    
    # 运行
    # 启动时指定国内镜像minikube start --image-mirror-country='cn' --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers'
    minikube start
    # 状态
    minikube status
    # 登录
    minikube ssh
    
  5. 使用kind(不成熟,不推荐)

  6. 最复杂的方法(https://github.com/kelseyhightower/Kubernetes-the-hard-way)

3.2 与k8s集群交互

下载kubectl

  1. 下载kubectl(https://github.com/kubernetes/kubectl)

  1. 添加别名:
1
2
# .zshrc
alias k=kubectl
  1. 自动补全:
1
2
source <(kubectl completion bash)
complete -o default -F __start_kubectl k
  1. 配置文件~/.kube/config

使用kubectl

1
2
3
4
5
6
# 获取集群信息
kubectl cluster-info
# 查看nodes
kubectl get nodes
# node详情
k describe nodes minikube

dashboard

1
minikube dashboard

3.3 运行应用

使用命令行创建deployment

1
k create deployment kiada --image qiaocc/kiada:0.1

查看deployment:

1
kubectl get deployments

你可能想要查看container的状态:

1
kubectl get containers

返回报错, error: the server doesn’t have a resource type “containers”

实际上,在k8s中没有container类型, container不是k8s中最小的单元。

Pod

在Kubernetes中,不是部署单个容器,而是部署一组位于同一位置的容器,即所谓的pod。

特点:

  • 一组密切关联的容器
  • 在同一个节点运行
  • 共享Linux namespace

我们可以认为,每个pod是一个独立的物理机。

查看pod:

1
kubectl get pods

查看详情:

1
kubectl describe pod

运行kubectl create后,k8s在背后做了什么事情?

执行kubectl create命令时,会先想api server发送一个http请求, 说明我要创建一个deployment了。k8s创建Pod对象(这时候,只是创建对象,还没有真正创建pod)。然后将pod对象调度到工作节点,节点上的kubelete会指导Docker创建对应的容器。

暴露应用

应用已经跑起来了,如何访问这个服务呢?每个pod有独立的ip,但是这个ip只能通过集群内部访问。如何在集群外部访问呢?

一种办法是,创建Service,指定类型是LoadBalancer。

1
kubectl expose deployment kiada --type=LoadBalancer --port 8080

这个命令会:

  • 把所有属于kiada的pod,作为服务暴露出去。
  • 外部用户通过负载均衡访问

查看刚刚创建的服务:

1
kubectl get service

创建服务的流程:

其中, 第3步,k8s本身不提供负载均衡。如果你的集群在云上部署,他会使用云厂商的负载均衡。

EXTERNAL-IP状态从pending改为真正的ip后, 就可以使用curl命令访问:

1
curl 35.246.179.22:8080

注意:minikube不支持这种方式。

minikube如何访问服务呢?

1
minikube service kiada --url

水平扩展

现在我们运行了一个单实例的应用。如果突然有很多人访问应用,那么单实例就抗不住大量的流量。这时候,你需要额外的实例,去分担整个流量。这就是水平扩展。

1
kubectl scale deployment kiada --replicas=3

你只需要告诉k8s,最终想要达到的效果是, 有3个kiada的副本。k8s就会自动扩展。

这是k8s中的一个基础原则。你只要告诉k8s,最终想实现的效果,k8s就会去实现它。你不用关心k8s如何实现的。k8s会自动检查当前状态,和最终实现的状态,它们两者的差异,最终会决定如何实现它。

1
2
3
$ k get deployments
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
kiada   3/3     3            3           4h56m

3个实例已经up-to-date, 已经ready。

我们查看一下pod的信息:

1
2
3
4
5
$ k get pods
NAME                     READY   STATUS    RESTARTS   AGE
kiada-5c7544c656-46hfr   1/1     Running   0          64s
kiada-5c7544c656-g8mnr   1/1     Running   0          64s
kiada-5c7544c656-vwtp5   1/1     Running   0          24m

所有pod都已经ready,状态是Running。

如果你运行的是单节点集群, 那么所有pod都在同一个节点。

如果是多节点集群, 怎么查看pod位于哪个节点呢?

1
2
3
4
5
k get pods -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP           NODE                       NOMINATED NODE   READINESS GATES
kiada-5c7544c656-46hfr   1/1     Running   0          80s   10.74.0.71   cn-shanghai.172.19.85.52   <none>           <none>
kiada-5c7544c656-g8mnr   1/1     Running   0          80s   10.74.0.72   cn-shanghai.172.19.85.52   <none>           <none>
kiada-5c7544c656-vwtp5   1/1     Running   0          24m   10.74.0.70   cn-shanghai.172.19.85.52   <none>           <none>

多运行几次,观察一下响应:

1
2
3
4
5
6
7
8
9
$ curl 47.101.61.136:8080

Kiada version 0.1. Request processed by "kiada-5c7544c656-46hfr". Client IP: ::ffff:172.19.85.53
 ~/.kube  curl 47.101.61.136:8080
Kiada version 0.1. Request processed by "kiada-5c7544c656-46hfr". Client IP: ::ffff:172.19.85.53
 ~/.kube  curl 47.101.61.136:8080
Kiada version 0.1. Request processed by "kiada-5c7544c656-g8mnr". Client IP: ::ffff:10.74.0.65
 ~/.kube  curl 47.101.61.136:8080
Kiada version 0.1. Request processed by "kiada-5c7544c656-46hfr". Client IP: ::ffff:172.19.85.53

我们会发现, 请求由不同的pod来处理。