『K8S 入门』一:基础概念与初步搭建
一、kubernetes 组件
- 官方示图
- 抽象示图
Master 控制面板
- Api-Server:接口服务,基于 REST 风格开放 k8s 接口的服务
- ControllerManager
- cloud-controller-manager:云控制管理器。第三方平台提供的控制器 API 对接功能
- kube-controller-manager:控制器管理器。管理各个类型的控制器,针对 K8S 中的各种资源进行管理
- kube-scheduler:调度器。负责将 Pod 基于一定算法,将其调度到更合适的节点(服务器)上
- etcd:理解为 K8S 的数据库,键值类型存储的分布式数据库,提供基于 Raft 算法实现自主的集群高可用
节点 Node
- Kubelet:负责 Pod 的生命周期、存储、网络
- kube-proxy:网络代理,负责 Service 的服务发现,负载均衡(4 层负载)
- container-runtime:容器运行时环境。例如 docker、containerd、CRI-O
二、资源对象
服务分类
- 无状态:支持可扩容,不存储数据
- 有状态:可以独立存储数据,实现数据管理,水平扩容复杂
对象规约与状态
- 规约(spec):必须的,描述了对象的期望状态,可以理解为是个 Java 的类
- 状态(Status):对象的实际状态,由 k8s 自己维护,让对象尽量与期望状态重合,相当于 Java 的对象
资源分类
- 集群级:集群级别的资源,作用于集群之上,集群下的所有资源都可以共享使用,就是整个物理集群
- 命名空间:命名空间的资源,作用在命名空间之上,通常只能在该命名空间范围内使用,相当于逻辑空间
- 工作负载型
- Pod:k8s 最小可部署单元,一个 Pod(容器组)包含了一个应用程序器(某些情况下多个)、存储资源、一个唯一的网络地址。最好 Pod 只运行一个容器,如果要运行多个写作的容器,一定要是紧密耦合的
- 副本(replicas):一个 Pod 可以被复制成多份,除了 Pod 的名字、uid 等不一样外,其他都一样
- 控制器
- 适用无状态服务
- Replication Controller(已废弃):RC 可以管理 Pod 的服务数量,不过和 Pod 是绑定的
- ReplicaSet:RC 的升级版,通过 selector 控制打了标签的哪些 Pod 进行扩缩容
- Deployment:RS 的升级版,能够支持更多功能(例如,创建 RS、滚动回滚升级、平滑扩缩容、暂停与恢复 Deployment)
- 适用有状态服务
- StatefulSet:StatefulSet 中每个 Pod 的 DNS 格式为 statefulSetName-{0…N-1}.serviceName.namespace.svc.cluster.local(其中,serviceName 为 Headless Service 的名字;{0…N-1} 为 Pod 所在的序号,从 0 开始到 N-1;statefulSetName 为 StatefulSet 的名字;namespace 为服务所在的 namespace;Headless Servic 和 StatefulSet 必须在相同的 namespace;.cluster.local 为 Cluster Domain)
- Headless Service:用于定义网络标志,将域名与 ip 绑定映射关系,有序
- volumeClaimTemplate:用于创建 PersistentVolumes
- StatefulSet:StatefulSet 中每个 Pod 的 DNS 格式为 statefulSetName-{0…N-1}.serviceName.namespace.svc.cluster.local(其中,serviceName 为 Headless Service 的名字;{0…N-1} 为 Pod 所在的序号,从 0 开始到 N-1;statefulSetName 为 StatefulSet 的名字;namespace 为服务所在的 namespace;Headless Servic 和 StatefulSet 必须在相同的 namespace;.cluster.local 为 Cluster Domain)
- 守护进程
- DaemonSet:保证在每个 Node 上都运行一个容器副本,常用来部署一些集群的日志、监控或者其他系统管理应用。典型应用比如日志收集、系统监控、系统程序等
- 任务/定时任务
- Job:一次性任务,运行完成后Pod销毁,不再重新启动新容器
- CronJob:是在 Job 基础上加上了定时功能
- 适用无状态服务
- Pod:k8s 最小可部署单元,一个 Pod(容器组)包含了一个应用程序器(某些情况下多个)、存储资源、一个唯一的网络地址。最好 Pod 只运行一个容器,如果要运行多个写作的容器,一定要是紧密耦合的
- 服务发现
- Service:把 Pod 暴露出来提供服务,对外表现为一个访问入口,访问该入口的请求将经过负载均衡,转发到后端 Pod 中的容器(只能横向访问)
- Ingress:提供外网访问 Service 的能力,可以把某个请求地址映射、路由到特定的 Service(负责纵向流量)
- 存储
- Volume:数据卷,共享 Pod 中容器使用的数据。用来放持久化的数据,比如数据库数据
- CSI:Container Storage Interface,一个标准接口规范,旨在将任意存储系统暴露给容器化应用程序
- 特殊类型配置
- ConfigMap:用来放明文配置
- Secret:解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec 中
- downwardAPI:让 Pod 里的容器能够直接获取到这个 Pod 对象本身的一些信息,一般有 2 种方式将 Pod 信息注入到容器内部例如环境变量、volume 挂载
- 其他
- Role:一组权限的集合,例如 Role 可以包含列出 Pod 权限及列出 Deployment 权限,Role 用于给某个 NameSpace 中的资源进行鉴权
- RoleBinding:将 Subject 绑定到 Role,RoleBinding 使规则在命名空间内生效
Pod 基本原理图
- 其实就是相当于把紧凑合的应用,通过 pause 提供一个统一访问的环境,例如进行网络共享、应用之间的文件共享
pause 基本原理图 - 通过 pause 就可以使 pod 里面的应用通过 localhost 访问
Replication Controller 基本原理图
- 能够帮助更新 Pod 的副本数量,只不过是和 Pod 相关绑定
ReplicaSet、Deployment 基本原理图
- 通过 selector 可以选择对哪些标签的 Pod 进行扩缩容生效
StatefulSet 基本原理图 - 为网络定义访问的 DNS
DaemonSet 基本原理图 - 同样通过 selector 选择自动部署一些日志收集器之类的程序
Service/Ingress 基本原理图 - Service 负责横向服务访问,Ingress 负责纵向服务访问
- 元数据级:元数据级别的资源,对于资源的元数据描述,每一个资源都可以使用元空间的数据
- Horizontal Pod Autoscaler(HPA):根据自定义的 metrics 对 Pod 进行扩/缩容
- Pod Template:关于 Pod 的定义
- LimitRange:对 Pod 的资源使用限制
三、基础部署
- 准备三台虚拟机
角色 | ip |
---|---|
k8s-master | 192.168.199.152 |
k8s-node1 | 192.168.199.228 |
k8s-node2 | 192.168.199.189 |
- 初始化操作(三台机子都要操作,除非特别标注)
- 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
- 关闭 selinux
# 永久
sed -i 's/enforcing/disabled/' /etc/selinux/config
# 临时
setenforce 0
- 关闭 swap(一定要重启一下虚拟机)
# 临时
swapoff -a
# 永久
sed -ri 's/.*swap.*/#&/' /etc/fstab
- 根据规划设置主机名
# 自己设置相应主机名
hostnamectl set-hostname <hostname>
- 添加 hosts
cat >> /etc/hosts << EOF
192.168.199.152 k8s-master
192.168.199.228 k8s-node1
192.168.199.189 k8s-node2
EOF
- 将桥接的 IPv4 流量传递到 iptables 的链
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
# 生效
sysctl --system
- 时间同步
yum install ntpdate -y
ntpdate time.windows.com
- 安装基础软件
- 安装 docker(centenOS)
- 安装必要的一些系统工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
- 添加软件源信息
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 更新并安装 Docker-CE
sudo yum makecache fast sudo yum -y install docker-ce
- 开启 Docker 服务
sudo service docker start
- 添加阿里云源
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
- 安装 kubeadm、kubelet、kubectl
yum install -y kubelet-1.23.6 kubeadm-1.23.6 kubectl-1.23.6
systemctl enable kubelet
# 配置关闭 Docker 的 cgroups,修改 /etc/docker/daemon.json,加入以下内容
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
# 重启 docker
systemctl daemon-reload
systemctl restart docker
- 部署 Kubernetes Master
kubeadm init \
--apiserver-advertise-address=192.168.199.152 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.23.6 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16
# 安装成功后,复制如下配置并执行
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
5. 加入 Kubernetes Node
# 分别在 k8s-node1 和 k8s-node2 执行
# 下方命令可以在 k8s master 控制台初始化成功后复制 join 命令
kubeadm join 192.168.199.152:6443 --token <执行 init 后最后一行 token> --discovery-token-ca-cert-hash sha256:<master 控制台的 hash>
# 如果初始化的 token 不小心清空了,可以通过如下命令获取或者重新申请
# 如果 token 已经过期,就重新申请
kubeadm token create
# token 没有过期可以通过如下命令获取
kubeadm token list
# (需要在 master 节点执行)获取 --discovery-token-ca-cert-hash 值,得到值后需要在前面拼接上 sha256:
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
6. 部署 CNI 网络插件(在 master 节点执行)
- 先执行查看命令,发现三个节点都还没 ready
kubectl get nodes
- 查看组件状态时否正常
kubectl get componentstatus
- k8s 创建的 Pod 默认会放在 kube-system 命名空间下,通过下面命令查看一下现在的 Pod 状态,会发现两个 coredns 还在 pending 中
kubectl get pods -n kube-system
- 把下面的文件下载到 /opt/k8s 目录下
curl https://docs.projectcalico.org/manifests/calico.yaml -O
- 修改 calico.yaml 的内容
1.修改 calico.yaml 文件中的 CALICO_IPV4POOL_CIDR 配置,修改为与初始化的 cidr(即 pod-network-cidr=10.244.0.0/16) 相同
2.删除镜像 docker.io/ 前缀,避免下载过慢导致失败
sed -i 's#docker.io/##g' calico.yaml
- 通过下面命令执行聚合文件构建应用
kubectl apply -f calico.yaml
- 再通过下面命令,查看 pod 的状态
kubectl get po -n kube-system
- 这时候,我们可以看到一些 Init 的节点,可以通过下面命令,看看现在的执行状态。如果 Events 属性里面,镜像没下载下来,可以自己手动通过
docker pull
下载
kubectl describe po calico-kube-controllers-74dbdc644f-kk7bl -n kube-system
7. 测试 kubernetes 集群
- 执行下面命令
# 创建部署
kubectl create deployment nginx --image=nginx
# 暴露端口
kubectl expose deployment nginx --port=80 --type=NodePort
# 查看 pod 以及服务信息
kubectl get pod,svc
- 访问暴露的 ip 和端口,就可以看到是否显示 nginx 的页面了:http://192.168.199.152:32667
四、命令行工具 kubectl
- 在任意节点使用 kubectl
- 执行下面命令
# 1. 将 master 节点中 /etc/kubernetes/admin.conf 拷贝到需要运行的服务器的 /etc/kubernetes 目录中
scp /etc/kubernetes/admin.conf root@k8s-node1:/etc/kubernetes
# 2. 在对应的服务器上配置环境变量
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source ~/.bash_profile
# 3. 然后在其他节点测试
kubectl get nodes
- 资源类型与别名
资源类型 | 别名 |
---|---|
pods | po |
deployments | deploy |
services | svc |
namespace | ns |
nodes | no |
- API 概述
- 类型
- Alpha:包含 alpha 名称的版本,该软件可能包含错误。启用一个功能可能会导致 bug
- beta:包含 beta 名称的版本,该软件经过很好的测试
- Stable:该版本名称命名方式:vX 这里 X 是一个整数
- 访问控制:认证、授权