kubernetes 入门学习

kubernetes 学习

kubernetes 简介

Kubernetes这个名字源自希腊语,意思是“舵手”,也是“管理者”,“治理者”等词的源头。k8s是Kubernetes的简称(用数字『8』替代中间的8个字母『ubernete』)。

Kubernetes不是PaaS(平台即服务)。

  • Kubernetes并不对支持的应用程序类型有任何限制。 它并不指定应用框架,限制语言类型,也不仅仅迎合 12-factor应用程序模式. Kubernetes旨在支持各种多种多样的负载类型:只要一个程序能够在容器中运行,它就可以在Kubernetes中运行。
  • Kubernetes并不关注代码到镜像领域。它并不负责应用程序的构建。不同的用户和项目对持续集成流程都有不同的需求和偏好,所以我们分层支持持续集成但并不规定和限制它的工作方式。
  • 另一方面, 确实有不少PaaS系统运行在Kubernetes之上,比如Openshift和Deis。同样你也可以将定制的PaaS系统,结合一个持续集成系统再Kubernetes上进行实施:只需生成容器镜像并通过Kubernetes部署。
  • 由于Kubernetes运行再应用层而不是硬件层,所以它提供了一些一般PaaS提供的功能,比如部署,扩容,负载均衡,日志,监控,等等。无论如何,Kubernetes不是一个单一应用,所以这些解决方案都是可选可插拔的。

Kubernetes并不是单单的"编排系统";它排除了对编排的需要:+

  • “编排”的技术定义为按照指定流程执行一系列动作:执行A,然后B,然后C。相反,Kubernetes有一系列控制进程组成,持续地控制从当前状态到指定状态的流转。无需关注你是如何从A到C:只需结果如此。这样将使得系统更加易用,强大,健壮和弹性。

kubernetes组件介绍

kube抽象层

  • Label(标签):给容器打标签。
  • Pod:包含一组容器和卷。同一个Pod里的容器共享同一个网络命名空间,可以使用localhost互相通信。Pod是短暂的,不是持续性实体。
  • Service(服务):提供前端容器正确可靠地指向后台容器。Service是定义一系列Pod以及访问这些Pod的策略的一层抽象。Service通过Label找到Pod组。因为Service是抽象的,所以在图表里通常看不到它们的存在。

kubernetes 集群中的机器划分为一个master节点和一群工作节点(node)

其中kube master通过以下服务,对整个集群的资源管理、pod调度、弹性伸缩、安全控制、系统监控和纠错进行管理。

  • kube-apiserver kubernetes的API服务器
  • kube-scheduer:kubernetes调度器,容器的启动、迁移、扩容缩减时候,选择哪个node,就看它了。
  • Replication Controller(复制控制器): 确保任意时间都有指定数量的Pod“副本”在运行。

kube node 为集群的工作节点,以下服务对pod的创建、启动、监控、重启、销毁以及实现软件模式的负载均衡器。

  • Container(容器):实际的docker容器。
  • kubelet:负责node的管理,基本所有操作都靠它。
  • kube-controller-manager:kubernetes对node的控制行为,比如怎么去调用node启动一个容器。
  • kube-proxy:每个node里的container都在一个私有网络中,kube-proxy的作用就是做一个反向代理,让访问者访问这个node的时候,可以转发到内部对应的container。

从这里我们能够识别出三个“网络”:

node network:承载kubernetes集群中各个“物理”Node(master和minion)通信的网络;
service network:由kubernetes集群中的Services所组成的“网络”;
flannel network: 即Pod网络,集群中承载各个Pod相互通信的网络。
node network自不必多说,node间通过你的本地局域网(无论是物理的还是虚拟的)通信。

service network比较特殊,每个新创建的service会被分配一个service IP,在当前集群中,这个IP的分配范围是192.168.3.0/24。不过这个IP并不“真实”,更像一个“占位符”并且只有入口流量,所谓的“network”也是“名不符实”的,后续我们会详尽说明。

flannel network是我们要理解的重点,cluster中各个Pod要实现相互通信,必须走这个网络,无论是在同一node上的Pod还是跨node的Pod。我们的cluster中,flannel net的分配范围是:172.16.0.0/16。

