Post

AEWS 8์ฃผ์ฐจ ์ •๋ฆฌ

๐Ÿ”ง ์‹ค์Šตํ™˜๊ฒฝ ๊ตฌ์„ฑ

1. docker-compose-plugin ์„ค์น˜ - x86_64

1
2
3
4
sudo mkdir -p /usr/local/lib/docker/cli-plugins
sudo curl -SL https://github.com/docker/compose/releases/latest/download/docker-compose-linux-x86_64 -o /usr/local/lib/docker/cli-plugins/docker-compose
sudo chmod +x /usr/local/lib/docker/cli-plugins/docker-compose
docker compose version

2. ์ž‘์—… ๋””๋ ‰ํ† ๋ฆฌ ์ƒ์„ฑ ํ›„ ์ด๋™

1
2
mkdir cicd-labs
cd cicd-labs

3. Docker Compose ํŒŒ์ผ ์ƒ์„ฑ ํŒŒ์ผ ์ƒ์„ฑ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
cat <<EOT > docker-compose.yaml
services:

  jenkins:
    container_name: jenkins
    image: jenkins/jenkins
    restart: unless-stopped
    networks:
      - cicd-network
    ports:
      - "8080:8080"
      - "50000:50000"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - jenkins_home:/var/jenkins_home

  gogs:
    container_name: gogs
    image: gogs/gogs
    restart: unless-stopped
    networks:
      - cicd-network
    ports:
      - "10022:22"
      - "3000:3000"
    volumes:
      - gogs-data:/data

volumes:
  jenkins_home:
  gogs-data:

networks:
  cicd-network:
    driver: bridge
EOT

4. Docker Compose ์‹คํ–‰

1
docker compose up -d

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
[+] Running 21/21
 โœ” jenkins Pulled                                                                                                                           20.4s 
   โœ” 7cd785773db4 Pull complete                                                                                                              9.6s 
   โœ” 4323b613447d Pull complete                                                                                                             11.4s 
   โœ” eec1952536a9 Pull complete                                                                                                             11.6s 
   โœ” b9fcd549558d Pull complete                                                                                                             11.6s 
   โœ” 743c1c69eb66 Pull complete                                                                                                             11.6s 
   โœ” 2b005e8acf52 Pull complete                                                                                                             15.3s 
   โœ” e7e22a1da8f6 Pull complete                                                                                                             15.4s 
   โœ” 5daee7ea5eb6 Pull complete                                                                                                             15.5s 
   โœ” bbb418a8a466 Pull complete                                                                                                             17.0s 
   โœ” ccfc3f9a95cb Pull complete                                                                                                             17.0s 
   โœ” b6a32e0eef53 Pull complete                                                                                                             17.0s 
   โœ” 5faefa2d0cdc Pull complete                                                                                                             17.0s 
 โœ” gogs Pulled                                                                                                                              22.8s 
   โœ” f18232174bc9 Pull complete                                                                                                             14.2s 
   โœ” b6b017e7a7f5 Pull complete                                                                                                             16.8s 
   โœ” c80b57c5e4ee Pull complete                                                                                                             16.8s 
   โœ” 1760f004baf4 Pull complete                                                                                                             16.8s 
   โœ” 629cc8eb21da Pull complete                                                                                                             16.9s 
   โœ” 894de22ca6a0 Pull complete                                                                                                             19.3s 
   โœ” af5aa0b7df25 Pull complete                                                                                                             19.4s 
[+] Running 5/5
 โœ” Network cicd-labs_cicd-network   Created                                                                                                  0.0s 
 โœ” Volume "cicd-labs_gogs-data"     Created                                                                                                  0.0s 
 โœ” Volume "cicd-labs_jenkins_home"  Created                                                                                                  0.0s 
 โœ” Container gogs                   Started                                                                                                  0.2s 
 โœ” Container jenkins                Started                                                                                                  0.2s 

5. ์ปจํ…Œ์ด๋„ˆ ์ƒํƒœ ํ™•์ธ

1
docker compose ps

โœ…ย ์ถœ๋ ฅ

1
2
3
NAME      IMAGE             COMMAND                  SERVICE   CREATED          STATUS                             PORTS
gogs      gogs/gogs         "/app/gogs/docker/stโ€ฆ"   gogs      12 seconds ago   Up 12 seconds (health: starting)   0.0.0.0:3000->3000/tcp, [::]:3000->3000/tcp, 0.0.0.0:10022->22/tcp, [::]:10022->22/tcp
jenkins   jenkins/jenkins   "/usr/bin/tini -- /uโ€ฆ"   jenkins   12 seconds ago   Up 12 seconds                      0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp, 0.0.0.0:50000->50000/tcp, [::]:50000->50000/tcp

6. ์ปจํ…Œ์ด๋„ˆ ๊ธฐ๋ณธ ์ •๋ณด ํ™•์ธ

1
for i in gogs jenkins ; do echo ">> container : $i <<"; docker compose exec $i sh -c "whoami && pwd"; echo; done

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
>> container : gogs <<
root
/app/gogs

>> container : jenkins <<
jenkins
/

7. ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€ ์ ‘์† ๋ฐ ์ข…๋ฃŒ

1
2
3
4
docker compose exec jenkins bash

jenkins@12f4b7ed7515:/$ exit
exit
1
2
3
4
docker compose exec gogs bash

a0dda4a63d1b:/app/gogs# exit
exit

8. Jenkins ์ดˆ๊ธฐ ์•”ํ˜ธ ํ™•์ธ

1
docker compose exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

โœ…ย ์ถœ๋ ฅ

1
57a5b0cc2ff2402ba1ccb00d8fda37f0

9. Jenkins ์›น ์ดˆ๊ธฐ ์„ค์ • ์ง„ํ–‰

(1) http://127.0.0.1:8080 ์ ‘์† ํ›„, ์ดˆ๊ธฐ ์•”ํ˜ธ ์ž…๋ ฅ

(2) Install suggested plugins

(3) ๊ธฐ๋ณธ ๊ด€๋ฆฌ์ž ๊ณ„์ • (admin / qwe123) ์„ค์ •

(4) IP ํ™•์ธ ๋ฐ ์„ค์ •

1
ifconfig | grep 192.168.

โœ…ย ์ถœ๋ ฅ

1
2
        inet 192.168.122.1  netmask 255.255.255.0  broadcast 192.168.122.255
        inet 192.168.219.103  netmask 255.255.255.0  broadcast 192.168.219.255

(5) http://192.168.219.103:8080 ์ ‘์† ํ›„, ๋กœ๊ทธ์ธ (admin / qwe123)


๐Ÿณ Jenkins ์ปจํ…Œ์ด๋„ˆ์—์„œ ํ˜ธ์ŠคํŠธ์— ๋„์ปค ๋ฐ๋ชฌ ์‚ฌ์šฉ ์„ค์ •

1. Jenkins ์ปจํ…Œ์ด๋„ˆ์— root ๊ด€๋ฆฌ์ž ๊ถŒํ•œ์œผ๋กœ ์ ‘์†

1
2
3
4
docker compose exec --privileged -u root jenkins bash

# ๊ฒฐ๊ณผ
root@12f4b7ed7515:/# 

2. Docker CLI ์„ค์น˜ ๋ฐ ํ™˜๊ฒฝ ๊ตฌ์„ฑ

1
2
3
4
5
6
7
8
9
root@12f4b7ed7515:/# id

curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update && apt install docker-ce-cli curl tree jq yq -y

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
uid=0(root) gid=0(root) groups=0(root)
Get:1 http://deb.debian.org/debian bookworm InRelease [151 kB]
Get:2 http://deb.debian.org/debian bookworm-updates InRelease [55.4 kB]                
Get:3 http://deb.debian.org/debian-security bookworm-security InRelease [48.0 kB]
Get:4 https://download.docker.com/linux/debian bookworm InRelease [47.0 kB]
Get:5 http://deb.debian.org/debian bookworm/main amd64 Packages [8792 kB]
Get:6 https://download.docker.com/linux/debian bookworm/stable amd64 Packages [38.1 kB]
Get:7 http://deb.debian.org/debian bookworm-updates/main amd64 Packages [512 B]
Get:8 http://deb.debian.org/debian-security bookworm-security/main amd64 Packages [250 kB]
Fetched 9382 kB in 1s (7293 kB/s)                         
Reading package lists... Done
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
curl is already the newest version (7.88.1-10+deb12u12).
The following additional packages will be installed:
  docker-buildx-plugin docker-compose-plugin libjq1 libnsl2 libonig5 libpython3-stdlib libpython3.11-minimal libpython3.11-stdlib
  libtirpc-common libtirpc3 libyaml-0-2 media-types python3 python3-argcomplete python3-importlib-metadata python3-minimal
  python3-more-itertools python3-toml python3-typing-extensions python3-xmltodict python3-yaml python3-zipp python3.11 python3.11-minimal
Suggested packages:
  python3-doc python3-tk python3-venv python3.11-venv python3.11-doc binutils binfmt-support
The following NEW packages will be installed:
  docker-buildx-plugin docker-ce-cli docker-compose-plugin jq libjq1 libnsl2 libonig5 libpython3-stdlib libpython3.11-minimal
  libpython3.11-stdlib libtirpc-common libtirpc3 libyaml-0-2 media-types python3 python3-argcomplete python3-importlib-metadata python3-minimal
  python3-more-itertools python3-toml python3-typing-extensions python3-xmltodict python3-yaml python3-zipp python3.11 python3.11-minimal tree
  yq
