提示:针对kubernetes的服务网络学习。
什么是Service?
Service就是将一组 Pods 公开为网络服务的抽象方法。(意思就是将多个Pod分到一个Service统一的操作。)
命令行方式:
# 1. 暴露名为my-dep的Deploy,--port就是service要暴露的端口,--target-port是service到pod的端口。
[root@k8s-master ~]$ kubectl expose deployment my-dep --port=8000 --target-port=80 --type=ClusterIP(默认就是CLusterIP)
service/my-dep exposed # 会显示创建的service
# 2. 查看pod的标签
kubectl get pod --show-labels
# 2. 使用标签检索Pod
kubectl get pod -l app=my-dep
查看service,并且测试:
[root@k8s-master ~]$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 32h
my-dep ClusterIP 10.96.4.197 <none> 8000/TCP 24s
[root@k8s-master ~]# curl 10.96.4.197:8000
hello,world2@@@
[root@k8s-master ~]# curl 10.96.4.197:8000
hello,world!
通过配置文件,也可以创建Service:
apiVersion: v1
kind: Service
metadata:
labels:
app: my-dep
name: my-dep
spec:
selector:
app: my-dep
ports:
- port: 8000
protocol: TCP
targetPort: 80
访问Service的方式:
Service是具有服务发现效果的,如果进行了缩容,那么就不会将请求发给下线的pod。
# 1. 获取service列表
kubectl get svc
# 2. 删除之前的service
kubectl delete svc my-dep
# 3. 创建一个NodePort的service
# 将type指定为NodePort
kubectl expose deployment my-dep --port=8000 --target-port=80 --type=NodePort
此外,还会随机暴露一个端口:
Ingress定义:Service的统一网关入口。
官网地址:https://kubernetes.github.io/ingress-nginx/
网络的三个层次:
k8s默认是没有安装Ingress的。
# 官方下载(可能太慢)
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.47.0/deploy/static/provider/baremetal/deploy.yaml
# 所以可以考虑修改镜像
vi ingress.yaml
#将image的值改为如下值:
registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/ingress-nginx-controller:v0.46.0
# -A 参数可以查看全部service,默认defalut名称空间的
kubectl get svc -A
# 检查安装的结果
kubectl get pod,svc -n ingress-nginx
# 最后别忘记把svc暴露的端口要放行
如果下载不到,考虑使用该文件: http://cdn.itholmes.com/itholmes-learn/k8s/install-Ingress.yaml
这样就可以通过http://139.198.183.197:30269/ 或者 https://139.198.183.197:139.198.183.197:30921/ 来进行访问测试了。
实战环境搭建:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-server
spec:
replicas: 2
selector:
matchLabels:
app: hello-server
template:
metadata:
labels:
app: hello-server
spec:
containers:
- name: hello-server
image: registry.cn-hangzhou.aliyuncs.com/lfy_k8s_images/hello-server
ports:
- containerPort: 9000
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-demo
name: nginx-demo
spec:
replicas: 2
selector:
matchLabels:
app: nginx-demo
template:
metadata:
labels:
app: nginx-demo
spec:
containers:
- image: nginx
name: nginx
---
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-demo
name: nginx-demo
spec:
selector:
app: nginx-demo
ports:
- port: 8000
protocol: TCP
targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
labels:
app: hello-server
name: hello-server
spec:
selector:
app: hello-server
ports:
- port: 8000
protocol: TCP
targetPort: 9000
上面配置文件作用:创建了多个Pod,并且将Pod按照Service进行了分配。
接下来就是告诉Ingress当访问哪个域名的时候,走哪个service。相当于给Ingress配置规则。
配置Ingress,当访问hello.abc.com域名时,走名为hello-server的service的8000端口:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-host-bar
spec:
ingressClassName: nginx
rules:
- host: "hello.abc.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
name: hello-server
port:
number: 8000
# 可以配置多个规则
- host: "demo.abc.com"
http:
paths:
- pathType: Prefix
path: "/nginx" # 把请求会转给下面的服务,下面的服务一定要能处理这个路径,不能处理就是404
backend:
service:
name: nginx-demo ## java,比如使用路径重写,去掉前缀nginx
port:
number: 8000
# kubectl get ingress可以查看ingress的一些明细
[root@k8s-master ~]$ kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-host-bar nginx hello.abc.com,demo.abc.com 172.31.0.4 80 9s
知识点:可以使用utools的hosts插件,来控制本地域名映射方便测试。
这样进行测试访问,就完成了(此处,青云网站阻挡了,得使用一个备案过得域名才行。)。
还可以根据path路径,配置Ingress规则,走哪条service。
# 1. 获取明细列表
kubectl get ing
# 2. 修改配置文件
kubectl edit ing ingress名称
也可以参考一些rewrite一些功能啥的:
NFS系统:网络文件系统。
NFS系统原理:就是再各个节点都创建一份相同的存储空间,然后不断进行同步。
NFS架构图:
第一步:NFS环境搭建
# 在所有节点都进行nfs环境安装
yum install -y nfs-utils
第二步:在master节点配置nfs主节点。
# 1. 在master节点执行如下命令(也就是master就是 nfs主节点 了)
# 以下是个配置暴露规则
echo "/nfs/data/ *(insecure,rw,sync,no_root_squash)" > /etc/exports
# 2. 创建对应文件夹
mkdir -p /nfs/data
# 3. 启动rpcbind服务
systemctl enable rpcbind --now
# 4. 启动nfc服务
systemctl enable nfs-server --now
# 5. 让配置生效
exportfs -r
# 6. 进行查看
exportfs
# 7. 通过showmount查看ip暴露了哪些目录
[root@k8s-master ~]$ showmount -e 172.31.0.2
Export list for 172.31.0.2:
/nfs/data *
第三步:在node节点配置,从节点。
# 1. 在master节点通过该命令可以查看IP暴露了那些目录
[root@k8s-master ~]$ showmount -e 172.31.0.2
Export list for 172.31.0.2:
/nfs/data *
# 2. 在node节点执行以下命令:
# 创建对应目录,执行以下命令挂载 nfs 服务器上的共享目录到本机路径 /root/nfsmount
mkdir -p /nfs/data
# 挂载远程172.31.0.2(master)服务器下的/nfs/data这个服务。
mount -t nfs 172.31.0.2:/nfs/data /nfs/data
# 这样无论在那个节点进行测试都会同步。
echo "hello nfs server" > /nfs/data/test.txt
这样NFS就搭建成功。
NFS进行挂载:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-pv-demo
name: nginx-pv-demo
spec:
replicas: 2
selector:
matchLabels:
app: nginx-pv-demo
template:
metadata:
labels:
app: nginx-pv-demo
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
nfs:
server: 172.31.0.2 # 改为自己nfs-server的ip地址(也就是master)
path: /nfs/data/nginx-pv
注意:可能需要先创建出对应目录来/nfs/data/nginx-pv。不然,pod无法启动起来。
提示:nfs系统不算是很好的方式。(一者没办法定义每个Pod的容量;二者如果Pod被清除了对应卷的资源不会被清除,无法释放。)
PV:持久卷(Persistent Volume),将应用需要持久化的数据保存到指定位置
PVC:持久卷申明(Persistent Volume Claim),申明需要使用的持久卷规格(申请多少容量)
第一步:创建pv池(静态供应)。
# 在nfs主节点(对应master节点),创建三个模块
mkdir -p /nfs/data/01
mkdir -p /nfs/data/02
mkdir -p /nfs/data/03
创建PV:(master节点运行)
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv01-10m
spec:
capacity:
storage: 10M
accessModes:
- ReadWriteMany
storageClassName: nfs
nfs:
path: /nfs/data/01
server: 172.31.0.2
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv02-1gi
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
storageClassName: nfs
nfs:
path: /nfs/data/02
server: 172.31.0.2
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv03-3gi
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
storageClassName: nfs
nfs:
path: /nfs/data/03
server: 172.31.0.2
# 查看PV池相关信息
kubectl get persistentvolume
第二步:PVC创建与绑定。(相当于写一个规格申请)
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: nginx-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 200Mi
storageClassName: nfs
删除了就会释放:
删除了在重新应用上,发现并不会再原来的pv创建原因如下:
第三步:创建Pod并且绑定PVC。
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deploy-pvc
name: nginx-deploy-pvc
spec:
replicas: 2
selector:
matchLabels:
app: nginx-deploy-pvc
template:
metadata:
labels:
app: nginx-deploy-pvc
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
volumes:
- name: html
persistentVolumeClaim:
claimName: nginx-pvc
# 查看pvc信息:
[root@k8s-master ~]$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
nginx-pvc Bound pv03-3gi 2Gi RWX nfs 6m42s
# 查看pvc,pv的关系
[root@k8s-master ~]$ kubectl get pvc,pv
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/nginx-pvc Bound pv03-3gi 2Gi RWX nfs 7m43s
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pv01-10m 10M RWX Retain Available nfs 17m
persistentvolume/pv02-1gi 1Gi RWX Retain Released default/nginx-pvc nfs 17m
persistentvolume/pv03-3gi 2Gi RWX Retain Bound default/nginx-pvc nfs 17m
这样PV与PVC搭建完成。
还有一种的动态供应PV池:
ConfigMap抽取应用配置,并且可以自动更新。
以redis为案例:
[root@k8s-master 03]$ vi redis.conf
[root@k8s-master 03]$ cat redis.conf
# ConfigMap挂载的配置文件,是引用的,并不是替换的。因此,写必须的就可以。
appendonly yes
第一步:先创建配置集。
# 1. 创建一个名为redis-conf的配置集
[root@k8s-master ~]$ kubectl create cm redis-conf --from-file=redis.conf
configmap/redis-conf created
# 2. 查看配置集
[root@k8s-master ~]$ kubectl get cm
NAME DATA AGE
kube-root-ca.crt 1 2d8h
redis-conf 1 7s
# 3. 其实配置集在k8s的etcd里面(专门存储配置的那个库)
# 可以通过 名称 + -oyaml 来查看对应的yaml配置。
kubectl get cm redis-conf -oyaml
解析一下配置:
[root@k8s-master ~]$ kubectl get cm redis-conf -oyaml
apiVersion: v1
data: #data是所有真正的数据,key:默认是文件名 value:配置文件的内容
redis.conf: |
appendonly yes
kind: ConfigMap
metadata:
name: redis-conf
namespace: default
第二步:创建Pod,并且进行配置引用配置集。
创建Pod,并且
apiVersion: v1
kind: Pod
metadata:
name: redis
spec:
containers:
- name: redis
image: redis
command:
- redis-server
- "/redis-master/redis.conf" #指的是redis容器内部的位置
ports:
- containerPort: 6379
volumeMounts:
- mountPath: /data
name: data
- mountPath: /redis-master
name: config
volumes:
- name: data
emptyDir: {}
- name: config
configMap:
name: redis-conf
items:
- key: redis.conf
path: redis.conf
这样配置就算完成。
第三步:如果修改了ConfigMap,就检查是否更新。
apiVersion: v1
kind: ConfigMap
metadata:
name: example-redis-config
data:
redis-config: |
maxmemory 2mb
maxmemory-policy allkeys-lru
kubectl exec -it redis -- redis-cli
# CONFIG GET key名 查询配置文件中的某个key的值。
127.0.0.1:6379> CONFIG GET maxmemory
127.0.0.1:6379> CONFIG GET maxmemory-policy
检查指定文件内容是否已经更新
修改了CM。Pod里面的配置文件会跟着变
配置值未更改,因为需要重新启动 Pod 才能从关联的 ConfigMap 中获取更新的值。
原因:我们的Pod部署的中间件自己本身没有热更新能力
像密码,认证令牌,SSH密钥等都属于敏感信息。
# 1. 就是设置一个用户密码邮箱之类的,例如下面登录私有docker库的用户名密码。
kubectl create secret docker-registry leifengyang-docker \
--docker-username=leifengyang \
--docker-password=Lfy123456 \
--docker-email=534096094@qq.com
# 2. 命令格式为
kubectl create secret docker-registry regcred \
--docker-server=<你的镜像仓库服务器> \
--docker-username=<你的用户名> \
--docker-password=<你的密码> \
--docker-email=<你的邮箱地址>
# 3. 获取secret相关信息
kubectl get secret
创建一个Pod拉取的镜像,登录私有docker库:
apiVersion: v1
kind: Pod
metadata:
name: private-nginx
spec:
containers:
- name: private-nginx
image: leifengyang/guignginx:v1.0
imagePullSecrets:
- name: leifengyang-docker