从K8S部署示例进一步理解容器化编排技术的强大
概念
Kubernetes,也称为K8s,生产级别的容器编排系统,是一个用于自动化部署、扩展和管理容器化应用程序的开源系统。K8s是一个go语言开发,docker也是go语言开发,可见go语言的是未来的趋势;从公有云Iaas、Paas、Saas的云计算时代开始,到Docker Swarm用于容器化集群和Apache Mesos为分布式资源管理框架,Kubernetes最终打败其他容器化编排技术成为主流引领者。
kubeadm部署
部署规划
服务器最低配置要求: 2core 、2G、 50G,由于需要部署docker,因此如果是centos则要求7以上
所有服务器的操作系统
cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
主机名 | IP |
---|---|
k8s-master2 | 192.168.50.36 |
k8s-node-1 | 192.168.50.34 |
k8s-node-2 | 192.168.50.35 |
网段划分
名称 | IP网段 | 备注 |
---|---|---|
service-cluster-ip | 10.10.0.0/16 | 可用地址 65534 |
pods-ip | 10.20.0.0/16 | 可用地址 65534 |
集群dns | 10.10.0.2 | 用于集群service域名解析 |
k8s svc | 10.10.0.1 | 集群 kubernetes svc 解析ip |
部署步骤
下面是所有的节点均需操作
#部署docker,找出最新版本
yum list docker-ce --showduplicates | sort -r
yum list docker-ce-cli --showduplicates | sort -r
#修改为最新的版本
yum -y install docker-ce-20.10.8 docker-ce-cli-20.10.8 containerd.io
#添加/etc/docker/daemon.json内容为
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
"exec-opts": ["native.cgroupdriver=systemd"]
}
# 重启docker
systemctl restart docker
systemctl enable docker.service
#关闭防火墙
systemctl stop firewalld # 临时
systemctl disable firewalld # 永久
#关闭 selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久
setenforce 0 # 临时
#关闭 swap
swapoff -a # 临时
vim /etc/fstab # 永久
#修改主机名
hostnamectl set-hostname <hostname>
#添加 hosts
cat >> /etc/hosts << EOF
192.168.50.34 k8s-node-1
192.168.50.35 k8s-node-2
192.168.50.36 k8s-master-2
EOF
#使桥接流量对iptables可见,将桥接的 IPv4 流量传递到 iptables 的链
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system
#时间同步
yum install ntpdate -y
ntpdate time.windows.com
# 使用本地软件包管理软件安装 kubectl 二进制文件
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=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
EOF
#安装 kubeadm,kubelet 和 kubectl
yum install -y kubelet-1.22.1 kubeadm-1.22.1 kubectl-1.22.1
systemctl enable kubelet
查看已安装版本信息
kubeadm init --kubernetes-version=1.22.1 \
--apiserver-advertise-address=192.168.50.36 \
--ignore-preflight-errors=all \
--image-repository registry.aliyuncs.com/google_containers \
--service-cidr=10.10.0.0/16 \
--pod-network-cidr=10.20.0.0/16
根据上面的提示信息继续操作
kubectl get nodesmkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
#下面这段是后面在node节点加入k8s集群的命令
kubeadm join 192.168.50.36:6443 --token jagf90.w67s5swmocymags3 \
--discovery-token-ca-cert-hash sha256:0afe56b1ca4354bc1148bf25c97e18412ab4f1340d3b62080d1fb1d0901d07c9
# 如需要重新生成token重新生成加入集群命令可使用下面这个
kubeadm token create --print-join-command
#查看当前集群节点信息,目前集群的网络还没有打通,因此状态为NotReady
kubectl get nodes
#查看当前节点的docker镜像,kubeadm部署方式是以docker镜像方式运行集群
docker images
分别在两台node节点192.168.50.34、192.168.50.35执行加k8s集群的命令
kubeadm join 192.168.50.36:6443 --token jagf90.w67s5swmocymags3 \
--discovery-token-ca-cert-hash sha256:0afe56b1ca4354bc1148bf25c97e18412ab4f1340d3b62080d1fb1d0901d07c9
#使kubectl自动补全
source <(kubectl completion bash)
# 查询目前三个节点的信息如下
kubectl get nodes
kubectl get pod --all-namespaces -o wide
接下来需要给k8s集群添加CNI网络插件,有很多方式,这里先提供两种
#calico网络
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
#或者选择kube-flannel网络
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
#过两分钟后再查看节点的状态
通过查找pod的详细信息发现问题
#calico.yaml先下载下来
wget https://docs.projectcalico.org/manifests/calico.yaml
#calico.yaml增加两行信息 - name: IP_AUTODETECTION_METHOD value: "interface=ens.*",interface后面根据实际,我的机器网卡是ens160所以直接填
# Cluster type to identify the deployment type
- name: CLUSTER_TYPE
value: "k8s,bgp"
- name: IP_AUTODETECTION_METHOD
value: "interface=ens160"
# Auto-detect the BGP IP address.
- name: IP
value: "autodetect"
#重新应用calico.yaml
kubectl apply -f calico.yaml
我们再来解决coredns的ImagePullBackOff的问题
#查看coredns pod的镜像
kubectl get pods coredns-7f6cbbb7b8-d2rzk -n kube-system -o yaml | grep image
#显示信息如下
image: registry.aliyuncs.com/google_containers/coredns:v1.8.4
imagePullPolicy: IfNotPresent
- image: registry.aliyuncs.com/google_containers/coredns:v1.8.4
imageID: ""
message: Back-off pulling image "registry.aliyuncs.com/google_containers/coredns:v1.8.4"
#由于registry.aliyuncs.com/google_containers/coredns:v1.8.4官方是没有的,官方镜像是coredns/coredns:1.8.4
#在coredns节点上也即是k8s-node-2也即是192.168.50.35上先下载镜像
docker pull coredns/coredns:1.8.4
#查看coredns/coredns:1.8.4镜像的imageid,给镜像手动打tag为registry.aliyuncs.com/google_containers/coredns:v1.8.4
docker tag 8d147537fb7d registry.aliyuncs.com/google_containers/coredns:v1.8.4
常见几个问题
1. 加入集群时报错: /etc/kubernetes/kubelet.conf already exists
原因: 上次的配置文件没有清理干净,删除即可
rm -rf /etc/kubernetes/kubelet.conf /etc/kubernetes/pki/ca.crt
2. 加入集群时报错: [ERROR Port-10250]: Port 10250 is in use
原因:上次加入没有成功就关闭。重置kubeadm
kubeadm reset
3. 加入集群报错:/proc/sys/net/ipv4/ip_forward contents are not set to 1
echo "1" >/proc/sys/net/ipv4/ip_forward
容器编排示例
nginx部署示例
所有命令不清楚就是用--help这个万能的神命令查看,这里采用deployment部署,当然也可以单独创建pod,这种在实际场景会比较少用
#创建nginx部署
kubectl create deployment nginx --image=nginx
#暴露端口 type类型可以有多种
kubectl expose deployment nginx --port=80 --type=NodePort
#查看pods和services的信息,这里是缩写,其他缩写可以查询--help命令,像上面deployment缩写为deploy,对应复数可是可以使用,一般使用简写
kubectl get pod,svc -o wide
上面有几个Ip和端口需要理解下。k8s-node-1的ip是192.168.50.34,宿主机上的端口为32173,所以我们可以通过http://192.168.50.34:32173 访问到这个pod暴露的服务
#更新镜像版本
kubectl set image deploy nginx nginx=nginx:1.7.9
#查看更新状态
kubectl rollout status deploy nginx
#describe显示特定资源或资源组的详细信息,这里显示nginx部署详细信息
kubectl describe deploy nginx
#回退到上一次的版本
kubectl rollout undo deploy nginx
#查看deployment变更的对应版本
kubectl rollout history deploy nginx
#查看deployment变更的对应版本的细节
kubectl rollout history deploy nginx --revision=7
#回滚到指定的版本
kubectl rollout undo deploy nginx --to-revision=7
# kubectl proxy主要用于测试,可以通过
kubectl proxy
curl http://localhost:8001/api/v1/proxy/namespaces/default/pods/podname访问
容器扩缩容示例
#扩容nginx pod数量为4
kubectl scale deploy nginx --replicas=4
#查看pod信息,第一次查询结果k8s-node-1上pod马上就有,应该k8s-node-1之前下载了nginx镜像,第二次k8s-node-2下载完镜像也启动两个pod,k8s有自己的算法比较均衡将pod分布集群节点上
kubectl get pod -o wide
#缩容nginx pod数量为2,
kubectl scale deploy kubernetes-bootcamp --replicas=2
基于yaml文件方式部署
上面我们都是基于kubectl也即是命令方式直接创建deployment和pod、service,这种方式一般是简单测试使用,接下来我们基于yaml文件方式部署
编写单独创建pod的yaml文件nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
# 通过create命令用yaml来创建pod,另外还可以使用apply命令用yaml来创建
kubectl create -f nginx-pod.yaml
编写创建deploy的yaml文件nginx-deploy.yaml,也可以直接通过下面命令生成一个deployment的yaml文件
kubectl create deployment nginx-d1 --image=nginx:1.18 -o yaml --dry-run > nginx-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
creationTimestamp: null
labels:
app: nginx
name: nginx-deploment
spec:
replicas: 2
selector:
matchLabels:
app: nginx
strategy: {}
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.18
name: nginx
resources: {}
status: {}
#删除deployment
kubectl delete deploy nginx
# 基于yaml创建deployment
kubectl apply -f nginx-deploy.yaml
#查看labels标签为app=nginx的pod,上面选择器为app=nginx,我们创建多个pod,找到label,services也是根据这个label找到然后做负载均衡
kubectl get pods -l app=nginx
#可以查看pod的日志,和我们之前docker logs一样
kubectl logs pod -f
接下来我们看下service部分,也即是kubernetes的ingress来暴露应用,创建nginx-service.yaml文件
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
ports:
- port: 8080
targetPort: 80
nodePort: 30080
selector:
app: nginx
type: NodePort
#创建service
kubectl create -f nginx-service.yaml
#查看创建service详细信息,安装完系统有一个名称为kubernetes的service,这个相当把apiserver做成一个ip
kubectl describe service nginx-service
有几个重要端口我们一起来了解下
- nodePort:这个是提供给集群外部的集群访问的,像这类配置为30080则可以提供给外部访问,比如这里直接访问http://192.168.50.34:30080,service内部实现服务发现和负载均衡
- targetPort:容器的端口,与制作容器镜像时暴露端口一致,和我们之前学习docker制作dockerfile文件是一样的,例如我们这里的测试的nginx,docker.io官方镜像暴露端口就是80
- port:这个是kubernetes集群内部各个服务之间互相访问的端口,比如我们mysql容器虽然暴露3306端口,没有配置nodePort,外部无法直接访问容器,但集群内部容器之间是可以通过访问mysql服务
我们可以进入任意一个容器进行测试,我们进入到kubernetes-bootcamp,然后访问nginx的pod服务
#由于目前这个容器只有一个pod
kubectl exec -it kubernetes-bootcamp /bin/bash
#如果有多个pod,那就需要通过docker命令找到容器的名称指定了
kubectl exec -it kubernetes-bootcamp --container xxxxx /bin/bash
#进入一个装有工具箱的环境,一般用于测试
kubectl run busybox --rm=true --image=busybox --restart=Never --tty -i
生成10.20网段的地址是容器内的地址,10.10网段是用于集群内容通信的地址,也可以pod直接访问 ,比如我们这里的http://10.10.11.146
基于dns访问集群
#查询所有命名空间的service,kube-dns集群地址为10.10.0.10,这个是kubeadm创建dns服务
kubectl get svc -A
#如果是手动安装我们可以通过apply方式部署dns,kube-dns.yaml,下载地址可以网上找,比如https://github.com/liuyi01/kubernetes-starter/blob/master/kubernetes-with-ca/services/kube-dns.yaml
kubectl apply -f kube-dns.yaml
可以通过nginx-service名称访问到nginx的服务
安装仪表盘
# 下载 dashboard.yaml 文件到本地,可以在github kubernetes dashboard项目上查看最新版本,目前U最新版本为v2.3.1
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.3.1/aio/deploy/recommended.yaml
kubectl apply -f recommended.yaml
kubectl proxy
# 设置可以在外部访问dashboard,修改 dashboard以 nodePort 访问,编辑配置文件
kubectl -n kubernetes-dashboard edit service kubernetes-dashboard
修改类型
type: ClusterIP
改为
type: NodePort
#查看暴露的端口
kubectl -n kubernetes-dashboard get service kubernetes-dashboard
通过节点访问https://192.168.50.34:30109/#/login 页面
在我们上面下载recommended.yaml文件里面就有subjects,表示创建了 kubernetes-dashbord 账户
# 为该账户创建登录 token
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep kubernetes-dashboard | awk '{print $1}')
Data
====
ca.crt: 1099 bytes
namespace: 20 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6Im5EOGxxZHFIdnFKeTRabmlicHhRNDVBZ3Y0WlR1enRLQkdoZ21EcFExLWcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZC10b2tlbi1xenNiayIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjcyNGQ0ODRmLTY2M2YtNGM2YS1hNGMyLTVlOTk3OTliYzczMyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlcm5ldGVzLWRhc2hib2FyZDprdWJlcm5ldGVzLWRhc2hib2FyZCJ9.czIcgip4VJe7dEY_nulArhqKtd2Lc3JGlUrNmn4jGc2ZZ5TMeluRvv71Sztdmb-iYftWKnqil-OuCBgTFss6atShfiQ3__2i4V-vBAM1cFjBtxKZ0QgOpRvDri0hAj34XnF9uSzjH24Gt4x50OX9qaIKmJ8ppHVe0lxBWXP-Z-N4JbrKkRbD6c-EwYBhMoJo7ndUGmkxVsCvuNaE4yRfXENRaunPmGYJMgvFo4XSAz37cznNNVVj8BaIbSxgxv8XPgUEdQZxP2bm2TskVb3AYqeSVd4YR87NxYFod91IezRUBelbupaVWllJVcsEIaANfk4NNN61atWkGO9aNgyK4Q
将上面的token复制,点击登录即可
从K8S部署示例进一步理解容器化编排技术的强大的更多相关文章
- Spring Boot 项目转容器化 K8S 部署实用经验分享
转载自:https://cloud.tencent.com/developer/article/1477003 我们知道 Kubernetes 是 Google 开源的容器集群管理系统,它构建在目前流 ...
- AspNetCore容器化(Docker)部署(三) —— Docker Compose容器编排
一.前言 上一篇部署了一个最基础的helloworld应用,创建了两个容器和一个network,还算应付得过来. 如果该应用继续引入mysql.redis.job等若干服务,到时候发布一次得工作量之大 ...
- AspNetCore容器化(Docker)部署(一) —— 入门
一.docker注册安装 Windows Docker Desktop https://www.docker.com/products/docker-desktop Linux Docker CE h ...
- AspNetCore容器化(Docker)部署(二) —— 多容器通信
一.前言 着上一篇 AspNetCore容器化(Docker)部署(一) —— 入门,在单个容器helloworld的基础上引入nginx反向代理服务器组成多容器应用. 二.配置反向代理转接 配置转接 ...
- AspNetCore容器化(Docker)部署(四) —— Jenkins自动化部署
一.前言 (Jenkins.Docker.Git/Svn组建一套简单的自动化发布流程) 文章中用到的相关服务器角色 角色 环境 功能 开发机 Win10.Docker(Linux OS) 编码.调试 ...
- BI系统打包Docker镜像及容器化部署的具体实现
在过去的几年中,"云"作为明星热词站在了各种新潮技术之中,你可能使用过,但说不清它的原理:或者是没用过,但听过它的大名:也可能连它的名字都没听过,但你对这只蓝色鲸鱼一定十分眼熟.作 ...
- .NET Core+MySql+Nginx 容器化部署
.NET Core容器化@Docker .NET Core容器化之多容器应用部署@Docker-Compose .NET Core+MySql+Nginx 容器化部署 GitHub-Demo:Dock ...
- 浅谈surging服务引擎中的rabbitmq组件和容器化部署
1.前言 上个星期完成了surging 的0.9.0.1 更新工作,此版本通过nuget下载引擎组件,下载后,无需通过代码build集成,引擎会通过Sidecar模式自动扫描装配异构组件来构建服务引擎 ...
- 通过 Azure Pipelines 实现持续集成之docker容器化及自动化部署
通过 Azure Pipelines 实现持续集成之docker容器化及自动化部署 Intro Azure DevOps Pipeline 现在对于公开的项目完全免费,这对于开源项目来讲无疑是个巨大的 ...
随机推荐
- [GYCTF2020]Easyphp
知识点 反序列化pop链 反序列化字符逃逸 解题过程 www.zip 备份文件获取源码 审计代码构造pop链 <?php Class UpdateHelper{ public $id; publ ...
- C++构造函数写法
笔记 class complex{ public: complex (double r = 0, double i = 0) : re(r), im(i) {} private: double re, ...
- idea明明设置了utf-8, 但是提交的配置文件到远程中文乱码
IDEA中编辑的.properties配置文件提交到Git后显示乱码 解决方法:
- 如何删除一个win10的服务
使用场景: 之前电脑玩腾讯qq微端游戏,后来卸载残留服务一直在后台占用系统资源.那么如何关闭这个服务呢. 1.首先 管理员运行--cmd.exe 2.打开任务管理器,找到服务名称,如果服务开启可以关闭 ...
- Linux检测磁盘空间
在linux中,文件系统将所有的磁盘都并入一个虚拟目录下,在使用新的存储媒体之前,需要把它放到虚拟目录下,这项工作称为挂载. 1.mount命令 mount会输出当前系统上挂载的设备列表,要在虚拟目录 ...
- 【python】python之list
1.判断list是否为空 方式一: list_temp=[] if len(list_temp): #非空即为真 print('list is not empty') else: print('lis ...
- BZOJ 3694&&DTOJ 1972: 最短路
题目描述 给出一个n个点m条边的无向图,n个点的编号从1~n,定义源点为1.定义最短路树如下:从源点1经过边集T到任意一点i有且仅有一条路径,且这条路径是整个图1到i的最短路径,边集T构成最短路树. ...
- 最短剩余时间优先法则SRTN
- linux中chage命令的基本使用
在Linux中chage命令常用于设置系统用户的账户属性 Usage: chage [options] LOGIN Options: -d, --lastday LAST_DAY set date o ...
- 17.Power of Four-Leetcode
#define IMIN numeric_limits<int>::min() #define IMAX numeric_limits<int>::max() class So ...