0 upgraded, 28 newly installed, 0 to remove and 1 not upgraded.
Need to get 71.5 MB of archives.
After this operation, 240 MB of additional disk space will be used.
Get:1 http://deb.debian.org/debian bookworm/main amd64 libpython3.11-minimal amd64 3.11.2-6+deb12u5 [816 kB]
Get:2 https://download.docker.com/linux/debian bookworm/stable amd64 docker-buildx-plugin amd64 0.22.0-1~debian.12~bookworm [35.3 MB]
Get:3 http://deb.debian.org/debian bookworm/main amd64 python3.11-minimal amd64 3.11.2-6+deb12u5 [2067 kB]
Get:4 http://deb.debian.org/debian bookworm/main amd64 python3-minimal amd64 3.11.2-1+b1 [26.3 kB]
Get:5 http://deb.debian.org/debian bookworm/main amd64 media-types all 10.0.0 [26.1 kB]
Get:6 http://deb.debian.org/debian bookworm/main amd64 libtirpc-common all 1.3.3+ds-1 [14.0 kB]
Get:7 http://deb.debian.org/debian bookworm/main amd64 libtirpc3 amd64 1.3.3+ds-1 [85.2 kB]
Get:8 http://deb.debian.org/debian bookworm/main amd64 libnsl2 amd64 1.3.0-2 [39.5 kB]
Get:9 http://deb.debian.org/debian bookworm/main amd64 libpython3.11-stdlib amd64 3.11.2-6+deb12u5 [1797 kB]
Get:10 http://deb.debian.org/debian bookworm/main amd64 python3.11 amd64 3.11.2-6+deb12u5 [573 kB]
Get:11 http://deb.debian.org/debian bookworm/main amd64 libpython3-stdlib amd64 3.11.2-1+b1 [9312 B]
Get:12 http://deb.debian.org/debian bookworm/main amd64 python3 amd64 3.11.2-1+b1 [26.3 kB]
Get:13 http://deb.debian.org/debian bookworm/main amd64 libonig5 amd64 6.9.8-1 [188 kB]
Get:14 http://deb.debian.org/debian bookworm/main amd64 libjq1 amd64 1.6-2.1 [135 kB]
Get:15 http://deb.debian.org/debian bookworm/main amd64 jq amd64 1.6-2.1 [64.9 kB]
Get:16 http://deb.debian.org/debian bookworm/main amd64 libyaml-0-2 amd64 0.2.5-1 [53.6 kB]
Get:17 http://deb.debian.org/debian bookworm/main amd64 python3-typing-extensions all 4.4.0-1 [45.2 kB]
Get:18 http://deb.debian.org/debian bookworm/main amd64 python3-more-itertools all 8.10.0-2 [53.0 kB]
Get:19 http://deb.debian.org/debian bookworm/main amd64 python3-zipp all 1.0.0-6 [6696 B]      
Get:20 http://deb.debian.org/debian bookworm/main amd64 python3-importlib-metadata all 4.12.0-1 [24.9 kB]
Get:21 http://deb.debian.org/debian bookworm/main amd64 python3-argcomplete all 2.0.0-1 [34.7 kB]   
Get:22 http://deb.debian.org/debian bookworm/main amd64 python3-toml all 0.10.2-1 [16.2 kB] 
Get:23 http://deb.debian.org/debian bookworm/main amd64 python3-xmltodict all 0.13.0-1 [16.7 kB]
Get:24 http://deb.debian.org/debian bookworm/main amd64 python3-yaml amd64 6.0-3+b2 [119 kB]
Get:25 http://deb.debian.org/debian bookworm/main amd64 tree amd64 2.1.0-1 [52.5 kB]
Get:26 http://deb.debian.org/debian bookworm/main amd64 yq all 3.1.0-3 [19.2 kB]
Get:27 https://download.docker.com/linux/debian bookworm/stable amd64 docker-ce-cli amd64 5:28.0.4-1~debian.12~bookworm [15.8 MB]
Get:28 https://download.docker.com/linux/debian bookworm/stable amd64 docker-compose-plugin amd64 2.34.0-1~debian.12~bookworm [14.1 MB]
Fetched 71.5 MB in 4s (18.9 MB/s)                 
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package libpython3.11-minimal:amd64.
(Reading database ... 10537 files and directories currently installed.)
Preparing to unpack .../libpython3.11-minimal_3.11.2-6+deb12u5_amd64.deb ...
Unpacking libpython3.11-minimal:amd64 (3.11.2-6+deb12u5) ...
Selecting previously unselected package python3.11-minimal.
Preparing to unpack .../python3.11-minimal_3.11.2-6+deb12u5_amd64.deb ...
Unpacking python3.11-minimal (3.11.2-6+deb12u5) ...
Setting up libpython3.11-minimal:amd64 (3.11.2-6+deb12u5) ...
Setting up python3.11-minimal (3.11.2-6+deb12u5) ...
Selecting previously unselected package python3-minimal.
(Reading database ... 10844 files and directories currently installed.)
Preparing to unpack .../0-python3-minimal_3.11.2-1+b1_amd64.deb ...
Unpacking python3-minimal (3.11.2-1+b1) ...
Selecting previously unselected package media-types.
Preparing to unpack .../1-media-types_10.0.0_all.deb ...
Unpacking media-types (10.0.0) ...
....

3. ์„ค์น˜ ํ™•์ธ ๋ฐ ๋„์ปค ์ •๋ณด ๊ฒ€์ฆ

(1) ๋„์ปค ํด๋ผ์ด์–ธํŠธ ๋ฐ ์„œ๋ฒ„ ์ •๋ณด ํ™•์ธ

1
root@12f4b7ed7515:/# docker info

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Client: Docker Engine - Community
 Version:    28.0.4
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.22.0
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.34.0
    Path:     /usr/libexec/docker/cli-plugins/docker-compose

Server:
 Containers: 5
  Running: 5
  Paused: 0
  Stopped: 0
 Images: 6
 Server Version: 28.0.1
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Using metacopy: true
  Native Overlay Diff: false
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: systemd
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 1a43cb6a1035441f9aca8f5666a9b3ef9e70ab20.m
 runc version: 
 init version: de40ad0
 Security Options:
  seccomp
   Profile: builtin
  cgroupns
 Kernel Version: 6.13.7-arch1-1
 Operating System: Arch Linux
 OSType: linux
 Architecture: x86_64
 CPUs: 18
 Total Memory: 30.9GiB
 Name: gram88
 ID: 7b6ceb90-0683-4037-a905-12f0f9197c48
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Experimental: false
 Insecure Registries:
  ::1/128
  127.0.0.0/8
 Live Restore Enabled: false

(2) ์‹คํ–‰ ์ค‘์ธ ์ปจํ…Œ์ด๋„ˆ ๋ชฉ๋ก ์กฐํšŒ

1
root@12f4b7ed7515:/# docker ps

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
CONTAINER ID   IMAGE                  COMMAND                  CREATED          STATUS                    PORTS                                                                                          NAMES
12f4b7ed7515   jenkins/jenkins        "/usr/bin/tini -- /uโ€ฆ"   25 minutes ago   Up 25 minutes             0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp, 0.0.0.0:50000->50000/tcp, [::]:50000->50000/tcp   jenkins
a0dda4a63d1b   gogs/gogs              "/app/gogs/docker/stโ€ฆ"   25 minutes ago   Up 25 minutes (healthy)   0.0.0.0:3000->3000/tcp, [::]:3000->3000/tcp, 0.0.0.0:10022->22/tcp, [::]:10022->22/tcp         gogs
0730dcf6eb6f   kindest/node:v1.30.4   "/usr/local/bin/entrโ€ฆ"   2 days ago       Up 50 minutes                                                                                                            myk8s-worker
720250bf1479   kindest/node:v1.30.4   "/usr/local/bin/entrโ€ฆ"   2 days ago       Up 50 minutes                                                                                                            myk8s-worker2
12914ca62737   kindest/node:v1.30.4   "/usr/local/bin/entrโ€ฆ"   2 days ago       Up 50 minutes             0.0.0.0:30000-30002->30000-30002/tcp, 127.0.0.1:44509->6443/tcp                                myk8s-control-plane

(3) ๋„์ปค ์‹คํ–‰ ํŒŒ์ผ ์œ„์น˜ ํ™•์ธ

1
root@12f4b7ed7515:/# which docker

โœ…ย ์ถœ๋ ฅ

1
/usr/bin/docker

4. Jenkins ์œ ์ €์— ๋Œ€ํ•œ Docker ์‹คํ–‰ ๊ถŒํ•œ ๋ถ€์—ฌ

1
2
3
4
5
6
7
8
9
10
11
12
13
root@12f4b7ed7515:/# groupadd -g 1001 -f docker
root@12f4b7ed7515:/# chgrp docker /var/run/docker.sock

root@12f4b7ed7515:/# ls -l /var/run/docker.sock
srw-rw---- 1 root docker 0 Mar 29 02:44 /var/run/docker.sock

root@12f4b7ed7515:/# usermod -aG docker jenkins

root@12f4b7ed7515:/# cat /etc/group | grep docker
docker:x:1001:jenkins

