手游下载网

手游下载网

Kubernetes 入门教程

admin 73 40

前言

本文是一篇kubernetes(下文用k8s代替)的入门文章,将会涉及k8s的架构、集群搭建、一个Redis的例子,以及如何使用operator-sdk开发operator的教程。在文章过程中,会穿插引出Pod、Deployment、StatefulSet等k8s的概念,这些概念通过例子引出来,更容易理解和实践。文章参考了很多博客以及资料,放在最后参考资料部分。

一k8s架构

我们看下k8s集群的架构,从左到右,分为两部分,第一部分是Master节点(也就是图中的ControlPlane),第二部分是Node节点。

Master节点一般包括四个组件,apiserver、scheduler、controller-manager、etcd,他们分别的作用是什么:

Apiserver:上知天文下知地理,上连其余组件,下接ETCD,提供各类api处理、鉴权,和Node上的kubelet通信等,只有apiserver会连接ETCD。

Controller-manager:控制各类controller,通过控制器模式,致力于将当前状态转变为期望的状态。

Scheduler:调度,打分,分配资源。

Etcd:整个集群的数据库,也可以不部署在Master节点,单独搭建。

Node节点一般也包括三个组件,docker,kube-proxy,kubelet

Docker:具体跑应用的载体。

Kube-proxy:主要负责网络的打通,早期利用iptables,现在使用ipvs技术。

Kubelet:agent,负责管理容器的生命周期。

总结一下就是k8s集群是一个由两部分组件Master和Node节点组成的架构,其中Master节点是整个集群的大脑,Node节点来运行Master节点调度的应用,我们后续会以一个具体的调度例子来解释这些组件的交互过程。

二搭建k8s集群

上面说完了k8s集群中有哪些组件,接下来我们先看下如何搭建一个k8s集群,有以下几种方法(参考文末链接):

当我们安装了DockerDesktopAPP之后,勾选k8s支持就能搭建起来。

使用MiniKube来搭建,社区提供的一键安装脚本。

直接在云平台购买,例如阿里云ack。

使用kubeadmin,这是k8s社区推荐的可以部署生产级别k8s的工具。

使用二进制,下载各组件安装,此教程需要注意,下载的各组件版本要和博客中保持一致,就可以成功。

本文后面的例子均采用本地DockerDesktopAPP搭建的k8s。

➜~kubectlversionClientVersion:{Major:"1",Minor:"21",GitVersion:"",GitCommit:"3cce4a82b44f032d0cd1a1790e6d2f5a55d20aae",GitTreeState:"clean",BuildDate:"2021-08-11T18:16:05Z",GoVersion:"",Compiler:"gc",Platform:"darwin/amd64"}ServerVersion:{Major:"1",Minor:"21",GitVersion:"",GitCommit:"3cce4a82b44f032d0cd1a1790e6d2f5a55d20aae",GitTreeState:"clean",BuildDate:"2021-08-11T18:10:22Z",GoVersion:"",Compiler:"gc",Platform:"linux/amd64"}
三从需求出发

下面我们从一个实际的需求出发,来看看如何在k8s上部署Redis服务。

部署一个Redis服务

支持高可用

提供统一的Point访问地址

1部署单机版

如果我们想在k8s上部署一个单机版本Redis,我们执行下面的命令即可:

➜~kubectlrunredis--image=redispod/rediscreated➜~kubectlgetpodsNAMEREADYSTATUSRESTARTSAGEredis1/1Running05s

可以用kubectlexec来进入到Pod内部连接Redis执行命令:

➜~kubectlexec-itredis--bashroot@redis:/data类型为statefulsetmetadata:name:redis-sfs这里的service下面解释replicas:2镜像版本command:-bash-"-c"-|set-exordinal=`hostname|awk-F'-''{print$NF}'`如果是0,作为主echo/tmp/""/tmp/按照redis-sfs-11/1Running028s

接着我们继续看下主从关系生效了没,查看redis-sfs-1的日志,却发现:

➜~kubectllogs-fredis-sfs-11:S05Nov202108:02:44.243*:63791:S05Nov202108:02:50.287这里的None就是Headless的意思,表示会主动由k8s分配ports:-port:6379name:redis-sfsselector:app:redis-sfs

再次查看,发现redis-sfs-1已经主备同步成功了,因为创建HeadlessService之后,在集群中就是唯一可访问的了。

