K8s 概要
k8s 功能
服务发现和负载均衡
存储编排
自动部署和回滚
自动完成装箱计算
自我修复
密钥与配置管理
资源隔离
资源利用
k8s 组件:控制平面组件(Control Plane Components)
参考:https://kubernetes.io/zh/docs/concepts/overview/components/
控制平面的组件对集群做出全局决策(比如调度),以及检测和响应集群事件(例如,当不满足部署的 replicas 字段时,启动新的 pod)。
控制平面组件可以在集群中的任何节点上运行。 然而,为了简单起见,设置脚本通常会在同一个计算机上启动所有控制平面组件,并且不会在此计算机上运行用户容器。 请参阅构建高可用性集群 中对于多主机 VM 的设置示例。
1、kube-apiserver
API 服务器是 Kubernetes 控制面的组件, 该组件公开了 Kubernetes API,API 服务器是 Kubernetes 控制面的前端;
Kubernetes API 服务器的主要实现是 kube-apiserver。 kube-apiserver 设计上考虑了水平伸缩,也就是说,它可通过部署多个实例进行伸缩。 你可以运行 kube-apiserver 的多个实例,并在这些实例之间平衡流量。
2、etcd
兼具一致性和高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库;您的 Kubernetes 集群的 etcd 数据库通常需要有个备份计划。
3、**kube-scheduler **
主节点上的组件,该组件监视那些新创建的未指定运行节点的 Pod,并选择节点让 Pod 在上面运行。
调度决策考虑的因素包括单个 Pod 和 Pod 集合的资源需求、硬件/软件/策略约束、亲和性和反亲和性规范、数据位置、工作负载间的干扰和最后时限 。
4、kube-controller-manager
在主节点上运行控制器的组件。
从逻辑上讲,每个控制器都是一个单独的进程,但是为了降低复杂性,它们都被编译到同一个可执行文件,并在一个进程中运行。
这些控制器包括:
- 节点控制器(Node Controller): 负责在节点出现故障时进行通知和响应。
- 副本控制器(Replication Controller): 负责为系统中的每个副本控制器对象维护正确数量的 Pod。
- 端点控制器(Endpoints Controller): 填充端点(Endpoints)对象(即加入 Service 与 Pod)。
- 服务帐户和令牌控制器(Service Account & Token Controllers): 为新的命名空间创建默认帐户和 API 访问令牌.
cloud-contro
5、cloud-controller-manager
云控制器管理器是 1.8 的 alpha 特性,在未来发布的版本中,这是将 Kubernetes 与任何其他云集成的最佳方式。
k8s 组件:Node 组件
节点组件在每个节点上运行,维护运行的 Pod 并提供 Kubernetes 运行环境。
1、**kubelet **
一个在集群中每个节点上运行的代理。它保证容器都运行在 Pod 中。
kubelet 接收一组通过各类机制提供给它的 PodSpecs,确保这些 PodSpecs 中描述的容器处于运行状态且健康。kubelet 不会管理不是由 Kubernetes 创建的容器。
2、kube-proxy
kube-proxy 是集群中每个节点上运行的网络代理,实现 Kubernetes Service 概念的一部分。
kube-proxy 维护节点上的网络规则。这些网络规则允许从集群内部或外部的网络会话与 Pod 进行网络通信。
如果操作系统提供了数据包过滤层并可用的话,kube-proxy会通过它来实现网络规则。否则,kube-proxy 仅转发流量本身。
3、Container Runtime
比如 Docker
4、Addons
插件列表:https://kubernetes.io/zh/docs/concepts/cluster-administration/addons/
插件使用 Kubernetes 资源(DaemonSet、 Deployment等)实现集群功能。 因为这些插件提供集群级别的功能,插件中命名空间域的资源属于 kube-system 命名空间。
比如 DNS 插件、容器资源监控插件、日志收集插件 等。
Canal 、Flannel、CoreDNS 、Dashboard 、
5、k8s网络组件
这个其实不属于 k8s 的组件,只是属于 Addons (插件),常用的有 flannel 和 calico,功能是 实现不同主机的容器的网络通信。
# K8s 安装环境 与 流程概要 --- ### 安装环境 本文的安装是基于上一篇文章 《CentOS8.2 安装 Docker》 的安装环境进行的,具体环境如下:
OS:CentOS Linux release 8.2.2004 (Core)
内核:Linux version 4.18.0-193.el8.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC)) #1 SMP Fri May 8 10:59:10 UTC 2020
Docker:19.03.13
Kubernetes: v1.19.4
安装大纲
1、安装docker-ce 19.03.13(所有机器)
2、设置k8s环境前置条件(所有机器)
3、安装k8s v1.19.4 master管理节点
4、安装k8s v1.19.4 node工作节点
5、安装 k8s组件,calico 或 flannel(master)
准备工作
- 关闭防火墙
- 修改内核参数
- 配置网络
- 禁用 selinux
- 关闭 swap
- 设置 hostname
- 修改 hosts
1、关闭防火墙
systemctl stop firewalld.service
systemctl disable firewalld.service
2、修改内核参数,将桥接的IPv4流量传递到iptables的链
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system
3、配置网络
可以通过 IPADDR 配置内网IP,配置后需要重启网卡来生效
cat /etc/sysconfig/network-scripts/ifcfg-enp0s3
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=enp0s3
UUID=039303a5-c70d-4973-8c91-97eaa071c23d
DEVICE=enp0s3
ONBOOT=yes
IPADDR=192.168.122.21
NETMASK=255.255.255.0
GATEWAY=192.168.122.1
DNS1=223.5.5.5
4、关闭 selinux
# 临时关闭
setenforce 0
# 永久关闭
sudo sed -i "s/^SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
reboot
5、关闭 swap
swapoff -a
sed -i 's/.*swap.*/#&/' /etc/fstab
free -h
6、设置hostname
hostnamectl set-hostname k8s-172
7、修改 hosts 文件
echo "192.168.10.202 k8s-172" >> /etc/hosts
# 或者
cat >> /etc/hosts << EOF
192.168.10.202 k8s-172
EOF
安装 kubeadm、kubelet、kubectl
1、添加阿里kubernetes源
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
2、安装 kubeadm、kubelet、kubectl
dnf install kubectl kubelet kubeadm
systemctl enable kubelet
3、查看是否安装成功
# 查看 k8s 的版本
kubelet --version
# 查看 kubeadm 的版本
kubeadm version
# 查看 kubectl 版本
kubectl version --client
4、启动 kubelet ,并设置开机自启动
systemctl enable kubelet && systemctl start kubelet
Master 初始化 与 Node 加入
Master 初始化
1、查看 Master 初始化需要的镜像
kubeadm config images list
# 或者
kubeadm config images list --kubernetes-version=v1.19.4
需要的镜像结果如下,可以看到是对应的 Master 的组件
k8s.gcr.io/kube-apiserver:v1.19.4
k8s.gcr.io/kube-controller-manager:v1.19.4
k8s.gcr.io/kube-scheduler:v1.19.4
k8s.gcr.io/kube-proxy:v1.19.4
k8s.gcr.io/pause:3.2
k8s.gcr.io/etcd:3.4.13-0
k8s.gcr.io/coredns:1.7.0
2、修改 Cgroup Driver
通过 docker info 命令 查看docker服务的 Cgroup Driver,如果值为 cgroupfs 则需要修改
在daemon.json中加入 “exec-opts”: [“native.cgroupdriver=systemd”]
3、执行初始化命令 kubeadm init
kubeadm init --kubernetes-version=1.19.4 \
--apiserver-advertise-address=192.168.10.202 \
--image-repository registry.aliyuncs.com/google_containers \
--service-cidr=10.10.0.0/16 --pod-network-cidr=10.122.0.0/16
- kubernetes-version:k8s 版本号
- apiserver-advertise-address:本机IP(也是 Master的IP),使用内网IP
- image-repository:拉取镜像的地址,这里使用阿里云的镜像仓库
- service-cidr:暴露 服务的 IP 网段
- pod-network-cidr: Pod 的 IP 网段
我们顺便如下链接学习一下,10.122.0.0/16 里头的 16 的含义:
https://www.orchome.com/602
出现如下信息则表示初始化成功:
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.10.202:6443 --token xxxx.xxxx \
--discovery-token-ca-cert-hash sha256:xxxx
4、执行如下命令,使配置生效,这些命令也是kubeadm init 成功后的提示信息
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
5、使kubectl可以自动补充
dnf install bash-completion -y
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
6、检查是否安装成功
kubectl get node
# or
kubectl get node -o wide
# 输出
NAME STATUS ROLES AGE VERSION
k8s-172 NotReady master 8m29s v1.19.4
可以看到,k8s 已安装成功,但是 status 还是 NotReady,是因为尚未安装 网络组件。
Node 加入
1、如果是刚 执行完 kubeadm init,则提示信息有现成的加入node 的命令,里头已经有了 token 和 hash:
kubeadm join 192.168.10.202:6443 --token xxxx.xxxx\
--discovery-token-ca-cert-hash sha256:xxxx
2、ssh 登录机器,并切换到 root 用户,然后执行:
kubeadm join --token <token> <control-plane-host>:<control-plane-port> --discovery-token-ca-cert-hash sha256:<hash>
查看 token:
kubeadm token list
token 有效期是24小时之内,如果过期则可以重新获取:
kubeadm token create
discovery-token-ca-cert-hash 的值是不会变的,想要查看则执行:
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^.* //'
3、查看 是否 join 成功
kubectl get node -o wide
# 输出
k8s-172 NotReady master 56m v1.19.4 192.168.10.202 <none> CentOS Linux 8 (Core) 4.18.0-193.28.1.el8_2.x86_64 docker://19.3.13
k8s-173 NotReady <none> 58s v1.19.4 192.168.10.203 <none> CentOS Linux 8 (Core) 4.18.0-193.el8.x86_64 docker://19.3.13
kubectl get pod --all-namespaces
# 输出
kube-system coredns-6d56c8448f-4z8ll 0/1 Pending 0 58m
kube-system coredns-6d56c8448f-gb7tk 0/1 Pending 0 58m
kube-system etcd-k8s-172 1/1 Running 0 58m
kube-system kube-apiserver-k8s-172 1/1 Running 0 58m
kube-system kube-controller-manager-k8s-172 1/1 Running 0 58m
kube-system kube-proxy-c2fpx 1/1 Running 0 58m
kube-system kube-proxy-rgpv6 0/1 ContainerCreating 0 2m58s
kube-system kube-scheduler-k8s-172 1/1 Running 0 58m
为 K8s 安装网络组件
网络组件说明
calico 官网:https://www.projectcalico.org/
安装 calico
在 Master 执行如下命令
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
对于 Centos 系统,这里特别注意,安装完 calico 之后,Node 节点还是 NotReady 状态,查看 pods 状态:
kubectl get pods --all-namespaces
可以看到有一个 calico-node 的 pod 一直是 init 的状态, 一个 kube-proxy 的 pod 一直是 ContainerCreating 的状态,通过如下命令查看 pod 的具体情况:
kubectl describe pod -n kube-system calico-node-id
kubectl describe pod -n kube-system kube-proxy-id
发现这个 Pod 是在 Node 节点上,且出现一个报错:
open /run/systemd/resolve/resolv.conf: no such file or directory
此时,只需要在 Node 节点创建文件夹,并根据 Master 赋予权限和组属:
cd /run/systemd/
mkdir resolve
chmod 755 /resolve
chown systemd-resolve:systemd-resolve /resolve
最后把 Master 的 /run/systemd/resolve 文件夹下的所有文件 拷贝到 Node 对应的目录,过几秒就可以通过如下命令查看,一切恢复正常!
kubectl get pods --all-namespaces
kubectl get nodes -o wide
K8s 常用命令
k8s 资料
1、使用kubeadm在Centos8上部署kubernetes1.18 (kubernetes中文社区)
https://www.kubernetes.org.cn/7189.html
2、半兽人教程
https://www.orchome.com/9907
3、非常好和非常全的k8s资源文件模板!
https://www.kubebiz.com/
4、Installing kubeadm (k8s 官网)
https://kubernetes.io/zh/docs/setup/production-environment/tools/kubeadm
5、calico 官网
https://www.projectcalico.org/
1、深入理解Kubernetes Operator
https://mp.weixin.qq.com/s/aTblvy0kW85QUgG_AOuyNg
2、Kubernetes 上对应用程序进行故障排除的 6 个技巧
https://mp.weixin.qq.com/s/8UZvtL9OwgS5zpYv9K-VaA
3、Kubernetes 的这些原理,你一定要了解
https://mp.weixin.qq.com/s/VuE_bUgCUm7qdleWqFMduw
编排无状态应用的 deployment,编排有状态应用的 statefulset,编排守护进程 daemonset 以及编排离线业务的 job/cronjob;
replicaset 控制 pod 的数量,而 deployment 控制 replicaset 的版本属性。这种设计模式也为两种最基本的编排动作实现了基础,即数量控制的水平扩缩容、版本属性控制的更新/回滚。
网络通信,kubernetes 首先得有”三通”基础
node 到 pod 之间可以通
node 的 pod 之间可以通
不同 node 之间的 pod 可以通
简单来说,不同 pod 之间通过 cni0/docker0 网桥实现了通信,node 访问 pod 也是通过 cni0/docker0 网桥通信即可。
而不同 node 之间的 pod 通信有很多种实现方案,包括现在比较普遍的 flannel 的 vxlan/hostgw 模式等。flannel 通过 etcd 获知其他 node 的网络信息,并会为本 node 创建路由表,最终使得不同 node 间可以实现跨主机通信。