本篇已加入《.NET Core on K8S学习实践系列文章索引》,可以点击查看更多容器化技术相关系列文章。

在上一个小系列文章《ASP.NET Core on K8S学习初探》中,通过在Windows上通过Docker for Windows搭建了一个单节点的K8S环境,并初步尝试将ASP.NET Core WebAPI项目部署到了K8S,把玩了一下快速部署和实例伸缩。这个系列开始,会继续学习K8S以及在Linux上搭建集群来深入把玩。本篇会回顾一下K8S的基本概念以及架构组成,然后会通过Kubeadm快速地搭建一个K8S集群供后续学习把玩之用。

一、K8S基础概念回顾

  1.Cluster 集群

  计算、存储和网络资源的集合,Kubernetes利用这些资源运行各种基于容器的应用。

  2.Master

  Master是Cluster的大脑,负责调度(决定将应用放在哪里运行),一般为了实现高可用,会有多个Master。

  3.Node

  负责运行具体的容器,Node由Master管理,它会监控并汇报容器的状态,同时根据Master的要求管理容器的生命周期。
  eg. 在交互实验中,这个Cluster中只有一个主机,它既是Master也是Node。

  4.Pod

  Kubernetes的最小工作单元,每个Pod包含一个或多个容器。Pod中的容器会被作为一个整体被Master调度到一个Node上运行。
  (1)为何引入Pod?
  一是方便管理:
  有些容器天生联系紧密,需要在一起工作。Pod提供了比容器更高层次的抽象,将它们封装到一个部署单元中。K8S以Pod为最小单位进行调度、扩展、共享资源、管理生命周期。
  eg.正例:File Puller & Web Server => 需要部署在一起工作
    反例:Tomecat & MySQL => 不需要部署在一起工作
  二是可以共享资源和通信:
  Pod中所有容器使用同一个网络namespace,即相同的IP和端口空间,可以直接用localhost通信,而且还可以共享存储(本质是通过将Volume挂载到Pod中的每个容器)
  (2)如何使用Pod?
  运行单个容器:one-container-per-Pod,K8S中最常见的模型,即使这种情形下,K8S管理的也是Pod而不是单个容器。
  运行多个容器:将联系非常紧密的多个容器部署到一个Pod中,可以直接共享资源。

  5.Controller

  K8S不会直接创建Pod,是通过Controller来管理Pod的。为了满足不同业务场景,K8S提供了多种Controller:
  (1)Deployment
  最常见的Controller,可以管理Pod的多个副本,并确保Pod按照期望的状态运行。
  (2)ReplicaSet
  实现了Pod的多副本管理,使用Deployment时会自动创建ReplicaSet。换句话说,Deployment是通过ReplicaSet来管理Pod的多个副本的,通常不需要直接使用ReplicaSet。
  (3)DaemonSet
  用于每个Node最多只运行一个Pod副本的场景,DaemonSet通常用于运行daemon(守护进程、后台程序)。
  (4)StatefuleSet
  用于保证Pod的每个副本在整个生命周期中名称是不变的,而其他的Controller不提供这个功能。(非StatefuleSet下,当某个Pod发生故障需要删除并重启时,Pod的名称是会变化的)
  (5)Job
  用于运行结束就删除的应用,其他Controller下Pod通常是长期持续运行的。

  6.Service

  K8S定义了外界访问一个或一组特定Pod的方式,就是Service。每个Service有自己的IP和端口,并且为Pod提供了负载均衡。
  如果说K8S运行Pod的任务是交给了Controller去做,那么访问Pod的任务则是交给了Service去做。

  7.Namespace

  Namespace将一个物理的Cluster从逻辑上划分为多个虚拟Cluster,每个虚拟Cluster就是一个Namespace,不同Namespace中的资源是完全隔离的。
K8S中会自动创建两个Namespace:
  (1)default:创建资源时如果不指定Namespace就会放到这里
  (2)kube-system: K8S自己创建的系统资源都会放到这个Namespace中

二、K8S集群架构解析

  下面展示了一个最小化的K8S集群,一个master节点和两个node节点:
*.master上也有kubelet和kube-proxy是因为master同时也是一个Node

  1.Master节点

  K8S集群的“大脑”,运行以下多个Daemon服务:
  • API Server(kube-apiserver)
    • 提供Restful API => Kubernetes API,供其他组件调用以管理Cluster的各种资源
  • Scheduler(kube-scheduler)
    • 负责决定将Pod放在哪个Node上Run起来
    • 调度时会根据指定算法选择Pod(eg.集群拓扑结构、各节点负载情况、HA等等)
  • Controller Manager(kube-controller-manager)
    • 负责管理集群中的各种资源,保证资源处于预期的状态
    • 由多种Controller组成
      • Replication Controller:管理Deployment、StatefuleSet、DaemonSet的生命周期
      • Endpoints Controller
      • Namespace Controller:管理Namespace资源
      • Serviceaccounts Controller
  • Etcd
    • 负责保存K8S集群中的配置信息和各种资源的状态信息
    • 当数据发生变化时,会及时通知K8S相关组件
  • Pod网络
    • 保证Pod能够相互通信,Flannel是一个可选方案

  2.Node节点

  运行Pod的主战场,主要运行以下K8S组件:
  • kubelet
    • Node的Agent,负责创建运行容器与向Master报告运行状态
  • kube-proxy
    • 每个Node都会运行proxy,它负责请求转发到后端的容器
  • Pod网络
    • 保证Pod能够相互通信,Flannel是一个可选方案

三、K8S集群环境搭建

3.1 K8S环境搭建的几种方式

  搭建K8S环境有几种常见的方式如下:

  (1)Minikube

  Minikube是一个工具,可以在本地快速运行一个单点的K8S,供初步尝试K8S或日常开发的用户使用,不能用于生产环境。

  (2)Kubeadm

  Kubeadm是K8S官方社区推出的一套用于简化快速部署K8S集群的工具,Kubeadm的设计目的是为新用户开始尝试K8S提供一种简单的方法。

  (3)二进制包

  除了以上两种方式外,我们还可以通过从官方下载二进制包,手动部署每个组件组成K8S集群,这也是目前企业生产环境中广为使用的方式,但对K8S管理人员的要求较高。

  本次学习实践我们主要借助Kubeadm工具搭建K8S集群,以便后续实践部署ASP.NET Core应用集群。

3.2 搭建前的准备工作

  (1)准备三台Linux服务器

  这里我选择通过VMware Workstaion来搭建3个虚拟机,每个配置2CPU和2G内存,如下图:

  

  (2)配置主机名与静态IP地址如下表所示:

角色 主机名 IP地址
Master k8s-master 192.168.2.100
Node k8s-node1 192.168.2.101
Node k8s-node2 192.168.2.102

  然后,更改hosts文件添加主机名与IP映射关系

# vim /etc/hosts
192.168.2.100 k8s-master
192.168.2.101 k8s-node1
192.168.2.102 k8s-node2

  (3)关闭防火墙

systemctl stop firewalld
systemctl disable firewalld

  (4)关闭selinux

sed -i 's/enforcing/disabled/' /etc/selinux/config
setenforce

  (5)关闭swap => K8S中不支持swap分区

# vim /etc/fstab
#/dev/mapper/centos-swap swap swap defaults

  *.编辑etc/fstab将swap那一行注释掉或者删除掉

  (6)将桥接的IPv4流量传递到iptables的链

# cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables =
net.bridge.bridge-nf-call-iptables =
EOF # sysctl --system

3.3 安装Docker&Kubeadm&Kubelet

  以下步骤请在所有节点中操作:

  (1)安装Docker

# wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O
/etc/yum.repos.d/docker-ce.repo
# yum -y install docker-ce-18.06..ce-.el7
# systemctl enable docker && systemctl start docker
# docker --version
Docker version 18.06.-ce, build e68fc7a

  *.这里安装的是18.06社区版,如果你之前有安装低版本的Docker,为了配合本次实验的K8S版本(1.13.x),建议先卸载掉,卸载过程可以参考这篇文章《CentOS7 Docker升级》。

  (2)添加阿里云Yum软件源

# cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=
gpgcheck=
repo_gpgcheck=
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

  (3)安装Kubeadm&Kubelet&Kubectl

  注意:本次部署K8S版本号为1.13.3

