云原生时代之Kubernetes容器编排初步探索及部署、使用实战-v1.22
概述
**本人博客网站 **IT小神 www.itxiaoshen.com
Kubernetes官网地址 https://kubernetes.io
Kubernetes GitHub源码地址 https://github.com/kubernetes/kubernetes
Kubernetes,也称为K8s,生产级别的容器编排系统,是一个用于自动化部署、扩展和管理容器化应用程序的开源系统。
- Kubernetes,是一个go语言开发(docker也是go语言开发,可见go语言的厉害和趋势,其兼具 Python 等动态语言的开发速度和 C/C++ 等编译型语言的性能与安全性”,部署简单、并发性好、语言设计良好、执行性能高,后续我们专题学习它)用于跨多个主机管理容器化应用程序的开放源代码系统。它为应用程序的部署、维护和扩展提供了基本机制。
- Kubernetes的发展历史,从公有云Iaas、Paas、Saas的云计算时代开始,到Docker Swarm用于容器化集群和Apache Mesos为分布式资源管理框架,最终成为容器化编排主流引领者
特性
-
- Kubernetes 会分步骤地将针对应用或其配置的更改上线,同时监视应用程序运行状况以确保你不会同时终止所有实例。如果出现问题,Kubernetes 会为你回滚所作更改。你应该充分利用不断成长的部署方案生态系统。
-
- 无需修改你的应用程序即可使用陌生的服务发现机制。Kubernetes 为容器提供了自己的 IP 地址和一个 DNS 名称,并且可以在它们之间实现负载均衡。
-
- 部署和更新 Secrets 和应用程序的配置而不必重新构建容器镜像,且 不必将软件堆栈配置中的秘密信息暴露出来。
-
- 根据资源需求和其他约束自动放置容器,同时避免影响可用性。将关键性工作负载和尽力而为性质的服务工作负载进行混合放置,以提高资源利用率并节省更多资源。
-
- 除了服务之外,Kubernetes 还可以管理你的批处理和 CI 工作负载,在期望时替换掉失效的容器。
-
- 为 Pod 和 Service 分配 IPv4 和 IPv6 地址
-
- 使用一个简单的命令、一个 UI 或基于 CPU 使用情况自动对应用程序进行扩缩。
-
- 重新启动失败的容器,在节点死亡时替换并重新调度容器,杀死不响应用户定义的健康检查的容器,并且在它们准备好服务之前不会将它们公布给客户端。
-
- 无需更改上游源码即可扩展你的 Kubernetes 集群
kubernetes使用
文档
演进过程:传统部署时代 - 虚拟化部署时代 - 容器部署时代
- 传统部署时代:在物理服务器上运行应用程序
- 虚拟化部署时代:虚拟化技术允许你在单个物理服务器的 CPU 上运行多个虚拟机
- 容器部署时代:与 VM 类似,可以在应用程序之间共享操作系统,容器被认为是轻量级的,具有自己的文件系统、CPU、内存、进程空间
概念
Kubernetes 组件
-
控制平面组件(Control Plane Components)
- kube-apiserver:提供了 Kubernetes API的统一入口,是 Kubernetes 控制面的前端,提供 HTTP API,以供用户、集群中的不同部分和集群外部组件相互通信,可以查询和操纵 Kubernetes API 中对象(例如:Pod、Namespace、ConfigMap 和 Event)的状态,大部分操作都可以通过kubectl命令行接口或 类似kubeadm这类命令行工具来执行, 这些工具在背后也是调用 API,也可以使用 REST 调用来访问这些 API或者使用客户端库
- etcd:兼具一致性和高可用性的分布式键值数据库,用于保存 Kubernetes 所有集群和状态包括Pod、Deployment、Service等
- kube-scheduler:负责监视新创建的、未指定运行节点和pod,计算和选择 Pod 在哪些节点上运行,包括节点控制器、任务控制器、端点控制器等
- kube-controller-manager:用于集群监控、故障转移等,执行集群级别的功能,如复制组件、追踪工作结点状态、处理结点失败等
-
可选组件
- kube-dns:负责整个集群内部dns解析服务,属于非必要组件,可实现所有pod通过名称访问
- dashboard:仪表盘,是 Kubernetes 集群的通用的、基于 Web 的用户界面。 它使用户可以管理集群中运行的应用程序以及集群本身并进行故障排除
- cloud-controller-manager:嵌入特定云的控制逻辑的控制平面组件
-
Node 组件(节点可以是一个虚拟机或者物理机器,节点组件在每个节点上运行,负责运行容器的软件维护运行的 Pod )
- kubelet:负责节点上运行Pod容器中,管理工作节点上的容器
- kube-proxy:主节点代理,集群中每个节点上运行的网络代理,实现Kubernetes 的Service映射访问
- 容器运行时:提供 Kubernetes 运行环境实际运行容器的组件比如docker、containerd、CRI-O
-
网络插件(两个docker宿主机之间通信需要具有实现CNI的插件)
- 部署基于 Pod 网络插件的容器网络接口(CNI),让 Pod 可以相互通信,网络插件包括Calico、Flannel、Cilium、Weave等,官方还提供其他网络插件
概念
Pod
Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元和调度单位,Pod可以包含是一个或者多个容器化应用、挂载和网络。而一个节点Node只要资源足够是可以运行和管理很多很多的pod;Pod安装在节点上,包含一组容器和卷。同一个Pod里的容器共享同一个网络命名空间,可以使用localhost互相通信
如果Pod是短暂的,那么怎么才能持久化容器数据使其能够跨重启而存在? 是的,Kubernetes支持卷的概念,因此可以使用持久化的卷类型。
Replication Controller
是否手动创建Pod,如果想要创建同一个容器的多份拷贝,需要一个个分别创建出来么?可以手动创建单个Pod,但是也可以使用Replication Controller使用Pod模板创建出多份拷贝。
Replication Controller确保任意时间都有指定数量的Pod“副本”在运行。如果为某个Pod创建了Replication Controller并且指定3个副本,它会创建3个Pod,并且持续监控它们。如果某个Pod不响应,那么Replication Controller会替换它,保持总数为3。如果之前不响应的Pod恢复了,现在就有4个Pod了,那么Replication Controller会将其中一个终止保持总数为3。如果在运行中将副本总数改为5,Replication Controller会立刻启动2个新Pod,保证总数为5。还可以按照这样的方式缩小Pod,这个特性在执行滚动升级时很有用。
当创建Replication Controller时,需要指定两个东西:
- Pod模板:用来创建Pod副本的模板
- Label:Replication Controller需要监控的Pod的标签
Deployment
deployment是pod版本管理的工具,用来区分不同版本的pod,保证pod的数量和健康;从开发者角度看,deployment也即是部署意思,对于完整的应用部署流程,除了运行代码(既pod)之外,需要考虑更新策略,副本数量,回滚,重启等步骤
Service
Service是一个逻辑的概念,是定义一系列Pod以及访问这些Pod的策略的一层抽象。Service通过Label找到Pod组;通常用于将一组相同pod应用有一个虚拟网络IP进行管理,如果Pod是短暂的,那么重启时IP地址可能会改变,那么怎么才能从前端容器正确可靠地指向后台容器呢?这时可以使用Service,Service还可以实现其一组pod内部的服务发现和负载均衡,通过每个Node上运行的代理(kube-proxy)完成。
部署
部署方式
部署Kubernetes集群有多种方式,包括kind、minikube、kubeadm、二进制文件、yum安装、第三方工具、kops、kubespray、花钱购买
- kind让你能够在本地计算机上运行 Kubernetes,一般用于学习使用
- minikube与kind类似,运行一个单节点的 Kubernetes 集群,也是用于学习使用
- kubeadm该工具能够执行必要的动作并用一种用户友好的方式启动一个可用的、安全的集群。部署简单,通过kubeadm init和kubeadm join两个命令就可以创建集群。也比较适合学习Kubernetes运维,现在也比较稳定可用于生产环境
- 二进制文件:下载二进制包,手动部署每个组件,比较繁琐,但是能对Kubernetes各个组件有更清晰更深刻的认识
- yum安装:通过yum安装每个组件,由于yum源有可能比较老,一般也较少使用
- 第三方工具,比如GitHub有些大神封装的一些工具用于部署Kubernetes集群
- kops、kubespray
- 花钱购买:比如阿里云、腾讯云共有云k8s平台,一键搞定
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
第三方方式部署
部署规划
GitHub上搜索kubernetes二进制,选择一个较新的进行部署
GitHub kubernetes集群部署,下载源码文件
服务器最低配置要求: 2core 、2G、 50G,由于需要部署docker,因此如果是centos则要求7以上
所有服务器的操作系统
cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
服务器规划
主机名 | IP |
---|---|
k8s-master1 | 192.168.50.33 |
k8s-node-1 | 192.168.50.34 |
k8s-node-2 | 192.168.50.35 |
nginx-ingress-slb | 192.168.50.36 |
网段划分
名称 | 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 CE version 20.10.8
- Kubernetes Version 1.22.1
- Etcd Version v3.5.0
集群说明
- 所有主机使用 CentOS Linux release 7.9.2009 (Core) 版本,并且内核都升到5.x版本。
- kube-proxy 使用 ipvs 模式(预留iptables模式)
- Calico 使用 IPIP 模式
- 集群域使用默认 svc.cluster.local
- 10.10.0.1 为集群 kubernetes svc 解析ip
- haproxy设置TCP监听nginx-ingress的svc端口,实现ingress高可用
- nginx-ingress后端获取客户端真实IP
部署步骤
- 初始化
- 关闭 firewalld
- 关闭 swap
- 关闭 Selinux
- 修改内核参数
- 预先设置 PATH
- 设置hostname
- 判断内核并升级
- 安装docker
- 证书生成
- 准备cfssl证书生成工具
- 自签TLS证书,metrics-server 证书
- 部署Etcd集群
- 从Github下载Etcd二进制文件和k8s相关组件,解压k8s二进制包
- 拷贝master上的ssl证书到node
- 设置kubeconfig
- 依次启动etcd
- 健康检查
- 部署Master Node
- 部署kube-apiserver
- 部署kube-controller-manager
- 部署kube-scheduler
- 配置kubelet证书自动续期和创建Node授权用户
- 批准kubelet证书申请并加入集群
- 部署Worker Node
- 创建工作目录并拷贝二进制文件
- 拷贝master上的ssl证书到node
- 部署kubelet
- 部署kube-proxy
先将k8s-normal-master.zip文件上传到master和node节点上并解压,如果节点已安装docker先执行卸载老版本
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
修改shell文件夹下面的init.sh脚本文件,按照下面修改两处地方
#修改host内容为我们
echo "192.168.50.33 k8s-master-1" >> /etc/hosts
echo "192.168.50.34 k8s-node-1" >> /etc/hosts
echo "192.168.50.35 k8s-node-2" >> /etc/hosts
#找出最新版本
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
#设置hosts须手动修改,并授予init
#master-1节点上执行
sh init.sh k8s-master-1
#node1节点上执行
sh init.sh k8s-node-1
#node2节点上执行
sh init.sh k8s-node-2
至此,三台服务器的docker安装已安装完毕
证书生成执行步骤
修改mktls.sh里面hosts为我们部署节点host
cat > server-csr.json <<EOF
{
"CN": "kubernetes",
"hosts": [
"127.0.0.1",
"192.168.50.33",
"192.168.50.34",
"192.168.50.35",
"10.10.0.1",
"kubernetes",
"kubernetes.default",
"kubernetes.default.svc",
"kubernetes.default.svc.cluster",
"kubernetes.default.svc.cluster.local"
],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"L": "BeiJing",
"ST": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}
EOF
#在master节点上执行
sh mktls.sh
# 将生成的证书相关的文件copy到所有node机器上
scp -r /k8s/kubernetes/ssl/* root@192.168.50.34:/k8s/kubernetes/ssl
scp -r /k8s/kubernetes/ssl/* root@192.168.50.35:/k8s/kubernetes/ssl
部署Etcd集群执行步骤
修改etcd_install.sh脚本etcd版本为最新的v3.5.0
# 修改为etcd最新版本
wget https://github.com/etcd-io/etcd/releases/download/v3.5.0/etcd-v3.5.0-linux-amd64.tar.gz
tar zxvf etcd-v3.5.0-linux-amd64.tar.gz
cd etcd-v3.5.0-linux-amd64
# master节点上执行
sh etcd_install.sh
# master节点创建目录
mkdir /opt/package-k8s
# 将所有二级制文件下载到该目录下
cd /opt/package-k8s
# cpoy 执行文件到 /opt/kubernetes/bin 目录,并对所有文件增加可执行的权限
cp -a kube-apiserver kube-controller-manager kube-scheduler kubectl kubelet kube-proxy /k8s/kubernetes/bin
# 修改kubeconfig.sh部分内容,根据实际情况修改KUBE_APISERVER地址
export KUBE_APISERVER="https://192.168.50.33:6443"
#执行配置脚本
sh kubeconfig.sh
#拷贝目录到所有节点上
scp -r /k8s/* root@192.168.50.34:/k8s/
scp -r /k8s/* root@192.168.50.35:/k8s/
# master节点上执行etcd配置命令
sh etcd_conf.sh etcd01 192.168.50.33 etcd01=https://192.168.50.33:2380,etcd02=https://192.168.50.34:2380,etcd03=https://192.168.50.35:2380
# node1节点上执行etcd配置命令
sh etcd_conf.sh etcd02 192.168.50.34 etcd01=https://192.168.50.33:2380,etcd02=https://192.168.50.34:2380,etcd03=https://192.168.50.35:2380
# node2节点上执行etcd配置命令
sh etcd_conf.sh etcd03 192.168.50.35 etcd01=https://192.168.50.33:2380,etcd02=https://192.168.50.34:2380,etcd03=https://192.168.50.35:2380
# etcd健康检查
ETCDCTL_API=3 /k8s/etcd/bin/etcdctl --write-out=table \
--cacert=/k8s/kubernetes/ssl/ca.pem --cert=/k8s/kubernetes/ssl/server.pem --key=/k8s/kubernetes/ssl/server-key.pem \
--endpoints=https://192.168.50.33:2379,https://192.168.50.34:2379,https://192.168.50.35:2379 endpoint health
部署Master Node执行步骤
修改apiserver.sh中内容
#去掉kubelet-https
--kubelet-https=true \\
##增加service-accoun配置
--service-account-issuer=kubernetes.default.svc \\
--service-account-signing-key-file=/k8s/kubernetes/ssl/ca-key.pem \\
去掉controller-manager.sh中内容--feature-gates=RotateKubeletClientCertificate=true \
#master节点配置apiserver
sh apiserver.sh 192.168.50.33 https://192.168.50.33:2379,https://192.168.50.34:2379,https://192.168.50.35:2379
#master节点配置controller-manager
sh controller-manager.sh 127.0.0.1
#master节点配置scheduler
sh scheduler.sh 127.0.0.1
# 查看master三个服务是否正常运行
ps -ef | grep kube
netstat -ntpl | grep kube-
准备admin证书配置 admin-csr.json,放在 admin目录
{
"CN": "admin",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "Beijing",
"L": "XS",
"O": "system:masters",
"OU": "System"
}
]
}
使用根证书(ca.pem)签发admin证书
cfssl gencert \
-ca=/k8s/kubernetes/ssl/ca.pem \
-ca-key=/k8s/kubernetes/ssl/ca-key.pem \
-config=/k8s/kubernetes/ssl/ca-config.json \
-profile=kubernetes admin-csr.json | cfssljson -bare admin
#指定apiserver的地址和证书位置(ip自行修改)
kubectl config set-cluster kubernetes \
--certificate-authority=/k8s/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=https://192.168.50.36:6443
#设置客户端认证参数,指定admin证书和秘钥
kubectl config set-credentials admin \
--client-certificate=/k8s/kubernetes/ssl/admin/admin.pem \
--embed-certs=true \
--client-key=/k8s/kubernetes/ssl/admin/admin-key.pem
#关联用户和集群
kubectl config set-context kubernetes \
--cluster=kubernetes --user=admin
#设置当前上下文
kubectl config use-context kubernetes
#查看组件的状态测试下
kubectl get cs
#查看pod
kubectl get pods
暂时先到这里,其他部署后续有时间我们再继续,本篇我们主要还是学习命令和部署实战
容器编排部署实战
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及简单命令,后续再学习k8s进阶内容、例如configmap、secrets、有状态应用、高可用k8s集群、helm以及基于微服务集群容器编排部署实战等