k8s的介绍
k8s的配置介绍
- 构建一套K8S云计算平台,至少2台服务器(硬件服务器),基于Linux操作系统,最好Linux内核3.8+以上,推荐使用3.10内核版本,对应Linux操作系统发行版:RHEL7.x、CentOS7.x、Ubuntu16.x;
- 构建K8S底层2台硬件服务器的配置:
- CPU:1C
- MEM:1G
- DISK:40GB
- NET:1000Mb+10Gb
- K8S云计算框架技术,C/S模式,Master节点和Node节点,1台Master节点,一台Node节点;
Master节点称为控制节点,用于管理Node节点,对Node节点上资源进行调度和管理的;
Node节点称为被控节点,用于创建Docker容器、虚拟机、管理容器、容器网络、镜像管理,主要用于提供云主机; - 配置Master和Node节点网络连通,Node节点是用于Docker容器管理,启动Docker容器,为了实现宿主机跟其他宿主机上的Docker容器网络通信的话,引入Flannel软件,主要解决跨网络主机通信的
- NODE节点主要是用于资源分配、资源池,真正消耗资源的Node节点,而不是Master节点,可以添加节点、删除节点
Etcd
- ETCD是分布式的K-V(KEY-VALUE)存储系统,称为配置文件代码保存中心,主要是用于存储K8S+Flannel网络相关的信息的,例如存储Flannel网段信息,K8S读取ETCD的K-V值,默认配置文件:/etc/etcd/etcd.conf
Flannel
- 用来打通所有节点之间的网络,各个节点可以进行通信
- Flannel网络读取ETCD配置中心的K-V,ETCD提前创建K-V信息,Flannel网络的配置段信息(IP段信息),在etcd配置中心创建K-V网段信息
# master节点上的操作
etcdctl mk /atomic.io/network/config '{"Network":"172.17.0.0/16"}'
k8s安装步骤
k8s平台必备条件(每台机器)
# 关闭自启动
systemctl disable firewalld
# 关闭防火墙
systemctl stop firewalld
# 关闭selinux
# 临时禁用selinux
setenforce 0
# 永久关闭 修改/etc/sysconfig/selinux文件设置
sed -i 's/SELINUX=permissive/SELINUX=disabled/g' /etc/sysconfig/selinux
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
# 禁用交换分区
swapoff -a
# 永久禁用,打开/etc/fstab注释掉swap那一行。
sed -i 's/.*swap.*/#&/' /etc/fstab
yum -y install ntp
# 同步时间
ntpdate pool.ntp.org
# 再启动服务
systemctl start ntpd
systemctl enable ntpd
# 这个是第二种同步时间的方式(生产环境)
# 定时任务
# 每个3小时同步时间
0 */3 * * * ntpdate pool.ntp.org
# 重启一下crond
service crond restart
Kubernetes Master安装与配置
master服务
yum install kubernetes-master etcd flannel *rhsm* -y
etcd的配置
# etcd配置中心,可以单独部署在一台服务器上
# 配置etcd的配置
cd /etc/etcd
# 备份文件
cp etcd.conf etcd.conf.bak
# 查看不是#开头的配置
grep -v "^#" etcd.conf
# 数据目录
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
# localhost 替换为 etcd的服务ip
# 本地监听网卡和端口;
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
# 默认名字为default,可以随意去etcd1
ETCD_NAME="default"
# ETCD对外宣告访问地址;
ETCD_ADVERTISE_CLIENT_URLS="http://172.20.10.6:2379"
# vim里的替换
%s/localhost/172.20.10.6/g
sed -i "s/localhost/172.20.10.6/g" etcd.conf
# 通过不同的设置api 版本环境变量,支持的命令行不同
cat >> /etc/profile << EOF
export ETCDCTL_API=2
EOF
source /etc/profile
# 重启etcd的服务
service etcd restart
systemctl enable etcd
# etcd集群搭建
kubernetes的配置
cd /etc/kubernetes/
apiserver:用于用户、控制端去操作NODE节点的入口,API访问接口
# 配置apiserver
vim apiserver
KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"
# 配置etcd的服务ip
KUBE_ETCD_SERVERS="--etcd-servers=http://172.20.10.6:2379"
# default admission control policies
#KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"
# 不用账户和安全认证,去掉SecurityContextDeny,ServiceAccount
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,ResourceQuota"
# 配置config
vim config
# kube的本地ip
KUBE_MASTER="--master=http://172.20.10.6:8080"
# 如果为true,表示ui界面,在创建容器的时候,高级选项里面,可以以特权身份运行(root)
KUBE_ALLOW_PRIV="--allow-privileged=true"
# controller-manager和scheduler 不需要修改
# 开启服务
service kube-apiserver restart
service kube-controller-manager restart
service kube-scheduler restart
# 第二中开启服务
systemctl restart kube-apiserver
systemctl restart kube-controller-manager
systemctl restart kube-scheduler
# 开机启动
systemctl enable kube-apiserver
systemctl enable kube-controller-manager
systemctl enable kube-scheduler
# 查看服务
ps -ef | grep -E "apiserver|manager|scheduler"
Kubernetes Node1安装与配置
node服务
yum install kubernetes-node docker flannel *rhsm* -y
kubernetes的配置
cd /etc/kubernetes/
# 3个配置文件的作用
config:客户端系统配置文件,指向Master端apiserver接口文件;
Kubelet:Node节点的agent客户端配置文件,监听Agent程序,同时指定master端口apisever,接受Master端控制,可以管理本地Docker引擎服务(下载镜像、启动容器、映射访问);
Proxy:代理配置文件,主要是用于后期服务均衡、服务访问使用的
# 配置config
vim config
# kube的master的ip
KUBE_MASTER="--master=http://172.20.10.6:8080"
# 如果为true,表示ui界面,在创建容器的时候,高级选项里面,可以以特权身份运行(root)
KUBE_ALLOW_PRIV="--allow-privileged=true"
# 配置kubelet
vim kubelet
# node1 本地ip
KUBELET_ADDRESS="--address=172.20.10.7"
KUBELET_HOSTNAME="--hostname-override=172.20.10.7"
# master ip
KUBELET_API_SERVER="--api-servers=http://172.20.10.6:8080"
# proxy 不需要修改
# 启动服务
service kube-proxy restart
service kubelet restart
service docker restart
systemctl restart kube-proxy
systemctl restart kubelet
systemctl restart docker
systemctl enable kube-proxy
systemctl enable kubelet
systemctl enable docker
Kubernetes flanneld 网络配置(每台)
# 作用
用来打通所有节点之间的网络,各个节点可以进行通信
cd /etc/sysconfig
# 配置flanneld
vim flanneld
# 配置etcd的ip
FLANNEL_ETCD_ENDPOINTS="http://172.20.10.6:2379"
# etcd里key的前缀,flannel根绝这个key的前缀,来获取网段信息,所以需要在etcd里创建该key前缀的信息
FLANNEL_ETCD_PREFIX="/atomic.io/network"
# 启动服务
service flanneld restart
# 此时启动会启动不起来,需要去etcd的服务器里,配置相应的信息
# 添加网段的信息,以后容器里的ip都在这个范围
etcdctl mk /atomic.io/network/config '{"Network":"172.17.0.0/16"}'
# master node启动服务
service flanneld restart
# 此时node 需要重启docker,保证docker和flannel在同一个网段
service docker restart
# 第二种启动
systemctl restart flanneld
systemctl restart docker
# 开机启动
systemctl enable flanneld
Etcd测试
在Maste服务器,测试Etcd集群是否正常,
创建flannel网络配置:
vim /etc/profile
# 通过不同的设置api 版本环境变量,支持的命令行不同
export ETCDCTL_API=2
source /etc/profile
# 重启etcd的服务
service etcd restart
etcdctl member list
etcdctl cluster-health
# 获取网段的信息
etcdctl get /atomic.io/network/config
# 查看网络信息
etcdctl ls /atomic.io/network/subnets
# 删除,不操作
etcdctl rm /atomic.io/network/ --recursive
# 添加网段的信息
etcdctl mk /atomic.io/network/config '{"Network":"172.17.0.0/16"}'
ping通网络
# master
etcdctl ls /atomic.io/network/subnets
/atomic.io/network/subnets/172.17.20.0-24
/atomic.io/network/subnets/172.17.5.0-24
ping 172.17.20.0
ping 172.17.5.0
# node1
ping 172.17.20.0
ping 172.17.5.0
# 如果没有ping通,在master和node上执行
service flanneld restart;service docker restart;iptables -P FORWARD ACCEPT
查看结果
# 查看节点的信息
kubectl get nodes # 如果有结果了,就表示成功了
# 删除节点
kubectl delete nodes/172.20.10.8
# 查看日志
tail -fn 100 /var/log/messages
Kuberetes Dashboard UI实战
node服务器里的操作
# node服务器里的操作
# 下载两个镜像
pod-infrastructure
kubernetes-dashboard-amd64
docker pull docker.io/tianyebj/pod-infrastructure
docker pull siriuszg/kubernetes-dashboard-amd64:v1.6.3
# 修改镜像的名字,
docker tag $(docker images | grep pod-infrastructure | awk '{print $3}') registry.access.redhat.com/rhel7/pod-infrastructure
# 因为node节点中的/etc/kubernetes/kubelet 配置文件中指定的就是这个名字的镜像
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"
docker tag $(docker images | grep kubernetes-dashboard-amd64 | awk '{print $3}') bestwu/kubernetes-dashboard-amd64:v1.6.3
# 因为master节点中,创建dashboard-controller.yaml文件里指定了这个镜像的名字和版本
master服务的操作
mkdir -p /etc/dashboard
vim dashboard-controller.yaml
vim dashboard-service.yaml
dashboard-controller.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: kubernetes-dashboard
namespace: kube-system
labels:
k8s-app: kubernetes-dashboard
kubernetes.io/cluster-service: "true"
spec:
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
annotations:
scheduler.alpha.kubernetes.io/critical-pod: ''
scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]'
spec:
containers:
- name: kubernetes-dashboard
# 注意镜像名和版本号
image: bestwu/kubernetes-dashboard-amd64:v1.6.3
resources:
limits:
cpu: 100m
memory: 50Mi
requests:
cpu: 100m
memory: 50Mi
ports:
- containerPort: 9090
args:
# 此处需要修改,master的ip
- --apiserver-host=http://172.20.10.6:8080
livenessProbe:
httpGet:
path: /
port: 9090
initialDelaySeconds: 30
timeoutSeconds: 30
dashboard-service.yaml
apiVersion: v1
kind: Service
metadata:
name: kubernetes-dashboard
namespace: kube-system
labels:
k8s-app: kubernetes-dashboard
kubernetes.io/cluster-service: "true"
spec:
selector:
k8s-app: kubernetes-dashboard
ports:
- port: 80
targetPort: 9090
启动
# master服务器里的操作
cd /etc/dashboard
# 启动
kubectl create -f dashboard-service.yaml
kubectl create -f dashboard-controller.yaml --validate=false
# 查看是否启动成功
kubectl get pods --all-namespaces
# 删除
kubectl delete -f dashboard-service.yaml
kubectl delete -f dashboard-controller.yaml
# 获取容器的ip和services的ip
kubectl get pods -o wide
kubectl get services -o wide
# 查看日志
tail -fn 100 /var/log/messages
# 访问
http://172.20.10.6:8080
# 访问ui界面
http://172.20.10.6:8080/ui
容器操作
通过UI界面操作
# 扩容10台nginx容器
点击overview->查看部署->点击nginx里的 查看/编辑->更改里面的配置replicas改为10
# 删除10台nginx容器
点击overview->查看部署->点击nginx里的 查看/编辑->更改里面的配置replicas改为1
然后再删除部署里的nginx->删除副本集的nginx->删除容器组的nginx
通过命令行
# master服务器
通过ui界面,首先先创建一台nginx容器
点击overview->查看部署->点击nginx里的 查看/编辑->点击复制
# 创建一台的时候这样操作
vim create_nginx.yaml
kubectl create -f create_nginx.yaml
Kubernetes平台组件概念
Kubernetes节点介绍
- Kubernetes集群中主要存在两种类型的节点:master,minion(node)节点
- Minion节点为运行Docker容器的节点,负责和节点上运行的
- Docker进行交互,并且提供了代理功能
Kubernetes master的介绍
- Kubelect Master:Master节点负责对外提供一些列管理集群的API接口,并且通过和Minion(node)节点交互来实现对集群的操作管理
- apiserver:用户和kubernetes集群交互的入口,封装了核心对象的增删改查操作,提供了RESTFul风格的API接口,通过etcd来实现持久化并维护对象的一致性
- scheduler:负责集群资源的调度和管理,例如当有pod(相当于一个盒子,里面装了很多容器,容器组)异常退出需要重新分配机器时,scheduler通过一定的调度算法从而找到最合适的节点
- controller-manager:主要用于保证replication(副本) controller定义的复制数量和实际运行的pod数量一致,另外还保证了从service到pod的映射关系总是最新的
Kubernetes node的介绍
- kubelet:运行在minion(node)节点,负责和节点上的Docker交互,例如启停容器,监控运行状态等
- proxy:运行运行在minion(node)节点,负责为pod提供代理功能,会定期从etcd获取service信息,并根据service信息通过修改iptables来实现流量转发(最初的版本是直接通过程序提供转发功能,效率较低),将流量转发到要访问的pod所在的节点上去
Etcd
- etcd是一个分布式一致性k-v存储系统数据库,可用于服务注册发现与共享配置存储数据库,用来存储kubernetes的信息的,etcd组件作为一个高可用,强一致性的服务发现存储仓库,渐渐为开发人员所关注。在云计算时代,如何让服务快速透明地接入到计算集群中,如何让共享配置信息快速被集群中的所有机器发现,更为重要的是,如何构建这样一套高可用,安全,易于部署以及响应快速的服务集群,etcd的诞生就是为解决该问题
etcd的操作:
etcdctl help
# 查看
etcdctl ls /
# 创建目录
etcdctl mkdir /user
# 设置值
etcdctl set /user/name zs
# 获取值
etcdctl get /user/name
# 删除值
etcdctl rm /user/name
# 删除文件夹
etcdctl rmdir /user
Flannel
- Flannel是CoreOs团队针对Kubernetes设计的ige覆盖网络(Overlay Network)工具,Flannel目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得同一个内容且不重复的IP地址,并让属于不同节点上的容器能够直接通过内容IP通信
POD
- 容器集合,调度部署的基本单位
例如:有两台node机器,需要部署3台centos和3台nginx
# 部署的结果
node1:有2台centos容器,2台nginx容器,这个就表示,该node1里有两个pod,一个pod负责2台centos容器,一个pod负责2台nginx的容器
node2:有2台centos容器,1台nginx容器,这个就表示,该node2里有两个pod,一个pod负责1台centos容器,一个负责1台nginx的容器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SR0K3QC8-1583832328404)(./images/pod.png)]
service
- pod访问代理抽象,作用,就是不关心ip的变化,因为重启的时候,容器的ip会发生变化
- Service是kubernetes最核心的概念,通过创建service,可以为一组具有相同功能的POD应用提供统一的访问入口,并且将请求进行负载分发到后端的各个容器应用上
- 在kubernetes中,在受到RC(副本)调控的时候,pod副本是变化的,对于虚拟ip也是变化的,比如发生迁移或者伸缩的时候,这对于pod访问者来说是不可接受的(ip发生变化,很难根据ip去访问项目)
- Kubernetes分配给service的固定ip是要给虚拟ip,并不是一个真实的ip,在外部是无法寻址的,在真实的系统实现上,kubernetes是通过kube-proxy组件来实现的虚拟ip路由及转发,所以在之前集群部署的环节上,我们在每个node上均部署了proxy这个组件,从而实现了kubernetes层级的虚拟转发网络
内部服务:
- 会生成一个cluster ip,在宿主机上通过访问cluster ip加映射的端口号,就可以访问,外部需要访问的话,需要在通过nginx转发
例如,创建2台nginx的内部服务,端口映射30080-80,生成一个cluster ip 10.254.10.54,在master或node机上访问,http://10.254.10.54:30080,即可访问到内部的nginx
外部需要访问的话,可以通过nginx转发
外部服务
- 会生成一个cluster ip,指定的映射端口和随机的端口,外部需要访问的话,node-ip:随机端口
例如,创建2台nginx的外部服务,端口映射30081-80,生成一个cluster ip 10.254.127.27,以及一个随机端口号30546,在master或node机上访问,http://10.254.127.27:30081,即可访问到内部的nginx;
外部需要访问的话,也可以直接任意node-ip:随机端口,可以利用nginx的负载均衡,也可以利用nginx转发
外部访问service
Kubernetes提供了NodePort,LoadBalancer,lngress三种方式:
- NodePort,原理是Kubernetes会在每一个Node上暴露出一个端口:NodePort,外部网络可以通过(任一Node)[NodeIp]:[NodePort](随机端口)访问到后端的service
- LoadBalancer,在NodePort基础上,Kubernetes可以请求底层云平台创建一个负载均衡器,将每个Node作为后端,进行服务分发,该模式需要底层平台(例如GCE)支持
例如NodePort(外部服务),nginx的配置:
upstream k8s_nginx {
# max_fails表示尝试连接的次数,fail_timeout表示超市的时间单位为秒
server 172.20.10.7:30546 weight=1 max_fails=2 fail_timeout=15;
server 172.20.10.8:30546 weight=1 max_fails=2 fail_timeout=15;
}
server {
listen 80;
server_name _;
charset utf-8;
client_max_body_size 1024M;
fastcgi_read_timeout 600s;
location / {
proxy_set_header Host $host;
proxy_pass http://k8s_nginx;
}
}
replication controller(RC)
- 副本集,pod的复制抽象,副本集有多少,同一时刻就存在多少数量的容器
k8s工作原理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AGrlF3Mo-1583832328407)(./images/k8s.png)]
各服务的作用
- apiserver 用户通过kubectl命令向apiserver发送创建service的命令,apiserver接受到请求以后将数据存储到etcd中
- kube-proxy kubernetes的每个节点中都有一个叫做kube-proxy的进程,这个进程负责感知service,pod的变化,并将变化的信息写入到本地的iptables中
- iptables 使用NAT等技术将virtual ip(虚拟ip)的流量转至endpoint中
查看网络规则
# 虚拟ip对应到那个容器
iptables -t nat -L -n --line-numbers | more
# 查看路由规则
route -n
k8s升级
更新
# 将服务sh-nginx-v1部署应用的镜像修改为 最新的镜像名称:nginx:v1
# -n:命名控件 sh-nginx-v1 服务名称,把该服务更新为最新的nginx
kubectl -n default set image deployments/sh-nginx-v1 sh-nginx-v1=nginx:v1
回滚
# 把服务sh-nginx-v1回滚到上一个版本
kubectl -n default rollout undo deployments/sh-nginx-v1
# 查看回滚的状态
kubectl -n default rollout status deployments/sh-nginx-v1
查看版本
# 查看所有版本信息
kubectl rollout history deploy/sh-nginx-v1
# 查看版本的详细信息
kubectl rollout history deploy/sh-nginx-v1 --revision=2
# 回滚到指定的版本
kubectl -n default rollout status deployments/sh-nginx-v1 --to-revision=3
k8s开启多个centos
下载centos镜像
# 下载镜像,带ssh的
docker pull docker.io/lemonbar/centos6-ssh
# 该镜像的名字
docker tag docker.io/lemonbar/centos6-ssh 172.20.10.6:5000/centos6
# push到docker私有仓库
docker push 172.20.10.6:5000/centos6
在ui界面上创建centos
# 容器镜像,会去本地仓库拉取
172.20.10.6:5000/centos6
# 然后查看镜像的ip,登录进去
ssh root@ip # 初始密码为123456
# 查看登录密码(master)
docker history centos6 # master
docker history 172.20.10.6:5000/centos6 # node
# 拷贝模板,显示的好看一些
cp /etc/skel/.bash* /root/
su
traceroute(查看ip访问)
yum install traceroute -y
traceroute # 查看help
# 可以查看本地是怎么去一步步访问到别人的IP的
traceroute www.baidu.com
1 gateway (172.20.10.1) 3.051 ms 2.907 ms 3.936 ms
2 * * *
3 172.16.2.53 (172.16.2.53) 62.444 ms 62.304 ms 62.147 ms
4 * * *
5 111.47.195.57 (111.47.195.57) 42.056 ms 41.945 ms 41.841 ms
6 211.137.61.49 (211.137.61.49) 48.203 ms 38.259 ms 38.157 ms
7 221.183.39.209 (221.183.39.209) 42.172 ms * 221.183.39.213 (221.183.39.213) 52.230 ms
# 本地访问到www.baidu.com,是先走网关172.20.10.1,然后转到172.16.2.53,然后...
问题
k8s v1.5.2 中 service的cluster ip无法访问的问题