单节点k8s(kubernetes)的一个小例子
最近开始阅读《Kubernetes权威指南》这本书,根据书上有一个单节点k8s的小例子一步步来做,踩过的坑记录这是一个简单的Java Web应用,结构简单,是一个运行在Tomcat里的Web App,JSP页面通过JDBC直接访问MySQL数据库并展示数据。此应用需要启动两个容器:Web App容器和MySQL容器,并且Web App容器需要访问MySQL容器。环境准备VM下一台虚拟机,N...
最近开始阅读《Kubernetes权威指南》这本书,根据书上有一个单节点k8s的小例子一步步来做,踩过的坑记录
这是一个简单的Java Web应用,结构简单,是一个运行在Tomcat里的Web App,JSP页面通过JDBC直接访问MySQL数据库并展示数据。
此应用需要启动两个容器:Web App容器和MySQL容器,并且Web App容器需要访问MySQL容器。
环境准备
VM下一台虚拟机,NAT网络模式
关闭防火墙
centos7自带firewall的防火墙业务,而k8s的master与工作node之间会有大量的网络通信,安全的做法实在防火墙上配置各种需要相互通信的端口号,比如后面用到的3306,30001等端口。本文直接关闭防火墙服务。
systemctl disable firewalld.service
systemctl stop firewalld.service
安装和配置k8s
安装etcd和k8s软件(安装过程中会自动安装Docker软件)
yum install -y etcd kubernetes
配置修改
安装完成后,需要修改相关配置
vim /etc/sysconfig/docker
将其中的OPTIONS的内容设置为:OPTIONS=’–selinux-enabled=false --insecure-registry gcr.io’
vim /etc/kubernetes/apiserver
在KUBE_ADMISSION_CONTROL选项中去掉ServiceAccount选项。否则在后面的pod创建中,会报错。
切换docker hub镜像源
在 Linux 环境下,我们可以通过修改 /etc/docker/daemon.json ( 如果文件不存在,你可以直接创建它 ) 这个 Docker 服务的配置文件达到效果
vim /etc/docker/daemon.json
{
"registry-mirrors": ["http://f1361db2.m.daocloud.io", "http://hub-mirror.c.163.com", "https://registry.docker-cn.com"]
}
配置后重启 docker 让配置生效
systemctl restart docker
通过 docker info 来查阅当前注册的镜像源列表,验证我们配置的镜像源是否生效
docker info
安装其他所需依赖
这个坑踩了半天,发现 pod 一直处于ContainerCreating状态,这里先介绍如何解决问题
kubectl describe pod xxx
Kubernetes 报错:
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)”
解决方法如下:
yum install -y *rhsm*
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 | tee /etc/rhsm/ca/redhat-uep.pem
按顺序启动所有服务
systemctl start etcd
systemctl start docker
systemctl start kube-apiserver.service
systemctl start kube-controller-manager.service
systemctl start kube-scheduler.service
systemctl start kubelet.service
systemctl start kube-proxy.service
到目前为止,一个单机版的k8s环境就跑起来了。
启动MySQL容器服务
先拉去mysql的服务镜像:
docker pull mysql
启动MySQL服务
首先为MySQL服务创建一个RC定义文件:mysql-rc.yaml。RC(Replication Controller)定义文件中有3个关键信息:
目标Pod的定义。
目标Pod需要运行的副本数量(Replicas)
要监控的目标Pod的标签(Label),Label是Service和Pod之间的纽带
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: hub.c.163.com/library/mysql #容器对应的Docker image
ports:
- containerPort: 3306 #容器应用监听的端口号
env: #注入容器内的环境变量
- name: MYSQL_ROOT_PASSWORD
value: "123456"
创建好mysql-rc.yaml后,在master节点使用kubectl命令将它发布到k8s集群中。
kubectl create -f mysql-rc.yaml
接下来使用kubectl命令查看刚刚创建的RC:
kubectl get rc
使用下面命令查看Pod的创建情况:
kubectl get pods
可见Pod的状态处于ContainerCreating,需要等到状态为Runing才算成功
创建关联Service
创建一个与之关联的Kubernetes Service-MySQL的定义文件:mysql-svc.yaml
apiVersion: v1
kind: Service #表明是K8s Service
metadata:
name: mysql #Service的全局唯一名称
spec:
ports:
- port: 3306 #Service提供服务的端口号
selector: #Service对应的Pod拥有这里定义的标签
app: mysql
spec.selector确定了哪些Pod副本(实例)对应到本服务。类似地,我们通过kubectl create命令创建Service对象。
运行kubectl命令,创建service:
kubectl create -f mysql-svc.yaml
再运行如下状态,查看刚刚创建的service:
kubectl get svc
注意到MySQL服务被分配到了一个值为10.254.198.153的Cluster IP地址,这是一个虚地址,随后,k8s集群中其他新创建的Pod就可以通过Service的Cluster IP+端口号3306来连接和访问它了。现在我们只需知道,根据Service的唯一名字,容器可以从环境变量中获取到Service对应的Cluster IP地址和端口,从而发起TCP/IP连接请求了。
到这里,MySQL容器服务就启动了。
小结
创建过程,首先,拉取服务镜像,然后创建RC定义文件,再发布到k8s中,可以看到pod被创建。最后创建一个与之关联的k8s Service,也是通过.yaml文件和kubectl create命令创建。
启动Web容器服务
有了上面启动MySQL容器服务的经验,我们来启动Web容器服务,过程是一样的。
先拉取一个测试镜像到本地
docker pull kubeguide/tomcat-app:v1
创建对应的RC文件myweb-rc.yaml,内容如下:
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb
spec:
replicas: 5 #Pod副本期待数量为5
selector:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- name: myweb
image: docker.io/kubeguide/tomcat-app:v1
ports:
- containerPort: 8080
env:
- name: MYSQL_SERVICE_HOST
value: "mysql"
- name: MYSQL_SERVICE_PORT
value: "3306"
然后通过kubectl create命令完成RC的创建和验证工作:
kubectl create -f myweb-rc.yaml
kubectl get rc
kubectl get pods
从输出看到,在RC中声明了5个Pod期待的数量,现在都已经建立并运行起来了,可以看出k8s在自动升级,扩容等方面带来的优势了。
创建对应的Service
最后,创建对应的Service,以下是完整的yaml定义文件(myweb-svc.yaml):
apiVersion: v1
kind: Service
metadata:
name: myweb
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30001
selector:
app: myweb
type=NodePort和nodePort=30001的两个属性,表明此Service开启了NodePort方式的外网访问模式。在k8s集群之外,比如在本机的浏览器里,可以通过30001这个端口访问myweb(对应到8080的虚端口上)。所以前面要关闭防火墙。
运行kubectl create命令进行创建:
kubectl create -f myweb-svc.yaml
最后,使用kubectl查看前面创建的Service
kubectl get services
验证与总结
通过上面的几个步骤,我们可以成功实现了一个简单的k8s单机版例子。有两种方法验证我们的结果。
192.168.245.129是我虚拟机的IP
首先,可以在本机浏览器中输入http://192.168.245.129:30001/demo/来测试我们发的web应用。然而,很不幸,报错了:
报了一个JDBC连接的错误。如果网页能打开的话,是有一个表格并且可以进行操作的。按书上的说法,看不到网页有几个原因:比如防火墙的问题,无法访问30001端口,或者是因为通过代理上网的,浏览器错把这个虚拟机的IP地址当成远程地址了。所以有了第二种验证方法,直接运行如下命令:
curl http://192.168.245.129:30001
输出为:
更多推荐
所有评论(0)