Kubernetes入门(一)
Kubernetes也叫做k8s。它是一个开源系统,主要用于自动部署、扩容缩容和管理容器化应用。它将诸多应用的容器分为若干个逻辑单元以便于管理和发现。kubernetes拥有着Google高负载生产环境的15年经验,并结合了社区的优秀思想和实践。
Kubernetes官网:https://kubernetes.io/
在Kubernetes中,service是核心,我们并不需要太多关心kubernetes里面是怎么工作的,我们只需要关心它给我们提供什么service。就像docker容器可以提供一个mysqld的服务、web服务等。
它需要拥有一个唯一的名字、以及ip:port来对外提供服务。提供service的是容器,为了保证service的高可用,提供service的容器不能只有一个,需要一组,这一组容器我们把它叫做pod。pod是kubernetes最基本的操作单元。
为了实现service和pod之间的管理,又有了标签(label)的概念,我们把功能相同的pod设定为同一个标签。比如,可以把所有提供mysql服务的pod打上标签name=mysql,这样mysql service要作用于所有包含name=mysql标签的pod上。
pod运行在Node上,Node可以是一台物理机,也可以是虚拟机。通常一个Node上会运行几百个pod,每个pod里运行着一个特殊的容器,叫做Pause,其它容器叫做业务容器,业务容器共享Pause容器的网络栈和Volume挂载卷,因此同一个pod内的业务容器之间的通信和数据交换更为高效。
在集群管理方面,kubernetes将集群中的机器划分为一个Master节点和一群工作节点Node,其中Master上运行着kube-apiserver、kube-controller-manager、kube-scheduler,他们实现了资源管理、pod调度、弹性伸缩、安全控制、系统监控、纠错等功能。Node是工作节点,运行应用程序,提供服务。Node上的最小单元是pod,Node上运行着kubernetesd的kubelet、kube-proxy服务进程,它们负责pod的创建、启动、监控、重启、销毁,已经实现负载均衡。
扩容和升级需要一个关键的东西,Replication controller(RC),RC需要包含3个关键信息:
1)目标pod的定义
2)目标pod需要运行的副本数量(replicas)
3)要监控的目标pod的标签(Label)
工作过程:RC里需要定义好3个指标,kubernetes会根据RC定义的Label筛选出对应的pod,并实时监控其状态和数量,当实例数量少于定义的副本数(replicas)时,则会根据RC定义的pod模板来创建新的pod,然后将此pod调度到合适的Node上启动并运行。整个过程完全自动化,无需人工干涉。
示例:
下面从一个例子开始:webapp + mysql 。准备一台centos7机器。
- 关闭firewalld和selinux:
- # systemctl stop firewalld && systemctl disable firewalld
- # setenforce 0
安装etcd和kubernetes:
# yum install -y etcd kubernetes
修改配置文件:
# vim /etc/sysconfig/docker
将 --selinux-enabled 改为 --selinux-enabled=false --insecure-registry gcr.io
# vim /etc/kubernetes/apiserver
将 KUBE_ADMISSION_CONTROL 参数中的 ServiceAccount 删除 - 准备工作:
# yum install -y python-rhsm-certificates
如果提示:Package python-rhsm-certificates-1.19.10-1.el7_4.x86_64 is obsoleted by subscription-manager-rhsm-certificates-1.21.10-3.el7.centos.x86_64 which is already installed ,
则执行下面步骤,否则不执行
# wget http://mirror.centos.org/centos/7/os/x86_64/Packages/python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm
# rpm2cpio python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm | cpio -iv --to-stdout ./etc/rhsm/ca/redhat-uep.pem > /etc/rhsm/ca/redhat-uep.pem
配置docker加速器:
# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://dhq9bx4f.mirror.aliyuncs.com"]
}
按顺序启动所有服务:
# for s in etcd docker kube-apiserver kube-controller-manager kube-scheduler kubelet kube-proxy; do systemctl start $s; done
创建一个rc文件:
# vim mysql-rc.yaml
apiVersion: v1
kind: ReplicationController #副本控制器RC
metadata:
name: mysql #RC的名称,全剧唯一
spec:
replicas: 1 #Pod副本的期待数量
selector:
app: mysql #符合目标的Pod拥有此标签
template: #根据此模板创建Pod的副本(实例)
metadata:
labels:
app: mysql #Pod副本拥有的标签,对应RC的Selector
spec:
containers: #Pod内容器的定义部分
- name: mysql #容器的名称
image: mysql:5.6 #容器对应的Docker image
ports:
- containerPort: 3306 #容器应用监听的端口号
env: #注入容器内的环境变量
- name: MYSQL_ROOT_PASSWORD
value: "123456"
# docker pull registry.access.redhat.com/rhel7/pod-infrastructure:latest
# docker pull mysql:5.6
# kubectl create -f mysql-rc.yaml #创建pod。上面两步可省略,若提前拉取镜像则该步执行更快
replicationcontroller "mysql" created
# kubectl get pod
NAME READY STATUS RESTARTS AGE
mysql-f16r2 0/1 ContainerCreating 0 1m #容器正在创建中
# kubectl get pod
NAME READY STATUS RESTARTS AGE
mysql-f16r2 1/1 Running 0 3m #已经启动
# vim mysql-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql
spec:
ports:
- port: 3306
selector:
app: mysql
# kubectl create -f mysql-svc.yaml #创建service
service "mysql" created
# kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.254.0.1 <none> 443/TCP 58m
mysql 10.254.218.177 <none> 3306/TCP 33s
# yum install -y mysql
# mysql -uroot -p123456 -h10.254.218.177 #此时就可以直接访问这个mysql服务
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
+--------------------+
3 rows in set (0.01 sec)
创建web的rc文件:
kind: ReplicationController
metadata:
name: myweb
spec:
replicas: 1
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: '10.254.218.177' #如果已经搭建kube-dns服务,此处可直接填mysql即可
- name: MYSQL_SERVICE_PORT
value: '3306'
# kubectl create -f myweb-rc.yaml
replicationcontroller "myweb" created
# kubectl get pod
NAME READY STATUS RESTARTS AGE
mysql-f16r2 1/1 Running 0 20m
myweb-f8xw9 0/1 ContainerCreating 0 8s #正在创建中
# kubectl get pod
NAME READY STATUS RESTARTS AGE
mysql-f16r2 1/1 Running 0 23m
myweb-f8xw9 1/1 Running 0 3m
创建web的svc文件:
# vim myweb-svc.yaml
kind: Service
metadata:
name: myweb
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30001 #通过Node ip访问,映射到Node上的这个端口
selector:
app: myweb
# kubectl create -f myweb-svc.yaml
service "myweb" created
# kubectl get svc
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.254.0.1 <none> 443/TCP 1h
mysql 10.254.218.177 <none> 3306/TCP 26m
myweb 10.254.171.116 <nodes> 8080:30001/TCP 1m
# curl 10.254.171.116:8080/demo/
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>HPE University Docker&Kubernetes Learning</title>
</head>
<body align="center">
<h2>Congratulations!!</h2>
<br></br>
<input type="button" value="Add..." onclick="location.href='input.html'" >
<br></br>
<TABLE align="center" border="1" width="600px">
<TR>
<TD>Name</TD>
<TD>Level(Score)</TD>
</TR>
<TR>
<TD>google</TD>
<TD>100</TD>
</TR>
<TR>
<TD>docker</TD>
<TD>100</TD>
</TR>
<TR>
<TD>teacher</TD>
<TD>100</TD>
</TR>
<TR>
<TD>HPE</TD>
<TD>100</TD>
</TR>
<TR>
<TD>our team</TD>
<TD>100</TD>
</TR>
<TR>
<TD>me</TD>
<TD>100</TD>
</TR>
</TABLE>
</body>
</html>
# curl 192.168.30.128:30001/demo/ #可以看到,通过本机ip的30001端口也可以访问到相同的数据
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>HPE University Docker&Kubernetes Learning</title>
</head>
<body align="center">
<h2>Congratulations!!</h2>
<br></br>
<input type="button" value="Add..." onclick="location.href='input.html'" >
<br></br>
<TABLE align="center" border="1" width="600px">
<TR>
<TD>Name</TD>
<TD>Level(Score)</TD>
</TR>
<TR>
<TD>google</TD>
<TD>100</TD>
</TR>
<TR>
<TD>docker</TD>
<TD>100</TD>
</TR>
<TR>
<TD>teacher</TD>
<TD>100</TD>
</TR>
<TR>
<TD>HPE</TD>
<TD>100</TD>
</TR>
<TR>
<TD>our team</TD>
<TD>100</TD>
</TR>
<TR>
<TD>me</TD>
<TD>100</TD>
</TR>
</TABLE>
</body>
</html>
通过浏览器访问:
# iptables -P FORWARD ACCEPT
新增一条记录
再到mysql数据库查看
# mysql -uroot -p123456 -h10.254.218.177
MySQL [(none)]> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| HPE_APP |
| mysql |
| performance_schema |
+--------------------+
4 rows in set (0.01 sec)
MySQL [(none)]> use HPE_APP;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MySQL [HPE_APP]> show tables;
+-------------------+
| Tables_in_HPE_APP |
+-------------------+
| T_USERS |
+-------------------+
1 row in set (0.00 sec)
MySQL [HPE_APP]> select * from T_USERS;
+----+-----------+-------+
| ID | USER_NAME | LEVEL |
+----+-----------+-------+
| 1 | me | 100 |
| 2 | our team | 100 |
| 3 | HPE | 100 |
| 4 | teacher | 100 |
| 5 | docker | 100 |
| 6 | google | 100 |
| 7 | lzx | 100 |
+----+-----------+-------+
7 rows in set (0.00 sec)
可以看到,有刚刚新增的lzx记录。