实战

服务器规划

服务器名称 服务器IP 安装的软件 角色
linux-node2 192.168.56.12 kube-apiserverkube-controller-managerkube-scheduleretcd master
linux-node3 192.168.56.13 kubeletproxydocker node

配置推荐

软硬件 最低配置 推荐配置
CPU和内存 Master:至少1core和2G内存。 Node:至少1core和2G内存 Master:2core和4G内存 Node:由于要运行Docker,所以根据需要进行调整
Docker 1.9版本及以上 1.12版本
ETCD 2.0版本及以上 3.0版本

配置镜像

cat >/etc/yum.repos.d/virt7-docker-common-release.repo<<EOF
[virt7-docker-common-release]
name=virt7-docker-common-release
baseurl=http://cbs.centos.org/repos/virt7-docker-common-release/x86_64/os/
gpgcheck=0
EOF
cat >> /etc/yum.repos.d/kubernetes.repo <<EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
EOF

配置域名解析

cat >>/etc/hosts <<EOF
192.168.56.12 linux-node2
192.168.56.13 linux-node3
EOF

安装桥接工具

yum install bridge-utils -y 

配置Limitations

cat >/etc/sysctl.d/k8s.conf<<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl -p /etc/sysctl.d/k8s.conf

安装并配置etcd

yum install etcd -y
egrep -v "#|^$" /etc/etcd/etcd.conf 
ETCD_NAME=default
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://0.0.0.0:2379"
  • ETCD_NAME:etcd的名称 .
  • ETCD_DATA_DIR :etcd的数据目录.
  • ETCD_LISTEN_CLIENT_URLS :客户端连接端口.
  • ETCD_ADVERTISE_CLIENT_URLS: 分布式连接端口.

启动etcd

systemctl enable etcd
systemctl start etcd

检查etcd是否可用

etcdctl cluster-health

设置一个kv,给kubernetes使用。

shell> etcdctl mkdir /biglittleant.cn/network
shell > etcdctl mk /biglittleant.cn/network/config '{ "Network": "10.10.0.0/16", "SubnetLen": 24, "Backend": { "Type": "vxlan" } }'        

# { "Network": "10.10.0.0/16", "SubnetLen": 24, "Backend": { "Type": "vxlan" } }
shell> etcdctl -o extended get /biglittleant.cn/network/config
Key: /biglittleant.cn/network/config
Created-Index: 293299
Modified-Index: 293299
TTL: 0
Index: 293319

{ "Network": "10.10.0.0/16" }

安装配置 master 节点

yum install kubernetes-master flannel docker -y 
egrep -v "#|^$" /etc/kubernetes/apiserver 
KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"
KUBE_API_PORT="--port=8080"
KUBELET_PORT="--kubelet-port=10250"
KUBE_ETCD_SERVERS="--etcd-servers=http://192.168.56.12:2379"
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"
KUBE_API_ARGS=""
  • --insecure-bind-address:api监听地址.
  • --insecure-port:api监听端口.
  • --service-cluster-ip-range:上面说到service角色是定义集群中一个pod集合,这个pod中容器提供一种服务,当创建service时会分配一个CLUSTER_IP提供统一的访问入口,那么,这个选项就是指定分配的IP范围.以CIDI格式表示,例如:192.168.0.0/16,该IP范围不能与物理机的真实IP段有重合。
  • --etcd_servers:指定etcd连接地址.
  • --admission-control 中删除,ServiceAccount. kubernetes集群的准入控制设置,各控制模块以插件的形式依次生效。
  • --service-node-prot-range: kubernetes集群中Server可映射的物理机端口号范围,默认为3000~32767
  • --log-dir=/var/log/kubernetes --v:日志级别 定义日志位置及日志级别。
egrep -v "#|^$" /etc/kubernetes/controller-manager 
KUBE_CONTROLLER_MANAGER_ARGS="--node-monitor-grace-period=10s --pod-eviction-timeout=10s"

cotroller 依赖于apiserver

