kubernetes详述-k8s安装与使用

目录

kubernetes

官网:https://kubernetes.io/

kubernetes简介

kubernetes是使用go语言开发的一个可移植的、可拓展的开源平台。主要用于管理容器;可以使用促进声明式配置和自动化。kubernetes有一个非常庞大的生态环境。它的服务、工具被广泛运用。

kubernetes是一个全新的基于容器技术的分布式领先方案,简称:K8S。
它是Google开源的容器集群管理系统,它的设计灵感来自于Google内部的一个叫作Borg的容器管理系统,继承了google十余年的容器集群使用经验。它为容器化的应用提供了部署运行、资源调度、服务发现和动态伸缩等一些列完整的功能,极大地提高了大规模容器集群管理的便捷性。

通常部署k8s有两种方式,分别是:自动化工具安装、二进制安装。

# 在kubernetes中,有两个角色,分别是:Master节点和Worker节点。
kubectl是客户端
kubectl通过安全认证连接APIserver控制中心
APIserver控制中心通过调度分析器控制调度器进行探测并把结果返回APIserver控制中心
APIserver控制中心通过控制器进行监控、重启容器等管理容器的操作
ETCD是K8S的数据库,不属于节点里面;
kubelet通过安全认证把数据给APIserver传到etcd
kubelet负责监控、部署、重启、销毁pod等管理pod的操作
kube-proxy负责pod之间网络互通
互联网的流量通过ipvs和iptables转到pod

image

kubeadm方式部署k8s

1、 部署的系统

软件 配置/版本
CentOS 7.9 7.9 2核4G
Docker 19
kubernets v1.20.5

2、节点规划

Hostname IP 内核版本
k8s01-m 172.16.1.101 4.4
k8s02-w1 172.16.1.102 4.4
k8s03-w2 172.16.1.103 4.4

3、集群免密(每台机器都执行)

ssh-keygen
ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.101
ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.102
ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.103

4、关闭Selinux(每台机器)

# 永久关闭
sed -i 's#enforcing#disabled#g' /etc/selinux/config
# 临时关闭
setenforce 0

5、关闭Swap分区(每台机器)

swapoff -a
sed -i.bak 's/^.*centos-swap/#&/g' /etc/fstab
echo 'KUBELET_EXTRA_ARGS="--fail-swap-on=false"' > /etc/sysconfig/kubelet

6、配置国内的yum源(每台机器)

yum install wget
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0
repo_gpgcheck=0
EOF

setenforce 0

# 生成缓存
yum makecache

# 不升级内核更新
yum update -y --exclud=kernel*

7、更换系统内核(每台机器)

# 下载内核包
wget http://106.13.81.75/kernel-lt-4.4.233-1.el7.elrepo.x86_64.rpm
wget http://106.13.81.75/kernel-lt-devel-4.4.233-1.el7.elrepo.x86_64.rpm

# 安装
yum localinstall -y kernel-lt*
grub2-set-default  0 && grub2-mkconfig -o /etc/grub2.cfg
grubby --default-kernel

# 重启
reboot

8、设置内核参数(每台机器)

cat > /etc/sysctl.d/k8s.conf << EOF
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
fs.may_detach_mounts = 1
vm.overcommit_memory=1
vm.panic_on_oom=0
fs.inotify.max_user_watches=89100
fs.file-max=52706963
fs.nr_open=52706963
net.ipv4.tcp_keepalive_time = 600
net.ipv4.tcp.keepaliv.probes = 3
net.ipv4.tcp_keepalive_intvl = 15
net.ipv4.tcp.max_tw_buckets = 36000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp.max_orphans = 327680
net.ipv4.tcp_orphan_retries = 3
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_conntrack_max = 65536
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.top_timestamps = 0
net.core.somaxconn = 16384
EOF

# 立即生效
sysctl --system

9、安装基础软件(每台机器)

yum install wget expect vim net-tools ntp bash-completion ipvsadm ipset jq iptables conntrack sysstat libseccomp -y

10、关闭防火墙(每台机器)

systemctl disable --now firewalld

11、安装Docker(每台机器)

详见网址:https://www.cnblogs.com/90s-blog/p/16051882.html

# step 1: 安装必要的一些系统工具
sudo yum install -y yum-utils device-mapper-persistent-data lvm2

# Step 2: 添加软件源信息
sudo yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

# Step 3
sudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo

# Step 4: 更新并安装Docker-CE
sudo yum makecache fast

