Kubernetes食用指南_k8s

Kubernetes食用简介

Kubernetes是Google在2014年6月开源的一个容器集群管理系统,使用Go语言开发,Kubernetes也叫K8S。K8S是Google内部一个叫Borg的容器集群管理系统衍生出来的,Borg已经在Google大规模生产运行十年之久。

K8S主要用于自动化部署、扩展和管理容器应用,提供了资源调度、部署管理、服务发现、扩容缩容、监控等一整套功能;2015年7月,Kubernetes v1.0正式发布,截止到2018年8月2日最新稳定版本是​​v1.15.1​​​,最新稳定版本是​​v1.16.0-alpha.2​​,Kubernetes目标是让部署容器化应用简单高效。

官方网站:​​https://kubernetes.io​

Kubernetes主要功效

  • 数据卷
  • Pod中容器之间共享数据,可以使用数据卷;
  • 应用程序健康检
  • 查容器内服务可能进程堵塞无法处理请求,可以设置监控检查策略保证应用健壮性;
  • 复制应用程序实例
  • 控制器维护着Pod副本数量,保证一个Pod或一组同类的Pod数量始终可用;
  • 弹性伸缩
  • 根据设定的指标(CPU利用率)自动缩放Pod副本数;
  • 服务发现
  • 使用环境变量或DNS服务插件保证容器中程序发现Pod入口访问地址;
  • 负载均衡
  • 一组Pod副本分配一个私有的集群IP地址,负载均衡转发请求到后端容器,在集群内部其他Pod可通过这个ClusterIP访问应用;
  • 滚动更新
  • 更新服务不中断,一次更新一个Pod,而不是同时删除整个服务;
  • 服务编排
  • 通过文件描述部署服务,使得应用程序部署变得更高效;
  • 资源监控
  • Node节点组件集成cAdvisor资源收集工具,可通过Heapster汇总整个集群节点资源数据,然后存储到InfluxDB时序数据库,再由Grafana展示;
  • 提供认证和授权
  • 支持属性访问控制(ABAC)、角色访问控制(RBAC)认证授权策略;

Kubernetes基本对象概念

  • PodPod
  • 是最小部署单元,一个Pod有一个或多个容器组成,Pod中容器共享存储和网络,在同一台Docker主机上运行;
  • Service
  • Service一个应用服务抽象,定义了Pod逻辑集合和访问这个Pod集合的策略,Service代理Pod集合对外表现是为一个访问入口,分配一个集群IP地址,来自这个IP的请求将负载均衡转发后端Pod中的容器,Service通过Lable Selector选择一组Pod提供服务;
  • Volume
  • 数据卷,共享Pod中容器使用的数据;
  • Namespace
  • 命名空间将对象逻辑上分配到不同Namespace,可以是不同的项目、用户等区分管理,并设定控制策略,从而实现多租户;命名空间也称为虚拟集群;
  • Lable
  • 标签用于区分对象(比如Pod、Service),键/值对存在,每个对象可以有多个标签,通过标签关联对象;
  • ReplicaSet
  • 下一代Replication Controller;确保任何给定时间指定的Pod副本数量,并提供声明式更新等功能;RC与RS唯一区别就是lable selector支持不同,RS支持新的基于集合的标签,RC仅支持基于等式的标签;
  • Deployment
  • Deployment是一个更高层次的API对象,它管理ReplicaSets和Pod,并提供声明式更新等功能,官方建议使用Deployment管理ReplicaSets,而不是直接使用ReplicaSets,这就意味着可能永远不需要直接操作ReplicaSet对象;
  • Stateful
  • SetStatefulSet适合持久性的应用程序,有唯一的网络标识符(IP),持久存储,有序的部署、扩展、删除和滚动更新;
  • DaemonSet
  • DaemonSet确保所有(或一些)节点运行同一个Pod;当节点加入Kubernetes集群中,Pod会被调度到该节点上运行,当节点从集群中移除时,DaemonSet的Pod会被删除;删除DaemonSet会清理它所有创建的Pod;
  • Job
  • 一次性任务,运行完成后Pod销毁,不再重新启动新容器,还可以任务定时运行;

Kubernetes食用指南_k8s_02

Kubernetes成分

Master组件:

kube-apiserver
Kubernetes API,集群的统一入口,各组件协调者,以HTTP API提供接口服务,所有对象资源的增删改查和监听操作都交给APIServer处理后再提交给Etcd存储;


