kubernetes
k8s概述
- 由来:来自谷歌的borg系统,后经go语言重写
- 作用:开源的容器编排框架工具
- 意义:解决裸跑docker
- 官网:https://kubernetes.io
k8s优势
- 自动装箱,水平扩展,自我修复
- 服务发现和负载均衡
- 自动发布和回滚
- 集中化配置管理和密钥管理
- 存储编排
- 任务分批处理运行
资源类型
名称空间级别
- 工作负载型资源(workload):Pod、ReplicaSet、Deployment、StatefulSet、DaemonSet、Job、CronJob(ReplicationController 在v1.11版本被废弃)
- 服务发现及负载均衡型资源(ServiceDiscovery LoadBalance):Service、Ingress…
- 配置与存储型资源:Volume(存储卷 )、CSI(容器存储接口,可以扩展各种各样的第三方存储卷)
- 特殊类型的存储卷:ConfigMap(当配置中心来使用的资源类型)、Secret(保存敏感数据)、DownwardAPI(把外部环境中的信息输出给容器)
集群级资源:Namespace、Node、Role、ClusterRole、RoleBinding、ClusterRoleBinding
元数据型资源:HPA、PodTemplate、LimitRange
pod和pod控制器
pod
- pod是k8s里能够被运行的最小的逻辑单元
- 1个pod里面可以运行多个容器(边车模式),多个容器中共享UTS+NET+IPC名称空间
- 可以吧pod理解成豌豆荚,每一个豌豆荚的豌豆为容器
pod的生命周期
Pod 遵循一个预定义的生命周期,起始于 Pending 阶段,如果至少 其中有一个主要容器正常启动,则进入 Running,之后取决于 Pod 中是否有容器以 失败状态结束而进入 Succeeded 或者 Failed 阶段。
pod控制器
-
pod控制器是pod启动的一种模式,用来保证在k8s里启动的pod按照预期执行
-
k8s内提供多个pod控制器
- Deployment Deployment为Pod和ReplicaSet提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController来方便的管理应用。典型的应用场景包括:
* 定义Deployment来创建Pod和ReplicaSet
* 滚动升级和回滚应用
* 扩容和缩容
* 暂停和继续Deployment - **DaemonSet ** 每一个运算节点都启一份
- ReplicationController和ReplicaSet RC用来确保容器应用的副本数始终保持在用户自定义的副本数,即如果有容器异常退出,会自动创建新的Pod来替代;而如果异常多出来的容器也会自动回收 在新版本的Kubernetes中建议使用ReplicaSet来取代ReplicationController。ReplicaSet跟ReplicationController没有本质的不同,只是名字不一样,并且ReplicaSet支持集合式的selector
- StatefulSet 管理有状态应用的pod控制器
- Job 管理任务
- Cronjob 管理定时周期任务
pod状态
- 挂起(Pending):Pod已被Kubernetes系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度Pod的时间和通过网络下载镜像的时间,这可能需要花点时间
- 运行(Running):该Pod已经绑定到了一个节点上 ,Pod中所有的容器都已经被创建,至少有一个容器正在运行,或者正处于启动或重启状态
- 成功(Succeeded):Pod中的所有容器都被成功终止,并且不会再重启
- 失败(Failed):Pod中的所有容器都已经终止了,并且至少有一个容器是因为失败终止,也就是说,容器以非0状态退出或者被系统终止
- 未知(Unkown):因为某些原因无法取得Pod的状态,通常是因为与Pod所在的主机通信失败
Pod的分类
- 自主式Pod:Pod退出了,此类型的Pod不会被创建
- 控制器管理的Pod:在控制器的生命周期里,始终要维持Pod的副本数目
- Deployment Deployment为Pod和ReplicaSet提供了一个声明式定义(declarative)方法,用来替代以前的ReplicationController来方便的管理应用。典型的应用场景包括:
name和namespace
name
- 由k8s内部,使用“资源”来定义每一种逻辑,每种“资源”都有自己的名称
- “资源”有API版本类别、元数据、定义清单、状态
- “名称”通常定义在“资源”的“元数据”信息
namespace
- 随着项目增多、人员增多、集群规模加大,用来隔离k8s内的各种“资源”,这就是名称空间
- 名称空间可以理解为k8s内部的虚拟集群组
- 不同名称空间内的“资源”,名称可以相同,相同名称空间内的同种“资源”,“名称”不能相同
- 合理的使用k8s的名称空间,使得集群管理员能够更好的对交付到k8s里的服务进行分类管理和浏览
- k8s里默认存在的名称空间有:default、kube-system、kube-public
- 查询k8s里特定“资源”要带上相应的名称空间
label和label选择器
lable
- 标签是k8s特色的管理方式,便于分类管理资源对象。
- 一个标签可以对应多个资源,一个资源也可以有多个标签,它们是多对多的关系
- 一个资源拥有多个标签,可以实现不同维度的管理
- 标签的组成:key=value
- 与标签类似的,还有一种“注解”
label选择器
- 给资源打上标签后,可以使用标签选择器过滤指定的标签
- 标签选择器目前有两个:基于等值关系和基于集合关系
- 许多资源支持内嵌选择器字段
- matchLabels
- matchExpressions
service和ingress
service
- 在k8s的世界里,虽然每个pod都会被分配一个单独的ip地址,但这个ip地址会随着pod的销毁而消失
- service就是用来解决这个问题的核心
- 一个service可以看做一组提供相同服务的pod的对外访问接口
- service作用于哪些pod是通过标签选择器来定义
- 防止pod失联
- 定义一组pod的访问策略
ingress
- ingress是k8s集群里工作在OSI网络参考模型,第7层的应用,对外暴露的接口
- service只能进行L4流量调度,表现形式是ip+port
- ingress则可以调度不同业务域、不同URL访问路径的业务流量
核心组件
-
配置存储中心–>etcd服务
-
主控节点(master)
- kube-apiserver服务
- 提供了集群管理的RESTAPI接口(鉴权、校验、集群状态变更)
- 负责其他模块之间的数据交互,承担通信枢纽功能
- 是资源配额控制的入口
- 提供完备的集群安全机制
- kube-controller-manager服务 控制器管理控制器
- 由一系列控制器组成,通过apiserver监控整个集群的状态,并确保集群处于预期的工作状态
- Node Controller 节点控制器
- Deployment Controller pod控制器
- Server Controller 服务控制器
- Volume Controller 存储卷控制器
- Endpoint Controller 接入点控制器
- Garbage Controller 垃圾回收控制器
- Namespace Controller 名称空间控制器
- Job Controller 任务控制器
- Resource quta Controller 资源配额控制器
- kube-scheduler服务
- 主要功能是接收调度pod到适合的运算节点上
- 预算策略
- 优选策略
- kube-apiserver服务
-
运算节点(node)
- kube-kubelet服务
- kubelet的主要功能就是定时从某个地方获取节点上pod的期望状态,并调用对应的容器平台接口这个状态
- 定时汇报当前节点的状态给apiserver,以供调度的时候使用
- 镜像和容器的清理工作,保证节点上镜像不会沾满磁盘空间,退出的容器不会占用太多资源
- kube-proxy服务
- 是k8s在每个节点上运行网络代理,server资源的载体
- 建立了pod网络和集群网络的关系
- 负责建立和删除包括更新调度规则、通知apiserver自己的更新,或者从apiserver哪里获取其他kube-proxy的调度规则变化来更新自己的
- 常用三种流量调度模式
- Userspace (废弃)
- Iptables (濒临废弃)
- ipvs (推荐)
- kube-kubelet服务
-
CLI客户端
- kubectl
-
k8s节点网络
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dJ6KiTH3-1640685570793)(C:\Users\超哥小学生\Desktop\微信图片_20200827145118.png)]
-
k8s逻辑图
核心附件
- CNI网络插件–>flannel/calico
- 服务发现用插件–>coredns
- 服务暴露用插件–>traefik
- GUI管理插件–>Dashboard
SLL证书
加密
- 对称加密:加密解密用相同的密钥
- 非对称加密:用公钥~私钥的密钥对实现加解密 (银行服务器使用私钥,客户访问银行的服务器时,将会下载一个公钥,然后通过下载的公钥将自己的账号密码进行加密,再将加密文件传给服务器,通过指定的私钥进行解密)
- 单向加密:只能加密不能解密 (md5)
ssl证书来源
- 网络第三方机构,通常用于外部用户访问
- 自签证书 (在内网使用)
签证机构(CA) 自建
- openssl
- cfssl
二进制单master k8s集群
master 192.168.109.100 2G 2G 60G k8s-master
node1 192.168.109.101 2G 2G 60G k8s-node1
node2 192.168.109.102 2G 2G 60G k8s-node2
-
初始化服务器
-
关闭防火墙
systemctl stop firewalld systemctl disable firewalld
-
关闭selinux
setenforce 0 vim /etc/selinux/config 改成disable
-
配置主机名
hostnamectl set-hostname 主机名
-
配置名称解析
vim /etc/hosts 加上 ip+主机名 eg:192.168.109.100 k8s-master
-
关闭交换分区
swapoff -a vim /etc/fstab 删除最后一行 free -m
-
配置时间同步
选择一个为服务端,剩下的为客户端
- 配置k8s-master
yum install chrony -y vim /etc/chrony.conf server 127.127.1.0 iburst allow 192.168.109.0/24
local stratum 10
* 配置k8s-node ```shell yum install chrony -y vim /etc/chrony.conf server 192.168.109.100 iburst
-
-
给etcd颁发证书
-
创建证书颁发机构
[root@k8s-master etcd]# cat generate_etcd_cert.sh [root@k8s-master etcd]# ./generate_etcd_cert.sh
-
填写表单(etcd所在节点的ip地址)
vim server-csr.json "hosts": [ "192.168.109.100", "192.168.109.101", "192.168.109.102" ],
-
向证书颁发机构申请证书
-
-
部署etcd
-
将etcd安装到三台服务器上
将服务脚本etcd.service ,etcd
centos 7 /usr/lib/systemd/system centos 6 /etc/rc.d/rcN.d mv etcd /opt/etcd vim /opt/etcd/cfg/etcd.conf #[Member] 单节点 ETCD_NAME="etcd-1" 当前etcd的唯一名称 ETCD_DATA_DIR="/var/lib/etcd/default.etcd" 存储数据的位置 ETCD_LISTEN_PEER_URLS="https://192.168.109.100:2380" etcd和其他的etcd通信数据端口 ETCD_LISTEN_CLIENT_URLS="https://192.168.109.100:2379" etcd和外部master客户端通信 #[Clustering] 集群 ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.109.100:2380" 给其他的集群进行通告 ETCD_ADVERTISE_CLIENT_URLS="https://192.168.109.100:2379" 给其他的集群进行通告 ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.109.100:2380,etcd-2=https://192.168.109.101:2380,etcd-3=https://192.168.109.102:2380" 所有etcd的信息 ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new" new表示新创建的集群 如果是existing已存在 alias 别名 alias cdnet='cd /etc/sysconfig/network-scripts' \命令 表示不使用别名 最后将etcd文件scp到另外两台服务器上 测试etcd是否部署成功 /opt/etcd/bin/etcdctl \ --ca-file=/opt/etcd/ssl/ca.pem --cert-file=/opt/etcd/ssl/server.pem --key-file=/opt/etcd/ssl/server-key.pem \ --endpoints="https://192.168.109.100:2379,https://192.168.109.101:2379,https://192.168.109.102:2379" \ cluster-health member 33656cb8c2a8d5e2 is healthy: got healthy result from https://192.168.109.100:2379 member 992a804200dc2b57 is healthy: got healthy result from https://192.168.109.102:2379 member 9e5391bd37c0ab08 is healthy: got healthy result from https://192.168.109.101:2379 cluster is healthy
-
-
部署master服务
cd /root/ssl/TLS/k8s vim server-csr.json { "CN": "kubernetes", "hosts": [ "10.0.0.1", "127.0.0.1", "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster", "kubernetes.default.svc.cluster.local", "192.168.109.100", "192.168.109.101", "192.168.109.102" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing", "O": "k8s", "OU": "System" } ] } 执行./generate_k8s_cert.sh tar zxvf k8s-master.tar.gz cp kube-apiserver.service kube-controller-manager.service kube-scheduler.service /usr/lib/systemd/system cp /root/ssl/TLS/k8s/{ca*pem,server.pem,server-key.pem} /opt/kubernetes/ssl/ -rvf vim /opt/kubernetes/cfg/kube-apiserver.conf KUBE_APISERVER_OPTS="--logtostderr=false \ 错误信息打印到标准输出 false不打印 --v=2 \ 日志级别 1,2,3,4,5,6,7 日志级别越高 记录信息越详细 但占用磁盘越多 --log-dir=/opt/ku,ernetes/logs \ 日志文件位置 --etcd-servers=https://192.168.109.100:2379,https://192.168.109.101:2379,https://192.168.109.102:2379 \ etcd节点和端口 --bind-address=192.168.109.100 \ master监听IP地址 --secure-port=6443 \ master监听端口 --advertise-address=192.168.109.100 \ 通过地址 --allow-privileged=true \ 是否设置启用超级管理员权限 --service-cluster-ip-range=10.0.0.0/24 \ server服务的虚拟网段 --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \ 允许的插件控制 --authorization-mode=RBAC,Node \ 授权模式 rbac角色授权 node节点授权 --enable-bootstrap-token-auth=true \ 实现token自动颁发证书 --token-auth-file=/opt/kubernetes/cfg/token.csv \ 特定用户颁发的证书 --service-node-port-range=30000-32767 \ 暴露端口的范围 --kubelet-client-certificate=/opt/kubernetes/ssl/server.pem \ kubernetes相关证书 --kubelet-client-key=/opt/kubernetes/ssl/server-key.pem \ --tls-cert-file=/opt/kubernetes/ssl/server.pem \ https访问apiserver时所使用的证书 --tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \ --client-ca-file=/opt/kubernetes/ssl/ca.pem \ --service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \ --etcd-cafile=/opt/etcd/ssl/ca.pem \ etcd所使用的证书 --etcd-certfile=/opt/etcd/ssl/server.pem \ --etcd-keyfile=/opt/etcd/ssl/server-key.pem \ --audit-log-maxage=30 \ --audit-log-maxbackup=3 \ --audit-log-maxsize=100 \ --audit-log-path=/opt/kubernetes/logs/k8s-audit.log" cat /opt/kubernetes/cfg/token.csv c47ffb939f5ca36231d9e3121a252940,kubelet-bootstrap,10001,"system:node-bootstrapper" tken,同户名,用户过期时间,用户所在的namespace的名称空间 vim /opt/kubernetes/cfg/kube-contorller-manager KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \ --v=2 \ --log-dir=/opt/kubernetes/logs \ --leader-elect=true \ --master=127.0.0.1:8080 \ 指定apiserver的地址 --address=127.0.0.1 \ 服务监听地址 --allocate-node-cidrs=true \ 是否支持网络插件 --cluster-cidr=10.244.0.0/16 \ --service-cluster-ip-range=10.0.0.0/24 \ --cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \ --cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem \ --root-ca-file=/opt/kubernetes/ssl/ca.pem \ --service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \ --experimental-cluster-signing-duration=87600h0m0s" vim /opt/kubernetes/cfg/kube-scheduler.conf KUBE_SCHEDULER_OPTS="--logtostderr=false \ --v=2 \ --log-dir=/opt/kubernetes/logs \ --leader-elect \ --master=127.0.0.1:8080 \ --address=127.0.0.1" 配置自动颁发证书 给kubelet-bootstrap授权: kubectl create clusterrolebinding kubelet-bootstrap \ --clusterrole=system:node-bootstrapper \ --user=kubelet-bootstrap
-
安装node节点
-
安装docker:启动容器
tar xvf k8s-node.tar.gz mv docker.service /usr/lib/systemd/system [root@k8s-node-1 ~]# mkdir /etc/docker [root@k8s-node-1 ~]# cp daemon.json /etc/docker/ tar xf docker-18.09.6.tgz mv docker/* /bin/ systemctl start docker
-
安装kubelet:接受apiserver的指令,控制docker容器
tar xvf k8s-node.tar.gz mv kubelet.service /usr/lib/systemd/system/ mv kubernetes /opt/
-
kube-proxy:为node上的容器配置网络工作
tar xvf k8s-node.tar.gz mv kube-proxy.service usr/lib/systemd/system/ mv kubernetes /opt/
-
配置文件
vim /opt/kubernetes/cfg/kube-proxy.kubeconfig apiVersion: v1 clusters: - cluster: certificate-authority: /opt/kubernetes/ssl/ca.pem server: https://192.168.31.61:6443 master地址 name: kubernetes contexts: - context: cluster: kubernetes user: kube-proxy name: default current-context: default kind: Config preferences: {} users: - name: kube-proxy user: client-certificate: /opt/kubernetes/ssl/kube-proxy.pem client-key: /opt/kubernetes/ssl/kube-proxy-key.pem vim /opt/kubernetes/cfg/kube-proxy-config.yml kind: KubeProxyConfiguration apiVersion: kubeproxy.config.k8s.io/v1alpha1 address: 0.0.0.0 metricsBindAddress: 0.0.0.0:10249 clientConnection: kubeconfig: /opt/kubernetes/cfg/kube-proxy.kubeconfig hostnameOverride: k8s-node1 主机名 clusterCIDR: 10.0.0.0/24 mode: ipvs ipvs: scheduler: "rr" iptables: masqueradeAll: true vim /opt/kubernetes/cfg/bootstrap.kubeconfig apiVersion: v1 clusters: - cluster: certificate-authority: /opt/kubernetes/ssl/ca.pem server: https://192.168.109.100:6443 master地址 name: kubernetes contexts: - context: cluster: kubernetes user: kubelet-bootstrap name: default current-context: default kind: Config preferences: {} users: - name: kubelet-bootstrap user: token: c47ffb939f5ca36231d9e3121a252940 vim /opt/kubernetes/cfg/kubelet.conf systemctl start kube-proxy systemctl start kubelet
-
从master节点复制证书到node节点
cd /root/ssl/TLS/k8s/ scp kube-proxy.pem kube-proxy-key.pem ca.pem root@k8s-node1:/opt/kubernetes/ssl/
-
启动kubelet和kube-proxy
kubelet get csr kubectl certificate approve nodeID 用master节点给node节点颁发证书
-
-
安装网络插件
-
确认启用cni
-
安装插件
创建一个文件 mkdir -pv /opt/cni/bin /etc/cni/net.d‘ 解压cni插件到/opt/cni/bin tar xf cni-plugins-linux-amd64-v0.8.2.tgz -C /opt/cni/bin kubectl describe node k8s-node-2 查看node信息
-
-
在master上执行yaml脚本,实现在node节点安装启动网络插件功能
cd YAML/ kubectl apply -f kube-flannel.yaml 查看节点状态 kubectl get nodes
-
授权apiserver可以访问kubelet
[root@k8s-master YAML]# kubectl apply -f apiserver-to-kubelet-rbac.yaml [root@k8s-master YAML]# kubectl apply -f apiserver-to-kubelet-rbac.yaml kubectl apply -f apiserver-to-kubelet-rbac.yaml shell
-
启动nginx容器
-
修改docker配置文件
vim /etc/docker/daemon/json
{
“registry-mirrors”:[
“https://docker.mirrors.ustc.edu.cn”
],
“insecure-registries”: [“192.168.109.101”]
}
systemctl daemon-reload
systemctl restart docker* 下载nginx镜像 ```shell docker pull nginx:1.7.9 docker save nginx:1.7.9>./nginx-1.7.9.tar.gz docker load -i nginx-1.7.9.tar.gz
-
创建deployment,通过deployment来创建管理nginx容器
kubectl create deployment [name] --image=nginx:1.7.9 kubectl get deployment
-
暴露物理机端口
kubectl expose deployment [name] --port=80 --type=NodePort kubectl get svc
-
-
配置web界面
-
kuboard
kubectl apply -f kuboard.yaml kubectl get pods -n kube-system
-
生成token
kubectl -n kube-system get secret $(kubectl -n kube-system get secret | grep kuboard-user | awk '{print $1}') -o go-template='{{.data.token}}' | base64 -d
k8s部署项目流程
-
1.制作镜像
-
2.控制器管理pod
-
3.暴露应用
-
4.对外发布应用
-
5.日志/监控
-
暴露物理机端口
kubectl expose deployment [name] --port=80 --type=NodePort kubectl get svc
-
-
配置web界面
-
kuboard
kubectl apply -f kuboard.yaml kubectl get pods -n kube-system
-
生成token
kubectl -n kube-system get secret $(kubectl -n kube-system get secret | grep kuboard-user | awk '{print $1}') -o go-template='{{.data.token}}' | base64 -d
k8s部署项目流程
-
1.制作镜像
-
2.控制器管理pod
-
3.暴露应用
-
4.对外发布应用
-
5.日志/监控
-