# Step 5: 安装docker19.03.12版本
yum install docker-ce-19.03.12 -y

# Step 6 : 启动Docker
systemctl enable --now docker

12、同步集群信息(每台机器)

yum install ntp -y
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
echo 'Asia/Shanghai' > /etc/timezone
ntpdate time2.aliyun.com

# 写入定时任务
crontab -e
*/1 * * * * ntpdate time2.aliyun.com > /dev/null 2>&1

13、部署kubernetes(每台机器)

[root@kubernetes-node-01 ~]# cat /etc/yum.repos.d/kubernetes.repo 
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg

[root@kubernetes-node-01 ~]# setenforce 0

[root@kubernetes-node-01 ~]# systemctl daemon-reload
[root@kubernetes-node-01 ~]# yum install -y kubelet-1.20.5 kubeadm-1.20.5 kubectl-1.20.5 -y

[root@kubernetes-node-01 ~]# systemctl enable --now kubelet

14、修改hostname(不同机器执行)

# 在master执行
hostnamectl set-hostname k8s01-m
# 在node节点1执行
hostnamectl set-hostname k8s02-w1
# 在node节点2执行
hostnamectl set-hostname k8s03-w2

# 每台机器执行:
cat <<EOF >> /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

172.16.1.51 k8s01-m
172.16.1.52 k8s02-w1
172.16.1.53 k8s03-w2
EOF

15、初始化Master节点(只在Master节点上运行)

# 执行下面这段命令来初始化(下载镜像需要外网下载,可以提前准备下载好以下镜像到本地再初始化):
# 注意:如果不能上外网的话:可以提前准备以下镜像后再修改镜像的tag

kubeadm init \
--image-repository=registry.cn-hangzhou.aliyuncs.com/k8sos \
--kubernetes-version=v1.20.5 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16

# 解释以上命令参数:
--image-repository : 指定下载镜像的仓库
--kubernetes-version : k8s的版本号
--service-cidr:service的网段
--pod-network-cidr	: pod的网段

# 管理集群
  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config


# 安装k8s命令提示
yum install -y bash-completion
source /usr/share/bash-completion/bash_completion
source <(kubectl completion bash)
echo "source <(kubectl completion bash)" >> ~/.bashrc

image-20220329160542150

image-20220329161840060

16、部署Pod网络(只在Master节点上运行)

wget https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml

image-20220329162259798

17、验证Master节点初始化是否成功

# 执行命令之后,等待READY结果全部为1/1即为成功,多次执行查看
kubectl get pods -n kube-system   

image-20220329162742128

18、将Worker节点加入集群

# Step 1 : 在Master节点上创建接入Token,把执行结果拿到worker节点执行一遍即可
kubeadm token create  --print-join-command

# Step 2 : 在Node节点1上运行该命令加入集群
kubeadm join 192.168.13.51:6443 --token 7zkt86.bx3g8ctvmq87jfzw     --discovery-token-ca-cert-hash sha256:68629cf4dcc1a24de1b7f5aacd46f89307aedd70d5ed0f382e72efa842feebad 

# Step 3 : 在Node节点2上运行该命令加入集群
kubeadm join 192.168.13.51:6443 --token 7zkt86.bx3g8ctvmq87jfzw     --discovery-token-ca-cert-hash sha256:68629cf4dcc1a24de1b7f5aacd46f89307aedd70d5ed0f382e72efa842feebad 

# 在master节点查看node
kubectl get node

image-20220329163511962

19、验证集群

[root@k8s-m-01 ~]# kubectl run --rm test -it --image=busybox:1.28.3 

If you don't see a command prompt, try pressing enter.
/ # nslookup kubernetes
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
/ # 

k8s基础

img

1、Pod

Pod是k8s中最基础的单元。Pod是由一组容器组成的。Pod最主要的功能是管理一组容器的,为其提供网络、存储、监控等服务。

1.1 创建第一个Pod

在k8s中可以通过三种方式创建Pod,通常通过配置清单的方式来创建。

1.1.1 使用命令创建Pod

[root@kubernetes-master-01 ~]# kubectl run test --image=nginx 
pod/test created
[root@kubernetes-master-01 ~]# kubectl get pods 
NAME   READY   STATUS              RESTARTS   AGE
test   0/1     ContainerCreating   0          9s
  • 参数
参数 解释
--image 指定镜像
--port 指定容器端口的
--rm 当容器结束时,Pod自动删除

1.1.2 使用配置清单的方式创建Pod

[root@kubernetes-master-01 ~]# vim test.yaml

