公司怎么建立网站,磁业 东莞网站建设,网站模板库,sem推广软件文章目录 概述由来主要功能 K8S架构架构图组件说明ClusterMasterNodekubectl 组件处理流程 K8S概念组成PodPod控制器ReplicationController#xff08;副本控制器#xff09;ReplicaSet #xff08;副本集#xff09;DeploymentStatefulSet #xff08;有状态副本集#… 文章目录 概述由来主要功能 K8S架构架构图组件说明ClusterMasterNodekubectl 组件处理流程 K8S概念组成PodPod控制器ReplicationController副本控制器ReplicaSet 副本集DeploymentStatefulSet 有状态副本集DaemonSetJobCronjob ServiceClusterIPNodePortLoadBalancerExternalName Endpoint网络Ingress Controller K8S安装安装方式选择MinikubeKubeadmin二进制包 K8S集群准备环境准备一个Master两个Node初始化环境三台安装docker三台 安装K8S集群安装kubeadm, kubelet and kubectl三台配置kubeadmmaster下载镜像(三台)初始化master加入node安装网络插件测试常用命令 K8s资源清单什么是资源资源分类资源清单 工作负载型资源(workloadPodPod控制器ReplicasetPod控制器Deployment 参考博客 本篇内容属于资料整理非笔者操作笔记用于学习记录其中有问题的地方请指出。 概述
由来
kubernetes简称K8s是用8代替8个字符“kubernete”而成的缩写。是一个开源的用于管理云平台中多个主机上的容器化的应用即我们常说的容器编排工具K8S的目标是让部署容器化的应用简单并且高效
k8s是谷歌开源的容器编排工具其实也是管理应用的全生命周期的一个工具Kubernetes在Docker技术之上为容器化的应用提供了资源调度、部署运行、服务发现和扩容缩容等丰富多样的功能从创建应用应用部署应用提供服务扩容缩容应用更新都非常的方便而且可以做到故障自愈例如一个服务器挂了可以自动将这个服务器上的服务调度到另外一个主机上进行运行无需进行人工干涉。如果你曾经用过Docker部署容器那么可以将Docker看成Kubernetes底层使用的组件Kubernetes是Docker的上层封装通过它可以很方便的进行Docker集群的管理。
主要功能
基于容器的应用部署、维护和滚动升级
自我修复负载均衡和服务发现跨机器和跨地区的集群调度自动伸缩、水平扩展无状态服务和有状态服务广泛的Volume存储卷的支持插件机制保证扩展性
K8S架构
架构图 组件说明
Cluster
Cluster是计算、存储和网络资源的集合Kubernetes利用这些资源运行各种基于容器的应用. Kubernetes Cluster由Master和Node组成节点上运行着若干Kubernetes服务。
Master
API server 提供了k8s各类资源对象pod,RC,Service等的增删改查及watch等HTTP Rest接口是整个系统 的数据总线和数据中心。Controlle Manager (kube-controller-manager) kubernets 里面所有资源对象的自动化控制中心可以理解为资源对象的大总管保证集群中各种资 源的状态和用户定义(yaml)的状态一致, 如果出现偏差, 则修正资源的状态(维护容器的数量始终和 定义的一样)。Scheduler (kube-scheduler) 负责资源调度pod调度的进程调度器的职责主要是通过调度算 法为新创建的pod在集群中寻找最合适的node并将pod调度到Node上。Controlle Manager (kube-controller-manager) kubernets 里面所有资源对象的自动化控制中心可以理解为资源对象的大总管保证集群中各种资源的状态和用户定义(yaml)的状态一致, 如果出现偏差, 则修正资源的状态(维护容器的数量始终和定义的一样)。Scheduler (kube-scheduler) 负责资源调度pod调度的进程调度器的职责主要是通过调度算 法为新创建的pod在集群中寻找最合适的node并将pod调度到Node上。Etcd Etcd分布式键值存储是Kubernetes集群中的一个关键组件。用于持久化存储集群中所有的资源对象如Node、Service、Pod、RC、Namespace等API Server提供了操作etcd的封装接口API这些API基本上都是集群中资源对象的增删改查及监听资源变化的接口。 Etcd是由CoreOS开发的一种高可用性、一致性和分布式的键值存储系统它作为Kubernetes的后端数据库负责存储集群状态信息、配置数据和访问控制列表等。Etcd使用Raft一致性算法1来保证数据的一致性和可靠性并提供了简单的API接口供其他组件进行读写操作。 Etcd在Kubernetes中扮演着存储和共享集群配置、元数据和状态信息的角色为集群的正常运行提供支持。
Node Kubelet 负责pod对应的容器创建、启停等任务同时与master 节点密切协作处理 Master 节点下发到本 节点的任务按照 PodSpec 描述来管理Pod 和其中的容器,实现集群管理的基本功能。 kube-proxy 实现Kubernetes Service的服务发现与负载均衡机制的重要组件,比如要通过外网访问k8s就需要该组 件进行代理容器与容器之间负载均衡也需要kube-proxy。 Docker Engine Docker引擎负责本机的容器创建和管理工作。
kubectl
kubectl是Kubernetes的命令行工具用于与Kubernetes集群进行交互和管理。它允许用户通过命令行界面执行各种操作如创建、删除、更新和查看Kubernetes资源对象如Pods、Services、Deployments等。
使用kubectl命令来管理Kubernetes集群例如
创建和启动应用程序的Pods、Deployments和Services扩展和缩小应用程序的副本数量查看和监视集群中的资源状态更新和回滚应用程序的配置调试和故障排除集群中的问题管理命名空间、访问控制和安全策略等。
kubectl提供了丰富的命令选项和参数可用于满足各种需求。通过与Kubernetes API进行通信kubectl使得与Kubernetes集群交互变得方便和直观。
组件处理流程
通过Kubectl提交一个创建RC的请求该请求通过API Server被写入etcd中(存储请求)此时Controller Manager通过API Server的监听资源变化的接口监听到这个RC事件分析之后发现当前集群中还没有它所对应的Pod实例于是根据RC里的Pod模板定义生成一个Pod对象通过API Server写入etcd(创建pod)接下来此事件被Scheduler发现它立即执行一个复杂的调度流程为这个新Pod选定一个落户的Node然后通过API Server将这一结果写入到etcd中Pod分配Node随后目标Node上运行的Kubelet进程通过API Server监测到这个“新生的”Pod并按照它的定义启动该Pod并任劳任怨地负责它的下半生直到Pod的生命结束。(接管Pod)接着通过Kubectl提交一个新的映射到该Pod的Service的创建请求Controller Manager会通过Label标签查询到相关联的Pod实例然后生成Service的Endpoints信息可被访问的服务端点即一个状态为running的pod并通过API Server写入到etcd中接下来所有Node上运行的Proxy进程通过API Server查询并监听Service对象与其对应的Endpoints信息建立一个软件方式的负载均衡器来实现Service访问到后端Pod的流量转发功能。
K8S概念组成
Pod
Pod是K8S中可以创建的最小部署单元一个Pod代表集群上正在运行的一个进程。Pod代表部署的一个单位K8S中单个应用的实例它可能由单个容器或多个容器共享组成。
Pod中的容器共享两种资源网络和存储。
每个Pod被分配一个独立的IP地址Pod中的每个容器共享网络命名空间包括IP地址和网络端口Pod可以指定一组共享存储volumes。
Pod管理方式不同也分为
自助式PodPod退出了不会被创建。控制器管理的Pod始终会维持Pod的副本数。
Pod控制器
Kubernetes 中内建了很多 controller控制器这些相当于一个状态机用来控制 Pod 的具体状态和行为。
ReplicationController副本控制器
确保Pod的数量始终保持设定的个数如果容器异常退出会自动创建新的Pod来替代也支持Pod的滚动更新。 已经废弃的Pod建议使用ReplicaSet 。 滚动更新创建新的版本然后删除旧的版本实现版本的最新滚动更新。
ReplicaSet 副本集
它和ReplicationController没有根本的区别它支持集合式的Selector选择多个Pod,但是它不直接使用由一个声明式更新的控制器叫Deployment来负责管理。 有状态服务通常指需要持久状态的服务 (Mysql)无状态:通常指无需存储服务状态的服务(tomcat)。
Deployment
Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义 (declarative) 方法用来替代以前的 ReplicationController 来方便的管理应用只需要在Deployment中描述你想要的目标状态是什么Deployment controller就会帮你将Pod和Replica Set的实际状态改变到你的目标状态。
典型的应用场景包括
定义 Deployment 来创建 Pod 和 ReplicaSet滚动升级和回滚应用扩容和缩容暂停和继续 Deployment
但是Deployment只能负责管理那些无状态的应用。
StatefulSet 有状态副本集
负责管理有状态的应用。
使用场景如
稳定的持久化存储Pod重新调度后还能访问到相同的持久化数据稳定的网络标志Pod重新调度后PodName和HostName不变有序部署Pod有序删除Pod
DaemonSet
用来确保每一个Node上只运行一个Pod副本Node加入集群时为他们创建一个Pod,当有Node从集群中移除时,Pod会被回收删除DaemonSet将会删除它创建的所有Pod。
使用场景 为每一个Node创建一个日志收集的Pod
Job
负责批处理任务即仅执行一次任务。 比如某个应用生成了一大堆数据集现在需要临时启动一个Pod去清理这些数据集清理完成后这个Pod就可以结束了。 这些不需要一直处于运行状态的应用就用Job这个类型的控制器去控制。如果Pod运行过程中意外中止了Job负责重启Pod。如果Pod任务执行完了就不需要再启动了。
Cronjob
周期性作业。 使用场景 周期性的执行备份数据库
Service
我们不应该期望 Kubernetes Pod 是健壮的而是要假设 Pod 中的容器很可能因为各种原因发生故障而死掉。Deployment 等 controller 会通过动态创建和销毁 Pod 来保证应用整体的健壮性。换句话说Pod 是脆弱的但应用是健壮的。每个 Pod 都有自己的 IP 地址。当 controller 用新 Pod 替代发生故障的 Pod 时新 Pod 会分配到新的 IP 地址。
这样就产生了一个问题
如果一组 Pod 对外提供服务比如 HTTP它们的 IP 很有可能发生变化那么客户端如何找到并访问这个服务呢Kubernetes 给出的解决方案是 Service。
Service可以看作是一组提供相同服务的Pod对外的访问接口。借助Service应用可以方便地实现服务发现和负载均衡。
Kubernetes Service 从逻辑上代表了一组 Pod具体是哪些 Pod 则是由 label 来挑选。Service 有自己 IP而且这个 IP 是不变的。客户端只需要访问 Service 的 IPKubernetes 则负责建立和维护 Service 与 Pod 的映射关系。无论后端 Pod 如何变化对客户端不会有任何影响因为 Service 没有变。
ClusterIP
给service指定默认的ClusterIP这种方式分配的ip只能在集群内部访问。
NodePort
在每个节点上都监听一个同样的端口号(30000-32767)ClusterIP和路由规则会自动创建。集群外部可以访问:联系到集群内部服务可以配合外部负载均衡使用。 简单理解使用端口映射方式去访问容器
LoadBalancer
要配合支持公有云负载均衡使用比如GCE、AWS。其实也是NodePort不过除了使用一个Cluster IP和nodePort之外还会向所使用的公有云申请一个负载均衡器(负载均衡器后端映射到各节点的nodePort)实现从集群外通过LB访问服务。
ExternalName
创建一个dns别名指到service name上主要是防止service name发生变化要配合dns插件使用。
理解Service
Endpoint
是可被访问的服务端点即一个状态为running的pod它是service访问的落点只有service关联的pod才可能成为endpoint。简单理解endpoint 用来记录一个service对应的所有pod的访问地址。
网络
节点网络 各主机Master、Node、ETCD等自身所属的网络地址配置在主机的网络接口用于各主机之间的通信又称为节点网络。Pod网络 专用于Pod资源对象的网络它是一个虚拟网络用于为各Pod对象设定IP地址等网络参数其地址配置在Pod中容器的网络接口上。Pod网络需要借助kubenet插件或CNI插件实现。Service网络 专用于Service资源对象的网络它也是一个虚拟网络用于为K8S集群之中的Service配置IP地址但是该地址不会配置在任何主机或容器的网络接口上而是通过Node上的kube-proxy配置为iptables或ipvs规则从而将发往该地址的所有流量调度到后端的各Pod对象之上。
Ingress Controller
Service 是后端真实服务的抽象一个 Service 可以代表多个相同的后端服务。
Ingress 是反向代理规则用来规定 HTTP/S 请求应该被转发到哪个 Service 上比如根据请求中不同的 Host 和 url 路径让请求落到不同的 Service 上。
Ingress Controller 就是一个反向代理程序它负责解析 Ingress 的反向代理规则如果 Ingress 有增删改的变动所有的 Ingress Controller 都会及时更新自己相应的转发规则当 Ingress Controller 收到请求后就会根据这些规则将请求转发到对应的 Service。
K8S安装
安装方式选择
安装部署主要方式分为三大类minikube(单机) kubeadmin二进制包(生产环境) 我们这里采用kubeadmin的方式来安装。
Minikube
最为单机运行的k8s集群直接使用官网感受一下点击launch terminal 浏览器下发会弹出命令界面。
Kubeadmin
配置基础环境 - 安装kubeadmin部署工具 - 使用kubeadmin配置master 、node、网络、dashboard等等。下面使用这种方式安装。
二进制包
相比上述两种有些复杂但是可以通过二进制安装学到不少东西。
K8S集群准备 环境准备一个Master两个Node
推荐配置内存4G以上CPU 2 核以上 安装ContOS的磁盘 100G以上网络使用桥接。
设置静态IP三台 可以通过可视化界面修改
vi /etc/sysconfig/network-scripts/ifcfg-ens32TYPEEthernet
PROXY_METHODnone
BROWSER_ONLYno
BOOTPROTOstatic # 使用静态IP地址默认为dhcp
IPADDR192.168.241.100 # 设置的静态IP地址
NETMASK255.255.255.0 # 子网掩码
GATEWAY192.168.241.1 # 网关地址
DNS1192.168.241.1 # DNS服务器
DNS2119.29.29.29
DEFROUTEyes
IPV4_FAILURE_FATALno
IPV6INITyes
IPV6_AUTOCONFyes
IPV6_DEFROUTEyes
IPV6_FAILURE_FATALno
IPV6_ADDR_GEN_MODEstable-privacy
NAMEens33
DEVICEens33
ONBOOTyes #是否开机启用## 删除
rm -f /etc/udev/rule.d/70-persistent-net.rules
reboot 查看ip和上网分别设置主机名
hostnamectl set-hostname k8smaster
hostnamectl set-hostname k8snode01
hostnamectl set-hostname k8snode02确保网络ok
ping www.baidu.com初始化环境三台
设置hosts vi /etc/hosts172.16.7.252 k8snode02
172.16.7.251 k8snode01
172.16.7.250 k8smaster关闭防火墙 # 关闭防火墙并禁止开机启动
systemctl stop firewalld systemctl disable firewalld
# 查看防火墙状态
systemctl status firewalld禁用selinux # 临时禁用
setenforce 0# 永久禁用
vim /etc/sysconfig/selinux
修改SELINUXdisabled #查看selinux的状态信息
/usr/sbin/sestatus禁用交换分区
# 临时关闭
swapoff -a# 永久关闭
vi /etc/fstab
# 注释掉以下字段
/dev/mapper/cl-swap swap swap defaults 0 0创建k8s配置
# 写入配置
cat EOF /etc/sysctl.d/k8s.confnet.bridge.bridge-nf-call-ip6tables 1net.bridge.bridge-nf-call-iptables 1net.ipv4.ip_forward 1vm.swappiness0 EOF
# 执行命令使修改生效
modprobe br_netfilter
# 查看
sysctl -p /etc/sysctl.d/k8s.confkube-proxy开启ipvs的前置条件
# 保证在节点重启后能自动加载所需模块
cat /etc/sysconfig/modules/ipvs.modules EOF
#!/bin/bash
modprobe -- ip_vs
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
modprobe -- ip_vs_sh
modprobe -- nf_conntrack_ipv4EOF# 加上执行权限
chmod 755 /etc/sysconfig/modules/ipvs.modules bash /etc/sysconfig/modules/ipvs.modules lsmod | grep -e ip_vs -e nf_conntrack_ipv4
# 查看是否已经正确加载所需的内核模块
lsmod | grep -e ip_vs -e nf_conntrack_ipv4
# 安装了ipset软件包
yum -y install ipset
# 为了便于查看ipvs的代理规则,安装管理工具ipvsadm
yum -y install ipvsadm同步时间
yum -y install ntp ntpdate
ntpdate cn.pool.ntp.org
hwclock --systohc
timedatectl安装docker三台
菜鸟教程安装
卸载旧版本
yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-selinux \docker-engine-selinux \docker-engine
安装
# 预装工具
yum install -y yum-utils device-mapper-persistent-data lvm2
# 配置docker源
sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo# 更新yum缓存
sudo yum makecache fast
# 查看版本
yum list docker-ce --showduplicates | sort -r
# 安装指定版本
yum install docker-ce-18.06.3.ce-3.el7
# 安装(最新版本)
sudo yum -y install docker-ce配置镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json -EOF
{registry-mirrors: [https://5pfmrxk8.mirror.aliyuncs.com]
}
EOF启动
systemctl daemon-reload systemctl start docker systemctl enable docker注意确认一下iptables filter表中FOWARD链的默认策略(pllicy)为ACCEPT
iptables -nvLChain INPUT (policy ACCEPT 9 packets, 760 bytes)
pkts bytes target prot opt in out source destination Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination如果不是ACCEPT则修改
iptables -P FORWARD ACCEPT
8.8.8.8kubeadm初始化警告”cgroupfs“解决
安装K8S集群
安装kubeadm, kubelet and kubectl三台
配置yum路径
cat EOF /etc/yum.repos.d/kubernetes.repo[kubernetes]nameKubernetesbaseurlhttps://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/enabled1gpgcheck1repo_gpgcheck1gpgkeyhttps://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpgEOF安装kubeadm, kubelet and kubectl
yum install -y kubelet-1.15.6 kubeadm-1.15.6 kubectl-1.15.6启动
systemctl enable kubelet systemctl start kubelet配置kubeadmmaster
创建kubeadm配置文件
kubeadm config print init-defaults --kubeconfig ClusterConfiguration kubeadm.yml编辑配置文件
vim kubeadm.yml#只需要Master创建创建好之后修改配置文件内容
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:- system:bootstrappers:kubeadm:default-node-tokentoken: abcdef.0123456789abcdefttl: 24h0m0susages:- signing- authentication
kind: InitConfiguration
localAPIEndpoint:advertiseAddress: 192.168.1.250 #master地址bindPort: 6443
nodeRegistration:criSocket: /var/run/dockershim.sockname: k8smastertaints:- effect: NoSchedulekey: node-role.kubernetes.io/master
---
apiServer:timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:type: CoreDNS
etcd:local:dataDir: /var/lib/etcd
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers #修改镜像
kind: ClusterConfiguration
kubernetesVersion: v1.15.0
networking:dnsDomain: cluster.localpodSubnet: 192.168.0.0/16 # 集群的网络serviceSubnet: 10.96.0.0/12 #子网掩码
scheduler: {}
# 开启 IPVS 模式在 scheduler:{}下面加上 --- 然后复制下面内容
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
featureGates:SupportIPVSProxyMode: true
mode: ipvs下载镜像(三台)
查看所需镜像列表
kubeadm config images list --config kubeadm.yml
# 拉取镜像 - 不要执行下面这个命令
kubeadm config images pull --config kubeadm.yml
# 注意由于下载很慢所以采用已经打包好的镜像docker镜像批量打包 由于在内网环境或网速较慢的时候下载镜像比较慢所以可以将镜像打包成文件进行拷贝。这里写了一个批量打包镜像的语句。 批量打包镜像:
将机器上的所有镜像打包到haha.tar文件里面。
docker save $(docker images | grep -v REPOSITORY | awk BEGIN{OFS:;ORS }{print $1,$2}) -o k8simgs.tar#打包指定镜像
docker save imgName2:version imgName2:version-o /打包的镜像名.tar#机器之间拷贝文件
scp -r /k8simgs.tar root192.168.1.100:/# 加载镜像
docker load -i /k8simgs.tar然后docker images就可以看到拷贝过来的镜像了。
上传打包好的镜像
# 使用ftp工具上传到目录
/root/k8simgs.tar 在三台机器加载镜像
#拷贝文件到另外两个centos
scp -r /root/k8simgs.tar root192.168.0.114:/root/k8simgs.tar也可以把压缩包上传到三个cenos分别再加载。
加载镜像
docker load -i /root/k8simgs.tar初始化master
初始化进入主节点kubeadm.yml 所在目录执行
kubeadm init --configkubeadm.yml 如果要重新初始化可以执行kubeadm reset 重置。
Master执行配置从上面输出中拷贝
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 node
# 并且拷贝命令到个节点执行kubeadm初始化警告”cgroupfs“解决
加入node
将 slave 加入到集群拷贝命令,从上面输出中拷贝不要拷贝我的要拷贝你自己的日志里面
kubeadm join 172.16.40.252:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:9f792d9c1bf57977ff22f317b599504a733b3f66688273ac3aa7505931f8e378 验证是否加入成功
kubectl get nodes这里的status是NotReady是因为容器之间还没通信。 加入失败 如果 slave 节点加入 master 时配置有问题可以在 slave 节点上使用 kubeadm reset 重置配置再使用 kubeadm join 命令重新加入即可。希望在 master 节点删除 node 可以使用 kubeadm delete nodes 删除。 可以使用journalctl -f -u kubelet查看错误日志 k8s 集群 节点状态显示notready Pod 状态查看
kubectl get pod -n kube-system -o wide由此可以看出 coredns 尚未运行此时我们还需要安装网络插件。
安装网络插件 容器网络 容器之间需要通信需要安装网络插件我们使用CNI插件 容器网络是容器选择连接到其他容器、主和外部网络的机制。容器的 runtime 提供了各种网络模式每种模式都会产生不同的体验。例如Docker 默认情况下可以为容器配置以下网络 bridge 网络这是 Docker 默认的网络模式。在此模式下Docker 守护进程会创建一个名为 docker0 的虚拟网桥并为每个新容器分配一个 IP 地址。容器可以通过此网桥与宿主机和其他容器进行通信。它还使用 NATNetwork Address Translation来实现容器与外部网络的通信。 none 容器没有网络接口。容器仅能通过 Unix Socket 进行与宿主机通信。这种模式适用于一些特殊的用例如只需要运行某些系统工具的容器。 host 容器与宿主机共享网络栈。容器直接使用宿主机的网络接口和 IP 地址因此容器可以通过宿主机的 IP 直接与外部网络通信。这意味着容器与宿主机共享相同的网络命名空间。 自定义网桥用户定义的网桥具有更多的灵活性、隔离性和其他便利功能 默认的网络模式不适用这里使用CNI。 什么是 CNI CNI(Container Network Interface) 是一个标准的通用的接口。在容器平台DockerKubernetesMesos 容器网络解决方案 flannel(Docker提供)calico(Kubernetes提供)weave(Mesos 提供)。只要提供一个标准的接口就能为同样满足该协议的所有容器平台提供网络功能而 CNI 正是这样的一个标准接口协议。 Kubernetes 中的 CNI 插件 CNI 的初衷是创建一个框架用于在配置或销毁容器时动态配置适当的网络配置和资源。插件负责为接口配置和管理 IP 地址并且通常提供与 IP 管理、每个容器的 IP 分配、以及多主机连接相关的功能。容器运行时会调用网络插件从而在容器启动时分配 IP 地址并配置网络并在删除容器时再次调用它以清理这些资源。 运行时或协调器决定了容器应该加入哪个网络以及它需要调用哪个插件。然后插件会将接口添加到容器网络命名空间中作为一个 veth 对的一侧。接着它会在主机上进行更改包括将 veth 的其他部分连接到网桥。再之后它会通过调用单独的 IPAMIP地址管理插件来分配 IP 地址并设置路由。 在 Kubernetes 中kubelet 可以在适当的时间调用它找到的插件为通过 kubelet 启动的 pod进行自动的网络配置。 Kubernetes 中可选的 CNI 插件如下Flannel、Calico、Canal 、Weave 这里使用Calico 什么是 Calico Calico 为容器和虚拟机提供了安全的网络连接解决方案并经过了大规模生产验证在公有云和跨数千个集群节点中可与 KubernetesOpenShiftDockerMesosDC / OS 和 OpenStack 集成。 Calico 还提供网络安全规则的动态实施。使用 Calico 的简单策略语言您可以实现对容器虚拟机工作负载和裸机主机端点之间通信的细粒度控制。 安装 Calico三台参考官方文档安装
kubectl apply -f https://docs.projectcalico.org/v3.9/manifests/calico.yaml注意如果node下载不了直接在所有节点通过docker pull下载
验证成功 watch kubectl get pods --all-namespaces查看Nodes kubectl get nodes
测试常用命令
检查组件运行状态
kubectl get cs# 输出如下
NAME STATUS MESSAGE ERROR
# 调度服务主要作用是将 POD 调度到 Node
scheduler Healthy ok
# 自动化修复服务主要作用是 Node 宕机后自动修复 Node 回到正常的工作状态
controller-manager Healthy ok
# 服务注册与发现
etcd-0 Healthy {health:true} 检查 Master 状态
kubectl cluster-info# 输出如下
# 主节点状态
Kubernetes master is running at https://172.16.33.165:6443# DNS 状态
KubeDNS is running athttps://172.16.33.165:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxyTo further debug and diagnose cluster problems, use kubectl cluster-info dump.检查 Nodes 状态
kubectl get nodes# 输出如下STATUS 为 Ready 即为正常状态
[rootkmaster-01 calico]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
kmaster-01 Ready master 22m v1.15.2
knode-01 Ready none 11m v1.15.2查看全部 Pods 的状态
kubectl get pods kubectl get pods 等价于 kubectl get pods -n default ,default是默认的名称空间kubectl get pods -n kube-system# kube-system 是k8s内部组件的名称空间
输出如下需要等待一小段实践STATUS 为 Running 即为运行成功
NAME READY STATUS RESTARTS AGE
nginx-755464dd6c-qnmwp 1/1 Running 0 90m
nginx-755464dd6c-shqrp 1/1 Running 0 90m查看已部署的服务
kubectl get deployment# 输出如下
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 2/2 2 2 91m映射服务让用户可以访问
kubectl expose deployment nginx --port80 --typeLoadBalancer# 输出如下
service/nginx exposed查看已发布的服务
kubectl get services# 输出如下
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 none 443/TCP 44h
# 由此可见Nginx 服务已成功发布并将 80 端口映射为 31738
nginx LoadBalancer 10.108.121.244 pending 80:31738/TCP 88m查看服务详情
kubectl describe service nginx# 输出如下
Name: nginx
Namespace: default
Labels: runnginx
Annotations: none
Selector: runnginx
Type: LoadBalancer
IP: 10.108.121.244
Port: unset 80/TCP
TargetPort: 80/TCP
NodePort: unset 31738/TCP
Endpoints: 192.168.17.5:80,192.168.8.134:80
Session Affinity: None
External Traffic Policy: Cluster
Events: none验证是否成功 通过浏览器访问 Master 服务器 http://172.16.33.165:31738/ 此时 Kubernetes 会以负载均衡的方式访问部署的 Nginx 服务能够正常看到 Nginx 的欢迎页即表示成功。容器实际部署在其它 Node 节点上通过访问 Node 节点的 IP:Port 也是可以的。停止服务
kubectl delete deployment nginx# 输出如下
deployment.extensions nginx deletedkubectl delete service nginx# 输出如下
service nginx deleted# 看系统日志
cat /var/log/messages# 用kubectl 查看日志# 注意使用Kubelet describe 查看日志一定要带上 命名空间否则会报如下错误
[rootnode2 ~]# kubectl describe pod coredns-6c65fc5cbb-8ntpv
Error from server (NotFound): pods coredns-6c65fc5cbb-8ntpv not foundkubectl describe pod kubernetes-dashboard-849cd79b75-s2snt --namespace kube-systemkubectl logs -f pods/monitoring-influxdb-fc8f8d5cd-dbs7d -n kube-systemkubectl logs --tail 200 -f kube-apiserver -n kube-system |morekubectl logs --tail 200 -f podname -n jenkins# 用journalctl查看日志非常管用journalctl -u kube-schedulerjournalctl -xefu kubeletjournalctl -u kube-apiserverjournalctl -u kubelet |tailjournalctl -xe# 用docker查看日志docker logs c36c56e4cfa3 (容器id)# 换3.9版本
# 先现在node
# 杀死所有正在运行的容器
docker kill $(docker ps -a -q)删除所有已经停止的容器
docker rm $(docker ps -a -q)删除所有未打 dangling 标签的镜
docker rmi $(docker images -q -f danglingtrue)删除所有镜像
docker rmi $(docker images -q)强制删除 无法删除的镜像
docker rmi -f IMAGE_ID
docker rmi -f $(docker images -q)~/.bash_aliases杀死所有正在运行的容器.
alias dockerkilldocker kill $(docker ps -a -q)删除所有已经停止的容器.
alias dockercleancdocker rm $(docker ps -a -q)删除所有未打标签的镜像.
alias dockercleanidocker rmi $(docker images -q -f danglingtrue)删除所有已经停止的容器和未打标签的镜像.
alias dockercleandockercleanc || true dockercleaniK8s资源清单
什么是资源
k8s中所有的内容都被抽象为资源资源实例化之后叫做对象。简单理解资源清单就是一个编写好的资源文件k8s根据资源清单来进行pod的创建
资源分类
名称空间级别 这一类资源仅在此名称空间下生效k8s的系统组件是默认放在kube-system名称空间下的而kubectl get pod等价于kubectl get pod -n default因此查看不到k8s的系统组件。
工作负载型资源(workloadPod【k8s最小组成部分共享网络栈共享存储卷】、ReplicaSet【RS调度器、控制器通过标签去控制pod的创建、副本数量】、Deployment【控制器通过控制RS的创建去创建pod】、StatefulSet【为有状态服务所建立的管理器】、DaemonSet【可以在每一个节点都运行一个pod的组件】、Job【工作、任务】、CronJob【轮询工作、轮询任务为批处理而生的】ReplicationController在v1.11版本被废弃服务发现及负载均衡型资源ServiceDiscovery LoadBalance):Service【简称svc服务将服务暴露出去】、Ingress【将服务暴露出去】、…配置与存储型资源Volume存储卷【给pod提供持久化的能力】、CSI容器存储接口可以扩展各种各样的第三方存储卷特殊类型的存储卷ConfigMap当配置中心来使用的资源类型【一般用来存储配置文件达到热更新的状态】、Secret保存敏感数据【加密方案存储数据一般用来保存密码文件、密钥等等】、DownwardAPI把外部环境中的信息输出给容器【类似于CSI】 集群级别 不管在任何名称空间下定义在其他的名称空间下都能看得到在定义的时候无需指定名称空间 例如Namespace【名称空间】、Node【节点】、Role【角色】、ClusterRole、RoleBinding、ClusterRoleBinding 元数据级别 提供一个指标不像是名称空间类型又不像集群级别本质上更像是在两者之间但是它有自己的特点所以更应该作为一个单独的分类例如HPA【通过cpu的利用率进行平滑扩展】就是一个很明显的元数据类型通过指标进行操作。 根据一些指标去进行对应的操作 例如HPA、PodTemplate【pod模板】、LimitRange【资源限制】
资源清单
什么是资源清单 k8s一般都是通过定义资源清单的方式去创建资源资源清单等价于剧本写好了每一步应该如何去做。在k8s中一般使用yaml格式的文件来创建符合我们预期期望的资源这样的yaml文件我们一般称为资源清单。资源清单定义格式 必须存在的字段 具体定义使用yaml格式如下
apiVersion: group/apiversion #如果没有给定group名称那么默认为core可以使用kubectl api-versions命令获取当前k8s版本上所有的apiversion版本信息每个版本可能不同
kind: #资源类别
metadata: #资源元数据name: namespace: lables: annotations: #主要目的是方便用户阅读查找
spec: #期望的状态disired state)
status: #当前状态本字段由Kubernetes自身维护用户不能去定义
apiVersion: v1
kind: Pod #定义pod资源
metadata:name: myapp-pod #pod的名字labels:app: myApp #pod标签version: v1 #pod的版本
spec: #pod的详细配置containers: #pod包含的多个容器配置- name: app #第一个容器image: myapp:v1 #容器版本- name: myapp # 第二个容器报错删除后没有问题image: myapp:v1 #容器版本常见命令 查看pod的yml清单配置语法
kubectl explain pod# 这个命令会告诉我们编写一个pod资源的yml清单应该使用那些语法
kubectl explain pod.apiVersion2. 导出yml资源清单
kubectl get pods # 查看有那些pod
kubectl get pod pod的名字 -o yaml 工作负载型资源(workload
Pod
Pod是K8S中可以创建的最小部署单元一个Pod代表集群上正在运行的一个进程。Pod代表部署的一个单位K8S中单个应用的实例它可能由单个容器或多个容器共享组成。
演示案例把一个Nignx容器运行在一个Pod中
创建资源文件
vi poddemo.yaml # 内容如下添加如下内容
apiVersion: v1
kind: Pod
metadata:name: app-pod #pod名字labels:app: app-label #pod的标签version: v1
spec:containers:- name: app #容器名字
image: nginx #容器镜像
imagePullPolicy: IfNotPresent #或者 Never 从本地找镜像根据资源文件创建pod
kubectl apply -f poddemo.yaml相关命令
kubectl get pod # 查看pod
kubectl get pod -o wide # 详细信息包括ip
kubectl describe pod app-pod # 查询pod描述 可以看到那个pod启动状态
kubectl logs app-pod -c app # 查看pod里面那个容器的启动状态
kubectl delete pod app-pod # 删除指定pod
kubectl delete -f poddemo.yaml # 删除全部
kubectl create -f poddemo.yaml # 效果和kubectl apply差不多Pod控制器Replicaset
通常不直接部署及管理Pod而是借助控制器Controller进行管理包括 ReplicationController老版本的、ReplicaSet、Deployment、StatefulSet、Job等。Pod控制器通常包含三个组成部分标签选择器、期望的副本数、Pod模板。 Replicaset是ReplicationController的替代者确保Pod副本数在任一时刻都精确满足期望值可以进行扩缩容也可以进行升级。
创建资源文件
vi rs.yaml加入如下内容
apiVersion: apps/v1
kind: ReplicaSet
metadata:name: rs-example #RS的名字
spec:replicas: 2 #创建2个pod副本selector: #选择什么样的podmatchLabels:app: rs-demo #选择名字叫rs-demo的podtemplate: #定义pod的模板metadata:labels:app: rs-demo #pod的标签正好被RS选择spec:containers: #pod中的容器配置- name: myappimage: nginximagePullPolicy: Never #IfNotPresent如果不存在再去网络拉取ports: #暴露容器的端口- name: httpcontainerPort: 80创建ReplicaSet
kubectl create -f rs.yaml相关命令
kubectl get pods删除pod后会自动复制
Kubectl delete pod --all显示标签
kubectl get pods --show-labels 修改标签
kubectl label pod rs-example-knjhx apprs-demo1 --overwritetrue更改后lable后重新补齐
Pod控制器Deployment
Deployment构建于ReplicaSet之上 支持事件和状态查看回滚版本记录暂停和启动升级多种自动更新方案Recreate先删除再新建Deployment支持RollingUpdate(滚动升级逐步替换)
什么是滚动升级如有三个副本先建立一个新的副本然后删除一个老的副本再建立一个新的副本删除一个老的副本
准备镜像(可以跳过) 我们基于tomcat准备三个不同版本的tomcat镜像为Deployment做滚动升级做准备您可以按照如下步骤打包三个tomcat镜像也可以使用课件资料中的resources/tomcatimgs.tar我已经准备好的资源镜像包如果使用我的镜像包就上传tomcatimgs.tar到三个k8s服务器/root目录执行docker load -i /root/tomcatimgs.tar 即可加载三个版本的镜像。
下载tomcat镜像
docker pull tomcat运行tomcat容器
docker run -id --nametomcat -p 8080:8080 tomcat准备index.jsp
% page languagejava contentTypetext/html; charsetutf-8 importjava.net.InetAddresspageEncodingutf-8%
!DOCTYPE html PUBLIC -//W3C//DTD HTML 4.01 Transitional//EN http://www.w3.org/TR/html4/loose.dtd
html
head
meta http-equivContent-Type contenttext/html; charsetutf-8
titleindex.jsp/title
/head
bodyh2v1/h2%InetAddress addr InetAddress.getLocalHost();out.println(主机地址addr.getHostAddress());out.println(主机名addr.getHostName()); %
/body
/html创建镜像 修改分别得到tomcat:v1 tomcat:v2 tomcat:v3
docker exec -it tomcat /bin/bash 进入容器
mkdir /usr/local/tomcat/webapps/ROOT
exit 退出容器vim index.jsp 创建页面拷贝上面jsp内容
docker cp index.jsp tomcat:/usr/local/tomcat/webapps/ROOT/
http://192.168.0.113:8080/ 访问测试
docker commit tomcat tomcat:v1 构建镜像tomat:v1修改index.jsp内容 h2v2/h2
docker cp index.jsp tomcat:/usr/local/tomcat/webapps/ROOT/
http://192.168.0.113:8080/ 访问测试
docker commit tomcat tomcat:v2 构建镜像tomat:v2修改index.jsp内容 h2v3/h2
docker cp index.jsp tomcat:/usr/local/tomcat/webapps/ROOT/
http://192.168.0.113:8080/ 访问测试
docker commit tomcat tomcat:v3 构建镜像tomat:v3拷贝镜像 打包三个镜像共享给其他节点
docker save tomcat:v1 tomcat:v2 tomcat:v3 -o /root/tomcatimgs.tar
# 其他两个节点做
scp -r tomcatimgs.tar root192.168.0.114:/root加载镜像
docker load -i /root/tomcatimgs.tarDeployment控制pod
(1) 创建pod
创建资源文件
vi deploy.yaml加入如下内容
apiVersion: apps/v1
kind: Deployment
metadata:name: deploy-example
spec:replicas: 2selector:matchLabels:app: deploy-demotemplate:metadata:labels:app: deploy-demospec:containers:- name: myappimage: tomcat:v1 #这里是对应我们三个tomcat镜像imagePullPolicy: Never #IfNotPresent如果不存在再去网络拉取ports:- name: httpcontainerPort: 8080创建Deployment
kubectl apply -f deploy.yaml需要注意三个k8s机器上都要有镜像tomcat:v1;tomcat:v2:tomcat:v3
查看pods
kubectl get pods -o wide # 查看pod详情
curl 192.168.32.168:8080 # 访问容器通过pod的网络访问外网目前访问不到
kubectl get deployments # 查看deployments(2) 扩容缩容
方式一 使用命令修改pod数量
kubectl scale deployment deploy-example --replicas3 # 修改pod数量到 3 个方式2 直接修改yaml文件的方式进行扩容
spec:
replicas: 5方式3 通过打补丁的方式进行扩容 - 了解
kubectl patch deployment myapp-deploy -p {spec:{replicas:5}}(3) 版本更新 这里有两种方式1)滚动更新(rolling update) 2)重新创建(recreate) 。默认为滚动更新 1)滚动更新使用2个ReplicaSetRS1删除一个旧的podRS2创建一个新的pod依次类推实现pod滚动升级 2)重新创建使用1个ReplicaSet删除一个创建一个依次类推 方式1yaml改镜像版本并应用 复制资源文件进行修改 cp deploy.yaml deploy1.yaml 把镜像版本修改为tomcat:v2 进行镜像升级vi deploy1.yaml 应用资源文件 kubectl apply -f deploy1.yaml 查看Replicaset kubectl get rs 查看deployement 多一个deployeement,原本的 3 个pod已经被干掉变成了 0 创建了新的 2 个 pod 因为我新的资源文件中的replicas值为2 查看访问测试一下容器中的项目版本已经更新
kubectl get pods -o wide # 查看pod网络
curl 192.168.32.179:8080 # 访问pod方式2命令设置镜像
设置镜像版本
kubectl set image deployment/deploy-example myapptomcat:v2
# deploy-example : deployment的名字
# myapptomcat:v2 镜像名镜像:版本查看rs
kubectl get rs 3. 查看pod
kubectl get pods4. 访问容器内容
curl 192.168.185.220:8080(4) 版本还原
查看历史
kubectl rollout history deploy deploy-example2. 查看具体版本
kubectl rollout history deploy deploy-example --revision13. 回退版本
kubectl rollout undo deploy deploy-example --to-revision1参考博客
一文解读云原生(转)K8s – Service RaftRaft一致性算法是一种用于分布式系统中实现一致性的共识算法。它旨在提供容错性和可理解性使得在网络不可靠或节点故障的情况下分布式系统仍能保持一致性。 Raft算法通过选举一个领导者称为leader来管理复制状态机的日志复制过程。领导者负责接收客户端请求并将它们复制到其他节点上的日志中。当多数节点确认接收到日志后该日志被认为是已提交的然后被应用到状态机中。这种方式确保了一致性。 Raft算法关注三个关键问题领导选举、日志复制和安全性。领导选举确保了集群中只有一个领导者避免冲突和混乱。日志复制确保了所有节点持有相同的日志序列从而达到一致性。安全性方面Raft算法使用了多数派原则在大多数节点正常运行的情况下才能保证系统的正常运行。 相比于一些其他共识算法如PaxosRaft算法更易于理解和实现。由于其简洁性和可理解性Raft算法被广泛应用于分布式系统包括Kubernetes集群中的Etcd组件。 ↩︎