Docker简介
虚拟机,就是在你的操作系统里面,装一个软件,然后通过这个软件,再模拟一台甚至多台“子电脑”出来。
虚拟机,类似于子电脑
在“子电脑”里,你可以和正常电脑一样运行程序,例如开QQ。如果你愿意,你可以变出好几个“子电脑”,里面都开上QQ。“子电脑”和“子电脑”之间,是相互隔离的,互不影响。
虚拟机属于虚拟化技术。而Docker这样的容器技术,也是虚拟化技术,属于轻量级的虚拟化。
虚拟机虽然可以隔离出很多“子电脑”,但占用空间更大,启动更慢,虚拟机软件可能还要花钱(例如VMWare)。
而容器技术恰好没有这些缺点。它不需要虚拟出整个操作系统,只需要虚拟一个小规模的环境(类似沙箱)。
大家需要注意,Docker本身并不是容器,它是创建容器的工具,是应用容器引擎。
想要搞懂Docker,其实看它的两句口号就行。
第一句,是“Build, Ship and Run”。
也就是,“搭建、发送、运行”,三板斧。
第二句口号就是:“Build once,Run anywhere(搭建一次,到处能用)”。
Docker技术的三大核心概念,分别是:
- 镜像(Image)
- 容器(Container)
- 仓库(Repository)
说白了,这个Docker镜像,是一个特殊的文件系统。它除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(例如环境变量)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
负责对Docker镜像进行管理的,是Docker Registry服务(类似仓库管理员)。不是任何人建的任何镜像都是合法的。所以,Docker Registry服务对镜像的管理是非常严格的。
最常使用的Registry公开服务,是官方的Docker Hub,这也是默认的Registry,并拥有大量的高质量的官方镜像。
K8S简介
就在Docker容器技术被炒得热火朝天之时,大家发现,如果想要将Docker应用于具体的业务实现,是存在困难的——编排、管理和调度等各个方面,都不容易。于是,人们迫切需要一套管理系统,对Docker及容器进行更高级更灵活的管理。
就在这个时候,K8S出现了。
K8S,就是基于容器的集群管理平台,它的全称,是kubernetes。
Kubernetes这个单词来自于希腊语,含义是舵手或领航员。K8S是它的缩写,用“8”字替代了“ubernete”这8个字符。
K8S并不是一件全新的发明。它的前身,是Google自己捣鼓了十多年的Borg系统。
一个K8S系统,通常称为一个K8S集群(Cluster)。
这个集群主要包括两个部分:
- 一个Master节点(主节点)
- 一群Node节点(计算节点)
一看就明白:Master节点主要还是负责管理和控制。Node节点是工作负载节点,里面是具体的容器。
Master节点
Master节点包括API Server、Scheduler、Controller manager、etcd。
API Server是整个系统的对外接口,供客户端和其它组件调用,相当于“营业厅”。
Scheduler负责对集群内部的资源进行调度,相当于“调度室”。
Controller manager负责管理控制器,相当于“大总管”。
然后是Node节点。
Node节点包括Docker、kubelet、kube-proxy、Fluentd、kube-dns(可选),还有就是Pod。
Pod是Kubernetes最基本的操作单元。一个Pod代表着集群中运行的一个进程,它内部封装了一个或多个紧密相关的容器。除了Pod之外,K8S还有一个Service的概念,一个Service可以看作一组提供相同服务的Pod的对外访问接口。
Docker,不用说了,创建容器的。
Kubelet,主要负责监视指派到它所在Node上的Pod,包括创建、修改、监控、删除等。
Kube-proxy,主要负责为Pod对象提供代理。
Fluentd,主要负责日志收集、存储与查询。
注意
其实绝大部分Java开发人员都不需要掌握k8s+istio等
大厂的经验不等于小厂也适用,发展规模和阶段不一样,更重要是能力差异,大部分企业选择最合适的技术能够迅速落地,才是最重要的,毕竟资源、能力、精力都有限。
市面上大部分的项目依然还是中小型的,Spring boot/cloud技术栈就已经足矣,杀鸡焉用牛刀?部署k8s、istio的人,都不算上是主流的Java研发人员,和Java研发人员也没真正的关系,他们求职的职位也往往是k8s运维工程师、容器开发工程师等偏运维的岗位。
docker私库搭建
1.拉取docker默认私库镜像
docker pull registry
2.修改docker配置 docker.service ,开启远程端口2376,用于上传下载
vi /usr/lib/systemd/system/docker.service
修改docker.service中的ExecStart
[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2376 -H fd:// --containerd=/run/containerd/containerd.sock --bip=172.20.49.1/24 --mtu=1450
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
验证2376端口
netstat -nap|grep 2376
netstat命令是一个监控TCP/IP网络的非常有用的工具,它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息。
- -n或–numeric:直接使用ip地址,而不通过域名服务器;
- -a或–all:显示所有连线中的Socket;
- -p或–programs:显示正在使用Socket的程序识别码和程序名称;
3.开启私库http上传下载
在 /etc/docker/ 下,新建daemon.json,内容如下
{
"registry-mirrors": ["https://th3lgj42.mirror.aliyuncs.com"],
"insecure-registries":["10.0.1.104:5000"]
}
4.启动私库镜像,暴露5000端口,用于推送
docker run --name wisefly-docker-registry -idt -p 5000:5000 registry
5.重启docker服务
systemctl daemon-reload;service docker restart
maven docker 配置
1、在需要上传到docker的pom文件中做如下配置
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-report-plugin</artifactId>
<version>2.12.2</version>
</plugin>
<!--新增的docker maven插件-->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${docker-maven-plugin.version}</version>
<!--docker镜像相关的配置信息-->
<configuration>
<!--镜像名,要带上私有服务器IP和端口-->
<imageName>${docker-registryUrl}/${project.artifactId}:${project.version}</imageName>
<!--TAG,这里用工程版本号-->
<imageTags>
<imageTag>${project.version}</imageTag>
<imageTag>latest</imageTag>
</imageTags>
<!--镜像的FROM,使用java官方镜像-->
<baseImage>${docker-baseImage}</baseImage>
<!--该镜像的容器启动后,直接运行spring boot工程-->
<entryPoint>["java", "-jar", "/${project.build.finalName}.jar"]</entryPoint>
<!--构建镜像的配置信息-->
<resources>
<resource>
<targetPath>/</targetPath>
<!--指定复制jar包的根目录-->
<directory>${project.build.directory}</directory>
<!--指定复制的文件-->
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
<!--指定推送的仓库-->
<registryUrl>${docker-registryUrl}</registryUrl>
<!-- 开启远程API -->
<dockerHost>${docker-dockerHost}</dockerHost>
<!-- 是否有push功能 -->
<pushImage>true</pushImage>
<!--push后是否覆盖存在的标签镜像-->
<forceTags>true</forceTags>
</configuration>
</plugin>
</plugins>
</build>
2、顶级pom文件中定义公共参数,方便统一修改docker maven版本,仓库地址,远程API等
<docker-maven-plugin.version>1.2.1</docker-maven-plugin.version>
<docker-registryUrl>10.0.1.104:5000</docker-registryUrl>
<docker-dockerHost>http://10.0.1.104:2376</docker-dockerHost>
<docker-baseImage>java:8</docker-baseImage>
<maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
<build-helper-maven-plugin.vrsion>3.2.0</build-helper-maven-plugin.vrsion>
maven推送docker镜像
1、选择需要推送的项目
2、执行
mvn clean package -DskipTests docker:build
验证镜像是否上传成功
执行 docker images 指令,查看镜像
启动镜像,生成容器
1、启动脚本文件上传,找到工程中的docker-compose文件夹,找到需要启动镜像的文件(文件名中会有项目名)。
2、上传到服务器,目前104测试服务器都放在/home/wisefly/compose
3、执行docker-compose指定运行文件
docker-compose -f business-file-compose.yaml up -d
4、验证镜像是否启动成功
执行3步骤的指令返回done表示执行成功,通过 docker ps 也能查看容器是否启动成功
docker常用指令
docker images 查看镜像
docker rmi 镜像名或者ID 删除镜像
docker ps 查看运气容器
docker ps -a 查看所有容器(包含启动失败或者停止的)
docker kill 镜像ID 关闭容器
docker rm 镜像名或者ID 删除容器
docker-compose启动所有镜像
执行 docker-compose -f docker-compose.yaml up -d
启动文件配置所有的镜像,生成容器,用于初始化时启动所有容器。更新单个容器用上面说到的方法。
k8安装部署(单机部署)
以下内容为单机模式:
k8s系统准备
环境准备
部署集群没有特殊说明均使用root用户执行命令
硬件信息
k8s-master 内存16GB 硬盘20GB k8s 控制节点 + Node节点
软件信息
CentOS Linux release
Kubernetes
Docker
修改主机名
hostnamectl set-hostname k8s-master
关闭防火墙
(仅用于测试,生产请不要使用)
systemctl disable --now firewalld
禁用swap
swapoff -a
sed -i 's/.*swap.*/#&/' /etc/fstab
关闭 SELinux
setenforce 0
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
设置系统时区、同步时间
timedatectl set-timezone Asia/Shanghai
systemctl enable --now chronyd
# 将当前的 UTC 时间写入硬件时钟
timedatectl set-local-rtc 0
# 重启依赖于系统时间的服务
systemctl restart rsyslog && systemctl restart crond
部署docker
添加docker yum源
# 安装必要依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加aliyun docker-ce yum源
yum -y install yum-utils
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 重建yum缓存
yum makecache fast
安装指定版本docker
yum install -y docker-ce-19.03.12-3.el7
确保网络模块开机自动加载
lsmod | grep overlay
lsmod | grep br_netfilter
若上面命令无返回值输出或提示文件不存在,需执行以下命令:
cat > /etc/modules-load.d/docker.conf <
使桥接流量对iptables可见
cat > /etc/sysctl.d/k8s.conf <
验证是否生效,均返回 1 即正确
sysctl -n net.bridge.bridge-nf-call-iptables
sysctl -n net.bridge.bridge-nf-call-ip6tables
配置docker
mkdir /etc/docker
#修改cgroup驱动为systemd[k8s官方推荐]、限制容器日志量、修改存储类型,最后的docker家目录可修改
cat > /etc/docker/daemon.json <
部署kubernetes
添加kubernetes源
cat > /etc/yum.repos.d/kubernetes.repo <
查看安装版本
yum list |grep kubelet
yum list |grep kubeadm
yum list |grep kubectl
安装kubeadm、kubelet、kubectl,此处根据自己当前安装的版本进行版本替换
yum install -y kubelet-1.19.0-0 --disableexcludes=kubernetes
yum install -y kubeadm-1.19.0-0 --disableexcludes=kubernetes
yum install -y kubectl-1.19.0-0 --disableexcludes=kubernetes
systemctl enable --now kubelet
配置自动补全命令
#安装bash自动补全插件
yum install bash-completion -y
#设置kubectl与kubeadm命令补全,下次login生效
kubectl completion bash >/etc/bash_completion.d/kubectl
kubeadm completion bash > /etc/bash_completion.d/kubeadm
预拉取kubernetes镜像,此处根据自己当前安装的版本进行版本替换
kubeadm config images list --kubernetes-version v1.19.0
新建脚本get-k8s-images.sh,内容如下:
#!/bin/bash
# Script For Quick Pull K8S Docker Images
KUBE_VERSION=v1.19.0
PAUSE_VERSION=3.2
CORE_DNS_VERSION=1.7.0
ETCD_VERSION=3.4.9-1
# pull kubernetes images from hub.docker.com
docker pull kubesphere/kube-proxy-amd64:$KUBE_VERSION
docker pull kubesphere/kube-controller-manager-amd64:$KUBE_VERSION
docker pull kubesphere/kube-apiserver-amd64:$KUBE_VERSION
docker pull kubesphere/kube-scheduler-amd64:$KUBE_VERSION
# pull aliyuncs mirror docker images
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/pause:$PAUSE_VERSION
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:$CORE_DNS_VERSION
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:$ETCD_VERSION
docker pull quay.io/coreos/flannel:v0.12.0-arm64
docker pull quay.io/coreos/flannel:v0.12.0-amd64
# retag to k8s.gcr.io prefix
docker tag kubesphere/kube-proxy-amd64:$KUBE_VERSION k8s.gcr.io/kube-proxy:$KUBE_VERSION
docker tag kubesphere/kube-controller-manager-amd64:$KUBE_VERSION k8s.gcr.io/kube-controller-manager:$KUBE_VERSION
docker tag kubesphere/kube-apiserver-amd64:$KUBE_VERSION k8s.gcr.io/kube-apiserver:$KUBE_VERSION
docker tag kubesphere/kube-scheduler-amd64:$KUBE_VERSION k8s.gcr.io/kube-scheduler:$KUBE_VERSION
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/pause:$PAUSE_VERSION k8s.gcr.io/pause:$PAUSE_VERSION
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:$CORE_DNS_VERSION k8s.gcr.io/coredns:$CORE_DNS_VERSION
docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:$ETCD_VERSION k8s.gcr.io/etcd:$ETCD_VERSION
# untag origin tag, the images won't be delete.
docker rmi kubesphere/kube-proxy-amd64:$KUBE_VERSION
docker rmi kubesphere/kube-controller-manager-amd64:$KUBE_VERSION
docker rmi kubesphere/kube-apiserver-amd64:$KUBE_VERSION
docker rmi kubesphere/kube-scheduler-amd64:$KUBE_VERSION
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/pause:$PAUSE_VERSION
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/coredns:$CORE_DNS_VERSION
docker rmi registry.cn-hangzhou.aliyuncs.com/google_containers/etcd:$ETCD_VERSION
脚本添加可执行权限,执行脚本拉取镜像:
chmod +x get-k8s-images.sh
./get-k8s-images.sh
初始化kube-master
修改kubelet配置默认cgroup driver
mkdir -p /var/lib/kubelet/
cat > /var/lib/kubelet/config.yaml <
测试环境是否正常(WARNING是正常的),此处选用国内阿里镜像源
kubeadm init --image-repository registry.aliyuncs.com/google_containers --ignore-preflight-errors=Swap
初始化master 10.244.0.0/16是flannel固定使用的IP段,设置取决于网络组件要求
kubeadm init --image-repository registry.aliyuncs.com/google_containers --pod-network-cidr=10.244.0.0/16
配置master认证
echo 'export KUBECONFIG=/etc/kubernetes/admin.conf' >> /etc/profile
source /etc/profile
安装网络组件flannel
# 注意这里下载kubectl apply -f kube-flannel.yaml需要科学上网
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yaml
查看kube-master节点状态
kubectl get nodes
如果长时间达不到 ready 可以查看所有pod 状态
kubectl get pods --all-namespaces
如果有pod有异常,可以查看描述以解决异常
kubectl describe pod pod-id -n kube-system
还可以观察POD的内的启动日志
kubectl logs pod-id -n kube-system
Kubernetes 将Pod调度到Master节点(单机运行K8S)去除 master 的污点
出于安全考虑,默认配置下Kubernetes不会将Pod调度到Master节点。如果希望将k8s-master也当作Node使用,可以执行如下命令:
kubectl taint node k8s-master node-role.kubernetes.io/master-
其中k8s-master是主机节点hostname如果要恢复Master Only状态,执行如下命令:
kubectl taint node k8s-master node-role.kubernetes.io/master=""