# yum install -y kubelet-1.13. kubeadm-1.13. kubectl-1.13.
# systemctl enable kubelet

  遇到的一些坑如下:

  ① 碰到需要kubernetes-cni的问题:

#####错误:软件包:kubelet-1.13.-.x86_64 (kubernetes)
需要:kubernetes-cni = 0.6.
可用: kubernetes-cni-0.3.0.1-.07a8a2.x86_64 (kubernetes)
kubernetes-cni = 0.3.0.1-.07a8a2
可用: kubernetes-cni-0.5.-.x86_64 (kubernetes)
kubernetes-cni = 0.5.-
可用: kubernetes-cni-0.5.-.x86_64 (kubernetes)
kubernetes-cni = 0.5.-
可用: kubernetes-cni-0.6.-.x86_64 (kubernetes)
kubernetes-cni = 0.6.-
正在安装: kubernetes-cni-0.7.-.x86_64 (kubernetes)
kubernetes-cni = 0.7.-
您可以尝试添加 --skip-broken 选项来解决该问题
您可以尝试执行:rpm -Va --nofiles --nodigest

  解决:手动安装kubernetes-cni对应的版本

yum install -y kubelet-1.13. kubeadm-1.13. kubectl-1.13. kubernetes-cni-0.6. 

  ② 使用yum安装程序时,提示xxx.rpm公钥尚未安装

从 https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg 检索密钥
导入 GPG key 0xA7317B0F:
用户ID : "Google Cloud Packages Automatic Signing Key <gc-team@google.com>"
指纹 : d0bc 747f d8ca f711 d6fa c208 a731 7b0f
来自 : https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg e3438a5f740b3a907758799c3be2512a4b5c64dbe30352b2428788775c6b359e-kubectl-1.13.-.x86_64.rpm 的公钥尚未安装 失败的软件包是:kubectl-1.13.-.x86_64
GPG 密钥配置为:https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg

  解决:使用 yum install xxx.rpm --nogpgcheck 命令格式跳过公钥检查,比如跳过kubectl和kubeadm的公钥检查如下命令:

yum install kubectl-1.13.-.x86_64 --nogpgcheck
yum install kubeadm-1.13.-.x86_64 --nogpgcheck

3.4 部署Kubernetes Master

  以下步骤请在k8s-master节点上操作:

kubeadm init \
--apiserver-advertise-address=192.168.2.100 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.13.3 \
--service-cidr=10.1.0.0/16 \
--pod-network-cidr=10.244.0.0/

PS:由于默认拉取镜像地址k8s.gcr.io国内无法访问,这里指定阿里云镜像仓库地址(registry.aliyuncs.com/google_containers)。官方建议服务器至少2CPU+2G内存,当然内存1G也是可以的,但是会出Warning,建议还是老老实实升2G内存把。

  

  接下来,为了顺利使用kubectl命令,执行以下命令:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# kubectl get nodes

  这时你可以使用kubectl了,当你执行完kubectl get nodes之后,你会看到如下状态:

  

3.5 部署Pod网络插件(CNI)

  同样,继续在k8s-master上操作:

kubectl apply -f \
https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml

  然后通过以下命令验证:全部为Running则OK,其中一个不为Running,比如:Pending、ImagePullBackOff都表明Pod没有就绪

  

  如果其中有的Pod没有Running,可以通过以下命令查看具体错误原因,比如这里我想查看kube-flannel-ds-amd64-8bmbm这个pod的错误信息:

kubectl describe pod kube-flannel-ds-amd64-8bmbm -n kube-system

  在此过程中可能会遇到无法从qury.io拉取flannel镜像从而导致无法正常Running,解决办法如下:

  使用国内云服务商提供的镜像源然后通过修改tag的方式曲线救国

docker pull quay-mirror.qiniu.com/coreos/flannel:v0.11.0-amd64
docker tag quay-mirror.qiniu.com/coreos/flannel:v0.11.0-amd64 quay.io/coreos/flannel:v0.10.0-amd64
docker rmi quay-mirror.qiniu.com/coreos/flannell:v0.11.0-amd64

  这时,我们再看看master节点的状态就会从NotReady变为Ready:

  

  那么,恭喜你,Master节点部署结束了。如果你只想要一个单节点的K8S,那么这里就完成了部署了。