➜~/redis-sfscreated➜~kubectlgetserviceNAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)/TCP24dredis-sfsClusterIPNonenone6379/TCP33s➜~kubectllogs-fredis-sfs-11:S05Nov202108:23:31.341*:63791:S05Nov202108:23:31.345*MASTER-REPLICAsyncstarted1:S05Nov202108:23:31.345*:S05Nov202108:23:31.346*MasterrepliedtoPING,replicationcancontinue1:S05Nov202108:23:31.346*Partialresynchronizationnotpossible(nocachedmaster)1:S05Nov202108:23:31.348*Fullresyncfrommaster:29d1c03da6ee2af173b8dffbb85b6ad504ccc28f:01:S05Nov202108:23:31.425*MASTER-REPLICAsync:receiving175bytesfrommastertodisk1:S05Nov202108:23:31.426*MASTER-REPLICAsync:Flushingolddata1:S05Nov202108:23:31.426*MASTER-REPLICAsync:LoadingDBinmemory1:S05Nov202108:23:31.431*:S05Nov202108:23:31.431*RDBage0seconds1:S05Nov202108:23:31.431*:S05Nov202108:23:31.431:6379:6379

此时无论我们删除哪个Pod,它都会按照原来的名称被拉起来,从而可以保证准备关系,这个例子只是一个StatefulSet的示例,分析下来可以发现,虽然它可以维护主备关系,但是当主挂了的时候,此时备无法切换上来,因为没有组件可以帮我们做这个切换操作,一个办法是用RedisSentinel,可以参考这个项目的配置:k8s-redis-ha-master,如果你的k8s较新,需要merge此PR.

六Operator

虽然有了StatefulSet,但是这只能对基础版有用,如果想自己定制更加复杂的操作,k8s的解法是operator,简而言之,operator就是定制自己k8s对象及对象所对应操作的解法。

那什么是对象呢?一个Redis集群,一个etcd集群,zk集群,都可以是一个对象,现实中我们想描述什么,就来定义什么,实际上我们定一个是k8syaml中的kind,之前的例子中,我们使用过Pod,Deployment,StatefulSet,它们是k8s默认实现,现在如果要定义自己的对象,有两个流程:

定义对象,比如你的集群默认有几个节点,都有啥组件

定义对象触发的操作,当创建对象时候要做什么流程,HA时候要做什么流程等

operator的方式是基于编程实现的,可以用多种语言,用的最多的就是go语言,通常大家会借助operator-sdk来完成,因为有很多代码会自动生成。相当于operator会生成框架,然后我们实现对应的业务逻辑。

1准备工作

安装好go环境

安装operator-sdk

2初始化项目

然后我们按照官网的sdk例子,来一步一步实现一个memcached的operator,这里也可以换成Redis,但是为了保证和官网一致,我们就按照官网来创建memcachedoperator。

➜~cd$GOPATH/src➜srcmkdirmemcached-operator➜srccdmemcached-operator➜memcac/yangbodong22011/memcached-operator--skip-go-version-check//这里需要注意domain最好是和你在,因为后续会发布docker镜像WritingkustomizemanifestsforyoutoeditWritingscaffoldforyoutoeditGetcontrollerruntime:$/controller-runtime@:$gomodtidyNext:definearesourcewith:$operator-sdkcreateapi

3创建API和Controller

➜memcached-operatoroperator-sdkcreateapi--groupcache--versionv1alpha1--kindMemcached--resource--controllerWritingkustomizemanifestsforyoutoeditWritingscaffoldforyoutoeditapi/v1alpha1/memcached_/memcached_:$gomodtidyRunningmake:$makegeneratego::/controller-tools/cmd/controller-gen@:installingexecutableswith'goget',use'goget-d'.Toinstallusingrequirementsofthecurrentmodule,use'goinstall'.Toinstallignoringthecurrentmodule,use'goinstall'withaversion,like'/cmd@latest'.Formoreinformation,see'gohelpget'or'gohelpinstall'.goget://Users/yangbodong/go/src/memcached-operator/bin/controller-genobject:headerFile="hack/"paths="./"➜memcached-operator

上面的步骤实际上生成了一个operator的框架,接下来我们首先来定义memcached集群都包括啥,将默认实现修改为Size,表示一个Memcached集群中Memcached的数量,最后调用makegenerate和makemanifests来自动生成deepcopy和CRD资源。

