- 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"