kubernetes原理之引蛇出洞

在这里插入图片描述在这里插入图片描述

Swarm是Docker官方提供的一款集群管理工具,其主要作用是把若干台Docker主机抽象为一个整体,并且通过一个入口统一管理这些Docker主机上的各种Docker资源。Swarm和Kubernetes比较类似,但是更加轻,具有的功能也较kubernetes更少一些。https://www.cnblogs.com/franknihao/p/8490416.html

Mesos是一个开源的资源管理系统,可以对集群中的资源做弹性管理。
https://www.cnblogs.com/sdifens/p/11350859.html

自我修复:一旦这个容四了,k8s会再其他地方重新启动一个一模一样的容器,(启动之前会先试着进行重启,如果重启不成功就会重新启动一个新的)

服务发现和负载均衡:我们知道如果有一个nginx下面有两个web服务器,如果我们要新增一个服务的话需要修改nginx配置,在nginx里新增一个节点,然后重启nginx, 而k8s他会自动加入这个负载均衡不不需要重新启动,因为他有监听机制,

自动部署和回滚:k8s只有你给他提供镜像他就会自动帮你部署,k8s支持历史版本,只要新版本有问题的话,他把这个历史版本进行回滚,

弹性伸缩:可以通过监控,监控到这个pod压力比较答的时候他会自动帮我们在扩充一个,入宫还不够再扩。

K8s应用场景:
主要应用于微服务架构。

传统架构:比如京东这个这个项目,如果我要新增一个功能需要修改他的首页,重新部署,用的是同一个数据库,服务之前耦合度比较高,一旦有一个服务出问题了,也会影响到其他服务,导致用户体检差。

微服务架构:就是每个功能就是一个架构,服务于服务之间是相互独立的,互不影响,有独立的数据库,解耦,需要新增功能的时候不需要重新启动其他服务,

传统架构:如果你的请求越来越多的时候一个tomcat就不够了,你需要扩展tomcat,你tomcat扩展了,但是你数据库扩展不了,(如果要扩展需要扩展整个个数据库,但是如果只是其中一个功能请求比较大,就造成数据资源的浪费)

微服务架构:可以扩展tomcat,数据库,这样可以支持海量的并发,扩展性就更强了。

那么微服务和k8s有什么关系呢?
如果我们的微服务是运行在物理机上的,当我们的秒杀业务访问量增多的时候,你直接去扩他的物理机是不可能的,一般我们是再给他增加一个秒杀的集群,这样;分担他的一些压力,来达到性能的扩展,如果这时候我们的秒杀访问量下降了,我们的超市访问量上来了,这个时候会导致任务闲置,我们需要把秒杀下架,这样有重新部署,重新配置环境,这个时候我们k8s可以对他进行替换把秒杀变成超市,
我们用户业务可能时刻在变化,那会我们每天就忙着部署,下架,配置环境,一会是秒杀一会是超市的,你认为天天干的都是重复的劳动,这样我们就可以用K8s,让他提前预留一些资源,我们这个资源是百搭类型的,使用k8s的弹性伸缩,当压力答时候就给他扩,闲置了就缩,这样就可以减少运维人员的重复劳动了。

Etcd:相当于数据库的功能。
Apiserver:是k8s最核心的部分后期的开发运维都是基于apiserver的
Controller manager:自愈功能
Scheduler:k8s架构分两种节点一个是master,节点,一个是node节点,一个master节点可以管理上百台,上千台node节点,当有大量node节点的时候每个node的剩余情况是不一样的,比如说我们一个用户(运维人员)通过一个命令来控制master节点,需要运行一个容器,这个master就会从node节点里选择一个来运行这个pod,我有这么多节点应该让谁来运行比较合适呢,这个时候Scheduler就起作用了,Scheduler会把每个node节点资源剩余情况统计出来,剩余多少cup,剩余多少内存,会挑选出来一个比较空闲的节点来创建任务。来保证所有node节点的工作尽可能的均衡。
Kubelet:kubelet是运行在node节点上的,这样的话我们用户只需要操作master节点,master会控制kubelet节点, kubelet会控制我们的容器Container runtime。
Container runtime:docker,rkt,
Kube-proxy:我们每次启动一个容器是不能被外界访问的需要做端口映射,这里就需要一个Kube-proxy在node节点上的容器,给他做一个端口映射,可以被外界访问。这样外界用户访问是node节点,而不是master节点。