➜memcached-operatorvimapi/v1alpha1/memcached_//修改下面Memcached集群的定义//MemcachedSpecdefinesthedesiredstateofMemcachedtypeMemcachedSpecstruct{//+kubebuilder:validation:Minimum=0//SizeisthesizeofthememcacheddeploymentSizeint32`json:"size"`}//MemcachedStatusdefinestheobservedstateofMemcachedtypeMemcachedStatusstruct{//NodesarethenamesofthememcachedpodsNodes[]string`json:"nodes"`}➜memcached-operatormakegenerate/Users/yangbodong/go/src/memcached-operator/bin/controller-genobject:headerFile="hack/"paths="./"➜memcached-operatormakemanifests/Users/yangbodong/go/src/memcached-operator/bin/controller-gen"crd:trivialVersions=true,preserveUnknownFields=false"rbac:roleName=manager-rolewebhookpaths="./"output:crd:artifacts:config=config/crd/bases➜memcached-operator

4实现Controller

接下来是第二步,定义当创建一个Memcached集群时候,具体要干啥。

➜memcached-operatorvimcontrollers/memcached_,注意,//注释中的也要换,实际不是注释,而是一种格式➜memcached-operatorgomodtidy;makemanifests/Users/yangbodong/go/src/memcached-operator/bin/controller-gen"crd:trivialVersions=true,preserveUnknownFields=false"rbac:roleName=manager-rolewebhookpaths="./"output:crd:artifacts:config=config/crd/bases
5发布operator镜像
➜memcached-operatorvimMakefile将-IMG?=controller:latest改为+IMG?=$(IMAGE_TAG_BASE):$(VERSION)➜memcached-operatordockerlogin//提前登录下'thaveaDockerID,headoverto!Yourpasswordwillbestoredunencryptedin/Users/yangbodong/.docker/➜memcached-operatorsudomakedocker-builddocker-push==writingimagesha256:a7313209==/yangbodong22011/memcached-operator:0.0.10.0sfac03a24e25a:Pushed6d75f23be3dd::digest:sha256:242380214f997d98186df8acb9c13db12f61e8d0f921ed507d7087ca4b67ce59size:739

6修改镜像和部署

➜memcached-operatorvimconfig/manager/:controller:latest修改为yangbodong22011/memcached-operator:0.0.1➜memcached-operatorvimconfig/default/manager_auth_proxy_因为国内访问不了:/kubebuilder/kube-rbac-proxy:修改为kubesphere/kube-rbac-proxy:➜memcached-operatormakedeployconfigmap/memcached-operator-manager-configcreatedservice/memcach/memcached-operator-controller-managercreated➜memcached-operatorkubectlgetdeployment-nmemcached-operator-system//ready说明operator已经部署了NAMEREADYUP-TO-DATEAVAILABLEAGEmemcached-operator-controller-manager1/11131s➜memcached-operator

7创建Memcached集群

➜memcached-operatorcatconfig/samples/cache_v1alpha1_:/v1alpha1kind:Memcachedmetadata:name:memcached-samplespec:size:1➜memcached-operatorkubectlapply-fconfig/samples/cache_v1alpha1_/memcached-samplecreated➜memcached-operatorkubectlgetpodsNAMEREADYSTATUSRESTARTSAGEmemcached-sample-6c765df685-xhhjc1/1Running0104sredis1/1Running0177mredis-deployment-866c4c6cf9-zskkb1/1Running03h4mredis-sfs-01/1Running0112mredis-sfs-11/1Running0112m➜memcached-operator

可以通过kubectllogs来查看operator的日志:

➜~kubectllogs-fdeployment/memcached-operator-controller-manager-nmemcached-operator-system2021-11-05T09:50:46.042{"reconcilergroup":"","reconcilerkind":"Memcached","name":"memcached-sample","namespace":"default","":"default","":"memcached-sample"}

至此,我们的operator-sdk的任务暂时告一段落。

七总结

本文介绍了k8s的架构,各组件的功能,以及通过一个循序渐进的Redis例子介绍了k8s中Pod,Deployment,StatefulSet的概念,并通过operator-sdk演示了一个完整的operator制作的例子。

八参考资料

[1]《深入剖析Kubernetes》张磊,CNCFTOC成员,at阿里巴巴。
[2]《Kubernetes权威指南》第五版
[3]《Large-scaleclustermanagementatGooglewithBorg》

[4]
[5]
[6]
[7]
[8]
[9]
[10]
[11]
[12]
[13]

作者|凡澈

本文为阿里云原创内容,未经允许不得转载。