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-apiserver 、kube-controller-manager 、 kube-scheduler 、etcd |
master |
linux-node3 | 192.168.56.13 | kubelet 、proxy 、docker |
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"