egrep -v "#|^$" /etc/kubernetes/config           
KUBE_LOGTOSTDERR="--logtostderr=true"
KUBE_LOG_LEVEL="--v=0"
KUBE_ALLOW_PRIV="--allow-privileged=false"
KUBE_MASTER="--master=http://192.168.56.12:8080"

config依赖于apiserver服务

  • --master=http://192.168.56.12:8080 api的URL
  • --logtostderr=false 设置为false表示将日志写入文件,不写入stdeer。
  • --log-dir=/var/log/kubernetes 日志目录。
  • --v = 2 日志级别。

启动服务

systemctl enable kube-apiserver kube-scheduler kube-controller-manager
systemctl start kube-apiserver kube-scheduler kube-controller-manager

检查服务器端是否正常启动

ss -lntup |egrep "kube|etcd"
tcp    LISTEN     0      128            127.0.0.1:2380                  *:*      users:(("etcd",3143,5))
tcp    LISTEN     0      128                   :::6443                 :::*      users:(("kube-apiserver",3290,50))
tcp    LISTEN     0      128                   :::10251                :::*      users:(("kube-scheduler",3295,7))
tcp    LISTEN     0      128                   :::2379                 :::*      users:(("etcd",3143,6))
tcp    LISTEN     0      128                   :::10252                :::*      users:(("kube-controller",3291,5))
tcp    LISTEN     0      128                   :::8080                 :::*      users:(("kube-apiserver",3290,51))

配置 flannel网络

egrep -v "#|^$" /etc/sysconfig/flanneld    
FLANNEL_ETCD_ENDPOINTS="http://192.168.56.12:2379"
FLANNEL_ETCD_PREFIX="/biglittleant.cn/network"
systemctl enable flanneld
systemctl restart flanneld docker

安装配置 node 节点

yum install kubernetes-node flannel docker -y
egrep -v "#|^$" /etc/kubernetes/config 
KUBE_LOGTOSTDERR="--logtostderr=true"
KUBE_LOG_LEVEL="--v=0"
KUBE_ALLOW_PRIV="--allow-privileged=false"
KUBE_MASTER="--master=http://192.168.56.12:8080"
egrep -v "#|^$" /etc/kubernetes/kubelet 
KUBELET_ADDRESS="--address=0.0.0.0"
KUBELET_PORT="--port=10250"
KUBELET_HOSTNAME="--hostname-override=192.168.56.13"
KUBELET_API_SERVER="--api-servers=http://192.168.56.12:8080"
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"
KUBELET_ARGS=""

kubelet 依赖于docker

  • --api-servers:指定apiserver的URL,可以指定多个。
  • --hostname-override:设置本node的名称。
  • --logtostderr=false 设置为false表示将日志写入文件,不写入stdeer。
  • --log-dir=/var/log/kubernetes 日志目录。
  • --v = 2 日志级别。
systemctl enable kubelet kube-proxy
systemctl start kubelet kube-proxy
egrep -v "#|^$" /etc/sysconfig/flanneld    
FLANNEL_ETCD_ENDPOINTS="http://192.168.56.12:2379"
FLANNEL_ETCD_PREFIX="/biglittleant.cn/network"
systemctl enable flanneld
systemctl restart flanneld docker

检查集群中master能够看到node

kubectl get nodes 
NAME            STATUS     AGE
192.168.56.13   Ready      17s

如果配置错误可以删除当前节点重新添加。

kubectl delete nodes 127.0.0.1 
node "127.0.0.1" deleted

可以查看该node节点的详细信息

kubectl describe node 192.168.56.13

在Master节点查看flannel子网分配情况。

shell > etcdctl ls /biglittleant.cn/network
/biglittleant.cn/network/subnets
/biglittleant.cn/network/config

手动启动kubernetes容器

第一步创建deployment

 kubectl run hello-world --replicas=2 --labels="run=load-balancer-example" --image=docker.io/nginx  --port=8080
deployment "hello-world" created
  • 上述命令将创建一个Deployment对象和一个关联的ReplicaSet对象。 ReplicaSet有两个Pod,每个都运行nginx应用程序。
  • Deployment会自动帮你创建pod和replicasets。

查看Deployment的信息

