Ansible一键安装Harbor服务_云原生


环境说明

企业内网环境,使用docker-compose的方式安装Harbor服务,需要先安装docker、docker-compose两个服务,将以二进制的方式安装docker和docker-compose,以适配各种安装环境。

  • docker版本:20.10.21,建议使用20.10以上的版本,低版本的会出现安装异常;
  • Docker-compose版本:2.24.7
  • Harbor版本:2.10.3

一、编写ansible role

1.1 初始化ansible role

使用ansible-galaxy init命令初始化一个安装harbor的ansible role。

$ ansible-galaxy init /etc/ansible/roles/harbor-install

1.2 设置环境变量

通过环境变量的方式自定义安装环境,使用时候修改对应环境变量的值即可。

$ cat roles/harbor-install/vars/main.yml
---
# vars file for harbor-install
DOCKER_VERSION: "20.10.21"  #docker服务版本
HARBOR_VERSION: 2.10.3     #harbor服务版本
INSTALL_PATH: /app         #安装目录
HTTP_PORT: 8888            #harbor服务端口(http)
HTTPS_PORT:                #harbor服务端口(https)
DATA_PATH: /app/data       #harbor数据目录,规划好大小

1.3 下载文件

因为考虑到企业内网环境,提前将对应版本的安装包下载好放到roles/harbor-install/files/目录下。

$ wget -c https://download.docker.com/linux/static/stable/x86_64/docker-20.10.21.tgz
$ wget -c https://github.com/docker/compose/releases/download/v2.24.7/docker-compose-linux-x86_64
$ wget -c https://github.com/goharbor/harbor/releases/download/v2.10.3/harbor-offline-installer-v2.10.3.tgz

1.4 创建服务启动文件

安装harbor时依赖docker和containerd两个服务,将服务启动文件写好放到role/harbor-install/files/目录下。

  • 创建containerd服务启动文件
$ cat role/harbor-install/files/containerd.service
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target

[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/bin/containerd

Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=1048576
TasksMax=infinity
OOMScoreAdjust=-999

[Install]
WantedBy=multi-user.target
  • 创建docker启动文件
$ cat role/harbor-install/files/docker.service
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target docker.socket firewalld.service containerd.service time-set.target
Wants=network-online.target containerd.service
Requires=docker.socket

[Service]
Type=notify
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutStartSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
KillMode=process
OOMScoreAdjust=-500

[Install]
WantedBy=multi-user.target

Ansible一键安装Harbor服务_云原生_02

1.5 创建Harbor配置文件模块

使用jinjia2模板文件来更具环境变量来自动生成Harbor的配置文件。

$ cat /etc/ansible/roles/harbor-install/templates/harbor.yml.j2
# Configuration file of Harbor

# The IP address or hostname to access admin UI and registry service.
# DO NOT use localhost or 127.0.0.1, because Harbor needs to be accessed by external clients.
hostname: {{ ansible_host }}

# http related config
http:
  # port for http, default is 80. If https enabled, this port will redirect to https port
  port: {{ HTTP_PORT }}

# https related config
#https:
  # https port for harbor, default is 443
  #port: 443
  # The path of cert and key files for nginx
  #certificate: /your/certificate/path
  #private_key: /your/private/key/path
  # enable strong ssl ciphers (default: false)
  # strong_ssl_ciphers: false

# # Uncomment following will enable tls communication between all harbor components
# internal_tls:
#   # set enabled to true means internal tls is enabled
#   enabled: true
#   # put your cert and key files on dir
#   dir: /etc/harbor/tls/internal


# Uncomment external_url if you want to enable external proxy
# And when it enabled the hostname will no longer used
# external_url: https://reg.mydomain.com:8433
external_url: http://{{ ansible_host }}:{{ HTTP_PORT }}

# The initial password of Harbor admin
# It only works in first time to install harbor
# Remember Change the admin password from UI after launching Harbor.
harbor_admin_password: Harbor12345

...
#以下内容根据实际情况调整,本处保持默认的配置。

1.6 编写tasks文件

main.yml入口引用相关的tasks部署任务文件。

Ansible一键安装Harbor服务_云原生_03

$ cat roles/harbor-install/tasks/main.yml
---
- include_tasks: host-init.yml
- include_tasks: install-docker.yml
- include_tasks: harbor-install.yml

1)编写主机初始化的tasks