# Api版本号
apiVersion: v1
# 资源名称
kind: Pod
# 基础信息
metadata:
  # 资源名称
  name: testv1
# 定义容器相关
spec:
  # 定义容器
  containers:
    - name: nginx # 定义名称
      image: nginx

[root@kubernetes-master-01 k8s]# kubectl apply -f test.yaml 
pod/testv1 created

1.2 查看Pod

[root@kubernetes-master-01 k8s]# kubectl get pods
NAME     READY   STATUS    RESTARTS   AGE
test     1/1     Running   0          15m
test1    1/1     Running   0          12m
testv1   1/1     Running   0          39s

# 解释:
NAME : 资源名称
READY:容器状态
STATUS:资源运行状态
RESTARTS:资源重启次数
AGE:启动的时长


# 参数:
-o : 指定打印的类型
  wide : 展示更加详细的信息
  yaml : 以yaml格式打印Pod
  json : 以json格式打印Pod

-w : 实时监控

image-20220401190723445

1.3 Pod的详细信息

[root@kubernetes-master-01 k8s]# kubectl describe pod test
Name:         test
Namespace:    default
Priority:     0
Node:         kubernetes-master-03/192.168.13.53
Start Time:   Mon, 28 Mar 2022 11:53:24 +0800
Labels:       run=test
Annotations:  <none>
Status:       Running
IP:           10.240.136.2
IPs:
  IP:  10.240.136.2
