k8s
k8s是一个可移植容器的编排管理工具
之前学习过compose
容器编排工具,compose 在启动容器使用yaml文件
Kubernetes,也被称为K8s,是一个用于自动化部署、扩展和管理容器化应用程序的开源系统。
k8s有Google等公司的支持,10多年的生产使用经验,稳定性和扩展性等方面有保障。
kubernetes与 compose的区别
-
compose属于docker公司,kubernetes是CNCF(Google等)
-
compose只能在一台宿主机上编排容器,而k8s可以在很多台机器上编排容器
-
Docker Compose是一个基于Docker的单主机容器编排工具.而k8s是一个跨主机的集群部署工具
二、K8s的架构 https://kubernetes.io/zh-cn/docs/tutorials/kubernetes-basics/(官方文档)
2.1 k8s的组件
-
maser 控制平面组件(control plane components)
- 控制平面组件会为集群做出全局决策,比如资源的调度,以及检测和响应集群事件。例如当不满足部署的replicas字段是,要启动新的pod
- kube-apiserver
- API 服务器是 Kubernetes 控制平面的前端
- etcd 数据库
- 兼具一致性和高可用性的键值数据库,可以作为保存 kubernetes 所有集群数据的后台数据库。
- kube-scheduler 调度器
- 调度那些 pod 在那些 节点node 上创建运行
- controller-manager 运行控制器进程的控制平面组件
- 从逻辑上讲,每个控制器都是一个单独的进程,但是为了降低复杂度,他们都被编译到同一个可执行文件,并在一个进程中运行
-
Node 组件
- 节点组件会在每个节点上运行,负责维护运行的 Pod 并提供 Kubernetes 运行环境
- kubelet
- 在集群中每个节点 Node 上运行。保证容器 (containers)都运行在Pod中
- kube-proxy
- 是集群中每个节点Node 所上运行的网络代理,实现kubernetes 服务
2.2 容器和pod是什么关系
1. 一个pod里可以多个容器
2. pod是在kubernetes 中创建和管理,最小的,可部署的计算单元
2.3 pod的启动流程
2.4 k8s里有哪些控制器 controller-manager
从逻辑上讲,每个控制器都是一个单独的进程,但是为了降低复杂度,他们都被编译到同一个可执行文件,并在一个进程中运行
- 节点控制器(Node controller)
- 负责在节点出现故障时进行通知和响应
- 任务控制器(job controller)
- 监测代表一次性任务的job对象, 然后创建Pods来运行这些任务直至完成
- 端点控制器 (endpoints controller)
- 填充端点(endpoints)对象(即加入service 与 pod)
- 服务账户和令牌控制器(service account & token controllers)
- 为新的命名空间创建默认账户和API访问令牌
部署kubernetes
实验环境(4台虚拟机)
1台master,3台node ,安装好docker
一个kubernetes 集群包含两种类型的资源:
- master 调度整个集群 —> 运行执行管理功能的pod
- nodes 负责运行应用 ----> 运行业务pod的地方
采用kubeadm方式安装
名称 | ip | |
---|---|---|
master | 192.168.222.148 | |
node1 | 192.168.222.152 | |
node2 | 192.168.222.153 | |
node3 | 192.168.222.151 |
1. 先安装docker,启动docker,并且设置开机启动
2. 配置docker使用systemd作为默认Cgroups驱动
每台服务器上都要操作,master和node上都要操作
cat <<EOF > /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
重启docker
systemctl restart docker
3. 关闭 swap 分区
因为k8s不想使用swap分区来存储数据,使用swap会降低性能
每台服务器都需要操作
swapoff -a 临时关闭
swapon 开启
vim /etc/fstab ---》 永久关闭
5.在hosts文件中添加
cat >> /etc/hosts << EOF
192.168.222.148 master
192.168.222.152 node1
192.168.222.153 node2
192.168.222.151 node3
EOF
6. 安装kubeadm,kubelet 和kubectl
每台服务器都需要
kubeadm
:用来初始化集群的指令。kubelet
:在集群中的每个节点上用来启动 Pod 和容器等。kubectl
:用来与集群通信的命令行工具。
添加kubernetes yum软件源
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[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
# 将 SELinux 设置为 permissive 模式(相当于将其禁用)
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
安装kubeadm kubelet kubectl
[root@master docker]# yum install -y kubelet-1.23.5-0.x86_64 kubeadm-1.23.5-0.x86_64 kubectl-1.23.5-0.x86_64
sudo yum install -y kubelet kubeadm kubectl
设置开机自启,因为kubelet 是 K8s在node节点上的代理,必须开机要运行的
sudo systemctl enable kubelet
kubeadm config images list
7. 在master主机执行如下操作
部署kubernetes master
提前准备coredns:1.8.4的镜像,后面需要使用,需要在每台机器上 下载镜像
docker pull coredns/coredns:1.8.4
docker tag coredns/coredns:1.8.4 registry.aliyuncs.com/google_containers/coredns:v1.8.4
初始化操作
kubeadm init \
--apiserver-advertise-address=192.168.222.148 \
--image-repository registry.aliyuncs.com/google_containers \
--service-cidr=10.1.0.0/16 \
--pod-network-cidr=10.244.0.0/16
# 192.168.222.148 是master的ip
kubeadm init --kubernetes-version=v1.23.5 --apiserver-advertise-address=192.168.222.148 --image-repository registry.aliyuncs.com/google_containers --service-cidr=10.1.0.0/16 --pod-network-cidr=10.244.0.0/16
解决出错问题https://cloud.tencent.com/developer/article/2039072
故障
报错:[kubelet-check] The HTTP call equal to ‘curl -sSL http://localhost:10248/healthz’ failed with error: Get “http://localhost:10248/healthz”: dial tcp [::1]:10248: connect: connection refused.
问题分析:
之前我的Docker是用yum安装的,docker的cgroup驱动程序默认设置为system。默认情况下Kubernetes cgroup为systemd,我们需要更改Docker cgroup驱动,
解决方法
添加以下内容
vim /etc/docker/daemon.json
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
复制
# 重启docker
systemctl restart docker
复制
# 重新初始化
kubeadm reset # 先重置
kubeadm init \
--apiserver-advertise-address=192.168.42.122 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.22.2 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--ignore-preflight-errors=all
9. 接下来执行
要使非 root 用户可以运行 kubectl,请运行以下命令, 它们也是 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
或者,如果你是 root
用户,则可以运行:
export KUBECONFIG=/etc/kubernetes/admin.conf
10. node 加入节点
所有的node都需要关闭swap分区,swapoff -a
建议, 不要先在node节点上运行kubelet服务,不然会导致join失败,如果已经运行了,建议关闭,然后删除提示失败的文件和目录
kubeadm join --token <token> <control-plane-host>:<control-plane-port> --discovery-token-ca-cert-hash sha256:<hash>
如果没有令牌,可以通过在控制平面master节点上运行以下命令来获取令牌
kubeadm token list
如果你没有 --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/^.* //'
`kubectl get nodes`
加入节点
节点是你的工作负载(容器和 Pod 等)运行的地方。要将新节点添加到集群,请对每台计算机执行以下操作:
-
SSH 到机器
-
成为 root (例如
sudo su -
) -
必要时安装一个运行时
-
运行
kubeadm init
输出的命令,例如:kubeadm join --token <token> <control-plane-host>:<control-plane-port> --discovery-token-ca-cert-hash sha256:<hash>
如果没有令牌,可以通过在控制平面节点上运行以下命令来获取令牌:
kubeadm token list
输出类似于以下内容:
TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS
8ewj1p.9r9hcjoqgajrj4gi 23h 2018-06-12T02:51:28Z authentication, The default bootstrap system:
signing token generated by bootstrappers:
'kubeadm init'. kubeadm:
default-node-token
默认情况下,令牌会在 24 小时后过期。如果要在当前令牌过期后将节点加入集群, 则可以通过在控制平面节点上运行以下命令来创建新令牌:
kubeadm token create
输出类似于以下内容:
5didvk.d09sbcov8ph2amjw
如果你没有 --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/^.* //'
输出类似于以下内容:
8cb2de97839780a412b93877f8507ad6c94f73add17d5d7058e91741c9d5ec78
说明: 要为 <control-plane-host>:<control-plane-port>
指定 IPv6 元组,必须将 IPv6 地址括在方括号中,例如:[2001:db8::101]:2073
输出应类似于:
[preflight] Running pre-flight checks
... (log output of join workflow) ...
Node join complete:
* Certificate signing request sent to control-plane and response
received.
* Kubelet informed of new secure connection details.
Run 'kubectl get nodes' on control-plane to see this machine join.
几秒钟后,当你在控制平面节点上执行 kubectl get nodes
,你会注意到该节点出现在输出中。
说明: 由于集群节点通常是按顺序初始化的,CoreDNS Pod 很可能都运行在第一个控制面节点上。 为了提供更高的可用性,请在加入至少一个新节点后 使用 kubectl -n kube-system rollout restart deployment coredns
命令,重新平衡这些 CoreDNS Pod。
查看master节点上的所有节点服务器
[root@master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
master NotReady control-plane,master 2m32s v1.23.5
node1 NotReady <none> 103s v1.23.5
node2 NotReady <none> 87s v1.23.5
node3 NotReady <none> 16s v1.23.5
[root@master ~]#
# NotReady 说明master和node节点之间的通信还是有问题的,容器之间通信还没有准备好
删除节点
使用适当的凭证与控制平面节点通信,运行:
kubectl drain <node name> --delete-emptydir-data --force --ignore-daemonsets
在删除节点之前,请重置 kubeadm
安装的状态:
kubeadm reset
11. 安装网络插件flannel(在master节点执行)
get pod -n kube-system 看kube-system命令空间里的pod
查看各个节点详细信息
[root@master ~]# kubectl get nodes -n kube-system -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
master Ready control-plane,master 96m v1.23.5 192.168.222.154 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://20.10.18
node1 Ready <none> 95m v1.23.5 192.168.222.155 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://20.10.18
node2 Ready <none> 95m v1.23.5 192.168.222.156 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://20.10.18
node3 Ready <none> 93m v1.23.5 192.168.222.151 <none> CentOS Linux 7 (Core) 3.10.0-1160.el7.x86_64 docker://20.10.18
[root@master ~]#
查看k8s里的命令空间有哪些 —》 k8s 自己创建的
[root@master ~]# kubectl get ns
NAME STATUS AGE
default Active 101m
kube-node-lease Active 101m
kube-public Active 101m
kube-system Active 101m
永久修改
cat <<EOF >> /etc/sysctl.conf
net.bridge.bridge-nf-call-ip6tables =1
net.bridge.bridge-nf-call-iptables =1
net.ipv4.ip_forward = 1
vm.swappiness = 0
EOF
sysctl -p
多master 的 k8s集群
为什么master至少要3台?
答:数据的一致性问题,如何实现同时写的问题,每台master上的数据都是一样的
raft协议:一致性协议
paxos : Mysql的group replication 使用的
奇数台控制平面节点有利于机器故障或者网络分区时进行重新选主
deployment 控制器
查看有哪些命名空间namespace
[root@master ~]# kubectl get ns
NAME STATUS AGE
default Active 27m
kube-node-lease Active 27m
kube-public Active 27m
kube-system Active 27m
kubectl get deployment
[root@master ~]# kubectl get deployment
No resources found in default namespace.
resources: 部署控制器,pod, api, node,servers等
kubectl get deployment -n kube-system
[root@master ~]# kubectl get deployment -n kube-system
NAME READY UP-TO-DATE AVAILABLE AGE
coredns 0/2 2 0 161m
副本控制器:作用就是监控pod副本的数量,如果某个node节点挂了,这个节点上的pod也会挂了,这个时候,副本控制器会在其他的node节点上启动新的pod,数量总数达到副本控制器当时设置的数量 ----> 高可用
以pod制pod
kubectl create deployment k8s-nginx --image=nginx -r 8
kubectl create deployment 创建部署控制器
k8s-nginx 是控制器的名字
--images=nginx 指定控制器去启动pod使用的镜像
-r 8 启动8个nginx的pod
[root@master ~]# kubectl get pod -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
coredns-6d8c4cb4d-2gsqd 1/1 Running 0 34m 10.244.0.3 master <none> <none>
coredns-6d8c4cb4d-7tkw4 1/1 Running 0 34m 10.244.0.2 master <none> <none>
etcd-master 1/1 Running 1 35m 192.168.222.148 master <none> <none>
kube-apiserver-master 1/1 Running 1 35m 192.168.222.148 master <none> <none>
kube-controller-manager-master 1/1 Running 1 35m 192.168.222.148 master <none> <none>
kube-flannel-ds-dplgf 1/1 Running 0 51s 192.168.222.155 node1 <none> <none>
kube-flannel-ds-p5mqn 1/1 Running 0 51s 192.168.222.156 node2 <none> <none>
kube-flannel-ds-pgdrh 1/1 Running 0 51s 192.168.222.151 node3 <none> <none>
kube-flannel-ds-s5j95 1/1 Running 0 51s 192.168.222.148 master <none> <none>
kube-proxy-799xw 1/1 Running 0 30m 192.168.222.151 node3 <none> <none>
kube-proxy-8csdh 1/1 Running 0 32m 192.168.222.155 node1 <none> <none>
kube-proxy-dqhgj 1/1 Running 0 20m 192.168.222.156 node2 <none> <none>
kube-proxy-msnzp 1/1 Running 0 34m 192.168.222.148 master <none> <none>
kube-scheduler-master 1/1 Running 1 35m 192.168.222.148 master <none> <none>
[root@master ~]#
创建pod
[root@master ~]# kubectl create deployment k8s-nginx --image=nginx -r 8
deployment.apps/k8s-nginx created
[root@master ~]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
k8s-nginx 0/8 8 0 12s
[root@master ~]#
[root@master ~]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
k8s-nginx 8/8 8 8 54m
[root@master ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
k8s-nginx-6d779d947c 8 8 8 55m
[root@master ~]#
``