这是我们运维或者开发通过操作apiserver,比如创建一个资源,最终我们创建的资源都是通过apiserver进行创建的,你只需要申明一个配置文件就行了。
Apiserver会控制我们的Scheduler进行调度,主要就是分配合适node节点。
Controller manager是来保证每个运行起来的容器高可用,当他死了,就会立刻给他起一个新的,始终让你的业务高可用。Etcd就是一个数据库,当我们的集群起来的时候都会去etcd里都数据,(支持分布式锁),看看要维护那些容器。
Node节点主要有两个服务,kubelet主要是接受apiserver调度,apiserver来控制kubelet创建容器,kubelet再控制docker来创建容器(pod)。Kube-proxy帮助容器做端口映射。
K8s还会对我们的集群做监控,做监控就需要采集数据,这个就是CADvisor,
CADvisor已经集成到kubelet里了,早期版本需要集成CADvisor,

K8s网络通信
扁平:直接可以通过pod直接到达

K8s安装:

1.安装wget命令
yum -y install wget
2.下载阿里云远程镜像
Wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
3.yum install -y bash-completion.noarch
4. yum install net-tools
查看linux版本
cat /etc/redhat-release
Linux建议用7.4 or 7.6

systemctl stop firewalld
systemctl disable firewalld

systemctl stop NetworkManager.service
systemctl disable NetworkManager.service

vi /etc/hosts
cat /etc/hosts
Hosts解析拷贝其他节点
scp -rp /etc/hosts 192.168.21.130:/etc/hosts

这里监听两个端口,2380是用来做数据同步的,2379是用来对外提供服务用的

systemctl start etcd
systemctl enable etcd
netstat -lntup

yum install kubernetes-master.x86_64 -y

vi /etc/kubernetes/apiserver
vi /etc/kubernetes/config
systemctl start kube-apiserver.service
systemctl enable kube-apiserver.service
systemctl start kube-controller-manager.service
systemctl enable kube-controller-manager.service
systemctl start kube-scheduler.service
Controller manager和Scheduler共用一个配置文件

都启动成功后我们使用一条命令来检查他的状态:
kubectl get componentstatus

yum install kubernetes-node.x86_64 -y

在安装node的时候他会自动依赖帮你装装上docker
启动kubelet :systemctl start kubelet.service
设置开机自启:systemctl enable kubelet.service

启动kube-proxy:systemctl start kube-proxy.service
设置开机自启:systemctl enable kube-proxy.service

vi /etc/kubernetes/config 配置其他节点
执行 kubectl get nodes 查看
删除节点:kubectl delete node 主机名

vi /etc/kubernetes/kubelet 修改配置
systemctl status docker
kubectl get nodes
修改主机名方式:
方式一、
[root@localhost ~]# hostnamectl set-hostname lsx02.com
方式二、
修改配置文件 /etc/hostname 保存退出
[root@localhost ~]# vi /etc/hostname
lsx02.com
:wq
以上完成后reboot

yum install flannel -y

vi /etc/sysconfig/flanneld

systemctl restart flanneld.service
systemctl restart docker

etcdctl set /atomic.io/network/config ‘{“Network”:“172.16.0.0/16”}’

ip拼不通解决方法:
iptables -L -n
iptables -P FORWARD ACCEPT
为啥防止每次开启都执行该命令,我进行如下配置。
vi /usr/lib/systemd/system/docker.service

ExecStart=/usr/sbin/iptables -P FORWARD ACCEPT

执行 systemctl daemon-reload 生效

K8s是怎么运行容器的?
主要是通过pod资源来运行容器的。

修改linux主机名的两种方式:
方式一:hostnamectl set-hostname 名称
方式二:vi /etc/hostname
Liuqh