$ cat roles/harbor-install/tasks/host-init.yml
---
#主机初始化配置

- name: "关闭SELinux(临时)"
  selinux:
    state: disabled

- name: "关闭SELinux(永久)"
  lineinfile:
    path: /etc/selinux/config
    regexp: '^SELINUX='
    line: 'SELINUX=disabled'
    create: yes

- name: "停止firewalld"
  service:
    name: firewalld
    state: stopped
    enabled: no
  ignore_errors: yes

- name: "停止iptables"
  service:
    name: iptables
    state: stopped
    enabled: no
  ignore_errors: yes

- name: "加载内核模块"
  shell: 
    cmd: "modprobe br_netfilter"

- name: "设置内核参数(必须)"
  sysctl:
    name: "{{ item.key }}"
    value: "{{ item.value }}"
    sysctl_set: yes
    state: present
    reload: yes
  loop: 
    - { key: 'net.ipv4.ip_forward', value: '1' }
    - { key: 'net.bridge.bridge-nf-call-iptables', value: '1' }
    - { key: 'net.bridge.bridge-nf-call-ip6tables', value: '1' }

- name: "创建安装目录"
  file: 
    path: "{{ INSTALL_PATH }}"
    state: directory
  • 2)编写安装docker的tasks

编写一个tasks任务,用于二进制安装containerd、docker和docker-compose服务。

$ cat roles/harbor-install/tasks/install-docker.yml 
#二进制方式安装docker-ce、docker-compose 
---
#当docker命令返回非零状态码时,即未安装时执行安装docker任务
- name: "检查docker是否安装"
  shell: docker --version
  register: docker_version
  ignore_errors: true

- name: "若未安装docker则安装(二进制)"
  when: docker_version.rc != 0
  block:
  - name: "分发docker-ce离线二进制安装包" 
    unarchive:
      src: "docker-{{ DOCKER_VERSION }}.tgz"
      dest: "{{ INSTALL_PATH }}/"
      mode: 0755

  - name: "复制二进制文件到/usr/bin/下"
    copy: 
      src: "{{ INSTALL_PATH }}/docker/{{ item }}"
      dest: "/usr/bin/" 
      mode: '0755'
      remote_src: yes
    loop:
    - containerd
    - containerd-shim
    - containerd-shim-runc-v2
    - ctr
    - docker 
    - dockerd
    - docker-init
    - docker-proxy
    - runc

  - name: "清理安装包"
    file: 
      path: "{{ INSTALL_PATH }}/docker"
      state: absent

  #- name: "分发docker配置文件"
  #  copy:
  #    src: daemon.json
  #    dest: /etc/docker/
  #    mode: '0755'

  - name: "分发docker.socket文件(必需)"
    copy: 
      dest: /usr/lib/systemd/system/docker.socket
      mode: '0644'
      content: |
        [Unit]
        Description=Docker Socket for the API
        [Socket]
        ListenStream=/var/run/docker.sock
        SocketMode=0660
        SocketUser=root
        SocketGroup=docker
        [Install]
        WantedBy=sockets.target

  - name: "分发containerd服务启动文件"
    copy: 
      src: containerd.service
      dest: /usr/lib/systemd/system/containerd.service
      mode: '0644'

  - name: "分发docker服务启动文件"
    copy: 
      src: docker.service
      dest: /usr/lib/systemd/system/docker.service
      mode: '0644'

  - name: "创建docker用户组"
    group:
      name: docker
      state: present
      #system: yes
      #create_home: no
  
  - name: "启动docker服务"
    service: 
      name: docker
      state: started
      enabled: yes
      daemon_reload: yes

- name: "安装docker-compose(二进制)"
  copy:
    src: docker-compose-linux-x86_64
    dest: /usr/local/bin/docker-compose
    mode: '0755'
  • 3)编写安装harbor的tasks文件
$ cat roles/harbor-install/tasks/harbor-install.yml 
---
- name: "创建数据目录"
  file: 
    path: "{{ DATA_PATH }}"
    state: directory

