twitter -> 后来迁移
Mesos是Apache下的开源分布式资源管理框架,它被称为是分布式系统的内核。-> 抽象资源+调度任务。
Mesos采用了经典的“主-从”架构,其中主节点(管理节点)可以使用Zookeeper来做HA。Mesos master 服务奖运行在主节点上,Mesos slave 服务则需要运行在各个计算任务节点上。负责完成具体任务的应用框架,与Mesos master进行交互,来申请资源。
Mesos有三个基本的组件:管理服务(master)、任务服务(slave)以及应用框架(framework)。
调度:
对于一个资源调度框架来说,最核心的就是调度机制,怎么能快速高效地完成对某个应用框架资源的分配,是核心竞争力所在。最理想情况下(大部分时候都无法实现),最好是能猜到应用们的实际需求,实现最大化的资源使用率。Mesos为了实现尽量优化的调度,采取了两层(two-layer)的调度算法
调度的基本思路很简单,master先全局调度一大块资源给某个framework,framework自己在实现内部的细粒度调度,决定那个任务用多少资源。两层调度简化了Mesos master自身的调度过程,通过将复杂的细粒度调度交由framework实现,避免了Mesos master成为性能的瓶颈。
调度过程:调度通过offer发送的方式进行交互。一个offer是一组资源例如<1 CPU ,2GB Mem>>。
基本调度过程如下:
具体给出一个例子:
某从节点想主节点汇报自己有<4 CPU , 8 GB Mem>的空闲资源,同时,主节点看到某个应用框架请求<3 CPU , 6 GB Mem>,就创建一个offer
Docker Swarm --> 只提供Docker组件
Swarm是Docker公司推出的用来管理docker集群的平台,几乎全部用GO语言来完成的开发的,代码开源在https://github.com/docker/swarm, 它是将一群Docker宿主机变成一个单一的虚拟主机,Swarm使用标准的Docker API接口作为其前端的访问入口,换言之,各种形式的DockerClient都可以直接与其进行通讯,方便用户部署集群主机服务。
Docker Compose 在单一主机上面部署服务
Docker Swarm 多台主机上面管理服务
Swarm deamon只是一个调度器(Scheduler)加路由器(router),Swarm自己不运行容器,它只是接受Docker客户端发来的请求,调度适合的节点来运行容器,这就意味着,即使Swarm由于某些原因挂掉了,集群中的节点也会照常运行,放Swarm重新恢复运行之后,他会收集重建集群信息。
Docker Client使用Swarm对 集群(Cluster)进行调度使用,Swarm是典型的master-slave结构,通过发现服务来选举manager。manager是中心管理节点,各个node上运行agent接受manager的统一管理,集群会自动通过Raft协议分布式选举出manager节点,无需额外的发现服务支持,避免了单点的瓶颈问题,同时也内置了DNS的负载均衡和对外部负载均衡机制的集成支持
集群创建过程:
1)发现Docker集群中的各个节点,收集节点状态、角色信息,并监视节点状态的变化
2)初始化内部调度(scheduler)模块
3)创建并启动API监听服务模块
Google --> 10年容器基础架构Borg 2014开源–> 使用GO重构[[GO基础学习]]重构K8S
Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载和服务,可促进声明式配置和自动化。 Kubernetes 拥有一个庞大且快速增长的生态,其服务、支持和工具的使用范围相当广泛。方便伸缩扩容
服务发现和负载均衡
Kubernetes 可以使用 DNS 名称或自己的 IP 地址来曝露容器。 如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。
存储编排
Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。
自动部署和回滚
你可以使用 Kubernetes 描述已部署容器的所需状态, 它可以以受控的速率将实际状态更改为期望状态。 例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。
自动完成装箱计算
Kubernetes 允许你指定每个容器所需 CPU 和内存(RAM)。 当容器指定了资源请求时,Kubernetes 可以做出更好的决策来为容器分配资源。
自我修复
Kubernetes 将重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器, 并且在准备好服务之前不将其通告给客户端。
密钥与配置管理
Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。
弹性伸缩
特点:
Swarm:适合中小型系统,在这个范畴它的价值和可扩展性最好
Kubernetes:适合中等规模高度冗余的系统
Mesos:目前最稳定的平台,适合大规模系统
#todo
Node是Pod真正运行的主机,可以物理机,也可以是虚拟机。为了管理Pod,每个Node节点上至少要运行container runtime(容器运行环境:比如docker或者rkt)、kubelet和kube-proxy服务。
创建POD进行部署
通过Service统一接口进行访问
架构举例:
每一个厂都有一个Kubelet代理,负责当前应用启停和销毁,当出现问题的时候由Kubelet进行处理,回报信息给秘书(ApiServer)-> Controller - manager(领导人-决定)
-> 交给决策者进行处理(动态调度进行调度处理)
-> 存储决策文件
-> 分配决策
-> 存储决策文件到档案库ETCD
-> ApiServer进行通知Kubelet进行处理
当应用构建结束之后,应用之间相互调用由Kube-Proxy(门卫)进行统一处理,打通整个服务,门卫之间信息相互同步。
最终实际上整个集群由KubeCtl(程序员命令)进行直接控制,启动开启集群,这个命令实质上也是发送个ApiServer进行实际处理。
[[K8S集群搭建]]
搭建工具:
- Kubeadmin:K8S部署工具,使用Kubeadm Init、Kubeadm Init
- 二进制包:手动部署每个组件
是官方社区推出的快速部署KuberNetes集群工具,可以通过一下两个命令实现快速搭建。
集群分配:
192.168.153.131 k8s_master
192.168.153.129 slave1
192.168.153.130 slave2
192.168.153.128 slave3
root账户密码为:
root : 123456789
#关闭防火墙
#临时
systemctl stop firewalld
#永久关闭
systemctl disable firewalld
出现如下报错,请使用apt install -y firewalld
关闭selinux How to disable/enable SELinux on Ubuntu 20.04 Focal Fossa Linux - Linux Tutorials - Learn Linux Configuration
sudo apt install policycoreutils selinux-utils selinux-basics
sudo selinux-activate
sudo selinux-config-enforcing
/etc/selinux/config
SELINUX=disabled
关闭Swap yes
# 临时
swapoff -a
# 永久关闭
sed -ri 's/.*swap.*/#&/' /etc/fstab
#设置主机名称
hostnamectl set-hostname xxxx
cat >> /etc/hosts <
# 将桥接的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
apt install ntpdate -y
ntpdate time.windows.com
#ubuntu
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
#centos
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
Docker 加速 [[镜像加速]]
换源 [[Ubuntu 换源]]
设置开机自启动
systemctl enable docker && systemctl start docker
systemctl restart docker
注意版本兼容性问题
所有节点都进行安装
kubelet
、kubeadm
、kubect
sudo apt-get install -y apt-transport-https ca-certificates curl
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
systemctl enable kubelet
kubeadm init \
--apiserver-advertise-address=(master节点ip) \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.23.8 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--ignore-preflight-errors=all
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
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
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.153.131:6443 --token 080k86.3w1djwjhxe5q4l4p --discovery-token-ca-cert-hash sha256:8b82312bf868a68919b8de12cbbf7a97be20cd795d816332bcc9f3d81a0838d3
查看主节点工作情况kubeadm get nodes
:
在从节点中执行命令:kubeadm join 192.168.153.131:6443 --token 080k86.3w1djwjhxe5q4l4p --discovery-token-ca-cert-hash sha256:8b82312bf868a68919b8de12cbbf7a97be20cd795d816332bcc9f3d81a0838d3
成功结果:
主节点中查看状态:
注:执行时候出现:
解决方案:执行kubeadm reset
恢复设置,之后再次执行上述命令
root执行:
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
插件可能因为网络原因执行失败,这里附上文件kube-flannel.yml,使用kubectl apply -f进行执行
---
kind: Namespace
apiVersion: v1
metadata:
name: kube-flannel
labels:
pod-security.kubernetes.io/enforce: privileged
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: flannel
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- ""
resources:
- nodes
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: flannel
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: flannel
subjects:
- kind: ServiceAccount
name: flannel
namespace: kube-flannel
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: flannel
namespace: kube-flannel
---
kind: ConfigMap
apiVersion: v1
metadata:
name: kube-flannel-cfg
namespace: kube-flannel
labels:
tier: node
app: flannel
data:
cni-conf.json: |
{
"name": "cbr0",
"cniVersion": "0.3.1",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
net-conf.json: |
{
"Network": "10.244.0.0/16",
"Backend": {
"Type": "vxlan"
}
}
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: kube-flannel-ds
namespace: kube-flannel
labels:
tier: node
app: flannel
spec:
selector:
matchLabels:
app: flannel
template:
metadata:
labels:
tier: node
app: flannel
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
hostNetwork: true
priorityClassName: system-node-critical
tolerations:
- operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni-plugin
#image: flannelcni/flannel-cni-plugin:v1.1.0 for ppc64le and mips64le (dockerhub limitations may apply)
image: rancher/mirrored-flannelcni-flannel-cni-plugin:v1.1.0
command:
- cp
args:
- -f
- /flannel
- /opt/cni/bin/flannel
volumeMounts:
- name: cni-plugin
mountPath: /opt/cni/bin
- name: install-cni
#image: flannelcni/flannel:v0.18.1 for ppc64le and mips64le (dockerhub limitations may apply)
image: rancher/mirrored-flannelcni-flannel:v0.18.1
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
#image: flannelcni/flannel:v0.18.1 for ppc64le and mips64le (dockerhub limitations may apply)
image: rancher/mirrored-flannelcni-flannel:v0.18.1
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
resources:
requests:
cpu: "100m"
memory: "50Mi"
limits:
cpu: "100m"
memory: "50Mi"
securityContext:
privileged: false
capabilities:
add: ["NET_ADMIN", "NET_RAW"]
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: EVENT_QUEUE_DEPTH
value: "5000"
volumeMounts:
- name: run
mountPath: /run/flannel
- name: flannel-cfg
mountPath: /etc/kube-flannel/
- name: xtables-lock
mountPath: /run/xtables.lock
volumes:
- name: run
hostPath:
path: /run/flannel
- name: cni-plugin
hostPath:
path: /opt/cni/bin
- name: cni
hostPath:
path: /etc/cni/net.d
- name: flannel-cfg
configMap:
name: kube-flannel-cfg
- name: xtables-lock
hostPath:
path: /run/xtables.lock
type: FileOrCreate
查看当前节点pods状态 kubectl get pods -n kube-system
:
观察是否ready为全部上线,图例如下:
kubectl get nodes
创建一个Nginx集群:
kubectl create deployment nginx --image=nginx
kubectl get pod
kubectl expose deployment nginx --port=80 --type=NodePort
查看状态:
kubectl get pod,svc
查看暴露的端口是,30612,从集群中任意节点都可以访问 -> 测试如下:
未做,待更
KubeAdmin:
二进制:
是一个K8s集群的管理工具,实现对集群的基本管理和处理。
语法:kubectl command type name flags
kubectl get nodes slave1
kubectl get pod,svc
:查看pod运行在线情况
kubectl --help
:命令行工具 (kubectl) | Kubernetes
kubectl create deployment web --image=nginx -o yaml --dry-run
生成文件如下:
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: web
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web
spec:
containers:
- image: nginx
name: nginx
resources: {}
status: {}
kubectl get deploy nginx -o=yaml > my.yaml
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
creationTimestamp: "2022-07-13T08:06:10Z"
generation: 1
labels:
app: nginx
name: nginx
namespace: default
resourceVersion: "4889"
uid: e235528a-958f-4b83-8205-cba3b0f0255d
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx
imagePullPolicy: Always
name: nginx
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
status:
availableReplicas: 1
conditions:
- lastTransitionTime: "2022-07-13T08:07:57Z"
lastUpdateTime: "2022-07-13T08:07:57Z"
message: Deployment has minimum availability.
reason: MinimumReplicasAvailable
status: "True"
type: Available
- lastTransitionTime: "2022-07-13T08:06:10Z"
lastUpdateTime: "2022-07-13T08:07:57Z"
message: ReplicaSet "nginx-8f458dc5b" has successfully progressed.
reason: NewReplicaSetAvailable
status: "True"
type: Progressing
observedGeneration: 1
readyReplicas: 1
replicas: 1
updatedReplicas: 1
为什么管理的不是容器?
因为正常处理情况下:
1. 容器之间相互隔离,通过namespace和group组进行隔离
多个容器在同一个namespace中就可以实现网络共享。
POD在创建过程中首先会创建一个根容器(Pause容器也叫Info容器)当你每创建一个用户业务
容器都会把用户容器加入到Info容器中,也就是变成了处于同一个名称空间,一个mac地址一个IP地址
1. 持久化数据类型:
1. 日志数据
2. 业务数据
共享存储由数据卷Volumn构成,通过数据卷进行持久化存储,映射数据/
imagePullPolicy
1. IfNotPresent:不存在的时候拉取(默认)
2. Always:每次创建POD都会自动重新拉取
3. Never:POD从不主动拉取,必须手动拉取
Request:调度资源大小
Limit:最大大小
本身实际上是由Docker来限制资源的
restartPolicy
1. Always:容器终止后自动重启(适用于一般使用容器)
2. OnFailure:容器异常退出,状态码非零重启
3. Never:容器终止从不退出
原始情况我们检测的是容器是否运行,但是比如Java发生OOM的时候,容器时正常的,但是业务不正常。因此需要从业务层面监控。
1. livenessProbe(存活检查):检查失败就杀掉容器,根据POD 的restartPolicy进行处理
2. readinessProbe(就绪检查):检查失败会从service endpoint中剔除
影响调度的因素:
根据设置的分组名称:组名,进行调度
1. 设置分组别名 kubectl label node node1 env_role=dev
这里将node1起一个tag(名字随意)为dev标签。
查看node标记的资源标签:kubectl get nodes xxx --show-labels
3. 节点亲和性
nodeAffinity:根据节点标签约束来决定Pod调度放到哪个节点上面,有的话满足条件,不满足也可以正常使用。
1. 硬亲和性(requiredxxx):其中标注的条件必须满足(这里是目前环境中必须满足dev test),不满足就会进入等待。
weight:权重
key:环境分组Key
operator:支持常见支持符
1. In:里面包含
2. . NotIn:不包含(反亲和性)
3. Exists:存在
4. GT:大于
5. LT:小于
6. DowsNotExists:不存在
nodeSelector和nodeAffinity:POd调度到某些节点上,POd属性,调度时候实现。
kubectl describe node xxxx | grep Taint
master默认存在污点
kubectl taint node xxx key
=value:污点的三个参数kubectl taint node xxx key:污点值-
key:污点设置的key value:污点设置的value
由于每一个POD是由Deployment进行创建管理的,因此执行kubectl delete pod xxx
其实无效只是删除了一个POD而已,但是存在容灾控制,因此需要先删除相应的Deployment,之后其管理的POD会自动被删除。
kubectl get deployment
kubectl delete deployment xxx
kubectl get pods
在集群中管理运行容器的对象
1. POD和Controller之间通过Label标签建立关系Selector
2. POD通过controller实现应用的运维,比如弹性伸缩,滚动升级等
Web服务、微服务
1. 部署无状态应用
2. 管理POD和ReplicaSet(副本)
3. 部署,滚动升级等功能
命令行:kubectl create deployment web --image=nginx --dry-run -o=yaml
生成一个yaml并不运行
打开的yaml文件:
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: web
name: web
spec:
replicas: 1
selector: #控制器绑定POD标签的选择器
matchLabels: #标签
app: web
strategy: {}
template: #POD模板
metadata:
creationTimestamp: null
labels: #POD标签
app: web #值
spec:
containers:
- image: nginx
name: nginx
resources: {}
status: {}
部署yaml文件:kubectl apply -f web.yaml
kubectl create deployment web --image=镜像名称 --dry-run -o=yaml
kubectl apply -f xxx.yaml
kubectl get pods
kubectl expose deployment web --port=pod端口 --type=NodePort --target-port=外部端口 --name=发布名称 -o=yaml > web-port.yaml
apiVersion: v1
kind: Service
metadata:
creationTimestamp: "2022-07-18T06:56:05Z"
labels:
app: web
name: web1
namespace: default
resourceVersion: "31313"
uid: 1bc421ea-5ce8-4f54-ab4a-17e7fdfc1e4a
spec:
clusterIP: 10.102.187.245
clusterIPs:
- 10.102.187.245
externalTrafficPolicy: Cluster
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- nodePort: 32019
port: 80
protocol: TCP
targetPort: 80
selector:
app: web
sessionAffinity: None
type: NodePort
status:
loadBalancer: {}
发布:kubectl apply -f xxx.yaml
先部署一个应用:设置副本和版本
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: web
name: web
spec:
replicas: 2
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: web
spec:
containers:
- image: nginx:1.14
name: nginx
resources: {}
status: {}
~
执行kubectl apply -f xxxx.yaml
进行部署
kubectl set image deployment 应用名称 容器名称=容器名称:版本号
kubectl set image deployment web nginx=nginx:1.15
升级中:
在这个过程中,实际上副本只设置了2个,但是这里有三个,因为一个个升级,并且在下载启动设置中旧版本继续运行,最后将旧的替换掉
使用命令进行查看升级状态: kubectl rollout status deployment web
回滚版本:
kubectl scale deployment web --replicas=10
持续更新,学习中ing…
没有容器约定,容器迁移可以直接使用(随便用) ↩︎
容器之间有相互约定,相互依赖,迁移之后不能直接使用 ↩︎