kubernetes详述-k8s安装与使用
- kubernetes
- kubernetes简介
- kubeadm方式部署k8s
- 1、 部署的系统
- 2、节点规划
- 3、集群免密(每台机器都执行)
- 4、关闭Selinux(每台机器)
- 5、关闭Swap分区(每台机器)
- 6、配置国内的yum源(每台机器)
- 7、更换系统内核(每台机器)
- 8、设置内核参数(每台机器)
- 9、安装基础软件(每台机器)
- 10、关闭防火墙(每台机器)
- 11、安装Docker(每台机器)
- 12、同步集群信息(每台机器)
- 13、部署kubernetes(每台机器)
- 14、修改hostname(不同机器执行)
- 15、初始化Master节点(只在Master节点上运行)
- 16、部署Pod网络(只在Master节点上运行)
- 17、验证Master节点初始化是否成功
- 18、将Worker节点加入集群
- 19、验证集群
- k8s基础
kubernetes
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
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
16、部署Pod网络(只在Master节点上运行)
wget https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml
17、验证Master节点初始化是否成功
# 执行命令之后,等待READY结果全部为1/1即为成功,多次执行查看
kubectl get pods -n kube-system
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
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基础
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 : 实时监控
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>
1.4 Pod的状态
状态 | 解释 |
---|---|
Running | 正在运行状态 |
Terminating | 正在结束状态 |
Pending | 正在调度状态 |
ContainerCreating | 正在创建容器状态 |
ErrImagePull | 下载镜像失败 |
ImagePullBackOff | 重试拉取镜像 |
CrashLoopBackOff | 镜像运行失败状态 |
Completed | 已完成状态(镜像的生命周期正常结束) |
1.5、Pod的重启策略(restartPolicy)
当Pod遇见运行问题时,一般会自动重启;我们可以通过配置控制其重启策略。
重启策略 | 解释 |
---|---|
Always | 总是重启(无论什么状态下都重启) |
OnFailure | 只有在运行失败时重启 |
Never | 在任何情况下都不重启 |
1.6、Pod的生命周期
Pod从创建完成直到删除之间发生的一些事情。
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
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
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
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"