:wq
重启 reboot

第一章、什么是kube-controller-manager?
Controller Manager 由 kube-controller-manager 和 cloud-controller-manager 组成, 是Kubernetes 的大脑, 它通过 apiserver 监控整个集群的状态, 并确保集群处于预期的工作状态。
kube-controller-manager 由一系列的控制器组成

1 Replication Controller
2 Node Controller
3 CronJob Controller
4 Daemon Controller
5 Deployment Controller
6 Endpoint Controller
7 Garbage Collector
8 Namespace Controller
9 Job Controller
10 Pod AutoScaler
11 RelicaSet
12 Service Controller
13 ServiceAccount Controller
14 StatefulSet Controller
15 Volume Controller
16 Resource quota Controller

cloud-controller-manager 在 Kubernetes 启用 Cloud Provider 的时候才需要, 用来配合云服务提供商的控制, 也包括一系列的控制器, 如
1 Node Controller2 Route Controller3 Service Controller
第二章、常见Pod控制器及含义
Replication Controller

Replication Controller 保证了在所有时间内,都有特定数量的Pod副本正在运行,如果太多了,Replication Controller就杀死几个,如果太少了,Replication Controller会新建几个,和直接创建的pod不同的是,Replication Controller会替换掉那些删除的或者被终止的pod,不管删除的原因是什么(维护阿,更新啊,Replication Controller都不关心)。基于这个理由,我们建议即使是只创建一个pod,我们也要使用Replication Controller。Replication Controller 就像一个进程管理器,监管着不同node上的多个pod,而不是单单监控一个node上的pod,Replication Controller 会委派本地容器来启动一些节点上服务(Kubelet ,Docker)。
Replication Controller只会对那些RestartPolicy = Always的Pod的生效,(RestartPolicy的默认值就是Always),Replication Controller 不会去管理那些有不同启动策略pod
Replication Controller永远不会自己关闭,但是,我们并不希望Replication Controller成为一个长久存在的服务。服务可能会有多个Pod组成,这些Pod又被多个Replication Controller控制着,我们希望Replication Controller 会在服务的生命周期中被删除和新建(例如在这些pod中发布一个更新),对于服务和用户来说,Replication Controller是通过一种无形的方式来维持着服务的状态

ReplicaSets

ReplicaSet是下一代复本控制器。ReplicaSet和 Replication Controller之间的唯一区别是现在的选择器支持。Replication Controller只支持基于等式的selector(env=dev或environment!=qa),但ReplicaSet还支持新的,基于集合的selector(version in (v1.0, v2.0)或env notin (dev, qa))。
大多数kubectl支持Replication Controller的命令也支持ReplicaSets。rolling-update命令有一个例外 。如果想要滚动更新功能,请考虑使用Deployments。此外, rolling-update命令是必须的,而Deployments是声明式的,因此我们建议通过rollout命令使用Deployments。
虽然ReplicaSets可以独立使用,但是今天它主要被 Deployments 作为协调pod创建,删除和更新的机制。当使用Deployments时,不必担心管理他们创建的ReplicaSets。Deployments拥有并管理其ReplicaSets。

Deployment

Deployment为Pod和Replica Set(下一代Replication Controller)提供声明式更新。
你只需要在Deployment中描述你想要的目标状态是什么,Deployment controller就会帮你将Pod和Replica Set的实际状态改变到你的目标状态。你可以定义一个全新的Deployment,也可以创建一个新的替换旧的Deployment。
一个典型的用例如下:
1.使用Deployment来创建ReplicaSet。ReplicaSet在后台创建pod。检查启动状态,看它是成功还是失败。
2.然后,通过更新Deployment的PodTemplateSpec字段来声明Pod的新状态。这会创建一个新的ReplicaSet,Deployment会按照控制的速率将pod从旧的ReplicaSet移动到新的ReplicaSet中。
3.如果当前状态不稳定,回滚到之前的Deployment revision。每次回滚都会更新Deployment的revision。
4.扩容Deployment以满足更高的负载。
5.暂停Deployment来应用PodTemplateSpec的多个修复,然后恢复上线。
6.根据Deployment 的状态判断上线是否hang住了。
7.清除旧的不必要的ReplicaSet。