3.6 加入Kubernetes Node

  在两台Node节点上执行join命令:

kubeadm join 192.168.2.100: --token ekqxk2.iiu5wx5bbnbdtxsw --discovery-token-ca-cert-hash \
sha256:c50bb83d04f64f4a714b745f04682b27768c1298f331e697419451f3550f2d05

  这里需要注意的就是,带上在Master节点Init成功后输出的Token。如果找不到了,没关系,可以通过以下命令来查看:

kubeadm token list

  Node节点上成功join之后会得到以下信息:

  

  这时,我们在master节点上执行以下命令可以看到集群各个节点的状态了:

  

  如果看到两个Node状态不是Ready,那么可能需要检查哪些Pod没有正常运行:

kubectl get pod --all-namespaces

  然后按照3.5中的检查方式进行检查并修复,最终kubectl get nodes效果应该状态都是Running。注意的是在检查时需要注意是哪个Node上的错误,然后在对应的Node进行修复,比如拉取flannel镜像。

  至此,一个最小化的K8S集群已经搭建完毕。

3.7 测试Kubernetes集群

  这里为了快速地验证一下我们的K8S集群是否可用,创建一个示例Pod(这里默认是一个副本):

kubectl create deployment nginx --image=nginx
kubectl expose deployment nginx --port= --type=NodePort
kubectl get pod,svc

  

  如果想要看到更多的信息,比如pod被部署在了哪个Node上,可以通过 kubectl get pods,svc -o wide来查看。

  

  因为是NodePort方式,因此其映射的端口号会在30000-32767范围内随机取一个,我们可以直接通过浏览器输入IP地址访问,比如这时我们通过浏览器来访问一下任一Node的IP地址加端口号,例如192.168.2.101:31174或192.168.2.102:31174

  

  

  如果能够成功看到,那么恭喜你,你的K8S集群能够成功运行了,万里长征走完了第一步!

四、小结

  本文快速地介绍了一下Kubernetes的核心构成组件及其作用,然后通过在三台Linux主机上通过Kubeadm搭建了一个Master节点两个Node节点的集群,最后通过部署一个Deployment来快速地验证了一下集群是否可用。下一篇会通过一个ASP.NET Core的部署例子来演示和介绍一下各个组件之间是如何协作的,以及部署Dashboard。

参考资料

(1)CloudMan,《每天5分钟玩转Kubernetes

(2)李振良,《一天入门Kubernets教程

(3)李振良,《30分钟部署一个Kubernetes集群

(4)cao_xiaobo,《CentOS7 部署K8S集群

作者:周旭龙

出处:https://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

