Docker和K8S简介和安装部署

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网络的非常有用的工具,它可以显示路由表、实际的网络连接以及每一个网络接口设备的状态信息。

  1. -n或–numeric:直接使用ip地址,而不通过域名服务器;
  2. -a或–all:显示所有连线中的Socket;
  3. -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=""

   转载规则


《Docker和K8S简介和安装部署》 锦泉 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录