kubectl get deployments hello-world
kubectl describe deployments hello-world

查看replicasets的信息

 kubectl get replicasets
 kubectl describe replicasets

使用 describe 查看详细信息

第二步 创建一个对外服务的Service对象

kubectl expose deployment hello-world --type=NodePort --name=example-service

查看刚才services的信息

 kubectl describe services example-service

输出信息如下:

Name:                   example-service
Namespace:              default
Labels:                 run=load-balancer-example
Selector:               run=load-balancer-example
Type:                   NodePort
IP:                     10.254.21.162
Port:                   <unset> 8080/TCP
NodePort:               <unset> 32187/TCP
Endpoints:              <none>
Session Affinity:       None
No events.

这里需要注意的是,Service使用的是虚拟IP地址,因些无法ping通过;但访问8080端口时,可以访问到对应的资源。

列出运行hello word的pod

kubectl get pods --selector="run=load-balancer-example" --output=wide
NAME                           READY   STATUS    ...  IP           NODE
 hello-world-2895499144-bsbk5   1/1     Running   ...  10.200.1.4   worker1
 hello-world-2895499144-m1pwt   1/1     Running   ...  10.200.2.5   worker2

kubernetes的event概念,event是一个事件的记录,记录了事件的最早产生时间、最后重现时间、重复次数、发起者、类型以及导致此事件的原因等众多信息。当我们发现某个pod迟迟不能启动时,可以使用kubectl describe pod xxx 来查看他的描述信息,来定位问题。

帮助文档查看

Guides提供了Kubernetes文档的功能,以及管理和旋转起来集群,包括用法示例。
Tutorials 包含Kubernetes工作流程的详细演练。
Tasks 包含常用Kubernetes任务的一步一步的指示。
Concepts提供Kubernetes如何运作的深刻理解。
API提供了有关Kubernetes API和完整的信息kubectl的命令行界面。

谷歌HPA程序

flannel原理解释

flannel 使用etcd存储配置数据和子网分配信息。flannel 启动之后,后台进程首先检索配置和正在使用的子网列表,然后选择一个可用的子网,然后尝试去注册它。

通过查看/biglittleant.cn/network/subnets这个目录中获取已经注册的网段。

flannel 使用etcd的watch机制监视/biglittleant.cn/network/subnets下面所有元素的变化信息,并且根据他来维护一个路由表。为了提高性能,flannel优化了Universal TAP/TUN设备,对TUN和UDP之间的ip分片做了代理。

etcdctl ls /biglittleant.cn/network/subnets
/biglittleant.cn/network/subnets/10.10.47.0-24
/biglittleant.cn/network/subnets/10.10.61.0-24
7: flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast state UNKNOWN qlen 500
    link/none 
    inet 10.10.61.0/16 scope global flannel0
       valid_lft forever preferred_lft forever
31: flannel0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1472 qdisc pfifo_fast state UNKNOWN qlen 500
    link/none 
    inet 10.10.47.0/16 scope global flannel0
       valid_lft forever preferred_lft forever

从上面的IP可以看出每个flannel会获得一个IP端。
flannel会获取/24的网段,所有/biglittleant.cn/network这个网段最好设置大网段。

除了flannel网络以为还可以配置open vSwitch 或者直接路由(使用Quagga来实现路由规则的动态添加)。

参考文档

follow-me-install-kubernetes-cluster
如何在Kubernetes中暴露服务访问
flannel网络原理
kubernetes-yum安装
kubernetes-各服务介绍
Kubernetes中文文档
用 Flannel 配置 Kubernetes 网络
Kubernetes管理基本教程
如果有10000台机器,你想怎么玩
Kubernetes高级实践:Master高可用方案设计和踩过的那些坑
kubernetes-中文文档
和我一步步部署 KUBERNETES 集群
kubernetes 翻译

报错汇总

启动一个pod 没有生成相应的docker容器

kubectl describe rs mynginx 
Error creating: No API token found for service account "default", retry after the token is automatically created and added to the service account
KUBE_ADMISSION_CONTROL="--admission_control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"
原文地址:https://www.cnblogs.com/biglittleant/p/7463426.html