ASP.NET Core on K8S深入学习(1)K8S基础知识与集群搭建的更多相关文章

  1. ASP.NET Core应用程序容器化、持续集成与Kubernetes集群部署(一)(转载)

    本文结构 ASP.NET Core应用程序的构建 ASP.NET Core应用程序容器化所需注意的问题 应用程序的配置信息 端口侦听 ASP.NET Core的容器版本 docker镜像构建上下文(B ...

  2. Zookeeper学习之路 (二)集群搭建

    ZooKeeper 软件安装须知 鉴于 ZooKeeper 本身的特点,服务器集群的节点数推荐设置为奇数台.我这里我规划为三台, 为别为 hadoop1,hadoop2,hadoop3 ZooKeep ...

  3. spark学习(1)--ubuntu14.04集群搭建、配置(jdk)

    环境:ubuntu14.04 jdk-8u161-linux-x64.tar.gz 1.文本模式桌面模式切换 ctrl+alt+F6 切换到文本模式 ctrl + alt +F7 /输入命令start ...

  4. 大数据学习系列(7)-- hadoop集群搭建

    1.配置ssh免登陆 #进入到我的home目录 cd ~/.ssh ssh-keygen -t rsa 执行完这个命令后,会生成两个文件id_rsa(私钥).id_rsa.pub(公钥) 将公钥拷贝到 ...

  5. 大数据学习系列(6)-- zookeeper集群搭建

    下载 wget http://mirrors.shuosc.org/apache/zookeeper/zookeeper-3.3.6/zookeeper-3.3.6.tar.gz tar -zxvf ...

  6. java 学习笔记(三)ZooKeeper集群搭建实例,以及集成dubbo时的配置 (转)

    ZooKeeper集群搭建实例,以及集成dubbo时的配置 zookeeper是什么: Zookeeper,一种分布式应用的协作服务,是Google的Chubby一个开源的实现,是Hadoop的分布式 ...

  7. Es学习第十课,ElasticSearch集群搭建

    前面几课我们已经把ES的基本概念和查询了解了,大家知道ES的核心优势就是天生支持分布式,所以,这课我们专门讲讲怎么搭建实现ES的集群部署. ES分布式原理 1.es分布式概念 主分片(Primary ...

  8. K8S之集群搭建

    转自声明 ASP.NET Core on K8S深入学习(1)K8S基础知识与集群搭建 1.K8S环境搭建的几种方式 搭建K8S环境有几种常见的方式如下: (1)Minikube Minikube是一 ...

  9. ASP.NET Core 借助 Helm 部署应用至K8S

    前言 玩K8S也有一段时间了,借助云服务提供商的K8S控制台,已经可以很方便的快速部署应用至K8S.通过简单的点击,可以一次性帮忙创建K8S 对象:Deployment.Service.Ingress ...

随机推荐

  1. SpringBoot从入门到精通二(SpringBoot整合myBatis的两种方式)

    前言 通过上一章的学习,我们已经对SpringBoot有简单的入门,接下来我们深入学习一下SpringBoot,我们知道任何一个网站的数据大多数都是动态的,也就是说数据是从数据库提取出来的,而非静态数 ...

  2. Spark学习之路(十)—— Spark SQL 外部数据源

    一.简介 1.1 多数据源支持 Spark支持以下六个核心数据源,同时Spark社区还提供了多达上百种数据源的读取方式,能够满足绝大部分使用场景. CSV JSON Parquet ORC JDBC/ ...

  3. java内存管理机制剖析(一)

    最近利用工作之余学习研究了一下java的内存管理机制,在这里记录总结一下. 1-1.java内存区域 当java程序运行时,java虚拟机会将内存划分为若干个不同的数据区域,这些内存区域创建和销毁的时 ...

  4. python3下re模块的使用

    **explain:**python3中的re库是一个正则匹配的函数库,里面包含了各种功能的正则函数,下面,我们一起学习下其中的几个常用函数 * **match()方法**: 从主串的起始位置开始匹配 ...

  5. sql-实现select取行号、分组后在分组内排序、每个分组中的前n条数据

    表结构设计: 实现select取行号 sql局部变量的2种方式 set @name='cm3333f'; select @id:=1; 区别:set 可以用=号赋值,而select 不行,必须使用:= ...

  6. HDU 1542:Atlantis(扫描线+线段树 矩形面积并)***

    题目链接 题意 给出n个矩形,求面积并. 思路 使用扫描线,我这里离散化y轴,按照x坐标从左往右扫过去.离散化后的y轴可以用线段树维护整个y上面的线段总长度,当碰到扫描线的时候,就可以统计面积.这里要 ...

  7. sqlserver、oracle数据库排序空值null问题解决办法

    转:https://www.cnblogs.com/pacer/archive/2010/03/02/1676371.html [sqlserver]: sqlserver 认为 null 最小. 升 ...

  8. 爬取链家网租房图 使用ImagesPipeline保存图片

    # 爬虫文件 # -*- coding: utf-8 -*- import scrapy import os from urllib import request from lianjia.items ...

  9. javascript高级笔记——内含事件,DOM,BOM等

    JavaScript高级笔记 1,DOM的简单学习 1.1,功能:用于控制HTML文档的内容: 1.2,获取页面标签对象:Element *document.getElementById(" ...

  10. RDBMS与数据库之间的关系

    什么是数据库? 数据库就是用来存放数据的仓库,它是一种特殊的文件. 什么是关系型数据库? 关系型数据库就是指建立在关系模型基础上的数据库,通常由多张表组成,这些表之间存在一定的关系. 什么是RDBMS ...