Kubernetes(一)Overview

1. Kubernetes介绍

要了解Kubernetes,首先我们需要了解Container与Orchestration。

 

Docker

Docker的出现是为了解决:部署依赖、以及兼容性、以及繁琐的启动配置问题

Docker使用的是底层的OS(也就是docker中的share kernel)。在container中,虽然定义了AMI中的操作系统,但是实际上,Container中不会运行一个OS,而是使用底层的OS Kernel。如下图所示:

与之不同的是Virtual Machine,云计算虚拟机中,底层同样是Hardware Infrastructure 以及 OS。然后是Docker这层对应的是Hypervisor,之上就是VM。每个Virtual Machine中也是有Libs与Deps,以及Application运行,这些都与Container一样。唯一不同的地方在于,VM中有一套独立的OS,而Container均是使用的底层shared OS。所以VM中会大量使用底层系统资源,而Docker不会使用大量底层资源,且启动速度相对来说会更快。

Docker中的Image可以封装一个执行环境,我们可以通过docker运行一个Image,以保证运行环境的一致性。

 

安装docker

在各个节点上均安装docker:

sudo yum install docker

 

启动 docker 守护进程:

sudo /etc/init.d/docker start

 

测试docker run:

sudo docker run docker/whalesay cowsay boo

 

Container Orchestration

现在我们知道了Docker 与 Container,在一个Docker Host 上,可以运行多个Docker Container。

但是在生产环境中,场景会更为复杂,常见的需求如:

  1. 一个Container依赖于另外的Container,如Web Container 依赖于 MySQL Container
  2. 根据流量,Container扩容与缩容

为了满足这些需求,首先我们至少需要多个Docker Host,以提供更多的Container 资源用于运行。之后我们还需要一个用于跨Docker Host 管理Container的系统,便是Container Orchestration:

当前主要有三种Orchestration技术,分别为:

  1. Docker Swarm :由Docker提出。部署简单,便于使用,但是缺少一些高级功能,对复杂应用的使用场景有限
  2. Kubernetes:当前最流行。部署稍微复杂,可以提供很多用户自定义部署,并支持部署复杂的架构
  3. Mesos:由Apache提出。部署复杂,但是支持一些高级功能

所以Kubernetes是一种Orchestration技术,可用于部署并管理集群中成千上万的Containers,实现用户业务架构。

 

Kubernetes Set Up

这里我们选择Kubeadm工具进行部署,基于以下顺序:

  1. 一个Master节点以及(一个或多个)Worker节点
  2. 在所有节点上均安装并启动docker守护进程
  3. 在所有节点上均安装kubeadm
  4. 初始化Master节点
  5. 设置Master与Worker节点间的POD Network
  6. 将Worker节点加入Master节点

以上是自建时所需要做的步骤,不过当前有各种第三方工具可用于部署。这里我们使用的是 kops,实例我们使用的是 AWS EC2。kops的官方文档如下:

https://github.com/kubernetes/kops/blob/master/docs/getting_started/aws.md

kops将集群的状态保存在s3中,所以我们需要创建一个 kops 用的 s3 桶,这个桶也会用于保存集群配置。

在使用 kops 启动集群后,我们可以使用kubectl 确认一下节点状态:

> kubectl get nodes
NAME                                               STATUS   ROLES    AGE    VERSION
Ip-xx.xx.xx.xx                            Ready    node     3h2m   v1.15.5
Ip-xx.xx.xx.xx                            Ready    node     3h2m   v1.15.5
Ip-xx.xx.xx.xx                            Ready    master   3h3m   v1.15.5

 

集群组件

在 Kubernetes 中,构成K8s集群的很多组件都是使用k8s自身进行部署的,所有k8s组件都在kube-system 命名空间下,我们接下来介绍以下几个比较重要的组件。

 

Kubernetes Proxy

