Kubernetes(k8s) 笔记总结

Posted IT_Holmes

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kubernetes(k8s) 笔记总结相关的知识,希望对你有一定的参考价值。

提示:针对kubernetes的服务网络学习。

文章目录


一、Kubernetes的 Service服务发现 ClusterIP方式

1. Service 介绍

什么是Service?

Service就是将一组 Pods 公开为网络服务的抽象方法。(意思就是将多个Pod分到一个Service统一的操作。)

2. Service 暴露ClusterIP的方式(集群内部访问)

命令行方式:

# 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的方式:

  • 通过IP:直接通过IP访问。
  • 通过Service的名称访问:
  • 通过域名进行操作,域名规则:服务明.所在名称空间.svc 都可以的。

    Service是具有服务发现效果的,如果进行了缩容,那么就不会将请求发给下线的pod。
    以上几种方式就是ClusterIP方式:
  • ClusterIP就是集群IP,暴露出来的IP只能在集群内部访问。

3. Service 暴露NodePort方式(集群外也可以访问)


# 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

此外,还会随机暴露一个端口:

  • 通过公网IP + 该端口,可以访问service里面的pod应用。

NodePort范围在 30000-32767 之间。

二、Kubernets 之 Ingress

1. Ingress 介绍

Ingress定义:Service的统一网关入口。

官网地址:https://kubernetes.github.io/ingress-nginx/

网络的三个层次:

  • Ingress网关入口,Ingress底层就是nginx。
  • service层网络
  • Pod层网络

2. Ingress 安装

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/ 来进行访问测试了。


Ingress架构图:

3. Ingress 实战域名访问

实战架构:

实战环境搭建:

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名称

4. Ingress高级用法 路径重写

也可以参考一些rewrite一些功能啥的:

5. Ingress 流量限制

去官方看看案例教程就可以

三、kubernetes 之 存储抽象

1. 存储层架构

存储层:

2. NFS系统搭建

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就搭建成功。

3. 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被清除了对应卷的资源不会被清除,无法释放。)

4. PV与PVC挂载(适合挂载目录)

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池:

5. ConfigMap挂载(适合挂载配置文件)

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

针对配置的一个解释:

可以去看看对应的pod的内部目录:

这样配置就算完成。

第三步:如果修改了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部署的中间件自己本身没有热更新能力

6. Secret (适用于保存敏感信息)


像密码,认证令牌,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

以上是关于Kubernetes(k8s) 笔记总结的主要内容,如果未能解决你的问题,请参考以下文章

Kubernetes(k8s) 笔记总结

Kubernetes(k8s) 笔记总结

Kubernetes(k8s) 笔记总结

Kubernetes(k8s) 笔记总结

Kubernetes 学习总结(19)—— Kubernetes 集群管理平台如何选择?Rancher vs KubeSphere

Kubernetes 学习总结(19)—— Kubernetes 集群管理平台如何选择?Rancher vs KubeSphere