- name: "分发离线安装包"
  unarchive:
    src: "harbor-offline-installer-v{{ HARBOR_VERSION }}.tgz"
    dest: "{{ INSTALL_PATH }}"

- name: "分发配置文件"
  template:
    src: harbor.yml.j2
    dest: "{{ INSTALL_PATH }}/harbor/harbor.yml"

- name: "导入镜像 <docker load  -i xxx.tar.gz>"
  shell:
    cmd: "docker load  -i harbor.v{{ HARBOR_VERSION }}.tar.gz "
    chdir: "{{ INSTALL_PATH }}/harbor"

- name: "将配置文件注入到组件中 <./prepare>"
  shell:
    cmd: "./prepare"
    chdir: "{{ INSTALL_PATH }}/harbor"

- name: "安装并启动服务 <./install.sh --with-trivy>"
  shell:
    cmd: "./install.sh --with-trivy"
    chdir: "{{ INSTALL_PATH }}/harbor"

- name: "查看服务状态<docker-compose ps>"
  shell:
    cmd: docker-compose ps
    chdir: "{{ INSTALL_PATH }}/harbor"
  register: docker_compose_output
 
- debug:
     msg: "{{ docker_compose_output.stdout }}"

至此,部署harbor的ansible role编写就完成了,下面说明如何使用。

二、ansible部署Harbor

使用前面创建好的ansible role来部署Harbor镜像仓库服务。

2.1 创建ansible plabook

$ cat Plabooks/harbor-deploy.yml
---
- hosts: lidabai       #指定部署Harbor的主机
  become: yes
  roles:
  - harbor-install    #调用安装harbor的ansible role

2.2 执行ansible plabook任务

$ ansible-plabook Plabooks/harbor-deploy.yml
[root@lidabai-console ansible]# ansible-playbook Plabooks/harbor-deploy.yml

PLAY [lidabai] ****************************************************************************************************************************************************

TASK [Gathering Facts] ********************************************************************************************************************************************
ok: [192.168.2.201]

TASK [harbor-install : include_tasks] *****************************************************************************************************************************
included: /etc/ansible/roles/harbor-install/tasks/host-init.yml for 192.168.2.201

TASK [harbor-install : 关闭SELinux(临时)] *****************************************************************************************************************************
ok: [192.168.2.201]

TASK [harbor-install : 关闭SELinux(永久)] *****************************************************************************************************************************
ok: [192.168.2.201]

TASK [harbor-install : 停止firewalld] *******************************************************************************************************************************
fatal: [192.168.2.201]: FAILED! => {"changed": false, "msg": "Could not find the requested service firewalld: host"}
...ignoring

TASK [harbor-install : 停止iptables] ********************************************************************************************************************************
fatal: [192.168.2.201]: FAILED! => {"changed": false, "msg": "Could not find the requested service iptables: host"}
...ignoring

TASK [harbor-install : 加载内核模块] ************************************************************************************************************************************
changed: [192.168.2.201]

TASK [harbor-install : 设置内核参数(必须)] ********************************************************************************************************************************
ok: [192.168.2.201] => (item={u'value': u'1', u'key': u'net.ipv4.ip_forward'})
ok: [192.168.2.201] => (item={u'value': u'1', u'key': u'net.bridge.bridge-nf-call-iptables'})
ok: [192.168.2.201] => (item={u'value': u'1', u'key': u'net.bridge.bridge-nf-call-ip6tables'})

TASK [harbor-install : 创建安装目录] ************************************************************************************************************************************
changed: [192.168.2.201]

TASK [harbor-install : include_tasks] *****************************************************************************************************************************
included: /etc/ansible/roles/harbor-install/tasks/install-docker.yml for 192.168.2.201

TASK [harbor-install : 检查docker是否安装] ******************************************************************************************************************************
fatal: [192.168.2.201]: FAILED! => {"changed": true, "cmd": "docker --version", "delta": "0:00:00.018281", "end": "2024-08-16 14:26:47.562401", "msg": "non-zero return code", "rc": 127, "start": "2024-08-16 14:26:47.544120", "stderr": "/bin/sh: docker: 未找到命令", "stderr_lines": ["/bin/sh: docker: 未找到命令"], "stdout": "", "stdout_lines": []}
...ignoring