StatefulSet

StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计),其应用场景包括
1.稳定的持久化存储,即Pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现
2.稳定的网络标志,即Pod重新调度后其PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现
3.有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态),基于init containers来实现
4.有序收缩,有序删除(即从N-1到0)

从上面的应用场景可以发现,StatefulSet由以下几个部分组成:
1.用于定义网络标志(DNS domain)的Headless Service
2.用于创建PersistentVolumes的volumeClaimTemplates
3.定义具体应用的StatefulSet

StatefulSet中每个Pod的DNS格式为statefulSetName-{0…N-1}.serviceName.namespace.svc.cluster.local,其中
1.serviceName为Headless Service的名字2.0…N-1为Pod所在的序号,从0开始到N-1
3.statefulSetName为StatefulSet的名字
4.namespace为服务所在的namespace,Headless Servic和StatefulSet必须在相同的namespace
5…cluster.local为Cluster Domain,

DaemonSet
DaemonSet保证在每个Node上都运行一个容器副本,常用来部署一些集群的日志、监控或者其他系统管理应用。典型的应用包括:

日志收集,比如fluentd,logstash等
系统监控,比如Prometheus Node Exporter,collectd,New Relic agent,Ganglia gmond等
系统程序,比如kube-proxy, kube-dns, glusterd, ceph等
第三章、简单示例
Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deploy
spec:
replicas: 5
selector:
matchLabels:
app: myapp
release: canary
template:
metadata:
labels:
app: myapp
release: canary
spec:
containers:
- name: myapp
image: ikubernetes/myapp:v2
ports:
- name: httpd
containerPort: 80

Deployment+ DaemonSet

apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: redis
role: logstor
template:
metadata:
labels:
app: redis
role: logstor
spec:
containers:
- name: redis
image: redis:4.0-alpine
ports:
- name: redis
containerPort: 6379


apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat-ds
spec:
selector:
matchLabels:
app: filebeat
release: stable
template:
metadata:
labels:
app: filebeat
release: stable
spec:
containers:
- name: filebeat
image: ikubernetes/filebeat:5.6.5-alpine
env:
- name: REDIS_HOST
value: redis.default.svc.cluster.local
- name: REDIS_LOG_LEVEL
value: info

StatefulSet


apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:

  • port: 80
    name: web
    clusterIP: None
    selector:
    app: nginx—
    apiVersion: apps/v1beta1
    kind: StatefulSet
    metadata:
    name: web
    spec:
    serviceName: “nginx”
    replicas: 2
    template:
    metadata:
    labels:
    app: nginx
    spec:
    containers:
    • name: nginx
      image: gcr.io/google_containers/nginx-slim:0.8
      ports:
      • containerPort: 80
        name: web
        volumeMounts:
      • name: www
        mountPath: /usr/share/nginx/html
        volumeClaimTemplates:
  • metadata:
    name: www
    annotations:
    volume.alpha.kubernetes.io/storage-class: anything
    spec:
    accessModes: [ “ReadWriteOnce” ]
    resources:
    requests:
    storage: 1Gi

#spec.updateStrategy.rollingUpdate.partition #该参数可以控制statefulset的升级策略,可使用金丝雀和灰度发布的功能

Job
我们用Job这个资源对象来创建一个任务,我们定一个Job来执行一个倒计时的任务,定义YAML文件:

apiVersion: batch/v1
kind: Job
metadata:
name: job-demo
spec:
template:
metadata:
name: job-demo
spec:
restartPolicy: Never
containers:
- name: counter
image: busybox
command:
- “bin/sh”
- “-c”
- “for i in 9 8 7 6 5 4 3 2 1; do echo $i; done”

