思考并回答以下问题:
- 容器技术的核心概念是容器、镜像、仓库。为什么?
- 容器编排就是这些容器之上的管理、调度工作。怎么理解?
- 容器技术只解决了应用的打包、安装问题,面对复杂的生产环境就束手无策了,解决之道就是容器编排,它能够组织管理各个应用容器之间的关系,让它们顺利地协同运行。怎么理解?
- Kubernetes就是一个生产级别的容器编排平台和集群管理系统,不仅能够创建、调度容器,还能够监控、管理服务器。怎么理解?
- minikube只能够搭建Kubernetes环境,要操作Kubernetes,还需要另一个专门的客户端工具“kubectl”。怎么理解?
kubectl run ngx --image=nginx:alpine
命令执行之后可以看到,在Kubernetes集群里就有了一个名字叫ngx的Pod正在运行,是什么意思?kubectl get pod
是什么意思?- 所谓的“云”,现在就指的是Kubernetes,那么“云原生”的意思就是应用的开发、部署、运维等一系列工作都要向Kubernetes看齐,使用容器、微服务、声明式API等技术,保证应用的整个生命周期都能够在Kubernetes环境里顺利实施,不需要附加额外的条件。怎么理解?
什么是容器编排
容器技术的核心概念是容器、镜像、仓库,使用这三大基本要素我们就可以轻松地完成应用的打包、分发工作,实现“一次开发,到处运行”的梦想。
不过,当我们熟练地掌握了容器技术,信心满满地要在服务器集群里大规模实施的时候,却会发现容器技术的创新只是解决了运维部署工作中一个很小的问题。现实生产环境的复杂程度实在是太高了,除了最基本的安装,还会有各式各样的需求,比如服务发现、负载均衡、状态监控、健康检查、扩容缩容、应用迁移、高可用等等。
虽然容器技术开启了云原生时代,但它也只走出了一小步,再继续前进就无能为力了,因为这已经不再是隔离一两个进程的普通问题,而是要隔离数不清的进程,还有它们之间互相通信、互相协作的超级问题,困难程度可以说是指数级别的上升。
这些容器之上的管理、调度工作,就是这些年最流行的词汇:“容器编排”(Container Orchestration)。
容器编排这个词听起来好像挺高大上,但如果你理解了之后就会发现其实也并不神秘。像我们在上次课里使用Docker部署WordPress网站的时候,把Nginx、WordPress、MariaDB这三个容器理清次序、配好IP地址去运行,就是最初级的一种“容器编排”,只不过这是纯手工操作,比较原始、粗糙。
面对单机上的几个容器,“人肉”编排调度还可以应付,但如果规模上到几百台服务器、成千上万的容器,处理它们之间的复杂联系就必须要依靠计算机了,而目前计算机用来调度管理的“事实标准”,就是我们专栏的主角:Kubernetes。
什么是Kubernetes
Kubernetes就是一个生产级别的容器编排平台和集群管理系统,不仅能够创建、调度容器,还能够监控、管理服务器。
什么是minikube
Kubernetes一般都运行在大规模的计算集群上,管理很严格,这就对我们个人来说造成了一定的障碍,没有实际操作环境怎么能够学好用好呢?
好在Kubernetes充分考虑到了这方面的需求,提供了一些快速搭建Kubernetes环境的工具,在官网上推荐的有两个:kind和minikube,它们都可以在本机上运行完整的Kubernetes环境。
kind基于Docker,意思是“Kubernetes in Docker”。它功能少,用法简单,也因此运行速度快,容易上手。不过它缺少很多Kubernetes的标准功能,例如仪表盘、网络插件,也很难定制化,所以我认为它比较适合有经验的Kubernetes用户做快速开发测试,不太适合学习研究。
不选kind还有一个原因,它的名字与Kubernetes YAML配置里的字段kind重名,会对初学者造成误解,干扰学习。
再来看minikube,从名字就能够看出来,它是一个“迷你”版本的Kubernetes。
minikube最大特点就是“小而美”,可执行文件仅有不到100MB,运行镜像也不过1GB,但就在这么小的空间里却集成了Kubernetes的绝大多数功能特性,不仅有核心的容器编排功能,还有丰富的插件,例如Dashboard、GPU、Ingress、Istio、Kong、Registry等等,综合来看非常完善。
如何搭建minikube环境
minikube支持Mac、Windows、Linux这三种主流平台,你可以在它的官网找到详细的安装说明,当然在我们这里就只用虚拟机里的Linux了。
minikube的最新版本是1.25.2,支持的Kubernetes版本是1.23.3,所以我们就选定它作为我们初级篇的学习工具。
minikube不包含在系统自带的apt/yum软件仓库里,我们只能自己去网上找安装包。不过因为它是用Go语言开发的,整体就是一个二进制文件,没有多余的依赖,所以安装过程也非常简单,只需要用curl或者wget下载就行。
minikube的官网提供了各种系统的安装命令,通常就是下载、拷贝这两步,不过你需要注意一下本机电脑的硬件架构,Intel芯片要选择带“amd64”后缀,Apple M1芯片要选择“arm64”后缀,选错了就会因为CPU指令集不同而无法运行。
我也把官网上Linux系统安装的命令抄在了这里,你可以直接拷贝后安装:1
2
3
4
5
6
7# Intel x86_64
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
# Apple arm64
curl -Lo minikube https://storage.googleapis.com/minikube/releases/latest/minikube-linux-arm64
sudo install minikube /usr/local/bin/
安装完成之后,你可以执行命令minikube version
,看看它的版本号,验证是否安装成功:1
minikube version
不过minikube只能够搭建Kubernetes环境,要操作Kubernetes,还需要另一个专门的客户端工具“kubectl”。
kubectl的作用有点类似之前我们学习容器技术时候的工具“docker”,它也是一个命令行工具,作用也比较类似,同样是与Kubernetes后台服务通信,把我们的命令转发给Kubernetes,实现容器和集群的管理功能。
kubectl是一个与Kubernetes、minikube彼此独立的项目,所以不包含在minikube里,但minikube提供了安装它的简化方式,你只需执行下面的这条命令:1
minikube kubectl
它就会把与当前Kubernetes版本匹配的kubectl下载下来,存放在内部目录(例如.minikube/cache/linux/arm64/v1.23.3
),然后我们就可以使用它来对Kubernetes“发号施令”了。
所以,在minikube环境里,我们会用到两个客户端:minikube管理Kubernetes集群环境,kubectl操作实际的Kubernetes功能,和Docker比起来有点复杂。
我画了一个简单的minikube环境示意图,方便你理解它们的关系。
实际验证minikube环境
前面的工作都做完之后,我们就可以在本机上运行minikube,创建Kubernetes实验环境了。
使用命令minikube start
会从Docker Hub上拉取镜像,以当前最新版本的Kubernetes启动集群。不过为了保证实验环境的一致性,我们可以在后面再加上一个参数--kubernetes-version
,明确指定要使用Kubernetes版本。
这里我使用“1.23.3”,启动命令就是:1
minikube start --kubernetes-version=v1.23.3
现在Kubernetes集群就已经在我们本地运行了,你可以使用minikube status
、minikube node list
这两个命令来查看集群的状态:1
2minikube status
minikube node list
从截图里可以看到,Kubernetes集群里现在只有一个节点,名字就叫“minikube”,类型是“Control Plane”,里面有host、kubelet、apiserver三个服务,IP地址是192.168.49.2。
你还可以用命令minikube ssh
登录到这个节点上,虽然它是虚拟的,但用起来和实机也没什么区别:
有了集群,接下来我们就可以使用kubectl来操作一下,初步体会Kubernetes这个容器编排系统,最简单的命令当然就是查看版本:1
kubectl version
不过这条命令还不能直接用,因为使用minikube自带的kubectl有一点形式上的限制,要在前面加上minikube的前缀,后面再有个--
,像这样:1
minikube kubectl -- version
为了避免这个不大不小的麻烦,我建议你使用Linux的“alias”功能,为它创建一个别名,写到当前用户目录下的.bashrc
里,也就是这样:1
2
3
4
5tee -a $HOME/.bashrc <<'EOF'
alias kubectl="minikube kubectl --"
EOF
source $HOME/.bashrc
另外,kubectl还提供了命令自动补全的功能,你还应该再加上“kubectl completion
”:1
source <(kubectl completion bash)
现在,我们就可以愉快地使用kubectl了:
下面我们在Kubernetes里运行一个Nginx应用,命令与Docker一样,也是run,不过形式上有点区别,需要用--image
指定镜像,然后Kubernetes会自动拉取并运行(由于国内网络环境下载gcr.io的镜像比较困难,minikube提供了特殊的启动参数--image-mirror-country=cn, --registry-mirror=https://twm4fpgj.mirror.aliyuncs.com, --image-repository=registry.cn-hangzhou.aliyuncs.com/google_containers
等):1
kubectl run ngx --image=nginx:alpine
这里涉及Kubernetes里的一个非常重要的概念:Pod,你可以暂时把它理解成是“穿了马甲”的容器,查看Pod列表需要使用命令kubectl get pod
,它的效果类似docker ps
:
命令执行之后可以看到,在Kubernetes集群里就有了一个名字叫ngx的Pod正在运行,表示我们的这个单节点minikube环境已经搭建成功。
小结
什么是云原生呢?所谓的“云”,现在就指的是Kubernetes,那么“云原生”的意思就是应用的开发、部署、运维等一系列工作都要向Kubernetes看齐,使用容器、微服务、声明式API等技术,保证应用的整个生命周期都能够在Kubernetes环境里顺利实施,不需要附加额外的条件。
换句话说,“云原生”就是Kubernetes里的“原住民”,而不是从其他环境迁过来的“移民”。
1,容器技术只解决了应用的打包、安装问题,面对复杂的生产环境就束手无策了,解决之道就是容器编排,它能够组织管理各个应用容器之间的关系,让它们顺利地协同运行。
2,操作Kubernetes需要使用命令行工具kubectl,只有通过它才能与Kubernetes集群交互。
3,kubectl的用法与docker类似,也可以拉取镜像运行,但操作的不是简单的容器,而是Pod。
Kubernetes的中文官网
课下作业
1,你是怎么理解容器编排和Kubernetes的?它们应该能够解决什么问题?
2,你认为Kubernetes和Docker之间有什么区别?
精选留言
1,镜像拉取的几个坑:
- docker版本过低,docker升级到20.10.1以上
- 不能用root账号,加上
--force
或者sudo usermod -aG docker ${USER} # 当前用户加入docker组
- 镜像拉取不下来,切换到国内镜像,先执行
minikube delete
,再执行minikube start --image-mirror-country='cn'
2,docker和k8s之间的区别,一个是容器技术,一个是容器编排技术,两者思考的维度是不一样的,就容器而言,容器解决的问题是隔离,是一次打包到处运行的问题,最大的价值就在于镜像的迁移。编排技术则是关注的是整个系统的问题,如果你只关注一个服务,迁移一个服务,那docker就够,但要迁移整个系统以及运维,那就需要编排,包括网络关系,负载均衡,回滚,监控,扩缩容问题则需要容器编排技术。
3,minikube start
无法启动,minikube delete --all --purge
解决。