第一章 Kubernetes 核心概念
1、主流的容器集群管理系统
容器编排系统:
- Kubernetes
- Swarm
- Mesos Marathon
2、Kubernetes介绍
Kubernetes是Google在2014年开源的一个容器集群管理系统,Kubernetes简称K8s。
Kubernetes用于容器化应用程序的部署,扩展和管理,目标是让部署容器化应用简单高效。
官方网站:Kubernetes
注意:熟悉文档中的【概念】、【任务】
3、Kubernetes集群架构与组件
3.1 Master 组件
- kube-apiserver
Kubernetes API,集群的统一入口,各组件协调者,以RESTful API提供接口服务,所有对象资源的增删改查和监听操作都交给APIServer处理后再提交给Etcd存储。
- kube-scheduler
根据调度算法为新创建的Pod选择一个Node节点,可以任意部署,可以部署在同一个节点上,也可以部署在不同的节点上。
- kube-controller-manager
处理集群中常规后台任务,一个资源对应一个控制器,而ControllerManager就是负责管理这些控制器的。例如:Deployment、Service
- etcd
分布式键值存储系统。用于保存集群状态数据,比如Pod、Service等对象信息(可以部署在Master节点或者独立节点)
3.2 Work/node 组件
- kubelet
kubelet是Master在Node节点上的Agent,管理本机运行容器的生命周期,比如创建容器、Pod挂载数据卷、下载secret、获取容器和节点状态等工作。kubelet将每个Pod转换成一组容器。
- kube-proxy
在Node节点上实现Pod网络代理,维护网络规则和四层负载均衡工作。
- 第三方容器引擎
容器引擎,运行容器, 例如docker、containerd、podman
第二章 Kubernetes集群部署、配置和验证
1、生产环境部署K8s的2种方式
- kubeadm
Kubeadm是一个工具,提供 kubeadm init 和 kubeadm join,用于快速部署Kubernetes集群。
部署地址:Kubeadm | Kubernetes
- 二进制
从官方下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群。
- 第三方工具或者Web
2、服务器硬件配置推荐
3、使用kubeadm快速部署一个K8s集群
- 安装Docker(docker-ce容器引擎、cri-docker容器运行时)
- 创建 Master 、node节点
- kubeadm init初始化集群
- 将一个 Node 节点加入到当前集群中 (kubeadm join < Master节点的IP和端口 >)
- 部署容器网络(CNI)(kubectl apply -f calico.yaml)
- 部署Web UI(Dashboard)
部署k8s集群避坑:
- cri-docker 版本 必须使用的是 0.3(最新的版本),否则将会存在兼容性问题;
- 使用镜像拉取比较慢的问题(可能是网络问题),使用docker pull在别的服务器进行下载,通过docker save保存下来,通过 docker load 导入所有节点;
- 在master上 kubeadm init 时执行失败,大部分问题为kubelet无法启动,原因可能是主机的初始化为准备好、其次cri-docker没安装最新版本
- 安装有问题需要清空环境配置,通过 kubeadm reset --cri-socket=unix:///var/run/cri-dockerd.sock 进行还原
- kubeadm init 会输出关于工作节点进行join的命令,有效期24小时,通过 kubeadm token create --print-join-command 生成新的token
4、部署的网络组件起什么作用?
Q: 不同docker服务器的两个容器间的访问遇到问题:
① 容器1和容器2 分配的IP有可能一样,是因为docker主机有各自的网络管理机制、独立的?
- 思路:设置不同网段
② 容器1和容器2 分配的IP即使不一样,也是网络无法ping通,是因为容器1发送的数据包不知道送往何处?
- 思路:配置路由
③ 即使知道将数据包送往何处,那通过什么方式通过容器送达?
- 思路:容器的数据包需要通过宿主机网络将数据包发送到对端的宿主机再传送到里面的容器
A: 部署网络组件的目的是打通Pod到Pod之间网络、Node与Pod之间网络,从而集群中数据包可以任意传输,形成了一 个扁平化网络。所以网络组件的主要作用是可以实现容器跨主机通信
**目前主流的网络组件:Flannel、Calico 等 ;**而所谓的 CNI( Container Network Interface,容器网络接口)就是k8s对接这些第三方网络组件的接口。
补充:
CNI 容器网络接口,对接网络组件
CRI 容器运行时接口,对接容器引擎
CSI 容器存储接口,对接存储组件
5、Kubernetes将弃用Docker!
在Kubernetes平台中,为了解决与容器运行时(例如Docker)集成 问题,在早期社区推出了CRI(Container Runtime Interface,容 器运行时接口),以支持更多的容器运行时。
当我们使用Docker作为容器运行时之后,架构是这样的,如图所示:
Kubernetes 计划弃用就是kubelet中dockershim。即 Kubernetes kubelet 实现中的组件之一,它能够与 Docker Engine 进行通信。
Q:为什么这么做?
- K8s核心代码优化
- Docker内部调用链比较复杂,多层封装和调用,导致性能降低、提升故障率、不易排查
- Docker还会在宿主机创建网络规则、存储卷,也带来了安全隐患
Q:如何应对?
可通过 cri-dockerd 继续使用Docker,并了解其他主流容器运行时。除了docker之外,CRI还支持很多容器运行时,例如:
- containerd:containerd与Docker相兼容,相比Docker轻量很多,目前较为成熟
- cri-o,podman:都是红帽(RedHat)项目,目前红帽主推podman
Q:相关 containerd 切换的其它疑问?
① 独立的容器运行时,在一个集群中可以有多个运行时,一般再测试环境下才会有两个容器运行时
② 正常要求下,在切换容器运行时,建议在所有的节点都要进行切换操作,不建议混用,不利于后期的维护
③ 目前主流的镜像都是通用的
6、kubeconfig配置文件
kubectl 使用 kubeconfig 认证文件连接K8s集群,使用 kubectl config 指令生成 kubeconfig文件。
了解:关于config文件 只是一个"管理工具" 无论在哪个节点 都可以访问 (例如:在本地虚拟机上也可以访问公司的集群)
7、kubectl命令行管理工具
官方文档参考地址:命令行工具 (kubectl) | Kubernetes
bash
# 自动补全
yum -y install bash-completion
source <(kubectl completion bash)
vi .bashrc //将 source <(kubectl completion bash) 写入,开机自启
bash
# 查看客户端和服务端的版本
[root@k8s-master-1-71 ~]# kubectl version
WARNING: This version information is deprecated and will be replaced with the output from kubectl version --short. Use --output=yaml|json to get the full version. //提示未来会弃用需要加参数
[root@k8s-master-1-71 ~]# kubectl version --output=yaml
clientVersion: //客户端版本
buildDate: "2022-12-08T19:58:30Z"
compiler: gc
gitCommit: b46a3f887ca979b1a5d14fd39cb1af43e7e5d12d
gitTreeState: clean
gitVersion: v1.26.0
goVersion: go1.19.4
major: "1"
minor: "26"
platform: linux/amd64
kustomizeVersion: v4.5.7
serverVersion: //APIserver版本
buildDate: "2022-12-08T19:51:45Z"
compiler: gc
gitCommit: b46a3f887ca979b1a5d14fd39cb1af43e7e5d12d
gitTreeState: clean
gitVersion: v1.26.0
goVersion: go1.19.4
major: "1"
minor: "26"
platform: linux/amd64
bash
# 创建资源(功能),例如deployment、service等
例:kubectl create deployment java-demo --image=镜像来源
# --image=镜像来源
1、docker官方公共镜像仓库(hub.docker.com),默认使用,镜像地址没有带域名或者IP
2、指定镜像仓库,即镜像地址带域名或者IP
例:kubectl create deployment java-demo --image=镜像来源 --replices=1
# --replices 副本数(默认是1副本)
# 暴露应用
例:kubectl expose deployment java-demo --port=端口 --target-port=端口 --type=NodePort
--port=service的端口
--target-port=镜像内服务运行的端口
--type=service的类型,例如NodePort
# 查看相关镜像
例:kubectl get pods --show-lables
例:kubectl get pods -l app=ngix
--show-lables //查看pods标签
-l 标签 //可以进行过滤
# 查看服务
kubectl get service
8、快速部署一个网站
使用Deployment控制器部署镜像:
bash
[root@k8s-master-1-71 ~]# kubectl create deployment java-demo --image=lizhenliang/java-demo
deployment.apps/java-demo created
[root@k8s-master-1-71 ~]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
java-demo 1/1 1 1 5m51s
[root@k8s-master-1-71 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
java-demo-5cb596f979-47g2r 1/1 Running 0 5m46s
使用Service将Pod暴露出去:
bash
[root@k8s-master-1-71 ~]# kubectl expose deployment java-demo --port=80 --target-port=8080 --type=NodePort
service/java-demo exposed
[root@k8s-master-1-71 ~]# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
java-demo NodePort 10.105.177.89 <none> 80:32710/TCP 88s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3h7m
或者
[root@k8s-master-1-71 ~]# kubectl get svc //svc为缩写
访问应用:
http://NodeIP:Port # 端口随机生成,通过kubectl get service获取
9、基本资源概念
- Pod:K8s最小部署单元,一组容器的集合
- Deployment:最常见的控制器,用于更高级别部署和管理Pod
- Service:为一组Pod提供负载均衡,对外提供统一访问入口
- Label :标签,附加到某个资源上,用于关联对象、查询和筛选
- Namespaces :命名空间,将对象逻辑上隔离,也利于权限控制
9.1 标签(Label)
创建标签:kubectl label deployment/pod/其他 xxx -n 命名空间 标签名=标签值 --overwrite
bash
[root@k8s-master-1-71 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
java-demo-5cb596f979-47g2r 1/1 Running 0 28m
# 查看资源的标签
[root@k8s-master-1-71 ~]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
java-demo-5cb596f979-47g2r 1/1 Running 0 28m app=java-demo,pod-template-hash=5cb596f979
# 根据标签过滤显示资源
[root@k8s-master-1-71 ~]# kubectl get pods -l app=java-demo
NAME READY STATUS RESTARTS AGE
java-demo-5cb596f979-47g2r 1/1 Running 0 29m
9.2 命名空间(Namespace)
Kubernetes将资源对象逻辑上隔离,从而形成多个虚拟集群
应用场景:
- 资源分类管理,可根据不同团队、项目划分命名空间
- 基于命名空间权限授权
查看命名空间:kubectl get namespace
default:默认命名空间
kube-system:K8s系统方面的命名空间
kube-public:公开的命名空间,谁都可以访问
kube-node-lease:K8s内部命名空间
bash
[root@k8s-master-1-71 ~]# kubectl get namespace
NAME STATUS AGE
default Active 55m
kube-node-lease Active 55m
kube-public Active 55m
kube-system Active 55m
kubernetes-dashboard Active 9m38s
创建命名空间:kubectl create namespace 命名空间
bash
[root@k8s-master-1-71 ~]# kubectl create namespace test
namespace/test created
[root@k8s-master-1-71 ~]# kubectl get namespaces
NAME STATUS AGE
default Active 3h25m
kube-node-lease Active 3h25m
kube-public Active 3h25m
kube-system Active 3h25m
kubernetes-dashboard Active 160m
test Active 9s
或者
[root@k8s-master-1-71 ~]# kubectl get ns
两种方法指定资源所属的命名空间:
- 命令行加 -n
- yaml 资源元数据里指定 namespace字段
bash
[root@k8s-master-1-71 ~]# kubectl create deployment java-demo2 --image=lizhenliang/java-demo -n test
deployment.apps/java-demo2 created
[root@k8s-master-1-71 ~]# kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
java-demo2-58bc68b877-46gq7 1/1 Running 0 30s
扩展实践
1、使用kubeadm搭建一个K8s集群
2、新建一个命名空间,创建一个deployment并暴露Service
- 命名空间:aliang-cka
- 名称:web
- 镜像:nginx
3、列出命名空间下指定标签pod
- 命名空间名称:kube-system
- 标签:k8s-app=kube-dns
小结:
本篇为 【Kubernetes CKA认证 Day1】的学习笔记,希望这篇笔记可以让您初步了解到 k8s核心概念与集群搭建,课后还有扩展实践,不妨跟着我的笔记步伐亲自实践一下吧!
Tip:毕竟两个人的智慧大于一个人的智慧,如果你不理解本章节的内容或需要相关笔记、视频,可私信小安,请不要害羞和回避,可以向他人请教,花点时间直到你真正的理解。