kube-controller-manager
处理集群中常规后台任务,一个资源对应一个控制器,而ControllerManager就是负责管理这些控制器的;


kube-scheduler
根据调度算法为新创建的Pod选择一个Node节点;

Node组件:

kubelet
kubelet是Master在Node节点上的Agent,管理本机运行容器的生命周期,比如创建容器、Pod挂载数据卷、下载secret、获取容器和节点状态等工作,kubelet将每个Pod转换成一组容器;


kube-proxy
在Node节点上实现Pod网络代理,维护网络规则和四层负载均衡工作;


docker或rocket/rkt
运行容器;

第三方服务:

etcd

分布式键值存储系统;用于保持集群状态,比如Pod、Service等对象信息;

非必要组件:

kube-dns
负责为整个集群提供DNS服务


Ingress Controller
为服务提供外网入口


Heapster
提供资源监控


Dashboard
提供GUI


Federation
提供跨可用区的集群


Fluentd-elasticsearch
提供集群日志采集、存储与查询

Kubernetes食用指南_Kubernetes_03

Kubernetes食用配方

角色

IP

组件

master

192.168.0.201

etcd

kube-apiserver

kube-controller-manager

kube-scheduler

node01

192.168.0.202

kubelet

kube-proxy

docker

node02

192.168.0.203

kubelet

kube-proxy

docker

Pod 网络

10.244.0.0/16


Service 网络

10.96.0.0/12


  1. 获取 yum 源
  2. 安装 Docker、Kubelet、Kubeadm、Kubectl 到所有节点上
  3. Master节点初始化
  4. Flannel安装
  5. 节点加入

获取 yum 源

#进入 yum 的 repo 目录
cd /etc/yum.repos.d/
#获取 Docker 的 yum 源
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

#编写 Kubernetes 的 yum 源
vim /etc/yum.repos.d/kubernetes.repo
[Kubernetes]
name=Kubernetes Repo
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
enabled=1

#检测 yum 源的可用性
yum repolist

安装 Docker、Kubelet、Kubeadm、Kubectl 到所有节点上

#yum 安装所需部件
yum -y install docker-ce kubelet kubeadm kubectl

#启动 Docker 服务
systemctl start docker

#设置开机自启
systemctl enable docker
systemctl enable kubelet

注意:在启动 Docker 前,由于某种不可抗力和不可描述的原因,建议国内的程序猿修改HttpsProxy的参数,具体如下:

vim /usr/lib/systemd/system/docker.service 
Environment="HTTPS_PROXY=http://www.ik8s.io:10080"
Environment="NO_PROXY=127.0.0.0/8,192.168.0.0/24"

systemctl daemon-reload
systemctl restart docker
docker info

Kubernetes食用指南_Kubernetes_04

#检查bridge-nf
cat /proc/sys/net/bridge/bridge-nf-call-ip6tables
1
cat /proc/sys/net/bridge/bridge-nf-call-iptables
1

Master节点初始化

#配置kubelet文件,使其忽略 Swap 的报错
vim /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--fail-swap-on=false"

kubeadm init --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --ignore-preflight-errors=Swap

Kubernetes食用指南_k8s_05

#根据初始化完成后所给的提示进行设置(建议创建普通用户进行操作)
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

#查看集群健康状态
kubectl get cs
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health":"true"}

#查看集群节点信息
kubectl get node
NAME STATUS ROLES AGE VERSION
centos701.if010.com NotReady master 9m52s v1.15.2
#查看 docker 容器
docker ps

Kubernetes食用指南_docker_06

#查看 docker 镜像
docker images

Kubernetes食用指南_Kubernetes_07

信息:节点状态之所以显示 NoReady 是应为还没有安装flannel;

Flannel安装

#自动拉取镜像启动
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

#查看 Pods 网络信息
kubectl get pods -n kube-system -o wide

#查看节点状态是否为 Ready 状态
kubectl get node
NAME STATUS ROLES AGE VERSION
centos701.if010.com Ready master 27m v1.15.2

节点加入集群

#加入集群
kubeadm join [MastertIP地址]:6443 --token [token值] --discovery-token-ca-cert-hash [证书哈希值] --ignore-preflight-errors=Swap

#主节点上获取节点信息
kubectl get node
NAME STATUS ROLES AGE VERSION
centos701.if010.com Ready master 15h v1.15.2
centos702.if010.com Ready <none> 15h v1.15.2
centos703.if010.com Ready <none> 15h v1.15.2