注意Job的RestartPolicy仅支持Never和OnFailure两种,不支持Always,我们知道Job就相当于来执行一个批处理任务,执行完就结束了,如果支持Always的话是不是就陷入了死循环了?
然后来创建该Job,保存为job-demo.yaml:
$ kubectl create -f ./job.yaml
job “job-demo” created
然后我们可以查看当前的Job资源对象:
$ kubectl get jobs
注意查看我们的Pod的状态,同样我们可以通过kubectl logs来查看当前任务的执行结果。

CronJob
CronJob其实就是在Job的基础上加上了时间调度,我们可以:在给定的时间点运行一个任务,也可以周期性地在给定时间点运行。这个实际上和我们Linux中的crontab就非常类似了。
一个CronJob对象其实就对应中crontab文件中的一行,它根据配置的时间格式周期性地运行一个Job,格式和crontab也是一样的。
crontab的格式如下:
分 时 日 月 星期 要运行的命令 第1列分钟0~59 第2列小时0~23) 第3列日1~31 第4列月1~12 第5列星期0~7(0和7表示星期天) 第6列要运行的命令
现在,我们用CronJob来管理我们上面的Job任务,

apiVersion: batch/v2alpha1
kind: CronJob
metadata:
name: cronjob-demo
spec:
schedule: “*/1 * * * *”
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: hello
image: busybox
args:
- “bin/sh”
- “-c”
- “for i in 9 8 7 6 5 4 3 2 1; do echo $i; done”

我们这里的Kind是CronJob了,要注意的是.spec.schedule字段是必须填写的,用来指定任务运行的周期,格式就和crontab一样,另外一个字段是.spec.jobTemplate, 用来指定需要运行的任务,格式当然和Job是一致的。还有一些值得我们关注的字段.spec.successfulJobsHistoryLimit和.spec.failedJobsHistoryLimit,表示历史限制,是可选的字段。它们指定了可以保留多少完成和失败的Job,默认没有限制,所有成功和失败的Job都会被保留。然而,当运行一个Cron Job时,Job可以很快就堆积很多,所以一般推荐设置这两个字段的值。如果设置限制的值为 0,那么相关类型的Job完成后将不会被保留。
接下来我们来创建这个cronjob
$ kubectl create -f cronjob-demo.yaml
cronjob “cronjob-demo” created
当然,也可以用kubectl run来创建一个CronJob:

kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox – /bin/sh -c “date; echo Hello from the Kubernetes cluster”
$ kubectl get cronjob
NAME SCHEDULE SUSPEND ACTIVE LAST-SCHEDULE
hello */1 * * * * False 0
$ kubectl get jobs
NAME DESIRED SUCCESSFUL AGE
hello-1202039034 1 1 49s
$ pods=$(kubectl get pods --selector=job-name=hello-1202039034 --output=jsonpath={.items…metadata.name} -a)
$ kubectl logs $pods
Mon Aug 29 21:34:09 UTC 2016
Hello from the Kubernetes cluster
$ kubectl delete cronjob hello
cronjob “hello” deleted

一旦不再需要 Cron Job,简单地可以使用 kubectl 命令删除它:
$ kubectl delete cronjob hello
cronjob “hello” deleted
这将会终止正在创建的 Job。然而,运行中的 Job 将不会被终止,不会删除 Job 或 它们的 Pod。为了清理那些 Job 和 Pod,需要列出该 Cron Job 创建的全部 Job,然后删除它们:
1
2
3
4 $ kubectl get jobs
NAME DESIRED SUCCESSFUL AGE
hello-1201907962 1 1 11m
hello-1202039034 1 1 8m
  
1
2
3 [root@k8s-master01 jobs]# kubectl get cronjobs.batch
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob-demo */1 * * * * False 1 9s 4m

1
2
3 $ kubectl delete jobs hello-1201907962 hello-1202039034 …
job “hello-1201907962” deleted
job “hello-1202039034” deleted
  
一旦 Job 被删除,由 Job 创建的 Pod 也会被删除。注意,所有由名称为 “hello” 的 Cron Job 创建的 Job 会以前缀字符串 “hello-” 进行命名。如果想要删除当前 Namespace 中的所有 Job,可以通过命令 kubectl delete jobs --all 立刻删除它们。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值