前言
好久没有复习k8s,忘了好多,这几天复习k8s,今天来练习一下,本博客仅有练习意义,毕竟为了博客提供高可用意义不大
环境使用k8s集群+docker+harbor部署mysql+wordpress容器
首先从最简单的单节点单pod开始部署(使用宿主机网络),然后增加分离wordpress与mysql,并且使用service控制wordpress接受访问(NodePort),wordpress使用IP连接mysql,最后,完成一个简单的wordpress小集群
使用节点
| NODE | IP | ROLE |
|---|---|---|
| k8s-a | 192.168.179.11 | master(control) |
| k8s-b | 192.168.179.12 | slave(node) |
| k8s-c | 192.168.179.13 | slave(node) |
| harbor | harbor.A.com(已解析) | harbor仓库 |
单节点,单pod
1.创建secret(用于harbor授权)
apiVersion: v1
kind: Secret
metadata:
name: harbor-secret
data:
.dockerconfigjson: ewoJImF1dGhzIjogewoJCSJjcnBpLXIwM2V5cHF3ZDN3NGY2czkuY24temhhbmdqaWFrb3UucGVyc29uYWwuY3IuYWxpeXVuY3MuY29tIjogewoJCQkiYXV0aCI6ICJZV3hwZVhWdU1UY3dNalEzT0RjMk1UcDNlVzB4T1RJdU1UWTRRRUE9IgoJCX0sCgkJImhhcmJvci5BLmNvbSI6IHsKCQkJImF1dGgiOiAiWVdSdGFXNDZNUT09IgoJCX0KCX0KfQ==
type: kubernetes.io/dockerconfigjson注意点:
- .dockerconfigjson的值必须只有一行,不能换行,他的值可以通过
docker login登录harbor后cat /root/.docker/config.json | base64 -w 0进行加密授权信息即可获取 - type不能修改
2.创建sa授权账户
kind: ServiceAccount
metadata:
name: harbor-sa
imagePullSecrets:
- name: harbor-secrets接下会轮流使用sa账户与secret拉取harbor镜像
3.清单(使用ds控制器)
apiVersion: apps/v1
kind: Deployment
metadata:
name: t1-deploy-wordpress
namespace: t1
spec:
#replicas: 2 使用hostNetwork,启动2个pod导致端口冲突,只能启动一个pod
replicas: 1
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
spec:
#使用imagePullSecrets使用harbor授权信息
imagePullSecrets:
- name: t1-secret-harbor
#使用宿主机网络,指定的containerPort会映射到相同的宿主机端口
hostNetwork: true
containers:
- name: mysql
image: harbor.A.com/k8s/mysql:8.0.32-oracle
ports:
- containerPort: 3306
env:
- name: MYSQL_ALLOW_EMPTY_PASSWORD
#注意,value无法解析boolen值,只能使用string
value: "true"
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wordpress
- name: MYSQL_PASSWORD
value: wordpress
- name: wordpress
image: harbor.A.com/k8s/wordpress
ports:
- containerPort: 80
env:
#部署在一个pod内,直接使用127.0.0.1即可访问
- name: WORDPRESS_DB_HOST
value: '127.0.0.1'
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_PASSWORD
value: wordpress注意点:
- 默认情况下mysql使需要传入MYSQL_ROOT_PASSWORD,但是使用MYSQL_ALLOW_EMPTY_PASSWORD后就可以允许没有密码
访问容器所在节点IP+容器映射端口80即可访问(通过kubectl get pods -o wide发现在k8s-b节点)
关于pod通信:因为是在一个deploy中配置的,所以会被deploy配置到一个pod内,因此这两个容器是同节点同pod,所以可以使用127.0.0.1来进行通信,使用起来等同于同时部署在宿主的情况,同时也可以通过容器IP进行通信
关于访问容器:因为设置了hostNetwork,所以节点IP是直接映射到宿主机上的,必须保证映射端口没有被占用,直接访问容器所在节点的IP+port即可访问该容器
多pod
1.mysql-deploy清单
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deploy
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
#使用sa账户,已经授权harbor-secret
serviceAccount: harbor-sa
#imagePullSecrets:
#- name: harbor-secret
containers:
- name: mysql
image: harbor.A.com/k8s/mysql:8.0.32-oracle
ports:
- containerPort: 3306
env:
- name: MYSQL_ALLOW_EMPTY_PASSWORD
value: "true"
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wordpress
- name: MYSQL_PASSWORD
value: wordpress需要现创建mysql-deploy,通过kubectl get pod -o wide获取mysql容器的IP,接下来的tomcat-deploy清单将会使用该IP
2.wordpress-deploy清单
注意,使用了2个副本,所以实际上会有2个wordpress的pod
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-deploy
spec:
replicas: 2
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
namespace: t1
spec:
imagePullSecrets:
- name: t1-secret-harbor
containers:
- name: wordpress
image: harbor.A.com/k8s/wordpress
ports:
- containerPort: 80
env:
- name: WORDPRESS_DB_HOST
#使用mysql容器的IP
value: "10.100.1.8"
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_PASSWORD
value: wordpress3.创建svc
因为没有使用hostNetwork,所以需要用svc做负载均衡转发请求
apiVersion: v1
kind: Service
metadata:
name: wordpress-svc
spec:
selector:
app: wordpress
type: NodePort
ports:
#svc的端口(用于内部访问)
- port: 80
#容器的端口(转发目标端口)
targetPort: 80
#节点端口(用于外部访问)
nodePort: 30080注意点
- nodePort默认只能是30000-32767,通过对/etc/kubernetes/manifests/kube-apiserver.yaml静态pod资源清单进行修改,添加
- --service-node-port-range=3000-50000,即可修改nodeport范围为3000-50000,但是需要小心修改,防止占用一些重要服务的默认端口
关于pod间的通信:使用svc给wordpress做负载均衡,所以mysql是可以通过svc的VIP+端口(port)svc,svc会转发到wordpress的端口(containerport),但是没有这个需求所以没有用,反过来说,并没有给mysql设置svc导致wordpress只能使用IP访问mysql
注意点:
- 直接使用svc的vip在容器内进行访问是没有用的,甚至都ping不了,使用curl必须加端口(port),一般情况下会卡住,因为不会响应,没有返回内容
关于外部访问pod:使用了NodePort形式的svc,svc拥有VIP,但是这个VIP不同于keepalive的VIP,他是没有实体的,无法被外部解析,实际上,作为VIP,他拥有VIP的能力,访问任意k8s集群内的节点(包括master)+端口(nodeport)就可以从外部访问svc,svc会转发到容器的端口
关于使用svc:因为使用了同一个mysql数据库,所以无论svc转发到哪个容器都会有之前输入的内容,实现了小型的负载均衡
缺点:
- 虽然使用IP直接很简单,但是控制器管理的容器很容易重启,一旦重启,就会导致IP变动,可以参考后面的错误部分
- 无法共享图片,因为mysql数据库无法存储图片,图片都是wordpress存在自己的文件目录中的,而这个需要通过数据卷挂载共享
写一个博客一直刷新可能出现如下状况
最终版:nfs挂载+两个svc
1.mysql-svc清单
因为mysql不需要外部访问,所以选择ClusterIP类型,仅允许内部访问
apiVersion: v1
kind: Service
metadata:
name: mysql-svc
spec:
selector:
app: mysql
#其实默认type就是ClusterIP
type: ClusterIP
ports:
- port: 3306
targetPort: 3306
# ClusterIP没有nodePort字段
# nodePort: 30080通过svc名(mysql-svc)+端口(3306)即可在其他容器内进行内部访问svc,svc会转发到mysql
2.mysql-deploy清单
与之前的相同,基本不修改
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql-deploy
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
imagePullSecrets:
- name: harbor-secret
containers:
- name: mysql
image: harbor.A.com/k8s/mysql:8.0.32-oracle
ports:
- containerPort: 3306
env:
- name: MYSQL_ALLOW_EMPTY_PASSWORD
value: "true"
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wordpress
- name: MYSQL_PASSWORD
value: wordpress3.wordpress-svc清单
与之前相同,不修改
apiVersion: v1
kind: Service
metadata:
name: wordpress-svc
spec:
selector:
app: wordpress
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 300804.安装nfs并且设置共享路径
master节点作为nfs服务端
#安装服务NFS与RPC
yum install -y rpcbind nfs-utils
#启动RPC服务(111端口号)
systemctl start rpcbind
systemctl enable rpcbind
#启动NFS服务(2049端口)
systemctl start nfs
systemctl enable nfs
#NFS服务端配置 /etc/exports
vim /etc/exports
/data/ *(rw,no_root_squash,sync)
systemctl reload nfs
#修改共享目录权限
chown -R nfsnobody.nfsnobody /data/
chmod 777 /data/
#查看
exportfsnode节点需要作为nfs客户端
#安装nfs
yum install -y nfs-utils
#挂载共享目录到某文件夹(测试)
mount -t nfs 10.0.0.128:/data/ /mnt
#使用umount /mnt可以取消挂载
#查看挂载
df -h5.wordpress
修改了mysql的地址
apiVersion: apps/v1
kind: Deployment
metadata:
name: wordpress-deploy
spec:
replicas: 2
selector:
matchLabels:
app: wordpress
template:
metadata:
labels:
app: wordpress
namespace: t1
spec:
imagePullSecrets:
- name: harbor-secret
volumes:
- name: data1
nfs:
server: 192.168.179.11
path: /data/wordpress/data
containers:
- name: wordpress
image: harbor.A.com/k8s/wordpress
ports:
- containerPort: 80
env:
- name: WORDPRESS_DB_HOST
value: "mysql-svc"
- name: WORDPRESS_DB_USER
value: wordpress
- name: WORDPRESS_DB_PASSWORD
value: wordpress
volumeMounts:
- name: data1
mountPath: /var/www/html/wp-content/uploads经过查询,wordpress的图片存储路径为/var/www/html/wp-content/uploads/,因为是由deploy控制的pod不一定部署到一个node上,所以必须使用nfs挂载才能实现跨node的pod的数据卷挂载.
优化:
- 使用PVC挂载而不是直接使用nfs类型的volume挂载
- 对nfs挂载IP做出限制




