Docker集群编排工具之Kubernetes(K8s)介绍、安装及使用
K8s基础原理
k8s中文社区:https://www.kubernetes.org.cn/
简介
Kubernetes与较早的集群管理系统Mesos和YARN相比,对容器尤其是 Docker的支持更加原生,同时提供了更强大的机制实现资源调度,自动 管理容器生命周期,负载均衡,高可用等底层功能,使开发者可以专注于开发应用。
Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的一种机制。
K8s特性
Kubernetes是为生产环境而设计的容器调度管理系统,对于负载均衡、 服务发现、高可用、滚动升级、自动伸缩等容器云平台的功能要求有原生支持
一个K8s集群是由分布式存储(etcd)、服务节点(Minion, etcd现在称为Node)和控制节点(Master)构成的。所有的集群状态都保存在etcd中,Master节点上则运行集群的管理控制模块。Node节点是真正运行应用容器的主机节点,在每个Minion节点上都会运行一个Kubelet代理,控制该节点上的容器、镜像和存储卷等。
K8s架构图,介绍
Master(管理节点)
- API Server:供Kubernetes API接口,主要处理 Rest操作以及更新Etcd中的对象。 所有资源增删改查的唯一入口。
- Scheduler:绑定Pod到Node上,资源调度。
- Controller Manager: 所有其他群集级别的功能,目前由控制器Manager执行。资源对象的 自动化控制中心。
- Etcd:所有持久化的状态信息存储在Etcd中。
Node(计算节点)
- Kubelet:管理Pods以及容器、镜像、Volume等,实现对集群 对节点的管理
- Kube-proxy:提供网络代理以及负载均衡,实现与Service通讯。
- Docker Engine:负责节点的容器的管理工作。
API SERVER(授权)
- 只有API Server与存储通信,其他模块通过 API Server访问集群状态。
- 一个工作节点的问题不影响集群体。
- 在K8s集群中,所有的配置管理操作都声明 式而非命令式的。
- 各个模块在内存中缓存自己的相关状态以 提高系统性能。
Scheduler(资源调度)
- 负责集群的资源调度,根据特定的调度算法将pod调度到指定的minion上。
- 这部分工作分出来变成一个组件,意味着可以很方便地替换成其他的调度器。
- Scheduler调度器输入是待调度pod和可用的工作节点列表,输出则是应用调度 算法从列表中选择一个最优的用于绑定待调度的pod节点。
Controller Manager(控制管理中心)
- Controller Manager作为集群内部的管理控制中心,负责集群内的Node、Pod副本、服务端点、命名空间、服务账号、资源定额等的管理并执行自动化修复流程,确保集群处于预期的工作状态
- 在Kubernetes集群中,每个Controller就是一个操作系统,它通过API Server监控系统的共享状态,并尝试着将系统状态从“现有状态”修正到“期望状态”
POD(资源池)
- Pod是K8s集群中所有业务类型的基础
- Pod是在K8s集群中运行部署应用或服务的最小单元,它是可以支持多容器的。
- Pod的设计理念是支持多个容器在一个Pod中共享网络地址和文件系统。
- POD控制器Deployment、Job、DaemonSet和 PetSet
LABEL(标签)
- Label是一个 key=value的键值对,由用户指定,可以附加到 K8S资源之上。
- 给某个资源定义一个标签,随后可以通过label进行查询和筛选 ,类似SQL的where语句。
- Label可以给对象创建多组标签
Replication Controller,RC
- RC是K8s集群中最早的保证Pod高可用的API对象。通过监控运行中的Pod来保证集群中运行指定数目的Pod副本。
- 指定的数目可以是多个也可以是1个;少于指定数目,RC就会启动运行新的Pod副本;多于指定数目,RC就会杀死多余的Pod副本。
- 即使在指定数目为1的情况下,通过RC运行Pod也比直接运行Pod更明智,因为RC也可以发挥它高可用的能力,保证永远有1个Pod在运行。
PC总结
- RC里包括完整的POD定义模板
- RC通过Label Selector(标签选择器)机制实现对POD副本的自动控制。
- 通过改变RC里的POD副本以实现POD的扩容和缩容
- 通过改变RC里POD模块中的镜像版本,可以实现POD的滚动升级。
K8s组件
K8s安装配置
K8s安装方法
yum安装 1.5.2
二进制安装
kubeadm安装(官方) 需要梯子,全部容器化
minkube安装
编译安装
自动化安装
K8s资源
官网 kubernetes.io
中文社区 https://www.kubernetes.org.cn/
Github https://github.com/kubernetes/kubernetes
命令行参考 https://kubernetes.io/docs/reference/generated/kub ectl/kubectl-commands#
K8s的安装环境要求
1、linux 内核3.10以上
2、64位系统
3、内存4G
4、安装epel
5、安装docker
6、开启yum cache保存安装RPM包
K8s中有三种类型的ip
物理ip(宿主机ip)
集群ip(cluster ip):10.254.0.0/16
pod(容器的ip):172.16.0.0/16
K8s安装与使用
安装
环境:三台机器,两个node(计算节点),一个主节点(master)
yum源需要:repo:CentOS-Base.repo docker1.12
主节点(master)
主机名:K8s-master ip:10.0.0.11 系统:centos7.2
yum install etcd -y yum install docker -y yum install kubernetes -y yum install flannel -y
计算节点(node)
K8s-node-1 10.0.0.12 centos7.2
K8s-node-2 10.0.0.13 centos7.2
yum install docker -y yum install kubernetes -y yum install flannel -y
在master节点上
修改配置
修改etcd配置文件
[root@k8s-master ~]# vim /etc/etcd/etcd.conf ETCD_NAME="default" ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379" ETCD_ADVERTISE_CLIENT_URLS="http://10.0.0.11:2379"
启动
systemctl enable etcd.service
systemctl start etcd.service
检查
[root@k8s-master ~]# etcdctl -C http://10.0.0.11:2379 cluster-health member 8e9e05c52164694d is healthy: got healthy result from http://10.0.0.11:2379 cluster is healthy
修改/etc/kubernetes/apiserver
vim /etc/kubernetes/apiserver 8 KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0" 11 KUBE_API_PORT="--port=8080" 17 KUBE_ETCD_SERVERS="--etcd-servers=http://10.0.0.11:2379" 23 KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"
修改/etc/kubernetes/config
vim /etc/kubernetes/config 22 KUBE_MASTER="--master=http://10.0.0.11:8080"
启动
systemctl enable kube-apiserver.service systemctl start kube-apiserver.service systemctl enable kube-controller-manager.service systemctl start kube-controller-manager.service systemctl enable kube-scheduler.service systemctl start kube-scheduler.service
查看是否启动成功
systemctl status kube-apiserver.service kube-controller-manager.service kube-scheduler.service
在node节点
vim /etc/kubernetes/config KUBE_MASTER="--master=http://10.0.0.11:8080"
node-1
vim /etc/kubernetes/kubelet KUBELET_ADDRESS="--address=0.0.0.0" KUBELET_HOSTNAME="--hostname-override=10.0.0.12" KUBELET_API_SERVER="--api-servers=http://10.0.0.11:8080"
node-2
vim /etc/kubernetes/kubelet KUBELET_ADDRESS="--address=0.0.0.0" KUBELET_HOSTNAME="--hostname-override=10.0.0.13" KUBELET_API_SERVER="--api-servers=http://10.0.0.11:8080"
启动检查
systemctl enable kubelet.service systemctl start kubelet.service systemctl enable kube-proxy.service systemctl start kube-proxy.service
检查:
[root@k8s-master ~]# kubectl get nodes NAME STATUS AGE 10.0.0.12 Ready 3m 10.0.0.13 Ready 3m
配置flannel网络
修改配置文件
master、node上均编辑/etc/sysconfig/flanneld
vim /etc/sysconfig/flanneld FLANNEL_ETCD_ENDPOINTS="http://10.0.0.11:2379"
配置flannel的网络范围
etcdctl mk /atomic.io/network/config '{ "Network": "172.16.0.0/16" }'
实操:
[root@k8s-master ~]# etcdctl mk /atomic.io/network/config '{ "Network": "172.16.0.0/16" }' { "Network": "172.16.0.0/16" }
启动
在master执行:
systemctl enable flanneld.service systemctl start flanneld.service service docker restart systemctl restart kube-apiserver.service systemctl restart kube-controller-manager.service systemctl restart kube-scheduler.service
在node上执行:
systemctl enable flanneld.service
systemctl start flanneld.service
service docker restart
systemctl restart kubelet.service
systemctl restart kube-proxy.service
K8s常见命令操作
命令:kubectl create -f hello.yaml
文件内容:
[root@k8s-master ~]# vim hello.yaml apiVersion: v1 kind: Pod metadata: name: hello-world spec: restartPolicy: Never containers: - name: hello image: "docker.io/busybox:latest" command: ["/bin/echo","hello”,”world"]
实操:
[root@k8s-master ~]# kubectl create -f hello.yaml pod "hello-world" created kubectl get pods 查看默认name信息 kubectl describe pods hello-world 查看hello-world的详细信息 kubectl delete pods hello-world 删除名叫hello-world kubectl replace -f nginx-rc.yaml 对已有资源进行更新、替换 kubectl edit rc nginx 对现有资源直接进行修改,立即生效 kubectl logs nginx-gt1jd 查看访问日志
存在的坑
因为没有证书,拉取图像失败。
[root@k8s-master ~]# kubectl describe pods hello-world Name: hello-world Namespace: default Node: 10.0.0.13/10.0.0.13 Start Time: Fri, 02 Feb 2018 19:28:31 +0800 Labels: <none> Status: Pending IP: Controllers: <none> Containers: hello: Container ID: Image: docker.io/busybox:latest Image ID: Port: Command: /bin/echo hello”,”world State: Waiting Reason: ContainerCreating Ready: False Restart Count: 0 Volume Mounts: <none> Environment Variables: <none> Conditions: Type Status Initialized True Ready False PodScheduled True No volumes. QoS Class: BestEffort Tolerations: <none> Events: FirstSeen LastSeen Count From SubObjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 4m 4m 1 {default-scheduler } Normal Scheduled Successfully assigned hello-world to 10.0.0.13 4m 1m 5 {kubelet 10.0.0.13} Warning FailedSync Error syncing pod, skipping: failed to "StartContainer" for "POD" with ErrImagePull: "image pull failed for registry.access.redhat.com/rhel7/pod-infrastructure:latest, this may be because there are no credentials on this request. details: (open /etc/docker/certs.d/registry.access.redhat.com/redhat-ca.crt: no such file or directory)" 3m 5s 16 {kubelet 10.0.0.13} Warning FailedSync Error syncing pod, skipping: failed to "StartContainer" for "POD" with ImagePullBackOff: "Back-off pulling image \"registry.access.redhat.com/rhel7/pod-infrastructure:latest\""
解决:yum install python-rhsm* -y
创建:
[root@k8s-master ~]# kubectl create -f nginx.yaml pod "hello-nginx" created
检查是否成功
[root@k8s-master ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE hello-nginx 1/1 Running 0 2h 172.16.42.2 10.0.0.13
RC:保证高可用
- RC是K8s集群中最早的保证Pod高可用的API对象。通过监控运行中的Pod来保证集群中运行指定数目的Pod副本。
- 指定的数目可以是多个也可以是1个;少于指定数目,RC就会启动运行新的Pod副本;多于指定数目,RC就会杀死多余的Pod副本。
- 即使在指定数目为1的情况下,通过RC运行Pod也比直接运行Pod更明智,因为RC也可以发挥它高可用的能力,保证永远有1个Pod在运行。
始终保持一个在活着
rc版yaml编写:
[root@k8s-master ~]# cat nginx-rc.yaml apiVersion: v1 kind: ReplicationController metadata: name: nginx spec: replicas: 1 selector: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80
启动rc版容器
[root@k8s-master ~]# kubectl create -f nginx-rc.yaml replicationcontroller "nginx" created
检查:
[root@k8s-master ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE nginx-gt1jd 1/1 Running 0 2m 172.16.79.2 10.0.0.12
这样的话就算删除了这个容器RC也会立马在起一个
版本升级
[root@k8s-master ~]# cat web-rc2.yaml apiVersion: v1 kind: ReplicationController metadata: name: myweb-2 spec: replicas: 2 selector: app: myweb-2 template: metadata: labels: app: myweb-2 spec: containers: - name: myweb-2 image: kubeguide/tomcat-app:v2 ports: - containerPort: 8080 env: - name: MYSQL_SERVICE_HOST value: 'mysql' - name: MYSQL_SERVICE_PORT value: '3306'
升级操作:
[root@k8s-master ~]# kubectl rolling-update myweb -f web-rc2.yaml Created myweb-2 Scaling up myweb-2 from 0 to 2, scaling down myweb from 2 to 0 (keep 2 pods available, don't exceed 3 pods) Scaling myweb-2 up to 1 Scaling myweb down to 1 Scaling myweb-2 up to 2 Scaling myweb down to 0 Update succeeded. Deleting myweb replicationcontroller "myweb" rolling updated to "myweb-2"
升级过程
[root@k8s-master ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE myweb-2-mmlcm 1/1 Running 0 32s 172.16.42.3 10.0.0.13 myweb-71438 1/1 Running 0 2m 172.16.42.2 10.0.0.13 myweb-cx9j2 1/1 Running 0 2m 172.16.79.3 10.0.0.12 nginx-gt1jd 1/1 Running 0 1h 172.16.79.2 10.0.0.12 [root@k8s-master ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE myweb-2-0kmzf 1/1 Running 0 7s 172.16.79.4 10.0.0.12 myweb-2-mmlcm 1/1 Running 0 1m 172.16.42.3 10.0.0.13 myweb-cx9j2 1/1 Running 0 2m 172.16.79.3 10.0.0.12 nginx-gt1jd 1/1 Running 0 1h 172.16.79.2 10.0.0.12
回滚
[root@k8s-master ~]# cat web-rc.yaml apiVersion: v1 kind: ReplicationController metadata: name: myweb spec: replicas: 2 selector: app: myweb template: metadata: labels: app: myweb spec: containers: - name: myweb image: kubeguide/tomcat-app:v1 ports: - containerPort: 8080 env: - name: MYSQL_SERVICE_HOST value: 'mysql' - name: MYSQL_SERVICE_PORT value: '3306'
操作:
[root@k8s-master ~]# kubectl rolling-update myweb-2 -f web-rc.yaml Created myweb Scaling up myweb from 0 to 2, scaling down myweb-2 from 2 to 0 (keep 2 pods available, don't exceed 3 pods) Scaling myweb up to 1 Scaling myweb-2 down to 1 Scaling myweb up to 2 Scaling myweb-2 down to 0 Update succeeded. Deleting myweb-2 replicationcontroller "myweb-2" rolling updated to "myweb"
检查
[root@k8s-master ~]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE myweb-mbndc 1/1 Running 0 1m 172.16.79.3 10.0.0.12 myweb-qh38r 1/1 Running 0 2m 172.16.42.2 10.0.0.13 nginx-gt1jd 1/1 Running 0 1h 172.16.79.2 10.0.0.12
svc设置
[root@k8s-master ~]# cat web-svc.yaml apiVersion: v1 kind: Service metadata: name: myweb spec: type: NodePort ports: - port: 8080 nodePort: 30001 selector: app: myweb
[root@k8s-master ~]# kubectl create -f web-svc.yaml
[root@k8s-master ~]# kubectl get svc NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes 10.254.0.1 <none> 443/TCP 6h myweb 10.254.91.34 <nodes> 8080:30001/TCP 1m
然后取node节点检查30001端口是否启动
然后浏览器web访问node节点的ip:30001进行测试
web界面管理
[root@k8s-master ~]# cat dashboard.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: # Keep the name in sync with image version and # gce/coreos/kube-manifests/addons/dashboard counterparts name: kubernetes-dashboard-latest namespace: kube-system spec: replicas: 1 template: metadata: labels: k8s-app: kubernetes-dashboard version: latest kubernetes.io/cluster-service: "true" spec: containers: - name: kubernetes-dashboard image: index.tenxcloud.com/google_containers/kubernetes-dashboard-amd64:v1.4.1 resources: # keep request = limit to keep this container in guaranteed class limits: cpu: 100m memory: 50Mi requests: cpu: 100m memory: 50Mi ports: - containerPort: 9090 args: - --apiserver-host=http://10.0.0.11:8080 livenessProbe: httpGet: path: / port: 9090 initialDelaySeconds: 30 timeoutSeconds: 30
操作:
[root@k8s-master ~]# cat dashboard-svc.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
启动:
kubectl create -f dashboard.yaml
kubectl create -f dashboard-svc.yaml
然后访问:http://10.0.0.11:8080/ui/