Kubernetes Proxy 负责转发网络流量到 Kubernetes 集群中的负载均衡服务。为了完成此目的,proxy必须在每个节点上都运行。K8s有一个API对象名为DaemonSet,在很多集群中都是通过它完成的此任务。不过这取决于集群的配置,并不是所有集群都用的 DaemonSet。但是集群中所有集群都会运行kube-proxy container。

 

Kubernetes DNS

K8s 也会运行一个DNS server,它为集群内部的dns 命名与解析提供服务。这个DNS server也会以一个replicated service 运行在集群中。根据集群的大小,我们可能会看到一个或多个DNS servers。一个运行的dns server如:

> kubectl get deployments --namespace=kube-system kube-dns
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
kube-dns   2/2     2            2           5h18m

 

也会有 k8s 服务用于为 DNS server 做负载均衡,如:

> kubectl get service --namespace=kube-system kube-dns
NAME       TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)         AGE
kube-dns   ClusterIP   100.64.0.10   <none>        53/UDP,53/TCP   5h18m

 

这个负载均衡使得集群的 DNS 服务有一个ip地址(100.64.0.10)。如果我们登录到一个container中,则可以看到这个地址已被写入到了 /etc/resolv.conf 文件。

 

2. Kubernetes 组件

一个Kubernetes集群由控制节点(master)和工作节点(node)构成,每个节点上都会安装不同的组件。

  • Master:集群的控制层面,负责集群的决策。
    • ApiServer:资源操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制
    • Scheduler:负责集群资源调度,按照预定的调度策略将Pod调度到相应的node节点上。例如根据负载,计算到将Pod调度到node 1 上,但并不负责分配的工作,只计算,分配由ControllerManager 完成
    • ControllerManager:负责维护集群的状态,比如程序部署安排、故障检测、自动扩展、滚动更新等
    • Etcd:负责存储集群中各种资源对象的信息,默认用的etcd,也可以配置为其他数据库。例如Pod在哪个节点。

 

  • Node:集群的数据层面,负责为容器提供运行环境
    • Kubelet:负责维护容器的生命周期,即通过控制docker,来创建、更新、销毁容器
    • KubeProxy:负责提供集群内部的服务发现和负载均衡;例如Pod部署了一个nginx,外部需要访问到它时,需通过KubeProxy
    • Docker:负责节点上容器的各种操作

如下图所示:

各组件之间调用关系

下面以部署一个nginx服务,来说明kubernetes系统各个组件之间的调用关系:

  1. 首先要明确,一旦kubernetes环境启动后,master和node都会将自身的信息存储到etcd数据库中
  2. 一个nginx服务器的安装请求会首先发送到master的apiServer
  3. apiServer组件会调用scheduler组件来决定到底应该把哪个服务安装到哪个node节点上。此时,它会从etcd中读取各个node节点的信息,然后按照一定的算法进行选择,并将结果告知apiServer
  4. apiServer调用controller-manager去调度Node节点安装nginx服务
  5. kubelet接受到指令后,会通知docker,然后由docker来启动一个nginx的pod。Pod是kubernetes的最小操作单元,容器必须跑在pod中
  6. 一个nginx服务就运行了,如果需要访问nginx,就需要通过kube-proxy来对pod产生访问的代理。

这样,外网用户即可访问集群中的nginx服务了。

 

Kubernetes 各个概念

  • Master:集群控制节点,每个集群需要至少一个master节点负责集群的管控
  • Node:工作负载节点,由master分配容器到这些node工作节点上,然后node节点上的docker负责容器运行
  • Pod:kubernetes的最小控制单元,容器都是运行在pod中的,一个pod中可以有1个或多个容器
  • Controller:控制器,通过它来实现对pod的管理,比如启动pod、停止pod、伸缩pod的数量等等
  • Service:pod对外服务的统一入口,下面可以维护同一类的多个pod
  • Label:标签,用于对pod进行分类,同一pod会拥有相同的标签
  • NameSpace:命令空间,用来隔离pod的运行环境

 

如下图所示:

为了让外部分访问到tomcat服务,需要通过一个Service来提供。可以看到Service只映射到了其中3个tomcat 的Pod,这就是通过 Label 对不同的Pod进行的分类。这个是kubernetes定义的标签-选择器机制,通过标签进行定义,通过选择器来进行选择。

默认情况下,所有pod都是可以相互访问的。若是需要隔离访问,则就需要通过NameSpace来实现了。它会对pod进行逻辑区分,仅有同一个NameSpace的pod能够互相访问,实现隔离。

 

3. Kubernetes 集群

集群分类

Kubernetes集群大体上分为两类:一主多从和多主多从。

  • 一主多从:1台Master节点和多台Node节点,搭建简单,但有单机故障风险,适合用于测试环境
  • 多主多从:多台Master节点和多台Node节点,搭建麻烦,安全性高,适合用于生产环境

安装方式

主流方式有kubeadm、minikube、二进制包

  • minikube:快速搭建单节点kubernetes集群
  • kubeadm:快速搭建kubernetes集群
  • 二进制包:从官网下载每个组件的二进制包,依次安装,非常麻烦

 

在kubernetes中service有2种代理模型,一种基于iptables,一种基于ipvs。相较来说,ipvs的性能明显要高一些,但是如果要使用它,需要手动载入ipvs模块。

 

4. 访问 aws eks

1. 启动 eks 集群后,先在客户端安装必要软件:

kubectl:

https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/install-kubectl.html

 

eksctl:

https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/eksctl.html

 

2. 配置kubeconfig

aws eks --region <region-code> update-kubeconfig --name <cluster_name>

 

检查是否可以访问:

> kubectl get nodes

NAME                                        STATUS   ROLES    AGE    VERSION

ip-10-0-1-217.cn-north-1.compute.internal   Ready    <none>   110m   v1.18.9-eks-d1db3c

 

需要注意的是:当您创建 Amazon EKS 集群时,将在控制层面内集群的 RBAC 配置中自动为 IAM 实体用户或角色(例如,创建集群的联合身份用户)授予 system:masters 权限。此 IAM 实体不会出现在 ConfigMap 或任何其他可见配置中,因此请确保保持跟踪哪个 IAM 实体最初创建了集群。要授予其他 AWS 用户或角色与您的集群进行交互的能力,您必须编辑 Kubernetes 内的 aws-auth ConfigMap

 

也就是说,只有创建集群的用户有权限访问集群。若是需要为其他Role或User添加访问集群权限,则需要参考:

https://docs.aws.amazon.com/zh_cn/eks/latest/userguide/add-user-role.html

 

一个参考的配置:

$ cat aws-auth-cm.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: aws-auth
  namespace: kube-system
data:
  mapRoles: |
    - rolearn: arn:aws-cn:iam::xxxxx:role/xxxxx
      username: ec2admin
      groups:
        - system:masters

    - rolearn: arn:aws-cn:iam::xxxxxx:role/eks_node
      username: system:node:{{EC2PrivateDNSName}}
      groups:
        - system:bootstrappers
        - system:nodes

 

5. 测试集群

尝试部署一个nginx程序:

# 部署nginx
kubectl create deployment nginx --image=nginx:1.14-alpine

# 暴露端口
kubectl expose deployment nginx --port=80 --type=NodePort

# 查看服务状态,svc就是service
$ kubectl get pods,svc
NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-55f8fd7cfc-7qzdd   1/1     Running   0          76s

NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/kubernetes   ClusterIP   172.20.0.1       <none>        443/TCP        4h7m
service/nginx        NodePort    172.20.172.246   <none>        80:30210/TCP   26s

=> 此配置说明的是,需要通过访问节点的30210 的端口,此端口会映射到节点的80端口。

# curl node 节点的 30210 端口
$ curl 10.0.1.217:30210
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>

 

posted @ 2021-02-22 23:20  ZacksTang  阅读(339)  评论(0编辑  收藏  举报