TASK [harbor-install : 分发docker-ce离线二进制安装包] ***********************************************************************************************************************
changed: [192.168.2.201]

TASK [harbor-install : 复制二进制文件到/usr/bin/下] ************************************************************************************************************************
ok: [192.168.2.201] => (item=containerd)
ok: [192.168.2.201] => (item=containerd-shim)
ok: [192.168.2.201] => (item=containerd-shim-runc-v2)
ok: [192.168.2.201] => (item=ctr)
changed: [192.168.2.201] => (item=docker)
changed: [192.168.2.201] => (item=dockerd)
ok: [192.168.2.201] => (item=docker-init)
changed: [192.168.2.201] => (item=docker-proxy)
ok: [192.168.2.201] => (item=runc)

TASK [harbor-install : 清理安装包] *************************************************************************************************************************************
changed: [192.168.2.201]

TASK [harbor-install : 分发docker.socket文件(必需)] *********************************************************************************************************************
changed: [192.168.2.201]

TASK [harbor-install : 分发containerd服务启动文件] ************************************************************************************************************************
ok: [192.168.2.201]

TASK [harbor-install : 分发docker服务启动文件] ****************************************************************************************************************************
changed: [192.168.2.201]

TASK [harbor-install : 创建docker用户组] *******************************************************************************************************************************
ok: [192.168.2.201]

TASK [harbor-install : 启动docker服务] ********************************************************************************************************************************
changed: [192.168.2.201]

TASK [harbor-install : 安装docker-compose(二进制)] *********************************************************************************************************************
ok: [192.168.2.201]

TASK [harbor-install : include_tasks] *****************************************************************************************************************************
included: /etc/ansible/roles/harbor-install/tasks/harbor-install.yml for 192.168.2.201

TASK [harbor-install : 创建数据目录] ************************************************************************************************************************************
changed: [192.168.2.201]

TASK [harbor-install : 分发离线安装包] ***********************************************************************************************************************************
changed: [192.168.2.201]

TASK [harbor-install : 分发配置文件] ************************************************************************************************************************************
changed: [192.168.2.201]

TASK [harbor-install : 导入镜像 <docker load  -i xxx.tar.gz>] *********************************************************************************************************
changed: [192.168.2.201]

TASK [harbor-install : 将配置文件注入到组件中 <./prepare>] *******************************************************************************************************************
changed: [192.168.2.201]

TASK [harbor-install : 安装并启动服务 <./install.sh --with-trivy>] *******************************************************************************************************
changed: [192.168.2.201]

TASK [harbor-install : 查看服务状态<docker-compose ps>] *****************************************************************************************************************
changed: [192.168.2.201]

TASK [harbor-install : debug] *************************************************************************************************************************************
ok: [192.168.2.201] => {
    "msg": "NAME                COMMAND                  SERVICE             STATUS               PORTS\nharbor-core         \"/harbor/entrypoint.…\"   core                running (starting)   \nharbor-db           \"/docker-entrypoint.…\"   postgresql          running (starting)   \nharbor-jobservice   \"/harbor/entrypoint.…\"   jobservice          restarting           \nharbor-log          \"/bin/sh -c /usr/loc…\"   log                 running (starting)   127.0.0.1:1514->10514/tcp\nharbor-portal       \"nginx -g 'daemon of…\"   portal              running (starting)   \nnginx               \"nginx -g 'daemon of…\"   proxy               running (starting)   0.0.0.0:8021->8080/tcp, :::8021->8080/tcp\nredis               \"redis-server /etc/r…\"   redis               running (starting)   \nregistry            \"/home/harbor/entryp…\"   registry            running (starting)   \nregistryctl         \"/home/harbor/start.…\"   registryctl         running (starting)   \ntrivy-adapter       \"/home/scanner/entry…\"   trivy-adapter       running (starting)   "
}

PLAY RECAP ********************************************************************************************************************************************************
192.168.2.201              : ok=29   changed=16   unreachable=0    failed=0    skipped=0    rescued=0    ignored=3

部署完成!

Ansible一键安装Harbor服务_云原生_04

Ps: 本篇文章提供word文档及写好的ansible role。