信息:token值和证书哈希值在初始化集群的时候有提供;

Dashboard可视化插件

#下载yaml文件到本地
wget https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml

#修改yaml文件,使其外网能访问
vim kubernetes-dashboard.yaml
......
---
# ------------------- Dashboard Service ------------------- #

kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
type: NodePort #增加type: NodePort
ports:
- port: 443
targetPort: 8443
nodePort: 31620 #增加nodePort: 31620
selector:
k8s-app: kubernetes-dashboard

#修改配置从阿里云仓库拉取镜像
vim kubernetes-dashboard.yaml
......
containers:
- name: kubernetes-dashboard
#image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1
image: registry.cn-hangzhou.aliyuncs.com/google_containers/kubernetes-dashboard-amd64:v1.10.1
ports:
......

#执行部署dashboard服务
kubectl create -f kubernetes-dashboard.yaml

信息:查看Pod的状态为running说明dashboard已经部署成功

kubectl get pod --namespace=kube-system -o wide | grep dashboard

信息:Dashboard 会在 kube-system namespace 中创建自己的 Deployment 和 Service

kubectl get deployment kubernetes-dashboard --namespace=kube-system

kubectl get service kubernetes-dashboard --namespace=kube-system

Kubernetes食用指南_docker_08

访问 ​​https://[host_ip]:31620/#!/login​

Kubernetes食用指南_Kubernetes_09

#创建dashboard-adminuser.yaml,获取 Token
vim dashboard-adminuser.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kube-system
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kube-system

#执行yaml文件
kubectl create -f dashboard-adminuser.yaml

#查看admin-user账户的token
kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep admin-user | awk '{print $1}')

Kubernetes食用指南_docker_10

使用获取到的 Token 值登陆 Dashboard 面板

Kubernetes食用指南_docker_11

Kubernetes食用指南_docker_12

Kubernetes食用方式

#查询节点信息
kubectl describe node [节点名称]

#查看集群信息
kubectl cluster-info

#查看创建了的 Pods
kubectl get pods -o wide

#查看创建了的 Services
kubectl get services -o wide

#查看 Pod 的网络信息
kubectl describe pods [Pod名称]

#查看 Pod 的网络信息
kubectl describe service [Pod名称]
#运行Pod
kubectl run NAME --image=image [--env="key=value"] [--port=port] [--replicas=replicas] [--dry-run=bool] [--overrides=inline-json] [--command] -- [COMMAND] [args...] [options]
#栗子:
运行 Nginx
kubectl run nginx --image=nginx:1.14 --port=80 --replicas=1
运行 Busybox
kubectl run client --image=busybox --replicas=1 -it --restart=Never

--image 指定所需食用的镜像

--port 指定暴露的端口

--replicas 指定创建的个数

#删除 Pod
kubectl delete ([-f FILENAME] | [-k DIRECTORY] | TYPE [(NAME | -l label | --all)])
#栗子:
kubectl delete pods nginx-7c45b84548-7bnr6

TYPE 指定删除的是什么类型,如 services,pods

NAME 指定名称

-l 指定标签

#创建 service
kubectl expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP|SCTP] [--target-port=number-or-name] [--name=name] [--external-ip=external-ip-of-service] [--type=type] [options]
#栗子:
kubectl expose deployment nginx --name=nginx-service --port=8081 --target-port=80 --protocol=TCP

deployment 指定 deployment pod 的名称

--name services的名称

--port 对外的端口

--target-port 对内的端口(pod 暴露的端口)

--protocol 指定协议

#扩展/缩减 pod的数量
kubectl scale [--resource-version=version] [--current-replicas=count] --replicas=COUNT (-f FILENAME | TYPE NAME)
#栗子:
kubectl scale --replicas=0 deployment myapp

--replicas 指定数量

#滚动升级
kubectl set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1
#栗子:
kubectl set image deployment nginx-web nginx-web=nginx:1.10

#回滚到上一版本
kubectl rollout undo deployment [Pod名称]
#查看状态
kubectl rollout status deployment nginx-web

CONTAINER_NAME_1 pod的名称

CONTAINER_IMAGE_1 升级到那个镜像

#添加标签
kubectl label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]
#栗子:
kubectl label pods test-pod release=canary

TYPE 指定类型,如:svc,pods

NAME 指定名称

KEY 指定键值

VAL 指定标签值

信息:get信息时可以添加--show-labels查看标签