root@12f4b7ed7515:/# exit
exit

5. Jenkins ์ปจํ…Œ์ด๋„ˆ ์žฌ๊ธฐ๋™

1
docker compose restart jenkins

โœ…ย ์ถœ๋ ฅ

1
2
[+] Restarting 1/1
 โœ” Container jenkins  Started    

6. Jenkins ์ปจํ…Œ์ด๋„ˆ ๋‚ด ๋„์ปค ํ™˜๊ฒฝ ์ƒํƒœ ๋ฐ ์‚ฌ์šฉ์ž ๊ถŒํ•œ ์ ๊ฒ€

(1) Jenkins ์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€ ์‚ฌ์šฉ์ž ๋ฐ ๊ถŒํ•œ ํ™•์ธ

1
docker compose exec jenkins id

โœ…ย ์ถœ๋ ฅ

1
uid=1000(jenkins) gid=1000(jenkins) groups=1000(jenkins),1001(docker)

(2) ๋„์ปค ์ •๋ณด ํ™•์ธ

1
docker compose exec jenkins docker info

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
Client: Docker Engine - Community
 Version:    28.0.4
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.22.0
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.34.0
    Path:     /usr/libexec/docker/cli-plugins/docker-compose

Server:
 Containers: 5
  Running: 5
  Paused: 0
  Stopped: 0
 Images: 6
 Server Version: 28.0.4
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Using metacopy: true
  Native Overlay Diff: false
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: systemd
 Cgroup Version: 2
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
 Swarm: inactive
 Runtimes: io.containerd.runc.v2 runc
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: 1a43cb6a1035441f9aca8f5666a9b3ef9e70ab20.m
 runc version: 
 init version: de40ad0
 Security Options:
  seccomp
   Profile: builtin
  cgroupns
 Kernel Version: 6.13.8-arch1-1
 Operating System: Arch Linux
 OSType: linux
 Architecture: x86_64
 CPUs: 18
 Total Memory: 30.9GiB
 Name: gram88
 ID: 7b6ceb90-0683-4037-a905-12f0f9197c48
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 Experimental: false
 Insecure Registries:
  ::1/128
  127.0.0.0/8
 Live Restore Enabled: false

(3) ์‹คํ–‰ ์ค‘์ธ ์ปจํ…Œ์ด๋„ˆ ๋ชฉ๋ก ํ™•์ธ

1
docker compose exec jenkins docker ps

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
CONTAINER ID   IMAGE                  COMMAND                  CREATED             STATUS                   PORTS                                                                                          NAMES
12f4b7ed7515   jenkins/jenkins        "/usr/bin/tini -- /uโ€ฆ"   About an hour ago   Up About a minute        0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp, 0.0.0.0:50000->50000/tcp, [::]:50000->50000/tcp   jenkins
a0dda4a63d1b   gogs/gogs              "/app/gogs/docker/stโ€ฆ"   About an hour ago   Up 5 minutes (healthy)   0.0.0.0:3000->3000/tcp, [::]:3000->3000/tcp, 0.0.0.0:10022->22/tcp, [::]:10022->22/tcp         gogs
0730dcf6eb6f   kindest/node:v1.30.4   "/usr/local/bin/entrโ€ฆ"   2 days ago          Up 5 minutes                                                                                                            myk8s-worker
720250bf1479   kindest/node:v1.30.4   "/usr/local/bin/entrโ€ฆ"   2 days ago          Up 5 minutes                                                                                                            myk8s-worker2
12914ca62737   kindest/node:v1.30.4   "/usr/local/bin/entrโ€ฆ"   2 days ago          Up 5 minutes             0.0.0.0:30000-30002->30000-30002/tcp, 127.0.0.1:44509->6443/tcp                                myk8s-control-plane