Containers:
  test:
    Container ID:   docker://b33398b141b4e25b3bb4aeb62a90ee1d59f143c2fa3077304127fed5db9d28dc
    Image:          nginx
    Image ID:       docker-pullable://nginx@sha256:4ed64c2e0857ad21c38b98345ebb5edb01791a0a10b0e9e3d9ddde185cdbd31a
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Mon, 28 Mar 2022 11:53:46 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-gwkgt (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-gwkgt:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-gwkgt
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 360s
                 node.kubernetes.io/unreachable:NoExecute for 360s
Events:          <none>

微信截图_20220401191005

1.4 Pod的状态

解释
Running 正在运行状态
Terminating 正在结束状态
Pending 正在调度状态
ContainerCreating 正在创建容器状态
ErrImagePull 下载镜像失败
ImagePullBackOff 重试拉取镜像
CrashLoopBackOff 镜像运行失败状态
Completed 已完成状态(镜像的生命周期正常结束)

1.5、Pod的重启策略(restartPolicy)

​ 当Pod遇见运行问题时,一般会自动重启;我们可以通过配置控制其重启策略。

重启策略 解释
Always 总是重启(无论什么状态下都重启)
OnFailure 只有在运行失败时重启
Never 在任何情况下都不重启

1.6、Pod的生命周期

​ Pod从创建完成直到删除之间发生的一些事情。

img

1.6、启动回调(lifecycle)

当Pod刚刚创建完成时运行的回调任务。

[root@kubernetes-master-01 k8s]# vim nginx-test.yaml
# Api版本号
apiVersion: v1
# 资源名称
kind: Pod
# 基础信息
metadata:
  # 资源名称
  name: testv1
  # 注解
  annotations:
    xxx: 'This is Nginx Pod'
# 定义容器相关
spec:
  restartPolicy: Always
  # 定义容器
  containers:
    - name: nginx # 定义名称
      image: nginx
      lifecycle:
        postStart:
          exec:
            command:
              - '/bin/sh'
              - '-c'
              - 'echo "HelloWorld" > /usr/share/nginx/html/index.html'

          httpGet:	# 当容器刚刚运行起来之后,去访问的连接
            port: 80
            host: www.baidu.com

          tcpSocket:	# 相当于去ping一下80端口
            port: 80
            
[root@kubernetes-master-01 k8s]# kubectl apply -f nginx-test.yaml 

image-20220401200428817

1.7 存活性探测(livenessProbe)

​ 就是用来探测容器是否正常运行。如果探测失败(也就是说容器没有正常运行),则会立即重启容器。

[root@kubernetes-master-01 k8s]# vim nginx-test02.yaml

# Api版本号
apiVersion: v1
# 资源名称
kind: Pod
# 基础信息
metadata:
  # 资源名称
  name: nginx-test02
  # 注解
  annotations:
    xxx: 'This is Nginx Pod'
# 定义容器相关
spec:
  restartPolicy: Always
  # 定义容器
  containers:
    - name: nginx # 定义名称
      image: nginx
      livenessProbe:
        exec:
          command:
            - '/bin/sh'
            - '-c'
            - 'xxx'

# 部署
[root@kubernetes-master-01 k8s]# kubectl apply -f nginx-test02.yaml 

# 删除
[root@kubernetes-master-01 k8s]# kubectl delete -f nginx-test02.yaml 

# 重新部署
[root@kubernetes-master-01 k8s]# kubectl apply -f nginx-test02.yaml 

# 查看详细信息
[root@kubernetes-master-01 k8s]# kubectl describe pod nginx-test02

YU7aINMikeB4p6q

1.8 就绪性探测

​ 当一个容器正常运行起来之后,并不能保证容器一定能够外提供服务。就绪性探测就是探测该容器是否能够正常对外提供服务,如果探测失败,则立即清理出集群。

在k8s中有一个名命空间级资源:service , 相当于负载均衡。

[root@kubernetes-master-01 k8s]# vim nginx-test03.yaml

# Api版本号
apiVersion: v1
# 资源名称
kind: Pod
# 基础信息
metadata:
  # 资源名称
  name: nginx-test03
  labels:
    app: test
  # 注解
  annotations:
    xxx: 'This is Nginx Pod'
# 定义容器相关
spec:
  restartPolicy: Always
  # 定义容器
  containers:
    - name: nginx # 定义名称
      image: nginx
      readinessProbe:
        exec:
          command:
            - '/bin/sh'
            - '-c'
            - 'xxx'
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-test03
spec:
  selector:
    app: test
  ports:
    - port: 80
      targetPort: 80
      
[root@kubernetes-master-01 k8s]# kubectl apply -f nginx-test03.yaml 

[root@kubernetes-master-01 k8s]# kubectl get pods -o wide

[root@kubernetes-master-01 k8s]# docker ps

[root@kubernetes-master-01 k8s]# docker -it 116ef2fc5fc1 bash

root@116ef2fc5fc1:/  rm -rf /usr/share/nginx/html/index.html
root@116ef2fc5fc1:/  exit

[root@kubernetes-master-01 k8s]# kubectl get service

[root@kubernetes-master-01 k8s]# curl 10.96.200.199

1.9 环境变量

设置容器内部的环境变量。

[root@kubernetes-master-01 k8s]# vim django-test.yaml

---
kind: Pod
apiVersion: v1
metadata:
  name: django-test
spec:
  containers:
    - name: django
      image: registry.cn-hangzhou.aliyuncs.com/alvinos/django:v1
      env:
        - name: DJANGO_NAME
          value: 'Django==2.2.2'
 [root@kubernetes-master-01 k8s]# kubectl apply -f django-test.yaml
 [root@kubernetes-master-01 k8s]# kubectl describe pod django-test
  [root@kubernetes-master-01 k8s]# kubectl get pods -o wide
 [root@k8s01-m test01]# curl 10.244.1.31

2、Deployment

​ dopleoyment是k8s中的无状态控制器。

​ 功能:1、能够控制Pod的数量;2、监控Pod

2.1、Deployment初体验

[root@k8s01-m test01]# kubectl explain deployment
[root@k8s01-m test01]# vi deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: django
spec:
  # 选择器
  selector:
    matchLabels:
      app: django
  # 创建Pod模板
  template:
    metadata:
      labels:
        app: django
    spec:
      containers:
        - name: django
          image: registry.cn-hangzhou.aliyuncs.com/alvinos/django:v1

2.2、控制Pod的数量

2.2.1 通过命令

[root@kubernetes-master-01 k8s]# kubectl scale deployment django --replicas=10
deployment.apps/django scaled

2.2.2 通过yaml

[root@k8s01-m test01]# vi deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: django
spec:
  replicas: 5
  # 选择器
  selector:
    matchLabels:
      app: django
  # 创建Pod模板
  template:
    metadata:
      labels:
        app: django
    spec:
      containers:
        - name: django
          image: registry.cn-hangzhou.aliyuncs.com/alvinos/django:v1

2.2.3 打标签

[root@kubernetes-master-01 k8s]# kubectl patch deployments.apps django -p '{"spec":{"replicas": 5}}'
deployment.apps/django patched

3、label

​ 标签算是k8s中各个组件之间的桥梁。

3.1 查看label

[root@kubernetes-master-01 k8s]# kubectl get pods --show-labels 
NAME                      READY   STATUS    RESTARTS   AGE   LABELS
django-657f99699c-cg78n   1/1     Running   0          16m   app=django,pod-template-hash=657f99699c

3.2 增加label

[root@kubernetes-master-01 k8s]# kubectl label pod django-test deploy=test

image-20220403172018324

3.3 删除lable

[root@kubernetes-master-01 k8s]# kubectl label pod django-test deploy-

3.4 案例:使用Deployment部署Nginx代理Django

3.4.1 准备Django

[root@kubernetes-master-01 k8s]# vim /root/test01/django/Dockerfile

FROM python:3.6
RUN pip install django==2.2.2 -i https://pypi.tuna.tsinghua.edu.cn/simple/
ADD ./ /opt
WORKDIR /opt
EXPOSE 8000
CMD python manage.py runserver 0.0.0.0:8000

[root@kubernetes-master-01 k8s]# docker build django:v2 .
[root@kubernetes-master-01 k8s]# # 登录阿里云上传镜像,后面需要用

3.4.2 准备nginx

[root@kubernetes-master-01 k8s]# vim django.conf

server {
  listen 80;
  server_name _;
  location / {
    proxy_pass 127.0.0.1:8000;
}

[root@kubernetes-master-01 k8s]# vim /root/test01/nginx/Dockerfile

FROM nginx
ADD django.conf /etc/nginx/conf.d/default.conf
EXPOSE 80 443
CMD nginx -g 'daemon off;'

[root@kubernetes-master-01 k8s]# docker build django:nginxv2 .
[root@kubernetes-master-01 k8s]# # 登录阿里云上传镜像,后面需要用

3.4.3 编辑deployment

[root@kubernetes-master-01 k8s]# vim /root/test01/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: django
spec:
  replicas: 3
  # 选择器
  selector:
    matchLabels:
      app: django
  # 创建Pod模板
  template:
    metadata:
      labels:
        app: django
    spec:
      containers:
        - name: django
          image: registry.cn-hangzhou.aliyuncs.com/alvinos/django:v2
        - name: nginx
          image: registry.cn-hangzhou.aliyuncs.com/alvinos/django:nginxv2
          
[root@kubernetes-master-01 k8s]# kubectl apply -f deployment.yaml

4、Service(svc)

​ 可以理解为k8s中的负载均衡器。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: django
spec:
  replicas: 3
  # 选择器
  selector:
    matchLabels:
      app: django
  # 创建Pod模板
  template:
    metadata:
      labels:
        app: django
    spec:
      containers:
        - name: django
          image: alvinos/django:v1
          readinessProbe:
            httpGet:
              port: 80
              path: /index
---
kind: Service
apiVersion: v1
metadata:
  name: django
spec:
  selector:
    app: django
  ports:
    - port: 80   # 负载均衡的端口
      targetPort: 80  # 后端服务的端口

4.1 Service的类型

​ Service一般有四种类型,分别是:ClusterIP、NodePort、LoadBalancer以及ExternalName。

4.1.1 ClusterIP

​ 在k8s中,默认的类型就是ClusterIP。它为服务提供一个VIP,这个VIP只在集群内部生效。

kind: Service
apiVersion: v1
metadata:
  name: django
spec:
  selector:
    app: django
  ports:
    - port: 80   # 负载均衡的端口
      targetPort: 80  # 后端服务的端口
  type: ClusterIP
  clusterIP: 10.96.12.60

4.1.2 NodePort

​ 利用宿主主机的HOST和Port来代理k8s的端口

kind: Service
apiVersion: v1
metadata:
  name: django
spec:
  selector:
    app: django
  ports:
    - port: 80   # 负载均衡的端口
      targetPort: 80  # 后端服务的端口
      nodePort: 30080
  type: NodePort
  clusterIP: 10.96.12.60

4.1.3 LoadBalancer

​ 利用公网上面的负载均衡器代理k8s服务。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: django
spec:
  replicas: 5
  # 选择器
  selector:
    matchLabels:
      app: django
  # 创建Pod模板
  template:
    metadata:
      labels:
        app: django
    spec:
      containers:
        - name: django
          image: alvinos/django:v1
          readinessProbe:
            httpGet:
              port: 80
              path: /index
---
kind: Service
apiVersion: v1
metadata:
  name: django
spec:
  selector:
    app: django
  ports:
    - port: 80   # 负载均衡的端口
      targetPort: 80  # 后端服务的端口
  type: LoadBalancer
  clusterIP: 10.96.12.60

4.1.4 ExternalName

​ ExternalName最主要的功能是将外部服务接入到集群内部管理。

---
kind: Service
apiVersion: v1
metadata:
  name: baidu
spec:
  type: ExternalName
  externalName: www.baidu.com

4.1.5 案例:使用Service部署Nginx + Django

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: testv3
spec:
  selector:
    matchLabels:
      app: testv3
  template:
    metadata:
      labels:
        app: testv3
    spec:
      containers:
        - name: django
          image: registry.cn-hangzhou.aliyuncs.com/alvinos/django:v2
          readinessProbe:
            tcpSocket:
              port: 8000
        - name: nginx
          image: registry.cn-hangzhou.aliyuncs.com/alvinos/django:nginxv2
---
kind: Service
apiVersion: v1
metadata:
  name: testv3
spec:
  selector:
    app: testv3
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30081
  type: NodePort

4.2 Endpoints

在k8s集群中,service代理Pod使用的实际上是endpoints。

  • endpoints负责在集群中寻找pod。
  • service 负责提供一个VIP。

注意:当Service和Endpoints的名称相同时,k8s默认将其关联起来。

注意:Endpoints除此之外还可以将外部的服务接入集群,接入集群之后像集群内部的资源一样去管理服务。

---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
        - name: mysql
          image: mysql:5.7
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: '123456'

---
kind: Endpoints
apiVersion: v1
metadata:
  name: mysql
subsets:
  - addresses:
      - ip: 106.13.81.75
    ports:
      - port: 49154
---
kind: Service
apiVersion: v1
metadata:
  name: mysql
spec:
  ports:
    - port: 3306
      targetPort: 49154

4.3 Service别名

​ 在k8s集群中,每一个service都有一个vip,但是vip重建之后会发生改变,也就是说service的ip是不固定的,k8s集群就自动给service的名称提供域名解析。

[root@kubernetes-master-01 k8s]# kubectl run --rm -it testv7 --image=busybox:1.28.3
If you don't see a command prompt, try pressing enter.
/ # nslookup django
Server:    10.96.0.2
Address 1: 10.96.0.2 kube-dns.kube-system.svc.cluster.local

Name:      django
Address 1: 10.96.12.59 django.default.svc.cluster.local

​ 其中:django.default.svc.cluster.local 就是service的别名。

​ 语法:service名称.命名空间名称.svc.cluster.local

# 在容器中进入容器可以使用service别名
root@mysql-5b7f695f-qkkj5:/# mysql -uroot -p123456 -hmysql.default.svc.cluster.local

5、存储卷

​ 在k8s集群中,跟在docker中类似,数据是无法永久保存的。所以,k8s集群提供了一个存储卷。

5.1 configMap(一般用来存储配置文件)

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: django
data:
  default.conf: |
    server {
    	listen 80;
    	server_name _;
    	location / {
    		proxy_pass http://127.0.0.1:8000;
    	}
    }
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: django
spec:
  selector:
    matchLabels:
      app: django
  template:
    metadata:
      labels:
        app: django
    spec:
      containers:
        - name: nginx
          image: nginx
          volumeMounts:
            - mountPath: /etc/nginx/conf.d/
              name: django-conf
      volumes:
        - name: django-conf
          configMap:
            name: django
            items:
              - key: default.conf
                path: default.conf  # 挂载目录的相对路径

5.1.1 案例:使用configmap实现nginx + django

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: django
data:
  default.conf: |
    server {
    	listen 80;
    	server_name _;
    	location / {
    		proxy_pass http://127.0.0.1:8000;
    	}
    }
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: django
spec:
  selector:
    matchLabels:
      app: django
  template:
    metadata:
      labels:
        app: django
    spec:
      containers:
        - name: django
          image: registry.cn-hangzhou.aliyuncs.com/alvinos/django:v2
          readinessProbe:
            tcpSocket:
              port: 8000
        - name: nginx
          image: nginx
          volumeMounts:
            - mountPath: /etc/nginx/conf.d/
              name: django-conf
      volumes:
        - name: django-conf
          configMap:
            name: django
            items:
              - key: default.conf
                path: default.conf  # 挂载目录的相对路径
---
kind: Service
apiVersion: v1
metadata:
  name: django
spec:
  selector:
    app: django
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30082
  type: NodePort

5.1.2 configmap用作环境变量

---
kind: ConfigMap
apiVersion: v1
metadata:
  name: test
data:
  MYSQL_ROOT_PASSWORD: '123456'
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: test
spec:
  selector:
    matchLabels:
      app: test
  template:
    metadata:
      labels:
        app: test
    spec:
      containers:
        - name: mysql
          image: mysql:5.7
          envFrom:
            - configMapRef:
                name: test

5.2 secret(一般用于加密存储)

Secret解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。Secret可以以Volume或者环境变量的方式使用。通常需要将保存至secret中的数据进行base64加密。

---
kind: Secret
apiVersion: v1
metadata:
  name: test
data:
  MYSQL_ROOT_PASSWORD: MTIzNDU2Cg==

5.2.1 Opaque

opaque主要用来保存密码、密钥等信息。它也是secret中的默认类型。

1、用作环境变量

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-secret
spec:
  selector:
    matchLabels:
      app: test-secret
  template:
    metadata:
      labels:
        app: test-secret
    spec:
      containers:
        - name: nginx
          image: nginx
          envFrom:
            - secretRef:
                name: test

2、挂载

​ 注意:环境变量的方式是直接挂载到容器的环境变量上;使用存储卷的方式是挂载成一个文件。

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: test-secret
spec:
  selector:
    matchLabels:
      app: test-secret
  template:
    metadata:
      labels:
        app: test-secret
    spec:
      containers:
        - name: nginx
          image: nginx
          volumeMounts:
            - mountPath: /tmp/
              name: test
      volumes:
        - name: test
          secret:
            secretName: test
            items:
              - key: MYSQL_ROOT_PASSWORD
                path: password

5.3 emptyDir(多容器之间共享临时数据)

注意用来多个容器之间共享临时数据。当pod生命周期结束之后,emptyDir中的数据也会立即删除。

---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: emptydir
spec:
  selector:
    matchLabels:
      app: emptydir
  template:
    metadata:
      labels:
        app: emptydir
    spec:
      containers:
        - name: test
          image: busybox:1.28.3
          command:
            - '/bin/sh'
            - '-c'
            - 'while true; do echo `date` > /tmp/1.txt; sleep 1; done'
          volumeMounts:
            - mountPath: /tmp/
              name: emptydir
        - name: test2
          image: busybox:1.28.3
          command:
            - '/bin/sh'
            - '-c'
            - 'while true; do echo `date "+%F %H:%m:%d"` > /tmp/1.txt; sleep 1; done'
          volumeMounts:
            - mountPath: /tmp/
              name: emptydir
      volumes:
        - name: emptydir
          emptyDir: {}

5.4 hostPath(跟宿主主机之间的存储互通)

​ 跟宿主主机之间的存储互通。也就是说部署到那一台机器上就跟那一个宿主主机存储互通。

---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: hostpath
spec:
  selector:
    matchLabels:
      app: hostpath
  template:
    metadata:
      labels:
        app: hostpath
    spec:
      containers:
        - name: test
          image: nginx
          volumeMounts:
            - mountPath: /usr/share/nginx/html/
              name: hostpath
      volumes:
        - name: hostpath
          hostPath:
            path: /tmp # 宿主主机的路径

# 后续使用:在docker中跑一个docker

5.5 网络存储

在k8s中,还可以使用网络存储来作为k8s的后端存储。

[root@kubernetes-master-01 k8s]# for i in m1 m2 m3 n1 n2 n3 n4 n5; do ssh root@$i 'yum install nfs-utils -y';  done
[root@kubernetes-master-01 k8s]# for i in m1 m2 m3 n1 n2 n3 n4 n5; do ssh root@$i 'groupadd www -g 666 && useradd www -u 666 -g 666';  done
[root@kubernetes-master-01 k8s]# vim /etc/exports
[root@kubernetes-master-01 k8s]# cat /etc/exports
/backup 192.168.13.0(rw,sync,all_squash,anonuid=666,anongid=666) 
[root@kubernetes-master-01 k8s]# systemctl enable --now nfs-server rpcbind
[root@kubernetes-master-01 k8s]# mkdir /backup
[root@kubernetes-master-01 k8s]# chown www.www /backup

[root@kubernetes-master-01 k8s]# vim nfs.yaml
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: nfs
spec:
  selector:
    matchLabels:
      app: nfs
  template:
    metadata:
      labels:
        app: nfs
    spec:
      containers:
        - name: nfs
          image: nginx
          volumeMounts:
            - mountPath: /usr/share/nginx/html
              name: nfs
      volumes:
        - name: nfs
          nfs:
            path: /backup
            server: 192.168.13.51

5.6 PV/PVC(动态匹配)

5.6.1 PV(存储)

  • pv的访问策略

    模式 解释
    ReadWriteOnce(RWO) 可读可写,但只支持被单个节点挂载。
    ReadOnlyMany(ROX) 只读,可以被多个节点挂载。
    ReadWriteMany(RWX) 多路可读可写。这种存储可以以读写的方式被多个节点共享。不是每一种存储都支持这三种方式,像共享方式,目前支持的还比较少,比较常用的是NFS。在 PVC 绑定 PV 时通常根据两个条件来绑定,一个是存储的大小,另一个就是访问模式。

---
kind: PersistentVolume
apiVersion: v1
metadata:
  name: v0001
spec:
  accessModes:
    - ReadOnlyMany
  capacity:
    storage: 20Gi
  nfs:
    path: /backup/v10001
    server: 192.168.13.51
  • pv的回收策略

    策略 解释
    Retain 不清理, 保留 Volume(需要手动清理)
    Recycle 删除数据,即rm -rf /thevolume/*(只有 NFS 和 HostPath 支持)
    Delete 删除存储资源,比如删除AWS EBS 卷(只有 AWS EBS, GCE PD, Azure Disk 和 Cinder 支持)
    kind: PersistentVolume
    apiVersion: v1
    metadata:
      name: v0001
    spec:
      persistentVolumeReclaimPolicy: Delete
      accessModes:
        - ReadWriteMany
      capacity:
        storage: 20Gi
      nfs:
        path: /backup/v10001
        server: 192.168.13.51
    
    • pv的状态

      状态 解释
      Available 可用。
      Bound 已经分配给PVC。
      Released PVC 解绑但还未执行回收策略。
      Failed 发生错误。

5.6.2 PVC(存储请求)

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: v0001
spec:
  accessModes:
    - ReadOnlyMany
  resources:
    requests:
      storage: "10Gi"

案例

---
kind: PersistentVolume
apiVersion: v1
metadata:
  name: v0001
spec:
  persistentVolumeReclaimPolicy: Delete
  accessModes:
    - ReadWriteMany
  capacity:
    storage: 20Gi
  nfs:
    path: /backup/v10001
    server: 192.168.13.51
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: v0001
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: "10Gi"
---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: v0001
spec:
  selector:
    matchLabels:
      app: v0001
  template:
    metadata:
      labels:
        app: v0001
    spec:
      containers:
        - name: nginx
          image: nginx
          volumeMounts:
            - mountPath: /usr/share/nginx/html
              name: v0001
      volumes:
        - name: v0001
          persistentVolumeClaim:
            claimName: v0001

5.7 StorageClass(动态创建PV的一个存储类)

5.7.1 部署StorageClass

​ 通常使用Helm来部署StorageClass。

# Helm 相当于 yum
[root@kubernetes-master-01 k8s]# wget https://get.helm.sh/helm-v3.8.1-linux-amd64.tar.gz

[root@kubernetes-master-01 k8s]# tar -xf helm-v3.8.1-linux-amd64.tar.gz

[root@kubernetes-master-01 k8s]# cd linux-amd64/
[root@kubernetes-master-01 linux-amd64]# mv helm /usr/local/bin/


# 安装helm仓库
[root@kubernetes-master-01 k8s]# helm repo add moikot https://moikot.github.io/helm-charts

# 下载nfs-client安装包
[root@kubernetes-master-01 k8s]# helm pull rimusz/nfs-client-provisioner

[root@kubernetes-master-01 k8s]# tar -xf nfs-client-provisioner-0.1.6.tgz
[root@kubernetes-master-01 k8s]# cd nfs-client-provisioner/
[root@kubernetes-master-01 k8s]# vim values.yaml
## Cloud Filestore instance
nfs:
  ## Set IP address
  server: "192.168.13.51"
  ## Set file share name
  path: "/backup/v10003"
storageClass:
 accessModes: ReadWriteMany

[root@kubernetes-master-01 k8s]# helm install nfs-client ./

5.7.2 使用StorageClass创建PV

---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: sc
spec:
  selector:
    matchLabels:
      app: sc
  template:
    metadata:
      labels:
        app: sc
    spec:
      containers:
        - name: nginx
          image: nginx
          volumeMounts:
            - mountPath: /usr/share/nginx/html
              name: sc
      volumes:
        - name: sc
          persistentVolumeClaim:
            claimName: sc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sc
spec:
  storageClassName: nfs-client
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: "10Gi"
posted @ 2022-04-16 16:52  90啊  阅读(1788)  评论(0编辑  收藏  举报