kubernetes介绍
Kubernetes是Google在2014年6月开源的一个容器集群管理系统,使用Go语言开发,Kubernetes也叫K8S。
K8S是Google内部一个叫Borg的容器集群管理系统衍生出来的,Borg已经在Google大规模生产运行十年之久。
K8S主要用于自动化部署、扩展和管理容器应用,提供了资源调度、部署管理、服务发现、扩容缩容、监控等一整套功能。
2015年7月,Kubernetes v1.0正式发布,截止到2017年9月29日最新稳定版本是v1.8。
Kubernetes目标是让部署容器化应用简单高效。
官方网站:www.kubernetes.io
- 数据卷
- Pod中容器之间共享数据,可以使用数据卷。
- 应用程序健康检查
- 容器内服务可能进程堵塞无法处理请求,可以设置监控检查策略保证应用健壮性。
- 复制应用程序实例
- 控制器维护着Pod副本数量,保证一个Pod或一组同类的Pod数量始终可用。
- 弹性伸缩
- 根据设定的指标(CPU利用率)自动缩放Pod副本数。
- 服务发现
- 使用环境变量或DNS服务插件保证容器中程序发现Pod入口访问地址。
- 负载均衡
- 一组Pod副本分配一个私有的集群IP地址,负载均衡转发请求到后端容器。在集群内部其他Pod可通过这个ClusterIP访问应用。
- 滚动更新
- 更新服务不中断,一次更新一个Pod,而不是同时删除整个服务。
- 服务编排
- 通过文件描述部署服务,使得应用程序部署变得更高效。
- 资源监控
- Node节点组件集成cAdvisor资源收集工具,可通过Heapster汇总整个集群节点资源数据,然后存储到InfluxDB时序数据库,再由Grafana展示。
- 提供认证和授权
- 支持属性访问控制(ABAC)、角色访问控制(RBAC)认证授权策略。
- Pod
- Pod是最小部署单元,一个Pod有一个或多个容器组成,Pod中容器共享存储和网络,在同一台Docker主机上运行。
- Service
- Service一个应用服务抽象,定义了Pod逻辑集合和访问这个Pod集合的策略。
- Service代理Pod集合对外表现是为一个访问入口,分配一个集群IP地址,来自这个IP的请求将负载均衡转发后端Pod中的容器。
- Service通过Lable Selector选择一组Pod提供服务。
- Volume
- 数据卷,共享Pod中容器使用的数据。
- Namespace
- 命名空间将对象逻辑上分配到不同Namespace,可以是不同的项目、用户等区分管理,并设定控制策略,从而实现多租户。命名空间也称为虚拟集群。
- Lable
- 标签用于区分对象(比如Pod、Service),键/值对存在;每个对象可以有多个标签,通过标签关联象。
- ReplicaSet
- Deployment
- StatefulSet
- DaemonSet
- Job
- minikube
Minikube是一个工具,可以在本地快速运行一个单点的Kubernetes,尝试Kubernetes或日常开发的用户使用。不能用于生产环境。
官方地址:https://kubernetes.io/docs/setup/minikube/
- kubeadm
Kubeadm也是一个工具,提供kubeadm init和kubeadm join,用于快速部署Kubernetes集群。
官方地址:https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/
- 二进制包
从官方下载发行版的二进制包,手动部署每个组件,组成Kubernetes集群。
小结:
生产环境中部署Kubernetes集群,只有Kubeadm和二进制包可选,Kubeadm降低部署门槛,但屏蔽了很多细节,遇到问题很难排查。我们这里使用二进制包部署Kubernetes集群,我也是推荐大家使用这种方式,虽然手动部署麻烦点,但学习很多工作原理,更有利于后期维护。
| 软件 | 版本 |
|---|---|
| 操作系统 | CentOS7.5_x64 |
| Docker | 18-ce |
| Kubernetes | 1.12 |
| 角色 | IP | 组件 |
|---|---|---|
| k8s-master | 192.168.31.63 | kube-apiserver,kube-controller-manager,kube-scheduler,etcd |
| k8s-node1 | 192.168.31.65 | kubelet,kube-proxy,docker,flannel,etcd |
| k8s-node2 | 192.168.31.66 | kubelet,kube-proxy,docker,flannel,etcd |
架构图
| 组件 | 证书文件 |
|---|---|
| kube-apiserver | ca.pem,ca-key.pem,server.pem,server-key.pem |
| kube-controller-manager | ca.pem,ca-key.pem |
| kube-scheduler | - |
| etcd | ca.pem,server.pem,server-key.pem |
| kubelet | ca.pem,ca-key.pem |
| kube-proxy | ca.pem,kube-proxy.pem,kube-proxy-key.pem |
| docker | |
| flannel | ca.pem,server.pem,server-key.pem |
| kubectl | ca.pem,admin.pem,admin-key.pem |
wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64 mv cfssl_linux-amd64 /usr/local/bin/cfssl mv cfssljson_linux-amd64 /usr/local/bin/cfssljson mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo生成CA证书
mkdir /opt/certificate/conf cat > /opt/certificate/conf/ca-config.json </opt/certificate/conf/ca-csr.json < 生成server证书 #注意修改机器IP(内网,外网) cat > /opt/certificate/conf/server-csr.json <生成admin证书 #创建admin相关证书 cat > /opt/certificate/conf/admin-csr.json <生成kube-proxy证书 #创建kube-proxy相关证书 cat > /opt/certificate/conf/kube-proxy-csr.json <生成metrics-server证书 cat > /opt/certificate/conf/metrics-server-csr.json < #将生成好的证书迁移到ssl目录 cd /opt/certificate/conf/ mv *.pem ../etcd部署Etcd集群以下部署步骤在规划的三个etcd节点操作一样,唯一不同的是etcd配置文件中的服务器IP要写当前的:
解压二进制包:
mkdir /root/software/etcd/conf #创建快捷方式(方便后期扩展) ln -s /root/software/etcd/ /opt/etcd wget https://github.com/etcd-io/etcd/releases/download/v3.3.13/etcd-v3.3.13-linux-amd64.tar.gz #解压 tar zxvf etcd-v3.3.13-linux-amd64.tar.gz #提出需文件-> opt/etcd/bin mv etcd-v3.3.13-linux-amd64/{etcd,etcdctl} /opt/etcd/ chmod +x etcdctl etcd创建etcd配置文件:
#注意修改机器IP,etcd只能部署单数否则无法选举 cat > /opt/etcd/conf/etcd.conf <
- ETCD_NAME 节点名称
- ETCD_DATA_DIR 数据目录
- ETCD_LISTEN_PEER_URLS 集群通信监听地址
- ETCD_LISTEN_CLIENT_URLS 客户端访问监听地址
- ETCD_INITIAL_ADVERTISE_PEER_URLS 集群通告地址
- ETCD_ADVERTISE_CLIENT_URLS 客户端通告地址
- ETCD_INITIAL_CLUSTER 集群节点地址
- ETCD_INITIAL_CLUSTER_TOKEN 集群Token
- ETCD_INITIAL_CLUSTER_STATE 加入集群的当前状态,new是新集群,existing表示加入已有集群
systemd管理etcd:
cat > /usr/lib/systemd/system/etcd.service <配置etcd环境变量:
vi /etc/profile PATH=$PATH:/disk/software/etcd source /etc/profileSSH互信:
ssh-keygen ls /root/.ssh/ ssh-copy-id -p 22 root@117.48.214.66 scpbash启动并设置开启启动:
systemctl start etcd systemctl enable etcd都部署完成后,检查etcd集群状态:
/opt/etcd/etcdctl --ca-file=/opt/certificate/ca.pem --cert-file=/opt/certificate/server.pem --key-file=/opt/certificate/server-key.pem --endpoints="https://172.16.0.6:2379" cluster-health如果输出上面信息,就说明集群部署成功。如果有问题第一步先看日志:/var/log/message 或 journalctl -u etcd
部署Flannel网络 网络术语概念
- 二层交换技术
- 工作在OSI七层网络模型的第二层,通过MAC地址进行帧转发。
- 三层交换技术
- 也称为IP交换技术,工作在OSI七层网络模型的第三层,通过IP地址进行包转发。它解决了局域网中网段划分之后,网段中子网必须依赖路由器进行管理的局面。
- 网桥(Bridge)
- 工作在OSI七层网络模型的第二层,根据MAC地址转发,类似于二层交换机。Linux网桥将不同的网络口连接起来,连接的网络接口可以来自不同的局域网,网桥决定了接收的数据包是转发给同一个局域网内主机还是别的网络上。
- VLAN( Virtual Local Area Network,虚拟局域网)
- 在物理网络(通常路由器接口)基础上建立一个或多个逻辑子网,将一个大的广播域切分若干小的广播域。一个VLAN就是一个广播域,VLAN之间通信通过三层路由器来完成。
**Overlay Network **
Overlay Network
- 覆盖网络,在基础网络上叠加的一种虚拟网络技术模式,该网络中的主机通过虚拟链路连接起来。
VXLAN
- 数据包封装到UDP中,并使用物理网络的IP/MAC作为外层报文头进行封装,然后在IP网络上传输,到达目的地后由隧道端点解封装并将数据发送给目标地址。
Flannel
- 是Overlay网络的一种,也是将源数据包封装在另外一种网络包里面进行路由转发和通讯,目前已经支持UDP、VXLAN、AWS、VPC和GCE路由等数据转发方式。
多主机容器网络通讯其他主流方案
- 隧道方案(Weave、OpenvSwith),路由方案(Calico)
工作原理:
部署配置Falnnel要用etcd存储自身一个子网信息,所以要保证能成功连接Etcd,写入预定义子网段:
#只需要在master上执行 /opt/etcd/etcdctl --ca-file=/opt/certificate/ca.pem --cert-file=/opt/certificate/server.pem --key-file=/opt/certificate/server-key.pem --endpoints="https://172.16.0.6:2379" set /coreos.com/network/config '{ "Network": "172.1.0.0/16", "Backend": {"Type": "vxlan"}}'下载二进制包:
mkdir /root/software/flannel/conf #创建快捷方式(方便后期扩展) ln -s /root/software/flannel/ /opt/flannel wget https://github.com/coreos/flannel/releases/download/v0.11.0/flannel-v0.11.0-linux-amd64.tar.gz #解压 tar zxvf flannel-v0.11.0-linux-amd64.tar.gz mv flanneld mk-docker-opts.sh /opt/flannel chmod +x flanneld mk-docker-opts.sh将主节点上的证书以及flannel传输到当前node节点
#传输目标文件必须存在 scp /opt/certificate/ root@117.48.214.66:/opt/certificate scp /opt/flannel/conf/ root@117.48.214.66:/opt/flannel/conf #如果报错 -bash: ssh-copy-id: command not found 安装客户端即可 yum -y install openssh-clients配置Flannel:
cat > /opt/flannel/conf/flanneld.conf <systemd管理Flannel:
cat > /usr/lib/systemd/system/flanneld.service <配置Docker启动指定子网段:
vi /usr/lib/systemd/system/docker.service [Service] EnvironmentFile=/run/flannel/subnet.env #注:ecStart后面加 $DOCKER_NETWORK_OPTIONS 即可 ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS重启flannel和docker:
systemctl daemon-reload systemctl start flanneld systemctl enable flanneld systemctl restart docker部署kubernetes-master 部署apiserver组件下载二进制包:
wget https://dl.k8s.io/v1.15.0-beta.2/kubernetes-server-linux-amd64.tar.gz tar zxvf kubernetes-server-linux-amd64 mkdir -p /root/software/kubernetes/{master,node} mkdir /root/software/kubernetes/master/conf mkdir /root/software/kubernetes/node/conf #提取 kubernetes-server-linux-amd64中的 kubernetes/server/bin cp kube-apiserver kube-controller-manager kube-scheduler /root/software/kubernetes/master cp kubectl kube-proxy kube-scheduler /root/software/kubernetes/node生成token:
export BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ') cat > token.csv <参数说明:
- 5f75639ff311b557134e062c48692401 随机字符串,自己可生成
- kubelet-bootstrap 用户名
- 10001 UID
- system:kubelet-bootstrap 用户组
创建apiserver配置文件:
#配置好前面生成的证书,确保能连接etcd。 cat > /opt/kubernetes/master/conf/kube-apiserver.conf <参数说明:
- –logtostderr 启用日志
- —v 日志等级
- –etcd-servers etcd集群地址
- –bind-address 监听地址
- –secure-port https安全端口
- –advertise-address 集群通告地址
- –allow-privileged 启用授权
- –service-cluster-ip-range Service虚拟IP地址段
- –enable-admission-plugins 准入控制模块
- –authorization-mode 认证授权,启用RBAC授权和节点自管理
- –enable-bootstrap-token-auth 启用TLS bootstrap功能,后面会讲到
- –token-auth-file token文件
- –service-node-port-range Service Node类型默认分配端口范围
- –requestheader-XXX、–proxy-client-XXX 是 kube-apiserver 的 aggregator layer 相关的配置参数,metrics-server & HPA 需要使用;
- –requestheader-client-ca-file:用于签名 --proxy-client-cert-file 和 --proxy-client-key-file 指定的证书;在启用了 metric aggregator 时使用;
- 如果 kube-apiserver 机器没有运行 kube-proxy,则还需要添加 --enable-aggregator-routing=true 参数
systemd管理apiserver:
cat > /usr/lib/systemd/system/kube-apiserver.service <启动:
systemctl daemon-reload systemctl enable kube-apiserver systemctl restart kube-apiserver部署controller-manager组件创建controller-manager配置文件:
cat > /opt/kubernetes/master/conf/kube-controller-manager.conf <参数说明:
- leader-elect 多个组件存在用户选举
- address 连接地址
- service-cluster 监听地址
systemd管理controller-manager组件:
cat > /usr/lib/systemd/system/kube-controller-manager.service <启动:
systemctl daemon-reload systemctl enable kube-controller-manager systemctl restart kube-controller-manager部署scheduler组件创建schduler配置文件:
cat > /opt/kubernetes/master/conf/kube-scheduler.conf <参数说明:
- –master 连接本地apiserver
- –leader-elect 当该组件启动多个时,自动选举(HA)
systemd管理schduler组件:
cat > /usr/lib/systemd/system/kube-scheduler.service <启动:
systemctl daemon-reload systemctl enable kube-scheduler systemctl restart kube-scheduler设置全局可用kubectl
vi /etc/profile #添加下面行 export PATH=/data-disk/software/kubernetes:$PATH source /etc/profile #添加命令行自动补全 source <(kubectl completion bash) echo "source <(kubectl completion bash)" >> ~/.bashrc所有组件都已经启动成功,通过kubectl工具查看当前集群组件状态:
[root@imaxun-qcloud kubernetes]# kubectl get cs NAME STATUS MESSAGE ERROR etcd-0 Healthy {"health":"true"} scheduler Healthy ok controller-manager Healthy ok部署kubernetes-node 流程概念Master apiserver启用TLS认证后,Node节点kubelet组件想要加入集群,必须使用CA签发的有效证书才能与apiserver通信,当Node节点很多时,签署证书是一件很繁琐的事情,因此有了TLS Bootstrapping机制,kubelet会以一个低权限用户自动向apiserver申请证书,kubelet的证书由apiserver动态签署。
认证大致工作流程如图所示:
kubelet-bootstrap用户绑定到系统集群角色kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap创建kubeconfig文件cd /opt/kubernetes/node/conf # 创建kubelet bootstrapping kubeconfig export BOOTSTRAP_TOKEN=5f75639ff311b557134e062c48692401 export KUBE_APISERVER="https://139.199.179.66:6443" # 设置集群参数 kubectl config set-cluster kubernetes --certificate-authority=/opt/certificate/ca.pem --embed-certs=true --server=${KUBE_APISERVER} --kubeconfig=bootstrap.kubeconfig # 设置客户端认证参数 kubectl config set-credentials kubelet-bootstrap --token=${BOOTSTRAP_TOKEN} --kubeconfig=bootstrap.kubeconfig # 设置上下文参数 kubectl config set-context default --cluster=kubernetes --user=kubelet-bootstrap --kubeconfig=bootstrap.kubeconfig # 设置默认上下文 kubectl config use-context default --kubeconfig=bootstrap.kubeconfig #---------------------- # 创建kube-proxy kubeconfig文件 kubectl config set-cluster kubernetes --certificate-authority=/opt/certificate/ca.pem --embed-certs=true --server=${KUBE_APISERVER} --kubeconfig=kube-proxy.kubeconfig kubectl config set-credentials kube-proxy --client-certificate=/opt/certificate/kube-proxy.pem --client-key=/opt/certificate/kube-proxy-key.pem --embed-certs=true --kubeconfig=kube-proxy.kubeconfig kubectl config set-context default --cluster=kubernetes --user=kube-proxy --kubeconfig=kube-proxy.kubeconfig kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig # ls bootstrap.kubeconfig kube-proxy.kubeconfig部署kubelet组件配置主机名
vi /etc/hosts #在原有配置后面添加 139.199.179.66 imaxun-qcloud imaxun-qcloud 117.48.214.66 imaxun-jdcloud imaxun-jdcloud创建kubelet配置文件:
cat > /opt/kubernetes/node/conf/kubelet.conf <参数说明:
- –hostname-override 在集群中显示的主机名
- –kubeconfig 指定kubeconfig文件位置,会自动生成
- –bootstrap-kubeconfig 指定刚才生成的bootstrap.kubeconfig文件
- –cert-dir 颁发证书存放位置
- –pod-infra-container-image 管理Pod网络的镜像
其中/opt/kubernetes/cfg/kubelet.config配置文件如下:
kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 address: 192.168.31.65 port: 10250 readOnlyPort: 10255 cgroupDriver: cgroupfs clusterDNS: ["10.0.0.2"] clusterDomain: cluster.local. failSwapOn: false authentication: anonymous: enabled: truesystemd管理kubelet组件:
cat > /usr/lib/systemd/system/kubelet.service <启动:
systemctl daemon-reload systemctl enable kubelet systemctl restart kubelet在Master审批Node加入集群:
启动后还没加入到集群中,需要手动允许该节点才可以。
在Master节点查看请求签名的Node:kubectl get csr kubectl certificate approve node-csr-Ti1zfmUCNQzWdKKWz253zuLBGh1Xq9MaM39r-7CpG6Q kubectl get node部署kube-proxy组件创建kube-proxy配置文件:
cat > /opt/kubernetes/node/conf/kube-proxy.conf << EOF KUBE_PROXY_OPTS="--logtostderr=true --v=4 --hostname-override=imaxun-qcloud --cluster-cidr=10.0.0.0/24 --kubeconfig=/opt/kubernetes/conf/node/kube-proxy.kubeconfig" EOFsystemd管理kube-proxy组件:
cat > /usr/lib/systemd/system/kube-proxy.service <启动:
systemctl daemon-reload systemctl enable kube-proxy systemctl restart kube-proxykubectl远程连接集群#设置集群项中名为kubernetes的apiserver地址与根证书 kubectl config set-cluster kubernetes --server=https://139.199.179.66 --certificate-authority=/opt/certificate/ca.pem #设置用户项中cluster-admin用户证书认证字段 kubectl config set-credentials cluster-admin --certificate=authority=/opt/certificate/ca.pem --client-key=/opt/certificate/admin-key.pem #设置环境项中名为default的默认集群和用户 kubectl config set-context defaulf --cluster=kubernetes --user=cluster-admin #设置默认环境项为default kubectl config use-context defaulfkubectl常用命令
类型 命令 描述 基础命令 create 通过文件名或标准输入创建资源 expose 将一个资源公开为一个新的Kubernetes服务 run 创建并运行一个特定的镜像,可能是副本
创建一个deployment或job管理创建的容器get 显示一个或多个资源 explain 文档参考资料 get 显示一个或多个资源 edit 使用默认的编辑器编辑一个资源 delete 通过文件名、标准输入、资源名称或标签选择器来删除资源 部署命令 rollout 管理资源的发布 rolling-update 执行指定复制控制的滚动更新 scale 扩容或缩容Pod数量,Deployment、ReplicaSet、RC或Job autoscale 创建一个自动选择扩容或缩容并设置Pod数量 集群管理命令 certificate 修改证书资源 cluster-info 显示集群信息 top 显示资源(CPU/Memory/Storage)使用。需要Heapster运行 cordon 标记节点不可调度 uncordon 标记节点可调度 drain 维护期间排除节点 taint
类型 命令 描述 故障诊断和调试命令 describe 显示特定资源或资源组的详细信息 logs 在pod或指定的资源中容器打印日志。如果pod只有一个容器,容器名称是可选的 attach 附加到一个进程到一个已经运行的容器 exec 执行命令到容器 port-forward 转发一个或多个本地端口到一个pod proxy 为kubernetes API Server启动服务代理 cp 拷贝文件或目录到容器中 auth 检查授权 高级命令 apply 通过文件名或标准输入对资源应用配置 patch 使用补丁修改、更新资源的字段 replace 通过文件名或标准输入替换一个资源 convert 不同的API版本之间转换配置文件。YAML和JSON格式都接受 设置命令 label 更新资源上的标签 annotate 在一个或多个资源上更新注释 completion 用于实现kubectl工具自动补全 其他命令 api-versions 打印受支持的API版本 config 修改kubeconfig文件(用于访问API,比如配置认证信息) help 所有命令帮助 plugin 运行一个命令行插件。 version 打印客户端和服务版本信息 示例:
# 运行应用程序 kubectl run hello-world --replicas=3 --labels="app=example" --image=nginx:1.10 --port=80 # 显示有关Deployments信息 kubectl get deployments hello-world kubectl describe deployments hello-world # 显示有关ReplicaSet信息 kubectl get replicasets kubectl describe replicasets # 创建一个Service对象暴露Deployment(在88端口负载TCP流量) kubectl expose deployment hello-world --port=88 --type=NodePort --target-port=80 --name=example-service # 创建一个Service对象暴露Deployment(在4100端口负载UDP流量) kubectl expose deployment hello-world --port=4100 --type=NodePort --protocol=udp --target-port=80 -- name=example-service # 显示有关Service信息 kubectl describe services example-service # 使用节点IP和节点端口访问应用程序 curl http://: 示例:
# 列出运行应用程序的pod kubectl get pods --selector="app=example" --output=wide # 查看pods所有标签 kubectl get pods --show-labels # 根据标签查看pods kubectl get pods -l app=example # 扩容Pod副本数 kubectl scale deployment --replicas=10 hello-world # 清理应用程序 kubectl delete services example-service kubectl delete deployment hello-world # kubectl get pods -o wide --all-namespaces #创建证书 kubectl create secret tls imaxun.com --cert=fullchain.cer --key=imaxun.com.key #修改主机名 hostnamectl set-hostname imaxun-qcloud1 #设置lb权限 kubectl label nodes imaxun-qcloud node-role.kubernetes.io/lb=lb-qcloud #创建腾讯云秘钥 kubectl create secret docker-registry qcloud --docker-server=ccr.ccs.tencentyun.com --docker-username=100001149985 --docker-password=xxx -n default --docker-server: 仓库地址 --docker-username: 仓库登陆账号 --docker-password: 仓库登陆密码 --docker-email: 邮件地址(选填) -n 命名空间 #docker 腾讯云推送镜像 docker login --username=100001149985 ccr.ccs.tencentyun.com docker tag [ImageId] ccr.ccs.tencentyun.com/imaxun/hexo:[tag] docker push ccr.ccs.tencentyun.com/imaxun/hexo:[tag]