7. Gogs ์ดˆ๊ธฐ ์„ค์น˜ ์ ‘์† (http://127.0.0.1:3000/install)

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์œ ํ˜•: SQLite3

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ URL: 192.168.219.103

  • ๊ด€๋ฆฌ์ž ๊ณ„์ •: devops / qwe123

8. Gogs ํ† ํฐ ์ƒ์„ฑ ๋ฐ ์„ค์ •

  • ๋กœ๊ทธ์ธ ํ›„ โ€œYour Settingsโ€ โ†’ โ€œApplicationsโ€ ๋ฉ”๋‰ด๋กœ ์ด๋™
  • โ€œGenerate New Tokenโ€ ํด๋ฆญ ํ›„, Token ์ด๋ฆ„(ex. k8s-cicd) ์ž…๋ ฅ

  • โ€œGenerate Tokenโ€์„ ํด๋ฆญํ•˜์—ฌ ํ† ํฐ์„ ์ƒ์„ฑํ•˜๊ณ , ์ƒ์„ฑ๋œ ํ† ํฐ ๊ฐ’์„ ๋ฉ”๋ชจํ•ด๋‘ 

9. ๋‘ ๊ฐœ์˜ ๋ ˆํฌ์ง€ํ† ๋ฆฌ ์ƒ์„ฑ ๋ฐ ์„ค์ •

  • dev-app - ๊ฐœ๋ฐœํŒ€์šฉ

  • ops-deploy - ๋ฐ๋ธŒ์˜ต์ŠคํŒ€์šฉ


๐Ÿ“ Gogs ์‹ค์Šต์„ ์œ„ํ•œ ์ €์žฅ์†Œ ์„ค์ •

1. ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •

1
2
3
4
5
TOKEN=<๊ฐ์ž Gogs Token>
TOKEN=fef3afd3ae1c5e0869a5e6d3233ff0949f1e4e04

MyIP=<๊ฐ์ž ์ž์‹ ์˜ PC IP>
MyIP=192.168.219.103

2. ๊ฐœ๋ฐœํŒ€์šฉ ์ €์žฅ์†Œ ํด๋ก  ๋ฐ Git ์ดˆ๊ธฐ ์„ค์ •

(1) Gogs์— ์ƒ์„ฑ๋œ ๊ฐœ๋ฐœํŒ€์šฉ ์ €์žฅ์†Œ(dev-app) ํด๋ก 

1
2
3
4
5
6
7
8
9
git clone http://devops:$TOKEN@$MyIP:3000/devops/dev-app.git

# ๊ฒฐ๊ณผ
Cloning into 'dev-app'...
remote: Enumerating objects: 4, done.
remote: Counting objects: 100% (4/4), done.
remote: Compressing objects: 100% (3/3), done.
remote: Total 4 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
Unpacking objects: 100% (4/4), 692 bytes | 692.00 KiB/s, done.

(2) ํด๋ก  ํ›„ ์ž‘์—… ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ด๋™

1
cd dev-app

(3) ๋กœ์ปฌ Git ์„ค์ • ๋ณ€๊ฒฝ

1
2
3
4
5
6
git --no-pager config --local --list
git config --local user.name "devops"
git config --local user.email "abc@abc.com"
git config --local init.defaultBranch main
git config --local credential.helper store
git --no-pager config --local --list

(4) .git/config ํŒŒ์ผ ํ™•์ธ

1
cat .git/config

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
remote.origin.url=http://devops:fef3afd3ae1c5e0869a5e6d3233ff0949f1e4e04@192.168.219.103:3000/devops/dev-app.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.main.remote=origin
branch.main.merge=refs/heads/main
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
remote.origin.url=http://devops:fef3afd3ae1c5e0869a5e6d3233ff0949f1e4e04@192.168.219.103:3000/devops/dev-app.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.main.remote=origin
branch.main.merge=refs/heads/main
user.name=devops
user.email=abc@abc.com
init.defaultbranch=main
credential.helper=store
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[remote "origin"]
	url = http://devops:fef3afd3ae1c5e0869a5e6d3233ff0949f1e4e04@192.168.219.103:3000/devops/dev-app.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
	remote = origin
	merge = refs/heads/main
[user]
	name = devops
	email = abc@abc.com
[init]
	defaultBranch = main
[credential]
	helper = store

(5) ํ˜„์žฌ ๋ธŒ๋žœ์น˜ ๋ฐ ์›๊ฒฉ ์ •๋ณด ํ™•์ธ

1
2
git --no-pager branch
git remote -v

โœ…ย ์ถœ๋ ฅ

1
2
3
* main
origin	http://devops:fef3afd3ae1c5e0869a5e6d3233ff0949f1e4e04@192.168.219.103:3000/devops/dev-app.git (fetch)
origin	http://devops:fef3afd3ae1c5e0869a5e6d3233ff0949f1e4e04@192.168.219.103:3000/devops/dev-app.git (push)

3. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ ์ž‘์„ฑ ๋ฐ ํ…Œ์ŠคํŠธ

(1) server.py ํŒŒ์ผ ์ž‘์„ฑ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
cat > server.py <<EOF
from http.server import ThreadingHTTPServer, BaseHTTPRequestHandler
from datetime import datetime
import socket

class RequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        match self.path:
            case '/':
                now = datetime.now()
                hostname = socket.gethostname()
                response_string = now.strftime("The time is %-I:%M:%S %p, VERSION 0.0.1\n")
                response_string += f"Server hostname: {hostname}\n"                
                self.respond_with(200, response_string)
            case '/healthz':
                self.respond_with(200, "Healthy")
            case _:
                self.respond_with(404, "Not Found")

    def respond_with(self, status_code: int, content: str) -> None:
        self.send_response(status_code)
        self.send_header('Content-type', 'text/plain')
        self.end_headers()
        self.wfile.write(bytes(content, "utf-8")) 

def startServer():
    try:
        server = ThreadingHTTPServer(('', 80), RequestHandler)
        print("Listening on " + ":".join(map(str, server.server_address)))
        server.serve_forever()
    except KeyboardInterrupt:
        server.shutdown()

if __name__== "__main__":
    startServer()
EOF

(2) ์„œ๋ฒ„ ์‹คํ–‰ ๋ฐ ํ…Œ์ŠคํŠธ

1
2
3
sudo python3 server.py
curl localhost
curl localhost/healthz

4. Dockerfile ๋ฐ ๋ฒ„์ „ ํŒŒ์ผ ์ƒ์„ฑ

(1) Dockerfile ์ƒ์„ฑ

1
2
3
4
5
6
7
cat > Dockerfile <<EOF
FROM python:3.12
ENV PYTHONUNBUFFERED 1
COPY . /app
WORKDIR /app 
CMD python3 server.py
EOF

(2) VERSION ํŒŒ์ผ ์ƒ์„ฑ

1
echo "0.0.1" > VERSION

(3) ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ ํ™•์ธ

1
tree

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
.
โ”œโ”€โ”€ Dockerfile
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ server.py
โ””โ”€โ”€ VERSION

1 directory, 4 files

5. Git ์ปค๋ฐ‹ ๋ฐ ์›๊ฒฉ ์ €์žฅ์†Œ๋กœ ํ‘ธ์‹œ

(1) ๋ณ€๊ฒฝ ์‚ฌํ•ญ ํ™•์ธ

1
git status

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
On branch main
Your branch is up to date with 'origin/main'.

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	Dockerfile
	VERSION
	server.py

nothing added to commit but untracked files present (use "git add" to track)

(2) ์Šคํ…Œ์ด์ง•

1
git add .

(3) ์ปค๋ฐ‹

1
git commit -m "Add dev-app"

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
[main 99e9476] Add dev-app
 3 files changed, 40 insertions(+)
 create mode 100644 Dockerfile
 create mode 100644 VERSION
 create mode 100644 server.py

(4) ์ปค๋ฐ‹ ๋‚ด์šฉ์„ ์›๊ฒฉ ์ €์žฅ์†Œ์— ํ‘ธ์‹œํ•˜์—ฌ ๋ฐ˜์˜

1
git push -u origin main

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
Enumerating objects: 6, done.
Counting objects: 100% (6/6), done.
Delta compression using up to 18 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 1015 bytes | 1015.00 KiB/s, done.
Total 5 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To http://192.168.219.103:3000/devops/dev-app.git
   1b07e97..99e9476  main -> main
branch 'main' set up to track 'origin/main'.

6. Docker Hub ์ €์žฅ์†Œ ์ƒ์„ฑ ๋ฐ Personal Access Token(PAT) ๋ฐœ๊ธ‰

(1) ์ž์‹ ์˜ Docker Hub ๊ณ„์ •์— dev-app (Private) ์ €์žฅ์†Œ ์ƒ์„ฑ

(2) ๊ณ„์ • โ†’ Account settings

(3) Security โ†’ Personal access tokens โ†’ Generate new token

  • ๋งŒ๋ฃŒ์ผ(ํŽธํ•œ๋Œ€๋กœ), Access permissions(Read, Write, Delete)

  • ์ƒ์„ฑ๋œ ํ† ํฐ์„ ๋ฉ”๋ชจํ•˜์—ฌ ์ดํ›„ ์ธ์ฆ ๋ฐ ํ‘ธ์‹œ ์ž‘์—…์— ํ™œ์šฉ


๐Ÿš€ kind ๋กœ k8s ๋ฐฐํฌ

1. ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •

1
2
MyIP=<๊ฐ์ž ์ž์‹ ์˜ PC IP>
MyIP=192.168.219.103

2. ํด๋Ÿฌ์Šคํ„ฐ ๊ตฌ์„ฑ ํŒŒ์ผ ์ž‘์„ฑ

  • cicd-labs ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ์•„๋ž˜ ํŒŒ์ผ ์ž‘์„ฑ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
cd ..
cat > kind-3node.yaml <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
networking:
  apiServerAddress: "$MyIP"
nodes:
- role: control-plane
  extraPortMappings:
  - containerPort: 30000
    hostPort: 30000
  - containerPort: 30001
    hostPort: 30001
  - containerPort: 30002
    hostPort: 30002
  - containerPort: 30003
    hostPort: 30003
- role: worker
- role: worker
EOF

3. ํด๋Ÿฌ์Šคํ„ฐ ์ƒ์„ฑ

1
kind create cluster --config kind-3node.yaml --name myk8s --image kindest/node:v1.32.2

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Creating cluster "myk8s" ...
 โœ“ Ensuring node image (kindest/node:v1.32.2) ๐Ÿ–ผ 
 โœ“ Preparing nodes ๐Ÿ“ฆ ๐Ÿ“ฆ ๐Ÿ“ฆ  
 โœ“ Writing configuration ๐Ÿ“œ 
 โœ“ Starting control-plane ๐Ÿ•น๏ธ 
 โœ“ Installing CNI ๐Ÿ”Œ 
 โœ“ Installing StorageClass ๐Ÿ’พ 
 โœ“ Joining worker nodes ๐Ÿšœ 
Set kubectl context to "kind-myk8s"
You can now use your cluster with:

kubectl cluster-info --context kind-myk8s

Have a question, bug, or feature request? Let us know! https://kind.sigs.k8s.io/#community ๐Ÿ™‚

4. ๋…ธ๋“œ ๋ชฉ๋ก ํ™•์ธ

1
kind get nodes --name myk8s

โœ…ย ์ถœ๋ ฅ

1
2
3
myk8s-worker
myk8s-worker2
myk8s-control-plane

5. ๊ธฐ๋ณธ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ํ™œ์„ฑํ™”

1
kubens default

โœ…ย ์ถœ๋ ฅ

1
โœ” Active namespace is "default"

6. Docker ๋„คํŠธ์›Œํฌ ๋ชฉ๋ก ํ™•์ธ

(1) Docker ๋„คํŠธ์›Œํฌ ๋ชฉ๋ก ํ™•์ธ

1
docker network ls

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
NETWORK ID     NAME                     DRIVER    SCOPE
823451dd3cf5   bridge                   bridge    local
8dc45b4bfaf3   cicd-labs_cicd-network   bridge    local
bb4d74152d4a   host                     host      local
dbf072d0a217   kind                     bridge    local
056dcb2c01d1   none                     null      local

(2) kind ๋„คํŠธ์›Œํฌ ์ƒ์„ธ ์ •๋ณด ํ™•์ธ

1
docker inspect kind | jq

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
[
  {
    "Name": "kind",
    "Id": "dbf072d0a217f53e0b62f42cee01bcecc1b2f6ea216475178db001f2e38681f5",
    "Created": "2025-01-26T16:18:22.33980443+09:00",
    "Scope": "local",
    "Driver": "bridge",
    "EnableIPv4": true,
    "EnableIPv6": true,
    "IPAM": {
      "Driver": "default",
      "Options": {},
      "Config": [
        {
          "Subnet": "172.18.0.0/16",
          "Gateway": "172.18.0.1"
        },
        {
          "Subnet": "fc00:f853:ccd:e793::/64",
          "Gateway": "fc00:f853:ccd:e793::1"
        }
      ]
    },
    "Internal": false,
    "Attachable": false,
    "Ingress": false,
    "ConfigFrom": {
      "Network": ""
    },
    "ConfigOnly": false,
    "Containers": {
      "33b78e624fbd6ec1dc97e16c3a0accfb709d191ac8ebf2d3a632daaab2bfed7e": {
        "Name": "myk8s-worker2",
        "EndpointID": "2408ab1a6b39536a8ce5f13b1c65538e1093687cbe24e0d0605cfcd3c37e5fb8",
        "MacAddress": "7e:91:b1:5c:f9:f8",
        "IPv4Address": "172.18.0.3/16",
        "IPv6Address": "fc00:f853:ccd:e793::3/64"
      },
      "921a8848ddd4294e46a8e1531e206702b919d0f1e3d1fef1c7b621020b9ec05a": {
        "Name": "myk8s-worker",
        "EndpointID": "4757fa8c31137275765f9f9558975032574808b70c2d2c55256aae4b0fa22c2a",
        "MacAddress": "d6:1f:1a:3b:8f:15",
        "IPv4Address": "172.18.0.2/16",
        "IPv6Address": "fc00:f853:ccd:e793::2/64"
      },
      "f4b058d07f4a2710b835d42a1d8499d43b7f26c7f737735010ab0d1587cf3373": {
        "Name": "myk8s-control-plane",
        "EndpointID": "e2c1ffbc055525505bb4ed6c8a84261cdaaa2f829b135a099c21dafe363ded1c",
        "MacAddress": "e6:5f:e9:6b:10:06",
        "IPv4Address": "172.18.0.4/16",
        "IPv6Address": "fc00:f853:ccd:e793::4/64"
      }
    },
    "Options": {
      "com.docker.network.bridge.enable_ip_masquerade": "true",
      "com.docker.network.driver.mtu": "1500"
    },
    "Labels": {}
  }
]

7. ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ํด๋Ÿฌ์Šคํ„ฐ ์ •๋ณด ํ™•์ธ

1
kubectl cluster-info

โœ…ย ์ถœ๋ ฅ

1
2
3
4
Kubernetes control plane is running at https://192.168.219.103:36865
CoreDNS is running at https://192.168.219.103:36865/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

8. ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๋…ธ๋“œ ์ •๋ณด ํ™•์ธ

1
kubectl get node -o wide

โœ…ย ์ถœ๋ ฅ

1
2
3
4
NAME                  STATUS   ROLES           AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                         KERNEL-VERSION   CONTAINER-RUNTIME
myk8s-control-plane   Ready    control-plane   20m   v1.32.2   172.18.0.4    <none>        Debian GNU/Linux 12 (bookworm)   6.13.8-arch1-1   containerd://2.0.3
myk8s-worker          Ready    <none>          20m   v1.32.2   172.18.0.2    <none>        Debian GNU/Linux 12 (bookworm)   6.13.8-arch1-1   containerd://2.0.3
myk8s-worker2         Ready    <none>          20m   v1.32.2   172.18.0.3    <none>        Debian GNU/Linux 12 (bookworm)   6.13.8-arch1-1   containerd://2.0.3

9. ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ํŒŒ๋“œ ์ƒํƒœ ํ™•์ธ

1
kubectl get pod -A -o wide

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
NAMESPACE            NAME                                          READY   STATUS    RESTARTS   AGE   IP           NODE                  NOMINATED NODE   READINESS GATES
kube-system          coredns-668d6bf9bc-9jr7l                      1/1     Running   0          20m   10.244.0.3   myk8s-control-plane   <none>           <none>
kube-system          coredns-668d6bf9bc-wwd8c                      1/1     Running   0          20m   10.244.0.2   myk8s-control-plane   <none>           <none>
kube-system          etcd-myk8s-control-plane                      1/1     Running   0          20m   172.18.0.4   myk8s-control-plane   <none>           <none>
kube-system          kindnet-gjp2z                                 1/1     Running   0          20m   172.18.0.3   myk8s-worker2         <none>           <none>
kube-system          kindnet-m45kh                                 1/1     Running   0          20m   172.18.0.4   myk8s-control-plane   <none>           <none>
kube-system          kindnet-sbjrk                                 1/1     Running   0          20m   172.18.0.2   myk8s-worker          <none>           <none>
kube-system          kube-apiserver-myk8s-control-plane            1/1     Running   0          20m   172.18.0.4   myk8s-control-plane   <none>           <none>
kube-system          kube-controller-manager-myk8s-control-plane   1/1     Running   0          20m   172.18.0.4   myk8s-control-plane   <none>           <none>
kube-system          kube-proxy-8zvnt                              1/1     Running   0          20m   172.18.0.2   myk8s-worker          <none>           <none>
kube-system          kube-proxy-pqrln                              1/1     Running   0          20m   172.18.0.3   myk8s-worker2         <none>           <none>
kube-system          kube-proxy-xjbwl                              1/1     Running   0          20m   172.18.0.4   myk8s-control-plane   <none>           <none>
kube-system          kube-scheduler-myk8s-control-plane            1/1     Running   0          20m   172.18.0.4   myk8s-control-plane   <none>           <none>
local-path-storage   local-path-provisioner-7dc846544d-7hx2m       1/1     Running   0          20m   10.244.0.4   myk8s-control-plane   <none>           <none>

10. ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๋„ค์ž„์ŠคํŽ˜์ด์Šค ๋ชฉ๋ก ํ™•์ธ

1
kubectl get namespaces

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
NAME                 STATUS   AGE
default              Active   21m
kube-node-lease      Active   21m
kube-public          Active   21m
kube-system          Active   21m
local-path-storage   Active   21m

11. ๋„์ปค ์ปจํ…Œ์ด๋„ˆ ์ƒํƒœ ํ™•์ธ

1
docker ps

โœ…ย ์ถœ๋ ฅ

1
2
3
4
CONTAINER ID   IMAGE                  COMMAND                  CREATED          STATUS          PORTS                                                                   NAMES
921a8848ddd4   kindest/node:v1.32.2   "/usr/local/bin/entrโ€ฆ"   21 minutes ago   Up 21 minutes                                                                           myk8s-worker
33b78e624fbd   kindest/node:v1.32.2   "/usr/local/bin/entrโ€ฆ"   21 minutes ago   Up 21 minutes                                                                           myk8s-worker2
f4b058d07f4a   kindest/node:v1.32.2   "/usr/local/bin/entrโ€ฆ"   21 minutes ago   Up 21 minutes   0.0.0.0:30000-30003->30000-30003/tcp, 192.168.219.103:36865->6443/tcp   myk8s-control-plan

12. kube-ops-view ์„ค์น˜

1
2
helm repo add geek-cookbook https://geek-cookbook.github.io/charts/
helm install kube-ops-view geek-cookbook/kube-ops-view --version 1.2.2 --set service.main.type=NodePort,service.main.ports.http.nodePort=30001 --set env.TZ="Asia/Seoul" --namespace kube-system

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
NAME: kube-ops-view
LAST DEPLOYED: Sat Mar 29 14:50:17 2025
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. Get the application URL by running these commands:
  export NODE_PORT=$(kubectl get --namespace kube-system -o jsonpath="{.spec.ports[0].nodePort}" services kube-ops-view)
  export NODE_IP=$(kubectl get nodes --namespace kube-system -o jsonpath="{.items[0].status.addresses[0].address}")
  echo http://$NODE_IP:$NODE_PORT

13. kube-ops-view ์„ค์น˜ ํ™•์ธ

1
kubectl get deploy,pod,svc,ep -n kube-system -l app.kubernetes.io/instance=kube-ops-view

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
NAME                            READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/kube-ops-view   1/1     1            1           53s

NAME                                 READY   STATUS    RESTARTS   AGE
pod/kube-ops-view-6658c477d4-w247s   1/1     Running   0          53s

NAME                    TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/kube-ops-view   NodePort   10.96.236.75   <none>        8080:30001/TCP   53s

NAME                      ENDPOINTS         AGE
endpoints/kube-ops-view   10.244.3.2:8080   53s

http://127.0.0.1:30001/#scale=1.5 ์ ‘์†


โš™๏ธ ์  ํ‚จ์Šค ์„ค์ • ๋ฐ CI/CD ํŒŒ์ดํ”„๋ผ์ธ ๊ตฌ์„ฑ

1. ์  ํ‚จ์Šค ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์น˜

  • Plugins ๋ฉ”๋‰ด ์„ ํƒ

  • Available plugins: Pipeline Stage View, Docker Pipeline, Gogs ํ”Œ๋Ÿฌ๊ทธ์ธ ์„ค์น˜

2. ์ž๊ฒฉ์ฆ๋ช… ์„ค์ •

  • Jenkins ๊ด€๋ฆฌ โ†’ Credentials โ†’ Domains(global) โ†’ Add Credentials

  • Gogs Repo ์ž๊ฒฉ์ฆ๋ช… ์„ค์ • : gogs-crd
  • Kind : Username with password
  • Username : devops / Password(Gogs ํ† ํฐ) : fef3afd3ae1c5e0869a5e6d3233ff0949f1e4e04 / ID : gogs-crd

  • ๋„์ปค ํ—ˆ๋ธŒ ์ž๊ฒฉ์ฆ๋ช… ์„ค์ • : dockerhub-crd
  • Kind : Username with password
  • Username : shinminjin / Password : xxxxxxxxxxxxxxxxxxxxx / ID : dockerhub-crd

  • k8s(kind) ์ž๊ฒฉ์ฆ๋ช… ์„ค์ • : k8s-crd
  • Kind : Secret file / File : <kubeconfig ํŒŒ์ผ ์—…๋กœ๋“œ> / ID : k8s-crd
1
cp ~/.kube/config ./kube-config

  • 3๊ฐœ์˜ ์ž๊ฒฉ์ฆ๋ช… ์…‹ํŒ… ์™„๋ฃŒ

3. ์  ํ‚จ์Šค ํŒŒ์ดํ”„๋ผ์ธ ์…‹ํŒ…

  • ํŒŒ์ดํ”„๋ผ์ธ ์ƒ์„ฑ

  • ํŒŒ์ดํ”„๋ผ์ธ ์Šคํฌ๋ฆฝํŠธ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
pipeline {
    agent any
    environment {
        DOCKER_IMAGE = 'shinminjin/dev-app' // Docker ์ด๋ฏธ์ง€ ์ด๋ฆ„, <์ž์‹ ์˜ ๋„์ปค ํ—ˆ๋ธŒ ๊ณ„์ •>/dev-app
    }
    stages {
        stage('Checkout') {
            steps {
                 git branch: 'main',
                 url: 'http://192.168.219.103:3000/devops/dev-app.git',  // Git์—์„œ ์ฝ”๋“œ ์ฒดํฌ์•„์›ƒ, <์ž์‹ ์˜ ์ง‘ IP>
                 credentialsId: 'gogs-crd'  // Credentials ID
            }
        }
        stage('Read VERSION') {
            steps {
                script {
                    // VERSION ํŒŒ์ผ ์ฝ๊ธฐ
                    def version = readFile('VERSION').trim()
                    echo "Version found: ${version}"
                    // ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •
                    env.DOCKER_TAG = version
                }
            }
        }
        stage('Docker Build and Push') {
            steps {
                script {
                    docker.withRegistry('https://index.docker.io/v1/', 'dockerhub-crd') {
                        // DOCKER_TAG ์‚ฌ์šฉ
                        def appImage = docker.build("${DOCKER_IMAGE}:${DOCKER_TAG}")
                        appImage.push()
                        appImage.push("latest")
                    }
                }
            }
        }
    }
    post {
        success {
            echo "Docker image ${DOCKER_IMAGE}:${DOCKER_TAG} has been built and pushed successfully!"
        }
        failure {
            echo "Pipeline failed. Please check the logs."
        }
    }
}

4. ํŒŒ์ดํ”„๋ผ์ธ ์‹คํ–‰


๐Ÿ“ก k8s ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ ๋ฐ ๊ฒ€์ฆ (Jenkins Pipeline CI)

1. Timeserver Deployment ์ƒ์„ฑ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
DHUSER=<๋„์ปค ํ—ˆ๋ธŒ ๊ณ„์ •๋ช…>
DHUSER=shinminjin

cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: timeserver
spec:
  replicas: 2
  selector:
    matchLabels:
      pod: timeserver-pod
  template:
    metadata:
      labels:
        pod: timeserver-pod
    spec:
      containers:
      - name: timeserver-container
        image: docker.io/$DHUSER/dev-app:0.0.1
        livenessProbe:
          initialDelaySeconds: 30
          periodSeconds: 30
          httpGet:
            path: /healthz
            port: 80
            scheme: HTTP
          timeoutSeconds: 5
          failureThreshold: 3
          successThreshold: 1
EOF

# ๊ฒฐ๊ณผ
deployment.apps/timeserver created

2. ์ด๋ฏธ์ง€ ํ’€ ์—๋Ÿฌ ๋ฐ ์ด๋ฒคํŠธ ํ™•์ธ

1
kubectl get events -w --sort-by '.lastTimestamp'

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
warning: --watch requested, --sort-by will be ignored for watch events received
LAST SEEN   TYPE      REASON                    OBJECT                             MESSAGE
11m         Normal    Starting                  node/myk8s-control-plane           
96s         Normal    Scheduled                 pod/timeserver-6cd9654cc7-l4v9d    Successfully assigned default/timeserver-6cd9654cc7-l4v9d to myk8s-worker
96s         Normal    Scheduled                 pod/timeserver-6cd9654cc7-f7ck7    Successfully assigned default/timeserver-6cd9654cc7-f7ck7 to myk8s-worker2
11m         Normal    Starting                  node/myk8s-worker2                 
11m         Normal    Starting                  node/myk8s-worker                  
11m         Normal    NodeAllocatableEnforced   node/myk8s-worker2                 Updated Node Allocatable limit across pods
11m         Normal    Starting                  node/myk8s-worker2                 Starting kubelet.
11m         Normal    Starting                  node/myk8s-worker                  Starting kubelet.
11m         Normal    NodeHasSufficientPID      node/myk8s-control-plane           Node myk8s-control-plane status is now: NodeHasSufficientPID
11m         Normal    NodeHasNoDiskPressure     node/myk8s-control-plane           Node myk8s-control-plane status is now: NodeHasNoDiskPressure
11m         Normal    Starting                  node/myk8s-control-plane           Starting kubelet.
11m         Normal    NodeAllocatableEnforced   node/myk8s-worker                  Updated Node Allocatable limit across pods
11m         Normal    NodeAllocatableEnforced   node/myk8s-control-plane           Updated Node Allocatable limit across pods
11m         Normal    NodeHasSufficientMemory   node/myk8s-control-plane           Node myk8s-control-plane status is now: NodeHasSufficientMemory
11m         Normal    NodeHasNoDiskPressure     node/myk8s-worker                  Node myk8s-worker status is now: NodeHasNoDiskPressure
11m         Normal    NodeHasSufficientMemory   node/myk8s-worker2                 Node myk8s-worker2 status is now: NodeHasSufficientMemory
11m         Normal    NodeHasNoDiskPressure     node/myk8s-worker2                 Node myk8s-worker2 status is now: NodeHasNoDiskPressure
11m         Normal    NodeHasSufficientPID      node/myk8s-worker2                 Node myk8s-worker2 status is now: NodeHasSufficientPID
11m         Normal    NodeHasSufficientPID      node/myk8s-worker                  Node myk8s-worker status is now: NodeHasSufficientPID
11m         Normal    NodeHasSufficientMemory   node/myk8s-worker                  Node myk8s-worker status is now: NodeHasSufficientMemory
11m         Normal    RegisteredNode            node/myk8s-worker                  Node myk8s-worker event: Registered Node myk8s-worker in Controller
11m         Normal    RegisteredNode            node/myk8s-worker2                 Node myk8s-worker2 event: Registered Node myk8s-worker2 in Controller
11m         Normal    RegisteredNode            node/myk8s-control-plane           Node myk8s-control-plane event: Registered Node myk8s-control-plane in Controller
96s         Normal    ScalingReplicaSet         deployment/timeserver              Scaled up replica set timeserver-6cd9654cc7 from 0 to 2
96s         Normal    SuccessfulCreate          replicaset/timeserver-6cd9654cc7   Created pod: timeserver-6cd9654cc7-f7ck7
96s         Normal    SuccessfulCreate          replicaset/timeserver-6cd9654cc7   Created pod: timeserver-6cd9654cc7-l4v9d
24s         Warning   Failed                    pod/timeserver-6cd9654cc7-l4v9d    Error: ImagePullBackOff
24s         Normal    BackOff                   pod/timeserver-6cd9654cc7-l4v9d    Back-off pulling image "docker.io/shinminjin/dev-app:0.0.1"
23s         Normal    BackOff                   pod/timeserver-6cd9654cc7-f7ck7    Back-off pulling image "docker.io/shinminjin/dev-app:0.0.1"
23s         Warning   Failed                    pod/timeserver-6cd9654cc7-f7ck7    Error: ImagePullBackOff
9s          Normal    Pulling                   pod/timeserver-6cd9654cc7-f7ck7    Pulling image "docker.io/shinminjin/dev-app:0.0.1"
9s          Normal    Pulling                   pod/timeserver-6cd9654cc7-l4v9d    Pulling image "docker.io/shinminjin/dev-app:0.0.1"
7s          Warning   Failed                    pod/timeserver-6cd9654cc7-f7ck7    Error: ErrImagePull
7s          Warning   Failed                    pod/timeserver-6cd9654cc7-l4v9d    Error: ErrImagePull
7s          Warning   Failed                    pod/timeserver-6cd9654cc7-l4v9d    Failed to pull image "docker.io/shinminjin/dev-app:0.0.1": failed to pull and unpack image "docker.io/shinminjin/dev-app:0.0.1": failed to resolve reference "docker.io/shinminjin/dev-app:0.0.1": pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
7s          Warning   Failed                    pod/timeserver-6cd9654cc7-f7ck7    Failed to pull image "docker.io/shinminjin/dev-app:0.0.1": failed to pull and unpack image "docker.io/shinminjin/dev-app:0.0.1": failed to resolve reference "docker.io/shinminjin/dev-app:0.0.1": pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
0s          Normal    BackOff                   pod/timeserver-6cd9654cc7-f7ck7    Back-off pulling image "docker.io/shinminjin/dev-app:0.0.1"
0s          Warning   Failed                    pod/timeserver-6cd9654cc7-f7ck7    Error: ImagePullBackOff
  • Private ์ €์žฅ์†Œ๋ผ ์ด๋ฏธ์ง€ ํ’€ ๊ถŒํ•œ์ด ์—†์–ด์„œ ImagePullBackOff ์—๋Ÿฌ ๋ฐœ์ƒ

3. ๋„์ปค ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ ์ž๊ฒฉ์ฆ๋ช… ์„ค์ •

1
2
DHUSER=<๋„์ปค ํ—ˆ๋ธŒ ๊ณ„์ •>
DHPASS=<๋„์ปค ํ—ˆ๋ธŒ ์•”ํ˜ธ ํ˜น์€ ํ† ํฐ>
1
2
3
4
5
6
7
kubectl create secret docker-registry dockerhub-secret \
  --docker-server=https://index.docker.io/v1/ \
  --docker-username=$DHUSER \
  --docker-password=$DHPASS

# ๊ฒฐ๊ณผ
secret/dockerhub-secret created

4. ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค Secret ๋ชฉ๋ก ํ™•์ธ

1
kubectl get secret

โœ…ย ์ถœ๋ ฅ

1
2
NAME               TYPE                             DATA   AGE
dockerhub-secret   kubernetes.io/dockerconfigjson   1      22s

5. ๋ฐฐํฌ ์ƒํƒœ ๋ฐ ํŒŒ๋“œ ํ™•์ธ

1
kubectl get deploy,pod

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/timeserver   2/2     2            2           9m2s

NAME                              READY   STATUS    RESTARTS   AGE
pod/timeserver-69c87f9f8c-jn2zv   1/1     Running   0          51s
pod/timeserver-69c87f9f8c-r5j6l   1/1     Running   0          83s

6. ์ ‘์† ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•œ Curl ํŒŒ๋“œ ์ƒ์„ฑ

1
2
3
4
kubectl run curl-pod --image=curlimages/curl:latest --command -- sh -c "while true; do sleep 3600; done"

# ๊ฒฐ๊ณผ
pod/curl-pod created

7. Timeserver ํŒŒ๋“œ IP ํ™•์ธ ๋ฐ ์ ‘์† ํ…Œ์ŠคํŠธ

(1) Timeserver ํŒŒ๋“œ IP ํ™•์ธ

1
kubectl get pod -owide

โœ…ย ์ถœ๋ ฅ

1
2
3
4
NAME                          READY   STATUS    RESTARTS   AGE     IP           NODE            NOMINATED NODE   READINESS GATES
curl-pod                      1/1     Running   0          20s     10.244.1.4   myk8s-worker    <none>           <none>
timeserver-69c87f9f8c-jn2zv   1/1     Running   0          2m34s   10.244.1.3   myk8s-worker    <none>           <none>
timeserver-69c87f9f8c-r5j6l   1/1     Running   0          3m6s    10.244.3.4   myk8s-worker2   <none>           <none

(2) Timeserver ํŒŒ๋“œ ์ค‘ ํ•œ ๊ฐœ์˜ IP(ex. 10.244.1.3)๋ฅผ ๋ณ€์ˆ˜ PODIP1์— ํ• ๋‹น

1
2
PODIP1=<timeserver-Y ํŒŒ๋“œ IP>
PODIP1=10.244.1.3

(3) curl-pod ์—์„œ ํ•ด๋‹น IP๋กœ ์ ‘์†ํ•˜์—ฌ ๊ธฐ๋ณธ ์—”๋“œํฌ์ธํŠธ(/) ์‘๋‹ต ํ™•์ธ

1
kubectl exec -it curl-pod -- curl $PODIP1

โœ…ย ์ถœ๋ ฅ

1
2
The time is 6:53:49 AM, VERSION 0.0.1
Server hostname: timeserver-69c87f9f8c-jn2zv

(4) /healthz ์—”๋“œํฌ์ธํŠธ์— ๋Œ€ํ•œ ์‘๋‹ต ํ™•์ธ

1
kubectl exec -it curl-pod -- curl $PODIP1/healthz

โœ…ย ์ถœ๋ ฅ

1
Healthy%

8. ํŒŒ๋“œ ๋กœ๊ทธ ๋ชจ๋‹ˆํ„ฐ๋ง

1
kubectl stern deploy/timeserver

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
+ timeserver-69c87f9f8c-r5j6l โ€บ timeserver-container
+ timeserver-69c87f9f8c-jn2zv โ€บ timeserver-container
timeserver-69c87f9f8c-jn2zv timeserver-container Listening on 0.0.0.0:80
timeserver-69c87f9f8c-jn2zv timeserver-container 10.244.1.1 - - [29/Mar/2025 06:50:49] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-jn2zv timeserver-container 10.244.1.1 - - [29/Mar/2025 06:51:19] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-jn2zv timeserver-container 10.244.1.1 - - [29/Mar/2025 06:51:49] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-jn2zv timeserver-container 10.244.1.1 - - [29/Mar/2025 06:52:19] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-jn2zv timeserver-container 10.244.1.1 - - [29/Mar/2025 06:52:49] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-jn2zv timeserver-container 10.244.1.1 - - [29/Mar/2025 06:53:19] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-jn2zv timeserver-container 10.244.1.4 - - [29/Mar/2025 06:53:49] "GET / HTTP/1.1" 200 -
timeserver-69c87f9f8c-jn2zv timeserver-container 10.244.1.1 - - [29/Mar/2025 06:53:49] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-jn2zv timeserver-container 10.244.1.1 - - [29/Mar/2025 06:54:19] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-jn2zv timeserver-container 10.244.1.4 - - [29/Mar/2025 06:54:22] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-jn2zv timeserver-container 10.244.1.1 - - [29/Mar/2025 06:54:49] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-r5j6l timeserver-container Listening on 0.0.0.0:80
timeserver-69c87f9f8c-r5j6l timeserver-container 10.244.3.1 - - [29/Mar/2025 06:50:17] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-r5j6l timeserver-container 10.244.3.1 - - [29/Mar/2025 06:50:47] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-r5j6l timeserver-container 10.244.3.1 - - [29/Mar/2025 06:51:17] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-r5j6l timeserver-container 10.244.3.1 - - [29/Mar/2025 06:51:47] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-r5j6l timeserver-container 10.244.3.1 - - [29/Mar/2025 06:52:17] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-r5j6l timeserver-container 10.244.3.1 - - [29/Mar/2025 06:52:47] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-r5j6l timeserver-container 10.244.3.1 - - [29/Mar/2025 06:53:17] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-r5j6l timeserver-container 10.244.3.1 - - [29/Mar/2025 06:53:47] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-r5j6l timeserver-container 10.244.3.1 - - [29/Mar/2025 06:54:17] "GET /healthz HTTP/1.1" 200 -
timeserver-69c87f9f8c-r5j6l timeserver-container 10.244.3.1 - - [29/Mar/2025 06:54:47] "GET /healthz HTTP/1.1" 200 -

9. ์„œ๋น„์Šค ์ƒ์„ฑ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Service
metadata:
  name: timeserver
spec:
  selector:
    pod: timeserver-pod
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    nodePort: 30000
  type: NodePort
EOF

# ๊ฒฐ๊ณผ
service/timeserver created

10. ์ƒ์„ฑ๋œ ์„œ๋น„์Šค์™€ ์—”๋“œํฌ์ธํŠธ ํ™•์ธ

1
kubectl get service,ep timeserver -owide

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
NAME                 TYPE       CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE   SELECTOR
service/timeserver   NodePort   10.96.206.165   <none>        80:30000/TCP   68s   pod=timeserver-pod

NAME                   ENDPOINTS                     AGE
endpoints/timeserver   10.244.1.3:80,10.244.3.4:80   68s

11. ์„œ๋น„์Šค ์ ‘์† ๋ฐ ์™ธ๋ถ€ ์ ‘๊ทผ ํ™•์ธ

(1) curl-pod ๋‚ด์—์„œ ์ ‘๊ทผ ํ™•์ธ

1
2
kubectl exec -it curl-pod -- curl timeserver
kubectl exec -it curl-pod -- curl timeserver/healthz

โœ…ย ์ถœ๋ ฅ

1
2
3
4
The time is 7:02:54 AM, VERSION 0.0.1
Server hostname: timeserver-69c87f9f8c-jn2zv

Healthy%

(2) ๋กœ์ปฌ์—์„œ ์ ‘๊ทผ ํ™•์ธ

1
2
curl http://127.0.0.1:30000
curl http://127.0.0.1:30000/healthz

โœ…ย ์ถœ๋ ฅ

1
2
3
4
The time is 7:04:09 AM, VERSION 0.0.1
Server hostname: timeserver-69c87f9f8c-jn2zv

Healthy%

12. ๋ถ€ํ•˜ ๋ถ„์‚ฐ ํ…Œ์ŠคํŠธ

(1) ๋ฌดํ•œ ๋ฐ˜๋ณต์œผ๋กœ curl ๋ช…๋ น ์‹คํ–‰

1
while true; do curl -s --connect-timeout 1 http://127.0.0.1:30000 ; sleep 1 ; done

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
The time is 9:08:08 AM, VERSION 0.0.1
Server hostname: timeserver-69c87f9f8c-r5j6l
The time is 9:08:09 AM, VERSION 0.0.1
Server hostname: timeserver-69c87f9f8c-jn2zv
The time is 9:08:10 AM, VERSION 0.0.1
Server hostname: timeserver-69c87f9f8c-jn2zv
The time is 9:08:11 AM, VERSION 0.0.1
Server hostname: timeserver-69c87f9f8c-r5j6l
The time is 9:08:12 AM, VERSION 0.0.1
Server hostname: timeserver-69c87f9f8c-r5j6l
The time is 9:08:13 AM, VERSION 0.0.1
Server hostname: timeserver-69c87f9f8c-jn2zv
...

(2) 100๋ฒˆ์˜ ํ˜ธ์ถœ ๊ฒฐ๊ณผ ์ง‘๊ณ„

1
for i in {1..100};  do curl -s http://127.0.0.1:30000 | grep name; done | sort | uniq -c | sort -nr

โœ…ย ์ถœ๋ ฅ

1
2
     59 Server hostname: timeserver-69c87f9f8c-jn2zv
     41 Server hostname: timeserver-69c87f9f8c-r5j6l

๐Ÿ”„ ์  ํ‚จ์Šค ํŒŒ์ดํ”„๋ผ์ธ์„ ํ™œ์šฉํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์—…๋ฐ์ดํŠธ

1. ์ƒ˜ํ”Œ ์•ฑ server.py ์ฝ”๋“œ ๋ณ€๊ฒฝ

  • VERSION ํŒŒ์ผ ๋ณ€๊ฒฝ : 0.0.2
  • server.py ํŒŒ์ผ ๋ณ€๊ฒฝ : 0.0.2

2. Git ์ปค๋ฐ‹ / ํ‘ธ์‹œ

1
git add . && git commit -m "VERSION $(cat VERSION) Changed" && git push -u origin main

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
[main e0e3cf9] VERSION 0.0.2 Changed
 2 files changed, 2 insertions(+), 2 deletions(-)
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 18 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 343 bytes | 343.00 KiB/s, done.
Total 4 (delta 2), reused 0 (delta 0), pack-reused 0 (from 0)
To http://192.168.219.103:3000/devops/dev-app.git
   99e9476..e0e3cf9  main -> main
branch 'main' set up to track 'origin/main'.

3. ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค Deployment ์—…๋ฐ์ดํŠธ ์‹œ๋„ ๋ฐ ๋ฌธ์ œ ๋ฐœ์ƒ

1
kubectl set image deployment timeserver timeserver-container=$DHUSER/dev-app:0.0.2 && watch -d "kubectl get deploy,ep timeserver; echo; kubectl get rs,pod"

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Every 2.0s: kubectl get deploy,ep timeserver; echo; kubectl get rs,pod                                                         gram88: 06:20:02 PM
                                                                                                                                     in 0.175s (0)
NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/timeserver   2/2     1            2           158m

NAME                   ENDPOINTS                     AGE
endpoints/timeserver   10.244.1.3:80,10.244.3.4:80   138m

NAME                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/timeserver-69c87f9f8c   2         2         2       151m
replicaset.apps/timeserver-6cd9654cc7   0         0         0       158m
replicaset.apps/timeserver-79d564b95c   1         1         0       7s

NAME                              READY   STATUS         RESTARTS   AGE
pod/curl-pod                      1/1     Running        0          148m
pod/timeserver-69c87f9f8c-jn2zv   1/1     Running        0          150m
pod/timeserver-69c87f9f8c-r5j6l   1/1     Running        0          151m
pod/timeserver-79d564b95c-nck7r   0/1     ErrImagePull   0          7s
  • ์ƒˆ ํƒœ๊ทธ 0.0.2์˜ ์ด๋ฏธ์ง€๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์•„ ์ด๋ฏธ์ง€ ํ’€ ์—๋Ÿฌ(ErrImagePull) ๋ฐœ์ƒ

4. ์  ํ‚จ์Šค ๋นŒ๋“œ๋ฅผ ํ†ตํ•œ ์ƒˆ๋กœ์šด ์ด๋ฏธ์ง€ ์ƒ์„ฑ ๋ฐ ๋ฐฐํฌ ์—…๋ฐ์ดํŠธ

  • ์  ํ‚จ์Šค(์ง€๊ธˆ ๋นŒ๋“œ ์‹คํ–‰) : ์ƒˆ 0.0.2 ๋ฒ„์ „ ํƒœ๊ทธ๋กœ ์ปจํ…Œ์ด๋„ˆ ์ด๋ฏธ์ง€ ๋นŒ๋“œ
  • ์ปจํ…Œ์ด๋„ˆ ์ €์žฅ์†Œ Push โ‡’ k8s deployment ์—…๋ฐ์ดํŠธ ๋ฐฐํฌ

  • 0.0.2 ๋ฒ„์ „์˜ ์ด๋ฏธ์ง€๊ฐ€ ๋ฐฐํฌ๋จ
1
kubectl set image deployment timeserver timeserver-container=$DHUSER/dev-app:0.0.2 && watch -d "kubectl get deploy,ep timeserver; echo; kubectl get rs,pod"

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Every 2.0s: kubectl get deploy,ep timeserver; echo; kubectl get rs,pod                                                         gram88: 06:27:20 PM
                                                                                                                                     in 0.243s (0)
NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/timeserver   2/2     2            2           166m

NAME                   ENDPOINTS                     AGE
endpoints/timeserver   10.244.1.5:80,10.244.3.5:80   146m

NAME                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/timeserver-69c87f9f8c   0         0         0       158m
replicaset.apps/timeserver-6cd9654cc7   0         0         0       166m
replicaset.apps/timeserver-79d564b95c   2         2         2       7m25s

NAME                              READY   STATUS    RESTARTS   AGE
pod/curl-pod                      1/1     Running   0          155m
pod/timeserver-79d564b95c-74gpz   1/1     Running   0          113s
pod/timeserver-79d564b95c-nck7r   1/1     Running   0          7m25s

5. Gogs ์„ค์ • ๋ณ€๊ฒฝ ๋ฐ ์›นํ›… ๋“ฑ๋ก

(1) gogs ์ปจํ…Œ์ด๋„ˆ ๋‚ด /data/gogs/conf/app.ini ํŒŒ์ผ ์ˆ˜์ •

1
2
3
4
docker compose exec gogs bash

a0dda4a63d1b:/# cd /data/gogs/conf/
a0dda4a63d1b:/data/gogs/conf# vi app.ini

LOCAL_NETWORK_ALLOWLIST = 192.168.219.103 ์ถ”๊ฐ€

1
2
3
4
[security]
INSTALL_LOCK = true
SECRET_KEY   = 0QLuknjrgYnZbGu
LOCAL_NETWORK_ALLOWLIST = 192.168.219.103

(2) ์ปจํ…Œ์ด๋„ˆ ์žฌ๊ธฐ๋™

1
2
3
4
5
docker compose restart gogs

# ๊ฒฐ๊ณผ
[+] Restarting 1/1
 โœ” Container gogs  Started

(3) Gogs Webhook ์„ค์ •

  • Webhooks > Gogs ์„ ํƒ

  • Payload URL : http://192.168.219.103:8080/gogs-webhook/?job=SCM-Pipeline/ <์ž์‹ ์˜ ์ง‘="" IP="">
  • Content Type : application/json / Secret : qwe123
  • When should this webhook be triggered? : Just the push event / Active : Check

6. ์  ํ‚จ์Šค ํŒŒ์ดํ”„๋ผ์ธ ์„ค์ •

  • GitHub project : http://192.168.219.103:3000/devops/dev-app <์ž์‹ ์˜ ์ง‘="" IP="">
  • Use Gogs secret : qwe123
  • Build Triggers : Build when a change is pushed to Gogs ์„ ํƒ

  • Pipeline script from SCM / SCM : Git
  • Repo URL(http://192.168.219.103:3000/devops/dev-app) / Credentials(devops**/*****) / Branch(*/main)
  • Script Path : Jenkinsfile

7. Jenkinsfile ๋ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ ์—…๋ฐ์ดํŠธ

1
2
3
4
5
# Jenkinsfile ๋นˆ ํŒŒ์ผ ์ž‘์„ฑ
touch Jenkinsfile

# VERSION ํŒŒ์ผ : 0.0.3 ์ˆ˜์ •
# server.py ํŒŒ์ผ : 0.0.3 ์ˆ˜์ •

Jenkinsfile ์ž‘์„ฑ

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
pipeline {
    agent any
    environment {
        DOCKER_IMAGE = 'shinminjin/dev-app' // Docker ์ด๋ฏธ์ง€ ์ด๋ฆ„, <์ž์‹ ์˜ ๋„์ปค ํ—ˆ๋ธŒ ๊ณ„์ •>/dev-app
    }
    stages {
        stage('Checkout') {
            steps {
                 git branch: 'main',
                 url: 'http://192.168.219.103:3000/devops/dev-app.git',  // Git์—์„œ ์ฝ”๋“œ ์ฒดํฌ์•„์›ƒ, <์ž์‹ ์˜ ์ง‘ IP>:3000
                 credentialsId: 'gogs-crd'  // Credentials ID
            }
        }
        stage('Read VERSION') {
            steps {
                script {
                    // VERSION ํŒŒ์ผ ์ฝ๊ธฐ
                    def version = readFile('VERSION').trim()
                    echo "Version found: ${version}"
                    // ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ์„ค์ •
                    env.DOCKER_TAG = version
                }
            }
        }
        stage('Docker Build and Push') {
            steps {
                script {
                    docker.withRegistry('https://index.docker.io/v1/', 'dockerhub-crd') {
                        // DOCKER_TAG ์‚ฌ์šฉ
                        def appImage = docker.build("${DOCKER_IMAGE}:${DOCKER_TAG}")
                        appImage.push()
                        appImage.push("latest")
                    }
                }
            }
        }
    }
    post {
        success {
            echo "Docker image ${DOCKER_IMAGE}:${DOCKER_TAG} has been built and pushed successfully!"
        }
        failure {
            echo "Pipeline failed. Please check the logs."
        }
    }
}

8. ๋ณ€๊ฒฝ์‚ฌํ•ญ ์ปค๋ฐ‹ ๋ฐ Git Push

1
git add . && git commit -m "VERSION $(cat VERSION) Changed" && git push -u origin main

โœ…ย ์ถœ๋ ฅ

1
2
3
4
5
6
7
8
9
10
11
12
[main 6f80ffb] VERSION 0.0.3 Changed
 3 files changed, 48 insertions(+), 2 deletions(-)
 create mode 100644 Jenkinsfile
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 18 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (5/5), 1.07 KiB | 1.07 MiB/s, done.
Total 5 (delta 1), reused 0 (delta 0), pack-reused 0 (from 0)
To http://192.168.219.103:3000/devops/dev-app.git
   e0e3cf9..6f80ffb  main -> main
branch 'main' set up to track 'origin/main'.

9. ์  ํ‚จ์Šค Job ๋นŒ๋“œ ์‹คํ–‰

This post is licensed under CC BY 4.0 by the author.