k8s 简介:
什么是k8s?
Kubernetes (k8s)是Google开源的容器集群管理系统(谷歌内部:Borg)。在Docker技术基础上,为容器化的应用提供部署运行、资源调度、服务发现和动态伸缩等一系列完整的功能,提高了大规模容器集群管理的便捷性。
Kubernetes的优势:
- 容器编排
- 轻量级
- 开源
- 弹性伸缩
- 负载均衡
相关网站:
Kubernetes (k8s) 官网:https://kubernetes.io/
Kubernetes (k8s) 官方文档:https://kubernetes.io/docs/home/
Kubernetes(k8s)中文文档:https://www.kubernetes.org.cn/k8s
Kubernetes (k8s) 中文社区:https://www.kubernetes.org.cn/tags/cncf
Kubernetes (k8s )核心组件
- etcd etcd是一个高可用的分布式键值存储系统,存储元数据,保证集群的高可用,K8s使用它来存储各个资源的状态,从而实现了Restful的API;
- api server 提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
- controller manager 负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
- scheduler 负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
- kubelet 负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;
- Container runtime 负责镜像管理以及Pod和容器的真正运行(CRI);
- kube-proxy 负责为Service提供cluster内部的服务发现和负载均衡;
master与node节点服务:
- Master节点上面主要由四个模块组成:APIServer、scheduler、controller manager、etcd
- Node节点主要由三个模块组成:kubelet、kube-proxy、runtime
- coredns 负责为整个集群提供DNS服务
- flanneld 负责为整个集群提供网络服务
pod创建过程
kubernetes之pod生命周期:https://www.kubernetes.org.cn/5335.html
k8s中的名词概念
cluster
cluster 是计算、存储、网络资源的集合,k8s利用这些资源运行各种基于容器的应用
master
master 是cluster的大脑,他的主要职责是调度,即决定将应用放在哪里运行。master运行linux操作系统,可以是物理机或者虚拟机。为了高可用,可以运行多个master
node
node的职责是运行容器应用。node由master管理,node负责监控并汇报容器的状态,同时根据master的要求管理容器的生命周期。node运行在linux
pod
pod是k8s最小工作单元.Pod是最小的,管理,创建,计划的最小单元,每个pod包含一个或多个容器;pod中的容器会作为一个整体被master调度到一个node上运行
controller
k8s通常不会直接创建pod,而是通过controller来管理pod的;controller中定义了pod的部署特性,比如有几个剧本,在什么样的node上运行等。为了满足不同的业务场景,k8s提供了多种controller ,包括:deployment 、replicaset、daemonset 、job 等
deployment
Deployment为Pod和ReplicaSet提供了一个声明式定义(declarative)方法。使用Deployment来创建ReplicaSet;ReplicaSet在后台创建pod。
- 定义Deployment来创建Pod和ReplicaSet
- 滚动升级和回滚应用
- 扩容和缩容
- 暂停和继续Deployment
replicaset
Deployment创建ReplicaSet;ReplicaSet在后台创建pod.replicaset实现了pod的多副本管理。使用deployment时会自动创建replicaset,也就是说deployment是通过replicaset来管理pod的多个副本的,我们通常不需要直接使用replicaset
保证了在所有时间内,都有特定数量的Pod副本正在运行,如果太多了,Replication Controller就杀死几个,如果太少了,Replication Controller会新建几个,和直接创建的pod不同的是,Replication Controller会替换掉那些删除的或者被终止的pod,不管删除的原因是什么(维护阿,更新啊,Replication Controller都不关心)
daemonset
DaemonSet保证在每个Node上都运行一个容器副本,常用来部署一些集群的日志、监控或者其他系统管理应用,
- 日志收集,比如fluentd,logstash等
- 系统监控,比如Prometheus Node Exporter,collectd,New Relic agent,Ganglia gmond等
- 系统程序,比如kube-proxy, kube-dns, glusterd, ceph等
StatefulSet
稳定的持久化存储;能够保证pod的每个副本在整个生命周期中名称是不变的;当某个pod发生故障需要删除并重新启动时,pod的名称会发生变化,同时statefulset会保证副本按照固定的顺序启动、更新或者删除
详解网址:https://www.kubernetes.org.cn/statefulset
job
Job负责批量处理短暂的一次性任务 (short lived one-off tasks),即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。
CronJob
CronJob即定时任务,就类似于Linux系统的crontab,在指定的时间周期运行指定的任务。在Kubernetes 1.5,使用CronJob需要开启batch/v2alpha1 API,即–runtime-config=batch/v2alpha1
https://www.kubernetes.org.cn/cronjob
service
https://www.kubernetes.org.cn/kubernetes-services
https://www.cnblogs.com/du-z/p/11388805.html
namespace
可以将一个物理的cluster逻辑上划分成多个虚拟cluster,每个cluster就是一个namespace。不同的namespace里的资源是完全隔离的
部署k8s集群
实验集群环境
node1 : IP=192.168.137.3 ;MEM-->2G ;CPU-->2核 ;关闭交换分区 master
node2 : IP=192.168.137.4 ;MEM-->2G ;CPU-->2核 ;关闭交换分区 node
node3 : IP=192.168.137.5 ;MEM-->2G ;CPU-->2核 ;关闭交换分区 node
所有节点的操作
第一步:主机名解析
╭─root@node* ~
╰─➤ vim /etc/hosts
...
192.168.137.3 node1
192.168.137.4 node2
192.168.137.5 node3
第二步:禁用交换分区
╭─root@node* ~
╰─➤ swapoff -a
╭─root@node* ~
╰─➤ vim /etc/fstab
...
#/dev/mapper/cl-swap swap swap defaults 0 0
...
╭─root@node* ~
╰─➤ free -h
total used free shared buff/cache available
Mem: 1.8G 821M 204M 50M 797M 738M
Swap: 0B 0B 0B
第三步:安装docker
╭─root@node* ~
╰─➤ cat docker-sbeed.sh
#!/bin/bash
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
mv docker-ce.repo /etc/yum.repos.d
yum install docker-ce -y
# aliyun 镜像加速
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://*****.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
╭─root@node* ~
╰─➤ bash docker-sbeed.sh
第四步:要保证打开内置的桥功能,这个是借助于iptables来实现的
╭─root@node2 ~
╰─➤ echo "1" >/proc/sys/net/bridge/bridge-nf-call-iptables
# 需要安装docker才会成/proc/sys/net/bridge/bridge-nf-call-iptables
第五步:准备k8s安装源
╭─root@node* ~
╰─➤ vim /etc/yum.repos.d/k8s.repo
[k8s]
name=k8s
enabled=1
gpgcheck=0
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
第六步:下载程序包
╭─root@node* ~
╰─➤ yum install kubelet kubectl kubeadm -y
# kubelet 实现pod创建
# kubeadm 集群初始化
# kubectl 命令行工作
第七步:kubelet开机自启
╭─root@node* ~
╰─➤ systemctl enable kubelet
master节点运行命令
第一步:初始化master
╭─root@node1 ~
╰─➤ kubeadm init --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.15.2 --apiserver-advertise-address 192.168.137.3 --pod-network-cidr=10.244.0.0/16
# # –image-repository string:这个用于指定从什么位置来拉取镜像(1.13版本才有的),默认值是k8s.gcr.io,我们将其指定为国内镜像地址:registry.aliyuncs.com/google_containers
# # –kubernetes-version string:指定kubenets版本号,默认值是stable-1,会导致从https://dl.k8s.io/release/stable-1.txt下载最新的版本号,我们可以将其指定为固定版本(v1.15.1)来跳过网络请求。
# # –apiserver-advertise-address 指明用 Master 的哪个 interface 与 Cluster 的其他节点通信。如果 Master 有多个 interface,建议明确指定,如果不指定,kubeadm 会自动选择有默认网关的 interface。
# # –pod-network-cidr指定 Pod 网络的范围。Kubernetes 支持多种网络方案,而且不同网络方案对 –pod-network-cidr有自己的要求,这里设置为10.244.0.0/16 是因为我们将使用 flannel 网络方案,必须设置成这个 CIDR。
如果初始化失败,请使用如下代码清除后重新初始化
kubeadm reset
ifconfig cni0 down
ip link delete cni0
ifconfig flannel.1 down
ip link delete flannel.1
rm -rf /var/lib/cni/
rm -rf /var/lib/etcd/*
第二步:配置kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# kubectl 是管理 Kubernetes Cluster 的命令行工具,前面我们已经在所有的节点安装了 kubectl。Master 初始化完成后需要做一些配置工作,然后 kubectl 就能使用了
为了使用更便捷,启用 kubectl 命令的自动补全功能
╭─root@node1 ~
╰─➤ echo "source <(kubectl completion bash)" >> ~/.bashrc
第三步:安装pod网络
╭─root@node1 ~
╰─➤ kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# 要让 Kubernetes Cluster 能够工作,必须安装 Pod 网络,否则 Pod 之间无法通信。
# Kubernetes 支持多种网络方案,这里我们先使用 flannel
为k8s添加节点
node 节点操作
╭─root@node2 ~
╰─➤ kubeadm join 192.168.137.3:6443 --token 1lxhha.rvtg5i1n53vm9hs1
--discovery-token-ca-cert-hash sha256:0b5ce146f98a5efcfddda3637374de1e62d69e10f1b9e37e792e0ac555422039
# 通过kubeadm初始化后,都会提供node加入的token (在初始化的最后一行输出)
# node 节点加入运行此命令即可
# rm -rf /etc/kubernetes/* 重新添加节点需删除上次添加节点时生成的文件
token过期了怎么办
- 通过kubeadm初始化后,都会提供node加入的token
- 默认token的有效期为24小时,当过期之后,该token就不可用了
第一步:在master节点上重新生成token
╭─root@node1 ~
╰─➤ kubeadm token create
zlbwtm.1mtft6bb9k7a2108
第二步:在master节点上获取证书sha256 编码hash值
╭─root@node1 ~
╰─➤ openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
0b5ce146f98a5efcfddda3637374de1e62d69e10f1b9e37e792e0ac555422039
第三步:在node节点上节点加入集群
╭─root@node3 ~
╰─➤ kubeadm join 192.168.137.3:6443 --token zlbwtm.1mtft6bb9k7a2108
--discovery-token-ca-cert-hash sha256:0b5ce146f98a5efcfddda3637374d
e1e62d69e10f1b9e37e792e0ac555422039
k8s集群创建pods
第一步:创建nginx pod
╭─root@node1 ~
╰─➤ kubectl run nginx --image=nginx -r 2
# -r 指定创建的pod数量
第二步:查看pod (详细)
╭─root@node1 ~
╰─➤ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-7bb7cd8db5-d2qf2 0/1 ContainerCreating 0 5m56s <none> node2 <none> <none>
nginx-7bb7cd8db5-sr7qt 0/1 ContainerCreating 0 5m56s <none> node3 <none> <none>
第三步:查看deployment
# kubectl api-resources 查看缩写
╭─root@node1 ~
╰─➤ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 0/2 2 0 15m
# READY 2/2 第一个2是已经启动的pod数,第二个2是需要总共启动的pod数量
# UP-TO-DATE 需要的数量
# AVAILABLE 可用的数量
分析创建过程
- kubectl 通过api-server创建nginx deployment
- deployment-manager 创建nginx deployment
- scheduler把两个pod调度到不同的节点之上
- 节点之上的kubelet创建两个pod
k8s集群deployment
第一步:查看当前deployment
╭─root@node1 ~
╰─➤ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 0/2 2 0 15m
第二步:查看当前deployment详细信息
╭─root@node1 ~
╰─➤ kubectl describe deploy nginx
Name: nginx
Namespace: default
CreationTimestamp: Tue, 20 Aug 2019 03:43:44 -0400
Labels: run=nginx
Annotations: deployment.kubernetes.io/revision: 1
Selector: run=nginx
Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: run=nginx
Containers:
nginx:
Image: nginx
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: nginx-7bb7cd8db5 (2/2 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 56m deployment-controller Scaled up replica set nginx-7bb7cd8db5 to 2
第三步:查看replicaset
╭─root@node1 ~
╰─➤ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-7bb7cd8db5 2 2 2 58m
第四步:查看replicaset详细信息
╭─root@node1 ~
╰─➤ kubectl describe rs nginx-7bb7cd8db5
Name: nginx-7bb7cd8db5
Namespace: default
Selector: pod-template-hash=7bb7cd8db5,run=nginx
Labels: pod-template-hash=7bb7cd8db5
run=nginx
Annotations: deployment.kubernetes.io/desired-replicas: 2
deployment.kubernetes.io/max-replicas: 3
deployment.kubernetes.io/revision: 1
Controlled By: Deployment/nginx # replicaset 被deployment管理
Replicas: 2 current / 2 desired
Pods Status: 2 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: pod-template-hash=7bb7cd8db5
run=nginx
Containers:
nginx:
Image: nginx
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 60m replicaset-controller Created pod: nginx-7bb7cd8db5-sr7qt
Normal SuccessfulCreate 60m replicaset-controller Created pod: nginx-7bb7cd8db5-d2qf2
第五步:查看pod详细信息
╭─root@node1 ~
╰─➤ kubectl get po
NAME READY STATUS RESTARTS AGE
nginx-7bb7cd8db5-d2qf2 1/1 Running 0 62m
nginx-7bb7cd8db5-sr7qt 1/1 Running 0 62m
╭─root@node1 ~
╰─➤ kubectl describe pod nginx-7bb7cd8db5-d2qf2
Name: nginx-7bb7cd8db5-d2qf2
Namespace: default
Priority: 0
Node: node2/192.168.137.4
Start Time: Tue, 20 Aug 2019 03:43:46 -0400
Labels: pod-template-hash=7bb7cd8db5
run=nginx
Annotations: <none>
Status: Running
IP: 10.244.1.2
Controlled By: ReplicaSet/nginx-7bb7cd8db5
Containers:
nginx:
Container ID: docker://67466adb9736a6d86f12513f589fa50c47003b7f37ca1abb0155a39b37064d0c
Image: nginx
Image ID: docker-pullable://nginx@sha256:53ddb41e46de3d63376579acf46f9a41a8d7de33645db47a486de9769201fec9
Port: <none>
Host Port: <none>
State: Running
Started: Tue, 20 Aug 2019 04:02:04 -0400
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-ngn4n (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-ngn4n:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-ngn4n
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Pulled 45m kubelet, node2 Successfully pulled image "nginx"
Normal Created 45m kubelet, node2 Created container nginx
Normal Started 45m kubelet, node2 Started container nginx
第六步:监测pod日志
╭─root@node1 ~
╰─➤ kubectl logs -f nginx-7bb7cd8db5-d2qf2